MODUL 5, lectia 1: RadarScreen si tranzactiile de 5 stele

Transcrierile 1 si 2 (extract_audio + transcribe pe MODUL 5, 7/7 lectii).
Sumarizarea lectiei 1: 14 diagrame, audit curat, generatoarele in gen/.

De reparat la verificare: eticheta TP1 119.53 da ca preturi ale cursului o
valoare derivata; cursul rosteste pivotul la 119 (transcrierea 01, linia 221).

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-01 21:10:52 +00:00
parent 43236af73e
commit be53a64003
7 changed files with 4381 additions and 0 deletions

193
gen/radarscreen_subst.py Normal file
View File

@@ -0,0 +1,193 @@
"""Substituie marcatorii <!--SVG:nume--> din capitolul de RadarScreen.
Diagramele de candele vin din gen/radarscreen_5_stele.py (output JSON);
cele schematice (fără candele) sunt scrise aici.
Rulează: .venv/bin/python gen/radarscreen_subst.py /cale/rs.json
"""
import json
import re
import sys
SRC = "/workspace/atm-curs-dl/gen/radarscreen_5_stele.md.in" # textul cu marcatori
MD = "/workspace/atm-curs-dl/summaries/06_MODUL_5/01_radarscreen_5_stele.md"
COLS = [("SIMBOL", "WBD"), ("INTERVAL", "60 min"), ("LAST", "—"),
("OFF HIGH", "—"), ("NET CHG", "—"), ("RANGE", "122%"),
("RVOL", "167%"), ("TRINITY", "—"), ("TRIGGER", "bull rev")]
def rand_radar() -> str:
w, x0, cw = 640, 14, 68
parts = [f'<svg viewBox="0 0 {w} 232" xmlns="http://www.w3.org/2000/svg"'
' style="width:100%;height:auto;font:12px sans-serif">',
'<text x="14" y="22" fill="#333" style="font-weight:bold">'
'Un rând de RadarScreen = un grafic întreg, scris ca numere</text>']
for k, (head, val) in enumerate(COLS):
x = x0 + k * cw
parts.append(f'<rect x="{x}" y="36" width="{cw}" height="24" fill="#eef2f7"'
' stroke="#9bb0c7" stroke-width="1"/>')
parts.append(f'<text x="{x + 4}" y="52" fill="#44576e" font-size="10">{head}</text>')
parts.append(f'<rect x="{x}" y="60" width="{cw}" height="26" fill="#fff"'
' stroke="#9bb0c7" stroke-width="1"/>')
col = "#188a3e" if val in ("122%", "167%", "bull rev") else "#555"
parts.append(f'<text x="{x + 4}" y="78" fill="{col}" font-size="10">{val}</text>')
parts += [
'<path d="M 320 92 L 320 112" stroke="#1a5fb4" stroke-width="1.5"/>',
'<path d="M 316 106 L 320 114 L 324 106 Z" fill="#1a5fb4"/>',
'<text x="14" y="134" fill="#1a5fb4">Fiecare celulă e un calcul pe exact'
' aceleași date pe care le-ai citi pe chart:</text>',
'<text x="14" y="152" fill="#555">RANGE = înălțimea candelei față de media'
' ultimelor trei; RVOL = volumul ultimei bare față de media a 10;</text>',
'<text x="14" y="170" fill="#555">TRINITY = verdictul celor trei indicatori'
' proprii; TRIGGER = reversal, doji sau momentum pe candela curentă.</text>',
'<text x="14" y="194" fill="#666" font-size="11">Celulele cu „—" nu sunt'
' rostite în lecție pentru WBD: din el avem range 122%, RVol 167% și</text>',
'<text x="14" y="210" fill="#666" font-size="11">bull reversal, pe 60 de'
' minute. Așa citești 500 de companii fără să deschizi niciun grafic.</text>',
'</svg>']
return "\n ".join(parts)
LADDER = [("Trinity: volum + relative strength + power, toți în aceeași direcție",
"3 stele", "#188a3e"),
("+ un trigger: bull reversal, buy doji sau buy momentum", "4", "#188a3e"),
("+ locul: suport, pivot sau rezistență sub pragul de proximitate",
"5 stele", "#188a3e"),
("+ o divergență bull pe unul din indicatori", "„aproape 7”", "#1a5fb4")]
def trinity_stele() -> str:
parts = [f'<svg viewBox="0 0 640 {60 + 44 * len(LADDER) + 62}"'
' xmlns="http://www.w3.org/2000/svg"'
' style="width:100%;height:auto;font:12px sans-serif">',
'<text x="14" y="22" fill="#333" style="font-weight:bold">'
'Cum se adună stelele (numărătoarea e cea din curs)</text>']
for k, (txt, star, col) in enumerate(LADDER):
y = 40 + 44 * k
parts.append(f'<rect x="14" y="{y}" width="470" height="32" fill="#f7f9fb"'
' stroke="#9bb0c7" stroke-width="1"/>')
parts.append(f'<text x="22" y="{y + 21}" fill="#333" font-size="11">{txt}</text>')
parts.append(f'<rect x="496" y="{y}" width="130" height="32" fill="{col}"'
' fill-opacity="0.12" stroke="' + col + '" stroke-width="1"/>')
parts.append(f'<text x="561" y="{y + 21}" fill="{col}" text-anchor="middle"'
f' style="font-weight:bold">{star}</text>')
y = 40 + 44 * len(LADDER) + 18
parts.append(f'<text x="14" y="{y}" fill="#666" font-size="11">Cursul nu dă un'
' barem fix: fiecare confirmare în plus, pe aceeași candelă și în'
' aceeași direcție,</text>')
parts.append(f'<text x="14" y="{y + 16}" fill="#666" font-size="11">crește'
' probabilitatea.</text>')
parts.append('</svg>')
return "\n ".join(parts)
ROWS = [("volum (indicatorul propriu)", "A+ / A− / D+ / D−",
"candele peste/sub 0", "1 (cel mai important)"),
("relative strength", "cadranul 1-4", "candele în cadran", "2"),
("power", "cadranul 1-4", "candele în cadran", "3 (reacționează primul)")]
READ = [("AAPL — 3 stele", "relative strength în cadranul 2 (se îmbunătățește)",
"power în cadranul 1", "volum A− (sub 0, dar în acumulare, 29 de candele)",
"#188a3e"),
("ABV — 3 stele cu minus", "relative strength în cadranul 3 (se înrăutățește)",
"power în cadranul 4", "volum D− (sub 0 și în distribuție)", "#c00")]
def trinity_stele_detaliu() -> str:
parts = ['<svg viewBox="0 0 640 348" xmlns="http://www.w3.org/2000/svg"'
' style="width:100%;height:auto;font:12px sans-serif">',
'<text x="14" y="22" fill="#333" style="font-weight:bold">Cele șase'
' coloane Trinity: pentru fiecare indicator, starea și vechimea'
' ei</text>',
'<text x="22" y="46" fill="#44576e" font-size="10">INDICATOR</text>',
'<text x="212" y="46" fill="#44576e" font-size="10">COLOANA 1 — starea</text>',
'<text x="332" y="46" fill="#44576e" font-size="10">COLOANA 2 — vechimea</text>',
'<text x="480" y="46" fill="#44576e" font-size="10">IMPORTANȚA</text>',
'<line x1="14" y1="52" x2="626" y2="52" stroke="#9bb0c7" stroke-width="1"/>']
for k, (name, c1, c2, imp) in enumerate(ROWS):
y = 74 + 30 * k
parts.append(f'<text x="22" y="{y}" fill="#333" font-size="11">{name}</text>')
parts.append(f'<text x="212" y="{y}" fill="#1a5fb4" font-size="11">{c1}</text>')
parts.append(f'<text x="332" y="{y}" fill="#555" font-size="10">{c2}</text>')
parts.append(f'<text x="480" y="{y}" fill="#b06000" font-size="10">{imp}</text>')
parts.append('<text x="14" y="186" fill="#333" style="font-weight:bold">'
'Cele două citiri din lecție</text>')
for k, (title, a, b, c, col) in enumerate(READ):
y = 200 + 66 * k
parts.append(f'<rect x="14" y="{y}" width="612" height="56" fill="{col}"'
f' fill-opacity="0.07" stroke="{col}" stroke-width="1"/>')
parts.append(f'<text x="24" y="{y + 18}" fill="{col}"'
f' style="font-weight:bold">{title}</text>')
parts.append(f'<text x="24" y="{y + 36}" fill="#333" font-size="11">{a}</text>')
parts.append(f'<text x="330" y="{y + 36}" fill="#333" font-size="11">{b}</text>')
parts.append(f'<text x="24" y="{y + 50}" fill="#333" font-size="11">{c}</text>')
parts.append('<text x="14" y="342" fill="#666" font-size="11">Trinity numără'
' direcția, nu semnul: la AAPL volumul e negativ, dar în urcare —'
' tot stea e.</text>')
parts.append('</svg>')
return "\n ".join(parts)
def pivot_culori() -> str:
"""Două panouri: preț deasupra pivotului (verde) și sub pivot (roșu)."""
parts = ['<svg viewBox="0 0 640 262" xmlns="http://www.w3.org/2000/svg"'
' style="width:100%;height:auto;font:12px sans-serif">',
'<text x="14" y="22" fill="#333" style="font-weight:bold">Ce spune'
' culoarea de pe coloana de pivot</text>']
for k, (lab, col, py, dy) in enumerate([("preț DEASUPRA pivotului", "#188a3e", 120, -50),
("preț SUB pivot", "#c00", 120, 34)]):
x = 20 + k * 312
parts.append(f'<rect x="{x}" y="40" width="288" height="150" fill="#f7f9fb"'
' stroke="#9bb0c7" stroke-width="1"/>')
parts.append(f'<text x="{x + 10}" y="60" fill="{col}"'
f' style="font-weight:bold">{lab}</text>')
parts.append(f'<rect x="{x + 10}" y="{py - 14}" width="268" height="28"'
' fill="#1a5fb4" fill-opacity="0.08"/>')
parts.append(f'<line x1="{x + 10}" y1="{py}" x2="{x + 278}" y2="{py}"'
' stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>')
parts.append(f'<text x="{x + 14}" y="{py - 22}" fill="#1a5fb4"'
' font-size="10">pivot + banda de proximitate</text>')
parts.append(f'<circle cx="{x + 60}" cy="{py + dy}" r="5" fill="{col}"/>')
parts.append(f'<text x="{x + 72}" y="{py + dy + 4}" fill="{col}"'
' font-size="11">ultimul preț</text>')
txt = ("coloana e verde: „destul de strong bull”" if k == 0
else "coloana e roșie: „cam strong bear”")
parts.append(f'<text x="{x + 10}" y="182" fill="#333" font-size="11">{txt}</text>')
parts += ['<text x="14" y="212" fill="#333">Banda de proximitate: 0,5%'
' intraday, 2% pe daily. Fond alb cu cifră colorată = ești în'
' bandă.</text>',
'<text x="14" y="232" fill="#666" font-size="11">Coloana RR spune,'
' separat, dacă stai lângă suport (valoare mare) sau lângă'
' rezistență (valoare mică).</text>',
'</svg>']
return "\n ".join(parts)
HAND = {"rand_radar": rand_radar, "trinity_stele": trinity_stele,
"trinity_stele_detaliu": trinity_stele_detaliu,
"pivot_culori": pivot_culori}
def main() -> None:
charts = json.load(open(sys.argv[1], encoding="utf-8"))
md = open(SRC, encoding="utf-8").read()
missing = []
def sub(m: re.Match) -> str:
name = m.group(1)
if name in charts:
return charts[name]
if name in HAND:
return HAND[name]()
missing.append(name)
return m.group(0)
out = re.sub(r"<!--SVG:([a-z_0-9]+)-->", sub, md)
assert not missing, f"marcatori fără diagramă: {missing}"
n_used = len(re.findall(r"<svg ", out))
open(MD, "w", encoding="utf-8").write(out)
print(f"{n_used} diagrame lipite în {MD}")
if __name__ == "__main__":
main()