buy_doji: refacut ca tutorial pe 3 niveluri, cu diagrame adnotate
Userul a respins mostra de format tutorial: prea lunga, prea multe trimiteri in text, termeni tehnici nedefiniti, prea multe cifre fara desen. Cerintele lui sunt acum contract in STYLE.md (FORMAT TUTORIAL v2). Textul: 8430 -> 4190 de cuvinte. Nivel 1 (din avion, cu mini-glosar) -> nivel 2 (6 pasi mecanici, o diagrama fiecare) -> oglinda short -> nivel 3 (rafinari). Trimiterile fisier:linie ies din corp si se aduna la final, cu legenda de prescurtari. Doua tabele in tot documentul. Toate cele 14 diagrame refacute: zone dreptunghiulare de evidentiere si sageti care spun si de ce, nu doar ce. svg_candles primeste Zone si Arrow; render() nu mai muta obiectul la iesire. Trei corecturi de continut: - un singur trade prin toata procedura (doji 50.10/49.25, intrare 50.40, stop 49.20, 1R 1.20, TP1 51.60); seria e acum o functie comuna, importata de stop/transe/iesire - short: stopul urca la 100.15, ca sa fie deasupra maximului cum cere regula oglindita; cifra cursului ramane in text ca observatie - LABU: trei minime dar doua atingeri ale pivotului 86.00, ceea ce impaca "triple bottom" cu "al doilea test", ambele din transcriere Reparat si bug-ul vechi din buy_doji_sell.svg: titlul peste eticheta dojiului. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
This commit is contained in:
@@ -133,14 +133,28 @@ def candles(bars, x0, gap, yf):
|
||||
|
||||
|
||||
out.append('<defs><marker id="pt-arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" '
|
||||
'markerHeight="7" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker></defs>')
|
||||
'markerHeight="7" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker>'
|
||||
'<marker id="pt-red" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" '
|
||||
'markerHeight="7" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#c00"/></marker></defs>')
|
||||
text(20, 22, "Aceeași regulă pe trei perechi — exemplu construit (fără ticker)", bold=True, size=14)
|
||||
|
||||
def zone(x0, y0_, x1, y1, color):
|
||||
out.append(f'<rect x="{x0:.1f}" y="{y0_:.1f}" width="{x1 - x0:.1f}" height="{y1 - y0_:.1f}" '
|
||||
f'fill="{color}" fill-opacity="0.10" stroke="{color}" stroke-width="1"/>')
|
||||
|
||||
|
||||
def bracket(x, ya, yb_, color, label):
|
||||
"""Paranteză verticală între două prețuri, cu eticheta la dreapta."""
|
||||
out.append(f'<path d="M{x - 5:.1f},{ya:.1f} H{x:.1f} V{yb_:.1f} H{x - 5:.1f}" '
|
||||
f'fill="none" stroke="{color}" stroke-width="1.6"/>')
|
||||
text(x + 5, (ya + yb_) / 2 + 4, label, fill=color, bold=True)
|
||||
|
||||
|
||||
y0 = 40
|
||||
ROW_H = 290
|
||||
for key, f, tf_big, tf_small, cap, exp in ROWS:
|
||||
big, small = scaled(BIG_A, f), scaled(SMALL_A, f)
|
||||
g = check(key, big, small, exp)
|
||||
first = key == "A"
|
||||
|
||||
# titlu rând + subtitluri
|
||||
text(20, y0 + 14, f"{key}. {tf_big} → {tf_small}", bold=True, size=13)
|
||||
@@ -155,60 +169,79 @@ for key, f, tf_big, tf_small, cap, exp in ROWS:
|
||||
yb = lambda p, t=top, m=bmax, s=bs: t + (m - p) * s # noqa: E731
|
||||
ys = lambda p, t=top, m=smax, s=ss: t + (m - p) * s # noqa: E731
|
||||
|
||||
# TF mare
|
||||
# TF mare: zonă peste doji + confirmare, eticheta dedesubt
|
||||
zx0, zx1 = BX0 + 9 * BGAP - 9, BX0 + 10 * BGAP + 9
|
||||
zone(zx0, yb(big[10][1]) - 5, zx1, yb(g["dl"]) + 5, GREEN)
|
||||
text((zx0 + zx1) / 2, yb(g["dl"]) + 20, "doji + confirmare:", fill=GREEN, anchor="middle", bold=True)
|
||||
text((zx0 + zx1) / 2, yb(g["dl"]) + 34, "aici se decide direcția", fill=GREEN,
|
||||
anchor="middle", bold=True)
|
||||
hline(BX0 - 16, BX0 + 10 * BGAP + 12, yb(g["dh"]), GRAY, "3 3")
|
||||
text(BX0 - 14, yb(g["dh"]) + 14, f"high doji {tf_big} {g['dh']:.2f}", fill="#666")
|
||||
candles(big, BX0, BGAP, yb)
|
||||
text(BX0 + 9 * BGAP, yb(g["dl"]) + 15, "doji", fill="#b06000", anchor="middle", bold=True)
|
||||
text(BX0 + 10 * BGAP - 4, yb(big[10][2]) + 15, "confirmare: long permis",
|
||||
fill=GREEN, bold=True)
|
||||
|
||||
# zoom: de la close-ul confirmării mari la open-ul primei bare mici (același preț)
|
||||
# săgeata-zoom: de la close-ul confirmării mari la open-ul primei bare mici (același preț)
|
||||
x1, y1 = BX0 + 10 * BGAP + 8, yb(g["conf"])
|
||||
x2, y2 = SX0 - 10, ys(g["conf"])
|
||||
out.append(f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{x2:.1f}" y2="{y2:.1f}" stroke="#555" '
|
||||
f'stroke-width="1.3" stroke-dasharray="5 3" marker-end="url(#pt-arr)"/>')
|
||||
text(300, y1 + 2, f"zoom pe {tf_small},", fill="#555")
|
||||
text(300, y1 + 16, "după confirmare", fill="#555")
|
||||
text(290, y1 + 2, "apoi cobori", fill="#555")
|
||||
text(290, y1 + 16, "pe graficul mic", fill="#555")
|
||||
|
||||
# TF mic: niveluri
|
||||
y_dh, y_e, y_sl, y_tp = ys(g["dh"]), ys(g["entry"]), ys(g["sl"]), ys(g["tp"])
|
||||
assert abs((y_sl - y_e) / (y_e - y_tp) - 1) < 1e-6, f"{key}: SL-intrare != intrare-TP1 în px"
|
||||
# zonă peste doji-ul mic + confirmare, eticheta dedesubt
|
||||
sx0, sx1 = SX0 + 8 * SGAP - 9, SX0 + 9 * SGAP + 9
|
||||
zone(sx0, y_e - 6, sx1, y_sl + 5, GREEN)
|
||||
text((sx0 + sx1) / 2, y_sl + 20, "doji la nivel:", fill=GREEN, anchor="middle", bold=True)
|
||||
text((sx0 + sx1) / 2, y_sl + 34, "aici intri", fill=GREEN, anchor="middle", bold=True)
|
||||
hline(SL_X1, SL_X2, y_dh, GRAY, "3 3")
|
||||
hline(SL_X1, SL_X2, y_e, GREEN, "6 3")
|
||||
hline(SL_X1, SL_X2, y_sl, RED, "6 3")
|
||||
hline(SL_X1, SL_X2, y_tp, GREEN, "2 3")
|
||||
text(COL_X, y_tp + 4, f"TP1 1:1 {g['tp']:.2f}", fill=GREEN, size=11)
|
||||
text(COL_X, y_tp + 4, f"ținta 1:1 {g['tp']:.2f}", fill=GREEN, size=11)
|
||||
text(COL_X, y_e + 4, f"intrare {g['entry']:.2f}", fill=GREEN, size=11)
|
||||
text(COL_X, y_dh - 5, f"high doji {g['dh']:.2f}", fill="#666", size=11)
|
||||
text(COL_X, y_sl + 12, f"SL {g['sl']:.2f}", fill=RED, size=11)
|
||||
text(COL_X, y_sl + 25, "= low 4 candele", fill=RED, size=11)
|
||||
text(COL_X, y_sl + 12, f"stop {g['sl']:.2f}", fill=RED, size=11)
|
||||
if first:
|
||||
text(COL_X, y_sl + 25, "sub ultimele", fill=RED, size=11)
|
||||
text(COL_X, y_sl + 38, "4 candele", fill=RED, size=11)
|
||||
candles(small, SX0, SGAP, ys)
|
||||
|
||||
# paranteză peste pullback-ul de 8 candele (barele 0..7)
|
||||
yb8 = y_tp - 12
|
||||
xa, xb = SX0 - 5, SX0 + 7 * SGAP + 5
|
||||
out.append(f'<path d="M{xa:.1f},{yb8 + 6:.1f} V{yb8:.1f} H{xb:.1f} V{yb8 + 6:.1f}" '
|
||||
f'fill="none" stroke="#555" stroke-width="1"/>')
|
||||
text((xa + xb) / 2, yb8 - 5, "pullback: 8 candele", fill="#555", anchor="middle")
|
||||
text(SX0 + 8 * SGAP + 4, y_sl + 15, "doji la nivel", fill="#b06000", anchor="end", bold=True)
|
||||
text(SX0 + 9 * SGAP - 8, y_e - 5, "intrare", fill=GREEN, anchor="end", bold=True)
|
||||
|
||||
# text sub rând
|
||||
text(20, top + PLOT_H + 50, cap.format(p=g["pct"], pb=g["b_pct"]), fill=INK, bold=True)
|
||||
if first:
|
||||
# paranteză peste pullback-ul de 8 candele (barele 0..7), doar pe primul rând
|
||||
yb8 = y_tp - 12
|
||||
xa, xb = SX0 - 5, SX0 + 7 * SGAP + 5
|
||||
out.append(f'<path d="M{xa:.1f},{yb8 + 6:.1f} V{yb8:.1f} H{xb:.1f} V{yb8 + 6:.1f}" '
|
||||
f'fill="none" stroke="#555" stroke-width="1"/>')
|
||||
text((xa + xb) / 2, yb8 - 5, "pullback: 8 candele", fill="#555", anchor="middle")
|
||||
# parantezele de stop: același setup, măsurat pe TF mare și pe TF mic
|
||||
bx = zx1 + 8
|
||||
bracket(bx, yb(g["b_entry"]), yb(g["b_sl"]), RED, f"stop {g['b_pct']:.2f} %".replace(".", ","))
|
||||
kx = SX0 + 9 * SGAP + 14
|
||||
bracket(kx, y_e, y_sl, RED, f"stop {g['pct']:.2f} %".replace(".", ","))
|
||||
ratio = g["b_pct"] / g["pct"]
|
||||
assert 4 <= ratio < 4.5, f"raportul stopurilor {ratio:.2f} nu e „de 4 ori”"
|
||||
# săgeata dintre ele, sub rând
|
||||
ya = top + PLOT_H + 58
|
||||
out.append(f'<line x1="{bx + 20:.1f}" y1="{ya:.1f}" x2="{kx + 20:.1f}" y2="{ya:.1f}" '
|
||||
f'stroke="{RED}" stroke-width="1.6" marker-end="url(#pt-red)"/>')
|
||||
text((bx + kx) / 2 + 20, ya + 17, "același setup, stop de 4 ori mai mic", fill=RED,
|
||||
anchor="middle", bold=True)
|
||||
text((bx + kx) / 2 + 20, ya + 31, "→ de 4 ori mai multe acțiuni la același risc", fill=RED,
|
||||
anchor="middle", bold=True)
|
||||
print(f"{key}: doji mare {g['dh']:.2f}/{g['dl']:.2f} conf {g['conf']:.2f} | intrare {g['entry']:.2f} "
|
||||
f"SL {g['sl']:.2f} risc {g['risk']:.2f} ({g['pct']:.2f} %) TP1 {g['tp']:.2f} | "
|
||||
f"doar mare: risc {g['b_risk']:.2f} ({g['b_pct']:.2f} %)")
|
||||
y0 += ROW_H
|
||||
y0 += 320 if first else 270
|
||||
if key != "C":
|
||||
out.append(f'<line x1="20" y1="{y0 - 14:.0f}" x2="{W - 20}" y2="{y0 - 14:.0f}" stroke="#ddd"/>')
|
||||
|
||||
text(20, y0 + 4, "Cifre construite, aceeași formă scalată pe trei perechi.", fill="#555")
|
||||
text(20, y0 + 21, "Procentele reale depind de simbol (LABU daily: stop 9 %).", fill="#555")
|
||||
H = y0 + 32
|
||||
H = y0 - 20
|
||||
|
||||
svg = (f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/svg" '
|
||||
f'style="width:100%;height:auto;font:12px sans-serif">\n ' + "\n ".join(out) + "\n</svg>")
|
||||
assert "\n\n" not in svg
|
||||
assert ".md:" not in svg and "Surse" not in svg, "trimiteri la surse în SVG"
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT} ({W}x{H:.0f})")
|
||||
|
||||
Reference in New Issue
Block a user