MODUL 5: 13 reparatii pe lectiile 1-3, dupa verificare
Trei blocante: regula "masori de la extrem" era trecuta la "din curs" desi cursul masoara doar din punctul 2 pe exemplul Pepsi, fara sa enunte regula; "dubleaza de doua ori R-ul" nu se potrivea cu propriile cifre (2.7R -> 6.5R); si partea a 4-a proiecteaza tinta de la close-ul de breakout, nu de la linia sparta ca partile 2-3, fara sa semnaleze diferenta - acum o spune, cu citatele. Restul: 122% era pus pe WBD desi cursul il rosteste pe un simbol nenumit; o afirmatie de exclusivitate falsa; SPY dat ca "la jumatate" cand sursa spune "aproape indeplinit"; Apple mutat din daily in 4 ore; "sell the rally" atribuit bear flag-ului in loc de wedge; doua enumerari de "singurele cifre" incomplete; si trei suprapuneri de eticheta pe diagrame. Anti-regresie: _desprinse() in gen/patternuri_complexe_4.py pica daca o eticheta din lista clear= sta la sub 5 px de o linie desenata. L-a prins de sase ori in timpul reparatiilor. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
This commit is contained in:
@@ -406,7 +406,7 @@ check(Chart(
|
||||
Level(RIM_C, f"rezistență {RIM_C:.2f}", "#c00"),
|
||||
Level(MANER, f"minimul mânerului {MANER:.2f}", "#b06000"),
|
||||
Level(SL_C, f"SL {SL_C:.2f}", "#c00", label_at="left"),
|
||||
Level(LIMITA50, f"limita de 50% {LIMITA50:.2f}", "#777"),
|
||||
Level(LIMITA50, f"limita de 50% {LIMITA50:.2f}", "#8b5cf6"),
|
||||
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"),
|
||||
@@ -415,7 +415,7 @@ check(Chart(
|
||||
mas=[MA(20, "#777", dash="4 3")],
|
||||
scale=4.2, gap=15, body_w=9, left=46, width=620, 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. Cele două top-uri la 120.00 = double top."),
|
||||
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])
|
||||
|
||||
# ----------------------------------------- cup with handle: mâner prea adânc
|
||||
@@ -449,7 +449,7 @@ print(f"cup&handle NU: maner {MANER_N:.2f} = {PROC_N:.0%} din adancime")
|
||||
check(Chart(
|
||||
candles=cn,
|
||||
levels=[Level(RIM_C, f"rezistență {RIM_C:.2f}", "#c00"),
|
||||
Level(LIMITA50, f"limita de 50% {LIMITA50:.2f}", "#777", label_at="left"),
|
||||
Level(LIMITA50, f"limita de 50% {LIMITA50:.2f}", "#8b5cf6", label_at="left"),
|
||||
Level(MANER_N, f"minimul mânerului {MANER_N:.2f}", "#c00"),
|
||||
Level(FUND_C, f"fundul ceștii {FUND_C:.2f}", "#b06000", label_at="left")],
|
||||
marks=[Mark(4, "top 1", "#c00", dy=-20), Mark(19, "top 2", "#c00", dy=-20),
|
||||
|
||||
@@ -58,7 +58,31 @@ def txt(i, p, s, color="#8b5cf6", anchor="middle", dx=0.0, dy=0.0, bold=True):
|
||||
return dict(i=i, p=p, s=s, color=color, anchor=anchor, dx=dx, dy=dy, bold=bold)
|
||||
|
||||
|
||||
def deco(ch, name, segs=(), texts=(), distante=()):
|
||||
def _desprinse(svg, name, etichete, min_px=5.0):
|
||||
"""Etichetele date nu au voie sa stea pe nicio linie (regresia 11/12)."""
|
||||
# fitilele candelelor (#1a1a1a) nu se numara: desenul le traverseaza oricum
|
||||
lines = [tuple(map(float, m.groups()[:4])) for m in re.finditer(
|
||||
r'<line x1="(-?[\d.]+)" y1="(-?[\d.]+)" x2="(-?[\d.]+)" y2="(-?[\d.]+)"'
|
||||
r'[^/]*?stroke="(#[0-9a-f]{6})"', svg) if m.group(5) != "#1a1a1a"]
|
||||
for m in re.finditer(r'<text x="(-?[\d.]+)" y="(-?[\d.]+)"([^>]*)>([^<]*)</text>', svg):
|
||||
tx, ty, attrs, s = float(m.group(1)), float(m.group(2)), m.group(3), m.group(4)
|
||||
if s not in etichete:
|
||||
continue
|
||||
w = 6.2 * len(s)
|
||||
x0 = tx if 'anchor="start"' in attrs else tx - w if 'anchor="end"' in attrs else tx - w / 2
|
||||
x1, top, bot = x0 + w, ty - 9 - min_px, ty + 3 + min_px
|
||||
for lx1, ly1, lx2, ly2 in lines:
|
||||
if max(lx1, lx2) < x0 or min(lx1, lx2) > x1:
|
||||
continue
|
||||
ys = [ly1 + (ly2 - ly1) * (max(min(x, max(lx1, lx2)), min(lx1, lx2)) - lx1)
|
||||
/ ((lx2 - lx1) or 1) for x in (x0, x1)] if lx1 != lx2 else [ly1, ly2]
|
||||
if min(ys) <= bot and max(ys) >= top:
|
||||
raise AssertionError(
|
||||
f"{name}: eticheta '{s}' sta pe linia "
|
||||
f"({lx1:.0f},{ly1:.0f})-({lx2:.0f},{ly2:.0f})")
|
||||
|
||||
|
||||
def deco(ch, name, segs=(), texts=(), distante=(), clear=()):
|
||||
"""Randează graficul, injectează liniile/textele, verifică, salvează."""
|
||||
saved = ch.top, ch.left, ch.width
|
||||
try:
|
||||
@@ -89,6 +113,8 @@ def deco(ch, name, segs=(), texts=(), distante=()):
|
||||
for m in re.finditer(r"\d+\.\d\d", re.sub(r"<[^>]+>", "", t)):
|
||||
assert m.group(0) in desenate, \
|
||||
f"{name}: eticheta numește {m.group(0)}, care nu e un nivel desenat"
|
||||
if clear:
|
||||
_desprinse(svg, name, set(clear))
|
||||
sus = min(ch._y(c.h) for c in ch.candles)
|
||||
jos = max(ch._y(c.l) for c in ch.candles)
|
||||
for lv in ch.levels:
|
||||
@@ -161,15 +187,15 @@ deco(Chart(
|
||||
Level(E_D, f"intrare {E_D:.2f}", "#188a3e"),
|
||||
Level(TP_D, f"TP1 {TP_D:.2f} = {R_D}R", "#1a5fb4")],
|
||||
marks=[Mark(2, "trend ascendent anterior", "#188a3e", "below", dy=8),
|
||||
Mark(13, "picior 1", "#c00", "below"),
|
||||
Mark(13, "picior 1", "#c00", "below", dy=16),
|
||||
Mark(19, "picior 2 (mai jos)", "#c00", "below"),
|
||||
Mark(25, "hammer in capul triunghiului", "#b06000", "below"),
|
||||
Mark(25, "hammer in capul triunghiului", "#b06000", "below", dy=8),
|
||||
Mark(27, "breakout cu volum", "#188a3e")],
|
||||
zones=[Zone(10, 26, "wedge descendent = consolidare contra-trend (17 bare)",
|
||||
"#8b5cf6")],
|
||||
arrows=[Arrow(29, "stopul sta sub low-ul candelei de breakout:\n"
|
||||
"daca pretul se intoarce in triunghi, ideea a murit",
|
||||
price=SL_D, where="below", color="#c00", dy=18)],
|
||||
price=SL_D, where="below", color="#c00", dy=30, dx=44)],
|
||||
mas=[MA(20, "#b06000", dash="4 3", text="SMA-20")],
|
||||
scale=24, gap=16, body_w=9, left=46, width=730, top=62, vol_h=70,
|
||||
title="Wedge descendent — bull",
|
||||
@@ -179,11 +205,12 @@ deco(Chart(
|
||||
seg(10, L0, 13, lo_d(13), "#8b5cf6", "4 3", 1.2),
|
||||
seg(13, lo_d(13), 27, lo_d(27)),
|
||||
seg(10.0, L0, 10.0, U0, "#8b5cf6", "", 2.2),
|
||||
seg(30.6, E_D, 30.6, TP_D, "#1a5fb4", "", 2.2)],
|
||||
seg(35.6, E_D, 35.6, TP_D, "#1a5fb4", "", 2.2)],
|
||||
texts=[txt(10.1, (U0 + L0) / 2, f"baza = {BAZA_D:.2f}", anchor="start", dx=4),
|
||||
txt(30.4, (E_D + TP_D) / 2, f"aceeasi {BAZA_D:.2f}", "#1a5fb4",
|
||||
anchor="end", dx=-4)],
|
||||
distante=(BAZA_D,))
|
||||
txt(35.8, (E_D + TP_D) / 2, f"aceeasi {BAZA_D:.2f}", "#1a5fb4",
|
||||
anchor="start", dx=4)],
|
||||
distante=(BAZA_D,),
|
||||
clear=("picior 1", "breakout cu volum", "hammer in capul triunghiului"))
|
||||
|
||||
# ================================================ 2. wedge vs flag (forma)
|
||||
cl = (ramp(29.6, 34.00, 6) # 0-5 urcare
|
||||
@@ -420,7 +447,7 @@ deco(Chart(
|
||||
Level(TP2_F, f"TP2 {TP2_F:.2f} = batul steagului = {R2_F}R", "#1a5fb4")],
|
||||
marks=[Mark(2, "A", "#555", "below"), Mark(11, "B", "#555", dy=-20),
|
||||
Mark(20, "C = aici era by the dip", "#b06000", "below"),
|
||||
Mark(23, "breakout cu volum", "#188a3e", dy=-16)],
|
||||
Mark(23, "breakout cu volum", "#188a3e", dy=-36)],
|
||||
zones=[Zone(11, 22, "flamura (12 bare)", "#999")],
|
||||
mas=[MA(20, "#b06000", dash="4 3", text="SMA-20")],
|
||||
scale=13, gap=16, body_w=9, left=46, width=730, top=62, vol_h=70,
|
||||
@@ -432,9 +459,11 @@ deco(Chart(
|
||||
seg(14, lo_f(14), 23, lo_f(23), "#1a5fb4"),
|
||||
seg(11.0, 37.00, 11.0, 40.00, "#1a5fb4", "", 2.2),
|
||||
seg(3.3, POLE_A, 3.3, POLE_B, "#188a3e", "", 2.2)],
|
||||
texts=[txt(11.1, 38.50, f"canal {CANAL:.2f}", "#1a5fb4", anchor="start", dx=4),
|
||||
texts=[txt(11.1, 37.00, f"canal {CANAL:.2f}", "#1a5fb4", anchor="start",
|
||||
dx=4, dy=32),
|
||||
txt(3.2, 33.00, f"batul = {BAT:.2f}", "#188a3e", anchor="end", dx=-4)],
|
||||
distante=(CANAL, BAT))
|
||||
distante=(CANAL, BAT),
|
||||
clear=(f"canal {CANAL:.2f}", "breakout cu volum"))
|
||||
|
||||
# ======================================================= 6. bear flag / ABCD short
|
||||
POLE_A2, POLE_B2 = 60.00, 50.00
|
||||
@@ -498,7 +527,7 @@ deco(Chart(
|
||||
Level(TP2_B, f"TP2 {TP2_B:.2f} = batul steagului = {R2_B}R", "#1a5fb4")],
|
||||
marks=[Mark(2, "A", "#555", "below", dy=4), Mark(11, "B", "#555", "below", dy=14),
|
||||
Mark(20, "C = aici era sell the rally", "#b06000", dy=-20),
|
||||
Mark(23, "breakdown cu volum", "#c00", "below", dy=14)],
|
||||
Mark(23, "breakdown cu volum", "#c00", "below", dy=38)],
|
||||
zones=[Zone(11, 22, "flamura (12 bare)", "#999")],
|
||||
mas=[MA(20, "#b06000", dash="4 3", text="SMA-20")],
|
||||
scale=13, gap=16, body_w=9, left=46, width=730, top=66, vol_h=70,
|
||||
@@ -510,9 +539,11 @@ deco(Chart(
|
||||
seg(11, 50.00, 23, lo_b(23), "#1a5fb4"),
|
||||
seg(11.0, 50.00, 11.0, 53.00, "#1a5fb4", "", 2.2),
|
||||
seg(3.3, POLE_B2, 3.3, POLE_A2, "#c00", "", 2.2)],
|
||||
texts=[txt(11.1, 51.50, f"canal {CANAL2:.2f}", "#1a5fb4", anchor="start", dx=4),
|
||||
texts=[txt(11.1, 50.00, f"canal {CANAL2:.2f}", "#1a5fb4", anchor="start",
|
||||
dx=4, dy=28),
|
||||
txt(3.2, 56.00, f"batul = {BAT2:.2f}", "#c00", anchor="end", dx=-4)],
|
||||
distante=(CANAL2, BAT2))
|
||||
distante=(CANAL2, BAT2),
|
||||
clear=(f"canal {CANAL2:.2f}", "breakdown cu volum", "C = aici era sell the rally"))
|
||||
|
||||
# ============================================ 7. marubozu retestat — DA si NU
|
||||
def marubozu_serie(retest_close, retest_wick_up, cont):
|
||||
|
||||
@@ -140,11 +140,12 @@ susținut de volum.** Patru coloane, în ordinea din tabel:
|
||||
- **Net change** — cât la sută a urcat sau a scăzut prețul față de închiderea
|
||||
zilei precedente (exemplul din lecție: 5,03%).
|
||||
- **Range** — înălțimea candelei curente ca procent din media ultimelor trei
|
||||
candele. Peste 100% înseamnă volatilitate peste normal; în lecție, pe WBD
|
||||
(Warner Bros), o candelă verde plină de bull reversal arată **122%**.
|
||||
candele. Peste 100% înseamnă volatilitate peste normal; în lecție, o candelă
|
||||
plină arată **122%** (autorul nu numește simbolul pe care o găsește).
|
||||
- **RVol** — volumul ultimei bare față de media ultimelor 10 (input 10). Pe
|
||||
același WBD: **167%**, adică volum cu 67% peste medie. Range mare *plus*
|
||||
volum mare = mișcarea are susținere, nu e doar un fitil.
|
||||
WBD (Warner Bros), unde autorul arată o candelă verde plină de bull reversal:
|
||||
**167%**, adică volum cu 67% peste medie. Range mare *plus* volum mare =
|
||||
mișcarea are susținere, nu e doar un fitil.
|
||||
|
||||
<!--SVG:range_rvol-->
|
||||
|
||||
@@ -345,7 +346,7 @@ piața — același lucru pe care cursul îl face zilnic în predeschidere, uit
|
||||
la câte semnale noi de buy și de sell apar.
|
||||
|
||||
## Exemplul complet, long — XOM
|
||||
Singurul set de prețuri reale din lecție e cel de pe XOM (Exxon Mobil), citit
|
||||
Singurul set complet de prețuri reale din lecție e cel de pe XOM (Exxon Mobil), citit
|
||||
pe graficul daily de pe board-ul de 60 de minute, cu pivoții monthly: suportul
|
||||
**S1 = 113.03** (proiecție bull), prețul închis la **115.02**, deci coloana
|
||||
arată **1,76%** distanță față de suport; pivotul este rostit ca fiind la
|
||||
|
||||
@@ -210,8 +210,8 @@ CH["range_rvol"] = Chart(
|
||||
mas=[MA(20, "#b06000", dash="4 3", text="SMA-20")],
|
||||
**COMMON, scale=40, vol_h=70, vol_label="volum (ultima bară vs. media a 10)",
|
||||
title="Exemplu construit (fără ticker) — 60 de minute",
|
||||
caption="Cifrele cursului pentru WBD: range 122%, RVol 167%. Seria care le"
|
||||
" produce e a mea.").render()
|
||||
caption="Cifrele cursului: range 122% (rostit pe un simbol nenumit), RVol"
|
||||
" 167% pe WBD. Seria care le produce e a mea.").render()
|
||||
|
||||
|
||||
# ------------------------------------------------- 5 stele, long (XOM, real)
|
||||
|
||||
@@ -13,7 +13,7 @@ SRC = "/workspace/atm-curs-dl/gen/radarscreen_5_stele.md.in" # textul cu marcat
|
||||
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%"),
|
||||
("OFF HIGH", "—"), ("NET CHG", "—"), ("RANGE", "—"),
|
||||
("RVOL", "167%"), ("TRINITY", "—"), ("TRIGGER", "bull rev")]
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ def rand_radar() -> str:
|
||||
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"
|
||||
col = "#188a3e" if val in ("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"/>',
|
||||
@@ -42,7 +42,7 @@ def rand_radar() -> str:
|
||||
'<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>',
|
||||
' rostite în lecție pentru WBD: din el avem RVol 167% și un</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>']
|
||||
|
||||
Reference in New Issue
Block a user