diff --git a/gen/patternuri_candele.py b/gen/patternuri_candele.py index aca9744..c055535 100644 --- a/gen/patternuri_candele.py +++ b/gen/patternuri_candele.py @@ -13,12 +13,39 @@ import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) -from svg_candles import Chart, Candle, Level +from svg_candles import Chart, Candle, Level, Mark, MA, from_closes P = [] def w(t): P.append(t) def svg(ch): P.append(ch.render()) +# Exemplele de trade sunt grafice reale (STYLE.md, 13.09.2026): serie continuă +# în care pattern-ul are context în stânga și în dreapta. Barele pattern-ului +# rămân exact cele din text; doar gap-urile cerute de pattern (engulfing, +# morning star) rup regula open = close-ul precedent. +RK = dict(gap=16, body_w=9, left=40, width=700, title="XYZ — daily (ilustrativ)", + mas=[MA(20, "#b06000", dash="4 3", text="SMA-20")]) + +def serie(pre, start, pattern, post, wick=0.12): + cds = from_closes(pre, wick=wick, start=start) + pattern + cds += from_closes(post, wick=wick, start=pattern[-1].c) + for c in cds: + assert c.l <= min(c.o, c.c) and c.h >= max(c.o, c.c), c + print(" close-uri:", " ".join(f"{c.c:.2f}" for c in cds)) + return cds + +def check_trade(cds, i_in, entry, sl, tp, long=True): + """intrarea e atinsă de bara i_in, stopul nu e atins după, ținta da, 2R exact""" + after = cds[i_in:] + assert cds[i_in].l <= entry <= cds[i_in].h, (entry, cds[i_in]) + if long: + assert min(c.l for c in after) > sl and max(c.h for c in after) >= tp + else: + assert max(c.h for c in after) < sl and min(c.l for c in after) <= tp + risc, castig = abs(entry - sl), abs(tp - entry) + print(f" intrare {entry} SL {sl} TP {tp}: risc {risc:.2f}, țintă {castig:.2f} = {castig/risc:.2f}R") + return castig / risc + w("""# Modul 1 / #5 — Pattern-uri de bază pe candele (candlestick) ## TLDR @@ -132,14 +159,24 @@ svg(Chart( w(""" **Trade complet, long:**""") -svg(Chart( - candles=[Candle(63.05, 63.30, 62.10, 63.30, "hammer", "hammer — low-ul 62.10 e nivelul care ține ipoteza"), - Candle(63.40, 64.20, 63.30, 64.10, "confirmare", "confirmare — închide 64.10, peste 63.30")], +print("hammer, trade:") +cds = serie([67.20, 67.45, 67.00, 66.70, 66.85, 66.40, 66.10, 66.30, 65.85, 65.50, + 65.65, 65.20, 64.90, 65.05, 64.60, 64.25, 64.40, 63.95, 63.60, 63.75, 63.30, 63.05], + 67.00, + [Candle(63.05, 63.30, 62.10, 63.30, note="hammer — low-ul 62.10 e nivelul care ține ipoteza"), + Candle(63.30, 64.20, 63.30, 64.10, note="confirmare — închide 64.10, peste 63.30")], + [63.90, 64.35, 64.80, 64.55, 65.10, 65.45, 65.25, 65.80, 66.10]) +H = 22 +assert cds[H].l == min(c.l for c in cds) == 62.10 and cds[H+1].c > cds[H].h +assert round(cds[H].o - cds[H].l, 2) == 0.95 and round(cds[H].c - cds[H].o, 2) == 0.25 # fitil ≈ 4 × corp +assert abs(check_trade(cds, H + 1, 63.35, 62.05, 65.95) - 2.0) < 1e-9 +svg(Chart(candles=cds, **RK, levels=[Level(65.95, "TP 65.95 — 2R", "#188a3e"), - Level(63.35, "intrare 63.35", "#1a5fb4"), + Level(63.35, "intrare 63.35", "#1a5fb4", label_at="left"), Level(62.05, "SL 62.05 — sub low-ul hammer-ului", "#c00")], - scale=52, gap=110, left=110, trend="down", - caption="Scară: 1.00 = 52 px. Distanța intrare→TP e exact dublul distanței intrare→SL.")) + marks=[Mark(H, "hammer", "#188a3e", "below"), Mark(H + 1, "confirmare", "#188a3e", dy=-4)], + scale=46, + caption="Scară: 1.00 = 46 px. Distanța intrare→TP e exact dublul distanței intrare→SL.")) w(""" | | Preț | De ce acolo | @@ -234,14 +271,23 @@ devine rezistență până e depășit la închidere. **Trade complet, short:**""") -svg(Chart( - candles=[Candle(64.10, 65.10, 63.90, 63.95, "shooting star", "shooting star — high-ul 65.10 e oferta"), - Candle(64.00, 64.05, 63.60, 63.70, "confirmare", "confirmare — închide 63.70, sub low-ul 63.90")], +print("shooting star, trade:") +cds = serie([60.20, 59.95, 60.40, 60.75, 60.55, 61.00, 61.35, 61.15, 61.60, 61.95, + 61.80, 62.25, 62.60, 62.40, 62.85, 63.20, 63.00, 63.45, 63.80, 63.65, 64.10], + 60.40, + [Candle(64.10, 65.10, 63.90, 63.95, note="shooting star — high-ul 65.10 e oferta"), + Candle(63.95, 64.05, 63.60, 63.70, note="confirmare — închide 63.70, sub low-ul 63.90")], + [63.30, 62.95, 63.15, 62.60, 62.20, 62.40, 61.90, 61.55, 61.30]) +H = 21 +assert cds[H].h == max(c.h for c in cds) == 65.10 and cds[H+1].c < cds[H].l +assert abs(check_trade(cds, H + 1, 63.85, 65.15, 61.25, long=False) - 2.0) < 1e-9 +svg(Chart(candles=cds, **RK, levels=[Level(65.15, "SL 65.15 — peste high", "#c00"), Level(63.85, "intrare 63.85 short", "#1a5fb4"), - Level(61.25, "TP 61.25 — 2R", "#188a3e")], - scale=44, gap=110, left=110, trend="up", - caption="Scară: 1.00 = 44 px. Risc 1.30 în sus, țintă 2.60 în jos — exact dublul.")) + Level(61.25, "TP 61.25 — 2R", "#188a3e", label_at="left")], + marks=[Mark(H, "shooting star", "#c00", dy=-14), Mark(H + 1, "confirmare", "#c00", "below", dy=45)], + scale=46, + caption="Scară: 1.00 = 46 px. Risc 1.30 în sus, țintă 2.60 în jos — exact dublul.")) w(""" ## Doji — nimeni n-a câștigat @@ -271,14 +317,24 @@ Fără pasul 3, un doji e zgomot. Apar des. **Trade complet, long (după downtrend):**""") -svg(Chart( - candles=[Candle(62.75, 63.30, 62.10, 62.73, "doji", "doji — extremele 63.30 și 62.10 sunt pragurile"), - Candle(62.80, 64.10, 62.70, 64.00, "confirmare", "confirmare — închide 64.00, peste 63.30")], +print("doji, trade:") +cds = serie([66.90, 67.10, 66.60, 66.25, 66.45, 66.00, 65.70, 65.90, 65.40, 65.10, + 65.30, 64.85, 64.50, 64.70, 64.25, 63.90, 64.05, 63.60, 63.20, 63.40, 62.95, 62.75], + 66.70, + [Candle(62.75, 63.30, 62.10, 62.73, note="doji — extremele 63.30 și 62.10 sunt pragurile"), + Candle(62.73, 64.10, 62.70, 64.00, note="confirmare — închide 64.00, peste 63.30")], + [63.75, 64.20, 64.65, 64.40, 64.95, 65.30, 65.10, 65.70, 66.05]) +H = 22 +assert cds[H].l == min(c.l for c in cds) == 62.10 and cds[H+1].c > cds[H].h +assert abs(cds[H].o - cds[H].c - 0.02) < 1e-9 and abs(cds[H].h - cds[H].l - 1.20) < 1e-9 +assert abs(check_trade(cds, H + 1, 63.35, 62.05, 65.95) - 2.0) < 1e-9 +svg(Chart(candles=cds, **RK, levels=[Level(65.95, "TP 65.95 — 2R", "#188a3e"), - Level(63.35, "intrare 63.35", "#1a5fb4"), + Level(63.35, "intrare 63.35", "#1a5fb4", label_at="left"), Level(62.05, "SL 62.05 — sub low-ul doji", "#c00")], - scale=52, gap=110, left=110, trend="down", - caption="Scară: 1.00 = 52 px. Risc 1.30, țintă 2.60 — exact dublul.")) + marks=[Mark(H, "doji", "#333", "below"), Mark(H + 1, "confirmare", "#188a3e", dy=-4)], + scale=46, + caption="Scară: 1.00 = 46 px. Risc 1.30, țintă 2.60 — exact dublul.")) w(""" **Short (oglindă, după uptrend):** același doji la vârf, urmat de o candelă @@ -350,12 +406,25 @@ pornește prost. **Ce faci când îl vezi, concret:** aștepți retestul la **midpoint** — jumătatea corpului, 63.00 în exemplul de sus.""") -svg(Chart( - candles=[Candle(62.00, 64.00, 62.00, 64.00, "marubozu", "marubozu bull — corp de 2.00, fără fitile"), - Candle(63.90, 63.95, 63.05, 63.15, "pullback", "pullback — coboară până la 63.05, aproape de midpoint"), - Candle(63.20, 64.30, 63.10, 64.25, "reluare", "reluare — cumpărătorii revin din midpoint")], +print("marubozu, retest:") +cds = serie([61.60, 61.85, 61.70, 61.95, 61.75, 62.05, 61.80, 62.10, 61.90, 62.15, + 61.95, 61.80, 62.05, 61.85, 62.10, 61.90, 62.00], + 61.75, + [Candle(62.00, 64.00, 62.00, 64.00, note="marubozu bull — corp de 2.00, fără fitile"), + Candle(64.00, 64.00, 63.05, 63.15, note="pullback — coboară până la 63.05, aproape de midpoint"), + Candle(63.15, 64.30, 63.10, 64.25, note="reluare — cumpărătorii revin din midpoint")], + [64.60, 64.40, 64.85, 65.20, 65.00, 65.45, 65.30, 65.70], wick=0.10) +M = 17 +mid = (cds[M].o + cds[M].c) / 2 +assert mid == 63.00 and cds[M].o == cds[M].l and cds[M].c == cds[M].h +assert cds[M+1].l == 63.05 > mid and cds[M+2].l <= 63.10 <= cds[M+2].h +assert min(c.l for c in cds[M+2:]) > 62.95, "stopul de sub 62.95 n-ar trebui atins" +assert max(c.h for c in cds[:M]) < cds[M].c, "marubozu-ul iese din consolidare" +print(f" midpoint {mid}, risc la retest {63.10-62.95:.2f} vs la close {64.00-62.00:.2f}") +svg(Chart(candles=cds, **RK, levels=[Level(63.00, "midpoint 63.00", "#b06000", "5 3")], - scale=70, gap=105, left=95, + marks=[Mark(M, "marubozu", "#188a3e", "below", dy=16), Mark(M + 1, "pullback", "#c00", "below", dy=58.25)], + scale=55, caption="Intri la 63.10 cu stop sub 62.95, nu la 64.00 cu stop la 62.00. Același trade, sfert de risc.")) w(""" @@ -412,14 +481,24 @@ Fără condiția 1, aștepți confirmare ca la restul. **Trade complet, long:**""") -svg(Chart( - candles=[Candle(62.80, 62.85, 62.25, 62.30, "c1", "candela 1 — cei care au vândut aici sunt acum pe pierdere"), - Candle(62.20, 63.05, 62.15, 63.00, "c2 — engulfing", "candela 2 — intri la închiderea ei")], +print("engulfing, trade:") +cds = serie([66.10, 66.30, 65.85, 65.55, 65.75, 65.30, 65.00, 65.20, 64.75, 64.45, + 64.65, 64.20, 63.90, 64.10, 63.65, 63.35, 63.55, 63.15, 62.90, 63.05, 62.80], + 65.90, + [Candle(62.80, 62.85, 62.25, 62.30, note="candela 1 — cei care au vândut aici sunt acum pe pierdere"), + Candle(62.20, 63.05, 62.15, 63.00, note="candela 2 — intri la închiderea ei")], + [63.35, 63.20, 63.65, 64.00, 63.85, 64.30, 64.65, 64.50, 64.95, 65.25]) +C1 = 21 +assert cds[C1+1].o < cds[C1].c and cds[C1+1].c > cds[C1].o, "corpul c2 trebuie să cuprindă corpul c1" +assert cds[C1+1].l == min(c.l for c in cds) and cds[C1+2].l <= 63.10 <= cds[C1+2].h +assert abs(check_trade(cds, C1 + 2, 63.10, 62.10, 65.10) - 2.0) < 1e-9 +svg(Chart(candles=cds, **RK, levels=[Level(65.10, "TP 65.10 — 2R", "#188a3e"), - Level(63.10, "intrare 63.10", "#1a5fb4"), + Level(63.10, "intrare 63.10", "#1a5fb4", label_at="left"), Level(62.10, "SL 62.10 — sub low-ul c2", "#c00")], - scale=62, gap=110, left=110, trend="down", - caption="Scară: 1.00 = 62 px. Risc 1.00, țintă 2.00 — exact dublul.")) + marks=[Mark(C1, "c1", "#c00", "below"), Mark(C1 + 1, "c2 — engulfing", "#188a3e", dy=-40)], + scale=60, + caption="Scară: 1.00 = 60 px. Risc 1.00, țintă 2.00 — exact dublul.")) w(""" | | Preț | De ce acolo | @@ -551,14 +630,24 @@ tratezi ca atare. **Trade complet, long:**""") -svg(Chart( - candles=[Candle(64.00, 64.10, 62.10, 62.20, "c1", ""), - Candle(62.05, 62.20, 61.90, 62.00, "c2", "low-ul candelei 2 (61.90) e nivelul de invalidare"), - Candle(62.10, 63.50, 62.05, 63.40, "c3", "intri la închiderea candelei 3, la 63.45")], +print("morning star, trade:") +cds = serie([68.30, 68.55, 68.05, 67.70, 67.90, 67.40, 67.05, 67.25, 66.75, 66.40, + 66.60, 66.10, 65.75, 65.95, 65.40, 65.05, 65.25, 64.70, 64.35, 64.55, 64.00], + 68.10, + [Candle(64.00, 64.10, 62.10, 62.20), + Candle(62.05, 62.20, 61.90, 62.00, note="low-ul candelei 2 (61.90) e nivelul de invalidare"), + Candle(62.10, 63.50, 62.05, 63.40, note="intri la închiderea candelei 3, la 63.45")], + [63.80, 63.60, 64.20, 64.75, 64.50, 65.15, 65.60, 65.35, 66.00, 66.45, 66.80]) +C1 = 21 +mid = (cds[C1].o + cds[C1].c) / 2 +assert abs(mid - 63.10) < 1e-9 and cds[C1+2].c > mid and cds[C1+1].l == min(c.l for c in cds) == 61.90 +assert abs(check_trade(cds, C1 + 3, 63.45, 61.85, 66.65) - 2.0) < 1e-9 +svg(Chart(candles=cds, **RK, levels=[Level(66.65, "TP 66.65 — 2R", "#188a3e"), - Level(63.45, "intrare 63.45", "#1a5fb4"), + Level(63.45, "intrare 63.45", "#1a5fb4", label_at="left"), Level(61.85, "SL 61.85 — sub low-ul c2", "#c00")], - scale=42, gap=105, left=95, trend="down", + marks=[Mark(C1, "c1", "#c00", dy=-2), Mark(C1 + 1, "c2", "#333", "below"), Mark(C1 + 2, "c3", "#188a3e", dy=-6)], + scale=42, caption="Scară: 1.00 = 42 px. Risc 1.60, țintă 3.20 — exact dublul.")) w(""" diff --git a/summaries/01_MODUL_1/04_candele_ohlc_timeframes_swing_high_low.html b/summaries/01_MODUL_1/04_candele_ohlc_timeframes_swing_high_low.html index 00e4522..1946263 100644 --- a/summaries/01_MODUL_1/04_candele_ohlc_timeframes_swing_high_low.html +++ b/summaries/01_MODUL_1/04_candele_ohlc_timeframes_swing_high_low.html @@ -172,20 +172,123 @@ mai puternică.

Breakout = o candelă se închide dincolo de nivelul unui swing anterior (deasupra unui swing high pentru direcția long, sub un swing low pentru short). Nu contează o simplă atingere cu fitilul — contează închiderea.

-

-breakout (long) vs breakdown (short) — traversarea unui swing anterior -109.950 — fost swing high - - - -închidere peste nivel -→ breakout, intrare long -109.639 — fost swing low - - - -închidere sub nivel -→ breakdown, intrare short +

+ USD/JPY — 15 min (ilustrativ) + + 109.950 — fost swing high + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + swing high + swing low + închidere peste nivel + → breakout, intrare long +

+

+ USD/JPY — 15 min (ilustrativ) + + 109.639 — fost swing low + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + swing low + swing high + închidere sub nivel + → breakdown, intrare short

Nivelurile folosite (109.950 și 109.639) sunt exact swing high-ul și swing low-ul din diagramele de mai sus — un breakout nu e un concept separat, e @@ -204,29 +307,115 @@ fitilul nu e suficientă — aștepți close-ul. Abia după ce o candelă se în dincolo de nivel ai un breakout confirmat pe care poți acționa.

Trigger valid vs. prea devreme — DA/NU cu cifre (nivel: swing high 109.950 din diagrama de mai sus):

-

-DA — close peste nivel confirmă breakout -NU — doar fitilul trece, close revine sub nivel - -109.950 — nivel - - - - - - -close 109.980 > nivel 109.950 -→ DA, breakout confirmat - -109.950 — nivel - - - - - - -fitil 110.010 > nivel, close -109.920 < nivel → NU +

+ USD/JPY — 15 min (ilustrativ) + + 109.950 — nivel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + close 109.980 > nivel 109.950 + DA — close peste nivel confirmă breakout → DA, breakout confirmat +

+

+ USD/JPY — 15 min (ilustrativ) + + 109.950 — nivel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fitil 110.010 > nivel, close 109.920 < nivel → NU + NU — doar fitilul trece, close revine sub nivel

Exemplu complet 1 — breakout long, de la identificare la ieșire: candela care testează 109.950 se închide la 109.980 — breakout confirmat @@ -237,55 +426,236 @@ breakout-ul a eșuat (nivelul redevine resistance în loc de support). Take-prof 0.311; o proiectezi de la punctul de breakout în sus (measured move), pentru că aceeași forță care a produs prima mișcare e candidatul cel mai plauzibil pentru următoarea.

-

-breakout long — entry/SL/TP - - -109.950 — nivel spart - -entry 109.980 (close peste nivel) - -SL 109.900 - -TP 110.291 (measured move: 0.311) -risc 0.080, recompensă 0.311 → R:R ≈ 1:3.9 +

+ USD/JPY — 15 min (ilustrativ) + + TP 110.291 (measured move: 0.311) + + 109.950 — nivel spart + + SL 109.900 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + swing high + swing low 109.639 + entry 109.980 + breakout long — risc 0.080, recompensă 0.311 → R:R ≈ 1:3.9

Exemplu complet 2 — breakdown short (aceeași logică, oglindită): nivel = swing low 109.639. Candela de breakdown se închide la 109.600. Intrare: 109.600. Stop-loss: 109.690 — deasupra nivelului rupt, cu marjă. Take-profit: 109.289 — același measured move (0.311), proiectat în jos de la punctul de breakdown.

-

-breakdown short — entry/SL/TP - - -109.639 — nivel spart - -entry 109.600 (close sub nivel) - -SL 109.690 - -TP 109.289 (measured move: 0.311) -risc 0.090, recompensă 0.311 → R:R ≈ 1:3.5 +

+ USD/JPY — 15 min (ilustrativ) + + SL 109.690 + + 109.639 — nivel spart + + TP 109.289 (measured move: 0.311) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + swing low + swing high 109.950 + entry 109.600 + breakdown short — risc 0.090, recompensă 0.311 → R:R ≈ 1:3.5

Exemplu 3 — eșec, costul de a intra pe fitil în loc de close (cazul NU de mai sus, dus până la capăt): un trader intră la 109.995, în mijlocul fitilului, anticipând breakout-ul, fără să aștepte close-ul. Candela se închide la 109.920 — sub nivel, deci nu a fost breakout deloc — și prețul continuă să scadă până îi atinge stop-loss-ul la 109.900.

-

-intrare greșită pe fitil, înainte de close — stop atins - - -109.950 — nivel - -entrare greșită 109.995 (pe fitil) - -close 109.920 — sub nivel, nu era breakout - -SL 109.900 — atins -pierdere: 109.995 − 109.900 = 0.095 -costul de a nu aștepta close-ul +

+ USD/JPY — 15 min (ilustrativ) + + 109.950 — nivel + + SL 109.900 — atins + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + entrare greșită 109.995 (pe fitil), close 109.920 + pierdere: 109.995 − 109.900 = 0.095 — costul de a nu aștepta close-ul

Gotchas practice

Money management și execuție

Context macro și poziționare

Instrumente și piețe

Psihologie și disciplină