Neues Modul: Visuelle Chartmuster-Erkennung (core/patterns.py) — reine Anzeige
Erkennt aus M30-Swing-Pivots: Doppeltop/-boden, Kopf-Schulter/inverse SKS, Tasse+Henkel/invers, auf-/absteigendes+symmetrisches Dreieck. Je Muster Richtung, Trigger/Nackenlinie, Measured-Move-Ziel, Status (bildet sich/bestätigt/ungültig), Güte. Dashboard-Karte #card-patterns + Disclaimer (v=116). KEIN Signal, kein Verdict-Gewicht — Signal-Einfluss erst nach Backtest (Muster-Klasse 2x verworfen, hohe Beweislast). Live getestet: findet bestätigten Doppeltop. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
cd8ee5b01b
commit
e5589da08b
+32
@@ -224,6 +224,37 @@ function renderCircuitBreaker(cb) {
|
||||
}
|
||||
}
|
||||
|
||||
// Chartmuster (visuell) — reine Anzeige. Status: bildet sich / bestätigt / (ungültig raus).
|
||||
function renderPatterns(pt) {
|
||||
const el = $("pt-list");
|
||||
if (!el) return;
|
||||
const items = (pt && pt.patterns) || [];
|
||||
if (!items.length) {
|
||||
el.innerHTML = `<span class="dim">Aktuell kein klares Muster erkannt.</span>`;
|
||||
return;
|
||||
}
|
||||
el.innerHTML = items.map(m => {
|
||||
const dirCls = m.dir === "bull" ? "up" : m.dir === "bear" ? "down" : "dim";
|
||||
const arr = m.dir === "bull" ? "▲" : m.dir === "bear" ? "▼" : "◆";
|
||||
const st = m.status === "confirmed"
|
||||
? `<span class="pt-badge conf">bestätigt</span>`
|
||||
: `<span class="pt-badge form">bildet sich</span>`;
|
||||
const tgt = m.target != null
|
||||
? `Ziel <b>${fmt(m.target, 2)}</b>` : `Ausbruch offen`;
|
||||
const q = Math.round((m.quality || 0) * 100);
|
||||
return `<div class="pt-item ${dirCls}">
|
||||
<div class="pt-head"><span class="pt-name">${arr} ${m.name}</span>${st}
|
||||
<span class="pt-q">Güte ${q}%</span></div>
|
||||
<div class="pt-det">Trigger <b>${fmt(m.trigger, 2)}</b> · ${tgt}
|
||||
· Höhe ${m.height_atr}×ATR · vor ${m.bars_ago} Bars</div>
|
||||
<div class="pt-note">${m.note || ""}</div>
|
||||
</div>`;
|
||||
}).join("") +
|
||||
`<div class="pt-disclaimer">📊 Reine Anzeige (mechanisch aus M30-Pivots) — KEIN Signal,
|
||||
kein Einfluss auf die Empfehlung. Muster-Klasse im Projekt als Signal noch unbelegt;
|
||||
Einfluss erst nach Backtest.</div>`;
|
||||
}
|
||||
|
||||
function render(d) {
|
||||
// ── Header ──────────────────────────────
|
||||
$("conn").className = "dot " + (d.connected ? "on" : "off");
|
||||
@@ -314,6 +345,7 @@ function render(d) {
|
||||
// ── Gesamtempfehlung (aggregiert) ───────
|
||||
renderVerdict(d.verdict || {}, d);
|
||||
renderCircuitBreaker(d.circuit_breaker);
|
||||
renderPatterns(d.patterns);
|
||||
renderStructure(d.structure);
|
||||
renderStatsCompact(d.stats_compact, d.market);
|
||||
renderGaps(d.gaps, d.market);
|
||||
|
||||
+8
-2
@@ -6,7 +6,7 @@
|
||||
<meta name="theme-color" content="#0d1117">
|
||||
<title>Oil · MT5</title>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="stylesheet" href="style.css?v=115">
|
||||
<link rel="stylesheet" href="style.css?v=116">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Modul-Menü (ganz oben) -->
|
||||
@@ -116,6 +116,12 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Chartmuster (visuell) — reine Anzeige, kein Signal (noch nicht backtestet) -->
|
||||
<section class="card wide" id="card-patterns">
|
||||
<h2>Chartmuster <span class="pt-tf">M30 · visuell</span></h2>
|
||||
<div class="pt-list" id="pt-list"><span class="dim">—</span></div>
|
||||
</section>
|
||||
|
||||
<!-- KI-Agent -->
|
||||
<section class="card wide" id="card-agent">
|
||||
<h2>KI-Copilot</h2>
|
||||
@@ -220,6 +226,6 @@
|
||||
<div id="toast" class="toast hidden"></div>
|
||||
|
||||
<script src="lightweight-charts.standalone.production.js?v=114"></script>
|
||||
<script src="app.js?v=115"></script>
|
||||
<script src="app.js?v=116"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -141,6 +141,21 @@ main{display:grid;grid-template-columns:1fr 1fr;gap:11px;padding:11px}
|
||||
.circuit.tripped{background:#3d1a1a;color:#ff6b6b;border:1px solid var(--down);
|
||||
box-shadow:0 0 0 1px var(--down)}
|
||||
.circuit.near{background:#2a1f00;color:var(--accent);border:1px solid #4a3600}
|
||||
/* Chartmuster-Karte (visuell, reine Anzeige) */
|
||||
#card-patterns .pt-tf{font-size:11px;color:var(--dim);font-weight:600;margin-left:6px}
|
||||
.pt-item{background:var(--surface-2);border:1px solid var(--border);border-left:3px solid var(--line);
|
||||
border-radius:var(--r-sm);padding:9px 12px;margin-bottom:8px}
|
||||
.pt-item.up{border-left-color:var(--up)} .pt-item.down{border-left-color:var(--down)}
|
||||
.pt-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
||||
.pt-name{font-weight:700;font-size:15px}
|
||||
.pt-item.up .pt-name{color:var(--up)} .pt-item.down .pt-name{color:var(--down)}
|
||||
.pt-badge{font-size:11px;font-weight:700;border-radius:4px;padding:1px 7px}
|
||||
.pt-badge.conf{background:#0d2a16;color:var(--up);border:1px solid #1a4731}
|
||||
.pt-badge.form{background:#2a1f00;color:var(--accent);border:1px solid #4a3600}
|
||||
.pt-q{margin-left:auto;font-size:12px;color:var(--dim);font-family:var(--mono)}
|
||||
.pt-det{font-size:13px;margin-top:4px;font-family:var(--mono);color:var(--bright)}
|
||||
.pt-note{font-size:12px;color:var(--dim);margin-top:3px}
|
||||
.pt-disclaimer{font-size:12px;color:var(--dim);margin-top:6px;line-height:1.4}
|
||||
#card-verdict{border-color:var(--accent)}
|
||||
.vd-head{display:flex;align-items:center;gap:14px;margin-bottom:10px}
|
||||
.vd-ring{width:60px;height:60px;border-radius:50%;flex:0 0 auto;
|
||||
|
||||
Reference in New Issue
Block a user