Files
atm-curs-dl/gen/patternuri_candele.py
Claude Agent 0e810567ee Q&A 29.07.2025 sumarizata (22/28): divergenta cu Momentum(28), intrarea in trei transe
Scrisa de un agent, cu noul standard de diagrame: 12 grafice reale, serii
continue de 30-42 de bare, cu panou de volum si, la strategia de divergenta,
un panou de Momentum(28) calculat cu formula lui (close minus close-ul de
acum 28 de bare). 61 de assert-uri in generator.

Continut: semnalele care anunta o corectie (volum pe put-uri, VIX),
buy doji weekly cu intrare in trei transe, marubozu care "sta in picioare"
cat timp nu inchide sub open (DA/NU), double bottom cu al doilea picior mai
jos (cand merge si cand nu), strategia completa de divergenta cu Momentum,
canal de trend, bull flag cu cele doua tinte, si de ce nu recomanda inca
optiunile.

11 intrari noi in INDEX_TEMATIC.md. Referintele sunt IG si Cboe, nu
Investopedia: agentul n-a putut verifica linkurile Investopedia din mediul
lui, deci nu le-a pus.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtSTyTmt6AbCL9j5ajEDm1
2026-09-13 08:18:28 +00:00

771 lines
38 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""
Regenerează summaries/01_MODUL_1/05_patternuri_candele.md.
Diagramele NU se editează de mână. Versiunea desenată manual avea ținta de
2R plasată la distanța de 1R față de intrare și eticheta de open a unui
marubozu deasupra celei de close. Aici coordonatele vin din prețuri prin
svg_candles.py, deci scara e corectă prin construcție.
Rulează: .venv/bin/python gen/patternuri_candele.py
"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
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
O candelă codifică patru prețuri dintr-un interval — open, high, low, close —
într-o formă. Formele care se repetă se numesc pattern-uri, și fiecare e o
poveste despre **cine a controlat prețul la începutul intervalului și cine la
final**.
Un pattern nu e un semnal de cumpărare. E o întrebare la care graficul
răspunde în candela următoare. Mai jos, pentru fiecare: ce arată, ce s-a
întâmplat mecanic, **de ce îl urmărești**, **ce faci concret când îl vezi**,
și unde e cazul — trade-ul complet, cu intrare, stop-loss și țintă.
Toate diagramele de mai jos sunt desenate la scară: o unitate de preț are
aceeași înălțime oriunde pe desen, inclusiv între intrare, stop-loss și
țintă.
## Anatomia unei candele
Corpul arată distanța dintre open și close. Fitilele arată cât de departe a
ajuns prețul în fiecare direcție **înainte să fie împins înapoi**.""")
svg(Chart(
candles=[Candle(50.00, 50.65, 49.80, 50.60, "bull", "bull — O 50.00, H 50.65, L 49.80, C 50.60 (close peste open)"),
Candle(50.60, 50.65, 49.80, 50.00, "bear", "bear — O 50.60, H 50.65, L 49.80, C 50.00 (close sub open)")],
scale=150, gap=140, left=90,
caption="Aceleași patru prețuri, ordine inversă a lui open și close. Scară: 0.10 = 15 px."))
w("""
Verde (bull) înseamnă close peste open — cumpărătorii au terminat intervalul
în avantaj. Roșu (bear) înseamnă invers.
**De ce contează distincția corp / fitil:** corpul e ce a rămas, fitilul e ce
a fost respins. Două candele cu același corp dar fitile diferite spun povești
complet diferite despre cine a încercat ce.
## Mecanismul comun: ce înseamnă un fitil lung
Toate pattern-urile de reversal de mai jos funcționează pe același
mecanism, așa că îl explic o singură dată, aici.
Un fitil lung în jos înseamnă că prețul a **ajuns** acolo — cineva a vândut
efectiv la acele prețuri — și apoi a fost împins înapoi sus. Ca să se
întâmple asta, cumpărătorii au trebuit să absoarbă toată vânzarea de la
nivelul acela **și** să mai rămână cu destulă cerere ca să urce prețul la loc.
<svg viewBox="0 0 620 240" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="20" fill="#666">preț ↑</text>
<line x1="120" y1="60" x2="120" y2="200" stroke="#1a1a1a" stroke-width="1.5"/>
<rect x="107" y="60" width="26" height="34" fill="#188a3e"/>
<line x1="150" y1="94" x2="330" y2="94" stroke="#888" stroke-dasharray="3 3"/>
<text x="340" y="90" fill="#333">aici s-a închis intervalul</text>
<line x1="150" y1="200" x2="330" y2="200" stroke="#888" stroke-dasharray="3 3"/>
<text x="340" y="196" fill="#c00">până aici au împins vânzătorii</text>
<line x1="86" y1="94" x2="86" y2="200" stroke="#188a3e" stroke-width="2"/>
<line x1="81" y1="94" x2="91" y2="94" stroke="#188a3e" stroke-width="2"/>
<line x1="81" y1="200" x2="91" y2="200" stroke="#188a3e" stroke-width="2"/>
<text x="24" y="152" fill="#188a3e" style="font-weight:bold">absorbit</text>
<text x="340" y="150" fill="#333">Toată vânzarea din zona asta a fost cumpărată</text>
<text x="340" y="168" fill="#333">de cineva, la acele prețuri.</text>
<text x="24" y="228" fill="#555">Cu cât fitilul e mai lung față de corp, cu atât respingerea a fost mai decisă.</text>
</svg>
**De ce te interesează, concret:** fitilul îți dă un **nivel**, nu doar o
senzație. Extrema fitilului e prețul la care cererea a apărut efectiv. Acel
nivel devine reperul tău de invalidare: dacă prețul trece sub el, ipoteza ta
a fost greșită, și știi asta imediat, fără să aștepți.
---
# Pattern-uri de o candelă
## Hammer — reversal bull, după downtrend
**Ce arată:** corp mic sus, fitil lung în jos (cel puțin dublul corpului),
fitil de sus aproape inexistent.""")
svg(Chart(
candles=[Candle(63.05, 63.30, 62.10, 63.30, "hammer", "O 63.05, H = C 63.30, L 62.10 — fitil de 0.95, corp de 0.25")],
scale=100, left=110, trend="down",
caption="Fitilul e de aproape 4 ori corpul. Scară: 0.10 = 10 px."))
w("""
**Ce s-a întâmplat:** vânzătorii au dus prețul până la 62.10 și au eșuat.
Cumpărătorii au absorbit tot și au închis intervalul la maxim.
**De ce îl urmărești:** îți spune că la **62.10** există cerere reală, nu
presupusă. Asta transformă o zonă vagă de „pare suport" într-un nivel
testabil. Decizia pe care ți-o ajută să iei: dacă merită să încerci un long
aici, și unde pui stopul ca să afli repede că te-ai înșelat.
**Ce faci când îl vezi:** nimic încă. Notezi 62.10 ca nivel de invalidare și
63.30 ca prag de confirmare. **Aștepți candela următoare.**
**Trigger valid / invalid:**""")
svg(Chart(
candles=[Candle(63.05, 63.30, 62.10, 63.30, "hammer", ""),
Candle(63.20, 64.20, 63.10, 64.10, "DA", "DA — candela următoare închide la 64.10, peste high-ul hammer-ului (63.30)")],
scale=64, left=110, gap=110,
levels=[Level(63.30, "prag de confirmare 63.30", "#888", "2 2")],
caption=""))
svg(Chart(
candles=[Candle(63.05, 63.30, 62.10, 63.30, "hammer", ""),
Candle(63.20, 63.28, 61.90, 62.00, "NU", "NU — închide la 62.00, sub low-ul hammer-ului: downtrend-ul continuă")],
scale=64, left=110, gap=110,
levels=[Level(62.10, "nivel de invalidare 62.10", "#888", "2 2")],
caption=""))
w("""
**Trade complet, long:**""")
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", label_at="left"),
Level(62.05, "SL 62.05 — sub low-ul hammer-ului", "#c00")],
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 |
|---|---|---|
| Intrare | 63.35 | peste high-ul hammer-ului — cumpărătorii au depășit pragul pe care nu-l puteau trece |
| Stop-loss | 62.05 | sub 62.10; dacă se tranzacționează acolo, cererea care a făcut fitilul nu mai există |
| Risc | 1.30 | 63.35 − 62.05 |
| Țintă | 65.95 | 2R = 63.35 + 2 × 1.30 |
**Mărimea poziției:** dacă riști 2% dintr-un cont de 10.000 $, adică 200 $,
și riscul per acțiune e 1.30 $, cumperi **153 de acțiuni** (200 ÷ 1.30).
Nu „cât simți".
## Inverted Hammer — tot bull, tot după downtrend, dar mai slab
**Ce arată:** aceeași logică, oglindită — corp mic **jos**, fitil lung în
**sus**.""")
svg(Chart(
candles=[Candle(62.15, 63.30, 62.10, 62.40, "inverted hammer", "O 62.15, H 63.30, L 62.10, C 62.40")],
scale=100, left=130, trend="down",
caption="Fitilul de sus e de aproape 4 ori corpul. Scară: 0.10 = 10 px."))
w("""
**Ce s-a întâmplat:** cumpărătorii au dus prețul până la 63.30 — o încercare
reală, după o cădere — dar au fost respinși și au închis aproape de unde au
deschis.
**De ce îl urmărești, deși încercarea a eșuat:** într-un downtrend, cel mai
important lucru nu e cine câștigă, e **dacă apare cerere deloc**. Un inverted
hammer e prima dovadă că există cumpărători dispuși să plătească mult mai
sus. Au pierdut runda asta, dar existența lor e informația.
**Ce faci când îl vezi:** îl tratezi ca pe un avertisment, nu ca pe un
set-up. Concret: **nu mai deschizi short-uri noi** în direcția trendului, și
aștepți. Confirmarea cerută e mai strictă decât la hammer — o candelă care
închide peste **63.30**, nu doar peste corp.
**De ce e mai slab decât hammer:** la hammer, intervalul s-a încheiat cu
cumpărătorii în control (close la maxim). Aici s-a încheiat cu vânzătorii în
control (close aproape de open). Aceeași informație, dar cu rezultatul
final încă în favoarea taberei vechi.
## Hanging Man — aceeași formă ca hammer, sens opus
**Ce arată:** geometric **identic** cu hammer. Singura diferență e ce a fost
înainte pe grafic: un **uptrend**.""")
svg(Chart(
candles=[Candle(63.05, 63.30, 62.10, 63.30, "hanging man", "O 63.05, H = C 63.30, L 62.10 — exact aceleași cifre ca la hammer")],
scale=100, left=130, trend="up",
caption="Formă identică cu hammer. Contextul de trend e singura diferență."))
w("""
**Ce s-a întâmplat:** în mijlocul unui trend de creștere, cineva a vândut
suficient cât să ducă prețul cu 1.20 mai jos în timpul intervalului.
Cumpărătorii au recuperat până la închidere — dar **vânzarea aia n-ar fi
trebuit să existe**.
**De ce îl urmărești:** îți semnalează prima ofertă serioasă într-un trend
care până atunci nu întâlnise rezistență. Nu îți spune că trendul s-a
terminat; îți spune că a apărut cineva de partea cealaltă.
**Ce faci când îl vezi, concret** — și aici e diferența practică față de
hammer: dacă ești deja long, **muți stop-loss-ul sub 62.10**. Nu ieși, nu
inversezi. Îți protejezi profitul la nivelul pe care vânzătorii tocmai l-au
testat.
## Shooting Star — reversal bear, după uptrend
**Ce arată:** corp mic jos, fitil lung în sus, la vârful unei mișcări de
creștere. Geometric identic cu inverted hammer.""")
svg(Chart(
candles=[Candle(64.10, 65.10, 63.90, 63.95, "shooting star", "O 64.10, H 65.10, L 63.90, C 63.95")],
scale=90, left=130, trend="up",
caption="Scară: 0.10 = 9 px."))
w("""
**Ce s-a întâmplat:** cumpărătorii au împins până la 65.10 și au fost
respinși complet. Tot avansul intervalului a fost anulat până la închidere.
**De ce îl urmărești:** îți dă **nivelul exact al ofertei** — 65.10. Acolo
există vânzători care au fost dispuși să vândă în cantitate. Nivelul ăla
devine rezistență până e depășit la închidere.
**Ce faci când îl vezi:**
- dacă ești long — muți stop-ul sau marchezi profit parțial;
- dacă vrei short — aștepți o candelă care închide **sub low-ul** shooting
star-ului (63.90), cu stop peste 65.10;
- dacă nu ești în piață — notezi 65.10 ca rezistență și nu cumperi sub el.
**Trade complet, short:**""")
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", 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
**Ce arată:** open și close practic egale, cu fitile în ambele direcții.""")
svg(Chart(
candles=[Candle(62.75, 63.30, 62.10, 62.73, "doji", "O 62.75, C 62.73 — corp de 0.02, interval total de 1.20")],
scale=100, left=130,
caption="Prețul s-a mișcat 1.20 și a închis exact de unde a plecat. Scară: 0.10 = 10 px."))
w("""
**Ce s-a întâmplat:** amândouă taberele au împins, niciuna n-a păstrat
teren. Intervalul s-a încheiat la egalitate perfectă.
**De ce îl urmărești — și de ce e diferit de celelalte:** un doji **nu îți
dă direcție**. Îți spune un singur lucru: partea care domina până acum
și-a pierdut avantajul. E informație despre trendul vechi, nu despre cel nou.
**Ce faci când îl vezi:**
1. Dacă ești într-o poziție pe direcția trendului — **nu mai adaugi**.
2. Dacă voiai să intri pe direcția trendului — amâni.
3. Dacă vrei reversal — aștepți confirmarea: o candelă care închide dincolo
de **extrema doji-ului**, în direcția opusă trendului anterior.
Fără pasul 3, un doji e zgomot. Apar des.
**Trade complet, long (după downtrend):**""")
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", label_at="left"),
Level(62.05, "SL 62.05 — sub low-ul doji", "#c00")],
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ă
care închide sub 62.10. Intrare **62.05** short, SL **63.35** (peste high-ul
doji-ului), risc 1.30, TP **59.45**.
**Invalidarea, în ambele cazuri:** candela următoare închide în interiorul
doji-ului, nu dincolo de o extremă. Atunci nu s-a rezolvat nimic — aștepți
în continuare.
## Spinning Top — doji cu corp vizibil
**Ce arată:** fitile lungi în ambele direcții, corp mic **dar nu neglijabil**.""")
svg(Chart(
candles=[Candle(62.60, 63.25, 62.15, 62.80, "spinning top", "O 62.60, C 62.80 — corp de 0.20 într-un interval de 1.10")],
scale=100, left=130,
caption="Corpul e sub 20% din interval. Scară: 0.10 = 10 px."))
w("""
**Ce s-a întâmplat:** același echilibru ca la doji, cu un avantaj minim
pentru o parte. Prețul a explorat 1.10 și a păstrat 0.20.
**De ce îl urmărești — și de ce nu îl tranzacționezi:** un spinning top
izolat nu înseamnă aproape nimic; apare constant. Valoarea lui e **în
serie**. Dacă vezi două-trei spinning tops consecutive într-un trend,
trendul a intrat în echilibru: mișcarea per interval a scăzut, dar
volatilitatea nu.
**Ce faci când îl vezi, concret:**
- **nu intri** pe el, niciodată singur;
- dacă ai o poziție deschisă pe trend și apar 2-3 la rând, **strângi
stop-ul** — impulsul care ți-a dus poziția s-a terminat;
- îl folosești ca filtru pentru alte set-up-uri: un breakout care are în
spate trei spinning tops are mai puține șanse decât unul care vine dintr-o
mișcare direcțională.
**Diferența practică față de doji:** doji-ul e un eveniment (echilibru
perfect, rar), spinning top-ul e o stare (echilibru aproximativ, frecvent).
De aia doji-ul merită o confirmare și un trade, iar spinning top-ul merită
doar o ajustare de risc.
## Marubozu — control total, și de ce e periculos să intri pe el
**Ce arată:** corp maxim, **fără fitile**. La cel bull: open = low și
close = high. La cel bear: invers.""")
svg(Chart(
candles=[Candle(62.00, 64.00, 62.00, 64.00, "marubozu bull", "bull — O = L = 62.00 (jos), C = H = 64.00 (sus)"),
Candle(64.00, 64.00, 62.00, 62.00, "marubozu bear", "bear — O = H = 64.00 (sus), C = L = 62.00 (jos)")],
scale=70, gap=150, left=140,
caption="La cel bull, open-ul e la minim; la cel bear, open-ul e la maxim. Scară: 1.00 = 70 px."))
w("""
**Ce s-a întâmplat:** o singură parte a controlat prețul din primul până în
ultimul tick. N-a existat niciun moment în care cealaltă tabără să împingă
prețul înapoi, nici măcar temporar.
**De ce îl urmărești:** e cea mai clară afirmație de direcție pe care o poate
face o singură candelă. Îți spune fără ambiguitate cine deține controlul
**acum**.
**De ce e, totuși, cea mai proastă candelă pe care să intri:** tocmai pentru
că nu are fitile, întreaga ei înălțime e mișcare deja consumată. Dacă intri
la închiderea unui marubozu bull de 2.00, intri la maximul intervalului, iar
stop-ul logic (sub low-ul candelei) e la 2.00 distanță. Raportul risc/câștig
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.""")
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")],
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("""
**Comparația care justifică așteptarea:**
| Cum intri | Intrare | Stop logic | Risc |
|---|---|---|---|
| La închiderea marubozu-ului | 64.00 | sub 62.00 | **2.00** |
| La retestul midpoint-ului | 63.10 | sub 62.95 | **0.15** |
Aceeași idee, aceeași direcție. Riscul diferă de peste 13 ori.
**Ce te costă răbdarea:** uneori prețul nu mai revine la midpoint și pleacă
fără tine. Asta e prețul — și e motivul pentru care un marubozu foarte mare,
într-un trend puternic, se tranzacționează cu jumătate de poziție la retest,
nu cu tot.""")
w("""
---
# Pattern-uri de două candele
## Engulfing — schimbare directă de control
**Ce arată:** a doua candelă acoperă complet corpul primei, în culoarea
opusă. În varianta strictă folosită în curs, îi depășește și fitilele.""")
svg(Chart(
candles=[Candle(62.80, 62.85, 62.25, 62.30, "candela 1", "candela 1 (mică, bear) — O 62.80, H 62.85, L 62.25, C 62.30"),
Candle(62.20, 63.05, 62.15, 63.00, "candela 2", "candela 2 (mare, bull) — O 62.20, H 63.05, L 62.15, C 63.00")],
scale=200, gap=120, left=130, trend="down",
caption="Corpul candelei 2 (62.20→63.00) cuprinde complet corpul candelei 1 (62.80→62.30). Scară: 0.10 = 20 px."))
w("""
**Ce s-a întâmplat — și de ce e cel mai puternic reversal de două candele:**
candela 2 a deschis **sub** close-ul candelei 1 și a închis **peste** open-ul
ei. Concret: **toți cei care au vândut în intervalul 1 sunt acum pe
pierdere**, fără excepție. Nu o parte dintre ei — toți.
Asta contează pentru că oamenii aceia devin cumpărători forțați: ca să iasă
dintr-un short, trebuie să cumperi. Presiunea de cumpărare din zilele
următoare nu vine doar din convingere, vine din nevoia lor de a ieși.
**De ce îl urmărești:** e singurul pattern de două candele care îți dă
schimbarea de control **și** lista de perdanți în același timp.
**Ce faci când îl vezi — diferența față de hammer și doji:** aici **poți
intra la închiderea candelei 2**, fără o a treia candelă de confirmare, cu
două condiții:
1. e la un nivel care conta deja (suport, pivot, fostă rezistență);
2. corpul candelei 2 e vizibil mai mare decât media ultimelor candele.
Fără condiția 1, aștepți confirmare ca la restul.
**Trade complet, long:**""")
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", label_at="left"),
Level(62.10, "SL 62.10 — sub low-ul c2", "#c00")],
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 |
|---|---|---|
| Intrare | 63.10 | la închiderea candelei 2, fără să aștepți alta |
| Stop-loss | 62.10 | sub low-ul candelei 2 — dacă se rupe, cumpărătorii care au înghițit candela 1 au cedat |
| Risc | 1.00 | |
| Țintă | 65.10 | 2R |
**Bearish Engulfing** e simetric: după uptrend, candelă mare roșie care
înghite corpul verde precedent. Toți cei care au cumpărat în intervalul 1
sunt pe pierdere. Short la închiderea candelei 2, stop peste high-ul ei.
## Harami — contracție bruscă, nu inversare
**Ce arată:** exact opusul engulfing-ului. Candela 2 e mică și încape
complet **în interiorul corpului** candelei 1. Numele vine din japoneză,
„gravidă".""")
svg(Chart(
candles=[Candle(64.00, 64.10, 62.10, 62.20, "candela 1", "candela 1 (mare, bear) — O 64.00, H 64.10, L 62.10, C 62.20"),
Candle(62.60, 62.95, 62.55, 62.90, "candela 2", "candela 2 (mică, bull) — O 62.60, C 62.90, interval total 0.40")],
scale=95, gap=120, left=130, trend="down",
caption="Candela 2 se tranzacționează într-un interval de 0.40, în interiorul corpului de 1.80 al candelei 1."))
w("""
**Ce s-a întâmplat:** vânzarea masivă din candela 1 s-a **oprit brusc**. În
intervalul următor nimeni n-a mai reușit — sau n-a mai vrut — să miște
prețul.
**Diferența esențială față de engulfing**, și motivul pentru care harami e un
semnal mai slab: la engulfing, cumpărătorii au **bătut** vânzătorii. Aici,
vânzătorii pur și simplu **nu s-au mai prezentat**. Absența unei forțe nu e
același lucru cu prezența forței opuse.
**De ce îl urmărești:** e un detector de **epuizare**, nu de inversare. Îți
spune că mișcarea care era în curs și-a pierdut combustibilul. Ce urmează
poate fi inversare, dar la fel de bine consolidare laterală sau reluarea
trendului după o pauză.
**Ce faci când îl vezi, concret:**
- **Nu intri pe el.** Un harami singur nu e set-up de intrare.
- Dacă ești în poziție pe direcția trendului — **strângi stop-ul** la
extrema candelei 1. Ai luat mișcarea; ce urmează e incert.
- Dacă aștepți un reversal — ai nevoie de o a treia candelă care închide
dincolo de extrema candelei 1 (peste 64.10 pentru bull). Abia atunci
devine set-up, și atunci e de fapt un alt pattern.
**Bear Harami** e simetric: candelă mare verde după uptrend, urmată de una
mică roșie în interiorul corpului ei. Aceeași citire — cumpărătorii au
rămas fără muniție, nu au fost bătuți.
## Piercing Line și Dark Cloud Cover — engulfing incomplet
**Ce arată:** două candele, ca la engulfing, dar candela 2 **nu** acoperă tot
corpul candelei 1 — doar trece de jumătatea lui (midpoint).""")
svg(Chart(
candles=[Candle(63.80, 63.90, 62.40, 62.50, "candela 1", "candela 1 (bear) — O 63.80, C 62.50, midpoint 63.15"),
Candle(62.30, 63.45, 62.25, 63.40, "candela 2", "candela 2 (bull) — deschide sub 62.50 și închide la 63.40, peste midpoint")],
levels=[Level(63.15, "midpoint 63.15", "#b06000", "5 3")],
scale=120, gap=120, left=130, trend="down",
caption="Candela 2 recuperează peste jumătate din corpul candelei 1, dar nu tot. Scară: 0.10 = 12 px."))
w("""
**Ce s-a întâmplat:** candela 2 a deschis cu gap în jos — adică sentimentul
era încă negativ la deschidere — și apoi a recuperat mai mult de jumătate din
căderea precedentă.
**De ce contează pragul de 50%, și nu altul:** midpoint-ul e prețul mediu
plătit de cei care au vândut în candela 1. Când prețul trece peste el,
**mai mult de jumătate** dintre ei sunt pe pierdere. Sub prag, majoritatea
încă sunt pe profit și n-au niciun motiv să acționeze.
**De ce îl urmărești:** e versiunea slabă a engulfing-ului — aceeași direcție,
aceeași logică, dar cu jumătate din perdanți în loc de toți.
**Ce faci când îl vezi:** spre deosebire de engulfing, **ceri confirmare**.
Aștepți o candelă care închide peste high-ul candelei 2 (63.45). Stop-ul
merge sub low-ul candelei 2.
**Dark Cloud Cover** e oglinda: după uptrend, candela 2 deschide cu gap în
sus și închide sub midpoint-ul corpului verde precedent.
**Avertisment practic:** ambele cer un **gap la deschidere**. Pe instrumente
care se tranzacționează continuu (forex, cripto) gap-urile aproape nu există,
deci pattern-urile astea apar aproape exclusiv pe acțiuni și indici, la
deschiderea sesiunii.""")
w("""
---
# Pattern-uri de trei candele
## Morning Star — reversal bull, cel mai fiabil dintre clasice
**Ce arată:** candelă mare bear, candelă mică izolată jos, candelă mare bull
care închide peste midpoint-ul primei.""")
svg(Chart(
candles=[Candle(64.00, 64.10, 62.10, 62.20, "c1 — bear", "candela 1 — O 64.00, C 62.20, midpoint 63.10"),
Candle(62.05, 62.20, 61.90, 62.00, "c2 — indecizie", "candela 2 — corp mic, izolată jos: nici vânzătorii nu mai coboară"),
Candle(62.10, 63.50, 62.05, 63.40, "c3 — bull", "candela 3 — închide 63.40, peste midpoint-ul 63.10")],
levels=[Level(63.10, "midpoint 63.10 — pragul de validare", "#b06000", "5 3")],
scale=95, gap=105, left=95, trend="down",
caption="Scară: 0.10 = 9.5 px. Candela 3 trebuie să închidă peste 63.10, altfel nu e Morning Star."))
w("""
**Ce s-a întâmplat, pe etape:**
1. **Candela 1** — vânzătorii în control total, 1.80 în jos.
2. **Candela 2** — vânzătorii ajung jos și **nu mai pot coborî**. Nici
cumpărătorii nu preiau. Echilibru, la minimul mișcării.
3. **Candela 3** — cumpărătorii preiau și recuperează peste jumătate din
candela 1.
**De ce e mai fiabil decât un hammer sau un doji:** pattern-urile de o
candelă îți arată **un singur moment**. Morning Star îți arată o **secvență**:
epuizare, pauză, preluare. Fiecare etapă confirmă pe precedenta, iar
confirmarea e deja inclusă în pattern — nu mai aștepți o a patra candelă.
**De ce îl urmărești:** e unul dintre puținele pattern-uri care justifică
intrarea **fără confirmare suplimentară**, pentru că a treia candelă *este*
confirmarea.
**Ce faci când îl vezi:** verifici pragul. Dacă închiderea candelei 3 e sub
midpoint-ul candelei 1, **nu e Morning Star** — e doar un rebound, și îl
tratezi ca atare.
**Trade complet, long:**""")
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", label_at="left"),
Level(61.85, "SL 61.85 — sub low-ul c2", "#c00")],
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("""
**Evening Star** e oglinda exactă, după uptrend: candelă mare bull, candelă
mică izolată sus, candelă mare bear care închide sub midpoint-ul primei.
Short la închiderea candelei 3, stop peste high-ul candelei 2.
## Abandoned Baby — Morning Star cu gap-uri de ambele părți
**Ce arată:** aceeași structură, dar candela din mijloc e **complet izolată**
prin gap-uri — high-ul ei e sub low-ul candelei 1 **și** sub low-ul candelei 3.""")
svg(Chart(
candles=[Candle(64.00, 64.10, 62.60, 62.70, "c1 — bear", "candela 1 — low-ul ei e 62.60"),
Candle(62.15, 62.25, 62.00, 62.10, "c2 — abandonată", "candela 2 — high-ul ei (62.25) e SUB low-ul candelei 1: gap"),
Candle(62.50, 63.80, 62.45, 63.70, "c3 — bull", "candela 3 — low-ul ei (62.45) e PESTE high-ul candelei 2: al doilea gap")],
scale=110, gap=105, left=95, trend="down",
caption="Două gap-uri, unul de fiecare parte a candelei din mijloc. Scară: 0.10 = 11 px."))
w("""
**Ce s-a întâmplat în plus față de Morning Star:** gap-urile înseamnă că
**nu s-a tranzacționat nimic** la prețurile dintre candele. Schimbarea de
control a fost atât de bruscă încât n-a existat niciun preț intermediar la
care cumpărătorii și vânzătorii să se întâlnească.
**De ce e considerat mai puternic:** un gap e o zonă fără proprietari. Nimeni
nu a cumpărat acolo, deci nimeni nu are pierderi de recuperat acolo, deci nu
există ofertă care să oprească mișcarea în drumul înapoi.
**Ce faci când îl vezi:** identic cu Morning Star. Diferența e doar în
așteptări — merită dimensionat ceva mai mare, dacă e la un nivel.
**De ce îl vei vedea rar:** cere două gap-uri consecutive, deci apare aproape
exclusiv pe acțiuni și indici, la deschiderea sesiunii, și de obicei în jurul
unui catalizator (rezultate financiare, știre). Pe forex sau cripto, practic
nu apare.
## Three White Soldiers / Three Black Crows
**Ce arată:** trei candele consecutive cu corpuri mari în aceeași direcție,
fiecare deschizând în interiorul corpului precedentei și închizând peste
high-ul ei (sau sub low, la variantă bear).""")
svg(Chart(
candles=[Candle(62.10, 62.90, 62.05, 62.85, "1", ""),
Candle(62.55, 63.60, 62.50, 63.55, "2", "fiecare deschide în corpul precedentei și închide peste high-ul ei"),
Candle(63.25, 64.30, 63.20, 64.25, "3", "")],
scale=95, gap=105, left=110,
caption="Three White Soldiers. Varianta bear (Three Black Crows) e oglinda exactă."))
w("""
**Ce s-a întâmplat:** control susținut pe trei intervale consecutive, fără
respingeri serioase. E cel mai clar semnal de **continuare** din setul clasic.
**De ce cursul nu insistă pe ele — motivul real:** nu doar că apar rar.
Problema e **când** apar: patternul se completează abia la închiderea celei
de-a treia candele, adică după ce mișcarea a parcurs deja trei intervale
întregi. Intri la capătul lui, cu stop-ul logic sub low-ul primei candele —
adică riști toată mișcarea ca să prinzi ce urmează după ea.
**Ce faci când îl vezi, concret:** nu îl folosești ca semnal de intrare. Îl
folosești ca **confirmare de context**: dacă ai deja o poziție long și apar
trei soldați, ai dovada că trendul e susținut și poți ține mai mult. Dacă
nu ai poziție, aștepți un pullback, nu intri în al patrulea interval.
---
## Regula care le leagă pe toate
Toate pattern-urile de mai sus au aceeași structură logică:
| Element | Ce e | Exemplu la hammer |
|---|---|---|
| **Nivelul de invalidare** | prețul care, dacă e depășit, arată că ipoteza e greșită | low-ul, 62.10 |
| **Pragul de confirmare** | prețul care, dacă e depășit, arată că ipoteza e corectă | high-ul, 63.30 |
| **Zona de așteptare** | între ele, nu știi nimic | 62.10 - 63.30 |
Dacă un pattern nu îți dă cele două niveluri, nu e tranzacționabil — e doar
context.
## Gotchas practice
- **Fără nivel, nu există pattern.** Un hammer în mijlocul unei consolidări
nu înseamnă nimic. Același hammer la un pivot quarterly e un set-up.
Contextul nu e un bonus, e o condiție.
- **Formele identice se citesc invers.** Hammer și hanging man sunt aceeași
candelă. Inverted hammer și shooting star, la fel. Ce le separă e exclusiv
trendul dinainte — verifică-l întotdeauna înainte să numești patternul.
- **Un pattern nu îți spune cât de departe merge prețul.** Îți dă direcția și
nivelul de invalidare. Ținta vine din altceva: un nivel de rezistență, un
multiplu de risc, sau o proiecție geometrică.
- **Marubozu mare = risc mare la intrare directă.** Așteaptă retestul
midpoint-ului; diferența de risc e de peste zece ori, pe același trade.
- **Gap-urile nu apar pe orice instrument.** Abandoned Baby, Piercing Line și
Dark Cloud Cover cer gap-uri, deci apar pe acțiuni și indici, la
deschidere. Nu le aștepta pe forex sau cripto.
## Ce e completare a mea, dincolo de transcriere
Cursul descrie formele și denumirile, plus partea de scanare în TradeStation.
Următoarele sunt completările mele: mecanismul comun al fitilului, toate
exemplele numerice OHLC, secțiunile **de ce îl urmărești** și **ce faci când
îl vezi** pentru fiecare pattern, trade-urile complete cu intrare/SL/țintă,
comparația de risc la marubozu, explicația pragului de 50% la Piercing Line,
motivul real pentru care Three Soldiers se tranzacționează prost, tabelul cu
nivelul de invalidare / pragul de confirmare, și gotchas-urile.
Toate diagramele sunt generate din prețuri cu `svg_candles.py`, nu desenate
de mână — o unitate de preț are aceeași înălțime oriunde pe același desen,
deci o țintă de 2R e desenată la exact dublul distanței față de stop-loss.
## Referințe
- [IG — 16 Candlestick Patterns Every Trader Should Know](https://www.ig.com/en/trading-strategies/16-candlestick-patterns-every-trader-should-know-180615)
- [Investopedia — Hammer Candlestick](https://www.investopedia.com/terms/h/hammer.asp)
- [Investopedia — Engulfing Pattern](https://www.investopedia.com/terms/b/bullishengulfingpattern.asp)
- [CandleScanner — Piercing Pattern](https://www.candlescanner.com/candlestick-patterns/piercing/)""")
out = Path(__file__).resolve().parent.parent / "summaries/01_MODUL_1/05_patternuri_candele.md"
out.write_text("\n".join(P) + "\n", encoding="utf-8")
print(f"scris {out} ({len(P)} blocuri)")