etichete: cele trei care mint, si doua bug-uri de infrastructura
Cele trei, toate verificate pe ecran dupa reparatie: "minimul din care a pornit miscarea 99.80" intra sub o candela si se citea "99.8" (m2d_directie); "2 saptamani" era acoperita de caseta de citat si se citea "2 saptaman" (atmi_orizont); cele doua stopuri de la buy_doji_stop stateau la 12 px cu liniile incrucisate peste etichete, iar diagrama e tocmai despre diferenta dintre ele - acum fiecare sta la capatul propriei linii. Doua bug-uri gasite pe drum, mai grave decat ce reparam: 1. render_html trecea SVG-urile prin markdown. In mp2_pivoti_excel cele doua asteriscuri din formulele Excel (=2*E2-C2) deveneau un <em> pus peste </text>, iar parserul browserului arunca restul SVG-ului: jumatate de tabel lipsea din pagina, fara niciun semn in .md sau in audit. Acum SVG-urile sunt scoase din calea lui markdown si puse inapoi dupa, cu assert ca nu ramane niciun marcaj. 2. eticheta_libera nu citea <g transform>, deci la diagramele cu panouri compara coordonate din sisteme diferite si rata suprapuneri reale. Acum aplatizeaza translate/scale pe <g>-uri imbricate. Prima diagrama pe care a prins-o dupa reparatie e chiar una deja comisa, din capitolul 10. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
This commit is contained in:
@@ -17,6 +17,8 @@ from pathlib import Path
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
from svg_candles import Candle, Chart, Level, Zone, Arrow # noqa: E402
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
from eticheta_libera import eticheta_libera # noqa: E402
|
||||
from buy_doji_ansamblu import serie, DOJI, CONF, DOJI_L, ENTRY, SL, TP1, R # noqa: E402
|
||||
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
@@ -84,7 +86,11 @@ gata = Chart(
|
||||
candles=jos,
|
||||
levels=[Level(TP1, "ținta 1: 51.60", GREEN, "2 2", "left"),
|
||||
Level(ENTRY, "intrarea: 50.40", GREY, "4 3", "left"),
|
||||
Level(OCHI, "stop pus la ochi: 49.70", ORANGE, "4 3", "left"),
|
||||
# linia „la ochi" pornește de la bara de intrare, iar eticheta ei
|
||||
# stă în dreapta: pe toată lățimea, în stânga, cele două stopuri
|
||||
# cădeau la 12 px unul sub altul și linia portocalie trecea prin
|
||||
# eticheta celui din regulă — nu puteai atribui liniile
|
||||
Level(OCHI, "stop pus la ochi: 49.70", ORANGE, "4 3", i0=cf),
|
||||
Level(SL, "stopul din regulă: 49.20", RED, "4 3", "left")],
|
||||
# eticheta zonei o punem manual: Zone o ridică deasupra candelelor din
|
||||
# dreptul textului, adică departe de banda pe care o marchează
|
||||
@@ -111,7 +117,11 @@ def panou(ch, sus_de=0.0):
|
||||
h = float(re.search(r'viewBox="0 0 [\d.]+ ([\d.]+)"', svg).group(1))
|
||||
# render() mută `top` intern și îl restaurează; offsetul se citește din
|
||||
# prima linie de Level, altfel tot ce desenăm pe urmă iese mai sus cu ~22px
|
||||
off = float(re.search(r'<line x1="24" y1="([\d.]+)"', svg).group(1)) - ch._y(ch.levels[0].price)
|
||||
# „24.0", nu „24": svg_candles formatează începutul liniei cu :.1f de când
|
||||
# are Level.i0 — generatorul crăpa aici, nu mai era rulabil
|
||||
m = re.search(r'<line x1="24(?:\.0)?" y1="([\d.]+)"', svg)
|
||||
assert m, "nu găsesc prima linie de Level: s-a schimbat formatul din svg_candles"
|
||||
off = float(m.group(1)) - ch._y(ch.levels[0].price)
|
||||
return svg[svg.index(">") + 1:svg.rindex("</svg>")].strip(), h, off
|
||||
|
||||
|
||||
@@ -131,7 +141,7 @@ nums.append(f'<text x="24" y="{y_sub:.1f}" fill="#555">'
|
||||
h_sus = max(h_sus, y_sub + 12)
|
||||
|
||||
body_jos, h_jos, off_jos = panou(gata, h_sus + VGAP)
|
||||
zx = gata._cx(cf + 3) + 10
|
||||
zx = gata._cx(cf + 4) + 10 # dupa corpul candelei 14, nu peste el
|
||||
banda = (f'<text x="{zx:.1f}" y="{gata._y(OCHI) + off_jos - 6:.1f}" fill="{RED}" '
|
||||
f'style="font-weight:bold">pe aici trece al doilea picior</text>')
|
||||
H = h_jos + 8
|
||||
@@ -145,5 +155,17 @@ svg = "\n ".join([
|
||||
assert "\n\n" not in svg and "<svg" in svg, "linie goală în SVG"
|
||||
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})"
|
||||
# etichetele de nivel stau lipite de linia lor prin construcție, deci pentru
|
||||
# ele contează doar corpurile candelelor; pentru restul, și liniile
|
||||
eticheta_libera(svg, "buy_doji_stop", {"stop pus la ochi: 49.70",
|
||||
"stopul din regulă: 49.20",
|
||||
"intrarea: 50.40", "ținta 1: 51.60",
|
||||
"stopul: 49.20"}, rects=True, segmente=False,
|
||||
min_px=2.0) # marja mică: etichetele de nivel trec la ~8 px de
|
||||
# corpul candelei 7, iar CW supraestimează lățimea
|
||||
# eticheta benzii stă lipită deasupra liniei „la ochi", ca orice etichetă de
|
||||
# nivel: pentru ea contează doar candelele
|
||||
eticheta_libera(svg, "buy_doji_stop", {"pe aici trece al doilea picior"},
|
||||
rects=True, segmente=False)
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT} ({W}x{H:.0f})")
|
||||
|
||||
Reference in New Issue
Block a user