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:
@@ -11,7 +11,8 @@ Același pattern ca formă (downtrend → hammer → confirmare), context opus:
|
||||
peste media ultimelor 10 bare — „acumulare";
|
||||
- dreapta (NU): fără downtrend real (range lateral 44–46), hammer-ul în
|
||||
mijlocul intervalului (o=45.00, c=h=45.10, l=44.10), departe de orice
|
||||
nivel (suportul construit 42.50 e la 3,6 % sub low), confirmarea închide
|
||||
nivel (suportul construit 42.50 e la 3,8 % sub nivel, cu aceeași convenție
|
||||
de măsurare ca la pasul A2: diferența împărțită la nivel), confirmarea închide
|
||||
tot 45.15 peste 45.10, dar pe volum slab — context invalid.
|
||||
|
||||
Nivelurile 42.00 / 42.50 și cifrele de preț sunt construite (materialul nu
|
||||
@@ -34,6 +35,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, Mark, from_closes # noqa: E402
|
||||
|
||||
OUT = Path(__file__).resolve().parent / "hammer_mbt10_bh_aplus.svg"
|
||||
@@ -115,9 +118,16 @@ assert cds_a[HAM_A].c < cds_a[0].c - 5, "downtrendul A+ nu e vizibil"
|
||||
# 5. NU: (low[12] - 42.50) / 42.50 > 0.02 (hammer-ul NU e departe de nivel)
|
||||
dist_n = (ham_n.l - SUPORT_N) / SUPORT_N
|
||||
assert dist_n > 0.02, f"low hammer NU {ham_n.l} prea aproape de 42.50 ({dist_n:.1%})"
|
||||
# eticheta „la -3,6 %" din spec: (44.10 - 42.50) / 44.10
|
||||
pct_n = (ham_n.l - SUPORT_N) / ham_n.l * 100
|
||||
assert round(pct_n, 1) == 3.6, f"procentul NU e {pct_n:.2f} %, nu 3,6 %"
|
||||
# „cât de departe e nivelul" se măsoară la fel în tot capitolul: diferența
|
||||
# împărțită la NIVEL, nu la low-ul hammer-ului (pasul A2 face așa, iar
|
||||
# eticheta de aici împărțea la low și dădea alt număr — 3,6 % în loc de 3,8 %)
|
||||
pct_n = (ham_n.l - SUPORT_N) / SUPORT_N * 100
|
||||
assert round(pct_n, 1) == 3.8, f"procentul NU e {pct_n:.2f} %, nu 3,8 %"
|
||||
# aceeași convenție pe panoul A+: 0,24 % = (42.00 - 41.90) / 42.00
|
||||
assert round(abs(ham_a.l - SUPORT_A) / SUPORT_A * 100, 2) == 0.24
|
||||
ET_NIVEL_N = ("fără nivel apropiat (suport 42.50 la −"
|
||||
+ f"{pct_n:.1f}".replace(".", ",") + " %)")
|
||||
|
||||
# 6. NU: close[13] > high[12] (tehnic valid)
|
||||
assert conf_n.c > ham_n.h, f"NU close {conf_n.c} <= high hammer {ham_n.h}"
|
||||
assert abs(conf_n.c - 45.15) < 1e-9
|
||||
@@ -160,7 +170,7 @@ ch_a = Chart(
|
||||
)
|
||||
ch_n = Chart(
|
||||
candles=cds_n,
|
||||
levels=[Level(SUPORT_N, "fără nivel apropiat (suport 42.50 la −3,6 %)", GRAY,
|
||||
levels=[Level(SUPORT_N, ET_NIVEL_N, GRAY,
|
||||
label_at="left")],
|
||||
marks=[Mark(HAM_N, "hammer în mijloc de range", ORANGE, "below", dy=0),
|
||||
Mark(CONF_N, "volum slab", RED, "above", dy=0)],
|
||||
@@ -188,6 +198,16 @@ svg_a, svg_n = ch_a.render(), ch_n.render()
|
||||
|
||||
HA, HN = vb_height(svg_a), vb_height(svg_n)
|
||||
assert svg_a.count("\n\n") == 0 and svg_n.count("\n\n") == 0, "linie goală în panou"
|
||||
# pe fiecare panou separat: wrapper-ul le mută cu <g transform>, iar
|
||||
# `eticheta_libera` citește coordonate brute, deci nu merge pe el.
|
||||
# Etichetele de nivel stau lipite de linia lor prin construcție (segmente=False);
|
||||
# ce nu au voie e să cadă peste candele sau peste barele de volum.
|
||||
eticheta_libera(svg_a, "bh_aplus/A+",
|
||||
{"suport monthly 42.00", "hammer la nivel (low 41.90)", "acumulare"},
|
||||
rects=True, segmente=False)
|
||||
eticheta_libera(svg_n, "bh_aplus/NU",
|
||||
{ET_NIVEL_N, "hammer în mijloc de range", "volum slab"},
|
||||
rects=True, segmente=False)
|
||||
|
||||
TOTAL_W = PAD + PW + PANEL_GAP + PW + PAD
|
||||
TOTAL_H = PAD + TITLE_H + max(HA, HN) + FOOTER_H + PAD
|
||||
@@ -269,7 +289,7 @@ for i in range(len(all_txt)):
|
||||
|
||||
# etichetele cerute de spec există în desen
|
||||
for cheie in ("suport monthly 42.00", "hammer la nivel", "acumulare",
|
||||
"fără nivel apropiat (suport 42.50 la −3,6 %)", "volum slab",
|
||||
ET_NIVEL_N, "volum slab",
|
||||
"A+ — hammer la suport monthly",
|
||||
"Mediocru — hammer fără nivel"):
|
||||
assert cheie in wrapper, f"lipsește din desen: {cheie!r}"
|
||||
|
||||
Reference in New Issue
Block a user