selectia: diagramele refacute dupa sablon (textul urmeaza)
Agentul a atins pragul de context dupa diagrame; capitolul 04_selectia e inca in formatul vechi si se reia separat. Ce s-a schimbat: ansamblul nu mai arata ULTA mergand la TP2 — ULTA pica chiar filtrul de selectie (RVOL 0.61 si 5.01 % de suport), deci nu putea fi exemplul-vitrina; acum arata doar ce citeste selectia, cu granita "aici se termina selectia" marcata. Funnel-ul trece de la 8 trepte la 6, aliniat cu pasii nivelului 2, si fiecare treapta spune de ce. Cadranele primesc mini-histograme RS, ca sa se recunoasca dintr-un desen, nu dintr-o propozitie. Trimiterile fisier:linie sunt scoase de pe desene. Noi: univers (pragurile de pret si volum), sectoare (dominantul din cele 11), proximitate (banda de 3 % peste suportul monthly, cu observatia ca nu e pragul de 1-2 % din Buy Doji — masoara altceva). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
@@ -1,119 +0,0 @@
|
||||
<svg viewBox="0 0 680 508" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<rect x="24" y="221.6" width="642" height="18.0" fill="#777" opacity="0.10"/>
|
||||
<text x="24" y="48" fill="#333" style="font-weight:bold">SPY — daily: aceeași corecție, 4.0 % (DA) vs. 3.9 % (NU)</text>
|
||||
<line x1="24" y1="156.8" x2="666" y2="156.8" stroke="#333" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="652" y="150.8" fill="#333" text-anchor="end">100.00 — swing high</text>
|
||||
<line x1="24" y1="228.8" x2="666" y2="228.8" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="652" y="222.8" fill="#188a3e" text-anchor="end">96.00 = 4.0 % — DA, intri</text>
|
||||
<line x1="24" y1="56.0" x2="666" y2="56.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="652" y="50.0" fill="#1a5fb4" text-anchor="end">TP +10 % = 105.60</text>
|
||||
<line x1="44.0" y1="332.3" x2="44.0" y2="353.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="39.5" y="336.8" width="9" height="10.8" fill="#188a3e"/>
|
||||
<line x1="60.0" y1="316.1" x2="60.0" y2="342.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="55.5" y="320.6" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="76.0" y1="301.7" x2="76.0" y2="326.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="71.5" y="306.2" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="92.0" y1="289.1" x2="92.0" y2="311.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="87.5" y="293.6" width="9" height="12.6" fill="#188a3e"/>
|
||||
<line x1="108.0" y1="274.7" x2="108.0" y2="299.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="103.5" y="279.2" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="124.0" y1="260.3" x2="124.0" y2="284.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="119.5" y="264.8" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="140.0" y1="247.7" x2="140.0" y2="270.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="135.5" y="252.2" width="9" height="12.6" fill="#188a3e"/>
|
||||
<line x1="156.0" y1="235.1" x2="156.0" y2="257.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="151.5" y="239.6" width="9" height="12.6" fill="#188a3e"/>
|
||||
<line x1="172.0" y1="222.5" x2="172.0" y2="245.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="167.5" y="227.0" width="9" height="12.6" fill="#188a3e"/>
|
||||
<line x1="188.0" y1="206.3" x2="188.0" y2="232.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="183.5" y="210.8" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="204.0" y1="182.9" x2="204.0" y2="216.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="199.5" y="187.4" width="9" height="23.4" fill="#188a3e"/>
|
||||
<line x1="220.0" y1="156.8" x2="220.0" y2="192.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="215.5" y="156.8" width="9" height="30.6" fill="#188a3e"/>
|
||||
<line x1="236.0" y1="152.3" x2="236.0" y2="174.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="231.5" y="156.8" width="9" height="12.6" fill="#c00"/>
|
||||
<line x1="252.0" y1="164.9" x2="252.0" y2="189.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="247.5" y="169.4" width="9" height="14.4" fill="#c00"/>
|
||||
<line x1="268.0" y1="179.3" x2="268.0" y2="203.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="263.5" y="183.8" width="9" height="14.4" fill="#c00"/>
|
||||
<line x1="284.0" y1="193.7" x2="284.0" y2="214.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="279.5" y="198.2" width="9" height="10.8" fill="#c00"/>
|
||||
<line x1="300.0" y1="204.5" x2="300.0" y2="223.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="295.5" y="209.0" width="9" height="9.0" fill="#c00"/>
|
||||
<line x1="316.0" y1="213.5" x2="316.0" y2="230.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="311.5" y="218.0" width="9" height="7.2" fill="#c00"/>
|
||||
<line x1="332.0" y1="221.6" x2="332.0" y2="237.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="327.5" y="225.2" width="9" height="4.0" fill="#c00"/>
|
||||
<line x1="348.0" y1="225.2" x2="348.0" y2="231.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="343.5" y="228.8" width="9" height="1.6" fill="#188a3e"/>
|
||||
<line x1="364.0" y1="206.3" x2="364.0" y2="234.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="359.5" y="210.8" width="9" height="18.0" fill="#188a3e"/>
|
||||
<line x1="380.0" y1="190.1" x2="380.0" y2="216.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="375.5" y="194.6" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="396.0" y1="173.9" x2="396.0" y2="200.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="391.5" y="178.4" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="412.0" y1="157.7" x2="412.0" y2="183.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="407.5" y="162.2" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="428.0" y1="143.3" x2="428.0" y2="167.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="423.5" y="147.8" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="444.0" y1="128.9" x2="444.0" y2="153.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="439.5" y="133.4" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="460.0" y1="114.5" x2="460.0" y2="138.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="455.5" y="119.0" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="476.0" y1="100.1" x2="476.0" y2="124.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="471.5" y="104.6" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="492.0" y1="85.7" x2="492.0" y2="110.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="487.5" y="90.2" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="508.0" y1="71.3" x2="508.0" y2="95.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="503.5" y="75.8" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="524.0" y1="60.5" x2="524.0" y2="81.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="519.5" y="65.0" width="9" height="10.8" fill="#188a3e"/>
|
||||
<line x1="540.0" y1="56.0" x2="540.0" y2="70.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="535.5" y="56.0" width="9" height="9.0" fill="#188a3e"/>
|
||||
<line x1="24" y1="449.0" x2="666" y2="449.0" stroke="#888"/>
|
||||
<rect x="39.5" y="410.8" width="9" height="38.2" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="55.5" y="409.2" width="9" height="39.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="71.5" y="412.4" width="9" height="36.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="87.5" y="407.6" width="9" height="41.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="103.5" y="406.0" width="9" height="43.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="119.5" y="409.2" width="9" height="39.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="135.5" y="404.5" width="9" height="44.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="151.5" y="407.6" width="9" height="41.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="167.5" y="402.9" width="9" height="46.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="183.5" y="401.3" width="9" height="47.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="199.5" y="398.1" width="9" height="50.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="215.5" y="391.7" width="9" height="57.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="231.5" y="393.3" width="9" height="55.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="247.5" y="390.1" width="9" height="58.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="263.5" y="387.0" width="9" height="62.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="279.5" y="383.8" width="9" height="65.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="295.5" y="380.6" width="9" height="68.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="311.5" y="385.4" width="9" height="63.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="327.5" y="382.2" width="9" height="66.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="343.5" y="379.0" width="9" height="70.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="359.5" y="391.7" width="9" height="57.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="375.5" y="396.5" width="9" height="52.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="391.5" y="399.7" width="9" height="49.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="407.5" y="402.9" width="9" height="46.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="423.5" y="406.0" width="9" height="43.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="439.5" y="409.2" width="9" height="39.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="455.5" y="412.4" width="9" height="36.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="471.5" y="399.7" width="9" height="49.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="487.5" y="394.9" width="9" height="54.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="503.5" y="391.7" width="9" height="57.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="519.5" y="387.0" width="9" height="62.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="535.5" y="380.6" width="9" height="68.4" fill="#188a3e" opacity="0.55"/>
|
||||
<text x="24" y="373.0" fill="#555">volum</text>
|
||||
<text x="332.0" y="209.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">BIM</text>
|
||||
<text x="348.0" y="271.9" fill="#188a3e" text-anchor="middle" style="font-weight:bold">candelă verde → trigger</text>
|
||||
<text x="24" y="471.0" fill="#188a3e">Regula e pe procent, nu pe cât de dramatică arată linia: calea NU pare o cădere mare, dar e 3.9 %.</text>
|
||||
<text x="24" y="496" fill="#555">Calea DA (candele): 4.0 % la 96.00. Calea NU (punctat): 3.9 % („3.93 %” în curs) — fără intrare.</text>
|
||||
<polyline points="220.0,156.8 236.0,167.6 252.0,181.1 268.0,193.7 284.0,204.5 300.0,214.4 316.0,227.0 332.0,234.2 348.0,240.5 380.0,247.7 412.0,253.1 444.0,256.7" fill="none" stroke="#c00" stroke-width="1.8" stroke-dasharray="5 4"/>
|
||||
<line x1="24" y1="227.0" x2="666" y2="227.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<circle cx="316.0" cy="227.0" r="3.5" fill="#c00"/>
|
||||
<text x="652" y="239.0" fill="#c00" text-anchor="end">96.10 = 3.9 % — NU, sub prag</text>
|
||||
<text x="652" y="252.6" fill="#777" text-anchor="end">zonă quarterly</text>
|
||||
<text x="24" y="183.8" fill="#188a3e" style="font-weight:bold">calea DA (candelele)</text>
|
||||
<text x="444.0" y="272.7" fill="#c00" style="font-weight:bold">calea NU (continuă în jos)</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.8 KiB |
@@ -1,10 +1,16 @@
|
||||
"""ULTA — daily (pivoți monthly): diagrama de ansamblu a selecției (TIP: PRET).
|
||||
|
||||
Citește `gen/strategii/selectia_ansamblu.spec.txt`. Un simbol care vine dintr-un
|
||||
downtrend weekly, atinge suportul monthly 355.48 și face un buy doji la 373.30
|
||||
cu RVOL 0.61; apoi confirmarea (intrare 374.80) și drumul spre pivot/TP1 383.74,
|
||||
respectiv TP2 402.00. Grafic daily, 32 de candele, serie continuă, cu panou de
|
||||
volum și SMA-20 — construit prin `svg_candles` (from_closes), la scară.
|
||||
Rolul diagramei în capitol: arată **unde se termină selecția**. Filtrul citește
|
||||
contextul (downtrend, suportul monthly 355.48, pivotul monthly 383.74, buy doji
|
||||
la 373.30, RVOL 0.61) și se oprește la „simbolul intră pe listă". Intrarea,
|
||||
stopul și ținta nu apar aici, pentru că nu aparțin selecției — sunt ale
|
||||
capitolului 1 (Buy Doji). Partea de după linia verticală e desenată gri tocmai
|
||||
ca să se vadă că nu mai e treaba filtrului.
|
||||
|
||||
Cifrele cursului: close 373.30, suport monthly 355.48, pivot monthly 383.74,
|
||||
RVOL 0.61 (`04_MODUL_3/01_filtre_scaner_bull_bear_reversal_pp.md`). Procentele
|
||||
de 5.01 % și 2.72 % se recalculează din ele, cu assert. Structura barelor e
|
||||
construită, la scară, prin `svg_candles` (from_closes).
|
||||
|
||||
Rulează:
|
||||
python3 gen/strategii/selectia_ansamblu.py
|
||||
@@ -15,18 +21,20 @@ import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
from svg_candles import Chart, Level, Mark, MA, from_closes # noqa: E402
|
||||
from svg_candles import Chart, Level, Arrow, Zone, MA, from_closes # noqa: E402
|
||||
|
||||
OUT = Path(__file__).resolve().parent / "selectia_ansamblu.svg"
|
||||
|
||||
GRAY, RED, GREEN, BLUE, ORANGE, TEAL = "#777", "#c00", "#188a3e", "#1a5fb4", "#b06000", "#00a0aa"
|
||||
|
||||
SUPORT, PIVOT, DOJI_CLOSE = 355.48, 383.74, 373.30
|
||||
DOJI = 20 # indexul candelei de buy doji
|
||||
|
||||
# ---------------------------------------------------------------- seria (32 bare)
|
||||
# bare 0-11 : downtrend vizibil de la ~395 la ~362 (~0.8%/bara)
|
||||
# bare 12-19 : baza/churn 356-373, minimul atinge suportul 355.48 pe bara 15
|
||||
# bare 0-11 : downtrend vizibil de la ~395 la ~362 (~0.8 %/bară)
|
||||
# bare 12-19 : baza, minimul atinge suportul monthly 355.48 pe bara 15
|
||||
# bara 20 : buy doji, close 373.30 (open = close[19] = 373.00, corp 0.30)
|
||||
# bara 21 : confirmare, inchide peste intrarea 374.80
|
||||
# bare 22-31 : urcare spre pivot/TP1 383.74 (bara 26) si apoi spre TP2 402.00
|
||||
# bare 21-31 : ce urmează — nu mai e treaba selecției, desenat gri
|
||||
CLOSES = [
|
||||
395.00, 391.80, 388.60, 385.20, 382.00, 378.90, 375.70, 372.80, # 0-7
|
||||
369.90, 367.00, 364.20, 361.80, # 8-11
|
||||
@@ -38,92 +46,106 @@ CLOSES = [
|
||||
assert len(CLOSES) == 32, len(CLOSES)
|
||||
|
||||
WICKS = [(0.35, 0.40)] * 32
|
||||
WICKS[0] = (0.40, 0.50) # prima bara, deschide dintr-un varf al downtrend-ului
|
||||
WICKS[0] = (0.40, 0.50) # prima bară, deschide dintr-un vârf al downtrend-ului
|
||||
WICKS[15] = (0.30, 0.72) # low exact 355.48 = suportul monthly
|
||||
WICKS[16] = (0.40, 0.30) # rebound, nu sparge suportul
|
||||
WICKS[20] = (0.80, 0.30) # doji: high 374.10, low 372.70
|
||||
WICKS[31] = (0.55, 0.40) # high 402.05, atinge TP2 402.00
|
||||
WICKS[DOJI] = (1.45, 1.45) # doji: corp 0.30 din 3.20 înălțime = 9 %
|
||||
assert len(WICKS) == 32, len(WICKS)
|
||||
|
||||
# barele 25-31 in crestere; bara 20 (doji) sub media seriei (RVOL 0.61)
|
||||
# bara 20 (doji) sub media seriei: exact ce înseamnă RVOL 0.61
|
||||
VOLS = [
|
||||
42, 44, 41, 46, 43, 45, 40, 44, 47, 43, # 0-9
|
||||
40, 42, 38, 41, 52, # 10-14
|
||||
56, 50, 45, 42, 39, # 15-19
|
||||
30, # 20 doji, sub medie
|
||||
46, # 21 confirmare
|
||||
46, # 21
|
||||
48, 50, 52, 54, 58, 62, 66, 70, 76, 82, # 22-31
|
||||
]
|
||||
assert len(VOLS) == 32, len(VOLS)
|
||||
media_vol = sum(VOLS) / len(VOLS)
|
||||
assert VOLS[20] < media_vol, "bara 20 (doji) trebuie sub media seriei"
|
||||
assert all(a < b for a, b in zip(VOLS[25:32], VOLS[26:32])), "barele 25-31 nu cresc"
|
||||
# RVOL afisat (0.61) ~ raportul barei de doji fata de media seriei
|
||||
assert abs(VOLS[20] / media_vol - 0.61) < 0.02, VOLS[20] / media_vol
|
||||
assert abs(VOLS[DOJI] / media_vol - 0.61) < 0.02, VOLS[DOJI] / media_vol
|
||||
|
||||
cds = from_closes(CLOSES, wicks=WICKS, vols=VOLS, start=396.50)
|
||||
|
||||
# ---------------------------------------------------------------- assert-urile din spec
|
||||
assert abs(cds[20].c - 373.30) < 1e-9, "doji-ul trebuie sa inchida la 373.30"
|
||||
assert abs(max(cds[20].o, cds[20].c) - min(cds[20].o, cds[20].c)) <= 0.40, "bara 20 nu e doji"
|
||||
assert abs(min(c.l for c in cds[12:21]) - 355.48) < 0.05, "suportul 355.48 nu e atins"
|
||||
assert 352.00 < 355.48 < 373.30 < 374.80 < 383.74 < 402.00, "ordinea nivelurilor"
|
||||
risc = 374.80 - 352.00 # 22.80
|
||||
assert abs((383.74 - 374.80) / risc - 0.39) < 0.02, "TP1 nu e ~0.39R"
|
||||
assert abs((402.00 - 374.80) / risc - 1.19) < 0.02, "TP2 nu e ~1.19R"
|
||||
assert cds[-1].c >= 383.74, "TP1 nu e atins in serie"
|
||||
assert min(c.l for c in cds) >= 351.5, "SL-ul de 352.00 nu poate fi sub minimul seriei"
|
||||
# barele de după doji sunt gri: nu mai sunt în sarcina filtrului
|
||||
for cd in cds[DOJI + 1:]:
|
||||
cd.color = "#bbb"
|
||||
|
||||
# ---------------------------------------------------------------- assert-uri de conținut
|
||||
assert abs(cds[DOJI].c - DOJI_CLOSE) < 1e-9, "doji-ul trebuie să închidă la 373.30"
|
||||
corp = abs(cds[DOJI].o - cds[DOJI].c)
|
||||
inaltime = cds[DOJI].h - cds[DOJI].l
|
||||
assert corp / inaltime <= 0.10, f"bara {DOJI} nu e doji: corp {corp / inaltime:.0%} din înălțime"
|
||||
assert abs(min(c.l for c in cds[12:DOJI + 1]) - SUPORT) < 0.05, "suportul 355.48 nu e atins"
|
||||
# de la intrarea în bază și până la doji, prețul stă sub pivot: de asta pivotul
|
||||
# e rezistența cea mai apropiată deasupra doji-ului
|
||||
assert max(c.h for c in cds[12:DOJI + 1]) < PIVOT, "pivotul nu are voie atins în bază"
|
||||
for a, b in zip(cds, cds[1:]):
|
||||
assert abs(a.c - b.o) < 1e-9, "serie cu gol artificial intre bare"
|
||||
assert abs(a.c - b.o) < 1e-9, "serie cu gol artificial între bare"
|
||||
|
||||
# structura ceruta explicit: doji mic cu fitilele date, confirmare peste intrare
|
||||
assert abs(cds[20].h - 374.10) < 0.05 and abs(cds[20].l - 372.70) < 0.05, (cds[20].h, cds[20].l)
|
||||
assert cds[21].c > 374.80, "bara 21 nu confirma intrarea"
|
||||
assert max(cds[i].h for i in range(22, 27)) >= 383.74, "TP1 nu e atins in jurul barei 26"
|
||||
assert cds[31].h >= 402.00, "TP2 nu e atins spre final"
|
||||
# procentele din etichete se calculează, nu se scriu de mână
|
||||
pct_suport = (DOJI_CLOSE - SUPORT) / SUPORT * 100 # 5.01 %
|
||||
pct_pivot = (PIVOT - DOJI_CLOSE) / PIVOT * 100 # 2.72 %
|
||||
assert abs(pct_suport - 5.01) < 0.01, pct_suport
|
||||
assert abs(pct_pivot - 2.72) < 0.01, pct_pivot
|
||||
rvol = VOLS[DOJI] / media_vol
|
||||
|
||||
# ---------------------------------------------------------------- niveluri, etichete
|
||||
levels = [
|
||||
Level(352.00, "SL 352.00", RED, label_at="left"),
|
||||
Level(355.48, "suport monthly 355.48", BLUE, label_at="left"),
|
||||
Level(374.80, "intrare 374.80", GREEN),
|
||||
Level(383.74, "pivot / TP1 383.74", BLUE),
|
||||
Level(402.00, "TP2 402.00", BLUE),
|
||||
Level(SUPORT, f"suport monthly {SUPORT:.2f}", BLUE, label_at="left"),
|
||||
Level(PIVOT, f"pivot monthly {PIVOT:.2f}", BLUE),
|
||||
]
|
||||
|
||||
marks = [
|
||||
# „sub bara 0" ar insemna peste candelele care coboara (staircase); dy-ul
|
||||
# o ridica deasupra varfului de start, unde textul se citeste curat
|
||||
Mark(0, "downtrend weekly", GRAY, "below", dy=-62),
|
||||
Mark(20, "buy doji close 373.30 (RVOL 0.61)", TEAL, "below"),
|
||||
Mark(21, "intrare 374.80", GREEN, "above"),
|
||||
Mark(26, "TP1 383.74 = pivot", BLUE, "above", dy=-8),
|
||||
Mark(31, "TP2 402.00", BLUE, "above", dy=-22),
|
||||
zones = [
|
||||
Zone(0, 11, "1. downtrend — de asta apare în scaner", RED),
|
||||
Zone(12, DOJI, "", BLUE, p_bot=SUPORT - 0.6),
|
||||
]
|
||||
|
||||
caption = ("Ale cursului: close 373.30, suport 355.48, pivot 383.74, RVOL 0.61. "
|
||||
"Intrarea 374.80, SL 352.00 si TP2 402.00 sunt estimari din 04_MODUL_3/01; "
|
||||
"structura barelor dintre niveluri e construita, la scara.")
|
||||
arrows = [
|
||||
Arrow(15, f"2. suportul monthly {SUPORT:.2f} a mai întors prețul o dată:\n"
|
||||
f"acolo stau ordine de cumpărare, deci coborârea are unde să se oprească",
|
||||
where="below", price=SUPORT, color=BLUE, dx=-30, dy=34),
|
||||
Arrow(DOJI, f"3. buy doji, close {DOJI_CLOSE:.2f} — aici se oprește selecția\n"
|
||||
f"{pct_suport:.2f} % peste suport, {pct_pivot:.2f} % sub pivot: trece proximitatea față de pivot\n"
|
||||
f"volumul zilei = {rvol:.2f} din medie (RVOL {rvol:.2f}), sub pragul de 1.00: minus, nu veto",
|
||||
where="above", color=TEAL, dx=-250, dy=-66),
|
||||
Arrow(27, "trigger, stop și țintă sunt\nale capitolului Buy Doji",
|
||||
where="right", color=GRAY, dx=16, dy=-40),
|
||||
]
|
||||
|
||||
caption = ("Ale cursului: close 373.30, suport monthly 355.48, pivot monthly 383.74, RVOL 0.61. "
|
||||
"Procentele sunt calculate din ele. Structura barelor e construită, la scară. "
|
||||
"Intrarea, stopul și ținta nu apar pe desen: nu aparțin selecției.")
|
||||
|
||||
ch = Chart(
|
||||
candles=cds, levels=levels, marks=marks,
|
||||
candles=cds, levels=levels, zones=zones, arrows=arrows,
|
||||
mas=[MA(20, ORANGE, dash="4 3", text="SMA-20")],
|
||||
scale=8.5, gap=15, body_w=9, left=44, width=640, vol_h=70,
|
||||
vol_label="volum",
|
||||
title="ULTA — daily (pivoți monthly)",
|
||||
title="ULTA — daily: ce citește selecția și unde se oprește",
|
||||
caption=caption,
|
||||
)
|
||||
svg = ch.render()
|
||||
|
||||
# ---------------------------------------------------------------- verificarea de scara
|
||||
ys = {p: ch._y(p) for p in (352.00, 355.48, 374.80, 383.74, 402.00)}
|
||||
px_risc = ys[352.00] - ys[374.80] # y creste in jos, deci SL-ul are y mai mare
|
||||
assert abs((ys[374.80] - ys[383.74]) / px_risc - (383.74 - 374.80) / risc) < 1e-9, "TP1 la scara gresita"
|
||||
assert abs((ys[374.80] - ys[402.00]) / px_risc - (402.00 - 374.80) / risc) < 1e-9, "TP2 la scara gresita"
|
||||
# ---------------------------------------------------------------- linia verticală de predare
|
||||
# offsetul intern al randării, citit din prima linie de Level desenată
|
||||
m_off = re.search(r'<line x1="24" y1="([\d.]+)"', svg)
|
||||
assert m_off, "nu găsesc linia primului Level, din care citesc offsetul pe y"
|
||||
OFF = float(m_off.group(1)) - ch._y(levels[0].price)
|
||||
# render() mută și `left`; offsetul pe x se citește din dreptunghiul primei zone
|
||||
m_dx = re.search(r'<rect x="([\d.]+)"[^>]*fill="' + RED + r'"', svg)
|
||||
assert m_dx, "nu găsesc dreptunghiul primei zone, din care citesc offsetul pe x"
|
||||
DX = float(m_dx.group(1)) - (ch._cx(0) - ch.body_w / 2 - 5)
|
||||
x_sep = ch._cx(DOJI) + DX + ch.gap / 2
|
||||
y_top = ch._y(max(c.h for c in cds)) + OFF + 4
|
||||
y_bot = ch._y(min(c.l for c in cds)) + OFF + 16
|
||||
sep = (f'<line x1="{x_sep:.1f}" y1="{y_top:.1f}" x2="{x_sep:.1f}" y2="{y_bot:.1f}" '
|
||||
f'stroke="#444" stroke-width="1.5" stroke-dasharray="6 4"/>'
|
||||
f'<text x="{x_sep - 6:.1f}" y="{y_bot + 14:.1f}" fill="#444" text-anchor="end" '
|
||||
f'style="font-weight:bold">aici se termină selecția</text>'
|
||||
f'<text x="{x_sep + 6:.1f}" y="{y_bot + 14:.1f}" fill="#999">aici începe capitolul 1</text>')
|
||||
svg = svg.replace("</svg>", sep + "</svg>")
|
||||
|
||||
# ---------------------------------------------------------------- finisaj text
|
||||
# caption-ul pe un singur rand depaseste latimea panzei (se taie la viewBox):
|
||||
# il rupem in linii si crestem inaltimea desenului.
|
||||
# ---------------------------------------------------------------- caption pe mai multe rânduri
|
||||
def _wrap(text: str, max_chars: int) -> list[str]:
|
||||
lines, cur = [], ""
|
||||
for w in text.split():
|
||||
@@ -138,25 +160,27 @@ def _wrap(text: str, max_chars: int) -> list[str]:
|
||||
|
||||
|
||||
cap_lines = _wrap(caption, 92)
|
||||
m = re.search(r'<text x="24" y="(\d+)" fill="#555">' + re.escape(caption) + r"</text>\s*</svg>", svg)
|
||||
assert m, "caption-ul nu a fost gasit in SVG"
|
||||
m = re.search(r'<text x="24" y="(\d+)" fill="#555">' + re.escape(caption) + r"</text>", svg)
|
||||
assert m, "caption-ul nu a fost găsit în SVG"
|
||||
y0 = int(m.group(1))
|
||||
wrapped = "\n ".join(f'<text x="24" y="{y0 + 17 * i}" fill="#555">{ln}</text>'
|
||||
for i, ln in enumerate(cap_lines))
|
||||
svg = svg[:m.start()] + wrapped + "\n</svg>"
|
||||
svg = svg[:m.start()] + wrapped + svg[m.end():]
|
||||
vm = re.search(r'viewBox="0 0 (\d+) (\d+)"', svg)
|
||||
assert vm
|
||||
svg = svg.replace(vm.group(0),
|
||||
f'viewBox="0 0 {vm.group(1)} {int(vm.group(2)) + 17 * (len(cap_lines) - 1)}"', 1)
|
||||
f'viewBox="0 0 {vm.group(1)} {int(vm.group(2)) + 17 * (len(cap_lines) - 1) + 24}"', 1)
|
||||
|
||||
# „SMA-20" (x=515, y=269) sta la 12.6px de eticheta „intrare 374.80" (y=281.6),
|
||||
# adica lipite: o ridicam 12px pe linia libera de deasupra.
|
||||
svg, n = re.subn(r'(<text x="\d+" y=")(\d+)(" fill="#b06000">SMA-20</text>)',
|
||||
lambda mm: f'{mm.group(1)}{int(mm.group(2)) - 12}{mm.group(3)}', svg)
|
||||
assert n == 1, f"eticheta SMA-20: {n} potriviri"
|
||||
# ---------------------------------------------------------------- nicio cifră inventată în etichete
|
||||
desenate = {f"{SUPORT:.2f}", f"{PIVOT:.2f}", f"{DOJI_CLOSE:.2f}"}
|
||||
for txt in re.findall(r"<text[^>]*>([^<]*)</text>", svg):
|
||||
for nr in re.findall(r"\d+\.\d\d", txt):
|
||||
assert nr in desenate | {f"{pct_suport:.2f}", f"{pct_pivot:.2f}",
|
||||
f"{rvol:.2f}", "1.00"}, \
|
||||
f"eticheta numește {nr}, care nu e un nivel desenat: {txt!r}"
|
||||
|
||||
assert "<svg" in svg and "\n\n" not in svg, "linie goala in SVG"
|
||||
assert "<svg" in svg and "\n\n" not in svg, "linie goală în SVG"
|
||||
OUT.write_text(svg)
|
||||
print(f"scris {OUT.name}: {len(cds)} candele, doji {cds[20].c:.2f} (RVOL {VOLS[20]/media_vol:.2f}), "
|
||||
f"suport {min(c.l for c in cds[12:21]):.2f}, intrare 374.80, SL 352.00, "
|
||||
f"TP1 383.74 = 0.39R, TP2 402.00 = 1.19R, ultimul close {cds[-1].c:.2f}")
|
||||
print(f"scris {OUT.name}: 32 candele, doji {cds[DOJI].c:.2f} (RVOL {rvol:.2f}), "
|
||||
f"suport {SUPORT:.2f} ({pct_suport:.2f} % sub doji), pivot {PIVOT:.2f} "
|
||||
f"({pct_pivot:.2f} % peste doji), fără intrare/stop/țintă pe desen")
|
||||
|
||||
@@ -1,121 +1,126 @@
|
||||
<svg viewBox="0 0 640 653" 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">ULTA — daily (pivoți monthly)</text>
|
||||
<line x1="24" y1="481.4" x2="626" y2="481.4" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="475.4" fill="#c00">SL 352.00</text>
|
||||
<line x1="24" y1="451.8" x2="626" y2="451.8" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="445.8" fill="#1a5fb4">suport monthly 355.48</text>
|
||||
<line x1="24" y1="287.6" x2="626" y2="287.6" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="612" y="281.6" fill="#188a3e" text-anchor="end">intrare 374.80</text>
|
||||
<line x1="24" y1="211.6" x2="626" y2="211.6" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="612" y="205.6" fill="#1a5fb4" text-anchor="end">pivot / TP1 383.74</text>
|
||||
<line x1="24" y1="56.4" x2="626" y2="56.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="612" y="50.4" fill="#1a5fb4" text-anchor="end">TP2 402.00</text>
|
||||
<polyline points="329.0,311.7 344.0,320.9 359.0,327.8 374.0,332.8 389.0,335.6 404.0,336.3 419.0,335.0 434.0,331.2 449.0,325.4 464.0,317.1 479.0,306.0 494.0,291.9 509.0,275.0" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="515" y="257" fill="#b06000">SMA-20</text>
|
||||
<line x1="44.0" y1="99.8" x2="44.0" y2="120.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="39.5" y="103.2" width="9" height="12.8" fill="#c00"/>
|
||||
<line x1="59.0" y1="112.9" x2="59.0" y2="146.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="54.5" y="115.9" width="9" height="27.2" fill="#c00"/>
|
||||
<line x1="74.0" y1="140.1" x2="74.0" y2="173.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="69.5" y="143.1" width="9" height="27.2" fill="#c00"/>
|
||||
<line x1="89.0" y1="167.3" x2="89.0" y2="202.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="84.5" y="170.3" width="9" height="28.9" fill="#c00"/>
|
||||
<line x1="104.0" y1="196.2" x2="104.0" y2="229.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="99.5" y="199.2" width="9" height="27.2" fill="#c00"/>
|
||||
<line x1="119.0" y1="223.4" x2="119.0" y2="256.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="114.5" y="226.4" width="9" height="26.4" fill="#c00"/>
|
||||
<line x1="134.0" y1="249.8" x2="134.0" y2="283.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="129.5" y="252.8" width="9" height="27.2" fill="#c00"/>
|
||||
<line x1="149.0" y1="277.0" x2="149.0" y2="308.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="144.5" y="280.0" width="9" height="24.6" fill="#c00"/>
|
||||
<line x1="164.0" y1="301.6" x2="164.0" y2="332.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="159.5" y="304.6" width="9" height="24.7" fill="#c00"/>
|
||||
<line x1="179.0" y1="326.3" x2="179.0" y2="357.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="174.5" y="329.3" width="9" height="24.6" fill="#c00"/>
|
||||
<line x1="194.0" y1="350.9" x2="194.0" y2="381.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="189.5" y="353.9" width="9" height="23.8" fill="#c00"/>
|
||||
<line x1="209.0" y1="374.8" x2="209.0" y2="401.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="204.5" y="377.7" width="9" height="20.4" fill="#c00"/>
|
||||
<line x1="224.0" y1="383.2" x2="224.0" y2="401.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="219.5" y="386.2" width="9" height="11.9" fill="#188a3e"/>
|
||||
<line x1="239.0" y1="383.2" x2="239.0" y2="408.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="234.5" y="386.2" width="9" height="18.7" fill="#c00"/>
|
||||
<line x1="254.0" y1="401.9" x2="254.0" y2="429.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="249.5" y="404.9" width="9" height="21.2" fill="#c00"/>
|
||||
<line x1="269.0" y1="423.6" x2="269.0" y2="451.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="264.5" y="426.2" width="9" height="19.6" fill="#c00"/>
|
||||
<line x1="284.0" y1="410.0" x2="284.0" y2="448.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="279.5" y="413.4" width="9" height="32.3" fill="#188a3e"/>
|
||||
<line x1="299.0" y1="367.9" x2="299.0" y2="416.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="294.5" y="370.9" width="9" height="42.5" fill="#188a3e"/>
|
||||
<line x1="314.0" y1="329.7" x2="314.0" y2="374.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="309.5" y="332.7" width="9" height="38.2" fill="#188a3e"/>
|
||||
<line x1="329.0" y1="299.9" x2="329.0" y2="336.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="324.5" y="302.9" width="9" height="29.8" fill="#188a3e"/>
|
||||
<line x1="344.0" y1="293.6" x2="344.0" y2="305.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="339.5" y="300.4" width="9" height="2.6" fill="#188a3e"/>
|
||||
<line x1="359.0" y1="277.8" x2="359.0" y2="303.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="354.5" y="280.8" width="9" height="19.6" fill="#188a3e"/>
|
||||
<line x1="374.0" y1="265.9" x2="374.0" y2="284.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="369.5" y="268.9" width="9" height="11.9" fill="#188a3e"/>
|
||||
<line x1="389.0" y1="253.2" x2="389.0" y2="272.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="384.5" y="256.2" width="9" height="12.8" fill="#188a3e"/>
|
||||
<line x1="404.0" y1="237.1" x2="404.0" y2="259.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="399.5" y="240.0" width="9" height="16.1" fill="#188a3e"/>
|
||||
<line x1="419.0" y1="223.4" x2="419.0" y2="243.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="414.5" y="226.4" width="9" height="13.6" fill="#188a3e"/>
|
||||
<line x1="434.0" y1="202.2" x2="434.0" y2="229.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="429.5" y="205.2" width="9" height="21.2" fill="#188a3e"/>
|
||||
<line x1="449.0" y1="185.2" x2="449.0" y2="208.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="444.5" y="188.2" width="9" height="17.0" fill="#188a3e"/>
|
||||
<line x1="464.0" y1="159.7" x2="464.0" y2="191.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="459.5" y="162.7" width="9" height="25.5" fill="#188a3e"/>
|
||||
<line x1="479.0" y1="129.9" x2="479.0" y2="166.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="474.5" y="132.9" width="9" height="29.8" fill="#188a3e"/>
|
||||
<line x1="494.0" y1="91.7" x2="494.0" y2="136.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="489.5" y="94.7" width="9" height="38.2" fill="#188a3e"/>
|
||||
<line x1="509.0" y1="56.0" x2="509.0" y2="98.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="504.5" y="60.7" width="9" height="34.0" fill="#188a3e"/>
|
||||
<line x1="24" y1="577.4" x2="626" y2="577.4" stroke="#888"/>
|
||||
<rect x="39.5" y="541.6" width="9" height="35.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="54.5" y="539.9" width="9" height="37.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="69.5" y="542.4" width="9" height="35.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="84.5" y="538.2" width="9" height="39.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="99.5" y="540.7" width="9" height="36.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="114.5" y="539.0" width="9" height="38.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="129.5" y="543.3" width="9" height="34.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="144.5" y="539.9" width="9" height="37.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="159.5" y="537.3" width="9" height="40.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="174.5" y="540.7" width="9" height="36.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="189.5" y="543.3" width="9" height="34.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="204.5" y="541.6" width="9" height="35.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="219.5" y="545.0" width="9" height="32.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="234.5" y="542.4" width="9" height="35.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="249.5" y="533.0" width="9" height="44.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="264.5" y="529.6" width="9" height="47.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="279.5" y="534.7" width="9" height="42.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="294.5" y="539.0" width="9" height="38.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="309.5" y="541.6" width="9" height="35.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="324.5" y="544.1" width="9" height="33.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="339.5" y="551.8" width="9" height="25.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="354.5" y="538.2" width="9" height="39.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="369.5" y="536.4" width="9" height="41.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="384.5" y="534.7" width="9" height="42.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="399.5" y="533.0" width="9" height="44.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="414.5" y="531.3" width="9" height="46.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="429.5" y="527.9" width="9" height="49.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="444.5" y="524.5" width="9" height="52.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="459.5" y="521.1" width="9" height="56.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="474.5" y="517.7" width="9" height="59.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="489.5" y="512.5" width="9" height="64.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="504.5" y="507.4" width="9" height="70.0" fill="#188a3e" opacity="0.55"/>
|
||||
<text x="24" y="501.4" fill="#555">volum</text>
|
||||
<text x="32.0" y="78.2" fill="#777" text-anchor="start" style="font-weight:bold">downtrend weekly</text>
|
||||
<text x="344.0" y="325.5" fill="#00a0aa" text-anchor="middle" style="font-weight:bold">buy doji close 373.30 (RVOL 0.61)</text>
|
||||
<text x="359.0" y="267.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">intrare 374.80</text>
|
||||
<text x="434.0" y="184.2" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">TP1 383.74 = pivot</text>
|
||||
<text x="509.0" y="24.0" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">TP2 402.00</text>
|
||||
<text x="24" y="607" fill="#555">Ale cursului: close 373.30, suport 355.48, pivot 383.74, RVOL 0.61. Intrarea 374.80, SL</text>
|
||||
<text x="24" y="624" fill="#555">352.00 si TP2 402.00 sunt estimari din 04_MODUL_3/01; structura barelor dintre niveluri e</text>
|
||||
<text x="24" y="641" fill="#555">construita, la scara.</text>
|
||||
</svg>
|
||||
<svg viewBox="0 0 836 803" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<text x="24" y="104" fill="#333" style="font-weight:bold">ULTA — daily: ce citește selecția și unde se oprește</text>
|
||||
<rect x="188.3" y="146.0" width="184.0" height="317.7" fill="#c00" fill-opacity="0.08" stroke="#c00" stroke-width="1"/>
|
||||
<text x="188.3" y="141.0" fill="#c00" style="font-weight:bold">1. downtrend — de asta apare în scaner</text>
|
||||
<rect x="368.3" y="334.3" width="139.0" height="176.9" fill="#1a5fb4" fill-opacity="0.08" stroke="#1a5fb4" stroke-width="1"/>
|
||||
<line x1="24" y1="506.1" x2="822" y2="506.1" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="500.1" fill="#1a5fb4">suport monthly 355.48</text>
|
||||
<line x1="24" y1="265.9" x2="822" y2="265.9" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="808" y="259.9" fill="#1a5fb4" text-anchor="end">pivot monthly 383.74</text>
|
||||
<polyline points="482.8,365.9 497.8,375.2 512.8,382.1 527.8,387.0 542.8,389.8 557.8,390.5 572.8,389.2 587.8,385.5 602.8,379.6 617.8,371.3 632.8,360.3 647.8,346.1 662.8,329.2" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="669" y="323" fill="#b06000">SMA-20</text>
|
||||
<line x1="197.8" y1="154.0" x2="197.8" y2="174.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="193.3" y="157.4" width="9" height="12.8" fill="#c00"/>
|
||||
<line x1="212.8" y1="167.2" x2="212.8" y2="200.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="208.3" y="170.1" width="9" height="27.2" fill="#c00"/>
|
||||
<line x1="227.8" y1="194.4" x2="227.8" y2="227.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="223.3" y="197.3" width="9" height="27.2" fill="#c00"/>
|
||||
<line x1="242.8" y1="221.6" x2="242.8" y2="256.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="238.3" y="224.5" width="9" height="28.9" fill="#c00"/>
|
||||
<line x1="257.8" y1="250.5" x2="257.8" y2="284.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="253.3" y="253.4" width="9" height="27.2" fill="#c00"/>
|
||||
<line x1="272.8" y1="277.7" x2="272.8" y2="310.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="268.3" y="280.6" width="9" height="26.4" fill="#c00"/>
|
||||
<line x1="287.8" y1="304.0" x2="287.8" y2="337.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="283.3" y="307.0" width="9" height="27.2" fill="#c00"/>
|
||||
<line x1="302.8" y1="331.2" x2="302.8" y2="362.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="298.3" y="334.2" width="9" height="24.6" fill="#c00"/>
|
||||
<line x1="317.8" y1="355.9" x2="317.8" y2="386.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="313.3" y="358.8" width="9" height="24.7" fill="#c00"/>
|
||||
<line x1="332.8" y1="380.5" x2="332.8" y2="411.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="328.3" y="383.5" width="9" height="24.6" fill="#c00"/>
|
||||
<line x1="347.8" y1="405.2" x2="347.8" y2="435.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="343.3" y="408.1" width="9" height="23.8" fill="#c00"/>
|
||||
<line x1="362.8" y1="429.0" x2="362.8" y2="455.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="358.3" y="431.9" width="9" height="20.4" fill="#c00"/>
|
||||
<line x1="377.8" y1="437.5" x2="377.8" y2="455.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="373.3" y="440.4" width="9" height="11.9" fill="#188a3e"/>
|
||||
<line x1="392.8" y1="437.5" x2="392.8" y2="462.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="388.3" y="440.4" width="9" height="18.7" fill="#c00"/>
|
||||
<line x1="407.8" y1="456.2" x2="407.8" y2="483.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="403.3" y="459.1" width="9" height="21.2" fill="#c00"/>
|
||||
<line x1="422.8" y1="477.8" x2="422.8" y2="506.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="418.3" y="480.4" width="9" height="19.6" fill="#c00"/>
|
||||
<line x1="437.8" y1="464.2" x2="437.8" y2="502.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="433.3" y="467.6" width="9" height="32.3" fill="#188a3e"/>
|
||||
<line x1="452.8" y1="422.2" x2="452.8" y2="471.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="448.3" y="425.1" width="9" height="42.5" fill="#188a3e"/>
|
||||
<line x1="467.8" y1="383.9" x2="467.8" y2="428.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="463.3" y="386.9" width="9" height="38.2" fill="#188a3e"/>
|
||||
<line x1="482.8" y1="354.2" x2="482.8" y2="390.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="478.3" y="357.1" width="9" height="29.8" fill="#188a3e"/>
|
||||
<line x1="497.8" y1="342.3" x2="497.8" y2="369.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="493.3" y="354.6" width="9" height="2.6" fill="#188a3e"/>
|
||||
<line x1="512.8" y1="332.1" x2="512.8" y2="358.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="508.3" y="335.0" width="9" height="19.6" fill="#bbb"/>
|
||||
<line x1="527.8" y1="320.2" x2="527.8" y2="338.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="523.3" y="323.1" width="9" height="11.9" fill="#bbb"/>
|
||||
<line x1="542.8" y1="307.4" x2="542.8" y2="326.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="538.3" y="310.4" width="9" height="12.8" fill="#bbb"/>
|
||||
<line x1="557.8" y1="291.3" x2="557.8" y2="313.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="553.3" y="294.2" width="9" height="16.1" fill="#bbb"/>
|
||||
<line x1="572.8" y1="277.7" x2="572.8" y2="297.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="568.3" y="280.6" width="9" height="13.6" fill="#bbb"/>
|
||||
<line x1="587.8" y1="256.4" x2="587.8" y2="284.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="583.3" y="259.4" width="9" height="21.2" fill="#bbb"/>
|
||||
<line x1="602.8" y1="239.4" x2="602.8" y2="262.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="598.3" y="242.4" width="9" height="17.0" fill="#bbb"/>
|
||||
<line x1="617.8" y1="213.9" x2="617.8" y2="245.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="613.3" y="216.9" width="9" height="25.5" fill="#bbb"/>
|
||||
<line x1="632.8" y1="184.2" x2="632.8" y2="220.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="628.3" y="187.1" width="9" height="29.8" fill="#bbb"/>
|
||||
<line x1="647.8" y1="145.9" x2="647.8" y2="190.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="643.3" y="148.9" width="9" height="38.2" fill="#bbb"/>
|
||||
<line x1="662.8" y1="111.9" x2="662.8" y2="152.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="658.3" y="114.9" width="9" height="34.0" fill="#bbb"/>
|
||||
<line x1="24" y1="703.1" x2="822" y2="703.1" stroke="#888"/>
|
||||
<rect x="193.3" y="667.2" width="9" height="35.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="208.3" y="665.5" width="9" height="37.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="223.3" y="668.1" width="9" height="35.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="238.3" y="663.8" width="9" height="39.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="253.3" y="666.4" width="9" height="36.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="268.3" y="664.7" width="9" height="38.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="283.3" y="668.9" width="9" height="34.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="298.3" y="665.5" width="9" height="37.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="313.3" y="662.9" width="9" height="40.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="328.3" y="666.4" width="9" height="36.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="343.3" y="668.9" width="9" height="34.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="358.3" y="667.2" width="9" height="35.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="373.3" y="670.6" width="9" height="32.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="388.3" y="668.1" width="9" height="35.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="403.3" y="658.7" width="9" height="44.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="418.3" y="655.3" width="9" height="47.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="433.3" y="660.4" width="9" height="42.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="448.3" y="664.7" width="9" height="38.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="463.3" y="667.2" width="9" height="35.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="478.3" y="669.8" width="9" height="33.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="493.3" y="677.5" width="9" height="25.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="508.3" y="663.8" width="9" height="39.3" fill="#bbb" opacity="0.55"/>
|
||||
<rect x="523.3" y="662.1" width="9" height="41.0" fill="#bbb" opacity="0.55"/>
|
||||
<rect x="538.3" y="660.4" width="9" height="42.7" fill="#bbb" opacity="0.55"/>
|
||||
<rect x="553.3" y="658.7" width="9" height="44.4" fill="#bbb" opacity="0.55"/>
|
||||
<rect x="568.3" y="657.0" width="9" height="46.1" fill="#bbb" opacity="0.55"/>
|
||||
<rect x="583.3" y="653.6" width="9" height="49.5" fill="#bbb" opacity="0.55"/>
|
||||
<rect x="598.3" y="650.1" width="9" height="52.9" fill="#bbb" opacity="0.55"/>
|
||||
<rect x="613.3" y="646.7" width="9" height="56.3" fill="#bbb" opacity="0.55"/>
|
||||
<rect x="628.3" y="643.3" width="9" height="59.8" fill="#bbb" opacity="0.55"/>
|
||||
<rect x="643.3" y="638.2" width="9" height="64.9" fill="#bbb" opacity="0.55"/>
|
||||
<rect x="658.3" y="633.1" width="9" height="70.0" fill="#bbb" opacity="0.55"/>
|
||||
<text x="24" y="627.1" fill="#555">volum</text>
|
||||
<line x1="392.8" y1="570.1" x2="419.2" y2="517.2" stroke="#1a5fb4" stroke-width="1.8"/>
|
||||
<polygon points="422.8,510.1 422.8,519.0 415.6,515.4" fill="#1a5fb4"/>
|
||||
<text x="392.8" y="584.1" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">2. suportul monthly 355.48 a mai întors prețul o dată:</text>
|
||||
<text x="392.8" y="598.1" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">acolo stau ordine de cumpărare, deci coborârea are unde să se oprească</text>
|
||||
<line x1="247.8" y1="80.0" x2="492.2" y2="332.5" stroke="#00a0aa" stroke-width="1.8"/>
|
||||
<polygon points="497.8,338.3 489.4,335.3 495.1,329.7" fill="#00a0aa"/>
|
||||
<text x="247.8" y="47.0" fill="#00a0aa" text-anchor="middle" style="font-weight:bold">3. buy doji, close 373.30 — aici se oprește selecția</text>
|
||||
<text x="247.8" y="61.0" fill="#00a0aa" text-anchor="middle" style="font-weight:bold">5.01 % peste suport, 2.72 % sub pivot: trece proximitatea față de pivot</text>
|
||||
<text x="247.8" y="75.0" fill="#00a0aa" text-anchor="middle" style="font-weight:bold">volumul zilei = 0.61 din medie (RVOL 0.61), sub pragul de 1.00: minus, nu veto</text>
|
||||
<line x1="657.3" y1="202.4" x2="617.3" y2="237.2" stroke="#777" stroke-width="1.8"/>
|
||||
<polygon points="611.3,242.4 614.7,234.1 620.0,240.2" fill="#777"/>
|
||||
<text x="661.3" y="199.4" fill="#777" text-anchor="start" style="font-weight:bold">trigger, stop și țintă sunt</text>
|
||||
<text x="661.3" y="213.4" fill="#777" text-anchor="start" style="font-weight:bold">ale capitolului Buy Doji</text>
|
||||
<text x="24" y="733" fill="#555">Ale cursului: close 373.30, suport monthly 355.48, pivot monthly 383.74, RVOL 0.61.</text>
|
||||
<text x="24" y="750" fill="#555">Procentele sunt calculate din ele. Structura barelor e construită, la scară. Intrarea,</text>
|
||||
<text x="24" y="767" fill="#555">stopul și ținta nu apar pe desen: nu aparțin selecției.</text>
|
||||
<line x1="505.3" y1="116.0" x2="505.3" y2="522.1" stroke="#444" stroke-width="1.5" stroke-dasharray="6 4"/><text x="499.3" y="536.1" fill="#444" text-anchor="end" style="font-weight:bold">aici se termină selecția</text><text x="511.3" y="536.1" fill="#999">aici începe capitolul 1</text></svg>
|
||||
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 11 KiB |
@@ -32,7 +32,7 @@ Rulare: .venv/bin/python gen/strategii/selectia_cadrane.py
|
||||
import html
|
||||
from pathlib import Path
|
||||
|
||||
W, H = 700, 720
|
||||
W, H = 700, 812
|
||||
|
||||
BLACK = "#000000"
|
||||
GRAY = "#777777"
|
||||
@@ -46,7 +46,7 @@ RED_BG = "#fdeeee"
|
||||
|
||||
# ---------------------------------------------------------------- geometrie
|
||||
PLOT_X0, PLOT_X1 = 130.0, 570.0
|
||||
PLOT_Y0, PLOT_Y1 = 134.0, 414.0
|
||||
PLOT_Y0, PLOT_Y1 = 134.0, 502.0
|
||||
CX = (PLOT_X0 + PLOT_X1) / 2.0 # 350
|
||||
CY = (PLOT_Y0 + PLOT_Y1) / 2.0 # 266
|
||||
|
||||
@@ -61,7 +61,7 @@ Q2 = {"x": CX + GUT / 2, "y": CY + GUT / 2} # sub 0, peste MA
|
||||
for _q in (Q1, Q2, Q3, Q4):
|
||||
_q["w"], _q["h"] = CW, CH
|
||||
|
||||
BAND = {"x": 40.0, "y": 460.0, "w": 620.0, "h": 196.0}
|
||||
BAND = {"x": 40.0, "y": 556.0, "w": 620.0, "h": 196.0}
|
||||
|
||||
# ---------------------------------------------------------------- collect
|
||||
TEXTS = [] # (x, y, s, size, weight, fill, anchor)
|
||||
@@ -97,6 +97,39 @@ def line(x1, y1, x2, y2, stroke=GRAY, width=1.0, dash=None):
|
||||
f'stroke="{stroke}" stroke-width="{width}"{d}/>')
|
||||
|
||||
|
||||
def ma4(vals):
|
||||
"""Media mobilă pe 4, ca în indicatorul cursului: histogramă + MA peste ea."""
|
||||
return [sum(vals[max(0, i - 3):i + 1]) / len(vals[max(0, i - 3):i + 1])
|
||||
for i in range(len(vals))]
|
||||
|
||||
|
||||
def sketch(q, dy, vals, color):
|
||||
"""Mini-histogramă RS cu linia de 0 și media mobilă peste ea, în celula q.
|
||||
|
||||
Ultima bară e cea care decide cadranul, așa că e desenată plină, iar
|
||||
poziția ei față de 0 și față de MA e verificată prin assert de mai jos.
|
||||
"""
|
||||
w, h = 158.0, 46.0
|
||||
x0 = q["x"] + (q["w"] - w) / 2.0
|
||||
y0 = q["y"] + dy
|
||||
yz = y0 + h / 2.0 # linia de 0, la mijloc
|
||||
unit = (h / 2.0 - 3) / max(abs(v) for v in vals)
|
||||
bw = w / (len(vals) * 1.6)
|
||||
out = [f'<rect x="{x0:.1f}" y="{y0:.1f}" width="{w:.1f}" height="{h:.1f}" '
|
||||
f'fill="#ffffff" stroke="{GRAY}" stroke-width="0.8"/>',
|
||||
line(x0, yz, x0 + w, yz, BLACK, 1.0)]
|
||||
xs = [x0 + w * (i + 0.5) / len(vals) for i in range(len(vals))]
|
||||
for i, v in enumerate(vals):
|
||||
top = yz - v * unit if v > 0 else yz
|
||||
out.append(f'<rect x="{xs[i] - bw / 2:.1f}" y="{top:.1f}" width="{bw:.1f}" '
|
||||
f'height="{abs(v) * unit:.1f}" fill="{color}" '
|
||||
f'fill-opacity="{1.0 if i == len(vals) - 1 else 0.35}"/>')
|
||||
pts = " ".join(f"{xs[i]:.1f},{yz - m * unit:.1f}" for i, m in enumerate(ma4(vals)))
|
||||
out.append(f'<polyline points="{pts}" fill="none" stroke="{ORANGE}" '
|
||||
f'stroke-width="1.6" stroke-dasharray="3 2"/>')
|
||||
return out
|
||||
|
||||
|
||||
def cell_text(q, dy, s, *a, **k):
|
||||
add(q["x"] + q["w"] / 2.0, q["y"] + dy, s, *a, **k)
|
||||
|
||||
@@ -134,67 +167,76 @@ p.append(rect(Q4["x"], Q4["y"], CW, CH, "Q4", fill=RED_BG, stroke=RED, sw=1.6,
|
||||
dash="6 4"))
|
||||
p.append(rect(Q2["x"], Q2["y"], CW, CH, "Q2", fill=GREEN_BG, stroke=GREEN, sw=1.6))
|
||||
|
||||
# seriile mini-histogramelor: ultima bară decide cadranul
|
||||
H3 = [6, 6, 5, 5, 4, 3, 3, 2, 1] # peste 0, dar sub MA
|
||||
H1 = [-1, 0, 1, 2, 2, 3, 4, 5, 6] # peste 0 și peste MA
|
||||
H4 = [1, 0, -1, -2, -2, -3, -4, -5, -6] # sub 0 și sub MA
|
||||
H2 = [-6, -6, -5, -5, -4, -3, -3, -2, -1] # sub 0, dar peste MA
|
||||
|
||||
# Cadran 3 — top-left: peste 0, sub MA -> SHORT
|
||||
cell_text(Q3, 30, "Cadran 3", 16, "bold", BLACK)
|
||||
cell_text(Q3, 52, "înrăutățire", 14, "bold", RED)
|
||||
cell_text(Q3, 80, "peste 0, dar sub MA", 13, "normal", BLACK)
|
||||
cell_text(Q3, 112, "SHORT", 16, "bold", RED)
|
||||
cell_text(Q3, 26, "Cadran 3", 16, "bold", BLACK)
|
||||
cell_text(Q3, 48, "înrăutățire", 14, "bold", RED)
|
||||
cell_text(Q3, 70, "peste 0, dar sub MA", 13, "normal", BLACK)
|
||||
cell_text(Q3, 94, "SHORT", 16, "bold", RED)
|
||||
p += sketch(Q3, 106, H3, RED)
|
||||
|
||||
# Cadran 1 — top-right: peste 0, peste MA -> LONG
|
||||
cell_text(Q1, 30, "Cadran 1", 16, "bold", BLACK)
|
||||
cell_text(Q1, 52, "supraperformanță", 14, "bold", GREEN)
|
||||
cell_text(Q1, 80, "peste 0 și peste MA", 13, "normal", BLACK)
|
||||
cell_text(Q1, 112, "LONG", 16, "bold", GREEN)
|
||||
cell_text(Q1, 26, "Cadran 1", 16, "bold", BLACK)
|
||||
cell_text(Q1, 48, "supraperformanță", 14, "bold", GREEN)
|
||||
cell_text(Q1, 70, "peste 0 și peste MA", 13, "normal", BLACK)
|
||||
cell_text(Q1, 94, "LONG", 16, "bold", GREEN)
|
||||
p += sketch(Q1, 106, H1, GREEN)
|
||||
|
||||
# Cadran 4 — bottom-left: sub 0, sub MA -> SHORT / stai pe margine
|
||||
cell_text(Q4, 26, "Cadran 4", 16, "bold", BLACK)
|
||||
cell_text(Q4, 48, "subperformanță", 14, "bold", RED)
|
||||
cell_text(Q4, 74, "sub 0 și sub MA", 13, "normal", BLACK)
|
||||
cell_text(Q4, 100, "SHORT", 15, "bold", RED)
|
||||
cell_text(Q4, 122, "stai pe margine", 13, "normal", RED)
|
||||
cell_text(Q4, 24, "Cadran 4", 16, "bold", BLACK)
|
||||
cell_text(Q4, 46, "subperformanță", 14, "bold", RED)
|
||||
cell_text(Q4, 68, "sub 0 și sub MA", 13, "normal", BLACK)
|
||||
cell_text(Q4, 90, "SHORT — stai pe margine", 14, "bold", RED)
|
||||
p += sketch(Q4, 102, H4, RED)
|
||||
|
||||
# Cadran 2 — bottom-right: sub 0, peste MA -> LONG (zona de cumpărat)
|
||||
cell_text(Q2, 26, "Cadran 2", 16, "bold", BLACK)
|
||||
cell_text(Q2, 48, "îmbunătățire", 14, "bold", GREEN)
|
||||
cell_text(Q2, 74, "sub 0, dar peste MA", 13, "normal", BLACK)
|
||||
cell_text(Q2, 100, "LONG", 15, "bold", GREEN)
|
||||
cell_text(Q2, 122, "zona de cumpărat", 13, "normal", GREEN)
|
||||
cell_text(Q2, 24, "Cadran 2", 16, "bold", BLACK)
|
||||
cell_text(Q2, 46, "îmbunătățire", 14, "bold", GREEN)
|
||||
cell_text(Q2, 68, "sub 0, dar peste MA", 13, "normal", BLACK)
|
||||
cell_text(Q2, 90, "LONG — zona de cumpărat", 14, "bold", GREEN)
|
||||
p += sketch(Q2, 102, H2, GREEN)
|
||||
|
||||
# fiecare schiță trebuie să arate exact cadranul pe care îl ilustrează
|
||||
for _nume, _h, _peste0, _pesteMA in (("3", H3, True, False), ("1", H1, True, True),
|
||||
("4", H4, False, False), ("2", H2, False, True)):
|
||||
_last, _ma = _h[-1], ma4(_h)[-1]
|
||||
assert (_last > 0) == _peste0, f"schița cadranului {_nume}: ultima bară față de 0"
|
||||
assert (_last > _ma) == _pesteMA, f"schița cadranului {_nume}: ultima bară față de MA"
|
||||
|
||||
# ---- concluzia de sub matrice
|
||||
add(W / 2, 442, "Long = cadranele 1-2 · Short = cadranele 3-4",
|
||||
add(W / 2, 530, "Long = cadranele 1-2 · Short = cadranele 3-4",
|
||||
14, "bold", BLACK)
|
||||
add(W / 2, 548, "în fiecare cadran: histograma RS (barele), linia de 0 și media mobilă (punctat portocaliu)",
|
||||
13, "normal", GRAY)
|
||||
|
||||
# ---- banda de avertisment (cadranul 4)
|
||||
p.append(rect(BAND["x"], BAND["y"], BAND["w"], BAND["h"], "band",
|
||||
fill="#fdf0e0", stroke=ORANGE, sw=1.6))
|
||||
add(BAND["x"] + 20, 488, "Avertisment — cadranul 4 nu se tranzacționează pe orb",
|
||||
add(BAND["x"] + 20, 584, "Avertisment — cadranul 4 nu se tranzacționează pe orb",
|
||||
15, "bold", RED, "start")
|
||||
add(BAND["x"] + 20, 516,
|
||||
add(BAND["x"] + 20, 612,
|
||||
"„Cadranul 4 nu se tranzacționează pe orb: aștepți trecerea în 2 sau 1,",
|
||||
13, "normal", BLACK, "start")
|
||||
add(BAND["x"] + 20, 536, "ori un MP4-1 / MBT-10 long ca semn de schimbare.”",
|
||||
add(BAND["x"] + 20, 632, "ori un MP4-1 / MBT-10 long ca semn de schimbare.”",
|
||||
13, "normal", BLACK, "start")
|
||||
add(BAND["x"] + 20, 566,
|
||||
add(BAND["x"] + 20, 662,
|
||||
"„Un setup de bottom cu RS fără îmbunătățire are șanse mai mici.”",
|
||||
13, "bold", BLACK, "start")
|
||||
add(BAND["x"] + 20, 596,
|
||||
add(BAND["x"] + 20, 692,
|
||||
"Notă: transcrierea descrierii cadranului 4 are o eroare (îl descrie ca pe",
|
||||
13, "normal", GRAY, "start")
|
||||
add(BAND["x"] + 20, 616,
|
||||
"cadranul 3); definiția de mai sus e completarea sumarului —",
|
||||
add(BAND["x"] + 20, 712,
|
||||
"cadranul 3, care e altceva). Definiția din tabloul de mai sus e cea",
|
||||
13, "normal", GRAY, "start")
|
||||
add(BAND["x"] + 20, 636,
|
||||
"03_MODUL_2/06_indicatorul_de_performanta.md:41-48.",
|
||||
add(BAND["x"] + 20, 732,
|
||||
"corectă și e singura folosită în tot capitolul.",
|
||||
13, "normal", GRAY, "start")
|
||||
|
||||
# ---- surse
|
||||
add(W / 2, 686,
|
||||
"Surse: 08_ANALIZA_ZILNICA/11_selectia_simbolului.md:486-499, :501-508;",
|
||||
13, "normal", GRAY)
|
||||
add(W / 2, 704,
|
||||
"03_MODUL_2/06_indicatorul_de_performanta.md:31-39.",
|
||||
13, "normal", GRAY)
|
||||
|
||||
# =============================================================== EMITERE
|
||||
head = (f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" '
|
||||
f'width="{W}" height="{H}" font-family="system-ui, sans-serif" role="img" '
|
||||
@@ -244,8 +286,8 @@ assert any(t[2] == "sub 0, dar peste MA" for t in TEXTS)
|
||||
assert any(t[2] == "peste 0, dar sub MA" for t in TEXTS)
|
||||
assert any(t[2] == "sub 0 și sub MA" for t in TEXTS)
|
||||
# direcția: LONG pe 1-2, SHORT pe 3-4
|
||||
assert svg.count(">LONG</text>") == 2, "LONG trebuie să apară exact de 2 ori"
|
||||
assert svg.count(">SHORT</text>") == 2, "SHORT trebuie să apară exact de 2 ori"
|
||||
assert sum(t[2].startswith("LONG") for t in TEXTS) == 2, "LONG trebuie să apară de 2 ori"
|
||||
assert sum(t[2].startswith("SHORT") for t in TEXTS) == 2, "SHORT trebuie să apară de 2 ori"
|
||||
assert "stai pe margine" in svg, "lipsește «stai pe margine» din cadranul 4"
|
||||
assert "zona de cumpărat" in svg, "lipsește «zona de cumpărat» din cadranul 2"
|
||||
assert "Long = cadranele 1-2" in svg and "Short = cadranele 3-4" in svg
|
||||
@@ -260,10 +302,7 @@ for req in ("Relative strength — cele 4 cadrane",
|
||||
"MP4-1 / MBT-10 long",
|
||||
"Un setup de bottom cu RS fără îmbunătățire are șanse mai mici",
|
||||
"transcrierea descrierii cadranului 4 are o eroare",
|
||||
"e completarea sumarului",
|
||||
"03_MODUL_2/06_indicatorul_de_performanta.md:41-48",
|
||||
"11_selectia_simbolului.md:486-499",
|
||||
"06_indicatorul_de_performanta.md:31-39"):
|
||||
"histograma RS (barele), linia de 0 și media mobilă"):
|
||||
assert req in svg, f"lipsește din desen: {req!r}"
|
||||
|
||||
# 5. etichetele cadranului 2 și 3 care se pot încurca: verifică asocierea
|
||||
|
||||
@@ -1,47 +1,92 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 720" width="700" height="720" font-family="system-ui, sans-serif" role="img" aria-label="Matricea 2x2 a relative strength: cadranele 1 si 2 sunt pentru long, cadranele 3 si 4 pentru short; cadranul 4 nu se tranzactioneaza pe orb">
|
||||
<rect x="0" y="0" width="700" height="720" fill="#ffffff"/>
|
||||
<rect x="130.0" y="134.0" width="440.0" height="280.0" fill="#ffffff" stroke="#777777" stroke-width="1.0"/>
|
||||
<line x1="130.0" y1="274.0" x2="570.0" y2="274.0" stroke="#777777" stroke-width="1.0" stroke-dasharray="4 4"/>
|
||||
<line x1="350.0" y1="134.0" x2="350.0" y2="414.0" stroke="#777777" stroke-width="1.0" stroke-dasharray="4 4"/>
|
||||
<rect x="130.0" y="134.0" width="218.0" height="138.0" fill="#fdeeee" stroke="#c00" stroke-width="1.6"/>
|
||||
<rect x="352.0" y="134.0" width="218.0" height="138.0" fill="#eef7f0" stroke="#188a3e" stroke-width="1.6"/>
|
||||
<rect x="130.0" y="276.0" width="218.0" height="138.0" fill="#fdeeee" stroke="#c00" stroke-width="1.6" stroke-dasharray="6 4"/>
|
||||
<rect x="352.0" y="276.0" width="218.0" height="138.0" fill="#eef7f0" stroke="#188a3e" stroke-width="1.6"/>
|
||||
<rect x="40.0" y="460.0" width="620.0" height="196.0" fill="#fdf0e0" stroke="#b06000" stroke-width="1.6"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 812" width="700" height="812" font-family="system-ui, sans-serif" role="img" aria-label="Matricea 2x2 a relative strength: cadranele 1 si 2 sunt pentru long, cadranele 3 si 4 pentru short; cadranul 4 nu se tranzactioneaza pe orb">
|
||||
<rect x="0" y="0" width="700" height="812" fill="#ffffff"/>
|
||||
<rect x="130.0" y="134.0" width="440.0" height="368.0" fill="#ffffff" stroke="#777777" stroke-width="1.0"/>
|
||||
<line x1="130.0" y1="318.0" x2="570.0" y2="318.0" stroke="#777777" stroke-width="1.0" stroke-dasharray="4 4"/>
|
||||
<line x1="350.0" y1="134.0" x2="350.0" y2="502.0" stroke="#777777" stroke-width="1.0" stroke-dasharray="4 4"/>
|
||||
<rect x="130.0" y="134.0" width="218.0" height="182.0" fill="#fdeeee" stroke="#c00" stroke-width="1.6"/>
|
||||
<rect x="352.0" y="134.0" width="218.0" height="182.0" fill="#eef7f0" stroke="#188a3e" stroke-width="1.6"/>
|
||||
<rect x="130.0" y="320.0" width="218.0" height="182.0" fill="#fdeeee" stroke="#c00" stroke-width="1.6" stroke-dasharray="6 4"/>
|
||||
<rect x="352.0" y="320.0" width="218.0" height="182.0" fill="#eef7f0" stroke="#188a3e" stroke-width="1.6"/>
|
||||
<rect x="160.0" y="240.0" width="158.0" height="46.0" fill="#ffffff" stroke="#777777" stroke-width="0.8"/>
|
||||
<line x1="160.0" y1="263.0" x2="318.0" y2="263.0" stroke="#000000" stroke-width="1.0"/>
|
||||
<rect x="163.3" y="243.0" width="11.0" height="20.0" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="180.8" y="243.0" width="11.0" height="20.0" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="198.4" y="246.3" width="11.0" height="16.7" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="216.0" y="246.3" width="11.0" height="16.7" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="233.5" y="249.7" width="11.0" height="13.3" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="251.1" y="253.0" width="11.0" height="10.0" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="268.6" y="253.0" width="11.0" height="10.0" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="286.2" y="256.3" width="11.0" height="6.7" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="303.7" y="259.7" width="11.0" height="3.3" fill="#c00" fill-opacity="1.0"/>
|
||||
<polyline points="168.8,243.0 186.3,243.0 203.9,244.1 221.4,244.7 239.0,246.3 256.6,248.8 274.1,250.5 291.7,253.0 309.2,255.5" fill="none" stroke="#b06000" stroke-width="1.6" stroke-dasharray="3 2"/>
|
||||
<rect x="382.0" y="240.0" width="158.0" height="46.0" fill="#ffffff" stroke="#777777" stroke-width="0.8"/>
|
||||
<line x1="382.0" y1="263.0" x2="540.0" y2="263.0" stroke="#000000" stroke-width="1.0"/>
|
||||
<rect x="385.3" y="263.0" width="11.0" height="3.3" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="402.8" y="263.0" width="11.0" height="0.0" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="420.4" y="259.7" width="11.0" height="3.3" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="438.0" y="256.3" width="11.0" height="6.7" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="455.5" y="256.3" width="11.0" height="6.7" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="473.1" y="253.0" width="11.0" height="10.0" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="490.6" y="249.7" width="11.0" height="13.3" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="508.2" y="246.3" width="11.0" height="16.7" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="525.7" y="243.0" width="11.0" height="20.0" fill="#188a3e" fill-opacity="1.0"/>
|
||||
<polyline points="390.8,266.3 408.3,264.7 425.9,263.0 443.4,261.3 461.0,258.8 478.6,256.3 496.1,253.8 513.7,251.3 531.2,248.0" fill="none" stroke="#b06000" stroke-width="1.6" stroke-dasharray="3 2"/>
|
||||
<rect x="160.0" y="422.0" width="158.0" height="46.0" fill="#ffffff" stroke="#777777" stroke-width="0.8"/>
|
||||
<line x1="160.0" y1="445.0" x2="318.0" y2="445.0" stroke="#000000" stroke-width="1.0"/>
|
||||
<rect x="163.3" y="441.7" width="11.0" height="3.3" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="180.8" y="445.0" width="11.0" height="0.0" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="198.4" y="445.0" width="11.0" height="3.3" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="216.0" y="445.0" width="11.0" height="6.7" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="233.5" y="445.0" width="11.0" height="6.7" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="251.1" y="445.0" width="11.0" height="10.0" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="268.6" y="445.0" width="11.0" height="13.3" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="286.2" y="445.0" width="11.0" height="16.7" fill="#c00" fill-opacity="0.35"/>
|
||||
<rect x="303.7" y="445.0" width="11.0" height="20.0" fill="#c00" fill-opacity="1.0"/>
|
||||
<polyline points="168.8,441.7 186.3,443.3 203.9,445.0 221.4,446.7 239.0,449.2 256.6,451.7 274.1,454.2 291.7,456.7 309.2,460.0" fill="none" stroke="#b06000" stroke-width="1.6" stroke-dasharray="3 2"/>
|
||||
<rect x="382.0" y="422.0" width="158.0" height="46.0" fill="#ffffff" stroke="#777777" stroke-width="0.8"/>
|
||||
<line x1="382.0" y1="445.0" x2="540.0" y2="445.0" stroke="#000000" stroke-width="1.0"/>
|
||||
<rect x="385.3" y="445.0" width="11.0" height="20.0" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="402.8" y="445.0" width="11.0" height="20.0" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="420.4" y="445.0" width="11.0" height="16.7" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="438.0" y="445.0" width="11.0" height="16.7" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="455.5" y="445.0" width="11.0" height="13.3" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="473.1" y="445.0" width="11.0" height="10.0" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="490.6" y="445.0" width="11.0" height="10.0" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="508.2" y="445.0" width="11.0" height="6.7" fill="#188a3e" fill-opacity="0.35"/>
|
||||
<rect x="525.7" y="445.0" width="11.0" height="3.3" fill="#188a3e" fill-opacity="1.0"/>
|
||||
<polyline points="390.8,465.0 408.3,465.0 425.9,463.9 443.4,463.3 461.0,461.7 478.6,459.2 496.1,457.5 513.7,455.0 531.2,452.5" fill="none" stroke="#b06000" stroke-width="1.6" stroke-dasharray="3 2"/>
|
||||
<rect x="40.0" y="556.0" width="620.0" height="196.0" fill="#fdf0e0" stroke="#b06000" stroke-width="1.6"/>
|
||||
<text x="350.0" y="34.0" font-size="20" font-weight="bold" fill="#000000" text-anchor="middle">Relative strength — cele 4 cadrane</text>
|
||||
<text x="350.0" y="58.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">RS = cât de bine se mișcă simbolul față de benchmark (ex. SPY)</text>
|
||||
<text x="350.0" y="80.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">Axa verticală: histograma RS față de 0 (peste / sub 0)</text>
|
||||
<text x="350.0" y="98.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">Axa orizontală: histograma RS față de MA (peste / sub MA)</text>
|
||||
<text x="241.0" y="122.0" font-size="14" font-weight="bold" fill="#b06000" text-anchor="middle">sub MA</text>
|
||||
<text x="461.0" y="122.0" font-size="14" font-weight="bold" fill="#1a5fb4" text-anchor="middle">peste MA</text>
|
||||
<text x="122.0" y="203.0" font-size="14" font-weight="bold" fill="#188a3e" text-anchor="end">peste 0</text>
|
||||
<text x="122.0" y="345.0" font-size="14" font-weight="bold" fill="#c00" text-anchor="end">sub 0</text>
|
||||
<text x="239.0" y="164.0" font-size="16" font-weight="bold" fill="#000000" text-anchor="middle">Cadran 3</text>
|
||||
<text x="239.0" y="186.0" font-size="14" font-weight="bold" fill="#c00" text-anchor="middle">înrăutățire</text>
|
||||
<text x="239.0" y="214.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">peste 0, dar sub MA</text>
|
||||
<text x="239.0" y="246.0" font-size="16" font-weight="bold" fill="#c00" text-anchor="middle">SHORT</text>
|
||||
<text x="461.0" y="164.0" font-size="16" font-weight="bold" fill="#000000" text-anchor="middle">Cadran 1</text>
|
||||
<text x="461.0" y="186.0" font-size="14" font-weight="bold" fill="#188a3e" text-anchor="middle">supraperformanță</text>
|
||||
<text x="461.0" y="214.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">peste 0 și peste MA</text>
|
||||
<text x="461.0" y="246.0" font-size="16" font-weight="bold" fill="#188a3e" text-anchor="middle">LONG</text>
|
||||
<text x="239.0" y="302.0" font-size="16" font-weight="bold" fill="#000000" text-anchor="middle">Cadran 4</text>
|
||||
<text x="239.0" y="324.0" font-size="14" font-weight="bold" fill="#c00" text-anchor="middle">subperformanță</text>
|
||||
<text x="239.0" y="350.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">sub 0 și sub MA</text>
|
||||
<text x="239.0" y="376.0" font-size="15" font-weight="bold" fill="#c00" text-anchor="middle">SHORT</text>
|
||||
<text x="239.0" y="398.0" font-size="13" font-weight="normal" fill="#c00" text-anchor="middle">stai pe margine</text>
|
||||
<text x="461.0" y="302.0" font-size="16" font-weight="bold" fill="#000000" text-anchor="middle">Cadran 2</text>
|
||||
<text x="461.0" y="324.0" font-size="14" font-weight="bold" fill="#188a3e" text-anchor="middle">îmbunătățire</text>
|
||||
<text x="461.0" y="350.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">sub 0, dar peste MA</text>
|
||||
<text x="461.0" y="376.0" font-size="15" font-weight="bold" fill="#188a3e" text-anchor="middle">LONG</text>
|
||||
<text x="461.0" y="398.0" font-size="13" font-weight="normal" fill="#188a3e" text-anchor="middle">zona de cumpărat</text>
|
||||
<text x="350.0" y="442.0" font-size="14" font-weight="bold" fill="#000000" text-anchor="middle">Long = cadranele 1-2 · Short = cadranele 3-4</text>
|
||||
<text x="60.0" y="488.0" font-size="15" font-weight="bold" fill="#c00" text-anchor="start">Avertisment — cadranul 4 nu se tranzacționează pe orb</text>
|
||||
<text x="60.0" y="516.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">„Cadranul 4 nu se tranzacționează pe orb: aștepți trecerea în 2 sau 1,</text>
|
||||
<text x="60.0" y="536.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">ori un MP4-1 / MBT-10 long ca semn de schimbare.”</text>
|
||||
<text x="60.0" y="566.0" font-size="13" font-weight="bold" fill="#000000" text-anchor="start">„Un setup de bottom cu RS fără îmbunătățire are șanse mai mici.”</text>
|
||||
<text x="60.0" y="596.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Notă: transcrierea descrierii cadranului 4 are o eroare (îl descrie ca pe</text>
|
||||
<text x="60.0" y="616.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">cadranul 3); definiția de mai sus e completarea sumarului —</text>
|
||||
<text x="60.0" y="636.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">03_MODUL_2/06_indicatorul_de_performanta.md:41-48.</text>
|
||||
<text x="350.0" y="686.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">Surse: 08_ANALIZA_ZILNICA/11_selectia_simbolului.md:486-499, :501-508;</text>
|
||||
<text x="350.0" y="704.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">03_MODUL_2/06_indicatorul_de_performanta.md:31-39.</text>
|
||||
<text x="122.0" y="225.0" font-size="14" font-weight="bold" fill="#188a3e" text-anchor="end">peste 0</text>
|
||||
<text x="122.0" y="411.0" font-size="14" font-weight="bold" fill="#c00" text-anchor="end">sub 0</text>
|
||||
<text x="239.0" y="160.0" font-size="16" font-weight="bold" fill="#000000" text-anchor="middle">Cadran 3</text>
|
||||
<text x="239.0" y="182.0" font-size="14" font-weight="bold" fill="#c00" text-anchor="middle">înrăutățire</text>
|
||||
<text x="239.0" y="204.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">peste 0, dar sub MA</text>
|
||||
<text x="239.0" y="228.0" font-size="16" font-weight="bold" fill="#c00" text-anchor="middle">SHORT</text>
|
||||
<text x="461.0" y="160.0" font-size="16" font-weight="bold" fill="#000000" text-anchor="middle">Cadran 1</text>
|
||||
<text x="461.0" y="182.0" font-size="14" font-weight="bold" fill="#188a3e" text-anchor="middle">supraperformanță</text>
|
||||
<text x="461.0" y="204.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">peste 0 și peste MA</text>
|
||||
<text x="461.0" y="228.0" font-size="16" font-weight="bold" fill="#188a3e" text-anchor="middle">LONG</text>
|
||||
<text x="239.0" y="344.0" font-size="16" font-weight="bold" fill="#000000" text-anchor="middle">Cadran 4</text>
|
||||
<text x="239.0" y="366.0" font-size="14" font-weight="bold" fill="#c00" text-anchor="middle">subperformanță</text>
|
||||
<text x="239.0" y="388.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">sub 0 și sub MA</text>
|
||||
<text x="239.0" y="410.0" font-size="14" font-weight="bold" fill="#c00" text-anchor="middle">SHORT — stai pe margine</text>
|
||||
<text x="461.0" y="344.0" font-size="16" font-weight="bold" fill="#000000" text-anchor="middle">Cadran 2</text>
|
||||
<text x="461.0" y="366.0" font-size="14" font-weight="bold" fill="#188a3e" text-anchor="middle">îmbunătățire</text>
|
||||
<text x="461.0" y="388.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">sub 0, dar peste MA</text>
|
||||
<text x="461.0" y="410.0" font-size="14" font-weight="bold" fill="#188a3e" text-anchor="middle">LONG — zona de cumpărat</text>
|
||||
<text x="350.0" y="530.0" font-size="14" font-weight="bold" fill="#000000" text-anchor="middle">Long = cadranele 1-2 · Short = cadranele 3-4</text>
|
||||
<text x="350.0" y="548.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">în fiecare cadran: histograma RS (barele), linia de 0 și media mobilă (punctat portocaliu)</text>
|
||||
<text x="60.0" y="584.0" font-size="15" font-weight="bold" fill="#c00" text-anchor="start">Avertisment — cadranul 4 nu se tranzacționează pe orb</text>
|
||||
<text x="60.0" y="612.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">„Cadranul 4 nu se tranzacționează pe orb: aștepți trecerea în 2 sau 1,</text>
|
||||
<text x="60.0" y="632.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">ori un MP4-1 / MBT-10 long ca semn de schimbare.”</text>
|
||||
<text x="60.0" y="662.0" font-size="13" font-weight="bold" fill="#000000" text-anchor="start">„Un setup de bottom cu RS fără îmbunătățire are șanse mai mici.”</text>
|
||||
<text x="60.0" y="692.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Notă: transcrierea descrierii cadranului 4 are o eroare (îl descrie ca pe</text>
|
||||
<text x="60.0" y="712.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">cadranul 3, care e altceva). Definiția din tabloul de mai sus e cea</text>
|
||||
<text x="60.0" y="732.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">corectă și e singura folosită în tot capitolul.</text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 10 KiB |
@@ -15,7 +15,7 @@ import sys
|
||||
from pathlib import Path
|
||||
|
||||
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 Candle, Chart, Level, Arrow, Zone, MA, from_closes # noqa: E402
|
||||
|
||||
OUT = Path(__file__).resolve().parent / "selectia_exemplu.svg"
|
||||
|
||||
@@ -107,26 +107,33 @@ levels = [
|
||||
Level(72.00, "TP 72.00", GREEN, label_at="left"),
|
||||
]
|
||||
|
||||
marks = [
|
||||
Mark(10, "gap down, open 79.20", "#333", "above", dy=-16),
|
||||
Mark(12, "sell doji close 78.60", RED, "above", dy=-4),
|
||||
Mark(13, "intrare short 78.10", GREEN, "below", dy=26),
|
||||
Mark(10, "RVOL 200%", RED, "below", dy=12),
|
||||
zones = [
|
||||
Zone(10, 13, "ce l-a scos în față din cele 16 rezultate", RED, p_top=80.4),
|
||||
]
|
||||
|
||||
arrows = [
|
||||
Arrow(10, f"gap down: deschide la {cds[10].o:.2f}, mult sub\n"
|
||||
f"închiderea de ieri — vânzare, nu pauză",
|
||||
where="above", color=RED, dx=-160, dy=32),
|
||||
Arrow(12, "sell doji close 78.60: vânzătorii și cumpărătorii la egalitate,\nîncă nu e semnal",
|
||||
where="below", price=77.6, color="#333", dx=-120, dy=70),
|
||||
Arrow(13, "aici ar intra strategia de intrare, nu selecția:\nînchidere sub low-ul doji-ului",
|
||||
where="right", price=78.10, color=GREEN, dx=40, dy=110),
|
||||
]
|
||||
|
||||
title = "HIG — daily (Sell Doji + Bear Reversal, RVOL 200%)"
|
||||
caption = ("RVOL 200% si simbolul sunt reale (04_MODUL_3/01:196-199). Toate "
|
||||
"nivelurile de preț (79.20 / 78.60 / 78.10 / 82.00 / 72.00) sunt "
|
||||
"construite in sumarul 04_MODUL_3/01:293-296, nu date de curs; "
|
||||
"structura barelor e construita, la scara.")
|
||||
caption = ("Ale cursului: simbolul HIG, semnalul Sell Doji + Bear Reversal și RVOL-ul de 200 %, "
|
||||
"cel mai mare din cele 16 rezultate ale scanerului. Nivelurile de preț "
|
||||
"(79.20 / 78.60 / 78.10 / 82.00 / 72.00) și structura barelor sunt construite, la scară: "
|
||||
"cursul nu dă cifre pentru HIG.")
|
||||
|
||||
ch = Chart(
|
||||
candles=cds, levels=levels, marks=marks,
|
||||
candles=cds, levels=levels, zones=zones, arrows=arrows,
|
||||
mas=[MA(20, ORANGE, dash="4 3", text="SMA-20")],
|
||||
scale=16.0, gap=15, body_w=9, left=44, width=640, vol_h=70,
|
||||
vol_label="volum",
|
||||
title="", # titlul se injecteaza sus, ca sa nu se suprapuna
|
||||
caption=caption, # cu eticheta nivelului "rezistenta 84.50" (stanga)
|
||||
title=title,
|
||||
caption=caption,
|
||||
)
|
||||
svg = ch.render()
|
||||
|
||||
@@ -137,14 +144,28 @@ px_reward = ys[72.00] - ys[78.10]
|
||||
assert px_risc > 0 and px_reward > 0
|
||||
assert abs(px_risc / px_reward - risc / reward) < 1e-9, "SL/TP la scara gresita"
|
||||
|
||||
# ---------------------------------------------------------------- titlu injectat
|
||||
m_svg = re.search(r"<svg[^>]*>", svg)
|
||||
assert m_svg, "tag <svg> lipsa"
|
||||
svg = svg.replace(
|
||||
m_svg.group(0),
|
||||
m_svg.group(0) + f'\n <text x="24" y="16" fill="#333" style="font-weight:bold">{title}</text>',
|
||||
1,
|
||||
)
|
||||
# ---------------------------------------------------------------- RVOL, pe panoul de volum
|
||||
# RVOL e o afirmație despre volum, deci eticheta stă pe panoul de volum, nu în
|
||||
# cel de preț: linia întreruptă e media seriei, iar bara 10 e de două ori cât ea.
|
||||
m_vb = re.search(r'<line x1="24" y1="([\d.]+)" x2="[\d.]+" y2="[\d.]+" stroke="#888"/>', svg)
|
||||
assert m_vb, "nu gasesc linia de baza a panoului de volum"
|
||||
vol_base = float(m_vb.group(1))
|
||||
vmax = max(VOLS)
|
||||
y_media = vol_base - media_vol / vmax * 70.0 # vol_h = 70
|
||||
y_bara = vol_base - VOLS[10] / vmax * 70.0
|
||||
assert abs((vol_base - y_bara) / (vol_base - y_media) - 2.0) < 1e-9, \
|
||||
"bara de RVOL nu e de doua ori media, desenata"
|
||||
m_w = re.search(r'viewBox="0 0 (\d+) ', svg)
|
||||
assert m_w
|
||||
w_svg = int(m_w.group(1))
|
||||
vol_note = (f'<line x1="24" y1="{y_media:.1f}" x2="{w_svg - 14}" y2="{y_media:.1f}" '
|
||||
f'stroke="{GRAY}" stroke-width="1.2" stroke-dasharray="4 3"/>'
|
||||
f'<text x="{w_svg - 16}" y="{y_media - 4:.1f}" fill="{GRAY}" text-anchor="end">'
|
||||
f'media volumului pe serie</text>'
|
||||
f'<text x="92" y="{y_bara - 5:.1f}" fill="{RED}" style="font-weight:bold">'
|
||||
f'ziua gap-ului: de {VOLS[10] / media_vol:.0f} ori media (RVOL 200 %) — '
|
||||
f'se vinde dublu față de o zi normală</text>')
|
||||
svg = svg.replace(m_vb.group(0), m_vb.group(0) + vol_note, 1)
|
||||
|
||||
# ---------------------------------------------------------------- caption pe randuri
|
||||
def _wrap(text: str, max_chars: int) -> list[str]:
|
||||
|
||||
@@ -1,113 +1,124 @@
|
||||
<svg viewBox="0 0 640 433" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<text x="24" y="16" fill="#333" style="font-weight:bold">HIG — daily (Sell Doji + Bear Reversal, RVOL 200%)</text>
|
||||
<line x1="24" y1="34.0" x2="626" y2="34.0" stroke="#777" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="612" y="28.0" fill="#777" text-anchor="end">rezistenta 84.50</text>
|
||||
<line x1="24" y1="74.0" x2="626" y2="74.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="612" y="68.0" fill="#c00" text-anchor="end">SL 82.00</text>
|
||||
<line x1="24" y1="136.4" x2="626" y2="136.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="130.4" fill="#1a5fb4">intrare short 78.10</text>
|
||||
<line x1="24" y1="234.0" x2="626" y2="234.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="228.0" fill="#188a3e">TP 72.00</text>
|
||||
<polyline points="329.0,107.0 344.0,110.5 359.0,114.3 374.0,119.0 389.0,124.7 404.0,129.8 419.0,136.1 434.0,143.4 449.0,151.7 464.0,160.8 479.0,170.7" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="485" y="165" fill="#b06000">SMA-20</text>
|
||||
<line x1="44.0" y1="98.8" x2="44.0" y2="115.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="39.5" y="106.0" width="9" height="3.2" fill="#188a3e"/>
|
||||
<line x1="59.0" y1="90.0" x2="59.0" y2="113.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="54.5" y="96.4" width="9" height="9.6" fill="#188a3e"/>
|
||||
<line x1="74.0" y1="78.8" x2="74.0" y2="102.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="69.5" y="86.8" width="9" height="9.6" fill="#188a3e"/>
|
||||
<line x1="89.0" y1="66.8" x2="89.0" y2="94.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="84.5" y="75.6" width="9" height="11.2" fill="#188a3e"/>
|
||||
<line x1="104.0" y1="68.4" x2="104.0" y2="90.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="99.5" y="75.6" width="9" height="6.4" fill="#c00"/>
|
||||
<line x1="119.0" y1="61.2" x2="119.0" y2="88.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="114.5" y="69.2" width="9" height="12.8" fill="#188a3e"/>
|
||||
<line x1="134.0" y1="52.4" x2="134.0" y2="77.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="129.5" y="59.6" width="9" height="9.6" fill="#188a3e"/>
|
||||
<line x1="149.0" y1="42.0" x2="149.0" y2="66.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="144.5" y="48.4" width="9" height="11.2" fill="#188a3e"/>
|
||||
<line x1="164.0" y1="36.4" x2="164.0" y2="54.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="159.5" y="42.0" width="9" height="6.4" fill="#188a3e"/>
|
||||
<line x1="179.0" y1="34.0" x2="179.0" y2="49.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="174.5" y="38.8" width="9" height="3.2" fill="#188a3e"/>
|
||||
<line x1="194.0" y1="112.4" x2="194.0" y2="130.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="189.5" y="118.8" width="9" height="4.0" fill="#c00"/>
|
||||
<line x1="209.0" y1="115.6" x2="209.0" y2="132.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="204.5" y="122.8" width="9" height="3.2" fill="#c00"/>
|
||||
<line x1="224.0" y1="120.4" x2="224.0" y2="134.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="219.5" y="126.0" width="9" height="2.4" fill="#c00"/>
|
||||
<line x1="239.0" y1="122.0" x2="239.0" y2="143.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="234.5" y="128.4" width="9" height="8.8" fill="#c00"/>
|
||||
<line x1="254.0" y1="130.0" x2="254.0" y2="152.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="249.5" y="137.2" width="9" height="8.8" fill="#c00"/>
|
||||
<line x1="269.0" y1="134.0" x2="269.0" y2="152.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="264.5" y="141.2" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="284.0" y1="134.0" x2="284.0" y2="157.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="279.5" y="141.2" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="299.0" y1="143.6" x2="299.0" y2="166.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="294.5" y="150.8" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="314.0" y1="148.4" x2="314.0" y2="166.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="309.5" y="155.6" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="329.0" y1="148.4" x2="329.0" y2="173.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="324.5" y="155.6" width="9" height="11.2" fill="#c00"/>
|
||||
<line x1="344.0" y1="159.6" x2="344.0" y2="182.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="339.5" y="166.8" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="359.0" y1="164.4" x2="359.0" y2="182.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="354.5" y="171.6" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="374.0" y1="164.4" x2="374.0" y2="187.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="369.5" y="171.6" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="389.0" y1="174.0" x2="389.0" y2="195.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="384.5" y="181.2" width="9" height="8.0" fill="#c00"/>
|
||||
<line x1="404.0" y1="177.2" x2="404.0" y2="195.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="399.5" y="184.4" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="419.0" y1="177.2" x2="419.0" y2="202.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="414.5" y="184.4" width="9" height="11.2" fill="#c00"/>
|
||||
<line x1="434.0" y1="188.4" x2="434.0" y2="211.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="429.5" y="195.6" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="449.0" y1="198.0" x2="449.0" y2="221.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="444.5" y="205.2" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="464.0" y1="207.6" x2="464.0" y2="230.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="459.5" y="214.8" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="479.0" y1="216.4" x2="479.0" y2="244.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="474.5" y="224.4" width="9" height="11.2" fill="#c00"/>
|
||||
<line x1="24" y1="340.4" x2="626" y2="340.4" stroke="#888"/>
|
||||
<rect x="39.5" y="309.6" width="9" height="30.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="54.5" y="311.7" width="9" height="28.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="69.5" y="308.9" width="9" height="31.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="84.5" y="305.4" width="9" height="35.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="99.5" y="310.3" width="9" height="30.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="114.5" y="302.6" width="9" height="37.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="129.5" y="304.0" width="9" height="36.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="144.5" y="298.4" width="9" height="42.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="159.5" y="306.8" width="9" height="33.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="174.5" y="305.4" width="9" height="35.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="189.5" y="270.4" width="9" height="70.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="204.5" y="294.9" width="9" height="45.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="219.5" y="305.4" width="9" height="35.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="234.5" y="287.9" width="9" height="52.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="249.5" y="304.7" width="9" height="35.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="264.5" y="309.6" width="9" height="30.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="279.5" y="302.6" width="9" height="37.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="294.5" y="306.8" width="9" height="33.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="309.5" y="311.0" width="9" height="29.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="324.5" y="305.4" width="9" height="35.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="339.5" y="308.9" width="9" height="31.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="354.5" y="313.1" width="9" height="27.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="369.5" y="306.1" width="9" height="34.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="384.5" y="310.3" width="9" height="30.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="399.5" y="314.5" width="9" height="25.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="414.5" y="308.2" width="9" height="32.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="429.5" y="311.7" width="9" height="28.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="444.5" y="304.0" width="9" height="36.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="459.5" y="313.8" width="9" height="26.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="474.5" y="309.6" width="9" height="30.8" fill="#c00" opacity="0.55"/>
|
||||
<text x="24" y="264.4" fill="#555">volum</text>
|
||||
<text x="194.0" y="86.4" fill="#333" text-anchor="middle" style="font-weight:bold">gap down, open 79.20</text>
|
||||
<text x="224.0" y="106.4" fill="#c00" text-anchor="middle" style="font-weight:bold">sell doji close 78.60</text>
|
||||
<text x="239.0" y="189.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">intrare short 78.10</text>
|
||||
<text x="194.0" y="162.8" fill="#c00" text-anchor="middle" style="font-weight:bold">RVOL 200%</text>
|
||||
<text x="24" y="370" fill="#555">RVOL 200% si simbolul sunt reale (04_MODUL_3/01:196-199). Toate</text>
|
||||
<text x="24" y="387" fill="#555">nivelurile de preț (79.20 / 78.60 / 78.10 / 82.00 / 72.00) sunt</text>
|
||||
<text x="24" y="404" fill="#555">construite in sumarul 04_MODUL_3/01:293-296, nu date de curs;</text>
|
||||
<text x="24" y="421" fill="#555">structura barelor e construita, la scara.</text>
|
||||
<svg viewBox="0 0 737 510" 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">HIG — daily (Sell Doji + Bear Reversal, RVOL 200%)</text>
|
||||
<rect x="281.8" y="121.6" width="64.0" height="52.0" fill="#c00" fill-opacity="0.08" stroke="#c00" stroke-width="1"/>
|
||||
<text x="281.8" y="116.6" fill="#c00" style="font-weight:bold">ce l-a scos în față din cele 16 rezultate</text>
|
||||
<line x1="24" y1="56.0" x2="723" y2="56.0" stroke="#777" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="709" y="50.0" fill="#777" text-anchor="end">rezistenta 84.50</text>
|
||||
<line x1="24" y1="96.0" x2="723" y2="96.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="709" y="90.0" fill="#c00" text-anchor="end">SL 82.00</text>
|
||||
<line x1="24" y1="158.4" x2="723" y2="158.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="152.4" fill="#1a5fb4">intrare short 78.10</text>
|
||||
<line x1="24" y1="256.0" x2="723" y2="256.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="250.0" fill="#188a3e">TP 72.00</text>
|
||||
<polyline points="426.3,129.0 441.3,132.5 456.3,136.3 471.3,141.0 486.3,146.7 501.3,151.8 516.3,158.1 531.3,165.4 546.3,173.7 561.3,182.8 576.3,192.7" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="582" y="187" fill="#b06000">SMA-20</text>
|
||||
<line x1="141.3" y1="120.8" x2="141.3" y2="137.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="136.8" y="128.0" width="9" height="3.2" fill="#188a3e"/>
|
||||
<line x1="156.3" y1="112.0" x2="156.3" y2="135.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="151.8" y="118.4" width="9" height="9.6" fill="#188a3e"/>
|
||||
<line x1="171.3" y1="100.8" x2="171.3" y2="124.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="166.8" y="108.8" width="9" height="9.6" fill="#188a3e"/>
|
||||
<line x1="186.3" y1="88.8" x2="186.3" y2="116.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="181.8" y="97.6" width="9" height="11.2" fill="#188a3e"/>
|
||||
<line x1="201.3" y1="90.4" x2="201.3" y2="112.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="196.8" y="97.6" width="9" height="6.4" fill="#c00"/>
|
||||
<line x1="216.3" y1="83.2" x2="216.3" y2="110.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="211.8" y="91.2" width="9" height="12.8" fill="#188a3e"/>
|
||||
<line x1="231.3" y1="74.4" x2="231.3" y2="99.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="226.8" y="81.6" width="9" height="9.6" fill="#188a3e"/>
|
||||
<line x1="246.3" y1="64.0" x2="246.3" y2="88.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="241.8" y="70.4" width="9" height="11.2" fill="#188a3e"/>
|
||||
<line x1="261.3" y1="58.4" x2="261.3" y2="76.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="256.8" y="64.0" width="9" height="6.4" fill="#188a3e"/>
|
||||
<line x1="276.3" y1="56.0" x2="276.3" y2="71.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="271.8" y="60.8" width="9" height="3.2" fill="#188a3e"/>
|
||||
<line x1="291.3" y1="134.4" x2="291.3" y2="152.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="286.8" y="140.8" width="9" height="4.0" fill="#c00"/>
|
||||
<line x1="306.3" y1="137.6" x2="306.3" y2="154.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="301.8" y="144.8" width="9" height="3.2" fill="#c00"/>
|
||||
<line x1="321.3" y1="142.4" x2="321.3" y2="156.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="316.8" y="148.0" width="9" height="2.4" fill="#c00"/>
|
||||
<line x1="336.3" y1="144.0" x2="336.3" y2="165.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="331.8" y="150.4" width="9" height="8.8" fill="#c00"/>
|
||||
<line x1="351.3" y1="152.0" x2="351.3" y2="174.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="346.8" y="159.2" width="9" height="8.8" fill="#c00"/>
|
||||
<line x1="366.3" y1="156.0" x2="366.3" y2="174.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="361.8" y="163.2" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="381.3" y1="156.0" x2="381.3" y2="179.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="376.8" y="163.2" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="396.3" y1="165.6" x2="396.3" y2="188.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="391.8" y="172.8" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="411.3" y1="170.4" x2="411.3" y2="188.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="406.8" y="177.6" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="426.3" y1="170.4" x2="426.3" y2="195.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="421.8" y="177.6" width="9" height="11.2" fill="#c00"/>
|
||||
<line x1="441.3" y1="181.6" x2="441.3" y2="204.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="436.8" y="188.8" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="456.3" y1="186.4" x2="456.3" y2="204.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="451.8" y="193.6" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="471.3" y1="186.4" x2="471.3" y2="209.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="466.8" y="193.6" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="486.3" y1="196.0" x2="486.3" y2="217.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="481.8" y="203.2" width="9" height="8.0" fill="#c00"/>
|
||||
<line x1="501.3" y1="199.2" x2="501.3" y2="217.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="496.8" y="206.4" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="516.3" y1="199.2" x2="516.3" y2="224.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="511.8" y="206.4" width="9" height="11.2" fill="#c00"/>
|
||||
<line x1="531.3" y1="210.4" x2="531.3" y2="233.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="526.8" y="217.6" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="546.3" y1="220.0" x2="546.3" y2="243.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="541.8" y="227.2" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="561.3" y1="229.6" x2="561.3" y2="252.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="556.8" y="236.8" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="576.3" y1="238.4" x2="576.3" y2="266.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="571.8" y="246.4" width="9" height="11.2" fill="#c00"/>
|
||||
<line x1="24" y1="399.8" x2="723" y2="399.8" stroke="#888"/><line x1="24" y1="364.8" x2="723" y2="364.8" stroke="#777" stroke-width="1.2" stroke-dasharray="4 3"/><text x="721" y="360.8" fill="#777" text-anchor="end">media volumului pe serie</text><text x="92" y="324.8" fill="#c00" style="font-weight:bold">ziua gap-ului: de 2 ori media (RVOL 200 %) — se vinde dublu față de o zi normală</text>
|
||||
<rect x="136.8" y="369.0" width="9" height="30.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="151.8" y="371.1" width="9" height="28.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="166.8" y="368.3" width="9" height="31.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="181.8" y="364.8" width="9" height="35.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="196.8" y="369.7" width="9" height="30.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="211.8" y="362.0" width="9" height="37.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="226.8" y="363.4" width="9" height="36.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="241.8" y="357.8" width="9" height="42.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="256.8" y="366.2" width="9" height="33.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="271.8" y="364.8" width="9" height="35.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="286.8" y="329.8" width="9" height="70.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="301.8" y="354.3" width="9" height="45.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="316.8" y="364.8" width="9" height="35.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="331.8" y="347.3" width="9" height="52.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="346.8" y="364.1" width="9" height="35.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="361.8" y="369.0" width="9" height="30.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="376.8" y="362.0" width="9" height="37.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="391.8" y="366.2" width="9" height="33.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="406.8" y="370.4" width="9" height="29.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="421.8" y="364.8" width="9" height="35.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="436.8" y="368.3" width="9" height="31.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="451.8" y="372.5" width="9" height="27.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="466.8" y="365.5" width="9" height="34.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="481.8" y="369.7" width="9" height="30.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="496.8" y="373.9" width="9" height="25.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="511.8" y="367.6" width="9" height="32.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="526.8" y="371.1" width="9" height="28.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="541.8" y="363.4" width="9" height="36.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="556.8" y="373.2" width="9" height="26.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="571.8" y="369.0" width="9" height="30.8" fill="#c00" opacity="0.55"/>
|
||||
<text x="24" y="323.8" fill="#555">volum</text>
|
||||
<line x1="131.3" y1="88.0" x2="283.6" y2="128.4" stroke="#c00" stroke-width="1.8"/>
|
||||
<polygon points="291.3,130.4 282.5,132.2 284.6,124.5" fill="#c00"/>
|
||||
<text x="131.3" y="69.0" fill="#c00" text-anchor="middle" style="font-weight:bold">gap down: deschide la 79.20, mult sub</text>
|
||||
<text x="131.3" y="83.0" fill="#c00" text-anchor="middle" style="font-weight:bold">închiderea de ieri — vânzare, nu pauză</text>
|
||||
<line x1="201.3" y1="266.8" x2="315.1" y2="175.4" stroke="#333" stroke-width="1.8"/>
|
||||
<polygon points="321.3,170.4 317.6,178.5 312.6,172.3" fill="#333"/>
|
||||
<text x="201.3" y="280.8" fill="#333" text-anchor="middle" style="font-weight:bold">sell doji close 78.60: vânzătorii și cumpărătorii la egalitate,</text>
|
||||
<text x="201.3" y="294.8" fill="#333" text-anchor="middle" style="font-weight:bold">încă nu e semnal</text>
|
||||
<line x1="414.8" y1="268.4" x2="349.1" y2="165.1" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<polygon points="344.8,158.4 352.5,163.0 345.7,167.3" fill="#188a3e"/>
|
||||
<text x="418.8" y="265.4" fill="#188a3e" text-anchor="start" style="font-weight:bold">aici ar intra strategia de intrare, nu selecția:</text>
|
||||
<text x="418.8" y="279.4" fill="#188a3e" text-anchor="start" style="font-weight:bold">închidere sub low-ul doji-ului</text>
|
||||
<text x="24" y="430" fill="#555">Ale cursului: simbolul HIG, semnalul Sell Doji + Bear Reversal și</text>
|
||||
<text x="24" y="447" fill="#555">RVOL-ul de 200 %, cel mai mare din cele 16 rezultate ale scanerului.</text>
|
||||
<text x="24" y="464" fill="#555">Nivelurile de preț (79.20 / 78.60 / 78.10 / 82.00 / 72.00) și</text>
|
||||
<text x="24" y="481" fill="#555">structura barelor sunt construite, la scară: cursul nu dă cifre pentru</text>
|
||||
<text x="24" y="498" fill="#555">HIG.</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 11 KiB |
@@ -1,19 +1,20 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fluxul de selecție — palnia de filtrare de la scanner la lista scurtă.
|
||||
|
||||
Diagramă conceptuală (NU grafic de preț): palnie cu 8 trepte care se
|
||||
îngustează de sus în jos, apoi lista scurtă; cutie separată de note laterale.
|
||||
Pentru `strategii/04_selectia.md`, Nivel 1, §1.2 „Fluxul de filtrare, pas cu
|
||||
pas". Citește specificația `gen/strategii/selectia_funnel.spec.txt` și scrie
|
||||
`gen/strategii/selectia_funnel.svg`.
|
||||
Diagramă conceptuală (NU grafic de preț): palnie cu 6 trepte care se
|
||||
îngustează de sus în jos, apoi lista scurtă; cutie separată cu ce rămâne pe
|
||||
nivelul 3. Pentru `summaries/17_STRATEGII/04_selectia.md`, nivelul 1 — harta
|
||||
celor șase pași din nivelul 2. Scrie `gen/strategii/selectia_funnel.svg`.
|
||||
|
||||
Fiecare treaptă spune pragul ȘI de ce există pragul; trimiterile la material
|
||||
nu stau pe desen, ci în `summaries/17_STRATEGII/fise/04_selectia_surse.md`.
|
||||
|
||||
Nu folosește `svg_candles` / `pchart`: SVG-ul e construit ca string, doar
|
||||
stdlib.
|
||||
|
||||
Fiecare treaptă are titlul, subtitlul cu pragul și trimiterea (sursa).
|
||||
Toate cifrele din desen (pragurile, „max ~300 simboluri”, „top 10”) sunt
|
||||
preluate textual din specificație; nu se inventează valori de RS sau de
|
||||
sectoare.
|
||||
Fiecare treaptă are titlul, pragul și motivul pragului. Toate cifrele din
|
||||
desen (pragurile, „max ~300 de simboluri”, „top 10”) vin din material; nu se
|
||||
inventează valori de RS sau de sectoare.
|
||||
|
||||
Rulare: .venv/bin/python gen/strategii/selectia_funnel.py
|
||||
"""
|
||||
@@ -22,7 +23,7 @@ import re
|
||||
from pathlib import Path
|
||||
|
||||
W = 700
|
||||
H = 1024
|
||||
H = 840
|
||||
|
||||
BLACK = "#000000"
|
||||
GRAY = "#777777"
|
||||
@@ -38,60 +39,53 @@ NOTE_BG = "#fdf0e0"
|
||||
# ---------------------------------------------------------------- geometrie
|
||||
CX = W / 2.0 # 350: axa palniei
|
||||
TOPW = 610.0 # lățimea gurii palniei
|
||||
NARROW = 24.0 # cât se strânge pe fiecare treaptă
|
||||
NARROW = 30.0 # cât se strânge pe fiecare treaptă
|
||||
Y0 = 100.0
|
||||
HSTEP = 76.0
|
||||
|
||||
LIST_W, LIST_Y, LIST_H = 410.0, 722.0, 62.0
|
||||
NOTE = {"x": 40.0, "y": 802.0, "w": 620.0, "h": 200.0}
|
||||
LIST_W, LIST_Y, LIST_H = 410.0, 566.0, 62.0
|
||||
NOTE = {"x": 40.0, "y": 648.0, "w": 620.0, "h": 176.0}
|
||||
|
||||
# ---------------------------------------------------------------- conținut
|
||||
# (titlu, subtitlu, [linii de sursă])
|
||||
STEPS = [
|
||||
("Scanner — multe semnale",
|
||||
"zeci sau sute de semnale",
|
||||
["08_ANALIZA_ZILNICA/11_selectia_simbolului.md:631-637"]),
|
||||
("Filtre de bază",
|
||||
"close > 30-40 $; volum mediu 3 luni > 1M (min 500k)",
|
||||
["09_QA/28_2025-05-27.md:372-380;",
|
||||
"03_MODUL_2/11_construire_scanere_sf_byd_sld.md:70-73"]),
|
||||
("Fundamental",
|
||||
"ATM score peste 7-8; 12-13 = spuma; F-score 6-9",
|
||||
["08_ANALIZA_ZILNICA/11_selectia_simbolului.md:199-221"]),
|
||||
("Universul și lichiditatea",
|
||||
"close peste 30-40 $; volum mediu ≥ 500.000 de acțiuni, ideal peste 1 milion",
|
||||
["de ce: pe un simbol subțire, ordinul tău mută singur prețul"]),
|
||||
("Scorul fundamental",
|
||||
"ATM score peste 7-8 (12-13 = spuma); F-score 6-9",
|
||||
["de ce: instituționalii cumpără bilanț, nu desen"]),
|
||||
("Sectorul care domină",
|
||||
"cele 11 sectoare S&P, sortate cadran 1 + valoarea RS",
|
||||
["08_ANALIZA_ZILNICA/11_selectia_simbolului.md:639-717"]),
|
||||
("Doar suport / pivot, după downtrend",
|
||||
"suport monthly, quarterly, anual sau pivot; proximitate ≤ 3%",
|
||||
["08_ANALIZA_ZILNICA/11_selectia_simbolului.md:719-728, 787-803"]),
|
||||
("Relative strength: cadran 1-2",
|
||||
"doar cadranele 1 și 2, RS pozitiv",
|
||||
["08_ANALIZA_ZILNICA/11_selectia_simbolului.md:730-739"]),
|
||||
("Relative volume peste 100%",
|
||||
"numeri din ce sector vin cele mai multe semnale",
|
||||
["de ce: multe semnale în același sector = bani care intră acolo"]),
|
||||
("Suport sau pivot, după downtrend",
|
||||
"proximitate până la 3 % (4 % „e cam departe”)",
|
||||
["de ce: la un nivel, cumpărătorii au motiv să apară"]),
|
||||
("Relative strength: cadranul 1 sau 2",
|
||||
"simbolul se mișcă mai bine decât indicele de referință",
|
||||
["de ce: cumperi ce urcă mai tare decât piața"]),
|
||||
("Relative volume peste 100 %",
|
||||
"candela de volum / media ultimelor 10 candele",
|
||||
["08_ANALIZA_ZILNICA/11_selectia_simbolului.md:741-747"]),
|
||||
("Stele (Trinity)",
|
||||
"RS + Power + volum, cadran 1",
|
||||
["08_ANALIZA_ZILNICA/11_selectia_simbolului.md:776-785"]),
|
||||
["de ce: confirmă că azi chiar participă lumea, nu doar tu"]),
|
||||
]
|
||||
|
||||
LIST = ("Listă scurtă",
|
||||
"câteva idei pe care le urmărești",
|
||||
"08_ANALIZA_ZILNICA/11_selectia_simbolului.md:42-50")
|
||||
"nicio poziție deschisă: trigger-ul e al altui capitol")
|
||||
|
||||
TITLE = "Fluxul de selecție — de la scanner la lista scurtă"
|
||||
SUBTITLE = ("selecția se face înainte de semnalul tehnic; "
|
||||
"ea nu spune CÂND intri")
|
||||
CAPTION = "Palnia se îngustează de sus în jos: 8 filtre, apoi lista scurtă."
|
||||
CAPTION = "Palnia se îngustează de sus în jos: 6 filtre, apoi lista scurtă."
|
||||
|
||||
NOTE_TITLE = "Note laterale"
|
||||
NOTE1 = ["După corecție masivă: doji / hammer la suporturi mari",
|
||||
"(monthly, quarterly, anual); scanner de apropiere de suport",
|
||||
"până la 3% (4% e cam departe)."]
|
||||
NOTE1_SRC = "08_ANALIZA_ZILNICA/11_selectia_simbolului.md:787-803"
|
||||
NOTE2 = ["Radarscreen (max ~300 simboluri): repetă fluxul — sectoare top 10,",
|
||||
"RS, apoi 3 stele."]
|
||||
NOTE2_SRC = "08_ANALIZA_ZILNICA/11_selectia_simbolului.md:815-825"
|
||||
NOTE_TITLE = "Ce nu intră în cei șase pași (rafinări, nivelul 3)"
|
||||
NOTE1 = ["Sortarea finală după 3 stele (Trinity: relative strength, Power și",
|
||||
"volum, toate în cadranul 1) și departajarea între doi candidați",
|
||||
"rămași: trend, apoi volum, apoi fundamental."]
|
||||
NOTE1_SRC = "un scor de 7 nu e motiv să-l iei, dacă ai altul mai bun"
|
||||
NOTE2 = ["Radarscreen (maximum ~300 de simboluri: cele 11 sectoare × top 10):",
|
||||
"același flux, rulat pe o listă fixă, nu pe tot scanerul."]
|
||||
NOTE2_SRC = "după o corecție mare, cauți doji sau hammer la suporturile mari"
|
||||
|
||||
# ---------------------------------------------------------------- colect
|
||||
TEXTS = [] # (x, y, s, size, weight, fill, anchor)
|
||||
@@ -143,7 +137,7 @@ add(W / 2, 34, TITLE, 20, "bold")
|
||||
add(W / 2, 57, SUBTITLE, 13, "normal", GRAY)
|
||||
add(W / 2, 79, CAPTION, 13, "normal", GRAY)
|
||||
|
||||
# ---- palnia: 8 trepte
|
||||
# ---- palnia: 6 trepte
|
||||
for i, (titlu, subtitlu, surse) in enumerate(STEPS):
|
||||
y = Y0 + i * HSTEP
|
||||
wt = TOPW - i * NARROW
|
||||
@@ -152,7 +146,7 @@ for i, (titlu, subtitlu, surse) in enumerate(STEPS):
|
||||
add(CX, y + 25, f"{i + 1}. {titlu}", 14.5, "bold", BLACK)
|
||||
add(CX, y + 45, subtitlu, 13, "normal", BLACK)
|
||||
for k, src in enumerate(surse):
|
||||
add(CX, y + 59 + k * 14, src, 13, "normal", GRAY)
|
||||
add(CX, y + 60 + k * 15, src, 13, "normal", GRAY)
|
||||
|
||||
# ---- lista scurtă (vârful palniei, cutie separată)
|
||||
p.append(rect(CX - LIST_W / 2, LIST_Y, LIST_W, LIST_H, "list",
|
||||
@@ -165,21 +159,21 @@ add(CX, LIST_Y + 57, LIST[2], 13, "normal", GRAY)
|
||||
p.append(rect(NOTE["x"], NOTE["y"], NOTE["w"], NOTE["h"], "note",
|
||||
fill=NOTE_BG, stroke=ORANGE, sw=1.6, rx=8))
|
||||
nx = NOTE["x"] + 20
|
||||
add(nx, NOTE["y"] + 28, NOTE_TITLE, 15, "bold", ORANGE, "start")
|
||||
add(nx, NOTE["y"] + 56, NOTE1[0], 13, "normal", BLACK, "start")
|
||||
add(nx, NOTE["y"] + 75, NOTE1[1], 13, "normal", BLACK, "start")
|
||||
add(nx, NOTE["y"] + 94, NOTE1[2], 13, "normal", BLACK, "start")
|
||||
add(nx, NOTE["y"] + 115, NOTE1_SRC, 13, "normal", GRAY, "start")
|
||||
add(nx, NOTE["y"] + 150, NOTE2[0], 13, "normal", BLACK, "start")
|
||||
add(nx, NOTE["y"] + 169, NOTE2[1], 13, "normal", BLACK, "start")
|
||||
add(nx, NOTE["y"] + 190, NOTE2_SRC, 13, "normal", GRAY, "start")
|
||||
add(nx, NOTE["y"] + 26, NOTE_TITLE, 15, "bold", ORANGE, "start")
|
||||
add(nx, NOTE["y"] + 50, NOTE1[0], 13, "normal", BLACK, "start")
|
||||
add(nx, NOTE["y"] + 68, NOTE1[1], 13, "normal", BLACK, "start")
|
||||
add(nx, NOTE["y"] + 86, NOTE1[2], 13, "normal", BLACK, "start")
|
||||
add(nx, NOTE["y"] + 104, NOTE1_SRC, 13, "normal", GRAY, "start")
|
||||
add(nx, NOTE["y"] + 130, NOTE2[0], 13, "normal", BLACK, "start")
|
||||
add(nx, NOTE["y"] + 148, NOTE2[1], 13, "normal", BLACK, "start")
|
||||
add(nx, NOTE["y"] + 166, NOTE2_SRC, 13, "normal", GRAY, "start")
|
||||
|
||||
# =============================================================== EMITERE
|
||||
head = (f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" '
|
||||
f'width="{W}" height="{H}" font-family="system-ui, sans-serif" '
|
||||
f'role="img" aria-label="Palnia de selectie: 8 trepte de filtrare de la '
|
||||
f'scanner la lista scurta, fiecare cu pragul si sursa ei, plus note '
|
||||
f'laterale despre suporturi si Radarscreen">')
|
||||
f'role="img" aria-label="Palnia de selectie: 6 trepte de filtrare de la '
|
||||
f'scanner la lista scurta, fiecare cu pragul ei si cu motivul pentru '
|
||||
f'care exista pragul, plus rafinarile de la nivelul 3">')
|
||||
body = [head, f'<rect x="0" y="0" width="{W}" height="{H}" fill="#ffffff"/>']
|
||||
body += p
|
||||
for x, y, s, size, weight, fill, anchor in TEXTS:
|
||||
@@ -189,10 +183,10 @@ svg = "\n".join(body) + "\n"
|
||||
|
||||
# =============================================================== VERIFICARE
|
||||
# 1. palnia are exact 8 trepte, conectate și tot mai înguste
|
||||
assert len(STEPS) == 8, f"aștept 8 trepte, am {len(STEPS)}"
|
||||
assert len(STEPS) == 6, f"aștept 6 trepte, am {len(STEPS)}"
|
||||
traps = [s for s in SHAPES if s[4].startswith("step")]
|
||||
assert len(traps) == 8, f"aștept 8 trapezoide, am {len(traps)}"
|
||||
assert len(WIDTHS) == 8
|
||||
assert len(traps) == 6, f"aștept 6 trapezoide, am {len(traps)}"
|
||||
assert len(WIDTHS) == 6
|
||||
for i, (wt, wb) in enumerate(WIDTHS):
|
||||
assert wt > wb, f"treapta {i} nu se îngustează"
|
||||
if i:
|
||||
@@ -208,7 +202,8 @@ for i, (titlu, subtitlu, surse) in enumerate(STEPS):
|
||||
assert any(t[2] == subtitlu for t in TEXTS), \
|
||||
f"lipsește subtitlul treptei {i + 1}: {subtitlu!r}"
|
||||
for src in surse:
|
||||
assert src in svg, f"lipsește sursa treptei {i + 1}: {src!r}"
|
||||
assert src in svg, f"lipsește «de ce»-ul treptei {i + 1}: {src!r}"
|
||||
assert surse[0].startswith("de ce:"), f"treapta {i + 1} nu spune de ce"
|
||||
assert any(t[2] == LIST[0] for t in TEXTS), "lipsește «Listă scurtă»"
|
||||
assert "câteva idei pe care le urmărești" in svg
|
||||
|
||||
@@ -219,7 +214,7 @@ for line in NOTE1 + [NOTE1_SRC] + NOTE2 + [NOTE2_SRC]:
|
||||
assert line in svg, f"lipsește din note: {line!r}"
|
||||
|
||||
# 4. fiecare textul încape în lățimea treptei lui (muchia de jos, cea îngustă)
|
||||
for i in range(8):
|
||||
for i in range(len(STEPS)):
|
||||
ytop = Y0 + i * HSTEP
|
||||
ybot = ytop + HSTEP
|
||||
wb = TOPW - (i + 1) * NARROW
|
||||
@@ -259,7 +254,7 @@ for i in range(len(boxes)):
|
||||
raise AssertionError(f"etichete suprapuse: {s1!r} / {s2!r}")
|
||||
|
||||
# 6. cutiile stau una sub alta, în ordinea palnie -> listă -> note
|
||||
assert LIST_Y >= Y0 + 8 * HSTEP, "lista scurtă se suprapune cu palnia"
|
||||
assert LIST_Y >= Y0 + len(STEPS) * HSTEP, "lista scurtă se suprapune cu palnia"
|
||||
assert NOTE["y"] >= LIST_Y + LIST_H, "notele se suprapun cu lista scurtă"
|
||||
assert NOTE["y"] + NOTE["h"] <= H, "notele ies din panză"
|
||||
|
||||
@@ -270,9 +265,9 @@ assert "<circle" not in svg and "<line" not in svg, "doar palnie, fără axe"
|
||||
|
||||
# 8. singurele cifre din desen (fără referințele de sursă) sunt pragurile
|
||||
# din specificație
|
||||
content = [t[2] for t in TEXTS if ".md:" not in t[2]]
|
||||
content = [t[2] for t in TEXTS]
|
||||
spec_numbers = {"1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
"30", "40", "500", "11", "12", "13", "100", "10", "300"}
|
||||
"30", "40", "500", "000", "11", "12", "13", "100", "10", "300"}
|
||||
nums = set(re.findall(r"\d+", " ".join(content)))
|
||||
assert nums <= spec_numbers, f"cifre neașteptate în desen: {nums - spec_numbers}"
|
||||
|
||||
|
||||
@@ -1,52 +1,43 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 1024" width="700" height="1024" font-family="system-ui, sans-serif" role="img" aria-label="Palnia de selectie: 8 trepte de filtrare de la scanner la lista scurta, fiecare cu pragul si sursa ei, plus note laterale despre suporturi si Radarscreen">
|
||||
<rect x="0" y="0" width="700" height="1024" fill="#ffffff"/>
|
||||
<path d="M 45.0 100.0 L 655.0 100.0 L 643.0 176.0 L 57.0 176.0 Z" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 57.0 176.0 L 643.0 176.0 L 631.0 252.0 L 69.0 252.0 Z" fill="#e4edf9" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 69.0 252.0 L 631.0 252.0 L 619.0 328.0 L 81.0 328.0 Z" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 81.0 328.0 L 619.0 328.0 L 607.0 404.0 L 93.0 404.0 Z" fill="#e4edf9" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 93.0 404.0 L 607.0 404.0 L 595.0 480.0 L 105.0 480.0 Z" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 105.0 480.0 L 595.0 480.0 L 583.0 556.0 L 117.0 556.0 Z" fill="#e4edf9" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 117.0 556.0 L 583.0 556.0 L 571.0 632.0 L 129.0 632.0 Z" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 129.0 632.0 L 571.0 632.0 L 559.0 708.0 L 141.0 708.0 Z" fill="#e4edf9" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<rect x="145.0" y="722.0" width="410.0" height="62.0" fill="#eef7f0" stroke="#188a3e" stroke-width="1.8" rx="8"/>
|
||||
<rect x="40.0" y="802.0" width="620.0" height="200.0" fill="#fdf0e0" stroke="#b06000" stroke-width="1.6" rx="8"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 840" width="700" height="840" font-family="system-ui, sans-serif" role="img" aria-label="Palnia de selectie: 6 trepte de filtrare de la scanner la lista scurta, fiecare cu pragul ei si cu motivul pentru care exista pragul, plus rafinarile de la nivelul 3">
|
||||
<rect x="0" y="0" width="700" height="840" fill="#ffffff"/>
|
||||
<path d="M 45.0 100.0 L 655.0 100.0 L 640.0 176.0 L 60.0 176.0 Z" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 60.0 176.0 L 640.0 176.0 L 625.0 252.0 L 75.0 252.0 Z" fill="#e4edf9" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 75.0 252.0 L 625.0 252.0 L 610.0 328.0 L 90.0 328.0 Z" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 90.0 328.0 L 610.0 328.0 L 595.0 404.0 L 105.0 404.0 Z" fill="#e4edf9" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 105.0 404.0 L 595.0 404.0 L 580.0 480.0 L 120.0 480.0 Z" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<path d="M 120.0 480.0 L 580.0 480.0 L 565.0 556.0 L 135.0 556.0 Z" fill="#e4edf9" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<rect x="145.0" y="566.0" width="410.0" height="62.0" fill="#eef7f0" stroke="#188a3e" stroke-width="1.8" rx="8"/>
|
||||
<rect x="40.0" y="648.0" width="620.0" height="176.0" fill="#fdf0e0" stroke="#b06000" stroke-width="1.6" rx="8"/>
|
||||
<text x="350.0" y="34.0" font-size="20" font-weight="bold" fill="#000000" text-anchor="middle">Fluxul de selecție — de la scanner la lista scurtă</text>
|
||||
<text x="350.0" y="57.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">selecția se face înainte de semnalul tehnic; ea nu spune CÂND intri</text>
|
||||
<text x="350.0" y="79.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">Palnia se îngustează de sus în jos: 8 filtre, apoi lista scurtă.</text>
|
||||
<text x="350.0" y="125.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">1. Scanner — multe semnale</text>
|
||||
<text x="350.0" y="145.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">zeci sau sute de semnale</text>
|
||||
<text x="350.0" y="159.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">08_ANALIZA_ZILNICA/11_selectia_simbolului.md:631-637</text>
|
||||
<text x="350.0" y="201.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">2. Filtre de bază</text>
|
||||
<text x="350.0" y="221.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">close > 30-40 $; volum mediu 3 luni > 1M (min 500k)</text>
|
||||
<text x="350.0" y="235.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">09_QA/28_2025-05-27.md:372-380;</text>
|
||||
<text x="350.0" y="249.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">03_MODUL_2/11_construire_scanere_sf_byd_sld.md:70-73</text>
|
||||
<text x="350.0" y="277.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">3. Fundamental</text>
|
||||
<text x="350.0" y="297.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">ATM score peste 7-8; 12-13 = spuma; F-score 6-9</text>
|
||||
<text x="350.0" y="311.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">08_ANALIZA_ZILNICA/11_selectia_simbolului.md:199-221</text>
|
||||
<text x="350.0" y="353.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">4. Sectorul care domină</text>
|
||||
<text x="350.0" y="373.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">cele 11 sectoare S&P, sortate cadran 1 + valoarea RS</text>
|
||||
<text x="350.0" y="387.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">08_ANALIZA_ZILNICA/11_selectia_simbolului.md:639-717</text>
|
||||
<text x="350.0" y="429.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">5. Doar suport / pivot, după downtrend</text>
|
||||
<text x="350.0" y="449.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">suport monthly, quarterly, anual sau pivot; proximitate ≤ 3%</text>
|
||||
<text x="350.0" y="463.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">08_ANALIZA_ZILNICA/11_selectia_simbolului.md:719-728, 787-803</text>
|
||||
<text x="350.0" y="505.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">6. Relative strength: cadran 1-2</text>
|
||||
<text x="350.0" y="525.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">doar cadranele 1 și 2, RS pozitiv</text>
|
||||
<text x="350.0" y="539.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">08_ANALIZA_ZILNICA/11_selectia_simbolului.md:730-739</text>
|
||||
<text x="350.0" y="581.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">7. Relative volume peste 100%</text>
|
||||
<text x="350.0" y="601.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">candela de volum / media ultimelor 10 candele</text>
|
||||
<text x="350.0" y="615.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">08_ANALIZA_ZILNICA/11_selectia_simbolului.md:741-747</text>
|
||||
<text x="350.0" y="657.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">8. Stele (Trinity)</text>
|
||||
<text x="350.0" y="677.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">RS + Power + volum, cadran 1</text>
|
||||
<text x="350.0" y="691.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">08_ANALIZA_ZILNICA/11_selectia_simbolului.md:776-785</text>
|
||||
<text x="350.0" y="746.0" font-size="16" font-weight="bold" fill="#188a3e" text-anchor="middle">Listă scurtă</text>
|
||||
<text x="350.0" y="765.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">câteva idei pe care le urmărești</text>
|
||||
<text x="350.0" y="779.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">08_ANALIZA_ZILNICA/11_selectia_simbolului.md:42-50</text>
|
||||
<text x="60.0" y="830.0" font-size="15" font-weight="bold" fill="#b06000" text-anchor="start">Note laterale</text>
|
||||
<text x="60.0" y="858.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">După corecție masivă: doji / hammer la suporturi mari</text>
|
||||
<text x="60.0" y="877.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">(monthly, quarterly, anual); scanner de apropiere de suport</text>
|
||||
<text x="60.0" y="896.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">până la 3% (4% e cam departe).</text>
|
||||
<text x="60.0" y="917.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">08_ANALIZA_ZILNICA/11_selectia_simbolului.md:787-803</text>
|
||||
<text x="60.0" y="952.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">Radarscreen (max ~300 simboluri): repetă fluxul — sectoare top 10,</text>
|
||||
<text x="60.0" y="971.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">RS, apoi 3 stele.</text>
|
||||
<text x="60.0" y="992.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">08_ANALIZA_ZILNICA/11_selectia_simbolului.md:815-825</text>
|
||||
<text x="350.0" y="79.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">Palnia se îngustează de sus în jos: 6 filtre, apoi lista scurtă.</text>
|
||||
<text x="350.0" y="125.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">1. Universul și lichiditatea</text>
|
||||
<text x="350.0" y="145.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">close peste 30-40 $; volum mediu ≥ 500.000 de acțiuni, ideal peste 1 milion</text>
|
||||
<text x="350.0" y="160.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">de ce: pe un simbol subțire, ordinul tău mută singur prețul</text>
|
||||
<text x="350.0" y="201.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">2. Scorul fundamental</text>
|
||||
<text x="350.0" y="221.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">ATM score peste 7-8 (12-13 = spuma); F-score 6-9</text>
|
||||
<text x="350.0" y="236.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">de ce: instituționalii cumpără bilanț, nu desen</text>
|
||||
<text x="350.0" y="277.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">3. Sectorul care domină</text>
|
||||
<text x="350.0" y="297.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">numeri din ce sector vin cele mai multe semnale</text>
|
||||
<text x="350.0" y="312.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">de ce: multe semnale în același sector = bani care intră acolo</text>
|
||||
<text x="350.0" y="353.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">4. Suport sau pivot, după downtrend</text>
|
||||
<text x="350.0" y="373.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">proximitate până la 3 % (4 % „e cam departe”)</text>
|
||||
<text x="350.0" y="388.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">de ce: la un nivel, cumpărătorii au motiv să apară</text>
|
||||
<text x="350.0" y="429.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">5. Relative strength: cadranul 1 sau 2</text>
|
||||
<text x="350.0" y="449.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">simbolul se mișcă mai bine decât indicele de referință</text>
|
||||
<text x="350.0" y="464.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">de ce: cumperi ce urcă mai tare decât piața</text>
|
||||
<text x="350.0" y="505.0" font-size="14.5" font-weight="bold" fill="#000000" text-anchor="middle">6. Relative volume peste 100 %</text>
|
||||
<text x="350.0" y="525.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">candela de volum / media ultimelor 10 candele</text>
|
||||
<text x="350.0" y="540.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">de ce: confirmă că azi chiar participă lumea, nu doar tu</text>
|
||||
<text x="350.0" y="590.0" font-size="16" font-weight="bold" fill="#188a3e" text-anchor="middle">Listă scurtă</text>
|
||||
<text x="350.0" y="609.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">câteva idei pe care le urmărești</text>
|
||||
<text x="350.0" y="623.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">nicio poziție deschisă: trigger-ul e al altui capitol</text>
|
||||
<text x="60.0" y="674.0" font-size="15" font-weight="bold" fill="#b06000" text-anchor="start">Ce nu intră în cei șase pași (rafinări, nivelul 3)</text>
|
||||
<text x="60.0" y="698.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">Sortarea finală după 3 stele (Trinity: relative strength, Power și</text>
|
||||
<text x="60.0" y="716.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">volum, toate în cadranul 1) și departajarea între doi candidați</text>
|
||||
<text x="60.0" y="734.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">rămași: trend, apoi volum, apoi fundamental.</text>
|
||||
<text x="60.0" y="752.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">un scor de 7 nu e motiv să-l iei, dacă ai altul mai bun</text>
|
||||
<text x="60.0" y="778.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">Radarscreen (maximum ~300 de simboluri: cele 11 sectoare × top 10):</text>
|
||||
<text x="60.0" y="796.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">același flux, rulat pe o listă fixă, nu pe tot scanerul.</text>
|
||||
<text x="60.0" y="814.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">după o corecție mare, cauți doji sau hammer la suporturile mari</text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 6.2 KiB |
171
gen/strategii/selectia_proximitate.py
Normal file
@@ -0,0 +1,171 @@
|
||||
"""Pasul 4 — cât de aproape de suport e prețul (TIP: PRET).
|
||||
|
||||
Pentru `summaries/17_STRATEGII/04_selectia.md`, pasul 4. Un singur grafic
|
||||
daily, cu suportul monthly și cu banda de 3 % de deasupra lui, desenată ca
|
||||
dreptunghi: înăuntru simbolul e „la nivel", în afară e „în aer". Două momente
|
||||
din aceeași serie, unul în fiecare parte, ca să se vadă diferența pe care
|
||||
ochiul n-o prinde.
|
||||
|
||||
Pragul de 3 % (cu 4 % „cam departe") e al cursului. Seria e construită, la
|
||||
scară; toate procentele din etichete se calculează din ea, cu assert.
|
||||
|
||||
Atenție la diferența față de capitolul Buy Doji: acolo pragul de 1-2 % se
|
||||
măsoară pentru low-ul doji-ului. Aici măsori închiderea simbolului față de
|
||||
suport, ca filtru de selecție — două măsurători diferite, praguri diferite.
|
||||
|
||||
Rulează:
|
||||
python3 gen/strategii/selectia_proximitate.py
|
||||
"""
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
from svg_candles import Chart, Level, Arrow, Zone, MA, from_closes # noqa: E402
|
||||
|
||||
OUT = Path(__file__).resolve().parent / "selectia_proximitate.svg"
|
||||
|
||||
GRAY, RED, GREEN, BLUE, ORANGE = "#777", "#c00", "#188a3e", "#1a5fb4", "#b06000"
|
||||
|
||||
SUPORT = 48.00
|
||||
PRAG = 0.03 # 3 % — pragul cursului
|
||||
BANDA_SUS = SUPORT * (1 + PRAG) # 49.44
|
||||
|
||||
DEPARTE, APROAPE = 10, 30 # barele comentate
|
||||
|
||||
CLOSES = [
|
||||
56.00, 55.60, 55.10, 54.70, 54.20, # 0-4
|
||||
53.80, 53.30, 52.90, 52.40, 52.00, # 5-9
|
||||
51.60, 51.20, 50.90, 50.50, 50.20, # 10-14
|
||||
49.90, 50.30, 50.00, 49.70, 49.40, # 15-19
|
||||
49.10, 49.50, 49.20, 48.90, 49.20, # 20-24
|
||||
48.90, 48.70, 49.00, 48.70, 48.50, # 25-29
|
||||
48.80, 49.10, # 30-31
|
||||
]
|
||||
assert len(CLOSES) == 32, len(CLOSES)
|
||||
|
||||
WICKS = [(0.22, 0.24)] * 32
|
||||
WICKS[0] = (0.30, 0.30)
|
||||
WICKS[29] = (0.20, 0.50) # low exact pe suport: 48.50 - 0.50 = 48.00
|
||||
assert len(WICKS) == 32
|
||||
|
||||
VOLS = [46, 44, 48, 45, 43, 47, 44, 42, 45, 41,
|
||||
40, 42, 39, 41, 38, 44, 36, 38, 35, 37,
|
||||
34, 40, 33, 36, 32, 35, 31, 34, 33, 48,
|
||||
44, 46]
|
||||
assert len(VOLS) == 32
|
||||
|
||||
cds = from_closes(CLOSES, wicks=WICKS, vols=VOLS, start=56.30)
|
||||
|
||||
# ---------------------------------------------------------------- assert-uri de conținut
|
||||
for a, b in zip(cds, cds[1:]):
|
||||
assert abs(a.c - b.o) < 1e-9, "serie cu gol artificial între bare"
|
||||
assert abs(min(c.l for c in cds) - SUPORT) < 1e-9, "suportul nu e atins de niciun low"
|
||||
|
||||
pct_departe = (cds[DEPARTE].c - SUPORT) / SUPORT * 100
|
||||
pct_aproape = (cds[APROAPE].c - SUPORT) / SUPORT * 100
|
||||
assert pct_departe > PRAG * 100, "bara «departe» trebuie să fie peste prag"
|
||||
assert pct_aproape < PRAG * 100, "bara «aproape» trebuie să fie sub prag"
|
||||
assert abs(pct_departe - 7.50) < 0.01, pct_departe
|
||||
assert abs(pct_aproape - 1.67) < 0.01, pct_aproape
|
||||
# banda acoperă exact ce trebuie: bara «aproape» înăuntru, bara «departe» afară
|
||||
assert SUPORT <= cds[APROAPE].c <= BANDA_SUS, "bara «aproape» nu e în bandă"
|
||||
assert cds[DEPARTE].c > BANDA_SUS, "bara «departe» nu e în afara benzii"
|
||||
# numărul din textul zonei == numărul de bare pe care le acoperă
|
||||
in_banda = [i for i, c in enumerate(cds) if SUPORT <= c.c <= BANDA_SUS]
|
||||
assert in_banda and in_banda[0] == 19, in_banda[:3]
|
||||
|
||||
levels = [
|
||||
Level(SUPORT, f"suport monthly {SUPORT:.2f}", BLUE, label_at="left"),
|
||||
Level(BANDA_SUS, f"suport + 3 % = {BANDA_SUS:.2f}", BLUE, dash="5 3"),
|
||||
]
|
||||
|
||||
zones = [
|
||||
# eticheta benzii o pun manual, după randare: banda ține toată lățimea, iar
|
||||
# eticheta automată ar urca deasupra primei candele, peste titlu
|
||||
Zone(0, 31, "", BLUE, p_top=BANDA_SUS, p_bot=SUPORT),
|
||||
]
|
||||
|
||||
arrows = [
|
||||
Arrow(DEPARTE, f"close {cds[DEPARTE].c:.2f} = {pct_departe:.2f} % peste suport\n"
|
||||
f"prea departe: până acolo prețul mai are de căzut,\n"
|
||||
f"deci nivelul nu-l poate opri acum",
|
||||
where="above", color=RED, dx=-60, dy=-4),
|
||||
Arrow(APROAPE, f"close {cds[APROAPE].c:.2f} = {pct_aproape:.2f} % peste suport\n"
|
||||
f"la nivel: dacă mai scade puțin, dă de ordinele\n"
|
||||
f"de cumpărare care au mai întors prețul de acolo",
|
||||
where="below", color=GREEN, dx=-320, dy=42),
|
||||
]
|
||||
|
||||
caption = ("Pragul de 3 % (cu 4 % „cam departe”) e al cursului; seria și prețurile sunt construite, "
|
||||
"la scară, iar procentele sunt calculate din serie. În capitolul Buy Doji, pragul de "
|
||||
"1-2 % măsoară altceva: low-ul doji-ului față de nivel, nu închiderea simbolului.")
|
||||
|
||||
ch = Chart(
|
||||
candles=cds, levels=levels, zones=zones, arrows=arrows,
|
||||
mas=[MA(20, ORANGE, dash="4 3", text="SMA-20")],
|
||||
scale=26.0, gap=15, body_w=9, left=44, width=660, vol_h=60,
|
||||
vol_label="volum",
|
||||
title="Cât de aproape de suport e prețul — daily, exemplu construit",
|
||||
caption=caption,
|
||||
)
|
||||
svg = ch.render()
|
||||
|
||||
# eticheta benzii, pusă în interiorul ei, în stânga
|
||||
m_band = re.findall(r'<line x1="24" y1="([\d.]+)"', svg)
|
||||
y_banda_sus, y_suport = float(m_band[1]), float(m_band[0])
|
||||
assert y_suport > y_banda_sus, "banda e desenată invers"
|
||||
svg = svg.replace("</svg>",
|
||||
f'<text x="230" y="{(y_banda_sus + y_suport) / 2 + 4:.1f}" fill="{BLUE}" '
|
||||
f'style="font-weight:bold">banda de 3 %: înăuntru simbolul e „la nivel”</text>'
|
||||
"</svg>")
|
||||
|
||||
# „SMA-20" cade peste eticheta nivelului de bandă: o ridic pe rândul liber
|
||||
svg, n = re.subn(r'(<text x="\d+" y=")([\d.]+)(" fill="#b06000">SMA-20</text>)',
|
||||
lambda mm: f'{mm.group(1)}{float(mm.group(2)) - 16:.1f}{mm.group(3)}', svg)
|
||||
assert n == 1, f"eticheta SMA-20: {n} potriviri"
|
||||
|
||||
# liniile nu au voie să cadă pe marginea cadrului
|
||||
m_sup = re.findall(r'<line x1="24" y1="([\d.]+)"', svg)
|
||||
assert m_sup, "nu găsesc liniile de nivel"
|
||||
y_sup = float(m_sup[0])
|
||||
m_vb = re.search(r'viewBox="0 0 (\d+) (\d+)"', svg)
|
||||
assert m_vb
|
||||
h_svg = int(m_vb.group(2))
|
||||
assert y_sup > 0.06 * h_svg, "linia suportului e lipită de marginea de sus"
|
||||
|
||||
# nicio etichetă nu numește un preț care nu e desenat
|
||||
desenate = {f"{SUPORT:.2f}", f"{BANDA_SUS:.2f}", f"{cds[DEPARTE].c:.2f}", f"{cds[APROAPE].c:.2f}",
|
||||
f"{pct_departe:.2f}", f"{pct_aproape:.2f}"}
|
||||
for t in re.findall(r"<text[^>]*>([^<]*)</text>", svg):
|
||||
for nr in re.findall(r"\d+\.\d\d", t):
|
||||
assert nr in desenate, f"eticheta numește {nr}, care nu e desenat: {t!r}"
|
||||
|
||||
|
||||
def _wrap(text: str, max_chars: int) -> list[str]:
|
||||
lines, cur = [], ""
|
||||
for w in text.split():
|
||||
if cur and len(cur) + 1 + len(w) > max_chars:
|
||||
lines.append(cur)
|
||||
cur = w
|
||||
else:
|
||||
cur = f"{cur} {w}".strip()
|
||||
if cur:
|
||||
lines.append(cur)
|
||||
return lines
|
||||
|
||||
|
||||
cap_lines = _wrap(caption, 96)
|
||||
m = re.search(r'<text x="24" y="(\d+)" fill="#555">' + re.escape(caption) + r"</text>", svg)
|
||||
assert m, "caption-ul nu a fost găsit în SVG"
|
||||
y0 = int(m.group(1))
|
||||
wrapped = "\n ".join(f'<text x="24" y="{y0 + 17 * i}" fill="#555">{ln}</text>'
|
||||
for i, ln in enumerate(cap_lines))
|
||||
svg = svg[:m.start()] + wrapped + svg[m.end():]
|
||||
svg = svg.replace(m_vb.group(0),
|
||||
f'viewBox="0 0 {m_vb.group(1)} {h_svg + 17 * (len(cap_lines) - 1)}"', 1)
|
||||
|
||||
assert "<svg" in svg and "\n\n" not in svg, "linie goală în SVG"
|
||||
OUT.write_text(svg)
|
||||
print(f"scris {OUT.name}: 32 candele, suport {SUPORT:.2f}, banda până la {BANDA_SUS:.2f}, "
|
||||
f"bara {DEPARTE} la {pct_departe:.2f} % (afară), bara {APROAPE} la {pct_aproape:.2f} % (înăuntru)")
|
||||
121
gen/strategii/selectia_proximitate.svg
Normal file
@@ -0,0 +1,121 @@
|
||||
<svg viewBox="0 0 683 594" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<text x="24" y="84" fill="#333" style="font-weight:bold">Cât de aproape de suport e prețul — daily, exemplu construit</text>
|
||||
<rect x="58.4" y="278.2" width="484.0" height="37.4" fill="#1a5fb4" fill-opacity="0.08" stroke="#1a5fb4" stroke-width="1"/>
|
||||
<line x1="24" y1="315.6" x2="669" y2="315.6" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="309.6" fill="#1a5fb4">suport monthly 48.00</text>
|
||||
<line x1="24" y1="278.2" x2="669" y2="278.2" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="5 3"/>
|
||||
<text x="655" y="272.2" fill="#1a5fb4" text-anchor="end">suport + 3 % = 49.44</text>
|
||||
<polyline points="352.9,206.8 367.9,215.8 382.9,223.7 397.9,231.4 412.9,238.9 427.9,245.4 442.9,251.8 457.9,257.7 472.9,262.8 487.9,267.6 502.9,272.2 517.9,275.8 532.9,278.5" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="539" y="256.0" fill="#b06000">SMA-20</text>
|
||||
<line x1="67.9" y1="92.0" x2="67.9" y2="115.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="63.4" y="99.8" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="82.9" y1="101.9" x2="82.9" y2="124.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="78.4" y="107.6" width="9" height="10.4" fill="#c00"/>
|
||||
<line x1="97.9" y1="112.3" x2="97.9" y2="137.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="93.4" y="118.0" width="9" height="13.0" fill="#c00"/>
|
||||
<line x1="112.9" y1="125.3" x2="112.9" y2="147.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="108.4" y="131.0" width="9" height="10.4" fill="#c00"/>
|
||||
<line x1="127.9" y1="135.7" x2="127.9" y2="160.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="123.4" y="141.4" width="9" height="13.0" fill="#c00"/>
|
||||
<line x1="142.9" y1="148.7" x2="142.9" y2="171.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="138.4" y="154.4" width="9" height="10.4" fill="#c00"/>
|
||||
<line x1="157.9" y1="159.1" x2="157.9" y2="184.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="153.4" y="164.8" width="9" height="13.0" fill="#c00"/>
|
||||
<line x1="172.9" y1="172.1" x2="172.9" y2="194.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="168.4" y="177.8" width="9" height="10.4" fill="#c00"/>
|
||||
<line x1="187.9" y1="182.5" x2="187.9" y2="207.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="183.4" y="188.2" width="9" height="13.0" fill="#c00"/>
|
||||
<line x1="202.9" y1="195.5" x2="202.9" y2="217.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="198.4" y="201.2" width="9" height="10.4" fill="#c00"/>
|
||||
<line x1="217.9" y1="205.9" x2="217.9" y2="228.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="213.4" y="211.6" width="9" height="10.4" fill="#c00"/>
|
||||
<line x1="232.9" y1="216.3" x2="232.9" y2="238.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="228.4" y="222.0" width="9" height="10.4" fill="#c00"/>
|
||||
<line x1="247.9" y1="226.7" x2="247.9" y2="246.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="243.4" y="232.4" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="262.9" y1="234.5" x2="262.9" y2="256.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="258.4" y="240.2" width="9" height="10.4" fill="#c00"/>
|
||||
<line x1="277.9" y1="244.9" x2="277.9" y2="264.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="273.4" y="250.6" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="292.9" y1="252.7" x2="292.9" y2="272.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="288.4" y="258.4" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="307.9" y1="250.1" x2="307.9" y2="272.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="303.4" y="255.8" width="9" height="10.4" fill="#188a3e"/>
|
||||
<line x1="322.9" y1="250.1" x2="322.9" y2="269.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="318.4" y="255.8" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="337.9" y1="257.9" x2="337.9" y2="277.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="333.4" y="263.6" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="352.9" y1="265.7" x2="352.9" y2="285.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="348.4" y="271.4" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="367.9" y1="273.5" x2="367.9" y2="293.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="363.4" y="279.2" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="382.9" y1="270.9" x2="382.9" y2="293.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="378.4" y="276.6" width="9" height="10.4" fill="#188a3e"/>
|
||||
<line x1="397.9" y1="270.9" x2="397.9" y2="290.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="393.4" y="276.6" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="412.9" y1="278.7" x2="412.9" y2="298.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="408.4" y="284.4" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="427.9" y1="278.7" x2="427.9" y2="298.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="423.4" y="284.4" width="9" height="7.8" fill="#188a3e"/>
|
||||
<line x1="442.9" y1="278.7" x2="442.9" y2="298.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="438.4" y="284.4" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="457.9" y1="286.5" x2="457.9" y2="303.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="453.4" y="292.2" width="9" height="5.2" fill="#c00"/>
|
||||
<line x1="472.9" y1="283.9" x2="472.9" y2="303.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="468.4" y="289.6" width="9" height="7.8" fill="#188a3e"/>
|
||||
<line x1="487.9" y1="283.9" x2="487.9" y2="303.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="483.4" y="289.6" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="502.9" y1="292.2" x2="502.9" y2="315.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="498.4" y="297.4" width="9" height="5.2" fill="#c00"/>
|
||||
<line x1="517.9" y1="289.1" x2="517.9" y2="308.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="513.4" y="294.8" width="9" height="7.8" fill="#188a3e"/>
|
||||
<line x1="532.9" y1="281.3" x2="532.9" y2="301.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="528.4" y="287.0" width="9" height="7.8" fill="#188a3e"/>
|
||||
<line x1="24" y1="517.8" x2="669" y2="517.8" stroke="#888"/>
|
||||
<rect x="63.4" y="460.3" width="9" height="57.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="78.4" y="462.8" width="9" height="55.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="93.4" y="457.8" width="9" height="60.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="108.4" y="461.6" width="9" height="56.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="123.4" y="464.1" width="9" height="53.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="138.4" y="459.1" width="9" height="58.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="153.4" y="462.8" width="9" height="55.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="168.4" y="465.3" width="9" height="52.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="183.4" y="461.6" width="9" height="56.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="198.4" y="466.6" width="9" height="51.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="213.4" y="467.8" width="9" height="50.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="228.4" y="465.3" width="9" height="52.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="243.4" y="469.1" width="9" height="48.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="258.4" y="466.6" width="9" height="51.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="273.4" y="470.3" width="9" height="47.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="288.4" y="462.8" width="9" height="55.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="303.4" y="472.8" width="9" height="45.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="318.4" y="470.3" width="9" height="47.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="333.4" y="474.1" width="9" height="43.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="348.4" y="471.6" width="9" height="46.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="363.4" y="475.3" width="9" height="42.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="378.4" y="467.8" width="9" height="50.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="393.4" y="476.6" width="9" height="41.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="408.4" y="472.8" width="9" height="45.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="423.4" y="477.8" width="9" height="40.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="438.4" y="474.1" width="9" height="43.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="453.4" y="479.1" width="9" height="38.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="468.4" y="475.3" width="9" height="42.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="483.4" y="476.6" width="9" height="41.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="498.4" y="457.8" width="9" height="60.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="513.4" y="462.8" width="9" height="55.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="528.4" y="460.3" width="9" height="57.5" fill="#188a3e" opacity="0.55"/>
|
||||
<text x="24" y="451.8" fill="#555">volum</text>
|
||||
<line x1="157.9" y1="80.0" x2="214.4" y2="194.7" stroke="#c00" stroke-width="1.8"/>
|
||||
<polygon points="217.9,201.9 210.8,196.5 218.0,192.9" fill="#c00"/>
|
||||
<text x="157.9" y="47.0" fill="#c00" text-anchor="middle" style="font-weight:bold">close 51.60 = 7.50 % peste suport</text>
|
||||
<text x="157.9" y="61.0" fill="#c00" text-anchor="middle" style="font-weight:bold">prea departe: până acolo prețul mai are de căzut,</text>
|
||||
<text x="157.9" y="75.0" fill="#c00" text-anchor="middle" style="font-weight:bold">deci nivelul nu-l poate opri acum</text>
|
||||
<line x1="197.9" y1="380.8" x2="510.1" y2="314.5" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<polygon points="517.9,312.8 510.9,318.4 509.2,310.6" fill="#188a3e"/>
|
||||
<text x="197.9" y="394.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">close 48.80 = 1.67 % peste suport</text>
|
||||
<text x="197.9" y="408.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">la nivel: dacă mai scade puțin, dă de ordinele</text>
|
||||
<text x="197.9" y="422.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">de cumpărare care au mai întors prețul de acolo</text>
|
||||
<text x="24" y="548" fill="#555">Pragul de 3 % (cu 4 % „cam departe”) e al cursului; seria și prețurile sunt construite, la</text>
|
||||
<text x="24" y="565" fill="#555">scară, iar procentele sunt calculate din serie. În capitolul Buy Doji, pragul de 1-2 % măsoară</text>
|
||||
<text x="24" y="582" fill="#555">altceva: low-ul doji-ului față de nivel, nu închiderea simbolului.</text>
|
||||
<text x="230" y="300.9" fill="#1a5fb4" style="font-weight:bold">banda de 3 %: înăuntru simbolul e „la nivel”</text></svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
@@ -18,7 +18,7 @@ Rulare: .venv/bin/python gen/strategii/selectia_scor.py
|
||||
import html
|
||||
from pathlib import Path
|
||||
|
||||
W, H = 700, 610
|
||||
W, H = 700, 546
|
||||
|
||||
BLACK = "#000000"
|
||||
GRAY = "#777777"
|
||||
@@ -111,7 +111,8 @@ p.append(rect(X12, BAR_Y - 6, X13 - X12, BAR_H + 12, "spuma",
|
||||
p.append(line(X7, BAR_Y - 10, X7, BAR_Y + BAR_H + 6, YELLOW, 2.4, "4 3"))
|
||||
# în interiorul barei, numele componentelor
|
||||
add((BAR_X0 + X_SPLIT) / 2, BAR_Y + BAR_H / 2 + 5, "F-score", 15, "bold", BLUE)
|
||||
add((X_SPLIT + BAR_X1) / 2, BAR_Y + BAR_H / 2 + 5, "value-score", 15, "bold", ORANGE)
|
||||
# eticheta stă în stânga casetei punctate 12-13, altfel se suprapune peste ea
|
||||
add((X_SPLIT + X12) / 2, BAR_Y + BAR_H / 2 + 5, "value-score", 15, "bold", ORANGE)
|
||||
|
||||
# ---- scale: tick-uri + numere 0..14 sub bară
|
||||
for i in range(15):
|
||||
@@ -159,7 +160,7 @@ add(60, 430, "Scor -1 = date indisponibile în platformă, NU scor 0.",
|
||||
14, "bold", BLACK, "start")
|
||||
add(60, 450, "Scorul -1 nu se citește ca 0.", 13, "normal", GRAY, "start")
|
||||
add(60, 470,
|
||||
"16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:45-46, 268-269.",
|
||||
"Îl vezi în coloana de scor a scanerului; dai refresh și îl recitești.",
|
||||
13, "normal", GRAY, "start")
|
||||
add(60, 498,
|
||||
"„peste 7-8” e formularea exactă a cursului. Sub 7 NU e excludere:",
|
||||
@@ -168,17 +169,6 @@ add(60, 518,
|
||||
"la 4/14 și 6/14 continuă analiza; scorul departajează candidații.",
|
||||
13, "normal", GRAY, "start")
|
||||
|
||||
# ---- surse
|
||||
add(W / 2, 556,
|
||||
"Surse: 08_ANALIZA_ZILNICA/11_selectia_simbolului.md:158-164, :199-204;",
|
||||
13, "normal", GRAY)
|
||||
add(W / 2, 574,
|
||||
"16_ANALIZA_FUNDAMENTALA/08_piotrowski_f_score.md:70-72;",
|
||||
13, "normal", GRAY)
|
||||
add(W / 2, 592,
|
||||
"16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:45-46, 268-269.",
|
||||
13, "normal", GRAY)
|
||||
|
||||
# =============================================================== EMITERE
|
||||
head = (f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" '
|
||||
f'width="{W}" height="{H}" font-family="system-ui, sans-serif" role="img" '
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 610" width="700" height="610" font-family="system-ui, sans-serif" role="img" aria-label="Scala ATM score 0-14: F-score 0-9 la care se adauga value-score 0-5; pragurile 7 (galben), 7-8 intrare in analiza, 12-13 spuma, 14 maxim">
|
||||
<rect x="0" y="0" width="700" height="610" fill="#ffffff"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 546" width="700" height="546" font-family="system-ui, sans-serif" role="img" aria-label="Scala ATM score 0-14: F-score 0-9 la care se adauga value-score 0-5; pragurile 7 (galben), 7-8 intrare in analiza, 12-13 spuma, 14 maxim">
|
||||
<rect x="0" y="0" width="700" height="546" fill="#ffffff"/>
|
||||
<rect x="60.0" y="150.0" width="372.9" height="48.0" fill="#eef2fb" stroke="#1a5fb4" stroke-width="1.8"/>
|
||||
<rect x="432.9" y="150.0" width="207.1" height="48.0" fill="#fdf0e0" stroke="#b06000" stroke-width="1.8"/>
|
||||
<line x1="432.9" y1="150.0" x2="432.9" y2="198.0" stroke="#000000" stroke-width="1.2" stroke-dasharray="3 3"/>
|
||||
@@ -35,7 +35,7 @@
|
||||
<text x="536.4" y="112.0" font-size="15" font-weight="bold" fill="#b06000" text-anchor="middle">value-score 0-5</text>
|
||||
<text x="536.4" y="131.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">5/14 din bară</text>
|
||||
<text x="246.4" y="179.0" font-size="15" font-weight="bold" fill="#1a5fb4" text-anchor="middle">F-score</text>
|
||||
<text x="536.4" y="179.0" font-size="15" font-weight="bold" fill="#b06000" text-anchor="middle">value-score</text>
|
||||
<text x="495.0" y="179.0" font-size="15" font-weight="bold" fill="#b06000" text-anchor="middle">value-score</text>
|
||||
<text x="60.0" y="224.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">0</text>
|
||||
<text x="101.4" y="224.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">1</text>
|
||||
<text x="142.9" y="224.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">2</text>
|
||||
@@ -68,10 +68,7 @@
|
||||
<text x="391.4" y="376.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">puternic</text>
|
||||
<text x="60.0" y="430.0" font-size="14" font-weight="bold" fill="#000000" text-anchor="start">Scor -1 = date indisponibile în platformă, NU scor 0.</text>
|
||||
<text x="60.0" y="450.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Scorul -1 nu se citește ca 0.</text>
|
||||
<text x="60.0" y="470.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:45-46, 268-269.</text>
|
||||
<text x="60.0" y="470.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Îl vezi în coloana de scor a scanerului; dai refresh și îl recitești.</text>
|
||||
<text x="60.0" y="498.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">„peste 7-8” e formularea exactă a cursului. Sub 7 NU e excludere:</text>
|
||||
<text x="60.0" y="518.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">la 4/14 și 6/14 continuă analiza; scorul departajează candidații.</text>
|
||||
<text x="350.0" y="556.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">Surse: 08_ANALIZA_ZILNICA/11_selectia_simbolului.md:158-164, :199-204;</text>
|
||||
<text x="350.0" y="574.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">16_ANALIZA_FUNDAMENTALA/08_piotrowski_f_score.md:70-72;</text>
|
||||
<text x="350.0" y="592.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">16_ANALIZA_FUNDAMENTALA/09_implementare_f_score_tradestation.md:45-46, 268-269.</text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 7.9 KiB |
153
gen/strategii/selectia_sectoare.py
Normal file
@@ -0,0 +1,153 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Pasul 3 — sectorul care domină: numeri semnalele pe sectoare.
|
||||
|
||||
Diagramă conceptuală (NU grafic de preț), pentru
|
||||
`summaries/17_STRATEGII/04_selectia.md`, pasul 3. Cele 11 sectoare S&P, cu
|
||||
câte semnale a dat scanerul în fiecare într-o singură zi; sectorul cu cele mai
|
||||
multe e evidențiat, pentru că acolo intră banii.
|
||||
|
||||
Ce vine din material: cele 11 sectoare S&P și ETF-urile lor, regula „uită-te
|
||||
ce predomină, în ce sectoare" și sortarea sectoarelor după cadranul 1 plus
|
||||
valoarea relative strength. Ce e al meu: **numărul de semnale din fiecare
|
||||
sector**. Cursul nu dă o zi cu cifre pe sectoare, așa că le-am construit; ele
|
||||
ilustrează operațiunea (numărarea), nu o zi reală de piață. Scrie asta și în
|
||||
desen, ca să nu fie luate drept date.
|
||||
|
||||
Nu folosește `svg_candles`: SVG-ul e construit ca string, doar stdlib.
|
||||
|
||||
Rulare: python3 gen/strategii/selectia_sectoare.py
|
||||
"""
|
||||
import html
|
||||
from pathlib import Path
|
||||
|
||||
W, H = 700, 620
|
||||
|
||||
BLACK, GRAY, RED, GREEN, BLUE, ORANGE = "#000000", "#777777", "#c00", "#188a3e", "#1a5fb4", "#b06000"
|
||||
BLUE_BG = "#eef3fb"
|
||||
|
||||
# (sector, ETF, semnale — numărul e construit de mine)
|
||||
SECTOARE = [
|
||||
("Sănătate", "XLV", 9),
|
||||
("Energie", "XLE", 6),
|
||||
("Financiar", "XLF", 5),
|
||||
("Real estate", "XLRE", 4),
|
||||
("Tehnologie", "XLK", 3),
|
||||
("Industrial", "XLI", 3),
|
||||
("Consum de bază", "XLP", 2),
|
||||
("Consum discreționar", "XLY", 2),
|
||||
("Utilități", "XLU", 1),
|
||||
("Materiale", "XLB", 1),
|
||||
("Comunicații", "XLC", 1),
|
||||
]
|
||||
|
||||
X_NUME = 40.0
|
||||
X0, X1 = 250.0, 600.0 # zona barelor
|
||||
Y0, ROW = 132.0, 30.0
|
||||
|
||||
TEXTS = []
|
||||
|
||||
|
||||
def add(x, y, s, size=13, weight="normal", fill=BLACK, anchor="middle"):
|
||||
TEXTS.append((x, y, s, size, weight, fill, anchor))
|
||||
|
||||
|
||||
def est_w(s, size, weight):
|
||||
return len(s) * size * (0.62 if weight == "bold" else 0.56)
|
||||
|
||||
|
||||
def txt(x, y, s, size, weight, fill, anchor):
|
||||
return (f'<text x="{x:.1f}" y="{y:.1f}" font-size="{size}" font-weight="{weight}" '
|
||||
f'fill="{fill}" text-anchor="{anchor}">{html.escape(s, quote=False)}</text>')
|
||||
|
||||
|
||||
p = []
|
||||
MAXS = max(s for *_, s in SECTOARE)
|
||||
assert SECTOARE[0][2] == MAXS, "prima linie trebuie să fie sectorul dominant"
|
||||
assert sum(1 for *_, s in SECTOARE if s == MAXS) == 1, "dominantul nu e unic"
|
||||
assert len(SECTOARE) == 11, "S&P are 11 sectoare"
|
||||
assert all(a[2] >= b[2] for a, b in zip(SECTOARE, SECTOARE[1:])), "lista nu e sortată descrescător"
|
||||
|
||||
add(W / 2, 34, "Pasul 3 — din ce sector vin cele mai multe semnale", 20, "bold")
|
||||
add(W / 2, 58, "cele 11 sectoare S&P, cu semnalele scanerului dintr-o singură zi",
|
||||
13, "normal", GRAY)
|
||||
add(W / 2, 78, "de ce: mai multe semnale în același sector = cineva mută bani acolo",
|
||||
13, "normal", GRAY)
|
||||
add(X_NUME, 110, "sector (ETF)", 13, "bold", GRAY, "start")
|
||||
add(X0, 110, "semnale în ziua asta", 13, "bold", GRAY, "start")
|
||||
|
||||
# dreptunghiul de evidențiere peste sectorul dominant
|
||||
p.append(f'<rect x="{X_NUME - 8:.1f}" y="{Y0 - 20:.1f}" width="{X1 - X_NUME + 60:.1f}" '
|
||||
f'height="{ROW:.1f}" fill="{BLUE_BG}" stroke="{BLUE}" stroke-width="1.6"/>')
|
||||
|
||||
for i, (nume, etf, n) in enumerate(SECTOARE):
|
||||
y = Y0 + i * ROW
|
||||
dominant = n == MAXS
|
||||
col = BLUE if dominant else GRAY
|
||||
add(X_NUME, y, f"{nume} ({etf})", 13, "bold" if dominant else "normal", col, "start")
|
||||
w = n / MAXS * (X1 - X0)
|
||||
p.append(f'<rect x="{X0:.1f}" y="{y - 12:.1f}" width="{w:.1f}" height="16" '
|
||||
f'fill="{col}" fill-opacity="{0.85 if dominant else 0.35}"/>')
|
||||
add(X0 + w + 8, y, str(n), 13, "bold" if dominant else "normal", col, "start")
|
||||
|
||||
# săgeata care spune de ce
|
||||
Y_ARR = Y0 - 6
|
||||
p.append(f'<path d="M {X1 + 46:.1f} {Y_ARR:.1f} L {X1 + 76:.1f} {Y_ARR - 26:.1f}" '
|
||||
f'stroke="{BLUE}" stroke-width="2" fill="none"/>')
|
||||
add(X1 + 80, Y_ARR - 30, "aici te uiți", 13, "bold", BLUE, "end")
|
||||
|
||||
Y_NOTE = Y0 + len(SECTOARE) * ROW + 26
|
||||
p.append(f'<rect x="40" y="{Y_NOTE:.1f}" width="620" height="96" fill="#fdf0e0" '
|
||||
f'stroke="{ORANGE}" stroke-width="1.6" rx="8"/>')
|
||||
add(60, Y_NOTE + 26, "Ce faci cu asta", 15, "bold", ORANGE, "start")
|
||||
add(60, Y_NOTE + 48, "Păstrezi simbolurile din sectorul dominant și le duci mai departe la pasul 4;",
|
||||
13, "normal", BLACK, "start")
|
||||
add(60, Y_NOTE + 66, "restul le lași pentru azi. Sectoarele se mai sortează și după cadranul 1 plus",
|
||||
13, "normal", BLACK, "start")
|
||||
add(60, Y_NOTE + 84, "valoarea relative strength — aceleași cadrane ca la pasul 5.",
|
||||
13, "normal", BLACK, "start")
|
||||
|
||||
add(W / 2, H - 14, "Numărul de semnale pe sector e construit de mine: cursul dă regula, nu o zi cu cifre.",
|
||||
13, "normal", GRAY)
|
||||
|
||||
head = (f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" width="{W}" '
|
||||
f'height="{H}" font-family="system-ui, sans-serif" role="img" '
|
||||
f'aria-label="Cele 11 sectoare S&P sortate dupa cate semnale a dat scanerul '
|
||||
f'in fiecare, cu sectorul dominant evidentiat">')
|
||||
body = [head, f'<rect x="0" y="0" width="{W}" height="{H}" fill="#ffffff"/>'] + p
|
||||
body += [txt(*t) for t in TEXTS]
|
||||
body.append("</svg>")
|
||||
svg = "\n".join(body) + "\n"
|
||||
|
||||
# =============================================================== VERIFICARE
|
||||
# lungimea barei e proporțională cu numărul din etichetă
|
||||
for i, (nume, etf, n) in enumerate(SECTOARE):
|
||||
w = n / MAXS * (X1 - X0)
|
||||
assert abs(w / (X1 - X0) - n / MAXS) < 1e-9, f"{nume}: bara nu e la scară"
|
||||
assert X0 + w <= X1 + 1e-9, f"{nume}: bara iese din zona ei"
|
||||
|
||||
# etichete în pânză, fără suprapuneri
|
||||
boxes = []
|
||||
for x, y, s, size, weight, fill, anchor in TEXTS:
|
||||
assert size >= 13, f"font sub 13px: {s!r}"
|
||||
w = est_w(s, size, weight)
|
||||
left = x - w if anchor == "end" else (x - w / 2 if anchor == "middle" else x)
|
||||
assert -2 <= left and left + w <= W + 2, f"text în afara pânzei: {s!r}"
|
||||
assert 0 <= y - size * 0.78 and y + size * 0.22 <= H, f"text în afara pânzei: {s!r}"
|
||||
boxes.append((left, left + w, y - size * 0.78, y + size * 0.22, s))
|
||||
for i in range(len(boxes)):
|
||||
for j in range(i + 1, len(boxes)):
|
||||
l1, r1, t1, b1, s1 = boxes[i]
|
||||
l2, r2, t2, b2, s2 = boxes[j]
|
||||
if r1 > l2 + 2 and r2 > l1 + 2 and b1 > t2 + 2 and b2 > t1 + 2:
|
||||
raise AssertionError(f"etichete suprapuse: {s1!r} / {s2!r}")
|
||||
|
||||
# numele de sector nu intră peste zona barelor
|
||||
for x, y, s, size, weight, fill, anchor in TEXTS:
|
||||
if anchor == "start" and x == X_NUME and y >= Y0:
|
||||
assert x + est_w(s, size, weight) < X0 - 6, f"numele iese peste bare: {s!r}"
|
||||
|
||||
assert "\n\n" not in svg, "linie goală în SVG"
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT.name} ({len(svg)} bytes, {len(TEXTS)} etichete, "
|
||||
f"{len(SECTOARE)} sectoare, dominant {SECTOARE[0][0]} cu {MAXS}, {W}x{H}), verificare OK")
|
||||
50
gen/strategii/selectia_sectoare.svg
Normal file
@@ -0,0 +1,50 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 620" width="700" height="620" font-family="system-ui, sans-serif" role="img" aria-label="Cele 11 sectoare S&P sortate dupa cate semnale a dat scanerul in fiecare, cu sectorul dominant evidentiat">
|
||||
<rect x="0" y="0" width="700" height="620" fill="#ffffff"/>
|
||||
<rect x="32.0" y="112.0" width="620.0" height="30.0" fill="#eef3fb" stroke="#1a5fb4" stroke-width="1.6"/>
|
||||
<rect x="250.0" y="120.0" width="350.0" height="16" fill="#1a5fb4" fill-opacity="0.85"/>
|
||||
<rect x="250.0" y="150.0" width="233.3" height="16" fill="#777777" fill-opacity="0.35"/>
|
||||
<rect x="250.0" y="180.0" width="194.4" height="16" fill="#777777" fill-opacity="0.35"/>
|
||||
<rect x="250.0" y="210.0" width="155.6" height="16" fill="#777777" fill-opacity="0.35"/>
|
||||
<rect x="250.0" y="240.0" width="116.7" height="16" fill="#777777" fill-opacity="0.35"/>
|
||||
<rect x="250.0" y="270.0" width="116.7" height="16" fill="#777777" fill-opacity="0.35"/>
|
||||
<rect x="250.0" y="300.0" width="77.8" height="16" fill="#777777" fill-opacity="0.35"/>
|
||||
<rect x="250.0" y="330.0" width="77.8" height="16" fill="#777777" fill-opacity="0.35"/>
|
||||
<rect x="250.0" y="360.0" width="38.9" height="16" fill="#777777" fill-opacity="0.35"/>
|
||||
<rect x="250.0" y="390.0" width="38.9" height="16" fill="#777777" fill-opacity="0.35"/>
|
||||
<rect x="250.0" y="420.0" width="38.9" height="16" fill="#777777" fill-opacity="0.35"/>
|
||||
<path d="M 646.0 126.0 L 676.0 100.0" stroke="#1a5fb4" stroke-width="2" fill="none"/>
|
||||
<rect x="40" y="488.0" width="620" height="96" fill="#fdf0e0" stroke="#b06000" stroke-width="1.6" rx="8"/>
|
||||
<text x="350.0" y="34.0" font-size="20" font-weight="bold" fill="#000000" text-anchor="middle">Pasul 3 — din ce sector vin cele mai multe semnale</text>
|
||||
<text x="350.0" y="58.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">cele 11 sectoare S&P, cu semnalele scanerului dintr-o singură zi</text>
|
||||
<text x="350.0" y="78.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">de ce: mai multe semnale în același sector = cineva mută bani acolo</text>
|
||||
<text x="40.0" y="110.0" font-size="13" font-weight="bold" fill="#777777" text-anchor="start">sector (ETF)</text>
|
||||
<text x="250.0" y="110.0" font-size="13" font-weight="bold" fill="#777777" text-anchor="start">semnale în ziua asta</text>
|
||||
<text x="40.0" y="132.0" font-size="13" font-weight="bold" fill="#1a5fb4" text-anchor="start">Sănătate (XLV)</text>
|
||||
<text x="608.0" y="132.0" font-size="13" font-weight="bold" fill="#1a5fb4" text-anchor="start">9</text>
|
||||
<text x="40.0" y="162.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Energie (XLE)</text>
|
||||
<text x="491.3" y="162.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">6</text>
|
||||
<text x="40.0" y="192.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Financiar (XLF)</text>
|
||||
<text x="452.4" y="192.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">5</text>
|
||||
<text x="40.0" y="222.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Real estate (XLRE)</text>
|
||||
<text x="413.6" y="222.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">4</text>
|
||||
<text x="40.0" y="252.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Tehnologie (XLK)</text>
|
||||
<text x="374.7" y="252.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">3</text>
|
||||
<text x="40.0" y="282.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Industrial (XLI)</text>
|
||||
<text x="374.7" y="282.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">3</text>
|
||||
<text x="40.0" y="312.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Consum de bază (XLP)</text>
|
||||
<text x="335.8" y="312.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">2</text>
|
||||
<text x="40.0" y="342.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Consum discreționar (XLY)</text>
|
||||
<text x="335.8" y="342.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">2</text>
|
||||
<text x="40.0" y="372.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Utilități (XLU)</text>
|
||||
<text x="296.9" y="372.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">1</text>
|
||||
<text x="40.0" y="402.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Materiale (XLB)</text>
|
||||
<text x="296.9" y="402.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">1</text>
|
||||
<text x="40.0" y="432.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">Comunicații (XLC)</text>
|
||||
<text x="296.9" y="432.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">1</text>
|
||||
<text x="680.0" y="96.0" font-size="13" font-weight="bold" fill="#1a5fb4" text-anchor="end">aici te uiți</text>
|
||||
<text x="60.0" y="514.0" font-size="15" font-weight="bold" fill="#b06000" text-anchor="start">Ce faci cu asta</text>
|
||||
<text x="60.0" y="536.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">Păstrezi simbolurile din sectorul dominant și le duci mai departe la pasul 4;</text>
|
||||
<text x="60.0" y="554.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">restul le lași pentru azi. Sectoarele se mai sortează și după cadranul 1 plus</text>
|
||||
<text x="60.0" y="572.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">valoarea relative strength — aceleași cadrane ca la pasul 5.</text>
|
||||
<text x="350.0" y="606.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">Numărul de semnale pe sector e construit de mine: cursul dă regula, nu o zi cu cifre.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
194
gen/strategii/selectia_univers.py
Normal file
@@ -0,0 +1,194 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Pasul 1 — universul și lichiditatea: cele două praguri, desenate ca o zonă.
|
||||
|
||||
Diagramă conceptuală (NU grafic de preț), pentru
|
||||
`summaries/17_STRATEGII/04_selectia.md`, pasul 1. Pe orizontală prețul de
|
||||
închidere, pe verticală volumul mediu zilnic. Pragurile cursului (close peste
|
||||
30-40 $, volum mediu de cel puțin 500.000 de acțiuni, ideal peste un milion)
|
||||
taie planul în patru; dreptunghiul verde e singurul colț din care ai voie să
|
||||
iei simboluri.
|
||||
|
||||
Cele trei simboluri sunt anonime (A, B, C) și cu cifre construite de mine:
|
||||
cursul dă pragurile, nu exemple numerice. Le pun ca să se vadă că un simbol
|
||||
poate pica pe oricare din cele două praguri, separat.
|
||||
|
||||
Nu folosește `svg_candles`: SVG-ul e construit ca string, doar stdlib.
|
||||
|
||||
Rulare: python3 gen/strategii/selectia_univers.py
|
||||
"""
|
||||
import html
|
||||
from pathlib import Path
|
||||
|
||||
W, H = 700, 604
|
||||
|
||||
BLACK, GRAY, RED, GREEN, BLUE, ORANGE = "#000000", "#777777", "#c00", "#188a3e", "#1a5fb4", "#b06000"
|
||||
GREEN_BG = "#eef7f0"
|
||||
|
||||
# ---------------------------------------------------------------- praguri (cursul)
|
||||
PRET_MIN, PRET_IDEAL = 30.0, 40.0 # close peste 30-40 $
|
||||
VOL_MIN, VOL_IDEAL = 0.5, 1.0 # milioane de acțiuni pe zi
|
||||
|
||||
# ---------------------------------------------------------------- simboluri (construite)
|
||||
# (nume, preț, volum mediu în milioane, verdict)
|
||||
SIMB = [
|
||||
("A", 58.0, 2.4, "trece"),
|
||||
("B", 24.0, 3.1, "cade pe preț"),
|
||||
("C", 72.0, 0.18, "cade pe volum"),
|
||||
]
|
||||
|
||||
# ---------------------------------------------------------------- geometrie
|
||||
X0, X1 = 110.0, 630.0
|
||||
Y0, Y1 = 130.0, 420.0
|
||||
PMAX, VMAX = 100.0, 3.5
|
||||
|
||||
|
||||
def px(p):
|
||||
return X0 + p / PMAX * (X1 - X0)
|
||||
|
||||
|
||||
def py(v):
|
||||
return Y1 - v / VMAX * (Y1 - Y0)
|
||||
|
||||
|
||||
TEXTS = []
|
||||
|
||||
|
||||
def add(x, y, s, size=13, weight="normal", fill=BLACK, anchor="middle"):
|
||||
TEXTS.append((x, y, s, size, weight, fill, anchor))
|
||||
|
||||
|
||||
def est_w(s, size, weight):
|
||||
return len(s) * size * (0.62 if weight == "bold" else 0.56)
|
||||
|
||||
|
||||
def txt(x, y, s, size, weight, fill, anchor):
|
||||
return (f'<text x="{x:.1f}" y="{y:.1f}" font-size="{size}" font-weight="{weight}" '
|
||||
f'fill="{fill}" text-anchor="{anchor}">{html.escape(s, quote=False)}</text>')
|
||||
|
||||
|
||||
def line(x1, y1, x2, y2, stroke=GRAY, w=1.0, dash=None):
|
||||
d = f' stroke-dasharray="{dash}"' if dash else ""
|
||||
return (f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{x2:.1f}" y2="{y2:.1f}" '
|
||||
f'stroke="{stroke}" stroke-width="{w}"{d}/>')
|
||||
|
||||
|
||||
p = []
|
||||
|
||||
add(W / 2, 34, "Pasul 1 — cine intră în universul de scanare", 20, "bold")
|
||||
add(W / 2, 58, "pe orizontală prețul de închidere, pe verticală volumul mediu zilnic",
|
||||
13, "normal", GRAY)
|
||||
add(W / 2, 78, "de ce pragurile: pe un simbol subțire, ordinul tău mută singur prețul",
|
||||
13, "normal", GRAY)
|
||||
|
||||
# zona verde: singurul colț bun
|
||||
p.append(f'<rect x="{px(PRET_MIN):.1f}" y="{Y0:.1f}" width="{X1 - px(PRET_MIN):.1f}" '
|
||||
f'height="{py(VOL_MIN) - Y0:.1f}" fill="{GREEN_BG}" stroke="{GREEN}" stroke-width="1.8"/>')
|
||||
add(px(PRET_MIN) + 10, Y0 + 22, "zona din care iei simboluri", 14, "bold", GREEN, "start")
|
||||
|
||||
# cadrul și axele
|
||||
p.append(line(X0, Y0, X0, Y1, GRAY, 1.2))
|
||||
p.append(line(X0, Y1, X1, Y1, GRAY, 1.2))
|
||||
|
||||
# pragurile
|
||||
p.append(line(px(PRET_MIN), Y0, px(PRET_MIN), Y1, GREEN, 1.8))
|
||||
p.append(line(px(PRET_IDEAL), Y0, px(PRET_IDEAL), Y1, GREEN, 1.2, "5 3"))
|
||||
p.append(line(X0, py(VOL_MIN), X1, py(VOL_MIN), GREEN, 1.8))
|
||||
p.append(line(X0, py(VOL_IDEAL), X1, py(VOL_IDEAL), GREEN, 1.2, "5 3"))
|
||||
|
||||
add(px(PRET_MIN), Y1 + 38, "30 $", 13, "bold", GREEN)
|
||||
add(px(PRET_IDEAL), Y1 + 56, "40 $ (ideal)", 13, "normal", GREEN)
|
||||
add(X0 - 10, py(VOL_MIN) + 4, "500.000", 13, "bold", GREEN, "end")
|
||||
add(X0 - 10, py(VOL_IDEAL) + 4, "1 milion", 13, "normal", GREEN, "end")
|
||||
|
||||
# repere de axă
|
||||
for v in (0, 1, 2, 3):
|
||||
p.append(line(X0 - 5, py(v), X0, py(v), GRAY, 1.0))
|
||||
add(X0 - 62, py(0) + 4, "0", 13, "normal", GRAY, "end")
|
||||
add(X0 - 62, py(2) + 4, "2 mil.", 13, "normal", GRAY, "end")
|
||||
add(X0 - 62, py(3) + 4, "3 mil.", 13, "normal", GRAY, "end")
|
||||
for pr in (0, 50, 100):
|
||||
p.append(line(px(pr), Y1, px(pr), Y1 + 5, GRAY, 1.0))
|
||||
add(px(pr), Y1 + 20, f"{pr} $", 13, "normal", GRAY)
|
||||
|
||||
add(X1, Y1 + 56, "prețul de închidere", 13, "normal", GRAY, "end")
|
||||
add(X0 - 48, Y0 - 12, "volum mediu zilnic", 13, "normal", GRAY, "start")
|
||||
|
||||
# cele trei simboluri
|
||||
for nume, pret, vol, verdict in SIMB:
|
||||
x, y = px(pret), py(vol)
|
||||
col = GREEN if verdict == "trece" else RED
|
||||
p.append(f'<circle cx="{x:.1f}" cy="{y:.1f}" r="7" fill="{col}"/>')
|
||||
add(x, y - 14, f"Simbol {nume}", 13, "bold", col)
|
||||
add(x, y + 26, f"{pret:.0f} $ · {vol:.2f} mil.", 13, "normal", BLACK)
|
||||
add(x, y + 44, verdict, 13, "bold", col)
|
||||
|
||||
# caseta cu de ce
|
||||
NOTE_Y = 504.0
|
||||
p.append(f'<rect x="40" y="{NOTE_Y}" width="620" height="76" fill="#fdf0e0" '
|
||||
f'stroke="{ORANGE}" stroke-width="1.6" rx="8"/>')
|
||||
add(60, NOTE_Y + 26, "De ce contează amândouă, nu doar una", 15, "bold", ORANGE, "start")
|
||||
add(60, NOTE_Y + 48,
|
||||
"Simbolul B se tranzacționează mult, dar e prea ieftin; simbolul C e scump, dar",
|
||||
13, "normal", BLACK, "start")
|
||||
add(60, NOTE_Y + 66,
|
||||
"aproape nimeni nu-l cumpără: acolo ordinul tău e cel care mișcă prețul.",
|
||||
13, "normal", BLACK, "start")
|
||||
|
||||
head = (f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" width="{W}" '
|
||||
f'height="{H}" font-family="system-ui, sans-serif" role="img" '
|
||||
f'aria-label="Pragurile de pret si de volum ale universului de scanare, '
|
||||
f'cu trei simboluri dintre care doar unul cade in zona buna">')
|
||||
body = [head, f'<rect x="0" y="0" width="{W}" height="{H}" fill="#ffffff"/>'] + p
|
||||
body += [txt(*t) for t in TEXTS]
|
||||
body.append("</svg>")
|
||||
svg = "\n".join(body) + "\n"
|
||||
|
||||
# =============================================================== VERIFICARE
|
||||
# 1. verdictul fiecărui simbol iese din cifrele lui, nu e scris de mână
|
||||
for nume, pret, vol, verdict in SIMB:
|
||||
trece = pret >= PRET_MIN and vol >= VOL_MIN
|
||||
assert trece == (verdict == "trece"), f"Simbol {nume}: verdictul nu iese din cifre"
|
||||
if verdict == "cade pe preț":
|
||||
assert pret < PRET_MIN and vol >= VOL_MIN, f"Simbol {nume} nu cade doar pe preț"
|
||||
if verdict == "cade pe volum":
|
||||
assert vol < VOL_MIN and pret >= PRET_MIN, f"Simbol {nume} nu cade doar pe volum"
|
||||
assert sum(1 for *_, v in SIMB if v == "trece") == 1, "aștept exact un simbol care trece"
|
||||
|
||||
# 2. zona verde e exact colțul „peste ambele praguri"
|
||||
assert px(PRET_MIN) > X0 and py(VOL_MIN) < Y1, "zona verde nu e un colț al planului"
|
||||
for nume, pret, vol, verdict in SIMB:
|
||||
inauntru = px(PRET_MIN) <= px(pret) <= X1 and Y0 <= py(vol) <= py(VOL_MIN)
|
||||
assert inauntru == (verdict == "trece"), f"Simbol {nume}: punctul nu e desenat în zona lui"
|
||||
|
||||
# 3. toate punctele încap în cadru
|
||||
for nume, pret, vol, _ in SIMB:
|
||||
assert X0 < px(pret) < X1, f"Simbol {nume}: prețul iese din cadru"
|
||||
assert Y0 < py(vol) < Y1, f"Simbol {nume}: volumul iese din cadru"
|
||||
|
||||
# 4. liniile de prag nu cad pe marginea cadrului
|
||||
for x in (px(PRET_MIN), px(PRET_IDEAL)):
|
||||
assert x - X0 > 20 and X1 - x > 20, "linie de prag lipită de marginea cadrului"
|
||||
for y in (py(VOL_MIN), py(VOL_IDEAL)):
|
||||
assert y - Y0 > 20 and Y1 - y > 20, "linie de prag lipită de marginea cadrului"
|
||||
|
||||
# 5. etichete în pânză și fără suprapuneri
|
||||
boxes = []
|
||||
for x, y, s, size, weight, fill, anchor in TEXTS:
|
||||
assert size >= 13, f"font sub 13px: {s!r}"
|
||||
w = est_w(s, size, weight)
|
||||
left = x - w if anchor == "end" else (x - w / 2 if anchor == "middle" else x)
|
||||
assert -2 <= left and left + w <= W + 2, f"text în afara pânzei: {s!r}"
|
||||
assert 0 <= y - size * 0.78 and y + size * 0.22 <= H, f"text în afara pânzei: {s!r}"
|
||||
boxes.append((left, left + w, y - size * 0.78, y + size * 0.22, s))
|
||||
for i in range(len(boxes)):
|
||||
for j in range(i + 1, len(boxes)):
|
||||
l1, r1, t1, b1, s1 = boxes[i]
|
||||
l2, r2, t2, b2, s2 = boxes[j]
|
||||
if r1 > l2 + 2 and r2 > l1 + 2 and b1 > t2 + 2 and b2 > t1 + 2:
|
||||
raise AssertionError(f"etichete suprapuse: {s1!r} / {s2!r}")
|
||||
|
||||
assert "\n\n" not in svg, "linie goală în SVG"
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT.name} ({len(svg)} bytes, {len(TEXTS)} etichete, "
|
||||
f"{len(SIMB)} simboluri, {W}x{H}), verificare OK")
|
||||
49
gen/strategii/selectia_univers.svg
Normal file
@@ -0,0 +1,49 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 604" width="700" height="604" font-family="system-ui, sans-serif" role="img" aria-label="Pragurile de pret si de volum ale universului de scanare, cu trei simboluri dintre care doar unul cade in zona buna">
|
||||
<rect x="0" y="0" width="700" height="604" fill="#ffffff"/>
|
||||
<rect x="266.0" y="130.0" width="364.0" height="248.6" fill="#eef7f0" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<line x1="110.0" y1="130.0" x2="110.0" y2="420.0" stroke="#777777" stroke-width="1.2"/>
|
||||
<line x1="110.0" y1="420.0" x2="630.0" y2="420.0" stroke="#777777" stroke-width="1.2"/>
|
||||
<line x1="266.0" y1="130.0" x2="266.0" y2="420.0" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<line x1="318.0" y1="130.0" x2="318.0" y2="420.0" stroke="#188a3e" stroke-width="1.2" stroke-dasharray="5 3"/>
|
||||
<line x1="110.0" y1="378.6" x2="630.0" y2="378.6" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<line x1="110.0" y1="337.1" x2="630.0" y2="337.1" stroke="#188a3e" stroke-width="1.2" stroke-dasharray="5 3"/>
|
||||
<line x1="105.0" y1="420.0" x2="110.0" y2="420.0" stroke="#777777" stroke-width="1.0"/>
|
||||
<line x1="105.0" y1="337.1" x2="110.0" y2="337.1" stroke="#777777" stroke-width="1.0"/>
|
||||
<line x1="105.0" y1="254.3" x2="110.0" y2="254.3" stroke="#777777" stroke-width="1.0"/>
|
||||
<line x1="105.0" y1="171.4" x2="110.0" y2="171.4" stroke="#777777" stroke-width="1.0"/>
|
||||
<line x1="110.0" y1="420.0" x2="110.0" y2="425.0" stroke="#777777" stroke-width="1.0"/>
|
||||
<line x1="370.0" y1="420.0" x2="370.0" y2="425.0" stroke="#777777" stroke-width="1.0"/>
|
||||
<line x1="630.0" y1="420.0" x2="630.0" y2="425.0" stroke="#777777" stroke-width="1.0"/>
|
||||
<circle cx="411.6" cy="221.1" r="7" fill="#188a3e"/>
|
||||
<circle cx="234.8" cy="163.1" r="7" fill="#c00"/>
|
||||
<circle cx="484.4" cy="405.1" r="7" fill="#c00"/>
|
||||
<rect x="40" y="504.0" width="620" height="76" fill="#fdf0e0" stroke="#b06000" stroke-width="1.6" rx="8"/>
|
||||
<text x="350.0" y="34.0" font-size="20" font-weight="bold" fill="#000000" text-anchor="middle">Pasul 1 — cine intră în universul de scanare</text>
|
||||
<text x="350.0" y="58.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">pe orizontală prețul de închidere, pe verticală volumul mediu zilnic</text>
|
||||
<text x="350.0" y="78.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">de ce pragurile: pe un simbol subțire, ordinul tău mută singur prețul</text>
|
||||
<text x="276.0" y="152.0" font-size="14" font-weight="bold" fill="#188a3e" text-anchor="start">zona din care iei simboluri</text>
|
||||
<text x="266.0" y="458.0" font-size="13" font-weight="bold" fill="#188a3e" text-anchor="middle">30 $</text>
|
||||
<text x="318.0" y="476.0" font-size="13" font-weight="normal" fill="#188a3e" text-anchor="middle">40 $ (ideal)</text>
|
||||
<text x="100.0" y="382.6" font-size="13" font-weight="bold" fill="#188a3e" text-anchor="end">500.000</text>
|
||||
<text x="100.0" y="341.1" font-size="13" font-weight="normal" fill="#188a3e" text-anchor="end">1 milion</text>
|
||||
<text x="48.0" y="424.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="end">0</text>
|
||||
<text x="48.0" y="258.3" font-size="13" font-weight="normal" fill="#777777" text-anchor="end">2 mil.</text>
|
||||
<text x="48.0" y="175.4" font-size="13" font-weight="normal" fill="#777777" text-anchor="end">3 mil.</text>
|
||||
<text x="110.0" y="440.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">0 $</text>
|
||||
<text x="370.0" y="440.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">50 $</text>
|
||||
<text x="630.0" y="440.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">100 $</text>
|
||||
<text x="630.0" y="476.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="end">prețul de închidere</text>
|
||||
<text x="62.0" y="118.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="start">volum mediu zilnic</text>
|
||||
<text x="411.6" y="207.1" font-size="13" font-weight="bold" fill="#188a3e" text-anchor="middle">Simbol A</text>
|
||||
<text x="411.6" y="247.1" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">58 $ · 2.40 mil.</text>
|
||||
<text x="411.6" y="265.1" font-size="13" font-weight="bold" fill="#188a3e" text-anchor="middle">trece</text>
|
||||
<text x="234.8" y="149.1" font-size="13" font-weight="bold" fill="#c00" text-anchor="middle">Simbol B</text>
|
||||
<text x="234.8" y="189.1" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">24 $ · 3.10 mil.</text>
|
||||
<text x="234.8" y="207.1" font-size="13" font-weight="bold" fill="#c00" text-anchor="middle">cade pe preț</text>
|
||||
<text x="484.4" y="391.1" font-size="13" font-weight="bold" fill="#c00" text-anchor="middle">Simbol C</text>
|
||||
<text x="484.4" y="431.1" font-size="13" font-weight="normal" fill="#000000" text-anchor="middle">72 $ · 0.18 mil.</text>
|
||||
<text x="484.4" y="449.1" font-size="13" font-weight="bold" fill="#c00" text-anchor="middle">cade pe volum</text>
|
||||
<text x="60.0" y="530.0" font-size="15" font-weight="bold" fill="#b06000" text-anchor="start">De ce contează amândouă, nu doar una</text>
|
||||
<text x="60.0" y="552.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">Simbolul B se tranzacționează mult, dar e prea ieftin; simbolul C e scump, dar</text>
|
||||
<text x="60.0" y="570.0" font-size="13" font-weight="normal" fill="#000000" text-anchor="start">aproape nimeni nu-l cumpără: acolo ordinul tău e cel care mișcă prețul.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |