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
194 lines
10 KiB
Python
194 lines
10 KiB
Python
"""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()
|