buy_doji: reparatiile de diagrame din verificare (11 puncte)

doji_forma nu mai foloseste 49.20 ca low al dojiului — era fix pretul
stopului, in prima diagrama pe care o vede un incepator. Bara e pe
50.10/49.25, cu procentele recalculate.

LABU: stopul e etichetat "pe cel mai jos dintre cele trei minime", nu
"sub minime"; zonele arata doua teste ale pivotului, cu "revenire peste
pivot 88.90" intre ele; numarul barei a iesit din desen, nota spune
"a 6-a bara dupa intrare", derivat din serie.

perechi_tf nu mai pune pretul TF-ului mare pe panoul TF-ului mic. aplus
nu mai numeste un nivel care nu e desenat. directie nu mai zice
"saptamanile" pe un panou daily. sell acopera toata cresterea, 14 bare.

transe: cele trei sageti nu mai converg intr-un ghem — fiecare are linia
ei cu pretul la capat; linia de intrare e desenata, ca parantezele de
risc sa plece de undeva. locatie arata 49.25, cifra din care iese 0,51 %.
stop si iesire: linii si sageti care taiau texte, mutate.

Jumatate din probleme erau aceeasi greseala: un pret scris de mana intr-o
eticheta, ramas in urma cand se schimba seria. Sunt acum aserttiuni care
o fac imposibila; PROGRESS.md spune care merita generalizata.

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-09-19 21:33:15 +00:00
parent f71cbf5a86
commit a92a12a65c
31 changed files with 888 additions and 658 deletions

View File

@@ -48,10 +48,12 @@ assert vols[14] > media_vol and vols[16] > media_vol, "volum peste medie pe doji
cds = from_closes(closes, wicks=wicks, vols=vols, start=closes[0])
doji, wait, conf = cds[14], cds[15], cds[16]
DOJI_I = 14 # indexul dojiului; barele 0..DOJI_I-1 sunt creșterea
doji, wait, conf = cds[DOJI_I], cds[15], cds[16]
# stopul 5 cenți DEASUPRA high-ului, oglinda pasului 5 (51.60 -> 51.55 pe long);
# cifrele vechi (SL 100.10, TP 97.90) puneau stopul exact pe high
entry, sl, tp = 99.00, 100.15, 97.85
risc = round(sl - entry, 2)
# --- cele 9 assert-uri cerute de specificație ------------------------------
# 1. SL-ul e 5 cenți peste high-ul ultimelor 4 candele (100.10)
@@ -80,6 +82,9 @@ assert cds[27].c < entry, "ieșirea n-ar fi pe profit"
assert abs(doji.o - doji.c) <= 0.10 * (doji.h - doji.l), "bara 14 nu e doji"
# 9. uptrend vizibil
assert cds[13].c > cds[0].c + 5, "uptrend prea mic"
# 10. creșterea ține de la bara 0 până imediat înainte de doji — asta acoperă
# zona „1. creștere de N candele", cu N = DOJI_I
assert cds[DOJI_I - 1].c > cds[0].c + 5, "creșterea nu urcă până la doji"
print(f"doji {doji.l:.2f}/{doji.h:.2f} intrare short {conf.c:.2f} "
f"SL {sl:.2f} TP {tp:.2f} trail {trail:.2f} ieșire bara 27 @ {cds[27].c:.2f}")
@@ -91,13 +96,16 @@ ch = Chart(
levels=[
# etichetele în dreapta, dincolo de ultima candelă (width > ultima
# candelă); titlul stă în stânga sus, deci nu mai are cu ce să se lovească
Level(sl, "stop 100.15", RED),
Level(entry, "intrare short 99.00", ORANGE),
Level(tp, "ținta 97.85", GREEN),
Level(sl, f"stop {sl:.2f}", RED),
Level(entry, f"intrare short {entry:.2f}", ORANGE),
Level(tp, f"ținta {tp:.2f}", GREEN),
],
zones=[
Zone(0, 9, "1. creștere de 10 candele", BLUE),
Zone(14, 14, "2. doji", ORANGE),
# zona acoperă TOATĂ creșterea (barele 0..13), iar numărul din etichetă
# iese din indici; p_top = high-ul dojiului, altfel eticheta urcă peste titlu
Zone(0, DOJI_I - 1, f"1. creșterea: {DOJI_I} candele",
BLUE, p_top=doji.h),
Zone(DOJI_I, DOJI_I, "2. doji", ORANGE),
# ca unealta „short position" din TradingView: roșu = risc, SUS;
# verde = câștig, JOS — pe short totul e întors față de long
Zone(16, 19, "", RED, p_top=sl, p_bot=entry),
@@ -107,15 +115,17 @@ ch = Chart(
Zone(25, 30, "", GRAY, p_top=trail, p_bot=trail - 0.02),
],
arrows=[
Arrow(18, "STOPUL SUS, la 100.15 — 5 cenți peste maximul ultimelor 4 candele:\n"
Arrow(18, f"STOPUL SUS, la {sl:.2f} — 5 cenți peste maximul ultimelor 4 candele:\n"
"dacă prețul urcă până aici, creșterea continuă și ideea e moartă",
where="above", price=sl, color=RED, dx=110),
Arrow(16, "AICI INTRI SHORT, la 99.00:\na doua candelă după doji e prima\n"
"care se ÎNCHIDE sub low-ul lui (99.20)",
Arrow(16, f"AICI INTRI SHORT, la {entry:.2f}:\na doua candelă după doji e prima\n"
f"care se ÎNCHIDE sub low-ul lui ({doji.l:.2f})",
where="below", color=ORANGE, dx=-70),
Arrow(19, "ținta JOS, la 97.85: tot 1.15, exact cât ai riscat;\naici închizi prima treime",
Arrow(19, f"ținta JOS, la {tp:.2f}: tot {risc:.2f}, exact cât ai riscat;\n"
"aici închizi prima treime",
where="right", price=tp, color=GREEN, dx=50, dy=-32),
Arrow(27, "trail-ul a coborât după preț (96.45);\nprima închidere peste el: ieși cu restul, 96.60",
Arrow(27, f"trail-ul a coborât după preț ({trail:.2f});\nprima închidere peste el: "
f"ieși cu restul, {cds[27].c:.2f}",
where="below", color=GRAY, dx=-40),
],
scale=45.0, gap=20, body_w=9, left=44, width=790, vol_h=60,
@@ -126,6 +136,16 @@ ch = Chart(
svg = ch.render()
assert "<svg" in svg and "\n\n" not in svg, "linie goală în SVG"
# fiecare preț din etichete e o valoare calculată din serie, nu una scrisă de mână
import re # noqa: E402
PERMISE = {f"{v:.2f}" for v in (sl, entry, tp, doji.l, doji.h, trail, cds[27].c, risc)}
for t in re.findall(r"<text[^>]*>([^<]*)</text>", svg):
for n in re.findall(r"\d+\.\d\d", t):
assert n in PERMISE, f"eticheta {t!r} numește {n}, care nu iese din serie"
# numărul din eticheta zonei 1 == câte bare acoperă efectiv zona (0..DOJI_I-1)
z1 = ch.zones[0]
assert f"{z1.i1 - z1.i0 + 1} candele" in z1.text, "eticheta zonei 1 nu spune câte bare acoperă"
assert z1.i1 == DOJI_I - 1 and cds[z1.i1].c > cds[z1.i0].c + 5, "zona 1 nu acoperă creșterea"
with open("/workspace/atm-curs-dl/gen/strategii/buy_doji_sell.svg", "w") as f:
f.write(svg)
print("scris gen/strategii/buy_doji_sell.svg")