MODUL 5: ultimele patru suprapuneri de eticheta, si verificatorul scos in gen/eticheta_libera.py

Assert-ul care verifica daca o eticheta sta lipita de o linie a devenit modul
propriu, importat din ambele generatoare de patternuri. Vede acum si
<polyline> (mediile mobile - punctul lui orb) si, optional, corpurile
candelelor. Avea si un bug tacut: regexul cerea culoare pe 6 cifre, deci sarea
peste tot ce e desenat cu #c00, adica exact sagetile si nivelurile rosii. Are
demo() cu self-check.

La bull_flag eticheta SMA-20 nu e mutabila din generator - pozitia ei o
calculeaza svg_candles - asa ca media e numita in caption, ca la cup with
handle.

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 02:32:27 +00:00
parent aea592091e
commit 0dd358802d
7 changed files with 171 additions and 80 deletions

View File

@@ -10,7 +10,9 @@ import re
import sys
sys.path.insert(0, "/workspace/atm-curs-dl")
sys.path.insert(0, "/workspace/atm-curs-dl/gen")
from svg_candles import Chart, Level, Mark, MA, Zone, from_closes # noqa: E402
from eticheta_libera import eticheta_libera # noqa: E402
MD = "/workspace/atm-curs-dl/summaries/06_MODUL_5/02_patternuri_complexe_partea_a_treia.md"
@@ -25,7 +27,7 @@ def hi(cds, a, b):
return round(max(c.h for c in cds[a:b + 1]), 2)
def check(ch, name, distante=()):
def check(ch, name, distante=(), clear=(), clear_rect=()):
"""Nicio etichetă nu poate numi un preț care nu e un nivel desenat."""
svg = ch.render()
assert "\n\n" not in svg, f"{name}: linie goală în svg"
@@ -42,6 +44,10 @@ def check(ch, name, distante=()):
for lv in ch.levels:
assert ch._y(lv.price) > sus - 0.06 * (jos - sus), \
f"{name}: nivelul {lv.price} e lipit de marginea de sus"
if clear:
eticheta_libera(svg, name, set(clear))
if clear_rect: # etichete de nivel: doar peste candele e o problemă
eticheta_libera(svg, name, set(clear_rect), rects=True, segmente=False)
SVG[name] = svg
@@ -410,13 +416,14 @@ check(Chart(
Level(FUND_C, f"fundul ceștii {FUND_C:.2f}", "#b06000", label_at="left")],
marks=[Mark(5, "top 1", "#c00"), Mark(23, "top 2", "#c00", dy=-18),
Mark(13, "fundul ceștii", "#b06000", "below"),
Mark(29, "breakout", "#188a3e", dy=-14)],
Mark(29, "breakout", "#188a3e", dy=-68)],
zones=[Zone(24, 27, "mânerul", "#b06000")],
mas=[MA(20, "#777", dash="4 3")],
scale=4.2, gap=15, body_w=9, left=46, width=620, vol_h=70, top=100,
scale=4.2, gap=15, body_w=9, left=46, width=700, vol_h=70, top=100,
vol_label="volum", title="Cup with handle — exemplu construit (fără ticker), monthly",
caption="Mânerul: 4 bare, −30% din adâncime. Două top-uri la 120.00 = double top. Gri punctat: SMA-20."),
"cu", [AD_C, RIM_C - MANER])
"cu", [AD_C, RIM_C - MANER],
clear=("breakout",), clear_rect=(f"minimul mânerului {MANER:.2f}", "breakout"))
# ----------------------------------------- cup with handle: mâner prea adânc
closes_cn = ([99.0, 105.0, 111.0, 116.0, 119.5] # 0-4 uptrend + rim 1