Files
atm-curs-dl/gen/strategii/mdsrt_iesire.py
Claude Agent f8dd2f7bd0 07_mdsrt: capitol reconstruit dupa sablon
Nivelurile 1-2-3, cei 6 pasi cu diagrama fiecare, mini-glosar de 33 de
termeni, oglinda pe short cu diagrama ei, checklist. Sursele in
fise/07_mdsrt_surse.md.

Capitolul avea TREI reguli numerice diferite in acelasi loc: stop fix pe
low in ansamblu, 0.10 sub low in aplus si exemplu, plus doua reguli de
intrare. Acum mdsrt_ansamblu.py tine seria si regulile, iar picior,
trigger, stop, iesire si short le importa — nu mai pot diverge.

Noi: zona (daily -> 60 min ca descompunere reala, 2 candele daily = 14
bare, cu caseta, ghidaje si pivotul pe ambele panouri), picior, trigger,
stop, iesire, short (seria long rasturnata, deci fiecare cifra are
perechea ei).

Verificare numerica text-diagrama: trei nepotriviri reparate, inclusiv o
cifra din proza care nu exista pe niciun desen.

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

97 lines
4.8 KiB
Python

"""MDSRT, Pasul 6 — ieșirea: TP1 la 1:1, breakeven, restul pe trail.
Aceeași serie canonică (importată din `mdsrt_ansamblu`), de la intrare
încolo: prima parte a poziției iese la ținta simetrică 1:1 (591.00), stopul
se mută la breakeven după ce prețul a trecut de jumătatea drumului până la
țintă, iar restul merge pe linia de trail — ultimul swing low — până la prima
închidere sub ea.
Din curs: ținta stabilită împreună cu stopul, simetric; trail pe Bull Trail
sau pe swing low, la alegerea traderului; trail-ul se evaluează pe candelă
închisă, nu în timpul barei. Numărul de tranșe NU e dat de curs —
transcrierea se întrerupe exact acolo.
Rulează: python3 gen/strategii/mdsrt_iesire.py
"""
import re
import sys
from pathlib import Path
sys.path.insert(0, "/workspace/atm-curs-dl")
sys.path.insert(0, str(Path(__file__).parent))
from svg_candles import Chart, Level, Mark, Arrow, Zone # noqa: E402
from mdsrt_ansamblu import (serie, CONF, ENTRY, SL, R, TP1, EXIT_I, TRAIL, # noqa: E402
bull_trail)
OUT = Path(__file__).with_suffix(".svg")
GREEN, RED, BLUE, GRAY, ORANGE = "#188a3e", "#c00", "#1a5fb4", "#555", "#b06000"
W = 720
S = 14
cds = serie()[S:EXIT_I + 1]
cf, tp_i, ex_i = CONF - S, 22 - S, EXIT_I - S
BE = ENTRY # stopul mutat la prețul de intrare
half = round(ENTRY + R / 2, 2) # jumătatea drumului până la țintă
be_i = next(i for i in range(cf + 1, len(cds)) if cds[i].c > half)
# ----------------------------------------------------------------- assert-uri
assert cds[cf].c == ENTRY and round(ENTRY - SL, 2) == R
assert round(TP1 - ENTRY, 2) == R, "ținta nu e simetrică cu stopul"
assert cds[tp_i].h >= TP1 and max(c.h for c in cds[cf + 1:tp_i]) < TP1, "TP1 atins altundeva"
assert cds[be_i].c > half and all(c.c <= half for c in cds[cf + 1:be_i]), "breakeven greșit"
assert be_i < tp_i, "breakeven-ul ar veni după țintă"
# trail: ultimul swing low înaintea întoarcerii; ieșirea e prima închidere sub el
assert cds[ex_i].c < TRAIL and all(c.c > TRAIL for c in cds[ex_i - 2:ex_i])
r_exit = round((cds[ex_i].c - ENTRY) / R, 2)
assert r_exit == 2.75, r_exit
# scara: distanța intrare→TP1 e egală cu distanța intrare→SL, și în preț, și în px
print(f"ieșire: TP1 {TP1:.2f} la bara {tp_i + S}, breakeven de la bara {be_i + S} "
f"(peste {half:.2f}), trail {TRAIL:.2f}, ieșire {cds[ex_i].c:.2f} = {r_exit:.2f}R")
ch = Chart(
candles=cds,
levels=[
Level(TP1, f"TP1 {TP1:.2f} = 1:1", GREEN, "2 2",
label_at="left"),
Level(ENTRY, f"intrare {ENTRY:.2f} = breakeven", GRAY, "4 3",
label_at="left"),
Level(SL, f"SL inițial {SL:.2f} (risc {R:.2f} = 1R)", RED, "4 3", label_at="left"),
],
marks=[Mark(ex_i, f"ieșire {cds[ex_i].c:.2f} = {r_exit:.2f}R", GREEN, "above")],
zones=[Zone(be_i, tp_i, "de aici stopul stă la breakeven", ORANGE)],
arrows=[
Arrow(be_i, f"prețul a trecut de jumătatea drumului ({half:.2f}):\n"
f"muți stopul la {BE:.2f} — trade-ul nu mai poate pierde",
where="below", price=SL, color=ORANGE, dx=-40, dy=44),
Arrow(tp_i, f"ținta 1:1 atinsă: {TP1:.2f}\nrestul poziției rămâne pe trail",
where="above", color=GREEN, dx=90, dy=-30),
Arrow(ex_i, f"prima închidere sub linia de trail ({TRAIL:.2f}):\n"
f"ieși cu restul — se citește pe candelă închisă,\nnu în timpul barei",
where="below", price=cds[ex_i].c, color=BLUE, dx=-30, dy=64),
],
scale=56.0, gap=24, body_w=12, left=200, width=W, top=44,
title="Pasul 6 — ieșirea: ținta 1:1, breakeven, restul pe trail (SPY 5 min, construit)",
caption="Câte tranșe faci nu e dat de curs: acolo se întrerupe transcrierea.",
)
svg = ch.render()
# linia de trail: ultimul swing low de la fiecare pas, desenată ca scară
trail_pts = bull_trail(cds, cf)
assert trail_pts[-1][1] == TRAIL, (trail_pts[-1], TRAIL)
assert len(trail_pts) > 5, trail_pts
d = []
for k, (i, p) in enumerate(trail_pts):
x0, x1 = ch._cx(i) - ch.gap / 2, ch._cx(i) + ch.gap / 2
d.append(("M" if k == 0 else "L") + f"{x0:.1f},{ch._y(p):.1f}")
d.append(f"L{x1:.1f},{ch._y(p):.1f}")
trail_svg = (f'<path d="{" ".join(d)}" fill="none" stroke="{BLUE}" stroke-width="1.6" '
f'stroke-dasharray="5 3"/>')
i = svg.rindex("</svg>")
svg = svg[:i] + " " + trail_svg + "\n" + svg[i:]
assert "\n\n" not in svg, "linie goală în SVG"
H = float(re.search(r'viewBox="0 0 [\d.]+ ([\d.]+)"', svg).group(1))
for x, y in re.findall(r'<text x="([-\d.]+)" y="([-\d.]+)"', svg):
assert 0 <= float(x) <= W and 0 <= float(y) <= H, f"text în afara pânzei la ({x}, {y})"
OUT.write_text(svg, encoding="utf-8")
print(f"scris {OUT.name} ({W}x{H:.0f})")