buy_doji: capitolul rescris ca tutorial in 9 pasi, cu 9 diagrame noi

Mostra de format ceruta de user pe 19.09.2026 — de aprobat inainte sa
aplicam formatul la celelalte 8 capitole. Specificatia e in STYLE.md,
sectiunea FORMAT TUTORIAL.

Structura: pasii 1-9 in ordinea in care faci lucrurile la ecran, fiecare
terminat cu "Treci mai departe doar daca...". Cele trei perechi de TF
(weekly-daily, monthly-weekly, daily-60min) una langa alta in pasul 2;
perechea monthly-weekly e acoperita doar partial de material si scrie asta.
Nivelurile 0/1/2 desfiintate ca structura. Niciun tabel de 2 coloane.
Sursele mutate la final.

14 diagrame, de la 5: cele 5 vechi raman neatinse, 9 noi. Un agent per
diagrama, fiecare cu audit + PNG privit. Toate 9 ies curate.

10 reguli din material care lipseau din versiunea veche, fiecare cu citat
si fisier:linie — printre ele stopul se numara pe TF-ul deciziei
(20_2025-08-25:9-15) si nu muti ordinul dupa pret (03_locul_crimei:296-311).
Contradictie noua, a 7-a: pe weekly regula de pivoti spune Quarterly, dar
MICI citeste pivotul monthly.

Completarile proprii stau in blocuri "Completare proprie:", conform
deciziei userului de azi.

Cunoscut, nereparat: audit_diagrams da 9 fals-pozitive pe buy_doji_aplus si
buy_doji_fereastra, care folosesc <g transform> (auditul nu-l intelege).
A zecea, in buy_doji_sell (titlu peste eticheta "doji 99.20 / 100.10"), e
reala si preexistenta.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
This commit is contained in:
Claude Agent
2026-09-19 18:27:13 +00:00
parent a8be65532a
commit 9c1936e73a
32 changed files with 6343 additions and 1143 deletions

View File

@@ -0,0 +1,182 @@
#!/usr/bin/env python3
"""Buy Doji — NU: Sell Doji daily contra unui Buy Doji weekly.
Citește `gen/strategii/buy_doji_directie.spec.txt` și scrie
`gen/strategii/buy_doji_directie.svg`. Două panouri stivuite: sus weekly
(10 bare, Buy Doji confirmat), jos daily (17 bare, uptrend, Sell Doji tehnic
valid, short-ul lovește SL-ul). Coordonatele sunt absolute (fără
<g transform>), ca audit_diagrams.py să vadă pozițiile reale ale textelor.
Rulare: python3 gen/strategii/buy_doji_directie.py
"""
from pathlib import Path
OUT = Path(__file__).with_suffix(".svg")
W = 720
def trend(start, closes, wick=0.15):
bars, o = [], start
for c in closes:
bars.append((o, round(max(o, c) + wick, 2), round(min(o, c) - wick, 2), c))
o = c
return bars
# --- seriile din spec: (open, high, low, close) -----------------------------
WK = trend(89.0, [88.0, 86.2, 84.9, 83.1, 81.6, 80.2, 78.9]) + [
(78.90, 79.80, 77.60, 78.80), # 7: doji
(78.80, 81.60, 78.60, 81.30), # 8: confirmare => Buy Doji weekly
(81.30, 82.70, 81.10, 82.40)]
DY = trend(81.30, [81.7, 82.2, 82.0, 82.6, 83.1, 83.5, 83.3, 83.9, 84.4]) + [
(84.40, 84.80, 83.95, 84.35), # 9: doji
(84.35, 84.45, 83.45, 83.60), # 10: confirmare => Sell Doji, intrare short
(83.60, 83.70, 83.00, 83.20),
(83.20, 84.00, 83.10, 83.90),
(83.90, 84.70, 83.80, 84.60),
(84.60, 85.25, 84.50, 85.10), # 14: SL lovit
(85.10, 85.75, 85.00, 85.60),
(85.60, 86.30, 85.50, 86.10)]
def eq(a, b):
return abs(a - b) < 0.005
# --- assert-urile din spec ---------------------------------------------------
assert len(WK) == 10 and len(DY) == 17
for name, bars in (("weekly", WK), ("daily", DY)):
for i, (o, h, l, c) in enumerate(bars):
assert h >= max(o, c) and l <= min(o, c), f"{name}[{i}] h/l incoerent"
if i:
assert eq(o, bars[i - 1][3]), f"{name}[{i}] open != close precedent"
for name, (o, h, l, c) in (("doji weekly", WK[7]), ("doji daily", DY[9])):
assert abs(o - c) <= 0.10 * (h - l) + 1e-9, f"{name} nu e doji"
assert WK[8][3] > WK[7][1], "weekly: fără confirmare"
assert DY[10][3] < DY[9][2], "daily: fără confirmare Sell Doji"
ENTRY = DY[10][3]
SL = max(b[1] for b in DY[7:11])
RISK = round(SL - ENTRY, 2)
TP1 = round(ENTRY - RISK, 2)
assert eq(ENTRY, 83.60) and eq(SL, 84.80) and eq(RISK, 1.20) and eq(TP1, 82.40)
LOW_AFTER = min(b[2] for b in DY[11:])
assert eq(LOW_AFTER, 83.00) and LOW_AFTER > TP1, "TP1 atins"
HIT = next(i for i in range(11, 17) if DY[i][1] >= SL - 1e-9)
assert HIT == 14, f"SL lovit la {HIT}"
assert eq(DY[0][0], WK[8][3]), "daily nu începe la close-ul confirmării weekly"
# --- desen -------------------------------------------------------------------
GREEN, RED, ORANGE, GRAY, INK = "#188a3e", "#c00", "#d06a00", "#777", "#333"
BODY_W = 9
out = []
def text(x, y, s, fill=INK, anchor="start", bold=False, size=None):
st = (["font-weight:bold"] if bold else []) + ([f"font-size:{size}px"] if size else [])
style = f' style="{";".join(st)}"' if st else ""
a = f' text-anchor="{anchor}"' if anchor != "start" else ""
out.append(f'<text x="{x:.1f}" y="{y:.1f}" fill="{fill}"{a}{style}>{s}</text>')
def line(x1, y1, x2, y2, color, width=1.5, dash=None, extra=""):
d = f' stroke-dasharray="{dash}"' if dash else ""
out.append(f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{x2:.1f}" y2="{y2:.1f}" '
f'stroke="{color}" stroke-width="{width}"{d}{extra}/>')
def rect(x, y, w, h, fill, opacity, stroke="none"):
out.append(f'<rect x="{x:.1f}" y="{y:.1f}" width="{w:.1f}" height="{h:.1f}" fill="{fill}" '
f'fill-opacity="{opacity}" stroke="{stroke}" rx="3"/>')
def candles(bars, x0, gap, yf):
for i, (o, h, l, c) in enumerate(bars):
cx = x0 + i * gap
line(cx, yf(h), cx, yf(l), "#1a1a1a", 1.2)
top = yf(max(o, c))
hh = max(yf(min(o, c)) - top, 1.6)
out.append(f'<rect x="{cx - BODY_W / 2:.1f}" y="{top:.1f}" width="{BODY_W}" '
f'height="{hh:.1f}" fill="{GREEN if c >= o else RED}"/>')
text(20, 24, "NU: Sell Doji daily contra unui Buy Doji weekly — exemplu construit",
bold=True, size=14)
# ---- panoul de sus: weekly ----------------------------------------------------
WX0, WGAP, WS, WT = 60, 16, 12.0, 66
wmax = max(b[1] for b in WK)
yw = lambda p: WT + (wmax - p) * WS # noqa: E731
xw = lambda i: WX0 + i * WGAP # noqa: E731
text(20, 50, "weekly: direcția", fill="#555", bold=True)
rect(xw(7) - 8, yw(WK[8][1]) - 4, WGAP + 16, yw(WK[7][2]) - yw(WK[8][1]) + 8,
GREEN, 0.12, GREEN)
candles(WK, WX0, WGAP, yw)
text(xw(7), yw(WK[7][2]) + 16, "doji weekly", fill=ORANGE, anchor="middle", bold=True)
text(xw(9) + 14, yw(WK[8][3]) + 4, "Buy Doji weekly: direcția = long", fill=GREEN, bold=True)
# insigna de direcție
rect(470, 66, 230, 58, GREEN, 0.10, GREEN)
text(585, 90, "WEEKLY: LONG ↑", fill=GREEN, anchor="middle", bold=True, size=16)
text(585, 110, "confirmare 81.30 &gt; high doji 79.80", fill=GREEN, anchor="middle", size=11)
w_bottom = yw(min(b[2] for b in WK))
# ---- panoul de jos: daily -----------------------------------------------------
DX0, DGAP, DS = 60, 18, 40.0
DT = w_bottom + 110
dmax = max(b[1] for b in DY)
yd = lambda p: DT + (dmax - p) * DS # noqa: E731
xd = lambda i: DX0 + i * DGAP # noqa: E731
line(20, w_bottom + 34, W - 20, w_bottom + 34, "#ddd", 1)
text(20, w_bottom + 56, "daily: săptămânile de după confirmare (open 81.30 = close-ul ei)",
fill="#555", bold=True)
LX1, LX2, COL = xd(9) - 10, 392, 400
y_sl, y_e, y_tp = yd(SL), yd(ENTRY), yd(TP1)
assert abs((y_sl - y_e) - (y_e - y_tp)) < 1e-6, "SL-intrare != intrare-TP1 în px"
rect(xd(9) - 8, yd(DY[9][1]) - 3, DGAP + 16, yd(DY[10][2]) - yd(DY[9][1]) + 6, ORANGE, 0.15, ORANGE)
line(LX1, y_sl, LX2, y_sl, RED, 1.5, "6 3")
line(xd(10) - 8, y_e, LX2, y_e, ORANGE, 1.5, "6 3")
line(xd(10) - 8, y_tp, LX2, y_tp, GRAY, 1.5, "2 3")
text(COL, y_sl + 4, "SL 84.80 = high 4 candele", fill=RED, size=11)
text(COL, y_e + 4, "intrare short 83.60", fill=ORANGE, size=11)
text(COL, y_tp + 4, "TP1 82.40 — neatins", fill=GRAY, size=11)
candles(DY, DX0, DGAP, yd)
# paranteza „short de 1-2 zile" peste barele 10-11
xa, xb, yb = xd(10) - 6, xd(11) + 6, y_sl - 12
out.append(f'<path d="M{xa:.1f},{yb + 6:.1f} V{yb:.1f} H{xb:.1f} V{yb + 6:.1f}" '
f'fill="none" stroke="{GRAY}" stroke-width="1.2"/>')
text(xb, yb - 6, "short de 1-2 zile: permis", fill=GRAY, anchor="end", bold=True)
# SL lovit la bara 14
cx14 = xd(HIT)
out.append(f'<circle cx="{cx14:.1f}" cy="{y_sl:.1f}" r="7" fill="none" stroke="{RED}" '
f'stroke-width="2"/>')
y_lbl = DT - 22
line(cx14, y_sl - 8, cx14, y_lbl + 4, RED, 1.2)
text(cx14 - 6, y_lbl, "SL lovit: poziția short contra weekly", fill=RED, anchor="middle", bold=True)
# Sell Doji: etichetă sub panou, cu leader spre confirmare
y_bot = yd(min(b[2] for b in DY))
y_sd = y_bot + 22
line(xd(10), yd(DY[10][2]) + 4, xd(10), y_sd - 12, ORANGE, 1.2)
text(xd(10) - 20, y_sd, "Sell Doji daily: tehnic valid (close 83.60 &lt; low doji 83.95)",
fill=ORANGE, bold=True)
# insigna de contrast
rect(470, DT - 36, 230, 58, RED, 0.08, RED)
text(585, DT - 12, "short daily = CONTRA ✗", fill=RED, anchor="middle", bold=True, size=16)
text(585, DT + 8, "weekly zice long; daily urcă mai departe", fill=RED, anchor="middle", size=11)
y0 = y_sd + 32
text(20, y0, "Short scurt înăuntrul structurii weekly: da. Poziție short contra ei: nu.",
fill=INK, bold=True)
text(20, y0 + 18, "Seria e construită: un singur caz ilustrează regula, nu o dovedește.", fill="#555")
H = y0 + 30
svg = (f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/svg" '
f'style="width:100%;height:auto;font:12px sans-serif">\n ' + "\n ".join(out) + "\n</svg>")
assert "\n\n" not in svg
OUT.write_text(svg, encoding="utf-8")
print(f"intrare {ENTRY:.2f} SL {SL:.2f} risc {RISK:.2f} TP1 {TP1:.2f} | min după {LOW_AFTER:.2f} | "
f"SL lovit la bara {HIT}")
print(f"scris {OUT} ({W}x{H:.0f})")

View File

@@ -0,0 +1,62 @@
SPEC DIAGRAMĂ — buy_doji_directie
=================================
tip: PRET, două panouri stivuite (sus weekly mic, jos daily)
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 2, după perechi_tf
cheie markdown: <!-- DIAGRAMA: directie -->
titlu SVG: „NU: Sell Doji daily contra unui Buy Doji weekly — exemplu construit"
stil: candele lipite (gap 15-18, body_w 9-10), fără volum; open = close anterior.
CE TREBUIE SĂ DEMONSTREZE
-------------------------
Pe weekly s-a confirmat un Buy Doji. Pe daily, în uptrend-ul care urmează,
apare un Sell Doji tehnic valid. Ca poziție short e contra direcției
weekly: prețul scade o zi, apoi urcă și lovește SL-ul. Zona „short de 1-2
zile" e marcată separat, ca să se vadă diferența dintre un short scurt
înăuntrul structurii și o poziție contra ei.
SERIA — panoul de sus (weekly, 10 bare, (o,h,l,c))
--------------------------------------------------
Close-uri: 88.0, 86.2, 84.9, 83.1, 81.6, 80.2, 78.9 (bara 0 open 89.0,
fitile 0.15 peste/sub corp), apoi:
7 doji (78.90, 79.80, 77.60, 78.80)
8 confirm (78.80, 81.60, 78.60, 81.30)
9 (81.30, 82.70, 81.10, 82.40)
Mark(7, "doji weekly"), Mark(8, "Buy Doji weekly: direcția = long").
SERIA — panoul de jos (daily, 17 bare, (o,h,l,c))
-------------------------------------------------
Barele 0-8, close-uri 81.7, 82.2, 82.0, 82.6, 83.1, 83.5, 83.3, 83.9, 84.4,
open[0] = 81.30, fitile 0.15 peste/sub corp (uptrend de 9 candele).
9 doji (84.40, 84.80, 83.95, 84.35)
10 confirmare (84.35, 84.45, 83.45, 83.60) close < low doji 83.95 => Sell Doji
11 (83.60, 83.70, 83.00, 83.20)
12 (83.20, 84.00, 83.10, 83.90)
13 (83.90, 84.70, 83.80, 84.60)
14 (84.60, 85.25, 84.50, 85.10) <- high 85.25 >= SL 84.80
15 (85.10, 85.75, 85.00, 85.60)
16 (85.60, 86.30, 85.50, 86.10)
NIVELURI (panoul daily)
-----------------------
intrare short 83.60 (portocaliu), SL 84.80 roșu („SL 84.80 = high 4 candele"),
TP1 82.40 punctat („TP1 82.40 — neatins").
Paranteză orizontală peste barele 10-11: „short de 1-2 zile: permis" (gri).
Mark(14, "SL lovit: poziția short contra weekly", roșu, above).
ASSERT-URI
----------
1. open[i] == close[i-1] pe ambele panouri; h/l cuprind o/c.
2. Doji weekly și doji daily: abs(o-c) <= 0.10*(h-l).
3. weekly close[8] > high[7]; daily close[10] < low[9].
4. SL == max(h for bare daily 7..10) == 84.80; risc == 1.20; TP1 == 82.40.
5. min(l for bare daily 11..16) == 83.00 > 82.40 (TP1 neatins).
6. primul i>10 cu high >= 84.80 este 14.
SURSA
-----
- „nu shorta împotriva unui Buy Doji weekly … Short-uri de termen scurt în
interiorul structurii, da (el însuși a shortat 2 zile…)":
summaries/09_QA/03_2026-08-11.md:220-223.
- summaries/08_ANALIZA_ZILNICA/01_buy_doji_si_strategia_mici.md:34-37.
- SL/TP short: summaries/03_MODUL_2/13_strategia_3_byh.md:227-232.
- Seria e CONSTRUITĂ; un singur caz nu dovedește regula, doar o ilustrează.

View File

@@ -0,0 +1,85 @@
<svg viewBox="0 0 720 605" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="20.0" y="24.0" fill="#333" style="font-weight:bold;font-size:14px">NU: Sell Doji daily contra unui Buy Doji weekly — exemplu construit</text>
<text x="20.0" y="50.0" fill="#555" style="font-weight:bold">weekly: direcția</text>
<rect x="164.0" y="152.6" width="32.0" height="56.0" fill="#188a3e" fill-opacity="0.12" stroke="#188a3e" rx="3"/>
<line x1="60.0" y1="66.0" x2="60.0" y2="81.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="55.5" y="67.8" width="9" height="12.0" fill="#c00"/>
<line x1="76.0" y1="78.0" x2="76.0" y2="103.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="71.5" y="79.8" width="9" height="21.6" fill="#c00"/>
<line x1="92.0" y1="99.6" x2="92.0" y2="118.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="87.5" y="101.4" width="9" height="15.6" fill="#c00"/>
<line x1="108.0" y1="115.2" x2="108.0" y2="140.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="103.5" y="117.0" width="9" height="21.6" fill="#c00"/>
<line x1="124.0" y1="136.8" x2="124.0" y2="158.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="119.5" y="138.6" width="9" height="18.0" fill="#c00"/>
<line x1="140.0" y1="154.8" x2="140.0" y2="175.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="135.5" y="156.6" width="9" height="16.8" fill="#c00"/>
<line x1="156.0" y1="171.6" x2="156.0" y2="190.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="151.5" y="173.4" width="9" height="15.6" fill="#c00"/>
<line x1="172.0" y1="178.2" x2="172.0" y2="204.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="167.5" y="189.0" width="9" height="1.6" fill="#c00"/>
<line x1="188.0" y1="156.6" x2="188.0" y2="192.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="183.5" y="160.2" width="9" height="30.0" fill="#188a3e"/>
<line x1="204.0" y1="143.4" x2="204.0" y2="162.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="199.5" y="147.0" width="9" height="13.2" fill="#188a3e"/>
<text x="172.0" y="220.6" fill="#d06a00" text-anchor="middle" style="font-weight:bold">doji weekly</text>
<text x="218.0" y="164.2" fill="#188a3e" style="font-weight:bold">Buy Doji weekly: direcția = long</text>
<rect x="470.0" y="66.0" width="230.0" height="58.0" fill="#188a3e" fill-opacity="0.1" stroke="#188a3e" rx="3"/>
<text x="585.0" y="90.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:16px">WEEKLY: LONG ↑</text>
<text x="585.0" y="110.0" fill="#188a3e" text-anchor="middle" style="font-size:11px">confirmare 81.30 &gt; high doji 79.80</text>
<line x1="20.0" y1="238.6" x2="700.0" y2="238.6" stroke="#ddd" stroke-width="1"/>
<text x="20.0" y="260.6" fill="#555" style="font-weight:bold">daily: săptămânile de după confirmare (open 81.30 = close-ul ei)</text>
<rect x="214.0" y="371.6" width="34.0" height="60.0" fill="#d06a00" fill-opacity="0.15" stroke="#d06a00" rx="3"/>
<line x1="212.0" y1="374.6" x2="392.0" y2="374.6" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="232.0" y1="422.6" x2="392.0" y2="422.6" stroke="#d06a00" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="232.0" y1="470.6" x2="392.0" y2="470.6" stroke="#777" stroke-width="1.5" stroke-dasharray="2 3"/>
<text x="400.0" y="378.6" fill="#c00" style="font-size:11px">SL 84.80 = high 4 candele</text>
<text x="400.0" y="426.6" fill="#d06a00" style="font-size:11px">intrare short 83.60</text>
<text x="400.0" y="474.6" fill="#777" style="font-size:11px">TP1 82.40 — neatins</text>
<line x1="60.0" y1="492.6" x2="60.0" y2="520.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="55.5" y="498.6" width="9" height="16.0" fill="#188a3e"/>
<line x1="78.0" y1="472.6" x2="78.0" y2="504.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="73.5" y="478.6" width="9" height="20.0" fill="#188a3e"/>
<line x1="96.0" y1="472.6" x2="96.0" y2="492.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="91.5" y="478.6" width="9" height="8.0" fill="#c00"/>
<line x1="114.0" y1="456.6" x2="114.0" y2="492.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="109.5" y="462.6" width="9" height="24.0" fill="#188a3e"/>
<line x1="132.0" y1="436.6" x2="132.0" y2="468.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="127.5" y="442.6" width="9" height="20.0" fill="#188a3e"/>
<line x1="150.0" y1="420.6" x2="150.0" y2="448.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="145.5" y="426.6" width="9" height="16.0" fill="#188a3e"/>
<line x1="168.0" y1="420.6" x2="168.0" y2="440.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="163.5" y="426.6" width="9" height="8.0" fill="#c00"/>
<line x1="186.0" y1="404.6" x2="186.0" y2="440.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="181.5" y="410.6" width="9" height="24.0" fill="#188a3e"/>
<line x1="204.0" y1="384.6" x2="204.0" y2="416.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="199.5" y="390.6" width="9" height="20.0" fill="#188a3e"/>
<line x1="222.0" y1="374.6" x2="222.0" y2="408.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="217.5" y="390.6" width="9" height="2.0" fill="#c00"/>
<line x1="240.0" y1="388.6" x2="240.0" y2="428.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="235.5" y="392.6" width="9" height="30.0" fill="#c00"/>
<line x1="258.0" y1="418.6" x2="258.0" y2="446.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="253.5" y="422.6" width="9" height="16.0" fill="#c00"/>
<line x1="276.0" y1="406.6" x2="276.0" y2="442.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="271.5" y="410.6" width="9" height="28.0" fill="#188a3e"/>
<line x1="294.0" y1="378.6" x2="294.0" y2="414.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="289.5" y="382.6" width="9" height="28.0" fill="#188a3e"/>
<line x1="312.0" y1="356.6" x2="312.0" y2="386.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="307.5" y="362.6" width="9" height="20.0" fill="#188a3e"/>
<line x1="330.0" y1="336.6" x2="330.0" y2="366.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="325.5" y="342.6" width="9" height="20.0" fill="#188a3e"/>
<line x1="348.0" y1="314.6" x2="348.0" y2="346.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="343.5" y="322.6" width="9" height="20.0" fill="#188a3e"/>
<path d="M234.0,368.6 V362.6 H264.0 V368.6" fill="none" stroke="#777" stroke-width="1.2"/>
<text x="264.0" y="356.6" fill="#777" text-anchor="end" style="font-weight:bold">short de 1-2 zile: permis</text>
<circle cx="312.0" cy="374.6" r="7" fill="none" stroke="#c00" stroke-width="2"/>
<line x1="312.0" y1="366.6" x2="312.0" y2="296.6" stroke="#c00" stroke-width="1.2"/>
<text x="306.0" y="292.6" fill="#c00" text-anchor="middle" style="font-weight:bold">SL lovit: poziția short contra weekly</text>
<line x1="240.0" y1="432.6" x2="240.0" y2="530.6" stroke="#d06a00" stroke-width="1.2"/>
<text x="220.0" y="542.6" fill="#d06a00" style="font-weight:bold">Sell Doji daily: tehnic valid (close 83.60 &lt; low doji 83.95)</text>
<rect x="470.0" y="278.6" width="230.0" height="58.0" fill="#c00" fill-opacity="0.08" stroke="#c00" rx="3"/>
<text x="585.0" y="302.6" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:16px">short daily = CONTRA ✗</text>
<text x="585.0" y="322.6" fill="#c00" text-anchor="middle" style="font-size:11px">weekly zice long; daily urcă mai departe</text>
<text x="20.0" y="574.6" fill="#333" style="font-weight:bold">Short scurt înăuntrul structurii weekly: da. Poziție short contra ei: nu.</text>
<text x="20.0" y="592.6" fill="#555">Seria e construită: un singur caz ilustrează regula, nu o dovedește.</text>
</svg>

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -0,0 +1,105 @@
#!/usr/bin/env python3
"""Ce e doji și ce nu — patru candele cu același high 50.10 și low 49.20.
Citește `gen/strategii/buy_doji_doji_forma.spec.txt` și scrie
`gen/strategii/buy_doji_doji_forma.svg`. Definiție de o candelă (stilul
vechi, candele izolate): diferă doar corpul, deci testul „corp ≤ 10 % din
range, fitil în ambele părți" se vede direct pe formă.
Desenat direct, nu cu `Chart`: `tag`/`note` din svg_candles pun etichetele
pe un singur rând sau în blocul de jos, iar aici fiecare etichetă trebuie să
stea lipită sub candela ei, pe 2-3 rânduri.
Rulare: python3 gen/strategii/buy_doji_doji_forma.py
"""
from pathlib import Path
OUT = Path(__file__).with_suffix(".svg")
GREEN, RED, GREY = "#188a3e", "#c00", "#555"
H, L = 50.10, 49.20
RNG = H - L
# (nume, o, h, l, c, verdict, rânduri de etichetă sub candelă)
CANDLES = [
("A", 49.60, 50.10, 49.20, 49.55, "DA", ["DA: corp 0.05", "= 5.6 % din range"]),
("B", 49.62, 50.10, 49.20, 49.53, "DA", ["DA, la limită:", "corp 0.09 = 10 %", "(parametrul 10)"]),
("C", 49.80, 50.10, 49.20, 49.50, "NU", ["NU: corp 0.30", "= 33 %"]),
("D", 50.05, 50.10, 49.20, 50.10, "NU", ["NU: corp mic (5.6 %),", "dar fără fitil sus"]),
]
# --- assert-urile din spec --------------------------------------------------
ratio = {n: round(abs(c - o) / (h - l), 4) for n, o, h, l, c, *_ in CANDLES}
for n, o, h, l, c, *_ in CANDLES:
assert h == H and l == L, (n, h, l) # 1
assert ratio == {"A": 0.0556, "B": 0.1000, "C": 0.3333, "D": 0.0556}, ratio # 2
for n, o, h, l, c, *_ in CANDLES[:2]: # 3
assert ratio[n] <= 0.10 and min(o, c) > l and max(o, c) < h, n
assert ratio["C"] > 0.10 # 4
_, oD, hD, _, cD, *_ = CANDLES[3]
assert max(oD, cD) == hD
# --- geometrie ---------------------------------------------------------------
SCALE, TOP, W = 260, 72, 740
XS = [150, 300, 450, 600] # centrele candelelor
BODY_W = 26
def y(p):
return TOP + (H - p) * SCALE
oA, cA = CANDLES[0][1], CANDLES[0][4]
assert y(oA) < y(cA), "open A trebuie să fie mai sus pe ecran decât close A" # 5
out = []
t = out.append
def text(x, yy, s, color=GREY, anchor="start", bold=False, size=12):
style = f' style="font-weight:bold;font-size:{size}px"' if bold else (
f' style="font-size:{size}px"' if size != 12 else "")
t(f'<text x="{x:.1f}" y="{yy:.1f}" fill="{color}" text-anchor="{anchor}"{style}>{s}</text>')
text(24, 22, "Ce e doji și ce nu — aceeași bară 50.10 / 49.20", "#333", bold=True)
# high și low comune: linii subțiri pe toată lățimea
for p in (H, L):
t(f'<line x1="{XS[0] - 30}" y1="{y(p):.1f}" x2="{W - 24}" y2="{y(p):.1f}" '
f'stroke="#bbb" stroke-dasharray="4 3"/>')
text(XS[0] - 36, y(H) + 4, "high 50.10", anchor="end")
text(XS[0] - 36, y(L) + 4, "low 49.20", anchor="end")
label_y0 = y(L) + 24
for (n, o, h, l, c, verdict, lines), x in zip(CANDLES, XS):
color = GREEN if c >= o else RED
vcol = GREEN if verdict == "DA" else RED
t(f'<line x1="{x}" y1="{y(h):.1f}" x2="{x}" y2="{y(l):.1f}" stroke="#1a1a1a" stroke-width="1.4"/>')
top, bot = y(max(o, c)), y(min(o, c))
t(f'<rect x="{x - BODY_W / 2:.1f}" y="{top:.1f}" width="{BODY_W}" '
f'height="{max(bot - top, 1.6):.1f}" fill="{color}"/>')
text(x, y(H) - 14, verdict, vcol, "middle", bold=True, size=18)
for k, s in enumerate(lines):
text(x, label_y0 + 16 * k, s, vcol, "middle", bold=(k == 0))
# prețurile pe A: open la stânga (mai sus), close la dreapta (mai jos)
x = XS[0]
text(x - 36, y(oA) + 2, "open 49.60", anchor="end")
t(f'<line x1="{x - 32}" y1="{y(oA):.1f}" x2="{x - 14}" y2="{y(oA):.1f}" stroke="{GREY}"/>')
text(x + 36, y(cA) + 8, "close 49.55")
t(f'<line x1="{x + 14}" y1="{y(cA):.1f}" x2="{x + 32}" y2="{y(cA):.1f}" stroke="{GREY}"/>')
# D: close = high, deci fitilul de sus lipsește
x = XS[3]
text(x + 20, y(H) + 12, "← fără fitil sus", RED)
cap_y = label_y0 + 16 * 3 + 14
text(24, cap_y, f"Test doji: corp ≤ 10 % din range ({RNG:.2f}) și fitil în ambele părți. "
"Scară: 0.10 = 26 px.")
height = cap_y + 12
svg = (f'<svg viewBox="0 0 {W} {height:.0f}" xmlns="http://www.w3.org/2000/svg" '
f'style="width:100%;height:auto;font:12px sans-serif">\n '
+ "\n ".join(out) + "\n</svg>\n")
OUT.write_text(svg, encoding="utf-8")
print(f"scris {OUT} ({W}x{height:.0f})")

View File

@@ -0,0 +1,38 @@
SPEC DIAGRAMĂ — buy_doji_doji_forma
===================================
tip: DEFINIȚIE de o candelă (stil vechi permis de STYLE.md: 4 candele
izolate, gap 92, body_w 26), fără trend, fără volum.
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 3
cheie markdown: <!-- DIAGRAMA: doji_forma -->
titlu SVG: „Ce e doji și ce nu — aceeași bară 50.10 / 49.20"
CE TREBUIE SĂ DEMONSTREZE
-------------------------
Testul „corp ≤ 10 % din range, fitil în ambele părți", pe patru candele cu
ACELAȘI high 50.10 și ACELAȘI low 49.20 (range 0.90). Diferă doar corpul.
CANDELELE (o, h, l, c) și eticheta de sub fiecare
-------------------------------------------------
A (49.60, 50.10, 49.20, 49.55) „DA: corp 0.05 = 5.6 % din range"
B (49.62, 50.10, 49.20, 49.53) „DA, la limită: corp 0.09 = 10 % (parametrul 10)"
C (49.80, 50.10, 49.20, 49.50) „NU: corp 0.30 = 33 %"
D (50.05, 50.10, 49.20, 50.10) „NU: corp mic (5.6 %), dar fără fitil sus"
Deasupra fiecărei candele: „DA" verde / „NU" roșu.
Etichete de preț pe A: „high 50.10", „low 49.20", „open 49.60", „close 49.55"
(open deasupra lui close, pentru că open > close; verifică ordinea pe axă).
ASSERT-URI
----------
1. Toate patru: h == 50.10, l == 49.20.
2. corp/range: A 0.0556, B 0.1000, C 0.3333, D 0.0556 (4 zecimale).
3. A, B: corp/range <= 0.10 și min(o,c) > l și max(o,c) < h (fitil ambele părți).
4. C: corp/range > 0.10. D: max(o,c) == h (fitil sus zero).
5. y(open A) < y(close A) în pixeli (open mai sus pe ecran, fiindcă e preț mai mare).
SURSA
-----
- Doji: open ≈ close, corp foarte mic față de range, fitil în ambele părți:
summaries/03_MODUL_2/13_strategia_3_byh.md:15-30 (candela 50.10/49.20/49.60/49.55
e cea din lecție, cu cifrele sumarizatorului).
- Parametrul standard de doji pe 10 (nu 5): summaries/09_QA/28_2025-05-27.md:343-349.
- Candelele B, C, D sunt CONSTRUITE pentru contrast.

View File

@@ -0,0 +1,34 @@
<svg viewBox="0 0 740 404" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24.0" y="22.0" fill="#333" text-anchor="start" style="font-weight:bold;font-size:12px">Ce e doji și ce nu — aceeași bară 50.10 / 49.20</text>
<line x1="120" y1="72.0" x2="716" y2="72.0" stroke="#bbb" stroke-dasharray="4 3"/>
<line x1="120" y1="306.0" x2="716" y2="306.0" stroke="#bbb" stroke-dasharray="4 3"/>
<text x="114.0" y="76.0" fill="#555" text-anchor="end">high 50.10</text>
<text x="114.0" y="310.0" fill="#555" text-anchor="end">low 49.20</text>
<line x1="150" y1="72.0" x2="150" y2="306.0" stroke="#1a1a1a" stroke-width="1.4"/>
<rect x="137.0" y="202.0" width="26" height="13.0" fill="#c00"/>
<text x="150.0" y="58.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:18px">DA</text>
<text x="150.0" y="330.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:12px">DA: corp 0.05</text>
<text x="150.0" y="346.0" fill="#188a3e" text-anchor="middle">= 5.6 % din range</text>
<line x1="300" y1="72.0" x2="300" y2="306.0" stroke="#1a1a1a" stroke-width="1.4"/>
<rect x="287.0" y="196.8" width="26" height="23.4" fill="#c00"/>
<text x="300.0" y="58.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:18px">DA</text>
<text x="300.0" y="330.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:12px">DA, la limită:</text>
<text x="300.0" y="346.0" fill="#188a3e" text-anchor="middle">corp 0.09 = 10 %</text>
<text x="300.0" y="362.0" fill="#188a3e" text-anchor="middle">(parametrul 10)</text>
<line x1="450" y1="72.0" x2="450" y2="306.0" stroke="#1a1a1a" stroke-width="1.4"/>
<rect x="437.0" y="150.0" width="26" height="78.0" fill="#c00"/>
<text x="450.0" y="58.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:18px">NU</text>
<text x="450.0" y="330.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:12px">NU: corp 0.30</text>
<text x="450.0" y="346.0" fill="#c00" text-anchor="middle">= 33 %</text>
<line x1="600" y1="72.0" x2="600" y2="306.0" stroke="#1a1a1a" stroke-width="1.4"/>
<rect x="587.0" y="72.0" width="26" height="13.0" fill="#188a3e"/>
<text x="600.0" y="58.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:18px">NU</text>
<text x="600.0" y="330.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:12px">NU: corp mic (5.6 %),</text>
<text x="600.0" y="346.0" fill="#c00" text-anchor="middle">dar fără fitil sus</text>
<text x="114.0" y="204.0" fill="#555" text-anchor="end">open 49.60</text>
<line x1="118" y1="202.0" x2="136" y2="202.0" stroke="#555"/>
<text x="186.0" y="223.0" fill="#555" text-anchor="start">close 49.55</text>
<line x1="164" y1="215.0" x2="182" y2="215.0" stroke="#555"/>
<text x="620.0" y="84.0" fill="#c00" text-anchor="start">← fără fitil sus</text>
<text x="24.0" y="392.0" fill="#555" text-anchor="start">Test doji: corp ≤ 10 % din range (0.90) și fitil în ambele părți. Scară: 0.10 = 26 px.</text>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,222 @@
#!/usr/bin/env python3
"""Buy Doji — ieșirea: trailing stop pe gap-uri și limita de 8 candele.
Citește `gen/strategii/buy_doji_iesire.spec.txt` și scrie
`gen/strategii/buy_doji_iesire.svg`: două panouri stivuite.
A — seria din buy_doji_transe (barele 0-18) continuată cu 19-23. Barele 19
și 21 deschid cu GAP (excepție cerută de spec): regula de trail cere o
bară cu low peste high-ul precedentei, imposibil dacă open = close
anterior. De aceea barele 15-23 sunt construite explicit, nu cu
`from_closes`.
B — doji 50.10 / 49.20, intrare 50.40, apoi 8 candele fără TP și fără SL.
Barele de după intrare, în ambele panouri, sunt CONSTRUITE.
Sursa regulilor: summaries/03_MODUL_2/13_strategia_3_byh.md:196-213.
Rulare: python3 gen/strategii/buy_doji_iesire.py
"""
import re
import sys
from pathlib import Path
sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Candle, Chart, Level, Mark, from_closes # noqa: E402
OUT = Path(__file__).with_suffix(".svg")
W = 660
VGAP = 10
GREEN, RED, ORANGE, BLUE, GREY = "#188a3e", "#c00", "#b06000", "#1a5fb4", "#555"
# --- PANOUL A ----------------------------------------------------------------
ENTRY_A, SL_A, TP1_A = 53.70, 51.55, 55.85
R_A = round(ENTRY_A - SL_A, 2) # 2.15
a = from_closes([60.40, 59.60, 59.90, 58.80, 58.10, 58.40, 57.20, 56.30,
56.60, 55.30, 54.20, 52.40], wick=0.15, start=61.00)
a += [Candle(*ohlc) for ohlc in [
(52.40, 53.00, 51.60, 52.30), # 12 doji
(52.30, 52.85, 52.10, 52.60), # 13 +1
(52.60, 53.85, 52.45, 53.70), # 14 confirmare = intrare
(53.70, 53.80, 53.10, 53.45), # 15
(53.45, 54.20, 53.35, 54.10), # 16
(54.10, 54.85, 54.00, 54.70), # 17
(54.70, 56.00, 54.60, 55.90), # 18 atinge TP1
(56.30, 56.95, 56.20, 56.80), # 19 GAP
(56.80, 57.35, 56.60, 57.20), # 20
(57.60, 58.10, 57.45, 57.90), # 21 GAP
(57.90, 58.00, 57.50, 57.60), # 22
(57.60, 57.70, 57.10, 57.20), # 23 close sub trail
]]
assert len(a) == 24
for c in a:
assert c.l <= min(c.o, c.c) and c.h >= max(c.o, c.c), "h/l nu cuprind o/c"
# A1. gap-urile reale
assert a[19].l > a[18].h and a[21].l > a[20].h, "barele de gap nu au low > high anterior"
# A2. open = close anterior, în afară de 19 și 21 (și 0-14, ca în transe)
for i in range(1, 24):
if i not in (19, 21):
assert abs(a[i].o - a[i - 1].c) < 1e-9, f"A: open[{i}] != close[{i-1}]"
# regula de trail, calculată pe serie: primul gap după intrare stabilește
# trail-ul, fiecare gap următor îl urcă; ieși la primul close sub el
trail, steps, exit_i = None, [], None
for i in range(15, 24):
if trail is not None and a[i].c < trail:
exit_i = i
break
if a[i].l > a[i - 1].h:
trail = a[i].l
steps.append((i, trail))
assert [(i, round(t, 2)) for i, t in steps] == [(19, 56.20), (21, 57.45)], steps
# A3.
assert a[22].c >= 57.45 and a[23].c < 57.45 and exit_i == 23, exit_i
EXIT_A = a[23].c
# A4.
assert R_A == 2.15 and round((EXIT_A - ENTRY_A) / R_A, 2) == 1.63
# A5. TP1 = 1R, atins prima oară la bara 18
assert round(ENTRY_A + R_A, 2) == TP1_A
assert next(i for i in range(15, 24) if a[i].h >= TP1_A) == 18
assert abs(a[14].c - ENTRY_A) < 1e-9
ch_a = Chart(
candles=a,
levels=[Level(ENTRY_A, "intrare 53.70", GREEN),
Level(TP1_A, "TP1 55.85 — tranșa 1: +1R", GREEN, dash="2 3")],
scale=40, gap=16, body_w=9, left=44, width=W,
title="A — trailing stop pe gap-uri (seria de la intrarea în tranșe)",
caption="a treia treime: o lași mai departe (break-even / trend)",
)
# --- PANOUL B ----------------------------------------------------------------
ENTRY_B, SL_B, TP1_B = 50.40, 49.20, 51.60
R_B = round(ENTRY_B - SL_B, 2) # 1.20
b = from_closes([52.20, 51.40, 50.60, 49.65], wick=0.15, start=53.00)
b += [Candle(*ohlc) for ohlc in [
(49.65, 50.10, 49.20, 49.60), # 4 doji
(49.60, 50.05, 49.45, 49.90), # 5 +1
(49.90, 50.55, 49.75, 50.40), # 6 confirmare = intrare
]]
b += from_closes([50.60, 50.30, 50.90, 50.50, 51.10, 50.80, 51.20, 50.70],
wick=0.15, start=b[-1].c)
assert len(b) == 15
# B1.
for i in range(1, 15):
assert abs(b[i].o - b[i - 1].c) < 1e-9, f"B: open[{i}] != close[{i-1}]"
d = b[4]
assert abs(d.o - d.c) <= 0.10 * (d.h - d.l) and (d.h, d.l) == (50.10, 49.20)
assert b[6].c > d.h and abs(b[6].c - ENTRY_B) < 1e-9
# B2. 8 candele fără TP și fără SL
after = b[7:15]
assert all(c.h < TP1_B and c.l > SL_B for c in after)
assert round(max(c.h for c in after), 2) == 51.35 and round(min(c.l for c in after), 2) == 50.15
assert round(ENTRY_B + R_B, 2) == TP1_B
# B3.
EXIT_B = b[14].c
assert round((EXIT_B - ENTRY_B) / R_B, 2) == 0.25
for k, c in enumerate(after, 1):
c.tag = str(k)
ch_b = Chart(
candles=b,
levels=[Level(TP1_B, "TP1 51.60", GREEN, dash="2 3"),
Level(ENTRY_B, "intrare 50.40", GREEN),
Level(SL_B, "SL 49.20", RED)],
marks=[Mark(4, "doji", ORANGE, "below")],
scale=48, gap=16, body_w=9, left=44, width=W,
title="B — limita de 8 candele",
)
# --- etichete plasate de mână: Mark centrează textul, iar aici textele lungi
# ar cădea peste candelele vecine. Le ancorez lângă bară, pe partea liberă.
def label(ch, i, price, text, color, anchor="start", dx=0):
x = ch._cx(i) + dx
return (f'<text x="{x:.1f}" y="{ch._y(price):.1f}" fill="{color}" '
f'text-anchor="{anchor}" style="font-weight:bold">{text}</text>')
def panel(ch, extra):
svg = ch.render() # render() fixează scala (_pmax, top)
h = float(re.search(r'viewBox="0 0 \d+ ([\d.]+)"', svg).group(1))
body = svg[svg.index(">") + 1:svg.rindex("</svg>")].strip()
return body + "".join("\n " + e for e in extra(ch)), h
def trail_a(ch):
x19, x21, x23 = ch._cx(19) - 7, ch._cx(21) - 8, ch._cx(23) + 7
y1, y2 = ch._y(steps[0][1]), ch._y(steps[1][1])
# golul dintre high-ul barei precedente și low-ul barei de gap, hașurat:
# la 0.10-0.20 de preț are doar câțiva pixeli și se pierde sub linia de trail
gaps = [f'<rect x="{ch._cx(i - 1) - 7:.1f}" y="{ch._y(a[i].l):.1f}" width="{ch.gap + 14}" '
f'height="{ch._y(a[i - 1].h) - ch._y(a[i].l):.1f}" fill="{ORANGE}" opacity="0.35"/>'
for i, _ in steps]
return gaps + [
f'<polyline points="{x19:.1f},{y1:.1f} {x21:.1f},{y1:.1f} {x21:.1f},{y2:.1f} '
f'{x23:.1f},{y2:.1f}" fill="none" stroke="{ORANGE}" stroke-width="2"/>',
label(ch, 18, 56.25, "TP1: ieși cu 1/3", GREEN, "end", 4),
label(ch, 19, 55.35, "gap: low &gt; high anterior → trail 56.20", ORANGE, "start", -4),
label(ch, 21, 58.35, "gap → trail 57.45", ORANGE, "middle"),
label(ch, 23, 57.30, "close sub trail: ieși cu 1/3", RED, "start", 14),
label(ch, 23, 56.88, f"la 57.20 = +{(EXIT_A - ENTRY_A) / R_A:.2f}R", RED, "start", 14),
]
def mark_b(ch):
return [
label(ch, 14, 51.05, "a 8-a candelă: nici TP, nici SL", GREY, "start", 10),
label(ch, 14, 50.75, f"→ ieși la 50.70 = +{(EXIT_B - ENTRY_B) / R_B:.2f}R", GREY, "start", 10),
]
# panourile se stivuiesc prin `top` (nu prin <g transform>): audit_diagrams
# citește coordonatele brute și ar vedea panourile suprapuse.
T = 26
ch_a.top += T
body_a, h_a = panel(ch_a, trail_a)
ch_b.top += h_a + VGAP
body_b, H_B = panel(ch_b, mark_b)
TITLE = "Ieșirea: trailing stop pe gap-uri și limita de 8 candele — exemple construite"
CAP = "Barele de după intrare sunt construite. Regulile: 13_strategia_3_byh.md:196-213."
cap_y = H_B + 12
H = cap_y + 10
svg = "\n ".join([
f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/svg" '
f'style="width:100%;height:auto;font:12px sans-serif">',
f'<text x="24" y="18" fill="#333" style="font-weight:bold">{TITLE}</text>',
body_a,
body_b,
f'<text x="24" y="{cap_y:.0f}" fill="{GREY}">{CAP}</text>',
]) + "\n</svg>"
assert "\n\n" not in svg
# --- etichete în panză și fără suprapuneri (lățimi aproximate) ---------------
TEXT = re.compile(r'<text x="([-\d.]+)" y="([-\d.]+)"([^>]*)>(.*?)</text>', re.S)
def texts(body, y_off, tag):
for m in TEXT.finditer(body):
x, y, attrs = float(m.group(1)), float(m.group(2)) + y_off, m.group(3)
s = m.group(4).replace("&gt;", ">")
wpx = len(s) * 12 * (0.62 if "bold" in attrs else 0.52)
anchor = re.search(r'text-anchor="(\w+)"', attrs)
anchor = anchor.group(1) if anchor else "start"
x0 = x - wpx if anchor == "end" else (x - wpx / 2 if anchor == "middle" else x)
yield x0, x0 + wpx, y, s, tag
labels = list(texts(body_a, 0, "A")) + list(texts(body_b, 0, "B"))
for x0, x1, y, s, tag in labels:
assert x0 >= -2 and x1 <= W + 2 and 0 <= y <= H, f"[{tag}] text iese din panză: {s!r}"
for i, (l1, r1, y1, s1, t1) in enumerate(labels):
for l2, r2, y2, s2, t2 in labels[i + 1:]:
assert not (t1 == t2 and abs(y1 - y2) < 12 and l1 < r2 - 4 and l2 < r1 - 4), \
f"[{t1}] texte suprapuse: {s1!r} / {s2!r}"
OUT.write_text(svg, encoding="utf-8")
print(f"A: trail {steps}, ieșire bara {exit_i} la {EXIT_A:.2f} = "
f"+{(EXIT_A - ENTRY_A) / R_A:.2f}R; B: ieșire la {EXIT_B:.2f} = "
f"+{(EXIT_B - ENTRY_B) / R_B:.2f}R")
print(f"scris {OUT} ({W}x{H:.0f})")

View File

@@ -0,0 +1,57 @@
SPEC DIAGRAMĂ — buy_doji_iesire
===============================
tip: PRET, două panouri stivuite
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 9 (ieșirea)
cheie markdown: <!-- DIAGRAMA: iesire -->
titlu SVG: „Ieșirea: trailing stop pe gap-uri și limita de 8 candele — exemple construite"
stil: candele lipite (gap 15-18, body_w 9-10), fără volum.
EXCEPȚIE CERUTĂ: în panoul A, barele 19 și 21 deschid cu GAP
(open != close anterior). Regula de trail are nevoie de o bară
cu low peste high-ul precedentei, ceea ce fără gap e imposibil.
Toate celelalte bare: open = close anterior.
PANOUL A — trailing stop (seria buy_doji_transe, continuată)
------------------------------------------------------------
Barele 0-18: identice cu buy_doji_transe. Apoi:
19 (56.30, 56.95, 56.20, 56.80) GAP: low 56.20 > high[18] 56.00 → trail = 56.20
20 (56.80, 57.35, 56.60, 57.20)
21 (57.60, 58.10, 57.45, 57.90) GAP: low 57.45 > high[20] 57.35 → trail urcă la 57.45
22 (57.90, 58.00, 57.50, 57.60) close 57.60 ≥ 57.45: rămâi
23 (57.60, 57.70, 57.10, 57.20) close 57.20 < 57.45: ieși
Niveluri: intrare 53.70; TP1 55.85 („tranșa 1: +1R"); trail în trepte:
segment 56.20 de la bara 19 la 20, segment 57.45 de la bara 21 la 23.
Marks: Mark(18, "TP1: ieși cu 1/3"), Mark(19, "gap: low > high anterior → trail 56.20"),
Mark(21, "trail 57.45"), Mark(23, "close sub trail: ieși cu 1/3 la 57.20 = +1.63R").
Text sub panou: „a treia treime: o lași mai departe (break-even / trend)".
PANOUL B — limita de 8 candele
------------------------------
open[0] = 53.00; close-uri: 52.20, 51.40, 50.60, 49.65, fitile 0.15;
4 doji (49.65, 50.10, 49.20, 49.60)
5 +1 (49.60, 50.05, 49.45, 49.90)
6 confirmare (49.90, 50.55, 49.75, 50.40) intrare 50.40
7-14 close-uri: 50.60, 50.30, 50.90, 50.50, 51.10, 50.80, 51.20, 50.70
(fitile 0.15; open = close anterior)
Niveluri: intrare 50.40, SL 49.20, TP1 51.60.
Numerotare 1..8 sub barele 7-14. Mark(14, "a 8-a candelă: nici TP, nici SL → ieși la 50.70 = +0.25R").
ASSERT-URI
----------
A1. low[19] > high[18] și low[21] > high[20] (gap-urile reale).
A2. open[i] == close[i-1] pentru i în 15..23, cu excepția 19 și 21.
A3. close[22] >= 57.45 și close[23] < 57.45; primul close sub trail după bara 19 e 23.
A4. round((57.20-53.70)/2.15, 2) == 1.63.
A5. primul i>14 cu high >= 55.85 este 18.
B1. open[i] == close[i-1] peste tot; doji abs(o-c) <= 0.10*(h-l); close[6] > 50.10.
B2. pentru barele 7-14: high < 51.60 și low > 49.20 (max high 51.35, min low 50.15).
B3. round((50.70-50.40)/1.20, 2) == 0.25.
SURSA
-----
- Trail: low-ul barei cu low peste high-ul precedentei; ieși la close sub el:
summaries/03_MODUL_2/13_strategia_3_byh.md:196-200.
- 3 poziții (1/3 TP, 1/3 trail, 1/3 mai departe): :204-213 (tabel marcat de
sumarizator ca completare, :341-350).
- Limita de 8 candele: :201-202.
- Doji 50.10/49.20, intrare 50.40, SL 49.20: exemplul lecției, :158-167.
- Barele după intrare, în ambele panouri, sunt CONSTRUITE.

View File

@@ -0,0 +1,114 @@
<svg viewBox="0 0 660 826" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="18" fill="#333" style="font-weight:bold">Ieșirea: trailing stop pe gap-uri și limita de 8 candele — exemple construite</text>
<text x="24" y="74" fill="#333" style="font-weight:bold">A — trailing stop pe gap-uri (seria de la intrarea în tranșe)</text>
<line x1="24" y1="380.0" x2="646" y2="380.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="632" y="374.0" fill="#188a3e" text-anchor="end">intrare 53.70</text>
<line x1="24" y1="294.0" x2="646" y2="294.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/>
<text x="632" y="288.0" fill="#188a3e" text-anchor="end">TP1 55.85 — tranșa 1: +1R</text>
<line x1="44.0" y1="82.0" x2="44.0" y2="118.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="39.5" y="88.0" width="9" height="24.0" fill="#c00"/>
<line x1="60.0" y1="106.0" x2="60.0" y2="150.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="55.5" y="112.0" width="9" height="32.0" fill="#c00"/>
<line x1="76.0" y1="126.0" x2="76.0" y2="150.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="71.5" y="132.0" width="9" height="12.0" fill="#188a3e"/>
<line x1="92.0" y1="126.0" x2="92.0" y2="182.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="87.5" y="132.0" width="9" height="44.0" fill="#c00"/>
<line x1="108.0" y1="170.0" x2="108.0" y2="210.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="103.5" y="176.0" width="9" height="28.0" fill="#c00"/>
<line x1="124.0" y1="186.0" x2="124.0" y2="210.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="119.5" y="192.0" width="9" height="12.0" fill="#188a3e"/>
<line x1="140.0" y1="186.0" x2="140.0" y2="246.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="135.5" y="192.0" width="9" height="48.0" fill="#c00"/>
<line x1="156.0" y1="234.0" x2="156.0" y2="282.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="151.5" y="240.0" width="9" height="36.0" fill="#c00"/>
<line x1="172.0" y1="258.0" x2="172.0" y2="282.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="167.5" y="264.0" width="9" height="12.0" fill="#188a3e"/>
<line x1="188.0" y1="258.0" x2="188.0" y2="322.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="183.5" y="264.0" width="9" height="52.0" fill="#c00"/>
<line x1="204.0" y1="310.0" x2="204.0" y2="366.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="199.5" y="316.0" width="9" height="44.0" fill="#c00"/>
<line x1="220.0" y1="354.0" x2="220.0" y2="438.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="215.5" y="360.0" width="9" height="72.0" fill="#c00"/>
<line x1="236.0" y1="408.0" x2="236.0" y2="464.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="231.5" y="432.0" width="9" height="4.0" fill="#c00"/>
<line x1="252.0" y1="414.0" x2="252.0" y2="444.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="247.5" y="424.0" width="9" height="12.0" fill="#188a3e"/>
<line x1="268.0" y1="374.0" x2="268.0" y2="430.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="263.5" y="380.0" width="9" height="44.0" fill="#188a3e"/>
<line x1="284.0" y1="376.0" x2="284.0" y2="404.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="279.5" y="380.0" width="9" height="10.0" fill="#c00"/>
<line x1="300.0" y1="360.0" x2="300.0" y2="394.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="295.5" y="364.0" width="9" height="26.0" fill="#188a3e"/>
<line x1="316.0" y1="334.0" x2="316.0" y2="368.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="311.5" y="340.0" width="9" height="24.0" fill="#188a3e"/>
<line x1="332.0" y1="288.0" x2="332.0" y2="344.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="327.5" y="292.0" width="9" height="48.0" fill="#188a3e"/>
<line x1="348.0" y1="250.0" x2="348.0" y2="280.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="343.5" y="256.0" width="9" height="20.0" fill="#188a3e"/>
<line x1="364.0" y1="234.0" x2="364.0" y2="264.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="359.5" y="240.0" width="9" height="16.0" fill="#188a3e"/>
<line x1="380.0" y1="204.0" x2="380.0" y2="230.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="375.5" y="212.0" width="9" height="12.0" fill="#188a3e"/>
<line x1="396.0" y1="208.0" x2="396.0" y2="228.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="391.5" y="212.0" width="9" height="12.0" fill="#c00"/>
<line x1="412.0" y1="220.0" x2="412.0" y2="244.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="407.5" y="224.0" width="9" height="16.0" fill="#c00"/>
<text x="24" y="494" fill="#555">a treia treime: o lași mai departe (break-even / trend)</text>
<rect x="325.0" y="280.0" width="30" height="8.0" fill="#b06000" opacity="0.35"/>
<rect x="357.0" y="230.0" width="30" height="4.0" fill="#b06000" opacity="0.35"/>
<polyline points="341.0,280.0 372.0,280.0 372.0,230.0 419.0,230.0" fill="none" stroke="#b06000" stroke-width="2"/>
<text x="336.0" y="278.0" fill="#188a3e" text-anchor="end" style="font-weight:bold">TP1: ieși cu 1/3</text>
<text x="344.0" y="314.0" fill="#b06000" text-anchor="start" style="font-weight:bold">gap: low &gt; high anterior → trail 56.20</text>
<text x="380.0" y="194.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">gap → trail 57.45</text>
<text x="426.0" y="236.0" fill="#c00" text-anchor="start" style="font-weight:bold">close sub trail: ieși cu 1/3</text>
<text x="426.0" y="252.8" fill="#c00" text-anchor="start" style="font-weight:bold">la 57.20 = +1.63R</text>
<text x="24" y="564" fill="#333" style="font-weight:bold">B — limita de 8 candele</text>
<line x1="24" y1="646.4" x2="646" y2="646.4" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/>
<text x="632" y="640.4" fill="#188a3e" text-anchor="end">TP1 51.60</text>
<line x1="24" y1="704.0" x2="646" y2="704.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="632" y="698.0" fill="#188a3e" text-anchor="end">intrare 50.40</text>
<line x1="24" y1="761.6" x2="646" y2="761.6" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="632" y="755.6" fill="#c00" text-anchor="end">SL 49.20</text>
<line x1="44.0" y1="572.0" x2="44.0" y2="624.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="39.5" y="579.2" width="9" height="38.4" fill="#c00"/>
<line x1="60.0" y1="610.4" x2="60.0" y2="663.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="55.5" y="617.6" width="9" height="38.4" fill="#c00"/>
<line x1="76.0" y1="648.8" x2="76.0" y2="701.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="71.5" y="656.0" width="9" height="38.4" fill="#c00"/>
<line x1="92.0" y1="687.2" x2="92.0" y2="747.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="87.5" y="694.4" width="9" height="45.6" fill="#c00"/>
<line x1="108.0" y1="718.4" x2="108.0" y2="761.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="103.5" y="740.0" width="9" height="2.4" fill="#c00"/>
<line x1="124.0" y1="720.8" x2="124.0" y2="749.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="119.5" y="728.0" width="9" height="14.4" fill="#188a3e"/>
<line x1="140.0" y1="696.8" x2="140.0" y2="735.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="135.5" y="704.0" width="9" height="24.0" fill="#188a3e"/>
<line x1="156.0" y1="687.2" x2="156.0" y2="711.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="151.5" y="694.4" width="9" height="9.6" fill="#188a3e"/>
<text x="156.0" y="779.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">1</text>
<line x1="172.0" y1="687.2" x2="172.0" y2="716.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="167.5" y="694.4" width="9" height="14.4" fill="#c00"/>
<text x="172.0" y="779.6" fill="#c00" text-anchor="middle" style="font-weight:bold">2</text>
<line x1="188.0" y1="672.8" x2="188.0" y2="716.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="183.5" y="680.0" width="9" height="28.8" fill="#188a3e"/>
<text x="188.0" y="779.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">3</text>
<line x1="204.0" y1="672.8" x2="204.0" y2="706.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="199.5" y="680.0" width="9" height="19.2" fill="#c00"/>
<text x="204.0" y="779.6" fill="#c00" text-anchor="middle" style="font-weight:bold">4</text>
<line x1="220.0" y1="663.2" x2="220.0" y2="706.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="215.5" y="670.4" width="9" height="28.8" fill="#188a3e"/>
<text x="220.0" y="779.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">5</text>
<line x1="236.0" y1="663.2" x2="236.0" y2="692.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="231.5" y="670.4" width="9" height="14.4" fill="#c00"/>
<text x="236.0" y="779.6" fill="#c00" text-anchor="middle" style="font-weight:bold">6</text>
<line x1="252.0" y1="658.4" x2="252.0" y2="692.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="247.5" y="665.6" width="9" height="19.2" fill="#188a3e"/>
<text x="252.0" y="779.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">7</text>
<line x1="268.0" y1="658.4" x2="268.0" y2="696.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="263.5" y="665.6" width="9" height="24.0" fill="#c00"/>
<text x="268.0" y="779.6" fill="#c00" text-anchor="middle" style="font-weight:bold">8</text>
<text x="108.0" y="775.6" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="278.0" y="672.8" fill="#555" text-anchor="start" style="font-weight:bold">a 8-a candelă: nici TP, nici SL</text>
<text x="278.0" y="687.2" fill="#555" text-anchor="start" style="font-weight:bold">→ ieși la 50.70 = +0.25R</text>
<text x="24" y="816" fill="#555">Barele de după intrare sunt construite. Regulile: 13_strategia_3_byh.md:196-213.</text>
</svg>

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -0,0 +1,114 @@
#!/usr/bin/env python3
"""Buy Doji — locația: doji la nivel vs. doji în aer (exemplu construit).
Citește `gen/strategii/buy_doji_locatie.spec.txt`. Două panouri alăturate cu
ACEEAȘI serie de 10 bare, pe aceeași scară și aceeași axă de preț (candelele
stau la aceleași y). Stânga: pivot monthly S1 49.00, la 0,41 % sub low-ul
dojiului. Dreapta: S1 46.00 și PP 53.50 — cel mai apropiat nivel sub doji e
la 6,96 %. Nivelurile se desenează de mână, cu coordonate absolute (liniile
din Chart pornesc mereu de la x=24, ar trece peste panoul vecin).
Rulare: python3 gen/strategii/buy_doji_locatie.py
"""
import re
import sys
sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Chart, Mark, from_closes # noqa: E402
OUT = "/workspace/atm-curs-dl/gen/strategii/buy_doji_locatie.svg"
CLOSES = [52.20, 51.40, 50.60, 49.65, 49.60, 49.90, 50.40, 50.80, 51.10, 51.50]
wicks = [(0.15, 0.15)] * len(CLOSES)
wicks[4] = (0.45, 0.40) # doji: h 50.10 / l 49.20
cds = from_closes(CLOSES, wicks=wicks, start=53.00)
doji = cds[4]
S1_DA, S1_NU, PP_NU = 49.00, 46.00, 53.50
NIVELURI_NU = [S1_NU, PP_NU]
# --- assert-urile din spec ---------------------------------------------------
for i in range(1, len(cds)): # 1
assert cds[i].o == cds[i - 1].c, f"open[{i}] != close[{i-1}]"
assert abs(doji.h - 50.10) < 1e-9 and abs(doji.l - 49.20) < 1e-9
assert abs(doji.o - doji.c) <= 0.10 * (doji.h - doji.l), "bara 4 nu e doji"
assert cds[6].c > doji.h, "bara 6 nu confirmă"
d_da = round((doji.l - S1_DA) / S1_DA * 100, 2) # 2
assert d_da == 0.41 and d_da <= 2
d_nu = round((doji.l - S1_NU) / S1_NU * 100, 2) # 3
assert d_nu == 6.96 and d_nu > 2 and (PP_NU - doji.h) > 0
assert not any(S1_NU < p < PP_NU for p in NIVELURI_NU)
d_pp = round((PP_NU - doji.l) / doji.l * 100, 2) # PP e deasupra, mai departe
assert d_pp == 8.74 and d_pp > d_nu
# --- layout: două panouri, aceeași axă --------------------------------------
BLUE, GREEN, RED, ORANGE, GREY = "#1a5fb4", "#188a3e", "#c00", "#b06000", "#555"
W, PW = 760, 350 # lățime totală, lățime panou
PX = [24, 24 + PW + 28] # x-ul stâng al fiecărui panou
SCALE, TOP = 36.0, 96 # px/unitate și y-ul celui mai mare preț
charts = []
for px in PX:
ch = Chart(candles=cds, marks=[Mark(4, "doji", ORANGE, "above", dy=-16),
Mark(6, "confirmare", GREEN, "above", dy=-26)],
scale=SCALE, gap=17, body_w=10, left=px + 34, width=px + PW, top=TOP)
body = ch.render()
charts.append((ch, body.split(">", 1)[1].rsplit("</svg>", 1)[0].strip()))
(ch_da, body_da), (ch_nu, body_nu) = charts
assert ch_da.scale == ch_nu.scale and ch_da._pmax == ch_nu._pmax, "scări diferite" # 4
y = ch_da._y # axa e comună: același y pe ambele panouri
def level(px, price, text, color):
yy = y(price)
return [f'<line x1="{px}" y1="{yy:.1f}" x2="{px + PW}" y2="{yy:.1f}" stroke="{color}" '
f'stroke-width="1.5" stroke-dasharray="4 3"/>',
f'<text x="{px + PW - 4}" y="{yy - 6:.1f}" fill="{color}" text-anchor="end">{text}</text>']
def arrow(x, y1, y2, color): # săgeată dublă verticală între y1 și y2
return [f'<line x1="{x:.1f}" y1="{y1:.1f}" x2="{x:.1f}" y2="{y2:.1f}" stroke="{color}" stroke-width="1.5"/>',
f'<polygon points="{x - 4:.1f},{y1 + 7:.1f} {x + 4:.1f},{y1 + 7:.1f} {x:.1f},{y1:.1f}" fill="{color}"/>',
f'<polygon points="{x - 4:.1f},{y2 - 7:.1f} {x + 4:.1f},{y2 - 7:.1f} {x:.1f},{y2:.1f}" fill="{color}"/>']
xd_da, xd_nu = ch_da._cx(4), ch_nu._cx(4)
y_low, y_bot = y(doji.l), y(S1_NU)
ly = y(S1_DA) + 24 # textul de distanță, sub linia 49.00
parts = [
f'<svg viewBox="0 0 {W} {y_bot + 62:.0f}" xmlns="http://www.w3.org/2000/svg" '
f'style="width:100%;height:auto;font:12px sans-serif">',
f'<text x="24" y="22" fill="#333" style="font-weight:bold">'
f'Doji la nivel vs. doji în aer — daily, pivoți monthly (exemplu construit)</text>',
f'<text x="{PX[0]}" y="48" fill="{GREEN}" style="font-weight:bold">DA — doji la nivel</text>',
f'<text x="{PX[1]}" y="48" fill="{RED}" style="font-weight:bold">NU — doji în aer</text>',
f'<line x1="{PX[1] - 14}" y1="36" x2="{PX[1] - 14}" y2="{y_bot + 8:.0f}" stroke="#ccc"/>',
*level(PX[0], S1_DA, "pivot monthly S1 49.00", BLUE),
*level(PX[1], PP_NU, "PP 53.50", BLUE),
*level(PX[1], S1_NU, "S1 46.00", BLUE),
body_da, body_nu,
# DA: low-ul dojiului atinge practic linia
f'<circle cx="{xd_da:.1f}" cy="{y_low:.1f}" r="5" fill="none" stroke="{BLUE}" stroke-width="1.5"/>',
f'<text x="{PX[0] + 8}" y="{ly:.1f}" fill="{BLUE}">low 49.20 = +0,41 % față de 49.00</text>',
f'<text x="{PX[0] + 8}" y="{ly + 16:.1f}" fill="{GREEN}" style="font-weight:bold">'
f'→ la nivel (daily: ≤ 1-2 %)</text>',
# NU: distanța până la cel mai apropiat nivel
*arrow(xd_nu, y_low + 3, y_bot - 2, RED),
f'<text x="{xd_nu + 12:.1f}" y="{(y_low + y_bot) / 2 - 8:.1f}" fill="{BLUE}">'
f'cel mai apropiat nivel: 46.00, la 6,96 %</text>',
f'<text x="{xd_nu + 12:.1f}" y="{(y_low + y_bot) / 2 + 8:.1f}" fill="{RED}" '
f'style="font-weight:bold">→ doji în aer</text>',
f'<text x="{xd_nu + 12:.1f}" y="{(y_low + y_bot) / 2 + 26:.1f}" fill="{GREY}">'
f'(PP 53.50 e deasupra, la 8,74 % de low)</text>',
f'<text x="24" y="{y_bot + 30:.0f}" fill="{GREY}">60 min: prag ≤ 0,5 %, pivoți weekly · '
f'daily: 1-2 %, pivoți monthly · weekly: pivoți quarterly</text>',
f'<text x="24" y="{y_bot + 48:.0f}" fill="{GREY}">Aceeași serie, aceeași scară; '
f'nivelurile 49.00 / 46.00 / 53.50 sunt construite.</text>',
"</svg>",
]
svg = "\n ".join(parts).replace("\n </svg>", "\n</svg>")
assert "\n\n" not in svg, "linie goală în SVG"
# nimic din panoul stâng nu trece de separator (etichete ancorate pe candele)
for m in re.finditer(r'<text x="([\d.]+)"[^>]*>(.*?)</text>', body_da):
assert float(m.group(1)) < PX[1] - 14, f"text din DA trece în NU: {m.group(2)}"
with open(OUT, "w") as f:
f.write(svg)
print(f"scris {OUT} ({W}x{y_bot + 62:.0f}); DA +{d_da}% NU {d_nu}% (PP {d_pp}%)")

View File

@@ -0,0 +1,46 @@
SPEC DIAGRAMĂ — buy_doji_locatie
================================
tip: PRET, două panouri cu ACEEAȘI serie, niveluri diferite
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 4
cheie markdown: <!-- DIAGRAMA: locatie -->
titlu SVG: „Doji la nivel vs. doji în aer — daily, pivoți monthly (exemplu construit)"
stil: candele lipite (gap 15-18, body_w 9-10), fără volum; open = close anterior.
CE TREBUIE SĂ DEMONSTREZE
-------------------------
Aceeași formă (trend → doji → confirmare), dar în stânga low-ul dojiului e
la 0,41 % de pivotul monthly (sub pragul de 1-2 % pe daily), iar în dreapta
cel mai apropiat nivel e la 6,96 % dedesubt. Pattern-ul nu te ajută să vezi
diferența; doar măsurătoarea.
SERIA (identică pe ambele panouri, 10 bare)
-------------------------------------------
Seria panoului DA din buy_doji_fereastra.spec.txt, extinsă cu 3 bare:
close-uri 52.20, 51.40, 50.60, 49.65, 49.60 (doji: o 49.65 h 50.10 l 49.20),
49.90, 50.40 (confirmare), 50.80, 51.10, 51.50; open[0] = 53.00; fitile 0.15.
NIVELURI
--------
Stânga (DA): „pivot monthly S1 49.00" (albastru), eticheta de distanță lângă
doji: „low 49.20 = +0,41 % față de 49.00 → la nivel (daily: ≤ 1-2 %)".
Dreapta (NU): „S1 46.00" jos, „PP 53.50" sus; eticheta: „cel mai apropiat
nivel: 46.00, la 6,96 % → doji în aer".
Sub ambele, text mic: „60 min: prag ≤ 0,5 %, pivoți weekly · daily: 1-2 %,
pivoți monthly · weekly: pivoți quarterly".
ASSERT-URI
----------
1. open[i] == close[i-1]; doji abs(o-c) <= 0.10*(h-l); close[6] > 50.10.
2. round((49.20-49.00)/49.00*100, 2) == 0.41 și <= 2.
3. round((49.20-46.00)/46.00*100, 2) == 6.96 și > 2; (53.50-50.10) > 0
(niciun nivel între 46.00 și 53.50 pe panoul NU).
4. Scara (px/unitate) identică pe cele două panouri (ca să se vadă că forma e
aceeași).
SURSA
-----
- Locația: summaries/03_MODUL_2/13_strategia_3_byh.md:188-190.
- Pragurile: summaries/03_MODUL_2/11_construire_scanere_sf_byd_sld.md:99-104.
- Pivoții pe TF: summaries/03_MODUL_2/11_construire_scanere_sf_byd_sld.md:63-69;
summaries/03_MODUL_2/03_timeframes_set_up.md:69-79.
- Nivelurile 49.00 / 46.00 / 53.50 sunt CONSTRUITE.

View File

@@ -0,0 +1,67 @@
<svg viewBox="0 0 760 415" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="22" fill="#333" style="font-weight:bold">Doji la nivel vs. doji în aer — daily, pivoți monthly (exemplu construit)</text>
<text x="24" y="48" fill="#188a3e" style="font-weight:bold">DA — doji la nivel</text>
<text x="402" y="48" fill="#c00" style="font-weight:bold">NU — doji în aer</text>
<line x1="388" y1="36" x2="388" y2="361" stroke="#ccc"/>
<line x1="24" y1="245.4" x2="374" y2="245.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="370" y="239.4" fill="#1a5fb4" text-anchor="end">pivot monthly S1 49.00</text>
<line x1="402" y1="83.4" x2="752" y2="83.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="748" y="77.4" fill="#1a5fb4" text-anchor="end">PP 53.50</text>
<line x1="402" y1="353.4" x2="752" y2="353.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="748" y="347.4" fill="#1a5fb4" text-anchor="end">S1 46.00</text>
<line x1="58.0" y1="96.0" x2="58.0" y2="135.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="53.0" y="101.4" width="10" height="28.8" fill="#c00"/>
<line x1="75.0" y1="124.8" x2="75.0" y2="164.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="70.0" y="130.2" width="10" height="28.8" fill="#c00"/>
<line x1="92.0" y1="153.6" x2="92.0" y2="193.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="87.0" y="159.0" width="10" height="28.8" fill="#c00"/>
<line x1="109.0" y1="182.4" x2="109.0" y2="227.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="104.0" y="187.8" width="10" height="34.2" fill="#c00"/>
<line x1="126.0" y1="205.8" x2="126.0" y2="238.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="121.0" y="222.0" width="10" height="1.8" fill="#c00"/>
<line x1="143.0" y1="207.6" x2="143.0" y2="229.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="138.0" y="213.0" width="10" height="10.8" fill="#188a3e"/>
<line x1="160.0" y1="189.6" x2="160.0" y2="218.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="155.0" y="195.0" width="10" height="18.0" fill="#188a3e"/>
<line x1="177.0" y1="175.2" x2="177.0" y2="200.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="172.0" y="180.6" width="10" height="14.4" fill="#188a3e"/>
<line x1="194.0" y1="164.4" x2="194.0" y2="186.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="189.0" y="169.8" width="10" height="10.8" fill="#188a3e"/>
<line x1="211.0" y1="150.0" x2="211.0" y2="175.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="206.0" y="155.4" width="10" height="14.4" fill="#188a3e"/>
<text x="126.0" y="179.8" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="160.0" y="153.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare</text>
<line x1="436.0" y1="96.0" x2="436.0" y2="135.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="431.0" y="101.4" width="10" height="28.8" fill="#c00"/>
<line x1="453.0" y1="124.8" x2="453.0" y2="164.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="448.0" y="130.2" width="10" height="28.8" fill="#c00"/>
<line x1="470.0" y1="153.6" x2="470.0" y2="193.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="465.0" y="159.0" width="10" height="28.8" fill="#c00"/>
<line x1="487.0" y1="182.4" x2="487.0" y2="227.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="482.0" y="187.8" width="10" height="34.2" fill="#c00"/>
<line x1="504.0" y1="205.8" x2="504.0" y2="238.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="499.0" y="222.0" width="10" height="1.8" fill="#c00"/>
<line x1="521.0" y1="207.6" x2="521.0" y2="229.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="516.0" y="213.0" width="10" height="10.8" fill="#188a3e"/>
<line x1="538.0" y1="189.6" x2="538.0" y2="218.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="533.0" y="195.0" width="10" height="18.0" fill="#188a3e"/>
<line x1="555.0" y1="175.2" x2="555.0" y2="200.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="550.0" y="180.6" width="10" height="14.4" fill="#188a3e"/>
<line x1="572.0" y1="164.4" x2="572.0" y2="186.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="567.0" y="169.8" width="10" height="10.8" fill="#188a3e"/>
<line x1="589.0" y1="150.0" x2="589.0" y2="175.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="584.0" y="155.4" width="10" height="14.4" fill="#188a3e"/>
<text x="504.0" y="179.8" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="538.0" y="153.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare</text>
<circle cx="126.0" cy="238.2" r="5" fill="none" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="32" y="269.4" fill="#1a5fb4">low 49.20 = +0,41 % față de 49.00</text>
<text x="32" y="285.4" fill="#188a3e" style="font-weight:bold">→ la nivel (daily: ≤ 1-2 %)</text>
<line x1="504.0" y1="241.2" x2="504.0" y2="351.4" stroke="#c00" stroke-width="1.5"/>
<polygon points="500.0,248.2 508.0,248.2 504.0,241.2" fill="#c00"/>
<polygon points="500.0,344.4 508.0,344.4 504.0,351.4" fill="#c00"/>
<text x="516.0" y="287.8" fill="#1a5fb4">cel mai apropiat nivel: 46.00, la 6,96 %</text>
<text x="516.0" y="303.8" fill="#c00" style="font-weight:bold">→ doji în aer</text>
<text x="516.0" y="321.8" fill="#555">(PP 53.50 e deasupra, la 8,74 % de low)</text>
<text x="24" y="383" fill="#555">60 min: prag ≤ 0,5 %, pivoți weekly · daily: 1-2 %, pivoți monthly · weekly: pivoți quarterly</text>
<text x="24" y="401" fill="#555">Aceeași serie, aceeași scară; nivelurile 49.00 / 46.00 / 53.50 sunt construite.</text>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -0,0 +1,214 @@
#!/usr/bin/env python3
"""Buy Doji — aceeași regulă pe trei perechi de timeframe-uri.
Citește `gen/strategii/buy_doji_perechi_tf.spec.txt` și scrie
`gen/strategii/buy_doji_perechi_tf.svg`. Trei rânduri (weekly→daily,
monthly→weekly, daily→60 min); pe fiecare, stânga = TF mare (11 candele,
buy doji + confirmare), dreapta = TF mic (15 candele, pullback de 8 candele
la high-ul dojiului mare, doji acolo, confirmare, intrare).
Rândul A e seria din spec; B și C se CALCULEAZĂ din A prin
p' = round(100 + f*(p - 100), 2), cu f = 2.5 și 0.4. Cifrele din desen ies
din serii, iar assert-urile le compară cu valorile afirmate în spec.
Coordonatele sunt absolute (fără <g transform>), ca audit_diagrams.py să
vadă pozițiile reale ale textelor.
Rulare: python3 gen/strategii/buy_doji_perechi_tf.py
"""
from pathlib import Path
OUT = Path(__file__).with_suffix(".svg")
W = 720
# --- seria A din spec: (open, high, low, close) ----------------------------
BIG_A = [(122.0, 122.6, 119.4, 120.0), (120.0, 120.5, 117.0, 117.5), (117.5, 119.0, 117.1, 118.4),
(118.4, 118.8, 114.3, 114.8), (114.8, 115.3, 111.5, 112.0), (112.0, 113.4, 111.6, 112.9),
(112.9, 113.2, 109.1, 109.6), (109.6, 110.0, 106.3, 106.8), (106.8, 107.2, 103.6, 104.0),
(104.0, 105.2, 101.9, 103.8), # 9: doji
(103.8, 107.4, 103.5, 107.0)] # 10: confirmare
SMALL_A = [(107.0, 107.2, 106.4, 106.6), (106.6, 106.8, 106.0, 106.1), (106.1, 106.6, 105.95, 106.4),
(106.4, 106.5, 105.8, 105.9), (105.9, 106.0, 105.5, 105.6), (105.6, 105.95, 105.5, 105.8),
(105.8, 105.9, 105.4, 105.5), (105.5, 105.6, 105.25, 105.35),
(105.35, 105.75, 105.10, 105.40), # 8: doji la nivel
(105.40, 106.40, 105.30, 106.30), # 9: confirmare => intrare
(106.3, 107.0, 106.2, 106.9), (106.9, 107.5, 106.7, 107.4), (107.4, 107.55, 107.0, 107.2),
(107.2, 108.0, 107.1, 107.9), (107.9, 108.6, 107.8, 108.5)]
def scaled(bars, f):
return [tuple(round(100 + f * (p - 100), 2) for p in b) for b in bars]
# key, f, TF mare, TF mic, text sub rând, valori așteptate din spec
ROWS = [
("A", 1.0, "weekly", "daily",
"stop {p:.2f} % (pe weekly ar fi {pb:.2f} %) · 8 candele = 8 zile de bursă",
dict(dh=105.20, dl=101.90, conf=107.00, sdl=105.10, entry=106.30, sl=105.10, risk=1.20,
pct=1.13, tp=107.50, b_entry=107.00, b_sl=101.90, b_risk=5.10, b_pct=4.77)),
("B", 2.5, "monthly", "weekly",
"stop {p:.2f} % (pe monthly ar fi {pb:.2f} %) · 8 candele = 8 săptămâni",
dict(dh=113.00, dl=104.75, conf=117.50, sdl=112.75, entry=115.75, sl=112.75, risk=3.00,
pct=2.59, tp=118.75, b_entry=117.50, b_sl=104.75, b_risk=12.75, b_pct=10.85)),
("C", 0.4, "daily", "60 min",
"stop {p:.2f} % (pe daily ar fi {pb:.2f} %) · 8 candele ≈ 1,2 zile de bursă (7 bare/zi)",
dict(dh=102.08, dl=100.76, conf=102.80, sdl=102.04, entry=102.52, sl=102.04, risk=0.48,
pct=0.47, tp=103.00, b_entry=102.80, b_sl=100.76, b_risk=2.04, b_pct=1.98)),
]
def eq(a, b):
return abs(a - b) < 0.005
def check(key, big, small, exp):
"""Assert-urile obligatorii din spec, pe seriile calculate; întoarce nivelurile."""
for name, bars in (("mare", big), ("mic", small)):
for i, (o, h, l, c) in enumerate(bars):
assert h >= max(o, c) and l <= min(o, c), f"{key} {name}[{i}] h/l incoerent"
if i:
assert eq(o, bars[i - 1][3]), f"{key} {name}[{i}] open != close precedent"
assert len(big) == 11 and len(small) == 15
assert eq(small[0][0], big[10][3]), f"{key}: open mic[0] != close mare[10]"
for name, (o, h, l, c) in (("doji mare", big[9]), ("doji mic", small[8])):
assert abs(o - c) <= 0.10 * (h - l) + 1e-9, f"{key}: {name} nu e doji"
assert big[10][3] > big[9][1] and small[9][3] > small[8][1], f"{key}: fără confirmare"
sl = min(b[2] for b in small[6:10])
assert eq(sl, small[8][2]), f"{key}: SL nu e low-ul dojiului mic"
entry = small[9][3]
risk = round(entry - sl, 2)
tp = round(entry + risk, 2)
first = next(i for i in range(10, 15) if small[i][1] >= tp - 1e-9)
assert first == 11, f"{key}: TP1 atins la {first}, nu la 11"
pct = risk / entry * 100
b_entry, b_sl = big[10][3], big[9][2]
b_risk = round(b_entry - b_sl, 2)
b_pct = b_risk / b_entry * 100
got = dict(dh=big[9][1], dl=big[9][2], conf=big[10][3], sdl=small[8][2], entry=entry, sl=sl,
risk=risk, pct=pct, tp=tp, b_entry=b_entry, b_sl=b_sl, b_risk=b_risk, b_pct=b_pct)
for k, v in exp.items():
assert eq(round(got[k], 2), v), f"{key}: {k} = {got[k]:.4f}, spec {v}"
assert abs(small[8][2] - big[9][1]) / big[9][1] <= 0.005, f"{key}: doji mic nu e la nivel"
assert 4 <= b_pct / pct <= 5, f"{key}: raport stopuri {b_pct / pct:.2f} nu e 4-5x"
return got
# --- desen ------------------------------------------------------------------
GREEN, RED, GRAY, INK = "#188a3e", "#c00", "#888", "#333"
PLOT_H = 160 # înălțimea zonei de preț, egală pe toate graficele
BX0, BGAP = 40, 16 # TF mare: x candele
SX0, SGAP = 392, 15 # TF mic
BODY_W = 9
SL_X1, SL_X2 = 380, 614 # liniile de nivel pe graficul mic
COL_X = 620 # coloana cu etichetele de nivel ale graficului mic
out = []
def text(x, y, s, fill=INK, anchor="start", bold=False, size=None):
st = []
if bold:
st.append("font-weight:bold")
if size:
st.append(f"font-size:{size}px")
style = f' style="{";".join(st)}"' if st else ""
a = f' text-anchor="{anchor}"' if anchor != "start" else ""
out.append(f'<text x="{x:.1f}" y="{y:.1f}" fill="{fill}"{a}{style}>{s}</text>')
def hline(x1, x2, y, color, dash):
out.append(f'<line x1="{x1:.1f}" y1="{y:.1f}" x2="{x2:.1f}" y2="{y:.1f}" '
f'stroke="{color}" stroke-width="1.5" stroke-dasharray="{dash}"/>')
def candles(bars, x0, gap, yf):
for i, (o, h, l, c) in enumerate(bars):
cx = x0 + i * gap
color = GREEN if c >= o else RED
out.append(f'<line x1="{cx:.1f}" y1="{yf(h):.1f}" x2="{cx:.1f}" y2="{yf(l):.1f}" '
f'stroke="#1a1a1a" stroke-width="1.2"/>')
top = yf(max(o, c))
hh = max(yf(min(o, c)) - top, 1.6)
out.append(f'<rect x="{cx - BODY_W / 2:.1f}" y="{top:.1f}" width="{BODY_W}" '
f'height="{hh:.1f}" fill="{color}"/>')
out.append('<defs><marker id="pt-arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" '
'markerHeight="7" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker></defs>')
text(20, 22, "Aceeași regulă pe trei perechi — exemplu construit (fără ticker)", bold=True, size=14)
y0 = 40
ROW_H = 290
for key, f, tf_big, tf_small, cap, exp in ROWS:
big, small = scaled(BIG_A, f), scaled(SMALL_A, f)
g = check(key, big, small, exp)
# titlu rând + subtitluri
text(20, y0 + 14, f"{key}. {tf_big} → {tf_small}", bold=True, size=13)
text(BX0 - 16, y0 + 32, f"{tf_big}: direcția", fill="#555")
text(SL_X1, y0 + 32, f"{tf_small}: intrarea", fill="#555")
top = y0 + 50
# scară proprie pe fiecare grafic, constantă în interiorul lui
bmax = max(b[1] for b in big); bmin = min(b[2] for b in big)
smax = max(b[1] for b in small); smin = min(b[2] for b in small)
bs, ss = PLOT_H / (bmax - bmin), PLOT_H / (smax - smin)
yb = lambda p, t=top, m=bmax, s=bs: t + (m - p) * s # noqa: E731
ys = lambda p, t=top, m=smax, s=ss: t + (m - p) * s # noqa: E731
# TF mare
hline(BX0 - 16, BX0 + 10 * BGAP + 12, yb(g["dh"]), GRAY, "3 3")
text(BX0 - 14, yb(g["dh"]) + 14, f"high doji {tf_big} {g['dh']:.2f}", fill="#666")
candles(big, BX0, BGAP, yb)
text(BX0 + 9 * BGAP, yb(g["dl"]) + 15, "doji", fill="#b06000", anchor="middle", bold=True)
text(BX0 + 10 * BGAP - 4, yb(big[10][2]) + 15, "confirmare: long permis",
fill=GREEN, bold=True)
# zoom: de la close-ul confirmării mari la open-ul primei bare mici (același preț)
x1, y1 = BX0 + 10 * BGAP + 8, yb(g["conf"])
x2, y2 = SX0 - 10, ys(g["conf"])
out.append(f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{x2:.1f}" y2="{y2:.1f}" stroke="#555" '
f'stroke-width="1.3" stroke-dasharray="5 3" marker-end="url(#pt-arr)"/>')
text(300, y1 + 2, f"zoom pe {tf_small},", fill="#555")
text(300, y1 + 16, "după confirmare", fill="#555")
# TF mic: niveluri
y_dh, y_e, y_sl, y_tp = ys(g["dh"]), ys(g["entry"]), ys(g["sl"]), ys(g["tp"])
assert abs((y_sl - y_e) / (y_e - y_tp) - 1) < 1e-6, f"{key}: SL-intrare != intrare-TP1 în px"
hline(SL_X1, SL_X2, y_dh, GRAY, "3 3")
hline(SL_X1, SL_X2, y_e, GREEN, "6 3")
hline(SL_X1, SL_X2, y_sl, RED, "6 3")
hline(SL_X1, SL_X2, y_tp, GREEN, "2 3")
text(COL_X, y_tp + 4, f"TP1 1:1 {g['tp']:.2f}", fill=GREEN, size=11)
text(COL_X, y_e + 4, f"intrare {g['entry']:.2f}", fill=GREEN, size=11)
text(COL_X, y_dh - 5, f"high doji {g['dh']:.2f}", fill="#666", size=11)
text(COL_X, y_sl + 12, f"SL {g['sl']:.2f}", fill=RED, size=11)
text(COL_X, y_sl + 25, "= low 4 candele", fill=RED, size=11)
candles(small, SX0, SGAP, ys)
# paranteză peste pullback-ul de 8 candele (barele 0..7)
yb8 = y_tp - 12
xa, xb = SX0 - 5, SX0 + 7 * SGAP + 5
out.append(f'<path d="M{xa:.1f},{yb8 + 6:.1f} V{yb8:.1f} H{xb:.1f} V{yb8 + 6:.1f}" '
f'fill="none" stroke="#555" stroke-width="1"/>')
text((xa + xb) / 2, yb8 - 5, "pullback: 8 candele", fill="#555", anchor="middle")
text(SX0 + 8 * SGAP + 4, y_sl + 15, "doji la nivel", fill="#b06000", anchor="end", bold=True)
text(SX0 + 9 * SGAP - 8, y_e - 5, "intrare", fill=GREEN, anchor="end", bold=True)
# text sub rând
text(20, top + PLOT_H + 50, cap.format(p=g["pct"], pb=g["b_pct"]), fill=INK, bold=True)
print(f"{key}: doji mare {g['dh']:.2f}/{g['dl']:.2f} conf {g['conf']:.2f} | intrare {g['entry']:.2f} "
f"SL {g['sl']:.2f} risc {g['risk']:.2f} ({g['pct']:.2f} %) TP1 {g['tp']:.2f} | "
f"doar mare: risc {g['b_risk']:.2f} ({g['b_pct']:.2f} %)")
y0 += ROW_H
if key != "C":
out.append(f'<line x1="20" y1="{y0 - 14:.0f}" x2="{W - 20}" y2="{y0 - 14:.0f}" stroke="#ddd"/>')
text(20, y0 + 4, "Cifre construite, aceeași formă scalată pe trei perechi.", fill="#555")
text(20, y0 + 21, "Procentele reale depind de simbol (LABU daily: stop 9 %).", fill="#555")
H = y0 + 32
svg = (f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/svg" '
f'style="width:100%;height:auto;font:12px sans-serif">\n ' + "\n ".join(out) + "\n</svg>")
assert "\n\n" not in svg
OUT.write_text(svg, encoding="utf-8")
print(f"scris {OUT} ({W}x{H:.0f})")

View File

@@ -0,0 +1,103 @@
SPEC DIAGRAMĂ — buy_doji_perechi_tf
====================================
tip: PRET (trei rânduri, câte două grafice pe rând)
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 2 („Alegi perechea…")
cheie markdown: <!-- DIAGRAMA: perechi_tf -->
generator: gen/strategii/buy_doji_perechi_tf.py (de scris de agentul de diagrame)
titlu SVG: „Aceeași regulă pe trei perechi — exemplu construit (fără ticker)"
stil: STYLE.md §„Cum trebuie să arate un grafic de preț": candele lipite
(gap 15-18, body_w 9-10), fără volum, open = close-ul precedentului.
Un singur SVG, 3 rânduri stivuite vertical (lățime 720, mobil).
Pe fiecare rând: stânga = TF mare (11 candele), dreapta = TF mic
(15 candele). Scară proprie pe fiecare grafic, dar UNA singură pe
tot graficul (px/unitate constant în interiorul lui).
CE TREBUIE SĂ DEMONSTREZE
-------------------------
1. Regula e identică pe toate trei perechile: TF mare dă buy doji confirmat
(direcția: long permis), TF mic face pullback de 8 candele până la high-ul
dojiului mare, face un doji acolo, confirmă, intri.
2. Ce se schimbă când cobori: stopul pe TF mic e de 4-5 ori mai mic decât
stopul pe TF mare pentru același setup; „8 candele" înseamnă alt timp.
3. Săgeată/paranteză „zoom" de la ultima candelă a graficului mare spre
graficul mic: graficul mic începe după confirmarea de pe TF mare.
SERIA — rândul A (weekly → daily), f = 1.0
------------------------------------------
TF mare (weekly), (open, high, low, close), index 0-10:
0 (122.0,122.6,119.4,120.0) 1 (120.0,120.5,117.0,117.5) 2 (117.5,119.0,117.1,118.4)
3 (118.4,118.8,114.3,114.8) 4 (114.8,115.3,111.5,112.0) 5 (112.0,113.4,111.6,112.9)
6 (112.9,113.2,109.1,109.6) 7 (109.6,110.0,106.3,106.8) 8 (106.8,107.2,103.6,104.0)
9 (104.0,105.2,101.9,103.8) <- doji weekly
10 (103.8,107.4,103.5,107.0) <- confirmare (close 107.0 > high doji 105.2)
TF mic (daily), index 0-14 (open[0] = 107.0 = close-ul barei mari 10):
0 (107.0,107.2,106.4,106.6) 1 (106.6,106.8,106.0,106.1) 2 (106.1,106.6,105.95,106.4)
3 (106.4,106.5,105.8,105.9) 4 (105.9,106.0,105.5,105.6) 5 (105.6,105.95,105.5,105.8)
6 (105.8,105.9,105.4,105.5) 7 (105.5,105.6,105.25,105.35)
8 (105.35,105.75,105.10,105.40) <- doji daily, low-ul atinge nivelul 105.20
9 (105.40,106.40,105.30,106.30) <- confirmare => intrare 106.30
10 (106.3,107.0,106.2,106.9) 11 (106.9,107.5,106.7,107.4) 12 (107.4,107.55,107.0,107.2)
13 (107.2,108.0,107.1,107.9) 14 (107.9,108.6,107.8,108.5)
SERIA — rândul B (monthly → weekly) și rândul C (daily → 60 min)
----------------------------------------------------------------
Aceeași formă, scalată: p' = round(100 + f*(p - 100), 2), cu f = 2.5 (B) și
f = 0.4 (C), aplicat pe fiecare o/h/l/c din rândul A. Generatorul calculează
seriile, NU le copiază de mână. Valorile care rezultă (de verificat cu assert):
B: doji mare h 113.00 / l 104.75; confirmare mare close 117.50;
doji mic l 112.75; intrare 115.75; SL 112.75; risc 3.00 (2.59 %); TP1 118.75
doar pe TF mare: intrare 117.50, SL 104.75, risc 12.75 (10.85 %)
C: doji mare h 102.08 / l 100.76; confirmare mare close 102.80;
doji mic l 102.04; intrare 102.52; SL 102.04; risc 0.48 (0.47 %); TP1 103.00
doar pe TF mare: intrare 102.80, SL 100.76, risc 2.04 (1.98 %)
A (pentru comparație): intrare 106.30; SL 105.10; risc 1.20 (1.13 %); TP1 107.50
doar pe TF mare: intrare 107.00, SL 101.90, risc 5.10 (4.77 %)
NIVELURI (pe fiecare rând)
--------------------------
Pe graficul mare: linie punctată gri la high-ul dojiului mare („high doji
weekly 105.20" / „high doji monthly 113.00" / „high doji daily 102.08").
Pe graficul mic: aceeași linie (nivelul la care se oprește pullback-ul);
intrare verde; SL roșu; TP1 verde punctat.
ETICHETE
--------
Titlu rând: A „weekly → daily" B „monthly → weekly" C „daily → 60 min"
Pe graficul mare: Mark(9, "doji"), Mark(10, "confirmare: long permis").
Pe graficul mic: Mark(8, "doji la nivel"), Mark(9, "intrare"),
Level SL „SL = low 4 candele", Level TP „TP1 1:1".
Sub fiecare rând, un text de o linie:
A: „stop 1.13 % (pe weekly ar fi 4.77 %) · 8 candele = 8 zile de bursă"
B: „stop 2.59 % (pe monthly ar fi 10.85 %) · 8 candele = 8 săptămâni"
C: „stop 0.47 % (pe daily ar fi 1.98 %) · 8 candele ≈ 1,2 zile de bursă (7 bare/zi)"
Legendă jos: „Cifre construite, aceeași formă scalată pe trei perechi.
Procentele reale depind de simbol (LABU daily: stop 9 %)."
ASSERT-URI OBLIGATORII ÎN GENERATOR
-----------------------------------
Pe fiecare rând (A, B, C), pe seriile calculate:
1. Fiecare bară: h >= max(o,c) și l <= min(o,c); open[i] == close[i-1]
(pe fiecare grafic separat).
2. open-ul primei bare mici == close-ul barei mari 10.
3. Doji mare (9) și doji mic (8): abs(o-c) <= 0.10*(h-l).
4. close mare[10] > high mare[9]; close mic[9] > high mic[8].
5. SL == min(l for bare mici 6..9) == low mic[8] (extrema ultimelor 4).
6. risc == intrare - SL; TP1 == intrare + risc; primul i>9 cu high >= TP1 este 11.
7. Valorile din lista „valori care rezultă" de mai sus, egale la 2 zecimale,
inclusiv procentele din textul de sub rând.
8. abs(low mic[8] - high mare[9]) / high mare[9] <= 0.005 (doji mic la nivel,
sub pragul cel mai strict, 0,5 %).
9. Raportul pixeli SL-intrare / intrare-TP1 == 1 pe fiecare grafic mic.
SURSA
-----
- Rolurile TF: weekly/monthly = direcția; daily = trigger de swing; 60 min
doar în direcția swing-ului de pe daily:
summaries/08_ANALIZA_ZILNICA/01_buy_doji_si_strategia_mici.md:32-40.
- Pullback-ul la high-ul dojiului ca retest ideal (MICI weekly): triaj/DECIZII.md:118
(citat în summaries/17_STRATEGII/A3_intrarea.md:245-246).
- Stopul se numără pe TF-ul deciziei: summaries/09_QA/20_2025-08-25.md:9-15.
- Perechile swing/position (60×daily, daily×weekly, weekly×monthly):
summaries/03_MODUL_2/14_strategia_1_m2d.md:461-466 (M2D, corelație).
- Seria e CONSTRUITĂ. Succesiunea „buy doji pe TF mare → buy doji pe TF mic
la pullback" e completarea capitolului, nu o procedură rostită în curs.

View File

@@ -0,0 +1,236 @@
<svg viewBox="0 0 720 942" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<defs><marker id="pt-arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker></defs>
<text x="20.0" y="22.0" fill="#333" style="font-weight:bold;font-size:14px">Aceeași regulă pe trei perechi — exemplu construit (fără ticker)</text>
<text x="20.0" y="54.0" fill="#333" style="font-weight:bold;font-size:13px">A. weekly → daily</text>
<text x="24.0" y="72.0" fill="#555">weekly: direcția</text>
<text x="380.0" y="72.0" fill="#555">daily: intrarea</text>
<line x1="24.0" y1="224.5" x2="212.0" y2="224.5" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<text x="26.0" y="238.5" fill="#666">high doji weekly 105.20</text>
<line x1="40.0" y1="90.0" x2="40.0" y2="114.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="35.5" y="94.6" width="9" height="15.5" fill="#c00"/>
<line x1="56.0" y1="106.2" x2="56.0" y2="133.3" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="51.5" y="110.1" width="9" height="19.3" fill="#c00"/>
<line x1="72.0" y1="117.8" x2="72.0" y2="132.5" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="67.5" y="122.5" width="9" height="7.0" fill="#188a3e"/>
<line x1="88.0" y1="119.4" x2="88.0" y2="154.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="83.5" y="122.5" width="9" height="27.8" fill="#c00"/>
<line x1="104.0" y1="146.4" x2="104.0" y2="175.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="99.5" y="150.3" width="9" height="21.6" fill="#c00"/>
<line x1="120.0" y1="161.1" x2="120.0" y2="175.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="115.5" y="165.0" width="9" height="7.0" fill="#188a3e"/>
<line x1="136.0" y1="162.7" x2="136.0" y2="194.3" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="131.5" y="165.0" width="9" height="25.5" fill="#c00"/>
<line x1="152.0" y1="187.4" x2="152.0" y2="216.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="147.5" y="190.5" width="9" height="21.6" fill="#c00"/>
<line x1="168.0" y1="209.0" x2="168.0" y2="236.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="163.5" y="212.1" width="9" height="21.6" fill="#c00"/>
<line x1="184.0" y1="224.5" x2="184.0" y2="250.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="179.5" y="233.8" width="9" height="1.6" fill="#c00"/>
<line x1="200.0" y1="207.5" x2="200.0" y2="237.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="195.5" y="210.6" width="9" height="24.7" fill="#188a3e"/>
<text x="184.0" y="265.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="196.0" y="252.6" fill="#188a3e" style="font-weight:bold">confirmare: long permis</text>
<line x1="208.0" y1="210.6" x2="382.0" y2="163.1" stroke="#555" stroke-width="1.3" stroke-dasharray="5 3" marker-end="url(#pt-arr)"/>
<text x="300.0" y="212.6" fill="#555">zoom pe daily,</text>
<text x="300.0" y="226.6" fill="#555">după confirmare</text>
<line x1="380.0" y1="245.4" x2="614.0" y2="245.4" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<line x1="380.0" y1="195.1" x2="614.0" y2="195.1" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="380.0" y1="250.0" x2="614.0" y2="250.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="380.0" y1="140.3" x2="614.0" y2="140.3" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/>
<text x="620.0" y="144.3" fill="#188a3e" style="font-size:11px">TP1 1:1 107.50</text>
<text x="620.0" y="199.1" fill="#188a3e" style="font-size:11px">intrare 106.30</text>
<text x="620.0" y="240.4" fill="#666" style="font-size:11px">high doji 105.20</text>
<text x="620.0" y="262.0" fill="#c00" style="font-size:11px">SL 105.10</text>
<text x="620.0" y="275.0" fill="#c00" style="font-size:11px">= low 4 candele</text>
<line x1="392.0" y1="154.0" x2="392.0" y2="190.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="387.5" y="163.1" width="9" height="18.3" fill="#c00"/>
<line x1="407.0" y1="172.3" x2="407.0" y2="208.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="402.5" y="181.4" width="9" height="22.9" fill="#c00"/>
<line x1="422.0" y1="181.4" x2="422.0" y2="211.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="417.5" y="190.6" width="9" height="13.7" fill="#188a3e"/>
<line x1="437.0" y1="186.0" x2="437.0" y2="218.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="432.5" y="190.6" width="9" height="22.9" fill="#c00"/>
<line x1="452.0" y1="208.9" x2="452.0" y2="231.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="447.5" y="213.4" width="9" height="13.7" fill="#c00"/>
<line x1="467.0" y1="211.1" x2="467.0" y2="231.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="462.5" y="218.0" width="9" height="9.1" fill="#188a3e"/>
<line x1="482.0" y1="213.4" x2="482.0" y2="236.3" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="477.5" y="218.0" width="9" height="13.7" fill="#c00"/>
<line x1="497.0" y1="227.1" x2="497.0" y2="243.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="492.5" y="231.7" width="9" height="6.9" fill="#c00"/>
<line x1="512.0" y1="220.3" x2="512.0" y2="250.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="507.5" y="236.3" width="9" height="2.3" fill="#188a3e"/>
<line x1="527.0" y1="190.6" x2="527.0" y2="240.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="522.5" y="195.1" width="9" height="41.1" fill="#188a3e"/>
<line x1="542.0" y1="163.1" x2="542.0" y2="199.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="537.5" y="167.7" width="9" height="27.4" fill="#188a3e"/>
<line x1="557.0" y1="140.3" x2="557.0" y2="176.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="552.5" y="144.9" width="9" height="22.9" fill="#188a3e"/>
<line x1="572.0" y1="138.0" x2="572.0" y2="163.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="567.5" y="144.9" width="9" height="9.1" fill="#c00"/>
<line x1="587.0" y1="117.4" x2="587.0" y2="158.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="582.5" y="122.0" width="9" height="32.0" fill="#188a3e"/>
<line x1="602.0" y1="90.0" x2="602.0" y2="126.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="597.5" y="94.6" width="9" height="27.4" fill="#188a3e"/>
<path d="M387.0,134.3 V128.3 H502.0 V134.3" fill="none" stroke="#555" stroke-width="1"/>
<text x="444.5" y="123.3" fill="#555" text-anchor="middle">pullback: 8 candele</text>
<text x="516.0" y="265.0" fill="#b06000" text-anchor="end" style="font-weight:bold">doji la nivel</text>
<text x="519.0" y="190.1" fill="#188a3e" text-anchor="end" style="font-weight:bold">intrare</text>
<text x="20.0" y="300.0" fill="#333" style="font-weight:bold">stop 1.13 % (pe weekly ar fi 4.77 %) · 8 candele = 8 zile de bursă</text>
<line x1="20" y1="316" x2="700" y2="316" stroke="#ddd"/>
<text x="20.0" y="344.0" fill="#333" style="font-weight:bold;font-size:13px">B. monthly → weekly</text>
<text x="24.0" y="362.0" fill="#555">monthly: direcția</text>
<text x="380.0" y="362.0" fill="#555">weekly: intrarea</text>
<line x1="24.0" y1="514.5" x2="212.0" y2="514.5" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<text x="26.0" y="528.5" fill="#666">high doji monthly 113.00</text>
<line x1="40.0" y1="380.0" x2="40.0" y2="404.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="35.5" y="384.6" width="9" height="15.5" fill="#c00"/>
<line x1="56.0" y1="396.2" x2="56.0" y2="423.3" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="51.5" y="400.1" width="9" height="19.3" fill="#c00"/>
<line x1="72.0" y1="407.8" x2="72.0" y2="422.5" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="67.5" y="412.5" width="9" height="7.0" fill="#188a3e"/>
<line x1="88.0" y1="409.4" x2="88.0" y2="444.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="83.5" y="412.5" width="9" height="27.8" fill="#c00"/>
<line x1="104.0" y1="436.4" x2="104.0" y2="465.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="99.5" y="440.3" width="9" height="21.6" fill="#c00"/>
<line x1="120.0" y1="451.1" x2="120.0" y2="465.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="115.5" y="455.0" width="9" height="7.0" fill="#188a3e"/>
<line x1="136.0" y1="452.7" x2="136.0" y2="484.3" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="131.5" y="455.0" width="9" height="25.5" fill="#c00"/>
<line x1="152.0" y1="477.4" x2="152.0" y2="506.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="147.5" y="480.5" width="9" height="21.6" fill="#c00"/>
<line x1="168.0" y1="499.0" x2="168.0" y2="526.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="163.5" y="502.1" width="9" height="21.6" fill="#c00"/>
<line x1="184.0" y1="514.5" x2="184.0" y2="540.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="179.5" y="523.8" width="9" height="1.6" fill="#c00"/>
<line x1="200.0" y1="497.5" x2="200.0" y2="527.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="195.5" y="500.6" width="9" height="24.7" fill="#188a3e"/>
<text x="184.0" y="555.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="196.0" y="542.6" fill="#188a3e" style="font-weight:bold">confirmare: long permis</text>
<line x1="208.0" y1="500.6" x2="382.0" y2="453.1" stroke="#555" stroke-width="1.3" stroke-dasharray="5 3" marker-end="url(#pt-arr)"/>
<text x="300.0" y="502.6" fill="#555">zoom pe weekly,</text>
<text x="300.0" y="516.6" fill="#555">după confirmare</text>
<line x1="380.0" y1="535.4" x2="614.0" y2="535.4" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<line x1="380.0" y1="485.1" x2="614.0" y2="485.1" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="380.0" y1="540.0" x2="614.0" y2="540.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="380.0" y1="430.3" x2="614.0" y2="430.3" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/>
<text x="620.0" y="434.3" fill="#188a3e" style="font-size:11px">TP1 1:1 118.75</text>
<text x="620.0" y="489.1" fill="#188a3e" style="font-size:11px">intrare 115.75</text>
<text x="620.0" y="530.4" fill="#666" style="font-size:11px">high doji 113.00</text>
<text x="620.0" y="552.0" fill="#c00" style="font-size:11px">SL 112.75</text>
<text x="620.0" y="565.0" fill="#c00" style="font-size:11px">= low 4 candele</text>
<line x1="392.0" y1="444.0" x2="392.0" y2="480.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="387.5" y="453.1" width="9" height="18.3" fill="#c00"/>
<line x1="407.0" y1="462.3" x2="407.0" y2="498.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="402.5" y="471.4" width="9" height="22.9" fill="#c00"/>
<line x1="422.0" y1="471.4" x2="422.0" y2="501.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="417.5" y="480.6" width="9" height="13.7" fill="#188a3e"/>
<line x1="437.0" y1="476.0" x2="437.0" y2="508.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="432.5" y="480.6" width="9" height="22.9" fill="#c00"/>
<line x1="452.0" y1="498.9" x2="452.0" y2="521.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="447.5" y="503.4" width="9" height="13.7" fill="#c00"/>
<line x1="467.0" y1="501.1" x2="467.0" y2="521.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="462.5" y="508.0" width="9" height="9.1" fill="#188a3e"/>
<line x1="482.0" y1="503.4" x2="482.0" y2="526.3" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="477.5" y="508.0" width="9" height="13.7" fill="#c00"/>
<line x1="497.0" y1="517.1" x2="497.0" y2="533.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="492.5" y="521.7" width="9" height="6.9" fill="#c00"/>
<line x1="512.0" y1="510.2" x2="512.0" y2="540.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="507.5" y="526.3" width="9" height="2.4" fill="#188a3e"/>
<line x1="527.0" y1="480.6" x2="527.0" y2="530.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="522.5" y="485.1" width="9" height="41.1" fill="#188a3e"/>
<line x1="542.0" y1="453.1" x2="542.0" y2="489.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="537.5" y="457.7" width="9" height="27.4" fill="#188a3e"/>
<line x1="557.0" y1="430.3" x2="557.0" y2="466.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="552.5" y="434.9" width="9" height="22.9" fill="#188a3e"/>
<line x1="572.0" y1="427.9" x2="572.0" y2="453.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="567.5" y="434.9" width="9" height="9.1" fill="#c00"/>
<line x1="587.0" y1="407.4" x2="587.0" y2="448.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="582.5" y="412.0" width="9" height="32.0" fill="#188a3e"/>
<line x1="602.0" y1="380.0" x2="602.0" y2="416.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="597.5" y="384.6" width="9" height="27.4" fill="#188a3e"/>
<path d="M387.0,424.3 V418.3 H502.0 V424.3" fill="none" stroke="#555" stroke-width="1"/>
<text x="444.5" y="413.3" fill="#555" text-anchor="middle">pullback: 8 candele</text>
<text x="516.0" y="555.0" fill="#b06000" text-anchor="end" style="font-weight:bold">doji la nivel</text>
<text x="519.0" y="480.1" fill="#188a3e" text-anchor="end" style="font-weight:bold">intrare</text>
<text x="20.0" y="590.0" fill="#333" style="font-weight:bold">stop 2.59 % (pe monthly ar fi 10.85 %) · 8 candele = 8 săptămâni</text>
<line x1="20" y1="606" x2="700" y2="606" stroke="#ddd"/>
<text x="20.0" y="634.0" fill="#333" style="font-weight:bold;font-size:13px">C. daily → 60 min</text>
<text x="24.0" y="652.0" fill="#555">daily: direcția</text>
<text x="380.0" y="652.0" fill="#555">60 min: intrarea</text>
<line x1="24.0" y1="804.5" x2="212.0" y2="804.5" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<text x="26.0" y="818.5" fill="#666">high doji daily 102.08</text>
<line x1="40.0" y1="670.0" x2="40.0" y2="694.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="35.5" y="674.6" width="9" height="15.5" fill="#c00"/>
<line x1="56.0" y1="686.2" x2="56.0" y2="713.3" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="51.5" y="690.1" width="9" height="19.3" fill="#c00"/>
<line x1="72.0" y1="697.8" x2="72.0" y2="712.5" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="67.5" y="702.5" width="9" height="7.0" fill="#188a3e"/>
<line x1="88.0" y1="699.4" x2="88.0" y2="734.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="83.5" y="702.5" width="9" height="27.8" fill="#c00"/>
<line x1="104.0" y1="726.4" x2="104.0" y2="755.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="99.5" y="730.3" width="9" height="21.6" fill="#c00"/>
<line x1="120.0" y1="741.1" x2="120.0" y2="755.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="115.5" y="745.0" width="9" height="7.0" fill="#188a3e"/>
<line x1="136.0" y1="742.7" x2="136.0" y2="774.3" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="131.5" y="745.0" width="9" height="25.5" fill="#c00"/>
<line x1="152.0" y1="767.4" x2="152.0" y2="796.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="147.5" y="770.5" width="9" height="21.6" fill="#c00"/>
<line x1="168.0" y1="789.0" x2="168.0" y2="816.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="163.5" y="792.1" width="9" height="21.6" fill="#c00"/>
<line x1="184.0" y1="804.5" x2="184.0" y2="830.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="179.5" y="813.8" width="9" height="1.6" fill="#c00"/>
<line x1="200.0" y1="787.5" x2="200.0" y2="817.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="195.5" y="790.6" width="9" height="24.7" fill="#188a3e"/>
<text x="184.0" y="845.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="196.0" y="832.6" fill="#188a3e" style="font-weight:bold">confirmare: long permis</text>
<line x1="208.0" y1="790.6" x2="382.0" y2="743.1" stroke="#555" stroke-width="1.3" stroke-dasharray="5 3" marker-end="url(#pt-arr)"/>
<text x="300.0" y="792.6" fill="#555">zoom pe 60 min,</text>
<text x="300.0" y="806.6" fill="#555">după confirmare</text>
<line x1="380.0" y1="825.4" x2="614.0" y2="825.4" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<line x1="380.0" y1="775.1" x2="614.0" y2="775.1" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="380.0" y1="830.0" x2="614.0" y2="830.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="380.0" y1="720.3" x2="614.0" y2="720.3" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/>
<text x="620.0" y="724.3" fill="#188a3e" style="font-size:11px">TP1 1:1 103.00</text>
<text x="620.0" y="779.1" fill="#188a3e" style="font-size:11px">intrare 102.52</text>
<text x="620.0" y="820.4" fill="#666" style="font-size:11px">high doji 102.08</text>
<text x="620.0" y="842.0" fill="#c00" style="font-size:11px">SL 102.04</text>
<text x="620.0" y="855.0" fill="#c00" style="font-size:11px">= low 4 candele</text>
<line x1="392.0" y1="734.0" x2="392.0" y2="770.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="387.5" y="743.1" width="9" height="18.3" fill="#c00"/>
<line x1="407.0" y1="752.3" x2="407.0" y2="788.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="402.5" y="761.4" width="9" height="22.9" fill="#c00"/>
<line x1="422.0" y1="761.4" x2="422.0" y2="791.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="417.5" y="770.6" width="9" height="13.7" fill="#188a3e"/>
<line x1="437.0" y1="766.0" x2="437.0" y2="798.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="432.5" y="770.6" width="9" height="22.9" fill="#c00"/>
<line x1="452.0" y1="788.9" x2="452.0" y2="811.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="447.5" y="793.4" width="9" height="13.7" fill="#c00"/>
<line x1="467.0" y1="791.1" x2="467.0" y2="811.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="462.5" y="798.0" width="9" height="9.1" fill="#188a3e"/>
<line x1="482.0" y1="793.4" x2="482.0" y2="816.3" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="477.5" y="798.0" width="9" height="13.7" fill="#c00"/>
<line x1="497.0" y1="807.1" x2="497.0" y2="823.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="492.5" y="811.7" width="9" height="6.9" fill="#c00"/>
<line x1="512.0" y1="800.3" x2="512.0" y2="830.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="507.5" y="816.3" width="9" height="2.3" fill="#188a3e"/>
<line x1="527.0" y1="770.6" x2="527.0" y2="820.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="522.5" y="775.1" width="9" height="41.1" fill="#188a3e"/>
<line x1="542.0" y1="743.1" x2="542.0" y2="779.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="537.5" y="747.7" width="9" height="27.4" fill="#188a3e"/>
<line x1="557.0" y1="720.3" x2="557.0" y2="756.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="552.5" y="724.9" width="9" height="22.9" fill="#188a3e"/>
<line x1="572.0" y1="718.0" x2="572.0" y2="743.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="567.5" y="724.9" width="9" height="9.1" fill="#c00"/>
<line x1="587.0" y1="697.4" x2="587.0" y2="738.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="582.5" y="702.0" width="9" height="32.0" fill="#188a3e"/>
<line x1="602.0" y1="670.0" x2="602.0" y2="706.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="597.5" y="674.6" width="9" height="27.4" fill="#188a3e"/>
<path d="M387.0,714.3 V708.3 H502.0 V714.3" fill="none" stroke="#555" stroke-width="1"/>
<text x="444.5" y="703.3" fill="#555" text-anchor="middle">pullback: 8 candele</text>
<text x="516.0" y="845.0" fill="#b06000" text-anchor="end" style="font-weight:bold">doji la nivel</text>
<text x="519.0" y="770.1" fill="#188a3e" text-anchor="end" style="font-weight:bold">intrare</text>
<text x="20.0" y="880.0" fill="#333" style="font-weight:bold">stop 0.47 % (pe daily ar fi 1.98 %) · 8 candele ≈ 1,2 zile de bursă (7 bare/zi)</text>
<text x="20.0" y="914.0" fill="#555">Cifre construite, aceeași formă scalată pe trei perechi.</text>
<text x="20.0" y="931.0" fill="#555">Procentele reale depind de simbol (LABU daily: stop 9 %).</text>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,138 @@
#!/usr/bin/env python3
"""Scanerul Buy Doji în TradeStation — ordinea filtrelor și capcanele.
Schemă conceptuală (NU grafic de preț): pâlnie de cutii tot mai înguste, de
sus în jos; în dreapta fiecărei cutii, notele și capcanele ei (roșu).
Pentru `strategii/01_buy_doji.md`, Pasul 1. Spec: `buy_doji_scaner.spec.txt`.
Fără cifre de „câte simboluri rămân" — materialul nu le dă.
Rulare: .venv/bin/python gen/strategii/buy_doji_scaner.py
"""
import html
import textwrap
from pathlib import Path
OUT = Path(__file__).resolve().parent / "buy_doji_scaner.svg"
W = 640
BLACK, GRAY, RED, BLUE, GREEN = "#000000", "#666666", "#c00", "#1a5fb4", "#188a3e"
GREEN_BG, BOX_BG = "#eef7f0", "#eef3fb"
BOX_CX = 165 # axa pâlniei (coloana stângă)
NOTE_X = 340 # începutul coloanei de note
NOTE_CHARS = 44 # wrap pentru note, la 12px
BOX_FS, NOTE_FS, LH = 13, 12, 16
WIDTHS = [300, 280, 260, 240, 220, 200]
# (linii în cutie, [(tip, text)]); tip: "n" = notă gri, "c" = capcană
BOXES = [
(["Univers:", "All Stocks (~13.000)", "S&P 500 · Russell 3000"],
[("n", "mai mare = găsește mai mult, durează mai mult")]),
(["Trigger: jbtgrshdATM", "BDATM = 0", "(Sell Doji: SDATM = 0)"],
[("c", "Interval = TF-ul scanerului, setat manual"),
("c", "0 = ultima candelă închisă; 1 = cu o zi în urmă")]),
(["Nivel: RSV1ATM", "% of PP ≤ 0.5 (60 min)", "% of PP ≤ 2 (daily)"],
[("n", "Pivot Interval: 2 = weekly (pe 60 min), 3 = monthly (pe daily)"),
("c", "RS/SR = 1 la filtrare; cu 100, pragul se scrie ×100")]),
(["Lichiditate: Volume Colors", "Average Volume ≥ 500.000",
"Average Length = 10"],
[("n", "volum daily, indiferent de TF-ul scanerului")]),
(["Opțional:", "Since Bear ≥ 8", "Bull Reversal = 1", "RVOL doar Display"],
[("c", "Bear Reversal e selectat implicit — comută pe Bull"),
("c", "în zile extreme, pragurile rigide golesc lista")]),
(["Lista de candidați", "→ o verifici pe grafic", "(pașii 2-6).",
"Scanerul nu e undă verde."], []),
]
FOOT = ("Delay: scanerul vede candela închisă — daily rulat la 12:00 "
"arată triggerul de ieri.")
def est_w(s, fs, bold=False):
return len(s) * fs * (0.60 if bold else 0.55)
def txt(x, y, s, fs, fill=BLACK, bold=False, anchor="start"):
return (f'<text x="{x:g}" y="{y:g}" font-family="system-ui, sans-serif" '
f'font-size="{fs}" font-weight="{700 if bold else 400}" fill="{fill}" '
f'text-anchor="{anchor}">{html.escape(s, quote=False)}</text>')
svg, bboxes, rects = [], [], [] # bboxes: (x0, x1, ytop, ybot, text)
def put(x, y, s, fs, fill=BLACK, bold=False, anchor="start"):
w = est_w(s, fs, bold)
x0 = x - w / 2 if anchor == "middle" else x
bboxes.append((x0, x0 + w, y - fs * 0.8, y + fs * 0.25, s))
svg.append(txt(x, y, s, fs, fill, bold, anchor))
return x0, x0 + w
put(W / 2, 30, "Scanerul Buy Doji în TradeStation", 18, bold=True, anchor="middle")
put(W / 2, 52, "ordinea filtrelor și capcanele", 13, GRAY, anchor="middle")
y = 76
for i, (lines, notes) in enumerate(BOXES):
last = i == len(BOXES) - 1
note_lines = []
for kind, s in notes:
pre = "capcană: " if kind == "c" else ""
wrapped = textwrap.wrap(pre + s, NOTE_CHARS)
note_lines.append([(kind, ln) for j, ln in enumerate(wrapped)])
n_note = sum(len(n) for n in note_lines) + max(0, len(note_lines) - 1) * 0.4
h = max(len(lines), n_note) * LH + 20
w = WIDTHS[i]
x = BOX_CX - w / 2
rects.append((x, y, w, h))
stroke, fill = (GREEN, GREEN_BG) if last else (BLUE, BOX_BG)
svg.append(f'<rect x="{x:g}" y="{y:g}" width="{w}" height="{h:g}" rx="6" '
f'fill="{fill}" stroke="{stroke}" stroke-width="{2 if last else 1.5}"/>')
ty = y + (h - len(lines) * LH) / 2 + 12
for j, ln in enumerate(lines):
x0, x1 = put(BOX_CX, ty + j * LH, ln, BOX_FS, GREEN if last else BLACK,
bold=(j == 0), anchor="middle")
assert x0 >= x + 6 and x1 <= x + w - 6, f"textul nu încape în cutia {i}: {ln!r}"
if note_lines:
assert x + w + 24 <= NOTE_X, f"cutia {i} prea aproape de note"
svg.append(f'<line x1="{x + w + 4:g}" y1="{y + h / 2:g}" x2="{NOTE_X - 8}" '
f'y2="{y + h / 2:g}" stroke="#bbbbbb" stroke-dasharray="3 3"/>')
ny = y + (h - n_note * LH) / 2 + 12
for group in note_lines:
for kind, ln in group:
put(NOTE_X, ny, ln, NOTE_FS, RED if kind == "c" else GRAY)
ny += LH
ny += 0.4 * LH
y += h
if not last:
svg.append(f'<path d="M {BOX_CX - 8} {y + 4:g} L {BOX_CX + 8} {y + 4:g} '
f'L {BOX_CX} {y + 14:g} Z" fill="{BLUE}"/>')
y += 18
y += 30
for j, ln in enumerate(textwrap.wrap(FOOT, 88)):
put(20, y + j * LH, ln, 12.5, BLACK)
H = int(y + LH + 20)
# ------------------------------------------------------------------ verificare
assert all(a > b for a, b in zip(WIDTHS, WIDTHS[1:])), "lățimile nu scad strict"
assert all(r1[2] > r2[2] for r1, r2 in zip(rects, rects[1:]))
for x0, x1, t, b, s in bboxes:
assert 0 <= x0 and x1 <= W and 0 <= t and b <= H, f"text în afara viewBox: {s!r}"
for a in range(len(bboxes)):
for b in range(a + 1, len(bboxes)):
p, q = bboxes[a], bboxes[b]
assert not (p[0] < q[1] and q[0] < p[1] and p[2] < q[3] and q[2] < p[3]), \
f"texte suprapuse: {p[4]!r} / {q[4]!r}"
for x0, x1, t, b, s in bboxes: # notele nu intră în cutii
if x0 >= NOTE_X - 1:
assert all(x0 > rx + rw for rx, _, rw, _ in rects), f"notă peste cutie: {s!r}"
out = "\n".join([
f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" width="{W}" '
f'height="{H}" role="img" aria-label="Scanerul Buy Doji în TradeStation — '
f'ordinea filtrelor și capcanele">',
f'<rect x="0" y="0" width="{W}" height="{H}" fill="#ffffff"/>',
*svg, "</svg>"]) + "\n"
assert "\n\n" not in out and not any(not ln.strip() for ln in out.splitlines()), "linie goală"
OUT.write_text(out, encoding="utf-8")
print(f"scris {OUT} ({W}x{H}), verificare OK")

View File

@@ -0,0 +1,47 @@
SPEC DIAGRAMĂ — buy_doji_scaner
===============================
tip: SCHEMĂ (fără candele): pâlnie de filtre, de sus în jos
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 1
cheie markdown: <!-- DIAGRAMA: scaner -->
titlu SVG: „Scanerul Buy Doji în TradeStation — ordinea filtrelor și capcanele"
stil: cutii dreptunghiulare stivuite, tot mai înguste (pâlnie), lățime 640;
în dreapta fiecărei cutii, o notă roșie „capcană" unde există.
Fără cifre de „câte simboluri rămân" — materialul nu le dă.
CUTIILE (text exact, de sus în jos)
-----------------------------------
1. „Univers: All Stocks (~13.000) · S&P 500 · Russell 3000"
notă gri: „mai mare = găsește mai mult, durează mai mult"
2. „Trigger: jbtgrshdATM → BDATM = 0 (Sell Doji: SDATM = 0)"
capcană: „Interval = TF-ul scanerului, setat manual"
capcană: „0 = ultima candelă închisă; 1 = cu o zi în urmă"
3. „Nivel: RSV1ATM → % of PP ≤ 0.5 (60 min) / ≤ 2 (daily)"
notă: „Pivot Interval: 2 = weekly (pe 60 min), 3 = monthly (pe daily)"
capcană: „RS/SR = 1 la filtrare; cu 100, pragul se scrie ×100"
4. „Lichiditate: Volume Colors → Average Volume ≥ 500.000, Average Length = 10"
notă: „volum daily, indiferent de TF-ul scanerului"
5. „Opțional: Since Bear ≥ 8 · Bull Reversal = 1 · RVOL doar Display"
capcană: „Bear Reversal e selectat implicit — comută pe Bull"
capcană: „în zile extreme, pragurile rigide golesc lista"
6. (cutie verde, cea mai îngustă) „Lista de candidați → o verifici pe grafic
(pașii 2-6). Scanerul nu e undă verde."
Sub pâlnie, o linie: „Delay: scanerul vede candela închisă — daily rulat la
12:00 arată triggerul de ieri."
ASSERT-URI
----------
1. Fiecare cutie e mai îngustă decât cea de deasupra (lățimi strict descrescătoare).
2. Niciun text nu iese din viewBox (bbox text în interiorul SVG-ului) și nicio
notă nu se suprapune cu alta (verificare pe bbox-uri, nu din ochi).
3. Fără linie goală în SVG.
SURSA
-----
- Univers și durată: summaries/03_MODUL_2/11_construire_scanere_sf_byd_sld.md:53-57.
- Trigger, Interval, Load Additional Data: :58-62; „= 0": summaries/09_QA/28_2025-05-27.md:47-52.
- RSV1ATM, Pivot Interval: :63-69; praguri :99-104; RS/SR: :80-97 și
summaries/04_MODUL_3/01_filtre_scaner_bull_bear_reversal_pp.md:329-341.
- Volum: :70-73. Since Bear: summaries/09_QA/28_2025-05-27.md:37-46.
- Bull/Bear Reversal, RVOL: summaries/04_MODUL_3/01_filtre_scaner_bull_bear_reversal_pp.md:19-28,
implicit Bear :343-346; praguri rigide :303-327.
- Delay: summaries/03_MODUL_2/11_construire_scanere_sf_byd_sld.md:321-324.

View File

@@ -0,0 +1,57 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 723" width="640" height="723" role="img" aria-label="Scanerul Buy Doji în TradeStation — ordinea filtrelor și capcanele">
<rect x="0" y="0" width="640" height="723" fill="#ffffff"/>
<text x="320" y="30" font-family="system-ui, sans-serif" font-size="18" font-weight="700" fill="#000000" text-anchor="middle">Scanerul Buy Doji în TradeStation</text>
<text x="320" y="52" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#666666" text-anchor="middle">ordinea filtrelor și capcanele</text>
<rect x="15" y="76" width="300" height="68" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="165" y="98" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Univers:</text>
<text x="165" y="114" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">All Stocks (~13.000)</text>
<text x="165" y="130" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">S&amp;P 500 · Russell 3000</text>
<line x1="319" y1="110" x2="332" y2="110" stroke="#bbbbbb" stroke-dasharray="3 3"/>
<text x="340" y="106" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">mai mare = găsește mai mult, durează mai</text>
<text x="340" y="122" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">mult</text>
<path d="M 157 148 L 173 148 L 165 158 Z" fill="#1a5fb4"/>
<rect x="25" y="162" width="280" height="90.4" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="165" y="195.2" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Trigger: jbtgrshdATM</text>
<text x="165" y="211.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">BDATM = 0</text>
<text x="165" y="227.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">(Sell Doji: SDATM = 0)</text>
<line x1="309" y1="207.2" x2="332" y2="207.2" stroke="#bbbbbb" stroke-dasharray="3 3"/>
<text x="340" y="184" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: Interval = TF-ul scanerului, setat</text>
<text x="340" y="200" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">manual</text>
<text x="340" y="222.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: 0 = ultima candelă închisă; 1 = cu</text>
<text x="340" y="238.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">o zi în urmă</text>
<path d="M 157 256.4 L 173 256.4 L 165 266.4 Z" fill="#1a5fb4"/>
<rect x="35" y="270.4" width="260" height="90.4" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="165" y="303.6" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Nivel: RSV1ATM</text>
<text x="165" y="319.6" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">% of PP ≤ 0.5 (60 min)</text>
<text x="165" y="335.6" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">% of PP ≤ 2 (daily)</text>
<line x1="299" y1="315.6" x2="332" y2="315.6" stroke="#bbbbbb" stroke-dasharray="3 3"/>
<text x="340" y="292.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">Pivot Interval: 2 = weekly (pe 60 min), 3 =</text>
<text x="340" y="308.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">monthly (pe daily)</text>
<text x="340" y="330.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: RS/SR = 1 la filtrare; cu 100,</text>
<text x="340" y="346.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">pragul se scrie ×100</text>
<path d="M 157 364.8 L 173 364.8 L 165 374.8 Z" fill="#1a5fb4"/>
<rect x="45" y="378.8" width="240" height="68" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="165" y="400.8" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Lichiditate: Volume Colors</text>
<text x="165" y="416.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Average Volume ≥ 500.000</text>
<text x="165" y="432.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Average Length = 10</text>
<line x1="289" y1="412.8" x2="332" y2="412.8" stroke="#bbbbbb" stroke-dasharray="3 3"/>
<text x="340" y="416.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">volum daily, indiferent de TF-ul scanerului</text>
<path d="M 157 450.8 L 173 450.8 L 165 460.8 Z" fill="#1a5fb4"/>
<rect x="55" y="464.8" width="220" height="90.4" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="165" y="490" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Opțional:</text>
<text x="165" y="506" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Since Bear ≥ 8</text>
<text x="165" y="522" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Bull Reversal = 1</text>
<text x="165" y="538" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">RVOL doar Display</text>
<line x1="279" y1="510" x2="332" y2="510" stroke="#bbbbbb" stroke-dasharray="3 3"/>
<text x="340" y="486.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: Bear Reversal e selectat implicit —</text>
<text x="340" y="502.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">comută pe Bull</text>
<text x="340" y="525.2" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: în zile extreme, pragurile rigide</text>
<text x="340" y="541.2" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">golesc lista</text>
<path d="M 157 559.2 L 173 559.2 L 165 569.2 Z" fill="#1a5fb4"/>
<rect x="65" y="573.2" width="200" height="84" rx="6" fill="#eef7f0" stroke="#188a3e" stroke-width="2"/>
<text x="165" y="595.2" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#188a3e" text-anchor="middle">Lista de candidați</text>
<text x="165" y="611.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#188a3e" text-anchor="middle">→ o verifici pe grafic</text>
<text x="165" y="627.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#188a3e" text-anchor="middle">(pașii 2-6).</text>
<text x="165" y="643.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#188a3e" text-anchor="middle">Scanerul nu e undă verde.</text>
<text x="20" y="687.2" font-family="system-ui, sans-serif" font-size="12.5" font-weight="400" fill="#000000" text-anchor="start">Delay: scanerul vede candela închisă — daily rulat la 12:00 arată triggerul de ieri.</text>
</svg>

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -0,0 +1,130 @@
"""Buy Doji — unde pui stopul: 4 candele înapoi, sub structură (exemplu construit).
Citește specificația `gen/strategii/buy_doji_stop.spec.txt`. Două panouri
stivuite, aceeași serie 0-14 ca buy_doji_transe (downtrend, doji 12, +1 13,
confirmare 14). Sus: numărătoarea celor 4 candele (1 = confirmarea). Jos:
același trade, stop „la ochi" 52.90 față de stopul din regulă 51.55.
"""
import re
import sys; sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Candle, Chart, Level, Mark
OUT = "/workspace/atm-curs-dl/gen/strategii/buy_doji_stop.svg"
# --- seria: barele 0-14 exact ca în buy_doji_transe.spec.txt -----------------
closes = [60.40, 59.60, 59.90, 58.80, 58.10, 58.40, 57.20, 56.30, 56.60,
55.30, 54.20, 52.40]
bars, o = [], 61.00
for c in closes: # fitile implicite 0.15 peste/sub corp
bars.append((o, max(o, c) + 0.15, min(o, c) - 0.15, c))
o = c
bars += [(52.40, 53.00, 51.60, 52.30), # 12 doji
(52.30, 52.85, 52.10, 52.60), # 13 +1
(52.60, 53.85, 52.45, 53.70)] # 14 confirmare
after = [(53.70, 53.75, 52.70, 52.90), # 15 lovește stopul la ochi
(52.90, 53.05, 52.00, 52.20), # 16 al doilea picior, higher low
(52.20, 53.40, 52.10, 53.30),
(53.30, 54.30, 53.20, 54.20),
(54.20, 55.10, 54.10, 55.00),
(55.00, 56.00, 54.90, 55.95)] # 20 TP1
full = bars + after
o_, h_, l_, c_ = (list(x) for x in zip(*full))
ENTRY, SL, OCHI, TP1, LOW4 = 53.70, 51.55, 52.90, 55.85, 51.60
# --- assert-urile din spec ---------------------------------------------------
for i in range(1, len(full)): # 1
assert abs(o_[i] - c_[i - 1]) < 1e-9, f"open[{i}] != close[{i-1}]"
for i in range(len(full)):
assert l_[i] <= min(o_[i], c_[i]) and h_[i] >= max(o_[i], c_[i]), f"bara {i}"
assert min(l_[11:15]) == min(l_[10:15]) == LOW4 # 2
assert l_.index(LOW4) == 12, "cel mai jos low nu e dojiul"
assert round(LOW4 - 0.05, 2) == SL
assert min(l_[15:21]) == 52.00 and SL < 52.00 < OCHI # 3
assert next(i for i in range(15, 21) if l_[i] <= OCHI) == 15 # 4
assert all(l_[i] > SL for i in range(15, 21))
assert next(i for i in range(15, 21) if h_[i] >= TP1) == 20 # 5
assert 52.00 > LOW4 # 6
assert round(ENTRY - OCHI, 2) == 0.80 and c_[14] == ENTRY
assert round(ENTRY + (ENTRY - SL), 2) == TP1
GREY, RED, ORANGE, GREEN, BLUE = "#555", "#c00", "#b06000", "#188a3e", "#1a5fb4"
W = 640
common: dict = dict(scale=34.0, gap=18, body_w=10, left=44, width=W)
def mk(n):
return [Candle(*b) for b in full[:n]]
# --- panoul de sus: numărătoarea ---------------------------------------------
top = Chart(
candles=mk(15),
levels=[Level(LOW4, "cel mai jos low: 51.60 (doji)", GREY, "2 2", "left"),
Level(SL, "SL 51.55", RED, "4 3")],
# fără Mark pe doji: la gap 18 eticheta calcă pe bara 11; îl numește
# paranteza de dedesubt și cercul de pe low
marks=[Mark(14, "confirmare 53.70", GREEN, "above")],
title="Unde pui stopul: 4 candele înapoi, sub structură — exemplu construit",
**common,
)
svg_top = top.render()
# numerele 4 3 2 1 + (5) sub bare, bandă de evidențiere, paranteză
yb = top._y(SL) + 18 # rândul cu numere, sub linia de SL
x = top._cx
extra_top = [
f'<rect x="{x(11) - 8:.1f}" y="{top._y(max(h_[11:15])) - 4:.1f}" '
f'width="{x(14) - x(11) + 16:.1f}" height="{yb + 6 - top._y(max(h_[11:15])):.1f}" '
f'fill="{BLUE}" opacity="0.08"/>',
f'<circle cx="{x(12):.1f}" cy="{top._y(LOW4):.1f}" r="4" fill="none" '
f'stroke="{RED}" stroke-width="1.5"/>',
]
for i, n in zip(range(11, 15), "4321"):
extra_top.append(f'<text x="{x(i):.1f}" y="{yb:.1f}" fill="{BLUE}" '
f'text-anchor="middle" style="font-weight:bold">{n}</text>')
extra_top.append(f'<text x="{x(10):.1f}" y="{yb:.1f}" fill="#999" '
f'text-anchor="middle">(5)</text>')
yp = yb + 8
extra_top.append(f'<polyline points="{x(11) - 5:.1f},{yp:.1f} {x(11) - 5:.1f},{yp + 5:.1f} '
f'{x(14) + 5:.1f},{yp + 5:.1f} {x(14) + 5:.1f},{yp:.1f}" '
f'fill="none" stroke="{BLUE}" stroke-width="1.2"/>')
extra_top.append(f'<text x="{x(14) + 14:.1f}" y="{yp + 9:.1f}" fill="{BLUE}">'
f'ultimele 4 candele (3 = doji, 1 = confirmarea)</text>')
extra_top.append(f'<text x="24" y="{yp + 28:.1f}" fill="#555">'
f'Cu 4 sau cu 5 candele iese la fel: în downtrend low-ul dojiului '
f'e oricum cel mai jos. SL = 51.60 − 0.05.</text>')
h_top = yp + 40
# --- panoul de jos: același trade, două stopuri -------------------------------
bot = Chart(
candles=mk(21),
levels=[Level(TP1, "TP1 55.85", GREEN, "2 2"),
Level(ENTRY, "intrare 53.70", GREY, "4 3"),
Level(OCHI, "stop la ochi 52.90 — lovit", ORANGE, "4 3"),
Level(SL, "SL din regulă 51.55 — ținut", RED, "4 3")],
marks=[Mark(16, "al doilea picior: 52.00, higher low", BLUE, "below", dy=10),
Mark(20, "TP1", GREEN, "above")],
title="Același trade: stop la ochi (0.80 sub intrare) vs stop din regulă",
caption="Barele 15-20 și stopul la ochi sunt construite, pentru contrast.",
top=h_top + 10 + 34, # panoul de jos începe sub cel de sus, fără <g transform>
**common,
)
svg_bot = bot.render()
extra_bot = [
f'<circle cx="{bot._cx(15):.1f}" cy="{bot._y(OCHI):.1f}" r="5" fill="none" '
f'stroke="{ORANGE}" stroke-width="2"/>',
]
# header-ul (viewBox) e al panoului de jos: el conține și offset-ul celui de sus
svg = "\n ".join([
svg_bot.split(">", 1)[0] + ">",
svg_top.split(">", 1)[1].rsplit("</svg>", 1)[0].strip(), *extra_top,
f'<line x1="24" y1="{h_top + 2:.0f}" x2="{W - 14}" y2="{h_top + 2:.0f}" stroke="#ccc"/>',
svg_bot.split(">", 1)[1].rsplit("</svg>", 1)[0].strip(), *extra_bot,
]) + "\n</svg>"
H = float(re.search(r'viewBox="0 0 \d+ ([\d.]+)"', svg).group(1))
assert "<svg" in svg and "\n\n" not in svg, "linie goală în SVG"
with open(OUT, "w") as f:
f.write(svg)
print(f"scris {OUT} ({W}x{H:.0f})")

View File

@@ -0,0 +1,55 @@
SPEC DIAGRAMĂ — buy_doji_stop
=============================
tip: PRET, două panouri stivuite, aceeași serie până la bara 14
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 8 (stopul)
cheie markdown: <!-- DIAGRAMA: stop -->
titlu SVG: „Unde pui stopul: 4 candele înapoi, sub structură — exemplu construit"
stil: ca buy_doji_transe (aceleași bare 0-14, copiate sau importate).
CE TREBUIE SĂ DEMONSTREZE
-------------------------
Sus: cum numeri cele 4 candele (confirmarea și cele 3 dinainte), și de ce
în downtrend nu contează dacă numeri 4 sau 5: low-ul dojiului e oricum cel
mai jos. Jos: același trade, cu un stop pus „la ochi" (52.90, sub intrare
cu 0.80) față de stopul din regulă (51.55). Piciorul al doilea coboară la
52.00: lovește stopul la ochi, nu atinge stopul din regulă; apoi prețul
ajunge la TP1.
SERIA
-----
Barele 0-14: identice cu buy_doji_transe (downtrend, doji 12, +1 13,
confirmare 14).
Panoul de sus: doar barele 0-14 (se oprește la intrare).
Panoul de jos: barele 0-14, apoi:
15 (53.70, 53.75, 52.70, 52.90)
16 (52.90, 53.05, 52.00, 52.20) <- al doilea picior, higher low 52.00
17 (52.20, 53.40, 52.10, 53.30)
18 (53.30, 54.30, 53.20, 54.20)
19 (54.20, 55.10, 54.10, 55.00)
20 (55.00, 56.00, 54.90, 55.95) <- TP1 55.85 atins
MARKS / NIVELURI
----------------
Sus: numerotare „4 3 2 1" sub barele 11, 12, 13, 14 (1 = confirmarea);
paranteză „ultimele 4 candele"; Level 51.60 „cel mai jos low: 51.60 (doji)";
Level 51.55 roșu „SL 51.55".
Jos: Level 52.90 portocaliu „stop la ochi 52.90 — lovit"; Level 51.55 roșu
„SL din regulă 51.55 — ținut"; Level 55.85 verde punctat „TP1 55.85";
Mark(16, "al doilea picior: 52.00, higher low", below).
ASSERT-URI
----------
1. open[i] == close[i-1] pe barele 15-20; h/l cuprind o/c.
2. min(l[11:15]) == min(l[10:15]) == 51.60 (4 sau 5 candele: același rezultat).
3. min(l[15:21]) == 52.00; 52.00 < 52.90 și 52.00 > 51.55.
4. primul i>14 cu low <= 52.90 este 15; niciun low din 15-20 <= 51.55.
5. primul i>14 cu high >= 55.85 este 20.
6. 52.00 > 51.60 (al doilea picior e higher low).
SURSA
-----
- SL = extrema ultimelor 4 candele de la confirmare: summaries/03_MODUL_2/13_strategia_3_byh.md:192-193;
în practică swing low-ul: summaries/09_QA/22_2025-08-04.md:23-29.
- Stopul sub structură, nu „undeva jos"; bottom-ul mai poate face un picior:
summaries/08_ANALIZA_ZILNICA/01_buy_doji_si_strategia_mici.md:833-836.
- Stopul „la ochi" 52.90 și barele 15-20 sunt CONSTRUITE (contrast).

View File

@@ -0,0 +1,104 @@
<svg viewBox="0 0 640 883" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="48" fill="#333" style="font-weight:bold">Unde pui stopul: 4 candele înapoi, sub structură — exemplu construit</text>
<line x1="24" y1="380.7" x2="626" y2="380.7" stroke="#555" stroke-width="1.5" stroke-dasharray="2 2"/>
<text x="30" y="374.7" fill="#555">cel mai jos low: 51.60 (doji)</text>
<line x1="24" y1="382.4" x2="626" y2="382.4" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="612" y="376.4" fill="#c00" text-anchor="end">SL 51.55</text>
<line x1="44.0" y1="56.0" x2="44.0" y2="86.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="39.0" y="61.1" width="10" height="20.4" fill="#c00"/>
<line x1="62.0" y1="76.4" x2="62.0" y2="113.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="57.0" y="81.5" width="10" height="27.2" fill="#c00"/>
<line x1="80.0" y1="93.4" x2="80.0" y2="113.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="75.0" y="98.5" width="10" height="10.2" fill="#188a3e"/>
<line x1="98.0" y1="93.4" x2="98.0" y2="141.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="93.0" y="98.5" width="10" height="37.4" fill="#c00"/>
<line x1="116.0" y1="130.8" x2="116.0" y2="164.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="111.0" y="135.9" width="10" height="23.8" fill="#c00"/>
<line x1="134.0" y1="144.4" x2="134.0" y2="164.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="129.0" y="149.5" width="10" height="10.2" fill="#188a3e"/>
<line x1="152.0" y1="144.4" x2="152.0" y2="195.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="147.0" y="149.5" width="10" height="40.8" fill="#c00"/>
<line x1="170.0" y1="185.2" x2="170.0" y2="226.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="165.0" y="190.3" width="10" height="30.6" fill="#c00"/>
<line x1="188.0" y1="205.6" x2="188.0" y2="226.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="183.0" y="210.7" width="10" height="10.2" fill="#188a3e"/>
<line x1="206.0" y1="205.6" x2="206.0" y2="260.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="201.0" y="210.7" width="10" height="44.2" fill="#c00"/>
<line x1="224.0" y1="249.8" x2="224.0" y2="297.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="219.0" y="254.9" width="10" height="37.4" fill="#c00"/>
<line x1="242.0" y1="287.2" x2="242.0" y2="358.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="237.0" y="292.3" width="10" height="61.2" fill="#c00"/>
<line x1="260.0" y1="333.1" x2="260.0" y2="380.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="255.0" y="353.5" width="10" height="3.4" fill="#c00"/>
<line x1="278.0" y1="338.2" x2="278.0" y2="363.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="273.0" y="346.7" width="10" height="10.2" fill="#188a3e"/>
<line x1="296.0" y1="304.2" x2="296.0" y2="351.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="291.0" y="309.3" width="10" height="37.4" fill="#188a3e"/>
<text x="296.0" y="294.2" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare 53.70</text>
<rect x="234.0" y="283.2" width="70.0" height="119.2" fill="#1a5fb4" opacity="0.08"/>
<circle cx="260.0" cy="380.7" r="4" fill="none" stroke="#c00" stroke-width="1.5"/>
<text x="242.0" y="400.4" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">4</text>
<text x="260.0" y="400.4" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">3</text>
<text x="278.0" y="400.4" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">2</text>
<text x="296.0" y="400.4" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">1</text>
<text x="224.0" y="400.4" fill="#999" text-anchor="middle">(5)</text>
<polyline points="237.0,408.4 237.0,413.4 301.0,413.4 301.0,408.4" fill="none" stroke="#1a5fb4" stroke-width="1.2"/>
<text x="310.0" y="417.4" fill="#1a5fb4">ultimele 4 candele (3 = doji, 1 = confirmarea)</text>
<text x="24" y="436.4" fill="#555">Cu 4 sau cu 5 candele iese la fel: în downtrend low-ul dojiului e oricum cel mai jos. SL = 51.60 − 0.05.</text>
<line x1="24" y1="450" x2="626" y2="450" stroke="#ccc"/>
<text x="24" y="506" fill="#333" style="font-weight:bold">Același trade: stop la ochi (0.80 sub intrare) vs stop din regulă</text>
<line x1="24" y1="694.6" x2="626" y2="694.6" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 2"/>
<text x="612" y="688.6" fill="#188a3e" text-anchor="end">TP1 55.85</text>
<line x1="24" y1="767.7" x2="626" y2="767.7" stroke="#555" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="612" y="761.7" fill="#555" text-anchor="end">intrare 53.70</text>
<line x1="24" y1="794.9" x2="626" y2="794.9" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="612" y="788.9" fill="#b06000" text-anchor="end">stop la ochi 52.90 — lovit</text>
<line x1="24" y1="840.8" x2="626" y2="840.8" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="612" y="834.8" fill="#c00" text-anchor="end">SL din regulă 51.55 — ținut</text>
<line x1="44.0" y1="514.4" x2="44.0" y2="545.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="39.0" y="519.5" width="10" height="20.4" fill="#c00"/>
<line x1="62.0" y1="534.8" x2="62.0" y2="572.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="57.0" y="539.9" width="10" height="27.2" fill="#c00"/>
<line x1="80.0" y1="551.8" x2="80.0" y2="572.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="75.0" y="556.9" width="10" height="10.2" fill="#188a3e"/>
<line x1="98.0" y1="551.8" x2="98.0" y2="599.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="93.0" y="556.9" width="10" height="37.4" fill="#c00"/>
<line x1="116.0" y1="589.2" x2="116.0" y2="623.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="111.0" y="594.3" width="10" height="23.8" fill="#c00"/>
<line x1="134.0" y1="602.8" x2="134.0" y2="623.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="129.0" y="607.9" width="10" height="10.2" fill="#188a3e"/>
<line x1="152.0" y1="602.8" x2="152.0" y2="653.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="147.0" y="607.9" width="10" height="40.8" fill="#c00"/>
<line x1="170.0" y1="643.6" x2="170.0" y2="684.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="165.0" y="648.7" width="10" height="30.6" fill="#c00"/>
<line x1="188.0" y1="664.0" x2="188.0" y2="684.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="183.0" y="669.1" width="10" height="10.2" fill="#188a3e"/>
<line x1="206.0" y1="664.0" x2="206.0" y2="718.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="201.0" y="669.1" width="10" height="44.2" fill="#c00"/>
<line x1="224.0" y1="708.2" x2="224.0" y2="755.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="219.0" y="713.3" width="10" height="37.4" fill="#c00"/>
<line x1="242.0" y1="745.6" x2="242.0" y2="817.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="237.0" y="750.7" width="10" height="61.2" fill="#c00"/>
<line x1="260.0" y1="791.5" x2="260.0" y2="839.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="255.0" y="811.9" width="10" height="3.4" fill="#c00"/>
<line x1="278.0" y1="796.6" x2="278.0" y2="822.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="273.0" y="805.1" width="10" height="10.2" fill="#188a3e"/>
<line x1="296.0" y1="762.6" x2="296.0" y2="810.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="291.0" y="767.7" width="10" height="37.4" fill="#188a3e"/>
<line x1="314.0" y1="766.0" x2="314.0" y2="801.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="309.0" y="767.7" width="10" height="27.2" fill="#c00"/>
<line x1="332.0" y1="789.8" x2="332.0" y2="825.5" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="327.0" y="794.9" width="10" height="23.8" fill="#c00"/>
<line x1="350.0" y1="777.9" x2="350.0" y2="822.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="345.0" y="781.3" width="10" height="37.4" fill="#188a3e"/>
<line x1="368.0" y1="747.3" x2="368.0" y2="784.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="363.0" y="750.7" width="10" height="30.6" fill="#188a3e"/>
<line x1="386.0" y1="720.1" x2="386.0" y2="754.1" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="381.0" y="723.5" width="10" height="27.2" fill="#188a3e"/>
<line x1="404.0" y1="689.5" x2="404.0" y2="726.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="399.0" y="691.2" width="10" height="32.3" fill="#188a3e"/>
<text x="332.0" y="854.8" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">al doilea picior: 52.00, higher low</text>
<text x="404.0" y="679.5" fill="#188a3e" text-anchor="middle" style="font-weight:bold">TP1</text>
<text x="24" y="871" fill="#555">Barele 15-20 și stopul la ochi sunt construite, pentru contrast.</text>
<circle cx="314.0" cy="794.9" r="5" fill="none" stroke="#b06000" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@@ -0,0 +1,132 @@
"""Buy Doji — intrarea în trei tranșe (exemplu construit, doji 53.00 / 51.60).
Citește specificația `gen/strategii/buy_doji_transe.spec.txt`. Barele 0-14
sunt aceleași ca în buy_doji_stop.py. Nivelurile de 1/3 și 1/2 se calculează
din corpul candelei de confirmare, nu se scriu de mână.
"""
import re
import sys; sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Candle, Chart, Level, Mark
OUT = "/workspace/atm-curs-dl/gen/strategii/buy_doji_transe.svg"
# --- seria: barele 0-14 identice cu buy_doji_stop.py --------------------------
closes = [60.40, 59.60, 59.90, 58.80, 58.10, 58.40, 57.20, 56.30, 56.60,
55.30, 54.20, 52.40]
bars, o = [], 61.00
for c in closes: # fitile implicite 0.15 peste/sub corp
bars.append((o, max(o, c) + 0.15, min(o, c) - 0.15, c))
o = c
bars += [(52.40, 53.00, 51.60, 52.30), # 12 doji
(52.30, 52.85, 52.10, 52.60), # 13 +1
(52.60, 53.85, 52.45, 53.70), # 14 confirmare
(53.70, 53.80, 53.10, 53.45), # 15 umple 1/3 și 1/2
(53.45, 54.20, 53.35, 54.10),
(54.10, 54.85, 54.00, 54.70),
(54.70, 56.00, 54.60, 55.90)] # 18 TP1
o_, h_, l_, c_ = (list(x) for x in zip(*bars))
# --- nivelurile, calculate din corpul barei 14 ---------------------------------
op, T1 = o_[14], c_[14]
corp = T1 - op
T2, T3 = round(T1 - corp / 3, 2), round(T1 - corp / 2, 2)
MED = round((T1 + T2 + T3) / 3, 2)
SL = round(min(l_[11:15]) - 0.05, 2)
TP1 = round(T1 + (T1 - SL), 2)
# --- assert-urile din spec -----------------------------------------------------
for i in range(1, len(bars)): # 1
assert abs(o_[i] - c_[i - 1]) < 1e-9, f"open[{i}] != close[{i-1}]"
for i in range(len(bars)):
assert l_[i] <= min(o_[i], c_[i]) and h_[i] >= max(o_[i], c_[i]), f"bara {i}"
assert abs(o_[12] - c_[12]) <= 0.10 * (h_[12] - l_[12]) + 1e-9 # 2
assert c_[13] <= h_[12] < c_[14] and h_[12] == 53.00
assert min(l_[11:15]) == l_[12] == 51.60 and SL == 51.55 # 3
assert (op, T1) == (52.60, 53.70) and (T2, T3) == (53.33, 53.15) # 4
assert l_[15] <= T3 < T2 # 5
assert MED == 53.39 and round(MED - SL, 2) == 1.84 # 6
assert round(T1 - SL, 2) == 2.15
assert TP1 == 55.85 # 7
assert next(i for i in range(15, len(bars)) if h_[i] >= TP1) == 18
hi, lo = h_[14], l_[14] # 8
assert round(hi - (hi - lo) / 3, 2) == 53.38 and round((hi + lo) / 2, 2) == T3
GREY, RED, ORANGE, GREEN, BLUE = "#555", "#c00", "#b06000", "#188a3e", "#1a5fb4"
W = 780
ch = Chart(
candles=[Candle(*b) for b in bars],
levels=[Level(TP1, f"TP1 {TP1:.2f} = 1R de la close", GREEN, "2 2"),
Level(SL, f"SL {SL:.2f} (low 4 candele 51.60, minus 5 cenți)", RED, "4 3")],
marks=[Mark(14, f"confirmare {T1:.2f}", GREEN, "above", dy=-38)],
title="Intrarea în trei tranșe — daily, exemplu construit (doji 53.00 / 51.60)",
scale=58.0, gap=18, body_w=10, left=44, width=W,
)
svg = ch.render()
y, x = ch._y, ch._cx
ex = []
# linia de ghidaj de la confirmare la eticheta ei (eticheta stă sus, peste bara 17)
ex.append(f'<line x1="{x(14):.1f}" y1="{y(h_[14]) - 3:.1f}" x2="{x(14):.1f}" '
f'y2="{y(h_[14]) - 44:.1f}" stroke="{GREEN}" stroke-width="1"/>')
# cele trei tranșe: linii de la bara 13 până la paranteza corpului
XB = 404 # paranteza corpului barei 14
for p, col, dash in ((T1, GREEN, ""), (T2, ORANGE, "3 3"), (T3, ORANGE, "3 3")):
d = f' stroke-dasharray="{dash}"' if dash else ""
ex.append(f'<line x1="{x(13) - 6:.1f}" y1="{y(p):.1f}" x2="{XB}" y2="{y(p):.1f}" '
f'stroke="{col}" stroke-width="1.5"{d}/>')
# paranteza: open 52.60 → close 53.70, cu diviziuni la 1/3 și 1/2
ex.append(f'<line x1="{XB}" y1="{y(T1):.1f}" x2="{XB}" y2="{y(op):.1f}" '
f'stroke="{GREY}" stroke-width="1.5"/>')
ex.append(f'<line x1="{XB - 6}" y1="{y(op):.1f}" x2="{XB}" y2="{y(op):.1f}" '
f'stroke="{GREY}" stroke-width="1.5"/>')
ex.append(f'<rect x="{XB - 3}" y="{y(MED) - 3:.1f}" width="6" height="6" fill="#888" '
f'transform="rotate(45 {XB} {y(MED):.1f})"/>')
# etichetele, răsfirate la dreapta, cu linii de ghidaj
yc, XL = y((T1 + T3) / 2), 440
labels = [(T1, f"1/3 la close {T1:.2f}", GREEN, ""),
(MED, f"medie {MED:.2f} → risc {MED - SL:.2f} pe acțiune (tot la close: {T1 - SL:.2f})", "#777", "2 2"),
(T2, f"1/3 la 1/3 din corp {T2:.2f}", ORANGE, "3 3"),
(T3, f"1/3 la 1/2 din corp {T3:.2f}", ORANGE, "3 3"),
(op, f"corp: open {op:.2f} → close {T1:.2f} = {corp:.2f}", GREY, "")]
for k, (p, txt, col, dash) in enumerate(labels):
ly = yc + (k - 1.5) * 22
d = f' stroke-dasharray="{dash}"' if dash else ""
ex.append(f'<polyline points="{XB},{y(p):.1f} {XL - 6},{ly - 4:.1f}" fill="none" '
f'stroke="{col}" stroke-width="1.2"{d}/>')
ex.append(f'<text x="{XL}" y="{ly:.1f}" fill="{col}" style="font-weight:bold">{txt}</text>')
# umpleri: T1 la close-ul barei 14, T2 și T3 pe low-ul barei 15; TP1 pe bara 18
for i, p, col in ((14, T1, GREEN), (15, T2, ORANGE), (15, T3, ORANGE), (18, TP1, GREEN)):
ex.append(f'<circle cx="{x(i):.1f}" cy="{y(p):.1f}" r="3.5" fill="#fff" '
f'stroke="{col}" stroke-width="2"/>')
# etichetele de sub candele, pe rânduri (Mark "below" le-ar pune pe același rând)
yb = y(SL) + 20
rows = [(15, f"low {l_[15]:.2f}: umple T2 și T3", ORANGE),
(13, f"+1: {c_[13]:.2f}, sub high", GREY),
(12, f"doji {h_[12]:.2f} / {l_[12]:.2f}", BLUE)]
for r, (i, txt, col) in enumerate(rows):
ry = yb + 16 * r
ex.append(f'<line x1="{x(i):.1f}" y1="{y(l_[i]) + 3:.1f}" x2="{x(i):.1f}" '
f'y2="{ry - 11:.1f}" stroke="{col}" stroke-width="1" stroke-dasharray="1 2"/>')
ex.append(f'<text x="{x(i) - 4:.1f}" y="{ry:.1f}" fill="{col}" '
f'style="font-weight:bold">{txt}</text>')
# legenda, pe două rânduri
ly = yb + 16 * len(rows) + 14
ex.append(f'<text x="24" y="{ly:.0f}" fill="#555">Măsurat pe corp (open {op:.2f} → close {T1:.2f}). '
f'Măsurat pe toată candela ({lo:.2f} → {hi:.2f}), 1/3 ar fi '
f'{hi - (hi - lo) / 3:.2f}; 1/2 iese tot {(hi + lo) / 2:.2f}.</text>')
ex.append(f'<text x="24" y="{ly + 17:.0f}" fill="#555">Stopul e unul singur, pentru toată '
f'poziția. Barele 0-11 și 15-18 sunt construite.</text>')
H = ly + 17 + 12
body = svg.rsplit("</svg>", 1)[0].rstrip()
svg = "\n ".join([body, *ex]) + "\n</svg>"
svg = re.sub(r'viewBox="0 0 (\d+) [\d.]+"', rf'viewBox="0 0 \1 {H:.0f}"', svg, count=1)
assert "<svg" in svg and "\n\n" not in svg, "linie goală în SVG"
with open(OUT, "w") as f:
f.write(svg)
print(f"scris {OUT} ({W}x{H:.0f})")

View File

@@ -0,0 +1,69 @@
SPEC DIAGRAMĂ — buy_doji_transe
===============================
tip: PRET
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 7 (intrarea)
cheie markdown: <!-- DIAGRAMA: transe -->
titlu SVG: „Intrarea în trei tranșe — daily, exemplu construit (doji 53.00 / 51.60)"
stil: candele lipite (gap 15-18, body_w 9-10), fără volum;
open = close anterior, fitile implicite 0.15 peste/sub corp la barele 0-11.
CE TREBUIE SĂ DEMONSTREZE
-------------------------
Pe candela de confirmare: o treime din poziție la close (53.70), o treime
cu limit la 1/3 din corp (53.33), o treime cu limit la 1/2 (53.15). Bara de
după coboară până la 53.10 și le umple pe amândouă. Stopul e unul singur.
Prețul mediu 53.39 → risc 1.84 pe acțiune, față de 2.15 cu tot la close.
SERIA (19 bare, (o,h,l,c))
--------------------------
open[0] = 61.00; close-uri 0-11 (downtrend de 12 candele):
60.40, 59.60, 59.90, 58.80, 58.10, 58.40, 57.20, 56.30, 56.60, 55.30, 54.20, 52.40
12 doji (52.40, 53.00, 51.60, 52.30)
13 +1 (52.30, 52.85, 52.10, 52.60) close sub 53.00: încă nimic
14 confirmare (52.60, 53.85, 52.45, 53.70) close peste 53.00: Buy Doji
15 (53.70, 53.80, 53.10, 53.45) umple 1/3 și 1/2
16 (53.45, 54.20, 53.35, 54.10)
17 (54.10, 54.85, 54.00, 54.70)
18 (54.70, 56.00, 54.60, 55.90) atinge TP1 55.85 (a 4-a după intrare)
NIVELURI
--------
T1 53.70 verde „1/3 la close 53.70"
T2 53.33 portocaliu punctat „1/3 la 1/3 din corp 53.33"
T3 53.15 portocaliu punctat „1/3 la 1/2 din corp 53.15"
preț mediu 53.39 gri punctat „medie 53.39"
SL 51.55 roșu „SL 51.55 (low 4 candele 51.60, minus 5 cenți)"
TP1 55.85 verde punctat „TP1 55.85 = 1R de la close"
MARKS
-----
Mark(12, "doji 53.00 / 51.60"), Mark(13, "+1: 52.60, sub high"),
Mark(14, "confirmare 53.70"), Mark(15, "low 53.10: umple T2 și T3", below)
LEGENDĂ
-------
„Măsurat pe corp (open 52.60 → close 53.70). Măsurat pe toată candela
(52.45 → 53.85), 1/3 ar fi 53.38; 1/2 iese tot 53.15."
ASSERT-URI
----------
1. open[i] == close[i-1]; h/l cuprind o/c.
2. doji: abs(o-c) <= 0.10*(h-l); close[13] <= 53.00 < close[14].
3. min(l[11:15]) == 51.60 (low-ul dojiului e cel mai jos din 4); SL == 51.55.
4. corp = 53.70 - 52.60; round(53.70 - corp/3, 2) == 53.33; round(53.70 - corp/2, 2) == 53.15.
5. low[15] <= 53.15 (ambele limit-uri umplute).
6. round((53.70+53.33+53.15)/3, 2) == 53.39; round(53.39-51.55, 2) == 1.84;
round(53.70-51.55, 2) == 2.15.
7. TP1 == 53.70 + 2.15 == 55.85; primul i>14 cu high >= 55.85 este 18.
8. round(53.85 - (53.85-52.45)/3, 2) == 53.38; (53.85+52.45)/2 == 53.15.
SURSA
-----
- Doji 53.00/51.60, close 52.60 apoi 53.70, SL 51.55, TP1 55.85 atins la a 4-a:
summaries/08_ANALIZA_ZILNICA/01_buy_doji_si_strategia_mici.md:136-144 (exemplu construit
al sumarului; seria de aici îl redesenează cu aceleași niveluri).
- Tranșele 1/3 la close, 1/3 la 1/3, 1/3 la 1/2: summaries/09_QA/23_2025-07-29.md:206-213;
transcripts/09_Q_and_A/19_08092025.txt:1067-1073 (citat în A3_intrarea.md:276-279).
- Măsurat de la low sau de la open: summaries/09_QA/20_2025-08-25.md:178-180;
„Iei high-ul și low-ul și calculezi": summaries/09_QA/23_2025-07-29.md:210-211.
- Barele 0-11 și 15-18 sunt CONSTRUITE.

View File

@@ -0,0 +1,75 @@
<svg viewBox="0 0 780 724" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="48" fill="#333" style="font-weight:bold">Intrarea în trei tranșe — daily, exemplu construit (doji 53.00 / 51.60)</text>
<line x1="24" y1="363.4" x2="766" y2="363.4" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 2"/>
<text x="752" y="357.4" fill="#188a3e" text-anchor="end">TP1 55.85 = 1R de la close</text>
<line x1="24" y1="612.8" x2="766" y2="612.8" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="752" y="606.8" fill="#c00" text-anchor="end">SL 51.55 (low 4 candele 51.60, minus 5 cenți)</text>
<line x1="44.0" y1="56.0" x2="44.0" y2="108.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="39.0" y="64.7" width="10" height="34.8" fill="#c00"/>
<line x1="62.0" y1="90.8" x2="62.0" y2="154.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="57.0" y="99.5" width="10" height="46.4" fill="#c00"/>
<line x1="80.0" y1="119.8" x2="80.0" y2="154.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="75.0" y="128.5" width="10" height="17.4" fill="#188a3e"/>
<line x1="98.0" y1="119.8" x2="98.0" y2="201.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="93.0" y="128.5" width="10" height="63.8" fill="#c00"/>
<line x1="116.0" y1="183.6" x2="116.0" y2="241.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="111.0" y="192.3" width="10" height="40.6" fill="#c00"/>
<line x1="134.0" y1="206.8" x2="134.0" y2="241.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="129.0" y="215.5" width="10" height="17.4" fill="#188a3e"/>
<line x1="152.0" y1="206.8" x2="152.0" y2="293.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="147.0" y="215.5" width="10" height="69.6" fill="#c00"/>
<line x1="170.0" y1="276.4" x2="170.0" y2="346.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="165.0" y="285.1" width="10" height="52.2" fill="#c00"/>
<line x1="188.0" y1="311.2" x2="188.0" y2="346.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="183.0" y="319.9" width="10" height="17.4" fill="#188a3e"/>
<line x1="206.0" y1="311.2" x2="206.0" y2="404.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="201.0" y="319.9" width="10" height="75.4" fill="#c00"/>
<line x1="224.0" y1="386.6" x2="224.0" y2="467.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="219.0" y="395.3" width="10" height="63.8" fill="#c00"/>
<line x1="242.0" y1="450.4" x2="242.0" y2="572.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="237.0" y="459.1" width="10" height="104.4" fill="#c00"/>
<line x1="260.0" y1="528.7" x2="260.0" y2="609.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="255.0" y="563.5" width="10" height="5.8" fill="#c00"/>
<line x1="278.0" y1="537.4" x2="278.0" y2="580.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="273.0" y="551.9" width="10" height="17.4" fill="#188a3e"/>
<line x1="296.0" y1="479.4" x2="296.0" y2="560.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="291.0" y="488.1" width="10" height="63.8" fill="#188a3e"/>
<line x1="314.0" y1="482.3" x2="314.0" y2="522.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="309.0" y="488.1" width="10" height="14.5" fill="#c00"/>
<line x1="332.0" y1="459.1" x2="332.0" y2="508.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="327.0" y="464.9" width="10" height="37.7" fill="#188a3e"/>
<line x1="350.0" y1="421.4" x2="350.0" y2="470.7" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="345.0" y="430.1" width="10" height="34.8" fill="#188a3e"/>
<line x1="368.0" y1="354.7" x2="368.0" y2="435.9" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="363.0" y="360.5" width="10" height="69.6" fill="#188a3e"/>
<text x="296.0" y="431.4" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare 53.70</text>
<line x1="296.0" y1="476.4" x2="296.0" y2="435.4" stroke="#188a3e" stroke-width="1"/>
<line x1="272.0" y1="488.1" x2="404" y2="488.1" stroke="#188a3e" stroke-width="1.5"/>
<line x1="272.0" y1="509.6" x2="404" y2="509.6" stroke="#b06000" stroke-width="1.5" stroke-dasharray="3 3"/>
<line x1="272.0" y1="520.0" x2="404" y2="520.0" stroke="#b06000" stroke-width="1.5" stroke-dasharray="3 3"/>
<line x1="404" y1="488.1" x2="404" y2="551.9" stroke="#555" stroke-width="1.5"/>
<line x1="398" y1="551.9" x2="404" y2="551.9" stroke="#555" stroke-width="1.5"/>
<rect x="401" y="503.1" width="6" height="6" fill="#888" transform="rotate(45 404 506.1)"/>
<polyline points="404,488.1 434,467.1" fill="none" stroke="#188a3e" stroke-width="1.2"/>
<text x="440" y="471.1" fill="#188a3e" style="font-weight:bold">1/3 la close 53.70</text>
<polyline points="404,506.1 434,489.1" fill="none" stroke="#777" stroke-width="1.2" stroke-dasharray="2 2"/>
<text x="440" y="493.1" fill="#777" style="font-weight:bold">medie 53.39 → risc 1.84 pe acțiune (tot la close: 2.15)</text>
<polyline points="404,509.6 434,511.1" fill="none" stroke="#b06000" stroke-width="1.2" stroke-dasharray="3 3"/>
<text x="440" y="515.1" fill="#b06000" style="font-weight:bold">1/3 la 1/3 din corp 53.33</text>
<polyline points="404,520.0 434,533.1" fill="none" stroke="#b06000" stroke-width="1.2" stroke-dasharray="3 3"/>
<text x="440" y="537.1" fill="#b06000" style="font-weight:bold">1/3 la 1/2 din corp 53.15</text>
<polyline points="404,551.9 434,555.1" fill="none" stroke="#555" stroke-width="1.2"/>
<text x="440" y="559.1" fill="#555" style="font-weight:bold">corp: open 52.60 → close 53.70 = 1.10</text>
<circle cx="296.0" cy="488.1" r="3.5" fill="#fff" stroke="#188a3e" stroke-width="2"/>
<circle cx="314.0" cy="509.6" r="3.5" fill="#fff" stroke="#b06000" stroke-width="2"/>
<circle cx="314.0" cy="520.0" r="3.5" fill="#fff" stroke="#b06000" stroke-width="2"/>
<circle cx="368.0" cy="363.4" r="3.5" fill="#fff" stroke="#188a3e" stroke-width="2"/>
<line x1="314.0" y1="525.9" x2="314.0" y2="621.8" stroke="#b06000" stroke-width="1" stroke-dasharray="1 2"/>
<text x="310.0" y="632.8" fill="#b06000" style="font-weight:bold">low 53.10: umple T2 și T3</text>
<line x1="278.0" y1="583.9" x2="278.0" y2="637.8" stroke="#555" stroke-width="1" stroke-dasharray="1 2"/>
<text x="274.0" y="648.8" fill="#555" style="font-weight:bold">+1: 52.60, sub high</text>
<line x1="260.0" y1="612.9" x2="260.0" y2="653.8" stroke="#1a5fb4" stroke-width="1" stroke-dasharray="1 2"/>
<text x="256.0" y="664.8" fill="#1a5fb4" style="font-weight:bold">doji 53.00 / 51.60</text>
<text x="24" y="695" fill="#555">Măsurat pe corp (open 52.60 → close 53.70). Măsurat pe toată candela (52.45 → 53.85), 1/3 ar fi 53.38; 1/2 iese tot 53.15.</text>
<text x="24" y="712" fill="#555">Stopul e unul singur, pentru toată poziția. Barele 0-11 și 15-18 sunt construite.</text>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -0,0 +1,117 @@
"""Buy Doji — trendul dinaintea dojiului: 9 candele vs. 3 candele (exemplu construit).
Citește specificația `gen/strategii/buy_doji_trend.spec.txt`. Două panouri
stivuite, aceeași scară și dojiul pe aceeași verticală, ca să se compare
direct: sus downtrend de 9 candele (ideal), jos range + 3 candele (acceptat,
semnal mai slab, scannerul cu Since Bear ≥ 8 nu-l găsește). Candelele
trendului sunt numerotate sub bară, ca numărătoarea să se vadă.
"""
import re
import sys; sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Candle, Chart, Mark
OUT = "/workspace/atm-curs-dl/gen/strategii/buy_doji_trend.svg"
DOJI = (49.65, 50.10, 49.20, 49.60)
CONF = (49.60, 50.55, 49.45, 50.40)
def series(start, closes):
"""Fitile implicite 0.15 peste/sub corp; open = close anterior."""
bars, o = [], start
for c in closes:
bars.append((o, max(o, c) + 0.15, min(o, c) - 0.15, c))
o = c
return bars + [DOJI, CONF]
L = series(55.50, [55.00, 54.30, 54.60, 53.60, 52.90, 53.10, 52.00, 51.20, 50.60, 49.65])
R = series(51.40, [51.70, 51.20, 51.60, 51.10, 51.50, 51.30, 51.70, 51.40, 50.90, 50.30, 49.65])
# --- assert-urile din spec ---------------------------------------------------
for bars in (L, R): # 1
for i, (o, h, l, c) in enumerate(bars):
assert l <= min(o, c) and h >= max(o, c), f"bara {i}"
if i:
assert abs(o - bars[i - 1][3]) < 1e-9, f"open[{i}] != close[{i-1}]"
assert L[10] == R[11] == DOJI # 2
assert abs(DOJI[0] - DOJI[3]) <= 0.10 * (DOJI[1] - DOJI[2])
cL = [b[3] for b in L]; cR = [b[3] for b in R]
assert cL[9] < cL[0] - 5 and cL[9] == min(cL[0:10]) # 3
assert sum(cL[i] < cL[i - 1] for i in range(1, 10)) >= 6
assert max(cR[0:8]) - min(cR[0:8]) <= 0.60 + 1e-9 # 4
assert cR[8] > cR[9] > cR[10]
assert L[11][3] > DOJI[1] and R[12][3] > DOJI[1] and L[11][3] == 50.40 # 5
GREY, GREEN, BLUE, ORANGE, RED = "#555", "#188a3e", "#1a5fb4", "#b06000", "#c00"
W, GAP = 540, 18
common: dict = dict(scale=30.0, gap=GAP, body_w=10, width=W)
def numbers(ch, idx, color):
"""Numără candelele trendului: 1, 2, 3... sub fiecare bară."""
return [f'<text x="{ch._cx(i):.1f}" y="{ch._y(ch.candles[i].l) + 14:.1f}" fill="{color}" '
f'text-anchor="middle" style="font-weight:bold;font-size:11px">{n}</text>'
for n, i in enumerate(idx, 1)]
def bracket(ch, a, b, y, text, color):
xa, xb = ch._cx(a) - 6, ch._cx(b) + 6
return [f'<polyline points="{xa:.1f},{y + 6:.1f} {xa:.1f},{y:.1f} {xb:.1f},{y:.1f} '
f'{xb:.1f},{y + 6:.1f}" fill="none" stroke="{color}" stroke-width="1.3"/>',
f'<text x="{xb + 8:.1f}" y="{y + 4:.1f}" fill="{color}" '
f'style="font-weight:bold">{text}</text>']
def body(svg):
return svg.split(">", 1)[1].rsplit("</svg>", 1)[0].strip()
# --- panoul de sus: 9 candele ------------------------------------------------
top = Chart(candles=[Candle(*b) for b in L], left=44 + GAP, # dojiul pe aceeași verticală
marks=[Mark(10, "doji", ORANGE, "below", dy=8),
Mark(11, "confirmare 50.40", GREEN, "above")],
title="Trendul dinaintea dojiului: 9 candele vs. 3 candele — exemplu construit",
**common)
svg_top = top.render()
y_br = top._y(max(b[1] for b in L[1:10])) - 10
ext_top = numbers(top, range(1, 10), RED) + bracket(top, 1, 9, y_br, "downtrend 9 candele", RED)
y_cap1 = top._y(DOJI[2]) + 50
ext_top.append(f'<text x="24" y="{y_cap1:.1f}" fill="{GREEN}" style="font-weight:bold">'
f'DA — ideal (8-10 candele)</text>')
# --- panoul de jos: range + 3 candele ----------------------------------------
y_sep = y_cap1 + 16
bot = Chart(candles=[Candle(*b) for b in R], left=44,
marks=[Mark(11, "doji", ORANGE, "below", dy=8),
Mark(12, "confirmare 50.40", GREEN, "above")],
top=int(y_sep + 62), **common) # titlul și paranteza range-ului, desenate mai jos
svg_bot = bot.render()
y_rg = bot._y(max(b[1] for b in R[0:8])) - 10
ext_bot = (numbers(bot, range(8, 11), RED)
+ bracket(bot, 8, 10, bot._y(R[8][1]) - 10, "doar 3 candele", RED)
+ bracket(bot, 0, 7, y_rg, "", GREY)
+ [f'<text x="24" y="{y_sep + 24:.1f}" fill="#333" style="font-weight:bold">'
f'Același doji, după un range</text>',
f'<text x="{bot._cx(0) - 6:.1f}" y="{y_rg - 5:.1f}" fill="{GREY}">'
f'range: nu se numără</text>'])
y_cap2 = bot._y(DOJI[2]) + 50
ext_bot += [f'<text x="24" y="{y_cap2:.1f}" fill="{ORANGE}" style="font-weight:bold">'
f'ACCEPTAT, semnal mai slab</text>',
f'<text x="24" y="{y_cap2 + 17:.1f}" fill="{GREY}">'
f'scannerul cu Since Bear ≥ 8 nu-l vede</text>']
H = y_cap2 + 30
# dojiul e aceeași bară, la aceeași scară, în același loc pe orizontală
assert abs(top._cx(10) - bot._cx(11)) < 1e-9 and top.scale == bot.scale
svg = "\n ".join([
f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/svg" '
f'style="width:100%;height:auto;font:12px sans-serif">',
body(svg_top), *ext_top,
f'<line x1="24" y1="{y_sep:.0f}" x2="{W - 14}" y2="{y_sep:.0f}" stroke="#ccc"/>',
body(svg_bot), *ext_bot,
]) + "\n</svg>"
assert "\n\n" not in svg, "linie goală în SVG"
with open(OUT, "w") as f:
f.write(svg)
print(f"scris {OUT} ({W}x{H:.0f})")

View File

@@ -0,0 +1,52 @@
SPEC DIAGRAMĂ — buy_doji_trend
==============================
tip: PRET, două panouri alăturate (sau stivuite pe mobil)
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 3, după doji_forma
cheie markdown: <!-- DIAGRAMA: trend -->
titlu SVG: „Trendul dinaintea dojiului: 9 candele vs. 3 candele — exemplu construit"
stil: candele lipite (gap 15-18, body_w 9-10), fără volum; open = close anterior;
fitile implicite 0.15 peste/sub corp, cu excepțiile de mai jos.
CE TREBUIE SĂ DEMONSTREZE
-------------------------
Același doji (h 50.10 / l 49.20) și aceeași confirmare (close 50.40), după
două trenduri diferite. Stânga = ideal (9 candele). Dreapta = acceptat, dar
semnal mai slab (3 candele după un range) — și e cazul pe care scannerul cu
„Since Bear ≥ 8" nu-l găsește.
PANOUL STÂNGA — 12 bare
-----------------------
open[0] = 55.50; close-uri 0-9: 55.00, 54.30, 54.60, 53.60, 52.90, 53.10, 52.00,
51.20, 50.60, 49.65 (barele 1-9 = trendul de 9 candele)
10 doji (49.65, 50.10, 49.20, 49.60)
11 confirmare (49.60, 50.55, 49.45, 50.40)
Mark(1..9 paranteză, "downtrend 9 candele"), Mark(10,"doji"), Mark(11,"confirmare 50.40").
Text sub panou: „DA — ideal (8-10 candele)".
PANOUL DREAPTA — 13 bare
------------------------
open[0] = 51.40; close-uri 0-7 (range): 51.70, 51.20, 51.60, 51.10, 51.50,
51.30, 51.70, 51.40; apoi 8: 50.90, 9: 50.30, 10: 49.65 (3 candele în jos)
11 doji (49.65, 50.10, 49.20, 49.60)
12 confirmare (49.60, 50.55, 49.45, 50.40)
Mark(8..10 paranteză, "doar 3 candele"), Mark(12,"confirmare 50.40").
Text sub panou: „ACCEPTAT, semnal mai slab · scannerul cu Since Bear ≥ 8 nu-l vede".
ASSERT-URI
----------
1. open[i] == close[i-1]; h/l cuprind o/c, pe ambele panouri.
2. Doji identic pe ambele (o,h,l,c) și abs(o-c) <= 0.10*(h-l).
3. Stânga: close[9] < close[0] - 5 și close[9] == min(close[0:10]);
cel puțin 6 din barele 1..9 închid sub close-ul barei precedente.
4. Dreapta: max(close[0:8]) - min(close[0:8]) <= 0.60 (range);
close[8] > close[9] > close[10] (exact 3 candele în jos).
5. Confirmarea închide peste 50.10 pe ambele.
SURSA
-----
- 8-10 candele ideal; 2-3 candele au funcționat, semnal mai slab:
summaries/03_MODUL_2/13_strategia_3_byh.md:185-187, 315-318.
- Scannerul cu Since Bear ≥ 8 pierde trendurile scurte:
summaries/09_QA/28_2025-05-27.md:144-149; Since Bear numără de la sell
momentum, nu candele descrescătoare: :43-46.
- Seria e CONSTRUITĂ.

View File

@@ -0,0 +1,81 @@
<svg viewBox="0 0 540 536" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="48" fill="#333" style="font-weight:bold">Trendul dinaintea dojiului: 9 candele vs. 3 candele — exemplu construit</text>
<line x1="62.0" y1="56.0" x2="62.0" y2="80.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="57.0" y="60.5" width="10" height="15.0" fill="#c00"/>
<line x1="80.0" y1="71.0" x2="80.0" y2="101.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="75.0" y="75.5" width="10" height="21.0" fill="#c00"/>
<line x1="98.0" y1="83.0" x2="98.0" y2="101.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="93.0" y="87.5" width="10" height="9.0" fill="#188a3e"/>
<line x1="116.0" y1="83.0" x2="116.0" y2="122.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="111.0" y="87.5" width="10" height="30.0" fill="#c00"/>
<line x1="134.0" y1="113.0" x2="134.0" y2="143.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="129.0" y="117.5" width="10" height="21.0" fill="#c00"/>
<line x1="152.0" y1="128.0" x2="152.0" y2="143.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="147.0" y="132.5" width="10" height="6.0" fill="#188a3e"/>
<line x1="170.0" y1="128.0" x2="170.0" y2="170.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="165.0" y="132.5" width="10" height="33.0" fill="#c00"/>
<line x1="188.0" y1="161.0" x2="188.0" y2="194.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="183.0" y="165.5" width="10" height="24.0" fill="#c00"/>
<line x1="206.0" y1="185.0" x2="206.0" y2="212.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="201.0" y="189.5" width="10" height="18.0" fill="#c00"/>
<line x1="224.0" y1="203.0" x2="224.0" y2="240.5" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="219.0" y="207.5" width="10" height="28.5" fill="#c00"/>
<line x1="242.0" y1="222.5" x2="242.0" y2="249.5" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="237.0" y="236.0" width="10" height="1.6" fill="#c00"/>
<line x1="260.0" y1="209.0" x2="260.0" y2="242.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="255.0" y="213.5" width="10" height="24.0" fill="#188a3e"/>
<text x="242.0" y="263.5" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="260.0" y="199.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare 50.40</text>
<text x="80.0" y="115.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">1</text>
<text x="98.0" y="115.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">2</text>
<text x="116.0" y="136.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">3</text>
<text x="134.0" y="157.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">4</text>
<text x="152.0" y="157.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">5</text>
<text x="170.0" y="184.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">6</text>
<text x="188.0" y="208.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">7</text>
<text x="206.0" y="226.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">8</text>
<text x="224.0" y="254.5" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">9</text>
<polyline points="74.0,67.0 74.0,61.0 230.0,61.0 230.0,67.0" fill="none" stroke="#c00" stroke-width="1.3"/>
<text x="238.0" y="65.0" fill="#c00" style="font-weight:bold">downtrend 9 candele</text>
<text x="24" y="299.5" fill="#188a3e" style="font-weight:bold">DA — ideal (8-10 candele)</text>
<line x1="24" y1="315" x2="526" y2="315" stroke="#ccc"/>
<line x1="44.0" y1="377.0" x2="44.0" y2="395.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="39.0" y="381.5" width="10" height="9.0" fill="#188a3e"/>
<line x1="62.0" y1="377.0" x2="62.0" y2="401.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="57.0" y="381.5" width="10" height="15.0" fill="#c00"/>
<line x1="80.0" y1="380.0" x2="80.0" y2="401.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="75.0" y="384.5" width="10" height="12.0" fill="#188a3e"/>
<line x1="98.0" y1="380.0" x2="98.0" y2="404.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="93.0" y="384.5" width="10" height="15.0" fill="#c00"/>
<line x1="116.0" y1="383.0" x2="116.0" y2="404.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="111.0" y="387.5" width="10" height="12.0" fill="#188a3e"/>
<line x1="134.0" y1="383.0" x2="134.0" y2="398.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="129.0" y="387.5" width="10" height="6.0" fill="#c00"/>
<line x1="152.0" y1="377.0" x2="152.0" y2="398.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="147.0" y="381.5" width="10" height="12.0" fill="#188a3e"/>
<line x1="170.0" y1="377.0" x2="170.0" y2="395.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="165.0" y="381.5" width="10" height="9.0" fill="#c00"/>
<line x1="188.0" y1="386.0" x2="188.0" y2="410.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="183.0" y="390.5" width="10" height="15.0" fill="#c00"/>
<line x1="206.0" y1="401.0" x2="206.0" y2="428.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="201.0" y="405.5" width="10" height="18.0" fill="#c00"/>
<line x1="224.0" y1="419.0" x2="224.0" y2="447.5" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="219.0" y="423.5" width="10" height="19.5" fill="#c00"/>
<line x1="242.0" y1="429.5" x2="242.0" y2="456.5" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="237.0" y="443.0" width="10" height="1.6" fill="#c00"/>
<line x1="260.0" y1="416.0" x2="260.0" y2="449.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="255.0" y="420.5" width="10" height="24.0" fill="#188a3e"/>
<text x="242.0" y="470.5" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="260.0" y="406.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare 50.40</text>
<text x="188.0" y="424.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">1</text>
<text x="206.0" y="442.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">2</text>
<text x="224.0" y="461.5" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">3</text>
<polyline points="182.0,382.0 182.0,376.0 230.0,376.0 230.0,382.0" fill="none" stroke="#c00" stroke-width="1.3"/>
<text x="238.0" y="380.0" fill="#c00" style="font-weight:bold">doar 3 candele</text>
<polyline points="38.0,373.0 38.0,367.0 176.0,367.0 176.0,373.0" fill="none" stroke="#555" stroke-width="1.3"/>
<text x="184.0" y="371.0" fill="#555" style="font-weight:bold"></text>
<text x="24" y="339.5" fill="#333" style="font-weight:bold">Același doji, după un range</text>
<text x="38.0" y="362.0" fill="#555">range: nu se numără</text>
<text x="24" y="506.5" fill="#b06000" style="font-weight:bold">ACCEPTAT, semnal mai slab</text>
<text x="24" y="523.5" fill="#555">scannerul cu Since Bear ≥ 8 nu-l vede</text>
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -65,22 +65,22 @@ Fișa din care vine capitolul: <a href="fise/selectia.html"><code>fise/selectia.
<tr> <tr>
<td><strong>1.3 Trigger</strong> (DA / NU prea devreme / NU invalidat)</td> <td><strong>1.3 Trigger</strong> (DA / NU prea devreme / NU invalidat)</td>
<td><strong>1.3 Ce oprește selecția (DA/NU)</strong> — validitatea filtrului, nu intrarea</td> <td><strong>1.3 Ce oprește selecția (DA/NU)</strong> — validitatea filtrului, nu intrarea</td>
<td>un filtru nu are trigger de intrare (<code>fise/selectia.md</code>:139-147)</td> <td>un filtru nu are trigger de intrare (<code>fise/selectia.md</code>:145-153)</td>
</tr> </tr>
<tr> <tr>
<td><strong>1.4 Stop-loss</strong></td> <td><strong>1.4 Stop-loss</strong></td>
<td><strong>1.4 Ce nu are selecția</strong> — rămâne NEACOPERIT ÎN MATERIAL</td> <td><strong>1.4 Ce nu are selecția</strong> — rămâne NEACOPERIT ÎN MATERIAL</td>
<td>un filtru nu are nivel de preț care să-l invalideze (<code>fise/selectia.md</code>:156-161)</td> <td>un filtru nu are nivel de preț care să-l invalideze (<code>fise/selectia.md</code>:161-166)</td>
</tr> </tr>
<tr> <tr>
<td><strong>1.5 Take-profit și tranșe</strong></td> <td><strong>1.5 Take-profit și tranșe</strong></td>
<td>inclus în 1.4</td> <td>inclus în 1.4</td>
<td>selecția nu are ținte sau tranșe (<code>fise/selectia.md</code>:163-167)</td> <td>selecția nu are ținte sau tranșe (<code>fise/selectia.md</code>:168-172)</td>
</tr> </tr>
<tr> <tr>
<td><strong>1.6 Mărimea poziției</strong></td> <td><strong>1.6 Mărimea poziției</strong></td>
<td><strong>1.5 Uneltele și de unde citești pragurile</strong></td> <td><strong>1.5 Uneltele și de unde citești pragurile</strong></td>
<td>selecția nu riscă nimic; sizing-ul se calculează la strategia de intrare (<code>fise/selectia.md</code>:287-302)</td> <td>selecția nu riscă nimic; sizing-ul se calculează la strategia de intrare (<code>fise/selectia.md</code>:294-309)</td>
</tr> </tr>
<tr> <tr>
<td><strong>Nivel 0, diagrama de ansamblu</strong></td> <td><strong>Nivel 0, diagrama de ansamblu</strong></td>
@@ -326,9 +326,11 @@ când pe grafic apare trigger-ul de intrare.</p>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p>Materialul nu dă un prag separat pentru „sub 7": el spune „peste 7-8 intră în <p>„Peste 7-8" e ce îl interesează, dar <strong>sub 7 nu e prag de excludere</strong>: la 4/14
analiză", iar sub 7 se deduce ca excludere, fără să fie declarat prag și la 6/14 continuă analiza (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:204</code>).
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:199-204</code>). Pe commodities Scorul <strong>departajează între doi candidați</strong> — „5 din 14, ala are 13 din 14. Păi,
mai bine au AI [sic] decât MARA" (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:212-213</code>) — iar pragul exact sub care n-ar
mai analiza un simbol rămâne nespus. Pe commodities
filtrul de relative strength cade (vezi Nivel 0). Pe ETF-uri scorul nu există.</p> filtrul de relative strength cade (vezi Nivel 0). Pe ETF-uri scorul nu există.</p>
<h3 id="12-fluxul-de-filtrare-pas-cu-pas">1.2 Fluxul de filtrare, pas cu pas</h3> <h3 id="12-fluxul-de-filtrare-pas-cu-pas">1.2 Fluxul de filtrare, pas cu pas</h3>
<p>Diagrama fluxului:</p> <p>Diagrama fluxului:</p>
@@ -389,8 +391,12 @@ filtrul de relative strength cade (vezi Nivel 0). Pe ETF-uri scorul nu există.<
(<code>09_QA/28_2025-05-27.md:372-380</code>; <code>03_MODUL_2/11_construire_scanere_sf_byd_sld.md:70-73</code>). (<code>09_QA/28_2025-05-27.md:372-380</code>; <code>03_MODUL_2/11_construire_scanere_sf_byd_sld.md:70-73</code>).
Toate condițiile pe același timeframe (<code>09_QA/28_2025-05-27.md:390-391</code>).</p> Toate condițiile pe același timeframe (<code>09_QA/28_2025-05-27.md:390-391</code>).</p>
<p><strong>F1. Fundamentalul.</strong> ATM score peste <strong>7-8</strong>; <strong>12-13</strong> e prioritatea <p><strong>F1. Fundamentalul.</strong> ATM score peste <strong>7-8</strong>; <strong>12-13</strong> e prioritatea
(„spuma"); F-score <strong>6-9</strong> solid/puternic. Elimini compania pe pierdere, cu („spuma"); F-score <strong>6-9</strong> solid/puternic. Compania pe pierdere, cu cash flow
cash flow negativ sau cu venit în scădere. Un scanner fundamental de lucru: negativ sau cu venit în scădere nu e de investiție (cel mult speculă pe
momentum); trecerea din profit în pierdere <strong>nu</strong> scoate singură simbolul de pe
listă — în patru cazuri a continuat analiza, trei dintre ele cu cash flow
pozitiv (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:227-228, 248</code>;
deducție: criteriul real pare cash flow-ul). Un scanner fundamental de lucru:
„top 500 de companii cu scori [sic] fundamental peste 7 și aflate în downtrend", „top 500 de companii cu scori [sic] fundamental peste 7 și aflate în downtrend",
downtrend pe weekly (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:199-221, downtrend pe weekly (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:199-221,
225-257</code>).</p> 225-257</code>).</p>
@@ -466,8 +472,8 @@ downtrend pe weekly (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:199-221,
<text x="60.0" y="430.0" font-size="14" font-weight="bold" fill="#000000" text-anchor="start">Scor -1 = date indisponibile în platformă, NU scor 0.</text> <text x="60.0" y="430.0" font-size="14" font-weight="bold" fill="#000000" text-anchor="start">Scor -1 = date indisponibile în platformă, NU scor 0.</text>
<text x="60.0" y="450.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Scorul -1 nu se citește ca 0.</text> <text x="60.0" y="450.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Scorul -1 nu se citește ca 0.</text>
<text x="60.0" y="470.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:45-46, 268-269.</text> <text x="60.0" y="470.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:45-46, 268-269.</text>
<text x="60.0" y="498.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">„peste 7-8” e formularea exactă a cursului; sub 7 se deduce ca excludere,</text> <text x="60.0" y="498.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">„peste 7-8” e formularea exactă a cursului. Sub 7 NU e excludere:</text>
<text x="60.0" y="518.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">nu e declarat ca prag separat (11_selectia_simbolului.md:199-204).</text> <text x="60.0" y="518.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">la 4/14 și 6/14 continuă analiza; scorul departajează candidații.</text>
<text x="350.0" y="556.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">Surse: 08_ANALIZA_ZILNICA/11_selectia_simbolului.md:158-164, :199-204;</text> <text x="350.0" y="556.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">Surse: 08_ANALIZA_ZILNICA/11_selectia_simbolului.md:158-164, :199-204;</text>
<text x="350.0" y="574.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">16_ANALIZA_FUNDAMENTALA/08_piotrowski_f_score.md:70-72;</text> <text x="350.0" y="574.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">16_ANALIZA_FUNDAMENTALA/08_piotrowski_f_score.md:70-72;</text>
<text x="350.0" y="592.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:45-46, 268-269.</text> <text x="350.0" y="592.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:45-46, 268-269.</text>
@@ -537,7 +543,10 @@ Strand [sic] și vedeți cine este în cadranul 1 și cadranul 2"
</svg></p> </svg></p>
<p><strong>F5. Relative volume peste 100%.</strong> Candela de volum împărțită la media <p><strong>F5. Relative volume peste 100%.</strong> Candela de volum împărțită la media
ultimelor <strong>10</strong> candele de volum ultimelor <strong>10</strong> candele de volum
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:741-747</code>). Pragul: peste 100%.</p> (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:741-747</code>). Pragul: peste 100%.
Sub prag e un <strong>minus care se compensează, nu un stop</strong>: la 0.99, 0.96, 0.94,
0.88 și 0.74 a continuat analiza; nespus dacă intră pe trigger sub prag
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:749-751, 766-770</code>).</p>
<p><strong>F6. Stelele (Trinity).</strong> Din ce a rămas, dacă au și 3 stele, poți sorta <p><strong>F6. Stelele (Trinity).</strong> Din ce a rămas, dacă au și 3 stele, poți sorta
direct după ele (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:776-785</code>).</p> direct după ele (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:776-785</code>).</p>
<p><strong>F7. Radarscreen.</strong> Repetă fluxul pe cele max ~300 de simboluri: sectoarele <p><strong>F7. Radarscreen.</strong> Repetă fluxul pe cele max ~300 de simboluri: sectoarele
@@ -563,9 +572,9 @@ fundamental</strong>; un scor de 7 nu e motiv să-l iei dacă ai altul mai bun
<td>ATM score 12-13, cadran 1, RVOL peste 100%</td> <td>ATM score 12-13, cadran 1, RVOL peste 100%</td>
</tr> </tr>
<tr> <tr>
<td><strong>NU — fundamental</strong></td> <td><strong>NU — fundamental (ca investiție)</strong></td>
<td>Scor 2-4 sau companie pe pierdere / cash flow negativ / venit în scădere</td> <td>Scor 2 sau companie pe pierdere / cash flow negativ / venit în scădere; trecerea din profit în pierdere cu cash flow pozitiv <strong>nu</strong> intră aici</td>
<td>APG <strong>2</strong>, FLR <strong>2</strong> — respinse ca investiție (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:230-257</code>)</td> <td>APG <strong>2</strong>, FLR <strong>2</strong> — respinse ca investiție, FLR cel mult „un swing" (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:230-257</code>)</td>
</tr> </tr>
<tr> <tr>
<td><strong>NU — relativ</strong></td> <td><strong>NU — relativ</strong></td>
@@ -573,9 +582,9 @@ fundamental</strong>; un scor de 7 nu e motiv să-l iei dacă ai altul mai bun
<td>aștepți trecerea în 2 sau 1 (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:493-499</code>)</td> <td>aștepți trecerea în 2 sau 1 (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:493-499</code>)</td>
</tr> </tr>
<tr> <tr>
<td><strong>NU — volum</strong></td> <td><strong>Minus, nu NU — volum</strong></td>
<td>Relative volume sub 100% în cazurile respinse; neconfirmat ca regulă generală (nu reiese că oprește orice intrare)</td> <td>Relative volume sub 100%: minus care se compensează; nespus dacă intră pe trigger sub prag</td>
<td>0.96 respins; 0.74 respins (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:749-761</code>)</td> <td>0.99 (QRVO, „pattern interesant"), 0.96, 0.94, 0.74 — a continuat analiza (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:749-770</code>)</td>
</tr> </tr>
<tr> <tr>
<td><strong>NU — deteriorare</strong></td> <td><strong>NU — deteriorare</strong></td>
@@ -591,11 +600,11 @@ fundamental</strong>; un scor de 7 nu e motiv să-l iei dacă ai altul mai bun
rămâne MBT-10 / buy doji / MP4-1 pe grafic." rămâne MBT-10 / buy doji / MP4-1 pe grafic."
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:831-833</code>).</li> (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:831-833</code>).</li>
<li><strong>Stop-loss — NEACOPERIT ÎN MATERIAL.</strong> Un filtru nu are nivel de preț care <li><strong>Stop-loss — NEACOPERIT ÎN MATERIAL.</strong> Un filtru nu are nivel de preț care
să-l invalideze (<code>fise/selectia.md</code>:156-161).</li> să-l invalideze (<code>fise/selectia.md</code>:161-166).</li>
<li><strong>Take-profit / tranșe / trailing — NEACOPERIT ÎN MATERIAL.</strong> Se stabilesc <li><strong>Take-profit / tranșe / trailing — NEACOPERIT ÎN MATERIAL.</strong> Se stabilesc
în strategia de intrare (<code>fise/selectia.md</code>:163-167).</li> în strategia de intrare (<code>fise/selectia.md</code>:168-172).</li>
<li><strong>Mărimea poziției</strong> nu aparține selecției: ea doar alege simbolul; sizing-ul <li><strong>Mărimea poziției</strong> nu aparține selecției: ea doar alege simbolul; sizing-ul
se face pe setup-ul de intrare (<code>fise/selectia.md</code>:287-302).</li> se face pe setup-ul de intrare (<code>fise/selectia.md</code>:294-309).</li>
<li><strong>Durata ținerii</strong> — neacoperită; trimite la trigger-ul strategiei de intrare <li><strong>Durata ținerii</strong> — neacoperită; trimite la trigger-ul strategiei de intrare
(<code>fise/selectia.md</code>:43-45).</li> (<code>fise/selectia.md</code>:43-45).</li>
</ul> </ul>
@@ -663,11 +672,11 @@ fundamental</strong>; un scor de 7 nu e motiv să-l iei dacă ai altul mai bun
<h3 id="16-checklist-de-tiparit">1.6 Checklist de tipărit</h3> <h3 id="16-checklist-de-tiparit">1.6 Checklist de tipărit</h3>
<ul> <ul>
<li>[ ] Am rulat scannerul pe universul potrivit (C1) și am scos close &lt; 30-40 $ / volum mediu &lt; 500k (C2-C4).</li> <li>[ ] Am rulat scannerul pe universul potrivit (C1) și am scos close &lt; 30-40 $ / volum mediu &lt; 500k (C2-C4).</li>
<li>[ ] Am verificat scorul fundamental (ATM peste 7-8 / F-score 6-9); am respins companiile pe pierdere, cu cash flow negativ sau venit în scădere.</li> <li>[ ] Am verificat scorul fundamental (ATM peste 7-8 / F-score 6-9); scorul departajează, nu respinge automat. Companiile pe pierdere, cu cash flow negativ sau venit în scădere nu sunt de investiție; la trecerea în pierdere m-am uitat la cash flow.</li>
<li>[ ] Am numărat din ce sector vin cele mai multe semnale și am luat sectorul dominant.</li> <li>[ ] Am numărat din ce sector vin cele mai multe semnale și am luat sectorul dominant.</li>
<li>[ ] Din sector, am reținut doar simbolurile în suport/pivot (monthly/quarterly/anual) după downtrend; proximitate ≤ 3%.</li> <li>[ ] Din sector, am reținut doar simbolurile în suport/pivot (monthly/quarterly/anual) după downtrend; proximitate ≤ 3%.</li>
<li>[ ] Am verificat RS: doar cadranul 1-2. Cadranul 4 fără îmbunătățire = nu intru pe listă.</li> <li>[ ] Am verificat RS: doar cadranul 1-2. Cadranul 4 fără îmbunătățire = aștept trecerea în 2/1 sau un trigger long (MP4-1 / MBT-10).</li>
<li>[ ] Am verificat relative volume &gt; 100% (candela / media ultimelor 10).</li> <li>[ ] Am verificat relative volume &gt; 100% (candela / media ultimelor 10); dacă e sub, l-am notat ca minus, nu l-am tăiat automat.</li>
<li>[ ] Dacă e cazul, am sortat după 3 stele (Trinity).</li> <li>[ ] Dacă e cazul, am sortat după 3 stele (Trinity).</li>
<li>[ ] Între doi candidați am ales prin contrast: trend → volum → fundamental.</li> <li>[ ] Între doi candidați am ales prin contrast: trend → volum → fundamental.</li>
<li>[ ] Am notat simbolul pe listă, <strong>fără</strong> să intru: trigger-ul se caută separat pe grafic.</li> <li>[ ] Am notat simbolul pe listă, <strong>fără</strong> să intru: trigger-ul se caută separat pe grafic.</li>
@@ -789,7 +798,7 @@ la <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md</code>):</p>
<tr> <tr>
<td>Relative volume</td> <td>Relative volume</td>
<td>peste 100% (<code>:766-770</code>)</td> <td>peste 100% (<code>:766-770</code>)</td>
<td>0.96 / 0.74 — respins (<code>:769-770</code>)</td> <td>0.96 / 0.74 — minus, dar continuă analiza (<code>:769-770</code>)</td>
</tr> </tr>
<tr> <tr>
<td>Sector</td> <td>Sector</td>
@@ -826,11 +835,13 @@ la <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md</code>):</p>
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:841-846</code>; (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:841-846</code>;
<code>08_ANALIZA_ZILNICA/10_sinteza.md:564-573</code>).</li> <code>08_ANALIZA_ZILNICA/10_sinteza.md:564-573</code>).</li>
<li><strong>Cash flow pozitiv dar în scădere nu e „ok".</strong> E deteriorare; cash flow-ul <li><strong>Cash flow pozitiv dar în scădere nu e „ok".</strong> E deteriorare; cash flow-ul
pozitiv îl cauți chiar și la companiile pe pierdere pozitiv îl cauți chiar și la companiile pe pierdere. Trecerea din profit în
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:326-391, 847-850</code>).</li> pierdere nu scoate simbolul de pe listă (4 cazuri; deducție: contează
<li><strong>Sub 100% relative volume l-a făcut să respingă.</strong> 0.96 și 0.74 sunt cash flow-ul) (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:248, 326-391, 847-850</code>).</li>
respingeri, nu „aproape"; dar nu a formulat o regulă generală că sub prag <li><strong>Sub 100% relative volume e un minus, nu un veto.</strong> La 0.99, 0.96, 0.94,
oprește orice intrare (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:749-770</code>).</li> 0.88 și 0.74 a continuat analiza; „aș fi vrut să văd un relativ volume mai
mare, dar [...] ce-mi place" (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:749-770, 836-838</code>).
Nespus dacă intră pe trigger sub prag.</li>
<li><strong>Nu pune praguri rigide de RVOL în zile extreme.</strong> Pe scanerul real de Buy <li><strong>Nu pune praguri rigide de RVOL în zile extreme.</strong> Pe scanerul real de Buy
Doji, RVOL era CDNS <strong>0.86</strong>, CRM <strong>1.03</strong>, ULTA <strong>0.61</strong>; un prag fix Doji, RVOL era CDNS <strong>0.86</strong>, CRM <strong>1.03</strong>, ULTA <strong>0.61</strong>; un prag fix
<code>RVOL ≥ 1.2</code> ar fi dat zero rezultate — de aceea cursul recomandă <code>Display</code>, <code>RVOL ≥ 1.2</code> ar fi dat zero rezultate — de aceea cursul recomandă <code>Display</code>,
@@ -851,12 +862,14 @@ la <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md</code>):</p>
-0.9, tot sub MA) cu <strong>divergență bull clară</strong> și preț la suport major -0.9, tot sub MA) cu <strong>divergență bull clară</strong> și preț la suport major
(prețul coboară sub suportul de 340.00 până la 338.50, cu doji pe suport) (prețul coboară sub suportul de 340.00 până la 338.50, cu doji pe suport)
este un long valid; entry 341.00, SL 337.80, TP 349.00.</li> este un long valid; entry 341.00, SL 337.80, TP 349.00.</li>
<li><strong>Practic pentru cine decide:</strong> cele două nu se exclud complet — varianta A <li><strong>Practic pentru cine decide:</strong> alternativa pe care o dă el la cadranul 4
interzice intrarea „pe orb", varianta B cere o condiție în plus (divergență <strong>nu e divergența, e un trigger</strong>: „as astepta imbunatatire pe cadranul 4,
clară, nu doar cadranul). Dar materialul nu dă o regulă unică: nu reiese sa treaca in cadranul 2 / Sau in cadranul 1 [...] Sau un MP4,1 long, sau
dacă divergența e suficientă singură sau dacă mai trebuie și trigger-ul de poate MBT10 long" [sic] (<code>transcripts/08_ANALIZĂ_ZILNICĂ/122_23022026.txt:103-106</code>). Nicăieri nu spune că
pe grafic. Cine aplică filtrul trebuie să decidă dacă acceptă cadranul 4 + divergența singură ajunge. Și la ACN divergența vine împreună cu prețul la
divergență sau respectă strict „aștept trecerea în 2/1".</li> suport major și un doji pe suport, adică tot un setup cu trigger, nu cadranul
4 + divergență goală. Regula de lucru: în cadranul 4 intri doar după trecerea
în 2/1 sau pe un trigger long (MP4-1 / MBT-10).</li>
</ul> </ul>
<p><strong>Punct neclar terminologic — „Trinity" are două sensuri.</strong></p> <p><strong>Punct neclar terminologic — „Trinity" are două sensuri.</strong></p>
<ul> <ul>
@@ -872,26 +885,28 @@ la <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md</code>):</p>
</ul> </ul>
<p><strong>Puncte neclare (fără rezolvare în material):</strong></p> <p><strong>Puncte neclare (fără rezolvare în material):</strong></p>
<ul> <ul>
<li><strong>Cadranul 3.</strong> Sursa spune doar „cadranul 3 înseamnă îmbunătățire" și că e <li><strong>Cadranul 3 = înrăutățire; o dată spune invers.</strong> Definiția din modul:
„pentru direcție short"; nu reiese ce anume se îmbunătățește, iar „cadranul 3, care înseamnă înrăutățire [...] histogramă este deasupra linii
formularea „îmbunătățire spre underperform" e interpretarea sumarului de de 0 dar sub moving average" (<code>transcripts/03_MODUL_2/06_6_INDICATORUL_DE_PERFORMANTA.txt:6</code>),
selecție (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:858</code>: „e confirmată în practică: „in cadranul 3 se inrautateste" [sic]
interpretarea mea"), nu a cursului (<code>transcripts/08_ANALIZĂ_ZILNICĂ/122_23022026.txt:87</code>). La <code>transcripts/08_ANALIZĂ_ZILNICĂ/99_27032026.txt:89</code> spune o
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:856-859</code>).</li> dată „cadranul 3 înseamnă îmbunătățire" — scăpare verbală, contrazisă de
<li><strong>Power.</strong> Sumarul de selecție nu-l descrie, dar trimite la el ca al treilea definiție (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:439-442, 856-859</code>).</li>
indicator, alături de RS și volum <li><strong>Power — doar formula lipsește.</strong> Ce măsoară e spus: „măsoară tăria
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:860-862</code>). Definiția există trend-ului", prin histogramă + moving average, cu 4 cadrane
în <code>03_MODUL_2/09_indicatorul_power.md:3-14</code>: histogramă proprie + MA, (<code>transcripts/03_MODUL_2/09_9_INDICATORUL_POWER.txt:1, 4-12</code>;
măsoară cât de tare/susținut e trend-ul curent și distanța față de medii <code>03_MODUL_2/09_indicatorul_power.md:3-14</code>). Cum se calculează histograma nu
(overbought/oversold); cel mai rapid leading dintre cei trei.</li> e spus (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:860-862</code>).</li>
<li><strong>Ce faci sub 100% relative volume.</strong> A respins 0.96 și 0.74, dar nu a <li><strong>Relative volume sub 100%: dacă intră pe trigger.</strong> Sub prag e un minus pe
formulat o regulă generală; nu reiese dacă sub prag oprește orice intrare care îl compensează cu pattern-ul și volumul pe TF mare; nu reiese dacă a
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:863-866</code>).</li> intrat efectiv sub prag (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:866-867</code>).</li>
<li><strong>Pragul de scor de excludere</strong> rămâne nespus: „peste 7-8" e ce îl
interesează, dar la 4/14 și 6/14 continuă (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:863-865</code>).</li>
</ul> </ul>
<h3 id="25-exemplul-complet-pas-cu-pas">2.5 Exemplul complet, pas cu pas</h3> <h3 id="25-exemplul-complet-pas-cu-pas">2.5 Exemplul complet, pas cu pas</h3>
<p>Materialul nu are <strong>niciun exemplu care să ducă un singur simbol real prin <p>Materialul nu are <strong>niciun exemplu care să ducă un singur simbol real prin
tot funnel-ul</strong> (fundamental → sector → suport → RS → RVOL → Trinity) cu tot funnel-ul</strong> (fundamental → sector → suport → RS → RVOL → Trinity) cu
scoruri și niveluri complete (<code>fise/selectia.md</code>:283-285). Exemplele sunt scoruri și niveluri complete (<code>fise/selectia.md</code>:290-292). Exemplele sunt
parțiale. Mai jos, cel mai apropiat caz: <strong>ULTA</strong>, găsit de scannerul de Buy parțiale. Mai jos, cel mai apropiat caz: <strong>ULTA</strong>, găsit de scannerul de Buy
Doji + Bull Reversal, și apoi <strong>HIG</strong>, găsit de scannerul oglindă de Sell Doji + Bull Reversal, și apoi <strong>HIG</strong>, găsit de scannerul oglindă de Sell
Doji + Bear Reversal.</p> Doji + Bear Reversal.</p>
@@ -957,7 +972,7 @@ avertisment de participare.</p>
<p><svg viewBox="0 0 640 433" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <p><svg viewBox="0 0 640 433" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="16" fill="#333" style="font-weight:bold">HIG — daily (Sell Doji + Bear Reversal, RVOL 200%)</text> <text x="24" y="16" fill="#333" style="font-weight:bold">HIG — daily (Sell Doji + Bear Reversal, RVOL 200%)</text>
<line x1="24" y1="34.0" x2="626" y2="34.0" stroke="#777" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="24" y1="34.0" x2="626" y2="34.0" stroke="#777" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="30" y="28.0" fill="#777">rezistenta 84.50</text> <text x="612" y="28.0" fill="#777" text-anchor="end">rezistenta 84.50</text>
<line x1="24" y1="74.0" x2="626" y2="74.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="24" y1="74.0" x2="626" y2="74.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="612" y="68.0" fill="#c00" text-anchor="end">SL 82.00</text> <text x="612" y="68.0" fill="#c00" text-anchor="end">SL 82.00</text>
<line x1="24" y1="136.4" x2="626" y2="136.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="24" y1="136.4" x2="626" y2="136.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
@@ -1107,7 +1122,7 @@ cu trimitere; restul e extrapolare și poate fi greșit.</p>
<h3 id="pe-cont-de-prop">Pe cont de prop</h3> <h3 id="pe-cont-de-prop">Pe cont de prop</h3>
<p>Selecția în sine <strong>nu deschide poziții</strong>, deci nu atinge limita de drawdown — <p>Selecția în sine <strong>nu deschide poziții</strong>, deci nu atinge limita de drawdown —
poate rula ca prefiltru fără să contrazică nicio regulă de prop poate rula ca prefiltru fără să contrazică nicio regulă de prop
(<code>fise/selectia.md</code>:308-314). Problema pe prop nu e riscul, ci <strong>uneltele</strong>: (<code>fise/selectia.md</code>:315-321). Problema pe prop nu e riscul, ci <strong>uneltele</strong>:
ATM-Score, RS/Power/Trinity și scanerele sunt proprietare TradeStation, iar ATM-Score, RS/Power/Trinity și scanerele sunt proprietare TradeStation, iar
ATM-Score cere cont premium ATM-Score cere cont premium
(<code>16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:91-96</code>).</p> (<code>16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:91-96</code>).</p>
@@ -1159,7 +1174,7 @@ reducă numărul de simboluri corelate prost alese</strong> (același sector, ac
poveste), care e exact ce multiplică pierderile într-o singură zi.</p> poveste), care e exact ce multiplică pierderile într-o singură zi.</p>
<p><strong>Verdict:</strong> merge ca atare ca logică, dar pe prop supraviețuiește doar <p><strong>Verdict:</strong> merge ca atare ca logică, dar pe prop supraviețuiește doar
partea cu unelte neproprietare (F-Score + RS/RVOL calculate), adică ~50-60% partea cu unelte neproprietare (F-Score + RS/RVOL calculate), adică ~50-60%
din proces (<code>fise/selectia.md</code>:308-314).</p> din proces (<code>fise/selectia.md</code>:315-321).</p>
<h3 id="pe-bvb-swing">Pe BVB (swing)</h3> <h3 id="pe-bvb-swing">Pe BVB (swing)</h3>
<p><strong>Ce cere strategia vs. ce există:</strong></p> <p><strong>Ce cere strategia vs. ce există:</strong></p>
<table> <table>
@@ -1348,7 +1363,7 @@ Distanța până la suport se calculează ca procent și se compară cu pragul d
<p><strong>Verdict:</strong> merge <strong>degradat</strong>. Rămâne scheletul fundamental (F-Score) + <p><strong>Verdict:</strong> merge <strong>degradat</strong>. Rămâne scheletul fundamental (F-Score) +
suport/pivot + relative strength calculat manual față de BET, pe un univers suport/pivot + relative strength calculat manual față de BET, pe un univers
de 8-10 nume lichide, cu verificare manuală în loc de scanner. de 8-10 nume lichide, cu verificare manuală în loc de scanner.
<strong>Cât din strategie supraviețuiește: ~30-35%</strong> (<code>fise/selectia.md</code>:304-326). <strong>Cât din strategie supraviețuiește: ~30-35%</strong> (<code>fise/selectia.md</code>:311-333).
Ce anume rămâne: <strong>F-Score-ul Piotroski</strong> (complet calculabil din rapoartele Ce anume rămâne: <strong>F-Score-ul Piotroski</strong> (complet calculabil din rapoartele
de pe bvb.ro) și <strong>relative strength manual față de BET</strong>; ce cade: de pe bvb.ro) și <strong>relative strength manual față de BET</strong>; ce cade:
scannerul automat, ATM-Score/value-score, Power/Trinity, cadranele de short scannerul automat, ATM-Score/value-score, Power/Trinity, cadranele de short

View File

@@ -140,7 +140,7 @@ sunt reconciliate explicit de material (vezi 2.4).</p>
scrie NEACOPERIT ÎN MATERIAL la MBT-10 (<code>strategii/fise/mbt10.md:186</code>), MBP scrie NEACOPERIT ÎN MATERIAL la MBT-10 (<code>strategii/fise/mbt10.md:186</code>), MBP
(<code>strategii/fise/mbp.md:322-326</code>), MDSRT (<code>strategii/fise/mdsrt.md:294-297</code>), (<code>strategii/fise/mbp.md:322-326</code>), MDSRT (<code>strategii/fise/mdsrt.md:294-297</code>),
BYH (<code>strategii/fise/byh.md:291-295</code>) și selecție BYH (<code>strategii/fise/byh.md:291-295</code>) și selecție
(<code>strategii/fise/selectia.md:300-302</code>). În acele cazuri se aplică plafonul (<code>strategii/fise/selectia.md:307-309</code>). În acele cazuri se aplică plafonul
general de 2% de mai sus.</p> general de 2% de mai sus.</p>
<h3 id="12-de-unde-vine-stopul-inainte-de-a-calcula-ceva">1.2 De unde vine stopul (înainte de a calcula ceva)</h3> <h3 id="12-de-unde-vine-stopul-inainte-de-a-calcula-ceva">1.2 De unde vine stopul (înainte de a calcula ceva)</h3>
<ul> <ul>
@@ -669,7 +669,7 @@ sizing — stopul pe structură, TP1/TP2/trail, jurnalul — se transferă ca at
<tr> <tr>
<td>volum mediu &gt; 500k, preț &gt; 30-40 $</td> <td>volum mediu &gt; 500k, preț &gt; 30-40 $</td>
<td>nu (praguri US)</td> <td>nu (praguri US)</td>
<td>praguri recalculate pe lichiditatea reală a numelor BET, nu pe cifrele US (<code>strategii/fise/selectia.md:318-320</code>)</td> <td>praguri recalculate pe lichiditatea reală a numelor BET, nu pe cifrele US (<code>strategii/fise/selectia.md:325-327</code>)</td>
</tr> </tr>
<tr> <tr>
<td>date fundamentale trimestriale</td> <td>date fundamentale trimestriale</td>

View File

@@ -105,8 +105,10 @@ intrare (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:5-6, 831-833</code>)
calendarul/contextul chiar înaintea oricărei idei pe simbol calendarul/contextul chiar înaintea oricărei idei pe simbol
(<code>08_ANALIZA_ZILNICA/10_sinteza.md:54-56</code>, marcat acolo ca reconstituire).</li> (<code>08_ANALIZA_ZILNICA/10_sinteza.md:54-56</code>, marcat acolo ca reconstituire).</li>
<li><strong>Scor fundamental:</strong> ATM score peste <strong>7-8</strong> intră în analiză; <strong>12-13</strong> e <li><strong>Scor fundamental:</strong> ATM score peste <strong>7-8</strong> intră în analiză; <strong>12-13</strong> e
„spuma"; <strong>7/14</strong> e „galben"; sub 7 se deduce că nu-l pui pe listă „spuma"; <strong>7/14</strong> e „galben". Sub 7 <strong>nu e prag de excludere</strong>: la 4/14 și
(nedeclarat ca prag separat). <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:199-204</code>. 6/14 continuă analiza; scorul departajează între candidați („5 din 14, ala
are 13 din 14. Păi, mai bine au AI [sic] decât MARA"); pragul exact de
excludere rămâne nespus. <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:199-204, 212-213</code>.
Pe F-score separat: <strong>8-9</strong> foarte puternic, <strong>6-7</strong> solid, <strong>4-5</strong> mixt, Pe F-score separat: <strong>8-9</strong> foarte puternic, <strong>6-7</strong> solid, <strong>4-5</strong> mixt,
<strong>0-3</strong> slab. <code>16_ANALIZA_FUNDAMENTALA/08_piotrowski_f_score.md:70-72</code>.</li> <strong>0-3</strong> slab. <code>16_ANALIZA_FUNDAMENTALA/08_piotrowski_f_score.md:70-72</code>.</li>
<li><strong>Trend:</strong> scannerul fundamental e „top 500 cu ATM score peste 7, în downtrend <li><strong>Trend:</strong> scannerul fundamental e „top 500 cu ATM score peste 7, în downtrend
@@ -121,13 +123,15 @@ intrare (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:5-6, 831-833</code>)
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:719-728</code>). După o corecție masivă, filtrul se schimbă: cauți doji / hammer (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:719-728</code>). După o corecție masivă, filtrul se schimbă: cauți doji / hammer
la suporturi mari, iar scannerul de apropiere de suport merge până la <strong>3%</strong> la suporturi mari, iar scannerul de apropiere de suport merge până la <strong>3%</strong>
(4% „e cam departe"). <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:787-803</code>.</li> (4% „e cam departe"). <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:787-803</code>.</li>
<li><strong>Volum:</strong> relative volume peste <strong>100%</strong> <li><strong>Volum:</strong> relative volume peste <strong>100%</strong>; sub prag (0.99, 0.96, 0.94, 0.88,
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:741-770</code>); verifică și <strong>volumul pe monthly/weekly</strong> la listă 0.74) e un minus care se compensează, nu un stop — nespus dacă intră pe
trigger sub prag (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:741-770</code>); verifică și <strong>volumul pe monthly/weekly</strong> la listă
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:209-213</code>).</li> (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:209-213</code>).</li>
<li><strong>Fundamental — ce descalifică:</strong> companie pe pierdere, cash flow negativ, <li><strong>Fundamental — ce descalifică:</strong> companie pe pierdere, cash flow negativ,
venit în scădere = speculă pe momentum, nu investiție; trecerea din profit în venit în scădere = speculă pe momentum, nu investiție; trecerea din profit în
pierdere = minus, dar nu reiese că scoate simbolul pierdere = minus, dar <strong>nu scoate simbolul</strong>: Vodafone, Baxter, Shopify și
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:225-257</code>). Cash flow pozitiv dar <strong>în scădere</strong> = deteriorare, nu-l pui pe spitalul au rămas în analiză, primele trei cu cash flow pozitiv (deducție:
criteriul real pare cash flow-ul) (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:225-257</code>). Cash flow pozitiv dar <strong>în scădere</strong> = deteriorare, nu-l pui pe
lista de investiție (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:326-391</code>).</li> lista de investiție (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:326-391</code>).</li>
<li><strong>Valuation:</strong> P/E forward mic contează doar dacă <strong>veniturile cresc</strong>; P/E <li><strong>Valuation:</strong> P/E forward mic contează doar dacă <strong>veniturile cresc</strong>; P/E
mic + venit în scădere = probleme, nu chilipir; P/E peste minimul de 5 ani mic + venit în scădere = probleme, nu chilipir; P/E peste minimul de 5 ani
@@ -141,8 +145,10 @@ fișierului-sursă). <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:18-27, 6
(minim 500k), volum mediu scanner <strong>≥ 500k</strong> (minim 500k), volum mediu scanner <strong>≥ 500k</strong>
(<code>09_QA/28_2025-05-27.md:372-380</code>, <code>03_MODUL_2/11_construire_scanere_sf_byd_sld.md:70-73</code>).</li> (<code>09_QA/28_2025-05-27.md:372-380</code>, <code>03_MODUL_2/11_construire_scanere_sf_byd_sld.md:70-73</code>).</li>
<li><strong>Fundamental</strong> — ATM score peste <strong>7-8</strong> (12-13 = prioritate); F-score <li><strong>Fundamental</strong> — ATM score peste <strong>7-8</strong> (12-13 = prioritate); F-score
6-9 solid/puternic; elimini companiile pe pierdere / cash flow negativ / 6-9 solid/puternic; scorul departajează, nu respinge automat. Companiile pe
venit în scădere. <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:199-221, 225-257</code>.</li> pierdere / cu cash flow negativ / venit în scădere nu sunt de investiție;
trecerea în pierdere cu cash flow pozitiv nu scoate simbolul.
<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:199-221, 225-257</code>.</li>
<li><strong>Sectorul care domină</strong> — numără din ce sector vin cele mai multe semnale <li><strong>Sectorul care domină</strong> — numără din ce sector vin cele mai multe semnale
(rotație); la nivel de sectoare sortezi după cadranul 1 + valoarea RS, pe (rotație); la nivel de sectoare sortezi după cadranul 1 + valoarea RS, pe
cele <strong>11 sectoare S&amp;P</strong>, și te uiți la componentele ETF-ului de sector. cele <strong>11 sectoare S&amp;P</strong>, și te uiți la componentele ETF-ului de sector.
@@ -173,11 +179,10 @@ pe grafic. Un simbol perfect pe hârtie, fără trigger, e doar pe listă."
<code>16_ANALIZA_FUNDAMENTALA/08_piotrowski_f_score.md:74-84</code>; <code>16_ANALIZA_FUNDAMENTALA/08_piotrowski_f_score.md:74-84</code>;
<code>16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:263-265</code>.)</p> <code>16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:263-265</code>.)</p>
<p><strong>DA / NU pentru validitatea selecției</strong> (nu pentru intrare): DA = trece toate <p><strong>DA / NU pentru validitatea selecției</strong> (nu pentru intrare): DA = trece toate
filtrele din §4-5; NU = scor 2-4 filtrele din §4-5; NU ca investiție = scor 2 (APG, FLR — FLR cel mult „un
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:230-257</code>), RS în cadranul 4 fără îmbunătățire swing") (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:230-257</code>), RS în cadranul 4 fără îmbunătățire = așteptare
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:493-499</code>), relative volume 0.96 / 0.74 (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:493-499</code>), cash flow în deteriorare (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:326-391</code>). Relative volume
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:749-761</code>), fundament în deteriorare sub 100% (0.96 / 0.74) e <strong>minus, nu NU</strong> (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:749-770</code>).</p>
(<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:225-257, 326-391</code>).</p>
<h2 id="7-stop-loss">7. Stop-loss</h2> <h2 id="7-stop-loss">7. Stop-loss</h2>
<p><strong>NEACOPERIT ÎN MATERIAL</strong> — un filtru de selecție nu are stop-loss. Nu există <p><strong>NEACOPERIT ÎN MATERIAL</strong> — un filtru de selecție nu are stop-loss. Nu există
nivel de preț care să invalideze selecția în material. Stop-loss-ul apare doar nivel de preț care să invalideze selecția în material. Stop-loss-ul apare doar
@@ -301,21 +306,22 @@ Take-profit-ul se stabilește în strategia de intrare
<li><strong>Cadranul 4 nu se cumpără pe orb.</strong> Aștepți trecerea în 2 sau 1 ori un <li><strong>Cadranul 4 nu se cumpără pe orb.</strong> Aștepți trecerea în 2 sau 1 ori un
MP4-1 / MBT-10 long; un scor fundamental bun nu anulează RS-ul slab. MP4-1 / MBT-10 long; un scor fundamental bun nu anulează RS-ul slab.
<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:493-499, 839-840</code>. <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:493-499, 839-840</code>.
<strong>Contradicție în material:</strong> fișierul de RS dă un contra-exemplu explicit Alternativa pe care o dă el nu e divergența, e un <strong>trigger</strong>: „as astepta
(ACN) — cadranul 4 cu <strong>divergență bull clară</strong> și preț la suport major poate imbunatatire pe cadranul 4, sa treaca in cadranul 2 / Sau in cadranul 1
fi long valid (<code>03_MODUL_2/06_indicatorul_de_performanta.md:337-342, 494-496</code>), [...] Sau un MP4,1 long, sau poate MBT10 long" [sic]
în timp ce <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:493-499</code> spune că nu se tranzacționează (<code>transcripts/08_ANALIZĂ_ZILNICĂ/122_23022026.txt:103-106</code>). Nicăieri nu spune că divergența singură
pe orb. Cele două nu se exclud complet (al doilea cere divergență, nu „pe ajunge. Exemplul ACN din fișierul de RS (cadranul 4 cu divergență bull,
orb"), dar nu reiese o regulă unică.</li> <code>03_MODUL_2/06_indicatorul_de_performanta.md:337-342, 494-496</code>) are și preț
la suport major cu doji pe suport, adică tot un setup cu trigger.</li>
<li><strong>„Trinity" are două sensuri în material.</strong> La selecție = RS + Power + volum <li><strong>„Trinity" are două sensuri în material.</strong> La selecție = RS + Power + volum
<strong>aliniate în cadranul 1</strong> (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:555-568</code>). În <strong>aliniate în cadranul 1</strong> (<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:555-568</code>). În
strategia MDSRT = cei trei indicatori <strong>în divergență simultană</strong> pe aceeași strategia MDSRT = cei trei indicatori <strong>în divergență simultană</strong> pe aceeași
zonă („nu e trinity-ul clasic", <code>05_MODUL_4/02_strategia_5_mdsrt.md:4-9, 34-42</code>). zonă („nu e trinity-ul clasic", <code>05_MODUL_4/02_strategia_5_mdsrt.md:4-9, 34-42</code>).
<code>09_QA/19_2025-09-08.md:53-54</code> numără altfel stelele (3 indicatori + bull <code>09_QA/19_2025-09-08.md:53-54</code> numără altfel stelele (3 indicatori + bull
reversal + suport = 5 stele). Nu sunt același lucru — nu le amesteca.</li> reversal + suport = 5 stele). Nu sunt același lucru — nu le amesteca.</li>
<li><strong>Sub 100% relative volume l-a făcut să respingă.</strong> 0.96 și 0.74 sunt <li><strong>Sub 100% relative volume e un minus, nu un veto.</strong> La 0.99, 0.96, 0.94,
respingeri, nu „aproape"; dar nu a formulat o regulă generală că sub prag 0.88 și 0.74 a continuat analiza; nespus dacă intră pe trigger sub prag.
oprește orice intrare. <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:749-770, 836-838, 863-866</code>.</li> <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:749-770, 836-838, 866-867</code>.</li>
<li><strong>Nu pune praguri rigide de RVOL în zile extreme.</strong> Pe scanerul real de Buy <li><strong>Nu pune praguri rigide de RVOL în zile extreme.</strong> Pe scanerul real de Buy
Doji, RVOL era CDNS 0.86, CRM 1.03, ULTA 0.61; un prag fix <code>RVOL ≥ 1.2</code> ar fi Doji, RVOL era CDNS 0.86, CRM 1.03, ULTA 0.61; un prag fix <code>RVOL ≥ 1.2</code> ar fi
dat zero rezultate, deși existau 3 candidați valizi — de aceea cursul dat zero rezultate, deși existau 3 candidați valizi — de aceea cursul
@@ -324,8 +330,9 @@ Take-profit-ul se stabilește în strategia de intrare
<li><strong>Prețul poate bate fundamentalul.</strong> Un setup cu scor 12/14 a fost respins de <li><strong>Prețul poate bate fundamentalul.</strong> Un setup cu scor 12/14 a fost respins de
un sell doji plus reject pe pivotul quarterly. <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:841-846</code>; un sell doji plus reject pe pivotul quarterly. <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:841-846</code>;
<code>08_ANALIZA_ZILNICA/10_sinteza.md:564-573</code>.</li> <code>08_ANALIZA_ZILNICA/10_sinteza.md:564-573</code>.</li>
<li><strong>Cash flow pozitiv dar în scădere nu e „ok".</strong> E deteriorare; la trecerea <li><strong>Cash flow pozitiv dar în scădere nu e „ok".</strong> E deteriorare. Trecerea din
din profit în pierdere nu reiese că scoate simbolul din listă. profit în pierdere, în schimb, nu scoate simbolul din listă (4 cazuri;
deducție: contează cash flow-ul).
<code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:326-391, 847-850</code>.</li> <code>08_ANALIZA_ZILNICA/11_selectia_simbolului.md:326-391, 847-850</code>.</li>
<li><strong>Relative strength nu funcționează pe commodities</strong> (compară cu SPY). <li><strong>Relative strength nu funcționează pe commodities</strong> (compară cu SPY).
<code>09_QA/19_2025-09-08.md:56-60</code>.</li> <code>09_QA/19_2025-09-08.md:56-60</code>.</li>