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
This commit is contained in:
Claude Agent
2026-10-02 05:29:33 +00:00
parent 80624653dc
commit f60d32cb34
20 changed files with 1156 additions and 987 deletions

View File

@@ -11,7 +11,8 @@ intrare.
REAL din curs (`18_2025-09-23.md:721-726`): că e buy hammer la suportul
monthly și că a dat +20 % în jumătate de lună. CONSTRUITE de sumarizator:
suportul 80.00, cifrele hammer-ului (80.80/80.90/79.60), intrarea 81.30, SL
79.60 și seria de prețuri — materialul nu dă entry, SL sau TP pentru cazul
79.55 (low − 5 cenți, regula proprie a capitolului) și seria de prețuri —
materialul nu dă entry, SL sau TP pentru cazul
ăsta. Legenda din desen spune exact asta.
Rulare: python3 gen/strategii/hammer_mbt10_bh_labu.py
@@ -21,6 +22,8 @@ import sys
from pathlib import Path
sys.path.insert(0, "/workspace/atm-curs-dl")
sys.path.insert(0, "/workspace/atm-curs-dl/gen")
from eticheta_libera import eticheta_libera # noqa: E402
from svg_candles import Chart, Level, MA, Mark, from_closes # noqa: E402
OUT = Path(__file__).with_suffix(".svg")
@@ -28,9 +31,9 @@ OUT = Path(__file__).with_suffix(".svg")
# --- nivelurile din specificație (toate CONSTRUITE) ------------------------
SUPPORT = 80.00 # suport monthly (construit)
HAMMER_H = 80.90 # high-ul hammer-ului = close (H=C)
HAMMER_L = 79.60 # low-ul hammer-ului = SL propus
HAMMER_L = 79.60 # low-ul hammer-ului
ENTRY = 81.30 # intrare = close-ul confirmării, peste 80.90 (construit)
SL = 79.60 # SL sub low-ul hammer-ului (construit)
SL = 79.55 # low 79.60 − 5 cenți: marja folosită în tot capitolul
PEAK = 97.56 # max close de după intrare: 97.56 / 81.30 = +20,0 % (real)
# --- seria de close-uri din specificație (38 bare, o = close precedent) ----
@@ -89,10 +92,14 @@ assert cds[23].c == cds[23].h == HAMMER_H, "close[23] != high[23] == 80.90"
assert abs(cds[24].c - ENTRY) < 1e-9, f"close[24]={cds[24].c} != intrare 81.30"
assert cds[24].c > cds[23].h == HAMMER_H, "confirmarea nu închide peste 80.90"
# 4. SL = min(low[22:25]) = low-ul hammer-ului = 79.60
# 4. SL = low-ul hammer-ului (cel mai jos din 22:25) minus marja de 5 cenți.
# Prețurile LABU sunt construite, deci se aplică regula proprie din capitol
# (summaries/17_STRATEGII/06_hammer_mbt10.md, pasul A4): stopul nu stă
# exact pe low, ci cu 5 cenți sub el.
min_22_25 = min(c.l for c in cds[22:25])
assert abs(min_22_25 - SL) < 1e-9, f"min low[22:25]={min_22_25} != SL {SL}"
assert abs(SL - cds[23].l) < 1e-9, "SL nu e low-ul hammer-ului"
assert abs(min_22_25 - cds[23].l) < 1e-9, f"min low[22:25]={min_22_25} != low[23]"
assert abs(SL - (cds[23].l - 0.05)) < 1e-9, f"SL {SL} nu e low 79.60 − 5 cenți"
assert SL < min_22_25, "linia stopului trebuie să stea sub toate fitilele"
# 5. procentul REAL al cursului: +20,0 % de la intrare la vârf
peak = max(c.c for c in cds[25:38])
@@ -115,7 +122,7 @@ ch = Chart(
levels=[
Level(SUPPORT, "suport monthly 80.00", "#777",
dash="4 3", label_at="left"),
Level(SL, "SL sub low-ul hammer-ului 79.60 (construit)", "#c00",
Level(SL, "SL 79.55 = low 79.60 − 5 cenți (construit)", "#c00",
label_at="right"),
Level(ENTRY, "intrare 81.30 (construit)", "#188a3e", label_at="right"),
],
@@ -140,6 +147,11 @@ cds[2].note = ("Procentul (+20 % în jumătate de lună) și contextul (suport "
svg = ch.render()
assert "\n\n" not in svg and "<svg" in svg, "SVG invalid (linie goală?)"
# eticheta de stop stă lipită de linia ei prin construcție: verificăm doar
# candelele și media mobilă de sub ea
eticheta_libera(svg, "bh_labu",
{"SL 79.55 = low 79.60 − 5 cenți (construit)",
"hammer 80.90 / 79.60 (construit)"}, rects=True, segmente=False)
# --- citirea SVG-ului: etichete în panză, fără suprapuneri -----------------
TEXT = re.compile(r'<text x="([-\d.]+)" y="([-\d.]+)"([^>]*)>(.*?)</text>', re.S)
@@ -171,7 +183,7 @@ assert xs[-1] + ch.body_w / 2 < w, f"ultima candelă iese din panză (x={xs[-1]}
assert all(xs[i + 1] - xs[i] == ch.gap for i in range(len(xs) - 1)), "serie cu goluri"
print(f"LABU: {len(cds)} bare, hammer {cds[23].l:.2f}/{cds[23].h:.2f} pe suport "
f"{SUPPORT:.2f}, intrare {entry:.2f}, SL {cds[23].l:.2f}, vârf {peak:.2f}")
f"{SUPPORT:.2f}, intrare {entry:.2f}, SL {SL:.2f}, vârf {peak:.2f}")
print(f"procent: {peak:.2f} / {entry:.2f} - 1 = +{pct:.1f} % (cifra cursului)")
print(f"scris {OUT} ({w}x{H:.0f}); {len(labels)} etichete verificate, fără suprapuneri")
OUT.write_text(svg, encoding="utf-8")