Files
atm-curs-dl/gen/strategii/hammer_mbt10_mbt_iesire.py
Claude Agent f60d32cb34 17_STRATEGII/06_hammer_mbt10: toate cele 9 restante, plus cele 3 cosmetice
Cea mai grava, si cea care a cerut refacerea seriei: exemplul central de
MBT-10 era luat de pe 60 de minute si bagat in procedura de daily, cu barele
numite "zile", desi sursa spune explicit de ce nu merge pe daily. Pe langa
asta, suportul fusese schimbat din 88.00 (testat de trei ori, cu compresie,
cum e in sursa) in 87.50 cu un double bottom si o divergenta de volum
imprumutate din alt exemplu.

Seria e refacuta pe exemplul materialului, cu assert pe cele trei atingeri ale
lui 88.00 si pe compresia varfurilor. Adaosurile au fost scoase, nu doar
marcate: cu ele in desen, suportul din sursa n-ar fi avut sens. Aritmetica a
supravietuit neatinsa.

Restul: stopul de 60.40 sta acum sub o structura reala; pivotul daily nu mai e
o linie fixa peste tot graficul, ci un segment peste ziua intrarii; SL-ul de
pe LABU respecta regula proprie de 5 centi; citatul de la A2 nu mai e dat ca
al autorului; pragul de 1-2% isi spune originea (cursul da 0,5%, pe 60 min);
o singura conventie de distanta, impartirea la nivel; swing low definit la fel
in pas si in glosar.

eticheta_libera a prins 7 suprapuneri reale. La bh_aplus a trebuit rulat pe
fiecare panou separat: wrapper-ul le muta cu <g transform>, pe care unealta
nu-l citeste - de notat pentru data viitoare.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
2026-10-02 05:29:33 +00:00

77 lines
3.8 KiB
Python

#!/usr/bin/env python3
"""MBT-10 — ieșirea: ținta e o structură din stânga, nu un procent.
Toată seria pasului „unde" (importată), de la vârful din care a pornit
coborârea până la atingerea lui înapoi. Ținta 95.20 nu e aleasă: e high-ul
ultimului maxim dinaintea coborârii, verificat prin assert. Fișierul
principal nu fixează nicio regulă proprie de take-profit — de aceea ținta e
numită pe desen ca structură, nu ca regulă.
Rulare: python3 gen/strategii/hammer_mbt10_mbt_iesire.py
"""
import re
import sys; sys.path.insert(0, "/workspace/atm-curs-dl")
sys.path.insert(0, "/workspace/atm-curs-dl/gen/strategii")
from pathlib import Path
from hammer_mbt10_mbt_confluente import CLOSE_I, INTRARE, SL, TP, VARF, serie
from svg_candles import Arrow, Chart, Level, Zone
OUT = Path(__file__).with_suffix(".svg")
GREEN, RED, BLUE, ORANGE, GREY = "#188a3e", "#c00", "#1a5fb4", "#b06000", "#555"
cds = serie()
RISC = round(INTRARE - SL, 2)
R_TINTA = round((TP - INTRARE) / RISC, 2)
prim_tp = next(i for i in range(CLOSE_I + 1, len(cds)) if cds[i].h >= TP)
# --- verificări -------------------------------------------------------------
assert round(cds[VARF].h, 2) == TP, "ținta nu e high-ul vârfului"
assert max(c.h for c in cds[VARF + 1:prim_tp]) < TP, "structura e depășită înainte de țintă"
# cifra din material/fișă e 2,0R (summaries/08_ANALIZA_ZILNICA/02_mbt10.md:451):
# raportul exact e 2.038, dar se rotunjește la o zecimală la 2.0 — verificăm
# exact ce se afișează pe desen, nu valoarea brută.
assert prim_tp == 26 and round(R_TINTA, 1) == 2.0, (prim_tp, R_TINTA)
assert min(c.l for c in cds[CLOSE_I:]) > SL, "stopul ar fi fost atins înainte de țintă"
assert cds[VARF].h > cds[CLOSE_I].c > SL, "ordinea vârf / intrare / stop e greșită"
zile = prim_tp - CLOSE_I
assert zile == 7, zile
ch = Chart(
candles=cds,
levels=[Level(TP, "ținta 95.20 = ultimul maxim dinaintea coborârii", BLUE),
Level(INTRARE, "intrare 89.90", GREEN, label_at="left"),
Level(SL, "SL 87.30", RED, label_at="left")],
zones=[Zone(VARF, VARF, "de aici a pornit coborârea", ORANGE, p_top=95.9),
Zone(CLOSE_I, prim_tp, "drumul până la structură: 7 bare", GREEN)],
arrows=[
Arrow(prim_tp, f"ieși la 95.20 (+{R_TINTA:.1f}R):\nprima structură care a oprit\nprețul "
"ultima dată",
price=TP, where="below", color=BLUE, dx=-200, dy=54),
],
scale=26.0, gap=17, body_w=10, left=54, width=700, top=58, vol_h=60, vol_label="volum",
title="MBT-10 — ieșirea la prima structură din stânga (60 de minute)",
)
svg = ch.render()
m = re.search(r'viewBox="0 0 (\d+) (\d+)"', svg)
W, H = int(m.group(1)), int(m.group(2))
linii = [
("Materialul nu dă o regulă proprie de take-profit la MBT-10. Ce au în comun toate "
"exemplele lui e că", "#333"),
("ținta e o structură vizibilă în stânga: un vârf anterior, ultimul maxim mai jos, sau "
"închiderea unui gap.", "#333"),
(f"Aici: 89.90 → 95.20 = {R_TINTA:.1f}R, în {zile} bare de 60 de minute. Cifrele "
"trade-ului sunt din exemplul materialului.", GREY),
]
add = 16 * len(linii) + 10
svg = svg.replace(f'viewBox="0 0 {W} {H}"', f'viewBox="0 0 {W} {H + add}"')
svg = svg.replace("</svg>", "".join(
f'<text x="24" y="{H + 10 + 16 * i}" fill="{c}">{t}</text>'
for i, (t, c) in enumerate(linii)) + "</svg>")
assert "\n\n" not in svg, "linie goală în SVG"
# ce se vede pe desen: ambele etichete trebuie să spună 2,0R, ca în material
assert f"(+{R_TINTA:.1f}R)" in svg and f"= {R_TINTA:.1f}R," in svg, \
"eticheta de ieșire nu afișează 2,0R"
assert "2.04R" not in svg, "a rămas eticheta veche cu 2.04R"
OUT.write_text(svg, encoding="utf-8")
print(f"scris {OUT.name} ({W}x{H + add}); ținta atinsă la bara {prim_tp} = +{R_TINTA:.1f}R")