Files
atm-curs-dl/gen/strategii/m2d_trigger.py
Claude Agent 0ed607134d m2d: diagramele refacute; ansamblul primeste corespondenta de TF
Ansamblul arata acum 15 min si 3 min ca descompunere reala (k=5, cu
assert), cu caseta punctata, ghidaje si nivelul comun legat prin
conector — sablonul din buy_doji_perechi_tf.

Noi, pentru pasii care nu aveau diagrama: directie (15 min ramane in Buy
vs. se inchide Sell), trigger (bara inchisa peste capat vs. atinsa doar
cu fitilul, plus al doilea semnal marcat "nu mai intri"), stop (cele 4
bare si alternativa 2xATR, cu cifrele SPY din curs), iesire (TP1 plus
bull trail, long si short, oglinda calculata nu desenata din ochi).
Secventa era din polilinii desenate de mana — rescrisa pe serie.

Stopul e fix pe extrema celor 4 bare, fara marja: asa spune cursul aici,
spre deosebire de 01_buy_doji. Diferenta trebuie spusa in text.

Textul capitolului e neatins — agentul a atins pragul de context.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
2026-09-20 12:45:14 +00:00

119 lines
5.9 KiB
Python

#!/usr/bin/env python3
"""M2D, pasul 3 — trigger-ul (A): DA (bară închisă peste) vs. NU (doar atins).
Pentru `summaries/17_STRATEGII/03_m2d.md`, marcajul `<!-- DIAGRAMA: trigger -->`.
Aceeași serie de 3 minute ca în diagrama de ansamblu până la bara 8; de acolo
încolo, două continuări. Sus: bara 9 se ÎNCHIDE peste capătul pullback-ului,
deci e trigger, și intri la close. Jos: bara 9 atinge același nivel cu
fitilul, dar se închide sub el — nu e trigger; pe barele următoare pullback-ul
rupe minimul de referință și setup-ul moare.
Indicatorul care dă săgeata de Buy Momentum e proprietar cursului. Pe desen,
săgeata e pusă acolo unde prețul se închide peste capătul pullback-ului —
construcția mea, ca regula să fie verificabilă cu ochiul pe un grafic.
Rulare: python3 gen/strategii/m2d_trigger.py
"""
import sys
from pathlib import Path
sys.path.insert(0, "/workspace/atm-curs-dl")
sys.path.insert(0, str(Path(__file__).resolve().parent))
from svg_candles import Arrow, Candle, Chart # noqa: E402
import m2d_duo as duo # noqa: E402
OUT = Path(__file__).with_suffix(".svg")
W, SCALE, GAP, LEFT = 680, 104.0, 30, 56
GREEN, RED, GREY = "#188a3e", "#c00", "#555"
REF_LOW = 99.80 # minimul din care a pornit mișcarea (vezi pașii 1 și 2)
COMUN = [(100.60, 100.70, 100.40, 100.45), (100.45, 100.50, 100.25, 100.30),
(100.30, 100.35, 100.15, 100.20), (100.20, 100.25, 100.05, 100.10),
(100.10, 100.15, 100.00, 100.05), (100.05, 100.10, 99.95, 100.00),
(100.00, 100.05, 99.92, 99.95), (99.95, 100.00, 99.90, 99.98),
(99.98, 100.08, 99.94, 100.02)]
TRIG = 9
DA = COMUN + [(100.02, 100.45, 100.00, 100.40), # 9: se ÎNCHIDE peste capăt
(100.40, 100.60, 100.35, 100.55), (100.55, 100.75, 100.50, 100.70),
(100.70, 101.00, 100.65, 100.95)]
NU = COMUN + [(100.02, 100.45, 99.98, 100.00), # 9: atinge, dar se închide sub
(100.00, 100.05, 99.82, 99.85),
(99.85, 99.90, 99.55, 99.60), # 11: rupe minimul de referință
(99.60, 99.70, 99.45, 99.50)]
# ---------------------------------------------------------------- verificări
for nume, bars in (("DA", DA), ("NU", NU)):
for i, (o, h, l, c) in enumerate(bars):
assert h >= max(o, c) and l <= min(o, c), f"{nume}[{i}]: high/low incoerent"
if i:
assert abs(o - bars[i - 1][3]) < 1e-9, f"{nume}[{i}]: open != close precedent"
assert DA[:TRIG] == NU[:TRIG] == COMUN, "panourile nu pornesc din aceeași serie"
CAPAT = max(b[1] for b in COMUN[6:]) # capătul pullback-ului = 100.08
assert abs(CAPAT - 100.08) < 1e-9, CAPAT
# nicio bară dinaintea trigger-ului nu se închidea deja peste capăt
assert all(b[3] <= CAPAT for b in COMUN[6:]), "o bară dinainte închidea deja peste capăt"
# DA: bara 9 se închide peste capăt — e trigger, și e PRIMA care face asta
assert DA[TRIG][3] > CAPAT, "DA: bara de trigger nu se închide peste capăt"
assert all(b[3] <= CAPAT for b in DA[6:TRIG]), "DA: trigger-ul nu e primul de după minim"
ENTRY = DA[TRIG][3]
assert abs(ENTRY - 100.40) < 1e-9, ENTRY
# al doilea semnal, pe care NU mai intri
AL_DOILEA = next(i for i in range(TRIG + 1, len(DA))
if DA[i][3] > max(b[1] for b in DA[i - 3:i]))
assert AL_DOILEA == 10, AL_DOILEA
# NU: bara 9 ATINGE capătul cu fitilul, dar se închide sub el
assert NU[TRIG][1] > CAPAT, "NU: bara 9 nici nu atinge capătul"
assert NU[TRIG][3] < CAPAT, "NU: bara 9 se închide totuși peste capăt"
assert all(b[3] <= CAPAT for b in NU[6:]), "NU: o bară se închide peste capăt"
RUPT = next(i for i, b in enumerate(NU) if b[3] < REF_LOW)
assert RUPT == 11, RUPT
def chart(bars, arrows):
return Chart(candles=[Candle(*b) for b in bars], arrows=arrows,
scale=SCALE, gap=GAP, body_w=12, left=LEFT, width=W, top=64)
ch_da = chart(DA, [
Arrow(TRIG, "s-a ÎNCHIS peste 100.08: ăsta e trigger-ul.\n"
"Intri la close, adică la 100.40",
where="below", color=GREEN, dx=-40, dy=54),
Arrow(AL_DOILEA, "al doilea semnal — aici NU mai intri:\n"
"statistica cursului e măsurată pe primul",
where="above", color=RED, dx=40, dy=-4)])
ch_nu = chart(NU, [
Arrow(TRIG, "fitilul a trecut peste 100.08, close-ul nu:\n"
"un puseu de câteva secunde nu e trigger",
where="above", color=RED, dx=-90, dy=4),
Arrow(RUPT, "pullback-ul rupe 99.80:\nsetup mort, cauți altul",
where="below", color=RED, dx=-30, dy=24)])
body_da, h_da = duo.panel(ch_da, W)
body_nu, h_nu = duo.panel(ch_nu, W)
nivel_capat = ["capătul pullback-ului 100.08", "peste el trebuie ÎNCHIS, nu doar atins"]
extra_da = (duo.titlu("DA — bara se închide peste capăt", color=GREEN)
+ duo.zone(ch_da, TRIG - 2, TRIG, "aici se decide intrarea", GREEN, pad=13, lift=30)
+ duo.level(ch_da, CAPAT, nivel_capat, GREY, W, below=True, at_left=False))
extra_nu = (duo.titlu("NU — atins cu fitilul, închis dedesubt: nu e trigger", color=RED)
+ duo.level(ch_nu, CAPAT, nivel_capat, GREY, W, below=False, at_left=False)
+ duo.level(ch_nu, REF_LOW, ["minimul din care a pornit mișcarea 99.80"],
RED, W, below=True, dash="2 3"))
svg, H, n = duo.build(
[("DA", body_da, h_da, extra_da), ("NU", body_nu, h_nu, extra_nu)],
["Primele 9 bare sunt identice pe ambele panouri; se schimbă doar ce urmează.",
"Trigger-ul se citește pe bară ÎNCHISĂ, nu pe fitil — la fel se citește și "
"ieșirea pe trail (pasul 5)."],
W)
duo.fara_preturi_straine(svg, [CAPAT, ENTRY, REF_LOW])
OUT.write_text(svg, encoding="utf-8")
print(f"scris {OUT} ({W}x{H:.0f}), {n} etichete | capăt {CAPAT:.2f} | "
f"DA: trigger la bara {TRIG}, intrare {ENTRY:.2f}, al doilea semnal la {AL_DOILEA} | "
f"NU: bara {TRIG} high {NU[TRIG][1]:.2f} close {NU[TRIG][3]:.2f}, rupe la bara {RUPT}")