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:
Claude Agent
2026-09-19 21:09:31 +00:00
parent aff03870e8
commit 8b7b5f6b44
50 changed files with 7011 additions and 6921 deletions

View File

@@ -1,4 +1,85 @@
# Progres — atm-curs-dl (actualizat 2026-09-19, 18:30 UTC) # Progres — atm-curs-dl (actualizat 2026-09-19, 21:15 UTC)
---
# 19.09.2026, 21:15 UTC — `01_buy_doji` refăcut după respingerea userului
## Ce a reclamat userul la mostra de format tutorial
A citit `01_buy_doji.html` și l-a respins. Cererile lui, care sunt acum
contract în `STYLE.md`, secțiunea **„FORMAT TUTORIAL v2"** (prima din fișier):
niveluri 1-2-3 de sus în jos; fiecare termen tehnic explicat inline la prima
folosire („iesire pe trail" nu se presupune știut); zero trimiteri
`fișier:linie` în corpul textului; diagrame „ca la proști", cu săgeți care
spun **și de ce**, și cu zona dreptunghiulară de evidențiere care i-a plăcut
la pasul 7; tranzacția în oglindă pe short cu **diagrama ei completă**; mai
puține tabele; mai scurt.
## Starea: gata, comis. Nimic nu mai rulează.
- Textul: de la **8430 la 4190 de cuvinte**, de la **2451 la ~570 de linii**.
Nivel 1 (din avion, cu mini-glosar de 9 termeni) → nivel 2 (6 pași
mecanici, fiecare cu diagrama lui și „Treci mai departe doar dacă…") →
oglinda short → nivel 3 (rafinări). Sursele, toate, la final, cu legendă de
prescurtări. Două tabele în tot documentul.
- **Toate cele 14 diagrame refăcute** cu zone și săgeți. `substituie.py`: 14
puse, 0 lipsă. Auditul: 8 raportări, toate fals-pozitive `<g transform>`
(perechi de etichete identice din panouri stivuite, în `aplus` și
`fereastra`) — verificate vizual, nu se atinge nimic.
- **Bug-ul vechi din `buy_doji_sell.svg`** (titlul peste eticheta
„doji 99.20 / 100.10") — reparat.
## Decizii de conținut luate azi (ca să nu fie redeschise)
1. **Un singur trade prin toată procedura.** Înainte, pașii 2-4 foloseau
doji 50.10 iar pașii 5-6 doji 53.00 — exact confuzia reclamată. Cifrele
canonice acum: doji **50.10 / 49.25**, intrare **50.40**, stop **49.20**,
1R = **1.20**, TP1 = **51.60**. Low-ul doji-ului a urcat de la 49.20 la
49.25 ca stopul să fie *sub* el, nu pe el. `buy_doji_ansamblu.serie()` e
sursa unică, importată de `stop`, `transe` și `iesire` — coerența e acum
structurală, nu ținută prin disciplină.
2. **Short: stop 100.15, nu 100.10.** Exemplul cursului punea stopul exact pe
high, contrazicând regula oglindită de la pasul 5. Am ales coerența cu
regula; cifra cursului (100.10 / 97.90) e păstrată în text ca observație.
3. **LABU: „triple bottom" și „al doilea test" nu se contrazic.** Ambele sunt
în transcriere. Seria arată acum **trei minime** (82.40 / 82.00 / 81.45)
dar **două atingeri** ale pivotului 86.00 — între primele două prețul urcă
la 88.90 și trece pe deasupra, înainte de al treilea urcă doar la 85.80.
Generatorul are o aserțiune care definește „test" ca minim precedat de o
revenire peste nivel, deci regula rezistă la ajustări viitoare.
4. Panoul de jos de la pasul 5 e **alt traseu**, nu seria comună (fundul mai
face un picior). Textul o spune explicit acum — altfel „a șasea candelă"
vs. „bara 19" pare eroare.
## Ce urmează
- **Userul trebuie să aprobe formatul** înainte să-l aplicăm la celelalte 8
capitole din `17_STRATEGII/`. Asta a fost înțelegerea de la început.
- Neatins, rămas de la `cap02`: în diagramele capitolului 02, SVG-ul cu Excel
etichetează „CROSSING BULL" ce e doar PPD > PPW, iar legenda SVG-ului
A+/mediocru dă confluența ca regulă a cursului, deși e completare.
- `aplus.spec.txt` cere doji cu high 79.00, generatorul are 78.50
(preexistent, nu din lotul de azi).
## CAPCANE NOI (din lotul ăsta)
- **`Chart.render()` restaura `top`/`left`/`width` la ieșire**, deci orice
coordonată calculată cu `_y()`/`_cx()` **după** randare ieșea deplasată cu
~22 px. Reparat azi în `svg_candles.py` (randarea nu mai mută obiectul);
generatoarele care își calculează singure offsetul din SVG-ul randat merg
mai departe — formula dă zero. Dacă ai nevoie de coordonate după randare,
folosește `_render()` și pune o aserțiune că `top`, `left` și lățimea din
`viewBox` n-au fost modificate: altfel o săgeată cu text prea lung mută
tăcut graficul și panourile stivuite se dezaliniază fără să pice nimic.
- **Eticheta unei `Zone` nu stă deasupra dreptunghiului**, ci deasupra celei
mai înalte candele din dreptul textului. La o zonă îngustă cu text lung
ajunge la zeci de pixeli de banda pe care o marchează. Soluție: `text=""`
și eticheta desenată manual, sau `p_top` distanțat pe verticală.
- **Agenții apar în `ListAgents` cu numele sesiunii-părinte**, identic cu al
sesiunii principale, nu cu numele lor de agent. Am cerut din greșeală
închiderea a patru agenți activi crezând că sunt sesiuni vechi. Au refuzat
corect, pentru că cererea era formulată „dacă ai ceva în lucru, refuză și
spune-mi ce ai atins". **Formulați mereu cererile de shutdown așa.**
--- ---

View File

@@ -3,6 +3,59 @@
Referință obligatorie înainte de a scrie/genera orice fișier nou în Referință obligatorie înainte de a scrie/genera orice fișier nou în
`summaries/`. Exemplul de referință: `summaries/05_MODUL_4/01_patternuri_complexe_partea_a_doua.md`. `summaries/`. Exemplul de referință: `summaries/05_MODUL_4/01_patternuri_complexe_partea_a_doua.md`.
## FORMAT TUTORIAL v2 — corecțiile userului după ce a citit `01_buy_doji` (19.09.2026, seara)
Userul a citit capitolul rescris în format tutorial și l-a respins. Ce a cerut,
punct cu punct. **Astea bat orice regulă de mai jos care le contrazice.**
### Structura: trei niveluri, de sus în jos
1. **Nivelul 1 — din avion.** O pagină. Ce e strategia, o diagramă mare cu
tot trade-ul adnotat, fraza de decizie, mini-glosarul termenilor. Cine
citește doar atât trebuie să știe deja ce caută pe ecran.
2. **Nivelul 2 — procedura mecanică.** Pașii, în ordinea în care îi faci.
Fiecare pas: o propoziție de acțiune, **o diagramă**, maximum ~300 de
cuvinte, și „Treci mai departe doar dacă…". Aici omul nu alege nimic — dă
din mână, mecanic.
3. **Nivelul 3 — rafinări.** Confirmările care fac un setup A+, perechile de
TF, tranșele, exemplul real, transferul pe prop/BVB, contradicțiile.
Începe cu o linie: „asta citești după 20 de trade-uri făcute mecanic".
### Limbaj
- **Explică fiecare termen tehnic la prima folosire, inline, într-o
propoziție.** „ieșire pe trail", „retest", „1R", „tranșe", „doji" — nimic
nu se presupune știut. Dacă termenul are formă pe grafic, desenează-l.
- Propoziții normale, nu telegrafice. Fără stil abrupt de notiță.
- Cifrele se plimbă cu o diagramă. Un pas care e doar text cu numere e un pas
prost scris.
### Referințe
- **Zero trimiteri `fișier:linie` în corpul textului.** Ele îngreunează
cititul. Toate se mută la finalul fiecărui nivel, într-un bloc „Surse",
grupate pe pas. În text, cel mult un link markdown către un alt capitol
din `summaries/`.
### Diagrame — „ca la proști"
- Fiecare diagramă de preț arată **săgeți cu text**: „aici intri", „aici pui
stopul — sub el ideea e moartă", „aici prima țintă".
- **Zonă dreptunghiulară de evidențiere** peste regiunea despre care e
vorba (userului i-a plăcut explicit cea de la pasul 7). Folosește-o.
- Fiecare săgeată spune și **de ce**, nu doar ce.
- **Tranzacția în oglindă (short) are diagrama ei completă**, nu o
propoziție „e invers". Userul e vizual.
### Volum
- Mai puține tabele. Un tabel doar dacă compari 3+ lucruri pe aceleași
criterii. Altfel: listă sau paragraf.
- Mai scurt. Userul: „te lungesti foarte mult", „daca imi dai extrem de
multe informatii nu stiu care sunt relevante". Ce nu intră în procedura
mecanică merge la nivelul 3 sau se taie.
- Exemplele concrete și setup-urile rămân — alea îi plac. Abstracțiile pleacă.
## FORMAT TUTORIAL pentru capitolele de strategie (cerut de user, 19.09.2026) ## FORMAT TUTORIAL pentru capitolele de strategie (cerut de user, 19.09.2026)
Userul a citit `17_STRATEGII/A3_intrarea.md` și a spus: conținutul îi place, Userul a citit `17_STRATEGII/A3_intrarea.md` și a spus: conținutul îi place,

View File

@@ -1,103 +1,166 @@
"""Buy Doji — diagrama de ansamblu (daily, exemplu construit, fără ticker). """Buy Doji — diagrama de ansamblu (daily, exemplu construit, fără ticker).
Citește specificația `gen/strategii/buy_doji_ansamblu.spec.txt`. Seria de Citește specificația `gen/strategii/buy_doji_ansamblu.spec.txt`.
32 de candele e construită din lista de close-uri dată, cu open-ul fiecărei
bare = close-ul precedentului; wick-urile sunt fixate ca nivelurile Seria de aici e SURSA UNICĂ a trade-ului din capitol: buy_doji_stop,
(doji 50.10/49.20, intrare 50.40, SL 49.20, TP1 51.60, trail 52.60, ieșire buy_doji_transe și buy_doji_iesire importă `serie()` și pornesc din
sub trail la bara 28) să iasă exact din serie, nu doar din etichetă. aceleași bare (doji 50.10/49.25, confirmare 50.40, SL 49.20, TP1 51.60),
ca începătorul să urmărească un singur trade prin toată procedura.
Barele 0-19: close-uri, open = close-ul precedentului. Barele 20-28 sunt
date explicit: 21 și 27 deschid cu GAP (low peste high-ul precedentei),
fiindcă regula de trail din curs se sprijină exact pe barele astea.
""" """
import sys; sys.path.insert(0, "/workspace/atm-curs-dl") import sys; sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Chart, Level, Mark, MA, from_closes from svg_candles import Candle, Chart, Level, MA, Zone, Arrow, from_closes
# --- seria: 32 de close-uri, exact ca în specificație ----------------------- OUT = "/workspace/atm-curs-dl/gen/strategii/buy_doji_ansamblu.svg"
closes = [
60.20, 59.20, 59.60, 58.40, 57.30, 57.70, 56.50, 55.40, 55.80, 54.70, # 0-9
53.50, 52.30, 51.00, 49.65, # 10-13 downtrend
49.60, # 14 doji
49.90, # 15 +1 (nu confirmă)
50.40, # 16 +2 confirmare => intrare
50.90, 51.20, 51.50, 51.80, 52.10, 52.40, 52.20, 52.70, 52.95, 53.20, # 17-26
52.80, 52.30, 52.00, 51.80, 51.90, # 27-31
]
assert len(closes) == 32
# wick-uri: (up, down) implicite (0.25, 0.30) + excepțiile din specificație DOJI, WAIT, CONF = 14, 15, 16 # indicii barelor-cheie
wicks = [(0.25, 0.30)] * 32 DOJI_H, DOJI_L = 50.10, 49.25
wicks[14] = (0.45, 0.40) # doji: high 50.10, low 49.20 ENTRY, SL, TP1 = 50.40, 49.20, 51.60
wicks[15] = (0.15, 0.15) # high 50.05, low 49.45 R = 1.20
wicks[16] = (0.15, 0.15) # high 50.55, low 49.75
for k in range(24, 28): # barele 24-27
wicks[k] = (0.25, 0.20)
# volum relativ ales de generator (materialul nu dă volum pe exemplu);
# peste medie pe doji (14) și pe confirmare (16), apoi normal
vols = [42, 44, 40, 46, 43, 41, 45, 42, 44, 47,
43, 45, 48, 52, 78, 46, 88, 55,
50, 48, 52, 47, 45, 49, 46, 44, 48, 51,
54, 47, 45, 46]
assert len(vols) == 32
media_vol = sum(vols) / len(vols)
assert vols[14] > media_vol and vols[16] > media_vol, "volum peste medie pe doji/confirmare"
cds = from_closes(closes, wicks=wicks, vols=vols, start=60.20) def serie() -> list[Candle]:
"""Cele 32 de bare ale trade-ului, cu verificările de bază."""
closes = [
60.20, 59.20, 59.60, 58.40, 57.30, 57.70, 56.50, 55.40, 55.80, 54.70, # 0-9
53.50, 52.30, 51.00, 49.65, # 10-13 downtrend
49.60, # 14 doji
49.90, # 15 +1 (nu confirmă)
50.40, # 16 confirmare => intrare
50.90, 51.20, 51.50, # 17-19 (19 atinge TP1)
]
wicks = [(0.25, 0.30)] * len(closes)
wicks[14] = (0.45, 0.35) # doji: high 50.10, low 49.25
wicks[15] = (0.15, 0.15) # high 50.05, low 49.45
wicks[16] = (0.15, 0.15) # high 50.55, low 49.75
cds = from_closes(closes, wicks=wicks, start=60.20)
cds += [Candle(*b) for b in [
(51.50, 51.85, 51.40, 51.75), # 20
(52.00, 52.30, 51.95, 52.20), # 21 GAP: low 51.95 > high[20] 51.85 → trail 51.95
(52.20, 52.45, 52.05, 52.35), # 22
(52.35, 52.40, 52.00, 52.10), # 23 retragere, close peste trail: rămâi
(52.10, 52.50, 52.05, 52.40), # 24
(52.40, 52.55, 52.25, 52.50), # 25
(52.50, 52.55, 52.35, 52.45), # 26
(52.70, 53.10, 52.60, 52.95), # 27 GAP: low 52.60 > high[26] 52.55 → trail 52.60
(52.95, 53.00, 52.20, 52.30), # 28 close 52.30 < 52.60: ieși
]]
cds += from_closes([52.00, 51.80, 51.90], wick=0.25, start=52.30) # 29-31
assert len(cds) == 32
for i, c in enumerate(cds):
assert c.l <= min(c.o, c.c) and c.h >= max(c.o, c.c), f"bara {i}: h/l nu cuprind o/c"
if i and i not in (21, 27):
assert abs(c.o - cds[i - 1].c) < 1e-9, f"open[{i}] != close[{i-1}]"
d = cds[DOJI]
assert (round(d.h, 2), round(d.l, 2)) == (DOJI_H, DOJI_L), (d.h, d.l)
assert abs(d.o - d.c) <= 0.10 * (d.h - d.l), "bara 14 nu e doji"
assert cds[WAIT].c <= DOJI_H < cds[CONF].c, "fereastra: 15 nu confirmă, 16 da"
assert abs(cds[CONF].c - ENTRY) < 1e-9
assert abs(min(c.l for c in cds[CONF - 3:CONF + 1]) - DOJI_L) < 1e-9, "low-ul doji nu e cel mai jos din 4"
assert round(DOJI_L - 0.05, 2) == SL and round(ENTRY - SL, 2) == R and round(ENTRY + R, 2) == TP1
return cds
# adnotările pe bara +1 și pe confirmare, ca linii sub grafic (fără suprapunere)
cds[15].color = "#777" # bara de așteptare: neutră, nu confirmă
cds[15].note = "bara 15: close 49.90 sub high-ul dojiului 50.10 — NU confirmă"
cds[16].note = "bara 16: close 50.40 peste 50.10 — confirmare (intrare)"
doji, wait, conf = cds[14], cds[15], cds[16] def trail(cds, start=CONF + 1):
entry, sl, tp1, trail = 50.40, 49.20, 51.60, 52.60 """Regula de trail: bara cu low > high-ul precedentei urcă linia la low-ul ei;
ieși la primul close sub linie. Întoarce (treptele, bara de ieșire)."""
t, steps = None, []
for i in range(start, len(cds)):
if t is not None and cds[i].c < t:
return steps, i
if cds[i].l > cds[i - 1].h:
t = cds[i].l
steps.append((i, round(t, 2)))
return steps, None
# --- cele 9 assert-uri cerute de specificație ------------------------------
# 1. SL-ul e exact low-ul dojiului, cel mai jos din fereastra de 4 candele
assert abs(min(cd.l for cd in cds[13:17]) - 49.20) < 1e-9, "min low[13:17] != 49.20"
# 2. intrarea e close-ul barei 16
assert abs(conf.c - entry) < 1e-9, f"close[16]={conf.c} != 50.40"
# 3. confirmarea închide peste high-ul dojiului
assert abs(doji.h - 50.10) < 1e-9 and conf.c > doji.h, "close[16] nu e peste high[14]"
# 4. bara +1 NU confirmă
assert wait.c <= doji.h, "bara 15 ar confirma, fereastra n-ar avea sens"
# 5. 1:1 exact
assert abs(abs(entry - sl) - abs(tp1 - entry)) < 1e-9 and abs((entry - sl) - 1.20) < 1e-9, \
"risc != recompensă (nu e 1:1 exact)"
# 6. primul high >= TP1 după intrare e bara 19
primul_tp = next(i for i in range(17, len(cds)) if cds[i].h >= tp1)
assert primul_tp == 19, f"TP1 51.60 atins întâi la bara {primul_tp}, nu 19"
# 7. trailing 52.60 = low[27]; ieșire la bara 28 sub el; ieșirea e pe profit
assert abs(cds[27].l - trail) < 1e-9, f"low[27]={cds[27].l} != 52.60"
assert abs(cds[28].c - 52.30) < 1e-9 and cds[28].c < trail, "close[28] nu e sub trail"
assert trail > entry, "trail sub intrare, ieșirea n-ar fi pe profit"
# 8. doji: corp <= 10% din amplitudine
assert abs(doji.o - doji.c) <= 0.10 * (doji.h - doji.l), "bara 14 nu e doji"
# 9. downtrend vizibil
assert cds[13].c < cds[0].c - 10, "downtrend prea mic"
print(f"doji {doji.h:.2f}/{doji.l:.2f} intrare {conf.c:.2f} " if __name__ == "__main__":
f"SL {sl:.2f} TP1 {tp1:.2f} trail {trail:.2f} ieșire bara 28 @ {cds[28].c:.2f}") cds = serie()
vols = [42, 44, 40, 46, 43, 41, 45, 42, 44, 47,
43, 45, 48, 52, 78, 46, 88, 55,
50, 48, 52, 47, 45, 49, 46, 44, 48, 51,
54, 47, 45, 46]
for c, v in zip(cds, vols):
c.vol = v
media_vol = sum(vols) / len(vols)
assert vols[DOJI] > media_vol and vols[CONF] > media_vol, "volum peste medie pe doji/confirmare"
# --- desenul ---------------------------------------------------------------- # --- aserțiunile specificației ---------------------------------------------
ch = Chart( primul_tp = next(i for i in range(CONF + 1, len(cds)) if cds[i].h >= TP1)
candles=cds, assert primul_tp == 19, f"TP1 51.60 atins întâi la bara {primul_tp}, nu 19"
levels=[ steps, iesire = trail(cds)
Level(sl, "SL 49.20 (low 4 candele)", "#c00", label_at="left"), assert steps == [(21, 51.95), (27, 52.60)], steps
Level(entry, "intrare 50.40", "#188a3e", label_at="left"), assert iesire == 28 and abs(cds[28].c - 52.30) < 1e-9, iesire
Level(tp1, "TP1 51.60 = 1R", "#1a5fb4", label_at="left"), assert steps[-1][1] > ENTRY, "trail sub intrare, ieșirea n-ar fi pe profit"
Level(trail, "trail 52.60", "#b06000"), R_IES = round((cds[28].c - ENTRY) / R, 2)
], assert R_IES == 1.58, R_IES
marks=[ assert cds[13].c < cds[0].c - 10, "downtrend prea mic"
Mark(14, "doji 50.10 / 49.20", "#b06000", "below"), print(f"doji {DOJI_H:.2f}/{DOJI_L:.2f} intrare {ENTRY:.2f} SL {SL:.2f} TP1 {TP1:.2f} "
Mark(28, "ieșire pe trail ~52.60", "#c00", "above", dy=-6), f"trail {steps} ieșire bara 28 @ {cds[28].c:.2f} = +{R_IES}R")
],
mas=[MA(20, "#777", dash="4 3", text="MA(20)")],
scale=24.0, gap=15, body_w=9, left=44, width=640, vol_h=70,
vol_label="volum", title="Buy Doji — daily (exemplu construit, fără ticker)",
caption="Intrare la close-ul confirmării, SL la low-ul ultimelor 4 candele, "
"TP1 1:1, apoi trailing stop.",
)
svg = ch.render() cds[WAIT].color = "#777" # bara de așteptare: neutră, nu confirmă
assert "<svg" in svg and "\n\n" not in svg, "linie goală în SVG" GREEN, RED, BLUE, ORANGE, GREY = "#188a3e", "#c00", "#1a5fb4", "#b06000", "#666"
with open("/workspace/atm-curs-dl/gen/strategii/buy_doji_ansamblu.svg", "w") as f: ch = Chart(
f.write(svg) candles=cds,
print("scris gen/strategii/buy_doji_ansamblu.svg") levels=[
Level(TP1, "ținta 1: 51.60", BLUE, label_at="left"),
Level(ENTRY, "intrare 50.40", GREEN, label_at="left"),
Level(SL, "stop 49.20", RED, label_at="left"),
],
zones=[
Zone(4, 13, "1. scăderea: vânzătorii obosesc", RED),
Zone(14, 15, "2. doji: pauză, încă nu intri", ORANGE, p_top=53.9),
Zone(16, 16, "3. confirmarea", GREEN, p_top=52.9),
Zone(17, 28, "4. ieșirea: o treime la țintă, restul pe trail", BLUE, p_top=54.9),
],
arrows=[
Arrow(DOJI, "stopul 49.20, 5 cenți sub doji\nsub el, ideea că vânzătorii\nau obosit e moartă",
where="below", price=SL, color=RED, dx=-150, dy=0),
Arrow(CONF, "AICI INTRI, la close 50.40\nabia acum știi că\ncumpărătorii au câștigat",
where="below", price=ENTRY, color=GREEN, dx=-10, dy=64),
Arrow(19, "ținta 1: 51.60 = riscul (1.20)\nîncă o dată: vinzi o treime",
where="below", price=TP1, color=BLUE, dx=95, dy=74),
Arrow(27, "trailing stop: urcă după preț\nla fiecare gap, nu coboară",
where="above", color=ORANGE, dx=40),
Arrow(28, "ieși la 52.30 (+1.58R)\nprima închidere sub trail",
where="right", color=RED, dx=40, dy=-48),
],
mas=[MA(20, "#999", dash="4 3", text="MA(20)")],
scale=40.0, gap=15, body_w=9, left=44, width=640, vol_h=60,
vol_label="volum", title="Buy Doji — un trade de la cap la coadă (daily, exemplu construit)",
)
svg = ch.render()
# render() mută `top` intern (titlu, săgeți) și îl restaurează: ch._y() de aici
# e mai sus cu atâta. Offsetul se citește din prima linie de Level desenată.
import re as _re
OFF = (float(_re.search(r'<line x1="24" y1="([\d.]+)"', svg).group(1))
- ch._y(ch.levels[0].price))
def Y(p):
return ch._y(p) + OFF
# linia de trail în trepte (Level ar trage-o pe toată lățimea, înainte să existe)
(i1, t1), (i2, t2) = steps
x0, xa, xb = ch._cx(i1) - 7, ch._cx(i2) - 7, ch._cx(iesire) + 7
ya, yb = Y(t1), Y(t2)
step = (f'<polyline points="{x0:.1f},{ya:.1f} {xa:.1f},{ya:.1f} {xa:.1f},{yb:.1f} '
f'{xb:.1f},{yb:.1f}" fill="none" stroke="{ORANGE}" stroke-width="2"/>')
# parantezele 1R: riscul jos, ținta sus, aceeași înălțime = „1:1"
xp = ch._cx(5)
br = []
for lo, hi, txt, col in ((SL, ENTRY, "1R = 1.20 (riscul)", RED),
(ENTRY, TP1, "1R = 1.20 (ținta)", BLUE)):
y1, y2 = Y(hi) + 2, Y(lo) - 2
br.append(f'<polyline points="{xp - 5:.1f},{y1:.1f} {xp:.1f},{y1:.1f} {xp:.1f},{y2:.1f} '
f'{xp - 5:.1f},{y2:.1f}" fill="none" stroke="{col}" stroke-width="1.5"/>')
br.append(f'<text x="{xp + 6:.1f}" y="{(y1 + y2) / 2 + 4:.1f}" fill="{col}" '
f'style="font-weight:bold">{txt}</text>')
body = svg.rsplit("</svg>", 1)[0].rstrip()
svg = "\n ".join([body, step, *br]) + "\n</svg>"
assert "<svg" in svg and "\n\n" not in svg, "linie goală în SVG"
with open(OUT, "w") as f:
f.write(svg)
print("scris gen/strategii/buy_doji_ansamblu.svg")

View File

@@ -1,58 +1,76 @@
TIP: PRET SPEC DIAGRAMĂ — buy_doji_ansamblu
CHEIE: ansamblu =================================
TITLU: Buy Doji — daily (exemplu construit, fără ticker) tip: PRET (un singur panou, cu volum)
MARCAJ .md: <!-- DIAGRAMA: ansamblu --> (Nivel 0, „Diagrama de ansamblu") destinație: summaries/17_STRATEGII/01_buy_doji.md, nivelul 1 („tot trade-ul")
cheie markdown: <!-- DIAGRAMA: ansamblu -->
titlu SVG: „Buy Doji — un trade de la cap la coadă (daily, exemplu construit)"
rol: SURSA UNICĂ a seriei. buy_doji_stop, buy_doji_transe și
buy_doji_iesire importă `serie()` din generatorul ăsta, ca
toate patru să arate ACELAȘI trade.
CE ARATĂ TRADE-UL (aceleași cifre în toate cele patru diagrame)
Graficul întreg al unui trade Buy Doji long: downtrend de 14 candele, ------------------------------------------------------
doji, o candelă de așteptare (în fereastră, care NU confirmă), apoi cea doji (bara 14): high 50.10, low 49.25
care confirmă; intrare la close-ul confirmării, SL la extrema ultimelor 4 bara 15 (+1): close 49.90, sub 50.10 — NU confirmă
candele, TP 1:1 atins, apoi poziția rămasă pe trailing stop până la bara 16 (+2): close 50.40 — confirmare => INTRARE 50.40
ieșire. Banda de jos = volum. cel mai jos low din ultimele 4 candele (13-16): 49.25 (al doji-ului)
STOP: 49.20 (5 cenți sub); 1R = 1.20; ȚINTA 1: 51.60 (atinsă la bara 19)
trailing stop: 51.95 (gap la bara 21) → 52.60 (gap la bara 27)
ieșire: close 52.30 la bara 28 = +1.58R
NIVELURILE ȘI ETICHETELE (cu trimitere) STRUCTURA SERIEI (32 bare, 0-indexate)
- doji high = 50.10, doji low = 49.20. Etichetă pe bară „doji 50.10 / 49.20". --------------------------------------
`13_strategia_3_byh.md:90`, exemplul din `13_strategia_3_byh.md:158-167`. Barele 0-19 din close-uri, open = close-ul precedentului, fitile (0.25, 0.30),
- intrare = 50.40 (close-ul candelei de confirmare). Etichetă „intrare 50.40". cu excepțiile: 14 (0.45, 0.35) → high 50.10 / low 49.25; 15 și 16 (0.15, 0.15).
`13_strategia_3_byh.md:158-167`. close-uri 0-19: 60.20, 59.20, 59.60, 58.40, 57.30, 57.70, 56.50, 55.40, 55.80,
- SL = 49.20 (low-ul dojiului = cel mai jos low din 4 candele). Etichetă 54.70, 53.50, 52.30, 51.00, 49.65, 49.60, 49.90, 50.40, 50.90, 51.20, 51.50.
„SL 49.20 (low 4 candele)". Regula: `13_strategia_3_byh.md:192-193`. Barele 20-28 date explicit (o, h, l, c) — 21 și 27 deschid cu GAP, fiindcă
- TP1 = 51.60 = 1R (50.40 + 1.20). Etichetă „TP1 51.60 = 1R". Regula 1:1: regula de trail cere o bară cu low peste high-ul precedentei:
`13_strategia_3_byh.md:194-195`. 20 (51.50, 51.85, 51.40, 51.75)
- linia de trailing = 52.60 (low-ul barei 27), etichetă „trail 52.60"; 21 (52.00, 52.30, 51.95, 52.20) GAP: low 51.95 > high[20] 51.85 → trail 51.95
ieșire la close sub ea (bara 28, close 52.30). Regula de trail: 22 (52.20, 52.45, 52.05, 52.35)
`13_strategia_3_byh.md:196-200`; „ieșire pe trail ~52.60" în diagrama 23 (52.35, 52.40, 52.00, 52.10) retragere, close peste trail: rămâi în trade
lecției: `13_strategia_3_byh.md:91`. 24 (52.10, 52.50, 52.05, 52.40)
25 (52.40, 52.55, 52.25, 52.50)
26 (52.50, 52.55, 52.35, 52.45)
27 (52.70, 53.10, 52.60, 52.95) GAP: low 52.60 > high[26] 52.55 → trail 52.60
28 (52.95, 53.00, 52.20, 52.30) close sub 52.60: IEȘIRE
Barele 29-31 din close-uri 52.00, 51.80, 51.90 (fitil 0.25).
Volum: peste media seriei pe doji (14) și pe confirmare (16), altfel normal.
Valorile de volum sunt alese de generator (materialul nu le dă).
STRUCTURA SERIEI (32 candele, 0-indexate, open = close-ul precedentului) ADNOTĂRI (formatul tutorial v2: zone + săgeți cu CE și DE CE)
Lista de close-uri: -------------------------------------------------------------
[60.20, 59.20, 59.60, 58.40, 57.30, 57.70, 56.50, 55.40, 55.80, 54.70, 4 zone dreptunghiulare: „1. scăderea: vânzătorii obosesc" (4-13),
53.50, 52.30, 51.00, 49.65, # 13 = ultima bară de downtrend „2. doji: pauză, încă nu intri" (14-15), „3. confirmarea" (16),
49.60, # 14 = doji (o 49.65, c 49.60, h 50.10, l 49.20) „4. ieșirea: o treime la țintă, restul pe trail" (17-28).
49.90, # 15 = +1, sub high-ul dojiului, NU confirmă 5 săgeți: stopul 49.20; „AICI INTRI, la close 50.40"; ținta 1 = riscul;
50.40, # 16 = +2, confirmare (close peste 50.10) => intrare trailing stop (urcă la fiecare gap); ieșirea la 52.30 (+1.58R).
50.90, 51.20, 51.50, 51.80, 52.10, 52.40, 52.20, 52.70, 52.95, 53.20, Două paranteze verticale egale: 49.20→50.40 „1R = 1.20 (riscul)" și
52.80, 52.30, 52.00, 51.80, 51.90] 50.40→51.60 „1R = 1.20 (ținta)" — așa se vede 1:1.
Mecioni (up, down) implicite (0.25, 0.30) pentru toate barele, cu excepțiile: Linia de trail e desenată în trepte (un Level ar trage-o pe toată lățimea,
- bara 14 (doji): o=49.65, c=49.60 => wu=0.45 (high 50.10), wd=0.40 (low 49.20); inclusiv înainte să existe).
- bara 15: o=49.60, c=49.90 => wu=0.15 (high 50.05), wd=0.15 (low 49.45);
- bara 16: o=49.90, c=50.40 => wu=0.15 (high 50.55), wd=0.15 (low 49.75);
- barele 24-27: wd=0.20. Cu lista de mai sus, low[27] = 52.60 (linia de trail).
Volum: peste media seriei pe doji și pe confirmare (publicul intră), apoi
normal. Valori relative, alese de generator (materialul nu dă volum pentru
acest exemplu).
CE VERIFICĂ GENERATORUL CU assert CE VERIFICĂ GENERATORUL CU assert
1. min(low[13:17]) == 49.20 (SL-ul e exact low-ul dojiului, cel mai jos din 4) ---------------------------------
2. close[16] == 50.40 == intrare 1. h/l cuprind o/c pe toate barele; open[i] == close[i-1] peste tot în afară
3. close[16] > high[14] == 50.10 (confirmarea chiar închide peste high) de barele de gap 21 și 27.
4. close[15] <= high[14] (bara +1 NU confirmă — altfel fereastra n-ar avea sens) 2. doji: high 50.10, low 49.25, corp <= 10% din amplitudine.
5. abs(entry - sl) == abs(tp1 - entry) == 1.20 (1:1 exact, nu aproximat) 3. close[15] <= 50.10 < close[16]; close[16] == 50.40 (fereastra are sens).
6. primul i>16 cu high[i] >= 51.60 este bara 19 4. min(low[13:17]) == 49.25; 49.25 - 0.05 == 49.20; 50.40 - 49.20 == 1.20;
7. low[27] == 52.60; close[28] == 52.30 < 52.60; și 52.60 > intrare 50.40 + 1.20 == 51.60.
(ieșirea pe trail e pe profit) 5. primul high >= 51.60 după intrare e bara 19.
8. doji: abs(o-c) <= 0.10 * (h-l) (corp ≤ 10%, criteriul din 6. regula de trail, calculată pe serie, dă exact [(21, 51.95), (27, 52.60)]
`28_2025-05-27.md:343-349`) și ieșire la bara 28, close 52.30; 52.60 > intrare (ieșire pe profit).
9. trend: close[13] < close[0] - 10 (downtrend vizibil) 7. (52.30 - 50.40) / 1.20 == 1.58.
STIL: gap=15, body_w=9, left=44, width=640, vol_h=70, scale ~24, MA(20) 8. volum peste medie pe 14 și 16.
opțional (linia mediei apare pe graficul lecției). Fără linie goală în SVG. 9. downtrend: close[13] < close[0] - 10.
SURSA
-----
- Doji 50.10/49.20 și intrarea la close-ul confirmării: summaries/03_MODUL_2/
13_strategia_3_byh.md:90, :158-167. Low-ul doji-ului e coborât aici la 49.25,
ca stopul de 49.20 să fie SUB el, nu exact pe el (decizie de redactare).
- SL = extrema ultimelor 4 candele: :192-193. Ținta 1:1: :194-195.
- Trail pe gap și ieșire la close sub linie: :196-200.
- Barele de după intrare sunt CONSTRUITE.

View File

@@ -1,116 +1,144 @@
<svg viewBox="0 0 640 498" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 709 739" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="48" fill="#333" style="font-weight:bold">Buy Doji — daily (exemplu construit, fără ticker)</text> <text x="24" y="48" fill="#333" style="font-weight:bold">Buy Doji — un trade de la cap la coadă (daily, exemplu construit)</text>
<line x1="24" y1="326.0" x2="626" y2="326.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="94.5" y="120.0" width="154.0" height="388.0" fill="#c00" fill-opacity="0.08" stroke="#c00" stroke-width="1"/>
<text x="30" y="320.0" fill="#c00">SL 49.20 (low 4 candele)</text> <text x="94.5" y="115.0" fill="#c00" style="font-weight:bold">1. scăderea: vânzătorii obosesc</text>
<line x1="24" y1="297.2" x2="626" y2="297.2" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="244.5" y="318.0" width="34.0" height="194.0" fill="#b06000" fill-opacity="0.08" stroke="#b06000" stroke-width="1"/>
<text x="30" y="291.2" fill="#188a3e">intrare 50.40</text> <text x="244.5" y="313.0" fill="#b06000" style="font-weight:bold">2. doji: pauză, încă nu intri</text>
<line x1="24" y1="268.4" x2="626" y2="268.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="274.5" y="358.0" width="19.0" height="134.0" fill="#188a3e" fill-opacity="0.08" stroke="#188a3e" stroke-width="1"/>
<text x="30" y="262.4" fill="#1a5fb4">TP1 51.60 = 1R</text> <text x="274.5" y="353.0" fill="#188a3e" style="font-weight:bold">3. confirmarea</text>
<line x1="24" y1="244.4" x2="626" y2="244.4" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="289.5" y="278.0" width="184.0" height="200.0" fill="#1a5fb4" fill-opacity="0.08" stroke="#1a5fb4" stroke-width="1"/>
<text x="612" y="238.4" fill="#b06000" text-anchor="end">trail 52.60</text> <text x="289.5" y="273.0" fill="#1a5fb4" style="font-weight:bold">4. ieșirea: o treime la țintă, restul pe trail</text>
<polyline points="329.0,205.1 344.0,215.2 359.0,223.7 374.0,232.3 389.0,239.8 404.0,245.3 419.0,251.0 434.0,255.0 449.0,258.1 464.0,262.3 479.0,265.5 494.0,267.6 509.0,268.0" fill="none" stroke="#777" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="24" y1="410.0" x2="695" y2="410.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="515" y="262" fill="#777">MA(20)</text> <text x="30" y="404.0" fill="#1a5fb4">ținta 1: 51.60</text>
<line x1="44.0" y1="56.0" x2="44.0" y2="69.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="24" y1="458.0" x2="695" y2="458.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
<rect x="39.5" y="62.0" width="9" height="1.6" fill="#188a3e"/> <text x="30" y="452.0" fill="#188a3e">intrare 50.40</text>
<line x1="59.0" y1="56.0" x2="59.0" y2="93.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="24" y1="506.0" x2="695" y2="506.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<rect x="54.5" y="62.0" width="9" height="24.0" fill="#c00"/> <text x="30" y="500.0" fill="#c00">stop 49.20</text>
<line x1="74.0" y1="70.4" x2="74.0" y2="93.2" stroke="#1a1a1a" stroke-width="1.2"/> <polyline points="329.0,304.5 344.0,321.4 359.0,335.4 374.0,349.9 389.0,362.5 404.0,372.3 419.0,382.7 434.0,390.8 449.0,395.7 464.0,402.7 479.0,408.1 494.0,411.5 509.0,412.3" fill="none" stroke="#999" stroke-width="1.5" stroke-dasharray="4 3"/>
<rect x="69.5" y="76.4" width="9" height="9.6" fill="#188a3e"/> <text x="515" y="406" fill="#999">MA(20)</text>
<line x1="89.0" y1="70.4" x2="89.0" y2="112.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="44.0" y1="56.0" x2="44.0" y2="78.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="84.5" y="76.4" width="9" height="28.8" fill="#c00"/> <rect x="39.5" y="66.0" width="9" height="1.6" fill="#188a3e"/>
<line x1="104.0" y1="99.2" x2="104.0" y2="138.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="59.0" y1="56.0" x2="59.0" y2="118.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="99.5" y="105.2" width="9" height="26.4" fill="#c00"/> <rect x="54.5" y="66.0" width="9" height="40.0" fill="#c00"/>
<line x1="119.0" y1="116.0" x2="119.0" y2="138.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="74.0" y1="80.0" x2="74.0" y2="118.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="114.5" y="122.0" width="9" height="9.6" fill="#188a3e"/> <rect x="69.5" y="90.0" width="9" height="16.0" fill="#188a3e"/>
<line x1="134.0" y1="116.0" x2="134.0" y2="158.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="89.0" y1="80.0" x2="89.0" y2="150.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="129.5" y="122.0" width="9" height="28.8" fill="#c00"/> <rect x="84.5" y="90.0" width="9" height="48.0" fill="#c00"/>
<line x1="149.0" y1="144.8" x2="149.0" y2="184.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="104.0" y1="128.0" x2="104.0" y2="194.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="144.5" y="150.8" width="9" height="26.4" fill="#c00"/> <rect x="99.5" y="138.0" width="9" height="44.0" fill="#c00"/>
<line x1="164.0" y1="161.6" x2="164.0" y2="184.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="119.0" y1="156.0" x2="119.0" y2="194.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="159.5" y="167.6" width="9" height="9.6" fill="#188a3e"/> <rect x="114.5" y="166.0" width="9" height="16.0" fill="#188a3e"/>
<line x1="179.0" y1="161.6" x2="179.0" y2="201.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="134.0" y1="156.0" x2="134.0" y2="226.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="174.5" y="167.6" width="9" height="26.4" fill="#c00"/> <rect x="129.5" y="166.0" width="9" height="48.0" fill="#c00"/>
<line x1="194.0" y1="188.0" x2="194.0" y2="230.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="149.0" y1="204.0" x2="149.0" y2="270.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="189.5" y="194.0" width="9" height="28.8" fill="#c00"/> <rect x="144.5" y="214.0" width="9" height="44.0" fill="#c00"/>
<line x1="209.0" y1="216.8" x2="209.0" y2="258.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="164.0" y1="232.0" x2="164.0" y2="270.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="204.5" y="222.8" width="9" height="28.8" fill="#c00"/> <rect x="159.5" y="242.0" width="9" height="16.0" fill="#188a3e"/>
<line x1="224.0" y1="245.6" x2="224.0" y2="290.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="179.0" y1="232.0" x2="179.0" y2="298.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="219.5" y="251.6" width="9" height="31.2" fill="#c00"/> <rect x="174.5" y="242.0" width="9" height="44.0" fill="#c00"/>
<line x1="239.0" y1="276.8" x2="239.0" y2="322.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="194.0" y1="276.0" x2="194.0" y2="346.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="234.5" y="282.8" width="9" height="32.4" fill="#c00"/> <rect x="189.5" y="286.0" width="9" height="48.0" fill="#c00"/>
<line x1="254.0" y1="304.4" x2="254.0" y2="326.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="209.0" y1="324.0" x2="209.0" y2="394.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="249.5" y="315.2" width="9" height="1.6" fill="#c00"/> <rect x="204.5" y="334.0" width="9" height="48.0" fill="#c00"/>
<line x1="269.0" y1="305.6" x2="269.0" y2="320.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="224.0" y1="372.0" x2="224.0" y2="446.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="264.5" y="309.2" width="9" height="7.2" fill="#777"/> <rect x="219.5" y="382.0" width="9" height="52.0" fill="#c00"/>
<line x1="284.0" y1="293.6" x2="284.0" y2="312.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="239.0" y1="424.0" x2="239.0" y2="500.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="279.5" y="297.2" width="9" height="12.0" fill="#188a3e"/> <rect x="234.5" y="434.0" width="9" height="54.0" fill="#c00"/>
<line x1="299.0" y1="279.2" x2="299.0" y2="304.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="254.0" y1="470.0" x2="254.0" y2="504.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="294.5" y="285.2" width="9" height="12.0" fill="#188a3e"/> <rect x="249.5" y="488.0" width="9" height="2.0" fill="#c00"/>
<line x1="314.0" y1="272.0" x2="314.0" y2="292.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="269.0" y1="472.0" x2="269.0" y2="496.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="309.5" y="278.0" width="9" height="7.2" fill="#188a3e"/> <rect x="264.5" y="478.0" width="9" height="12.0" fill="#777"/>
<line x1="329.0" y1="264.8" x2="329.0" y2="285.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="284.0" y1="452.0" x2="284.0" y2="484.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="324.5" y="270.8" width="9" height="7.2" fill="#188a3e"/> <rect x="279.5" y="458.0" width="9" height="20.0" fill="#188a3e"/>
<line x1="344.0" y1="257.6" x2="344.0" y2="278.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="299.0" y1="428.0" x2="299.0" y2="470.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="339.5" y="263.6" width="9" height="7.2" fill="#188a3e"/> <rect x="294.5" y="438.0" width="9" height="20.0" fill="#188a3e"/>
<line x1="359.0" y1="250.4" x2="359.0" y2="270.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="314.0" y1="416.0" x2="314.0" y2="450.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="354.5" y="256.4" width="9" height="7.2" fill="#188a3e"/> <rect x="309.5" y="426.0" width="9" height="12.0" fill="#188a3e"/>
<line x1="374.0" y1="243.2" x2="374.0" y2="263.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="329.0" y1="404.0" x2="329.0" y2="438.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="369.5" y="249.2" width="9" height="7.2" fill="#188a3e"/> <rect x="324.5" y="414.0" width="9" height="12.0" fill="#188a3e"/>
<line x1="389.0" y1="243.2" x2="389.0" y2="261.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="344.0" y1="400.0" x2="344.0" y2="418.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="384.5" y="249.2" width="9" height="4.8" fill="#c00"/> <rect x="339.5" y="404.0" width="9" height="10.0" fill="#188a3e"/>
<line x1="404.0" y1="236.0" x2="404.0" y2="258.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="359.0" y1="382.0" x2="359.0" y2="396.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="399.5" y="242.0" width="9" height="12.0" fill="#188a3e"/> <rect x="354.5" y="386.0" width="9" height="8.0" fill="#188a3e"/>
<line x1="419.0" y1="230.0" x2="419.0" y2="246.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="374.0" y1="376.0" x2="374.0" y2="392.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="414.5" y="236.0" width="9" height="6.0" fill="#188a3e"/> <rect x="369.5" y="380.0" width="9" height="6.0" fill="#188a3e"/>
<line x1="434.0" y1="224.0" x2="434.0" y2="240.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="389.0" y1="378.0" x2="389.0" y2="394.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="429.5" y="230.0" width="9" height="6.0" fill="#188a3e"/> <rect x="384.5" y="380.0" width="9" height="10.0" fill="#c00"/>
<line x1="449.0" y1="224.0" x2="449.0" y2="244.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="404.0" y1="374.0" x2="404.0" y2="392.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="444.5" y="230.0" width="9" height="9.6" fill="#c00"/> <rect x="399.5" y="378.0" width="9" height="12.0" fill="#188a3e"/>
<line x1="464.0" y1="233.6" x2="464.0" y2="258.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="419.0" y1="372.0" x2="419.0" y2="384.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="459.5" y="239.6" width="9" height="12.0" fill="#c00"/> <rect x="414.5" y="374.0" width="9" height="4.0" fill="#188a3e"/>
<line x1="479.0" y1="245.6" x2="479.0" y2="266.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="434.0" y1="372.0" x2="434.0" y2="380.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="474.5" y="251.6" width="9" height="7.2" fill="#c00"/> <rect x="429.5" y="374.0" width="9" height="2.0" fill="#c00"/>
<line x1="494.0" y1="252.8" x2="494.0" y2="270.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="449.0" y1="350.0" x2="449.0" y2="370.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="489.5" y="258.8" width="9" height="4.8" fill="#c00"/> <rect x="444.5" y="356.0" width="9" height="10.0" fill="#188a3e"/>
<line x1="509.0" y1="255.2" x2="509.0" y2="270.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="464.0" y1="354.0" x2="464.0" y2="386.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="504.5" y="261.2" width="9" height="2.4" fill="#188a3e"/> <rect x="459.5" y="356.0" width="9" height="26.0" fill="#c00"/>
<line x1="24" y1="422.0" x2="626" y2="422.0" stroke="#888"/> <line x1="479.0" y1="372.0" x2="479.0" y2="404.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="39.5" y="388.6" width="9" height="33.4" fill="#188a3e" opacity="0.55"/> <rect x="474.5" y="382.0" width="9" height="12.0" fill="#c00"/>
<rect x="54.5" y="387.0" width="9" height="35.0" fill="#c00" opacity="0.55"/> <line x1="494.0" y1="384.0" x2="494.0" y2="412.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="69.5" y="390.2" width="9" height="31.8" fill="#188a3e" opacity="0.55"/> <rect x="489.5" y="394.0" width="9" height="8.0" fill="#c00"/>
<rect x="84.5" y="385.4" width="9" height="36.6" fill="#c00" opacity="0.55"/> <line x1="509.0" y1="388.0" x2="509.0" y2="412.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="99.5" y="387.8" width="9" height="34.2" fill="#c00" opacity="0.55"/> <rect x="504.5" y="398.0" width="9" height="4.0" fill="#188a3e"/>
<rect x="114.5" y="389.4" width="9" height="32.6" fill="#188a3e" opacity="0.55"/> <line x1="24" y1="713.0" x2="695" y2="713.0" stroke="#888"/>
<rect x="129.5" y="386.2" width="9" height="35.8" fill="#c00" opacity="0.55"/> <rect x="39.5" y="684.4" width="9" height="28.6" fill="#188a3e" opacity="0.55"/>
<rect x="144.5" y="388.6" width="9" height="33.4" fill="#c00" opacity="0.55"/> <rect x="54.5" y="683.0" width="9" height="30.0" fill="#c00" opacity="0.55"/>
<rect x="159.5" y="387.0" width="9" height="35.0" fill="#188a3e" opacity="0.55"/> <rect x="69.5" y="685.7" width="9" height="27.3" fill="#188a3e" opacity="0.55"/>
<rect x="174.5" y="384.6" width="9" height="37.4" fill="#c00" opacity="0.55"/> <rect x="84.5" y="681.6" width="9" height="31.4" fill="#c00" opacity="0.55"/>
<rect x="189.5" y="387.8" width="9" height="34.2" fill="#c00" opacity="0.55"/> <rect x="99.5" y="683.7" width="9" height="29.3" fill="#c00" opacity="0.55"/>
<rect x="204.5" y="386.2" width="9" height="35.8" fill="#c00" opacity="0.55"/> <rect x="114.5" y="685.0" width="9" height="28.0" fill="#188a3e" opacity="0.55"/>
<rect x="219.5" y="383.8" width="9" height="38.2" fill="#c00" opacity="0.55"/> <rect x="129.5" y="682.3" width="9" height="30.7" fill="#c00" opacity="0.55"/>
<rect x="234.5" y="380.6" width="9" height="41.4" fill="#c00" opacity="0.55"/> <rect x="144.5" y="684.4" width="9" height="28.6" fill="#c00" opacity="0.55"/>
<rect x="249.5" y="360.0" width="9" height="62.0" fill="#c00" opacity="0.55"/> <rect x="159.5" y="683.0" width="9" height="30.0" fill="#188a3e" opacity="0.55"/>
<rect x="264.5" y="385.4" width="9" height="36.6" fill="#777" opacity="0.55"/> <rect x="174.5" y="681.0" width="9" height="32.0" fill="#c00" opacity="0.55"/>
<rect x="279.5" y="352.0" width="9" height="70.0" fill="#188a3e" opacity="0.55"/> <rect x="189.5" y="683.7" width="9" height="29.3" fill="#c00" opacity="0.55"/>
<rect x="294.5" y="378.2" width="9" height="43.8" fill="#188a3e" opacity="0.55"/> <rect x="204.5" y="682.3" width="9" height="30.7" fill="#c00" opacity="0.55"/>
<rect x="309.5" y="382.2" width="9" height="39.8" fill="#188a3e" opacity="0.55"/> <rect x="219.5" y="680.3" width="9" height="32.7" fill="#c00" opacity="0.55"/>
<rect x="324.5" y="383.8" width="9" height="38.2" fill="#188a3e" opacity="0.55"/> <rect x="234.5" y="677.5" width="9" height="35.5" fill="#c00" opacity="0.55"/>
<rect x="339.5" y="380.6" width="9" height="41.4" fill="#188a3e" opacity="0.55"/> <rect x="249.5" y="659.8" width="9" height="53.2" fill="#c00" opacity="0.55"/>
<rect x="354.5" y="384.6" width="9" height="37.4" fill="#188a3e" opacity="0.55"/> <rect x="264.5" y="681.6" width="9" height="31.4" fill="#777" opacity="0.55"/>
<rect x="369.5" y="386.2" width="9" height="35.8" fill="#188a3e" opacity="0.55"/> <rect x="279.5" y="653.0" width="9" height="60.0" fill="#188a3e" opacity="0.55"/>
<rect x="384.5" y="383.0" width="9" height="39.0" fill="#c00" opacity="0.55"/> <rect x="294.5" y="675.5" width="9" height="37.5" fill="#188a3e" opacity="0.55"/>
<rect x="399.5" y="385.4" width="9" height="36.6" fill="#188a3e" opacity="0.55"/> <rect x="309.5" y="678.9" width="9" height="34.1" fill="#188a3e" opacity="0.55"/>
<rect x="414.5" y="387.0" width="9" height="35.0" fill="#188a3e" opacity="0.55"/> <rect x="324.5" y="680.3" width="9" height="32.7" fill="#188a3e" opacity="0.55"/>
<rect x="429.5" y="383.8" width="9" height="38.2" fill="#188a3e" opacity="0.55"/> <rect x="339.5" y="677.5" width="9" height="35.5" fill="#188a3e" opacity="0.55"/>
<rect x="444.5" y="381.4" width="9" height="40.6" fill="#c00" opacity="0.55"/> <rect x="354.5" y="681.0" width="9" height="32.0" fill="#188a3e" opacity="0.55"/>
<rect x="459.5" y="379.0" width="9" height="43.0" fill="#c00" opacity="0.55"/> <rect x="369.5" y="682.3" width="9" height="30.7" fill="#188a3e" opacity="0.55"/>
<rect x="474.5" y="384.6" width="9" height="37.4" fill="#c00" opacity="0.55"/> <rect x="384.5" y="679.6" width="9" height="33.4" fill="#c00" opacity="0.55"/>
<rect x="489.5" y="386.2" width="9" height="35.8" fill="#c00" opacity="0.55"/> <rect x="399.5" y="681.6" width="9" height="31.4" fill="#188a3e" opacity="0.55"/>
<rect x="504.5" y="385.4" width="9" height="36.6" fill="#188a3e" opacity="0.55"/> <rect x="414.5" y="683.0" width="9" height="30.0" fill="#188a3e" opacity="0.55"/>
<text x="24" y="346.0" fill="#555">volum</text> <rect x="429.5" y="680.3" width="9" height="32.7" fill="#c00" opacity="0.55"/>
<text x="254.0" y="340.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji 50.10 / 49.20</text> <rect x="444.5" y="678.2" width="9" height="34.8" fill="#188a3e" opacity="0.55"/>
<text x="464.0" y="217.6" fill="#c00" text-anchor="middle" style="font-weight:bold">ieșire pe trail ~52.60</text> <rect x="459.5" y="676.2" width="9" height="36.8" fill="#c00" opacity="0.55"/>
<text x="24" y="444.0" fill="#777">bara 15: close 49.90 sub high-ul dojiului 50.10 — NU confirmă</text> <rect x="474.5" y="681.0" width="9" height="32.0" fill="#c00" opacity="0.55"/>
<text x="24" y="461.0" fill="#188a3e">bara 16: close 50.40 peste 50.10 — confirmare (intrare)</text> <rect x="489.5" y="682.3" width="9" height="30.7" fill="#c00" opacity="0.55"/>
<text x="24" y="486" fill="#555">Intrare la close-ul confirmării, SL la low-ul ultimelor 4 candele, TP1 1:1, apoi trailing stop.</text> <rect x="504.5" y="681.6" width="9" height="31.4" fill="#188a3e" opacity="0.55"/>
<text x="24" y="647.0" fill="#555">volum</text>
<line x1="104.0" y1="536.0" x2="246.1" y2="511.4" stroke="#c00" stroke-width="1.8"/>
<polygon points="254.0,510.0 246.8,515.3 245.4,507.4" fill="#c00"/>
<text x="104.0" y="550.0" fill="#c00" text-anchor="middle" style="font-weight:bold">stopul 49.20, 5 cenți sub doji</text>
<text x="104.0" y="564.0" fill="#c00" text-anchor="middle" style="font-weight:bold">sub el, ideea că vânzătorii</text>
<text x="104.0" y="578.0" fill="#c00" text-anchor="middle" style="font-weight:bold">au obosit e moartă</text>
<line x1="274.0" y1="576.0" x2="283.3" y2="470.0" stroke="#188a3e" stroke-width="1.8"/>
<polygon points="284.0,462.0 287.3,470.3 279.3,469.6" fill="#188a3e"/>
<text x="274.0" y="590.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">AICI INTRI, la close 50.40</text>
<text x="274.0" y="604.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">abia acum știi că</text>
<text x="274.0" y="618.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">cumpărătorii au câștigat</text>
<line x1="424.0" y1="520.0" x2="334.3" y2="420.0" stroke="#1a5fb4" stroke-width="1.8"/>
<polygon points="329.0,414.0 337.3,417.3 331.4,422.6" fill="#1a5fb4"/>
<text x="424.0" y="534.0" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">ținta 1: 51.60 = riscul (1.20)</text>
<text x="424.0" y="548.0" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">încă o dată: vinzi o treime</text>
<line x1="489.0" y1="320.0" x2="455.7" y2="341.6" stroke="#b06000" stroke-width="1.8"/>
<polygon points="449.0,346.0 453.5,338.3 457.9,345.0" fill="#b06000"/>
<text x="489.0" y="301.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">trailing stop: urcă după preț</text>
<text x="489.0" y="315.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">la fiecare gap, nu coboară</text>
<line x1="542.5" y1="334.0" x2="479.1" y2="377.5" stroke="#c00" stroke-width="1.8"/>
<polygon points="472.5,382.0 476.8,374.2 481.4,380.8" fill="#c00"/>
<text x="546.5" y="331.0" fill="#c00" text-anchor="start" style="font-weight:bold">ieși la 52.30 (+1.58R)</text>
<text x="546.5" y="345.0" fill="#c00" text-anchor="start" style="font-weight:bold">prima închidere sub trail</text>
<polyline points="352.0,396.0 442.0,396.0 442.0,370.0 471.0,370.0" fill="none" stroke="#b06000" stroke-width="2"/>
<polyline points="114.0,460.0 119.0,460.0 119.0,504.0 114.0,504.0" fill="none" stroke="#c00" stroke-width="1.5"/>
<text x="125.0" y="486.0" fill="#c00" style="font-weight:bold">1R = 1.20 (riscul)</text>
<polyline points="114.0,412.0 119.0,412.0 119.0,456.0 114.0,456.0" fill="none" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="125.0" y="438.0" fill="#1a5fb4" style="font-weight:bold">1R = 1.20 (ținta)</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -23,7 +23,7 @@ import sys
from pathlib import Path from pathlib import Path
sys.path.insert(0, "/workspace/atm-curs-dl") sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Candle, Chart, Level, Mark, MA, from_closes # noqa: E402 from svg_candles import Arrow, Candle, Chart, Level, Zone, from_closes # noqa: E402
OUT = Path(__file__).resolve().parent / "buy_doji_aplus.svg" OUT = Path(__file__).resolve().parent / "buy_doji_aplus.svg"
@@ -118,19 +118,25 @@ PW = 560 # lățimea fiecărui panou
ch_a = Chart( ch_a = Chart(
candles=cds_a, candles=cds_a,
levels=[Level(42.00, "suport 42.00", GREEN, label_at="left")], levels=[Level(42.00, "suport 42.00", GREEN, label_at="left")],
marks=[Mark(DOJI_A, "doji la nivel (low 41.95)", ORANGE, "below"), zones=[Zone(DOJI_A, DOJI_A, "", GREEN, p_top=43.2, p_bot=41.7)],
Mark(CONF_A, "acumulare", GREEN, "above", dy=-6)], arrows=[Arrow(DOJI_A, "doji chiar pe nivel:\nvânzarea s-a oprit pe suport",
where="below", color=GREEN, dx=-40),
Arrow(CONF_A, "confirmarea, pe volum mare:\ncumpărătorii mari intră",
where="above", color=GREEN, dx=60)],
mas=[], scale=22.0, gap=15, body_w=9, left=44, width=PW, vol_h=60, mas=[], scale=22.0, gap=15, body_w=9, left=44, width=PW, vol_h=60,
vol_label="volum", title="A+ — doji la suport, volum în acumulare", vol_label="volum", title="A+ — doji la suport, volum în acumulare",
caption="acumulare: volum peste media ultimelor 10 bare.",
) )
ch_n = Chart( ch_n = Chart(
candles=cds_n, candles=cds_n,
levels=[Level(78.50, "rezistență 78.50", RED, label_at="right")], levels=[Level(78.50, "rezistență 78.50", RED, label_at="right")],
marks=[Mark(DOJI_N, "doji 78.50 / 78.10", ORANGE, "below", dy=93)], # eticheta zonei ar urca peste titlul panoului (zona e chiar în vârf):
# textul stă pe săgeata din stânga
zones=[Zone(DOJI_N - 1, CONF_N, "", RED, p_top=79.62)],
arrows=[Arrow(DOJI_N, "gap-up în rezistență:\naici cumpără cei întârziați",
where="left", color=RED, dx=-30, dy=30),
Arrow(18, "cade înapoi sub 78.00:\nsemnalul a mințit", where="below", color=RED, dx=40)],
mas=[], scale=22.0, gap=15, body_w=9, left=44, width=PW, vol_h=60, mas=[], scale=22.0, gap=15, body_w=9, left=44, width=PW, vol_h=60,
vol_label="volum", title="Mediocru — gap-up în rezistență, volum varză", vol_label="volum", title="Mediocru — gap-up în rezistență, volum varză",
caption="gap-up + doji în rezistență, confirmare pe volum slab.",
) )
# ============================================================ wrapper: două panouri alăturate # ============================================================ wrapper: două panouri alăturate
@@ -145,20 +151,51 @@ def vb_height(svg: str) -> float:
return float(m.group(1)) return float(m.group(1))
PANEL_GAP, PAD = 24, 8 def vol_note(svg: str, i0: int, i1: int, text: str, color: str, box: bool) -> str:
TITLE_H, FOOTER_H = 30, 22 """Evidențiere în panoul de volum (Zone/Arrow din svg_candles lucrează doar pe preț).
svg_a, svg_n = ch_a.render(), ch_n.render()
# „gap-up, volum slab" stă în colțul liber din stânga-sus, cu linie indicatoare Coordonatele se citesc din SVG-ul randat (barele de volum sunt rect-urile cu
# spre golul dintre bara 13 (high 76.80) și dojiul barei 14 (open 78.20). opacity 0.55, în ordinea candelelor), ca să nu depindă de deplasarea internă
GAP_X = (ch_n._cx(DOJI_N - 1) + ch_n._cx(DOJI_N)) / 2 a lui Chart. Eticheta stă sub linia de bază, unde nu acoperă nimic;
GAP_Y = ch_n._y(77.50) `box` = dreptunghi peste bare, altfel săgeată de jos în sus, sub bară.
gap_ann = ( """
f'<text x="28" y="120" fill="{RED}" style="font-weight:bold">gap-up, volum slab</text>' bars = [tuple(map(float, m)) for m in re.findall(
f'<line x1="152" y1="116" x2="{GAP_X:.1f}" y2="{GAP_Y:.1f}" stroke="{RED}" stroke-width="1"/>' r'<rect x="([\d.]+)" y="([\d.]+)" width="([\d.]+)" height="([\d.]+)" '
f'<circle cx="{GAP_X:.1f}" cy="{GAP_Y:.1f}" r="2.5" fill="{RED}"/>' r'fill="#[0-9a-f]+" opacity="0.55"/>', svg)]
) base = bars[0][1] + bars[0][3]
svg_n = svg_n.replace("</svg>", gap_ann + "</svg>") x0, x1 = bars[i0][0] - 4, bars[i1][0] + bars[i1][2] + 4
top = min(b[1] for b in bars[i0:i1 + 1]) - 4
if box:
mark = (f'<rect x="{x0:.1f}" y="{top:.1f}" width="{x1 - x0:.1f}" height="{base - top:.1f}" '
f'fill="{color}" fill-opacity="0.12" stroke="{color}" stroke-width="1"/>')
ty = base + 15
else:
cx = (x0 + x1) / 2
mark = (f'<line x1="{cx:.1f}" y1="{base + 22:.1f}" x2="{cx:.1f}" y2="{base + 9:.1f}" '
f'stroke="{color}" stroke-width="1.8"/>'
f'<polygon points="{cx:.1f},{base + 2:.1f} {cx - 4:.1f},{base + 10:.1f} '
f'{cx + 4:.1f},{base + 10:.1f}" fill="{color}"/>')
ty = base + 34
label = (f'<text x="{x0:.1f}" y="{ty:.1f}" fill="{color}" '
f'style="font-weight:bold">{text}</text>')
# dreptunghiul/săgeata în spatele barelor, eticheta la final
i = svg.index('<rect', svg.index(f'y1="{base:.1f}"'))
svg = svg[:i] + mark + svg[i:]
return svg.replace("</svg>", label + "</svg>")
def grow(svg: str, dh: float) -> str:
"""Mărește viewBox-ul unui panou cu dh px jos, pentru eticheta de sub volum."""
h = vb_height(svg)
return svg.replace(f'0 0 {PW} {h:.0f}"', f'0 0 {PW} {h + dh:.0f}"', 1)
PANEL_GAP, PAD = 24, 8
TITLE_H, FOOTER_H = 30, 0
svg_a = grow(vol_note(ch_a.render(), CONF_A, CONF_A + 4,
"volum în creștere = acumulare", GREEN, box=True), 10)
svg_n = grow(vol_note(ch_n.render(), CONF_N, CONF_N,
"volum slab: nimeni mare nu cumpără", RED, box=False), 30)
HA, HN = vb_height(svg_a), vb_height(svg_n) HA, HN = vb_height(svg_a), vb_height(svg_n)
assert svg_a.count("\n\n") == 0 and svg_n.count("\n\n") == 0, "linie goală în panou" assert svg_a.count("\n\n") == 0 and svg_n.count("\n\n") == 0, "linie goală în panou"
@@ -168,9 +205,6 @@ TOTAL_H = PAD + TITLE_H + max(HA, HN) + FOOTER_H + PAD
OFF_A = (PAD, PAD + TITLE_H) OFF_A = (PAD, PAD + TITLE_H)
OFF_N = (PAD + PW + PANEL_GAP, PAD + TITLE_H) OFF_N = (PAD + PW + PANEL_GAP, PAD + TITLE_H)
FOOTER = ("Surse: 13_strategia_3_byh.md:188-190 (doji la nivel); "
"01_buy_doji_si_strategia_mici.md:227-235 (context invalid).")
wrapper = ( wrapper = (
f'<svg viewBox="0 0 {TOTAL_W} {TOTAL_H:.0f}" width="{TOTAL_W}" height="{TOTAL_H:.0f}" ' f'<svg viewBox="0 0 {TOTAL_W} {TOTAL_H:.0f}" width="{TOTAL_W}" height="{TOTAL_H:.0f}" '
f'xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">' f'xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">'
@@ -178,8 +212,6 @@ wrapper = (
f'style="font-weight:bold">Setup A+ vs. setup mediocru (două panouri, exemple construite)</text>' f'style="font-weight:bold">Setup A+ vs. setup mediocru (două panouri, exemple construite)</text>'
f'<g transform="translate({OFF_A[0]},{OFF_A[1]})">{inner(svg_a)}</g>' f'<g transform="translate({OFF_A[0]},{OFF_A[1]})">{inner(svg_a)}</g>'
f'<g transform="translate({OFF_N[0]},{OFF_N[1]})">{inner(svg_n)}</g>' f'<g transform="translate({OFF_N[0]},{OFF_N[1]})">{inner(svg_n)}</g>'
f'<text x="{TOTAL_W / 2:.0f}" y="{TOTAL_H - PAD:.0f}" fill="#555" '
f'text-anchor="middle">{FOOTER}</text>'
f'</svg>' f'</svg>'
) )
@@ -217,8 +249,7 @@ for frag, (ox, oy) in ((inner(svg_a), OFF_A), (inner(svg_n), OFF_N)):
all_txt.append((gx, gy, anchor, t)) all_txt.append((gx, gy, anchor, t))
# textele din wrapper (titlu + footer), în coordonate globale # textele din wrapper (titlu + footer), în coordonate globale
for x, y, anchor, t in ((TOTAL_W / 2, 20.0, "middle", for x, y, anchor, t in ((TOTAL_W / 2, 20.0, "middle",
"Setup A+ vs. setup mediocru (două panouri, exemple construite)"), "Setup A+ vs. setup mediocru (două panouri, exemple construite)"),):
(TOTAL_W / 2, TOTAL_H - PAD, "middle", FOOTER)):
gl, gr = span(x, anchor, t) gl, gr = span(x, anchor, t)
assert -1 <= gl and gr <= TOTAL_W + 1, f"text din wrapper iese din pânză: {t!r}" assert -1 <= gl and gr <= TOTAL_W + 1, f"text din wrapper iese din pânză: {t!r}"
assert 0 <= y <= TOTAL_H, f"text din wrapper în afara înălțimii: {t!r}" assert 0 <= y <= TOTAL_H, f"text din wrapper în afara înălțimii: {t!r}"
@@ -236,8 +267,10 @@ for i in range(len(all_txt)):
raise AssertionError(f"texte suprapuse: {si!r} / {sj!r}") raise AssertionError(f"texte suprapuse: {si!r} / {sj!r}")
# etichetele cerute de spec există în desen # etichetele cerute de spec există în desen
for cheie in ("suport 42.00", "doji la nivel", "acumulare", assert "Surse" not in wrapper and ".md:" not in wrapper, "trimiteri la surse în SVG"
"rezistență 78.50", "gap-up, volum slab", for cheie in ("suport 42.00", "doji chiar pe nivel", "vânzarea s-a oprit", "volum în creștere = acumulare",
"rezistență 78.50", "gap-up în rezistență", "cei întârziați",
"semnalul a mințit", "volum slab: nimeni mare nu cumpără",
"A+ — doji la suport, volum în acumulare", "A+ — doji la suport, volum în acumulare",
"Mediocru — gap-up în rezistență, volum varză"): "Mediocru — gap-up în rezistență, volum varză"):
assert cheie in wrapper, f"lipsește din desen: {cheie!r}" assert cheie in wrapper, f"lipsește din desen: {cheie!r}"

View File

@@ -29,11 +29,18 @@ STRUCTURA SERIEI
Panoul A+ (24 candele): downtrend de la 52 la ~42.60 (10 bare), apoi doji Panoul A+ (24 candele): downtrend de la 52 la ~42.60 (10 bare), apoi doji
cu low 41.95 / high 42.90 care „stă" pe suportul 42.00 (low-ul e la 0.1 % cu low 41.95 / high 42.90 care „stă" pe suportul 42.00 (low-ul e la 0.1 %
sub nivel), apoi confirmare close 43.60 (> high-ul dojiului) cu volum peste sub nivel), apoi confirmare close 43.60 (> high-ul dojiului) cu volum peste
media pe 10 bare. Etichete: „suport 42.00", „doji la nivel", „acumulare". media pe 10 bare. Adnotări: zonă verde peste doji („doji chiar pe nivel: vânzarea s-a oprit pe
suport"), zonă verde peste barele de volum ale confirmării („volum în
creștere = acumulare"), săgeată spre confirmare („confirmarea, pe volum
mare: cumpărătorii mari intră"). Level „suport 42.00".
Panoul NU (24 candele): uptrend de la 70 la ~77, apoi un gap-up de la 76.80 Panoul NU (24 candele): uptrend de la 70 la ~77, apoi un gap-up de la 76.80
la open 78.20, doji cu high 79.00 / low 78.10 chiar sub rezistența 78.50, la open 78.20, doji cu high 79.00 / low 78.10 chiar sub rezistența 78.50,
apoi confirmare close 79.30 pe volum sub media pe 10 bare, după care prețul apoi confirmare close 79.30 pe volum sub media pe 10 bare, după care prețul
cade înapoi sub 78.00. Etichete: „rezistență 78.50", „gap-up, volum slab". cade înapoi sub 78.00. Adnotări: zonă roșie peste gap-up + doji + confirmare, cu săgeata „gap-up în
rezistență: aici cumpără cei întârziați"; săgeată spre volumul confirmării
(„volum slab: nimeni mare nu cumpără"); săgeată spre căderea de după („cade
înapoi sub 78.00: semnalul a mințit"). Level „rezistență 78.50".
Fără linie de surse în SVG — trimiterile stau la finalul capitolului.
Nivelurile 42.00 / 78.50 / cifrele de preț sunt construite (materialul nu dă Nivelurile 42.00 / 78.50 / cifrele de preț sunt construite (materialul nu dă
prețuri pentru acest contrast); regulile și citatele de mai sus sunt din curs. prețuri pentru acest contrast); regulile și citatele de mai sus sunt din curs.

View File

@@ -1,5 +1,6 @@
<svg viewBox="0 0 1160 480" width="1160" height="480" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"><text x="580" y="20" fill="#333" text-anchor="middle" style="font-weight:bold">Setup A+ vs. setup mediocru (două panouri, exemple construite)</text><g transform="translate(8,38)"> <svg viewBox="0 0 1160 519" width="1160" height="519" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"><text x="580" y="20" fill="#333" text-anchor="middle" style="font-weight:bold">Setup A+ vs. setup mediocru (două panouri, exemple construite)</text><g transform="translate(8,38)">
<text x="24" y="48" fill="#333" style="font-weight:bold">A+ — doji la suport, volum în acumulare</text> <text x="24" y="48" fill="#333" style="font-weight:bold">A+ — doji la suport, volum în acumulare</text>
<rect x="184.5" y="256.2" width="19.0" height="33.0" fill="#188a3e" fill-opacity="0.08" stroke="#188a3e" stroke-width="1"/>
<line x1="24" y1="282.6" x2="546" y2="282.6" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="24" y1="282.6" x2="546" y2="282.6" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="30" y="276.6" fill="#188a3e">suport 42.00</text> <text x="30" y="276.6" fill="#188a3e">suport 42.00</text>
<line x1="44.0" y1="56.0" x2="44.0" y2="78.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="44.0" y1="56.0" x2="44.0" y2="78.0" stroke="#1a1a1a" stroke-width="1.2"/>
@@ -50,113 +51,125 @@
<rect x="369.5" y="177.0" width="9" height="6.6" fill="#188a3e"/> <rect x="369.5" y="177.0" width="9" height="6.6" fill="#188a3e"/>
<line x1="389.0" y1="163.8" x2="389.0" y2="183.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="389.0" y1="163.8" x2="389.0" y2="183.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="384.5" y="170.4" width="9" height="6.6" fill="#188a3e"/> <rect x="384.5" y="170.4" width="9" height="6.6" fill="#188a3e"/>
<line x1="24" y1="369.7" x2="546" y2="369.7" stroke="#888"/> <line x1="24" y1="436.7" x2="546" y2="436.7" stroke="#888"/>
<rect x="39.5" y="336.1" width="9" height="33.6" fill="#c00" opacity="0.55"/> <rect x="200.5" y="381.1" width="77.0" height="55.6" fill="#188a3e" fill-opacity="0.12" stroke="#188a3e" stroke-width="1"/><rect x="39.5" y="403.1" width="9" height="33.6" fill="#c00" opacity="0.55"/>
<rect x="54.5" y="337.9" width="9" height="31.8" fill="#c00" opacity="0.55"/> <rect x="54.5" y="404.9" width="9" height="31.8" fill="#c00" opacity="0.55"/>
<rect x="69.5" y="339.1" width="9" height="30.6" fill="#c00" opacity="0.55"/> <rect x="69.5" y="406.1" width="9" height="30.6" fill="#c00" opacity="0.55"/>
<rect x="84.5" y="340.3" width="9" height="29.4" fill="#c00" opacity="0.55"/> <rect x="84.5" y="407.3" width="9" height="29.4" fill="#c00" opacity="0.55"/>
<rect x="99.5" y="341.5" width="9" height="28.2" fill="#c00" opacity="0.55"/> <rect x="99.5" y="408.5" width="9" height="28.2" fill="#c00" opacity="0.55"/>
<rect x="114.5" y="342.7" width="9" height="27.0" fill="#c00" opacity="0.55"/> <rect x="114.5" y="409.7" width="9" height="27.0" fill="#c00" opacity="0.55"/>
<rect x="129.5" y="343.3" width="9" height="26.4" fill="#c00" opacity="0.55"/> <rect x="129.5" y="410.3" width="9" height="26.4" fill="#c00" opacity="0.55"/>
<rect x="144.5" y="344.5" width="9" height="25.2" fill="#c00" opacity="0.55"/> <rect x="144.5" y="411.5" width="9" height="25.2" fill="#c00" opacity="0.55"/>
<rect x="159.5" y="345.1" width="9" height="24.6" fill="#c00" opacity="0.55"/> <rect x="159.5" y="412.1" width="9" height="24.6" fill="#c00" opacity="0.55"/>
<rect x="174.5" y="346.3" width="9" height="23.4" fill="#c00" opacity="0.55"/> <rect x="174.5" y="413.3" width="9" height="23.4" fill="#c00" opacity="0.55"/>
<rect x="189.5" y="333.7" width="9" height="36.0" fill="#188a3e" opacity="0.55"/> <rect x="189.5" y="400.7" width="9" height="36.0" fill="#188a3e" opacity="0.55"/>
<rect x="204.5" y="318.1" width="9" height="51.6" fill="#188a3e" opacity="0.55"/> <rect x="204.5" y="385.1" width="9" height="51.6" fill="#188a3e" opacity="0.55"/>
<rect x="219.5" y="326.5" width="9" height="43.2" fill="#188a3e" opacity="0.55"/> <rect x="219.5" y="393.5" width="9" height="43.2" fill="#188a3e" opacity="0.55"/>
<rect x="234.5" y="324.7" width="9" height="45.0" fill="#188a3e" opacity="0.55"/> <rect x="234.5" y="391.7" width="9" height="45.0" fill="#188a3e" opacity="0.55"/>
<rect x="249.5" y="327.7" width="9" height="42.0" fill="#c00" opacity="0.55"/> <rect x="249.5" y="394.7" width="9" height="42.0" fill="#c00" opacity="0.55"/>
<rect x="264.5" y="322.9" width="9" height="46.8" fill="#188a3e" opacity="0.55"/> <rect x="264.5" y="389.9" width="9" height="46.8" fill="#188a3e" opacity="0.55"/>
<rect x="279.5" y="320.5" width="9" height="49.2" fill="#188a3e" opacity="0.55"/> <rect x="279.5" y="387.5" width="9" height="49.2" fill="#188a3e" opacity="0.55"/>
<rect x="294.5" y="321.7" width="9" height="48.0" fill="#c00" opacity="0.55"/> <rect x="294.5" y="388.7" width="9" height="48.0" fill="#c00" opacity="0.55"/>
<rect x="309.5" y="318.7" width="9" height="51.0" fill="#188a3e" opacity="0.55"/> <rect x="309.5" y="385.7" width="9" height="51.0" fill="#188a3e" opacity="0.55"/>
<rect x="324.5" y="316.9" width="9" height="52.8" fill="#188a3e" opacity="0.55"/> <rect x="324.5" y="383.9" width="9" height="52.8" fill="#188a3e" opacity="0.55"/>
<rect x="339.5" y="314.5" width="9" height="55.2" fill="#188a3e" opacity="0.55"/> <rect x="339.5" y="381.5" width="9" height="55.2" fill="#188a3e" opacity="0.55"/>
<rect x="354.5" y="312.7" width="9" height="57.0" fill="#188a3e" opacity="0.55"/> <rect x="354.5" y="379.7" width="9" height="57.0" fill="#188a3e" opacity="0.55"/>
<rect x="369.5" y="310.9" width="9" height="58.8" fill="#188a3e" opacity="0.55"/> <rect x="369.5" y="377.9" width="9" height="58.8" fill="#188a3e" opacity="0.55"/>
<rect x="384.5" y="309.7" width="9" height="60.0" fill="#188a3e" opacity="0.55"/> <rect x="384.5" y="376.7" width="9" height="60.0" fill="#188a3e" opacity="0.55"/>
<text x="24" y="303.7" fill="#555">volum</text> <text x="24" y="370.7" fill="#555">volum</text>
<text x="194.0" y="297.7" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji la nivel (low 41.95)</text> <line x1="154.0" y1="313.7" x2="187.3" y2="292.1" stroke="#188a3e" stroke-width="1.8"/>
<text x="209.0" y="225.9" fill="#188a3e" text-anchor="middle" style="font-weight:bold">acumulare</text> <polygon points="194.0,287.7 189.5,295.4 185.1,288.7" fill="#188a3e"/>
<text x="24" y="400" fill="#555">acumulare: volum peste media ultimelor 10 bare.</text> <text x="154.0" y="327.7" fill="#188a3e" text-anchor="middle" style="font-weight:bold">doji chiar pe nivel:</text>
</g><g transform="translate(592,38)"> <text x="154.0" y="341.7" fill="#188a3e" text-anchor="middle" style="font-weight:bold">vânzarea s-a oprit pe suport</text>
<line x1="269.0" y1="169.0" x2="214.3" y2="231.9" stroke="#188a3e" stroke-width="1.8"/>
<polygon points="209.0,237.9 211.2,229.2 217.3,234.5" fill="#188a3e"/>
<text x="269.0" y="150.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmarea, pe volum mare:</text>
<text x="269.0" y="164.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">cumpărătorii mari intră</text>
<text x="200.5" y="451.7" fill="#188a3e" style="font-weight:bold">volum în creștere = acumulare</text></g><g transform="translate(592,38)">
<text x="24" y="48" fill="#333" style="font-weight:bold">Mediocru — gap-up în rezistență, volum varză</text> <text x="24" y="48" fill="#333" style="font-weight:bold">Mediocru — gap-up în rezistență, volum varză</text>
<line x1="24" y1="78.0" x2="546" y2="78.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="229.5" y="56.0" width="49.0" height="86.5" fill="#c00" fill-opacity="0.08" stroke="#c00" stroke-width="1"/>
<text x="532" y="72.0" fill="#c00" text-anchor="end">rezistență 78.50</text> <line x1="24" y1="80.6" x2="546" y2="80.6" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="44.0" y1="249.6" x2="44.0" y2="269.4" stroke="#1a1a1a" stroke-width="1.2"/> <text x="532" y="74.6" fill="#c00" text-anchor="end">rezistență 78.50</text>
<rect x="39.5" y="254.0" width="9" height="11.0" fill="#188a3e"/> <line x1="44.0" y1="252.2" x2="44.0" y2="272.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="59.0" y1="238.6" x2="59.0" y2="258.4" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="39.5" y="256.6" width="9" height="11.0" fill="#188a3e"/>
<rect x="54.5" y="243.0" width="9" height="11.0" fill="#188a3e"/> <line x1="59.0" y1="241.2" x2="59.0" y2="261.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="74.0" y1="226.5" x2="74.0" y2="246.3" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="54.5" y="245.6" width="9" height="11.0" fill="#188a3e"/>
<rect x="69.5" y="230.9" width="9" height="12.1" fill="#188a3e"/> <line x1="74.0" y1="229.1" x2="74.0" y2="248.9" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="89.0" y1="214.4" x2="89.0" y2="234.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="69.5" y="233.5" width="9" height="12.1" fill="#188a3e"/>
<rect x="84.5" y="218.8" width="9" height="12.1" fill="#188a3e"/> <line x1="89.0" y1="217.0" x2="89.0" y2="236.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="104.0" y1="203.4" x2="104.0" y2="222.1" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="84.5" y="221.4" width="9" height="12.1" fill="#188a3e"/>
<rect x="99.5" y="207.8" width="9" height="11.0" fill="#188a3e"/> <line x1="104.0" y1="206.0" x2="104.0" y2="224.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="119.0" y1="192.4" x2="119.0" y2="211.1" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="99.5" y="210.4" width="9" height="11.0" fill="#188a3e"/>
<rect x="114.5" y="196.8" width="9" height="11.0" fill="#188a3e"/> <line x1="119.0" y1="195.0" x2="119.0" y2="213.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="134.0" y1="181.4" x2="134.0" y2="200.1" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="114.5" y="199.4" width="9" height="11.0" fill="#188a3e"/>
<rect x="129.5" y="185.8" width="9" height="11.0" fill="#188a3e"/> <line x1="134.0" y1="184.0" x2="134.0" y2="202.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="149.0" y1="171.5" x2="149.0" y2="189.1" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="129.5" y="188.4" width="9" height="11.0" fill="#188a3e"/>
<rect x="144.5" y="175.9" width="9" height="9.9" fill="#188a3e"/> <line x1="149.0" y1="174.1" x2="149.0" y2="191.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="164.0" y1="161.6" x2="164.0" y2="179.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="144.5" y="178.5" width="9" height="9.9" fill="#188a3e"/>
<rect x="159.5" y="166.0" width="9" height="9.9" fill="#188a3e"/> <line x1="164.0" y1="164.2" x2="164.0" y2="181.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="179.0" y1="151.7" x2="179.0" y2="169.3" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="159.5" y="168.6" width="9" height="9.9" fill="#188a3e"/>
<rect x="174.5" y="156.1" width="9" height="9.9" fill="#188a3e"/> <line x1="179.0" y1="154.3" x2="179.0" y2="171.9" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="194.0" y1="141.8" x2="194.0" y2="159.4" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="174.5" y="158.7" width="9" height="9.9" fill="#188a3e"/>
<rect x="189.5" y="146.2" width="9" height="9.9" fill="#188a3e"/> <line x1="194.0" y1="144.4" x2="194.0" y2="162.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="209.0" y1="133.0" x2="209.0" y2="149.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="189.5" y="148.8" width="9" height="9.9" fill="#188a3e"/>
<rect x="204.5" y="137.4" width="9" height="8.8" fill="#188a3e"/> <line x1="209.0" y1="135.6" x2="209.0" y2="152.1" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="224.0" y1="124.2" x2="224.0" y2="140.7" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="204.5" y="140.0" width="9" height="8.8" fill="#188a3e"/>
<rect x="219.5" y="128.6" width="9" height="8.8" fill="#188a3e"/> <line x1="224.0" y1="126.8" x2="224.0" y2="143.3" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="239.0" y1="115.4" x2="239.0" y2="131.9" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="219.5" y="131.2" width="9" height="8.8" fill="#188a3e"/>
<rect x="234.5" y="115.4" width="9" height="13.2" fill="#188a3e"/> <line x1="239.0" y1="118.0" x2="239.0" y2="134.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="254.0" y1="78.0" x2="254.0" y2="86.8" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="234.5" y="118.0" width="9" height="13.2" fill="#188a3e"/>
<rect x="249.5" y="84.6" width="9" height="1.6" fill="#188a3e"/> <line x1="254.0" y1="80.6" x2="254.0" y2="89.4" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="269.0" y1="56.0" x2="269.0" y2="86.8" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="249.5" y="87.2" width="9" height="1.6" fill="#188a3e"/>
<rect x="264.5" y="60.4" width="9" height="24.2" fill="#188a3e"/> <line x1="269.0" y1="58.6" x2="269.0" y2="89.4" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="284.0" y1="58.2" x2="284.0" y2="80.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="264.5" y="63.0" width="9" height="24.2" fill="#188a3e"/>
<rect x="279.5" y="60.4" width="9" height="15.4" fill="#c00"/> <line x1="284.0" y1="60.8" x2="284.0" y2="82.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="299.0" y1="73.6" x2="299.0" y2="93.4" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="279.5" y="63.0" width="9" height="15.4" fill="#c00"/>
<rect x="294.5" y="75.8" width="9" height="13.2" fill="#c00"/> <line x1="299.0" y1="76.2" x2="299.0" y2="96.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="314.0" y1="86.8" x2="314.0" y2="106.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="294.5" y="78.4" width="9" height="13.2" fill="#c00"/>
<rect x="309.5" y="89.0" width="9" height="13.2" fill="#c00"/> <line x1="314.0" y1="89.4" x2="314.0" y2="109.2" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="329.0" y1="98.9" x2="329.0" y2="115.4" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="309.5" y="91.6" width="9" height="13.2" fill="#c00"/>
<rect x="324.5" y="102.2" width="9" height="8.8" fill="#c00"/> <line x1="329.0" y1="101.5" x2="329.0" y2="118.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="344.0" y1="107.7" x2="344.0" y2="124.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="324.5" y="104.8" width="9" height="8.8" fill="#c00"/>
<rect x="339.5" y="111.0" width="9" height="8.8" fill="#c00"/> <line x1="344.0" y1="110.3" x2="344.0" y2="126.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="359.0" y1="116.5" x2="359.0" y2="130.8" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="339.5" y="113.6" width="9" height="8.8" fill="#c00"/>
<rect x="354.5" y="119.8" width="9" height="6.6" fill="#c00"/> <line x1="359.0" y1="119.1" x2="359.0" y2="133.4" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="374.0" y1="124.2" x2="374.0" y2="137.4" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="354.5" y="122.4" width="9" height="6.6" fill="#c00"/>
<rect x="369.5" y="126.4" width="9" height="6.6" fill="#c00"/> <line x1="374.0" y1="126.8" x2="374.0" y2="140.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="389.0" y1="129.7" x2="389.0" y2="144.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="369.5" y="129.0" width="9" height="6.6" fill="#c00"/>
<rect x="384.5" y="133.0" width="9" height="6.6" fill="#c00"/> <line x1="389.0" y1="132.3" x2="389.0" y2="146.6" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="24" y1="355.4" x2="546" y2="355.4" stroke="#888"/> <rect x="384.5" y="135.6" width="9" height="6.6" fill="#c00"/>
<rect x="39.5" y="311.8" width="9" height="43.6" fill="#188a3e" opacity="0.55"/> <line x1="24" y1="358.0" x2="546" y2="358.0" stroke="#888"/>
<rect x="54.5" y="309.9" width="9" height="45.5" fill="#188a3e" opacity="0.55"/> <line x1="269.0" y1="380.0" x2="269.0" y2="367.0" stroke="#c00" stroke-width="1.8"/><polygon points="269.0,360.0 265.0,368.0 273.0,368.0" fill="#c00"/><rect x="39.5" y="314.4" width="9" height="43.6" fill="#188a3e" opacity="0.55"/>
<rect x="69.5" y="310.9" width="9" height="44.5" fill="#188a3e" opacity="0.55"/> <rect x="54.5" y="312.6" width="9" height="45.5" fill="#188a3e" opacity="0.55"/>
<rect x="84.5" y="308.1" width="9" height="47.3" fill="#188a3e" opacity="0.55"/> <rect x="69.5" y="313.5" width="9" height="44.5" fill="#188a3e" opacity="0.55"/>
<rect x="99.5" y="309.0" width="9" height="46.4" fill="#188a3e" opacity="0.55"/> <rect x="84.5" y="310.8" width="9" height="47.3" fill="#188a3e" opacity="0.55"/>
<rect x="114.5" y="306.3" width="9" height="49.1" fill="#188a3e" opacity="0.55"/> <rect x="99.5" y="311.7" width="9" height="46.4" fill="#188a3e" opacity="0.55"/>
<rect x="129.5" y="307.2" width="9" height="48.2" fill="#188a3e" opacity="0.55"/> <rect x="114.5" y="308.9" width="9" height="49.1" fill="#188a3e" opacity="0.55"/>
<rect x="144.5" y="304.5" width="9" height="50.9" fill="#188a3e" opacity="0.55"/> <rect x="129.5" y="309.9" width="9" height="48.2" fill="#188a3e" opacity="0.55"/>
<rect x="159.5" y="305.4" width="9" height="50.0" fill="#188a3e" opacity="0.55"/> <rect x="144.5" y="307.1" width="9" height="50.9" fill="#188a3e" opacity="0.55"/>
<rect x="174.5" y="302.7" width="9" height="52.7" fill="#188a3e" opacity="0.55"/> <rect x="159.5" y="308.0" width="9" height="50.0" fill="#188a3e" opacity="0.55"/>
<rect x="189.5" y="303.6" width="9" height="51.8" fill="#188a3e" opacity="0.55"/> <rect x="174.5" y="305.3" width="9" height="52.7" fill="#188a3e" opacity="0.55"/>
<rect x="204.5" y="300.9" width="9" height="54.5" fill="#188a3e" opacity="0.55"/> <rect x="189.5" y="306.2" width="9" height="51.8" fill="#188a3e" opacity="0.55"/>
<rect x="219.5" y="301.8" width="9" height="53.6" fill="#188a3e" opacity="0.55"/> <rect x="204.5" y="303.5" width="9" height="54.5" fill="#188a3e" opacity="0.55"/>
<rect x="234.5" y="299.0" width="9" height="56.4" fill="#188a3e" opacity="0.55"/> <rect x="219.5" y="304.4" width="9" height="53.6" fill="#188a3e" opacity="0.55"/>
<rect x="249.5" y="302.7" width="9" height="52.7" fill="#188a3e" opacity="0.55"/> <rect x="234.5" y="301.7" width="9" height="56.4" fill="#188a3e" opacity="0.55"/>
<rect x="264.5" y="328.1" width="9" height="27.3" fill="#188a3e" opacity="0.55"/> <rect x="249.5" y="305.3" width="9" height="52.7" fill="#188a3e" opacity="0.55"/>
<rect x="279.5" y="305.4" width="9" height="50.0" fill="#c00" opacity="0.55"/> <rect x="264.5" y="330.8" width="9" height="27.3" fill="#188a3e" opacity="0.55"/>
<rect x="294.5" y="300.9" width="9" height="54.5" fill="#c00" opacity="0.55"/> <rect x="279.5" y="308.0" width="9" height="50.0" fill="#c00" opacity="0.55"/>
<rect x="309.5" y="297.2" width="9" height="58.2" fill="#c00" opacity="0.55"/> <rect x="294.5" y="303.5" width="9" height="54.5" fill="#c00" opacity="0.55"/>
<rect x="324.5" y="299.0" width="9" height="56.4" fill="#c00" opacity="0.55"/> <rect x="309.5" y="299.9" width="9" height="58.2" fill="#c00" opacity="0.55"/>
<rect x="339.5" y="295.4" width="9" height="60.0" fill="#c00" opacity="0.55"/> <rect x="324.5" y="301.7" width="9" height="56.4" fill="#c00" opacity="0.55"/>
<rect x="354.5" y="298.1" width="9" height="57.3" fill="#c00" opacity="0.55"/> <rect x="339.5" y="298.0" width="9" height="60.0" fill="#c00" opacity="0.55"/>
<rect x="369.5" y="296.3" width="9" height="59.1" fill="#c00" opacity="0.55"/> <rect x="354.5" y="300.8" width="9" height="57.3" fill="#c00" opacity="0.55"/>
<rect x="384.5" y="299.9" width="9" height="55.5" fill="#c00" opacity="0.55"/> <rect x="369.5" y="298.9" width="9" height="59.1" fill="#c00" opacity="0.55"/>
<text x="24" y="289.4" fill="#555">volum</text> <rect x="384.5" y="302.6" width="9" height="55.5" fill="#c00" opacity="0.55"/>
<text x="254.0" y="199.8" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji 78.50 / 78.10</text> <text x="24" y="292.0" fill="#555">volum</text>
<text x="24" y="385" fill="#555">gap-up + doji în rezistență, confirmare pe volum slab.</text> <line x1="185.5" y1="117.2" x2="238.3" y2="90.8" stroke="#c00" stroke-width="1.8"/>
<text x="28" y="120" fill="#c00" style="font-weight:bold">gap-up, volum slab</text><line x1="152" y1="116" x2="246.5" y2="100.0" stroke="#c00" stroke-width="1"/><circle cx="246.5" cy="100.0" r="2.5" fill="#c00"/></g><text x="580" y="472" fill="#555" text-anchor="middle">Surse: 13_strategia_3_byh.md:188-190 (doji la nivel); 01_buy_doji_si_strategia_mici.md:227-235 (context invalid).</text></svg> <polygon points="245.5,87.2 240.1,94.4 236.6,87.2" fill="#c00"/>
<text x="181.5" y="114.2" fill="#c00" text-anchor="end" style="font-weight:bold">gap-up în rezistență:</text>
<text x="181.5" y="128.2" fill="#c00" text-anchor="end" style="font-weight:bold">aici cumpără cei întârziați</text>
<line x1="354.0" y1="154.6" x2="319.6" y2="119.0" stroke="#c00" stroke-width="1.8"/>
<polygon points="314.0,113.2 322.4,116.2 316.7,121.8" fill="#c00"/>
<text x="354.0" y="168.6" fill="#c00" text-anchor="middle" style="font-weight:bold">cade înapoi sub 78.00:</text>
<text x="354.0" y="182.6" fill="#c00" text-anchor="middle" style="font-weight:bold">semnalul a mințit</text>
<text x="260.5" y="392.0" fill="#c00" style="font-weight:bold">volum slab: nimeni mare nu cumpără</text></g></svg>

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -12,7 +12,7 @@ Rulare: python3 gen/strategii/buy_doji_directie.py
from pathlib import Path from pathlib import Path
OUT = Path(__file__).with_suffix(".svg") OUT = Path(__file__).with_suffix(".svg")
W = 720 W = 900
def trend(start, closes, wick=0.15): def trend(start, closes, wick=0.15):
@@ -55,10 +55,11 @@ for name, (o, h, l, c) in (("doji weekly", WK[7]), ("doji daily", DY[9])):
assert WK[8][3] > WK[7][1], "weekly: fără confirmare" assert WK[8][3] > WK[7][1], "weekly: fără confirmare"
assert DY[10][3] < DY[9][2], "daily: fără confirmare Sell Doji" assert DY[10][3] < DY[9][2], "daily: fără confirmare Sell Doji"
ENTRY = DY[10][3] ENTRY = DY[10][3]
SL = max(b[1] for b in DY[7:11]) # stopul: 5 cenți peste high-ul ultimelor 4 candele, ca la pasul 5 (oglindit)
SL = round(max(b[1] for b in DY[7:11]) + 0.05, 2)
RISK = round(SL - ENTRY, 2) RISK = round(SL - ENTRY, 2)
TP1 = round(ENTRY - RISK, 2) TP1 = round(ENTRY - RISK, 2)
assert eq(ENTRY, 83.60) and eq(SL, 84.80) and eq(RISK, 1.20) and eq(TP1, 82.40) assert eq(ENTRY, 83.60) and eq(SL, 84.85) and eq(RISK, 1.25) and eq(TP1, 82.35)
LOW_AFTER = min(b[2] for b in DY[11:]) LOW_AFTER = min(b[2] for b in DY[11:])
assert eq(LOW_AFTER, 83.00) and LOW_AFTER > TP1, "TP1 atins" assert eq(LOW_AFTER, 83.00) and LOW_AFTER > TP1, "TP1 atins"
HIT = next(i for i in range(11, 17) if DY[i][1] >= SL - 1e-9) HIT = next(i for i in range(11, 17) if DY[i][1] >= SL - 1e-9)
@@ -89,6 +90,16 @@ def rect(x, y, w, h, fill, opacity, stroke="none"):
f'fill-opacity="{opacity}" stroke="{stroke}" rx="3"/>') f'fill-opacity="{opacity}" stroke="{stroke}" rx="3"/>')
def arrow(x1, y1, x2, y2, color):
"""Săgeată de la (x1,y1) la vârful (x2,y2): linie + cap triunghi."""
d = max(((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5, 1e-9)
ux, uy = (x2 - x1) / d, (y2 - y1) / d
bx, by = x2 - 9 * ux, y2 - 9 * uy
line(x1, y1, bx, by, color, 1.8)
out.append(f'<polygon points="{x2:.1f},{y2:.1f} {bx - 4.5 * uy:.1f},{by + 4.5 * ux:.1f} '
f'{bx + 4.5 * uy:.1f},{by - 4.5 * ux:.1f}" fill="{color}"/>')
def candles(bars, x0, gap, yf): def candles(bars, x0, gap, yf):
for i, (o, h, l, c) in enumerate(bars): for i, (o, h, l, c) in enumerate(bars):
cx = x0 + i * gap cx = x0 + i * gap
@@ -112,11 +123,12 @@ rect(xw(7) - 8, yw(WK[8][1]) - 4, WGAP + 16, yw(WK[7][2]) - yw(WK[8][1]) + 8,
GREEN, 0.12, GREEN) GREEN, 0.12, GREEN)
candles(WK, WX0, WGAP, yw) candles(WK, WX0, WGAP, yw)
text(xw(7), yw(WK[7][2]) + 16, "doji weekly", fill=ORANGE, anchor="middle", bold=True) text(xw(7), yw(WK[7][2]) + 16, "doji weekly", fill=ORANGE, anchor="middle", bold=True)
text(xw(9) + 14, yw(WK[8][3]) + 4, "Buy Doji weekly: direcția = long", fill=GREEN, bold=True) # săgeata weekly: ce + de ce
# insigna de direcție arrow(300, yw(WK[8][3]) - 6, xw(8) + 12, yw(WK[8][3]) - 6, GREEN)
rect(470, 66, 230, 58, GREEN, 0.10, GREEN) text(306, yw(WK[8][3]) - 10, "weekly: Buy Doji confirmat (close 81.30, peste high-ul doji-ului 79.80)",
text(585, 90, "WEEKLY: LONG ↑", fill=GREEN, anchor="middle", bold=True, size=16) fill=GREEN, bold=True)
text(585, 110, "confirmare 81.30 &gt; high doji 79.80", fill=GREEN, anchor="middle", size=11) text(306, yw(WK[8][3]) + 8, "deci direcția permisă e LONG: pe daily cauți doar Buy Doji",
fill=GREEN)
w_bottom = yw(min(b[2] for b in WK)) w_bottom = yw(min(b[2] for b in WK))
# ---- panoul de jos: daily ----------------------------------------------------- # ---- panoul de jos: daily -----------------------------------------------------
@@ -136,42 +148,33 @@ rect(xd(9) - 8, yd(DY[9][1]) - 3, DGAP + 16, yd(DY[10][2]) - yd(DY[9][1]) + 6, O
line(LX1, y_sl, LX2, y_sl, RED, 1.5, "6 3") line(LX1, y_sl, LX2, y_sl, RED, 1.5, "6 3")
line(xd(10) - 8, y_e, LX2, y_e, ORANGE, 1.5, "6 3") line(xd(10) - 8, y_e, LX2, y_e, ORANGE, 1.5, "6 3")
line(xd(10) - 8, y_tp, LX2, y_tp, GRAY, 1.5, "2 3") line(xd(10) - 8, y_tp, LX2, y_tp, GRAY, 1.5, "2 3")
text(COL, y_sl + 4, "SL 84.80 = high 4 candele", fill=RED, size=11) text(COL, y_sl + 4, "stop 84.85 = 5 cenți peste high-ul de 4 candele", fill=RED, size=11)
text(COL, y_e + 4, "intrare short 83.60", fill=ORANGE, size=11) text(COL, y_e + 4, "intrare short 83.60", fill=ORANGE, size=11)
text(COL, y_tp + 4, "TP1 82.40 — neatins", fill=GRAY, size=11) text(COL, y_tp + 4, "ținta 82.35 — neatinsă (a scăzut o zi, la 83.00)",
fill=GRAY, size=11)
candles(DY, DX0, DGAP, yd) candles(DY, DX0, DGAP, yd)
# paranteza „short de 1-2 zile" peste barele 10-11 # SL lovit la bara 14: săgeată din dreapta sus
xa, xb, yb = xd(10) - 6, xd(11) + 6, y_sl - 12
out.append(f'<path d="M{xa:.1f},{yb + 6:.1f} V{yb:.1f} H{xb:.1f} V{yb + 6:.1f}" '
f'fill="none" stroke="{GRAY}" stroke-width="1.2"/>')
text(xb, yb - 6, "short de 1-2 zile: permis", fill=GRAY, anchor="end", bold=True)
# SL lovit la bara 14
cx14 = xd(HIT) cx14 = xd(HIT)
out.append(f'<circle cx="{cx14:.1f}" cy="{y_sl:.1f}" r="7" fill="none" stroke="{RED}" ' out.append(f'<circle cx="{cx14:.1f}" cy="{y_sl:.1f}" r="7" fill="none" stroke="{RED}" '
f'stroke-width="2"/>') f'stroke-width="2"/>')
y_lbl = DT - 22 y_hit = DT - 40
line(cx14, y_sl - 8, cx14, y_lbl + 4, RED, 1.2) arrow(560, y_hit + 6, cx14 + 9, y_sl - 9, RED)
text(cx14 - 6, y_lbl, "SL lovit: poziția short contra weekly", fill=RED, anchor="middle", bold=True) text(568, y_hit, "aici te-a scos: stopul 84.85, lovit a patra zi", fill=RED, bold=True)
text(568, y_hit + 18, "banii mari de pe weekly cumpără mai departe", fill=RED)
# Sell Doji: etichetă sub panou, cu leader spre confirmare # intrarea short: săgeată de jos-dreapta spre close-ul confirmării
y_bot = yd(min(b[2] for b in DY)) y_bot = yd(min(b[2] for b in DY))
y_sd = y_bot + 22 x_e = xd(12) + 6
line(xd(10), yd(DY[10][2]) + 4, xd(10), y_sd - 12, ORANGE, 1.2) arrow(x_e, y_tp + 30, xd(10) + 7, y_e + 4, ORANGE)
text(xd(10) - 20, y_sd, "Sell Doji daily: tehnic valid (close 83.60 &lt; low doji 83.95)", text(x_e + 6, y_tp + 28, "aici ai intrat SHORT, la 83.60: Sell Doji corect ca formă",
fill=ORANGE, bold=True) fill=ORANGE, bold=True)
text(x_e + 6, y_tp + 46, "(close sub low-ul doji-ului 83.95) — dar contra weekly-ului",
fill=ORANGE)
# insigna de contrast y0 = max(y_bot, y_tp + 46) + 34
rect(470, DT - 36, 230, 58, RED, 0.08, RED) text(20, y0, "Seria e construită: un singur caz ilustrează regula, nu o dovedește.", fill="#555")
text(585, DT - 12, "short daily = CONTRA ✗", fill=RED, anchor="middle", bold=True, size=16) H = y0 + 24
text(585, DT + 8, "weekly zice long; daily urcă mai departe", fill=RED, anchor="middle", size=11)
y0 = y_sd + 32
text(20, y0, "Short scurt înăuntrul structurii weekly: da. Poziție short contra ei: nu.",
fill=INK, bold=True)
text(20, y0 + 18, "Seria e construită: un singur caz ilustrează regula, nu o dovedește.", fill="#555")
H = y0 + 30
svg = (f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/svg" ' 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>") f'style="width:100%;height:auto;font:12px sans-serif">\n ' + "\n ".join(out) + "\n</svg>")

View File

@@ -38,19 +38,32 @@ open[0] = 81.30, fitile 0.15 peste/sub corp (uptrend de 9 candele).
NIVELURI (panoul daily) NIVELURI (panoul daily)
----------------------- -----------------------
intrare short 83.60 (portocaliu), SL 84.80 roșu („SL 84.80 = high 4 candele"), intrare short 83.60 (portocaliu), stop 84.85 roșu („stop 84.85 = 5 cenți peste
TP1 82.40 punctat („TP1 82.40 — neatins"). high-ul de 4 candele"), ținta 82.35 punctată („neatinsă — a scăzut o zi, la 83.00").
Paranteză orizontală peste barele 10-11: „short de 1-2 zile: permis" (gri). Stopul e 5 cenți peste extremă, ca oglinda pasului 5 din capitol (51.60 -> 51.55).
Mark(14, "SL lovit: poziția short contra weekly", roșu, above). Paranteza „short de 1-2 zile: permis" a fost scoasă (nuanță de nivel 3, încărca
pasul mecanic), la fel și insignele de colț — locul lor îl iau săgețile.
SĂGEȚI (format tutorial v2: ce ȘI de ce, 1 pe weekly + 2 pe daily)
- weekly, spre confirmare: „weekly: Buy Doji confirmat (close 81.30, peste
high-ul doji-ului 79.80)" / „deci direcția permisă e LONG: pe daily cauți
doar Buy Doji".
- daily, spre close-ul confirmării: „aici ai intrat SHORT, la 83.60: Sell Doji
corect ca formă (close sub low-ul doji-ului 83.95) — dar contra weekly-ului".
- daily, spre bara 14 pe linia stopului: „aici te-a scos: stopul 84.85, lovit a
patra zi" / „banii mari de pe weekly cumpără mai departe".
Zone: verde peste doji-ul + confirmarea weekly, portocalie peste Sell Doji-ul
daily (portocaliu, nu roșu, ca să nu se confunde cu linia stopului).
Lățime 900 (textele săgeților stau în dreapta candelelor).
ASSERT-URI ASSERT-URI
---------- ----------
1. open[i] == close[i-1] pe ambele panouri; h/l cuprind o/c. 1. open[i] == close[i-1] pe ambele panouri; h/l cuprind o/c.
2. Doji weekly și doji daily: abs(o-c) <= 0.10*(h-l). 2. Doji weekly și doji daily: abs(o-c) <= 0.10*(h-l).
3. weekly close[8] > high[7]; daily close[10] < low[9]. 3. weekly close[8] > high[7]; daily close[10] < low[9].
4. SL == max(h for bare daily 7..10) == 84.80; risc == 1.20; TP1 == 82.40. 4. SL == max(h for bare daily 7..10) + 0.05 == 84.85; risc == 1.25; TP1 == 82.35.
5. min(l for bare daily 11..16) == 83.00 > 82.40 (TP1 neatins). 5. min(l for bare daily 11..16) == 83.00 > 82.35 (TP1 neatins).
6. primul i>10 cu high >= 84.80 este 14. 6. primul i>10 cu high >= 84.85 este 14.
SURSA SURSA
----- -----

View File

@@ -1,4 +1,4 @@
<svg viewBox="0 0 720 605" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 900 579" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="20.0" y="24.0" fill="#333" style="font-weight:bold;font-size:14px">NU: Sell Doji daily contra unui Buy Doji weekly — exemplu construit</text> <text x="20.0" y="24.0" fill="#333" style="font-weight:bold;font-size:14px">NU: Sell Doji daily contra unui Buy Doji weekly — exemplu construit</text>
<text x="20.0" y="50.0" fill="#555" style="font-weight:bold">weekly: direcția</text> <text x="20.0" y="50.0" fill="#555" style="font-weight:bold">weekly: direcția</text>
<rect x="164.0" y="152.6" width="32.0" height="56.0" fill="#188a3e" fill-opacity="0.12" stroke="#188a3e" rx="3"/> <rect x="164.0" y="152.6" width="32.0" height="56.0" fill="#188a3e" fill-opacity="0.12" stroke="#188a3e" rx="3"/>
@@ -23,19 +23,19 @@
<line x1="204.0" y1="143.4" x2="204.0" y2="162.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="204.0" y1="143.4" x2="204.0" y2="162.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="199.5" y="147.0" width="9" height="13.2" fill="#188a3e"/> <rect x="199.5" y="147.0" width="9" height="13.2" fill="#188a3e"/>
<text x="172.0" y="220.6" fill="#d06a00" text-anchor="middle" style="font-weight:bold">doji weekly</text> <text x="172.0" y="220.6" fill="#d06a00" text-anchor="middle" style="font-weight:bold">doji weekly</text>
<text x="218.0" y="164.2" fill="#188a3e" style="font-weight:bold">Buy Doji weekly: direcția = long</text> <line x1="300.0" y1="154.2" x2="209.0" y2="154.2" stroke="#188a3e" stroke-width="1.8"/>
<rect x="470.0" y="66.0" width="230.0" height="58.0" fill="#188a3e" fill-opacity="0.1" stroke="#188a3e" rx="3"/> <polygon points="200.0,154.2 209.0,149.7 209.0,158.7" fill="#188a3e"/>
<text x="585.0" y="90.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:16px">WEEKLY: LONG ↑</text> <text x="306.0" y="150.2" fill="#188a3e" style="font-weight:bold">weekly: Buy Doji confirmat (close 81.30, peste high-ul doji-ului 79.80)</text>
<text x="585.0" y="110.0" fill="#188a3e" text-anchor="middle" style="font-size:11px">confirmare 81.30 &gt; high doji 79.80</text> <text x="306.0" y="168.2" fill="#188a3e">deci direcția permisă e LONG: pe daily cauți doar Buy Doji</text>
<line x1="20.0" y1="238.6" x2="700.0" y2="238.6" stroke="#ddd" stroke-width="1"/> <line x1="20.0" y1="238.6" x2="880.0" y2="238.6" stroke="#ddd" stroke-width="1"/>
<text x="20.0" y="260.6" fill="#555" style="font-weight:bold">daily: săptămânile de după confirmare (open 81.30 = close-ul ei)</text> <text x="20.0" y="260.6" fill="#555" style="font-weight:bold">daily: săptămânile de după confirmare (open 81.30 = close-ul ei)</text>
<rect x="214.0" y="371.6" width="34.0" height="60.0" fill="#d06a00" fill-opacity="0.15" stroke="#d06a00" rx="3"/> <rect x="214.0" y="371.6" width="34.0" height="60.0" fill="#d06a00" fill-opacity="0.15" stroke="#d06a00" rx="3"/>
<line x1="212.0" y1="374.6" x2="392.0" y2="374.6" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/> <line x1="212.0" y1="372.6" x2="392.0" y2="372.6" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="232.0" y1="422.6" x2="392.0" y2="422.6" stroke="#d06a00" stroke-width="1.5" stroke-dasharray="6 3"/> <line x1="232.0" y1="422.6" x2="392.0" y2="422.6" stroke="#d06a00" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="232.0" y1="470.6" x2="392.0" y2="470.6" stroke="#777" stroke-width="1.5" stroke-dasharray="2 3"/> <line x1="232.0" y1="472.6" x2="392.0" y2="472.6" stroke="#777" stroke-width="1.5" stroke-dasharray="2 3"/>
<text x="400.0" y="378.6" fill="#c00" style="font-size:11px">SL 84.80 = high 4 candele</text> <text x="400.0" y="376.6" fill="#c00" style="font-size:11px">stop 84.85 = 5 cenți peste high-ul de 4 candele</text>
<text x="400.0" y="426.6" fill="#d06a00" style="font-size:11px">intrare short 83.60</text> <text x="400.0" y="426.6" fill="#d06a00" style="font-size:11px">intrare short 83.60</text>
<text x="400.0" y="474.6" fill="#777" style="font-size:11px">TP1 82.40 — neatins</text> <text x="400.0" y="476.6" fill="#777" style="font-size:11px">ținta 82.35 — neatinsă (a scăzut o zi, la 83.00)</text>
<line x1="60.0" y1="492.6" x2="60.0" y2="520.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="60.0" y1="492.6" x2="60.0" y2="520.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="55.5" y="498.6" width="9" height="16.0" fill="#188a3e"/> <rect x="55.5" y="498.6" width="9" height="16.0" fill="#188a3e"/>
<line x1="78.0" y1="472.6" x2="78.0" y2="504.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="78.0" y1="472.6" x2="78.0" y2="504.6" stroke="#1a1a1a" stroke-width="1.2"/>
@@ -70,16 +70,14 @@
<rect x="325.5" y="342.6" width="9" height="20.0" fill="#188a3e"/> <rect x="325.5" y="342.6" width="9" height="20.0" fill="#188a3e"/>
<line x1="348.0" y1="314.6" x2="348.0" y2="346.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="348.0" y1="314.6" x2="348.0" y2="346.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="343.5" y="322.6" width="9" height="20.0" fill="#188a3e"/> <rect x="343.5" y="322.6" width="9" height="20.0" fill="#188a3e"/>
<path d="M234.0,368.6 V362.6 H264.0 V368.6" fill="none" stroke="#777" stroke-width="1.2"/> <circle cx="312.0" cy="372.6" r="7" fill="none" stroke="#c00" stroke-width="2"/>
<text x="264.0" y="356.6" fill="#777" text-anchor="end" style="font-weight:bold">short de 1-2 zile: permis</text> <line x1="560.0" y1="280.6" x2="329.5" y2="360.6" stroke="#c00" stroke-width="1.8"/>
<circle cx="312.0" cy="374.6" r="7" fill="none" stroke="#c00" stroke-width="2"/> <polygon points="321.0,363.6 328.0,356.4 331.0,364.9" fill="#c00"/>
<line x1="312.0" y1="366.6" x2="312.0" y2="296.6" stroke="#c00" stroke-width="1.2"/> <text x="568.0" y="274.6" fill="#c00" style="font-weight:bold">aici te-a scos: stopul 84.85, lovit a patra zi</text>
<text x="306.0" y="292.6" fill="#c00" text-anchor="middle" style="font-weight:bold">SL lovit: poziția short contra weekly</text> <text x="568.0" y="292.6" fill="#c00">banii mari de pe weekly cumpără mai departe</text>
<line x1="240.0" y1="432.6" x2="240.0" y2="530.6" stroke="#d06a00" stroke-width="1.2"/> <line x1="282.0" y1="502.6" x2="250.8" y2="434.8" stroke="#d06a00" stroke-width="1.8"/>
<text x="220.0" y="542.6" fill="#d06a00" style="font-weight:bold">Sell Doji daily: tehnic valid (close 83.60 &lt; low doji 83.95)</text> <polygon points="247.0,426.6 254.9,432.9 246.7,436.7" fill="#d06a00"/>
<rect x="470.0" y="278.6" width="230.0" height="58.0" fill="#c00" fill-opacity="0.08" stroke="#c00" rx="3"/> <text x="288.0" y="500.6" fill="#d06a00" style="font-weight:bold">aici ai intrat SHORT, la 83.60: Sell Doji corect ca formă</text>
<text x="585.0" y="302.6" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:16px">short daily = CONTRA ✗</text> <text x="288.0" y="518.6" fill="#d06a00">(close sub low-ul doji-ului 83.95) — dar contra weekly-ului</text>
<text x="585.0" y="322.6" fill="#c00" text-anchor="middle" style="font-size:11px">weekly zice long; daily urcă mai departe</text> <text x="20.0" y="554.6" fill="#555">Seria e construită: un singur caz ilustrează regula, nu o dovedește.</text>
<text x="20.0" y="574.6" fill="#333" style="font-weight:bold">Short scurt înăuntrul structurii weekly: da. Poziție short contra ei: nu.</text>
<text x="20.0" y="592.6" fill="#555">Seria e construită: un singur caz ilustrează regula, nu o dovedește.</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -1,30 +1,31 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Ce e doji și ce nu — patru candele cu același high 50.10 și low 49.20. """Ce e un doji și ce nu — patru candele cu același high 50.10 și low 49.20.
Citește `gen/strategii/buy_doji_doji_forma.spec.txt` și scrie Citește `gen/strategii/buy_doji_doji_forma.spec.txt` și scrie
`gen/strategii/buy_doji_doji_forma.svg`. Definiție de o candelă (stilul `gen/strategii/buy_doji_doji_forma.svg`. E prima imagine din capitol: cine o
vechi, candele izolate): diferă doar corpul, deci testul „corp ≤ 10 % din vede nu știe ce e un doji, deci candela A primește săgeți pe corp și pe
range, fitil în ambele părți" se vede direct pe formă. fiecare fitil, cu explicația de ce arată așa, iar C și D sunt contraexemple.
Zonă verde peste A și B („doji"), zonă roșie peste C și D („nu e doji").
Desenat direct, nu cu `Chart`: `tag`/`note` din svg_candles pun etichetele Desenat direct, nu cu `Chart`: `tag`/`note` din svg_candles pun etichetele
pe un singur rând sau în blocul de jos, iar aici fiecare etichetă trebuie să pe un singur rând sau în blocul de jos, iar aici fiecare etichetă trebuie să
stea lipită sub candela ei, pe 2-3 rânduri. stea lipită sub candela ei, pe 2-3 rânduri, plus săgeți cu text pe lateral.
Rulare: python3 gen/strategii/buy_doji_doji_forma.py Rulare: python3 gen/strategii/buy_doji_doji_forma.py
""" """
from pathlib import Path from pathlib import Path
OUT = Path(__file__).with_suffix(".svg") OUT = Path(__file__).with_suffix(".svg")
GREEN, RED, GREY = "#188a3e", "#c00", "#555" GREEN, RED, GREY, BLUE = "#188a3e", "#c00", "#555", "#1a5fb4"
H, L = 50.10, 49.20 H, L = 50.10, 49.20
RNG = H - L RNG = H - L
# (nume, o, h, l, c, verdict, rânduri de etichetă sub candelă) # (nume, o, h, l, c, verdict, rânduri de etichetă sub candelă)
CANDLES = [ CANDLES = [
("A", 49.60, 50.10, 49.20, 49.55, "DA", ["DA: corp 0.05", "= 5.6 % din range"]), ("A", 49.60, 50.10, 49.20, 49.55, "DA", ["DA: corp 0.05", "= 5,6 % din înălțime"]),
("B", 49.62, 50.10, 49.20, 49.53, "DA", ["DA, la limită:", "corp 0.09 = 10 %", "(parametrul 10)"]), ("B", 49.62, 50.10, 49.20, 49.53, "DA", ["DA, la limită:", "corp 0.09 = 10 %"]),
("C", 49.80, 50.10, 49.20, 49.50, "NU", ["NU: corp 0.30", "= 33 %"]), ("C", 49.80, 50.10, 49.20, 49.50, "NU", ["NU: corp 0.30", "= 33 %"]),
("D", 50.05, 50.10, 49.20, 50.10, "NU", ["NU: corp mic (5.6 %),", "dar fără fitil sus"]), ("D", 50.05, 50.10, 49.20, 50.10, "NU", ["NU: corp mic (5,6 %),", "dar fără fitil sus"]),
] ]
# --- assert-urile din spec -------------------------------------------------- # --- assert-urile din spec --------------------------------------------------
@@ -39,8 +40,8 @@ _, oD, hD, _, cD, *_ = CANDLES[3]
assert max(oD, cD) == hD assert max(oD, cD) == hD
# --- geometrie --------------------------------------------------------------- # --- geometrie ---------------------------------------------------------------
SCALE, TOP, W = 260, 72, 740 SCALE, TOP, W = 260, 210, 1000
XS = [150, 300, 450, 600] # centrele candelelor XS = [350, 490, 690, 860] # centrele candelelor: A, B (doji) | C, D (nu)
BODY_W = 26 BODY_W = 26
@@ -61,16 +62,45 @@ def text(x, yy, s, color=GREY, anchor="start", bold=False, size=12):
t(f'<text x="{x:.1f}" y="{yy:.1f}" fill="{color}" text-anchor="{anchor}"{style}>{s}</text>') t(f'<text x="{x:.1f}" y="{yy:.1f}" fill="{color}" text-anchor="{anchor}"{style}>{s}</text>')
text(24, 22, "Ce e doji și ce nu — aceeași bară 50.10 / 49.20", "#333", bold=True) def zone(x0, x1, y0, y1, label, color):
t(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"/>')
text(x0 + 6, y0 - 7, label, color, bold=True)
def arrow(x1, y1, x2, y2, color, lines, anchor="start"):
"""Săgeată de la (x1,y1) [coada, lângă text] la (x2,y2) [vârf, pe țintă]."""
d = max(((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5, 1e-9)
ux, uy = (x2 - x1) / d, (y2 - y1) / d
bx, by = x2 - 8 * ux, y2 - 8 * uy
t(f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{bx:.1f}" y2="{by:.1f}" '
f'stroke="{color}" stroke-width="1.6"/>')
t(f'<polygon points="{x2:.1f},{y2:.1f} {bx - 4 * uy:.1f},{by + 4 * ux:.1f} '
f'{bx + 4 * uy:.1f},{by - 4 * ux:.1f}" fill="{color}"/>')
dx = -6 if anchor == "end" else (0 if anchor == "middle" else 6)
# la săgeata verticală textul stă deasupra cozii, altfel intră peste ea
y0 = (y1 - 10 - 14 * (len(lines) - 1) if anchor == "middle"
else y1 + 4 - 14 * (len(lines) - 1) / 2)
for k, s in enumerate(lines):
text(x1 + dx, y0 + 14 * k, s, color, anchor, bold=(k == 0))
text(24, 30, "Ce e un doji și ce nu — aceeași bară, 50.10 sus și 49.20 jos", "#333",
bold=True, size=14)
# zonele: A+B sunt doji, C+D nu
label_y0 = y(L) + 28
z_bot = label_y0 + 16 * 2 - 4
zone(XS[0] - 58, XS[1] + 62, y(H) - 30, z_bot, "doji", GREEN)
zone(XS[2] - 62, XS[3] + 74, y(H) - 30, z_bot, "nu e doji", RED)
# high și low comune: linii subțiri pe toată lățimea # high și low comune: linii subțiri pe toată lățimea
for p in (H, L): for p in (H, L):
t(f'<line x1="{XS[0] - 30}" y1="{y(p):.1f}" x2="{W - 24}" y2="{y(p):.1f}" ' t(f'<line x1="{XS[0] - 100}" y1="{y(p):.1f}" x2="{W - 24}" y2="{y(p):.1f}" '
f'stroke="#bbb" stroke-dasharray="4 3"/>') f'stroke="#bbb" stroke-dasharray="4 3"/>')
text(XS[0] - 36, y(H) + 4, "high 50.10", anchor="end") text(24, y(H) - 6, "cât de sus a urcat prețul: 50.10")
text(XS[0] - 36, y(L) + 4, "low 49.20", anchor="end") text(24, y(L) + 14, "cât de jos a coborât: 49.20")
label_y0 = y(L) + 24
for (n, o, h, l, c, verdict, lines), x in zip(CANDLES, XS): for (n, o, h, l, c, verdict, lines), x in zip(CANDLES, XS):
color = GREEN if c >= o else RED color = GREEN if c >= o else RED
vcol = GREEN if verdict == "DA" else RED vcol = GREEN if verdict == "DA" else RED
@@ -78,25 +108,34 @@ for (n, o, h, l, c, verdict, lines), x in zip(CANDLES, XS):
top, bot = y(max(o, c)), y(min(o, c)) top, bot = y(max(o, c)), y(min(o, c))
t(f'<rect x="{x - BODY_W / 2:.1f}" y="{top:.1f}" width="{BODY_W}" ' t(f'<rect x="{x - BODY_W / 2:.1f}" y="{top:.1f}" width="{BODY_W}" '
f'height="{max(bot - top, 1.6):.1f}" fill="{color}"/>') f'height="{max(bot - top, 1.6):.1f}" fill="{color}"/>')
text(x, y(H) - 14, verdict, vcol, "middle", bold=True, size=18)
for k, s in enumerate(lines): for k, s in enumerate(lines):
text(x, label_y0 + 16 * k, s, vcol, "middle", bold=(k == 0)) text(x, label_y0 + 16 * k, s, vcol, "middle", bold=(k == 0))
# prețurile pe A: open la stânga (mai sus), close la dreapta (mai jos) # --- săgețile pe A: corp, fitil sus, fitil jos -------------------------------
x = XS[0] xA = XS[0]
text(x - 36, y(oA) + 2, "open 49.60", anchor="end") arrow(xA - 60, y(49.92), xA - 3, y(49.85), BLUE, anchor="end",
t(f'<line x1="{x - 32}" y1="{y(oA):.1f}" x2="{x - 14}" y2="{y(oA):.1f}" stroke="{GREY}"/>') lines=["fitilul de sus", "cumpărătorii au împins, dar n-au ținut"])
text(x + 36, y(cA) + 8, "close 49.55") arrow(xA - 60, y(49.575), xA - 15, y(49.575), BLUE, anchor="end",
t(f'<line x1="{x + 14}" y1="{y(cA):.1f}" x2="{x + 32}" y2="{y(cA):.1f}" stroke="{GREY}"/>') lines=["corpul: aproape o linie",
"open și close aproape egale — nimeni",
"n-a câștigat ziua"])
arrow(xA - 60, y(49.30), xA - 3, y(49.375), BLUE, anchor="end",
lines=["fitilul de jos", "vânzătorii au împins, dar n-au ținut"])
# prețurile de open/close, în dreapta candelei A
text(xA + 20, y(oA) - 2, "open 49.60")
text(xA + 20, y(cA) + 10, "close 49.55")
# D: close = high, deci fitilul de sus lipsește # --- săgețile pe contraexemple ----------------------------------------------
x = XS[3] xC, xD = XS[2], XS[3]
text(x + 20, y(H) + 12, "← fără fitil sus", RED) arrow(xC + 34, y(H) - 112, xC + 14, y(49.78), RED,
lines=["corp prea gros (33 %)", "aici una din tabere a câștigat —", "nu mai e indecizie"])
arrow(xD, y(H) - 34, xD, y(H) - 4, RED, anchor="middle",
lines=["fără fitil sus", "regula cere fitil în ambele părți"])
cap_y = label_y0 + 16 * 3 + 14 cap_y = z_bot + 30
text(24, cap_y, f"Test doji: corp ≤ 10 % din range ({RNG:.2f}) și fitil în ambele părți. " text(24, cap_y, f"Doji = corpul e cel mult 10 % din înălțimea totală a barei "
"Scară: 0.10 = 26 px.") f"(aici înălțimea e {RNG:.2f}) și are fitil și sus, și jos.")
height = cap_y + 12 height = cap_y + 16
svg = (f'<svg viewBox="0 0 {W} {height:.0f}" xmlns="http://www.w3.org/2000/svg" ' svg = (f'<svg viewBox="0 0 {W} {height:.0f}" xmlns="http://www.w3.org/2000/svg" '
f'style="width:100%;height:auto;font:12px sans-serif">\n ' f'style="width:100%;height:auto;font:12px sans-serif">\n '

View File

@@ -1,10 +1,11 @@
SPEC DIAGRAMĂ — buy_doji_doji_forma SPEC DIAGRAMĂ — buy_doji_doji_forma
=================================== ===================================
tip: DEFINIȚIE de o candelă (stil vechi permis de STYLE.md: 4 candele tip: DEFINIȚIE de o candelă (stil vechi permis de STYLE.md: 4 candele
izolate, gap 92, body_w 26), fără trend, fără volum. izolate, body_w 26), fără trend, fără volum. Adnotată „ca la
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 3 proști": 2 zone dreptunghiulare + 5 săgeți cu text (CE + DE CE).
destinație: summaries/17_STRATEGII/01_buy_doji.md, nivelul 1 („Ce e un doji")
cheie markdown: <!-- DIAGRAMA: doji_forma --> cheie markdown: <!-- DIAGRAMA: doji_forma -->
titlu SVG: „Ce e doji și ce nu — aceeași bară 50.10 / 49.20" titlu SVG: „Ce e un doji și ce nu — aceeași bară, 50.10 sus și 49.20 jos"
CE TREBUIE SĂ DEMONSTREZE CE TREBUIE SĂ DEMONSTREZE
------------------------- -------------------------
@@ -17,9 +18,25 @@ A (49.60, 50.10, 49.20, 49.55) „DA: corp 0.05 = 5.6 % din range"
B (49.62, 50.10, 49.20, 49.53) „DA, la limită: corp 0.09 = 10 % (parametrul 10)" B (49.62, 50.10, 49.20, 49.53) „DA, la limită: corp 0.09 = 10 % (parametrul 10)"
C (49.80, 50.10, 49.20, 49.50) „NU: corp 0.30 = 33 %" C (49.80, 50.10, 49.20, 49.50) „NU: corp 0.30 = 33 %"
D (50.05, 50.10, 49.20, 50.10) „NU: corp mic (5.6 %), dar fără fitil sus" D (50.05, 50.10, 49.20, 50.10) „NU: corp mic (5.6 %), dar fără fitil sus"
Deasupra fiecărei candele: „DA" verde / „NU" roșu. Verdictul e în eticheta de sub candelă („DA: …" verde / „NU: …" roșu) și în
Etichete de preț pe A: „high 50.10", „low 49.20", „open 49.60", „close 49.55" eticheta zonei; nu se mai scrie DA/NU mare deasupra barei (se bătea cap în cap
(open deasupra lui close, pentru că open > close; verifică ordinea pe axă). cu textul săgeților).
Etichete de preț pe A: „cât de sus a urcat prețul: 50.10", „cât de jos a
coborât: 49.20", „open 49.60", „close 49.55" (open deasupra lui close, pentru
că open > close; verifică ordinea pe axă).
ZONE (dreptunghiuri de evidențiere, fill-opacity 0.10)
------------------------------------------------------
verde peste A și B, etichetă „doji"; roșie peste C și D, etichetă „nu e doji".
SĂGEȚI (text pe 2-3 rânduri: CE, apoi DE CE)
--------------------------------------------
pe A, din stânga: spre fitilul de sus („fitilul de sus / cumpărătorii au
împins, dar n-au ținut"); spre corp („corpul: aproape o linie / open și close
aproape egale — nimeni n-a câștigat ziua"); spre fitilul de jos („fitilul de
jos / vânzătorii au împins, dar n-au ținut").
pe C, de sus: „corp prea gros (33 %) / aici una din tabere a câștigat — nu mai
e indecizie". pe D, de sus: „fără fitil sus / regula cere fitil în ambele părți".
ASSERT-URI ASSERT-URI
---------- ----------

View File

@@ -1,34 +1,52 @@
<svg viewBox="0 0 740 404" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 1000 546" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24.0" y="22.0" fill="#333" text-anchor="start" style="font-weight:bold;font-size:12px">Ce e doji și ce nu — aceeași bară 50.10 / 49.20</text> <text x="24.0" y="30.0" fill="#333" text-anchor="start" style="font-weight:bold;font-size:14px">Ce e un doji și ce nu — aceeași bară, 50.10 sus și 49.20 jos</text>
<line x1="120" y1="72.0" x2="716" y2="72.0" stroke="#bbb" stroke-dasharray="4 3"/> <rect x="292.0" y="180.0" width="260.0" height="320.0" fill="#188a3e" fill-opacity="0.10" stroke="#188a3e" stroke-width="1"/>
<line x1="120" y1="306.0" x2="716" y2="306.0" stroke="#bbb" stroke-dasharray="4 3"/> <text x="298.0" y="173.0" fill="#188a3e" text-anchor="start" style="font-weight:bold;font-size:12px">doji</text>
<text x="114.0" y="76.0" fill="#555" text-anchor="end">high 50.10</text> <rect x="628.0" y="180.0" width="306.0" height="320.0" fill="#c00" fill-opacity="0.10" stroke="#c00" stroke-width="1"/>
<text x="114.0" y="310.0" fill="#555" text-anchor="end">low 49.20</text> <text x="634.0" y="173.0" fill="#c00" text-anchor="start" style="font-weight:bold;font-size:12px">nu e doji</text>
<line x1="150" y1="72.0" x2="150" y2="306.0" stroke="#1a1a1a" stroke-width="1.4"/> <line x1="250" y1="210.0" x2="976" y2="210.0" stroke="#bbb" stroke-dasharray="4 3"/>
<rect x="137.0" y="202.0" width="26" height="13.0" fill="#c00"/> <line x1="250" y1="444.0" x2="976" y2="444.0" stroke="#bbb" stroke-dasharray="4 3"/>
<text x="150.0" y="58.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:18px">DA</text> <text x="24.0" y="204.0" fill="#555" text-anchor="start">cât de sus a urcat prețul: 50.10</text>
<text x="150.0" y="330.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:12px">DA: corp 0.05</text> <text x="24.0" y="458.0" fill="#555" text-anchor="start">cât de jos a coborât: 49.20</text>
<text x="150.0" y="346.0" fill="#188a3e" text-anchor="middle">= 5.6 % din range</text> <line x1="350" y1="210.0" x2="350" y2="444.0" stroke="#1a1a1a" stroke-width="1.4"/>
<line x1="300" y1="72.0" x2="300" y2="306.0" stroke="#1a1a1a" stroke-width="1.4"/> <rect x="337.0" y="340.0" width="26" height="13.0" fill="#c00"/>
<rect x="287.0" y="196.8" width="26" height="23.4" fill="#c00"/> <text x="350.0" y="472.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:12px">DA: corp 0.05</text>
<text x="300.0" y="58.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:18px">DA</text> <text x="350.0" y="488.0" fill="#188a3e" text-anchor="middle">= 5,6 % din înălțime</text>
<text x="300.0" y="330.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:12px">DA, la limită:</text> <line x1="490" y1="210.0" x2="490" y2="444.0" stroke="#1a1a1a" stroke-width="1.4"/>
<text x="300.0" y="346.0" fill="#188a3e" text-anchor="middle">corp 0.09 = 10 %</text> <rect x="477.0" y="334.8" width="26" height="23.4" fill="#c00"/>
<text x="300.0" y="362.0" fill="#188a3e" text-anchor="middle">(parametrul 10)</text> <text x="490.0" y="472.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold;font-size:12px">DA, la limită:</text>
<line x1="450" y1="72.0" x2="450" y2="306.0" stroke="#1a1a1a" stroke-width="1.4"/> <text x="490.0" y="488.0" fill="#188a3e" text-anchor="middle">corp 0.09 = 10 %</text>
<rect x="437.0" y="150.0" width="26" height="78.0" fill="#c00"/> <line x1="690" y1="210.0" x2="690" y2="444.0" stroke="#1a1a1a" stroke-width="1.4"/>
<text x="450.0" y="58.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:18px">NU</text> <rect x="677.0" y="288.0" width="26" height="78.0" fill="#c00"/>
<text x="450.0" y="330.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:12px">NU: corp 0.30</text> <text x="690.0" y="472.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:12px">NU: corp 0.30</text>
<text x="450.0" y="346.0" fill="#c00" text-anchor="middle">= 33 %</text> <text x="690.0" y="488.0" fill="#c00" text-anchor="middle">= 33 %</text>
<line x1="600" y1="72.0" x2="600" y2="306.0" stroke="#1a1a1a" stroke-width="1.4"/> <line x1="860" y1="210.0" x2="860" y2="444.0" stroke="#1a1a1a" stroke-width="1.4"/>
<rect x="587.0" y="72.0" width="26" height="13.0" fill="#188a3e"/> <rect x="847.0" y="210.0" width="26" height="13.0" fill="#188a3e"/>
<text x="600.0" y="58.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:18px">NU</text> <text x="860.0" y="472.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:12px">NU: corp mic (5,6 %),</text>
<text x="600.0" y="330.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:12px">NU: corp mic (5.6 %),</text> <text x="860.0" y="488.0" fill="#c00" text-anchor="middle">dar fără fitil sus</text>
<text x="600.0" y="346.0" fill="#c00" text-anchor="middle">dar fără fitil sus</text> <line x1="290.0" y1="256.8" x2="339.4" y2="272.6" stroke="#1a5fb4" stroke-width="1.6"/>
<text x="114.0" y="204.0" fill="#555" text-anchor="end">open 49.60</text> <polygon points="347.0,275.0 338.2,276.4 340.6,268.8" fill="#1a5fb4"/>
<line x1="118" y1="202.0" x2="136" y2="202.0" stroke="#555"/> <text x="284.0" y="253.8" fill="#1a5fb4" text-anchor="end" style="font-weight:bold;font-size:12px">fitilul de sus</text>
<text x="186.0" y="223.0" fill="#555" text-anchor="start">close 49.55</text> <text x="284.0" y="267.8" fill="#1a5fb4" text-anchor="end">cumpărătorii au împins, dar n-au ținut</text>
<line x1="164" y1="215.0" x2="182" y2="215.0" stroke="#555"/> <line x1="290.0" y1="346.5" x2="327.0" y2="346.5" stroke="#1a5fb4" stroke-width="1.6"/>
<text x="620.0" y="84.0" fill="#c00" text-anchor="start">← fără fitil sus</text> <polygon points="335.0,346.5 327.0,350.5 327.0,342.5" fill="#1a5fb4"/>
<text x="24.0" y="392.0" fill="#555" text-anchor="start">Test doji: corp ≤ 10 % din range (0.90) și fitil în ambele părți. Scară: 0.10 = 26 px.</text> <text x="284.0" y="336.5" fill="#1a5fb4" text-anchor="end" style="font-weight:bold;font-size:12px">corpul: aproape o linie</text>
<text x="284.0" y="350.5" fill="#1a5fb4" text-anchor="end">open și close aproape egale — nimeni</text>
<text x="284.0" y="364.5" fill="#1a5fb4" text-anchor="end">n-a câștigat ziua</text>
<line x1="290.0" y1="418.0" x2="339.4" y2="401.1" stroke="#1a5fb4" stroke-width="1.6"/>
<polygon points="347.0,398.5 340.7,404.9 338.1,397.3" fill="#1a5fb4"/>
<text x="284.0" y="415.0" fill="#1a5fb4" text-anchor="end" style="font-weight:bold;font-size:12px">fitilul de jos</text>
<text x="284.0" y="429.0" fill="#1a5fb4" text-anchor="end">vânzătorii au împins, dar n-au ținut</text>
<text x="370.0" y="338.0" fill="#555" text-anchor="start">open 49.60</text>
<text x="370.0" y="363.0" fill="#555" text-anchor="start">close 49.55</text>
<line x1="724.0" y1="98.0" x2="704.8" y2="285.2" stroke="#c00" stroke-width="1.6"/>
<polygon points="704.0,293.2 700.8,284.8 708.8,285.6" fill="#c00"/>
<text x="730.0" y="88.0" fill="#c00" text-anchor="start" style="font-weight:bold;font-size:12px">corp prea gros (33 %)</text>
<text x="730.0" y="102.0" fill="#c00" text-anchor="start">aici una din tabere a câștigat —</text>
<text x="730.0" y="116.0" fill="#c00" text-anchor="start">nu mai e indecizie</text>
<line x1="860.0" y1="176.0" x2="860.0" y2="198.0" stroke="#c00" stroke-width="1.6"/>
<polygon points="860.0,206.0 856.0,198.0 864.0,198.0" fill="#c00"/>
<text x="860.0" y="152.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:12px">fără fitil sus</text>
<text x="860.0" y="166.0" fill="#c00" text-anchor="middle">regula cere fitil în ambele părți</text>
<text x="24.0" y="530.0" fill="#555" text-anchor="start">Doji = corpul e cel mult 10 % din înălțimea totală a barei (aici înălțimea e 0.90) și are fitil și sus, și jos.</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -6,10 +6,14 @@ Citește `gen/strategii/buy_doji_fereastra.spec.txt` și scrie
cu aceeași serie până la doji: sus confirmarea vine la bara +2 (în fereastră), cu aceeași serie până la doji: sus confirmarea vine la bara +2 (în fereastră),
jos niciuna din +1..+3 nu confirmă, iar a 4-a închide sub low-ul dojiului. jos niciuna din +1..+3 nu confirmă, iar a 4-a închide sub low-ul dojiului.
Toate cifrele din desen vin din specificație: doji h 50.10 / l 49.20, Adnotat „ca la proști": zonă dreptunghiulară peste cele 3 candele ale
closes-urile DA/NU, pragul 50.10, low-ul 49.20. Seriile sunt construite ferestrei pe ambele panouri, plus săgeți cu text care spun CE și DE CE
(open = close-ul barei anterioare, mai puțin open-ul primei bare, start-ul), („aici NU intri — s-a închis sub high-ul dojiului", „AICI INTRI, la close").
ca nivelurile afirmate să iasă exact din serie.
Toate cifrele din desen vin din specificație: doji h 50.10 / l 49.25,
closes-urile DA/NU, pragul 50.10. Seriile sunt construite (open = close-ul
barei anterioare, mai puțin open-ul primei bare, start-ul), ca nivelurile
afirmate să iasă exact din serie.
Rulare: python3 gen/strategii/buy_doji_fereastra.py Rulare: python3 gen/strategii/buy_doji_fereastra.py
""" """
@@ -18,21 +22,23 @@ import sys
from pathlib import Path from pathlib import Path
sys.path.insert(0, "/workspace/atm-curs-dl") sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Chart, Level, Mark, from_closes # noqa: E402 from svg_candles import Arrow, Chart, Mark, from_closes # noqa: E402
OUT = Path(__file__).with_suffix(".svg") OUT = Path(__file__).with_suffix(".svg")
W = 460 W = 640
VGAP = 34 VGAP = 0
SCALE = 45.0 # px / unitate, aceeași pe ambele panouri (comparație) SCALE = 60.0 # px / unitate, aceeași pe ambele panouri (comparație)
LEFT, GAP = 64, 40
ORANGE, RED, GREEN, BLUE, GREY = "#b06000", "#c00", "#188a3e", "#1a5fb4", "#555"
# --- seriile din specificație ---------------------------------------------- # --- seriile din specificație ----------------------------------------------
CLOSES_DA = [52.20, 51.40, 50.60, 49.65, CLOSES_DA = [52.20, 51.40, 50.60, 49.65,
49.60, # doji, h 50.10 / l 49.20 49.60, # doji, h 50.10 / l 49.25
49.90, # +1 — sub 50.10 49.90, # +1 — sub 50.10
50.40, # +2 — peste 50.10 => confirmă 50.40, # +2 — peste 50.10 => confirmă
50.80] 50.80]
CLOSES_NU = [52.20, 51.40, 50.60, 49.65, CLOSES_NU = [52.20, 51.40, 50.60, 49.65,
49.60, # doji, h 50.10 / l 49.20 49.60, # doji, h 50.10 / l 49.25
49.95, # +1 49.95, # +1
50.05, # +2 50.05, # +2
49.85, # +3 49.85, # +3
@@ -40,13 +46,13 @@ CLOSES_NU = [52.20, 51.40, 50.60, 49.65,
assert len(CLOSES_DA) == 8 and len(CLOSES_NU) == 9 assert len(CLOSES_DA) == 8 and len(CLOSES_NU) == 9
assert CLOSES_DA[:5] == CLOSES_NU[:5] assert CLOSES_DA[:5] == CLOSES_NU[:5]
HIGH_DOJI, LOW_DOJI = 50.10, 49.20 HIGH_DOJI, LOW_DOJI = 50.10, 49.25
# wick-uri: (up, down). Doji-ul (index 4) primește mecioni ca să iasă exact # wick-uri: (up, down). Doji-ul (index 4) primește fitile ca să iasă exact
# h=50.10 / l=49.20; restul au mecioni mici, egali. # h=50.10 / l=49.25; restul au fitile mici, egale.
wicks_da = [(0.15, 0.15)] * len(CLOSES_DA) wicks_da = [(0.15, 0.15)] * len(CLOSES_DA)
wicks_nu = [(0.15, 0.15)] * len(CLOSES_NU) wicks_nu = [(0.15, 0.15)] * len(CLOSES_NU)
wicks_da[4] = wicks_nu[4] = (0.45, 0.40) wicks_da[4] = wicks_nu[4] = (0.45, 0.35)
START = CLOSES_DA[0] + 0.15 # prima bară roșie, open > close START = CLOSES_DA[0] + 0.15 # prima bară roșie, open > close
cds_da = from_closes(CLOSES_DA, wicks=wicks_da, start=START) cds_da = from_closes(CLOSES_DA, wicks=wicks_da, start=START)
@@ -72,7 +78,7 @@ assert abs(cds_da[5].c - 49.90) < 1e-9 and cds_da[5].c <= HIGH_DOJI, \
assert abs(cds_da[6].c - entry) < 1e-9 and abs(entry - 50.40) < 1e-9, \ assert abs(cds_da[6].c - entry) < 1e-9 and abs(entry - 50.40) < 1e-9, \
"intrarea nu e close-ul de 50.40 al barei +2" "intrarea nu e close-ul de 50.40 al barei +2"
# 2. NU: niciun close din +1..+3 nu depășește 50.10; a 4-a închide sub 49.20 # 2. NU: niciun close din +1..+3 nu depășește 50.10; a 4-a închide sub 49.25
assert all(cds_nu[i].c <= HIGH_DOJI for i in (5, 6, 7)), \ assert all(cds_nu[i].c <= HIGH_DOJI for i in (5, 6, 7)), \
"un close din +1..+3 ar confirma, fereastra n-ar fi expirat" "un close din +1..+3 ar confirma, fereastra n-ar fi expirat"
assert cds_nu[8].c < LOW_DOJI, f"close[+4]={cds_nu[8].c} nu e sub {LOW_DOJI}" assert cds_nu[8].c < LOW_DOJI, f"close[+4]={cds_nu[8].c} nu e sub {LOW_DOJI}"
@@ -87,54 +93,102 @@ ser_nu = [(round(c.o, 9), round(c.h, 9), round(c.l, 9), round(c.c, 9)) for c in
assert ser_da == ser_nu, "panourile nu au aceeași serie până la doji" assert ser_da == ser_nu, "panourile nu au aceeași serie până la doji"
# --- desen: două Chart-uri, lipite vertical într-un singur SVG ------------- # --- desen: două Chart-uri, lipite vertical într-un singur SVG -------------
cds_nu[7].note = "+1: 49.95 · +2: 50.05 · +3: 49.85 — toate sub 50.10"
ch_da = Chart(
candles=cds_da,
marks=[Mark(4, "doji", ORANGE, "above")],
arrows=[
Arrow(5, "aici NU intri: s-a închis sub 50.10\nsemnalul cere o ÎNCHIDERE peste",
where="below", color=RED),
Arrow(6, "AICI INTRI, la close 50.40\nprima închidere peste\nhigh-ul dojiului",
price=entry, where="right", color=GREEN, dx=20, dy=46),
],
scale=SCALE, gap=GAP, body_w=13, left=LEFT, width=W,
title="DA — confirmare la +2, în fereastră",
)
ch_nu = Chart(
candles=cds_nu,
marks=[Mark(4, "doji", ORANGE, "above"), Mark(8, "a 4-a", RED, "above")],
arrows=[
Arrow(7, "a treia s-a închis tot sub 50.10\nfereastra s-a terminat: ștergi setup-ul",
where="above", color=RED, dx=135),
Arrow(8, "a închis sub low-ul dojiului\nsetup mort — nu mai intri",
where="below", color=RED),
],
scale=SCALE, gap=GAP, body_w=13, left=LEFT, width=W,
title="NU — nicio confirmare în 3 candele",
)
def _panel(ch: Chart): def _panel(ch: Chart):
svg = ch.render() """`_render()`, nu `render()`: al doilea restaurează top/left după desen,
m = re.search(r'viewBox="0 0 (\d+) ([\d.]+)"', svg) iar liniile și zonele desenate de mână ar pica deplasate față de body."""
svg = ch._render()
m = re.search(r'viewBox="0 0 ([\d.]+) ([\d.]+)"', svg)
assert m, "viewBox lipsă"
assert float(m.group(1)) == W, f"textul unei săgeți iese din {W}px"
body = svg[svg.index(">") + 1:svg.rindex("</svg>")] body = svg[svg.index(">") + 1:svg.rindex("</svg>")]
return body, float(m.group(2)) return body, float(m.group(2))
# DA — confirmarea vine la +2 def level(ch, price, text, color, below=False, at_left=True):
cds_da[5].note = "+1: close 49.90 — sub 50.10, nu confirmă" """Linie punctată pe toată lățimea + etichetă, desenată de mână: eticheta
cds_da[6].note = "+2: close 50.40 — peste 50.10, confirmă (intrare la close)" din `Level` stă lipită de linie și cade peste candelele care o traversează."""
ch_da = Chart( y = ch._y(price)
candles=cds_da, out = [f'<line x1="24" y1="{y:.1f}" x2="{W - 14}" y2="{y:.1f}" stroke="{color}" '
levels=[Level(HIGH_DOJI, "high doji 50.10", "#b06000", label_at="left"), f'stroke-width="1.5" stroke-dasharray="4 3"/>']
Level(LOW_DOJI, "low doji 49.20", "#c00", label_at="left")], for k, s in enumerate(text):
marks=[Mark(4, "doji", "#b06000", "above"), ty = (y + 15 + 14 * k) if below else (y - 6 - 14 * (len(text) - 1 - k))
Mark(6, f"confirmare +2 — intrare {entry:.2f}", "#188a3e", "above")], tx, anchor = (30, "start") if at_left else (W - 24, "end")
scale=SCALE, gap=40, body_w=13, left=44, width=W, out.append(f'<text x="{tx}" y="{ty:.1f}" fill="{color}" text-anchor="{anchor}" '
title="DA — confirmare la +2, în fereastră", f'style="font-weight:bold">{s}</text>')
) return out
def zone(ch, i0, i1, label, color, lift=0.0):
"""Dreptunghi de evidențiere peste candelele i0..i1, cu eticheta deasupra.
`lift` ridică marginea de sus (și deci eticheta), ca să nu cadă peste
săgețile care intră în zonă de sus."""
cds = ch.candles[i0:i1 + 1]
x0, x1 = ch._cx(i0) - 16, ch._cx(i1) + 16
y0 = ch._y(max(c.h for c in cds)) - 8 - lift
y1 = ch._y(min(c.l for c in cds)) + 8
return [f'<rect x="{x0:.1f}" y="{y0:.1f}" width="{x1 - x0:.1f}" height="{y1 - y0:.1f}" '
f'fill="{color}" fill-opacity="0.12" stroke="{color}" stroke-width="1"/>',
f'<text x="{x0 + 6:.1f}" y="{y0 - 7:.1f}" fill="{color}" '
f'style="font-weight:bold">{label}</text>']
# NU — nicio confirmare în 3 candele, apoi setup mort
cds_nu[5].note = "+1: 49.95; +2: 50.05; +3: 49.85 — toate sub 50.10"
cds_nu[8].note = "a 4-a: close 49.15 — sub low-ul dojiului 49.20, setup mort"
ch_nu = Chart(
candles=cds_nu,
levels=[Level(HIGH_DOJI, "high doji 50.10", "#b06000", label_at="left"),
Level(LOW_DOJI, "low doji 49.20", "#c00", label_at="left")],
marks=[Mark(4, "doji", "#b06000", "above"),
Mark(8, "a 4-a", "#c00", "above")],
scale=SCALE, gap=40, body_w=13, left=44, width=W,
title="NU — nicio confirmare în 3 candele",
)
body_da, h_da = _panel(ch_da) body_da, h_da = _panel(ch_da)
body_nu, h_nu = _panel(ch_nu) body_nu, h_nu = _panel(ch_nu)
extra_da = (zone(ch_da, 5, 7, "fereastra: 3 candele", BLUE)
+ level(ch_da, HIGH_DOJI,
["high-ul dojiului 50.10", "trebuie ÎNCHIS peste,", "nu doar atins"],
ORANGE, below=True)
+ level(ch_da, LOW_DOJI, ["low-ul dojiului 49.25"], RED, below=True))
extra_nu = (zone(ch_nu, 5, 7, "fereastra: 3 candele", BLUE)
+ level(ch_nu, HIGH_DOJI,
["high-ul dojiului 50.10", "trebuie ÎNCHIS peste,", "nu doar atins"],
ORANGE, below=True)
+ level(ch_nu, LOW_DOJI, ["low-ul dojiului 49.25"], RED, below=True))
cap1 = "Serii construite: open = close-ul barei anterioare." cap1 = "Serii construite: open = close-ul barei anterioare."
cap2 = "Doji: h 50.10 / l 49.20. Fereastra = maximum 3 candele după doji." cap2 = "Doji: h 50.10 / l 49.25. Fereastra = maximum 3 candele după doji."
cap_top = h_da + VGAP + h_nu + 20 cap_top = h_da + VGAP + h_nu + 20
H = cap_top + 22 H = cap_top + 22
parts = [ parts = [
f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/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">', f'style="width:100%;height:auto;font:12px sans-serif">',
f'<g transform="translate(0,0)">{body_da}</g>', # zonele și liniile întâi, ca să stea în spatele candelelor
f'<g transform="translate(0,{h_da + VGAP:.0f})">{body_nu}</g>', f'<g transform="translate(0,0)">{"".join(extra_da)}{body_da}</g>',
f'<text x="24" y="{cap_top:.0f}" fill="#555">{cap1}</text>', f'<g transform="translate(0,{h_da + VGAP:.0f})">{"".join(extra_nu)}{body_nu}</g>',
f'<text x="24" y="{cap_top + 17:.0f}" fill="#555">{cap2}</text>', f'<text x="24" y="{cap_top:.0f}" fill="{GREY}">{cap1}</text>',
f'<text x="24" y="{cap_top + 17:.0f}" fill="{GREY}">{cap2}</text>',
"</svg>", "</svg>",
] ]
svg = "\n ".join(parts) svg = "\n ".join(parts)
@@ -162,7 +216,8 @@ def _texts(body: str, y_off: float, tag: str):
return out return out
labels = _texts(body_da, 0.0, "DA") + _texts(body_nu, h_da + VGAP, "NU") labels = (_texts(body_da + "".join(extra_da), 0.0, "DA")
+ _texts(body_nu + "".join(extra_nu), h_da + VGAP, "NU"))
for left, right, y, s, tag in labels: for left, right, y, s, tag in labels:
assert left >= -2 and right <= W + 2, f"[{tag}] text iese din panză: {s!r}" assert left >= -2 and right <= W + 2, f"[{tag}] text iese din panză: {s!r}"
assert 0 <= y <= H, f"[{tag}] text în afara înălțimii: {s!r} (y={y:.0f})" assert 0 <= y <= H, f"[{tag}] text în afara înălțimii: {s!r} (y={y:.0f})"

View File

@@ -5,7 +5,7 @@ MARCAJ .md: <!-- DIAGRAMA: fereastra --> (Nivel 1, §1.2 Setup)
CE ARATĂ CE ARATĂ
Două panouri mici, unul sub altul, cu aceeași serie până la doji: Două panouri mici, unul sub altul, cu aceeași serie până la doji:
- Panoul DA: doji high 50.10; bara +1 închide 49.90 (sub high); bara +2 - Panoul DA: doji high 50.10 / low 49.25; bara +1 închide 49.90 (sub high); bara +2
închide 50.40 (peste 50.10) => Buy Doji valid, intrare la close. închide 50.40 (peste 50.10) => Buy Doji valid, intrare la close.
- Panoul NU: doji high 50.10; barele +1, +2, +3 închid 49.95, 50.05, 49.85 - Panoul NU: doji high 50.10; barele +1, +2, +3 închid 49.95, 50.05, 49.85
(toate sub high); a 4-a bară închide 49.15, sub low-ul dojiului => setup (toate sub high); a 4-a bară închide 49.15, sub low-ul dojiului => setup
@@ -15,7 +15,8 @@ numeric. Diferența e strict numerică, nu vizuală
(`13_strategia_3_byh.md:179-180`). (`13_strategia_3_byh.md:179-180`).
NIVELURILE ȘI ETICHETELE (cu trimitere) NIVELURILE ȘI ETICHETELE (cu trimitere)
- high doji = 50.10, low doji = 49.20 (exemplul construit al lecției): - high doji = 50.10, low doji = 49.25 (low-ul e coborât de la 49.20 ca stopul
de 49.20 din pașii 5-6 să iasă SUB low, nu exact pe el):
`13_strategia_3_byh.md:158-167`. `13_strategia_3_byh.md:158-167`.
- fereastra = maximum 3 candele după doji: `13_strategia_3_byh.md:151-156`. - fereastra = maximum 3 candele după doji: `13_strategia_3_byh.md:151-156`.
- „setup expirat, nu intri" la lipsa confirmării: `13_strategia_3_byh.md:168-176`; - „setup expirat, nu intri" la lipsa confirmării: `13_strategia_3_byh.md:168-176`;
@@ -23,23 +24,39 @@ NIVELURILE ȘI ETICHETELE (cu trimitere)
STRUCTURA SERIEI STRUCTURA SERIEI
Panoul DA (8 candele): close-uri [52.20, 51.40, 50.60, 49.65, Panoul DA (8 candele): close-uri [52.20, 51.40, 50.60, 49.65,
49.60 (doji, h 50.10 / l 49.20), 49.60 (doji, h 50.10 / l 49.25),
49.90 (+1), 50.40 (+2, confirmă), 50.80] 49.90 (+1), 50.40 (+2, confirmă), 50.80]
Panoul NU (9 candele): close-uri [52.20, 51.40, 50.60, 49.65, Panoul NU (9 candele): close-uri [52.20, 51.40, 50.60, 49.65,
49.60 (doji, h 50.10 / l 49.20), 49.60 (doji, h 50.10 / l 49.25),
49.95 (+1), 50.05 (+2), 49.85 (+3), 49.15 (a 4-a, sub low)] 49.95 (+1), 50.05 (+2), 49.85 (+3), 49.15 (a 4-a, sub low)]
Mecioni: doji wu=0.45/wd=0.40 ca să dea exact h=50.10, l=49.20; restul Fitile: doji wu=0.45/wd=0.35 ca să dea exact h=50.10, l=49.25; restul
(0.15, 0.15). Serie continuă, open = close-ul precedentului. (0.15, 0.15). Serie continuă, open = close-ul precedentului.
CE VERIFICĂ GENERATORUL CU assert CE VERIFICĂ GENERATORUL CU assert
1. Panoul DA: primul close > 50.10 e bara +2 (index 6 din panou), adică în 1. Panoul DA: primul close > 50.10 e bara +2 (index 6 din panou), adică în
fereastră; close[+1] <= 50.10. fereastră; close[+1] <= 50.10.
2. Panoul NU: niciun close din +1..+3 nu depășește 50.10; close[+4] < 49.20. 2. Panoul NU: niciun close din +1..+3 nu depășește 50.10; close[+4] < 49.25.
3. Ambele doji: abs(o-c) <= 0.10*(h-l). 3. Ambele doji: abs(o-c) <= 0.10*(h-l).
4. Ambele panouri au exact aceeași serie până la doji (aceleași 5 bare). 4. Ambele panouri au exact aceeași serie până la doji (aceleași 5 bare).
5. Distanța în pixeli de la 50.10 la 50.40 (DA) să fie > 0 și vizibil 5. Distanța în pixeli de la 50.10 la 50.40 (DA) să fie > 0 și vizibil
(scara comună pe panou). (scara comună pe panou).
STIL: două `Chart`-uri separate sau un SVG cu două grupuri; gap=40, body_w=13, ADNOTĂRI („ca la proști")
width=460, fără vol_h (nu se vorbește de volum aici). Titluri - ZONĂ albastră peste barele +1..+3 pe ambele panouri, etichetă
„DA — confirmare la +2, în fereastră" / „NU — nicio confirmare în 3 candele". „fereastra: 3 candele".
Fără linie goală în SVG. - Panoul DA: săgeată pe +1 („aici NU intri: s-a închis sub 50.10 / semnalul cere
o ÎNCHIDERE peste"); săgeată din dreapta pe close-ul barei +2 („AICI INTRI, la
close 50.40 / prima închidere peste / high-ul dojiului").
- Panoul NU: săgeată pe +3 („a treia s-a închis tot sub 50.10 / fereastra s-a
terminat: ștergi setup-ul"); săgeată pe a 4-a („a închis sub low-ul dojiului /
setup mort — nu mai intri").
- Liniile 50.10 și 49.25 și etichetele lor se desenează de mână, nu cu `Level`:
eticheta din `Level` stă lipită de linie, la dreapta, și cade peste candele.
Eticheta lui 50.10 e pe trei rânduri, jos-stânga: „high-ul dojiului 50.10 /
trebuie ÎNCHIS peste, / nu doar atins".
STIL: două `Chart`-uri în două grupuri `<g transform>`; scale=60, gap=40,
body_w=13, left=64, width=640, fără vol_h (nu se vorbește de volum aici).
Titluri „DA — confirmare la +2, în fereastră" / „NU — nicio confirmare în 3
candele". Randare cu `ch._render()` (vezi nota din buy_doji_trend.spec.txt).
Fără linie goală în SVG. Generatorul verifică singur că nicio etichetă nu iese
din pânză și că două etichete din același panou nu se suprapun.

View File

@@ -1,60 +1,65 @@
<svg viewBox="0 0 460 614" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 640 750" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<g transform="translate(0,0)"> <g transform="translate(0,0)"><rect x="248.0" y="141.0" width="112.0" height="106.0" fill="#1a5fb4" fill-opacity="0.12" stroke="#1a5fb4" stroke-width="1"/><text x="254.0" y="134.0" fill="#1a5fb4" style="font-weight:bold">fereastra: 3 candele</text><line x1="24" y1="200.0" x2="626" y2="200.0" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/><text x="30" y="215.0" fill="#b06000" text-anchor="start" style="font-weight:bold">high-ul dojiului 50.10</text><text x="30" y="229.0" fill="#b06000" text-anchor="start" style="font-weight:bold">trebuie ÎNCHIS peste,</text><text x="30" y="243.0" fill="#b06000" text-anchor="start" style="font-weight:bold">nu doar atins</text><line x1="24" y1="251.0" x2="626" y2="251.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/><text x="30" y="266.0" fill="#c00" text-anchor="start" style="font-weight:bold">low-ul dojiului 49.25</text>
<text x="24" y="48" fill="#333" style="font-weight:bold">DA — confirmare la +2, în fereastră</text> <text x="24" y="48" fill="#333" style="font-weight:bold">DA — confirmare la +2, în fereastră</text>
<line x1="24" y1="164.0" x2="446" y2="164.0" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="64.0" y1="56.0" x2="64.0" y2="83.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="30" y="158.0" fill="#b06000">high doji 50.10</text> <rect x="57.5" y="65.0" width="13" height="9.0" fill="#c00"/>
<line x1="24" y1="204.5" x2="446" y2="204.5" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="104.0" y1="65.0" x2="104.0" y2="131.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="30" y="198.5" fill="#c00">low doji 49.20</text> <rect x="97.5" y="74.0" width="13" height="48.0" fill="#c00"/>
<line x1="44.0" y1="56.0" x2="44.0" y2="76.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="144.0" y1="113.0" x2="144.0" y2="179.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="37.5" y="62.7" width="13" height="6.7" fill="#c00"/> <rect x="137.5" y="122.0" width="13" height="48.0" fill="#c00"/>
<line x1="84.0" y1="62.7" x2="84.0" y2="112.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="184.0" y1="161.0" x2="184.0" y2="236.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="77.5" y="69.5" width="13" height="36.0" fill="#c00"/> <rect x="177.5" y="170.0" width="13" height="57.0" fill="#c00"/>
<line x1="124.0" y1="98.8" x2="124.0" y2="148.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="224.0" y1="200.0" x2="224.0" y2="251.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="117.5" y="105.5" width="13" height="36.0" fill="#c00"/> <rect x="217.5" y="227.0" width="13" height="3.0" fill="#c00"/>
<line x1="164.0" y1="134.8" x2="164.0" y2="191.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="264.0" y1="203.0" x2="264.0" y2="239.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="157.5" y="141.5" width="13" height="42.8" fill="#c00"/> <rect x="257.5" y="212.0" width="13" height="18.0" fill="#188a3e"/>
<line x1="204.0" y1="164.0" x2="204.0" y2="204.5" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="304.0" y1="173.0" x2="304.0" y2="221.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="197.5" y="184.3" width="13" height="2.2" fill="#c00"/> <rect x="297.5" y="182.0" width="13" height="30.0" fill="#188a3e"/>
<line x1="244.0" y1="166.3" x2="244.0" y2="193.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="344.0" y1="149.0" x2="344.0" y2="191.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="237.5" y="173.0" width="13" height="13.5" fill="#188a3e"/> <rect x="337.5" y="158.0" width="13" height="24.0" fill="#188a3e"/>
<line x1="284.0" y1="143.8" x2="284.0" y2="179.8" stroke="#1a1a1a" stroke-width="1.2"/> <text x="224.0" y="190.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<rect x="277.5" y="150.5" width="13" height="22.5" fill="#188a3e"/> <line x1="264.0" y1="269.0" x2="264.0" y2="251.0" stroke="#c00" stroke-width="1.8"/>
<line x1="324.0" y1="125.8" x2="324.0" y2="157.2" stroke="#1a1a1a" stroke-width="1.2"/> <polygon points="264.0,243.0 268.0,251.0 260.0,251.0" fill="#c00"/>
<rect x="317.5" y="132.5" width="13" height="18.0" fill="#188a3e"/> <text x="264.0" y="283.0" fill="#c00" text-anchor="middle" style="font-weight:bold">aici NU intri: s-a închis sub 50.10</text>
<text x="204.0" y="154.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text> <text x="264.0" y="297.0" fill="#c00" text-anchor="middle" style="font-weight:bold">semnalul cere o ÎNCHIDERE peste</text>
<text x="284.0" y="133.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare +2 — intrare 50.40</text> <line x1="364.5" y1="228.0" x2="320.4" y2="187.4" stroke="#188a3e" stroke-width="1.8"/>
<text x="24" y="226.5" fill="#188a3e">+1: close 49.90 — sub 50.10, nu confirmă</text> <polygon points="314.5,182.0 323.1,184.5 317.7,190.4" fill="#188a3e"/>
<text x="24" y="243.5" fill="#188a3e">+2: close 50.40 — peste 50.10, confirmă (intrare la close)</text> <text x="368.5" y="218.0" fill="#188a3e" text-anchor="start" style="font-weight:bold">AICI INTRI, la close 50.40</text>
<text x="368.5" y="232.0" fill="#188a3e" text-anchor="start" style="font-weight:bold">prima închidere peste</text>
<text x="368.5" y="246.0" fill="#188a3e" text-anchor="start" style="font-weight:bold">high-ul dojiului</text>
</g> </g>
<g transform="translate(0,298)"> <g transform="translate(0,332)"><rect x="248.0" y="186.0" width="112.0" height="61.0" fill="#1a5fb4" fill-opacity="0.12" stroke="#1a5fb4" stroke-width="1"/><text x="254.0" y="179.0" fill="#1a5fb4" style="font-weight:bold">fereastra: 3 candele</text><line x1="24" y1="200.0" x2="626" y2="200.0" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/><text x="30" y="215.0" fill="#b06000" text-anchor="start" style="font-weight:bold">high-ul dojiului 50.10</text><text x="30" y="229.0" fill="#b06000" text-anchor="start" style="font-weight:bold">trebuie ÎNCHIS peste,</text><text x="30" y="243.0" fill="#b06000" text-anchor="start" style="font-weight:bold">nu doar atins</text><line x1="24" y1="251.0" x2="626" y2="251.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/><text x="30" y="266.0" fill="#c00" text-anchor="start" style="font-weight:bold">low-ul dojiului 49.25</text>
<text x="24" y="48" fill="#333" style="font-weight:bold">NU — nicio confirmare în 3 candele</text> <text x="24" y="48" fill="#333" style="font-weight:bold">NU — nicio confirmare în 3 candele</text>
<line x1="24" y1="164.0" x2="446" y2="164.0" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="64.0" y1="56.0" x2="64.0" y2="83.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="30" y="158.0" fill="#b06000">high doji 50.10</text> <rect x="57.5" y="65.0" width="13" height="9.0" fill="#c00"/>
<line x1="24" y1="204.5" x2="446" y2="204.5" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="104.0" y1="65.0" x2="104.0" y2="131.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="30" y="198.5" fill="#c00">low doji 49.20</text> <rect x="97.5" y="74.0" width="13" height="48.0" fill="#c00"/>
<line x1="44.0" y1="56.0" x2="44.0" y2="76.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="144.0" y1="113.0" x2="144.0" y2="179.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="37.5" y="62.7" width="13" height="6.7" fill="#c00"/> <rect x="137.5" y="122.0" width="13" height="48.0" fill="#c00"/>
<line x1="84.0" y1="62.7" x2="84.0" y2="112.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="184.0" y1="161.0" x2="184.0" y2="236.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="77.5" y="69.5" width="13" height="36.0" fill="#c00"/> <rect x="177.5" y="170.0" width="13" height="57.0" fill="#c00"/>
<line x1="124.0" y1="98.8" x2="124.0" y2="148.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="224.0" y1="200.0" x2="224.0" y2="251.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="117.5" y="105.5" width="13" height="36.0" fill="#c00"/> <rect x="217.5" y="227.0" width="13" height="3.0" fill="#c00"/>
<line x1="164.0" y1="134.8" x2="164.0" y2="191.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="264.0" y1="200.0" x2="264.0" y2="239.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="157.5" y="141.5" width="13" height="42.8" fill="#c00"/> <rect x="257.5" y="209.0" width="13" height="21.0" fill="#188a3e"/>
<line x1="204.0" y1="164.0" x2="204.0" y2="204.5" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="304.0" y1="194.0" x2="304.0" y2="218.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="197.5" y="184.3" width="13" height="2.2" fill="#c00"/> <rect x="297.5" y="203.0" width="13" height="6.0" fill="#188a3e"/>
<line x1="244.0" y1="164.0" x2="244.0" y2="193.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="344.0" y1="194.0" x2="344.0" y2="224.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="237.5" y="170.7" width="13" height="15.8" fill="#188a3e"/> <rect x="337.5" y="203.0" width="13" height="12.0" fill="#c00"/>
<line x1="284.0" y1="159.5" x2="284.0" y2="177.5" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="384.0" y1="206.0" x2="384.0" y2="266.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="277.5" y="166.3" width="13" height="4.5" fill="#188a3e"/> <rect x="377.5" y="215.0" width="13" height="42.0" fill="#c00"/>
<line x1="324.0" y1="159.5" x2="324.0" y2="182.0" stroke="#1a1a1a" stroke-width="1.2"/> <text x="224.0" y="190.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<rect x="317.5" y="166.3" width="13" height="9.0" fill="#c00"/> <text x="384.0" y="196.0" fill="#c00" text-anchor="middle" style="font-weight:bold">a 4-a</text>
<line x1="364.0" y1="168.5" x2="364.0" y2="213.5" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="479.0" y1="164.0" x2="351.9" y2="188.5" stroke="#c00" stroke-width="1.8"/>
<rect x="357.5" y="175.2" width="13" height="31.5" fill="#c00"/> <polygon points="344.0,190.0 351.1,184.6 352.6,192.4" fill="#c00"/>
<text x="204.0" y="154.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text> <text x="479.0" y="145.0" fill="#c00" text-anchor="middle" style="font-weight:bold">a treia s-a închis tot sub 50.10</text>
<text x="364.0" y="158.5" fill="#c00" text-anchor="middle" style="font-weight:bold">a 4-a</text> <text x="479.0" y="159.0" fill="#c00" text-anchor="middle" style="font-weight:bold">fereastra s-a terminat: ștergi setup-ul</text>
<text x="24" y="235.5" fill="#188a3e">+1: 49.95; +2: 50.05; +3: 49.85 — toate sub 50.10</text> <line x1="384.0" y1="296.0" x2="384.0" y2="278.0" stroke="#c00" stroke-width="1.8"/>
<text x="24" y="252.5" fill="#c00">a 4-a: close 49.15 — sub low-ul dojiului 49.20, setup mort</text> <polygon points="384.0,270.0 388.0,278.0 380.0,278.0" fill="#c00"/>
<text x="384.0" y="310.0" fill="#c00" text-anchor="middle" style="font-weight:bold">a închis sub low-ul dojiului</text>
<text x="384.0" y="324.0" fill="#c00" text-anchor="middle" style="font-weight:bold">setup mort — nu mai intri</text>
<text x="24" y="355.0" fill="#c00">+1: 49.95 · +2: 50.05 · +3: 49.85 — toate sub 50.10</text>
</g> </g>
<text x="24" y="592" fill="#555">Serii construite: open = close-ul barei anterioare.</text> <text x="24" y="728" fill="#555">Serii construite: open = close-ul barei anterioare.</text>
<text x="24" y="609" fill="#555">Doji: h 50.10 / l 49.20. Fereastra = maximum 3 candele după doji.</text> <text x="24" y="745" fill="#555">Doji: h 50.10 / l 49.25. Fereastra = maximum 3 candele după doji.</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -1,222 +1,150 @@
#!/usr/bin/env python3 """Buy Doji — ieșirea: prima treime la țintă, a doua pe trailing stop, limita de 8 candele.
"""Buy Doji — ieșirea: trailing stop pe gap-uri și limita de 8 candele.
Citește `gen/strategii/buy_doji_iesire.spec.txt` și scrie Citește `gen/strategii/buy_doji_iesire.spec.txt`. Barele vin din
`gen/strategii/buy_doji_iesire.svg`: două panouri stivuite. `buy_doji_ansamblu.serie()` — același trade ca în restul capitolului
(doji 50.10/49.25, intrare 50.40, stop 49.20, ținta 1 51.60).
A — seria din buy_doji_transe (barele 0-18) continuată cu 19-23. Barele 19 A — prima treime iese la ținta 51.60; apoi două candele cu gap urcă linia
și 21 deschid cu GAP (excepție cerută de spec): regula de trail cere o de trailing stop (51.95, apoi 52.60); a doua treime iese la prima
bară cu low peste high-ul precedentei, imposibil dacă open = close închidere sub linie, 52.30 (+1.58R).
anterior. De aceea barele 15-23 sunt construite explicit, nu cu B — același setup, dar prețul stă 8 candele între stop și țintă: ieși la
`from_closes`. close-ul celei de-a 8-a, 50.70 (+0.25R).
B — doji 50.10 / 49.20, intrare 50.40, apoi 8 candele fără TP și fără SL.
Barele de după intrare, în ambele panouri, sunt CONSTRUITE. Barele de după intrare din panoul B sunt CONSTRUITE.
Sursa regulilor: summaries/03_MODUL_2/13_strategia_3_byh.md:196-213.
Rulare: python3 gen/strategii/buy_doji_iesire.py
""" """
import re import re
import sys import sys
from pathlib import Path from pathlib import Path
sys.path.insert(0, "/workspace/atm-curs-dl") sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Candle, Chart, Level, Mark, from_closes # noqa: E402 sys.path.insert(0, str(Path(__file__).parent))
from svg_candles import Chart, Level, Zone, Arrow, from_closes # noqa: E402
from buy_doji_ansamblu import serie, CONF, ENTRY, SL, TP1, R, trail # noqa: E402
OUT = Path(__file__).with_suffix(".svg") OUT = Path(__file__).with_suffix(".svg")
W = 660 S = 10 # prima bară arătată
VGAP = 10
GREEN, RED, ORANGE, BLUE, GREY = "#188a3e", "#c00", "#b06000", "#1a5fb4", "#555" GREEN, RED, ORANGE, BLUE, GREY = "#188a3e", "#c00", "#b06000", "#1a5fb4", "#555"
W, VGAP = 760, 14
# --- PANOUL A ---------------------------------------------------------------- full = serie()
ENTRY_A, SL_A, TP1_A = 53.70, 51.55, 55.85 steps, iesire = trail(full) # [(21, 51.95), (27, 52.60)], 28
R_A = round(ENTRY_A - SL_A, 2) # 2.15 a = full[S:iesire + 1]
cf = CONF - S
EXIT_A = a[iesire - S].c
R_A = round((EXIT_A - ENTRY) / R, 2)
tp_i = next(i for i in range(CONF + 1, len(full)) if full[i].h >= TP1)
a = from_closes([60.40, 59.60, 59.90, 58.80, 58.10, 58.40, 57.20, 56.30, # --- aserțiunile panoului A -------------------------------------------------------
56.60, 55.30, 54.20, 52.40], wick=0.15, start=61.00) assert steps == [(21, 51.95), (27, 52.60)] and iesire == 28, (steps, iesire)
a += [Candle(*ohlc) for ohlc in [ for i, t in steps: # gap-urile sunt reale
(52.40, 53.00, 51.60, 52.30), # 12 doji assert full[i].l > full[i - 1].h, f"bara {i} nu deschide cu gap"
(52.30, 52.85, 52.10, 52.60), # 13 +1 assert all(full[i].c >= steps[0][1] for i in range(steps[0][0], iesire)), \
(52.60, 53.85, 52.45, 53.70), # 14 confirmare = intrare "ar fi ieșit mai devreme: un close sub linia de trail"
(53.70, 53.80, 53.10, 53.45), # 15 assert EXIT_A == 52.30 and R_A == 1.58 and EXIT_A < steps[-1][1]
(53.45, 54.20, 53.35, 54.10), # 16 assert tp_i == 19 and full[tp_i].h >= TP1 > full[tp_i - 1].h, tp_i
(54.10, 54.85, 54.00, 54.70), # 17
(54.70, 56.00, 54.60, 55.90), # 18 atinge TP1
(56.30, 56.95, 56.20, 56.80), # 19 GAP
(56.80, 57.35, 56.60, 57.20), # 20
(57.60, 58.10, 57.45, 57.90), # 21 GAP
(57.90, 58.00, 57.50, 57.60), # 22
(57.60, 57.70, 57.10, 57.20), # 23 close sub trail
]]
assert len(a) == 24
for c in a: # --- panoul B: 8 candele între stop și țintă --------------------------------------
assert c.l <= min(c.o, c.c) and c.h >= max(c.o, c.c), "h/l nu cuprind o/c" b = full[S:CONF + 1]
# A1. gap-urile reale b += from_closes([50.60, 50.30, 50.90, 50.50, 51.10, 50.80, 51.20, 50.70],
assert a[19].l > a[18].h and a[21].l > a[20].h, "barele de gap nu au low > high anterior" wick=0.15, start=ENTRY)
# A2. open = close anterior, în afară de 19 și 21 (și 0-14, ca în transe) opt = b[cf + 1:]
for i in range(1, 24): EXIT_B = opt[-1].c
if i not in (19, 21): R_B = round((EXIT_B - ENTRY) / R, 2)
assert abs(a[i].o - a[i - 1].c) < 1e-9, f"A: open[{i}] != close[{i-1}]" assert len(opt) == 8, len(opt)
# regula de trail, calculată pe serie: primul gap după intrare stabilește for i in range(1, len(b)):
# trail-ul, fiecare gap următor îl urcă; ieși la primul close sub el assert abs(b[i].o - b[i - 1].c) < 1e-9, f"B: open[{i}] != close[{i-1}]"
trail, steps, exit_i = None, [], None assert all(c.h < TP1 and c.l > SL for c in opt), "B: o bară atinge ținta sau stopul"
for i in range(15, 24): assert (round(max(c.h for c in opt), 2), round(min(c.l for c in opt), 2)) == (51.35, 50.15)
if trail is not None and a[i].c < trail: assert EXIT_B == 50.70 and R_B == 0.25
exit_i = i print(f"iesire A: treapta 1 {steps[0][1]:.2f}, treapta 2 {steps[1][1]:.2f}, "
break f"ieșire {EXIT_A:.2f} = +{R_A}R (ținta 1 {TP1:.2f} la bara {tp_i}); "
if a[i].l > a[i - 1].h: f"B: ieșire {EXIT_B:.2f} = +{R_B}R")
trail = a[i].l
steps.append((i, trail)) common: dict = dict(scale=40.0, gap=18, body_w=9, left=48, width=W)
assert [(i, round(t, 2)) for i, t in steps] == [(19, 56.20), (21, 57.45)], steps
# A3.
assert a[22].c >= 57.45 and a[23].c < 57.45 and exit_i == 23, exit_i
EXIT_A = a[23].c
# A4.
assert R_A == 2.15 and round((EXIT_A - ENTRY_A) / R_A, 2) == 1.63
# A5. TP1 = 1R, atins prima oară la bara 18
assert round(ENTRY_A + R_A, 2) == TP1_A
assert next(i for i in range(15, 24) if a[i].h >= TP1_A) == 18
assert abs(a[14].c - ENTRY_A) < 1e-9
ch_a = Chart( ch_a = Chart(
candles=a, candles=a,
levels=[Level(ENTRY_A, "intrare 53.70", GREEN), levels=[Level(TP1, "ținta 1: 51.60 (= 1R)", GREEN, "2 3"),
Level(TP1_A, "TP1 55.85 — tranșa 1: +1R", GREEN, dash="2 3")], Level(ENTRY, "intrarea: 50.40", GREY, "4 3"),
scale=40, gap=16, body_w=9, left=44, width=W, Level(SL, "stopul: 49.20", RED, "4 3")],
title="A — trailing stop pe gap-uri (seria de la intrarea în tranșe)", zones=[Zone(cf, tp_i - S, "", GREEN), Zone(tp_i - S + 1, iesire - S, "", BLUE)],
caption="a treia treime: o lași mai departe (break-even / trend)", arrows=[
Arrow(tp_i - S, "ținta 1 atinsă: vinzi prima treime\nai luat exact cât riscai (1R)",
where="above", price=TP1, color=GREEN, dx=10, dy=-26),
Arrow(steps[0][0] - S, "gap: low-ul de azi e peste high-ul de ieri\nlinia de trail urcă la 51.95",
where="below", price=steps[0][1], color=ORANGE, dx=130, dy=40),
Arrow(steps[1][0] - S, "încă un gap: linia urcă la 52.60\nurcă doar, nu coboară niciodată",
where="above", price=steps[1][1], color=ORANGE, dx=150),
Arrow(iesire - S, "prima închidere sub linie: ieși\ncu a doua treime, la 52.30 (+1.58R)",
where="below", price=EXIT_A, color=RED, dx=110, dy=96),
],
title="A — prima treime la țintă, a doua pe trailing stop",
**common,
) )
# --- PANOUL B ----------------------------------------------------------------
ENTRY_B, SL_B, TP1_B = 50.40, 49.20, 51.60
R_B = round(ENTRY_B - SL_B, 2) # 1.20
b = from_closes([52.20, 51.40, 50.60, 49.65], wick=0.15, start=53.00)
b += [Candle(*ohlc) for ohlc in [
(49.65, 50.10, 49.20, 49.60), # 4 doji
(49.60, 50.05, 49.45, 49.90), # 5 +1
(49.90, 50.55, 49.75, 50.40), # 6 confirmare = intrare
]]
b += from_closes([50.60, 50.30, 50.90, 50.50, 51.10, 50.80, 51.20, 50.70],
wick=0.15, start=b[-1].c)
assert len(b) == 15
# B1.
for i in range(1, 15):
assert abs(b[i].o - b[i - 1].c) < 1e-9, f"B: open[{i}] != close[{i-1}]"
d = b[4]
assert abs(d.o - d.c) <= 0.10 * (d.h - d.l) and (d.h, d.l) == (50.10, 49.20)
assert b[6].c > d.h and abs(b[6].c - ENTRY_B) < 1e-9
# B2. 8 candele fără TP și fără SL
after = b[7:15]
assert all(c.h < TP1_B and c.l > SL_B for c in after)
assert round(max(c.h for c in after), 2) == 51.35 and round(min(c.l for c in after), 2) == 50.15
assert round(ENTRY_B + R_B, 2) == TP1_B
# B3.
EXIT_B = b[14].c
assert round((EXIT_B - ENTRY_B) / R_B, 2) == 0.25
for k, c in enumerate(after, 1):
c.tag = str(k)
ch_b = Chart( ch_b = Chart(
candles=b, candles=b,
levels=[Level(TP1_B, "TP1 51.60", GREEN, dash="2 3"), levels=[Level(TP1, "ținta 1: 51.60 — neatinsă", GREEN, "2 3"),
Level(ENTRY_B, "intrare 50.40", GREEN), Level(ENTRY, "intrarea: 50.40", GREY, "4 3"),
Level(SL_B, "SL 49.20", RED)], Level(SL, "stopul: 49.20 — neatins", RED, "4 3")],
marks=[Mark(4, "doji", ORANGE, "below")], zones=[Zone(cf + 1, len(b) - 1, "", GREY, p_top=TP1, p_bot=SL)],
scale=48, gap=16, body_w=9, left=44, width=W, arrows=[
title="B — limita de 8 candele", Arrow(len(b) - 1, "a 8-a candelă: ieși oricum, la close 50.70 (+0.25R)\nbanii blocați aici lipsesc din alt trade",
where="below", price=EXIT_B, color=GREY, dx=120, dy=40),
],
title="B — limita de 8 candele: nici ținta, nici stopul",
**common,
) )
for k, c in enumerate(opt, 1):
c.tag = str(k)
# --- etichete plasate de mână: Mark centrează textul, iar aici textele lungi def panou(ch, sus_de=0.0):
# ar cădea peste candelele vecine. Le ancorez lângă bară, pe partea liberă. ch.top += sus_de
def label(ch, i, price, text, color, anchor="start", dx=0): svg = ch.render()
x = ch._cx(i) + dx h = float(re.search(r'viewBox="0 0 [\d.]+ ([\d.]+)"', svg).group(1))
return (f'<text x="{x:.1f}" y="{ch._y(price):.1f}" fill="{color}" ' # render() mută `top`/`left` intern și le restaurează: tot ce desenăm noi
f'text-anchor="{anchor}" style="font-weight:bold">{text}</text>') # după randare trebuie deplasat cu aceiași pixeli
off_y = float(re.search(r'<line x1="24" y1="([\d.]+)"', svg).group(1)) - ch._y(ch.levels[0].price)
off_x = float(re.search(r'<line x1="([\d.]+)"[^>]*stroke="#1a1a1a"', svg).group(1)) - ch._cx(0)
return svg[svg.index(">") + 1:svg.rindex("</svg>")].strip(), h, off_x, off_y
def panel(ch, extra): body_a, h_a, ax, ay = panou(ch_a)
svg = ch.render() # render() fixează scala (_pmax, top) Y, X = (lambda p: ch_a._y(p) + ay), (lambda i: ch_a._cx(i) + ax)
h = float(re.search(r'viewBox="0 0 \d+ ([\d.]+)"', svg).group(1)) (i1, t1), (i2, t2) = [(i - S, t) for i, t in steps]
body = svg[svg.index(">") + 1:svg.rindex("</svg>")].strip() extra_a = [
return body + "".join("\n " + e for e in extra(ch)), h # linia de trail, în trepte
f'<polyline points="{X(i1) - 7:.1f},{Y(t1):.1f} {X(i2) - 7:.1f},{Y(t1):.1f} '
f'{X(i2) - 7:.1f},{Y(t2):.1f} {X(iesire - S) + 7:.1f},{Y(t2):.1f}" '
f'fill="none" stroke="{ORANGE}" stroke-width="2"/>',
f'<text x="{X(iesire - S) + 14:.1f}" y="{Y(t2) + 4:.1f}" fill="{ORANGE}" style="font-weight:bold">'
f'linia de trailing stop</text>',
# etichetele zonelor, lângă ele (Zone le-ar ridica deasupra candelelor vecine)
f'<text x="{X(cf) - 6:.1f}" y="{Y(SL) + 60:.1f}" fill="{GREEN}" style="font-weight:bold">'
f'prima treime: de la intrare la ținta 1:1</text>',
f'<text x="{X(tp_i - S + 1) - 6:.1f}" y="{Y(SL) + 78:.1f}" fill="{BLUE}" style="font-weight:bold">'
f'a doua treime: merge pe trailing stop</text>',
]
extra_a.append(f'<text x="24" y="{Y(SL) + 100:.1f}" fill="{GREY}">A treia treime o lași mai '
f'departe, cu stopul mutat la intrare (break-even).</text>')
h_a = max(h_a, Y(SL) + 112)
body_b, h_b, bx, by = panou(ch_b, h_a + VGAP)
def trail_a(ch): extra_b = [
x19, x21, x23 = ch._cx(19) - 7, ch._cx(21) - 8, ch._cx(23) + 7 f'<text x="{ch_b._cx(cf + 1) + bx - 6:.1f}" y="{ch_b._y(TP1) + by - 8:.1f}" fill="{GREY}" '
y1, y2 = ch._y(steps[0][1]), ch._y(steps[1][1]) f'style="font-weight:bold">8 candele în care nu se întâmplă nimic</text>',
# golul dintre high-ul barei precedente și low-ul barei de gap, hașurat: ]
# la 0.10-0.20 de preț are doar câțiva pixeli și se pierde sub linia de trail H = h_b + 8
gaps = [f'<rect x="{ch._cx(i - 1) - 7:.1f}" y="{ch._y(a[i].l):.1f}" width="{ch.gap + 14}" '
f'height="{ch._y(a[i - 1].h) - ch._y(a[i].l):.1f}" fill="{ORANGE}" opacity="0.35"/>'
for i, _ in steps]
return gaps + [
f'<polyline points="{x19:.1f},{y1:.1f} {x21:.1f},{y1:.1f} {x21:.1f},{y2:.1f} '
f'{x23:.1f},{y2:.1f}" fill="none" stroke="{ORANGE}" stroke-width="2"/>',
label(ch, 18, 56.25, "TP1: ieși cu 1/3", GREEN, "end", 4),
label(ch, 19, 55.35, "gap: low &gt; high anterior → trail 56.20", ORANGE, "start", -4),
label(ch, 21, 58.35, "gap → trail 57.45", ORANGE, "middle"),
label(ch, 23, 57.30, "close sub trail: ieși cu 1/3", RED, "start", 14),
label(ch, 23, 56.88, f"la 57.20 = +{(EXIT_A - ENTRY_A) / R_A:.2f}R", RED, "start", 14),
]
def mark_b(ch):
return [
label(ch, 14, 51.05, "a 8-a candelă: nici TP, nici SL", GREY, "start", 10),
label(ch, 14, 50.75, f"→ ieși la 50.70 = +{(EXIT_B - ENTRY_B) / R_B:.2f}R", GREY, "start", 10),
]
# panourile se stivuiesc prin `top` (nu prin <g transform>): audit_diagrams
# citește coordonatele brute și ar vedea panourile suprapuse.
T = 26
ch_a.top += T
body_a, h_a = panel(ch_a, trail_a)
ch_b.top += h_a + VGAP
body_b, H_B = panel(ch_b, mark_b)
TITLE = "Ieșirea: trailing stop pe gap-uri și limita de 8 candele — exemple construite"
CAP = "Barele de după intrare sunt construite. Regulile: 13_strategia_3_byh.md:196-213."
cap_y = H_B + 12
H = cap_y + 10
svg = "\n ".join([ svg = "\n ".join([
f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/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">', f'style="width:100%;height:auto;font:12px sans-serif">',
f'<text x="24" y="18" fill="#333" style="font-weight:bold">{TITLE}</text>', body_a, *extra_a,
body_a, f'<line x1="24" y1="{h_a + VGAP / 2:.0f}" x2="{W - 14}" y2="{h_a + VGAP / 2:.0f}" stroke="#ddd"/>',
body_b, body_b, *extra_b,
f'<text x="24" y="{cap_y:.0f}" fill="{GREY}">{CAP}</text>',
]) + "\n</svg>" ]) + "\n</svg>"
assert "\n\n" not in svg assert "\n\n" not in svg, "linie goală în SVG"
for tx, ty in re.findall(r'<text x="([-\d.]+)" y="([-\d.]+)"', svg):
# --- etichete în panză și fără suprapuneri (lățimi aproximate) --------------- assert 0 <= float(tx) <= W and 0 <= float(ty) <= H, f"text în afara pânzei la ({tx}, {ty})"
TEXT = re.compile(r'<text x="([-\d.]+)" y="([-\d.]+)"([^>]*)>(.*?)</text>', re.S)
def texts(body, y_off, tag):
for m in TEXT.finditer(body):
x, y, attrs = float(m.group(1)), float(m.group(2)) + y_off, m.group(3)
s = m.group(4).replace("&gt;", ">")
wpx = len(s) * 12 * (0.62 if "bold" in attrs else 0.52)
anchor = re.search(r'text-anchor="(\w+)"', attrs)
anchor = anchor.group(1) if anchor else "start"
x0 = x - wpx if anchor == "end" else (x - wpx / 2 if anchor == "middle" else x)
yield x0, x0 + wpx, y, s, tag
labels = list(texts(body_a, 0, "A")) + list(texts(body_b, 0, "B"))
for x0, x1, y, s, tag in labels:
assert x0 >= -2 and x1 <= W + 2 and 0 <= y <= H, f"[{tag}] text iese din panză: {s!r}"
for i, (l1, r1, y1, s1, t1) in enumerate(labels):
for l2, r2, y2, s2, t2 in labels[i + 1:]:
assert not (t1 == t2 and abs(y1 - y2) < 12 and l1 < r2 - 4 and l2 < r1 - 4), \
f"[{t1}] texte suprapuse: {s1!r} / {s2!r}"
OUT.write_text(svg, encoding="utf-8") OUT.write_text(svg, encoding="utf-8")
print(f"A: trail {steps}, ieșire bara {exit_i} la {EXIT_A:.2f} = "
f"+{(EXIT_A - ENTRY_A) / R_A:.2f}R; B: ieșire la {EXIT_B:.2f} = "
f"+{(EXIT_B - ENTRY_B) / R_B:.2f}R")
print(f"scris {OUT} ({W}x{H:.0f})") print(f"scris {OUT} ({W}x{H:.0f})")

View File

@@ -1,57 +1,51 @@
SPEC DIAGRAMĂ — buy_doji_iesire SPEC DIAGRAMĂ — buy_doji_iesire
=============================== ===============================
tip: PRET, două panouri stivuite tip: PRET, două panouri stivuite
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 9 (ieșirea) destinație: summaries/17_STRATEGII/01_buy_doji.md, pasul cu ieșirea
cheie markdown: <!-- DIAGRAMA: iesire --> cheie markdown: <!-- DIAGRAMA: iesire -->
titlu SVG: „Ieșirea: trailing stop pe gap-uri și limita de 8 candele — exemple construite" titluri SVG: A „prima treime la țintă, a doua pe trailing stop";
stil: candele lipite (gap 15-18, body_w 9-10), fără volum. B „limita de 8 candele: nici ținta, nici stopul"
EXCEPȚIE CERUTĂ: în panoul A, barele 19 și 21 deschid cu GAP serie: `buy_doji_ansamblu.serie()` — A: barele 10-28; B: barele 10-16
(open != close anterior). Regula de trail are nevoie de o bară plus 8 bare construite.
cu low peste high-ul precedentei, ceea ce fără gap e imposibil.
Toate celelalte bare: open = close anterior.
PANOUL A — trailing stop (seria buy_doji_transe, continuată) PANOUL A — ieșirea în trepte
------------------------------------------------------------ ----------------------------
Barele 0-18: identice cu buy_doji_transe. Apoi: Intrare 50.40, stop 49.20, 1R = 1.20.
19 (56.30, 56.95, 56.20, 56.80) GAP: low 56.20 > high[18] 56.00 → trail = 56.20 - ținta 1 51.60 atinsă la bara 19: iese prima treime (+1R);
20 (56.80, 57.35, 56.60, 57.20) - bara 21 deschide cu gap (low 51.95 > high[20] 51.85): linia de trailing stop
21 (57.60, 58.10, 57.45, 57.90) GAP: low 57.45 > high[20] 57.35 → trail urcă la 57.45 se așază la 51.95;
22 (57.90, 58.00, 57.50, 57.60) close 57.60 ≥ 57.45: rămâi - bara 27, alt gap (low 52.60 > high[26] 52.55): linia urcă la 52.60;
23 (57.60, 57.70, 57.10, 57.20) close 57.20 < 57.45: ieși - bara 28 închide la 52.30, sub linie: iese a doua treime, +1.58R;
Niveluri: intrare 53.70; TP1 55.85 („tranșa 1: +1R"); trail în trepte: - a treia treime rămâne mai departe, cu stopul la intrare (break-even).
segment 56.20 de la bara 19 la 20, segment 57.45 de la bara 21 la 23. Adnotări: zonă verde de la intrare la țintă, zonă albastră pe porțiunea de
Marks: Mark(18, "TP1: ieși cu 1/3"), Mark(19, "gap: low > high anterior → trail 56.20"), trail, linia de trail desenată în trepte, patru săgeți (ținta atinsă, primul
Mark(21, "trail 57.45"), Mark(23, "close sub trail: ieși cu 1/3 la 57.20 = +1.63R"). gap, al doilea gap, ieșirea).
Text sub panou: „a treia treime: o lași mai departe (break-even / trend)".
PANOUL B — limita de 8 candele PANOUL B — limita de 8 candele
------------------------------ ------------------------------
open[0] = 53.00; close-uri: 52.20, 51.40, 50.60, 49.65, fitile 0.15; Aceleași bare până la confirmare, apoi 8 bare construite, close-uri 50.60,
4 doji (49.65, 50.10, 49.20, 49.60) 50.30, 50.90, 50.50, 51.10, 50.80, 51.20, 50.70 (fitile 0.15, open = close
5 +1 (49.60, 50.05, 49.45, 49.90) anterior). Niciuna nu atinge ținta 51.60 sau stopul 49.20 (max high 51.35, min
6 confirmare (49.90, 50.55, 49.75, 50.40) intrare 50.40 low 50.15). La close-ul celei de-a 8-a ieși oricum: 50.70 = +0.25R.
7-14 close-uri: 50.60, 50.30, 50.90, 50.50, 51.10, 50.80, 51.20, 50.70 Adnotări: zonă gri între stop și țintă peste cele 8 bare, numerotate 1..8, și o
(fitile 0.15; open = close anterior) săgeată: „banii blocați aici lipsesc din alt trade".
Niveluri: intrare 50.40, SL 49.20, TP1 51.60.
Numerotare 1..8 sub barele 7-14. Mark(14, "a 8-a candelă: nici TP, nici SL → ieși la 50.70 = +0.25R").
ASSERT-URI ASSERT-URI
---------- ----------
A1. low[19] > high[18] și low[21] > high[20] (gap-urile reale). A1. regula de trail, calculată pe serie, dă [(21, 51.95), (27, 52.60)];
A2. open[i] == close[i-1] pentru i în 15..23, cu excepția 19 și 21. barele 21 și 27 au low peste high-ul barei precedente (gap-uri reale).
A3. close[22] >= 57.45 și close[23] < 57.45; primul close sub trail după bara 19 e 23. A2. niciun close între bara 21 și ieșire nu e sub 51.95 (n-ar fi ieșit mai devreme).
A4. round((57.20-53.70)/2.15, 2) == 1.63. A3. ieșirea: close 52.30 la bara 28, sub 52.60; (52.30 - 50.40) / 1.20 == 1.58.
A5. primul i>14 cu high >= 55.85 este 18. A4. ținta 51.60 e atinsă prima dată la bara 19 (bara 18 nu o atinge).
B1. open[i] == close[i-1] peste tot; doji abs(o-c) <= 0.10*(h-l); close[6] > 50.10. B1. open[i] == close[i-1] pe toată seria; exact 8 bare după intrare.
B2. pentru barele 7-14: high < 51.60 și low > 49.20 (max high 51.35, min low 50.15). B2. toate cele 8 au high < 51.60 și low > 49.20; max high 51.35, min low 50.15.
B3. round((50.70-50.40)/1.20, 2) == 0.25. B3. ieșire 50.70; (50.70 - 50.40) / 1.20 == 0.25.
B4. niciun text nu iese din pânză.
SURSA SURSA
----- -----
- Trail: low-ul barei cu low peste high-ul precedentei; ieși la close sub el: - Trail: low-ul barei cu low peste high-ul precedentei; ieși la close sub el:
summaries/03_MODUL_2/13_strategia_3_byh.md:196-200. summaries/03_MODUL_2/13_strategia_3_byh.md:196-200.
- 3 poziții (1/3 TP, 1/3 trail, 1/3 mai departe): :204-213 (tabel marcat de - Trei poziții (1/3 la țintă, 1/3 pe trail, 1/3 mai departe): :204-213.
sumarizator ca completare, :341-350).
- Limita de 8 candele: :201-202. - Limita de 8 candele: :201-202.
- Doji 50.10/49.20, intrare 50.40, SL 49.20: exemplul lecției, :158-167. - Barele de după intrare din panoul B sunt CONSTRUITE.
- Barele după intrare, în ambele panouri, sunt CONSTRUITE.

View File

@@ -1,114 +1,122 @@
<svg viewBox="0 0 660 826" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 760 795" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="18" fill="#333" style="font-weight:bold">Ieșirea: trailing stop pe gap-uri și limita de 8 candele — exemple construite</text> <text x="24" y="48" fill="#333" style="font-weight:bold">A — prima treime la țintă, a doua pe trailing stop</text>
<text x="24" y="74" fill="#333" style="font-weight:bold">A — trailing stop pe gap-uri (seria de la intrarea în tranșe)</text> <rect x="146.5" y="176.0" width="73.0" height="96.0" fill="#188a3e" fill-opacity="0.08" stroke="#188a3e" stroke-width="1"/>
<line x1="24" y1="380.0" x2="646" y2="380.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="218.5" y="122.0" width="163.0" height="84.0" fill="#1a5fb4" fill-opacity="0.08" stroke="#1a5fb4" stroke-width="1"/>
<text x="632" y="374.0" fill="#188a3e" text-anchor="end">intrare 53.70</text> <line x1="24" y1="190.0" x2="746" y2="190.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/>
<line x1="24" y1="294.0" x2="646" y2="294.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/> <text x="732" y="184.0" fill="#188a3e" text-anchor="end">ținta 1: 51.60 (= 1R)</text>
<text x="632" y="288.0" fill="#188a3e" text-anchor="end">TP1 55.85 — tranșa 1: +1R</text> <line x1="24" y1="238.0" x2="746" y2="238.0" stroke="#555" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="44.0" y1="82.0" x2="44.0" y2="118.0" stroke="#1a1a1a" stroke-width="1.2"/> <text x="732" y="232.0" fill="#555" text-anchor="end">intrarea: 50.40</text>
<rect x="39.5" y="88.0" width="9" height="24.0" fill="#c00"/> <line x1="24" y1="286.0" x2="746" y2="286.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="60.0" y1="106.0" x2="60.0" y2="150.0" stroke="#1a1a1a" stroke-width="1.2"/> <text x="732" y="280.0" fill="#c00" text-anchor="end">stopul: 49.20</text>
<rect x="55.5" y="112.0" width="9" height="32.0" fill="#c00"/> <line x1="48.0" y1="56.0" x2="48.0" y2="126.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="76.0" y1="126.0" x2="76.0" y2="150.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="43.5" y="66.0" width="9" height="48.0" fill="#c00"/>
<rect x="71.5" y="132.0" width="9" height="12.0" fill="#188a3e"/> <line x1="66.0" y1="104.0" x2="66.0" y2="174.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="92.0" y1="126.0" x2="92.0" y2="182.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="61.5" y="114.0" width="9" height="48.0" fill="#c00"/>
<rect x="87.5" y="132.0" width="9" height="44.0" fill="#c00"/> <line x1="84.0" y1="152.0" x2="84.0" y2="226.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="108.0" y1="170.0" x2="108.0" y2="210.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="79.5" y="162.0" width="9" height="52.0" fill="#c00"/>
<rect x="103.5" y="176.0" width="9" height="28.0" fill="#c00"/> <line x1="102.0" y1="204.0" x2="102.0" y2="280.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="124.0" y1="186.0" x2="124.0" y2="210.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="97.5" y="214.0" width="9" height="54.0" fill="#c00"/>
<rect x="119.5" y="192.0" width="9" height="12.0" fill="#188a3e"/> <line x1="120.0" y1="250.0" x2="120.0" y2="284.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="140.0" y1="186.0" x2="140.0" y2="246.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="115.5" y="268.0" width="9" height="2.0" fill="#c00"/>
<rect x="135.5" y="192.0" width="9" height="48.0" fill="#c00"/> <line x1="138.0" y1="252.0" x2="138.0" y2="276.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="156.0" y1="234.0" x2="156.0" y2="282.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="133.5" y="258.0" width="9" height="12.0" fill="#188a3e"/>
<rect x="151.5" y="240.0" width="9" height="36.0" fill="#c00"/> <line x1="156.0" y1="232.0" x2="156.0" y2="264.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="172.0" y1="258.0" x2="172.0" y2="282.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="151.5" y="238.0" width="9" height="20.0" fill="#188a3e"/>
<rect x="167.5" y="264.0" width="9" height="12.0" fill="#188a3e"/> <line x1="174.0" y1="208.0" x2="174.0" y2="250.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="188.0" y1="258.0" x2="188.0" y2="322.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="169.5" y="218.0" width="9" height="20.0" fill="#188a3e"/>
<rect x="183.5" y="264.0" width="9" height="52.0" fill="#c00"/> <line x1="192.0" y1="196.0" x2="192.0" y2="230.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="204.0" y1="310.0" x2="204.0" y2="366.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="187.5" y="206.0" width="9" height="12.0" fill="#188a3e"/>
<rect x="199.5" y="316.0" width="9" height="44.0" fill="#c00"/> <line x1="210.0" y1="184.0" x2="210.0" y2="218.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="220.0" y1="354.0" x2="220.0" y2="438.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="205.5" y="194.0" width="9" height="12.0" fill="#188a3e"/>
<rect x="215.5" y="360.0" width="9" height="72.0" fill="#c00"/> <line x1="228.0" y1="180.0" x2="228.0" y2="198.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="236.0" y1="408.0" x2="236.0" y2="464.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="223.5" y="184.0" width="9" height="10.0" fill="#188a3e"/>
<rect x="231.5" y="432.0" width="9" height="4.0" fill="#c00"/> <line x1="246.0" y1="162.0" x2="246.0" y2="176.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="252.0" y1="414.0" x2="252.0" y2="444.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="241.5" y="166.0" width="9" height="8.0" fill="#188a3e"/>
<rect x="247.5" y="424.0" width="9" height="12.0" fill="#188a3e"/> <line x1="264.0" y1="156.0" x2="264.0" y2="172.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="268.0" y1="374.0" x2="268.0" y2="430.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="259.5" y="160.0" width="9" height="6.0" fill="#188a3e"/>
<rect x="263.5" y="380.0" width="9" height="44.0" fill="#188a3e"/> <line x1="282.0" y1="158.0" x2="282.0" y2="174.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="284.0" y1="376.0" x2="284.0" y2="404.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="277.5" y="160.0" width="9" height="10.0" fill="#c00"/>
<rect x="279.5" y="380.0" width="9" height="10.0" fill="#c00"/> <line x1="300.0" y1="154.0" x2="300.0" y2="172.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="300.0" y1="360.0" x2="300.0" y2="394.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="295.5" y="158.0" width="9" height="12.0" fill="#188a3e"/>
<rect x="295.5" y="364.0" width="9" height="26.0" fill="#188a3e"/> <line x1="318.0" y1="152.0" x2="318.0" y2="164.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="316.0" y1="334.0" x2="316.0" y2="368.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="313.5" y="154.0" width="9" height="4.0" fill="#188a3e"/>
<rect x="311.5" y="340.0" width="9" height="24.0" fill="#188a3e"/> <line x1="336.0" y1="152.0" x2="336.0" y2="160.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="332.0" y1="288.0" x2="332.0" y2="344.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="331.5" y="154.0" width="9" height="2.0" fill="#c00"/>
<rect x="327.5" y="292.0" width="9" height="48.0" fill="#188a3e"/> <line x1="354.0" y1="130.0" x2="354.0" y2="150.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="348.0" y1="250.0" x2="348.0" y2="280.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="349.5" y="136.0" width="9" height="10.0" fill="#188a3e"/>
<rect x="343.5" y="256.0" width="9" height="20.0" fill="#188a3e"/> <line x1="372.0" y1="134.0" x2="372.0" y2="166.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="364.0" y1="234.0" x2="364.0" y2="264.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="367.5" y="136.0" width="9" height="26.0" fill="#c00"/>
<rect x="359.5" y="240.0" width="9" height="16.0" fill="#188a3e"/> <line x1="220.0" y1="118.0" x2="211.2" y2="178.1" stroke="#188a3e" stroke-width="1.8"/>
<line x1="380.0" y1="204.0" x2="380.0" y2="230.0" stroke="#1a1a1a" stroke-width="1.2"/> <polygon points="210.0,186.0 207.2,177.5 215.1,178.7" fill="#188a3e"/>
<rect x="375.5" y="212.0" width="9" height="12.0" fill="#188a3e"/> <text x="220.0" y="99.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">ținta 1 atinsă: vinzi prima treime</text>
<line x1="396.0" y1="208.0" x2="396.0" y2="228.0" stroke="#1a1a1a" stroke-width="1.2"/> <text x="220.0" y="113.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">ai luat exact cât riscai (1R)</text>
<rect x="391.5" y="212.0" width="9" height="12.0" fill="#c00"/> <line x1="376.0" y1="246.0" x2="253.1" y2="183.6" stroke="#b06000" stroke-width="1.8"/>
<line x1="412.0" y1="220.0" x2="412.0" y2="244.0" stroke="#1a1a1a" stroke-width="1.2"/> <polygon points="246.0,180.0 254.9,180.1 251.3,187.2" fill="#b06000"/>
<rect x="407.5" y="224.0" width="9" height="16.0" fill="#c00"/> <text x="376.0" y="260.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">gap: low-ul de azi e peste high-ul de ieri</text>
<text x="24" y="494" fill="#555">a treia treime: o lași mai departe (break-even / trend)</text> <text x="376.0" y="274.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">linia de trail urcă la 51.95</text>
<rect x="325.0" y="280.0" width="30" height="8.0" fill="#b06000" opacity="0.35"/> <line x1="504.0" y1="120.0" x2="361.9" y2="144.6" stroke="#b06000" stroke-width="1.8"/>
<rect x="357.0" y="230.0" width="30" height="4.0" fill="#b06000" opacity="0.35"/> <polygon points="354.0,146.0 361.2,140.7 362.6,148.6" fill="#b06000"/>
<polyline points="341.0,280.0 372.0,280.0 372.0,230.0 419.0,230.0" fill="none" stroke="#b06000" stroke-width="2"/> <text x="504.0" y="101.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">încă un gap: linia urcă la 52.60</text>
<text x="336.0" y="278.0" fill="#188a3e" text-anchor="end" style="font-weight:bold">TP1: ieși cu 1/3</text> <text x="504.0" y="115.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">urcă doar, nu coboară niciodată</text>
<text x="344.0" y="314.0" fill="#b06000" text-anchor="start" style="font-weight:bold">gap: low &gt; high anterior → trail 56.20</text> <line x1="482.0" y1="288.0" x2="377.4" y2="171.9" stroke="#c00" stroke-width="1.8"/>
<text x="380.0" y="194.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">gap → trail 57.45</text> <polygon points="372.0,166.0 380.3,169.3 374.4,174.6" fill="#c00"/>
<text x="426.0" y="236.0" fill="#c00" text-anchor="start" style="font-weight:bold">close sub trail: ieși cu 1/3</text> <text x="482.0" y="302.0" fill="#c00" text-anchor="middle" style="font-weight:bold">prima închidere sub linie: ieși</text>
<text x="426.0" y="252.8" fill="#c00" text-anchor="start" style="font-weight:bold">la 57.20 = +1.63R</text> <text x="482.0" y="316.0" fill="#c00" text-anchor="middle" style="font-weight:bold">cu a doua treime, la 52.30 (+1.58R)</text>
<text x="24" y="564" fill="#333" style="font-weight:bold">B — limita de 8 candele</text> <polyline points="239.0,176.0 347.0,176.0 347.0,150.0 379.0,150.0" fill="none" stroke="#b06000" stroke-width="2"/>
<line x1="24" y1="646.4" x2="646" y2="646.4" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/> <text x="386.0" y="154.0" fill="#b06000" style="font-weight:bold">linia de trailing stop</text>
<text x="632" y="640.4" fill="#188a3e" text-anchor="end">TP1 51.60</text> <text x="150.0" y="346.0" fill="#188a3e" style="font-weight:bold">prima treime: de la intrare la ținta 1:1</text>
<line x1="24" y1="704.0" x2="646" y2="704.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/> <text x="222.0" y="364.0" fill="#1a5fb4" style="font-weight:bold">a doua treime: merge pe trailing stop</text>
<text x="632" y="698.0" fill="#188a3e" text-anchor="end">intrare 50.40</text> <text x="24" y="386.0" fill="#555">A treia treime o lași mai departe, cu stopul mutat la intrare (break-even).</text>
<line x1="24" y1="761.6" x2="646" y2="761.6" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="24" y1="405" x2="746" y2="405" stroke="#ddd"/>
<text x="632" y="755.6" fill="#c00" text-anchor="end">SL 49.20</text> <text x="24" y="460" fill="#333" style="font-weight:bold">B — limita de 8 candele: nici ținta, nici stopul</text>
<line x1="44.0" y1="572.0" x2="44.0" y2="624.8" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="164.5" y="602.0" width="145.0" height="96.0" fill="#555" fill-opacity="0.08" stroke="#555" stroke-width="1"/>
<rect x="39.5" y="579.2" width="9" height="38.4" fill="#c00"/> <line x1="24" y1="602.0" x2="746" y2="602.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/>
<line x1="60.0" y1="610.4" x2="60.0" y2="663.2" stroke="#1a1a1a" stroke-width="1.2"/> <text x="732" y="596.0" fill="#188a3e" text-anchor="end">ținta 1: 51.60 — neatinsă</text>
<rect x="55.5" y="617.6" width="9" height="38.4" fill="#c00"/> <line x1="24" y1="650.0" x2="746" y2="650.0" stroke="#555" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="76.0" y1="648.8" x2="76.0" y2="701.6" stroke="#1a1a1a" stroke-width="1.2"/> <text x="732" y="644.0" fill="#555" text-anchor="end">intrarea: 50.40</text>
<rect x="71.5" y="656.0" width="9" height="38.4" fill="#c00"/> <line x1="24" y1="698.0" x2="746" y2="698.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="92.0" y1="687.2" x2="92.0" y2="747.2" stroke="#1a1a1a" stroke-width="1.2"/> <text x="732" y="692.0" fill="#c00" text-anchor="end">stopul: 49.20 — neatins</text>
<rect x="87.5" y="694.4" width="9" height="45.6" fill="#c00"/> <line x1="48.0" y1="468.0" x2="48.0" y2="538.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="108.0" y1="718.4" x2="108.0" y2="761.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="43.5" y="478.0" width="9" height="48.0" fill="#c00"/>
<rect x="103.5" y="740.0" width="9" height="2.4" fill="#c00"/> <line x1="66.0" y1="516.0" x2="66.0" y2="586.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="124.0" y1="720.8" x2="124.0" y2="749.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="61.5" y="526.0" width="9" height="48.0" fill="#c00"/>
<rect x="119.5" y="728.0" width="9" height="14.4" fill="#188a3e"/> <line x1="84.0" y1="564.0" x2="84.0" y2="638.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="140.0" y1="696.8" x2="140.0" y2="735.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="79.5" y="574.0" width="9" height="52.0" fill="#c00"/>
<rect x="135.5" y="704.0" width="9" height="24.0" fill="#188a3e"/> <line x1="102.0" y1="616.0" x2="102.0" y2="692.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="156.0" y1="687.2" x2="156.0" y2="711.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="97.5" y="626.0" width="9" height="54.0" fill="#c00"/>
<rect x="151.5" y="694.4" width="9" height="9.6" fill="#188a3e"/> <line x1="120.0" y1="662.0" x2="120.0" y2="696.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="156.0" y="779.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">1</text> <rect x="115.5" y="680.0" width="9" height="2.0" fill="#c00"/>
<line x1="172.0" y1="687.2" x2="172.0" y2="716.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="138.0" y1="664.0" x2="138.0" y2="688.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="167.5" y="694.4" width="9" height="14.4" fill="#c00"/> <rect x="133.5" y="670.0" width="9" height="12.0" fill="#188a3e"/>
<text x="172.0" y="779.6" fill="#c00" text-anchor="middle" style="font-weight:bold">2</text> <line x1="156.0" y1="644.0" x2="156.0" y2="676.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="188.0" y1="672.8" x2="188.0" y2="716.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="151.5" y="650.0" width="9" height="20.0" fill="#188a3e"/>
<rect x="183.5" y="680.0" width="9" height="28.8" fill="#188a3e"/> <line x1="174.0" y1="636.0" x2="174.0" y2="656.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="188.0" y="779.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">3</text> <rect x="169.5" y="642.0" width="9" height="8.0" fill="#188a3e"/>
<line x1="204.0" y1="672.8" x2="204.0" y2="706.4" stroke="#1a1a1a" stroke-width="1.2"/> <text x="174.0" y="763.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">1</text>
<rect x="199.5" y="680.0" width="9" height="19.2" fill="#c00"/> <line x1="192.0" y1="636.0" x2="192.0" y2="660.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="204.0" y="779.6" fill="#c00" text-anchor="middle" style="font-weight:bold">4</text> <rect x="187.5" y="642.0" width="9" height="12.0" fill="#c00"/>
<line x1="220.0" y1="663.2" x2="220.0" y2="706.4" stroke="#1a1a1a" stroke-width="1.2"/> <text x="192.0" y="763.0" fill="#c00" text-anchor="middle" style="font-weight:bold">2</text>
<rect x="215.5" y="670.4" width="9" height="28.8" fill="#188a3e"/> <line x1="210.0" y1="624.0" x2="210.0" y2="660.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="220.0" y="779.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">5</text> <rect x="205.5" y="630.0" width="9" height="24.0" fill="#188a3e"/>
<line x1="236.0" y1="663.2" x2="236.0" y2="692.0" stroke="#1a1a1a" stroke-width="1.2"/> <text x="210.0" y="763.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">3</text>
<rect x="231.5" y="670.4" width="9" height="14.4" fill="#c00"/> <line x1="228.0" y1="624.0" x2="228.0" y2="652.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="236.0" y="779.6" fill="#c00" text-anchor="middle" style="font-weight:bold">6</text> <rect x="223.5" y="630.0" width="9" height="16.0" fill="#c00"/>
<line x1="252.0" y1="658.4" x2="252.0" y2="692.0" stroke="#1a1a1a" stroke-width="1.2"/> <text x="228.0" y="763.0" fill="#c00" text-anchor="middle" style="font-weight:bold">4</text>
<rect x="247.5" y="665.6" width="9" height="19.2" fill="#188a3e"/> <line x1="246.0" y1="616.0" x2="246.0" y2="652.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="252.0" y="779.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">7</text> <rect x="241.5" y="622.0" width="9" height="24.0" fill="#188a3e"/>
<line x1="268.0" y1="658.4" x2="268.0" y2="696.8" stroke="#1a1a1a" stroke-width="1.2"/> <text x="246.0" y="763.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">5</text>
<rect x="263.5" y="665.6" width="9" height="24.0" fill="#c00"/> <line x1="264.0" y1="616.0" x2="264.0" y2="640.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="268.0" y="779.6" fill="#c00" text-anchor="middle" style="font-weight:bold">8</text> <rect x="259.5" y="622.0" width="9" height="12.0" fill="#c00"/>
<text x="108.0" y="775.6" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text> <text x="264.0" y="763.0" fill="#c00" text-anchor="middle" style="font-weight:bold">6</text>
<text x="278.0" y="672.8" fill="#555" text-anchor="start" style="font-weight:bold">a 8-a candelă: nici TP, nici SL</text> <line x1="282.0" y1="612.0" x2="282.0" y2="640.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="278.0" y="687.2" fill="#555" text-anchor="start" style="font-weight:bold">→ ieși la 50.70 = +0.25R</text> <rect x="277.5" y="618.0" width="9" height="16.0" fill="#188a3e"/>
<text x="24" y="816" fill="#555">Barele de după intrare sunt construite. Regulile: 13_strategia_3_byh.md:196-213.</text> <text x="282.0" y="763.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">7</text>
<line x1="300.0" y1="612.0" x2="300.0" y2="644.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="295.5" y="618.0" width="9" height="20.0" fill="#c00"/>
<text x="300.0" y="763.0" fill="#c00" text-anchor="middle" style="font-weight:bold">8</text>
<line x1="420.0" y1="708.0" x2="307.0" y2="645.9" stroke="#555" stroke-width="1.8"/>
<polygon points="300.0,642.0 308.9,642.4 305.1,649.4" fill="#555"/>
<text x="420.0" y="722.0" fill="#555" text-anchor="middle" style="font-weight:bold">a 8-a candelă: ieși oricum, la close 50.70 (+0.25R)</text>
<text x="420.0" y="736.0" fill="#555" text-anchor="middle" style="font-weight:bold">banii blocați aici lipsesc din alt trade</text>
<text x="168.0" y="594.0" fill="#555" style="font-weight:bold">8 candele în care nu se întâmplă nimic</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -2,16 +2,19 @@
"""LABU — Buy Doji la pivotul monthly (Nivel 2.5). """LABU — Buy Doji la pivotul monthly (Nivel 2.5).
Citește `gen/strategii/buy_doji_labu.spec.txt` și scrie Citește `gen/strategii/buy_doji_labu.spec.txt` și scrie
`gen/strategii/buy_doji_labu.svg`: 49 de candele daily, downtrend → triple `gen/strategii/buy_doji_labu.svg`: 57 de candele daily, downtrend → triple
bottom → doji la pivotul monthly 86.00 → confirmare (close 89.50 peste bottom (trei minime aproape egale, dar pivotul lunar atins doar de două ori)
high-ul dojiului) → bull reversal → higher high, cu SL 81.45 (−9 %) și → doji la pivotul monthly 86.00 → confirmare (close 89.50 peste high-ul
dojiului) → bull reversal → higher high, cu SL 81.45 (−9 %) și
TP 116.35 (+30 %). TP 116.35 (+30 %).
Toate cifrele din desen vin din specificație: pivot 86.00, intrare 89.50, Toate cifrele din desen vin din specificație: pivot 86.00, intrare 89.50,
SL 81.45, TP 116.35, high/low-ul dojiului (86.30 / 84.20) și low-urile SL 81.45, TP 116.35, high/low-ul dojiului (86.30 / 84.20) și low-urile
triple bottom-ului (82.40 / 81.45 / 81.45). Procentele 9 % și 30 % sunt ale triple bottom-ului (82.40 / 81.45 / 81.45). Procentele 9 % și 30 % sunt ale
cursului (reale); nivelurile de preț sunt construite de sumarizator — cursului (reale); nivelurile de preț sunt construite de sumarizator —
legenda o spune explicit. legenda o spune explicit. Capitolul spune și „triple bottom", și „doji la al
doilea test al pivotului": desenul le satisface pe amândouă — trei minime în
zona 81-83, dintre care doar primele două vin după o urcare peste 86.00.
Rulare: python3 gen/strategii/buy_doji_labu.py Rulare: python3 gen/strategii/buy_doji_labu.py
""" """
@@ -20,7 +23,7 @@ import sys
from pathlib import Path from pathlib import Path
sys.path.insert(0, "/workspace/atm-curs-dl") sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Chart, Level, MA, Mark, from_closes # noqa: E402 from svg_candles import Arrow, Chart, Level, MA, Mark, Zone, from_closes # noqa: E402
OUT = Path(__file__).with_suffix(".svg") OUT = Path(__file__).with_suffix(".svg")
@@ -29,50 +32,88 @@ PIVOT = 86.00 # pivot monthly (construit)
ENTRY = 89.50 # intrare = close-ul confirmării (construit) ENTRY = 89.50 # intrare = close-ul confirmării (construit)
SL = 81.45 # SL = −9 % față de intrare (construit; procentul e real) SL = 81.45 # SL = −9 % față de intrare (construit; procentul e real)
TP = 116.35 # TP = +30 % față de intrare (construit; procentul e real) TP = 116.35 # TP = +30 % față de intrare (construit; procentul e real)
DOJI_H, DOJI_L = 86.30, 84.20 DOJI_H, DOJI_L = 86.80, 84.90
I_DOJI, I_CONF = 33, 34
B1, B2, B3 = 16, 25, 31 # cele trei picioare ale triplului fund
# (B1, B2 = testele pivotului; B3 rămâne sub el)
I_RETEST = 37 # revenirea care testează intrarea și ține
FLAG = (42, 45) # consolidarea scurtă (bull flag)
I_TP = 55 # bara pe care prețul atinge 116.35
# --- seria de close-uri din specificație ----------------------------------- # --- seria de close-uri -----------------------------------------------------
# Textul capitolului e sursa: „triple bottom" (trei minime aproape egale) și
# „doji la al doilea test al pivotului". Nu se bat cap în cap: sunt trei
# minime de preț, dar doar două dintre ele vin după o urcare peste 86.00 —
# al treilea e o alunecare care nu mai atinge pivotul de sus în jos.
# Restul: „+30 % într-o lună" (21 de bare daily de la confirmare) și etapele
# „retest → bull flag → breakout". Prețurile sunt construite în jurul
# nivelurilor deja folosite în capitol (86.00 / 89.50 / 81.45 / 97.55 / 116.35).
closes = [ closes = [
# downtrend 0-14 # downtrend 0-14
108.0, 106.5, 105.0, 103.0, 101.5, 100.0, 98.0, 96.5, 95.0, 93.5, 108.0, 106.5, 105.0, 103.0, 101.5, 100.0, 98.0, 96.5, 95.0, 93.5,
92.5, 91.0, 89.5, 87.5, 85.5, 92.5, 91.0, 89.5, 87.5, 85.5,
# triple bottom 15 / 23 / 31 # 15-16: primul test al pivotului (bottom 1, low 82.40)
82.80, 84.5, 86.5, 88.0, 88.50, 83.5, 82.80,
87.0, 85.0, 83.0, 81.50, # 17-20: revenire peste pivot (88.90 high) — de aici vine al doilea test
83.5, 85.5, 87.0, 87.80, 87.0, 85.0, 84.5, 86.5, 88.0, 88.5,
83.0, 81.60, 85.00, # 21-24: coboară înapoi prin pivot: al doilea test al lui 86.00
84.90, # 33 = doji (o 85.00, c 84.90, h 86.30, l 84.20) 87.0, 85.5, 84.0, 82.8,
89.50, # 34 = confirmare, close > 86.30 => intrare # 25: bottom 2 (low 82.00), la capătul celui de-al doilea test
# bull reversal / trend up 35-48 82.30,
91.0, 93.0, 92.0, 95.0, 97.0, 96.0, 99.0, 102.0, 101.0, 105.0, 108.0, # 26-29: un pull-up scurt care NU mai ajunge la pivot (high max 85.80)
112.0, 116.35, 118.0, 83.5, 84.8, 85.4, 84.2,
# 30: alunecă iar, fără să fi atins pivotul între timp
83.0,
# 31: bottom 3 (low 81.45 = stopul) — al treilea minim, nu un test nou
81.90,
# 32: bara de întoarcere, închide peste pivot
86.10,
# 33 = doji: o 86.10, c 86.00, h 86.80, l 84.90 — corpul chiar pe pivot
86.00,
# 34 = confirmare: close 89.50 peste high-ul dojiului => intrare
89.50,
# 35-36: pornirea
92.0, 94.0,
# 37: retest — cade la 89.60, pe intrare, și ține
91.0,
# 38-41: reia urcarea și trece de ținta 1:1 (97.55)
93.5, 95.5, 98.5, 100.0,
# 42-45: bull flag — patru candele care se odihnesc
99.2, 99.8, 98.9, 99.5,
# 46-54: breakout și continuare
102.5, 104.0, 103.0, 106.0, 108.5, 107.5, 110.5, 112.5, 114.0,
# 55: +30 % față de intrare; 56: încă un higher high
116.35, 117.5,
] ]
assert len(closes) == 49, f"seria are {len(closes)} bare, spec cere 49" assert len(closes) == 57, f"seria are {len(closes)} bare, aștept 57"
# wick-uri: (up, down). Restul (0.4, 0.5); ajustate ca low-urile/high-urile # wick-uri: (sus, jos) față de corp. Restul (0.4, 0.5); ajustate ca low-urile
# cerute de asserts să iasă exact (bar 15/23/31 = triple bottom; bar 16/24 # cerute de assert-uri să iasă exact.
# nu au voie să coboare sub piciorul din stânga; bar 33 = doji).
wicks = [(0.4, 0.5)] * len(closes) wicks = [(0.4, 0.5)] * len(closes)
wicks[15] = (0.4, 0.40) # low 82.40 wicks[B1] = (0.4, 0.40) # bottom 1: low 82.40
wicks[16] = (0.4, 0.20) # low 82.60 > 82.40 (piciorul 1 rămâne minim local) wicks[17] = (0.4, 0.00) # low 82.80 > 82.40 (piciorul 1 rămâne minim local)
wicks[23] = (0.4, 0.05) # low 81.45 wicks[B2] = (0.4, 0.30) # bottom 2: low 82.00
wicks[24] = (0.4, 0.00) # low 81.50 > 81.45 (piciorul 2 rămâne minim local) wicks[26] = (0.4, 0.00) # low 82.30 > 82.00 (piciorul 2 rămâne minim local)
wicks[31] = (0.4, 0.15) # low 81.45 wicks[B3] = (0.4, 0.45) # bottom 3: low 81.45 = stopul
wicks[32] = (0.4, 0.10) # low 81.50 (nu sub 81.45) wicks[32] = (0.4, 0.00) # low 81.90 (nu coboară sub 81.45)
wicks[33] = (1.30, 0.70) # doji: high 86.30, low 84.20 wicks[I_DOJI] = (0.70, 1.10) # doji: high 86.80, low 84.90
wicks[35] = (0.4, 0.00) # prima bară după intrare nu se mai duce sub 89.50
wicks[I_RETEST] = (0.4, 1.40) # retest: low 89.60, peste intrarea de 89.50
# volume construite: vânzare peste medie la triple bottom și la confirmare. # volume construite: vânzare peste medie la cele două picioare, volum mare pe
# Nu sunt numere din curs (nu sunt etichetate), doar panoul de volum cerut. # confirmare, volum mic pe flag. Nu sunt numere din curs.
vols = [ vols = [
55, 52, 48, 50, 45, 47, 44, 46, 42, 44, 55, 52, 48, 50, 45, 47, 44, 46, 42, 44,
40, 42, 38, 41, 58, 40, 42, 38, 41, 58,
62, 50, 46, 44, 43, 62, 68, 50, 46, 44,
45, 44, 47, 66, 55, 43, 45, 44, 47, 46,
50, 47, 45, 44, 42, 45, 47, 52, 45, 44,
43, 45, 60, 72, 84, 48, 70, 62, 58, 88,
78, 70, 64, 60, 58, 76, 70, 58, 62, 66,
54, 52, 56, 60, 66, 72, 70, 44, 40, 38,
74, 82, 90, 98, 42, 74, 70, 64, 68,
72, 66, 74, 78, 82,
90, 96,
] ]
assert len(vols) == len(closes), f"volume {len(vols)} != bare {len(closes)}" assert len(vols) == len(closes), f"volume {len(vols)} != bare {len(closes)}"
@@ -80,80 +121,134 @@ cds = from_closes(closes, wicks=wicks, vols=vols, start=110.0)
assert abs(cds[0].o - 110.0) < 1e-9 and cds[0].c < cds[0].o, "prima bară nu e roșie" assert abs(cds[0].o - 110.0) < 1e-9 and cds[0].c < cds[0].o, "prima bară nu e roșie"
# nota explicativă a dojiului (bloc stânga-jos, nu se suprapune cu candelele) # nota explicativă a dojiului (bloc stânga-jos, nu se suprapune cu candelele)
cds[33].note = ("bara 33 = doji: o 85.00, c 84.90, h 86.30, l 84.20 — " cds[I_DOJI].note = ("doji = corp mic (o 86.10, c 86.00): cumpărătorii și vânzătorii sunt la "
"corp mic exact pe pivotul monthly 86.00 (indecizie la suport)") "egalitate, exact pe pivotul lunar 86.00")
TP1 = round(ENTRY + (ENTRY - SL), 2) # ținta 1:1: cât ai riscat
assert abs(TP1 - 97.55) < 1e-9, f"ținta 1:1 = {TP1}, capitolul spune 97.55"
R = (TP - ENTRY) / (ENTRY - SL)
assert 3.2 <= R <= 3.4, f"{R:.2f}R, capitolul spune „cam 3,3R”"
I_TP1 = next(i for i in range(35, len(cds)) if cds[i].h >= TP1) # prima bară peste 1:1
cds[I_TP1].note = (f"ținta 1:1 ({TP1:.2f}) e atinsă pe bara {I_TP1}: acolo vinzi o treime, "
"restul merge mai departe — de asta nu vinzi tot la 1:1")
# --- assert-urile din specificație (toate, ca assert reale) ---------------- # --- assert-urile din specificație (toate, ca assert reale) ----------------
# 1. pivot 86.00 e straddled de doji # 1. pivot 86.00 e straddled de doji
assert cds[33].l <= PIVOT <= cds[33].h, "doji-ul nu straddlează 86.00" assert cds[I_DOJI].l <= PIVOT <= cds[I_DOJI].h, "doji-ul nu straddlează 86.00"
# corpul dojiului stă pe pivot, nu la un dolar sub el (eticheta spune „exact pe")
assert min(cds[I_DOJI].o, cds[I_DOJI].c) <= PIVOT <= max(cds[I_DOJI].o, cds[I_DOJI].c) + 0.15, \
f"corpul dojiului ({cds[I_DOJI].o}/{cds[I_DOJI].c}) nu e pe pivotul {PIVOT}"
# 2. confirmarea: close[34] == 89.50 == intrare și > high[33] # 2. confirmarea: close[34] == 89.50 == intrare și > high-ul dojiului
assert abs(cds[34].c - ENTRY) < 1e-9, f"close[34]={cds[34].c} != intrare 89.50" assert abs(cds[I_CONF].c - ENTRY) < 1e-9, f"close[{I_CONF}]={cds[I_CONF].c} != intrare 89.50"
assert cds[34].c > cds[33].h, "confirmarea nu închide peste high-ul dojiului" assert cds[I_CONF].c > cds[I_DOJI].h, "confirmarea nu închide peste high-ul dojiului"
# 3. SL = min(low[30:35]) (regula: extrema ultimelor 4 candele de la confirmare) # 3. SL = extrema ultimelor 4 candele de la confirmare
min_30_35 = min(c.l for c in cds[30:35]) min_win = min(c.l for c in cds[I_CONF - 4:I_CONF + 1])
assert abs(min_30_35 - SL) < 1e-9, f"min low[30:35]={min_30_35} != SL {SL}" assert abs(min_win - SL) < 1e-9, f"min low[{I_CONF - 4}:{I_CONF + 1}]={min_win} != SL {SL}"
# 4./5. procentele REALE ale cursului # 4./5. procentele REALE ale cursului
assert round((ENTRY - SL) / ENTRY * 100, 1) == 9.0, "stopul nu iese −9 %" assert round((ENTRY - SL) / ENTRY * 100, 1) == 9.0, "stopul nu iese −9 %"
assert round((TP - ENTRY) / ENTRY * 100, 1) == 30.0, "TP nu iese +30 %" assert round((TP - ENTRY) / ENTRY * 100, 1) == 30.0, "TP nu iese +30 %"
# 6. triple bottom: exact trei minime locale sub 86.00, în zona 81-83, # 6. triple bottom, dar pivotul atins de două ori — aserțiunea care ține
# al doilea și al treilea fără low nou semnificativ față de primul # laolaltă cele două formulări din capitol („trei minime aproape egale" și
# „doji la al doilea test al pivotului 86.00").
lows = [c.l for c in cds] lows = [c.l for c in cds]
bottom_idx = [i for i in range(1, len(cds) - 1) bottom_idx = [i for i in range(1, len(cds) - 1)
if lows[i] < lows[i - 1] and lows[i] < lows[i + 1] if lows[i] < lows[i - 1] and lows[i] < lows[i + 1]
and lows[i] < PIVOT and 81.0 <= lows[i] <= 83.0] and lows[i] < PIVOT and 81.0 <= lows[i] <= 83.0]
assert bottom_idx == [15, 23, 31], f"triple bottom la {bottom_idx}, nu [15, 23, 31]" assert bottom_idx == [B1, B2, B3], f"minimele fundului: {bottom_idx}, aștept [{B1}, {B2}, {B3}]"
b1, b2, b3 = lows[15], lows[23], lows[31] assert len(bottom_idx) == 3, f"{len(bottom_idx)} minime locale în zona fundului, aștept 3"
tol = 0.02 * b1 # „semnificativ" = > 2 % sub primul low b1, b2, b3 = (lows[i] for i in bottom_idx)
assert b2 >= b1 - tol and b3 >= b1 - tol, \ # „aproape egale": nici unul nu e cu mai mult de 2 % sub primul
f"al doilea/treilea picior coboară semnificativ sub primul: {b1}/{b2}/{b3}" assert max(b1, b2, b3) - min(b1, b2, b3) <= 0.02 * b1, \
assert abs(b1 - 82.40) < 1e-9 and abs(b2 - SL) < 1e-9 and abs(b3 - SL) < 1e-9, \ f"minimele nu sunt aproape egale: {b1}/{b2}/{b3}"
f"low-urile triple bottom: {b1}/{b2}/{b3}" assert abs(b1 - 82.40) < 1e-9 and abs(b2 - 82.00) < 1e-9 and abs(b3 - SL) < 1e-9, \
f"low-urile triplului fund: {b1}/{b2}/{b3}"
# un minim e „atingere a pivotului" doar dacă prețul a fost peste 86.00 după
# minimul dinainte: coboară prin pivot ca să ajungă acolo. Al treilea nu e.
tests = []
for k, i in enumerate(bottom_idx):
prev = bottom_idx[k - 1] + 1 if k else 0
if max(c.h for c in cds[prev:i]) >= PIVOT:
tests.append(i)
assert tests == [B1, B2], f"atingeri ale pivotului la {tests}, aștept [{B1}, {B2}]"
assert len(tests) == 2, f"{len(tests)} atingeri ale pivotului 86.00, aștept 2"
# între primele două picioare prețul urcă clar peste pivot (al doilea test)
assert max(c.h for c in cds[B1 + 1:B2]) > PIVOT + 1.5, "nu e revenire peste pivot înainte de B2"
# între al doilea și al treilea NU mai ajunge la pivot: al treilea nu e test
assert max(c.h for c in cds[B2 + 1:B3]) < PIVOT, \
f"pull-up-ul dintre B2 și B3 atinge pivotul ({max(c.h for c in cds[B2 + 1:B3]):.2f})"
# 7. TP atins: există i > 34 cu high[i] >= 116.35 # 7. TP atins la ~o lună de bursă de la confirmare (capitolul: „într-o lună")
assert any(c.h >= TP for c in cds[35:]), "TP 116.35 nu e atins după intrare" assert abs(cds[I_TP].c - TP) < 1e-9, f"close[{I_TP}]={cds[I_TP].c} != {TP}"
assert max(c.h for c in cds[I_CONF + 1:I_TP]) < TP, "TP atins mai devreme de bara 55"
bars_to_tp = I_TP - I_CONF
assert 20 <= bars_to_tp <= 22, f"{bars_to_tp} bare până la +30 %, aștept ~21 (o lună)"
# 8. doji: corp <= 10 % din amplitudine # 8. doji: corp <= 10 % din amplitudine
assert abs(cds[33].o - cds[33].c) <= 0.10 * (cds[33].h - cds[33].l), "bara 33 nu e doji" assert abs(cds[I_DOJI].o - cds[I_DOJI].c) <= 0.10 * (cds[I_DOJI].h - cds[I_DOJI].l), \
assert abs(cds[33].h - DOJI_H) < 1e-9 and abs(cds[33].l - DOJI_L) < 1e-9, \ "bara doji nu e doji"
"doji h/l nu ies 86.30/84.20" assert abs(cds[I_DOJI].h - DOJI_H) < 1e-9 and abs(cds[I_DOJI].l - DOJI_L) < 1e-9, \
"doji h/l nu ies 86.80/84.90"
# în plus: confirmarea vine cu volum peste medie (cerut de spec) # 9. retestul: revine până pe intrare și ține (nu o rupe)
assert ENTRY <= cds[I_RETEST].l <= ENTRY + 0.5, \
f"retestul nu atinge intrarea: low {cds[I_RETEST].l}"
assert min(c.l for c in cds[I_CONF + 1:]) >= ENTRY, "prețul cade sub intrare după confirmare"
# 10. bull flag: 4 candele strânse, sub high-ul barei dinainte, urmate de breakout
f0, f1 = FLAG
flag_h = max(c.h for c in cds[f0:f1 + 1])
flag_l = min(c.l for c in cds[f0:f1 + 1])
assert flag_h - flag_l <= 2.5, f"flag prea larg: {flag_h - flag_l:.2f}"
assert flag_h <= cds[f0 - 1].h, "flagul face high nou — nu mai e consolidare"
assert cds[f1 + 1].c > flag_h, "nu există breakout după flag"
# în plus: confirmarea vine cu volum peste medie, flagul cu volum sub medie
mean_vol = sum(vols) / len(vols) mean_vol = sum(vols) / len(vols)
assert vols[34] > mean_vol, f"volumul confirmării {vols[34]} <= media {mean_vol:.0f}" assert vols[I_CONF] > mean_vol, f"volumul confirmării {vols[I_CONF]} <= media {mean_vol:.0f}"
assert max(vols[f0:f1 + 1]) < mean_vol, "flagul nu vine pe volum scăzut"
entry = cds[34].c entry = cds[34].c
w = 820 # lățime mărită: 49 bare × gap 15 + etichetele din dreapta w = 990 # 57 bare × gap 15 + loc pentru etichetele din dreapta
# (spec sugera 760, dar ultima candelă ajunge la x=764)
ch = Chart( ch = Chart(
candles=cds, candles=cds,
levels=[Level(PIVOT, "pivot monthly 86.00 (construit)", "#777", levels=[Level(PIVOT, "pivot lunar 86.00", "#777", dash="4 3", label_at="left"),
dash="4 3", label_at="left"), Level(SL, "stop 81.45 = 9 % sub intrare (procent real)", "#c00", label_at="left"),
Level(SL, "SL 81.45 (construit) = −9 % (procent real)", "#c00", Level(ENTRY, "intrare 89.50", "#188a3e"),
label_at="left"), Level(TP1, f"ținta 1:1 {TP1:.2f}", "#777", dash="2 3", label_at="left"),
Level(ENTRY, "intrare 89.50 (construit)", "#188a3e"), Level(TP, "116.35 = +30 % față de intrare (procent real)", "#1a5fb4", label_at="left")],
Level(TP, "TP 116.35 (construit) = +30 % (procent real)", "#1a5fb4")], zones=[Zone(0, B3, "1. setup: scădere lungă, apoi trei minime aproape egale — pivotul 86.00 atins de două ori", "#777"),
marks=[Mark(15, f"bottom 1 {lows[15]:.2f}", "#c00", "below"), Zone(I_DOJI, I_CONF, "2. doji + confirmare", "#b06000"),
Mark(23, f"bottom 2 {lows[23]:.2f}", "#c00", "below"), # p_top sub 116.35: altfel eticheta zonei 3 se așază peste linia țintei
Mark(31, f"bottom 3 {lows[31]:.2f}", "#c00", "below"), Zone(I_CONF + 1, I_TP - 1, "3. trendul pornește", "#188a3e", p_top=113.0),
Mark(33, "doji", "#b06000", "above"), Zone(I_TP, len(cds) - 1, "4. ținta", "#1a5fb4")],
Mark(34, "confirmare (intrare)", "#188a3e", "above", dy=-14), arrows=[Arrow(I_CONF, "aici intri, la close 89.50:\nabia acum știi că au câștigat cumpărătorii",
Mark(48, "higher high — TP atins", "#188a3e", "above")], ENTRY, where="above", color="#188a3e", dx=-150),
Arrow(B3, "al treilea minim: 81.45,\nfără o nouă atingere a pivotului\naici pui stopul, sub minime",
SL, where="below", color="#c00", dx=-40),
Arrow(I_RETEST, "retest: cade înapoi pe intrare\nși ține — trendul e sănătos",
cds[I_RETEST].l, where="below", color="#188a3e", dx=110, dy=56),
Arrow(FLAG[0] + 1, "aici se odihnește, nu se strică:\nbull flag, pe volum mic",
cds[FLAG[0] + 1].h, where="above", color="#188a3e", dx=-20),
Arrow(I_TP, f"a ajuns la 116.35: +30 % în 21 de zile de bursă,\ncam {R:.1f}R din cât ai riscat".replace("3.3R", "3,3R"),
TP, where="left", color="#1a5fb4", dx=-30, dy=-40)],
marks=[Mark(B1, f"test 1 · {lows[B1]:.2f}", "#c00", "below"),
Mark(B2, f"test 2 · {lows[B2]:.2f}", "#c00", "below")],
mas=[MA(20, "#b06000", dash="4 3", text="SMA-20")], mas=[MA(20, "#b06000", dash="4 3", text="SMA-20")],
scale=8.0, gap=15, body_w=9, left=44, width=w, vol_h=70, scale=8.0, gap=15, body_w=9, left=44, width=w, vol_h=70,
vol_label="volum", title="LABU — daily", vol_label="volum", title="LABU — daily",
caption=("Procentele (stop 9 %, +30 %) sunt ale cursului; nivelurile de " caption=("Procentele (stop 9 %, +30 %) sunt ale cursului; "
"preț sunt construite de sumarizator (18_2025-09-23.md:713)."), "nivelurile de preț sunt puse de sumarizator."),
) )
svg = ch.render() svg = ch.render()
assert "\n\n" not in svg and "<svg" in svg, "SVG invalid (linie goală?)" assert "\n\n" not in svg and "<svg" in svg, "SVG invalid (linie goală?)"
# --- citirea SVG-ului: etichete în panză, fără suprapuneri ----------------- # --- citirea SVG-ului: etichete în panză, fără suprapuneri -----------------
TEXT = re.compile(r'<text x="([-\d.]+)" y="([-\d.]+)"([^>]*)>(.*?)</text>', re.S) TEXT = re.compile(r'<text x="([-\d.]+)" y="([-\d.]+)"([^>]*)>(.*?)</text>', re.S)
H = float(re.search(r'viewBox="0 0 (\d+) ([\d.]+)"', svg).group(2)) W_SVG, H = (float(x) for x in re.search(r'viewBox="0 0 (\d+) ([\d.]+)"', svg).groups())
labels = [] labels = []
for m in TEXT.finditer(svg): for m in TEXT.finditer(svg):
x, y, attrs, s = float(m.group(1)), float(m.group(2)), m.group(3), m.group(4) x, y, attrs, s = float(m.group(1)), float(m.group(2)), m.group(3), m.group(4)
@@ -165,7 +260,7 @@ for m in TEXT.finditer(svg):
labels.append((left, left + wpx, y, s)) labels.append((left, left + wpx, y, s))
for left, right, y, s in labels: for left, right, y, s in labels:
assert left >= -2 and right <= w + 2, f"text iese din panză: {s!r} [{left:.0f},{right:.0f}]" assert left >= -2 and right <= W_SVG + 2, f"text iese din panză: {s!r} [{left:.0f},{right:.0f}]"
assert 0 <= y <= H, f"text în afara înălțimii: {s!r} (y={y:.0f})" assert 0 <= y <= H, f"text în afara înălțimii: {s!r} (y={y:.0f})"
for i in range(len(labels)): for i in range(len(labels)):
@@ -177,14 +272,16 @@ for i in range(len(labels)):
# candelele sunt o serie continuă, lipită # candelele sunt o serie continuă, lipită
xs = [ch._cx(i) for i in range(len(cds))] xs = [ch._cx(i) for i in range(len(cds))]
assert xs[-1] + ch.body_w / 2 < w, f"ultima candelă iese din panză (x={xs[-1]})" assert ".md:" not in svg and "Surse" not in svg, "trimiteri la surse în SVG"
assert xs[-1] + ch.body_w / 2 < W_SVG, f"ultima candelă iese din panză (x={xs[-1]})"
assert all(xs[i + 1] - xs[i] == ch.gap for i in range(len(xs) - 1)), "serie cu goluri" assert all(xs[i + 1] - xs[i] == ch.gap for i in range(len(xs) - 1)), "serie cu goluri"
for a, b in zip(cds, cds[1:]): for a, b in zip(cds, cds[1:]):
assert abs(a.c - b.o) < 1e-9, "open != close-ul barei anterioare" assert abs(a.c - b.o) < 1e-9, "open != close-ul barei anterioare"
print(f"LABU: {len(cds)} bare, doji {cds[33].l:.2f}-{cds[33].h:.2f} peste pivot " print(f"LABU: {len(cds)} bare, doji {cds[33].l:.2f}-{cds[33].h:.2f} peste pivot "
f"{PIVOT:.2f}, intrare {entry:.2f}, SL {SL:.2f} (−9 %), TP {TP:.2f} (+30 %)") f"{PIVOT:.2f}, intrare {entry:.2f}, SL {SL:.2f} (−9 %), TP {TP:.2f} (+30 %)")
print(f"triple bottom: {b1:.2f} / {b2:.2f} / {b3:.2f} " print(f"triple bottom: {b1:.2f} / {b2:.2f} / {b3:.2f}; pivotul 86.00 atins de "
f"{len(tests)} ori (barele {tests}); +30 % după {bars_to_tp} bare "
f"volum confirmare {vols[34]} > medie {mean_vol:.0f}") f"volum confirmare {vols[34]} > medie {mean_vol:.0f}")
print(f"scris {OUT} ({w}x{H:.0f}); {len(labels)} etichete verificate, fără suprapuneri") print(f"scris {OUT} ({W_SVG:.0f}x{H:.0f}); {len(labels)} etichete verificate, fără suprapuneri")
OUT.write_text(svg, encoding="utf-8") OUT.write_text(svg, encoding="utf-8")

View File

@@ -4,8 +4,9 @@ TITLU: LABU — daily, Buy Doji la pivotul monthly (Nivel 2.5)
MARCAJ .md: <!-- DIAGRAMA: labu --> (Nivel 2, §2.5 Exemplul complet) MARCAJ .md: <!-- DIAGRAMA: labu --> (Nivel 2, §2.5 Exemplul complet)
CE ARATĂ CE ARATĂ
Exemplul complet din material: downtrend → consolidare → triple bottom → Exemplul complet din material: downtrend → consolidare → triple bottom (trei
doji la pivotul monthly 86.00 → candela verde care închide peste high-ul minime aproape egale, dar pivotul monthly atins doar de două ori — „al doilea
test") → doji la pivotul monthly 86.00 → candela verde care închide peste high-ul
dojiului (intrare 89.50) → bull reversal pe candela mare → retest → bull dojiului (intrare 89.50) → bull reversal pe candela mare → retest → bull
flag → breakout → higher high, higher low. SL 81.45 (−9 %), TP 116.35 flag → breakout → higher high, higher low. SL 81.45 (−9 %), TP 116.35
(+30 %), atins într-o lună. (+30 %), atins într-o lună.
@@ -17,12 +18,38 @@ CE E REAL ȘI CE E CONSTRUIT (obligatoriu în legendă)
higher high/higher low), `18_2025-09-23.md:716-719`; „al doilea test al higher high/higher low), `18_2025-09-23.md:716-719`; „al doilea test al
pivotului monthly, fără low nou" și „corp mic exact pe pivotul monthly: pivotului monthly, fără low nou" și „corp mic exact pe pivotul monthly:
indecizie la suport", `18_2025-09-23.md:710-712`. indecizie la suport", `18_2025-09-23.md:710-712`.
- REZOLVAT (19.09.2026): transcrierea și capitolul spun și „triple bottom"
(`:716-719`), și „al doilea test al pivotului monthly" (`:710-712`). Nu se
contrazic: sunt trei minime de PREȚ, dar nivelul 86.00 e atins doar de două
ori. Versiunea dinainte desena doar două minime și contrazicea „triple
bottom"; seria a fost reconstruită cu TREI minime aproape egale (82.40 /
82.00 / 81.45), dintre care doar primele două vin după o urcare peste 86.00.
Între minimul 2 și minimul 3 prețul se ridică doar până la 85.80 — sub
pivot, deci al treilea minim nu e un test nou. Generatorul asertează
explicit: 3 minime locale în zona 81-83 și 2 atingeri ale lui 86.00.
- CONSTRUITE de sumarizator (nu prețuri de curs): pivot 86.00, intrare - CONSTRUITE de sumarizator (nu prețuri de curs): pivot 86.00, intrare
89.50, SL 81.45, TP 116.35 — marcate ca „nivelurile sunt ale mele" 89.50, SL 81.45, TP 116.35 — marcate ca „nivelurile sunt ale mele"
(`18_2025-09-23.md:713`). Legenda diagramei trebuie să spună exact asta. (`18_2025-09-23.md:713`). Legenda diagramei trebuie să spună exact asta.
- Materialul nu dă niciun exemplu numeric complet de la intrare la ieșire - Materialul nu dă niciun exemplu numeric complet de la intrare la ieșire
(`13_strategia_3_byh.md:298-308`; `byh.md:256-280`). (`13_strategia_3_byh.md:298-308`; `byh.md:256-280`).
ADNOTĂRI (patru zone numerotate, ca subsecțiunile capitolului)
- Zona 1 (barele 0-31): „1. setup: scădere lungă, apoi trei minime aproape
egale — pivotul 86.00 atins de două ori"; Zona 2 (33-34): „2. doji + confirmare"; Zona 3 (35-54):
„3. trendul pornește"; Zona 4 (55-56): „4. ținta".
- Marcaje sub minimele 1 și 2 („test 1 · 82.40", „test 2 · 82.00") — doar
ele sunt atingeri ale pivotului; al treilea minim e numit de săgeata stopului.
- Săgeți: retestul („retest: cade înapoi pe intrare și ține — trendul e
sănătos"), bull flag-ul („aici se odihnește, nu se strică: bull flag, pe
volum mic"), intrarea („aici intri, la close 89.50: abia acum știi că au
câștigat cumpărătorii"), stopul, pe al treilea minim („al treilea minim:
81.45, fără o nouă atingere a pivotului, aici pui stopul, sub minime"), rezultatul („a ajuns la 116.35: +30 % într-o
lună, cam 3,3R din cât ai riscat").
- Linie punctată pentru ținta 1:1 (97.55), cu nota de dedesubt: acolo vinzi
o treime, restul merge mai departe.
- Fără trimiteri fișier:linie în SVG; legenda „procentele sunt ale cursului,
prețurile sunt puse de sumarizator" rămâne.
NIVELURILE ȘI ETICHETELE (cu trimitere) NIVELURILE ȘI ETICHETELE (cu trimitere)
- „pivot monthly 86.00" (`18_2025-09-23.md:615`) - „pivot monthly 86.00" (`18_2025-09-23.md:615`)
- „intrare 89.50" (`18_2025-09-23.md:619`) - „intrare 89.50" (`18_2025-09-23.md:619`)
@@ -30,22 +57,37 @@ NIVELURILE ȘI ETICHETELE (cu trimitere)
- „TP +30 % = 116.35" (`18_2025-09-23.md:620-621`) - „TP +30 % = 116.35" (`18_2025-09-23.md:620-621`)
Etichete marcate „(construit)" sau „(procent real)" în legendă. Etichete marcate „(construit)" sau „(procent real)" în legendă.
STRUCTURA SERIEI (49 candele daily, open = close-ul precedentului) STRUCTURA SERIEI (57 candele daily, open = close-ul precedentului)
Sugestie de close-uri: Seria e reconstruită după textul capitolului (19.09.2026): triple bottom cu
Etapa downtrend + triple bottom (0-33): DOUĂ atingeri ale pivotului („al doilea test"), 21 de bare de la confirmare la +30 % („într-o
lună"), retest al intrării la bara 37 și bull flag la barele 42-45. Corpul
dojiului stă pe pivot (o 86.10, c 86.00, h 86.80, l 84.90), nu cu un dolar
sub el. Nivelurile din capitol rămân: 86.00 / 89.50 / 81.45 / 97.55 / 116.35.
Close-uri:
[108.0, 106.5, 105.0, 103.0, 101.5, 100.0, 98.0, 96.5, 95.0, 93.5, [108.0, 106.5, 105.0, 103.0, 101.5, 100.0, 98.0, 96.5, 95.0, 93.5,
92.5, 91.0, 89.5, 87.5, 85.5, 82.80, 84.5, 86.5, 88.0, 88.50, 92.5, 91.0, 89.5, 87.5, 85.5,
87.0, 85.0, 83.0, 81.50, 83.5, 85.5, 87.0, 87.80, 87.0, 85.0, 83.5, 82.80, # 16 = primul test (low 82.40)
83.0, 81.60, 85.00, 84.5, 86.5, 88.0, 88.5, # 17-20 = urcare peste pivot (high 88.90)
84.90, # 33 = doji (o 85.00, c 84.90, h 86.30, l 84.20); straddlează 86.00 87.0, 85.5, 84.0, 82.8, # 21-24 = coborâre prin pivot = testul 2
89.50, # 34 = confirmare, close > 86.30 => intrare 82.30, # 25 = minimul 2 (low 82.00)
91.0, 93.0, 92.0, 95.0, 97.0, 96.0, 99.0, 102.0, 101.0, 105.0, 108.0, 83.5, 84.8, 85.4, 84.2, # 26-29 = pull-up sub pivot (high max 85.80)
112.0, 116.35, 118.0] 83.0, # 30 = alunecă iar, fără test nou
Mecioni: barele 15, 23, 31 au low-urile triple bottom-ului — bara 15 low 81.90, # 31 = minimul 3 (low 81.45 = stopul)
82.40, bara 23 low 81.45, bara 31 low 81.45; bara 32 (revenirea) wd=0.10 86.10, # 32 = bara de întoarcere, peste pivot
(low 81.50, nu sub 81.45); bara 33 (doji) high 86.30, low 84.20; restul 86.00, # 33 = doji (o 86.10, h 86.80, l 84.90)
(0.4, 0.5). Ajustează wick-urile ca low-urile/high-urile cerute la asserts 89.50, # 34 = confirmare => intrare
să iasă exact (în special min(low[30:35]) == 81.45). 92.0, 94.0,
91.0, # 37 = retest (low 89.60, peste intrare)
93.5, 95.5, 98.5, 100.0, # 40 = prima bară peste ținta 1:1
99.2, 99.8, 98.9, 99.5, # 42-45 = bull flag, volum mic
102.5, 104.0, 103.0, 106.0, 108.5, 107.5, 110.5, 112.5, 114.0,
116.35, 117.5] # 55 = +30 %, la 21 de bare de confirmare
Wick-uri: implicit (0.4, 0.5); bara 16 (0.4, 0.40) => low 82.40; bara 17
(0.4, 0.00) ca primul picior să rămână minim local; bara 25 (0.4, 0.30) =>
low 82.00; bara 26 (0.4, 0.00) ca al doilea picior să rămână minim local;
bara 31 (0.4, 0.45) => low 81.45; bara 32 (0.4, 0.00) ca să nu coboare sub stop; bara 33
(0.70, 1.10) = doji; bara 35 (0.4, 0.00) și bara 37 (0.4, 1.40) => retestul
atinge 89.60 și ține.
CE VERIFICĂ GENERATORUL CU assert CE VERIFICĂ GENERATORUL CU assert
1. pivot 86.00 e straddled de doji: low[33] <= 86.00 <= high[33] 1. pivot 86.00 e straddled de doji: low[33] <= 86.00 <= high[33]
@@ -54,13 +96,22 @@ CE VERIFICĂ GENERATORUL CU assert
confirmare, regula din `13_strategia_3_byh.md:192-193`) confirmare, regula din `13_strategia_3_byh.md:192-193`)
4. round((entry - sl) / entry * 100, 1) == 9.0 (procentul REAL al cursului) 4. round((entry - sl) / entry * 100, 1) == 9.0 (procentul REAL al cursului)
5. round((tp - entry) / entry * 100, 1) == 30.0 (procentul REAL al cursului) 5. round((tp - entry) / entry * 100, 1) == 30.0 (procentul REAL al cursului)
6. triple bottom: există trei minime locale succesive sub 86.00, în zona 6. triple bottom cu două teste: exact TREI minime locale sub 86.00, în zona
81-83, al doilea și al treilea fără low nou semnificativ față de primul 81-83 (barele 16, 25 și 31), diferența dintre ele <= 2 % („aproape
7. există i>34 cu high[i] >= 116.35 egale"); dintre ele, exact DOUĂ sunt atingeri ale pivotului 86.00 —
minimele precedate de un high >= 86.00 (barele 16 și 25). Între 16 și 25
prețul urcă peste 86.00 + 1.5; între 25 și 31 maximul rămâne sub 86.00,
deci al treilea minim nu e un test nou.
7. close[55] == 116.35, nimic peste 116.35 înainte, și 20 <= 55-34 <= 22
(„într-o lună")
9. retestul (bara 37) atinge 89.50-90.00 și nicio bară de după confirmare nu
închide/coboară sub intrare
10. bull flag (42-45): amplitudine <= 2.5, fără high nou față de bara 41,
breakout pe bara 46, volum sub medie
8. doji: abs(o-c) <= 0.10*(h-l) 8. doji: abs(o-c) <= 0.10*(h-l)
STIL: gap=15, body_w=9, left=44, width=760, vol_h=70 (volumul confirmă: STIL: gap=15, body_w=9, left=44, width=990, vol_h=70 (volumul confirmă:
„cel mai mare volum din serie" e în varianta MICI, nu obligatoriu aici — dar „cel mai mare volum din serie" e în varianta MICI, nu obligatoriu aici — dar
confirmarea are volum peste medie). scale astfel încât 86.00 → 116.35 să confirmarea are volum peste medie). scale astfel încât 86.00 → 116.35 să
încapă; linie punctată pentru pivotul 86.00. Legendă obligatorie: încapă; linie punctată pentru pivotul 86.00. Legendă obligatorie:
„Procentele (stop 9 %, +30 %) sunt ale cursului; nivelurile de preț sunt „Procentele (stop 9 %, +30 %) sunt ale cursului; nivelurile de preț sunt
construite de sumarizator (18_2025-09-23.md:713)." Fără linie goală în SVG. puse de sumarizator." (fără trimitere fișier:linie în SVG) Fără linie goală în SVG.

View File

@@ -1,170 +1,222 @@
<svg viewBox="0 0 820 507" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 990 622" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="48" fill="#333" style="font-weight:bold">LABU — daily</text> <text x="24" y="70" fill="#333" style="font-weight:bold">LABU — daily</text>
<line x1="24" y1="315.2" x2="806" y2="315.2" stroke="#777" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="34.5" y="129.6" width="484.0" height="247.6" fill="#777" fill-opacity="0.08" stroke="#777" stroke-width="1"/>
<text x="30" y="309.2" fill="#777">pivot monthly 86.00 (construit)</text> <text x="34.5" y="124.6" fill="#777" style="font-weight:bold">1. setup: scădere lungă, apoi trei minime aproape egale — pivotul 86.00 atins de două ori</text>
<line x1="24" y1="351.6" x2="806" y2="351.6" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="529.5" y="293.6" width="34.0" height="56.0" fill="#b06000" fill-opacity="0.08" stroke="#b06000" stroke-width="1"/>
<text x="30" y="345.6" fill="#c00">SL 81.45 (construit) = −9 % (procent real)</text> <text x="529.5" y="220.6" fill="#b06000" style="font-weight:bold">2. doji + confirmare</text>
<line x1="24" y1="287.2" x2="806" y2="287.2" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="559.5" y="116.8" width="304.0" height="196.0" fill="#188a3e" fill-opacity="0.08" stroke="#188a3e" stroke-width="1"/>
<text x="792" y="281.2" fill="#188a3e" text-anchor="end">intrare 89.50 (construit)</text> <text x="559.5" y="111.8" fill="#188a3e" style="font-weight:bold">3. trendul pornește</text>
<line x1="24" y1="72.4" x2="806" y2="72.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="859.5" y="69.6" width="34.0" height="51.2" fill="#1a5fb4" fill-opacity="0.08" stroke="#1a5fb4" stroke-width="1"/>
<text x="792" y="66.4" fill="#1a5fb4" text-anchor="end">TP 116.35 (construit) = +30 % (procent real)</text> <text x="859.5" y="64.6" fill="#1a5fb4" style="font-weight:bold">4. ținta</text>
<polyline points="329.0,249.9 344.0,258.3 359.0,266.9 374.0,275.7 389.0,284.3 404.0,291.5 419.0,297.3 434.0,301.7 449.0,305.2 464.0,308.4 479.0,311.8 494.0,315.6 509.0,319.3 524.0,321.1 539.0,322.2 554.0,320.6 569.0,317.3 584.0,313.9 599.0,311.7 614.0,308.9 629.0,305.5 644.0,301.9 659.0,296.3 674.0,288.7 689.0,280.9 704.0,272.3 719.0,263.3 734.0,253.3 749.0,241.9 764.0,229.5" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="24" y1="332.8" x2="976" y2="332.8" stroke="#777" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="770" y="224" fill="#b06000">SMA-20</text> <text x="30" y="326.8" fill="#777">pivot lunar 86.00</text>
<line x1="44.0" y1="120.0" x2="44.0" y2="143.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="24" y1="369.2" x2="976" y2="369.2" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<rect x="39.5" y="123.2" width="9" height="16.0" fill="#c00"/> <text x="30" y="363.2" fill="#c00">stop 81.45 = 9 % sub intrare (procent real)</text>
<line x1="59.0" y1="136.0" x2="59.0" y2="155.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="24" y1="304.8" x2="976" y2="304.8" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
<rect x="54.5" y="139.2" width="9" height="12.0" fill="#c00"/> <text x="962" y="298.8" fill="#188a3e" text-anchor="end">intrare 89.50</text>
<line x1="74.0" y1="148.0" x2="74.0" y2="167.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="24" y1="240.4" x2="976" y2="240.4" stroke="#777" stroke-width="1.5" stroke-dasharray="2 3"/>
<rect x="69.5" y="151.2" width="9" height="12.0" fill="#c00"/> <text x="30" y="234.4" fill="#777">ținta 1:1 97.55</text>
<line x1="89.0" y1="160.0" x2="89.0" y2="183.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="24" y1="90.0" x2="976" y2="90.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
<rect x="84.5" y="163.2" width="9" height="16.0" fill="#c00"/> <text x="30" y="84.0" fill="#1a5fb4">116.35 = +30 % față de intrare (procent real)</text>
<line x1="104.0" y1="176.0" x2="104.0" y2="195.2" stroke="#1a1a1a" stroke-width="1.2"/> <polyline points="329.0,269.5 344.0,277.3 359.0,285.1 374.0,292.9 389.0,300.5 404.0,308.0 419.0,315.0 434.0,320.8 449.0,325.5 464.0,329.4 479.0,333.1 494.0,336.9 509.0,340.5 524.0,341.9 539.0,342.5 554.0,340.9 569.0,337.5 584.0,333.0 599.0,330.4 614.0,327.6 629.0,324.6 644.0,320.6 659.0,315.4 674.0,309.9 689.0,303.6 704.0,297.2 719.0,290.3 734.0,282.7 749.0,275.0 764.0,268.0 779.0,259.2 794.0,249.0 809.0,238.8 824.0,229.0 839.0,218.4 854.0,208.6 869.0,198.9 884.0,189.5" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
<rect x="99.5" y="179.2" width="9" height="12.0" fill="#c00"/> <text x="890" y="184" fill="#b06000">SMA-20</text>
<line x1="119.0" y1="188.0" x2="119.0" y2="207.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="44.0" y1="137.6" x2="44.0" y2="160.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="114.5" y="191.2" width="9" height="12.0" fill="#c00"/> <rect x="39.5" y="140.8" width="9" height="16.0" fill="#c00"/>
<line x1="134.0" y1="200.0" x2="134.0" y2="223.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="59.0" y1="153.6" x2="59.0" y2="172.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="129.5" y="203.2" width="9" height="16.0" fill="#c00"/> <rect x="54.5" y="156.8" width="9" height="12.0" fill="#c00"/>
<line x1="149.0" y1="216.0" x2="149.0" y2="235.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="74.0" y1="165.6" x2="74.0" y2="184.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="144.5" y="219.2" width="9" height="12.0" fill="#c00"/> <rect x="69.5" y="168.8" width="9" height="12.0" fill="#c00"/>
<line x1="164.0" y1="228.0" x2="164.0" y2="247.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="89.0" y1="177.6" x2="89.0" y2="200.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="159.5" y="231.2" width="9" height="12.0" fill="#c00"/> <rect x="84.5" y="180.8" width="9" height="16.0" fill="#c00"/>
<line x1="179.0" y1="240.0" x2="179.0" y2="259.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="104.0" y1="193.6" x2="104.0" y2="212.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="174.5" y="243.2" width="9" height="12.0" fill="#c00"/> <rect x="99.5" y="196.8" width="9" height="12.0" fill="#c00"/>
<line x1="194.0" y1="252.0" x2="194.0" y2="267.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="119.0" y1="205.6" x2="119.0" y2="224.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="189.5" y="255.2" width="9" height="8.0" fill="#c00"/> <rect x="114.5" y="208.8" width="9" height="12.0" fill="#c00"/>
<line x1="209.0" y1="260.0" x2="209.0" y2="279.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="134.0" y1="217.6" x2="134.0" y2="240.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="204.5" y="263.2" width="9" height="12.0" fill="#c00"/> <rect x="129.5" y="220.8" width="9" height="16.0" fill="#c00"/>
<line x1="224.0" y1="272.0" x2="224.0" y2="291.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="149.0" y1="233.6" x2="149.0" y2="252.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="219.5" y="275.2" width="9" height="12.0" fill="#c00"/> <rect x="144.5" y="236.8" width="9" height="12.0" fill="#c00"/>
<line x1="239.0" y1="284.0" x2="239.0" y2="307.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="164.0" y1="245.6" x2="164.0" y2="264.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="234.5" y="287.2" width="9" height="16.0" fill="#c00"/> <rect x="159.5" y="248.8" width="9" height="12.0" fill="#c00"/>
<line x1="254.0" y1="300.0" x2="254.0" y2="323.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="179.0" y1="257.6" x2="179.0" y2="276.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="249.5" y="303.2" width="9" height="16.0" fill="#c00"/> <rect x="174.5" y="260.8" width="9" height="12.0" fill="#c00"/>
<line x1="269.0" y1="316.0" x2="269.0" y2="344.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="194.0" y1="269.6" x2="194.0" y2="284.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="264.5" y="319.2" width="9" height="21.6" fill="#c00"/> <rect x="189.5" y="272.8" width="9" height="8.0" fill="#c00"/>
<line x1="284.0" y1="324.0" x2="284.0" y2="342.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="209.0" y1="277.6" x2="209.0" y2="296.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="279.5" y="327.2" width="9" height="13.6" fill="#188a3e"/> <rect x="204.5" y="280.8" width="9" height="12.0" fill="#c00"/>
<line x1="299.0" y1="308.0" x2="299.0" y2="331.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="224.0" y1="289.6" x2="224.0" y2="308.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="294.5" y="311.2" width="9" height="16.0" fill="#188a3e"/> <rect x="219.5" y="292.8" width="9" height="12.0" fill="#c00"/>
<line x1="314.0" y1="296.0" x2="314.0" y2="315.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="239.0" y1="301.6" x2="239.0" y2="324.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="309.5" y="299.2" width="9" height="12.0" fill="#188a3e"/> <rect x="234.5" y="304.8" width="9" height="16.0" fill="#c00"/>
<line x1="329.0" y1="292.0" x2="329.0" y2="303.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="254.0" y1="317.6" x2="254.0" y2="340.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="324.5" y="295.2" width="9" height="4.0" fill="#188a3e"/> <rect x="249.5" y="320.8" width="9" height="16.0" fill="#c00"/>
<line x1="344.0" y1="292.0" x2="344.0" y2="311.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="269.0" y1="333.6" x2="269.0" y2="356.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="339.5" y="295.2" width="9" height="12.0" fill="#c00"/> <rect x="264.5" y="336.8" width="9" height="16.0" fill="#c00"/>
<line x1="359.0" y1="304.0" x2="359.0" y2="327.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="284.0" y1="349.6" x2="284.0" y2="361.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="354.5" y="307.2" width="9" height="16.0" fill="#c00"/> <rect x="279.5" y="352.8" width="9" height="5.6" fill="#c00"/>
<line x1="374.0" y1="320.0" x2="374.0" y2="343.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="299.0" y1="341.6" x2="299.0" y2="358.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="369.5" y="323.2" width="9" height="16.0" fill="#c00"/> <rect x="294.5" y="344.8" width="9" height="13.6" fill="#188a3e"/>
<line x1="389.0" y1="336.0" x2="389.0" y2="351.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="314.0" y1="325.6" x2="314.0" y2="348.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="384.5" y="339.2" width="9" height="12.0" fill="#c00"/> <rect x="309.5" y="328.8" width="9" height="16.0" fill="#188a3e"/>
<line x1="404.0" y1="332.0" x2="404.0" y2="351.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="329.0" y1="313.6" x2="329.0" y2="332.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="399.5" y="335.2" width="9" height="16.0" fill="#188a3e"/> <rect x="324.5" y="316.8" width="9" height="12.0" fill="#188a3e"/>
<line x1="419.0" y1="316.0" x2="419.0" y2="339.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="344.0" y1="309.6" x2="344.0" y2="320.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="414.5" y="319.2" width="9" height="16.0" fill="#188a3e"/> <rect x="339.5" y="312.8" width="9" height="4.0" fill="#188a3e"/>
<line x1="434.0" y1="304.0" x2="434.0" y2="323.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="359.0" y1="309.6" x2="359.0" y2="328.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="429.5" y="307.2" width="9" height="12.0" fill="#188a3e"/> <rect x="354.5" y="312.8" width="9" height="12.0" fill="#c00"/>
<line x1="449.0" y1="297.6" x2="449.0" y2="311.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="374.0" y1="321.6" x2="374.0" y2="340.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="444.5" y="300.8" width="9" height="6.4" fill="#188a3e"/> <rect x="369.5" y="324.8" width="9" height="12.0" fill="#c00"/>
<line x1="464.0" y1="297.6" x2="464.0" y2="311.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="389.0" y1="333.6" x2="389.0" y2="352.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="459.5" y="300.8" width="9" height="6.4" fill="#c00"/> <rect x="384.5" y="336.8" width="9" height="12.0" fill="#c00"/>
<line x1="479.0" y1="304.0" x2="479.0" y2="327.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="404.0" y1="345.6" x2="404.0" y2="362.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="474.5" y="307.2" width="9" height="16.0" fill="#c00"/> <rect x="399.5" y="348.8" width="9" height="9.6" fill="#c00"/>
<line x1="494.0" y1="320.0" x2="494.0" y2="343.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="419.0" y1="355.2" x2="419.0" y2="364.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="489.5" y="323.2" width="9" height="16.0" fill="#c00"/> <rect x="414.5" y="358.4" width="9" height="4.0" fill="#c00"/>
<line x1="509.0" y1="336.0" x2="509.0" y2="351.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="434.0" y1="349.6" x2="434.0" y2="362.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="504.5" y="339.2" width="9" height="11.2" fill="#c00"/> <rect x="429.5" y="352.8" width="9" height="9.6" fill="#188a3e"/>
<line x1="524.0" y1="320.0" x2="524.0" y2="351.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="449.0" y1="339.2" x2="449.0" y2="356.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="519.5" y="323.2" width="9" height="27.2" fill="#188a3e"/> <rect x="444.5" y="342.4" width="9" height="10.4" fill="#188a3e"/>
<line x1="539.0" y1="312.8" x2="539.0" y2="329.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="464.0" y1="334.4" x2="464.0" y2="346.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="534.5" y="323.2" width="9" height="1.6" fill="#c00"/> <rect x="459.5" y="337.6" width="9" height="4.8" fill="#188a3e"/>
<line x1="554.0" y1="284.0" x2="554.0" y2="328.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="479.0" y1="334.4" x2="479.0" y2="351.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="549.5" y="287.2" width="9" height="36.8" fill="#188a3e"/> <rect x="474.5" y="337.6" width="9" height="9.6" fill="#c00"/>
<line x1="569.0" y1="272.0" x2="569.0" y2="291.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="494.0" y1="344.0" x2="494.0" y2="360.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="564.5" y="275.2" width="9" height="12.0" fill="#188a3e"/> <rect x="489.5" y="347.2" width="9" height="9.6" fill="#c00"/>
<line x1="584.0" y1="256.0" x2="584.0" y2="279.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="509.0" y1="353.6" x2="509.0" y2="369.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="579.5" y="259.2" width="9" height="16.0" fill="#188a3e"/> <rect x="504.5" y="356.8" width="9" height="8.8" fill="#c00"/>
<line x1="599.0" y1="256.0" x2="599.0" y2="271.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="524.0" y1="328.8" x2="524.0" y2="365.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="594.5" y="259.2" width="9" height="8.0" fill="#c00"/> <rect x="519.5" y="332.0" width="9" height="33.6" fill="#188a3e"/>
<line x1="614.0" y1="240.0" x2="614.0" y2="271.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="539.0" y1="326.4" x2="539.0" y2="341.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="609.5" y="243.2" width="9" height="24.0" fill="#188a3e"/> <rect x="534.5" y="332.0" width="9" height="1.6" fill="#c00"/>
<line x1="629.0" y1="224.0" x2="629.0" y2="247.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="554.0" y1="301.6" x2="554.0" y2="336.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="624.5" y="227.2" width="9" height="16.0" fill="#188a3e"/> <rect x="549.5" y="304.8" width="9" height="28.0" fill="#188a3e"/>
<line x1="644.0" y1="224.0" x2="644.0" y2="239.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="569.0" y1="281.6" x2="569.0" y2="304.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="639.5" y="227.2" width="9" height="8.0" fill="#c00"/> <rect x="564.5" y="284.8" width="9" height="20.0" fill="#188a3e"/>
<line x1="659.0" y1="208.0" x2="659.0" y2="239.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="584.0" y1="265.6" x2="584.0" y2="288.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="654.5" y="211.2" width="9" height="24.0" fill="#188a3e"/> <rect x="579.5" y="268.8" width="9" height="16.0" fill="#188a3e"/>
<line x1="674.0" y1="184.0" x2="674.0" y2="215.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="599.0" y1="265.6" x2="599.0" y2="304.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="669.5" y="187.2" width="9" height="24.0" fill="#188a3e"/> <rect x="594.5" y="268.8" width="9" height="24.0" fill="#c00"/>
<line x1="689.0" y1="184.0" x2="689.0" y2="199.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="614.0" y1="269.6" x2="614.0" y2="296.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="684.5" y="187.2" width="9" height="8.0" fill="#c00"/> <rect x="609.5" y="272.8" width="9" height="20.0" fill="#188a3e"/>
<line x1="704.0" y1="160.0" x2="704.0" y2="199.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="629.0" y1="253.6" x2="629.0" y2="276.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="699.5" y="163.2" width="9" height="32.0" fill="#188a3e"/> <rect x="624.5" y="256.8" width="9" height="16.0" fill="#188a3e"/>
<line x1="719.0" y1="136.0" x2="719.0" y2="167.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="644.0" y1="229.6" x2="644.0" y2="260.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="714.5" y="139.2" width="9" height="24.0" fill="#188a3e"/> <rect x="639.5" y="232.8" width="9" height="24.0" fill="#188a3e"/>
<line x1="734.0" y1="104.0" x2="734.0" y2="143.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="659.0" y1="217.6" x2="659.0" y2="236.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="729.5" y="107.2" width="9" height="32.0" fill="#188a3e"/> <rect x="654.5" y="220.8" width="9" height="12.0" fill="#188a3e"/>
<line x1="749.0" y1="69.2" x2="749.0" y2="111.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="674.0" y1="217.6" x2="674.0" y2="231.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="744.5" y="72.4" width="9" height="34.8" fill="#188a3e"/> <rect x="669.5" y="220.8" width="9" height="6.4" fill="#c00"/>
<line x1="764.0" y1="56.0" x2="764.0" y2="76.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="689.0" y1="219.2" x2="689.0" y2="231.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="759.5" y="59.2" width="9" height="13.2" fill="#188a3e"/> <rect x="684.5" y="222.4" width="9" height="4.8" fill="#188a3e"/>
<line x1="24" y1="447.6" x2="806" y2="447.6" stroke="#888"/> <line x1="704.0" y1="219.2" x2="704.0" y2="233.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="39.5" y="408.3" width="9" height="39.3" fill="#c00" opacity="0.55"/> <rect x="699.5" y="222.4" width="9" height="7.2" fill="#c00"/>
<rect x="54.5" y="410.5" width="9" height="37.1" fill="#c00" opacity="0.55"/> <line x1="719.0" y1="221.6" x2="719.0" y2="233.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="69.5" y="413.3" width="9" height="34.3" fill="#c00" opacity="0.55"/> <rect x="714.5" y="224.8" width="9" height="4.8" fill="#188a3e"/>
<rect x="84.5" y="411.9" width="9" height="35.7" fill="#c00" opacity="0.55"/> <line x1="734.0" y1="197.6" x2="734.0" y2="228.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="99.5" y="415.5" width="9" height="32.1" fill="#c00" opacity="0.55"/> <rect x="729.5" y="200.8" width="9" height="24.0" fill="#188a3e"/>
<rect x="114.5" y="414.0" width="9" height="33.6" fill="#c00" opacity="0.55"/> <line x1="749.0" y1="185.6" x2="749.0" y2="204.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="129.5" y="416.2" width="9" height="31.4" fill="#c00" opacity="0.55"/> <rect x="744.5" y="188.8" width="9" height="12.0" fill="#188a3e"/>
<rect x="144.5" y="414.7" width="9" height="32.9" fill="#c00" opacity="0.55"/> <line x1="764.0" y1="185.6" x2="764.0" y2="200.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="159.5" y="417.6" width="9" height="30.0" fill="#c00" opacity="0.55"/> <rect x="759.5" y="188.8" width="9" height="8.0" fill="#c00"/>
<rect x="174.5" y="416.2" width="9" height="31.4" fill="#c00" opacity="0.55"/> <line x1="779.0" y1="169.6" x2="779.0" y2="200.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="189.5" y="419.0" width="9" height="28.6" fill="#c00" opacity="0.55"/> <rect x="774.5" y="172.8" width="9" height="24.0" fill="#188a3e"/>
<rect x="204.5" y="417.6" width="9" height="30.0" fill="#c00" opacity="0.55"/> <line x1="794.0" y1="149.6" x2="794.0" y2="176.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="219.5" y="420.5" width="9" height="27.1" fill="#c00" opacity="0.55"/> <rect x="789.5" y="152.8" width="9" height="20.0" fill="#188a3e"/>
<rect x="234.5" y="418.3" width="9" height="29.3" fill="#c00" opacity="0.55"/> <line x1="809.0" y1="149.6" x2="809.0" y2="164.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="249.5" y="406.2" width="9" height="41.4" fill="#c00" opacity="0.55"/> <rect x="804.5" y="152.8" width="9" height="8.0" fill="#c00"/>
<rect x="264.5" y="403.3" width="9" height="44.3" fill="#c00" opacity="0.55"/> <line x1="824.0" y1="133.6" x2="824.0" y2="164.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="279.5" y="411.9" width="9" height="35.7" fill="#188a3e" opacity="0.55"/> <rect x="819.5" y="136.8" width="9" height="24.0" fill="#188a3e"/>
<rect x="294.5" y="414.7" width="9" height="32.9" fill="#188a3e" opacity="0.55"/> <line x1="839.0" y1="117.6" x2="839.0" y2="140.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="309.5" y="416.2" width="9" height="31.4" fill="#188a3e" opacity="0.55"/> <rect x="834.5" y="120.8" width="9" height="16.0" fill="#188a3e"/>
<rect x="324.5" y="416.9" width="9" height="30.7" fill="#188a3e" opacity="0.55"/> <line x1="854.0" y1="105.6" x2="854.0" y2="124.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="339.5" y="415.5" width="9" height="32.1" fill="#c00" opacity="0.55"/> <rect x="849.5" y="108.8" width="9" height="12.0" fill="#188a3e"/>
<rect x="354.5" y="416.2" width="9" height="31.4" fill="#c00" opacity="0.55"/> <line x1="869.0" y1="86.8" x2="869.0" y2="112.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="369.5" y="414.0" width="9" height="33.6" fill="#c00" opacity="0.55"/> <rect x="864.5" y="90.0" width="9" height="18.8" fill="#188a3e"/>
<rect x="384.5" y="400.5" width="9" height="47.1" fill="#c00" opacity="0.55"/> <line x1="884.0" y1="77.6" x2="884.0" y2="94.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="399.5" y="408.3" width="9" height="39.3" fill="#188a3e" opacity="0.55"/> <rect x="879.5" y="80.8" width="9" height="9.2" fill="#188a3e"/>
<rect x="414.5" y="411.9" width="9" height="35.7" fill="#188a3e" opacity="0.55"/> <line x1="24" y1="546.2" x2="976" y2="546.2" stroke="#888"/>
<rect x="429.5" y="414.0" width="9" height="33.6" fill="#188a3e" opacity="0.55"/> <rect x="39.5" y="506.1" width="9" height="40.1" fill="#c00" opacity="0.55"/>
<rect x="444.5" y="415.5" width="9" height="32.1" fill="#188a3e" opacity="0.55"/> <rect x="54.5" y="508.3" width="9" height="37.9" fill="#c00" opacity="0.55"/>
<rect x="459.5" y="416.2" width="9" height="31.4" fill="#c00" opacity="0.55"/> <rect x="69.5" y="511.2" width="9" height="35.0" fill="#c00" opacity="0.55"/>
<rect x="474.5" y="417.6" width="9" height="30.0" fill="#c00" opacity="0.55"/> <rect x="84.5" y="509.7" width="9" height="36.5" fill="#c00" opacity="0.55"/>
<rect x="489.5" y="416.9" width="9" height="30.7" fill="#c00" opacity="0.55"/> <rect x="99.5" y="513.4" width="9" height="32.8" fill="#c00" opacity="0.55"/>
<rect x="504.5" y="415.5" width="9" height="32.1" fill="#c00" opacity="0.55"/> <rect x="114.5" y="511.9" width="9" height="34.3" fill="#c00" opacity="0.55"/>
<rect x="519.5" y="404.7" width="9" height="42.9" fill="#188a3e" opacity="0.55"/> <rect x="129.5" y="514.1" width="9" height="32.1" fill="#c00" opacity="0.55"/>
<rect x="534.5" y="396.2" width="9" height="51.4" fill="#c00" opacity="0.55"/> <rect x="144.5" y="512.7" width="9" height="33.5" fill="#c00" opacity="0.55"/>
<rect x="549.5" y="387.6" width="9" height="60.0" fill="#188a3e" opacity="0.55"/> <rect x="159.5" y="515.6" width="9" height="30.6" fill="#c00" opacity="0.55"/>
<rect x="564.5" y="391.9" width="9" height="55.7" fill="#188a3e" opacity="0.55"/> <rect x="174.5" y="514.1" width="9" height="32.1" fill="#c00" opacity="0.55"/>
<rect x="579.5" y="397.6" width="9" height="50.0" fill="#188a3e" opacity="0.55"/> <rect x="189.5" y="517.0" width="9" height="29.2" fill="#c00" opacity="0.55"/>
<rect x="594.5" y="401.9" width="9" height="45.7" fill="#c00" opacity="0.55"/> <rect x="204.5" y="515.6" width="9" height="30.6" fill="#c00" opacity="0.55"/>
<rect x="609.5" y="404.7" width="9" height="42.9" fill="#188a3e" opacity="0.55"/> <rect x="219.5" y="518.5" width="9" height="27.7" fill="#c00" opacity="0.55"/>
<rect x="624.5" y="406.2" width="9" height="41.4" fill="#188a3e" opacity="0.55"/> <rect x="234.5" y="516.3" width="9" height="29.9" fill="#c00" opacity="0.55"/>
<rect x="639.5" y="409.0" width="9" height="38.6" fill="#c00" opacity="0.55"/> <rect x="249.5" y="503.9" width="9" height="42.3" fill="#c00" opacity="0.55"/>
<rect x="654.5" y="410.5" width="9" height="37.1" fill="#188a3e" opacity="0.55"/> <rect x="264.5" y="501.0" width="9" height="45.2" fill="#c00" opacity="0.55"/>
<rect x="669.5" y="407.6" width="9" height="40.0" fill="#188a3e" opacity="0.55"/> <rect x="279.5" y="496.6" width="9" height="49.6" fill="#c00" opacity="0.55"/>
<rect x="684.5" y="404.7" width="9" height="42.9" fill="#c00" opacity="0.55"/> <rect x="294.5" y="509.7" width="9" height="36.5" fill="#188a3e" opacity="0.55"/>
<rect x="699.5" y="400.5" width="9" height="47.1" fill="#188a3e" opacity="0.55"/> <rect x="309.5" y="512.7" width="9" height="33.5" fill="#188a3e" opacity="0.55"/>
<rect x="714.5" y="394.7" width="9" height="52.9" fill="#188a3e" opacity="0.55"/> <rect x="324.5" y="514.1" width="9" height="32.1" fill="#188a3e" opacity="0.55"/>
<rect x="729.5" y="389.0" width="9" height="58.6" fill="#188a3e" opacity="0.55"/> <rect x="339.5" y="514.8" width="9" height="31.4" fill="#188a3e" opacity="0.55"/>
<rect x="744.5" y="383.3" width="9" height="64.3" fill="#188a3e" opacity="0.55"/> <rect x="354.5" y="513.4" width="9" height="32.8" fill="#c00" opacity="0.55"/>
<rect x="759.5" y="377.6" width="9" height="70.0" fill="#188a3e" opacity="0.55"/> <rect x="369.5" y="514.1" width="9" height="32.1" fill="#c00" opacity="0.55"/>
<text x="24" y="371.6" fill="#555">volum</text> <rect x="384.5" y="511.9" width="9" height="34.3" fill="#c00" opacity="0.55"/>
<text x="269.0" y="364.0" fill="#c00" text-anchor="middle" style="font-weight:bold">bottom 1 82.40</text> <rect x="399.5" y="512.7" width="9" height="33.5" fill="#c00" opacity="0.55"/>
<text x="389.0" y="365.6" fill="#c00" text-anchor="middle" style="font-weight:bold">bottom 2 81.45</text> <rect x="414.5" y="513.4" width="9" height="32.8" fill="#c00" opacity="0.55"/>
<text x="509.0" y="365.6" fill="#c00" text-anchor="middle" style="font-weight:bold">bottom 3 81.45</text> <rect x="429.5" y="511.9" width="9" height="34.3" fill="#188a3e" opacity="0.55"/>
<text x="539.0" y="302.8" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text> <rect x="444.5" y="508.3" width="9" height="37.9" fill="#188a3e" opacity="0.55"/>
<text x="554.0" y="260.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare (intrare)</text> <rect x="459.5" y="513.4" width="9" height="32.8" fill="#188a3e" opacity="0.55"/>
<text x="776.0" y="46.0" fill="#188a3e" text-anchor="end" style="font-weight:bold">higher high — TP atins</text> <rect x="474.5" y="514.1" width="9" height="32.1" fill="#c00" opacity="0.55"/>
<text x="24" y="469.6" fill="#c00">bara 33 = doji: o 85.00, c 84.90, h 86.30, l 84.20 — corp mic exact pe pivotul monthly 86.00 (indecizie la suport)</text> <rect x="489.5" y="511.2" width="9" height="35.0" fill="#c00" opacity="0.55"/>
<text x="24" y="495" fill="#555">Procentele (stop 9 %, +30 %) sunt ale cursului; nivelurile de preț sunt construite de sumarizator (18_2025-09-23.md:713).</text> <rect x="504.5" y="495.2" width="9" height="51.0" fill="#c00" opacity="0.55"/>
<rect x="519.5" y="501.0" width="9" height="45.2" fill="#188a3e" opacity="0.55"/>
<rect x="534.5" y="503.9" width="9" height="42.3" fill="#c00" opacity="0.55"/>
<rect x="549.5" y="482.0" width="9" height="64.2" fill="#188a3e" opacity="0.55"/>
<rect x="564.5" y="490.8" width="9" height="55.4" fill="#188a3e" opacity="0.55"/>
<rect x="579.5" y="495.2" width="9" height="51.0" fill="#188a3e" opacity="0.55"/>
<rect x="594.5" y="503.9" width="9" height="42.3" fill="#c00" opacity="0.55"/>
<rect x="609.5" y="501.0" width="9" height="45.2" fill="#188a3e" opacity="0.55"/>
<rect x="624.5" y="498.1" width="9" height="48.1" fill="#188a3e" opacity="0.55"/>
<rect x="639.5" y="493.7" width="9" height="52.5" fill="#188a3e" opacity="0.55"/>
<rect x="654.5" y="495.2" width="9" height="51.0" fill="#188a3e" opacity="0.55"/>
<rect x="669.5" y="514.1" width="9" height="32.1" fill="#c00" opacity="0.55"/>
<rect x="684.5" y="517.0" width="9" height="29.2" fill="#188a3e" opacity="0.55"/>
<rect x="699.5" y="518.5" width="9" height="27.7" fill="#c00" opacity="0.55"/>
<rect x="714.5" y="515.6" width="9" height="30.6" fill="#188a3e" opacity="0.55"/>
<rect x="729.5" y="492.2" width="9" height="54.0" fill="#188a3e" opacity="0.55"/>
<rect x="744.5" y="495.2" width="9" height="51.0" fill="#188a3e" opacity="0.55"/>
<rect x="759.5" y="499.5" width="9" height="46.7" fill="#c00" opacity="0.55"/>
<rect x="774.5" y="496.6" width="9" height="49.6" fill="#188a3e" opacity="0.55"/>
<rect x="789.5" y="493.7" width="9" height="52.5" fill="#188a3e" opacity="0.55"/>
<rect x="804.5" y="498.1" width="9" height="48.1" fill="#c00" opacity="0.55"/>
<rect x="819.5" y="492.2" width="9" height="54.0" fill="#188a3e" opacity="0.55"/>
<rect x="834.5" y="489.3" width="9" height="56.9" fill="#188a3e" opacity="0.55"/>
<rect x="849.5" y="486.4" width="9" height="59.8" fill="#188a3e" opacity="0.55"/>
<rect x="864.5" y="480.6" width="9" height="65.6" fill="#188a3e" opacity="0.55"/>
<rect x="879.5" y="476.2" width="9" height="70.0" fill="#188a3e" opacity="0.55"/>
<text x="24" y="470.2" fill="#555">volum</text>
<text x="284.0" y="381.6" fill="#c00" text-anchor="middle" style="font-weight:bold">test 1 · 82.40</text>
<text x="419.0" y="383.2" fill="#c00" text-anchor="middle" style="font-weight:bold">test 2 · 82.00</text>
<line x1="404.0" y1="274.8" x2="546.1" y2="299.4" stroke="#188a3e" stroke-width="1.8"/>
<polygon points="554.0,300.8 545.4,303.4 546.8,295.5" fill="#188a3e"/>
<text x="404.0" y="255.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">aici intri, la close 89.50:</text>
<text x="404.0" y="269.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">abia acum știi că au câștigat cumpărătorii</text>
<line x1="469.0" y1="399.2" x2="502.3" y2="377.6" stroke="#c00" stroke-width="1.8"/>
<polygon points="509.0,373.2 504.5,380.9 500.1,374.2" fill="#c00"/>
<text x="469.0" y="413.2" fill="#c00" text-anchor="middle" style="font-weight:bold">al treilea minim: 81.45,</text>
<text x="469.0" y="427.2" fill="#c00" text-anchor="middle" style="font-weight:bold">fără o nouă atingere a pivotului</text>
<text x="469.0" y="441.2" fill="#c00" text-anchor="middle" style="font-weight:bold">aici pui stopul, sub minime</text>
<line x1="709.0" y1="390.0" x2="605.4" y2="312.8" stroke="#188a3e" stroke-width="1.8"/>
<polygon points="599.0,308.0 607.8,309.6 603.0,316.0" fill="#188a3e"/>
<text x="709.0" y="404.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">retest: cade înapoi pe intrare</text>
<text x="709.0" y="418.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">și ține — trendul e sănătos</text>
<line x1="669.0" y1="177.6" x2="685.2" y2="208.1" stroke="#188a3e" stroke-width="1.8"/>
<polygon points="689.0,215.2 681.7,210.0 688.8,206.3" fill="#188a3e"/>
<text x="669.0" y="158.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">aici se odihnește, nu se strică:</text>
<text x="669.0" y="172.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">bull flag, pe volum mic</text>
<line x1="800.5" y1="50.0" x2="853.8" y2="85.6" stroke="#1a5fb4" stroke-width="1.8"/>
<polygon points="860.5,90.0 851.6,88.9 856.1,82.2" fill="#1a5fb4"/>
<text x="796.5" y="47.0" fill="#1a5fb4" text-anchor="end" style="font-weight:bold">a ajuns la 116.35: +30 % în 21 de zile de bursă,</text>
<text x="796.5" y="61.0" fill="#1a5fb4" text-anchor="end" style="font-weight:bold">cam 3,3R din cât ai riscat</text>
<text x="24" y="568.2" fill="#c00">doji = corp mic (o 86.10, c 86.00): cumpărătorii și vânzătorii sunt la egalitate, exact pe pivotul lunar 86.00</text>
<text x="24" y="585.2" fill="#188a3e">ținta 1:1 (97.55) e atinsă pe bara 40: acolo vinzi o treime, restul merge mai departe — de asta nu vinzi tot la 1:1</text>
<text x="24" y="610" fill="#555">Procentele (stop 9 %, +30 %) sunt ale cursului; nivelurile de preț sunt puse de sumarizator.</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -3,9 +3,9 @@
Citește `gen/strategii/buy_doji_locatie.spec.txt`. Două panouri alăturate cu Citește `gen/strategii/buy_doji_locatie.spec.txt`. Două panouri alăturate cu
ACEEAȘI serie de 10 bare, pe aceeași scară și aceeași axă de preț (candelele ACEEAȘI serie de 10 bare, pe aceeași scară și aceeași axă de preț (candelele
stau la aceleași y). Stânga: pivot monthly S1 49.00, la 0,41 % sub low-ul stau la aceleași y). Stânga: pivot lunar 49.00, la 0,51 % sub low-ul
dojiului. Dreapta: S1 46.00 și PP 53.50 — cel mai apropiat nivel sub doji e dojiului. Dreapta: S1 46.00 și PP 53.50 — cel mai apropiat nivel sub doji e
la 6,96 %. Nivelurile se desenează de mână, cu coordonate absolute (liniile la 7,07 %. Nivelurile se desenează de mână, cu coordonate absolute (liniile
din Chart pornesc mereu de la x=24, ar trece peste panoul vecin). din Chart pornesc mereu de la x=24, ar trece peste panoul vecin).
Rulare: python3 gen/strategii/buy_doji_locatie.py Rulare: python3 gen/strategii/buy_doji_locatie.py
@@ -13,13 +13,13 @@ Rulare: python3 gen/strategii/buy_doji_locatie.py
import re import re
import sys import sys
sys.path.insert(0, "/workspace/atm-curs-dl") sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Chart, Mark, from_closes # noqa: E402 from svg_candles import Arrow, Chart, Mark, from_closes # noqa: E402
OUT = "/workspace/atm-curs-dl/gen/strategii/buy_doji_locatie.svg" OUT = "/workspace/atm-curs-dl/gen/strategii/buy_doji_locatie.svg"
CLOSES = [52.20, 51.40, 50.60, 49.65, 49.60, 49.90, 50.40, 50.80, 51.10, 51.50] CLOSES = [52.20, 51.40, 50.60, 49.65, 49.60, 49.90, 50.40, 50.80, 51.10, 51.50]
wicks = [(0.15, 0.15)] * len(CLOSES) wicks = [(0.15, 0.15)] * len(CLOSES)
wicks[4] = (0.45, 0.40) # doji: h 50.10 / l 49.20 wicks[4] = (0.45, 0.35) # doji: h 50.10 / l 49.25
cds = from_closes(CLOSES, wicks=wicks, start=53.00) cds = from_closes(CLOSES, wicks=wicks, start=53.00)
doji = cds[4] doji = cds[4]
S1_DA, S1_NU, PP_NU = 49.00, 46.00, 53.50 S1_DA, S1_NU, PP_NU = 49.00, 46.00, 53.50
@@ -28,16 +28,16 @@ NIVELURI_NU = [S1_NU, PP_NU]
# --- assert-urile din spec --------------------------------------------------- # --- assert-urile din spec ---------------------------------------------------
for i in range(1, len(cds)): # 1 for i in range(1, len(cds)): # 1
assert cds[i].o == cds[i - 1].c, f"open[{i}] != close[{i-1}]" assert cds[i].o == cds[i - 1].c, f"open[{i}] != close[{i-1}]"
assert abs(doji.h - 50.10) < 1e-9 and abs(doji.l - 49.20) < 1e-9 assert abs(doji.h - 50.10) < 1e-9 and abs(doji.l - 49.25) < 1e-9
assert abs(doji.o - doji.c) <= 0.10 * (doji.h - doji.l), "bara 4 nu e doji" assert abs(doji.o - doji.c) <= 0.10 * (doji.h - doji.l), "bara 4 nu e doji"
assert cds[6].c > doji.h, "bara 6 nu confirmă" assert cds[6].c > doji.h, "bara 6 nu confirmă"
d_da = round((doji.l - S1_DA) / S1_DA * 100, 2) # 2 d_da = round((doji.l - S1_DA) / S1_DA * 100, 2) # 2
assert d_da == 0.41 and d_da <= 2 assert d_da == 0.51 and d_da <= 2
d_nu = round((doji.l - S1_NU) / S1_NU * 100, 2) # 3 d_nu = round((doji.l - S1_NU) / S1_NU * 100, 2) # 3
assert d_nu == 6.96 and d_nu > 2 and (PP_NU - doji.h) > 0 assert d_nu == 7.07 and d_nu > 2 and (PP_NU - doji.h) > 0
assert not any(S1_NU < p < PP_NU for p in NIVELURI_NU) assert not any(S1_NU < p < PP_NU for p in NIVELURI_NU)
d_pp = round((PP_NU - doji.l) / doji.l * 100, 2) # PP e deasupra, mai departe d_pp = round((PP_NU - doji.l) / doji.l * 100, 2) # PP e deasupra, mai departe
assert d_pp == 8.74 and d_pp > d_nu assert d_pp == 8.63 and d_pp > d_nu
# --- layout: două panouri, aceeași axă -------------------------------------- # --- layout: două panouri, aceeași axă --------------------------------------
BLUE, GREEN, RED, ORANGE, GREY = "#1a5fb4", "#188a3e", "#c00", "#b06000", "#555" BLUE, GREEN, RED, ORANGE, GREY = "#1a5fb4", "#188a3e", "#c00", "#b06000", "#555"
@@ -45,61 +45,67 @@ W, PW = 760, 350 # lățime totală, lățime panou
PX = [24, 24 + PW + 28] # x-ul stâng al fiecărui panou PX = [24, 24 + PW + 28] # x-ul stâng al fiecărui panou
SCALE, TOP = 36.0, 96 # px/unitate și y-ul celui mai mare preț SCALE, TOP = 36.0, 96 # px/unitate și y-ul celui mai mare preț
ARR = {
PX[0]: Arrow(8, "pivot lunar: nivel urmărit\nde mulți — aici apar\ncumpărătorii",
price=S1_DA, where="below", color=BLUE),
PX[1]: Arrow(4, "aceeași formă, dar nimic sub el\nnu are cine să-l susțină",
where="below", color=RED, dx=100),
}
charts = [] charts = []
for px in PX: for px in PX:
ch = Chart(candles=cds, marks=[Mark(4, "doji", ORANGE, "above", dy=-16), ch = Chart(candles=cds, marks=[Mark(4, "doji", ORANGE, "above", dy=-16),
Mark(6, "confirmare", GREEN, "above", dy=-26)], Mark(6, "confirmare", GREEN, "above", dy=-26)],
arrows=[ARR[px]],
scale=SCALE, gap=17, body_w=10, left=px + 34, width=px + PW, top=TOP) scale=SCALE, gap=17, body_w=10, left=px + 34, width=px + PW, top=TOP)
body = ch.render() # `_render()`, nu `render()`: al doilea restaurează top/left, iar zonele și
# etichetele desenate de mână ar pica deplasate față de body-ul randat
body = ch._render()
assert f'viewBox="0 0 {px + PW} ' in body, "textul unei săgeți iese din panou"
assert (ch.top, ch.left) == (TOP, px + 34), "Chart a mutat graficul: panourile s-ar dezalinia"
charts.append((ch, body.split(">", 1)[1].rsplit("</svg>", 1)[0].strip())) charts.append((ch, body.split(">", 1)[1].rsplit("</svg>", 1)[0].strip()))
(ch_da, body_da), (ch_nu, body_nu) = charts (ch_da, body_da), (ch_nu, body_nu) = charts
assert ch_da.scale == ch_nu.scale and ch_da._pmax == ch_nu._pmax, "scări diferite" # 4 assert ch_da.scale == ch_nu.scale and ch_da._pmax == ch_nu._pmax, "scări diferite" # 4
y = ch_da._y # axa e comună: același y pe ambele panouri y = ch_da._y # axa e comună: același y pe ambele panouri
def level(px, price, text, color): def level(px, price, text, color, below=False):
yy = y(price) yy = y(price)
ty, anchor, tx = (yy + 14, "start", px + 6) if below else (yy - 6, "end", px + PW - 4)
return [f'<line x1="{px}" y1="{yy:.1f}" x2="{px + PW}" y2="{yy:.1f}" stroke="{color}" ' return [f'<line x1="{px}" y1="{yy:.1f}" x2="{px + PW}" y2="{yy:.1f}" stroke="{color}" '
f'stroke-width="1.5" stroke-dasharray="4 3"/>', f'stroke-width="1.5" stroke-dasharray="4 3"/>',
f'<text x="{px + PW - 4}" y="{yy - 6:.1f}" fill="{color}" text-anchor="end">{text}</text>'] f'<text x="{tx}" y="{ty:.1f}" fill="{color}" text-anchor="{anchor}">{text}</text>']
def arrow(x, y1, y2, color): # săgeată dublă verticală între y1 și y2 def zone(px, p_top, p_bot, label, color, label_at_bottom=False):
return [f'<line x1="{x:.1f}" y1="{y1:.1f}" x2="{x:.1f}" y2="{y2:.1f}" stroke="{color}" stroke-width="1.5"/>', """Dreptunghi de evidențiere pe toată lățimea panoului, între două prețuri."""
f'<polygon points="{x - 4:.1f},{y1 + 7:.1f} {x + 4:.1f},{y1 + 7:.1f} {x:.1f},{y1:.1f}" fill="{color}"/>', y0, y1 = y(p_top), y(p_bot)
f'<polygon points="{x - 4:.1f},{y2 - 7:.1f} {x + 4:.1f},{y2 - 7:.1f} {x:.1f},{y2:.1f}" fill="{color}"/>'] ly, anchor, lx = ((y1 - 12, "start", px + 8) if label_at_bottom
else (y0 - 6, "end", px + PW - 4))
return [f'<rect x="{px}" y="{y0:.1f}" width="{PW}" height="{y1 - y0:.1f}" fill="{color}" '
f'fill-opacity="0.12" stroke="{color}" stroke-width="1"/>',
f'<text x="{lx}" y="{ly:.1f}" fill="{color}" text-anchor="{anchor}" '
f'style="font-weight:bold">{label}</text>']
xd_da, xd_nu = ch_da._cx(4), ch_nu._cx(4) y_bot = y(S1_NU)
y_low, y_bot = y(doji.l), y(S1_NU)
ly = y(S1_DA) + 24 # textul de distanță, sub linia 49.00
parts = [ parts = [
f'<svg viewBox="0 0 {W} {y_bot + 62:.0f}" xmlns="http://www.w3.org/2000/svg" ' f'<svg viewBox="0 0 {W} {y_bot + 62:.0f}" xmlns="http://www.w3.org/2000/svg" '
f'style="width:100%;height:auto;font:12px sans-serif">', f'style="width:100%;height:auto;font:12px sans-serif">',
f'<text x="24" y="22" fill="#333" style="font-weight:bold">' f'<text x="24" y="22" fill="#333" style="font-weight:bold">'
f'Doji la nivel vs. doji în aer — daily, pivoți monthly (exemplu construit)</text>', f'Doji la nivel vs. doji în aer — daily, pivoți lunari (exemplu construit)</text>',
f'<text x="{PX[0]}" y="48" fill="{GREEN}" style="font-weight:bold">DA — doji la nivel</text>', f'<text x="{PX[0]}" y="48" fill="{GREEN}" style="font-weight:bold">DA — doji la nivel</text>',
f'<text x="{PX[1]}" y="48" fill="{RED}" style="font-weight:bold">NU — doji în aer</text>', f'<text x="{PX[1]}" y="48" fill="{RED}" style="font-weight:bold">NU — doji în aer</text>',
f'<line x1="{PX[1] - 14}" y1="36" x2="{PX[1] - 14}" y2="{y_bot + 8:.0f}" stroke="#ccc"/>', f'<line x1="{PX[1] - 14}" y1="36" x2="{PX[1] - 14}" y2="{y_bot + 8:.0f}" stroke="#ccc"/>',
*level(PX[0], S1_DA, "pivot monthly S1 49.00", BLUE), *zone(PX[0], doji.l, S1_DA, f"{d_da:.2f} % — la nivel".replace(".", ","), GREEN),
*level(PX[1], PP_NU, "PP 53.50", BLUE), *zone(PX[1], doji.l, S1_NU, f"gol de {d_nu:.2f} % sub doji — doji în aer".replace(".", ","),
*level(PX[1], S1_NU, "S1 46.00", BLUE), RED, label_at_bottom=True),
*level(PX[0], S1_DA, "pivotul lunar 49.00", BLUE, below=True),
*level(PX[1], PP_NU, "pivotul lunar 53.50", BLUE),
*level(PX[1], S1_NU, "pivotul lunar 46.00", BLUE, below=True),
body_da, body_nu, body_da, body_nu,
# DA: low-ul dojiului atinge practic linia f'<text x="24" y="{y_bot + 30:.0f}" fill="{GREY}">daily: e „la nivel" dacă low-ul '
f'<circle cx="{xd_da:.1f}" cy="{y_low:.1f}" r="5" fill="none" stroke="{BLUE}" stroke-width="1.5"/>', f'dojiului e la cel mult 1-2 % de pivotul lunar (aici {d_da:.2f} %; în dreapta '
f'<text x="{PX[0] + 8}" y="{ly:.1f}" fill="{BLUE}">low 49.20 = +0,41 % față de 49.00</text>', f'{d_nu:.2f} %).</text>'.replace("0.51 %", "0,51 %").replace("7.07 %", "7,07 %"),
f'<text x="{PX[0] + 8}" y="{ly + 16:.1f}" fill="{GREEN}" style="font-weight:bold">'
f'→ la nivel (daily: ≤ 1-2 %)</text>',
# NU: distanța până la cel mai apropiat nivel
*arrow(xd_nu, y_low + 3, y_bot - 2, RED),
f'<text x="{xd_nu + 12:.1f}" y="{(y_low + y_bot) / 2 - 8:.1f}" fill="{BLUE}">'
f'cel mai apropiat nivel: 46.00, la 6,96 %</text>',
f'<text x="{xd_nu + 12:.1f}" y="{(y_low + y_bot) / 2 + 8:.1f}" fill="{RED}" '
f'style="font-weight:bold">→ doji în aer</text>',
f'<text x="{xd_nu + 12:.1f}" y="{(y_low + y_bot) / 2 + 26:.1f}" fill="{GREY}">'
f'(PP 53.50 e deasupra, la 8,74 % de low)</text>',
f'<text x="24" y="{y_bot + 30:.0f}" fill="{GREY}">60 min: prag ≤ 0,5 %, pivoți weekly · '
f'daily: 1-2 %, pivoți monthly · weekly: pivoți quarterly</text>',
f'<text x="24" y="{y_bot + 48:.0f}" fill="{GREY}">Aceeași serie, aceeași scară; ' f'<text x="24" y="{y_bot + 48:.0f}" fill="{GREY}">Aceeași serie, aceeași scară; '
f'nivelurile 49.00 / 46.00 / 53.50 sunt construite.</text>', f'nivelurile 49.00 / 46.00 / 53.50 sunt construite.</text>',
"</svg>", "</svg>",

View File

@@ -3,39 +3,44 @@ SPEC DIAGRAMĂ — buy_doji_locatie
tip: PRET, două panouri cu ACEEAȘI serie, niveluri diferite tip: PRET, două panouri cu ACEEAȘI serie, niveluri diferite
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 4 destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 4
cheie markdown: <!-- DIAGRAMA: locatie --> cheie markdown: <!-- DIAGRAMA: locatie -->
titlu SVG: „Doji la nivel vs. doji în aer — daily, pivoți monthly (exemplu construit)" titlu SVG: „Doji la nivel vs. doji în aer — daily, pivoți lunari (exemplu construit)"
stil: candele lipite (gap 15-18, body_w 9-10), fără volum; open = close anterior. stil: candele lipite (gap 15-18, body_w 9-10), fără volum; open = close anterior.
CE TREBUIE SĂ DEMONSTREZE CE TREBUIE SĂ DEMONSTREZE
------------------------- -------------------------
Aceeași formă (trend → doji → confirmare), dar în stânga low-ul dojiului e Aceeași formă (trend → doji → confirmare), dar în stânga low-ul dojiului e
la 0,41 % de pivotul monthly (sub pragul de 1-2 % pe daily), iar în dreapta la 0,51 % de pivotul lunar (sub pragul de 1-2 % pe daily), iar în dreapta
cel mai apropiat nivel e la 6,96 % dedesubt. Pattern-ul nu te ajută să vezi cel mai apropiat nivel e la 7,07 % dedesubt. Pattern-ul nu te ajută să vezi
diferența; doar măsurătoarea. diferența; doar măsurătoarea.
SERIA (identică pe ambele panouri, 10 bare) SERIA (identică pe ambele panouri, 10 bare)
------------------------------------------- -------------------------------------------
Seria panoului DA din buy_doji_fereastra.spec.txt, extinsă cu 3 bare: Seria panoului DA din buy_doji_fereastra.spec.txt, extinsă cu 3 bare:
close-uri 52.20, 51.40, 50.60, 49.65, 49.60 (doji: o 49.65 h 50.10 l 49.20), close-uri 52.20, 51.40, 50.60, 49.65, 49.60 (doji: o 49.65 h 50.10 l 49.25),
49.90, 50.40 (confirmare), 50.80, 51.10, 51.50; open[0] = 53.00; fitile 0.15. 49.90, 50.40 (confirmare), 50.80, 51.10, 51.50; open[0] = 53.00; fitile 0.15.
NIVELURI NIVELURI
-------- --------
Stânga (DA): „pivot monthly S1 49.00" (albastru), eticheta de distanță lângă Stânga (DA): „pivotul lunar 49.00" (albastru) + ZONĂ verde între low-ul dojiului
doji: „low 49.20 = +0,41 % față de 49.00 → la nivel (daily: ≤ 1-2 %)". (49.25) și 49.00, etichetă „0,51 % — la nivel"; SĂGEATĂ spre linia 49.00:
Dreapta (NU): „S1 46.00" jos, „PP 53.50" sus; eticheta: „cel mai apropiat „pivot lunar: nivel urmărit / de mulți — aici apar / cumpărătorii".
nivel: 46.00, la 6,96 % → doji în aer". Dreapta (NU): „pivotul lunar 46.00" jos, „pivotul lunar 53.50" sus; ZONĂ roșie
Sub ambele, text mic: „60 min: prag ≤ 0,5 %, pivoți weekly · daily: 1-2 %, între 49.25 și 46.00, etichetă „gol de 7,07 % sub doji — doji în aer"; SĂGEATĂ
pivoți monthly · weekly: pivoți quarterly". spre doji: „aceeași formă, dar nimic sub el / nu are cine să-l susțină".
Sub ambele, un singur rând: „daily: e «la nivel» dacă low-ul dojiului e la cel
mult 1-2 % de pivotul lunar (aici 0,51 %; în dreapta 7,07 %)". Rândul cu
pragurile pe 60 min / weekly s-a mutat la nivelul 3.
ASSERT-URI ASSERT-URI
---------- ----------
1. open[i] == close[i-1]; doji abs(o-c) <= 0.10*(h-l); close[6] > 50.10. 1. open[i] == close[i-1]; doji h 50.10 / l 49.25; abs(o-c) <= 0.10*(h-l);
2. round((49.20-49.00)/49.00*100, 2) == 0.41 și <= 2. close[6] > 50.10.
3. round((49.20-46.00)/46.00*100, 2) == 6.96 și > 2; (53.50-50.10) > 0 2. round((49.25-49.00)/49.00*100, 2) == 0.51 și <= 2.
3. round((49.25-46.00)/46.00*100, 2) == 7.07 și > 2; (53.50-50.10) > 0
(niciun nivel între 46.00 și 53.50 pe panoul NU). (niciun nivel între 46.00 și 53.50 pe panoul NU).
4. Scara (px/unitate) identică pe cele două panouri (ca să se vadă că forma e 4. Scara (px/unitate) identică pe cele două panouri (ca să se vadă că forma e
aceeași). aceeași); Chart nu are voie să mute graficul (ar dezalinia panourile) — se
randează cu `_render()` și se verifică top/left/lățimea.
SURSA SURSA
----- -----

View File

@@ -1,14 +1,18 @@
<svg viewBox="0 0 760 415" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 760 415" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="22" fill="#333" style="font-weight:bold">Doji la nivel vs. doji în aer — daily, pivoți monthly (exemplu construit)</text> <text x="24" y="22" fill="#333" style="font-weight:bold">Doji la nivel vs. doji în aer — daily, pivoți lunari (exemplu construit)</text>
<text x="24" y="48" fill="#188a3e" style="font-weight:bold">DA — doji la nivel</text> <text x="24" y="48" fill="#188a3e" style="font-weight:bold">DA — doji la nivel</text>
<text x="402" y="48" fill="#c00" style="font-weight:bold">NU — doji în aer</text> <text x="402" y="48" fill="#c00" style="font-weight:bold">NU — doji în aer</text>
<line x1="388" y1="36" x2="388" y2="361" stroke="#ccc"/> <line x1="388" y1="36" x2="388" y2="361" stroke="#ccc"/>
<rect x="24" y="236.4" width="350" height="9.0" fill="#188a3e" fill-opacity="0.12" stroke="#188a3e" stroke-width="1"/>
<text x="370" y="230.4" fill="#188a3e" text-anchor="end" style="font-weight:bold">0,51 % — la nivel</text>
<rect x="402" y="236.4" width="350" height="117.0" fill="#c00" fill-opacity="0.12" stroke="#c00" stroke-width="1"/>
<text x="410" y="341.4" fill="#c00" text-anchor="start" style="font-weight:bold">gol de 7,07 % sub doji — doji în aer</text>
<line x1="24" y1="245.4" x2="374" y2="245.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="24" y1="245.4" x2="374" y2="245.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="370" y="239.4" fill="#1a5fb4" text-anchor="end">pivot monthly S1 49.00</text> <text x="30" y="259.4" fill="#1a5fb4" text-anchor="start">pivotul lunar 49.00</text>
<line x1="402" y1="83.4" x2="752" y2="83.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="402" y1="83.4" x2="752" y2="83.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="748" y="77.4" fill="#1a5fb4" text-anchor="end">PP 53.50</text> <text x="748" y="77.4" fill="#1a5fb4" text-anchor="end">pivotul lunar 53.50</text>
<line x1="402" y1="353.4" x2="752" y2="353.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="402" y1="353.4" x2="752" y2="353.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="748" y="347.4" fill="#1a5fb4" text-anchor="end">S1 46.00</text> <text x="408" y="367.4" fill="#1a5fb4" text-anchor="start">pivotul lunar 46.00</text>
<line x1="58.0" y1="96.0" x2="58.0" y2="135.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="58.0" y1="96.0" x2="58.0" y2="135.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="53.0" y="101.4" width="10" height="28.8" fill="#c00"/> <rect x="53.0" y="101.4" width="10" height="28.8" fill="#c00"/>
<line x1="75.0" y1="124.8" x2="75.0" y2="164.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="75.0" y1="124.8" x2="75.0" y2="164.4" stroke="#1a1a1a" stroke-width="1.2"/>
@@ -17,7 +21,7 @@
<rect x="87.0" y="159.0" width="10" height="28.8" fill="#c00"/> <rect x="87.0" y="159.0" width="10" height="28.8" fill="#c00"/>
<line x1="109.0" y1="182.4" x2="109.0" y2="227.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="109.0" y1="182.4" x2="109.0" y2="227.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="104.0" y="187.8" width="10" height="34.2" fill="#c00"/> <rect x="104.0" y="187.8" width="10" height="34.2" fill="#c00"/>
<line x1="126.0" y1="205.8" x2="126.0" y2="238.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="126.0" y1="205.8" x2="126.0" y2="236.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="121.0" y="222.0" width="10" height="1.8" fill="#c00"/> <rect x="121.0" y="222.0" width="10" height="1.8" fill="#c00"/>
<line x1="143.0" y1="207.6" x2="143.0" y2="229.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="143.0" y1="207.6" x2="143.0" y2="229.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="138.0" y="213.0" width="10" height="10.8" fill="#188a3e"/> <rect x="138.0" y="213.0" width="10" height="10.8" fill="#188a3e"/>
@@ -31,6 +35,11 @@
<rect x="206.0" y="155.4" width="10" height="14.4" fill="#188a3e"/> <rect x="206.0" y="155.4" width="10" height="14.4" fill="#188a3e"/>
<text x="126.0" y="179.8" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text> <text x="126.0" y="179.8" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="160.0" y="153.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare</text> <text x="160.0" y="153.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare</text>
<line x1="194.0" y1="275.4" x2="194.0" y2="257.4" stroke="#1a5fb4" stroke-width="1.8"/>
<polygon points="194.0,249.4 198.0,257.4 190.0,257.4" fill="#1a5fb4"/>
<text x="194.0" y="289.4" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">pivot lunar: nivel urmărit</text>
<text x="194.0" y="303.4" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">de mulți — aici apar</text>
<text x="194.0" y="317.4" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">cumpărătorii</text>
<line x1="436.0" y1="96.0" x2="436.0" y2="135.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="436.0" y1="96.0" x2="436.0" y2="135.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="431.0" y="101.4" width="10" height="28.8" fill="#c00"/> <rect x="431.0" y="101.4" width="10" height="28.8" fill="#c00"/>
<line x1="453.0" y1="124.8" x2="453.0" y2="164.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="453.0" y1="124.8" x2="453.0" y2="164.4" stroke="#1a1a1a" stroke-width="1.2"/>
@@ -39,7 +48,7 @@
<rect x="465.0" y="159.0" width="10" height="28.8" fill="#c00"/> <rect x="465.0" y="159.0" width="10" height="28.8" fill="#c00"/>
<line x1="487.0" y1="182.4" x2="487.0" y2="227.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="487.0" y1="182.4" x2="487.0" y2="227.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="482.0" y="187.8" width="10" height="34.2" fill="#c00"/> <rect x="482.0" y="187.8" width="10" height="34.2" fill="#c00"/>
<line x1="504.0" y1="205.8" x2="504.0" y2="238.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="504.0" y1="205.8" x2="504.0" y2="236.4" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="499.0" y="222.0" width="10" height="1.8" fill="#c00"/> <rect x="499.0" y="222.0" width="10" height="1.8" fill="#c00"/>
<line x1="521.0" y1="207.6" x2="521.0" y2="229.2" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="521.0" y1="207.6" x2="521.0" y2="229.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="516.0" y="213.0" width="10" height="10.8" fill="#188a3e"/> <rect x="516.0" y="213.0" width="10" height="10.8" fill="#188a3e"/>
@@ -53,15 +62,10 @@
<rect x="584.0" y="155.4" width="10" height="14.4" fill="#188a3e"/> <rect x="584.0" y="155.4" width="10" height="14.4" fill="#188a3e"/>
<text x="504.0" y="179.8" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text> <text x="504.0" y="179.8" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="538.0" y="153.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare</text> <text x="538.0" y="153.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare</text>
<circle cx="126.0" cy="238.2" r="5" fill="none" stroke="#1a5fb4" stroke-width="1.5"/> <line x1="604.0" y1="266.4" x2="511.7" y2="242.4" stroke="#c00" stroke-width="1.8"/>
<text x="32" y="269.4" fill="#1a5fb4">low 49.20 = +0,41 % față de 49.00</text> <polygon points="504.0,240.4 512.7,238.5 510.7,246.3" fill="#c00"/>
<text x="32" y="285.4" fill="#188a3e" style="font-weight:bold">→ la nivel (daily: ≤ 1-2 %)</text> <text x="604.0" y="280.4" fill="#c00" text-anchor="middle" style="font-weight:bold">aceeași formă, dar nimic sub el</text>
<line x1="504.0" y1="241.2" x2="504.0" y2="351.4" stroke="#c00" stroke-width="1.5"/> <text x="604.0" y="294.4" fill="#c00" text-anchor="middle" style="font-weight:bold">nu are cine să-l susțină</text>
<polygon points="500.0,248.2 508.0,248.2 504.0,241.2" fill="#c00"/> <text x="24" y="383" fill="#555">daily: e „la nivel" dacă low-ul dojiului e la cel mult 1-2 % de pivotul lunar (aici 0,51 %; în dreapta 7,07 %).</text>
<polygon points="500.0,344.4 508.0,344.4 504.0,351.4" fill="#c00"/>
<text x="516.0" y="287.8" fill="#1a5fb4">cel mai apropiat nivel: 46.00, la 6,96 %</text>
<text x="516.0" y="303.8" fill="#c00" style="font-weight:bold">→ doji în aer</text>
<text x="516.0" y="321.8" fill="#555">(PP 53.50 e deasupra, la 8,74 % de low)</text>
<text x="24" y="383" fill="#555">60 min: prag ≤ 0,5 %, pivoți weekly · daily: 1-2 %, pivoți monthly · weekly: pivoți quarterly</text>
<text x="24" y="401" fill="#555">Aceeași serie, aceeași scară; nivelurile 49.00 / 46.00 / 53.50 sunt construite.</text> <text x="24" y="401" fill="#555">Aceeași serie, aceeași scară; nivelurile 49.00 / 46.00 / 53.50 sunt construite.</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -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" ' 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) 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 y0 = 40
ROW_H = 290
for key, f, tf_big, tf_small, cap, exp in ROWS: for key, f, tf_big, tf_small, cap, exp in ROWS:
big, small = scaled(BIG_A, f), scaled(SMALL_A, f) big, small = scaled(BIG_A, f), scaled(SMALL_A, f)
g = check(key, big, small, exp) g = check(key, big, small, exp)
first = key == "A"
# titlu rând + subtitluri # titlu rând + subtitluri
text(20, y0 + 14, f"{key}. {tf_big} → {tf_small}", bold=True, size=13) 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 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 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") 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") text(BX0 - 14, yb(g["dh"]) + 14, f"high doji {tf_big} {g['dh']:.2f}", fill="#666")
candles(big, BX0, BGAP, yb) 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"]) x1, y1 = BX0 + 10 * BGAP + 8, yb(g["conf"])
x2, y2 = SX0 - 10, ys(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" ' 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)"/>') 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(290, y1 + 2, "apoi cobori", fill="#555")
text(300, y1 + 16, "după confirmare", fill="#555") text(290, y1 + 16, "pe graficul mic", fill="#555")
# TF mic: niveluri # TF mic: niveluri
y_dh, y_e, y_sl, y_tp = ys(g["dh"]), ys(g["entry"]), ys(g["sl"]), ys(g["tp"]) 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" 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_dh, GRAY, "3 3")
hline(SL_X1, SL_X2, y_e, GREEN, "6 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_sl, RED, "6 3")
hline(SL_X1, SL_X2, y_tp, GREEN, "2 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_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_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 + 12, f"stop {g['sl']:.2f}", fill=RED, size=11)
text(COL_X, y_sl + 25, "= low 4 candele", 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) candles(small, SX0, SGAP, ys)
# paranteză peste pullback-ul de 8 candele (barele 0..7) if first:
yb8 = y_tp - 12 # paranteză peste pullback-ul de 8 candele (barele 0..7), doar pe primul rând
xa, xb = SX0 - 5, SX0 + 7 * SGAP + 5 yb8 = y_tp - 12
out.append(f'<path d="M{xa:.1f},{yb8 + 6:.1f} V{yb8:.1f} H{xb:.1f} V{yb8 + 6:.1f}" ' xa, xb = SX0 - 5, SX0 + 7 * SGAP + 5
f'fill="none" stroke="#555" stroke-width="1"/>') out.append(f'<path d="M{xa:.1f},{yb8 + 6:.1f} V{yb8:.1f} H{xb:.1f} V{yb8 + 6:.1f}" '
text((xa + xb) / 2, yb8 - 5, "pullback: 8 candele", fill="#555", anchor="middle") f'fill="none" stroke="#555" stroke-width="1"/>')
text(SX0 + 8 * SGAP + 4, y_sl + 15, "doji la nivel", fill="#b06000", anchor="end", bold=True) text((xa + xb) / 2, yb8 - 5, "pullback: 8 candele", fill="#555", anchor="middle")
text(SX0 + 9 * SGAP - 8, y_e - 5, "intrare", fill=GREEN, anchor="end", bold=True) # parantezele de stop: același setup, măsurat pe TF mare și pe TF mic
bx = zx1 + 8
# text sub rând bracket(bx, yb(g["b_entry"]), yb(g["b_sl"]), RED, f"stop {g['b_pct']:.2f} %".replace(".", ","))
text(20, top + PLOT_H + 50, cap.format(p=g["pct"], pb=g["b_pct"]), fill=INK, bold=True) 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} " 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"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} %)") f"doar mare: risc {g['b_risk']:.2f} ({g['b_pct']:.2f} %)")
y0 += ROW_H y0 += 320 if first else 270
if key != "C": if key != "C":
out.append(f'<line x1="20" y1="{y0 - 14:.0f}" x2="{W - 20}" y2="{y0 - 14:.0f}" stroke="#ddd"/>') 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") H = y0 - 20
text(20, y0 + 21, "Procentele reale depind de simbol (LABU daily: stop 9 %).", fill="#555")
H = y0 + 32
svg = (f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/svg" ' 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>") f'style="width:100%;height:auto;font:12px sans-serif">\n ' + "\n ".join(out) + "\n</svg>")
assert "\n\n" not in 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") OUT.write_text(svg, encoding="utf-8")
print(f"scris {OUT} ({W}x{H:.0f})") print(f"scris {OUT} ({W}x{H:.0f})")

View File

@@ -63,15 +63,17 @@ intrare verde; SL roșu; TP1 verde punctat.
ETICHETE ETICHETE
-------- --------
Titlu rând: A „weekly → daily" B „monthly → weekly" C „daily → 60 min" Titlu rând: A „weekly → daily" B „monthly → weekly" C „daily → 60 min"
Pe graficul mare: Mark(9, "doji"), Mark(10, "confirmare: long permis"). Pe graficul mare: zonă peste doji + confirmare, etichetată dedesubt
Pe graficul mic: Mark(8, "doji la nivel"), Mark(9, "intrare"), „doji + confirmare: aici se decide direcția".
Level SL „SL = low 4 candele", Level TP „TP1 1:1". Pe graficul mic: zonă peste doji + confirmare, etichetată „doji la nivel:
Sub fiecare rând, un text de o linie: aici intri"; Level „stop <preț>" (pe rândul A și „sub ultimele 4 candele"),
A: „stop 1.13 % (pe weekly ar fi 4.77 %) · 8 candele = 8 zile de bursă" Level „ținta 1:1 <preț>", Level „intrare <preț>".
B: „stop 2.59 % (pe monthly ar fi 10.85 %) · 8 candele = 8 săptămâni" Săgeata-zoom dintre grafice: „apoi cobori pe graficul mic".
C: „stop 0.47 % (pe daily ar fi 1.98 %) · 8 candele ≈ 1,2 zile de bursă (7 bare/zi)" Doar pe rândul A: paranteză de stop pe TF-ul mare („stop 4,77 %") și pe cel
Legendă jos: „Cifre construite, aceeași formă scalată pe trei perechi. mic („stop 1,13 %"), cu o săgeată între ele: „același setup, stop de 4 ori
Procentele reale depind de simbol (LABU daily: stop 9 %)." mai mic → de 4 ori mai multe acțiuni la același risc".
Restul cifrelor (praguri, „8 candele" pe fiecare pereche, cât ții) stau în
tabelul din capitol, nu în SVG: diagrama nu repetă tabelul.
ASSERT-URI OBLIGATORII ÎN GENERATOR ASSERT-URI OBLIGATORII ÎN GENERATOR
----------------------------------- -----------------------------------

View File

@@ -1,9 +1,12 @@
<svg viewBox="0 0 720 942" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 720 880" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<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> <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><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 x="20.0" y="22.0" fill="#333" style="font-weight:bold;font-size:14px">Aceeași regulă pe trei perechi — exemplu construit (fără ticker)</text> <text x="20.0" y="22.0" fill="#333" style="font-weight:bold;font-size:14px">Aceeași regulă pe trei perechi — exemplu construit (fără ticker)</text>
<text x="20.0" y="54.0" fill="#333" style="font-weight:bold;font-size:13px">A. weekly → daily</text> <text x="20.0" y="54.0" fill="#333" style="font-weight:bold;font-size:13px">A. weekly → daily</text>
<text x="24.0" y="72.0" fill="#555">weekly: direcția</text> <text x="24.0" y="72.0" fill="#555">weekly: direcția</text>
<text x="380.0" y="72.0" fill="#555">daily: intrarea</text> <text x="380.0" y="72.0" fill="#555">daily: intrarea</text>
<rect x="175.0" y="202.5" width="34.0" height="52.5" fill="#188a3e" fill-opacity="0.10" stroke="#188a3e" stroke-width="1"/>
<text x="192.0" y="270.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">doji + confirmare:</text>
<text x="192.0" y="284.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">aici se decide direcția</text>
<line x1="24.0" y1="224.5" x2="212.0" y2="224.5" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/> <line x1="24.0" y1="224.5" x2="212.0" y2="224.5" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<text x="26.0" y="238.5" fill="#666">high doji weekly 105.20</text> <text x="26.0" y="238.5" fill="#666">high doji weekly 105.20</text>
<line x1="40.0" y1="90.0" x2="40.0" y2="114.7" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="40.0" y1="90.0" x2="40.0" y2="114.7" stroke="#1a1a1a" stroke-width="1.2"/>
@@ -28,20 +31,22 @@
<rect x="179.5" y="233.8" width="9" height="1.6" fill="#c00"/> <rect x="179.5" y="233.8" width="9" height="1.6" fill="#c00"/>
<line x1="200.0" y1="207.5" x2="200.0" y2="237.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="200.0" y1="207.5" x2="200.0" y2="237.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="195.5" y="210.6" width="9" height="24.7" fill="#188a3e"/> <rect x="195.5" y="210.6" width="9" height="24.7" fill="#188a3e"/>
<text x="184.0" y="265.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="196.0" y="252.6" fill="#188a3e" style="font-weight:bold">confirmare: long permis</text>
<line x1="208.0" y1="210.6" x2="382.0" y2="163.1" stroke="#555" stroke-width="1.3" stroke-dasharray="5 3" marker-end="url(#pt-arr)"/> <line x1="208.0" y1="210.6" x2="382.0" y2="163.1" stroke="#555" stroke-width="1.3" stroke-dasharray="5 3" marker-end="url(#pt-arr)"/>
<text x="300.0" y="212.6" fill="#555">zoom pe daily,</text> <text x="290.0" y="212.6" fill="#555">apoi cobori</text>
<text x="300.0" y="226.6" fill="#555">după confirmare</text> <text x="290.0" y="226.6" fill="#555">pe graficul mic</text>
<rect x="503.0" y="189.1" width="33.0" height="65.9" fill="#188a3e" fill-opacity="0.10" stroke="#188a3e" stroke-width="1"/>
<text x="519.5" y="270.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">doji la nivel:</text>
<text x="519.5" y="284.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">aici intri</text>
<line x1="380.0" y1="245.4" x2="614.0" y2="245.4" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/> <line x1="380.0" y1="245.4" x2="614.0" y2="245.4" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<line x1="380.0" y1="195.1" x2="614.0" y2="195.1" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/> <line x1="380.0" y1="195.1" x2="614.0" y2="195.1" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="380.0" y1="250.0" x2="614.0" y2="250.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/> <line x1="380.0" y1="250.0" x2="614.0" y2="250.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="380.0" y1="140.3" x2="614.0" y2="140.3" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/> <line x1="380.0" y1="140.3" x2="614.0" y2="140.3" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/>
<text x="620.0" y="144.3" fill="#188a3e" style="font-size:11px">TP1 1:1 107.50</text> <text x="620.0" y="144.3" fill="#188a3e" style="font-size:11px">ținta 1:1 107.50</text>
<text x="620.0" y="199.1" fill="#188a3e" style="font-size:11px">intrare 106.30</text> <text x="620.0" y="199.1" fill="#188a3e" style="font-size:11px">intrare 106.30</text>
<text x="620.0" y="240.4" fill="#666" style="font-size:11px">high doji 105.20</text> <text x="620.0" y="240.4" fill="#666" style="font-size:11px">high doji 105.20</text>
<text x="620.0" y="262.0" fill="#c00" style="font-size:11px">SL 105.10</text> <text x="620.0" y="262.0" fill="#c00" style="font-size:11px">stop 105.10</text>
<text x="620.0" y="275.0" fill="#c00" style="font-size:11px">= low 4 candele</text> <text x="620.0" y="275.0" fill="#c00" style="font-size:11px">sub ultimele</text>
<text x="620.0" y="288.0" fill="#c00" style="font-size:11px">4 candele</text>
<line x1="392.0" y1="154.0" x2="392.0" y2="190.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="392.0" y1="154.0" x2="392.0" y2="190.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="387.5" y="163.1" width="9" height="18.3" fill="#c00"/> <rect x="387.5" y="163.1" width="9" height="18.3" fill="#c00"/>
<line x1="407.0" y1="172.3" x2="407.0" y2="208.9" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="407.0" y1="172.3" x2="407.0" y2="208.9" stroke="#1a1a1a" stroke-width="1.2"/>
@@ -74,163 +79,161 @@
<rect x="597.5" y="94.6" width="9" height="27.4" fill="#188a3e"/> <rect x="597.5" y="94.6" width="9" height="27.4" fill="#188a3e"/>
<path d="M387.0,134.3 V128.3 H502.0 V134.3" fill="none" stroke="#555" stroke-width="1"/> <path d="M387.0,134.3 V128.3 H502.0 V134.3" fill="none" stroke="#555" stroke-width="1"/>
<text x="444.5" y="123.3" fill="#555" text-anchor="middle">pullback: 8 candele</text> <text x="444.5" y="123.3" fill="#555" text-anchor="middle">pullback: 8 candele</text>
<text x="516.0" y="265.0" fill="#b06000" text-anchor="end" style="font-weight:bold">doji la nivel</text> <path d="M212.0,210.6 H217.0 V250.0 H212.0" fill="none" stroke="#c00" stroke-width="1.6"/>
<text x="519.0" y="190.1" fill="#188a3e" text-anchor="end" style="font-weight:bold">intrare</text> <text x="222.0" y="234.3" fill="#c00" style="font-weight:bold">stop 4,77 %</text>
<text x="20.0" y="300.0" fill="#333" style="font-weight:bold">stop 1.13 % (pe weekly ar fi 4.77 %) · 8 candele = 8 zile de bursă</text> <path d="M536.0,195.1 H541.0 V250.0 H536.0" fill="none" stroke="#c00" stroke-width="1.6"/>
<line x1="20" y1="316" x2="700" y2="316" stroke="#ddd"/> <text x="546.0" y="226.6" fill="#c00" style="font-weight:bold">stop 1,13 %</text>
<text x="20.0" y="344.0" fill="#333" style="font-weight:bold;font-size:13px">B. monthly → weekly</text> <line x1="237.0" y1="308.0" x2="561.0" y2="308.0" stroke="#c00" stroke-width="1.6" marker-end="url(#pt-red)"/>
<text x="24.0" y="362.0" fill="#555">monthly: direcția</text> <text x="399.0" y="325.0" fill="#c00" text-anchor="middle" style="font-weight:bold">același setup, stop de 4 ori mai mic</text>
<text x="380.0" y="362.0" fill="#555">weekly: intrarea</text> <text x="399.0" y="339.0" fill="#c00" text-anchor="middle" style="font-weight:bold">→ de 4 ori mai multe acțiuni la același risc</text>
<line x1="24.0" y1="514.5" x2="212.0" y2="514.5" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/> <line x1="20" y1="346" x2="700" y2="346" stroke="#ddd"/>
<text x="26.0" y="528.5" fill="#666">high doji monthly 113.00</text> <text x="20.0" y="374.0" fill="#333" style="font-weight:bold;font-size:13px">B. monthly → weekly</text>
<line x1="40.0" y1="380.0" x2="40.0" y2="404.7" stroke="#1a1a1a" stroke-width="1.2"/> <text x="24.0" y="392.0" fill="#555">monthly: direcția</text>
<rect x="35.5" y="384.6" width="9" height="15.5" fill="#c00"/> <text x="380.0" y="392.0" fill="#555">weekly: intrarea</text>
<line x1="56.0" y1="396.2" x2="56.0" y2="423.3" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="175.0" y="522.5" width="34.0" height="52.5" fill="#188a3e" fill-opacity="0.10" stroke="#188a3e" stroke-width="1"/>
<rect x="51.5" y="400.1" width="9" height="19.3" fill="#c00"/> <text x="192.0" y="590.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">doji + confirmare:</text>
<line x1="72.0" y1="407.8" x2="72.0" y2="422.5" stroke="#1a1a1a" stroke-width="1.2"/> <text x="192.0" y="604.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">aici se decide direcția</text>
<rect x="67.5" y="412.5" width="9" height="7.0" fill="#188a3e"/> <line x1="24.0" y1="544.5" x2="212.0" y2="544.5" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<line x1="88.0" y1="409.4" x2="88.0" y2="444.2" stroke="#1a1a1a" stroke-width="1.2"/> <text x="26.0" y="558.5" fill="#666">high doji monthly 113.00</text>
<rect x="83.5" y="412.5" width="9" height="27.8" fill="#c00"/> <line x1="40.0" y1="410.0" x2="40.0" y2="434.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="104.0" y1="436.4" x2="104.0" y2="465.8" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="35.5" y="414.6" width="9" height="15.5" fill="#c00"/>
<rect x="99.5" y="440.3" width="9" height="21.6" fill="#c00"/> <line x1="56.0" y1="426.2" x2="56.0" y2="453.3" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="120.0" y1="451.1" x2="120.0" y2="465.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="51.5" y="430.1" width="9" height="19.3" fill="#c00"/>
<rect x="115.5" y="455.0" width="9" height="7.0" fill="#188a3e"/> <line x1="72.0" y1="437.8" x2="72.0" y2="452.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="136.0" y1="452.7" x2="136.0" y2="484.3" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="67.5" y="442.5" width="9" height="7.0" fill="#188a3e"/>
<rect x="131.5" y="455.0" width="9" height="25.5" fill="#c00"/> <line x1="88.0" y1="439.4" x2="88.0" y2="474.2" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="152.0" y1="477.4" x2="152.0" y2="506.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="83.5" y="442.5" width="9" height="27.8" fill="#c00"/>
<rect x="147.5" y="480.5" width="9" height="21.6" fill="#c00"/> <line x1="104.0" y1="466.4" x2="104.0" y2="495.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="168.0" y1="499.0" x2="168.0" y2="526.9" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="99.5" y="470.3" width="9" height="21.6" fill="#c00"/>
<rect x="163.5" y="502.1" width="9" height="21.6" fill="#c00"/> <line x1="120.0" y1="481.1" x2="120.0" y2="495.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="184.0" y1="514.5" x2="184.0" y2="540.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="115.5" y="485.0" width="9" height="7.0" fill="#188a3e"/>
<rect x="179.5" y="523.8" width="9" height="1.6" fill="#c00"/> <line x1="136.0" y1="482.7" x2="136.0" y2="514.3" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="200.0" y1="497.5" x2="200.0" y2="527.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="131.5" y="485.0" width="9" height="25.5" fill="#c00"/>
<rect x="195.5" y="500.6" width="9" height="24.7" fill="#188a3e"/> <line x1="152.0" y1="507.4" x2="152.0" y2="536.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="184.0" y="555.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text> <rect x="147.5" y="510.5" width="9" height="21.6" fill="#c00"/>
<text x="196.0" y="542.6" fill="#188a3e" style="font-weight:bold">confirmare: long permis</text> <line x1="168.0" y1="529.0" x2="168.0" y2="556.9" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="208.0" y1="500.6" x2="382.0" y2="453.1" stroke="#555" stroke-width="1.3" stroke-dasharray="5 3" marker-end="url(#pt-arr)"/> <rect x="163.5" y="532.1" width="9" height="21.6" fill="#c00"/>
<text x="300.0" y="502.6" fill="#555">zoom pe weekly,</text> <line x1="184.0" y1="544.5" x2="184.0" y2="570.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="300.0" y="516.6" fill="#555">după confirmare</text> <rect x="179.5" y="553.8" width="9" height="1.6" fill="#c00"/>
<line x1="380.0" y1="535.4" x2="614.0" y2="535.4" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/> <line x1="200.0" y1="527.5" x2="200.0" y2="557.6" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="380.0" y1="485.1" x2="614.0" y2="485.1" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/> <rect x="195.5" y="530.6" width="9" height="24.7" fill="#188a3e"/>
<line x1="380.0" y1="540.0" x2="614.0" y2="540.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/> <line x1="208.0" y1="530.6" x2="382.0" y2="483.1" stroke="#555" stroke-width="1.3" stroke-dasharray="5 3" marker-end="url(#pt-arr)"/>
<line x1="380.0" y1="430.3" x2="614.0" y2="430.3" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/> <text x="290.0" y="532.6" fill="#555">apoi cobori</text>
<text x="620.0" y="434.3" fill="#188a3e" style="font-size:11px">TP1 1:1 118.75</text> <text x="290.0" y="546.6" fill="#555">pe graficul mic</text>
<text x="620.0" y="489.1" fill="#188a3e" style="font-size:11px">intrare 115.75</text> <rect x="503.0" y="509.1" width="33.0" height="65.9" fill="#188a3e" fill-opacity="0.10" stroke="#188a3e" stroke-width="1"/>
<text x="620.0" y="530.4" fill="#666" style="font-size:11px">high doji 113.00</text> <text x="519.5" y="590.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">doji la nivel:</text>
<text x="620.0" y="552.0" fill="#c00" style="font-size:11px">SL 112.75</text> <text x="519.5" y="604.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">aici intri</text>
<text x="620.0" y="565.0" fill="#c00" style="font-size:11px">= low 4 candele</text> <line x1="380.0" y1="565.4" x2="614.0" y2="565.4" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<line x1="392.0" y1="444.0" x2="392.0" y2="480.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="380.0" y1="515.1" x2="614.0" y2="515.1" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/>
<rect x="387.5" y="453.1" width="9" height="18.3" fill="#c00"/> <line x1="380.0" y1="570.0" x2="614.0" y2="570.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="407.0" y1="462.3" x2="407.0" y2="498.9" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="380.0" y1="460.3" x2="614.0" y2="460.3" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/>
<rect x="402.5" y="471.4" width="9" height="22.9" fill="#c00"/> <text x="620.0" y="464.3" fill="#188a3e" style="font-size:11px">ținta 1:1 118.75</text>
<line x1="422.0" y1="471.4" x2="422.0" y2="501.1" stroke="#1a1a1a" stroke-width="1.2"/> <text x="620.0" y="519.1" fill="#188a3e" style="font-size:11px">intrare 115.75</text>
<rect x="417.5" y="480.6" width="9" height="13.7" fill="#188a3e"/> <text x="620.0" y="560.4" fill="#666" style="font-size:11px">high doji 113.00</text>
<line x1="437.0" y1="476.0" x2="437.0" y2="508.0" stroke="#1a1a1a" stroke-width="1.2"/> <text x="620.0" y="582.0" fill="#c00" style="font-size:11px">stop 112.75</text>
<rect x="432.5" y="480.6" width="9" height="22.9" fill="#c00"/> <line x1="392.0" y1="474.0" x2="392.0" y2="510.6" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="452.0" y1="498.9" x2="452.0" y2="521.7" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="387.5" y="483.1" width="9" height="18.3" fill="#c00"/>
<rect x="447.5" y="503.4" width="9" height="13.7" fill="#c00"/> <line x1="407.0" y1="492.3" x2="407.0" y2="528.9" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="467.0" y1="501.1" x2="467.0" y2="521.7" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="402.5" y="501.4" width="9" height="22.9" fill="#c00"/>
<rect x="462.5" y="508.0" width="9" height="9.1" fill="#188a3e"/> <line x1="422.0" y1="501.4" x2="422.0" y2="531.1" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="482.0" y1="503.4" x2="482.0" y2="526.3" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="417.5" y="510.6" width="9" height="13.7" fill="#188a3e"/>
<rect x="477.5" y="508.0" width="9" height="13.7" fill="#c00"/> <line x1="437.0" y1="506.0" x2="437.0" y2="538.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="497.0" y1="517.1" x2="497.0" y2="533.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="432.5" y="510.6" width="9" height="22.9" fill="#c00"/>
<rect x="492.5" y="521.7" width="9" height="6.9" fill="#c00"/> <line x1="452.0" y1="528.9" x2="452.0" y2="551.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="512.0" y1="510.2" x2="512.0" y2="540.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="447.5" y="533.4" width="9" height="13.7" fill="#c00"/>
<rect x="507.5" y="526.3" width="9" height="2.4" fill="#188a3e"/> <line x1="467.0" y1="531.1" x2="467.0" y2="551.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="527.0" y1="480.6" x2="527.0" y2="530.9" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="462.5" y="538.0" width="9" height="9.1" fill="#188a3e"/>
<rect x="522.5" y="485.1" width="9" height="41.1" fill="#188a3e"/> <line x1="482.0" y1="533.4" x2="482.0" y2="556.3" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="542.0" y1="453.1" x2="542.0" y2="489.7" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="477.5" y="538.0" width="9" height="13.7" fill="#c00"/>
<rect x="537.5" y="457.7" width="9" height="27.4" fill="#188a3e"/> <line x1="497.0" y1="547.1" x2="497.0" y2="563.2" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="557.0" y1="430.3" x2="557.0" y2="466.9" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="492.5" y="551.7" width="9" height="6.9" fill="#c00"/>
<rect x="552.5" y="434.9" width="9" height="22.9" fill="#188a3e"/> <line x1="512.0" y1="540.2" x2="512.0" y2="570.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="572.0" y1="427.9" x2="572.0" y2="453.1" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="507.5" y="556.3" width="9" height="2.4" fill="#188a3e"/>
<rect x="567.5" y="434.9" width="9" height="9.1" fill="#c00"/> <line x1="527.0" y1="510.6" x2="527.0" y2="560.9" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="587.0" y1="407.4" x2="587.0" y2="448.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="522.5" y="515.1" width="9" height="41.1" fill="#188a3e"/>
<rect x="582.5" y="412.0" width="9" height="32.0" fill="#188a3e"/> <line x1="542.0" y1="483.1" x2="542.0" y2="519.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="602.0" y1="380.0" x2="602.0" y2="416.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="537.5" y="487.7" width="9" height="27.4" fill="#188a3e"/>
<rect x="597.5" y="384.6" width="9" height="27.4" fill="#188a3e"/> <line x1="557.0" y1="460.3" x2="557.0" y2="496.9" stroke="#1a1a1a" stroke-width="1.2"/>
<path d="M387.0,424.3 V418.3 H502.0 V424.3" fill="none" stroke="#555" stroke-width="1"/> <rect x="552.5" y="464.9" width="9" height="22.9" fill="#188a3e"/>
<text x="444.5" y="413.3" fill="#555" text-anchor="middle">pullback: 8 candele</text> <line x1="572.0" y1="457.9" x2="572.0" y2="483.1" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="516.0" y="555.0" fill="#b06000" text-anchor="end" style="font-weight:bold">doji la nivel</text> <rect x="567.5" y="464.9" width="9" height="9.1" fill="#c00"/>
<text x="519.0" y="480.1" fill="#188a3e" text-anchor="end" style="font-weight:bold">intrare</text> <line x1="587.0" y1="437.4" x2="587.0" y2="478.6" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="20.0" y="590.0" fill="#333" style="font-weight:bold">stop 2.59 % (pe monthly ar fi 10.85 %) · 8 candele = 8 săptămâni</text> <rect x="582.5" y="442.0" width="9" height="32.0" fill="#188a3e"/>
<line x1="20" y1="606" x2="700" y2="606" stroke="#ddd"/> <line x1="602.0" y1="410.0" x2="602.0" y2="446.6" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="20.0" y="634.0" fill="#333" style="font-weight:bold;font-size:13px">C. daily → 60 min</text> <rect x="597.5" y="414.6" width="9" height="27.4" fill="#188a3e"/>
<text x="24.0" y="652.0" fill="#555">daily: direcția</text> <line x1="20" y1="616" x2="700" y2="616" stroke="#ddd"/>
<text x="380.0" y="652.0" fill="#555">60 min: intrarea</text> <text x="20.0" y="644.0" fill="#333" style="font-weight:bold;font-size:13px">C. daily → 60 min</text>
<line x1="24.0" y1="804.5" x2="212.0" y2="804.5" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/> <text x="24.0" y="662.0" fill="#555">daily: direcția</text>
<text x="26.0" y="818.5" fill="#666">high doji daily 102.08</text> <text x="380.0" y="662.0" fill="#555">60 min: intrarea</text>
<line x1="40.0" y1="670.0" x2="40.0" y2="694.7" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="175.0" y="792.5" width="34.0" height="52.5" fill="#188a3e" fill-opacity="0.10" stroke="#188a3e" stroke-width="1"/>
<rect x="35.5" y="674.6" width="9" height="15.5" fill="#c00"/> <text x="192.0" y="860.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">doji + confirmare:</text>
<line x1="56.0" y1="686.2" x2="56.0" y2="713.3" stroke="#1a1a1a" stroke-width="1.2"/> <text x="192.0" y="874.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">aici se decide direcția</text>
<rect x="51.5" y="690.1" width="9" height="19.3" fill="#c00"/> <line x1="24.0" y1="814.5" x2="212.0" y2="814.5" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<line x1="72.0" y1="697.8" x2="72.0" y2="712.5" stroke="#1a1a1a" stroke-width="1.2"/> <text x="26.0" y="828.5" fill="#666">high doji daily 102.08</text>
<rect x="67.5" y="702.5" width="9" height="7.0" fill="#188a3e"/> <line x1="40.0" y1="680.0" x2="40.0" y2="704.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="88.0" y1="699.4" x2="88.0" y2="734.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="35.5" y="684.6" width="9" height="15.5" fill="#c00"/>
<rect x="83.5" y="702.5" width="9" height="27.8" fill="#c00"/> <line x1="56.0" y1="696.2" x2="56.0" y2="723.3" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="104.0" y1="726.4" x2="104.0" y2="755.8" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="51.5" y="700.1" width="9" height="19.3" fill="#c00"/>
<rect x="99.5" y="730.3" width="9" height="21.6" fill="#c00"/> <line x1="72.0" y1="707.8" x2="72.0" y2="722.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="120.0" y1="741.1" x2="120.0" y2="755.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="67.5" y="712.5" width="9" height="7.0" fill="#188a3e"/>
<rect x="115.5" y="745.0" width="9" height="7.0" fill="#188a3e"/> <line x1="88.0" y1="709.4" x2="88.0" y2="744.2" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="136.0" y1="742.7" x2="136.0" y2="774.3" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="83.5" y="712.5" width="9" height="27.8" fill="#c00"/>
<rect x="131.5" y="745.0" width="9" height="25.5" fill="#c00"/> <line x1="104.0" y1="736.4" x2="104.0" y2="765.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="152.0" y1="767.4" x2="152.0" y2="796.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="99.5" y="740.3" width="9" height="21.6" fill="#c00"/>
<rect x="147.5" y="770.5" width="9" height="21.6" fill="#c00"/> <line x1="120.0" y1="751.1" x2="120.0" y2="765.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="168.0" y1="789.0" x2="168.0" y2="816.9" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="115.5" y="755.0" width="9" height="7.0" fill="#188a3e"/>
<rect x="163.5" y="792.1" width="9" height="21.6" fill="#c00"/> <line x1="136.0" y1="752.7" x2="136.0" y2="784.3" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="184.0" y1="804.5" x2="184.0" y2="830.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="131.5" y="755.0" width="9" height="25.5" fill="#c00"/>
<rect x="179.5" y="813.8" width="9" height="1.6" fill="#c00"/> <line x1="152.0" y1="777.4" x2="152.0" y2="806.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="200.0" y1="787.5" x2="200.0" y2="817.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="147.5" y="780.5" width="9" height="21.6" fill="#c00"/>
<rect x="195.5" y="790.6" width="9" height="24.7" fill="#188a3e"/> <line x1="168.0" y1="799.0" x2="168.0" y2="826.9" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="184.0" y="845.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text> <rect x="163.5" y="802.1" width="9" height="21.6" fill="#c00"/>
<text x="196.0" y="832.6" fill="#188a3e" style="font-weight:bold">confirmare: long permis</text> <line x1="184.0" y1="814.5" x2="184.0" y2="840.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="208.0" y1="790.6" x2="382.0" y2="743.1" stroke="#555" stroke-width="1.3" stroke-dasharray="5 3" marker-end="url(#pt-arr)"/> <rect x="179.5" y="823.8" width="9" height="1.6" fill="#c00"/>
<text x="300.0" y="792.6" fill="#555">zoom pe 60 min,</text> <line x1="200.0" y1="797.5" x2="200.0" y2="827.6" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="300.0" y="806.6" fill="#555">după confirmare</text> <rect x="195.5" y="800.6" width="9" height="24.7" fill="#188a3e"/>
<line x1="380.0" y1="825.4" x2="614.0" y2="825.4" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/> <line x1="208.0" y1="800.6" x2="382.0" y2="753.1" stroke="#555" stroke-width="1.3" stroke-dasharray="5 3" marker-end="url(#pt-arr)"/>
<line x1="380.0" y1="775.1" x2="614.0" y2="775.1" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/> <text x="290.0" y="802.6" fill="#555">apoi cobori</text>
<line x1="380.0" y1="830.0" x2="614.0" y2="830.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/> <text x="290.0" y="816.6" fill="#555">pe graficul mic</text>
<line x1="380.0" y1="720.3" x2="614.0" y2="720.3" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/> <rect x="503.0" y="779.1" width="33.0" height="65.9" fill="#188a3e" fill-opacity="0.10" stroke="#188a3e" stroke-width="1"/>
<text x="620.0" y="724.3" fill="#188a3e" style="font-size:11px">TP1 1:1 103.00</text> <text x="519.5" y="860.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">doji la nivel:</text>
<text x="620.0" y="779.1" fill="#188a3e" style="font-size:11px">intrare 102.52</text> <text x="519.5" y="874.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">aici intri</text>
<text x="620.0" y="820.4" fill="#666" style="font-size:11px">high doji 102.08</text> <line x1="380.0" y1="835.4" x2="614.0" y2="835.4" stroke="#888" stroke-width="1.5" stroke-dasharray="3 3"/>
<text x="620.0" y="842.0" fill="#c00" style="font-size:11px">SL 102.04</text> <line x1="380.0" y1="785.1" x2="614.0" y2="785.1" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/>
<text x="620.0" y="855.0" fill="#c00" style="font-size:11px">= low 4 candele</text> <line x1="380.0" y1="840.0" x2="614.0" y2="840.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/>
<line x1="392.0" y1="734.0" x2="392.0" y2="770.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="380.0" y1="730.3" x2="614.0" y2="730.3" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/>
<rect x="387.5" y="743.1" width="9" height="18.3" fill="#c00"/> <text x="620.0" y="734.3" fill="#188a3e" style="font-size:11px">ținta 1:1 103.00</text>
<line x1="407.0" y1="752.3" x2="407.0" y2="788.9" stroke="#1a1a1a" stroke-width="1.2"/> <text x="620.0" y="789.1" fill="#188a3e" style="font-size:11px">intrare 102.52</text>
<rect x="402.5" y="761.4" width="9" height="22.9" fill="#c00"/> <text x="620.0" y="830.4" fill="#666" style="font-size:11px">high doji 102.08</text>
<line x1="422.0" y1="761.4" x2="422.0" y2="791.1" stroke="#1a1a1a" stroke-width="1.2"/> <text x="620.0" y="852.0" fill="#c00" style="font-size:11px">stop 102.04</text>
<rect x="417.5" y="770.6" width="9" height="13.7" fill="#188a3e"/> <line x1="392.0" y1="744.0" x2="392.0" y2="780.6" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="437.0" y1="766.0" x2="437.0" y2="798.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="387.5" y="753.1" width="9" height="18.3" fill="#c00"/>
<rect x="432.5" y="770.6" width="9" height="22.9" fill="#c00"/> <line x1="407.0" y1="762.3" x2="407.0" y2="798.9" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="452.0" y1="788.9" x2="452.0" y2="811.7" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="402.5" y="771.4" width="9" height="22.9" fill="#c00"/>
<rect x="447.5" y="793.4" width="9" height="13.7" fill="#c00"/> <line x1="422.0" y1="771.4" x2="422.0" y2="801.1" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="467.0" y1="791.1" x2="467.0" y2="811.7" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="417.5" y="780.6" width="9" height="13.7" fill="#188a3e"/>
<rect x="462.5" y="798.0" width="9" height="9.1" fill="#188a3e"/> <line x1="437.0" y1="776.0" x2="437.0" y2="808.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="482.0" y1="793.4" x2="482.0" y2="816.3" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="432.5" y="780.6" width="9" height="22.9" fill="#c00"/>
<rect x="477.5" y="798.0" width="9" height="13.7" fill="#c00"/> <line x1="452.0" y1="798.9" x2="452.0" y2="821.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="497.0" y1="807.1" x2="497.0" y2="823.1" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="447.5" y="803.4" width="9" height="13.7" fill="#c00"/>
<rect x="492.5" y="811.7" width="9" height="6.9" fill="#c00"/> <line x1="467.0" y1="801.1" x2="467.0" y2="821.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="512.0" y1="800.3" x2="512.0" y2="830.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="462.5" y="808.0" width="9" height="9.1" fill="#188a3e"/>
<rect x="507.5" y="816.3" width="9" height="2.3" fill="#188a3e"/> <line x1="482.0" y1="803.4" x2="482.0" y2="826.3" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="527.0" y1="770.6" x2="527.0" y2="820.9" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="477.5" y="808.0" width="9" height="13.7" fill="#c00"/>
<rect x="522.5" y="775.1" width="9" height="41.1" fill="#188a3e"/> <line x1="497.0" y1="817.1" x2="497.0" y2="833.1" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="542.0" y1="743.1" x2="542.0" y2="779.7" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="492.5" y="821.7" width="9" height="6.9" fill="#c00"/>
<rect x="537.5" y="747.7" width="9" height="27.4" fill="#188a3e"/> <line x1="512.0" y1="810.3" x2="512.0" y2="840.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="557.0" y1="720.3" x2="557.0" y2="756.9" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="507.5" y="826.3" width="9" height="2.3" fill="#188a3e"/>
<rect x="552.5" y="724.9" width="9" height="22.9" fill="#188a3e"/> <line x1="527.0" y1="780.6" x2="527.0" y2="830.9" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="572.0" y1="718.0" x2="572.0" y2="743.1" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="522.5" y="785.1" width="9" height="41.1" fill="#188a3e"/>
<rect x="567.5" y="724.9" width="9" height="9.1" fill="#c00"/> <line x1="542.0" y1="753.1" x2="542.0" y2="789.7" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="587.0" y1="697.4" x2="587.0" y2="738.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="537.5" y="757.7" width="9" height="27.4" fill="#188a3e"/>
<rect x="582.5" y="702.0" width="9" height="32.0" fill="#188a3e"/> <line x1="557.0" y1="730.3" x2="557.0" y2="766.9" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="602.0" y1="670.0" x2="602.0" y2="706.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="552.5" y="734.9" width="9" height="22.9" fill="#188a3e"/>
<rect x="597.5" y="674.6" width="9" height="27.4" fill="#188a3e"/> <line x1="572.0" y1="728.0" x2="572.0" y2="753.1" stroke="#1a1a1a" stroke-width="1.2"/>
<path d="M387.0,714.3 V708.3 H502.0 V714.3" fill="none" stroke="#555" stroke-width="1"/> <rect x="567.5" y="734.9" width="9" height="9.1" fill="#c00"/>
<text x="444.5" y="703.3" fill="#555" text-anchor="middle">pullback: 8 candele</text> <line x1="587.0" y1="707.4" x2="587.0" y2="748.6" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="516.0" y="845.0" fill="#b06000" text-anchor="end" style="font-weight:bold">doji la nivel</text> <rect x="582.5" y="712.0" width="9" height="32.0" fill="#188a3e"/>
<text x="519.0" y="770.1" fill="#188a3e" text-anchor="end" style="font-weight:bold">intrare</text> <line x1="602.0" y1="680.0" x2="602.0" y2="716.6" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="20.0" y="880.0" fill="#333" style="font-weight:bold">stop 0.47 % (pe daily ar fi 1.98 %) · 8 candele ≈ 1,2 zile de bursă (7 bare/zi)</text> <rect x="597.5" y="684.6" width="9" height="27.4" fill="#188a3e"/>
<text x="20.0" y="914.0" fill="#555">Cifre construite, aceeași formă scalată pe trei perechi.</text>
<text x="20.0" y="931.0" fill="#555">Procentele reale depind de simbol (LABU daily: stop 9 %).</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -27,24 +27,21 @@ WIDTHS = [300, 280, 260, 240, 220, 200]
# (linii în cutie, [(tip, text)]); tip: "n" = notă gri, "c" = capcană # (linii în cutie, [(tip, text)]); tip: "n" = notă gri, "c" = capcană
BOXES = [ BOXES = [
(["Univers:", "All Stocks (~13.000)", "S&P 500 · Russell 3000"], (["Univers:", "All Stocks (~13.000)", "S&P 500 · Russell 3000"],
[("n", "mai mare = găsește mai mult, durează mai mult")]), [("n", "mai mare = mai mulți candidați, scanare mai lentă")]),
(["Trigger: jbtgrshdATM", "BDATM = 0", "(Sell Doji: SDATM = 0)"], (["Trigger: jbtgrshdATM", "BDATM = 0", "(Sell Doji: SDATM = 0)"],
[("c", "Interval = TF-ul scanerului, setat manual"), [("c", "intervalul nu se aliniază singur cu TF-ul: îl pui de mână"),
("c", "0 = ultima candelă închisă; 1 = cu o zi în urmă")]), ("c", "vede doar candela închisă: daily rulat la prânz arată ieri")]),
(["Nivel: RSV1ATM", "% of PP ≤ 0.5 (60 min)", "% of PP ≤ 2 (daily)"], (["Nivel: RSV1ATM", "% of PP ≤ 0.5 (60 min)", "% of PP ≤ 2 (daily)"],
[("n", "Pivot Interval: 2 = weekly (pe 60 min), 3 = monthly (pe daily)"), [("n", "Pivot Interval: 2 = weekly (pe 60 min), 3 = monthly (pe daily)"),
("c", "RS/SR = 1 la filtrare; cu 100, pragul se scrie ×100")]), ("c", "RS/SR: 1 la filtrare, 100 doar la afișare")]),
(["Lichiditate: Volume Colors", "Average Volume ≥ 500.000", (["Lichiditate: Volume Colors", "Average Volume ≥ 500.000",
"Average Length = 10"], "Average Length = 10"],
[("n", "volum daily, indiferent de TF-ul scanerului")]), [("n", "volum daily, indiferent de TF-ul scanerului")]),
(["Opțional:", "Since Bear ≥ 8", "Bull Reversal = 1", "RVOL doar Display"], (["Opțional:", "Since Bear ≥ 8", "Bull Reversal = 1", "RVOL doar Display"],
[("c", "Bear Reversal e selectat implicit — comută pe Bull"), [("c", "pornește pe Bear Reversal: comută pe Bull")]),
("c", "în zile extreme, pragurile rigide golesc lista")]),
(["Lista de candidați", "→ o verifici pe grafic", "(pașii 2-6).", (["Lista de candidați", "→ o verifici pe grafic", "(pașii 2-6).",
"Scanerul nu e undă verde."], []), "Scanerul nu e undă verde."], []),
] ]
FOOT = ("Delay: scanerul vede candela închisă — daily rulat la 12:00 "
"arată triggerul de ieri.")
def est_w(s, fs, bold=False): def est_w(s, fs, bold=False):
@@ -94,10 +91,18 @@ for i, (lines, notes) in enumerate(BOXES):
assert x0 >= x + 6 and x1 <= x + w - 6, f"textul nu încape în cutia {i}: {ln!r}" assert x0 >= x + 6 and x1 <= x + w - 6, f"textul nu încape în cutia {i}: {ln!r}"
if note_lines: if note_lines:
assert x + w + 24 <= NOTE_X, f"cutia {i} prea aproape de note" assert x + w + 24 <= NOTE_X, f"cutia {i} prea aproape de note"
svg.append(f'<line x1="{x + w + 4:g}" y1="{y + h / 2:g}" x2="{NOTE_X - 8}" '
f'y2="{y + h / 2:g}" stroke="#bbbbbb" stroke-dasharray="3 3"/>')
ny = y + (h - n_note * LH) / 2 + 12 ny = y + (h - n_note * LH) / 2 + 12
for group in note_lines: for group in note_lines:
kind0 = group[0][0]
cy = ny - 4
# capcana arată spre filtrul pe care îl strică (vârful pe cutie)
col = RED if kind0 == "c" else "#bbbbbb"
dash = '' if kind0 == "c" else ' stroke-dasharray="3 3"'
svg.append(f'<line x1="{NOTE_X - 10}" y1="{cy:g}" x2="{x + w + 12:g}" y2="{cy:g}" '
f'stroke="{col}" stroke-width="{1.6 if kind0 == "c" else 1}"{dash}/>')
if kind0 == "c":
svg.append(f'<path d="M {x + w + 4:g} {cy:g} L {x + w + 13:g} {cy - 4:g} '
f'L {x + w + 13:g} {cy + 4:g} Z" fill="{RED}"/>')
for kind, ln in group: for kind, ln in group:
put(NOTE_X, ny, ln, NOTE_FS, RED if kind == "c" else GRAY) put(NOTE_X, ny, ln, NOTE_FS, RED if kind == "c" else GRAY)
ny += LH ny += LH
@@ -108,10 +113,7 @@ for i, (lines, notes) in enumerate(BOXES):
f'L {BOX_CX} {y + 14:g} Z" fill="{BLUE}"/>') f'L {BOX_CX} {y + 14:g} Z" fill="{BLUE}"/>')
y += 18 y += 18
y += 30 H = int(y + 20)
for j, ln in enumerate(textwrap.wrap(FOOT, 88)):
put(20, y + j * LH, ln, 12.5, BLACK)
H = int(y + LH + 20)
# ------------------------------------------------------------------ verificare # ------------------------------------------------------------------ verificare
assert all(a > b for a, b in zip(WIDTHS, WIDTHS[1:])), "lățimile nu scad strict" assert all(a > b for a, b in zip(WIDTHS, WIDTHS[1:])), "lățimile nu scad strict"
@@ -133,6 +135,7 @@ out = "\n".join([
f'ordinea filtrelor și capcanele">', f'ordinea filtrelor și capcanele">',
f'<rect x="0" y="0" width="{W}" height="{H}" fill="#ffffff"/>', f'<rect x="0" y="0" width="{W}" height="{H}" fill="#ffffff"/>',
*svg, "</svg>"]) + "\n" *svg, "</svg>"]) + "\n"
assert ".md:" not in out and "Surse" not in out, "trimiteri la surse în SVG"
assert "\n\n" not in out and not any(not ln.strip() for ln in out.splitlines()), "linie goală" assert "\n\n" not in out and not any(not ln.strip() for ln in out.splitlines()), "linie goală"
OUT.write_text(out, encoding="utf-8") OUT.write_text(out, encoding="utf-8")
print(f"scris {OUT} ({W}x{H}), verificare OK") print(f"scris {OUT} ({W}x{H}), verificare OK")

View File

@@ -5,28 +5,28 @@ destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 1
cheie markdown: <!-- DIAGRAMA: scaner --> cheie markdown: <!-- DIAGRAMA: scaner -->
titlu SVG: „Scanerul Buy Doji în TradeStation — ordinea filtrelor și capcanele" titlu SVG: „Scanerul Buy Doji în TradeStation — ordinea filtrelor și capcanele"
stil: cutii dreptunghiulare stivuite, tot mai înguste (pâlnie), lățime 640; stil: cutii dreptunghiulare stivuite, tot mai înguste (pâlnie), lățime 640;
în dreapta fiecărei cutii, o notă roșie „capcană" unde există. în dreapta fiecărei cutii, o notă roșie „capcană" unde există,
legată de cutie printr-o săgeată roșie (vârful pe filtrul
pe care îl strică).
Fără cifre de „câte simboluri rămân" — materialul nu le dă. Fără cifre de „câte simboluri rămân" — materialul nu le dă.
CUTIILE (text exact, de sus în jos) CUTIILE (text exact, de sus în jos)
----------------------------------- -----------------------------------
1. „Univers: All Stocks (~13.000) · S&P 500 · Russell 3000" 1. „Univers: All Stocks (~13.000) · S&P 500 · Russell 3000"
notă gri: „mai mare = găsește mai mult, durează mai mult" notă gri: „mai mare = mai mulți candidați, scanare mai lentă"
2. „Trigger: jbtgrshdATM → BDATM = 0 (Sell Doji: SDATM = 0)" 2. „Trigger: jbtgrshdATM → BDATM = 0 (Sell Doji: SDATM = 0)"
capcană: „Interval = TF-ul scanerului, setat manual" capcană: „intervalul nu se aliniază singur cu TF-ul: îl pui de mână"
capcană: „0 = ultima candelă închisă; 1 = cu o zi în urmă" capcană: „vede doar candela închisă: daily rulat la prânz arată ieri"
3. „Nivel: RSV1ATM → % of PP ≤ 0.5 (60 min) / ≤ 2 (daily)" 3. „Nivel: RSV1ATM → % of PP ≤ 0.5 (60 min) / ≤ 2 (daily)"
notă: „Pivot Interval: 2 = weekly (pe 60 min), 3 = monthly (pe daily)" notă: „Pivot Interval: 2 = weekly (pe 60 min), 3 = monthly (pe daily)"
capcană: „RS/SR = 1 la filtrare; cu 100, pragul se scrie ×100" capcană: „RS/SR: 1 la filtrare, 100 doar la afișare"
4. „Lichiditate: Volume Colors → Average Volume ≥ 500.000, Average Length = 10" 4. „Lichiditate: Volume Colors → Average Volume ≥ 500.000, Average Length = 10"
notă: „volum daily, indiferent de TF-ul scanerului" notă: „volum daily, indiferent de TF-ul scanerului"
5. „Opțional: Since Bear ≥ 8 · Bull Reversal = 1 · RVOL doar Display" 5. „Opțional: Since Bear ≥ 8 · Bull Reversal = 1 · RVOL doar Display"
capcană: „Bear Reversal e selectat implicit — comută pe Bull" capcană: „pornește pe Bear Reversal: comută pe Bull"
capcană: „în zile extreme, pragurile rigide golesc lista"
6. (cutie verde, cea mai îngustă) „Lista de candidați → o verifici pe grafic 6. (cutie verde, cea mai îngustă) „Lista de candidați → o verifici pe grafic
(pașii 2-6). Scanerul nu e undă verde." (pașii 2-6). Scanerul nu e undă verde."
Sub pâlnie, o linie: „Delay: scanerul vede candela închisă — daily rulat la Fără linie de subsol: întârzierea scanerului e capcana de la cutia 2.
12:00 arată triggerul de ieri."
ASSERT-URI ASSERT-URI
---------- ----------

View File

@@ -1,57 +1,60 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 723" width="640" height="723" role="img" aria-label="Scanerul Buy Doji în TradeStation — ordinea filtrelor și capcanele"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 670" width="640" height="670" role="img" aria-label="Scanerul Buy Doji în TradeStation — ordinea filtrelor și capcanele">
<rect x="0" y="0" width="640" height="723" fill="#ffffff"/> <rect x="0" y="0" width="640" height="670" fill="#ffffff"/>
<text x="320" y="30" font-family="system-ui, sans-serif" font-size="18" font-weight="700" fill="#000000" text-anchor="middle">Scanerul Buy Doji în TradeStation</text> <text x="320" y="30" font-family="system-ui, sans-serif" font-size="18" font-weight="700" fill="#000000" text-anchor="middle">Scanerul Buy Doji în TradeStation</text>
<text x="320" y="52" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#666666" text-anchor="middle">ordinea filtrelor și capcanele</text> <text x="320" y="52" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#666666" text-anchor="middle">ordinea filtrelor și capcanele</text>
<rect x="15" y="76" width="300" height="68" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/> <rect x="15" y="76" width="300" height="68" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="165" y="98" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Univers:</text> <text x="165" y="98" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Univers:</text>
<text x="165" y="114" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">All Stocks (~13.000)</text> <text x="165" y="114" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">All Stocks (~13.000)</text>
<text x="165" y="130" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">S&amp;P 500 · Russell 3000</text> <text x="165" y="130" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">S&amp;P 500 · Russell 3000</text>
<line x1="319" y1="110" x2="332" y2="110" stroke="#bbbbbb" stroke-dasharray="3 3"/> <line x1="330" y1="102" x2="327" y2="102" stroke="#bbbbbb" stroke-width="1" stroke-dasharray="3 3"/>
<text x="340" y="106" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">mai mare = găsește mai mult, durează mai</text> <text x="340" y="106" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">mai mare = mai mulți candidați, scanare mai</text>
<text x="340" y="122" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">mult</text> <text x="340" y="122" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">lentă</text>
<path d="M 157 148 L 173 148 L 165 158 Z" fill="#1a5fb4"/> <path d="M 157 148 L 173 148 L 165 158 Z" fill="#1a5fb4"/>
<rect x="25" y="162" width="280" height="90.4" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/> <rect x="25" y="162" width="280" height="90.4" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="165" y="195.2" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Trigger: jbtgrshdATM</text> <text x="165" y="195.2" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Trigger: jbtgrshdATM</text>
<text x="165" y="211.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">BDATM = 0</text> <text x="165" y="211.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">BDATM = 0</text>
<text x="165" y="227.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">(Sell Doji: SDATM = 0)</text> <text x="165" y="227.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">(Sell Doji: SDATM = 0)</text>
<line x1="309" y1="207.2" x2="332" y2="207.2" stroke="#bbbbbb" stroke-dasharray="3 3"/> <line x1="330" y1="180" x2="317" y2="180" stroke="#c00" stroke-width="1.6"/>
<text x="340" y="184" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: Interval = TF-ul scanerului, setat</text> <path d="M 309 180 L 318 176 L 318 184 Z" fill="#c00"/>
<text x="340" y="200" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">manual</text> <text x="340" y="184" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: intervalul nu se aliniază singur cu</text>
<text x="340" y="222.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: 0 = ultima candelă închisă; 1 = cu</text> <text x="340" y="200" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">TF-ul: îl pui de mână</text>
<text x="340" y="238.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">o zi în urmă</text> <line x1="330" y1="218.4" x2="317" y2="218.4" stroke="#c00" stroke-width="1.6"/>
<path d="M 309 218.4 L 318 214.4 L 318 222.4 Z" fill="#c00"/>
<text x="340" y="222.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: vede doar candela închisă: daily</text>
<text x="340" y="238.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">rulat la prânz arată ieri</text>
<path d="M 157 256.4 L 173 256.4 L 165 266.4 Z" fill="#1a5fb4"/> <path d="M 157 256.4 L 173 256.4 L 165 266.4 Z" fill="#1a5fb4"/>
<rect x="35" y="270.4" width="260" height="90.4" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/> <rect x="35" y="270.4" width="260" height="90.4" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="165" y="303.6" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Nivel: RSV1ATM</text> <text x="165" y="303.6" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Nivel: RSV1ATM</text>
<text x="165" y="319.6" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">% of PP ≤ 0.5 (60 min)</text> <text x="165" y="319.6" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">% of PP ≤ 0.5 (60 min)</text>
<text x="165" y="335.6" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">% of PP ≤ 2 (daily)</text> <text x="165" y="335.6" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">% of PP ≤ 2 (daily)</text>
<line x1="299" y1="315.6" x2="332" y2="315.6" stroke="#bbbbbb" stroke-dasharray="3 3"/> <line x1="330" y1="288.4" x2="307" y2="288.4" stroke="#bbbbbb" stroke-width="1" stroke-dasharray="3 3"/>
<text x="340" y="292.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">Pivot Interval: 2 = weekly (pe 60 min), 3 =</text> <text x="340" y="292.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">Pivot Interval: 2 = weekly (pe 60 min), 3 =</text>
<text x="340" y="308.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">monthly (pe daily)</text> <text x="340" y="308.4" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">monthly (pe daily)</text>
<text x="340" y="330.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: RS/SR = 1 la filtrare; cu 100,</text> <line x1="330" y1="326.8" x2="307" y2="326.8" stroke="#c00" stroke-width="1.6"/>
<text x="340" y="346.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">pragul se scrie ×100</text> <path d="M 299 326.8 L 308 322.8 L 308 330.8 Z" fill="#c00"/>
<text x="340" y="330.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: RS/SR: 1 la filtrare, 100 doar la</text>
<text x="340" y="346.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">afișare</text>
<path d="M 157 364.8 L 173 364.8 L 165 374.8 Z" fill="#1a5fb4"/> <path d="M 157 364.8 L 173 364.8 L 165 374.8 Z" fill="#1a5fb4"/>
<rect x="45" y="378.8" width="240" height="68" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/> <rect x="45" y="378.8" width="240" height="68" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="165" y="400.8" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Lichiditate: Volume Colors</text> <text x="165" y="400.8" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Lichiditate: Volume Colors</text>
<text x="165" y="416.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Average Volume ≥ 500.000</text> <text x="165" y="416.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Average Volume ≥ 500.000</text>
<text x="165" y="432.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Average Length = 10</text> <text x="165" y="432.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Average Length = 10</text>
<line x1="289" y1="412.8" x2="332" y2="412.8" stroke="#bbbbbb" stroke-dasharray="3 3"/> <line x1="330" y1="412.8" x2="297" y2="412.8" stroke="#bbbbbb" stroke-width="1" stroke-dasharray="3 3"/>
<text x="340" y="416.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">volum daily, indiferent de TF-ul scanerului</text> <text x="340" y="416.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#666666" text-anchor="start">volum daily, indiferent de TF-ul scanerului</text>
<path d="M 157 450.8 L 173 450.8 L 165 460.8 Z" fill="#1a5fb4"/> <path d="M 157 450.8 L 173 450.8 L 165 460.8 Z" fill="#1a5fb4"/>
<rect x="55" y="464.8" width="220" height="90.4" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/> <rect x="55" y="464.8" width="220" height="84" rx="6" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.5"/>
<text x="165" y="490" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Opțional:</text> <text x="165" y="486.8" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#000000" text-anchor="middle">Opțional:</text>
<text x="165" y="506" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Since Bear ≥ 8</text> <text x="165" y="502.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Since Bear ≥ 8</text>
<text x="165" y="522" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Bull Reversal = 1</text> <text x="165" y="518.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">Bull Reversal = 1</text>
<text x="165" y="538" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">RVOL doar Display</text> <text x="165" y="534.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#000000" text-anchor="middle">RVOL doar Display</text>
<line x1="279" y1="510" x2="332" y2="510" stroke="#bbbbbb" stroke-dasharray="3 3"/> <line x1="330" y1="498.8" x2="287" y2="498.8" stroke="#c00" stroke-width="1.6"/>
<text x="340" y="486.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: Bear Reversal e selectat implicit —</text> <path d="M 279 498.8 L 288 494.8 L 288 502.8 Z" fill="#c00"/>
<text x="340" y="502.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">comută pe Bull</text> <text x="340" y="502.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: pornește pe Bear Reversal: comută</text>
<text x="340" y="525.2" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">capcană: în zile extreme, pragurile rigide</text> <text x="340" y="518.8" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">pe Bull</text>
<text x="340" y="541.2" font-family="system-ui, sans-serif" font-size="12" font-weight="400" fill="#c00" text-anchor="start">golesc lista</text> <path d="M 157 552.8 L 173 552.8 L 165 562.8 Z" fill="#1a5fb4"/>
<path d="M 157 559.2 L 173 559.2 L 165 569.2 Z" fill="#1a5fb4"/> <rect x="65" y="566.8" width="200" height="84" rx="6" fill="#eef7f0" stroke="#188a3e" stroke-width="2"/>
<rect x="65" y="573.2" width="200" height="84" rx="6" fill="#eef7f0" stroke="#188a3e" stroke-width="2"/> <text x="165" y="588.8" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#188a3e" text-anchor="middle">Lista de candidați</text>
<text x="165" y="595.2" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#188a3e" text-anchor="middle">Lista de candidați</text> <text x="165" y="604.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#188a3e" text-anchor="middle">→ o verifici pe grafic</text>
<text x="165" y="611.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#188a3e" text-anchor="middle">→ o verifici pe grafic</text> <text x="165" y="620.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#188a3e" text-anchor="middle">(pașii 2-6).</text>
<text x="165" y="627.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#188a3e" text-anchor="middle">(pașii 2-6).</text> <text x="165" y="636.8" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#188a3e" text-anchor="middle">Scanerul nu e undă verde.</text>
<text x="165" y="643.2" font-family="system-ui, sans-serif" font-size="13" font-weight="400" fill="#188a3e" text-anchor="middle">Scanerul nu e undă verde.</text>
<text x="20" y="687.2" font-family="system-ui, sans-serif" font-size="12.5" font-weight="400" fill="#000000" text-anchor="start">Delay: scanerul vede candela închisă — daily rulat la 12:00 arată triggerul de ieri.</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -3,11 +3,12 @@
Citește specificația `gen/strategii/buy_doji_sell.spec.txt`. Seria de 31 de Citește specificația `gen/strategii/buy_doji_sell.spec.txt`. Seria de 31 de
candele e construită din lista de close-uri dată, cu open-ul fiecărei bare = candele e construită din lista de close-uri dată, cu open-ul fiecărei bare =
close-ul precedentului; wick-urile sunt fixate ca nivelurile (doji 99.20 / close-ul precedentului; wick-urile sunt fixate ca nivelurile (doji 99.20 /
100.10, intrare short 99.00, SL 100.10, TP 97.90, trail 96.45, ieșire la 96.60) 100.10, intrare short 99.00, SL 100.15 = 5 cenți peste high-ul de 4 candele,
TP 97.85 = 1R de 1.15, trail 96.45, ieșire la 96.60)
să iasă exact din serie, nu doar din etichetă. să iasă exact din serie, nu doar din etichetă.
""" """
import sys; sys.path.insert(0, "/workspace/atm-curs-dl") import sys; sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Chart, Level, Mark, from_closes from svg_candles import Arrow, Chart, Level, Zone, from_closes
# --- seria: 31 de close-uri, exact ca în specificație ----------------------- # --- seria: 31 de close-uri, exact ca în specificație -----------------------
closes = [ closes = [
@@ -46,17 +47,16 @@ 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]) cds = from_closes(closes, wicks=wicks, vols=vols, start=closes[0])
# adnotările pe bara +1 și pe confirmare, ca linii sub grafic (fără suprapunere)
cds[15].color = "#777" # bara de așteptare: neutră, nu confirmă
cds[15].note = "bara 15: close 99.40 peste low-ul dojiului 99.20 — NU confirmă"
cds[16].note = "bara 16: close 99.00 sub 99.20 — confirmare (intrare short)"
doji, wait, conf = cds[14], cds[15], cds[16] doji, wait, conf = cds[14], cds[15], cds[16]
entry, sl, tp = 99.00, 100.10, 97.90 # 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
# --- cele 9 assert-uri cerute de specificație ------------------------------ # --- cele 9 assert-uri cerute de specificație ------------------------------
# 1. SL-ul e exact high-ul ultimelor 4 candele # 1. SL-ul e 5 cenți peste high-ul ultimelor 4 candele (100.10)
assert abs(max(cd.h for cd in cds[13:17]) - 100.10) < 1e-9, "max high[13:17] != 100.10" assert abs(max(cd.h for cd in cds[13:17]) - 100.10) < 1e-9, "max high[13:17] != 100.10"
assert abs(sl - 100.10 - 0.05) < 1e-9, "SL nu e 5 cenți peste high"
# 2. intrarea e close-ul barei 16 # 2. intrarea e close-ul barei 16
assert abs(conf.c - entry) < 1e-9, f"close[16]={conf.c} != 99.00" assert abs(conf.c - entry) < 1e-9, f"close[16]={conf.c} != 99.00"
# 3. confirmarea închide sub low-ul dojiului # 3. confirmarea închide sub low-ul dojiului
@@ -64,11 +64,11 @@ assert abs(doji.l - 99.20) < 1e-9 and conf.c < doji.l, "close[16] nu e sub low[1
# 4. bara +1 NU confirmă # 4. bara +1 NU confirmă
assert wait.c >= doji.l, "bara 15 ar confirma, fereastra n-ar avea sens" assert wait.c >= doji.l, "bara 15 ar confirma, fereastra n-ar avea sens"
# 5. 1:1 exact # 5. 1:1 exact
assert abs(abs(sl - entry) - abs(entry - tp)) < 1e-9 and abs((entry - tp) - 1.10) < 1e-9, \ assert abs(abs(sl - entry) - abs(entry - tp)) < 1e-9 and abs((entry - tp) - 1.15) < 1e-9, \
"risc != recompensă (nu e 1:1 exact)" "risc != recompensă (nu e 1:1 exact)"
# 6. primul low <= TP după intrare e bara 19 # 6. primul low <= TP după intrare e bara 19
primul_tp = next(i for i in range(17, len(cds)) if cds[i].l <= tp) primul_tp = next(i for i in range(17, len(cds)) if cds[i].l <= tp)
assert primul_tp == 19, f"TP 97.90 atins întâi la bara {primul_tp}, nu 19" assert primul_tp == 19, f"TP 97.85 atins întâi la bara {primul_tp}, nu 19"
assert abs(cds[18].l - 98.05) < 1e-9 and abs(cds[19].l - 97.55) < 1e-9, "low-urile 18/19 nu ies" assert abs(cds[18].l - 98.05) < 1e-9 and abs(cds[19].l - 97.55) < 1e-9, "low-urile 18/19 nu ies"
# 7. trailing = high[25] = 96.45; primul close peste el e bara 27; ieșirea e pe profit # 7. trailing = high[25] = 96.45; primul close peste el e bara 27; ieșirea e pe profit
trail = cds[25].h trail = cds[25].h
@@ -85,26 +85,43 @@ 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}") f"SL {sl:.2f} TP {tp:.2f} trail {trail:.2f} ieșire bara 27 @ {cds[27].c:.2f}")
# --- desenul ---------------------------------------------------------------- # --- desenul ----------------------------------------------------------------
RED, GREEN, BLUE, ORANGE, GRAY = "#c00", "#188a3e", "#1a5fb4", "#b06000", "#555"
ch = Chart( ch = Chart(
candles=cds, candles=cds,
levels=[ levels=[
# toate etichetele în dreapta: în stânga sus se suprapuneau cu mark-ul # etichetele în dreapta, dincolo de ultima candelă (width > ultima
# dojiului (SL la y=62, text până în ~x196; doji la y=58, din ~x193) # candelă); titlul stă în stânga sus, deci nu mai are cu ce să se lovească
Level(sl, "SL 100.10 (high 4 candele)", "#c00"), Level(sl, "stop 100.15", RED),
Level(entry, "intrare short 99.00", "#188a3e"), Level(entry, "intrare short 99.00", ORANGE),
Level(tp, "TP 97.90 = 1R", "#1a5fb4"), Level(tp, "ținta 97.85", GREEN),
Level(trail, "trail 96.45", "#b06000"),
], ],
marks=[ zones=[
Mark(14, "doji 99.20 / 100.10", "#b06000", "above"), Zone(0, 9, "1. creștere de 10 candele", BLUE),
Mark(27, "ieșire pe trail 96.60", "#c00", "above", dy=-6), Zone(14, 14, "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),
Zone(16, 19, "", GREEN, p_top=entry, p_bot=tp),
# linia de trail doar unde contează (înălțime 0 nu se randează)
# (de la bara 25), nu pe toată lățimea
Zone(25, 30, "", GRAY, p_top=trail, p_bot=trail - 0.02),
], ],
scale=30.0, gap=15, body_w=9, left=44, width=640, vol_h=70, arrows=[
vol_label="volum", title="Sell Doji — daily (exemplu construit, fără ticker)", Arrow(18, "STOPUL SUS, la 100.15 — 5 cenți peste maximul ultimelor 4 candele:\n"
# scurt: o linie de caption mai lungă de ~90 de caractere iese din viewBox "dacă prețul urcă până aici, creșterea continuă și ideea e moartă",
# (640px) și se taie la randare where="above", price=sl, color=RED, dx=110),
caption="Intrare short la close sub low-ul dojiului, SL la high 4 candele, " Arrow(16, "AICI INTRI SHORT, la 99.00:\na doua candelă după doji e prima\n"
"TP 1:1, apoi trail.", "care se ÎNCHIDE sub low-ul lui (99.20)",
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",
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",
where="below", color=GRAY, dx=-40),
],
scale=45.0, gap=20, body_w=9, left=44, width=790, vol_h=60,
vol_label="volum", title="Sell Doji pe short — daily (exemplu construit)",
caption="Pe short câștigi când prețul COBOARĂ: stopul stă SUS, ținta JOS, "
"trail-ul coboară după preț. Roșu = ce riști, verde = ce câștigi.",
) )
svg = ch.render() svg = ch.render()

View File

@@ -1,16 +1,23 @@
TIP: PRET TIP: PRET
CHEIE: sell CHEIE: sell
TITLU: Sell Doji — daily (exemplu construit, fără ticker) TITLU: Sell Doji pe short — daily (exemplu construit)
MARCAJ .md: <!-- DIAGRAMA: sell --> (Nivel 1, §1.3 Trigger, oglinda short) MARCAJ .md: <!-- DIAGRAMA: sell --> (Nivel 1, §1.3 Trigger, oglinda short)
CE ARATĂ CE ARATĂ
Graficul întreg al unui trade Sell Doji short, oglinda ansamblului long: Graficul întreg al unui trade Sell Doji short, oglinda ansamblului long:
uptrend de 14 candele, doji, o bară de așteptare care NU confirmă, apoi o uptrend de 14 candele, doji, o bară de așteptare care NU confirmă, apoi o
bară care închide sub low, intrare short la close, SL deasupra high-ului bară care închide sub low, intrare short la close, SL 5 cenți deasupra
ultimelor 4 candele, TP 1:1 în jos, apoi trailing. Panou de volum dedesubt. high-ului ultimelor 4 candele, TP 1:1 în jos, apoi trailing. Panou de volum.
Format tutorial v2: zone de evidențiere („1. creștere de 10 candele",
„2. doji", cutie roșie = riscul, între intrare și stop, cutie verde = câștigul,
între intrare și țintă — ca unealta „short position" din TradingView; segment
gri = linia de trail) și 4 săgeți care spun ce ȘI de ce: stop, intrare, țintă,
ieșire pe trail. Etichetele nivelurilor în dreapta, dincolo de ultima candelă.
NIVELURILE ȘI ETICHETELE (cu trimitere) NIVELURILE ȘI ETICHETELE (cu trimitere)
- doji 99.20-100.10, intrare short 99.00, SL 100.10, TP 97.90 (1:1). - doji 99.20-100.10, intrare short 99.00, SL 100.15, TP 97.85 (1:1, 1R = 1.15).
SL mutat de la 100.10 (exact pe high) la 100.15, ca oglinda pasului 5 din
capitol, unde stopul long stă „puțin sub" low (51.60 -> 51.55).
Sursa principală construiește exact aceste cifre: Sursa principală construiește exact aceste cifre:
`13_strategia_3_byh.md:258-259` („short: doji 99.20–100.10, intrare `13_strategia_3_byh.md:258-259` („short: doji 99.20–100.10, intrare
99.00, SL 100.10, TP 97.90, trail ~97.30"). 99.00, SL 100.10, TP 97.90, trail ~97.30").
@@ -37,16 +44,16 @@ Mecioni (up, down) implicite (0.30, 0.25); excepții:
Volum: peste medie pe doji și pe confirmare (distribuție), apoi normal. Volum: peste medie pe doji și pe confirmare (distribuție), apoi normal.
CE VERIFICĂ GENERATORUL CU assert CE VERIFICĂ GENERATORUL CU assert
1. max(high[13:17]) == 100.10 == SL (cel mai înalt high din 4 candele) 1. max(high[13:17]) == 100.10 și SL == 100.10 + 0.05 == 100.15
2. close[16] == 99.00 == intrare 2. close[16] == 99.00 == intrare
3. close[16] < low[14] == 99.20 (confirmarea chiar închide sub low) 3. close[16] < low[14] == 99.20 (confirmarea chiar închide sub low)
4. close[15] >= low[14] (bara +1 NU confirmă) 4. close[15] >= low[14] (bara +1 NU confirmă)
5. abs(sl - entry) == abs(entry - tp) == 1.10 (1:1 exact) 5. abs(sl - entry) == abs(entry - tp) == 1.15 (1:1 exact)
6. primul i>16 cu low[i] <= 97.90 este bara 19 (low[18]=98.05, low[19]=97.55) 6. primul i>16 cu low[i] <= 97.85 este bara 19 (low[18]=98.05, low[19]=97.55)
7. linia de trail = high[25] = 96.45; primul close > 96.45 este barul 27 7. linia de trail = high[25] = 96.45; primul close > 96.45 este barul 27
(96.60); și 96.60 < intrare (profit pe short) (96.60); și 96.60 < intrare (profit pe short)
8. doji: abs(o-c) <= 0.10*(h-l) 8. doji: abs(o-c) <= 0.10*(h-l)
9. trend: close[13] > close[0] + 5 9. trend: close[13] > close[0] + 5
STIL: gap=15, body_w=9, left=44, width=640, vol_h=70, scale ~30. Etichete STIL: gap=20, body_w=9, left=44, width=790, vol_h=60, scale 45. Etichete
„SL 100.10 (high 4 candele)", „intrare short 99.00", „TP 97.90 = 1R". „stop 100.15", „intrare short 99.00", „ținta 97.85".
Fără linie goală în SVG. Fără linie goală în SVG.

View File

@@ -1,111 +1,129 @@
<svg viewBox="0 0 640 460" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 840 571" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="48" fill="#333" style="font-weight:bold">Sell Doji — daily (exemplu construit, fără ticker)</text> <text x="24" y="72" fill="#333" style="font-weight:bold">Sell Doji pe short — daily (exemplu construit)</text>
<line x1="24" y1="68.0" x2="626" y2="68.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="34.5" y="130.8" width="199.0" height="306.3" fill="#1a5fb4" fill-opacity="0.08" stroke="#1a5fb4" stroke-width="1"/>
<text x="612" y="62.0" fill="#c00" text-anchor="end">SL 100.10 (high 4 candele)</text> <text x="34.5" y="125.8" fill="#1a5fb4" style="font-weight:bold">1. creștere de 10 candele</text>
<line x1="24" y1="101.0" x2="626" y2="101.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="314.5" y="90.2" width="19.0" height="56.5" fill="#b06000" fill-opacity="0.08" stroke="#b06000" stroke-width="1"/>
<text x="612" y="95.0" fill="#188a3e" text-anchor="end">intrare short 99.00</text> <text x="314.5" y="85.2" fill="#b06000" style="font-weight:bold">2. doji</text>
<line x1="24" y1="134.0" x2="626" y2="134.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="354.5" y="96.0" width="79.0" height="51.8" fill="#c00" fill-opacity="0.08" stroke="#c00" stroke-width="1"/>
<text x="612" y="128.0" fill="#1a5fb4" text-anchor="end">TP 97.90 = 1R</text> <rect x="354.5" y="147.8" width="79.0" height="51.8" fill="#188a3e" fill-opacity="0.08" stroke="#188a3e" stroke-width="1"/>
<line x1="24" y1="177.5" x2="626" y2="177.5" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/> <rect x="534.5" y="262.5" width="119.0" height="0.9" fill="#555" fill-opacity="0.08" stroke="#555" stroke-width="1"/>
<text x="612" y="171.5" fill="#b06000" text-anchor="end">trail 96.45</text> <line x1="24" y1="96.0" x2="826" y2="96.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="44.0" y1="272.0" x2="44.0" y2="288.5" stroke="#1a1a1a" stroke-width="1.2"/> <text x="812" y="90.0" fill="#c00" text-anchor="end">stop 100.15</text>
<rect x="39.5" y="281.0" width="9" height="1.6" fill="#188a3e"/> <line x1="24" y1="147.8" x2="826" y2="147.8" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="59.0" y1="239.0" x2="59.0" y2="288.5" stroke="#1a1a1a" stroke-width="1.2"/> <text x="812" y="141.8" fill="#b06000" text-anchor="end">intrare short 99.00</text>
<rect x="54.5" y="248.0" width="9" height="33.0" fill="#188a3e"/> <line x1="24" y1="199.5" x2="826" y2="199.5" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="74.0" y1="239.0" x2="74.0" y2="267.5" stroke="#1a1a1a" stroke-width="1.2"/> <text x="812" y="193.5" fill="#188a3e" text-anchor="end">ținta 97.85</text>
<rect x="69.5" y="248.0" width="9" height="12.0" fill="#c00"/> <line x1="44.0" y1="404.3" x2="44.0" y2="429.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="89.0" y1="212.0" x2="89.0" y2="267.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="39.5" y="417.8" width="9" height="1.6" fill="#188a3e"/>
<rect x="84.5" y="221.0" width="9" height="39.0" fill="#188a3e"/> <line x1="64.0" y1="354.8" x2="64.0" y2="429.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="104.0" y1="179.0" x2="104.0" y2="228.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="59.5" y="368.3" width="9" height="49.5" fill="#188a3e"/>
<rect x="99.5" y="188.0" width="9" height="33.0" fill="#188a3e"/> <line x1="84.0" y1="354.8" x2="84.0" y2="397.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="119.0" y1="179.0" x2="119.0" y2="204.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="79.5" y="368.3" width="9" height="18.0" fill="#c00"/>
<rect x="114.5" y="188.0" width="9" height="9.0" fill="#c00"/> <line x1="104.0" y1="314.3" x2="104.0" y2="397.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="134.0" y1="152.0" x2="134.0" y2="204.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="99.5" y="327.8" width="9" height="58.5" fill="#188a3e"/>
<rect x="129.5" y="161.0" width="9" height="36.0" fill="#188a3e"/> <line x1="124.0" y1="264.8" x2="124.0" y2="339.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="149.0" y1="119.0" x2="149.0" y2="168.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="119.5" y="278.3" width="9" height="49.5" fill="#188a3e"/>
<rect x="144.5" y="128.0" width="9" height="33.0" fill="#188a3e"/> <line x1="144.0" y1="264.8" x2="144.0" y2="303.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="164.0" y1="119.0" x2="164.0" y2="144.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="139.5" y="278.3" width="9" height="13.5" fill="#c00"/>
<rect x="159.5" y="128.0" width="9" height="9.0" fill="#c00"/> <line x1="164.0" y1="224.3" x2="164.0" y2="303.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="179.0" y1="95.0" x2="179.0" y2="144.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="159.5" y="237.8" width="9" height="54.0" fill="#188a3e"/>
<rect x="174.5" y="104.0" width="9" height="33.0" fill="#188a3e"/> <line x1="184.0" y1="174.8" x2="184.0" y2="249.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="194.0" y1="68.0" x2="194.0" y2="111.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="179.5" y="188.3" width="9" height="49.5" fill="#188a3e"/>
<rect x="189.5" y="77.0" width="9" height="27.0" fill="#188a3e"/> <line x1="204.0" y1="174.8" x2="204.0" y2="213.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="209.0" y1="56.0" x2="209.0" y2="84.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="199.5" y="188.3" width="9" height="13.5" fill="#c00"/>
<rect x="204.5" y="65.0" width="9" height="12.0" fill="#188a3e"/> <line x1="224.0" y1="138.8" x2="224.0" y2="213.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="224.0" y1="56.0" x2="224.0" y2="81.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="219.5" y="152.2" width="9" height="49.5" fill="#188a3e"/>
<rect x="219.5" y="65.0" width="9" height="9.0" fill="#c00"/> <line x1="244.0" y1="98.3" x2="244.0" y2="163.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="239.0" y1="68.0" x2="239.0" y2="89.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="239.5" y="111.8" width="9" height="40.5" fill="#188a3e"/>
<rect x="234.5" y="74.0" width="9" height="7.5" fill="#c00"/> <line x1="264.0" y1="80.3" x2="264.0" y2="123.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="254.0" y1="68.0" x2="254.0" y2="95.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="259.5" y="93.8" width="9" height="18.0" fill="#188a3e"/>
<rect x="249.5" y="81.5" width="9" height="1.6" fill="#c00"/> <line x1="284.0" y1="80.3" x2="284.0" y2="118.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="269.0" y1="77.0" x2="269.0" y2="93.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="279.5" y="93.8" width="9" height="13.5" fill="#c00"/>
<rect x="264.5" y="83.0" width="9" height="6.0" fill="#777"/> <line x1="304.0" y1="98.2" x2="304.0" y2="129.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="284.0" y1="83.0" x2="284.0" y2="105.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="299.5" y="107.2" width="9" height="11.2" fill="#c00"/>
<rect x="279.5" y="89.0" width="9" height="12.0" fill="#c00"/> <line x1="324.0" y1="98.2" x2="324.0" y2="138.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="299.0" y1="92.0" x2="299.0" y2="123.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="319.5" y="118.5" width="9" height="2.3" fill="#c00"/>
<rect x="294.5" y="101.0" width="9" height="15.0" fill="#c00"/> <line x1="344.0" y1="111.8" x2="344.0" y2="136.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="314.0" y1="107.0" x2="314.0" y2="129.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="339.5" y="120.8" width="9" height="9.0" fill="#c00"/>
<rect x="309.5" y="116.0" width="9" height="6.0" fill="#c00"/> <line x1="364.0" y1="120.7" x2="364.0" y2="154.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="329.0" y1="113.0" x2="329.0" y2="144.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="359.5" y="129.8" width="9" height="18.0" fill="#c00"/>
<rect x="324.5" y="122.0" width="9" height="15.0" fill="#c00"/> <line x1="384.0" y1="134.3" x2="384.0" y2="181.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="344.0" y1="128.0" x2="344.0" y2="156.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="379.5" y="147.8" width="9" height="22.5" fill="#c00"/>
<rect x="339.5" y="137.0" width="9" height="12.0" fill="#c00"/> <line x1="404.0" y1="156.8" x2="404.0" y2="190.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="359.0" y1="140.0" x2="359.0" y2="168.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="399.5" y="170.3" width="9" height="9.0" fill="#c00"/>
<rect x="354.5" y="149.0" width="9" height="12.0" fill="#c00"/> <line x1="424.0" y1="165.8" x2="424.0" y2="213.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="374.0" y1="152.0" x2="374.0" y2="177.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="419.5" y="179.3" width="9" height="22.5" fill="#c00"/>
<rect x="369.5" y="161.0" width="9" height="9.0" fill="#c00"/> <line x1="444.0" y1="188.3" x2="444.0" y2="231.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="389.0" y1="161.0" x2="389.0" y2="186.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="439.5" y="201.8" width="9" height="18.0" fill="#c00"/>
<rect x="384.5" y="170.0" width="9" height="9.0" fill="#c00"/> <line x1="464.0" y1="206.3" x2="464.0" y2="249.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="404.0" y1="170.0" x2="404.0" y2="195.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="459.5" y="219.8" width="9" height="18.0" fill="#c00"/>
<rect x="399.5" y="179.0" width="9" height="9.0" fill="#c00"/> <line x1="484.0" y1="224.3" x2="484.0" y2="262.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="419.0" y1="177.5" x2="419.0" y2="203.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="479.5" y="237.8" width="9" height="13.5" fill="#c00"/>
<rect x="414.5" y="188.0" width="9" height="9.0" fill="#c00"/> <line x1="504.0" y1="237.8" x2="504.0" y2="276.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="434.0" y1="176.0" x2="434.0" y2="200.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="499.5" y="251.3" width="9" height="13.5" fill="#c00"/>
<rect x="429.5" y="185.0" width="9" height="12.0" fill="#188a3e"/> <line x1="524.0" y1="251.3" x2="524.0" y2="289.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="449.0" y1="164.0" x2="449.0" y2="192.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="519.5" y="264.8" width="9" height="13.5" fill="#c00"/>
<rect x="444.5" y="173.0" width="9" height="12.0" fill="#188a3e"/> <line x1="544.0" y1="262.5" x2="544.0" y2="300.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="464.0" y1="164.0" x2="464.0" y2="186.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="539.5" y="278.3" width="9" height="13.5" fill="#c00"/>
<rect x="459.5" y="173.0" width="9" height="6.0" fill="#c00"/> <line x1="564.0" y1="260.3" x2="564.0" y2="296.3" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="479.0" y1="170.0" x2="479.0" y2="195.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="559.5" y="273.8" width="9" height="18.0" fill="#188a3e"/>
<rect x="474.5" y="179.0" width="9" height="9.0" fill="#c00"/> <line x1="584.0" y1="242.3" x2="584.0" y2="285.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="494.0" y1="173.0" x2="494.0" y2="195.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="579.5" y="255.8" width="9" height="18.0" fill="#188a3e"/>
<rect x="489.5" y="182.0" width="9" height="6.0" fill="#188a3e"/> <line x1="604.0" y1="242.3" x2="604.0" y2="276.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="24" y1="384.5" x2="626" y2="384.5" stroke="#888"/> <rect x="599.5" y="255.8" width="9" height="9.0" fill="#c00"/>
<rect x="39.5" y="350.3" width="9" height="34.2" fill="#188a3e" opacity="0.55"/> <line x1="624.0" y1="251.3" x2="624.0" y2="289.5" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="54.5" y="351.8" width="9" height="32.7" fill="#188a3e" opacity="0.55"/> <rect x="619.5" y="264.8" width="9" height="13.5" fill="#c00"/>
<rect x="69.5" y="348.7" width="9" height="35.8" fill="#c00" opacity="0.55"/> <line x1="644.0" y1="255.8" x2="644.0" y2="289.5" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="84.5" y="353.4" width="9" height="31.1" fill="#188a3e" opacity="0.55"/> <rect x="639.5" y="269.3" width="9" height="9.0" fill="#188a3e"/>
<rect x="99.5" y="349.5" width="9" height="35.0" fill="#188a3e" opacity="0.55"/> <line x1="24" y1="529.0" x2="826" y2="529.0" stroke="#888"/>
<rect x="114.5" y="347.2" width="9" height="37.3" fill="#c00" opacity="0.55"/> <rect x="39.5" y="499.7" width="9" height="29.3" fill="#188a3e" opacity="0.55"/>
<rect x="129.5" y="351.1" width="9" height="33.4" fill="#188a3e" opacity="0.55"/> <rect x="59.5" y="501.0" width="9" height="28.0" fill="#188a3e" opacity="0.55"/>
<rect x="144.5" y="347.9" width="9" height="36.6" fill="#188a3e" opacity="0.55"/> <rect x="79.5" y="498.3" width="9" height="30.7" fill="#c00" opacity="0.55"/>
<rect x="159.5" y="345.6" width="9" height="38.9" fill="#c00" opacity="0.55"/> <rect x="99.5" y="502.3" width="9" height="26.7" fill="#188a3e" opacity="0.55"/>
<rect x="174.5" y="349.5" width="9" height="35.0" fill="#188a3e" opacity="0.55"/> <rect x="119.5" y="499.0" width="9" height="30.0" fill="#188a3e" opacity="0.55"/>
<rect x="189.5" y="344.1" width="9" height="40.4" fill="#188a3e" opacity="0.55"/> <rect x="139.5" y="497.0" width="9" height="32.0" fill="#c00" opacity="0.55"/>
<rect x="204.5" y="339.4" width="9" height="45.1" fill="#188a3e" opacity="0.55"/> <rect x="159.5" y="500.3" width="9" height="28.7" fill="#188a3e" opacity="0.55"/>
<rect x="219.5" y="346.4" width="9" height="38.1" fill="#c00" opacity="0.55"/> <rect x="179.5" y="497.7" width="9" height="31.3" fill="#188a3e" opacity="0.55"/>
<rect x="234.5" y="341.7" width="9" height="42.8" fill="#c00" opacity="0.55"/> <rect x="199.5" y="495.7" width="9" height="33.3" fill="#c00" opacity="0.55"/>
<rect x="249.5" y="314.5" width="9" height="70.0" fill="#c00" opacity="0.55"/> <rect x="219.5" y="499.0" width="9" height="30.0" fill="#188a3e" opacity="0.55"/>
<rect x="264.5" y="336.3" width="9" height="48.2" fill="#777" opacity="0.55"/> <rect x="239.5" y="494.3" width="9" height="34.7" fill="#188a3e" opacity="0.55"/>
<rect x="279.5" y="319.2" width="9" height="65.3" fill="#c00" opacity="0.55"/> <rect x="259.5" y="490.3" width="9" height="38.7" fill="#188a3e" opacity="0.55"/>
<rect x="294.5" y="340.9" width="9" height="43.6" fill="#c00" opacity="0.55"/> <rect x="279.5" y="496.3" width="9" height="32.7" fill="#c00" opacity="0.55"/>
<rect x="309.5" y="344.1" width="9" height="40.4" fill="#c00" opacity="0.55"/> <rect x="299.5" y="492.3" width="9" height="36.7" fill="#c00" opacity="0.55"/>
<rect x="324.5" y="345.6" width="9" height="38.9" fill="#c00" opacity="0.55"/> <rect x="319.5" y="469.0" width="9" height="60.0" fill="#c00" opacity="0.55"/>
<rect x="339.5" y="347.2" width="9" height="37.3" fill="#c00" opacity="0.55"/> <rect x="339.5" y="487.7" width="9" height="41.3" fill="#c00" opacity="0.55"/>
<rect x="354.5" y="348.7" width="9" height="35.8" fill="#c00" opacity="0.55"/> <rect x="359.5" y="473.0" width="9" height="56.0" fill="#c00" opacity="0.55"/>
<rect x="369.5" y="350.3" width="9" height="34.2" fill="#c00" opacity="0.55"/> <rect x="379.5" y="491.7" width="9" height="37.3" fill="#c00" opacity="0.55"/>
<rect x="384.5" y="351.8" width="9" height="32.7" fill="#c00" opacity="0.55"/> <rect x="399.5" y="494.3" width="9" height="34.7" fill="#c00" opacity="0.55"/>
<rect x="399.5" y="353.4" width="9" height="31.1" fill="#c00" opacity="0.55"/> <rect x="419.5" y="495.7" width="9" height="33.3" fill="#c00" opacity="0.55"/>
<rect x="414.5" y="349.5" width="9" height="35.0" fill="#c00" opacity="0.55"/> <rect x="439.5" y="497.0" width="9" height="32.0" fill="#c00" opacity="0.55"/>
<rect x="429.5" y="345.6" width="9" height="38.9" fill="#188a3e" opacity="0.55"/> <rect x="459.5" y="498.3" width="9" height="30.7" fill="#c00" opacity="0.55"/>
<rect x="444.5" y="348.7" width="9" height="35.8" fill="#188a3e" opacity="0.55"/> <rect x="479.5" y="499.7" width="9" height="29.3" fill="#c00" opacity="0.55"/>
<rect x="459.5" y="350.3" width="9" height="34.2" fill="#c00" opacity="0.55"/> <rect x="499.5" y="501.0" width="9" height="28.0" fill="#c00" opacity="0.55"/>
<rect x="474.5" y="351.1" width="9" height="33.4" fill="#c00" opacity="0.55"/> <rect x="519.5" y="502.3" width="9" height="26.7" fill="#c00" opacity="0.55"/>
<rect x="489.5" y="349.5" width="9" height="35.0" fill="#188a3e" opacity="0.55"/> <rect x="539.5" y="499.0" width="9" height="30.0" fill="#c00" opacity="0.55"/>
<text x="24" y="308.5" fill="#555">volum</text> <rect x="559.5" y="495.7" width="9" height="33.3" fill="#188a3e" opacity="0.55"/>
<text x="254.0" y="58.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji 99.20 / 100.10</text> <rect x="579.5" y="498.3" width="9" height="30.7" fill="#188a3e" opacity="0.55"/>
<text x="449.0" y="148.0" fill="#c00" text-anchor="middle" style="font-weight:bold">ieșire pe trail 96.60</text> <rect x="599.5" y="499.7" width="9" height="29.3" fill="#c00" opacity="0.55"/>
<text x="24" y="406.5" fill="#777">bara 15: close 99.40 peste low-ul dojiului 99.20 — NU confirmă</text> <rect x="619.5" y="500.3" width="9" height="28.7" fill="#c00" opacity="0.55"/>
<text x="24" y="423.5" fill="#c00">bara 16: close 99.00 sub 99.20 — confirmare (intrare short)</text> <rect x="639.5" y="499.0" width="9" height="30.0" fill="#188a3e" opacity="0.55"/>
<text x="24" y="448" fill="#555">Intrare short la close sub low-ul dojiului, SL la high 4 candele, TP 1:1, apoi trail.</text> <text x="24" y="463.0" fill="#555">volum</text>
<line x1="514.0" y1="66.0" x2="411.8" y2="90.2" stroke="#c00" stroke-width="1.8"/>
<polygon points="404.0,92.0 410.9,86.3 412.7,94.1" fill="#c00"/>
<text x="514.0" y="47.0" fill="#c00" text-anchor="middle" style="font-weight:bold">STOPUL SUS, la 100.15 — 5 cenți peste maximul ultimelor 4 candele:</text>
<text x="514.0" y="61.0" fill="#c00" text-anchor="middle" style="font-weight:bold">dacă prețul urcă până aici, creșterea continuă și ideea e moartă</text>
<line x1="294.0" y1="257.0" x2="359.4" y2="165.0" stroke="#b06000" stroke-width="1.8"/>
<polygon points="364.0,158.5 362.6,167.3 356.1,162.7" fill="#b06000"/>
<text x="294.0" y="271.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">AICI INTRI SHORT, la 99.00:</text>
<text x="294.0" y="285.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">a doua candelă după doji e prima</text>
<text x="294.0" y="299.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">care se ÎNCHIDE sub low-ul lui (99.20)</text>
<line x1="512.5" y1="167.5" x2="439.9" y2="196.5" stroke="#188a3e" stroke-width="1.8"/>
<polygon points="432.5,199.5 438.4,192.8 441.4,200.2" fill="#188a3e"/>
<text x="516.5" y="164.5" fill="#188a3e" text-anchor="start" style="font-weight:bold">ținta JOS, la 97.85: tot 1.15, exact cât ai riscat;</text>
<text x="516.5" y="178.5" fill="#188a3e" text-anchor="start" style="font-weight:bold">aici închizi prima treime</text>
<line x1="544.0" y1="315.0" x2="577.3" y2="293.4" stroke="#555" stroke-width="1.8"/>
<polygon points="584.0,289.0 579.5,296.7 575.1,290.0" fill="#555"/>
<text x="544.0" y="329.0" fill="#555" text-anchor="middle" style="font-weight:bold">trail-ul a coborât după preț (96.45);</text>
<text x="544.0" y="343.0" fill="#555" text-anchor="middle" style="font-weight:bold">prima închidere peste el: ieși cu restul, 96.60</text>
<text x="24" y="559" fill="#555">Pe short câștigi când prețul COBOARĂ: stopul stă SUS, ținta JOS, trail-ul coboară după preț. Roșu = ce riști, verde = ce câștigi.</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,130 +1,146 @@
"""Buy Doji — unde pui stopul: 4 candele înapoi, sub structură (exemplu construit). """Buy Doji — unde pui stopul: 4 candele înapoi, sub structură.
Citește specificația `gen/strategii/buy_doji_stop.spec.txt`. Două panouri Citește `gen/strategii/buy_doji_stop.spec.txt`. Barele vin din
stivuite, aceeași serie 0-14 ca buy_doji_transe (downtrend, doji 12, +1 13, `buy_doji_ansamblu.serie()` — e același trade ca în toate celelalte
confirmare 14). Sus: numărătoarea celor 4 candele (1 = confirmarea). Jos: diagrame ale capitolului (doji 50.10/49.25, intrare 50.40, stop 49.20).
același trade, stop „la ochi" 52.90 față de stopul din regulă 51.55.
Panoul de sus: cum numeri cele 4 candele, de la confirmare înapoi.
Panoul de jos: același trade, cu un stop pus „la ochi" (49.70, sub candela
de confirmare) față de stopul din regulă (49.20). Al doilea picior al
fundului coboară la 49.50: mătură stopul la ochi, nu-l atinge pe cel din
regulă. Barele de după intrare sunt CONSTRUITE.
""" """
import re import re
import sys; sys.path.insert(0, "/workspace/atm-curs-dl") import sys
from svg_candles import Candle, Chart, Level, Mark from pathlib import Path
OUT = "/workspace/atm-curs-dl/gen/strategii/buy_doji_stop.svg" sys.path.insert(0, "/workspace/atm-curs-dl")
sys.path.insert(0, str(Path(__file__).parent))
from svg_candles import Candle, Chart, Level, Zone, Arrow # noqa: E402
from buy_doji_ansamblu import serie, DOJI, CONF, DOJI_L, ENTRY, SL, TP1, R # noqa: E402
# --- seria: barele 0-14 exact ca în buy_doji_transe.spec.txt ----------------- OUT = Path(__file__).with_suffix(".svg")
closes = [60.40, 59.60, 59.90, 58.80, 58.10, 58.40, 57.20, 56.30, 56.60, S = 6 # prima bară arătată din serie
55.30, 54.20, 52.40] OCHI = 49.70 # stopul „la ochi", sub candela de confirmare
bars, o = [], 61.00 GREEN, RED, ORANGE, BLUE, GREY = "#188a3e", "#c00", "#b06000", "#1a5fb4", "#555"
for c in closes: # fitile implicite 0.15 peste/sub corp W, VGAP = 720, 14
bars.append((o, max(o, c) + 0.15, min(o, c) - 0.15, c))
o = c
bars += [(52.40, 53.00, 51.60, 52.30), # 12 doji
(52.30, 52.85, 52.10, 52.60), # 13 +1
(52.60, 53.85, 52.45, 53.70)] # 14 confirmare
after = [(53.70, 53.75, 52.70, 52.90), # 15 lovește stopul la ochi
(52.90, 53.05, 52.00, 52.20), # 16 al doilea picior, higher low
(52.20, 53.40, 52.10, 53.30),
(53.30, 54.30, 53.20, 54.20),
(54.20, 55.10, 54.10, 55.00),
(55.00, 56.00, 54.90, 55.95)] # 20 TP1
full = bars + after
o_, h_, l_, c_ = (list(x) for x in zip(*full))
ENTRY, SL, OCHI, TP1, LOW4 = 53.70, 51.55, 52.90, 55.85, 51.60 base = serie()[S:CONF + 1] # până la confirmare, inclusiv
after = [Candle(*b) for b in [
(50.40, 50.50, 49.85, 49.95), # +1: corecție
(49.95, 50.05, 49.50, 49.60), # +2: al doilea picior, low 49.50 — mătură 49.70
(49.60, 50.35, 49.55, 50.25),
(50.25, 50.90, 50.15, 50.80),
(50.80, 51.35, 50.70, 51.25),
(51.25, 51.80, 51.15, 51.70), # +6: atinge ținta 51.60
]]
jos = base + after
d, cf = DOJI - S, CONF - S # indici locali: doji, confirmare
# --- assert-urile din spec --------------------------------------------------- # --- aserțiuni -----------------------------------------------------------------
for i in range(1, len(full)): # 1 for i, c in enumerate(jos):
assert abs(o_[i] - c_[i - 1]) < 1e-9, f"open[{i}] != close[{i-1}]" assert c.l <= min(c.o, c.c) and c.h >= max(c.o, c.c), f"bara {i}: h/l nu cuprind o/c"
for i in range(len(full)): if i:
assert l_[i] <= min(o_[i], c_[i]) and h_[i] >= max(o_[i], c_[i]), f"bara {i}" assert abs(c.o - jos[i - 1].c) < 1e-9, f"open[{i}] != close[{i-1}]"
assert min(l_[11:15]) == min(l_[10:15]) == LOW4 # 2 # 1. cel mai jos low e al doji-ului, și cu 4 și cu 5 candele numărate
assert l_.index(LOW4) == 12, "cel mai jos low nu e dojiul" assert min(c.l for c in jos[cf - 3:cf + 1]) == min(c.l for c in jos[cf - 4:cf + 1]) == DOJI_L
assert round(LOW4 - 0.05, 2) == SL assert jos[d].l == DOJI_L and round(DOJI_L - 0.05, 2) == SL
assert min(l_[15:21]) == 52.00 and SL < 52.00 < OCHI # 3 # 2. al doilea picior: mătură stopul la ochi, nu-l atinge pe cel din regulă
assert next(i for i in range(15, 21) if l_[i] <= OCHI) == 15 # 4 dip = [c.l for c in after]
assert all(l_[i] > SL for i in range(15, 21)) assert min(dip) == 49.50 and SL < 49.50 < OCHI, dip
assert next(i for i in range(15, 21) if h_[i] >= TP1) == 20 # 5 assert next(k for k, c in enumerate(after) if c.l <= OCHI) == 1, "stopul la ochi nu e lovit de al doilea picior"
assert 52.00 > LOW4 # 6 assert all(c.l > SL for c in after), "stopul din regulă ar fi fost lovit"
assert round(ENTRY - OCHI, 2) == 0.80 and c_[14] == ENTRY # 3. al doilea picior e higher low față de low-ul doji-ului
assert round(ENTRY + (ENTRY - SL), 2) == TP1 assert min(dip) > DOJI_L
# 4. ținta e atinsă abia după corecție, la a 6-a bară de după intrare
assert next(k for k, c in enumerate(after, 1) if c.h >= TP1) == 6
# 5. stopul la ochi e mai aproape de intrare decât cel din regulă, și peste low-ul doji-ului
assert round(ENTRY - OCHI, 2) == 0.70 < R and DOJI_L < OCHI < jos[cf].l # sub candela de confirmare, peste low-ul doji-ului
assert round(ENTRY - SL, 2) == R
print(f"stop: low4 {DOJI_L:.2f} -> SL {SL:.2f}; la ochi {OCHI:.2f} lovit de low {min(dip):.2f}; "
f"țintă {TP1:.2f} la a 6-a bară")
GREY, RED, ORANGE, GREEN, BLUE = "#555", "#c00", "#b06000", "#188a3e", "#1a5fb4" common: dict = dict(scale=36.0, gap=20, body_w=10, left=48, width=W)
W = 640
common: dict = dict(scale=34.0, gap=18, body_w=10, left=44, width=W)
# --- panoul de sus: numărătoarea celor 4 candele --------------------------------
def mk(n): sus = Chart(
return [Candle(*b) for b in full[:n]] candles=base,
levels=[Level(SL, "stopul: 49.20", RED, "4 3", "left")],
zones=[Zone(cf - 3, cf, "numeri 4 candele, începând cu confirmarea", BLUE)],
# --- panoul de sus: numărătoarea --------------------------------------------- arrows=[
top = Chart( Arrow(d, "cel mai jos low din cele 4: 49.25\n(e al doji-ului)",
candles=mk(15), where="below", price=DOJI_L, color=GREY, dx=250, dy=34),
levels=[Level(LOW4, "cel mai jos low: 51.60 (doji)", GREY, "2 2", "left"), Arrow(cf - 1, "stopul: 49.20, cu 5 cenți mai jos\nsub el, ideea că vânzătorii\nau obosit e moartă",
Level(SL, "SL 51.55", RED, "4 3")], where="below", price=SL, color=RED, dx=250, dy=76),
# fără Mark pe doji: la gap 18 eticheta calcă pe bara 11; îl numește Arrow(cf, "confirmarea: close 50.40\nde aici numeri înapoi",
# paranteza de dedesubt și cercul de pe low where="above", color=GREEN, dx=250),
marks=[Mark(14, "confirmare 53.70", GREEN, "above")], ],
title="Unde pui stopul: 4 candele înapoi, sub structură — exemplu construit", title="Pasul 5 — stopul: numeri 4 candele înapoi de la confirmare",
**common, **common,
) )
svg_top = top.render()
# numerele 4 3 2 1 + (5) sub bare, bandă de evidențiere, paranteză
yb = top._y(SL) + 18 # rândul cu numere, sub linia de SL
x = top._cx
extra_top = [
f'<rect x="{x(11) - 8:.1f}" y="{top._y(max(h_[11:15])) - 4:.1f}" '
f'width="{x(14) - x(11) + 16:.1f}" height="{yb + 6 - top._y(max(h_[11:15])):.1f}" '
f'fill="{BLUE}" opacity="0.08"/>',
f'<circle cx="{x(12):.1f}" cy="{top._y(LOW4):.1f}" r="4" fill="none" '
f'stroke="{RED}" stroke-width="1.5"/>',
]
for i, n in zip(range(11, 15), "4321"):
extra_top.append(f'<text x="{x(i):.1f}" y="{yb:.1f}" fill="{BLUE}" '
f'text-anchor="middle" style="font-weight:bold">{n}</text>')
extra_top.append(f'<text x="{x(10):.1f}" y="{yb:.1f}" fill="#999" '
f'text-anchor="middle">(5)</text>')
yp = yb + 8
extra_top.append(f'<polyline points="{x(11) - 5:.1f},{yp:.1f} {x(11) - 5:.1f},{yp + 5:.1f} '
f'{x(14) + 5:.1f},{yp + 5:.1f} {x(14) + 5:.1f},{yp:.1f}" '
f'fill="none" stroke="{BLUE}" stroke-width="1.2"/>')
extra_top.append(f'<text x="{x(14) + 14:.1f}" y="{yp + 9:.1f}" fill="{BLUE}">'
f'ultimele 4 candele (3 = doji, 1 = confirmarea)</text>')
extra_top.append(f'<text x="24" y="{yp + 28:.1f}" fill="#555">'
f'Cu 4 sau cu 5 candele iese la fel: în downtrend low-ul dojiului '
f'e oricum cel mai jos. SL = 51.60 − 0.05.</text>')
h_top = yp + 40
# --- panoul de jos: același trade, două stopuri ------------------------------- # --- panoul de jos: stop la ochi vs stop din regulă -----------------------------
bot = Chart( gata = Chart(
candles=mk(21), candles=jos,
levels=[Level(TP1, "TP1 55.85", GREEN, "2 2"), levels=[Level(TP1, "ținta 1: 51.60", GREEN, "2 2", "left"),
Level(ENTRY, "intrare 53.70", GREY, "4 3"), Level(ENTRY, "intrarea: 50.40", GREY, "4 3", "left"),
Level(OCHI, "stop la ochi 52.90 — lovit", ORANGE, "4 3"), Level(OCHI, "stop pus la ochi: 49.70", ORANGE, "4 3", "left"),
Level(SL, "SL din regulă 51.55 — ținut", RED, "4 3")], Level(SL, "stopul din regulă: 49.20", RED, "4 3", "left")],
marks=[Mark(16, "al doilea picior: 52.00, higher low", BLUE, "below", dy=10), # eticheta zonei o punem manual: Zone o ridică deasupra candelelor din
Mark(20, "TP1", GREEN, "above")], # dreptul textului, adică departe de banda pe care o marchează
title="Același trade: stop la ochi (0.80 sub intrare) vs stop din regulă", zones=[Zone(cf + 1, cf + 2, "", RED, p_top=OCHI, p_bot=SL)],
caption="Barele 15-20 și stopul la ochi sunt construite, pentru contrast.", arrows=[
top=h_top + 10 + 34, # panoul de jos începe sub cel de sus, fără <g transform> Arrow(cf + 2, "stopul pus la ochi (49.70) e măturat\nera prea aproape de intrare",
where="below", price=OCHI, color=ORANGE, dx=230, dy=6),
Arrow(cf + 2, "al doilea picior al fundului: 49.50\nfundurile fac des asta",
where="below", price=49.50, color=BLUE, dx=230, dy=56),
Arrow(cf + 1, "stopul din regulă (49.20) ține\nal doilea picior rămâne peste el",
where="below", price=SL, color=RED, dx=230, dy=106),
Arrow(len(jos) - 1, "prețul ajunge la țintă\ndar numai cu stopul corect\nmai erai în trade",
where="above", price=TP1, color=GREEN, dx=150),
],
title="Același trade: stop „la ochi” (sub candela de confirmare) vs stopul din regulă",
caption="Barele de după intrare și stopul la ochi sunt construite, pentru contrast.",
**common, **common,
) )
svg_bot = bot.render()
extra_bot = [
f'<circle cx="{bot._cx(15):.1f}" cy="{bot._y(OCHI):.1f}" r="5" fill="none" '
f'stroke="{ORANGE}" stroke-width="2"/>',
]
# header-ul (viewBox) e al panoului de jos: el conține și offset-ul celui de sus def panou(ch, sus_de=0.0):
ch.top += sus_de
svg = ch.render()
h = float(re.search(r'viewBox="0 0 [\d.]+ ([\d.]+)"', svg).group(1))
# render() mută `top` intern și îl restaurează; offsetul se citește din
# prima linie de Level, altfel tot ce desenăm pe urmă iese mai sus cu ~22px
off = float(re.search(r'<line x1="24" y1="([\d.]+)"', svg).group(1)) - ch._y(ch.levels[0].price)
return svg[svg.index(">") + 1:svg.rindex("</svg>")].strip(), h, off
body_sus, h_sus, off_sus = panou(sus)
# numerele 4 3 2 1 sub barele numărate, plus (5) — arată că iese la fel
yb = sus._y(SL) + off_sus + 22
nums = []
for k, n in zip(range(cf - 3, cf + 1), "4321"):
nums.append(f'<text x="{sus._cx(k):.1f}" y="{yb:.1f}" fill="{BLUE}" text-anchor="middle" '
f'style="font-weight:bold">{n}</text>')
nums.append(f'<text x="{sus._cx(cf - 4):.1f}" y="{yb:.1f}" fill="#999" text-anchor="middle">(5)</text>')
nums.append(f'<text x="24" y="{yb + 20:.1f}" fill="#555">'
f'cu 4 sau cu 5 candele iese la fel: în scădere, low-ul doji-ului e oricum cel mai jos</text>')
h_sus = max(h_sus, yb + 32)
body_jos, h_jos, off_jos = panou(gata, h_sus + VGAP)
zx = gata._cx(cf + 3) + 10
banda = (f'<text x="{zx:.1f}" y="{gata._y(OCHI) + off_jos - 6:.1f}" fill="{RED}" '
f'style="font-weight:bold">pe aici trece al doilea picior</text>')
H = h_jos + 8
svg = "\n ".join([ svg = "\n ".join([
svg_bot.split(">", 1)[0] + ">", f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/svg" '
svg_top.split(">", 1)[1].rsplit("</svg>", 1)[0].strip(), *extra_top, f'style="width:100%;height:auto;font:12px sans-serif">',
f'<line x1="24" y1="{h_top + 2:.0f}" x2="{W - 14}" y2="{h_top + 2:.0f}" stroke="#ccc"/>', body_sus, *nums,
svg_bot.split(">", 1)[1].rsplit("</svg>", 1)[0].strip(), *extra_bot, f'<line x1="24" y1="{h_sus + VGAP / 2:.0f}" x2="{W - 14}" y2="{h_sus + VGAP / 2:.0f}" stroke="#ddd"/>',
body_jos, banda,
]) + "\n</svg>" ]) + "\n</svg>"
H = float(re.search(r'viewBox="0 0 \d+ ([\d.]+)"', svg).group(1)) assert "\n\n" not in svg and "<svg" in svg, "linie goală în SVG"
assert "<svg" in svg and "\n\n" not in svg, "linie goală în SVG" for x, y in re.findall(r'<text x="([-\d.]+)" y="([-\d.]+)"', svg):
with open(OUT, "w") as f: assert 0 <= float(x) <= W and 0 <= float(y) <= H, f"text în afara pânzei la ({x}, {y})"
f.write(svg) OUT.write_text(svg, encoding="utf-8")
print(f"scris {OUT} ({W}x{H:.0f})") print(f"scris {OUT} ({W}x{H:.0f})")

View File

@@ -1,55 +1,63 @@
SPEC DIAGRAMĂ — buy_doji_stop SPEC DIAGRAMĂ — buy_doji_stop
============================= =============================
tip: PRET, două panouri stivuite, aceeași serie până la bara 14 tip: PRET, două panouri stivuite
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 8 (stopul) destinație: summaries/17_STRATEGII/01_buy_doji.md, pasul cu stopul
cheie markdown: <!-- DIAGRAMA: stop --> cheie markdown: <!-- DIAGRAMA: stop -->
titlu SVG: „Unde pui stopul: 4 candele înapoi, sub structură — exemplu construit" titluri SVG: sus „Pasul 5 — stopul: numeri 4 candele înapoi de la confirmare";
stil: ca buy_doji_transe (aceleași bare 0-14, copiate sau importate). jos „Același trade: stop «la ochi» (sub candela de confirmare) vs stopul din regulă"
serie: `buy_doji_ansamblu.serie()`, barele 6-16 (același trade ca în tot
capitolul: doji 50.10/49.25, intrare 50.40, stop 49.20).
CE TREBUIE SĂ DEMONSTREZE CE TREBUIE SĂ DEMONSTREZE
------------------------- -------------------------
Sus: cum numeri cele 4 candele (confirmarea și cele 3 dinainte), și de ce Sus: cum numeri cele 4 candele (confirmarea și cele 3 dinainte) și de ce în
în downtrend nu contează dacă numeri 4 sau 5: low-ul dojiului e oricum cel scădere nu contează dacă numeri 4 sau 5 — low-ul doji-ului e oricum cel mai jos.
mai jos. Jos: același trade, cu un stop pus „la ochi" (52.90, sub intrare Jos: același trade, cu un stop pus „la ochi" la 49.70 (sub candela de
cu 0.80) față de stopul din regulă (51.55). Piciorul al doilea coboară la confirmare, care are low 49.75) față de stopul din regulă, 49.20. Al doilea
52.00: lovește stopul la ochi, nu atinge stopul din regulă; apoi prețul picior al fundului coboară la 49.50: mătură stopul la ochi, nu-l atinge pe cel
ajunge la TP1. din regulă; apoi prețul ajunge la ținta 51.60.
SERIA BARELE DE DUPĂ INTRARE (panoul de jos, CONSTRUITE)
----- --------------------------------------------------
Barele 0-14: identice cu buy_doji_transe (downtrend, doji 12, +1 13, +1 (50.40, 50.50, 49.85, 49.95)
confirmare 14). +2 (49.95, 50.05, 49.50, 49.60) <- al doilea picior, low 49.50
Panoul de sus: doar barele 0-14 (se oprește la intrare). +3 (49.60, 50.35, 49.55, 50.25)
Panoul de jos: barele 0-14, apoi: +4 (50.25, 50.90, 50.15, 50.80)
15 (53.70, 53.75, 52.70, 52.90) +5 (50.80, 51.35, 50.70, 51.25)
16 (52.90, 53.05, 52.00, 52.20) <- al doilea picior, higher low 52.00 +6 (51.25, 51.80, 51.15, 51.70) <- atinge ținta 51.60
17 (52.20, 53.40, 52.10, 53.30)
18 (53.30, 54.30, 53.20, 54.20)
19 (54.20, 55.10, 54.10, 55.00)
20 (55.00, 56.00, 54.90, 55.95) <- TP1 55.85 atins
MARKS / NIVELURI ADNOTĂRI
---------------- --------
Sus: numerotare „4 3 2 1" sub barele 11, 12, 13, 14 (1 = confirmarea); Sus: zonă albastră peste cele 4 candele numărate, „numeri 4 candele, începând
paranteză „ultimele 4 candele"; Level 51.60 „cel mai jos low: 51.60 (doji)"; cu confirmarea"; numerele 4 3 2 1 sub ele și (5) sub a cincea; Level „stopul:
Level 51.55 roșu „SL 51.55". 49.20"; săgeți: „cel mai jos low din cele 4: 49.25 (e al doji-ului)",
Jos: Level 52.90 portocaliu „stop la ochi 52.90 — lovit"; Level 51.55 roșu „stopul: 49.20, cu 5 cenți mai jos / sub el, ideea că vânzătorii au obosit e
„SL din regulă 51.55 — ținut"; Level 55.85 verde punctat „TP1 55.85"; moartă", „confirmarea: close 50.40 / de aici numeri înapoi".
Mark(16, "al doilea picior: 52.00, higher low", below). Jos: Level-uri 51.60 / 50.40 / 49.70 / 49.20; zonă roșie între 49.70 și 49.20
peste barele +1 și +2, etichetă „pe aici trece al doilea picior"; săgeți:
stopul la ochi măturat, al doilea picior 49.50 („fundurile fac des asta"),
stopul din regulă ține, și „prețul ajunge la țintă / dar numai cu stopul corect
mai erai în trade".
ASSERT-URI ASSERT-URI
---------- ----------
1. open[i] == close[i-1] pe barele 15-20; h/l cuprind o/c. 1. h/l cuprind o/c; open[i] == close[i-1] pe toată seria panoului de jos.
2. min(l[11:15]) == min(l[10:15]) == 51.60 (4 sau 5 candele: același rezultat). 2. min(low) pe ultimele 4 candele == pe ultimele 5 == 49.25 (low-ul doji-ului);
3. min(l[15:21]) == 52.00; 52.00 < 52.90 și 52.00 > 51.55. 49.25 - 0.05 == 49.20.
4. primul i>14 cu low <= 52.90 este 15; niciun low din 15-20 <= 51.55. 3. min(low) după intrare == 49.50, cu 49.20 < 49.50 < 49.70.
5. primul i>14 cu high >= 55.85 este 20. 4. prima bară de după intrare cu low <= 49.70 e a doua (al doilea picior);
6. 52.00 > 51.60 (al doilea picior e higher low). nicio bară de după intrare nu are low <= 49.20.
5. ținta 51.60 e atinsă abia la a 6-a bară de după intrare.
6. 49.50 > 49.25 (al doilea picior e higher low).
7. 50.40 - 49.70 == 0.70 < 1.20 (stopul la ochi e mai aproape de intrare) și
49.25 < 49.70 < low-ul candelei de confirmare (49.75).
8. niciun text nu iese din pânză.
SURSA SURSA
----- -----
- SL = extrema ultimelor 4 candele de la confirmare: summaries/03_MODUL_2/13_strategia_3_byh.md:192-193; - SL = extrema ultimelor 4 candele de la confirmare: summaries/03_MODUL_2/
în practică swing low-ul: summaries/09_QA/22_2025-08-04.md:23-29. 13_strategia_3_byh.md:192-193; în practică swing low-ul: summaries/09_QA/
- Stopul sub structură, nu „undeva jos"; bottom-ul mai poate face un picior: 22_2025-08-04.md:23-29.
- Stopul sub structură; bottom-ul mai poate face un picior:
summaries/08_ANALIZA_ZILNICA/01_buy_doji_si_strategia_mici.md:833-836. summaries/08_ANALIZA_ZILNICA/01_buy_doji_si_strategia_mici.md:833-836.
- Stopul „la ochi" 52.90 și barele 15-20 sunt CONSTRUITE (contrast). - Stopul „la ochi" 49.70 și barele de după intrare sunt CONSTRUITE (contrast).

View File

@@ -1,104 +1,112 @@
<svg viewBox="0 0 640 883" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 720 1162" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="48" fill="#333" style="font-weight:bold">Unde pui stopul: 4 candele înapoi, sub structură — exemplu construit</text> <text x="24" y="48" fill="#333" style="font-weight:bold">Pasul 5 — stopul: numeri 4 candele înapoi de la confirmare</text>
<line x1="24" y1="380.7" x2="626" y2="380.7" stroke="#555" stroke-width="1.5" stroke-dasharray="2 2"/> <rect x="178.0" y="289.2" width="80.0" height="88.0" fill="#1a5fb4" fill-opacity="0.08" stroke="#1a5fb4" stroke-width="1"/>
<text x="30" y="374.7" fill="#555">cel mai jos low: 51.60 (doji)</text> <text x="178.0" y="284.2" fill="#1a5fb4" style="font-weight:bold">numeri 4 candele, începând cu confirmarea</text>
<line x1="24" y1="382.4" x2="626" y2="382.4" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/> <line x1="24" y1="371.0" x2="706" y2="371.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="612" y="376.4" fill="#c00" text-anchor="end">SL 51.55</text> <text x="30" y="365.0" fill="#c00">stopul: 49.20</text>
<line x1="44.0" y1="56.0" x2="44.0" y2="86.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="48.0" y1="56.0" x2="48.0" y2="119.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="39.0" y="61.1" width="10" height="20.4" fill="#c00"/> <rect x="43.0" y="65.0" width="10" height="43.2" fill="#c00"/>
<line x1="62.0" y1="76.4" x2="62.0" y2="113.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="68.0" y1="99.2" x2="68.0" y2="158.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="57.0" y="81.5" width="10" height="27.2" fill="#c00"/> <rect x="63.0" y="108.2" width="10" height="39.6" fill="#c00"/>
<line x1="80.0" y1="93.4" x2="80.0" y2="113.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="88.0" y1="124.4" x2="88.0" y2="158.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="75.0" y="98.5" width="10" height="10.2" fill="#188a3e"/> <rect x="83.0" y="133.4" width="10" height="14.4" fill="#188a3e"/>
<line x1="98.0" y1="93.4" x2="98.0" y2="141.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="108.0" y1="124.4" x2="108.0" y2="183.8" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="93.0" y="98.5" width="10" height="37.4" fill="#c00"/> <rect x="103.0" y="133.4" width="10" height="39.6" fill="#c00"/>
<line x1="116.0" y1="130.8" x2="116.0" y2="164.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="128.0" y1="164.0" x2="128.0" y2="227.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="111.0" y="135.9" width="10" height="23.8" fill="#c00"/> <rect x="123.0" y="173.0" width="10" height="43.2" fill="#c00"/>
<line x1="134.0" y1="144.4" x2="134.0" y2="164.8" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="148.0" y1="207.2" x2="148.0" y2="270.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="129.0" y="149.5" width="10" height="10.2" fill="#188a3e"/> <rect x="143.0" y="216.2" width="10" height="43.2" fill="#c00"/>
<line x1="152.0" y1="144.4" x2="152.0" y2="195.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="168.0" y1="250.4" x2="168.0" y2="317.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="147.0" y="149.5" width="10" height="40.8" fill="#c00"/> <rect x="163.0" y="259.4" width="10" height="46.8" fill="#c00"/>
<line x1="170.0" y1="185.2" x2="170.0" y2="226.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="188.0" y1="297.2" x2="188.0" y2="365.6" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="165.0" y="190.3" width="10" height="30.6" fill="#c00"/> <rect x="183.0" y="306.2" width="10" height="48.6" fill="#c00"/>
<line x1="188.0" y1="205.6" x2="188.0" y2="226.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="208.0" y1="338.6" x2="208.0" y2="369.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="183.0" y="210.7" width="10" height="10.2" fill="#188a3e"/> <rect x="203.0" y="354.8" width="10" height="1.8" fill="#c00"/>
<line x1="206.0" y1="205.6" x2="206.0" y2="260.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="228.0" y1="340.4" x2="228.0" y2="362.0" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="201.0" y="210.7" width="10" height="44.2" fill="#c00"/> <rect x="223.0" y="345.8" width="10" height="10.8" fill="#188a3e"/>
<line x1="224.0" y1="249.8" x2="224.0" y2="297.4" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="248.0" y1="322.4" x2="248.0" y2="351.2" stroke="#1a1a1a" stroke-width="1.2"/>
<rect x="219.0" y="254.9" width="10" height="37.4" fill="#c00"/> <rect x="243.0" y="327.8" width="10" height="18.0" fill="#188a3e"/>
<line x1="242.0" y1="287.2" x2="242.0" y2="358.6" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="458.0" y1="433.2" x2="215.8" y2="375.1" stroke="#555" stroke-width="1.8"/>
<rect x="237.0" y="292.3" width="10" height="61.2" fill="#c00"/> <polygon points="208.0,373.2 216.7,371.2 214.8,379.0" fill="#555"/>
<line x1="260.0" y1="333.1" x2="260.0" y2="380.7" stroke="#1a1a1a" stroke-width="1.2"/> <text x="458.0" y="447.2" fill="#555" text-anchor="middle" style="font-weight:bold">cel mai jos low din cele 4: 49.25</text>
<rect x="255.0" y="353.5" width="10" height="3.4" fill="#c00"/> <text x="458.0" y="461.2" fill="#555" text-anchor="middle" style="font-weight:bold">(e al doji-ului)</text>
<line x1="278.0" y1="338.2" x2="278.0" y2="363.7" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="478.0" y1="477.0" x2="235.4" y2="378.0" stroke="#c00" stroke-width="1.8"/>
<rect x="273.0" y="346.7" width="10" height="10.2" fill="#188a3e"/> <polygon points="228.0,375.0 236.9,374.3 233.9,381.7" fill="#c00"/>
<line x1="296.0" y1="304.2" x2="296.0" y2="351.8" stroke="#1a1a1a" stroke-width="1.2"/> <text x="478.0" y="491.0" fill="#c00" text-anchor="middle" style="font-weight:bold">stopul: 49.20, cu 5 cenți mai jos</text>
<rect x="291.0" y="309.3" width="10" height="37.4" fill="#188a3e"/> <text x="478.0" y="505.0" fill="#c00" text-anchor="middle" style="font-weight:bold">sub el, ideea că vânzătorii</text>
<text x="296.0" y="294.2" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare 53.70</text> <text x="478.0" y="519.0" fill="#c00" text-anchor="middle" style="font-weight:bold">au obosit e moartă</text>
<rect x="234.0" y="283.2" width="70.0" height="119.2" fill="#1a5fb4" opacity="0.08"/> <line x1="498.0" y1="292.4" x2="256.0" y2="317.6" stroke="#188a3e" stroke-width="1.8"/>
<circle cx="260.0" cy="380.7" r="4" fill="none" stroke="#c00" stroke-width="1.5"/> <polygon points="248.0,318.4 255.5,313.6 256.4,321.6" fill="#188a3e"/>
<text x="242.0" y="400.4" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">4</text> <text x="498.0" y="273.4" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmarea: close 50.40</text>
<text x="260.0" y="400.4" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">3</text> <text x="498.0" y="287.4" fill="#188a3e" text-anchor="middle" style="font-weight:bold">de aici numeri înapoi</text>
<text x="278.0" y="400.4" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">2</text> <text x="188.0" y="393.0" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">4</text>
<text x="296.0" y="400.4" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">1</text> <text x="208.0" y="393.0" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">3</text>
<text x="224.0" y="400.4" fill="#999" text-anchor="middle">(5)</text> <text x="228.0" y="393.0" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">2</text>
<polyline points="237.0,408.4 237.0,413.4 301.0,413.4 301.0,408.4" fill="none" stroke="#1a5fb4" stroke-width="1.2"/> <text x="248.0" y="393.0" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">1</text>
<text x="310.0" y="417.4" fill="#1a5fb4">ultimele 4 candele (3 = doji, 1 = confirmarea)</text> <text x="168.0" y="393.0" fill="#999" text-anchor="middle">(5)</text>
<text x="24" y="436.4" fill="#555">Cu 4 sau cu 5 candele iese la fel: în downtrend low-ul dojiului e oricum cel mai jos. SL = 51.60 − 0.05.</text> <text x="24" y="413.0" fill="#555">cu 4 sau cu 5 candele iese la fel: în scădere, low-ul doji-ului e oricum cel mai jos</text>
<line x1="24" y1="450" x2="626" y2="450" stroke="#ccc"/> <line x1="24" y1="561" x2="706" y2="561" stroke="#ddd"/>
<text x="24" y="506" fill="#333" style="font-weight:bold">Același trade: stop la ochi (0.80 sub intrare) vs stop din regulă</text> <text x="24" y="616" fill="#333" style="font-weight:bold">Același trade: stop „la ochi” (sub candela de confirmare) vs stopul din regulă</text>
<line x1="24" y1="694.6" x2="626" y2="694.6" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 2"/> <rect x="258.0" y="921.0" width="40.0" height="18.0" fill="#c00" fill-opacity="0.08" stroke="#c00" stroke-width="1"/>
<text x="612" y="688.6" fill="#188a3e" text-anchor="end">TP1 55.85</text> <line x1="24" y1="852.6" x2="706" y2="852.6" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 2"/>
<line x1="24" y1="767.7" x2="626" y2="767.7" stroke="#555" stroke-width="1.5" stroke-dasharray="4 3"/> <text x="30" y="846.6" fill="#188a3e">ținta 1: 51.60</text>
<text x="612" y="761.7" fill="#555" text-anchor="end">intrare 53.70</text> <line x1="24" y1="895.8" x2="706" y2="895.8" stroke="#555" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="24" y1="794.9" x2="626" y2="794.9" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/> <text x="30" y="889.8" fill="#555">intrarea: 50.40</text>
<text x="612" y="788.9" fill="#b06000" text-anchor="end">stop la ochi 52.90 — lovit</text> <line x1="24" y1="921.0" x2="706" y2="921.0" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="24" y1="840.8" x2="626" y2="840.8" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/> <text x="30" y="915.0" fill="#b06000">stop pus la ochi: 49.70</text>
<text x="612" y="834.8" fill="#c00" text-anchor="end">SL din regulă 51.55 — ținut</text> <line x1="24" y1="939.0" x2="706" y2="939.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="44.0" y1="514.4" x2="44.0" y2="545.0" stroke="#1a1a1a" stroke-width="1.2"/> <text x="30" y="933.0" fill="#c00">stopul din regulă: 49.20</text>
<rect x="39.0" y="519.5" width="10" height="20.4" fill="#c00"/> <line x1="48.0" y1="624.0" x2="48.0" y2="687.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="62.0" y1="534.8" x2="62.0" y2="572.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="43.0" y="633.0" width="10" height="43.2" fill="#c00"/>
<rect x="57.0" y="539.9" width="10" height="27.2" fill="#c00"/> <line x1="68.0" y1="667.2" x2="68.0" y2="726.6" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="80.0" y1="551.8" x2="80.0" y2="572.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="63.0" y="676.2" width="10" height="39.6" fill="#c00"/>
<rect x="75.0" y="556.9" width="10" height="10.2" fill="#188a3e"/> <line x1="88.0" y1="692.4" x2="88.0" y2="726.6" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="98.0" y1="551.8" x2="98.0" y2="599.4" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="83.0" y="701.4" width="10" height="14.4" fill="#188a3e"/>
<rect x="93.0" y="556.9" width="10" height="37.4" fill="#c00"/> <line x1="108.0" y1="692.4" x2="108.0" y2="751.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="116.0" y1="589.2" x2="116.0" y2="623.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="103.0" y="701.4" width="10" height="39.6" fill="#c00"/>
<rect x="111.0" y="594.3" width="10" height="23.8" fill="#c00"/> <line x1="128.0" y1="732.0" x2="128.0" y2="795.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="134.0" y1="602.8" x2="134.0" y2="623.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="123.0" y="741.0" width="10" height="43.2" fill="#c00"/>
<rect x="129.0" y="607.9" width="10" height="10.2" fill="#188a3e"/> <line x1="148.0" y1="775.2" x2="148.0" y2="838.2" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="152.0" y1="602.8" x2="152.0" y2="653.8" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="143.0" y="784.2" width="10" height="43.2" fill="#c00"/>
<rect x="147.0" y="607.9" width="10" height="40.8" fill="#c00"/> <line x1="168.0" y1="818.4" x2="168.0" y2="885.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="170.0" y1="643.6" x2="170.0" y2="684.4" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="163.0" y="827.4" width="10" height="46.8" fill="#c00"/>
<rect x="165.0" y="648.7" width="10" height="30.6" fill="#c00"/> <line x1="188.0" y1="865.2" x2="188.0" y2="933.6" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="188.0" y1="664.0" x2="188.0" y2="684.4" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="183.0" y="874.2" width="10" height="48.6" fill="#c00"/>
<rect x="183.0" y="669.1" width="10" height="10.2" fill="#188a3e"/> <line x1="208.0" y1="906.6" x2="208.0" y2="937.2" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="206.0" y1="664.0" x2="206.0" y2="718.4" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="203.0" y="922.8" width="10" height="1.8" fill="#c00"/>
<rect x="201.0" y="669.1" width="10" height="44.2" fill="#c00"/> <line x1="228.0" y1="908.4" x2="228.0" y2="930.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="224.0" y1="708.2" x2="224.0" y2="755.8" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="223.0" y="913.8" width="10" height="10.8" fill="#188a3e"/>
<rect x="219.0" y="713.3" width="10" height="37.4" fill="#c00"/> <line x1="248.0" y1="890.4" x2="248.0" y2="919.2" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="242.0" y1="745.6" x2="242.0" y2="817.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="243.0" y="895.8" width="10" height="18.0" fill="#188a3e"/>
<rect x="237.0" y="750.7" width="10" height="61.2" fill="#c00"/> <line x1="268.0" y1="892.2" x2="268.0" y2="915.6" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="260.0" y1="791.5" x2="260.0" y2="839.1" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="263.0" y="895.8" width="10" height="16.2" fill="#c00"/>
<rect x="255.0" y="811.9" width="10" height="3.4" fill="#c00"/> <line x1="288.0" y1="908.4" x2="288.0" y2="928.2" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="278.0" y1="796.6" x2="278.0" y2="822.1" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="283.0" y="912.0" width="10" height="12.6" fill="#c00"/>
<rect x="273.0" y="805.1" width="10" height="10.2" fill="#188a3e"/> <line x1="308.0" y1="897.6" x2="308.0" y2="926.4" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="296.0" y1="762.6" x2="296.0" y2="810.2" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="303.0" y="901.2" width="10" height="23.4" fill="#188a3e"/>
<rect x="291.0" y="767.7" width="10" height="37.4" fill="#188a3e"/> <line x1="328.0" y1="877.8" x2="328.0" y2="904.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="314.0" y1="766.0" x2="314.0" y2="801.7" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="323.0" y="881.4" width="10" height="19.8" fill="#188a3e"/>
<rect x="309.0" y="767.7" width="10" height="27.2" fill="#c00"/> <line x1="348.0" y1="861.6" x2="348.0" y2="885.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="332.0" y1="789.8" x2="332.0" y2="825.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="343.0" y="865.2" width="10" height="16.2" fill="#188a3e"/>
<rect x="327.0" y="794.9" width="10" height="23.8" fill="#c00"/> <line x1="368.0" y1="845.4" x2="368.0" y2="868.8" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="350.0" y1="777.9" x2="350.0" y2="822.1" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="363.0" y="849.0" width="10" height="16.2" fill="#188a3e"/>
<rect x="345.0" y="781.3" width="10" height="37.4" fill="#188a3e"/> <line x1="518.0" y1="957.0" x2="295.9" y2="926.1" stroke="#b06000" stroke-width="1.8"/>
<line x1="368.0" y1="747.3" x2="368.0" y2="784.7" stroke="#1a1a1a" stroke-width="1.2"/> <polygon points="288.0,925.0 296.5,922.1 295.4,930.1" fill="#b06000"/>
<rect x="363.0" y="750.7" width="10" height="30.6" fill="#188a3e"/> <text x="518.0" y="971.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">stopul pus la ochi (49.70) e măturat</text>
<line x1="386.0" y1="720.1" x2="386.0" y2="754.1" stroke="#1a1a1a" stroke-width="1.2"/> <text x="518.0" y="985.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">era prea aproape de intrare</text>
<rect x="381.0" y="723.5" width="10" height="27.2" fill="#188a3e"/> <line x1="518.0" y1="1014.2" x2="295.5" y2="934.9" stroke="#1a5fb4" stroke-width="1.8"/>
<line x1="404.0" y1="689.5" x2="404.0" y2="726.9" stroke="#1a1a1a" stroke-width="1.2"/> <polygon points="288.0,932.2 296.9,931.1 294.2,938.7" fill="#1a5fb4"/>
<rect x="399.0" y="691.2" width="10" height="32.3" fill="#188a3e"/> <text x="518.0" y="1028.2" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">al doilea picior al fundului: 49.50</text>
<text x="332.0" y="854.8" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">al doilea picior: 52.00, higher low</text> <text x="518.0" y="1042.2" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">fundurile fac des asta</text>
<text x="404.0" y="679.5" fill="#188a3e" text-anchor="middle" style="font-weight:bold">TP1</text> <line x1="498.0" y1="1075.0" x2="274.9" y2="947.0" stroke="#c00" stroke-width="1.8"/>
<text x="24" y="871" fill="#555">Barele 15-20 și stopul la ochi sunt construite, pentru contrast.</text> <polygon points="268.0,943.0 276.9,943.5 272.9,950.5" fill="#c00"/>
<circle cx="314.0" cy="794.9" r="5" fill="none" stroke="#b06000" stroke-width="2"/> <text x="498.0" y="1089.0" fill="#c00" text-anchor="middle" style="font-weight:bold">stopul din regulă (49.20) ține</text>
<text x="498.0" y="1103.0" fill="#c00" text-anchor="middle" style="font-weight:bold">al doilea picior rămâne peste el</text>
<line x1="518.0" y1="822.6" x2="375.9" y2="847.2" stroke="#188a3e" stroke-width="1.8"/>
<polygon points="368.0,848.6 375.2,843.3 376.6,851.2" fill="#188a3e"/>
<text x="518.0" y="789.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">prețul ajunge la țintă</text>
<text x="518.0" y="803.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">dar numai cu stopul corect</text>
<text x="518.0" y="817.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">mai erai în trade</text>
<text x="24" y="1142" fill="#555">Barele de după intrare și stopul la ochi sunt construite, pentru contrast.</text>
<text x="318.0" y="915.0" fill="#c00" style="font-weight:bold">pe aici trece al doilea picior</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@@ -1,132 +1,134 @@
"""Buy Doji — intrarea în trei tranșe (exemplu construit, doji 53.00 / 51.60). """Buy Doji — intrarea în trei tranșe, pe același trade ca restul capitolului.
Citește specificația `gen/strategii/buy_doji_transe.spec.txt`. Barele 0-14 Citește `gen/strategii/buy_doji_transe.spec.txt`. Barele vin din
sunt aceleași ca în buy_doji_stop.py. Nivelurile de 1/3 și 1/2 se calculează `buy_doji_ansamblu.serie()`: doji 50.10/49.25, confirmare cu close 50.40,
din corpul candelei de confirmare, nu se scriu de mână. stop 49.20. Nivelurile de 1/3 și 1/2 se calculează din corpul candelei de
confirmare (open 49.90 → close 50.40), nu se scriu de mână.
Lecția: împărțind intrarea în trei, prețul mediu scade de la 50.40 la
50.26, deci riscul pe acțiune de la 1.20 la 1.06 — dacă prețul revine.
Bara de după confirmare coboară la 50.10 și umple ambele ordine limită.
""" """
import re import re
import sys; sys.path.insert(0, "/workspace/atm-curs-dl") import sys
from svg_candles import Candle, Chart, Level, Mark from pathlib import Path
OUT = "/workspace/atm-curs-dl/gen/strategii/buy_doji_transe.svg" sys.path.insert(0, "/workspace/atm-curs-dl")
sys.path.insert(0, str(Path(__file__).parent))
from svg_candles import Chart, Level, Zone, Arrow # noqa: E402
from buy_doji_ansamblu import serie, DOJI, CONF, DOJI_L, ENTRY, SL, TP1, R # noqa: E402
# --- seria: barele 0-14 identice cu buy_doji_stop.py -------------------------- OUT = Path(__file__).with_suffix(".svg")
closes = [60.40, 59.60, 59.90, 58.80, 58.10, 58.40, 57.20, 56.30, 56.60, S = 12 # prima bară arătată (zoom pe fereastra de intrare)
55.30, 54.20, 52.40] GREEN, RED, ORANGE, BLUE, GREY = "#188a3e", "#c00", "#b06000", "#1a5fb4", "#555"
bars, o = [], 61.00 W, SCALE = 930, 100.0
for c in closes: # fitile implicite 0.15 peste/sub corp
bars.append((o, max(o, c) + 0.15, min(o, c) - 0.15, c))
o = c
bars += [(52.40, 53.00, 51.60, 52.30), # 12 doji
(52.30, 52.85, 52.10, 52.60), # 13 +1
(52.60, 53.85, 52.45, 53.70), # 14 confirmare
(53.70, 53.80, 53.10, 53.45), # 15 umple 1/3 și 1/2
(53.45, 54.20, 53.35, 54.10),
(54.10, 54.85, 54.00, 54.70),
(54.70, 56.00, 54.60, 55.90)] # 18 TP1
o_, h_, l_, c_ = (list(x) for x in zip(*bars))
# --- nivelurile, calculate din corpul barei 14 --------------------------------- cds = serie()[S:20] # până la bara care atinge ținta
op, T1 = o_[14], c_[14] d, cf = DOJI - S, CONF - S # doji, confirmare (indici locali)
corp = T1 - op op, T1 = cds[cf].o, cds[cf].c # corpul candelei de confirmare
corp = round(T1 - op, 2)
T2, T3 = round(T1 - corp / 3, 2), round(T1 - corp / 2, 2) T2, T3 = round(T1 - corp / 3, 2), round(T1 - corp / 2, 2)
MED = round((T1 + T2 + T3) / 3, 2) MED = round((T1 + T2 + T3) / 3, 2)
SL = round(min(l_[11:15]) - 0.05, 2) RISC_MED, RISC_CLOSE = round(MED - SL, 2), round(T1 - SL, 2)
TP1 = round(T1 + (T1 - SL), 2) TP_MED = round(MED + RISC_MED, 2) # ținta de 1R socotită de la prețul mediu
retest = cds[cf + 1]
# --- aserțiuni ------------------------------------------------------------------
assert (op, T1) == (49.90, ENTRY) and corp == 0.50, (op, T1, corp)
assert (T2, T3) == (50.23, 50.15), (T2, T3)
assert MED == 50.26 and RISC_MED == 1.06 and RISC_CLOSE == R == 1.20
assert retest.l <= T3 < T2, "bara de după confirmare nu umple ambele ordine"
assert round(retest.l, 2) == 50.10, retest.l
assert min(c.l for c in cds[cf - 3:cf + 1]) == DOJI_L and round(DOJI_L - 0.05, 2) == SL
assert round(T1 + RISC_CLOSE, 2) == TP1
# ținta de 1R vine mai devreme dacă prețul mediu de intrare e mai bun
assert TP_MED == 51.32 == round(MED + RISC_MED, 2) and TP_MED < TP1
assert next(i for i in range(cf + 1, len(cds)) if cds[i].h >= TP1) == len(cds) - 1
# măsurat pe toată candela (nu doar pe corp) 1/2 iese tot T3; 1/3 iese 50.28
hi, lo = cds[cf].h, cds[cf].l
assert round(hi - (hi - lo) / 3, 2) == 50.28 and round((hi + lo) / 2, 2) == T3
print(f"transe: T1 {T1:.2f} T2 {T2:.2f} T3 {T3:.2f} medie {MED:.2f} "
f"risc {RISC_MED:.2f} (față de {RISC_CLOSE:.2f}) retest low {retest.l:.2f}")
def dy_sub(price, rand):
"""Săgeata pleacă din nivel și coboară sub linia stopului, pe rândul `rand`."""
return (price - SL) * SCALE + rand
# --- assert-urile din spec -----------------------------------------------------
for i in range(1, len(bars)): # 1
assert abs(o_[i] - c_[i - 1]) < 1e-9, f"open[{i}] != close[{i-1}]"
for i in range(len(bars)):
assert l_[i] <= min(o_[i], c_[i]) and h_[i] >= max(o_[i], c_[i]), f"bara {i}"
assert abs(o_[12] - c_[12]) <= 0.10 * (h_[12] - l_[12]) + 1e-9 # 2
assert c_[13] <= h_[12] < c_[14] and h_[12] == 53.00
assert min(l_[11:15]) == l_[12] == 51.60 and SL == 51.55 # 3
assert (op, T1) == (52.60, 53.70) and (T2, T3) == (53.33, 53.15) # 4
assert l_[15] <= T3 < T2 # 5
assert MED == 53.39 and round(MED - SL, 2) == 1.84 # 6
assert round(T1 - SL, 2) == 2.15
assert TP1 == 55.85 # 7
assert next(i for i in range(15, len(bars)) if h_[i] >= TP1) == 18
hi, lo = h_[14], l_[14] # 8
assert round(hi - (hi - lo) / 3, 2) == 53.38 and round((hi + lo) / 2, 2) == T3
GREY, RED, ORANGE, GREEN, BLUE = "#555", "#c00", "#b06000", "#188a3e", "#1a5fb4"
W = 780
ch = Chart( ch = Chart(
candles=[Candle(*b) for b in bars], candles=cds,
levels=[Level(TP1, f"TP1 {TP1:.2f} = 1R de la close", GREEN, "2 2"), levels=[Level(TP1, "ținta 1: 51.60 = 1R față de close", GREEN, "2 2"),
Level(SL, f"SL {SL:.2f} (low 4 candele 51.60, minus 5 cenți)", RED, "4 3")], Level(TP_MED, f"ținta 1: {TP_MED:.2f} = 1R față de prețul mediu {MED:.2f}", BLUE, "2 2"),
marks=[Mark(14, f"confirmare {T1:.2f}", GREEN, "above", dy=-38)], Level(SL, "stopul: 49.20", RED, "4 3", "left")],
title="Intrarea în trei tranșe — daily, exemplu construit (doji 53.00 / 51.60)", zones=[Zone(cf, cf, "", GREEN, p_top=T1, p_bot=op)],
scale=58.0, gap=18, body_w=10, left=44, width=W, arrows=[
Arrow(cf, "1/3 la close 50.40\nca să nu ratezi trade-ul dacă pleacă fără tine",
where="right", price=T1, color=GREEN, dx=150, dy=dy_sub(T1, 40)),
Arrow(cf, "1/3 cu ordin limită la 50.23 (o treime din corp)\nmai ieftin, dacă prețul revine",
where="right", price=T2, color=ORANGE, dx=150, dy=dy_sub(T2, 74)),
Arrow(cf, "1/3 cu ordin limită la 50.15 (jumătatea corpului)\nși mai ieftin",
where="right", price=T3, color=ORANGE, dx=150, dy=dy_sub(T3, 108)),
Arrow(cf - 1, "media mai bună coboară ținta:\nieși la 51.32, nu la 51.60",
where="above", price=TP_MED, color=BLUE, dx=150),
Arrow(cf + 1, "retestul: prețul revine la 50.10\nși umple amândouă ordinele limită",
where="below", price=retest.l, color=BLUE, dx=-150, dy=20),
],
scale=SCALE, gap=30, body_w=10, left=56, width=W,
title="Intrarea în trei tranșe — același trade (doji 50.10 / 49.25)",
caption="Paranteza de pe candela de confirmare e corpul ei (49.90 → 50.40): pe el se măsoară 1/3 și 1/2. Stopul e unul singur. Exemplu construit.",
) )
svg = ch.render() svg = ch.render()
y, x = ch._y, ch._cx OFF = (float(re.search(r'<line x1="24" y1="([\d.]+)"', svg).group(1))
- ch._y(ch.levels[0].price)) # render() mută `top` și îl restaurează
# același lucru pe orizontală: render() lărgește pânza și mută `left` când un
# text de săgeată ar ieși în stânga. Offsetul se citește din prima candelă.
OFF_X = (float(re.search(r'<line x1="([\d.]+)"[^>]*stroke="#1a1a1a"', svg).group(1))
- ch._cx(0))
def Y(p):
return ch._y(p) + OFF
def x(i):
return ch._cx(i) + OFF_X
ex = [] ex = []
# paranteza corpului, în stânga candelei de confirmare, cu diviziunile 1/3 și 1/2
# linia de ghidaj de la confirmare la eticheta ei (eticheta stă sus, peste bara 17) xb = x(cf) - 17
ex.append(f'<line x1="{x(14):.1f}" y1="{y(h_[14]) - 3:.1f}" x2="{x(14):.1f}" ' ex.append(f'<polyline points="{xb + 5:.1f},{Y(T1):.1f} {xb:.1f},{Y(T1):.1f} {xb:.1f},{Y(op):.1f} '
f'y2="{y(h_[14]) - 44:.1f}" stroke="{GREEN}" stroke-width="1"/>') f'{xb + 5:.1f},{Y(op):.1f}" fill="none" stroke="{GREY}" stroke-width="2"/>')
# fără etichetă lângă paranteză: oriunde lângă candele s-ar suprapune peste ele
# cele trei tranșe: linii de la bara 13 până la paranteza corpului # sau peste liniile săgeților. O numește legenda de sub grafic.
XB = 404 # paranteza corpului barei 14 # nivelurile de tranșă, ca segmente scurte peste candela de confirmare
for p, col, dash in ((T1, GREEN, ""), (T2, ORANGE, "3 3"), (T3, ORANGE, "3 3")): for p, col in ((T1, GREEN), (T2, ORANGE), (T3, ORANGE)):
d = f' stroke-dasharray="{dash}"' if dash else "" dash = "" if p == T1 else ' stroke-dasharray="3 3"'
ex.append(f'<line x1="{x(13) - 6:.1f}" y1="{y(p):.1f}" x2="{XB}" y2="{y(p):.1f}" ' ex.append(f'<line x1="{xb:.1f}" y1="{Y(p):.1f}" x2="{x(cf) + 8:.1f}" y2="{Y(p):.1f}" '
f'stroke="{col}" stroke-width="1.5"{d}/>') f'stroke="{col}" stroke-width="1.5"{dash}/>')
# paranteza: open 52.60 → close 53.70, cu diviziuni la 1/3 și 1/2 # unde se umple fiecare tranșă: T1 la close, T2 și T3 pe low-ul barei următoare
ex.append(f'<line x1="{XB}" y1="{y(T1):.1f}" x2="{XB}" y2="{y(op):.1f}" ' for i, p, col in ((cf, T1, GREEN), (cf + 1, T2, ORANGE), (cf + 1, T3, ORANGE)):
f'stroke="{GREY}" stroke-width="1.5"/>') ex.append(f'<circle cx="{x(i):.1f}" cy="{Y(p):.1f}" r="4" fill="#fff" '
ex.append(f'<line x1="{XB - 6}" y1="{y(op):.1f}" x2="{XB}" y2="{y(op):.1f}" '
f'stroke="{GREY}" stroke-width="1.5"/>')
ex.append(f'<rect x="{XB - 3}" y="{y(MED) - 3:.1f}" width="6" height="6" fill="#888" '
f'transform="rotate(45 {XB} {y(MED):.1f})"/>')
# etichetele, răsfirate la dreapta, cu linii de ghidaj
yc, XL = y((T1 + T3) / 2), 440
labels = [(T1, f"1/3 la close {T1:.2f}", GREEN, ""),
(MED, f"medie {MED:.2f} → risc {MED - SL:.2f} pe acțiune (tot la close: {T1 - SL:.2f})", "#777", "2 2"),
(T2, f"1/3 la 1/3 din corp {T2:.2f}", ORANGE, "3 3"),
(T3, f"1/3 la 1/2 din corp {T3:.2f}", ORANGE, "3 3"),
(op, f"corp: open {op:.2f} → close {T1:.2f} = {corp:.2f}", GREY, "")]
for k, (p, txt, col, dash) in enumerate(labels):
ly = yc + (k - 1.5) * 22
d = f' stroke-dasharray="{dash}"' if dash else ""
ex.append(f'<polyline points="{XB},{y(p):.1f} {XL - 6},{ly - 4:.1f}" fill="none" '
f'stroke="{col}" stroke-width="1.2"{d}/>')
ex.append(f'<text x="{XL}" y="{ly:.1f}" fill="{col}" style="font-weight:bold">{txt}</text>')
# umpleri: T1 la close-ul barei 14, T2 și T3 pe low-ul barei 15; TP1 pe bara 18
for i, p, col in ((14, T1, GREEN), (15, T2, ORANGE), (15, T3, ORANGE), (18, TP1, GREEN)):
ex.append(f'<circle cx="{x(i):.1f}" cy="{y(p):.1f}" r="3.5" fill="#fff" '
f'stroke="{col}" stroke-width="2"/>') f'stroke="{col}" stroke-width="2"/>')
# cele două paranteze de risc, la dreapta: tot la close vs cu tranșe
# etichetele de sub candele, pe rânduri (Mark "below" le-ar pune pe același rând) for xp, hi_p, txt, col in ((x(len(cds) - 1) + 40, T1,
yb = y(SL) + 20 f"risc {RISC_CLOSE:.2f} pe acțiune (tot la close)", RED),
rows = [(15, f"low {l_[15]:.2f}: umple T2 și T3", ORANGE), (x(len(cds) - 1) + 290, MED,
(13, f"+1: {c_[13]:.2f}, sub high", GREY), f"risc {RISC_MED:.2f} pe acțiune (cu tranșe, preț mediu {MED:.2f})", BLUE)):
(12, f"doji {h_[12]:.2f} / {l_[12]:.2f}", BLUE)] y1, y2 = Y(hi_p), Y(SL)
for r, (i, txt, col) in enumerate(rows): ex.append(f'<polyline points="{xp - 5:.1f},{y1:.1f} {xp:.1f},{y1:.1f} {xp:.1f},{y2:.1f} '
ry = yb + 16 * r f'{xp - 5:.1f},{y2:.1f}" fill="none" stroke="{col}" stroke-width="1.5"/>')
ex.append(f'<line x1="{x(i):.1f}" y1="{y(l_[i]) + 3:.1f}" x2="{x(i):.1f}" ' ex.append(f'<text x="{xp + 6:.1f}" y="{(y1 + y2) / 2 + 4:.1f}" fill="{col}" '
f'y2="{ry - 11:.1f}" stroke="{col}" stroke-width="1" stroke-dasharray="1 2"/>')
ex.append(f'<text x="{x(i) - 4:.1f}" y="{ry:.1f}" fill="{col}" '
f'style="font-weight:bold">{txt}</text>') f'style="font-weight:bold">{txt}</text>')
# legenda, pe două rânduri
ly = yb + 16 * len(rows) + 14
ex.append(f'<text x="24" y="{ly:.0f}" fill="#555">Măsurat pe corp (open {op:.2f} → close {T1:.2f}). '
f'Măsurat pe toată candela ({lo:.2f} → {hi:.2f}), 1/3 ar fi '
f'{hi - (hi - lo) / 3:.2f}; 1/2 iese tot {(hi + lo) / 2:.2f}.</text>')
ex.append(f'<text x="24" y="{ly + 17:.0f}" fill="#555">Stopul e unul singur, pentru toată '
f'poziția. Barele 0-11 și 15-18 sunt construite.</text>')
H = ly + 17 + 12
body = svg.rsplit("</svg>", 1)[0].rstrip() body = svg.rsplit("</svg>", 1)[0].rstrip()
svg = "\n ".join([body, *ex]) + "\n</svg>" svg = "\n ".join([body, *ex]) + "\n</svg>"
svg = re.sub(r'viewBox="0 0 (\d+) [\d.]+"', rf'viewBox="0 0 \1 {H:.0f}"', svg, count=1) vw, vh = (float(v) for v in re.search(r'viewBox="0 0 ([\d.]+) ([\d.]+)"', svg).groups())
assert "<svg" in svg and "\n\n" not in svg, "linie goală în SVG" for tx, attrs, txt in re.findall(r'<text x="([-\d.]+)"([^>]*)>(.*?)</text>', svg):
with open(OUT, "w") as f: ty = float(re.search(r'y="([-\d.]+)"', attrs).group(1))
f.write(svg) w = len(txt) * 6.2
print(f"scris {OUT} ({W}x{H:.0f})") x0 = float(tx) - (w if 'text-anchor="end"' in attrs else w / 2 if 'middle' in attrs else 0)
assert 0 <= x0 and x0 + w <= vw and 0 <= ty <= vh, f"text în afara pânzei: {txt!r}"
assert "\n\n" not in svg, "linie goală în SVG"
OUT.write_text(svg, encoding="utf-8")
print(f"scris {OUT} ({vw:.0f}x{vh:.0f})")

View File

@@ -1,69 +1,53 @@
SPEC DIAGRAMĂ — buy_doji_transe SPEC DIAGRAMĂ — buy_doji_transe
=============================== ===============================
tip: PRET tip: PRET (un panou, zoom pe fereastra de intrare)
destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 7 (intrarea) destinație: summaries/17_STRATEGII/01_buy_doji.md, nivelul 3 (tranșele)
cheie markdown: <!-- DIAGRAMA: transe --> cheie markdown: <!-- DIAGRAMA: transe -->
titlu SVG: „Intrarea în trei tranșe — daily, exemplu construit (doji 53.00 / 51.60)" titlu SVG: „Intrarea în trei tranșe — același trade (doji 50.10 / 49.25)"
stil: candele lipite (gap 15-18, body_w 9-10), fără volum; serie: `buy_doji_ansamblu.serie()`, barele 12-19.
open = close anterior, fitile implicite 0.15 peste/sub corp la barele 0-11.
CE TREBUIE SĂ DEMONSTREZE CE TREBUIE SĂ DEMONSTREZE
------------------------- -------------------------
Pe candela de confirmare: o treime din poziție la close (53.70), o treime Pe candela de confirmare (open 49.90 → close 50.40, corp 0.50): o treime din
cu limit la 1/3 din corp (53.33), o treime cu limit la 1/2 (53.15). Bara de poziție la close 50.40, o treime cu ordin limită la 1/3 din corp (50.23), o
după coboară până la 53.10 și le umple pe amândouă. Stopul e unul singur. treime la 1/2 din corp (50.15). Bara următoare coboară la 50.10 (retest) și
Prețul mediu 53.39 → risc 1.84 pe acțiune, față de 2.15 cu tot la close. umple amândouă ordinele limită. Prețul mediu iese 50.26, deci riscul pe acțiune
scade de la 1.20 (tot la close) la 1.06. Stopul rămâne unul singur, 49.20.
SERIA (19 bare, (o,h,l,c))
--------------------------
open[0] = 61.00; close-uri 0-11 (downtrend de 12 candele):
60.40, 59.60, 59.90, 58.80, 58.10, 58.40, 57.20, 56.30, 56.60, 55.30, 54.20, 52.40
12 doji (52.40, 53.00, 51.60, 52.30)
13 +1 (52.30, 52.85, 52.10, 52.60) close sub 53.00: încă nimic
14 confirmare (52.60, 53.85, 52.45, 53.70) close peste 53.00: Buy Doji
15 (53.70, 53.80, 53.10, 53.45) umple 1/3 și 1/2
16 (53.45, 54.20, 53.35, 54.10)
17 (54.10, 54.85, 54.00, 54.70)
18 (54.70, 56.00, 54.60, 55.90) atinge TP1 55.85 (a 4-a după intrare)
NIVELURI NIVELURI
-------- --------
T1 53.70 verde „1/3 la close 53.70" T1 50.40 (close) · T2 50.23 (o treime din corp) · T3 50.15 (jumătatea corpului)
T2 53.33 portocaliu punctat „1/3 la 1/3 din corp 53.33" preț mediu 50.26 · stop 49.20
T3 53.15 portocaliu punctat „1/3 la 1/2 din corp 53.15" ținta de 1R față de close: 51.60 (atinsă la ultima bară arătată)
preț mediu 53.39 gri punctat „medie 53.39" ținta de 1R față de prețul mediu: 51.32 (50.26 + 1.06) — vine mai devreme,
SL 51.55 roșu „SL 51.55 (low 4 candele 51.60, minus 5 cenți)" ăsta e avantajul tranșelor; desenată ca al doilea nivel punctat
TP1 55.85 verde punctat „TP1 55.85 = 1R de la close" Măsurat pe toată candela (49.75 → 50.55), 1/3 ar fi 50.28, iar 1/2 iese tot 50.15.
MARKS ADNOTĂRI
----- --------
Mark(12, "doji 53.00 / 51.60"), Mark(13, "+1: 52.60, sub high"), Zonă verde peste corpul candelei de confirmare; paranteză cu corpul
Mark(14, "confirmare 53.70"), Mark(15, "low 53.10: umple T2 și T3", below) (49.90 → 50.40) în stânga ei; trei segmente scurte pentru T1/T2/T3 și cerculețe
acolo unde se umple fiecare tranșă (T1 la close, T2 și T3 pe low-ul barei
LEGENDĂ următoare); trei săgeți, câte una pe tranșă, cu motivul („ca să nu ratezi
------- trade-ul dacă pleacă fără tine" / „mai ieftin, dacă prețul revine" / „și mai
„Măsurat pe corp (open 52.60 → close 53.70). Măsurat pe toată candela ieftin"); o săgeată pe retest; două paranteze de risc la dreapta: 1.20 tot la
(52.45 → 53.85), 1/3 ar fi 53.38; 1/2 iese tot 53.15." close vs 1.06 cu tranșe.
ASSERT-URI ASSERT-URI
---------- ----------
1. open[i] == close[i-1]; h/l cuprind o/c. 1. corpul candelei de confirmare: open 49.90, close 50.40, corp 0.50.
2. doji: abs(o-c) <= 0.10*(h-l); close[13] <= 53.00 < close[14]. 2. T2 == 50.23 și T3 == 50.15 (calculate din corp, nu scrise de mână).
3. min(l[11:15]) == 51.60 (low-ul dojiului e cel mai jos din 4); SL == 51.55. 3. medie == 50.26; medie - stop == 1.06; close - stop == 1.20 == 1R.
4. corp = 53.70 - 52.60; round(53.70 - corp/3, 2) == 53.33; round(53.70 - corp/2, 2) == 53.15. 3b. ținta de la medie == 51.32 == medie + 1.06, și e sub 51.60.
5. low[15] <= 53.15 (ambele limit-uri umplute). 4. low-ul barei următoare == 50.10 <= T3 (ambele ordine limită se umplu).
6. round((53.70+53.33+53.15)/3, 2) == 53.39; round(53.39-51.55, 2) == 1.84; 5. min(low) pe ultimele 4 candele de la confirmare == 49.25; stop 49.20.
round(53.70-51.55, 2) == 2.15. 6. close + 1.20 == 51.60, atinsă prima dată la ultima bară arătată.
7. TP1 == 53.70 + 2.15 == 55.85; primul i>14 cu high >= 55.85 este 18. 7. măsurat pe toată candela: 1/3 == 50.28, 1/2 == 50.15 (tot T3).
8. round(53.85 - (53.85-52.45)/3, 2) == 53.38; (53.85+52.45)/2 == 53.15. 8. niciun text nu iese din pânză.
SURSA SURSA
----- -----
- Doji 53.00/51.60, close 52.60 apoi 53.70, SL 51.55, TP1 55.85 atins la a 4-a: - Tranșele 1/3 la close, 1/3 la 1/3 din corp, 1/3 la 1/2: summaries/09_QA/
summaries/08_ANALIZA_ZILNICA/01_buy_doji_si_strategia_mici.md:136-144 (exemplu construit 23_2025-07-29.md:206-213; transcripts/09_Q_and_A/19_08092025.txt:1067-1073.
al sumarului; seria de aici îl redesenează cu aceleași niveluri). - Măsurat de la low sau de la open: summaries/09_QA/20_2025-08-25.md:178-180.
- Tranșele 1/3 la close, 1/3 la 1/3, 1/3 la 1/2: summaries/09_QA/23_2025-07-29.md:206-213; - Barele sunt CONSTRUITE (aceeași serie ca restul capitolului).
transcripts/09_Q_and_A/19_08092025.txt:1067-1073 (citat în A3_intrarea.md:276-279).
- Măsurat de la low sau de la open: summaries/09_QA/20_2025-08-25.md:178-180;
„Iei high-ul și low-ul și calculezi": summaries/09_QA/23_2025-07-29.md:210-211.
- Barele 0-11 și 15-18 sunt CONSTRUITE.

View File

@@ -1,75 +1,58 @@
<svg viewBox="0 0 780 724" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 982 561" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="48" fill="#333" style="font-weight:bold">Intrarea în trei tranșe — daily, exemplu construit (doji 53.00 / 51.60)</text> <text x="24" y="48" fill="#333" style="font-weight:bold">Intrarea în trei tranșe — același trade (doji 50.10 / 49.25)</text>
<line x1="24" y1="363.4" x2="766" y2="363.4" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 2"/> <rect x="218.3" y="271.0" width="20.0" height="50.0" fill="#188a3e" fill-opacity="0.08" stroke="#188a3e" stroke-width="1"/>
<text x="752" y="357.4" fill="#188a3e" text-anchor="end">TP1 55.85 = 1R de la close</text> <line x1="24" y1="151.0" x2="968" y2="151.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 2"/>
<line x1="24" y1="612.8" x2="766" y2="612.8" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/> <text x="954" y="145.0" fill="#188a3e" text-anchor="end">ținta 1: 51.60 = 1R față de close</text>
<text x="752" y="606.8" fill="#c00" text-anchor="end">SL 51.55 (low 4 candele 51.60, minus 5 cenți)</text> <line x1="24" y1="179.0" x2="968" y2="179.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="2 2"/>
<line x1="44.0" y1="56.0" x2="44.0" y2="108.2" stroke="#1a1a1a" stroke-width="1.2"/> <text x="954" y="173.0" fill="#1a5fb4" text-anchor="end">ținta 1: 51.32 = 1R față de prețul mediu 50.26</text>
<rect x="39.0" y="64.7" width="10" height="34.8" fill="#c00"/> <line x1="24" y1="391.0" x2="968" y2="391.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
<line x1="62.0" y1="90.8" x2="62.0" y2="154.6" stroke="#1a1a1a" stroke-width="1.2"/> <text x="30" y="385.0" fill="#c00">stopul: 49.20</text>
<rect x="57.0" y="99.5" width="10" height="46.4" fill="#c00"/> <line x1="108.3" y1="56.0" x2="108.3" y2="241.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="80.0" y1="119.8" x2="80.0" y2="154.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="103.3" y="81.0" width="10" height="130.0" fill="#c00"/>
<rect x="75.0" y="128.5" width="10" height="17.4" fill="#188a3e"/> <line x1="138.3" y1="186.0" x2="138.3" y2="376.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="98.0" y1="119.8" x2="98.0" y2="201.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="133.3" y="211.0" width="10" height="135.0" fill="#c00"/>
<rect x="93.0" y="128.5" width="10" height="63.8" fill="#c00"/> <line x1="168.3" y1="301.0" x2="168.3" y2="386.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="116.0" y1="183.6" x2="116.0" y2="241.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="163.3" y="346.0" width="10" height="5.0" fill="#c00"/>
<rect x="111.0" y="192.3" width="10" height="40.6" fill="#c00"/> <line x1="198.3" y1="306.0" x2="198.3" y2="366.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="134.0" y1="206.8" x2="134.0" y2="241.6" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="193.3" y="321.0" width="10" height="30.0" fill="#188a3e"/>
<rect x="129.0" y="215.5" width="10" height="17.4" fill="#188a3e"/> <line x1="228.3" y1="256.0" x2="228.3" y2="336.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="152.0" y1="206.8" x2="152.0" y2="293.8" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="223.3" y="271.0" width="10" height="50.0" fill="#188a3e"/>
<rect x="147.0" y="215.5" width="10" height="69.6" fill="#c00"/> <line x1="258.3" y1="196.0" x2="258.3" y2="301.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="170.0" y1="276.4" x2="170.0" y2="346.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="253.3" y="221.0" width="10" height="50.0" fill="#188a3e"/>
<rect x="165.0" y="285.1" width="10" height="52.2" fill="#c00"/> <line x1="288.3" y1="166.0" x2="288.3" y2="251.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="188.0" y1="311.2" x2="188.0" y2="346.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="283.3" y="191.0" width="10" height="30.0" fill="#188a3e"/>
<rect x="183.0" y="319.9" width="10" height="17.4" fill="#188a3e"/> <line x1="318.3" y1="136.0" x2="318.3" y2="221.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="206.0" y1="311.2" x2="206.0" y2="404.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="313.3" y="161.0" width="10" height="30.0" fill="#188a3e"/>
<rect x="201.0" y="319.9" width="10" height="75.4" fill="#c00"/> <line x1="417.3" y1="431.0" x2="243.3" y2="276.3" stroke="#188a3e" stroke-width="1.8"/>
<line x1="224.0" y1="386.6" x2="224.0" y2="467.8" stroke="#1a1a1a" stroke-width="1.2"/> <polygon points="237.3,271.0 245.9,273.3 240.6,279.3" fill="#188a3e"/>
<rect x="219.0" y="395.3" width="10" height="63.8" fill="#c00"/> <text x="421.3" y="428.0" fill="#188a3e" text-anchor="start" style="font-weight:bold">1/3 la close 50.40</text>
<line x1="242.0" y1="450.4" x2="242.0" y2="572.2" stroke="#1a1a1a" stroke-width="1.2"/> <text x="421.3" y="442.0" fill="#188a3e" text-anchor="start" style="font-weight:bold">ca să nu ratezi trade-ul dacă pleacă fără tine</text>
<rect x="237.0" y="459.1" width="10" height="104.4" fill="#c00"/> <line x1="417.3" y1="465.0" x2="243.0" y2="293.6" stroke="#b06000" stroke-width="1.8"/>
<line x1="260.0" y1="528.7" x2="260.0" y2="609.9" stroke="#1a1a1a" stroke-width="1.2"/> <polygon points="237.3,288.0 245.8,290.8 240.2,296.5" fill="#b06000"/>
<rect x="255.0" y="563.5" width="10" height="5.8" fill="#c00"/> <text x="421.3" y="462.0" fill="#b06000" text-anchor="start" style="font-weight:bold">1/3 cu ordin limită la 50.23 (o treime din corp)</text>
<line x1="278.0" y1="537.4" x2="278.0" y2="580.9" stroke="#1a1a1a" stroke-width="1.2"/> <text x="421.3" y="476.0" fill="#b06000" text-anchor="start" style="font-weight:bold">mai ieftin, dacă prețul revine</text>
<rect x="273.0" y="551.9" width="10" height="17.4" fill="#188a3e"/> <line x1="417.3" y1="499.0" x2="242.6" y2="302.0" stroke="#b06000" stroke-width="1.8"/>
<line x1="296.0" y1="479.4" x2="296.0" y2="560.6" stroke="#1a1a1a" stroke-width="1.2"/> <polygon points="237.3,296.0 245.6,299.3 239.6,304.6" fill="#b06000"/>
<rect x="291.0" y="488.1" width="10" height="63.8" fill="#188a3e"/> <text x="421.3" y="496.0" fill="#b06000" text-anchor="start" style="font-weight:bold">1/3 cu ordin limită la 50.15 (jumătatea corpului)</text>
<line x1="314.0" y1="482.3" x2="314.0" y2="522.9" stroke="#1a1a1a" stroke-width="1.2"/> <text x="421.3" y="510.0" fill="#b06000" text-anchor="start" style="font-weight:bold">și mai ieftin</text>
<rect x="309.0" y="488.1" width="10" height="14.5" fill="#c00"/> <line x1="348.3" y1="128.0" x2="205.9" y2="172.6" stroke="#1a5fb4" stroke-width="1.8"/>
<line x1="332.0" y1="459.1" x2="332.0" y2="508.4" stroke="#1a1a1a" stroke-width="1.2"/> <polygon points="198.3,175.0 204.7,168.8 207.1,176.4" fill="#1a5fb4"/>
<rect x="327.0" y="464.9" width="10" height="37.7" fill="#188a3e"/> <text x="348.3" y="109.0" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">media mai bună coboară ținta:</text>
<line x1="350.0" y1="421.4" x2="350.0" y2="470.7" stroke="#1a1a1a" stroke-width="1.2"/> <text x="348.3" y="123.0" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">ieși la 51.32, nu la 51.60</text>
<rect x="345.0" y="430.1" width="10" height="34.8" fill="#188a3e"/> <line x1="108.3" y1="414.0" x2="251.8" y2="309.7" stroke="#1a5fb4" stroke-width="1.8"/>
<line x1="368.0" y1="354.7" x2="368.0" y2="435.9" stroke="#1a1a1a" stroke-width="1.2"/> <polygon points="258.3,305.0 254.2,312.9 249.5,306.5" fill="#1a5fb4"/>
<rect x="363.0" y="360.5" width="10" height="69.6" fill="#188a3e"/> <text x="108.3" y="428.0" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">retestul: prețul revine la 50.10</text>
<text x="296.0" y="431.4" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare 53.70</text> <text x="108.3" y="442.0" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">și umple amândouă ordinele limită</text>
<line x1="296.0" y1="476.4" x2="296.0" y2="435.4" stroke="#188a3e" stroke-width="1"/> <text x="24" y="549" fill="#555">Paranteza de pe candela de confirmare e corpul ei (49.90 → 50.40): pe el se măsoară 1/3 și 1/2. Stopul e unul singur. Exemplu construit.</text>
<line x1="272.0" y1="488.1" x2="404" y2="488.1" stroke="#188a3e" stroke-width="1.5"/> <polyline points="216.3,271.0 211.3,271.0 211.3,321.0 216.3,321.0" fill="none" stroke="#555" stroke-width="2"/>
<line x1="272.0" y1="509.6" x2="404" y2="509.6" stroke="#b06000" stroke-width="1.5" stroke-dasharray="3 3"/> <line x1="211.3" y1="271.0" x2="236.3" y2="271.0" stroke="#188a3e" stroke-width="1.5"/>
<line x1="272.0" y1="520.0" x2="404" y2="520.0" stroke="#b06000" stroke-width="1.5" stroke-dasharray="3 3"/> <line x1="211.3" y1="288.0" x2="236.3" y2="288.0" stroke="#b06000" stroke-width="1.5" stroke-dasharray="3 3"/>
<line x1="404" y1="488.1" x2="404" y2="551.9" stroke="#555" stroke-width="1.5"/> <line x1="211.3" y1="296.0" x2="236.3" y2="296.0" stroke="#b06000" stroke-width="1.5" stroke-dasharray="3 3"/>
<line x1="398" y1="551.9" x2="404" y2="551.9" stroke="#555" stroke-width="1.5"/> <circle cx="228.3" cy="271.0" r="4" fill="#fff" stroke="#188a3e" stroke-width="2"/>
<rect x="401" y="503.1" width="6" height="6" fill="#888" transform="rotate(45 404 506.1)"/> <circle cx="258.3" cy="288.0" r="4" fill="#fff" stroke="#b06000" stroke-width="2"/>
<polyline points="404,488.1 434,467.1" fill="none" stroke="#188a3e" stroke-width="1.2"/> <circle cx="258.3" cy="296.0" r="4" fill="#fff" stroke="#b06000" stroke-width="2"/>
<text x="440" y="471.1" fill="#188a3e" style="font-weight:bold">1/3 la close 53.70</text> <polyline points="353.3,271.0 358.3,271.0 358.3,391.0 353.3,391.0" fill="none" stroke="#c00" stroke-width="1.5"/>
<polyline points="404,506.1 434,489.1" fill="none" stroke="#777" stroke-width="1.2" stroke-dasharray="2 2"/> <text x="364.3" y="335.0" fill="#c00" style="font-weight:bold">risc 1.20 pe acțiune (tot la close)</text>
<text x="440" y="493.1" fill="#777" style="font-weight:bold">medie 53.39 → risc 1.84 pe acțiune (tot la close: 2.15)</text> <polyline points="603.3,285.0 608.3,285.0 608.3,391.0 603.3,391.0" fill="none" stroke="#1a5fb4" stroke-width="1.5"/>
<polyline points="404,509.6 434,511.1" fill="none" stroke="#b06000" stroke-width="1.2" stroke-dasharray="3 3"/> <text x="614.3" y="342.0" fill="#1a5fb4" style="font-weight:bold">risc 1.06 pe acțiune (cu tranșe, preț mediu 50.26)</text>
<text x="440" y="515.1" fill="#b06000" style="font-weight:bold">1/3 la 1/3 din corp 53.33</text>
<polyline points="404,520.0 434,533.1" fill="none" stroke="#b06000" stroke-width="1.2" stroke-dasharray="3 3"/>
<text x="440" y="537.1" fill="#b06000" style="font-weight:bold">1/3 la 1/2 din corp 53.15</text>
<polyline points="404,551.9 434,555.1" fill="none" stroke="#555" stroke-width="1.2"/>
<text x="440" y="559.1" fill="#555" style="font-weight:bold">corp: open 52.60 → close 53.70 = 1.10</text>
<circle cx="296.0" cy="488.1" r="3.5" fill="#fff" stroke="#188a3e" stroke-width="2"/>
<circle cx="314.0" cy="509.6" r="3.5" fill="#fff" stroke="#b06000" stroke-width="2"/>
<circle cx="314.0" cy="520.0" r="3.5" fill="#fff" stroke="#b06000" stroke-width="2"/>
<circle cx="368.0" cy="363.4" r="3.5" fill="#fff" stroke="#188a3e" stroke-width="2"/>
<line x1="314.0" y1="525.9" x2="314.0" y2="621.8" stroke="#b06000" stroke-width="1" stroke-dasharray="1 2"/>
<text x="310.0" y="632.8" fill="#b06000" style="font-weight:bold">low 53.10: umple T2 și T3</text>
<line x1="278.0" y1="583.9" x2="278.0" y2="637.8" stroke="#555" stroke-width="1" stroke-dasharray="1 2"/>
<text x="274.0" y="648.8" fill="#555" style="font-weight:bold">+1: 52.60, sub high</text>
<line x1="260.0" y1="612.9" x2="260.0" y2="653.8" stroke="#1a5fb4" stroke-width="1" stroke-dasharray="1 2"/>
<text x="256.0" y="664.8" fill="#1a5fb4" style="font-weight:bold">doji 53.00 / 51.60</text>
<text x="24" y="695" fill="#555">Măsurat pe corp (open 52.60 → close 53.70). Măsurat pe toată candela (52.45 → 53.85), 1/3 ar fi 53.38; 1/2 iese tot 53.15.</text>
<text x="24" y="712" fill="#555">Stopul e unul singur, pentru toată poziția. Barele 0-11 și 15-18 sunt construite.</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -8,10 +8,10 @@ trendului sunt numerotate sub bară, ca numărătoarea să se vadă.
""" """
import re import re
import sys; sys.path.insert(0, "/workspace/atm-curs-dl") import sys; sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Candle, Chart, Mark from svg_candles import Arrow, Candle, Chart, Mark, Zone
OUT = "/workspace/atm-curs-dl/gen/strategii/buy_doji_trend.svg" OUT = "/workspace/atm-curs-dl/gen/strategii/buy_doji_trend.svg"
DOJI = (49.65, 50.10, 49.20, 49.60) DOJI = (49.65, 50.10, 49.25, 49.60)
CONF = (49.60, 50.55, 49.45, 50.40) CONF = (49.60, 50.55, 49.45, 50.40)
@@ -54,12 +54,20 @@ def numbers(ch, idx, color):
for n, i in enumerate(idx, 1)] for n, i in enumerate(idx, 1)]
def bracket(ch, a, b, y, text, color): def render_keep_offsets(ch):
xa, xb = ch._cx(a) - 6, ch._cx(b) + 6 """`Chart.render()` restaurează top/left după desen, deci `_y`/`_cx` de
return [f'<polyline points="{xa:.1f},{y + 6:.1f} {xa:.1f},{y:.1f} {xb:.1f},{y:.1f} ' după el dau coordonate deplasate față de body-ul randat (titlul și
f'{xb:.1f},{y + 6:.1f}" fill="none" stroke="{color}" stroke-width="1.3"/>', etichetele zonelor mută graficul în jos). `_render()` lasă offset-urile
f'<text x="{xb + 8:.1f}" y="{y + 4:.1f}" fill="{color}" ' puse, exact ce ne trebuie ca extra-urile desenate de mână să pice la locul
f'style="font-weight:bold">{text}</text>'] lor. Se cheamă o singură dată per Chart."""
return ch._render()
def fits(ch, svg):
"""Chart mută graficul dacă un text ar ieși din pânză — aici mutarea ar
dezalinia cele două panouri, deci verificăm că nu s-a întâmplat."""
assert f'viewBox="0 0 {ch.width} ' in svg, \
f"Chart a lărgit pânza ({svg[:60]}): textul unei săgeți iese din {ch.width}px"
def body(svg): def body(svg):
@@ -68,32 +76,35 @@ def body(svg):
# --- panoul de sus: 9 candele ------------------------------------------------ # --- panoul de sus: 9 candele ------------------------------------------------
top = Chart(candles=[Candle(*b) for b in L], left=44 + GAP, # dojiul pe aceeași verticală top = Chart(candles=[Candle(*b) for b in L], left=44 + GAP, # dojiul pe aceeași verticală
marks=[Mark(10, "doji", ORANGE, "below", dy=8), marks=[Mark(11, "confirmare 50.40", GREEN, "above")],
Mark(11, "confirmare 50.40", GREEN, "above")], zones=[Zone(1, 9, "9 candele de scădere — ideal", GREEN)],
title="Trendul dinaintea dojiului: 9 candele vs. 3 candele — exemplu construit", arrows=[Arrow(10, "doji la capătul scăderii\nvânzătorii s-au terminat",
where="below", color=ORANGE, dx=70)],
top=54, # titlul se desenează de mână: cel din Chart ar cădea peste eticheta zonei
**common) **common)
svg_top = top.render() svg_top = render_keep_offsets(top)
y_br = top._y(max(b[1] for b in L[1:10])) - 10 fits(top, svg_top)
ext_top = numbers(top, range(1, 10), RED) + bracket(top, 1, 9, y_br, "downtrend 9 candele", RED) ext_top = numbers(top, range(1, 10), RED) + [
y_cap1 = top._y(DOJI[2]) + 50 '<text x="24" y="22" fill="#333" style="font-weight:bold">Trendul dinaintea dojiului: '
'9 candele vs. 3 candele — exemplu construit</text>']
y_cap1 = max(top._y(DOJI[2]) + 50, top._arrow_geom(top.arrows[0])["box"][3] + 24)
ext_top.append(f'<text x="24" y="{y_cap1:.1f}" fill="{GREEN}" style="font-weight:bold">' ext_top.append(f'<text x="24" y="{y_cap1:.1f}" fill="{GREEN}" style="font-weight:bold">'
f'DA — ideal (8-10 candele)</text>') f'DA — ideal (8-10 candele)</text>')
# --- panoul de jos: range + 3 candele ---------------------------------------- # --- panoul de jos: range + 3 candele ----------------------------------------
y_sep = y_cap1 + 16 y_sep = y_cap1 + 16
bot = Chart(candles=[Candle(*b) for b in R], left=44, bot = Chart(candles=[Candle(*b) for b in R], left=44,
marks=[Mark(11, "doji", ORANGE, "below", dy=8), marks=[Mark(11, "doji", ORANGE, "below", dy=22),
Mark(12, "confirmare 50.40", GREEN, "above")], Mark(12, "confirmare 50.40", GREEN, "above")],
top=int(y_sep + 62), **common) # titlul și paranteza range-ului, desenate mai jos zones=[Zone(8, 10, "doar 3 candele — merge, dar mai slab", ORANGE)],
svg_bot = bot.render() arrows=[Arrow(3, "înainte: preț pe loc,\nnu scădere — de aceea\nsemnalul e mai slab",
y_rg = bot._y(max(b[1] for b in R[0:8])) - 10 where="above", color=GREY)],
top=int(y_sep + 118), **common) # loc pentru titlul panoului și textul săgeții
svg_bot = render_keep_offsets(bot)
fits(bot, svg_bot)
ext_bot = (numbers(bot, range(8, 11), RED) ext_bot = (numbers(bot, range(8, 11), RED)
+ bracket(bot, 8, 10, bot._y(R[8][1]) - 10, "doar 3 candele", RED)
+ bracket(bot, 0, 7, y_rg, "", GREY)
+ [f'<text x="24" y="{y_sep + 24:.1f}" fill="#333" style="font-weight:bold">' + [f'<text x="24" y="{y_sep + 24:.1f}" fill="#333" style="font-weight:bold">'
f'Același doji, după un range</text>', f'Același doji, după un range</text>'])
f'<text x="{bot._cx(0) - 6:.1f}" y="{y_rg - 5:.1f}" fill="{GREY}">'
f'range: nu se numără</text>'])
y_cap2 = bot._y(DOJI[2]) + 50 y_cap2 = bot._y(DOJI[2]) + 50
ext_bot += [f'<text x="24" y="{y_cap2:.1f}" fill="{ORANGE}" style="font-weight:bold">' ext_bot += [f'<text x="24" y="{y_cap2:.1f}" fill="{ORANGE}" style="font-weight:bold">'
f'ACCEPTAT, semnal mai slab</text>', f'ACCEPTAT, semnal mai slab</text>',

View File

@@ -5,11 +5,12 @@ destinație: summaries/17_STRATEGII/01_buy_doji.md, Pasul 3, după doji_form
cheie markdown: <!-- DIAGRAMA: trend --> cheie markdown: <!-- DIAGRAMA: trend -->
titlu SVG: „Trendul dinaintea dojiului: 9 candele vs. 3 candele — exemplu construit" titlu SVG: „Trendul dinaintea dojiului: 9 candele vs. 3 candele — exemplu construit"
stil: candele lipite (gap 15-18, body_w 9-10), fără volum; open = close anterior; stil: candele lipite (gap 15-18, body_w 9-10), fără volum; open = close anterior;
adnotări „ca la proști": zone dreptunghiulare + săgeți cu text (CE + DE CE).
fitile implicite 0.15 peste/sub corp, cu excepțiile de mai jos. fitile implicite 0.15 peste/sub corp, cu excepțiile de mai jos.
CE TREBUIE SĂ DEMONSTREZE CE TREBUIE SĂ DEMONSTREZE
------------------------- -------------------------
Același doji (h 50.10 / l 49.20) și aceeași confirmare (close 50.40), după Același doji (h 50.10 / l 49.25) și aceeași confirmare (close 50.40), după
două trenduri diferite. Stânga = ideal (9 candele). Dreapta = acceptat, dar două trenduri diferite. Stânga = ideal (9 candele). Dreapta = acceptat, dar
semnal mai slab (3 candele după un range) — și e cazul pe care scannerul cu semnal mai slab (3 candele după un range) — și e cazul pe care scannerul cu
„Since Bear ≥ 8" nu-l găsește. „Since Bear ≥ 8" nu-l găsește.
@@ -18,18 +19,22 @@ PANOUL STÂNGA — 12 bare
----------------------- -----------------------
open[0] = 55.50; close-uri 0-9: 55.00, 54.30, 54.60, 53.60, 52.90, 53.10, 52.00, open[0] = 55.50; close-uri 0-9: 55.00, 54.30, 54.60, 53.60, 52.90, 53.10, 52.00,
51.20, 50.60, 49.65 (barele 1-9 = trendul de 9 candele) 51.20, 50.60, 49.65 (barele 1-9 = trendul de 9 candele)
10 doji (49.65, 50.10, 49.20, 49.60) 10 doji (49.65, 50.10, 49.25, 49.60)
11 confirmare (49.60, 50.55, 49.45, 50.40) 11 confirmare (49.60, 50.55, 49.45, 50.40)
Mark(1..9 paranteză, "downtrend 9 candele"), Mark(10,"doji"), Mark(11,"confirmare 50.40"). Zone(1..9) verde, etichetă „9 candele de scădere — ideal"; numerele 1..9 sub bare;
săgeată pe doji: „doji la capătul scăderii / vânzătorii s-au terminat".
Mark(11,"confirmare 50.40").
Text sub panou: „DA — ideal (8-10 candele)". Text sub panou: „DA — ideal (8-10 candele)".
PANOUL DREAPTA — 13 bare PANOUL DREAPTA — 13 bare
------------------------ ------------------------
open[0] = 51.40; close-uri 0-7 (range): 51.70, 51.20, 51.60, 51.10, 51.50, open[0] = 51.40; close-uri 0-7 (range): 51.70, 51.20, 51.60, 51.10, 51.50,
51.30, 51.70, 51.40; apoi 8: 50.90, 9: 50.30, 10: 49.65 (3 candele în jos) 51.30, 51.70, 51.40; apoi 8: 50.90, 9: 50.30, 10: 49.65 (3 candele în jos)
11 doji (49.65, 50.10, 49.20, 49.60) 11 doji (49.65, 50.10, 49.25, 49.60)
12 confirmare (49.60, 50.55, 49.45, 50.40) 12 confirmare (49.60, 50.55, 49.45, 50.40)
Mark(8..10 paranteză, "doar 3 candele"), Mark(12,"confirmare 50.40"). Zone(8..10) portocalie, etichetă „doar 3 candele — merge, dar mai slab"; numerele
1..3 sub bare; săgeată pe range (bara 3): „înainte: preț pe loc, / nu scădere — de
aceea / semnalul e mai slab". Mark(11,"doji"), Mark(12,"confirmare 50.40").
Text sub panou: „ACCEPTAT, semnal mai slab · scannerul cu Since Bear ≥ 8 nu-l vede". Text sub panou: „ACCEPTAT, semnal mai slab · scannerul cu Since Bear ≥ 8 nu-l vede".
ASSERT-URI ASSERT-URI
@@ -42,6 +47,14 @@ ASSERT-URI
close[8] > close[9] > close[10] (exact 3 candele în jos). close[8] > close[9] > close[10] (exact 3 candele în jos).
5. Confirmarea închide peste 50.10 pe ambele. 5. Confirmarea închide peste 50.10 pe ambele.
NOTĂ DE RANDARE
---------------
Extra-urile desenate de mână (numere, titlu) folosesc `ch._render()`, nu
`ch.render()`: al doilea restaurează top/left după desen, deci `_y`/`_cx` ar da
coordonate deplasate cu offset-ul pe care Chart îl pune pentru titlu și pentru
etichetele zonelor. Titlul panoului de sus e desenat de mână din același motiv
(titlul din Chart cade exact peste eticheta zonei).
SURSA SURSA
----- -----
- 8-10 candele ideal; 2-3 candele au funcționat, semnal mai slab: - 8-10 candele ideal; 2-3 candele au funcționat, semnal mai slab:

View File

@@ -1,81 +1,86 @@
<svg viewBox="0 0 540 536" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif"> <svg viewBox="0 0 540 622" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
<text x="24" y="48" fill="#333" style="font-weight:bold">Trendul dinaintea dojiului: 9 candele vs. 3 candele — exemplu construit</text> <rect x="70.0" y="61.0" width="164.0" height="185.5" fill="#188a3e" fill-opacity="0.08" stroke="#188a3e" stroke-width="1"/>
<line x1="62.0" y1="56.0" x2="62.0" y2="80.0" stroke="#1a1a1a" stroke-width="1.2"/> <text x="70.0" y="56.0" fill="#188a3e" style="font-weight:bold">9 candele de scădere — ideal</text>
<rect x="57.0" y="60.5" width="10" height="15.0" fill="#c00"/> <line x1="62.0" y1="54.0" x2="62.0" y2="78.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="80.0" y1="71.0" x2="80.0" y2="101.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="57.0" y="58.5" width="10" height="15.0" fill="#c00"/>
<rect x="75.0" y="75.5" width="10" height="21.0" fill="#c00"/> <line x1="80.0" y1="69.0" x2="80.0" y2="99.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="98.0" y1="83.0" x2="98.0" y2="101.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="75.0" y="73.5" width="10" height="21.0" fill="#c00"/>
<rect x="93.0" y="87.5" width="10" height="9.0" fill="#188a3e"/> <line x1="98.0" y1="81.0" x2="98.0" y2="99.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="116.0" y1="83.0" x2="116.0" y2="122.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="93.0" y="85.5" width="10" height="9.0" fill="#188a3e"/>
<rect x="111.0" y="87.5" width="10" height="30.0" fill="#c00"/> <line x1="116.0" y1="81.0" x2="116.0" y2="120.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="134.0" y1="113.0" x2="134.0" y2="143.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="111.0" y="85.5" width="10" height="30.0" fill="#c00"/>
<rect x="129.0" y="117.5" width="10" height="21.0" fill="#c00"/> <line x1="134.0" y1="111.0" x2="134.0" y2="141.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="152.0" y1="128.0" x2="152.0" y2="143.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="129.0" y="115.5" width="10" height="21.0" fill="#c00"/>
<rect x="147.0" y="132.5" width="10" height="6.0" fill="#188a3e"/> <line x1="152.0" y1="126.0" x2="152.0" y2="141.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="170.0" y1="128.0" x2="170.0" y2="170.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="147.0" y="130.5" width="10" height="6.0" fill="#188a3e"/>
<rect x="165.0" y="132.5" width="10" height="33.0" fill="#c00"/> <line x1="170.0" y1="126.0" x2="170.0" y2="168.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="188.0" y1="161.0" x2="188.0" y2="194.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="165.0" y="130.5" width="10" height="33.0" fill="#c00"/>
<rect x="183.0" y="165.5" width="10" height="24.0" fill="#c00"/> <line x1="188.0" y1="159.0" x2="188.0" y2="192.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="206.0" y1="185.0" x2="206.0" y2="212.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="183.0" y="163.5" width="10" height="24.0" fill="#c00"/>
<rect x="201.0" y="189.5" width="10" height="18.0" fill="#c00"/> <line x1="206.0" y1="183.0" x2="206.0" y2="210.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="224.0" y1="203.0" x2="224.0" y2="240.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="201.0" y="187.5" width="10" height="18.0" fill="#c00"/>
<rect x="219.0" y="207.5" width="10" height="28.5" fill="#c00"/> <line x1="224.0" y1="201.0" x2="224.0" y2="238.5" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="242.0" y1="222.5" x2="242.0" y2="249.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="219.0" y="205.5" width="10" height="28.5" fill="#c00"/>
<rect x="237.0" y="236.0" width="10" height="1.6" fill="#c00"/> <line x1="242.0" y1="220.5" x2="242.0" y2="246.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="260.0" y1="209.0" x2="260.0" y2="242.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="237.0" y="234.0" width="10" height="1.6" fill="#c00"/>
<rect x="255.0" y="213.5" width="10" height="24.0" fill="#188a3e"/> <line x1="260.0" y1="207.0" x2="260.0" y2="240.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="242.0" y="263.5" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text> <rect x="255.0" y="211.5" width="10" height="24.0" fill="#188a3e"/>
<text x="260.0" y="199.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare 50.40</text> <text x="260.0" y="197.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare 50.40</text>
<text x="80.0" y="115.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">1</text> <line x1="312.0" y1="276.0" x2="249.5" y2="252.8" stroke="#b06000" stroke-width="1.8"/>
<text x="98.0" y="115.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">2</text> <polygon points="242.0,250.0 250.9,249.0 248.1,256.5" fill="#b06000"/>
<text x="116.0" y="136.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">3</text> <text x="312.0" y="290.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji la capătul scăderii</text>
<text x="134.0" y="157.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">4</text> <text x="312.0" y="304.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">vânzătorii s-au terminat</text>
<text x="152.0" y="157.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">5</text> <text x="80.0" y="113.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">1</text>
<text x="170.0" y="184.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">6</text> <text x="98.0" y="113.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">2</text>
<text x="188.0" y="208.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">7</text> <text x="116.0" y="134.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">3</text>
<text x="206.0" y="226.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">8</text> <text x="134.0" y="155.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">4</text>
<text x="224.0" y="254.5" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">9</text> <text x="152.0" y="155.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">5</text>
<polyline points="74.0,67.0 74.0,61.0 230.0,61.0 230.0,67.0" fill="none" stroke="#c00" stroke-width="1.3"/> <text x="170.0" y="182.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">6</text>
<text x="238.0" y="65.0" fill="#c00" style="font-weight:bold">downtrend 9 candele</text> <text x="188.0" y="206.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">7</text>
<text x="24" y="299.5" fill="#188a3e" style="font-weight:bold">DA — ideal (8-10 candele)</text> <text x="206.0" y="224.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">8</text>
<line x1="24" y1="315" x2="526" y2="315" stroke="#ccc"/> <text x="224.0" y="252.5" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">9</text>
<line x1="44.0" y1="377.0" x2="44.0" y2="395.0" stroke="#1a1a1a" stroke-width="1.2"/> <text x="24" y="22" fill="#333" style="font-weight:bold">Trendul dinaintea dojiului: 9 candele vs. 3 candele — exemplu construit</text>
<rect x="39.0" y="381.5" width="10" height="9.0" fill="#188a3e"/> <text x="24" y="331.0" fill="#188a3e" style="font-weight:bold">DA — ideal (8-10 candele)</text>
<line x1="62.0" y1="377.0" x2="62.0" y2="401.0" stroke="#1a1a1a" stroke-width="1.2"/> <line x1="24" y1="347" x2="526" y2="347" stroke="#ccc"/>
<rect x="57.0" y="381.5" width="10" height="15.0" fill="#c00"/> <rect x="178.0" y="465.0" width="56.0" height="77.5" fill="#b06000" fill-opacity="0.08" stroke="#b06000" stroke-width="1"/>
<line x1="80.0" y1="380.0" x2="80.0" y2="401.0" stroke="#1a1a1a" stroke-width="1.2"/> <text x="178.0" y="460.0" fill="#b06000" style="font-weight:bold">doar 3 candele — merge, dar mai slab</text>
<rect x="75.0" y="384.5" width="10" height="12.0" fill="#188a3e"/> <line x1="44.0" y1="464.0" x2="44.0" y2="482.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="98.0" y1="380.0" x2="98.0" y2="404.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="39.0" y="468.5" width="10" height="9.0" fill="#188a3e"/>
<rect x="93.0" y="384.5" width="10" height="15.0" fill="#c00"/> <line x1="62.0" y1="464.0" x2="62.0" y2="488.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="116.0" y1="383.0" x2="116.0" y2="404.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="57.0" y="468.5" width="10" height="15.0" fill="#c00"/>
<rect x="111.0" y="387.5" width="10" height="12.0" fill="#188a3e"/> <line x1="80.0" y1="467.0" x2="80.0" y2="488.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="134.0" y1="383.0" x2="134.0" y2="398.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="75.0" y="471.5" width="10" height="12.0" fill="#188a3e"/>
<rect x="129.0" y="387.5" width="10" height="6.0" fill="#c00"/> <line x1="98.0" y1="467.0" x2="98.0" y2="491.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="152.0" y1="377.0" x2="152.0" y2="398.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="93.0" y="471.5" width="10" height="15.0" fill="#c00"/>
<rect x="147.0" y="381.5" width="10" height="12.0" fill="#188a3e"/> <line x1="116.0" y1="470.0" x2="116.0" y2="491.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="170.0" y1="377.0" x2="170.0" y2="395.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="111.0" y="474.5" width="10" height="12.0" fill="#188a3e"/>
<rect x="165.0" y="381.5" width="10" height="9.0" fill="#c00"/> <line x1="134.0" y1="470.0" x2="134.0" y2="485.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="188.0" y1="386.0" x2="188.0" y2="410.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="129.0" y="474.5" width="10" height="6.0" fill="#c00"/>
<rect x="183.0" y="390.5" width="10" height="15.0" fill="#c00"/> <line x1="152.0" y1="464.0" x2="152.0" y2="485.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="206.0" y1="401.0" x2="206.0" y2="428.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="147.0" y="468.5" width="10" height="12.0" fill="#188a3e"/>
<rect x="201.0" y="405.5" width="10" height="18.0" fill="#c00"/> <line x1="170.0" y1="464.0" x2="170.0" y2="482.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="224.0" y1="419.0" x2="224.0" y2="447.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="165.0" y="468.5" width="10" height="9.0" fill="#c00"/>
<rect x="219.0" y="423.5" width="10" height="19.5" fill="#c00"/> <line x1="188.0" y1="473.0" x2="188.0" y2="497.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="242.0" y1="429.5" x2="242.0" y2="456.5" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="183.0" y="477.5" width="10" height="15.0" fill="#c00"/>
<rect x="237.0" y="443.0" width="10" height="1.6" fill="#c00"/> <line x1="206.0" y1="488.0" x2="206.0" y2="515.0" stroke="#1a1a1a" stroke-width="1.2"/>
<line x1="260.0" y1="416.0" x2="260.0" y2="449.0" stroke="#1a1a1a" stroke-width="1.2"/> <rect x="201.0" y="492.5" width="10" height="18.0" fill="#c00"/>
<rect x="255.0" y="420.5" width="10" height="24.0" fill="#188a3e"/> <line x1="224.0" y1="506.0" x2="224.0" y2="534.5" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="242.0" y="470.5" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text> <rect x="219.0" y="510.5" width="10" height="19.5" fill="#c00"/>
<text x="260.0" y="406.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare 50.40</text> <line x1="242.0" y1="516.5" x2="242.0" y2="542.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="188.0" y="424.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">1</text> <rect x="237.0" y="530.0" width="10" height="1.6" fill="#c00"/>
<text x="206.0" y="442.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">2</text> <line x1="260.0" y1="503.0" x2="260.0" y2="536.0" stroke="#1a1a1a" stroke-width="1.2"/>
<text x="224.0" y="461.5" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">3</text> <rect x="255.0" y="507.5" width="10" height="24.0" fill="#188a3e"/>
<polyline points="182.0,382.0 182.0,376.0 230.0,376.0 230.0,382.0" fill="none" stroke="#c00" stroke-width="1.3"/> <text x="242.0" y="556.0" fill="#b06000" text-anchor="middle" style="font-weight:bold">doji</text>
<text x="238.0" y="380.0" fill="#c00" style="font-weight:bold">doar 3 candele</text> <text x="260.0" y="493.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">confirmare 50.40</text>
<polyline points="38.0,373.0 38.0,367.0 176.0,367.0 176.0,373.0" fill="none" stroke="#555" stroke-width="1.3"/> <line x1="98.0" y1="437.0" x2="98.0" y2="455.0" stroke="#555" stroke-width="1.8"/>
<text x="184.0" y="371.0" fill="#555" style="font-weight:bold"></text> <polygon points="98.0,463.0 94.0,455.0 102.0,455.0" fill="#555"/>
<text x="24" y="339.5" fill="#333" style="font-weight:bold">Același doji, după un range</text> <text x="98.0" y="404.0" fill="#555" text-anchor="middle" style="font-weight:bold">înainte: preț pe loc,</text>
<text x="38.0" y="362.0" fill="#555">range: nu se numără</text> <text x="98.0" y="418.0" fill="#555" text-anchor="middle" style="font-weight:bold">nu scădere — de aceea</text>
<text x="24" y="506.5" fill="#b06000" style="font-weight:bold">ACCEPTAT, semnal mai slab</text> <text x="98.0" y="432.0" fill="#555" text-anchor="middle" style="font-weight:bold">semnalul e mai slab</text>
<text x="24" y="523.5" fill="#555">scannerul cu Since Bear ≥ 8 nu-l vede</text> <text x="188.0" y="511.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">1</text>
<text x="206.0" y="529.0" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">2</text>
<text x="224.0" y="548.5" fill="#c00" text-anchor="middle" style="font-weight:bold;font-size:11px">3</text>
<text x="24" y="371.0" fill="#333" style="font-weight:bold">Același doji, după un range</text>
<text x="24" y="592.0" fill="#b06000" style="font-weight:bold">ACCEPTAT, semnal mai slab</text>
<text x="24" y="609.0" fill="#555">scannerul cu Since Bear ≥ 8 nu-l vede</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -214,6 +214,6 @@ capitolului respectiv, secțiunea 2.2 (A+ vs. mediocru), apoi A2.</p>
<li><strong>Patru sesiuni de analiză zilnică nu sunt ținute de autor</strong> (25, 26, 29 și <li><strong>Patru sesiuni de analiză zilnică nu sunt ținute de autor</strong> (25, 26, 29 și
30 iunie 2026 — un înlocuitor). Regulile care se sprijineau doar pe zilele 30 iunie 2026 — un înlocuitor). Regulile care se sprijineau doar pe zilele
alea au fost scoase din material încă de la sumarizare.</li> alea au fost scoase din material încă de la sumarizare.</li>
</ul><nav class="pager"><a class="prev" href="00_SHORTLIST.html">← 00. Shortlist: ce merită să înveți, în ce ordine</a><a class="up" href="../index.html#17_STRATEGII">↑ index</a><a class="next" href="01_buy_doji.html">01. 1. Buy Doji / Sell Doji (Strategia 3 / BYH) →</a></nav> </ul><nav class="pager"><a class="prev" href="00_SHORTLIST.html">← 00. Shortlist: ce merită să înveți, în ce ordine</a><a class="up" href="../index.html#17_STRATEGII">↑ index</a><a class="next" href="01_buy_doji.html">01. 1. Buy Doji / Sell Doji (Strategia 3) →</a></nav>
</body> </body>
</html> </html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1432,6 +1432,6 @@ long-only. Rămâne miezul logic — doi pivoți, crossing, close peste pivotul
<li>Filtrele dinainte de strategie: <a href="04_selectia.html"><code>04_selectia.md</code></a>.</li> <li>Filtrele dinainte de strategie: <a href="04_selectia.html"><code>04_selectia.md</code></a>.</li>
<li>Risc și execuție: <a href="A1_risc.html"><code>A1_risc.md</code></a>.</li> <li>Risc și execuție: <a href="A1_risc.html"><code>A1_risc.md</code></a>.</li>
<li>Regula de trail și money management, integral: <a href="../03_MODUL_2/14_strategia_1_m2d.html"><code>03_MODUL_2/14_strategia_1_m2d.md</code></a>.</li> <li>Regula de trail și money management, integral: <a href="../03_MODUL_2/14_strategia_1_m2d.html"><code>03_MODUL_2/14_strategia_1_m2d.md</code></a>.</li>
</ul><nav class="pager"><a class="prev" href="01_buy_doji.html">← 01. 1. Buy Doji / Sell Doji (Strategia 3 / BYH)</a><a class="up" href="../index.html#17_STRATEGII">↑ index</a><a class="next" href="03_m2d.html">03. 3. M2D (Strategia 1, Mecanic 2 Time Frame-uri) →</a></nav> </ul><nav class="pager"><a class="prev" href="01_buy_doji.html">← 01. 1. Buy Doji / Sell Doji (Strategia 3)</a><a class="up" href="../index.html#17_STRATEGII">↑ index</a><a class="next" href="03_m2d.html">03. 3. M2D (Strategia 1, Mecanic 2 Time Frame-uri) →</a></nav>
</body> </body>
</html> </html>

File diff suppressed because one or more lines are too long

View File

@@ -89,6 +89,37 @@ class MA:
_check_dash(self.dash, "MA") _check_dash(self.dash, "MA")
@dataclass
class Zone:
"""Dreptunghi de evidențiere peste candelele i0..i1, desenat în spatele lor."""
i0: int # prima candelă acoperită
i1: int # ultima candelă acoperită (inclusiv)
text: str = "" # eticheta zonei, deasupra dreptunghiului
color: str = "#1a5fb4"
p_top: float | None = None # implicit: cel mai mare high din interval + 8 px
p_bot: float | None = None # implicit: cel mai mic low din interval + 8 px
def __post_init__(self) -> None:
if not 0 <= self.i0 <= self.i1:
raise ValueError(f"Zone(i0={self.i0}, i1={self.i1}): astept 0 <= i0 <= i1")
@dataclass
class Arrow:
"""Săgeată cu text spre o candelă: „aici intri / aici stopul / aici ținta"."""
i: int # candela țintită
text: str # textul săgeții; "\n" rupe rândul
price: float | None = None # implicit: high (above), low (below), close (left/right)
where: str = "above" # "above" | "below" | "left" | "right" — unde stă textul
color: str = "#1a5fb4"
dx: float = 0.0 # mută textul (și coada săgeții); vârful rămâne pe țintă
dy: float = 0.0
def __post_init__(self) -> None:
if self.where not in ("above", "below", "left", "right"):
raise ValueError(f"Arrow.where={self.where!r}, astept above/below/left/right")
@dataclass @dataclass
class Chart: class Chart:
candles: list[Candle] candles: list[Candle]
@@ -108,6 +139,17 @@ class Chart:
vol_gap: float = 26.0 # spațiu între panoul de preț și cel de volum vol_gap: float = 26.0 # spațiu între panoul de preț și cel de volum
vol_label: str = "volum" vol_label: str = "volum"
title: str = "" # ex. "SPY — daily" title: str = "" # ex. "SPY — daily"
zones: list[Zone] = field(default_factory=list)
arrows: list[Arrow] = field(default_factory=list)
def __post_init__(self) -> None:
n = len(self.candles)
for z in self.zones:
if z.i1 >= n:
raise ValueError(f"Zone(i0={z.i0}, i1={z.i1}): graficul are doar {n} candele")
for a in self.arrows:
if not 0 <= a.i < n:
raise ValueError(f"Arrow(i={a.i}): graficul are doar {n} candele")
def _y(self, price: float) -> float: def _y(self, price: float) -> float:
return self.top + (self._pmax - price) * self.scale return self.top + (self._pmax - price) * self.scale
@@ -115,10 +157,80 @@ class Chart:
def _cx(self, i: int) -> float: def _cx(self, i: int) -> float:
return self.left + i * self.gap return self.left + i * self.gap
def _zone_box(self, z: Zone) -> tuple[float, float, float, float]:
cds = self.candles[z.i0:z.i1 + 1]
pad = self.body_w / 2 + 5
y0 = self._y(z.p_top) if z.p_top is not None else self._y(max(c.h for c in cds)) - 8
y1 = self._y(z.p_bot) if z.p_bot is not None else self._y(min(c.l for c in cds)) + 8
return self._cx(z.i0) - pad, y0, self._cx(z.i1) + pad, y1
def _zone_label_y(self, z: Zone) -> float:
"""Baseline-ul etichetei: deasupra zonei și a candelelor din dreptul textului."""
x0, y0, _, _ = self._zone_box(z)
x1 = x0 + len(z.text) * 6.2
tops = [self._y(c.h) for j, c in enumerate(self.candles)
if x0 - self.body_w / 2 < self._cx(j) < x1 + self.body_w / 2]
return min([y0] + [t - 4 for t in tops]) - 5
def _arrow_geom(self, a: Arrow) -> dict:
"""Vârf, coadă, rânduri de text și bbox-ul textului (x0, x1, ytop, ybot)."""
LH, CW = 14, 6.2 # înălțime rând, lățime caracter bold 12px
cd, cx = self.candles[a.i], self._cx(a.i)
lines = a.text.split("\n")
tw = max(len(t) for t in lines) * CW
if a.where in ("above", "below"):
up = a.where == "above"
price = a.price if a.price is not None else (cd.h if up else cd.l)
tip = (cx, self._y(price) + (-4 if up else 4))
# textul stă peste candelele vecine din dreptul lui: urcă/coboară
# peste cea mai extremă, altfel acoperă fitilele
near = [c for j, c in enumerate(self.candles)
if abs(self._cx(j) - cx - a.dx) < tw / 2 + self.body_w] + [cd]
if up:
ty = min(tip[1] - 26, min(self._y(c.h) for c in near) - 8) + a.dy
base = [ty - 5 - LH * k for k in range(len(lines))][::-1]
else:
ty = max(tip[1] + 26, max(self._y(c.l) for c in near) + 8) + a.dy
base = [ty + 14 + LH * k for k in range(len(lines))]
tail, tx, anchor = (cx + a.dx, ty), cx + a.dx, "middle"
x0 = tx - tw / 2
else:
sgn = 1 if a.where == "right" else -1
price = a.price if a.price is not None else cd.c
tip = (cx + sgn * (self.body_w / 2 + 4), self._y(price))
tail = (tip[0] + sgn * 30 + a.dx, tip[1] + a.dy)
tx = tail[0] + sgn * 4
base = [tail[1] + 4 - LH * (len(lines) - 1) / 2 + LH * k for k in range(len(lines))]
anchor = "start" if sgn > 0 else "end"
x0 = tx if sgn > 0 else tx - tw
return dict(tip=tip, tail=tail, tx=tx, anchor=anchor, lines=lines, base=base,
box=(x0, x0 + tw, base[0] - 11, base[-1] + 3))
def render(self) -> str: def render(self) -> str:
# _render mută top/left/width ca să facă loc titlului, trendului și
# săgeților; le restaurăm, altfel a doua randare a aceluiași Chart iese deplasată
saved = self.top, self.left, self.width
try:
return self._render()
finally:
self.top, self.left, self.width = saved
def _render(self) -> str:
prices = [p for c in self.candles for p in (c.o, c.h, c.l, c.c)] prices = [p for c in self.candles for p in (c.o, c.h, c.l, c.c)]
prices += [lv.price for lv in self.levels] prices += [lv.price for lv in self.levels]
prices += [p for z in self.zones for p in (z.p_top, z.p_bot) if p is not None]
prices += [a.price for a in self.arrows if a.price is not None]
self._pmax, pmin = max(prices), min(prices) self._pmax, pmin = max(prices), min(prices)
# textul săgeților și etichetele zonelor nu au voie să iasă din pânză:
# mută graficul în jos / la dreapta și lărgește canvasul cât e nevoie
boxes = [self._arrow_geom(a)["box"] for a in self.arrows]
boxes += [(x0, x0 + len(z.text) * 6.2, self._zone_label_y(z) - 11, y0)
for z in self.zones if z.text for x0, y0, _, _ in [self._zone_box(z)]]
if boxes:
self.top += max(0, 14 - min(b[2] for b in boxes))
shift = max(0, 6 - min(b[0] for b in boxes))
self.left += shift
self.width = max(self.width + int(shift), int(max(b[1] for b in boxes) + shift + 8))
if self.title: if self.title:
self.top += 22 self.top += 22
# segmentul de trend iese din zona candelelor: rezervă loc pentru el, # segmentul de trend iese din zona candelelor: rezervă loc pentru el,
@@ -127,6 +239,10 @@ class Chart:
self.top += 56 self.top += 56
body_bottom = self.top + (self._pmax - pmin) * self.scale body_bottom = self.top + (self._pmax - pmin) * self.scale
extra = 62 if self.trend == "up" else 0 extra = 62 if self.trend == "up" else 0
low = [self._arrow_geom(a)["box"][3] for a in self.arrows]
low += [self._zone_box(z)[3] for z in self.zones]
if low:
extra = max(extra, max(low) - body_bottom + 6)
panel_bottom = body_bottom + extra panel_bottom = body_bottom + extra
vols = [c.vol for c in self.candles if c.vol is not None] vols = [c.vol for c in self.candles if c.vol is not None]
@@ -148,6 +264,15 @@ class Chart:
out.append(f'<text x="24" y="{self.top - (56 if self.trend == "down" else 0) - 8:.0f}" ' out.append(f'<text x="24" y="{self.top - (56 if self.trend == "down" else 0) - 8:.0f}" '
f'fill="#333" style="font-weight:bold">{self.title}</text>') f'fill="#333" style="font-weight:bold">{self.title}</text>')
# zonele primele, ca să stea în spatele nivelurilor și candelelor
for z in self.zones:
x0, y0, x1, y1 = self._zone_box(z)
out.append(f'<rect x="{x0:.1f}" y="{y0:.1f}" width="{x1 - x0:.1f}" height="{y1 - y0:.1f}" '
f'fill="{z.color}" fill-opacity="0.08" stroke="{z.color}" stroke-width="1"/>')
if z.text:
out.append(f'<text x="{x0:.1f}" y="{self._zone_label_y(z):.1f}" fill="{z.color}" '
f'style="font-weight:bold">{z.text}</text>')
# nivelurile: linie pe toată lățimea, eticheta deasupra liniei # nivelurile: linie pe toată lățimea, eticheta deasupra liniei
for lv in self.levels: for lv in self.levels:
y = self._y(lv.price) y = self._y(lv.price)
@@ -234,6 +359,23 @@ class Chart:
out.append(f'<text x="{cx:.1f}" y="{y:.1f}" fill="{mk.color}" ' out.append(f'<text x="{cx:.1f}" y="{y:.1f}" fill="{mk.color}" '
f'text-anchor="{anchor}" style="font-weight:bold">{mk.text}</text>') f'text-anchor="{anchor}" style="font-weight:bold">{mk.text}</text>')
# săgețile: linie de la text la țintă + vârf triunghi (nu marker, ca
# să nu depindă de suportul <defs> în randare); un <text> per rând,
# ca audit_diagrams.py să le măsoare corect
for a in self.arrows:
g = self._arrow_geom(a)
(x1, y1), (x2, y2) = g["tail"], g["tip"]
d = max(((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5, 1e-9)
ux, uy = (x2 - x1) / d, (y2 - y1) / d
bx, by = x2 - 8 * ux, y2 - 8 * uy
out.append(f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{bx:.1f}" y2="{by:.1f}" '
f'stroke="{a.color}" stroke-width="1.8"/>')
out.append(f'<polygon points="{x2:.1f},{y2:.1f} {bx - 4 * uy:.1f},{by + 4 * ux:.1f} '
f'{bx + 4 * uy:.1f},{by - 4 * ux:.1f}" fill="{a.color}"/>')
for t, y in zip(g["lines"], g["base"]):
out.append(f'<text x="{g["tx"]:.1f}" y="{y:.1f}" fill="{a.color}" '
f'text-anchor="{g["anchor"]}" style="font-weight:bold">{t}</text>')
# detaliile ca bloc stânga-jos, câte o linie per candelă: centrate sub # detaliile ca bloc stânga-jos, câte o linie per candelă: centrate sub
# candelă se suprapun între ele de îndată ce textul depășește `gap`. # candelă se suprapun între ele de îndată ce textul depășește `gap`.
ny = panel_bottom + (self.label_gap if tags else 18) + 4 ny = panel_bottom + (self.label_gap if tags else 18) + 4
@@ -319,7 +461,36 @@ def selftest():
assert min(c.l for c in ser[:3]) > min(c.l for c in ser[3:5]), \ assert min(c.l for c in ser[:3]) > min(c.l for c in ser[3:5]), \
"al doilea picior ar trebui să fie mai jos" "al doilea picior ar trebui să fie mai jos"
print("selftest ok: 2R la exact 2R, serie fără goluri, volum proporțional") # zone și săgeți: validare, text în pânză, vârful pe țintă
for bad in (lambda: Arrow(0, "x", where="up"), lambda: Zone(3, 1),
lambda: Chart(candles=ser, arrows=[Arrow(6, "x")]),
lambda: Chart(candles=ser, zones=[Zone(4, 6)])):
try:
bad()
raise AssertionError("validarea n-a prins argumente greșite")
except ValueError:
pass
ch3 = Chart(candles=ser, scale=40, gap=14, body_w=9, width=200,
zones=[Zone(1, 3, "baza")],
arrows=[Arrow(0, "intrare\npe close", where="above"),
Arrow(3, "stop", where="below"),
Arrow(5, "ținta de 2R, foarte departe", where="right")])
svg3 = ch3.render()
vw, vh = map(float, re.search(r'viewBox="0 0 ([\d.]+) ([\d.]+)"', svg3).groups())
assert vw > 200, "textul săgeții din dreapta iese din pânză"
for x, y in re.findall(r'<text x="([-\d.]+)" y="([-\d.]+)"', svg3):
assert 0 <= float(x) <= vw and 11 <= float(y) <= vh, f"text în afara pânzei la ({x}, {y})"
tip = ch3._arrow_geom(ch3.arrows[1])["tip"]
assert abs(tip[1] - (ch3._y(ser[3].l) + 4)) < 1e-6, "vârful săgeții below nu e sub low"
# a doua randare a aceluiași obiect trebuie să iasă identică
ch3.title, ch3.trend = "T", "down"
assert ch3.render() == ch3.render(), "render() modifică obiectul: a doua randare diferă"
assert (ch3.top, ch3.left, ch3.width) == (34, 64, 200), "render() a lăsat top/left/width modificate"
assert svg3.index("fill-opacity") < svg3.index("<rect", svg3.index("fill-opacity") + 1), \
"zona trebuie desenată înaintea candelelor"
assert svg3.count("<polygon") == 3 and "pe close</text>" in svg3
print("selftest ok: 2R la exact 2R, serie fără goluri, volum proporțional, zone+săgeți")
if __name__ == "__main__": if __name__ == "__main__":