Meta Description" name="description" />
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Brooks × ICT — Price Action Patterns</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700;900&family=JetBrains+Mono:wght@300;400;600&display=swap');
:root {
--bg: #0a0a0a;
--surface: #111111;
--border: #1e1e1e;
--gold: #c9a84c;
--gold-light: #e8c97a;
--bull: #26a69a;
--bear: #ef5350;
--neutral: #555;
--text: #e0e0e0;
--muted: #666;
--label: #aaa;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: var(--bg);
color: var(--text);
font-family: 'JetBrains Mono', monospace;
min-height: 100vh;
}
header {
padding: 32px 24px 20px;
border-bottom: 1px solid var(--border);
background: linear-gradient(180deg, #111 0%, #0a0a0a 100%);
}
header h1 {
font-family: 'Playfair Display', serif;
font-size: 1.6rem;
color: var(--gold);
letter-spacing: 0.04em;
}
header p {
font-size: 0.7rem;
color: var(--muted);
margin-top: 6px;
letter-spacing: 0.1em;
text-transform: uppercase;
}
.tabs {
display: flex;
gap: 0;
padding: 0 24px;
border-bottom: 1px solid var(--border);
background: var(--surface);
overflow-x: auto;
}
.tab {
padding: 14px 16px;
font-size: 0.65rem;
font-family: 'JetBrains Mono', monospace;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--muted);
cursor: pointer;
border-bottom: 2px solid transparent;
white-space: nowrap;
transition: all 0.2s;
background: none;
border-top: none;
border-left: none;
border-right: none;
}
.tab:hover { color: var(--gold-light); }
.tab.active { color: var(--gold); border-bottom-color: var(--gold); }
.panel { display: none; padding: 24px; }
.panel.active { display: block; }
.chart-wrap {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 4px;
padding: 20px 16px 12px;
margin-bottom: 20px;
position: relative;
}
.chart-title {
font-family: 'Playfair Display', serif;
font-size: 1rem;
color: var(--gold);
margin-bottom: 4px;
}
.chart-subtitle {
font-size: 0.6rem;
color: var(--muted);
letter-spacing: 0.1em;
text-transform: uppercase;
margin-bottom: 16px;
}
canvas {
width: 100%;
display: block;
}
.legend {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 14px;
padding-top: 12px;
border-top: 1px solid var(--border);
}
.legend-item {
display: flex;
align-items: center;
gap: 6px;
font-size: 0.6rem;
color: var(--label);
letter-spacing: 0.06em;
}
.dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.line-swatch {
width: 16px;
height: 2px;
flex-shrink: 0;
}
.explanation {
background: #0f0f0f;
border: 1px solid var(--border);
border-left: 3px solid var(--gold);
border-radius: 4px;
padding: 16px;
font-size: 0.68rem;
line-height: 1.8;
color: var(--label);
}
.explanation strong { color: var(--gold-light); }
.ict-map {
margin-top: 14px;
background: #0c0c0c;
border: 1px solid #1a1a1a;
border-radius: 4px;
padding: 14px;
}
.ict-map-title {
font-size: 0.58rem;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--gold);
margin-bottom: 10px;
}
.map-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 6px 0;
border-bottom: 1px solid #161616;
font-size: 0.62rem;
}
.map-row:last-child { border-bottom: none; }
.map-brooks { color: #aaa; }
.map-arrow { color: var(--gold); opacity: 0.5; }
.map-ict { color: var(--bull); }
</style>
</head>
<body>
<header>
<h1>Brooks × ICT — Price Action Patterns</h1>
<p>Visual candlestick examples with ICT concept mapping</p>
</header>
<div class="tabs">
<button class="tab active" onclick="showTab('high2')">High 2 / ABC</button>
<button class="tab" onclick="showTab('low2')">Low 2 Short</button>
<button class="tab" onclick="showTab('high3')">High 3 Wedge</button>
<button class="tab" onclick="showTab('high4')">High 4 Fail</button>
</div>
<!-- HIGH 2 -->
<div id="high2" class="panel active">
<div class="chart-wrap">
<div class="chart-title">High 2 — Bull Trend Pullback Entry</div>
<div class="chart-subtitle">ABC Correction → Buy Signal</div>
<canvas id="c-high2" height="260"></canvas>
<div class="legend">
<div class="legend-item"><div class="dot" style="background:#26a69a"></div> Bullish bar</div>
<div class="legend-item"><div class="dot" style="background:#ef5350"></div> Bearish bar</div>
<div class="legend-item"><div class="dot" style="background:#c9a84c"></div> Entry bar (High 2)</div>
<div class="legend-item"><div class="line-swatch" style="background:#c9a84c;opacity:0.5"></div> OB / FVG zone</div>
</div>
</div>
<div class="explanation">
<strong>What's happening:</strong> Market is in a bull trend. Price pulls back in two legs (A→B→C). The bar that closes above the high of the previous bar after leg C = <strong>High 2</strong>. That's your entry.<br><br>
<strong>ICT mapping:</strong> The C leg sweeps into an <strong>Order Block or Fair Value Gap</strong>. The High 2 bar is the <strong>MSS / COSD candle</strong> — Smart Money has absorbed sell-side and is now delivering upward.
</div>
<div class="ict-map">
<div class="ict-map-title">Brooks → ICT Translation</div>
<div class="map-row"><span class="map-brooks">A Leg (first drop)</span><span class="map-arrow">→</span><span class="map-ict">Initial displacement / liquidity sweep</span></div>
<div class="map-row"><span class="map-brooks">B Leg (bounce)</span><span class="map-arrow">→</span><span class="map-ict">Internal MSS / minor BOS</span></div>
<div class="map-row"><span class="map-brooks">C Leg (second drop)</span><span class="map-arrow">→</span><span class="map-ict">Tap into OB / FVG / breaker</span></div>
<div class="map-row"><span class="map-brooks">High 2 bar</span><span class="map-arrow">→</span><span class="map-ict">Confirmation MSS → entry</span></div>
</div>
</div>
<!-- LOW 2 -->
<div id="low2" class="panel">
<div class="chart-wrap">
<div class="chart-title">Low 2 — Bear Trend Pullback Short</div>
<div class="chart-subtitle">Two-Leg Rally → Sell Signal</div>
<canvas id="c-low2" height="260"></canvas>
<div class="legend">
<div class="legend-item"><div class="dot" style="background:#26a69a"></div> Bullish bar</div>
<div class="legend-item"><div class="dot" style="background:#ef5350"></div> Bearish bar</div>
<div class="legend-item"><div class="dot" style="background:#c9a84c"></div> Entry bar (Low 2)</div>
<div class="legend-item"><div class="line-swatch" style="background:#ef5350;opacity:0.4"></div> Bearish OB zone</div>
</div>
</div>
<div class="explanation">
<strong>What's happening:</strong> Market is in a bear trend. Price rallies in two legs. The bar that closes below the low of the previous bar after the second rally leg = <strong>Low 2</strong>. Short entry.<br><br>
<strong>ICT mapping:</strong> The two-leg rally sweeps <strong>buy-side liquidity</strong> (equal highs / BSL). Price taps a <strong>bearish OB or IFVG</strong>. The Low 2 bar is your <strong>MSS to the downside</strong> — confirmation that SM is distributing.
</div>
<div class="ict-map">
<div class="ict-map-title">Brooks → ICT Translation</div>
<div class="map-row"><span class="map-brooks">First rally leg</span><span class="map-arrow">→</span><span class="map-ict">SSL swept / displacement up</span></div>
<div class="map-row"><span class="map-brooks">Pullback in rally</span><span class="map-arrow">→</span><span class="map-ict">Internal retracement</span></div>
<div class="map-row"><span class="map-brooks">Second rally leg</span><span class="map-arrow">→</span><span class="map-ict">BSL swept / bearish OB tapped</span></div>
<div class="map-row"><span class="map-brooks">Low 2 bar</span><span class="map-arrow">→</span><span class="map-ict">MSS down → short entry</span></div>
</div>
</div>
<!-- HIGH 3 WEDGE -->
<div id="high3" class="panel">
<div class="chart-wrap">
<div class="chart-title">High 3 — Wedge Bull Flag</div>
<div class="chart-subtitle">3-Push Pullback → Exhaustion Entry</div>
<canvas id="c-high3" height="260"></canvas>
<div class="legend">
<div class="legend-item"><div class="dot" style="background:#26a69a"></div> Bullish bar</div>
<div class="legend-item"><div class="dot" style="background:#ef5350"></div> Bearish bar</div>
<div class="legend-item"><div class="dot" style="background:#c9a84c"></div> Entry bar (High 3)</div>
<div class="legend-item"><div class="line-swatch" style="background:#aaa;opacity:0.4;border-top:1px dashed #aaa"></div> Wedge trendlines</div>
</div>
</div>
<div class="explanation">
<strong>What's happening:</strong> Three legs of pullback form a <strong>wedge</strong> — each low is slightly higher, momentum weakening. The High 3 bar breaks above the prior bar's high = entry. Bulls have fully exhausted sellers.<br><br>
<strong>ICT mapping:</strong> This is a classic <strong>3-push retracement</strong> into a premium array. Each push down is a liquidity sweep attempt. By the 3rd push, sell-side is exhausted and SM begins accumulation. ICT would look for OTE (Optimal Trade Entry) around the 62–79% retracement of the swing.
</div>
<div class="ict-map">
<div class="ict-map-title">Brooks → ICT Translation</div>
<div class="map-row"><span class="map-brooks">Push 1 down (A)</span><span class="map-arrow">→</span><span class="map-ict">First SSL run</span></div>
<div class="map-row"><span class="map-brooks">Push 2 down (C)</span><span class="map-arrow">→</span><span class="map-ict">Second SSL run / OB approached</span></div>
<div class="map-row"><span class="map-brooks">Push 3 down (E)</span><span class="map-arrow">→</span><span class="map-ict">OTE zone hit / final sweep</span></div>
<div class="map-row"><span class="map-brooks">High 3 breakout</span><span class="map-arrow">→</span><span class="map-ict">MSS + accumulation complete</span></div>
</div>
</div>
<!-- HIGH 4 FAIL -->
<div id="high4" class="panel">
<div class="chart-wrap">
<div class="chart-title">High 4 Failure — Trend Reversal Warning</div>
<div class="chart-subtitle">4-Leg Pullback Fails → Stay Out / Reverse</div>
<canvas id="c-high4" height="260"></canvas>
<div class="legend">
<div class="legend-item"><div class="dot" style="background:#26a69a"></div> Bullish bar</div>
<div class="legend-item"><div class="dot" style="background:#ef5350"></div> Bearish bar</div>
<div class="legend-item"><div class="dot" style="background:#ef5350;opacity:0.5"></div> Failure / reversal</div>
<div class="legend-item"><div class="line-swatch" style="background:#ef5350;opacity:0.3"></div> Break of structure</div>
</div>
</div>
<div class="explanation">
<strong>What's happening:</strong> Four pullback legs form but price <strong>fails to resume the bull trend</strong> — it breaks below the High 4 setup low. This is a red flag. The market is no longer pulling back in a bull trend; it's likely reversing.<br><br>
<strong>ICT mapping:</strong> This is a <strong>liquidity sweep that doesn't hold</strong>. SM absorbed supply but couldn't push price up — suggesting <strong>distribution, not accumulation</strong>. ICT would see this as a premium OB that rejected and the market shifting to a bearish delivery. Wait for a new CHoCH / BOS to confirm the new direction.
</div>
<div class="ict-map">
<div class="ict-map-title">Brooks → ICT Translation</div>
<div class="map-row"><span class="map-brooks">High 4 setup forms</span><span class="map-arrow">→</span><span class="map-ict">4-leg retracement into OB/FVG</span></div>
<div class="map-row"><span class="map-brooks">High 4 entry triggered</span><span class="map-arrow">→</span><span class="map-ict">Long attempted at premium array</span></div>
<div class="map-row"><span class="map-brooks">Price breaks below H4 low</span><span class="map-arrow">→</span><span class="map-ict">CHoCH / BOS to downside</span></div>
<div class="map-row"><span class="map-brooks">Wait for more price action</span><span class="map-arrow">→</span><span class="map-ict">Wait for new HTF structure shift</span></div>
</div>
</div>
<script>
const BULL = '#26a69a';
const BEAR = '#ef5350';
const GOLD = '#c9a84c';
const GOLD_DIM = 'rgba(201,168,76,0.15)';
const BULL_DIM = 'rgba(38,166,154,0.12)';
const BEAR_DIM = 'rgba(239,83,80,0.12)';
const TEXT = '#666';
function setupCanvas(id) {
const canvas = document.getElementById(id);
const dpr = window.devicePixelRatio || 1;
const rect = canvas.parentElement.getBoundingClientRect();
const w = rect.width - 32;
const h = parseInt(canvas.getAttribute('height'));
canvas.width = w * dpr;
canvas.height = h * dpr;
canvas.style.width = w + 'px';
canvas.style.height = h + 'px';
const ctx = canvas.getContext('2d');
ctx.scale(dpr, dpr);
return { ctx, w, h };
}
function drawCandle(ctx, x, open, close, high, low, color, width) {
const w = width || 14;
// wick
ctx.strokeStyle = color;
ctx.lineWidth = 1.5;
ctx.beginPath();
ctx.moveTo(x, high);
ctx.lineTo(x, low);
ctx.stroke();
// body
ctx.fillStyle = color;
const top = Math.min(open, close);
const bot = Math.max(open, close);
const bodyH = Math.max(bot - top, 2);
ctx.fillRect(x - w/2, top, w, bodyH);
}
function drawLabel(ctx, x, y, text, color, align) {
ctx.font = '500 9px JetBrains Mono, monospace';
ctx.fillStyle = color || '#888';
ctx.textAlign = align || 'center';
ctx.fillText(text, x, y);
}
function drawArrow(ctx, x, y, up, color) {
ctx.fillStyle = color || GOLD;
ctx.beginPath();
if (up) {
ctx.moveTo(x, y);
ctx.lineTo(x - 6, y + 10);
ctx.lineTo(x + 6, y + 10);
} else {
ctx.moveTo(x, y);
ctx.lineTo(x - 6, y - 10);
ctx.lineTo(x + 6, y - 10);
}
ctx.closePath();
ctx.fill();
}
function drawZone(ctx, x1, x2, y1, y2, color) {
ctx.fillStyle = color;
ctx.fillRect(x1, y1, x2 - x1, y2 - y1);
}
// ---- HIGH 2 ----
function drawHigh2() {
const { ctx, w, h } = setupCanvas('c-high2');
const pad = { l: 30, r: 20, t: 20, b: 30 };
const cw = w - pad.l - pad.r;
const ch = h - pad.t - pad.b;
// price scale: 100-160
const pMin = 98, pMax = 162;
function py(p) { return pad.t + ch * (1 - (p - pMin) / (pMax - pMin)); }
// candles: bull trend then ABC pullback then High2
const candles = [
// Bull trend
{ o: 105, c: 112, h: 113, l: 104, bull: true },
{ o: 111, c: 118, h: 120, l: 110, bull: true },
{ o: 117, c: 125, h: 126, l: 116, bull: true },
{ o: 124, c: 132, h: 133, l: 123, bull: true },
{ o: 131, c: 140, h: 142, l: 130, bull: true },
// A leg down
{ o: 140, c: 133, h: 141, l: 131, bull: false, label: 'A' },
{ o: 133, c: 126, h: 134, l: 124, bull: false },
// B bounce
{ o: 126, c: 130, h: 131, l: 125, bull: true, label: 'B' },
// C leg down
{ o: 130, c: 123, h: 131, l: 121, bull: false, label: 'C' },
{ o: 123, c: 119, h: 124, l: 118, bull: false },
// High 2 entry
{ o: 119, c: 128, h: 130, l: 118, bull: true, entry: true, label: 'H2' },
// continuation
{ o: 127, c: 135, h: 137, l: 126, bull: true },
{ o: 134, c: 143, h: 145, l: 133, bull: true },
];
const total = candles.length;
const spacing = cw / (total + 1);
// Draw OB zone
drawZone(ctx, pad.l + spacing * 9, pad.l + spacing * 11.5, py(122), py(117), GOLD_DIM);
ctx.strokeStyle = 'rgba(201,168,76,0.3)';
ctx.lineWidth = 1;
ctx.setLineDash([3, 3]);
ctx.strokeRect(pad.l + spacing * 9, py(122), spacing * 2.5, py(117) - py(122));
ctx.setLineDash([]);
drawLabel(ctx, pad.l + spacing * 10.2, py(116), 'OB / FVG', GOLD, 'center');
candles.forEach((c, i) => {
const x = pad.l + spacing * (i + 1);
const color = c.entry ? GOLD : (c.bull ? BULL : BEAR);
drawCandle(ctx, x, py(c.o), py(c.c), py(c.h), py(c.l), color, c.entry ? 16 : 13);
if (c.label) {
const labelY = c.bull ? py(c.h) - 12 : py(c.l) + 18;
drawLabel(ctx, x, labelY, c.label, c.entry ? GOLD : '#aaa');
}
});
// Entry arrow
const entryX = pad.l + spacing * 11;
drawArrow(ctx, entryX, py(117) - 4, true, GOLD);
// Price axis labels
[110, 120, 130, 140].forEach(p => {
ctx.fillStyle = TEXT;
ctx.font = '9px JetBrains Mono, monospace';
ctx.textAlign = 'right';
ctx.fillText(p, pad.l - 4, py(p) + 3);
ctx.strokeStyle = '#1a1a1a';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(pad.l, py(p));
ctx.lineTo(w - pad.r, py(p));
ctx.stroke();
});
}
// ---- LOW 2 ----
function drawLow2() {
const { ctx, w, h } = setupCanvas('c-low2');
const pad = { l: 30, r: 20, t: 20, b: 30 };
const cw = w - pad.l - pad.r;
const ch = h - pad.t - pad.b;
const pMin = 95, pMax = 160;
function py(p) { return pad.t + ch * (1 - (p - pMin) / (pMax - pMin)); }
const candles = [
// Bear trend
{ o: 152, c: 145, h: 153, l: 143, bull: false },
{ o: 145, c: 138, h: 146, l: 137, bull: false },
{ o: 138, c: 131, h: 139, l: 130, bull: false },
{ o: 131, c: 124, h: 132, l: 122, bull: false },
// First rally leg up
{ o: 124, c: 131, h: 133, l: 123, bull: true, label: 'A' },
{ o: 131, c: 137, h: 138, l: 130, bull: true },
// Pullback
{ o: 137, c: 133, h: 138, l: 132, bull: false, label: 'B' },
// Second rally leg - sweeps BSL
{ o: 133, c: 140, h: 142, l: 132, bull: true, label: 'C' },
{ o: 140, c: 143, h: 145, l: 139, bull: true },
// Low 2 entry (short)
{ o: 143, c: 134, h: 144, l: 132, bull: false, entry: true, label: 'L2' },
// Continuation down
{ o: 134, c: 126, h: 135, l: 124, bull: false },
{ o: 126, c: 118, h: 127, l: 116, bull: false },
];
const total = candles.length;
const spacing = cw / (total + 1);
// Bearish OB zone at top of rally
drawZone(ctx, pad.l + spacing * 7.5, pad.l + spacing * 10, py(146), py(140), BEAR_DIM);
ctx.strokeStyle = 'rgba(239,83,80,0.25)';
ctx.lineWidth = 1;
ctx.setLineDash([3, 3]);
ctx.strokeRect(pad.l + spacing * 7.5, py(146), spacing * 2.5, py(140) - py(146));
ctx.setLineDash([]);
drawLabel(ctx, pad.l + spacing * 8.8, py(147.5), 'Bearish OB', '#ef5350', 'center');
// BSL line
ctx.strokeStyle = 'rgba(239,83,80,0.3)';
ctx.lineWidth = 1;
ctx.setLineDash([4, 4]);
ctx.beginPath();
ctx.moveTo(pad.l + spacing * 6, py(138));
ctx.lineTo(pad.l + spacing * 10, py(138));
ctx.stroke();
ctx.setLineDash([]);
drawLabel(ctx, pad.l + spacing * 6.5, py(138) - 6, 'BSL', '#ef5350');
candles.forEach((c, i) => {
const x = pad.l + spacing * (i + 1);
const color = c.entry ? GOLD : (c.bull ? BULL : BEAR);
drawCandle(ctx, x, py(c.o), py(c.c), py(c.h), py(c.l), color, c.entry ? 16 : 13);
if (c.label) {
const labelY = c.bull ? py(c.h) - 12 : py(c.l) + 18;
drawLabel(ctx, x, labelY, c.label, c.entry ? GOLD : '#aaa');
}
});
// Entry arrow (down)
const entryX = pad.l + spacing * 10;
drawArrow(ctx, entryX, py(131) + 4, false, GOLD);
[110, 120, 130, 140, 150].forEach(p => {
ctx.fillStyle = TEXT;
ctx.font = '9px JetBrains Mono, monospace';
ctx.textAlign = 'right';
ctx.fillText(p, pad.l - 4, py(p) + 3);
ctx.strokeStyle = '#1a1a1a';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(pad.l, py(p));
ctx.lineTo(w - pad.r, py(p));
ctx.stroke();
});
}
// ---- HIGH 3 WEDGE ----
function drawHigh3() {
const { ctx, w, h } = setupCanvas('c-high3');
const pad = { l: 30, r: 20, t: 20, b: 30 };
const cw = w - pad.l - pad.r;
const ch = h - pad.t - pad.b;
const pMin = 95, pMax = 160;
function py(p) { return pad.t + ch * (1 - (p - pMin) / (pMax - pMin)); }
const candles = [
// Bull trend
{ o: 110, c: 118, h: 119, l: 109, bull: true },
{ o: 117, c: 126, h: 127, l: 116, bull: true },
{ o: 125, c: 135, h: 136, l: 124, bull: true },
// Push 1 down (A)
{ o: 135, c: 127, h: 136, l: 125, bull: false, label: 'A' },
// Bounce
{ o: 127, c: 131, h: 132, l: 126, bull: true, label: 'B' },
// Push 2 down (C) - higher low
{ o: 131, c: 124, h: 132, l: 122, bull: false, label: 'C' },
// Bounce
{ o: 124, c: 128, h: 129, l: 123, bull: true, label: 'D' },
// Push 3 down (E) - higher low again
{ o: 128, c: 122, h: 129, l: 121, bull: false, label: 'E' },
// High 3 entry
{ o: 122, c: 132, h: 134, l: 121, bull: true, entry: true, label: 'H3' },
// Strong continuation
{ o: 131, c: 141, h: 143, l: 130, bull: true },
{ o: 140, c: 150, h: 152, l: 139, bull: true },
];
const total = candles.length;
const spacing = cw / (total + 1);
// OTE zone
drawZone(ctx, pad.l + spacing * 6.5, pad.l + spacing * 8.5, py(124), py(119), GOLD_DIM);
drawLabel(ctx, pad.l + spacing * 7.5, py(118), 'OTE Zone', GOLD, 'center');
// Wedge lines
const wx1 = pad.l + spacing * 3.5;
const wx2 = pad.l + spacing * 7.5;
const wx3 = pad.l + spacing * 8.5;
ctx.strokeStyle = 'rgba(150,150,150,0.3)';
ctx.lineWidth = 1;
ctx.setLineDash([4, 4]);
// Upper line: B to D highs
ctx.beginPath();
ctx.moveTo(pad.l + spacing * 4.5, py(132));
ctx.lineTo(pad.l + spacing * 6.5, py(129));
ctx.stroke();
// Lower line: A to C to E lows (rising)
ctx.beginPath();
ctx.moveTo(pad.l + spacing * 3.5, py(125));
ctx.lineTo(pad.l + spacing * 5.5, py(122));
ctx.lineTo(pad.l + spacing * 7.5, py(121));
ctx.stroke();
ctx.setLineDash([]);
drawLabel(ctx, pad.l + spacing * 4, py(126) + 18, 'WEDGE', '#666', 'center');
candles.forEach((c, i) => {
const x = pad.l + spacing * (i + 1);
const color = c.entry ? GOLD : (c.bull ? BULL : BEAR);
drawCandle(ctx, x, py(c.o), py(c.c), py(c.h), py(c.l), color, c.entry ? 16 : 13);
if (c.label) {
const labelY = c.bull ? py(c.h) - 12 : py(c.l) + 18;
drawLabel(ctx, x, labelY, c.label, c.entry ? GOLD : '#aaa');
}
});
drawArrow(ctx, pad.l + spacing * 9, py(120) - 4, true, GOLD);
[110, 120, 130, 140, 150].forEach(p => {
ctx.fillStyle = TEXT;
ctx.font = '9px JetBrains Mono, monospace';
ctx.textAlign = 'right';
ctx.fillText(p, pad.l - 4, py(p) + 3);
ctx.strokeStyle = '#1a1a1a';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(pad.l, py(p));
ctx.lineTo(w - pad.r, py(p));
ctx.stroke();
});
}
// ---- HIGH 4 FAIL ----
function drawHigh4() {
const { ctx, w, h } = setupCanvas('c-high4');
const pad = { l: 30, r: 20, t: 20, b: 30 };
const cw = w - pad.l - pad.r;
const ch = h - pad.t - pad.b;
const pMin = 90, pMax = 155;
function py(p) { return pad.t + ch * (1 - (p - pMin) / (pMax - pMin)); }
const candles = [
// Bull trend
{ o: 108, c: 116, h: 117, l: 107, bull: true },
{ o: 115, c: 124, h: 125, l: 114, bull: true },
{ o: 123, c: 132, h: 133, l: 122, bull: true },
// 4 pushes down — each bounce weaker
{ o: 132, c: 125, h: 133, l: 123, bull: false, label: '1' },
{ o: 125, c: 129, h: 130, l: 124, bull: true },
{ o: 129, c: 122, h: 130, l: 120, bull: false, label: '2' },
{ o: 122, c: 126, h: 127, l: 121, bull: true },
{ o: 126, c: 119, h: 127, l: 117, bull: false, label: '3' },
{ o: 119, c: 123, h: 124, l: 118, bull: true },
{ o: 123, c: 116, h: 124, l: 114, bull: false, label: '4' },
// H4 "entry" attempt — fails immediately
{ o: 116, c: 119, h: 120, l: 114, bull: true, label: 'H4?' },
// Failure — breaks below
{ o: 119, c: 110, h: 120, l: 108, bull: false, entry: true, label: 'FAIL' },
{ o: 110, c: 101, h: 111, l: 99, bull: false },
];
const total = candles.length;
const spacing = cw / (total + 1);
// Failed zone
drawZone(ctx, pad.l + spacing * 9.5, pad.l + spacing * 12, py(122), py(112), BEAR_DIM);
// BOS line
ctx.strokeStyle = 'rgba(239,83,80,0.5)';
ctx.lineWidth = 1.5;
ctx.setLineDash([]);
ctx.beginPath();
ctx.moveTo(pad.l + spacing * 9.5, py(114));
ctx.lineTo(pad.l + spacing * 13, py(114));
ctx.stroke();
drawLabel(ctx, pad.l + spacing * 12.5, py(114) - 6, 'BOS ↓', '#ef5350');
candles.forEach((c, i) => {
const x = pad.l + spacing * (i + 1);
let color = c.bull ? BULL : BEAR;
if (c.entry) color = BEAR;
if (c.label === 'H4?') color = '#888';
drawCandle(ctx, x, py(c.o), py(c.c), py(c.h), py(c.l), color, 13);
if (c.label) {
const labelY = c.bull ? py(c.h) - 12 : py(c.l) + 18;
const lColor = c.entry ? '#ef5350' : (c.label === 'H4?' ? '#888' : '#aaa');
drawLabel(ctx, x, labelY, c.label, lColor);
}
});
// X mark on H4
const failX = pad.l + spacing * 11;
ctx.strokeStyle = '#ef5350';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(failX - 8, py(121) - 8);
ctx.lineTo(failX + 8, py(121) + 8);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(failX + 8, py(121) - 8);
ctx.lineTo(failX - 8, py(121) + 8);
ctx.stroke();
[100, 110, 120, 130].forEach(p => {
ctx.fillStyle = TEXT;
ctx.font = '9px JetBrains Mono, monospace';
ctx.textAlign = 'right';
ctx.fillText(p, pad.l - 4, py(p) + 3);
ctx.strokeStyle = '#1a1a1a';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(pad.l, py(p));
ctx.lineTo(w - pad.r, py(p));
ctx.stroke();
});
}
function showTab(id) {
document.querySelectorAll('.panel').forEach(p => p.classList.remove('active'));
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.getElementById(id).classList.add('active');
event.target.classList.add('active');
setTimeout(drawAll, 50);
}
function drawAll() {
drawHigh2();
drawLow2();
drawHigh3();
drawHigh4();
}
window.addEventListener('load', () => setTimeout(drawAll, 100));
window.addEventListener('resize', () => setTimeout(drawAll, 100));
</script>
</body>
</html>
4
3
105KB
115KB
461.0ms
396.0ms
536.0ms