Nivelurile 1-2-3, cei 6 pasi cu diagrama fiecare, mini-glosar de 34 de termeni, oglinda pe short cu diagrama ei proprie, checklist. Sursele in fise/02_mp2_surse.md. Toate diagramele procedurii ies acum dintr-o singura serie (mp2_serie.py), deci capitolul nu mai poate avea doua reguli numerice. Ansamblul folosea NVDA cu stop la swing low absolut (-23 %), adica alta regula decat procedura celor 4 bare; NVDA a devenit "bottom", la nivelul 3, marcat explicit ca exceptie. perechi_tf e diagrama cu doua timeframe-uri: panoul mic e descompunerea reala a ultimelor 2 candele daily (1 zi = 7 bare de 60 min), cu pivotul weekly pe ambele panouri si conector. Pivotii se calculeaza din serie, nu sunt scrisi de mana. Reparate: trail-ul din proza era 600.05, calculul din serie da 600.75; doua SVG-uri aveau trimiteri fisier:linie desenate pe ele. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
75 lines
3.7 KiB
Python
75 lines
3.7 KiB
Python
"""MP² — stopul și mărimea poziției (Pasul 5 din `02_mp2.md`).
|
||
|
||
Aceeași serie. Numeri 4 bare înapoi, începând cu bara de trigger, iei cea
|
||
mai joasă dintre ele și acolo stă stopul. Pe desen mai apare și varianta de
|
||
la bottom major: swing low-ul absolut al mișcării, mult mai jos — regula
|
||
alternativă a cursului, nu o a doua regulă pentru trade-ul obișnuit.
|
||
|
||
Rulare: python3 gen/strategii/mp2_stop.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 Arrow, Chart, Level, Zone # noqa: E402
|
||
import mp2_serie as S # noqa: E402
|
||
|
||
OUT = Path(__file__).with_suffix(".svg")
|
||
RED, BLUE, GRAY, GREEN, ORANGE = "#c00", "#1a5fb4", "#777", "#188a3e", "#b06000"
|
||
W, B = 720, 30
|
||
cds = S.CDS[:B + 1]
|
||
i_low = min(range(len(cds)), key=lambda i: cds[i].l)
|
||
R_MARE = round(S.ENTRY - S.SWING_LOW, 2)
|
||
|
||
assert i_low == 7 and cds[i_low].l == S.SWING_LOW
|
||
assert S.SL == min(c.l for c in cds[S.TRIGGER - 3:S.TRIGGER + 1])
|
||
assert R_MARE == 12.00 and R_MARE == 2 * S.R
|
||
|
||
ch = Chart(
|
||
candles=cds,
|
||
levels=[Level(S.ENTRY, f"intrarea {S.ENTRY:.2f}", "#333", "4 3", "right"),
|
||
Level(S.SL, f"stopul din regulă {S.SL:.2f} — 1R = {S.R:.2f}", RED, "6 3", "left"),
|
||
Level(S.SWING_LOW, f"swing low absolut {S.SWING_LOW:.2f}", ORANGE, "2 4", "right")],
|
||
zones=[Zone(S.TRIGGER - S.BARE_STOP + 1, S.TRIGGER,
|
||
f"cele {S.BARE_STOP} bare pe care le numeri", BLUE)],
|
||
arrows=[
|
||
Arrow(22, f"cea mai joasă dintre cele {S.BARE_STOP}: {S.SL:.2f}\nacolo pui stopul, "
|
||
f"nu mai jos și nu mai aproape",
|
||
where="below", price=S.SL, color=RED, dx=-120, dy=6),
|
||
Arrow(i_low, f"minimul întregii mișcări: {S.SWING_LOW:.2f}\nasta folosești DOAR la un "
|
||
f"bottom major,\ncând retesturile dese te-ar scoate degeaba — 1R devine {R_MARE:.2f}",
|
||
where="below", price=S.SWING_LOW, color=ORANGE, dx=180, dy=48),
|
||
Arrow(S.TRIGGER, f"bara de trigger: {S.ENTRY:.2f}\nde aici numeri înapoi",
|
||
where="above", color=GREEN, dx=-96, dy=-4),
|
||
],
|
||
scale=14.0, gap=20, body_w=11, left=56, width=W, top=40,
|
||
title="Pasul 5 — numeri 4 bare înapoi de la trigger și iei cea mai joasă")
|
||
|
||
svg = ch.render()
|
||
off = S.offset(svg, ch)
|
||
y_num = ch._y(S.SL) + off + 20
|
||
nums = [f'<text x="{ch._cx(S.TRIGGER - k):.1f}" y="{y_num:.1f}" fill="{BLUE}" '
|
||
f'text-anchor="middle" style="font-weight:bold">{k + 1}</text>' for k in range(S.BARE_STOP)]
|
||
svg = S.injecteaza(svg, nums)
|
||
|
||
h = float(re.search(r'viewBox="0 0 [\d.]+ ([\d.]+)"', svg).group(1))
|
||
w = float(re.search(r'viewBox="0 0 ([\d.]+)', svg).group(1))
|
||
linii = [
|
||
("Mărimea poziției: riscul în bani se împarte la distanța până la stop.", "#333"),
|
||
(f"Cont {S.CONT:,.0f} $".replace(",", ".") +
|
||
f" × {S.RISC_PCT * 100:.1f} % = {S.CONT * S.RISC_PCT:.0f} $ de risc; "
|
||
f"{S.CONT * S.RISC_PCT:.0f} / {S.R:.2f} = {S.CONT * S.RISC_PCT / S.R:.1f} bucăți → "
|
||
f"{S.BUCATI} bucăți, adică două ordine de câte {S.BUCATI // 2}.", BLUE),
|
||
(f"Risc real: {S.BUCATI} × {S.R:.2f} = {S.RISC_REAL:.0f} $, adică "
|
||
f"{S.RISC_REAL / S.CONT * 100:.2f} % din cont — sub pragul de "
|
||
f"{S.RISC_PCT * 100:.1f} %.", GREEN),
|
||
]
|
||
blocs = [f'<text x="24" y="{h + 6 + 19 * i:.1f}" fill="{c}">{t}</text>' for i, (t, c) in enumerate(linii)]
|
||
H = h + 6 + 19 * len(linii)
|
||
svg = re.sub(r'viewBox="0 0 ([\d.]+) [\d.]+"', rf'viewBox="0 0 \1 {H:.0f}"', svg, count=1)
|
||
svg = svg.replace("</svg>", " " + "\n ".join(blocs) + "\n</svg>")
|
||
assert max(len(t) for t, _ in linii) * 5.7 + 24 < w, "linia de calcul iese din pânză"
|
||
S.scrie(OUT, svg, w, H)
|