From 3a6da7a9165b106d70ef96740dd22ea13dd82301 Mon Sep 17 00:00:00 2001
From: Claude Agent
Date: Fri, 18 Sep 2026 16:52:01 +0000
Subject: [PATCH] cele 7 diagrame din 11_selectia
Sunt diagrame conceptuale - funnel, bara de scor, matrice, cele patru
cadrane, Trinity, sectoare - nu grafice de pret, deci nu trec prin
svg_candles / pchart, care raman obligatorii doar pentru candele si
entry/SL/TP. Agent nou, diagramist, cate unul per diagrama, fiecare cu
generatorul lui in gen/selectia/; substitutia in .md o face
gen/az_selectia.py, ca sa nu scrie sapte agenti in acelasi fisier.
Regula de continut a agentului: fiecare cifra si eticheta trebuie sa
existe in document sau in citate. Ce nu reiese din sursa e scris pe
desen ca atare - ordinea celor 7 sectoare, ce se intampla sub 100%
relative volume. Fara semafor rosu/verde, care nu e in sursa.
Verificat cu ochii pe doua diagrame randate in browser.
Co-Authored-By: Claude Opus 5
Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
---
.opencode/agents/diagramist.md | 49 +++
.opencode/lot_diagrame.txt | 7 +
.opencode/lot_diagrame_rest.txt | 4 +
.opencode/mk_lot_diagrame.py | 67 ++++
gen/az_selectia.py | 28 ++
gen/selectia/cadrane.py | 187 ++++++++++++
gen/selectia/cadrane.spec.txt | 1 +
gen/selectia/cadrane.svg | 39 +++
gen/selectia/cash_flow.py | 195 ++++++++++++
gen/selectia/cash_flow.spec.txt | 1 +
gen/selectia/cash_flow.svg | 41 +++
gen/selectia/funnel.py | 146 +++++++++
gen/selectia/funnel.spec.txt | 1 +
gen/selectia/funnel.svg | 36 +++
gen/selectia/pe_venit.py | 122 ++++++++
gen/selectia/pe_venit.spec.txt | 1 +
gen/selectia/pe_venit.svg | 32 ++
gen/selectia/scor.py | 100 ++++++
gen/selectia/scor.spec.txt | 1 +
gen/selectia/scor.svg | 30 ++
gen/selectia/sectoare.py | 232 ++++++++++++++
gen/selectia/sectoare.spec.txt | 1 +
gen/selectia/sectoare.svg | 53 ++++
gen/selectia/trinity.py | 158 ++++++++++
gen/selectia/trinity.spec.txt | 1 +
gen/selectia/trinity.svg | 36 +++
.../11_selectia_simbolului.html | 288 +++++++++++++++++-
.../11_selectia_simbolului.md | 288 +++++++++++++++++-
28 files changed, 2131 insertions(+), 14 deletions(-)
create mode 100644 .opencode/agents/diagramist.md
create mode 100644 .opencode/lot_diagrame.txt
create mode 100644 .opencode/lot_diagrame_rest.txt
create mode 100644 .opencode/mk_lot_diagrame.py
create mode 100644 gen/az_selectia.py
create mode 100644 gen/selectia/cadrane.py
create mode 100644 gen/selectia/cadrane.spec.txt
create mode 100644 gen/selectia/cadrane.svg
create mode 100644 gen/selectia/cash_flow.py
create mode 100644 gen/selectia/cash_flow.spec.txt
create mode 100644 gen/selectia/cash_flow.svg
create mode 100644 gen/selectia/funnel.py
create mode 100644 gen/selectia/funnel.spec.txt
create mode 100644 gen/selectia/funnel.svg
create mode 100644 gen/selectia/pe_venit.py
create mode 100644 gen/selectia/pe_venit.spec.txt
create mode 100644 gen/selectia/pe_venit.svg
create mode 100644 gen/selectia/scor.py
create mode 100644 gen/selectia/scor.spec.txt
create mode 100644 gen/selectia/scor.svg
create mode 100644 gen/selectia/sectoare.py
create mode 100644 gen/selectia/sectoare.spec.txt
create mode 100644 gen/selectia/sectoare.svg
create mode 100644 gen/selectia/trinity.py
create mode 100644 gen/selectia/trinity.spec.txt
create mode 100644 gen/selectia/trinity.svg
diff --git a/.opencode/agents/diagramist.md b/.opencode/agents/diagramist.md
new file mode 100644
index 0000000..7c21588
--- /dev/null
+++ b/.opencode/agents/diagramist.md
@@ -0,0 +1,49 @@
+---
+description: Desenează o diagramă conceptuală (nu grafic de preț) ca SVG, dintr-o specificație
+mode: all
+model: opencode-go/deepseek-v4.1-flash
+temperature: 0.1
+permission:
+ read: allow
+ glob: allow
+ grep: allow
+ list: allow
+ edit: allow
+ bash: allow
+ webfetch: deny
+ websearch: deny
+ task: deny
+---
+Lucrezi în /workspace/atm-curs-dl. Desenezi **o singură** diagramă, într-un
+singur fișier, al tău: `gen/selectia/.py`, care scrie
+`gen/selectia/.svg`.
+
+Diagramele tale sunt **conceptuale** — funnel, matrice, cadrane, coloane
+comparate. Nu sunt grafice de preț. De aceea **nu** folosești `svg_candles`
+și `pchart`: alea desenează candele, și orice diagramă cu candele sau cu
+entry/SL/TP trebuie să treacă prin ele. A ta nu.
+
+REGULA DE CONȚINUT, cea mai importantă: fiecare cifră și fiecare etichetă din
+desen trebuie să existe în documentul în care intră diagrama sau în citatele
+lui. Un desen inventează mai ușor decât un paragraf, pentru că arată
+convingător. Dacă specificația cere un prag, un procent sau un cod de culoare
+cu înțeles (roșu/verde ca semafor) pe care textul nu-l susține, îl lași afară
+și spui în raport de ce.
+
+FORMĂ: lățime 700, `font-family: system-ui, sans-serif`, minim 13px, text
+negru pe alb, fără umbre și fără gradienți. Accente, dacă ai nevoie:
+`#777` gri, `#c00` roșu, `#188a3e` verde, `#1a5fb4` albastru, `#b06000`
+portocaliu. Pagina se citește și pe telefon: nu înghesui text sub 13px și nu
+lăsa etichete care se suprapun.
+
+VERIFICARE, în sarcina ta: rulează generatorul, apoi **citește SVG-ul
+rezultat** și confirmă că fiecare etichetă are coordonate în interiorul
+pânzei, că nu se suprapun două texte pe aceeași poziție și că toate cifrele
+sunt cele din document. Dacă se bat, rearanjezi și rulezi din nou. Un
+generator care rulează fără eroare nu e dovadă că desenul se citește.
+
+INTERZIS: alt fișier decât generatorul tău și SVG-ul lui (nu atingi `.md`-ul,
+nu atingi generatoarele altora), `git commit`, sub-agenți.
+
+RAPORT scurt: ce arată diagrama, ce cifre ai folosit și de unde vin, ce ai
+lăsat afară din specificație și de ce, și ce ai verificat citind SVG-ul.
diff --git a/.opencode/lot_diagrame.txt b/.opencode/lot_diagrame.txt
new file mode 100644
index 0000000..eb2274b
--- /dev/null
+++ b/.opencode/lot_diagrame.txt
@@ -0,0 +1,7 @@
+funnel Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: gen/selectia/funnel.py . Nu atinge niciun alt fisier - nici documentul .md, nici generatoarele altora. Ce desenezi: citeste specificatia cu cat gen/selectia/funnel.spec.txt . Contextul in care intra diagrama: deschide summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul (grep -n il gaseste) si citeste 60 de linii in jur - diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si spune in raport. Nu inventa praguri, procente sau culori cu inteles (rosu/verde ca semafor) care nu sunt in sursa. Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il scrie in gen/selectia/funnel.svg . NU folosi svg_candles / pchart - alea sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, #b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text sub 13px si nu lasa etichete care se suprapun. VERIFICARE, in sarcina ta, nu optionala: ruleaza .venv/bin/python gen/selectia/funnel.py , apoi deschide SVG-ul rezultat si CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie si ca toate cifrele sunt cele din document. Daca doua etichete se bat, rearanjeaza si ruleaza din nou. Daca ajungi la ~250k tokeni, opreste-te si raporteaza. INTERZIS: alt fisier, git commit, sub-agenti. RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai lasat afara din spec si de ce, si ce ai verificat citind SVG-ul.
+scor Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: gen/selectia/scor.py . Nu atinge niciun alt fisier - nici documentul .md, nici generatoarele altora. Ce desenezi: citeste specificatia cu cat gen/selectia/scor.spec.txt . Contextul in care intra diagrama: deschide summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul (grep -n il gaseste) si citeste 60 de linii in jur - diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si spune in raport. Nu inventa praguri, procente sau culori cu inteles (rosu/verde ca semafor) care nu sunt in sursa. Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il scrie in gen/selectia/scor.svg . NU folosi svg_candles / pchart - alea sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, #b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text sub 13px si nu lasa etichete care se suprapun. VERIFICARE, in sarcina ta, nu optionala: ruleaza .venv/bin/python gen/selectia/scor.py , apoi deschide SVG-ul rezultat si CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie si ca toate cifrele sunt cele din document. Daca doua etichete se bat, rearanjeaza si ruleaza din nou. Daca ajungi la ~250k tokeni, opreste-te si raporteaza. INTERZIS: alt fisier, git commit, sub-agenti. RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai lasat afara din spec si de ce, si ce ai verificat citind SVG-ul.
+pe_venit Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: gen/selectia/pe_venit.py . Nu atinge niciun alt fisier - nici documentul .md, nici generatoarele altora. Ce desenezi: citeste specificatia cu cat gen/selectia/pe_venit.spec.txt . Contextul in care intra diagrama: deschide summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul (grep -n il gaseste) si citeste 60 de linii in jur - diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si spune in raport. Nu inventa praguri, procente sau culori cu inteles (rosu/verde ca semafor) care nu sunt in sursa. Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il scrie in gen/selectia/pe_venit.svg . NU folosi svg_candles / pchart - alea sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, #b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text sub 13px si nu lasa etichete care se suprapun. VERIFICARE, in sarcina ta, nu optionala: ruleaza .venv/bin/python gen/selectia/pe_venit.py , apoi deschide SVG-ul rezultat si CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie si ca toate cifrele sunt cele din document. Daca doua etichete se bat, rearanjeaza si ruleaza din nou. Daca ajungi la ~250k tokeni, opreste-te si raporteaza. INTERZIS: alt fisier, git commit, sub-agenti. RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai lasat afara din spec si de ce, si ce ai verificat citind SVG-ul.
+cash_flow Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: gen/selectia/cash_flow.py . Nu atinge niciun alt fisier - nici documentul .md, nici generatoarele altora. Ce desenezi: citeste specificatia cu cat gen/selectia/cash_flow.spec.txt . Contextul in care intra diagrama: deschide summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul (grep -n il gaseste) si citeste 60 de linii in jur - diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si spune in raport. Nu inventa praguri, procente sau culori cu inteles (rosu/verde ca semafor) care nu sunt in sursa. Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il scrie in gen/selectia/cash_flow.svg . NU folosi svg_candles / pchart - alea sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, #b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text sub 13px si nu lasa etichete care se suprapun. VERIFICARE, in sarcina ta, nu optionala: ruleaza .venv/bin/python gen/selectia/cash_flow.py , apoi deschide SVG-ul rezultat si CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie si ca toate cifrele sunt cele din document. Daca doua etichete se bat, rearanjeaza si ruleaza din nou. Daca ajungi la ~250k tokeni, opreste-te si raporteaza. INTERZIS: alt fisier, git commit, sub-agenti. RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai lasat afara din spec si de ce, si ce ai verificat citind SVG-ul.
+cadrane Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: gen/selectia/cadrane.py . Nu atinge niciun alt fisier - nici documentul .md, nici generatoarele altora. Ce desenezi: citeste specificatia cu cat gen/selectia/cadrane.spec.txt . Contextul in care intra diagrama: deschide summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul (grep -n il gaseste) si citeste 60 de linii in jur - diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si spune in raport. Nu inventa praguri, procente sau culori cu inteles (rosu/verde ca semafor) care nu sunt in sursa. Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il scrie in gen/selectia/cadrane.svg . NU folosi svg_candles / pchart - alea sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, #b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text sub 13px si nu lasa etichete care se suprapun. VERIFICARE, in sarcina ta, nu optionala: ruleaza .venv/bin/python gen/selectia/cadrane.py , apoi deschide SVG-ul rezultat si CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie si ca toate cifrele sunt cele din document. Daca doua etichete se bat, rearanjeaza si ruleaza din nou. Daca ajungi la ~250k tokeni, opreste-te si raporteaza. INTERZIS: alt fisier, git commit, sub-agenti. RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai lasat afara din spec si de ce, si ce ai verificat citind SVG-ul.
+trinity Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: gen/selectia/trinity.py . Nu atinge niciun alt fisier - nici documentul .md, nici generatoarele altora. Ce desenezi: citeste specificatia cu cat gen/selectia/trinity.spec.txt . Contextul in care intra diagrama: deschide summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul (grep -n il gaseste) si citeste 60 de linii in jur - diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si spune in raport. Nu inventa praguri, procente sau culori cu inteles (rosu/verde ca semafor) care nu sunt in sursa. Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il scrie in gen/selectia/trinity.svg . NU folosi svg_candles / pchart - alea sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, #b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text sub 13px si nu lasa etichete care se suprapun. VERIFICARE, in sarcina ta, nu optionala: ruleaza .venv/bin/python gen/selectia/trinity.py , apoi deschide SVG-ul rezultat si CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie si ca toate cifrele sunt cele din document. Daca doua etichete se bat, rearanjeaza si ruleaza din nou. Daca ajungi la ~250k tokeni, opreste-te si raporteaza. INTERZIS: alt fisier, git commit, sub-agenti. RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai lasat afara din spec si de ce, si ce ai verificat citind SVG-ul.
+sectoare Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: gen/selectia/sectoare.py . Nu atinge niciun alt fisier - nici documentul .md, nici generatoarele altora. Ce desenezi: citeste specificatia cu cat gen/selectia/sectoare.spec.txt . Contextul in care intra diagrama: deschide summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul (grep -n il gaseste) si citeste 60 de linii in jur - diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si spune in raport. Nu inventa praguri, procente sau culori cu inteles (rosu/verde ca semafor) care nu sunt in sursa. Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il scrie in gen/selectia/sectoare.svg . NU folosi svg_candles / pchart - alea sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, #b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text sub 13px si nu lasa etichete care se suprapun. VERIFICARE, in sarcina ta, nu optionala: ruleaza .venv/bin/python gen/selectia/sectoare.py , apoi deschide SVG-ul rezultat si CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie si ca toate cifrele sunt cele din document. Daca doua etichete se bat, rearanjeaza si ruleaza din nou. Daca ajungi la ~250k tokeni, opreste-te si raporteaza. INTERZIS: alt fisier, git commit, sub-agenti. RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai lasat afara din spec si de ce, si ce ai verificat citind SVG-ul.
diff --git a/.opencode/lot_diagrame_rest.txt b/.opencode/lot_diagrame_rest.txt
new file mode 100644
index 0000000..c41cc21
--- /dev/null
+++ b/.opencode/lot_diagrame_rest.txt
@@ -0,0 +1,4 @@
+cash_flow Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: gen/selectia/cash_flow.py . Nu atinge niciun alt fisier - nici documentul .md, nici generatoarele altora. Ce desenezi: citeste specificatia cu cat gen/selectia/cash_flow.spec.txt . Contextul in care intra diagrama: deschide summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul (grep -n il gaseste) si citeste 60 de linii in jur - diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si spune in raport. Nu inventa praguri, procente sau culori cu inteles (rosu/verde ca semafor) care nu sunt in sursa. Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il scrie in gen/selectia/cash_flow.svg . NU folosi svg_candles / pchart - alea sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, #b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text sub 13px si nu lasa etichete care se suprapun. VERIFICARE, in sarcina ta, nu optionala: ruleaza .venv/bin/python gen/selectia/cash_flow.py , apoi deschide SVG-ul rezultat si CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie si ca toate cifrele sunt cele din document. Daca doua etichete se bat, rearanjeaza si ruleaza din nou. Daca ajungi la ~250k tokeni, opreste-te si raporteaza. INTERZIS: alt fisier, git commit, sub-agenti. RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai lasat afara din spec si de ce, si ce ai verificat citind SVG-ul.
+cadrane Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: gen/selectia/cadrane.py . Nu atinge niciun alt fisier - nici documentul .md, nici generatoarele altora. Ce desenezi: citeste specificatia cu cat gen/selectia/cadrane.spec.txt . Contextul in care intra diagrama: deschide summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul (grep -n il gaseste) si citeste 60 de linii in jur - diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si spune in raport. Nu inventa praguri, procente sau culori cu inteles (rosu/verde ca semafor) care nu sunt in sursa. Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il scrie in gen/selectia/cadrane.svg . NU folosi svg_candles / pchart - alea sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, #b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text sub 13px si nu lasa etichete care se suprapun. VERIFICARE, in sarcina ta, nu optionala: ruleaza .venv/bin/python gen/selectia/cadrane.py , apoi deschide SVG-ul rezultat si CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie si ca toate cifrele sunt cele din document. Daca doua etichete se bat, rearanjeaza si ruleaza din nou. Daca ajungi la ~250k tokeni, opreste-te si raporteaza. INTERZIS: alt fisier, git commit, sub-agenti. RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai lasat afara din spec si de ce, si ce ai verificat citind SVG-ul.
+trinity Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: gen/selectia/trinity.py . Nu atinge niciun alt fisier - nici documentul .md, nici generatoarele altora. Ce desenezi: citeste specificatia cu cat gen/selectia/trinity.spec.txt . Contextul in care intra diagrama: deschide summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul (grep -n il gaseste) si citeste 60 de linii in jur - diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si spune in raport. Nu inventa praguri, procente sau culori cu inteles (rosu/verde ca semafor) care nu sunt in sursa. Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il scrie in gen/selectia/trinity.svg . NU folosi svg_candles / pchart - alea sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, #b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text sub 13px si nu lasa etichete care se suprapun. VERIFICARE, in sarcina ta, nu optionala: ruleaza .venv/bin/python gen/selectia/trinity.py , apoi deschide SVG-ul rezultat si CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie si ca toate cifrele sunt cele din document. Daca doua etichete se bat, rearanjeaza si ruleaza din nou. Daca ajungi la ~250k tokeni, opreste-te si raporteaza. INTERZIS: alt fisier, git commit, sub-agenti. RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai lasat afara din spec si de ce, si ce ai verificat citind SVG-ul.
+sectoare Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: gen/selectia/sectoare.py . Nu atinge niciun alt fisier - nici documentul .md, nici generatoarele altora. Ce desenezi: citeste specificatia cu cat gen/selectia/sectoare.spec.txt . Contextul in care intra diagrama: deschide summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul (grep -n il gaseste) si citeste 60 de linii in jur - diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si spune in raport. Nu inventa praguri, procente sau culori cu inteles (rosu/verde ca semafor) care nu sunt in sursa. Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il scrie in gen/selectia/sectoare.svg . NU folosi svg_candles / pchart - alea sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, #b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text sub 13px si nu lasa etichete care se suprapun. VERIFICARE, in sarcina ta, nu optionala: ruleaza .venv/bin/python gen/selectia/sectoare.py , apoi deschide SVG-ul rezultat si CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie si ca toate cifrele sunt cele din document. Daca doua etichete se bat, rearanjeaza si ruleaza din nou. Daca ajungi la ~250k tokeni, opreste-te si raporteaza. INTERZIS: alt fisier, git commit, sub-agenti. RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai lasat afara din spec si de ce, si ce ai verificat citind SVG-ul.
diff --git a/.opencode/mk_lot_diagrame.py b/.opencode/mk_lot_diagrame.py
new file mode 100644
index 0000000..a13240c
--- /dev/null
+++ b/.opencode/mk_lot_diagrame.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+"""Pregateste cele 7 diagrame din 11_selectia_simbolului:
+- inlocuieste cu perechea de markeri ,
+ pastrand spec-ul intr-un fisier separat (specs/.txt), ca sa nu-l pierdem;
+- scrie .opencode/lot_diagrame.txt, cate o sarcina per diagrama.
+
+Fiecare agent scrie DOAR gen/selectia/.py, care produce
+gen/selectia/.svg. Substitutia in .md o face orchestratorul cu
+gen/az_selectia.py, ca sa nu scrie sapte agenti in acelasi fisier.
+"""
+import pathlib
+import re
+
+MD = pathlib.Path("summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md")
+OUT = pathlib.Path("gen/selectia")
+OUT.mkdir(parents=True, exist_ok=True)
+
+CHEI = ["funnel", "scor", "pe_venit", "cash_flow", "cadrane", "trinity", "sectoare"]
+
+md = MD.read_text(encoding="utf-8")
+specs = re.findall(r"", md, re.S)
+assert len(specs) == len(CHEI), f"{len(specs)} marcaje, {len(CHEI)} chei"
+
+for cheie, spec in zip(CHEI, specs):
+ (OUT / f"{cheie}.spec.txt").write_text(spec.strip() + "\n", encoding="utf-8")
+ md = md.replace(
+ f"", f"\n", 1
+ )
+MD.write_text(md, encoding="utf-8")
+
+P = (
+ "Lucrezi in /workspace/atm-curs-dl. Scrii UN SINGUR fisier: "
+ "gen/selectia/{cheie}.py . Nu atinge niciun alt fisier - nici documentul .md, "
+ "nici generatoarele altora. "
+ "Ce desenezi: citeste specificatia cu cat gen/selectia/{cheie}.spec.txt . "
+ "Contextul in care intra diagrama: deschide "
+ "summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md la marcajul "
+ " (grep -n il gaseste) si citeste 60 de linii in jur - "
+ "diagrama trebuie sa spuna ce spune textul de acolo, cu aceleasi cifre. "
+ "Fiecare cifra si fiecare eticheta din diagrama trebuie sa existe in text sau "
+ "in citatele lui; daca spec-ul cere ceva ce textul nu sustine, lasa afara si "
+ "spune in raport. Nu inventa praguri, procente sau culori cu inteles "
+ "(rosu/verde ca semafor) care nu sunt in sursa. "
+ "Cum scrii: Python fara dependinte, care construieste SVG-ul ca string si il "
+ "scrie in gen/selectia/{cheie}.svg . NU folosi svg_candles / pchart - alea "
+ "sunt pentru grafice de pret, iar asta nu e un grafic de pret. Latime 700, "
+ "font-family system-ui / sans-serif, font-size minim 13, text negru pe fundal "
+ "alb, fara umbre si fara gradienti. Culorile din celelalte generatoare, daca "
+ "ai nevoie de accente: #777 gri, #c00 rosu, #188a3e verde, #1a5fb4 albastru, "
+ "#b06000 portocaliu. Pagina se citeste si pe telefon, deci nu inghesui text "
+ "sub 13px si nu lasa etichete care se suprapun. "
+ "VERIFICARE, in sarcina ta, nu optionala: ruleaza "
+ ".venv/bin/python gen/selectia/{cheie}.py , apoi deschide SVG-ul rezultat si "
+ "CITESTE-L (cat / grep) ca sa confirmi ca fiecare eticheta are coordonate in "
+ "interiorul panzei (viewBox), ca nu se suprapun doua texte pe aceeasi pozitie "
+ "si ca toate cifrele sunt cele din document. Daca doua etichete se bat, "
+ "rearanjeaza si ruleaza din nou. "
+ "Daca ajungi la ~250k tokeni, opreste-te si raporteaza. "
+ "INTERZIS: alt fisier, git commit, sub-agenti. "
+ "RAPORT scurt: ce arata diagrama, ce cifre ai folosit si de unde vin, ce ai "
+ "lasat afara din spec si de ce, si ce ai verificat citind SVG-ul."
+)
+
+pathlib.Path(".opencode/lot_diagrame.txt").write_text(
+ "\n".join(f"{c}\t{P.format(cheie=c)}" for c in CHEI) + "\n"
+)
+print(len(CHEI), "sarcini; markerii sunt in .md, spec-urile in gen/selectia/")
diff --git a/gen/az_selectia.py b/gen/az_selectia.py
new file mode 100644
index 0000000..429bb40
--- /dev/null
+++ b/gen/az_selectia.py
@@ -0,0 +1,28 @@
+"""Bagă cele 7 diagrame din gen/selectia/*.svg în 11_selectia_simbolului.md.
+
+Diagramele sunt conceptuale (funnel, bară de scor, matrice, cadrane, Trinity,
+sectoare), nu grafice de preț — de aceea nu trec prin svg_candles/pchart.
+Fiecare are generatorul ei în gen/selectia/.py; ăsta doar le rulează
+și le substituie între markeri, ca să nu scrie mai mulți agenți în .md.
+
+Rulează: .venv/bin/python gen/az_selectia.py
+"""
+import re
+import subprocess
+import sys
+from pathlib import Path
+
+ROOT = Path(__file__).resolve().parent.parent
+MD = ROOT / "summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md"
+GEN = ROOT / "gen/selectia"
+CHEI = ["funnel", "scor", "pe_venit", "cash_flow", "cadrane", "trinity", "sectoare"]
+
+md = MD.read_text(encoding="utf-8")
+for cheie in CHEI:
+ subprocess.run([sys.executable, str(GEN / f"{cheie}.py")], check=True, cwd=ROOT)
+ svg = (GEN / f"{cheie}.svg").read_text(encoding="utf-8").strip()
+ pat = re.compile(rf".*?", re.S)
+ assert pat.search(md), f"marcatorul {cheie} lipsește din .md"
+ md = pat.sub(lambda _m: f"\n{svg}\n", md)
+MD.write_text(md, encoding="utf-8")
+print("scris", MD)
diff --git a/gen/selectia/cadrane.py b/gen/selectia/cadrane.py
new file mode 100644
index 0000000..eca3c84
--- /dev/null
+++ b/gen/selectia/cadrane.py
@@ -0,0 +1,187 @@
+#!/usr/bin/env python3
+"""Harta celor patru cadrane relative strength, fata de benchmark.
+
+Pentru `summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md` (SVG:cadrane),
+sectiunea 2.1. Nu e grafic de pret, deci nu se folosesc svg_candles / pchart:
+SVG scris de mana, doar stdlib.
+
+Ce arata: cadranele 1-4 asa cum le descrie documentul, grupate pe directie.
+Randul de sus = conditia de intrare LONG (cadranele 1 si 2), randul de jos =
+conditia de intrare SHORT (cadranele 3 si 4); sageti duble grupeaza perechile.
+Fiecare cadran are numarul, sensul si directia.
+
+Etichete si cifre, toate din text/glosar (fara axe inventate, fara procente):
+- RS = cat de bine se misca simbolul fata de benchmark (ex. SPY) (.md:62)
+- cadran 1 = supraperformanta, bate benchmark-ul, long (.md:63,310)
+- cadran 2 = imbunatatire spre supraperformanta, zona de cumparat,
+ la long, de preferat (.md:64,311)
+- cadran 3 = imbunatatire spre underperform, pentru short (.md:65,312)
+- cadran 4 = underperform, pierde in fata benchmark-ului,
+ short / stai pe margine (.md:66,313)
+- cadranul 4 nu se tranzactioneaza pe orb: astepti trecerea in 2 sau 1,
+ ori un MP4-1 / MBT-10 long ca semn de schimbare (.md:315-316)
+- setup de bottom cu RS fara imbunatatire: sanse mai mici (.md:323-324)
+
+Fara semafor rosu/verde (nu e in sursa); un singur accent albastru pe
+chenare/sageti/numere, text negru pe fundal alb.
+Ruleaza: .venv/bin/python gen/selectia/cadrane.py -> gen/selectia/cadrane.svg
+"""
+from pathlib import Path
+from xml.sax.saxutils import escape
+
+OUT = Path(__file__).with_suffix(".svg")
+
+W, H = 700, 580
+BLACK, GRAY, BLUE, WHITE = "#000000", "#777777", "#1a5fb4", "#ffffff"
+
+COL1_X, COL_W, GAP = 40, 290, 40
+COL2_X = COL1_X + COL_W + GAP # 370
+COL1_R = COL1_X + COL_W # 330
+COL2_R = COL2_X + COL_W # 660
+
+CARD_H = 150
+ROW1_Y, ROW2_Y = 86, 302
+ROW1_B, ROW2_B = ROW1_Y + CARD_H, ROW2_Y + CARD_H # 236 / 452
+BR1_Y, BR2_Y = ROW1_B + 14, ROW2_B + 14 # 250 / 466
+
+# fiecare card: (x, y, linii [(dy, text, size, weight, fill)])
+CARDS = [
+ (COL1_X, ROW1_Y, [
+ (34, "Cadran 1", 16, "700", BLACK),
+ (68, "supraperformanță", 14, "400", BLACK),
+ (96, "bate benchmark-ul", 13, "400", GRAY),
+ (124, "LONG", 13, "700", BLUE),
+ ]),
+ (COL2_X, ROW1_Y, [
+ (34, "Cadran 2", 16, "700", BLACK),
+ (66, "îmbunătățire spre", 14, "400", BLACK),
+ (86, "supraperformanță", 14, "400", BLACK),
+ (110, "zona de cumpărat, la long", 13, "400", GRAY),
+ (132, "LONG", 13, "700", BLUE),
+ ]),
+ (COL1_X, ROW2_Y, [
+ (34, "Cadran 3", 16, "700", BLACK),
+ (66, "îmbunătățire spre", 14, "400", BLACK),
+ (86, "underperform", 14, "400", BLACK),
+ (110, "pentru short", 13, "400", GRAY),
+ (132, "SHORT", 13, "700", BLUE),
+ ]),
+ (COL2_X, ROW2_Y, [
+ (34, "Cadran 4", 16, "700", BLACK),
+ (68, "underperform", 14, "400", BLACK),
+ (96, "pierde în fața benchmark-ului", 13, "400", GRAY),
+ (124, "SHORT / stai pe margine", 13, "700", BLUE),
+ ]),
+]
+
+TEXTS = [] # (x, y, text, size, weight, anchor) pentru verificare
+
+
+def txt(x, y, s, size=13, weight="400", fill=BLACK, anchor="middle"):
+ TEXTS.append((x, y, s, size, weight, anchor))
+ return (
+ f'{escape(s)}'
+ )
+
+
+def line(x1, y1, x2, y2, stroke=BLUE, width=1.5, dash=None):
+ d = f' stroke-dasharray="{dash}"' if dash else ""
+ return (f'')
+
+
+def arrow(x, y, direction, color=BLUE):
+ """Varf de sageata orizontal: direction=1 spre dreapta, -1 spre stanga."""
+ d = f"M {x} {y} L {x - 9 * direction} {y - 5} L {x - 9 * direction} {y + 5} Z"
+ return f''
+
+
+def card(x, y, lines):
+ out = [f'']
+ for dy, s, size, weight, fill in lines:
+ out.append(txt(x + COL_W / 2, y + dy, s, size, weight, fill))
+ return out
+
+
+def bracket(y, label):
+ """Bara dubla cu varfuri, grupeaza cele doua carduri de pe rand."""
+ x0, x1 = COL1_X + 16, COL2_R - 16
+ return [
+ line(x0, y, x1, y, BLUE, 1.5),
+ arrow(x1, y, 1),
+ arrow(x0, y, -1),
+ txt(W / 2, y + 22, label, 14, "700", BLUE),
+ ]
+
+
+def build():
+ p = [
+ f'')
+ return "\n".join(p) + "\n"
+
+
+# ---------------------------------------------------------------- verificare
+def est_w(s, size, weight):
+ factor = 0.62 if weight == "700" else 0.56
+ return len(s) * size * factor
+
+
+def verify():
+ for x, y, s, size, weight, anchor in TEXTS:
+ ew = est_w(s, size, weight)
+ left = x - ew if anchor == "end" else (x - ew / 2 if anchor == "middle" else x)
+ right = left + ew
+ assert -2 <= left and right <= W + 2, f"text in afara panzei: {s!r}"
+ assert 0 <= y <= H, f"text in afara inaltimii: {s!r} (y={y})"
+
+ for i in range(len(TEXTS)):
+ xi, yi, si, szi, wi, ai = TEXTS[i]
+ we = est_w(si, szi, wi)
+ li = xi - we if ai == "end" else (xi - we / 2 if ai == "middle" else xi)
+ ri = li + we
+ for j in range(i + 1, len(TEXTS)):
+ xj, yj, sj, szj, wj, aj = TEXTS[j]
+ wej = est_w(sj, szj, wj)
+ lj = xj - wej if aj == "end" else (xj - wej / 2 if aj == "middle" else xj)
+ rj = lj + wej
+ if abs(yi - yj) < 13 and li < rj - 4 and lj < ri - 4:
+ raise AssertionError(f"texte suprapuse: {si!r} / {sj!r}")
+
+ for x, y, lines in CARDS:
+ for dy, s, size, weight, fill in lines:
+ ew = est_w(s, size, weight)
+ assert ew <= COL_W - 24, f"eticheta nu incape in card: {s!r} ({ew:.0f})"
+ assert y + dy <= y + CARD_H - 8, f"eticheta iese din card: {s!r}"
+ assert "nan" not in OUT_TEXT[0]
+ return True
+
+
+OUT_TEXT = [build()]
+assert verify(), "verificare esuata"
+OUT.write_text(OUT_TEXT[0], encoding="utf-8")
+print(f"scris {OUT} ({W}x{H}), verificare OK: {len(TEXTS)} etichete")
diff --git a/gen/selectia/cadrane.spec.txt b/gen/selectia/cadrane.spec.txt
new file mode 100644
index 0000000..6eea1d1
--- /dev/null
+++ b/gen/selectia/cadrane.spec.txt
@@ -0,0 +1 @@
+cele 4 cadrane relative strength fata de benchmark: cadran 1 supraperformanta, cadran 2 imbunatatire (long), cadran 3 imbunatatire pe minus, cadran 4 underperform; sageti pentru conditiile de intrare long (1-2) si short (3-4)
diff --git a/gen/selectia/cadrane.svg b/gen/selectia/cadrane.svg
new file mode 100644
index 0000000..03b1afe
--- /dev/null
+++ b/gen/selectia/cadrane.svg
@@ -0,0 +1,39 @@
+
diff --git a/gen/selectia/cash_flow.py b/gen/selectia/cash_flow.py
new file mode 100644
index 0000000..431b480
--- /dev/null
+++ b/gen/selectia/cash_flow.py
@@ -0,0 +1,195 @@
+"""Trei stări de cash flow, din `summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md`
+(secțiunea 1.5 Cash flow):
+
+ - pozitiv și în creștere = se finanțează, stă în picioare -> îl cauți
+ - pozitiv, dar în scădere = deteriorare -> nu-l pui pe lista de investiție
+ - negativ = speculă pe momentum, nu investiție
+
+La ETF-uri, ETF-urile nu au scor, dar nu intră în această diagramă.
+
+SVG scris de mână (nu e grafic de preț, deci NU se folosesc svg_candles / pchart).
+Fără dependințe: doar stdlib. Rulare:
+ .venv/bin/python gen/selectia/cash_flow.py
+Scrie `gen/selectia/cash_flow.svg`.
+
+Notă de conținut: textul nu dă praguri, procente sau cod de culoare
+(verde/roșu ca semafor), deci diagrama nu inventează niciunul. Toate cifrele
+care apar în desen sunt referințe de citat (fișier:linii) existente în text.
+"""
+from pathlib import Path
+from xml.sax.saxutils import escape
+
+OUT = Path(__file__).resolve().parent / "cash_flow.svg"
+
+BLACK = "#000000"
+GRAY = "#777777"
+BLUE = "#1a5fb4"
+
+W = 700
+MARGIN = 30
+GAP = 20
+CARD_W = 200
+CARD_TOP = 80
+CARD_H = 216
+XS = [MARGIN + i * (CARD_W + GAP) for i in range(3)] # 30, 250, 470
+
+TITLE_Y = 34
+SUB_Y = 56
+
+# Fiecare card: header (poate fi pe două rânduri), "ce înseamnă" (2 rânduri),
+# acțiunea (1-2 rânduri, în caseta de jos) și sursa.
+CARDS = [
+ {
+ "header": ["Pozitiv", "și în creștere"],
+ "meaning": ["se finanțează,", "stă în picioare"],
+ "action": ["Îl cauți chiar și la", "companiile pe", "pierdere"],
+ "source": "66_18052026.txt:120-121",
+ },
+ {
+ "header": ["Pozitiv, dar", "în scădere"],
+ "meaning": ["deși e pozitiv,", "s-a deteriorat"],
+ "action": ["Nu-l pui pe lista", "de investiție"],
+ "source": "72_08052026.txt:241-243",
+ },
+ {
+ "header": ["Negativ"],
+ "meaning": ["speculă pe momentum"],
+ "action": ["Nu investiție"],
+ "source": "„Ce faci”, secțiunea 1.5",
+ },
+]
+
+FOOTNOTES = [
+ ("Cash flow-ul pozitiv e ce ține compania în picioare — îl cauți chiar și la",
+ BLACK),
+ ("companiile încă pe pierdere.", BLACK),
+ ("Pozitiv dar în scădere = deteriorare (53_09062026.txt:122-124).", GRAY),
+ ("Surse: 66_18052026.txt:120-121; 72_08052026.txt:241-243.", GRAY),
+ ("Secțiunea 1.5 Cash flow — summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md.",
+ GRAY),
+]
+
+FOOT_TOP = CARD_TOP + CARD_H + 30
+H = FOOT_TOP + (len(FOOTNOTES) - 1) * 20 + 30
+
+labels = [] # (x_left, x_right, y_top, y_bottom, text) pentru verificare
+
+
+def est_width(text, size, bold=False):
+ """Lățime aproximativă pentru system-ui, pentru verificarea suprapunerilor."""
+ factor = 0.62 if bold else 0.56
+ return len(text) * size * factor
+
+
+def txt(x, y, s, size=13, bold=False, fill=BLACK, anchor="middle"):
+ weight = "700" if bold else "400"
+ w = est_width(s, size, bold)
+ if anchor == "middle":
+ x0, x1 = x - w / 2, x + w / 2
+ elif anchor == "start":
+ x0, x1 = x, x + w
+ else: # end
+ x0, x1 = x - w, x
+ labels.append((x0, x1, y - size, y + 3, s))
+ return (
+ f'{escape(s)}'
+ )
+
+
+def card(idx, spec):
+ x = XS[idx]
+ parts = [
+ f'',
+ ]
+ # header
+ hy = CARD_TOP + 30
+ for line in spec["header"]:
+ parts.append(txt(x + CARD_W / 2, hy, line, size=16, bold=True))
+ hy += 21
+ sep_y = CARD_TOP + 64
+ parts.append(
+ f''
+ )
+ # ce înseamnă
+ parts.append(txt(x + 14, CARD_TOP + 88, "Ce înseamnă", size=13, fill=GRAY,
+ anchor="start"))
+ my = CARD_TOP + 108
+ for line in spec["meaning"]:
+ parts.append(txt(x + 14, my, line, size=13, anchor="start"))
+ my += 19
+ # caseta de acțiune
+ box_y = CARD_TOP + CARD_H - 74
+ parts.append(
+ f''
+ )
+ ay = box_y + 19
+ for line in spec["action"]:
+ parts.append(txt(x + CARD_W / 2, ay, line, size=13, bold=True))
+ ay += 17
+ # sursa
+ parts.append(txt(x + CARD_W / 2, CARD_TOP + CARD_H + 15, spec["source"],
+ size=13, fill=GRAY))
+ return parts
+
+
+svg = [
+ f'")
+
+# ------------------------------------------------------------------ verificare
+# 1. fiecare text încape în card / în panză
+for i, spec in enumerate(CARDS):
+ inner = CARD_W - 28
+ for line in spec["header"]:
+ assert est_width(line, 16, bold=True) <= inner, \
+ f"header nu incape in card {i}: {line!r}"
+ for line in spec["meaning"] + spec["action"]:
+ assert est_width(line, 13, line in spec["action"]) <= inner, \
+ f"text nu incape in card {i}: {line!r}"
+
+# 2. toate etichetele au coordonate în interiorul panzei
+for x0, x1, y0, y1, s in labels:
+ assert 0 <= x0 and x1 <= W, f"eticheta iese din panza pe orizontala: {s!r}"
+ assert 0 <= y0 and y1 <= H, f"eticheta iese din panza pe verticala: {s!r}"
+
+# 3. pe aceeași poziție / suprapuse
+for i in range(len(labels)):
+ for j in range(i + 1, len(labels)):
+ ax0, ax1, ay0, ay1, a = labels[i]
+ bx0, bx1, by0, by1, b = labels[j]
+ inter_w = min(ax1, bx1) - max(ax0, bx0)
+ inter_h = min(ay1, by1) - max(ay0, by0)
+ if inter_w > 1.5 and inter_h > 1.5:
+ raise AssertionError(f"texte suprapuse: {a!r} / {b!r}")
+
+# 4. nu se calcă pe verticală doua rânduri de text (baseline prea apropiat)
+ys = sorted((round((y0 + y1) / 2), s) for _, _, y0, y1, s in labels)
+for k in range(len(ys) - 1):
+ assert ys[k + 1][0] - ys[k][0] >= 14 or ys[k][0] == ys[k + 1][0], \
+ f"rânduri prea apropiate: {ys[k][1]!r} / {ys[k + 1][1]!r}"
+
+OUT.write_text("\n".join(svg) + "\n", encoding="utf-8")
+print(f"scris {OUT} ({W}x{H}), {len(CARDS)} stări, "
+ f"{len(labels)} etichete, verificare OK")
diff --git a/gen/selectia/cash_flow.spec.txt b/gen/selectia/cash_flow.spec.txt
new file mode 100644
index 0000000..6ca22c2
--- /dev/null
+++ b/gen/selectia/cash_flow.spec.txt
@@ -0,0 +1 @@
+trei stari de cash flow: pozitiv si in crestere = sanatos; pozitiv dar in scadere = deteriorare, scoti de pe lista; negativ = specula pe momentum, nu investitie
diff --git a/gen/selectia/cash_flow.svg b/gen/selectia/cash_flow.svg
new file mode 100644
index 0000000..0b93bd2
--- /dev/null
+++ b/gen/selectia/cash_flow.svg
@@ -0,0 +1,41 @@
+
diff --git a/gen/selectia/funnel.py b/gen/selectia/funnel.py
new file mode 100644
index 0000000..2725065
--- /dev/null
+++ b/gen/selectia/funnel.py
@@ -0,0 +1,146 @@
+"""Funnel-ul de selecție din `summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md`.
+
+Fluxul din scanner, de sus în jos, așa cum îl spune documentul:
+scanner (multe semnale) -> sectorul care domină -> doar suport/pivot, după
+downtrend -> RS cadranul 1-2 -> relative volume peste 100% -> stele (Trinity)
+-> listă scurtă.
+
+SVG scris de mână (nu e grafic de preț, deci nu se folosește svg_candles).
+Fără dependențe: doar stdlib. Rulare:
+ .venv/bin/python gen/selectia/funnel.py
+Scrie `gen/selectia/funnel.svg`.
+"""
+from pathlib import Path
+from xml.sax.saxutils import escape
+
+OUT = Path(__file__).resolve().parent / "funnel.svg"
+
+BLACK = "#000000"
+GRAY = "#777777"
+BLUE = "#1a5fb4"
+
+W = 700
+TITLE_Y = 34
+SUB_Y = 56
+
+BAND_H = 58
+GAP = 24
+STEP = BAND_H + GAP
+TOP0 = 84
+
+WIDTHS = [620, 566, 512, 458, 404, 350, 296]
+
+STAGES = [
+ ("Scanner — multe semnale", "zeci sau sute de semnale"),
+ ("Sectorul care domină", "multe simboluri din același sector = rotație de bani"),
+ ("Doar suport / pivot, după downtrend",
+ "suport monthly / quarterly / anual sau pivot"),
+ ("Relative strength: cadran 1-2", "doar cadranele 1 și 2, RS pozitiv"),
+ ("Relative volume peste 100%",
+ "candela de volum / media ultimelor 10 candele"),
+ ("Stele (Trinity)", "3 stele: RS + power + volum, cadran 1"),
+ ("Listă scurtă", "taie lista la câteva idei"),
+]
+
+N_BANDS = len(STAGES)
+BANDS_BOTTOM = TOP0 + (N_BANDS - 1) * STEP + BAND_H
+FOOT_Y = BANDS_BOTTOM + 34
+H = FOOT_Y + 96
+
+
+def est_width(text, size, bold=False):
+ """Lățime aproximativă pentru system-ui, folosită la verificarea suprapunerilor."""
+ factor = 0.62 if bold else 0.56
+ return len(text) * size * factor
+
+
+def txt(x, y, s, size=13, bold=False, fill=BLACK, anchor="middle"):
+ weight = "700" if bold else "400"
+ return (
+ f'{escape(s)}'
+ )
+
+
+def band(i):
+ name, detail = STAGES[i]
+ w = WIDTHS[i]
+ x = (W - w) / 2
+ y = TOP0 + i * STEP
+ parts = [
+ f'',
+ txt(W / 2, y + 25, name, size=15, bold=True),
+ txt(W / 2, y + 45, detail, size=13, fill=GRAY),
+ ]
+ return parts, (y, detail)
+
+
+def arrow(y):
+ """Chevron în jos, în golul dintre două benzi."""
+ return (
+ f''
+ )
+
+
+svg = [
+ f'")
+
+# ------------------------------------------------------------------ verificare
+for i, (name, detail) in enumerate(STAGES):
+ w = WIDTHS[i]
+ for s, size, bold in ((name, 15, True), (detail, 13, False)):
+ ew = est_width(s, size, bold)
+ assert ew <= w - 24, f"eticheta nu incape in banda {i}: {s!r} ({ew:.0f} > {w - 24})"
+ assert ew <= W - 20, f"eticheta iese din panza: {s!r}"
+
+for k in range(N_BANDS):
+ y0 = TOP0 + k * STEP
+ assert 0 < y0 and y0 + BAND_H < H, "banda iese din viewBox"
+
+seen = []
+for l, r, y, s in labels:
+ assert 0 <= l and r <= W, f"eticheta iese din panza pe orizontala: {s!r} ({l:.0f},{r:.0f})"
+ assert 0 <= y <= H, f"eticheta iese din panza pe verticala: {s!r}"
+ for l2, r2, y2, s2 in seen:
+ if abs(y - y2) < 14 and not (r < l2 or r2 < l):
+ raise AssertionError(f"posibile etichete suprapuse: {s!r} / {s2!r}")
+ seen.append((l, r, y, s))
+
+OUT.write_text("\n".join(svg) + "\n", encoding="utf-8")
+print(f"scris {OUT} ({W}x{H}), {N_BANDS} trepte, verificare OK")
diff --git a/gen/selectia/funnel.spec.txt b/gen/selectia/funnel.spec.txt
new file mode 100644
index 0000000..4591f60
--- /dev/null
+++ b/gen/selectia/funnel.spec.txt
@@ -0,0 +1 @@
+funnel de selecție: univers 3.000-12.000 companii -> scanner (multe semnale) -> sectorul care domină -> doar suport/pivot după downtrend -> relative strength cadran 1-2 -> relative volume >100% -> stele (Trinity) -> shortlist de 5-10 simboluri
diff --git a/gen/selectia/funnel.svg b/gen/selectia/funnel.svg
new file mode 100644
index 0000000..b4cc9b8
--- /dev/null
+++ b/gen/selectia/funnel.svg
@@ -0,0 +1,36 @@
+
diff --git a/gen/selectia/pe_venit.py b/gen/selectia/pe_venit.py
new file mode 100644
index 0000000..3fd7ef6
--- /dev/null
+++ b/gen/selectia/pe_venit.py
@@ -0,0 +1,122 @@
+"""Diagrama forward P/E x venit pentru 11_selectia_simbolului.md (marcaj pe_venit).
+
+Matrice 2x2: coloane = forward P/E (mic / mare), randuri = venit (creste / scade).
+Fiecare cifra si eticheta vine din textul din jurul marcajului sau din citatele
+lui (vezi caption-ul din josul SVG-ului). Nu e grafic de pret, deci nu foloseste
+svg_candles / pchart.
+
+Ruleaza:
+ .venv/bin/python gen/selectia/pe_venit.py
+Scrie gen/selectia/pe_venit.svg (fara dependinte, SVG construit ca string).
+"""
+import html
+import re
+from pathlib import Path
+
+W, H = 700, 620
+X0, X1 = 120, 660
+Y0, Y1 = 110, 520
+COL_MID = (X0 + X1) / 2.0
+ROW_MID = (Y0 + Y1) / 2.0
+C1 = (X0 + COL_MID) / 2.0
+C2 = (COL_MID + X1) / 2.0
+R1 = (Y0 + ROW_MID) / 2.0
+R2 = (ROW_MID + Y1) / 2.0
+
+GRAY, BLUE = "#777", "#1a5fb4"
+BLACK = "#000"
+TINT = "#eaf1fb"
+
+texts = []
+
+
+def text(x, y, s, size=14, weight="normal", fill=BLACK, anchor="middle", transform=""):
+ texts.append((x, y, s, size, weight, fill, anchor, transform))
+
+
+def cell_outline(x, y, w, h, accent=False):
+ fill = TINT if accent else "#fff"
+ stroke = BLUE if accent else "#999"
+ return (
+ f''
+ )
+
+
+parts = [
+ f'")
+svg = "\n".join(parts) + "\n"
+
+# ---------------------------------------------------------------- verificare in-script
+assert 'filter=' not in svg and 'gradient' not in svg, "fara umbre/gradienti"
+seen = set()
+for m in re.finditer(r']*font-size="(\d+)"', svg):
+ x, y, size = float(m.group(1)), float(m.group(2)), int(m.group(3))
+ assert 0 <= x <= W and 0 <= y <= H, f"eticheta in afara panzei: {x},{y}"
+ assert size >= 13, f"font sub 13: {size}"
+ key = (round(x), round(y))
+ assert key not in seen, f"doua texte pe aceeasi pozitie: {key}"
+ seen.add(key)
+assert "~23" in svg and "~15" in svg, "cifrele sursa lipsesc"
+
+OUT = Path(__file__).with_suffix(".svg")
+OUT.write_text(svg, encoding="utf-8")
+print(f"scris {OUT} ({len(svg)} bytes, {len(texts)} etichete, {W}x{H})")
diff --git a/gen/selectia/pe_venit.spec.txt b/gen/selectia/pe_venit.spec.txt
new file mode 100644
index 0000000..2f8c401
--- /dev/null
+++ b/gen/selectia/pe_venit.spec.txt
@@ -0,0 +1 @@
+matrice 2x2 forward P/E (mic/mare) x venit (creste/scade): PE mic + venit creste = candidat (TWLO); PE mic + venit scade = probleme (CRM); PE mare + venit creste = bun dar scump; PE mare + venit scade = eviti
diff --git a/gen/selectia/pe_venit.svg b/gen/selectia/pe_venit.svg
new file mode 100644
index 0000000..23d938b
--- /dev/null
+++ b/gen/selectia/pe_venit.svg
@@ -0,0 +1,32 @@
+
diff --git a/gen/selectia/scor.py b/gen/selectia/scor.py
new file mode 100644
index 0000000..86d3c0f
--- /dev/null
+++ b/gen/selectia/scor.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+"""Diagrama pentru summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md (SVG:scor).
+
+Bara ATM score 0-14, impartita in F-score 0-9 (max 9) si value-score 0-5
+(max 5). Marcate: 7/14 = "galben", 12-13 = "spuma", peste 7-8 = intra in
+analiza. Fara semafor rosu/verde (nu e in sursa).
+
+Cifrele si etichetele vin din text:
+- ATM score = F-score (max 9) + value-score (max 5) = max 14 (.md:128)
+- 7/14 "galben" (.md:137, 81_27042026.txt:180)
+- 12-13 "spuma" (.md:136, 83_22042026.txt:197)
+- peste 7-8 "intra in analiza" (.md:135, 83_22042026.txt:195)
+
+Ruleaza: .venv/bin/python gen/selectia/scor.py -> gen/selectia/scor.svg
+"""
+from pathlib import Path
+
+OUT = Path(__file__).with_suffix(".svg")
+
+W, H = 700, 360
+X0, X1 = 60, 640
+ATM_MAX, F_MAX, V_MAX = 14, 9, 5
+UNIT = (X1 - X0) / ATM_MAX
+
+GRAY, BLUE, ORANGE, TXT, WHITE = "#777", "#1a5fb4", "#b06000", "#000000", "#ffffff"
+BAR_TOP, BAR_H = 190, 46
+BAR_BOT = BAR_TOP + BAR_H
+
+
+def x(v):
+ return X0 + v * UNIT
+
+
+def text(px, py, s, size=14, fill=TXT, anchor="middle", weight="normal"):
+ return (
+ f'{s}'
+ )
+
+
+def line(x1, y1, x2, y2, stroke=GRAY, width=1.5, dash=None):
+ d = f' stroke-dasharray="{dash}"' if dash else ""
+ return (
+ f''
+ )
+
+
+def main():
+ p = []
+ p.append(f'')
+ OUT.write_text("\n".join(p) + "\n", encoding="utf-8")
+ print("scris", OUT)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/gen/selectia/scor.spec.txt b/gen/selectia/scor.spec.txt
new file mode 100644
index 0000000..94851b8
--- /dev/null
+++ b/gen/selectia/scor.spec.txt
@@ -0,0 +1 @@
+bara ATM score 0-14, impartita in F-score 0-9 si value-score 0-5; marcate 7/14 = "galben" (81_27042026.txt:180), 12-13 = "spuma" (83_22042026.txt:197), peste 7-8 = intra in analiza (83_22042026.txt:195); fara semafor rosu/verde, care nu e in sursa
diff --git a/gen/selectia/scor.svg b/gen/selectia/scor.svg
new file mode 100644
index 0000000..199e3a5
--- /dev/null
+++ b/gen/selectia/scor.svg
@@ -0,0 +1,30 @@
+
diff --git a/gen/selectia/sectoare.py b/gen/selectia/sectoare.py
new file mode 100644
index 0000000..8273d8c
--- /dev/null
+++ b/gen/selectia/sectoare.py
@@ -0,0 +1,232 @@
+"""Clasamentul celor 11 sectoare S&P: sortare după cadranul 1 + valoarea RS,
+cu rotația banilor între sectoare.
+
+Diagramă conceptuală pentru `summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md`
+(marcaj ``), §4.1 „Sectorul care domină".
+
+Ce susține textul din jurul marcajului:
+ - „cele 11 sectoare S&P" (rândul 439) și „clasamentul sectoarelor | 11 rânduri,
+ sortate săptămânal" (rândul 88);
+ - sortarea după „cadranul 1 + valoarea relativ strength"
+ (`54_08062026.txt:14`, citat la rândul 441-443);
+ - top 4-ul din citatul sursă: XLV primul, apoi energia, financiarul, real
+ estate (`54_08062026.txt:9-10`);
+ - rotația sectorială: „banii migrează dintr-un sector în altul" (rândul 71),
+ „se mută bani [...] rotație a banilor în acel sector"
+ (`32_15072026.txt:43-49`), „uită-te ce predomină, în ce sectoare"
+ (`148_11122025.txt:725-727`).
+
+CE NU AM PUS, pentru că sursa nu-l susține:
+ - valorile numerice de RS: textul/citatul dă doar regula de sortare
+ („cu cât este mai mare histograma de relativ strength și cadranul 1"),
+ nu și cifre concrete. Desenul redă deci ordinea, nu valori inventate;
+ - săgeți cu schimbări concrete „săptămâna trecută X, săptămâna asta Y":
+ nu există asemenea date în sursă. Săgețile arată doar conceptul de rotație
+ ciclică (semnale în același sector -> bani acolo -> sortare refăcută
+ săptămânal);
+ - ordinea celor 7 sectoare din afara top-ului: sursa enumeră doar primele 4.
+
+Nu e grafic de preț, deci NU folosește `svg_candles` / `pchart`: SVG-ul e
+construit ca string, fără dependințe. Rulează:
+ .venv/bin/python gen/selectia/sectoare.py
+Scrie `gen/selectia/sectoare.svg`.
+
+Fără semafor: textul nu leagă cadranul 1 de verde sau restul de roșu. Accentele
+sunt albastru (informativ) și gri (secundar).
+"""
+import html
+from pathlib import Path
+
+W, H = 700, 640
+
+BLACK = "#000000"
+GRAY = "#777777"
+BLUE = "#1a5fb4"
+
+texts = [] # (x, y, text, size, weight, fill, w_est, anchor)
+
+
+def add(x, y, s, size=13, weight="normal", fill=BLACK, anchor="middle"):
+ factor = 0.62 if weight == "bold" else 0.56
+ w = len(s) * size * factor
+ texts.append((x, y, s, size, weight, fill, w, anchor))
+ return texts[-1]
+
+
+def box(x, y, w, h, stroke=GRAY):
+ return (
+ f''
+ )
+
+
+def arrow_h(x0, x1, y, color=BLUE):
+ """Săgeată orizontală de la x0 la x1, vârful la x1."""
+ return (
+ f''
+ f''
+ )
+
+
+parts = [
+ f'")
+svg = "\n".join(parts) + "\n"
+
+# ---------------------------------------------------------------- verificare
+assert "filter=" not in svg and "gradient" not in svg, "fără umbre/gradienti"
+
+boxes = []
+for x, y, s, size, weight, fill, w, anchor in texts:
+ assert size >= 13, f"font sub 13px: {s!r} ({size})"
+ if anchor == "start":
+ left, right = x, x + w
+ elif anchor == "end":
+ left, right = x - w, x
+ else:
+ left, right = x - w / 2.0, x + w / 2.0
+ top, bottom = y - size * 0.78, y + size * 0.22
+ assert 0 <= left and right <= W, (
+ f"etichetă în afara panzei pe orizontală: {s!r} ({left:.0f}..{right:.0f})"
+ )
+ assert 0 <= top and bottom <= H, (
+ f"etichetă în afara panzei pe verticală: {s!r} ({top:.0f}..{bottom:.0f})"
+ )
+ boxes.append((left, right, top, bottom, s))
+
+for i in range(len(boxes)):
+ for j in range(i + 1, len(boxes)):
+ l1, r1, t1, b1, s1 = boxes[i]
+ l2, r2, t2, b2, s2 = boxes[j]
+ if r1 > l2 and r2 > l1 and b1 > t2 and b2 > t1:
+ raise AssertionError(f"etichete suprapuse: {s1!r} / {s2!r}")
+
+for required in ("Sectoare S&P 500", "cadranul 1", "valoarea RS",
+ "Healthcare (XLV)", "Energie (XLE)", "Financiar (XLF)",
+ "Imobiliare (XLRE)", "Tehnologie (XLK)",
+ "Consum discreționar (XLY)", "Comunicații (XLC)",
+ "Industrii (XLI)", "Consum de bază (XLP)",
+ "Utilități (XLU)", "Materiale (XLB)",
+ "rotația banilor", "săptămânal", "11 sectoare"):
+ assert html.escape(required, quote=False) in svg, \
+ f"lipsește din desen: {required!r}"
+
+# cele 11 sectoare apar exact o dată fiecare
+for _, name, _ in TOP4:
+ assert svg.count(name) == 1, f"sector duplicat sau lipsă: {name!r}"
+for name in REST:
+ assert svg.count(name) == 1, f"sector duplicat sau lipsă: {name!r}"
+
+OUT = Path(__file__).with_suffix(".svg")
+OUT.write_text(svg, encoding="utf-8")
+print(f"scris {OUT} ({len(svg)} bytes, {len(texts)} etichete, {W}x{H}), verificare OK")
diff --git a/gen/selectia/sectoare.spec.txt b/gen/selectia/sectoare.spec.txt
new file mode 100644
index 0000000..9af6878
--- /dev/null
+++ b/gen/selectia/sectoare.spec.txt
@@ -0,0 +1 @@
+cele 11 sectoare S&P sortate dupa cadranul 1 si valoarea RS, cu sageti care arata rotatia banilor dintr-o saptamana in alta
diff --git a/gen/selectia/sectoare.svg b/gen/selectia/sectoare.svg
new file mode 100644
index 0000000..f008eef
--- /dev/null
+++ b/gen/selectia/sectoare.svg
@@ -0,0 +1,53 @@
+
diff --git a/gen/selectia/trinity.py b/gen/selectia/trinity.py
new file mode 100644
index 0000000..1c4f5c7
--- /dev/null
+++ b/gen/selectia/trinity.py
@@ -0,0 +1,158 @@
+"""Trinity — 3 stele vs. trei divergențe simultane.
+
+Diagramă conceptuală pentru `summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md`
+(marcaj ``), §3 „Trinity și power — stelele".
+
+Două panouri:
+ 1. Trinity complet — relative strength, power și volum, toate în cadranul 1,
+ aceeași direcție => „3 stele cu plus".
+ 2. Trei divergențe simultane (volum, RS, power) => setup de bottom, dar fără
+ trigger încă: „doar pe listă".
+
+Nu e grafic de preț, deci NU folosește `svg_candles` / `pchart`: SVG-ul e
+construit ca string, fără dependințe. Rulează:
+ .venv/bin/python gen/selectia/trinity.py
+Scrie `gen/selectia/trinity.svg`.
+
+Fiecare cifră și etichetă de aici există în textul din jurul marcajului sau în
+citatele lui:
+ - „3 stele cu plus" / „3 stele" / cadranul 1 / relativ strength, power, volum:
+ `75_05052026.txt:101-106` și `82_24042026.txt:334-335`;
+ - cele trei divergențe simultane și așteptarea trigger-ului:
+ `98_30032026.txt:395-397`;
+ - „3 stele cu roșu" pe indice = short: `75_05052026.txt:101-106` și tabelul
+ Trinity DA/NU.
+Textul nu leagă DA de verde și nici divergențele de vreo culoare, așa că nu am
+folosit verde/semafor: roșu apare doar acolo unde sursa spune explicit „roșu".
+"""
+import html
+from pathlib import Path
+
+W, H = 700, 640
+
+BLACK = "#000000"
+GRAY = "#777777"
+RED = "#c00"
+BLUE = "#1a5fb4"
+
+texts = [] # (x, y, text, size, weight, fill, w_est)
+
+
+def add(x, y, s, size=13, weight="normal", fill=BLACK):
+ factor = 0.62 if weight == "bold" else 0.56
+ texts.append((x, y, s, size, weight, fill, len(s) * size * factor))
+ return x, y, s, size, weight, fill, len(s) * size * factor
+
+
+def box(x, y, w, h):
+ return (
+ f''
+ )
+
+
+parts = [
+ f'")
+svg = "\n".join(parts) + "\n"
+
+# ---------------------------------------------------------------- verificare
+assert "filter=" not in svg and "gradient" not in svg, "fără umbre/gradienti"
+
+boxes = []
+for x, y, s, size, weight, fill, w in texts:
+ assert size >= 13, f"font sub 13px: {s!r} ({size})"
+ left, right = x - w / 2.0, x + w / 2.0
+ top, bottom = y - size * 0.78, y + size * 0.22
+ assert 0 <= left and right <= W, f"etichetă în afara panzei pe orizontală: {s!r}"
+ assert 0 <= top and bottom <= H, f"etichetă în afara panzei pe verticală: {s!r}"
+ boxes.append((left, right, top, bottom, s))
+
+for i in range(len(boxes)):
+ for j in range(i + 1, len(boxes)):
+ l1, r1, t1, b1, s1 = boxes[i]
+ l2, r2, t2, b2, s2 = boxes[j]
+ if r1 > l2 and r2 > l1 and b1 > t2 and b2 > t1:
+ raise AssertionError(f"etichete suprapuse: {s1!r} / {s2!r}")
+
+for required in ("3 stele", "cadranul 1", "Relative strength", "Power", "Volum",
+ "3 stele cu plus", "divergență", "trei divergențe simultane",
+ "setup de bottom", "trigger", "doar pe listă",
+ "3 stele cu roșu", "short"):
+ assert required in svg, f"lipsește din desen: {required!r}"
+
+# fiecare din cele trei condiții apare o dată în panoul 1 și o dată în panoul 2
+for word in ("Relative strength", "Power", "Volum"):
+ assert svg.count(f">{word}") == 2, f"{word!r} nu apare de două ori"
+
+OUT = Path(__file__).with_suffix(".svg")
+OUT.write_text(svg, encoding="utf-8")
+print(f"scris {OUT} ({len(svg)} bytes, {len(texts)} etichete, {W}x{H}), verificare OK")
diff --git a/gen/selectia/trinity.spec.txt b/gen/selectia/trinity.spec.txt
new file mode 100644
index 0000000..625dcb4
--- /dev/null
+++ b/gen/selectia/trinity.spec.txt
@@ -0,0 +1 @@
+Trinity: trei coloane (relative strength, power, volum) toate in cadranul 1 => 3 stele; al doilea panou cu trei divergente simultane (volum, RS, power) => setup fara trigger inca
diff --git a/gen/selectia/trinity.svg b/gen/selectia/trinity.svg
new file mode 100644
index 0000000..82d670f
--- /dev/null
+++ b/gen/selectia/trinity.svg
@@ -0,0 +1,36 @@
+
diff --git a/summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.html b/summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.html
index 0e8f342..d7654b4 100644
--- a/summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.html
+++ b/summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.html
@@ -195,7 +195,44 @@ crească edge-ul, mai ales pentru swing trading și pentru investiții."
-
+
+
+
1. Fundamentalul — filtrul de dinaintea graficului
@@ -226,7 +263,38 @@ F-score, din 9 și 3 pe fundamental, value-score care aici pot să fie 5
maxim." (115_04032026.txt:73-75)
@@ -346,7 +414,40 @@ venitul în creștere." (125_18022026.txt:20-21, despre TWLO)
[...] Ideea este că aici avem niște probleme cu veniturile, adică generează
venituri, dar veniturile sunt în scădere." (125_18022026.txt:32-35)
-
+
+
+
Al doilea reper e istoric: dacă P/E-ul actual e sub minimul ultimilor 5 ani,
compania e subevaluată.
@@ -381,7 +482,49 @@ deși e pozitiv, este în scădere." (72_08052026.txt:241-243)
s-a deteriorat [...] asta nu-mi place din perspectivă fundamentală."
(53_09062026.txt:122-124)
-
+
+
+
Ce faci: cauți cash flow pozitiv chiar și la companiile pe pierdere; dacă e
pozitiv dar în scădere, e deteriorare (nu-l pui pe lista de investiție); cash
@@ -430,7 +573,47 @@ mai repede.
3 înseamnă îmbunătățire, cadranul 4 înseamnă deja că este underperform."
(99_27032026.txt:87-92)
-
+
+
+
@@ -531,7 +714,44 @@ am putea să spun că avem un Trinity." (82_24042026.txt:334-335)
Varianta scurtă a aceluiași lucru: RS în cadran de îmbunătățire + power în zona
de îmbunătățire = „o formă de Trinity cu 3 stele" (91_09042026.txt:52,95).
-
+
+
+
Trei divergențe simultane — volum, RS și power — nu sunt 3 stele, sunt un
setup: divergența pe toate trei arată că prețul e la fund, dar încă nu s-a
@@ -591,7 +811,61 @@ cele 11 sectoare S&P, apoi te uiți la componentele ETF-ului de sector:
strength, cu cât este mai mare histograma de relativ strength și cadranul 1,
cam așa arată sortarea sectoarelor în S&P." (54_08062026.txt:14)
-
+
+
+
Ce faci: când scannerul dă multe semnale, primul sort e sectorul — vezi ce
sector predomină și ia din el simbolurile cu relative volume mare; la nivel de
diff --git a/summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md b/summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md
index f32d059..ccb7f13 100644
--- a/summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md
+++ b/summaries/08_ANALIZA_ZILNICA/11_selectia_simbolului.md
@@ -87,7 +87,44 @@ Nu tot ce e aici e preț, deci nu totul se poate desena ca grafic de candele:
| fluxul din scanner | **diagramă** | funnel de filtrare |
| clasamentul sectoarelor | **tabel** | 11 rânduri, sortate săptămânal |
-
+
+
+
---
@@ -126,7 +163,38 @@ Scala e dată explicit:
**ATM score = F-score (max 9) + value-score (max 5) = max 14.**
-
+
+
+
| Prag | Ce înseamnă | Ce faci |
|---|---|---|
@@ -201,7 +269,40 @@ scădere e capcană, nu chilipir.
> [...] Ideea este că aici avem niște probleme cu veniturile, adică generează
> venituri, dar veniturile sunt în scădere." (`125_18022026.txt:32-35`)
-
+
+
+
Al doilea reper e istoric: dacă P/E-ul actual e sub minimul ultimilor 5 ani,
compania e subevaluată.
@@ -241,7 +342,49 @@ deteriorare: el nu l-a pus pe listă, „de asta nu l-am pusesem pe listă"
> s-a deteriorat [...] asta nu-mi place din perspectivă fundamentală."
> (`53_09062026.txt:122-124`)
-
+
+
+
**Ce faci:** cauți cash flow pozitiv chiar și la companiile pe pierdere; dacă e
pozitiv dar în scădere, e deteriorare (nu-l pui pe lista de investiție); cash
@@ -298,7 +441,47 @@ mai repede.
> 3 înseamnă îmbunătățire, cadranul 4 înseamnă deja că este underperform."
> (`99_27032026.txt:87-92`)
-
+
+
+
| Cadran | Ce înseamnă | Direcție |
|---|---|---|
@@ -387,7 +570,44 @@ celorlalte trei, nu ca un indicator separat, e interpretarea mea.
Varianta scurtă a aceluiași lucru: RS în cadran de îmbunătățire + power în zona
de îmbunătățire = „o formă de Trinity cu 3 stele" (`91_09042026.txt:52,95`).
-
+
+
+
**Trei divergențe simultane** — volum, RS și power — nu sunt 3 stele, sunt un
setup: divergența pe toate trei arată că prețul e la fund, dar încă nu s-a
@@ -436,7 +656,61 @@ cele 11 sectoare S&P, apoi te uiți la componentele ETF-ului de sector:
> strength, cu cât este mai mare histograma de relativ strength și cadranul 1,
> cam așa arată sortarea sectoarelor în S&P." (`54_08062026.txt:14`)
-
+
+
+
**Ce faci:** când scannerul dă multe semnale, primul sort e sectorul — vezi ce
sector predomină și ia din el simbolurile cu relative volume mare; la nivel de