07_mdsrt: capitol reconstruit dupa sablon
Nivelurile 1-2-3, cei 6 pasi cu diagrama fiecare, mini-glosar de 33 de termeni, oglinda pe short cu diagrama ei, checklist. Sursele in fise/07_mdsrt_surse.md. Capitolul avea TREI reguli numerice diferite in acelasi loc: stop fix pe low in ansamblu, 0.10 sub low in aplus si exemplu, plus doua reguli de intrare. Acum mdsrt_ansamblu.py tine seria si regulile, iar picior, trigger, stop, iesire si short le importa — nu mai pot diverge. Noi: zona (daily -> 60 min ca descompunere reala, 2 candele daily = 14 bare, cu caseta, ghidaje si pivotul pe ambele panouri), picior, trigger, stop, iesire, short (seria long rasturnata, deci fiecare cifra are perechea ei). Verificare numerica text-diagrama: trei nepotriviri reparate, inclusiv o cifra din proza care nu exista pe niciun desen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
@@ -161,7 +161,7 @@ if __name__ == "__main__":
|
||||
|
||||
]
|
||||
arrows = [
|
||||
Arrow(TRIG, "Buy Hammer: coadă lungă în jos\nvânzătorii au dus prețul sub nivel\nși nu l-au putut ține acolo",
|
||||
Arrow(TRIG, f"Buy Hammer: close {cds[TRIG].c:.2f}, coadă lungă în jos\nvânzătorii au dus prețul sub nivel\nși nu l-au putut ține acolo",
|
||||
where="below", price=leg2_l, color=RED, dx=210, dy=58),
|
||||
Arrow(CONF, f"intrare {ENTRY:.2f}: intri abia aici,\nla close peste high-ul candelei-trigger",
|
||||
where="above", color=GREEN, dx=40, dy=-44),
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
<text x="314.0" y="445.6" fill="#c00" text-anchor="middle" style="font-weight:bold">piciorul 2: low 589.50</text>
|
||||
<line x1="524.0" y1="514.8" x2="321.4" y2="433.8" stroke="#c00" stroke-width="1.8"/>
|
||||
<polygon points="314.0,430.8 322.9,430.1 319.9,437.5" fill="#c00"/>
|
||||
<text x="524.0" y="528.8" fill="#c00" text-anchor="middle" style="font-weight:bold">Buy Hammer: coadă lungă în jos</text>
|
||||
<text x="524.0" y="528.8" fill="#c00" text-anchor="middle" style="font-weight:bold">Buy Hammer: close 589.80, coadă lungă în jos</text>
|
||||
<text x="524.0" y="542.8" fill="#c00" text-anchor="middle" style="font-weight:bold">vânzătorii au dus prețul sub nivel</text>
|
||||
<text x="524.0" y="556.8" fill="#c00" text-anchor="middle" style="font-weight:bold">și nu l-au putut ține acolo</text>
|
||||
<line x1="369.0" y1="190.0" x2="330.6" y2="376.6" stroke="#188a3e" stroke-width="1.8"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@@ -149,7 +149,7 @@ marks = [
|
||||
Mark(10, "picior 1 = 622.40", BLUE, "below", dy=15),
|
||||
Mark(18, "picior 2 = 621.40 (mai jos) · Buy Hammer", RED, "below"),
|
||||
Mark(18, "hammer închide 622.60, înapoi peste pivot", GREEN, "above", dy=-42),
|
||||
Mark(19, "intri aici: close peste high-ul hammer-ului", GREEN, "above", dy=-62),
|
||||
Mark(19, "intri aici: close peste high-ul hammer-ului (622.70)", GREEN, "above", dy=-62),
|
||||
]
|
||||
|
||||
ch = Chart(
|
||||
@@ -185,6 +185,7 @@ assert "sunt reale, din curs" in svg and "construcția mea" in svg, \
|
||||
for eticheta in ("pivot daily 622.00", "picior 1 = 622.40",
|
||||
"picior 2 = 621.40 (mai jos) · Buy Hammer",
|
||||
"hammer închide 622.60, înapoi peste pivot",
|
||||
"intri aici: close peste high-ul hammer-ului (622.70)",
|
||||
"intrare 623.00 (construit)", "SL 621.30 (construit)",
|
||||
"TP1 624.70 = 1:1 (construit)"):
|
||||
assert eticheta in svg, f"lipsește eticheta: {eticheta!r}"
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
<text x="194.0" y="386.7" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">picior 1 = 622.40</text>
|
||||
<text x="314.0" y="430.6" fill="#c00" text-anchor="middle" style="font-weight:bold">picior 2 = 621.40 (mai jos) · Buy Hammer</text>
|
||||
<text x="314.0" y="278.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">hammer închide 622.60, înapoi peste pivot</text>
|
||||
<text x="329.0" y="232.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">intri aici: close peste high-ul hammer-ului</text>
|
||||
<text x="329.0" y="232.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">intri aici: close peste high-ul hammer-ului (622.70)</text>
|
||||
<text x="24" y="555.0" fill="#555">Legendă: nivelurile 622.40 / 622.00 / 621.40 / 622.60 și cele 8 candele dintre</text>
|
||||
<text x="24" y="572.0" fill="#555">picioare sunt reale, din curs. Intrarea 623.00, SL-ul 621.30 și TP-ul 624.70</text>
|
||||
<text x="24" y="589.0" fill="#555">sunt construcția mea — materialul nu le dă.</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
96
gen/strategii/mdsrt_iesire.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""MDSRT, Pasul 6 — ieșirea: TP1 la 1:1, breakeven, restul pe trail.
|
||||
|
||||
Aceeași serie canonică (importată din `mdsrt_ansamblu`), de la intrare
|
||||
încolo: prima parte a poziției iese la ținta simetrică 1:1 (591.00), stopul
|
||||
se mută la breakeven după ce prețul a trecut de jumătatea drumului până la
|
||||
țintă, iar restul merge pe linia de trail — ultimul swing low — până la prima
|
||||
închidere sub ea.
|
||||
|
||||
Din curs: ținta stabilită împreună cu stopul, simetric; trail pe Bull Trail
|
||||
sau pe swing low, la alegerea traderului; trail-ul se evaluează pe candelă
|
||||
închisă, nu în timpul barei. Numărul de tranșe NU e dat de curs —
|
||||
transcrierea se întrerupe exact acolo.
|
||||
|
||||
Rulează: python3 gen/strategii/mdsrt_iesire.py
|
||||
"""
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
from svg_candles import Chart, Level, Mark, Arrow, Zone # noqa: E402
|
||||
from mdsrt_ansamblu import (serie, CONF, ENTRY, SL, R, TP1, EXIT_I, TRAIL, # noqa: E402
|
||||
bull_trail)
|
||||
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
GREEN, RED, BLUE, GRAY, ORANGE = "#188a3e", "#c00", "#1a5fb4", "#555", "#b06000"
|
||||
W = 720
|
||||
S = 14
|
||||
|
||||
cds = serie()[S:EXIT_I + 1]
|
||||
cf, tp_i, ex_i = CONF - S, 22 - S, EXIT_I - S
|
||||
BE = ENTRY # stopul mutat la prețul de intrare
|
||||
half = round(ENTRY + R / 2, 2) # jumătatea drumului până la țintă
|
||||
be_i = next(i for i in range(cf + 1, len(cds)) if cds[i].c > half)
|
||||
|
||||
# ----------------------------------------------------------------- assert-uri
|
||||
assert cds[cf].c == ENTRY and round(ENTRY - SL, 2) == R
|
||||
assert round(TP1 - ENTRY, 2) == R, "ținta nu e simetrică cu stopul"
|
||||
assert cds[tp_i].h >= TP1 and max(c.h for c in cds[cf + 1:tp_i]) < TP1, "TP1 atins altundeva"
|
||||
assert cds[be_i].c > half and all(c.c <= half for c in cds[cf + 1:be_i]), "breakeven greșit"
|
||||
assert be_i < tp_i, "breakeven-ul ar veni după țintă"
|
||||
# trail: ultimul swing low înaintea întoarcerii; ieșirea e prima închidere sub el
|
||||
assert cds[ex_i].c < TRAIL and all(c.c > TRAIL for c in cds[ex_i - 2:ex_i])
|
||||
r_exit = round((cds[ex_i].c - ENTRY) / R, 2)
|
||||
assert r_exit == 2.75, r_exit
|
||||
# scara: distanța intrare→TP1 e egală cu distanța intrare→SL, și în preț, și în px
|
||||
print(f"ieșire: TP1 {TP1:.2f} la bara {tp_i + S}, breakeven de la bara {be_i + S} "
|
||||
f"(peste {half:.2f}), trail {TRAIL:.2f}, ieșire {cds[ex_i].c:.2f} = {r_exit:.2f}R")
|
||||
|
||||
ch = Chart(
|
||||
candles=cds,
|
||||
levels=[
|
||||
Level(TP1, f"TP1 {TP1:.2f} = 1:1", GREEN, "2 2",
|
||||
label_at="left"),
|
||||
Level(ENTRY, f"intrare {ENTRY:.2f} = breakeven", GRAY, "4 3",
|
||||
label_at="left"),
|
||||
Level(SL, f"SL inițial {SL:.2f} (risc {R:.2f} = 1R)", RED, "4 3", label_at="left"),
|
||||
],
|
||||
marks=[Mark(ex_i, f"ieșire {cds[ex_i].c:.2f} = {r_exit:.2f}R", GREEN, "above")],
|
||||
zones=[Zone(be_i, tp_i, "de aici stopul stă la breakeven", ORANGE)],
|
||||
arrows=[
|
||||
Arrow(be_i, f"prețul a trecut de jumătatea drumului ({half:.2f}):\n"
|
||||
f"muți stopul la {BE:.2f} — trade-ul nu mai poate pierde",
|
||||
where="below", price=SL, color=ORANGE, dx=-40, dy=44),
|
||||
Arrow(tp_i, f"ținta 1:1 atinsă: {TP1:.2f}\nrestul poziției rămâne pe trail",
|
||||
where="above", color=GREEN, dx=90, dy=-30),
|
||||
Arrow(ex_i, f"prima închidere sub linia de trail ({TRAIL:.2f}):\n"
|
||||
f"ieși cu restul — se citește pe candelă închisă,\nnu în timpul barei",
|
||||
where="below", price=cds[ex_i].c, color=BLUE, dx=-30, dy=64),
|
||||
],
|
||||
scale=56.0, gap=24, body_w=12, left=200, width=W, top=44,
|
||||
title="Pasul 6 — ieșirea: ținta 1:1, breakeven, restul pe trail (SPY 5 min, construit)",
|
||||
caption="Câte tranșe faci nu e dat de curs: acolo se întrerupe transcrierea.",
|
||||
)
|
||||
svg = ch.render()
|
||||
|
||||
# linia de trail: ultimul swing low de la fiecare pas, desenată ca scară
|
||||
trail_pts = bull_trail(cds, cf)
|
||||
assert trail_pts[-1][1] == TRAIL, (trail_pts[-1], TRAIL)
|
||||
assert len(trail_pts) > 5, trail_pts
|
||||
d = []
|
||||
for k, (i, p) in enumerate(trail_pts):
|
||||
x0, x1 = ch._cx(i) - ch.gap / 2, ch._cx(i) + ch.gap / 2
|
||||
d.append(("M" if k == 0 else "L") + f"{x0:.1f},{ch._y(p):.1f}")
|
||||
d.append(f"L{x1:.1f},{ch._y(p):.1f}")
|
||||
trail_svg = (f'<path d="{" ".join(d)}" fill="none" stroke="{BLUE}" stroke-width="1.6" '
|
||||
f'stroke-dasharray="5 3"/>')
|
||||
i = svg.rindex("</svg>")
|
||||
svg = svg[:i] + " " + trail_svg + "\n" + svg[i:]
|
||||
assert "\n\n" not in svg, "linie goală în SVG"
|
||||
H = float(re.search(r'viewBox="0 0 [\d.]+ ([\d.]+)"', svg).group(1))
|
||||
for x, y in re.findall(r'<text x="([-\d.]+)" y="([-\d.]+)"', svg):
|
||||
assert 0 <= float(x) <= W and 0 <= float(y) <= H, f"text în afara pânzei la ({x}, {y})"
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT.name} ({W}x{H:.0f})")
|
||||
65
gen/strategii/mdsrt_iesire.svg
Normal file
@@ -0,0 +1,65 @@
|
||||
<svg viewBox="0 0 755 478" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<text x="24" y="96" fill="#333" style="font-weight:bold">Pasul 6 — ieșirea: ținta 1:1, breakeven, restul pe trail (SPY 5 min, construit)</text>
|
||||
<rect x="357.0" y="213.6" width="46.0" height="60.8" fill="#b06000" fill-opacity="0.08" stroke="#b06000" stroke-width="1"/>
|
||||
<text x="357.0" y="148.2" fill="#b06000" style="font-weight:bold">de aici stopul stă la breakeven</text>
|
||||
<line x1="24" y1="235.6" x2="741" y2="235.6" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 2"/>
|
||||
<text x="30" y="229.6" fill="#188a3e">TP1 591.00 = 1:1</text>
|
||||
<line x1="24" y1="280.4" x2="741" y2="280.4" stroke="#555" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="274.4" fill="#555">intrare 590.20 = breakeven</text>
|
||||
<line x1="24" y1="325.2" x2="741" y2="325.2" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="319.2" fill="#c00">SL inițial 589.40 (risc 0.80 = 1R)</text>
|
||||
<line x1="200.0" y1="204.8" x2="200.0" y2="246.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="194.0" y="218.8" width="12" height="11.2" fill="#188a3e"/>
|
||||
<line x1="224.0" y1="204.8" x2="224.0" y2="258.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="218.0" y="218.8" width="12" height="22.4" fill="#c00"/>
|
||||
<line x1="248.0" y1="230.0" x2="248.0" y2="272.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="242.0" y="241.2" width="12" height="22.4" fill="#c00"/>
|
||||
<line x1="272.0" y1="255.2" x2="272.0" y2="294.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="266.0" y="263.6" width="12" height="25.2" fill="#c00"/>
|
||||
<line x1="296.0" y1="283.2" x2="296.0" y2="319.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="290.0" y="288.8" width="12" height="14.0" fill="#c00"/>
|
||||
<line x1="320.0" y1="274.8" x2="320.0" y2="305.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="314.0" y="280.4" width="12" height="22.4" fill="#188a3e"/>
|
||||
<line x1="344.0" y1="244.0" x2="344.0" y2="288.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="338.0" y="258.0" width="12" height="22.4" fill="#188a3e"/>
|
||||
<line x1="368.0" y1="238.4" x2="368.0" y2="266.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="362.0" y="241.2" width="12" height="16.8" fill="#188a3e"/>
|
||||
<line x1="392.0" y1="221.6" x2="392.0" y2="258.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="386.0" y="235.6" width="12" height="5.6" fill="#188a3e"/>
|
||||
<line x1="416.0" y1="204.8" x2="416.0" y2="252.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="410.0" y="218.8" width="12" height="16.8" fill="#188a3e"/>
|
||||
<line x1="440.0" y1="204.8" x2="440.0" y2="246.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="434.0" y="218.8" width="12" height="11.2" fill="#c00"/>
|
||||
<line x1="464.0" y1="196.4" x2="464.0" y2="246.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="458.0" y="210.4" width="12" height="19.6" fill="#188a3e"/>
|
||||
<line x1="488.0" y1="182.4" x2="488.0" y2="227.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="482.0" y="196.4" width="12" height="14.0" fill="#188a3e"/>
|
||||
<line x1="512.0" y1="168.4" x2="512.0" y2="213.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="506.0" y="182.4" width="12" height="14.0" fill="#188a3e"/>
|
||||
<line x1="536.0" y1="157.2" x2="536.0" y2="199.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="530.0" y="171.2" width="12" height="11.2" fill="#188a3e"/>
|
||||
<line x1="560.0" y1="120.8" x2="560.0" y2="188.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="554.0" y="134.8" width="12" height="36.4" fill="#188a3e"/>
|
||||
<line x1="584.0" y1="104.0" x2="584.0" y2="151.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="578.0" y="118.0" width="12" height="16.8" fill="#188a3e"/>
|
||||
<line x1="608.0" y1="104.0" x2="608.0" y2="146.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="602.0" y="118.0" width="12" height="11.2" fill="#c00"/>
|
||||
<line x1="632.0" y1="115.2" x2="632.0" y2="174.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="626.0" y="129.2" width="12" height="28.0" fill="#c00"/>
|
||||
<text x="632.0" y="105.2" fill="#188a3e" text-anchor="middle" style="font-weight:bold">ieșire 592.40 = 2.75R</text>
|
||||
<line x1="328.0" y1="399.2" x2="364.0" y2="336.1" stroke="#b06000" stroke-width="1.8"/>
|
||||
<polygon points="368.0,329.2 367.5,338.1 360.6,334.2" fill="#b06000"/>
|
||||
<text x="328.0" y="413.2" fill="#b06000" text-anchor="middle" style="font-weight:bold">prețul a trecut de jumătatea drumului (590.60):</text>
|
||||
<text x="328.0" y="427.2" fill="#b06000" text-anchor="middle" style="font-weight:bold">muți stopul la 590.20 — trade-ul nu mai poate pierde</text>
|
||||
<line x1="482.0" y1="66.0" x2="396.1" y2="210.7" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<polygon points="392.0,217.6 392.6,208.7 399.5,212.8" fill="#188a3e"/>
|
||||
<text x="482.0" y="47.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">ținta 1:1 atinsă: 591.00</text>
|
||||
<text x="482.0" y="61.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">restul poziției rămâne pe trail</text>
|
||||
<line x1="602.0" y1="318.8" x2="630.5" y2="169.1" stroke="#1a5fb4" stroke-width="1.8"/>
|
||||
<polygon points="632.0,161.2 634.4,169.8 626.6,168.3" fill="#1a5fb4"/>
|
||||
<text x="602.0" y="332.8" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">prima închidere sub linia de trail (592.50):</text>
|
||||
<text x="602.0" y="346.8" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">ieși cu restul — se citește pe candelă închisă,</text>
|
||||
<text x="602.0" y="360.8" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">nu în timpul barei</text>
|
||||
<text x="24" y="466" fill="#555">Câte tranșe faci nu e dat de curs: acolo se întrerupe transcrierea.</text>
|
||||
<path d="M308.0,245.6 L332.0,245.6 L332.0,228.8 L356.0,228.8 L356.0,206.4 L380.0,206.4 L380.0,198.0 L404.0,198.0 L404.0,192.4 L428.0,192.4 L428.0,192.4 L452.0,192.4 L452.0,192.4 L476.0,192.4 L476.0,192.4 L500.0,192.4 L500.0,192.4 L524.0,192.4 L524.0,192.4 L548.0,192.4 L548.0,128.0 L572.0,128.0 L572.0,91.6 L596.0,91.6 L596.0,91.6 L620.0,91.6 L620.0,91.6 L644.0,91.6" fill="none" stroke="#1a5fb4" stroke-width="1.6" stroke-dasharray="5 3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
76
gen/strategii/mdsrt_picior.py
Normal file
@@ -0,0 +1,76 @@
|
||||
"""MDSRT, Pasul 2 — al doilea picior: cine vinde acolo și cine cumpără înapoi.
|
||||
|
||||
Aceeași serie ca diagrama de ansamblu (importată din `mdsrt_ansamblu`), tăiată
|
||||
în jurul celor două picioare. Diagrama arată unde stau stopurile celor care au
|
||||
cumpărat la piciorul 1, de ce ruperea nivelului atrage vânzare, și de ce
|
||||
întoarcerea e bruscă: shorturile intrate pe rupere ies cu buy to cover.
|
||||
|
||||
Mecanica short squeeze-ului e a cursului (`09_QA/19_2025-09-08.md:158-196`);
|
||||
nivelurile sunt cele construite în `mdsrt_ansamblu`.
|
||||
|
||||
Rulează: python3 gen/strategii/mdsrt_picior.py
|
||||
"""
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
from svg_candles import Chart, Level, Zone, Arrow # noqa: E402
|
||||
from mdsrt_ansamblu import (serie, SUPORT, LEG1, TRIG, CONF, ENTRY, SL, # noqa: E402
|
||||
R, TP1, MARJA)
|
||||
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
GREEN, RED, BLUE, GRAY, ORANGE = "#188a3e", "#c00", "#1a5fb4", "#555", "#b06000"
|
||||
S, E = 4, 23 # fereastra arătată din serie
|
||||
W = 700
|
||||
|
||||
cds = serie()[S:E]
|
||||
l1, l2, cf = LEG1 - S, TRIG - S, CONF - S
|
||||
leg1_l, leg2_l = cds[l1].l, cds[l2].l
|
||||
STOPURI = round(leg1_l - 0.05, 2) # unde stau, tipic, stopurile de sub piciorul 1
|
||||
|
||||
# ----------------------------------------------------------------- assert-uri
|
||||
assert leg1_l == 590.10 and leg2_l == 589.50, (leg1_l, leg2_l)
|
||||
assert leg2_l < SUPORT < leg1_l, "povestea diagramei cere picior 1 peste nivel, picior 2 sub"
|
||||
assert leg2_l < STOPURI, "piciorul 2 nu ajunge la stopurile de sub piciorul 1"
|
||||
assert cds[l2].c > leg2_l and cds[l2].c < SUPORT, cds[l2].c
|
||||
assert cds[cf].c == ENTRY > cds[l2].h, (ENTRY, cds[l2].h)
|
||||
assert round(leg2_l - MARJA, 2) == SL
|
||||
# ruperea ține o singură candelă: nicio bară de după intrare nu mai coboară sub nivel
|
||||
assert all(c.l > SUPORT for c in cds[cf + 1:]), "prețul recade sub nivel după intrare"
|
||||
assert min(c.l for c in cds[cf + 1:]) > SL, "stopul ar fi fost atins după intrare"
|
||||
# distanța dintre picioare, peste minimul de 5 candele cerut de curs
|
||||
assert l2 - l1 == 8
|
||||
print(f"picior: 1 = {leg1_l:.2f} (peste {SUPORT:.2f}), 2 = {leg2_l:.2f}, "
|
||||
f"stopuri la {STOPURI:.2f}, intrare {ENTRY:.2f}, SL {SL:.2f}")
|
||||
|
||||
ch = Chart(
|
||||
candles=cds,
|
||||
levels=[
|
||||
Level(SUPORT, f"pivot daily {SUPORT:.2f}", BLUE, label_at="left"),
|
||||
Level(SL, f"SL {SL:.2f}", RED, label_at="left"),
|
||||
],
|
||||
zones=[Zone(l2, cf, "aici se schimbă mâna", RED)],
|
||||
arrows=[
|
||||
Arrow(l1, f"piciorul 1: low {leg1_l:.2f} — nivelul ține\n"
|
||||
f"cine cumpără aici își pune stopul chiar sub {leg1_l:.2f}",
|
||||
where="below", price=leg1_l, color=GRAY, dx=-30, dy=34),
|
||||
Arrow(l2, f"piciorul 2: low {leg2_l:.2f}\n1) mătură stopurile de sus\n"
|
||||
f"2) cei care shortează ruperea intră aici",
|
||||
where="below", price=leg2_l, color=RED, dx=150, dy=44),
|
||||
Arrow(cf, "close înapoi peste nivel: shorturile\nprinse cumpără ca să iasă (buy to cover)\n"
|
||||
"de aici urcarea e bruscă, nu treptată",
|
||||
where="above", color=GREEN, dx=40, dy=-30),
|
||||
],
|
||||
scale=62.0, gap=22, body_w=12, left=64, width=W, top=54,
|
||||
title="Pasul 2 — al doilea picior, sub nivel (SPY 5 min, exemplu construit)",
|
||||
caption="Vânzarea de sub nivel se epuizează într-o singură candelă: nu mai are cine vinde.",
|
||||
)
|
||||
svg = ch.render()
|
||||
assert "\n\n" not in svg, "linie goală în SVG"
|
||||
for x, y in re.findall(r'<text x="([-\d.]+)" y="([-\d.]+)"', svg):
|
||||
h = float(re.search(r'viewBox="0 0 [\d.]+ ([\d.]+)"', svg).group(1))
|
||||
assert 0 <= float(x) <= W and 0 <= float(y) <= h, f"text în afara pânzei la ({x}, {y})"
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT.name}")
|
||||
62
gen/strategii/mdsrt_picior.svg
Normal file
@@ -0,0 +1,62 @@
|
||||
<svg viewBox="0 0 700 587" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<text x="24" y="68" fill="#333" style="font-weight:bold">Pasul 2 — al doilea picior, sub nivel (SPY 5 min, exemplu construit)</text>
|
||||
<rect x="361.0" y="362.5" width="44.0" height="65.6" fill="#c00" fill-opacity="0.08" stroke="#c00" stroke-width="1"/>
|
||||
<text x="361.0" y="302.6" fill="#c00" style="font-weight:bold">aici se schimbă mâna</text>
|
||||
<line x1="24" y1="389.1" x2="686" y2="389.1" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="383.1" fill="#1a5fb4">pivot daily 590.00</text>
|
||||
<line x1="24" y1="426.3" x2="686" y2="426.3" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="420.3" fill="#c00">SL 589.40</text>
|
||||
<line x1="64.0" y1="76.0" x2="64.0" y2="153.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="58.0" y="91.5" width="12" height="43.4" fill="#c00"/>
|
||||
<line x1="86.0" y1="119.4" x2="86.0" y2="196.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="80.0" y="134.9" width="12" height="43.4" fill="#c00"/>
|
||||
<line x1="108.0" y1="144.2" x2="108.0" y2="196.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="102.0" y="159.7" width="12" height="18.6" fill="#188a3e"/>
|
||||
<line x1="130.0" y1="144.2" x2="130.0" y2="227.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="124.0" y="159.7" width="12" height="49.6" fill="#c00"/>
|
||||
<line x1="152.0" y1="193.8" x2="152.0" y2="271.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="146.0" y="209.3" width="12" height="43.4" fill="#c00"/>
|
||||
<line x1="174.0" y1="237.2" x2="174.0" y2="308.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="168.0" y="252.7" width="12" height="37.2" fill="#c00"/>
|
||||
<line x1="196.0" y1="274.4" x2="196.0" y2="382.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="190.0" y="289.9" width="12" height="74.4" fill="#c00"/>
|
||||
<line x1="218.0" y1="317.8" x2="218.0" y2="382.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="212.0" y="333.3" width="12" height="31.0" fill="#188a3e"/>
|
||||
<line x1="240.0" y1="286.8" x2="240.0" y2="351.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="234.0" y="302.3" width="12" height="31.0" fill="#188a3e"/>
|
||||
<line x1="262.0" y1="286.8" x2="262.0" y2="339.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="256.0" y="302.3" width="12" height="18.6" fill="#c00"/>
|
||||
<line x1="284.0" y1="293.0" x2="284.0" y2="339.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="278.0" y="308.5" width="12" height="12.4" fill="#188a3e"/>
|
||||
<line x1="306.0" y1="293.0" x2="306.0" y2="351.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="300.0" y="308.5" width="12" height="24.8" fill="#c00"/>
|
||||
<line x1="328.0" y1="320.9" x2="328.0" y2="367.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="322.0" y="333.3" width="12" height="24.8" fill="#c00"/>
|
||||
<line x1="350.0" y1="348.8" x2="350.0" y2="392.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="344.0" y="358.1" width="12" height="27.9" fill="#c00"/>
|
||||
<line x1="372.0" y1="379.8" x2="372.0" y2="420.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="366.0" y="386.0" width="12" height="15.5" fill="#c00"/>
|
||||
<line x1="394.0" y1="370.5" x2="394.0" y2="404.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="388.0" y="376.7" width="12" height="24.8" fill="#188a3e"/>
|
||||
<line x1="416.0" y1="336.4" x2="416.0" y2="386.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="410.0" y="351.9" width="12" height="24.8" fill="#188a3e"/>
|
||||
<line x1="438.0" y1="330.2" x2="438.0" y2="361.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="432.0" y="333.3" width="12" height="18.6" fill="#188a3e"/>
|
||||
<line x1="460.0" y1="311.6" x2="460.0" y2="351.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="454.0" y="327.1" width="12" height="6.2" fill="#188a3e"/>
|
||||
<line x1="166.0" y1="446.9" x2="192.4" y2="394.1" stroke="#555" stroke-width="1.8"/>
|
||||
<polygon points="196.0,386.9 196.0,395.8 188.8,392.3" fill="#555"/>
|
||||
<text x="166.0" y="460.9" fill="#555" text-anchor="middle" style="font-weight:bold">piciorul 1: low 590.10 — nivelul ține</text>
|
||||
<text x="166.0" y="474.9" fill="#555" text-anchor="middle" style="font-weight:bold">cine cumpără aici își pune stopul chiar sub 590.10</text>
|
||||
<line x1="522.0" y1="494.1" x2="379.2" y2="427.5" stroke="#c00" stroke-width="1.8"/>
|
||||
<polygon points="372.0,424.1 380.9,423.9 377.6,431.1" fill="#c00"/>
|
||||
<text x="522.0" y="508.1" fill="#c00" text-anchor="middle" style="font-weight:bold">piciorul 2: low 589.50</text>
|
||||
<text x="522.0" y="522.1" fill="#c00" text-anchor="middle" style="font-weight:bold">1) mătură stopurile de sus</text>
|
||||
<text x="522.0" y="536.1" fill="#c00" text-anchor="middle" style="font-weight:bold">2) cei care shortează ruperea intră aici</text>
|
||||
<line x1="434.0" y1="255.0" x2="396.7" y2="359.0" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<polygon points="394.0,366.5 392.9,357.6 400.5,360.3" fill="#188a3e"/>
|
||||
<text x="434.0" y="222.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">close înapoi peste nivel: shorturile</text>
|
||||
<text x="434.0" y="236.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">prinse cumpără ca să iasă (buy to cover)</text>
|
||||
<text x="434.0" y="250.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">de aici urcarea e bruscă, nu treptată</text>
|
||||
<text x="24" y="575" fill="#555">Vânzarea de sub nivel se epuizează într-o singură candelă: nu mai are cine vinde.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
102
gen/strategii/mdsrt_short.py
Normal file
@@ -0,0 +1,102 @@
|
||||
"""MDSRT pe short — oglinda completă a trade-ului long.
|
||||
|
||||
Seria e exact seria canonică a capitolului, răsturnată în jurul unui preț
|
||||
(p' = 690 − p): fiecare candelă verde devine roșie, fiecare low devine high.
|
||||
Așa, orice regulă verificată pe long e verificată și aici, cu semnul schimbat
|
||||
— și se vede că nu e „doar invers", ci un trade întreg.
|
||||
|
||||
ATENȚIE: varianta short a MDSRT NU e explicată în curs — transcrierea se
|
||||
întrerupe înainte. Regulile de aici sunt reconstruite prin oglindire de
|
||||
autorul sumarului, marcate ca atare, și se tratează ca ipoteză de testat.
|
||||
|
||||
Rulează: python3 gen/strategii/mdsrt_short.py
|
||||
"""
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
from svg_candles import Candle, Chart, Level, Mark, Zone, Arrow # noqa: E402
|
||||
from mdsrt_ansamblu import (serie, SUPORT, LEG1, TRIG, CONF, EXIT_I, # noqa: E402
|
||||
ENTRY, SL, R, TP1, MARJA, STOP_BARS)
|
||||
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
GREEN, RED, BLUE, GRAY, ORANGE = "#188a3e", "#c00", "#1a5fb4", "#555", "#b06000"
|
||||
W, K = 700, 690.0 # K = prețul în jurul căruia se răstoarnă seria
|
||||
S = 6
|
||||
|
||||
|
||||
def m(p):
|
||||
return round(K - p, 2)
|
||||
|
||||
|
||||
cds = [Candle(m(c.o), m(c.l), m(c.h), m(c.c), vol=c.vol) for c in serie()]
|
||||
REZ = m(SUPORT) # rezistența / pivotul, sus
|
||||
l1, l2, cf, ex = LEG1, TRIG, CONF, EXIT_I
|
||||
leg1_h, leg2_h = cds[l1].h, cds[l2].h
|
||||
entry = cds[cf].c
|
||||
sl = round(leg2_h + MARJA, 2)
|
||||
risk = round(sl - entry, 2)
|
||||
tp1 = round(entry - risk, 2)
|
||||
|
||||
# ----------------------------------------------------------------- assert-uri
|
||||
for i, c in enumerate(cds):
|
||||
assert c.h >= max(c.o, c.c) and c.l <= min(c.o, c.c), i
|
||||
if i:
|
||||
assert abs(c.o - cds[i - 1].c) < 1e-9, f"open[{i}] != close[{i-1}]"
|
||||
# 1. oglinda e exactă: fiecare cifră a trade-ului long are perechea ei
|
||||
assert (REZ, leg1_h, leg2_h, entry, sl, tp1) == (100.00, 99.90, 100.50, 99.80, 100.60, 99.00), \
|
||||
(REZ, leg1_h, leg2_h, entry, sl, tp1)
|
||||
assert risk == R == 0.80
|
||||
# 2. povestea: piciorul 1 nu trece de nivel, piciorul 2 îl rupe în sus și recade
|
||||
assert leg1_h < REZ < leg2_h
|
||||
assert cds[l2].c > REZ, "candela-trigger ar trebui să se închidă tot deasupra nivelului"
|
||||
assert cds[cf].c < REZ, "candela de intrare nu se închide înapoi sub nivel"
|
||||
# 3. intrarea rupe low-ul candelei-trigger, stopul e cu marja peste maximul ei
|
||||
assert entry < cds[l2].l, (entry, cds[l2].l)
|
||||
high4 = max(c.h for c in cds[cf - STOP_BARS + 1:cf + 1])
|
||||
assert high4 == leg2_h and round(high4 + MARJA, 2) == sl
|
||||
# 4. ținta e simetrică, atinsă la aceeași bară ca pe long
|
||||
assert abs((sl - entry) - (entry - tp1)) < 1e-9
|
||||
assert next(i for i in range(cf + 1, len(cds)) if cds[i].l <= tp1 + 1e-9) == 22
|
||||
# 5. ieșirea pe bear trail, tot la 2.75R
|
||||
r_exit = round((entry - cds[ex].c) / risk, 2)
|
||||
assert r_exit == 2.75, r_exit
|
||||
# 6. divergența, în oglindă: higher high pe preț, lower high pe indicator/volum
|
||||
assert cds[l2].h > cds[l1].h and cds[l2].vol > cds[l1].vol
|
||||
print(f"short: rezistență {REZ:.2f}, picior 1 {leg1_h:.2f}, picior 2 {leg2_h:.2f}, "
|
||||
f"intrare {entry:.2f}, SL {sl:.2f} (risc {risk:.2f}), TP1 {tp1:.2f}, ieșire {r_exit:.2f}R")
|
||||
|
||||
ch = Chart(
|
||||
candles=cds[S:ex + 1],
|
||||
levels=[
|
||||
Level(REZ, f"pivot daily {REZ:.2f} — zona, sus", BLUE, label_at="left"),
|
||||
Level(sl, f"SL {sl:.2f} = {MARJA:.2f} peste piciorul 2", RED, "4 3"),
|
||||
Level(entry, f"intrare short {entry:.2f}", GREEN, "6 3"),
|
||||
Level(tp1, f"TP1 {tp1:.2f} = 1:1", GREEN, "2 2", label_at="left"),
|
||||
],
|
||||
marks=[Mark(ex - S, f"ieșire pe trail {cds[ex].c:.2f} = {r_exit:.2f}R", GREEN, "below")],
|
||||
zones=[Zone(l2 - S, cf - S, "", RED)],
|
||||
arrows=[
|
||||
Arrow(l1 - S, f"piciorul 1: high {leg1_h:.2f}\nrezistența ține",
|
||||
where="above", price=leg1_h, color=GRAY, dx=-30, dy=-30),
|
||||
Arrow(l2 - S, f"piciorul 2: high {leg2_h:.2f} — rupe nivelul în sus\n"
|
||||
f"și mătură stopurile celor intrați pe short,\ndar nu poate ține acolo",
|
||||
where="above", price=leg2_h, color=RED, dx=60, dy=-16),
|
||||
Arrow(cf - S, f"intri short la {entry:.2f}: close sub nivel și sub low-ul candelei-trigger\n"
|
||||
f"cei prinși long vând ca să iasă — coborârea e bruscă",
|
||||
where="below", color=GREEN, dx=20, dy=30),
|
||||
],
|
||||
scale=58.0, gap=18, body_w=10, left=176, width=W, top=64, vol_h=60,
|
||||
vol_label="volum: la piciorul 2 volumul crește, prețul nu mai are cumpărători = divergență",
|
||||
title="Oglinda pe short (serie construită prin răsturnarea exemplului long)",
|
||||
caption="Varianta short nu e explicată în curs: e reconstruită prin oglindire.",
|
||||
)
|
||||
svg = ch.render()
|
||||
assert "\n\n" not in svg, "linie goală în SVG"
|
||||
H = float(re.search(r'viewBox="0 0 [\d.]+ ([\d.]+)"', svg).group(1))
|
||||
for x, y in re.findall(r'<text x="([-\d.]+)" y="([-\d.]+)"', svg):
|
||||
assert 0 <= float(x) <= W and 0 <= float(y) <= H, f"text în afara pânzei la ({x}, {y})"
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT.name} ({W}x{H:.0f})")
|
||||
110
gen/strategii/mdsrt_short.svg
Normal file
@@ -0,0 +1,110 @@
|
||||
<svg viewBox="0 0 700 552" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<text x="24" y="112" fill="#333" style="font-weight:bold">Oglinda pe short (serie construită prin răsturnarea exemplului long)</text>
|
||||
<rect x="382.0" y="118.0" width="38.0" height="62.4" fill="#c00" fill-opacity="0.08" stroke="#c00" stroke-width="1"/>
|
||||
<line x1="24" y1="155.0" x2="686" y2="155.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="149.0" fill="#1a5fb4">pivot daily 100.00 — zona, sus</text>
|
||||
<line x1="24" y1="120.2" x2="686" y2="120.2" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="672" y="114.2" fill="#c00" text-anchor="end">SL 100.60 = 0.10 peste piciorul 2</text>
|
||||
<line x1="24" y1="166.6" x2="686" y2="166.6" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/>
|
||||
<text x="672" y="160.6" fill="#188a3e" text-anchor="end">intrare short 99.80</text>
|
||||
<line x1="24" y1="213.0" x2="686" y2="213.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 2"/>
|
||||
<text x="30" y="207.0" fill="#188a3e">TP1 99.00 = 1:1</text>
|
||||
<line x1="176.0" y1="334.8" x2="176.0" y2="384.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="171.0" y="352.2" width="10" height="17.4" fill="#c00"/>
|
||||
<line x1="194.0" y1="305.8" x2="194.0" y2="384.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="189.0" y="323.2" width="10" height="46.4" fill="#188a3e"/>
|
||||
<line x1="212.0" y1="265.2" x2="212.0" y2="337.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="207.0" y="282.6" width="10" height="40.6" fill="#188a3e"/>
|
||||
<line x1="230.0" y1="230.4" x2="230.0" y2="297.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="225.0" y="247.8" width="10" height="34.8" fill="#188a3e"/>
|
||||
<line x1="248.0" y1="160.8" x2="248.0" y2="262.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="243.0" y="178.2" width="10" height="69.6" fill="#188a3e"/>
|
||||
<line x1="266.0" y1="160.8" x2="266.0" y2="221.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="261.0" y="178.2" width="10" height="29.0" fill="#c00"/>
|
||||
<line x1="284.0" y1="189.8" x2="284.0" y2="250.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="279.0" y="207.2" width="10" height="29.0" fill="#c00"/>
|
||||
<line x1="302.0" y1="201.4" x2="302.0" y2="250.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="297.0" y="218.8" width="10" height="17.4" fill="#188a3e"/>
|
||||
<line x1="320.0" y1="201.4" x2="320.0" y2="244.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="315.0" y="218.8" width="10" height="11.6" fill="#c00"/>
|
||||
<line x1="338.0" y1="189.8" x2="338.0" y2="244.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="333.0" y="207.2" width="10" height="23.2" fill="#188a3e"/>
|
||||
<line x1="356.0" y1="175.3" x2="356.0" y2="218.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="351.0" y="184.0" width="10" height="23.2" fill="#188a3e"/>
|
||||
<line x1="374.0" y1="152.1" x2="374.0" y2="192.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="369.0" y="157.9" width="10" height="26.1" fill="#188a3e"/>
|
||||
<line x1="392.0" y1="126.0" x2="392.0" y2="163.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="387.0" y="143.4" width="10" height="14.5" fill="#188a3e"/>
|
||||
<line x1="410.0" y1="140.5" x2="410.0" y2="172.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="405.0" y="143.4" width="10" height="23.2" fill="#c00"/>
|
||||
<line x1="428.0" y1="157.9" x2="428.0" y2="204.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="423.0" y="166.6" width="10" height="23.2" fill="#c00"/>
|
||||
<line x1="446.0" y1="181.1" x2="446.0" y2="210.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="441.0" y="189.8" width="10" height="17.4" fill="#c00"/>
|
||||
<line x1="464.0" y1="189.8" x2="464.0" y2="227.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="459.0" y="207.2" width="10" height="5.8" fill="#c00"/>
|
||||
<line x1="482.0" y1="195.6" x2="482.0" y2="244.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="477.0" y="213.0" width="10" height="17.4" fill="#c00"/>
|
||||
<line x1="500.0" y1="201.4" x2="500.0" y2="244.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="495.0" y="218.8" width="10" height="11.6" fill="#188a3e"/>
|
||||
<line x1="518.0" y1="201.4" x2="518.0" y2="253.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="513.0" y="218.8" width="10" height="20.3" fill="#c00"/>
|
||||
<line x1="536.0" y1="221.7" x2="536.0" y2="268.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="531.0" y="239.1" width="10" height="14.5" fill="#c00"/>
|
||||
<line x1="554.0" y1="236.2" x2="554.0" y2="282.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="549.0" y="253.6" width="10" height="14.5" fill="#c00"/>
|
||||
<line x1="572.0" y1="250.7" x2="572.0" y2="294.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="567.0" y="268.1" width="10" height="11.6" fill="#c00"/>
|
||||
<line x1="590.0" y1="262.3" x2="590.0" y2="331.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="585.0" y="279.7" width="10" height="37.7" fill="#c00"/>
|
||||
<line x1="608.0" y1="300.0" x2="608.0" y2="349.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="603.0" y="317.4" width="10" height="17.4" fill="#c00"/>
|
||||
<line x1="626.0" y1="305.8" x2="626.0" y2="349.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="621.0" y="323.2" width="10" height="11.6" fill="#188a3e"/>
|
||||
<line x1="644.0" y1="276.8" x2="644.0" y2="337.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="639.0" y="294.2" width="10" height="29.0" fill="#188a3e"/>
|
||||
<line x1="24" y1="510.3" x2="686" y2="510.3" stroke="#888"/>
|
||||
<rect x="171.0" y="483.0" width="10" height="27.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="189.0" y="481.7" width="10" height="28.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="207.0" y="480.3" width="10" height="30.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="225.0" y="478.9" width="10" height="31.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="243.0" y="474.8" width="10" height="35.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="261.0" y="484.4" width="10" height="25.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="279.0" y="483.0" width="10" height="27.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="297.0" y="481.7" width="10" height="28.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="315.0" y="483.7" width="10" height="26.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="333.0" y="480.3" width="10" height="30.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="351.0" y="476.2" width="10" height="34.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="369.0" y="470.8" width="10" height="39.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="387.0" y="450.3" width="10" height="60.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="405.0" y="455.8" width="10" height="54.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="423.0" y="462.6" width="10" height="47.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="441.0" y="466.7" width="10" height="43.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="459.0" y="470.8" width="10" height="39.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="477.0" y="469.4" width="10" height="40.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="495.0" y="472.8" width="10" height="37.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="513.0" y="474.8" width="10" height="35.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="531.0" y="476.2" width="10" height="34.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="549.0" y="477.6" width="10" height="32.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="567.0" y="478.9" width="10" height="31.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="585.0" y="474.8" width="10" height="35.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="603.0" y="477.6" width="10" height="32.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="621.0" y="481.7" width="10" height="28.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="639.0" y="478.9" width="10" height="31.4" fill="#188a3e" opacity="0.55"/>
|
||||
<text x="24" y="444.3" fill="#555">volum: la piciorul 2 volumul crește, prețul nu mai are cumpărători = divergență</text>
|
||||
<text x="656.0" y="357.7" fill="#188a3e" text-anchor="end" style="font-weight:bold">ieșire pe trail 97.60 = 2.75R</text>
|
||||
<line x1="218.0" y1="100.8" x2="244.2" y2="149.7" stroke="#555" stroke-width="1.8"/>
|
||||
<polygon points="248.0,156.8 240.7,151.6 247.7,147.9" fill="#555"/>
|
||||
<text x="218.0" y="81.8" fill="#555" text-anchor="middle" style="font-weight:bold">piciorul 1: high 99.90</text>
|
||||
<text x="218.0" y="95.8" fill="#555" text-anchor="middle" style="font-weight:bold">rezistența ține</text>
|
||||
<line x1="452.0" y1="80.0" x2="398.6" y2="117.4" stroke="#c00" stroke-width="1.8"/>
|
||||
<polygon points="392.0,122.0 396.3,114.1 400.8,120.7" fill="#c00"/>
|
||||
<text x="452.0" y="47.0" fill="#c00" text-anchor="middle" style="font-weight:bold">piciorul 2: high 100.50 — rupe nivelul în sus</text>
|
||||
<text x="452.0" y="61.0" fill="#c00" text-anchor="middle" style="font-weight:bold">și mătură stopurile celor intrați pe short,</text>
|
||||
<text x="452.0" y="75.0" fill="#c00" text-anchor="middle" style="font-weight:bold">dar nu poate ține acolo</text>
|
||||
<line x1="430.0" y1="387.3" x2="410.8" y2="184.4" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<polygon points="410.0,176.4 414.7,184.0 406.8,184.7" fill="#188a3e"/>
|
||||
<text x="430.0" y="401.3" fill="#188a3e" text-anchor="middle" style="font-weight:bold">intri short la 99.80: close sub nivel și sub low-ul candelei-trigger</text>
|
||||
<text x="430.0" y="415.3" fill="#188a3e" text-anchor="middle" style="font-weight:bold">cei prinși long vând ca să iasă — coborârea e bruscă</text>
|
||||
<text x="24" y="540" fill="#555">Varianta short nu e explicată în curs: e reconstruită prin oglindire.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.3 KiB |
138
gen/strategii/mdsrt_stop.py
Normal file
@@ -0,0 +1,138 @@
|
||||
"""MDSRT, Pasul 5 — unde pui stopul și de ce nu mai aproape.
|
||||
|
||||
Sus: cum numeri cele 4 candele înapoi de la candela de intrare, care e cel mai
|
||||
jos low dintre ele și unde ajunge stopul (0.10 sub el).
|
||||
Jos: același trade, cu o continuare construită în care prețul retestează
|
||||
nivelul. Stopul „la ochi", pus sub candela de intrare, e măturat de retest;
|
||||
stopul din regulă ține, iar trade-ul ajunge la țintă.
|
||||
|
||||
Cursul lasă două variante de stop (extrema ultimelor N candele sau ATR) și nu
|
||||
dă valoarea lui N; N = 4 e valoarea folosită la celelalte strategii mecanice
|
||||
ale cursului, iar marja de 0.10 e regula acestui capitol.
|
||||
|
||||
Rulează: python3 gen/strategii/mdsrt_stop.py
|
||||
"""
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
from svg_candles import Candle, Chart, Level, Zone, Arrow # noqa: E402
|
||||
from mdsrt_ansamblu import (serie, SUPORT, TRIG, CONF, ENTRY, SL, R, TP1, # noqa: E402
|
||||
MARJA, STOP_BARS)
|
||||
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
GREEN, RED, BLUE, GRAY, ORANGE = "#188a3e", "#c00", "#1a5fb4", "#555", "#b06000"
|
||||
W, VGAP = 720, 16
|
||||
S = 9 # prima bară arătată
|
||||
|
||||
base = serie()[S:CONF + 1]
|
||||
t, cf = TRIG - S, CONF - S
|
||||
low4 = min(c.l for c in base[cf - STOP_BARS + 1:cf + 1])
|
||||
OCHI = round(base[cf].l - MARJA, 2) # stopul „la ochi", sub candela de intrare
|
||||
|
||||
# continuare construită: un retest care coboară sub candela de intrare
|
||||
after = [Candle(*b) for b in [
|
||||
(590.20, 590.35, 589.60, 589.85), # +1: retestul; mătură stopul „la ochi"
|
||||
(589.85, 590.45, 589.80, 590.35),
|
||||
(590.35, 590.75, 590.25, 590.65),
|
||||
(590.65, 591.10, 590.55, 591.05), # +4: atinge ținta
|
||||
]]
|
||||
jos = base + after
|
||||
|
||||
# ----------------------------------------------------------------- assert-uri
|
||||
for i, c in enumerate(jos):
|
||||
assert c.h >= max(c.o, c.c) and c.l <= min(c.o, c.c), i
|
||||
if i:
|
||||
assert abs(c.o - jos[i - 1].c) < 1e-9, f"open[{i}] != close[{i-1}]"
|
||||
# 1. cel mai jos low din cele 4 candele e al piciorului 2, iar stopul e sub el
|
||||
assert low4 == base[t].l == 589.50, (low4, base[t].l)
|
||||
assert round(low4 - MARJA, 2) == SL == 589.40
|
||||
assert round(ENTRY - SL, 2) == R == 0.80
|
||||
# 2. cu 5 candele în loc de 4 iese același stop (minimul e tot al piciorului 2)
|
||||
assert min(c.l for c in base[cf - 4:cf + 1]) == low4
|
||||
# 3. stopul „la ochi" e mai aproape de intrare decât cel din regulă
|
||||
assert SL < OCHI < ENTRY and OCHI == 589.65, OCHI
|
||||
# 4. retestul mătură stopul „la ochi", dar nu-l atinge pe cel din regulă
|
||||
assert min(c.l for c in after) == 589.60
|
||||
assert SL < 589.60 < OCHI
|
||||
assert next(k for k, c in enumerate(after) if c.l <= OCHI) == 0
|
||||
assert all(c.l > SL for c in after), "stopul din regulă ar fi fost atins"
|
||||
# 5. ținta e atinsă abia după retest, la a 4-a bară de după intrare
|
||||
assert next(k for k, c in enumerate(after, 1) if c.h >= TP1) == 4
|
||||
print(f"stop: low4 {low4:.2f} → SL {SL:.2f} (marjă {MARJA:.2f}); la ochi {OCHI:.2f} "
|
||||
f"măturat de {min(c.l for c in after):.2f}; țintă {TP1:.2f} la a 4-a bară")
|
||||
|
||||
common: dict = dict(scale=52.0, gap=22, body_w=11, left=180, width=W)
|
||||
|
||||
sus = Chart(
|
||||
candles=base,
|
||||
levels=[Level(SUPORT, f"pivot daily {SUPORT:.2f}", BLUE, label_at="left"),
|
||||
Level(SL, f"stopul din regulă: {SL:.2f}", RED, "4 3", label_at="left")],
|
||||
zones=[Zone(cf - STOP_BARS + 1, cf, f"numeri {STOP_BARS} candele înapoi, de la intrare", BLUE)],
|
||||
arrows=[
|
||||
Arrow(t, f"cel mai jos low din cele {STOP_BARS}: {low4:.2f}\n"
|
||||
f"stopul merge cu {MARJA:.2f} sub el",
|
||||
where="below", price=low4, color=GRAY, dx=170, dy=34),
|
||||
Arrow(cf, f"intrare {ENTRY:.2f}\nde aici numeri înapoi",
|
||||
where="above", color=GREEN, dx=60, dy=-44),
|
||||
],
|
||||
title=f"Pasul 5 — stopul: {STOP_BARS} candele înapoi de la intrare, minus {MARJA:.2f}",
|
||||
**common,
|
||||
)
|
||||
gata = Chart(
|
||||
candles=jos,
|
||||
levels=[Level(TP1, f"ținta 1:1: {TP1:.2f}", GREEN, "2 2", label_at="left"),
|
||||
Level(ENTRY, f"intrarea: {ENTRY:.2f}", GRAY, "4 3", label_at="left"),
|
||||
Level(OCHI, f"stop pus la ochi: {OCHI:.2f}", ORANGE, "4 3"),
|
||||
Level(SL, f"stopul din regulă: {SL:.2f}", RED, "4 3", label_at="left")],
|
||||
zones=[Zone(cf + 1, cf + 1, "", RED, p_top=OCHI, p_bot=SL)],
|
||||
arrows=[
|
||||
Arrow(cf + 1, f"retestul coboară la {min(c.l for c in after):.2f}:\n"
|
||||
f"mătură stopul de {OCHI:.2f},\nnu-l atinge pe cel de {SL:.2f}",
|
||||
where="below", price=589.60, color=ORANGE, dx=150, dy=26),
|
||||
Arrow(len(jos) - 1, "cu stopul din regulă mai erai în trade\ncând a venit ținta",
|
||||
where="above", price=TP1, color=GREEN, dx=40, dy=-14),
|
||||
],
|
||||
title="Același trade, cu un retest: stopul „la ochi” e măturat, cel din regulă nu",
|
||||
caption="Barele de după intrare sunt construite, ca să arate retestul.",
|
||||
**common,
|
||||
)
|
||||
|
||||
|
||||
def panou(ch, sus_de=0.0):
|
||||
ch.top += sus_de
|
||||
svg = ch.render()
|
||||
h = float(re.search(r'viewBox="0 0 [\d.]+ ([\d.]+)"', svg).group(1))
|
||||
off = float(re.search(r'<line x1="24" y1="([\d.]+)"', svg).group(1)) - ch._y(ch.levels[0].price)
|
||||
return svg[svg.index(">") + 1:svg.rindex("</svg>")].strip(), h, off
|
||||
|
||||
|
||||
body_sus, h_sus, off_sus = panou(sus)
|
||||
# numerele 4 3 2 1 sub barele numărate
|
||||
yb = sus._y(SL) + off_sus + 20
|
||||
nums = [f'<text x="{sus._cx(k):.1f}" y="{yb:.1f}" fill="{BLUE}" text-anchor="middle" '
|
||||
f'style="font-weight:bold">{n}</text>'
|
||||
for k, n in zip(range(cf - STOP_BARS + 1, cf + 1), "4321")]
|
||||
nums.append(f'<text x="{sus._cx(cf - STOP_BARS):.1f}" y="{yb:.1f}" fill="#999" '
|
||||
f'text-anchor="middle">(5)</text>')
|
||||
y_sub = max([yb] + [float(m) for m in re.findall(r'<text[^>]*\sy="([\d.]+)"', body_sus)]) + 24
|
||||
nums.append(f'<text x="24" y="{y_sub:.1f}" fill="#555">cu 4 sau cu 5 candele iese același stop: '
|
||||
f'după o coborâre, low-ul piciorului 2 e oricum cel mai jos</text>')
|
||||
h_sus = max(h_sus, y_sub + 12)
|
||||
|
||||
body_jos, h_jos, _ = panou(gata, h_sus + VGAP)
|
||||
H = h_jos + 8
|
||||
svg = "\n ".join([
|
||||
f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/svg" '
|
||||
f'style="width:100%;height:auto;font:12px sans-serif">',
|
||||
body_sus, *nums,
|
||||
f'<line x1="24" y1="{h_sus + VGAP / 2:.0f}" x2="{W - 14}" y2="{h_sus + VGAP / 2:.0f}" stroke="#ddd"/>',
|
||||
body_jos,
|
||||
]) + "\n</svg>"
|
||||
assert "\n\n" not in svg, "linie goală în SVG"
|
||||
for x, y in re.findall(r'<text x="([-\d.]+)" y="([-\d.]+)"', svg):
|
||||
assert 0 <= float(x) <= W and 0 <= float(y) <= H, f"text în afara pânzei la ({x}, {y})"
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT.name} ({W}x{H:.0f})")
|
||||
96
gen/strategii/mdsrt_stop.svg
Normal file
@@ -0,0 +1,96 @@
|
||||
<svg viewBox="0 0 720 715" 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">Pasul 5 — stopul: 4 candele înapoi de la intrare, minus 0.10</text>
|
||||
<rect x="323.5" y="118.2" width="87.0" height="99.2" fill="#1a5fb4" fill-opacity="0.08" stroke="#1a5fb4" stroke-width="1"/>
|
||||
<text x="323.5" y="113.2" fill="#1a5fb4" style="font-weight:bold">numeri 4 candele înapoi, de la intrare</text>
|
||||
<line x1="24" y1="183.4" x2="706" y2="183.4" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="177.4" fill="#1a5fb4">pivot daily 590.00</text>
|
||||
<line x1="24" y1="214.6" x2="706" y2="214.6" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="208.6" fill="#c00">stopul din regulă: 589.40</text>
|
||||
<line x1="180.0" y1="56.0" x2="180.0" y2="115.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="174.5" y="69.0" width="11" height="31.2" fill="#c00"/>
|
||||
<line x1="202.0" y1="87.2" x2="202.0" y2="178.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="196.5" y="100.2" width="11" height="62.4" fill="#c00"/>
|
||||
<line x1="224.0" y1="123.6" x2="224.0" y2="178.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="218.5" y="136.6" width="11" height="26.0" fill="#188a3e"/>
|
||||
<line x1="246.0" y1="97.6" x2="246.0" y2="152.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="240.5" y="110.6" width="11" height="26.0" fill="#188a3e"/>
|
||||
<line x1="268.0" y1="97.6" x2="268.0" y2="141.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="262.5" y="110.6" width="11" height="15.6" fill="#c00"/>
|
||||
<line x1="290.0" y1="102.8" x2="290.0" y2="141.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="284.5" y="115.8" width="11" height="10.4" fill="#188a3e"/>
|
||||
<line x1="312.0" y1="102.8" x2="312.0" y2="152.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="306.5" y="115.8" width="11" height="20.8" fill="#c00"/>
|
||||
<line x1="334.0" y1="126.2" x2="334.0" y2="165.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="328.5" y="136.6" width="11" height="20.8" fill="#c00"/>
|
||||
<line x1="356.0" y1="149.6" x2="356.0" y2="186.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="350.5" y="157.4" width="11" height="23.4" fill="#c00"/>
|
||||
<line x1="378.0" y1="175.6" x2="378.0" y2="209.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="372.5" y="180.8" width="11" height="13.0" fill="#c00"/>
|
||||
<line x1="400.0" y1="167.8" x2="400.0" y2="196.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="394.5" y="173.0" width="11" height="20.8" fill="#188a3e"/>
|
||||
<line x1="548.0" y1="273.4" x2="385.5" y2="216.1" stroke="#555" stroke-width="1.8"/>
|
||||
<polygon points="378.0,213.4 386.9,212.3 384.2,219.8" fill="#555"/>
|
||||
<text x="548.0" y="287.4" fill="#555" text-anchor="middle" style="font-weight:bold">cel mai jos low din cele 4: 589.50</text>
|
||||
<text x="548.0" y="301.4" fill="#555" text-anchor="middle" style="font-weight:bold">stopul merge cu 0.10 sub el</text>
|
||||
<line x1="460.0" y1="93.8" x2="405.2" y2="157.7" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<polygon points="400.0,163.8 402.2,155.1 408.2,160.3" fill="#188a3e"/>
|
||||
<text x="460.0" y="74.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">intrare 590.20</text>
|
||||
<text x="460.0" y="88.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">de aici numeri înapoi</text>
|
||||
<text x="334.0" y="234.6" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">4</text>
|
||||
<text x="356.0" y="234.6" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">3</text>
|
||||
<text x="378.0" y="234.6" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">2</text>
|
||||
<text x="400.0" y="234.6" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">1</text>
|
||||
<text x="312.0" y="234.6" fill="#999" text-anchor="middle">(5)</text>
|
||||
<text x="24" y="325.4" fill="#555">cu 4 sau cu 5 candele iese același stop: după o coborâre, low-ul piciorului 2 e oricum cel mai jos</text>
|
||||
<line x1="24" y1="345" x2="706" y2="345" stroke="#ddd"/>
|
||||
<text x="24" y="401" fill="#333" style="font-weight:bold">Același trade, cu un retest: stopul „la ochi” e măturat, cel din regulă nu</text>
|
||||
<rect x="411.5" y="555.0" width="21.0" height="13.0" fill="#c00" fill-opacity="0.08" stroke="#c00" stroke-width="1"/>
|
||||
<line x1="24" y1="484.8" x2="706" y2="484.8" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 2"/>
|
||||
<text x="30" y="478.8" fill="#188a3e">ținta 1:1: 591.00</text>
|
||||
<line x1="24" y1="526.4" x2="706" y2="526.4" stroke="#555" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="520.4" fill="#555">intrarea: 590.20</text>
|
||||
<line x1="24" y1="555.0" x2="706" y2="555.0" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="692" y="549.0" fill="#b06000" text-anchor="end">stop pus la ochi: 589.65</text>
|
||||
<line x1="24" y1="568.0" x2="706" y2="568.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="562.0" fill="#c00">stopul din regulă: 589.40</text>
|
||||
<line x1="180.0" y1="409.4" x2="180.0" y2="469.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="174.5" y="422.4" width="11" height="31.2" fill="#c00"/>
|
||||
<line x1="202.0" y1="440.6" x2="202.0" y2="531.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="196.5" y="453.6" width="11" height="62.4" fill="#c00"/>
|
||||
<line x1="224.0" y1="477.0" x2="224.0" y2="531.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="218.5" y="490.0" width="11" height="26.0" fill="#188a3e"/>
|
||||
<line x1="246.0" y1="451.0" x2="246.0" y2="505.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="240.5" y="464.0" width="11" height="26.0" fill="#188a3e"/>
|
||||
<line x1="268.0" y1="451.0" x2="268.0" y2="495.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="262.5" y="464.0" width="11" height="15.6" fill="#c00"/>
|
||||
<line x1="290.0" y1="456.2" x2="290.0" y2="495.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="284.5" y="469.2" width="11" height="10.4" fill="#188a3e"/>
|
||||
<line x1="312.0" y1="456.2" x2="312.0" y2="505.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="306.5" y="469.2" width="11" height="20.8" fill="#c00"/>
|
||||
<line x1="334.0" y1="479.6" x2="334.0" y2="518.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="328.5" y="490.0" width="11" height="20.8" fill="#c00"/>
|
||||
<line x1="356.0" y1="503.0" x2="356.0" y2="539.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="350.5" y="510.8" width="11" height="23.4" fill="#c00"/>
|
||||
<line x1="378.0" y1="529.0" x2="378.0" y2="562.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="372.5" y="534.2" width="11" height="13.0" fill="#c00"/>
|
||||
<line x1="400.0" y1="521.2" x2="400.0" y2="549.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="394.5" y="526.4" width="11" height="20.8" fill="#188a3e"/>
|
||||
<line x1="422.0" y1="518.6" x2="422.0" y2="557.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="416.5" y="526.4" width="11" height="18.2" fill="#c00"/>
|
||||
<line x1="444.0" y1="513.4" x2="444.0" y2="547.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="438.5" y="518.6" width="11" height="26.0" fill="#188a3e"/>
|
||||
<line x1="466.0" y1="497.8" x2="466.0" y2="523.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="460.5" y="503.0" width="11" height="15.6" fill="#188a3e"/>
|
||||
<line x1="488.0" y1="479.6" x2="488.0" y2="508.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="482.5" y="482.2" width="11" height="20.8" fill="#188a3e"/>
|
||||
<line x1="572.0" y1="613.6" x2="429.6" y2="564.2" stroke="#b06000" stroke-width="1.8"/>
|
||||
<polygon points="422.0,561.6 430.9,560.4 428.2,568.0" fill="#b06000"/>
|
||||
<text x="572.0" y="627.6" fill="#b06000" text-anchor="middle" style="font-weight:bold">retestul coboară la 589.60:</text>
|
||||
<text x="572.0" y="641.6" fill="#b06000" text-anchor="middle" style="font-weight:bold">mătură stopul de 589.65,</text>
|
||||
<text x="572.0" y="655.6" fill="#b06000" text-anchor="middle" style="font-weight:bold">nu-l atinge pe cel de 589.40</text>
|
||||
<line x1="528.0" y1="440.8" x2="493.7" y2="475.1" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<polygon points="488.0,480.8 490.8,472.3 496.5,478.0" fill="#188a3e"/>
|
||||
<text x="528.0" y="421.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">cu stopul din regulă mai erai în trade</text>
|
||||
<text x="528.0" y="435.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">când a venit ținta</text>
|
||||
<text x="24" y="695" fill="#555">Barele de după intrare sunt construite, ca să arate retestul.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.3 KiB |
114
gen/strategii/mdsrt_trigger.py
Normal file
@@ -0,0 +1,114 @@
|
||||
"""MDSRT, Pasul 4 — trigger valid (DA) vs. trigger prematur (NU).
|
||||
|
||||
Aceeași formă de candelă, două locuri diferite. Sus: candela-trigger apare
|
||||
după ce M e complet (prețul e în zona pivotului și divergența s-a format
|
||||
acolo) — seria e cea canonică a capitolului, importată din `mdsrt_ansamblu`.
|
||||
Jos: o candelă la fel de frumoasă, dar la 2.50 deasupra zonei; M nu e complet,
|
||||
iar stopul pus sub ea e lovit de candela următoare.
|
||||
|
||||
Regula „forma candelei nu e trigger dacă M nu e complet" e a cursului
|
||||
(`05_MODUL_4/02_strategia_5_mdsrt.md:249-311`); prețurile sunt construite, pe
|
||||
scara exemplului din capitol.
|
||||
|
||||
Rulează: python3 gen/strategii/mdsrt_trigger.py
|
||||
"""
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
from svg_candles import Chart, Level, Zone, Arrow, from_closes # noqa: E402
|
||||
from mdsrt_ansamblu import serie, SUPORT, TRIG, CONF, ENTRY, SL, MARJA # noqa: E402
|
||||
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
GREEN, RED, BLUE, GRAY, ORANGE = "#188a3e", "#c00", "#1a5fb4", "#555", "#b06000"
|
||||
W, VGAP = 700, 16
|
||||
S = 8 # prima bară arătată din seria canonică
|
||||
|
||||
# ---------------------------------------------------------------- panoul DA
|
||||
da = serie()[S:CONF + 4]
|
||||
t, cf = TRIG - S, CONF - S
|
||||
assert da[t].l == 589.50 < SUPORT, da[t].l
|
||||
assert da[cf].c == ENTRY > da[t].h, (ENTRY, da[t].h)
|
||||
|
||||
# ---------------------------------------------------------------- panoul NU
|
||||
NU_CLOSES = [595.80, 595.20, 594.60, 594.00, 593.40, 592.90, 592.55,
|
||||
592.50, # 7 = doji frumos, dar sus
|
||||
592.10, 591.60, 591.20, 590.80, 590.50, 590.20, 589.90, 589.60]
|
||||
NU_WICKS = [(0.25, 0.30)] * len(NU_CLOSES)
|
||||
NU_WICKS[7] = (0.35, 0.35)
|
||||
nu = from_closes(NU_CLOSES, wicks=NU_WICKS, start=596.20)
|
||||
D = 7
|
||||
NU_SL = round(nu[D].l - MARJA, 2)
|
||||
|
||||
# doji: corp de cel mult 10 % din înălțimea candelei, fitile în ambele părți
|
||||
body = abs(nu[D].o - nu[D].c)
|
||||
rng = nu[D].h - nu[D].l
|
||||
assert body <= 0.10 * rng, (body, rng)
|
||||
assert nu[D].h > max(nu[D].o, nu[D].c) and nu[D].l < min(nu[D].o, nu[D].c)
|
||||
# e la 2.50 deasupra zonei — asta e tot ce-l deosebește de cel de sus
|
||||
assert round(nu[D].c - SUPORT, 2) == 2.50, nu[D].c - SUPORT
|
||||
# stopul pus sub el e lovit chiar de candela următoare
|
||||
lovit = next(i for i in range(D + 1, len(nu)) if nu[i].l <= NU_SL)
|
||||
assert lovit == D + 1, lovit
|
||||
# prețul chiar ajunge, mai târziu, în zona în care trigger-ul ar fi contat
|
||||
assert min(c.l for c in nu) < SUPORT
|
||||
print(f"trigger: DA la {da[t].l:.2f} (sub {SUPORT:.2f}), intrare {ENTRY:.2f}, SL {SL:.2f}; "
|
||||
f"NU la {nu[D].c:.2f} (+2.50), stop {NU_SL:.2f} lovit la bara {lovit}")
|
||||
|
||||
common: dict = dict(scale=40.0, gap=20, body_w=10, left=170, width=W)
|
||||
|
||||
sus = Chart(
|
||||
candles=da,
|
||||
levels=[Level(SUPORT, f"pivot daily {SUPORT:.2f}", BLUE, label_at="left"),
|
||||
Level(ENTRY, f"intrare {ENTRY:.2f}", GREEN, "6 3"),
|
||||
Level(SL, f"SL {SL:.2f}", RED, "4 3")],
|
||||
zones=[Zone(t, cf, "M complet: preț în zonă + divergență acolo", GREEN)],
|
||||
arrows=[Arrow(t, "DA — aceeași formă, dar în zonă:\ntrigger-ul contează",
|
||||
where="below", price=da[t].l, color=GREEN, dx=140, dy=30)],
|
||||
title="DA — trigger valid: candela apare după ce M e complet",
|
||||
**common,
|
||||
)
|
||||
jos = Chart(
|
||||
candles=nu,
|
||||
levels=[Level(SUPORT, f"pivot daily {SUPORT:.2f} — zona e abia aici", BLUE, label_at="left"),
|
||||
Level(NU_SL, f"stopul pus sub doji: {NU_SL:.2f}", RED, "4 3")],
|
||||
zones=[Zone(D, D, "doji corect ca formă", ORANGE)],
|
||||
arrows=[
|
||||
Arrow(D, f"NU — doji la {nu[D].c:.2f}, cu 2.50 deasupra zonei:\n"
|
||||
f"M nu e complet, deci nu e trigger",
|
||||
where="above", color=RED, dx=60, dy=-18),
|
||||
Arrow(D + 1, f"stopul de sub el, {NU_SL:.2f}, e lovit\nchiar de candela următoare",
|
||||
where="below", price=NU_SL, color=RED, dx=170, dy=30),
|
||||
],
|
||||
title="NU — trigger prematur: aceeași candelă, dar deasupra zonei",
|
||||
caption="Ce deosebește cele două candele nu e forma, ci unde stă prețul când apar.",
|
||||
**common,
|
||||
)
|
||||
|
||||
|
||||
def panou(ch, sus_de=0.0):
|
||||
ch.top += sus_de
|
||||
svg = ch.render()
|
||||
h = float(re.search(r'viewBox="0 0 [\d.]+ ([\d.]+)"', svg).group(1))
|
||||
off = float(re.search(r'<line x1="24" y1="([\d.]+)"', svg).group(1)) - ch._y(ch.levels[0].price)
|
||||
assert abs(off) < 40, off
|
||||
return svg[svg.index(">") + 1:svg.rindex("</svg>")].strip(), h
|
||||
|
||||
|
||||
body_sus, h_sus = panou(sus)
|
||||
body_jos, h_jos = panou(jos, h_sus + VGAP)
|
||||
H = h_jos + 8
|
||||
svg = "\n ".join([
|
||||
f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/svg" '
|
||||
f'style="width:100%;height:auto;font:12px sans-serif">',
|
||||
body_sus,
|
||||
f'<line x1="24" y1="{h_sus + VGAP / 2:.0f}" x2="{W - 14}" y2="{h_sus + VGAP / 2:.0f}" stroke="#ddd"/>',
|
||||
body_jos,
|
||||
]) + "\n</svg>"
|
||||
assert "\n\n" not in svg, "linie goală în SVG"
|
||||
for x, y in re.findall(r'<text x="([-\d.]+)" y="([-\d.]+)"', svg):
|
||||
assert 0 <= float(x) <= W and 0 <= float(y) <= H, f"text în afara pânzei la ({x}, {y})"
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT.name} ({W}x{H:.0f})")
|
||||
94
gen/strategii/mdsrt_trigger.svg
Normal file
@@ -0,0 +1,94 @@
|
||||
<svg viewBox="0 0 700 808" 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">DA — trigger valid: candela apare după ce M e complet</text>
|
||||
<rect x="360.0" y="162.0" width="40.0" height="48.0" fill="#188a3e" fill-opacity="0.08" stroke="#188a3e" stroke-width="1"/>
|
||||
<text x="360.0" y="123.0" fill="#188a3e" style="font-weight:bold">M complet: preț în zonă + divergență acolo</text>
|
||||
<line x1="24" y1="182.0" x2="686" y2="182.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="176.0" fill="#1a5fb4">pivot daily 590.00</text>
|
||||
<line x1="24" y1="174.0" x2="686" y2="174.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/>
|
||||
<text x="672" y="168.0" fill="#188a3e" text-anchor="end">intrare 590.20</text>
|
||||
<line x1="24" y1="206.0" x2="686" y2="206.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="672" y="200.0" fill="#c00" text-anchor="end">SL 589.40</text>
|
||||
<line x1="170.0" y1="56.0" x2="170.0" y2="106.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="165.0" y="66.0" width="10" height="28.0" fill="#c00"/>
|
||||
<line x1="190.0" y1="84.0" x2="190.0" y2="130.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="185.0" y="94.0" width="10" height="24.0" fill="#c00"/>
|
||||
<line x1="210.0" y1="108.0" x2="210.0" y2="178.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="205.0" y="118.0" width="10" height="48.0" fill="#c00"/>
|
||||
<line x1="230.0" y1="136.0" x2="230.0" y2="178.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="225.0" y="146.0" width="10" height="20.0" fill="#188a3e"/>
|
||||
<line x1="250.0" y1="116.0" x2="250.0" y2="158.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="245.0" y="126.0" width="10" height="20.0" fill="#188a3e"/>
|
||||
<line x1="270.0" y1="116.0" x2="270.0" y2="150.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="265.0" y="126.0" width="10" height="12.0" fill="#c00"/>
|
||||
<line x1="290.0" y1="120.0" x2="290.0" y2="150.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="285.0" y="130.0" width="10" height="8.0" fill="#188a3e"/>
|
||||
<line x1="310.0" y1="120.0" x2="310.0" y2="158.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="305.0" y="130.0" width="10" height="16.0" fill="#c00"/>
|
||||
<line x1="330.0" y1="138.0" x2="330.0" y2="168.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="325.0" y="146.0" width="10" height="16.0" fill="#c00"/>
|
||||
<line x1="350.0" y1="156.0" x2="350.0" y2="184.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="345.0" y="162.0" width="10" height="18.0" fill="#c00"/>
|
||||
<line x1="370.0" y1="176.0" x2="370.0" y2="202.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="365.0" y="180.0" width="10" height="10.0" fill="#c00"/>
|
||||
<line x1="390.0" y1="170.0" x2="390.0" y2="192.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="385.0" y="174.0" width="10" height="16.0" fill="#188a3e"/>
|
||||
<line x1="410.0" y1="148.0" x2="410.0" y2="180.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="405.0" y="158.0" width="10" height="16.0" fill="#188a3e"/>
|
||||
<line x1="430.0" y1="144.0" x2="430.0" y2="164.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="425.0" y="146.0" width="10" height="12.0" fill="#188a3e"/>
|
||||
<line x1="450.0" y1="132.0" x2="450.0" y2="158.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="445.0" y="142.0" width="10" height="4.0" fill="#188a3e"/>
|
||||
<line x1="510.0" y1="262.0" x2="377.4" y2="209.0" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<polygon points="370.0,206.0 378.9,205.3 375.9,212.7" fill="#188a3e"/>
|
||||
<text x="510.0" y="276.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">DA — aceeași formă, dar în zonă:</text>
|
||||
<text x="510.0" y="290.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">trigger-ul contează</text>
|
||||
<line x1="24" y1="333" x2="686" y2="333" stroke="#ddd"/>
|
||||
<text x="24" y="389" fill="#333" style="font-weight:bold">NU — trigger prematur: aceeași candelă, dar deasupra zonei</text>
|
||||
<rect x="300.0" y="531.0" width="20.0" height="46.0" fill="#b06000" fill-opacity="0.08" stroke="#b06000" stroke-width="1"/>
|
||||
<text x="300.0" y="526.0" fill="#b06000" style="font-weight:bold">doji corect ca formă</text>
|
||||
<line x1="24" y1="655.0" x2="686" y2="655.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="649.0" fill="#1a5fb4">pivot daily 590.00 — zona e abia aici</text>
|
||||
<line x1="24" y1="573.0" x2="686" y2="573.0" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="672" y="567.0" fill="#c00" text-anchor="end">stopul pus sub doji: 592.05</text>
|
||||
<line x1="170.0" y1="397.0" x2="170.0" y2="435.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="165.0" y="407.0" width="10" height="16.0" fill="#c00"/>
|
||||
<line x1="190.0" y1="413.0" x2="190.0" y2="459.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="185.0" y="423.0" width="10" height="24.0" fill="#c00"/>
|
||||
<line x1="210.0" y1="437.0" x2="210.0" y2="483.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="205.0" y="447.0" width="10" height="24.0" fill="#c00"/>
|
||||
<line x1="230.0" y1="461.0" x2="230.0" y2="507.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="225.0" y="471.0" width="10" height="24.0" fill="#c00"/>
|
||||
<line x1="250.0" y1="485.0" x2="250.0" y2="531.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="245.0" y="495.0" width="10" height="24.0" fill="#c00"/>
|
||||
<line x1="270.0" y1="509.0" x2="270.0" y2="551.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="265.0" y="519.0" width="10" height="20.0" fill="#c00"/>
|
||||
<line x1="290.0" y1="529.0" x2="290.0" y2="565.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="285.0" y="539.0" width="10" height="14.0" fill="#c00"/>
|
||||
<line x1="310.0" y1="539.0" x2="310.0" y2="569.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="305.0" y="553.0" width="10" height="2.0" fill="#c00"/>
|
||||
<line x1="330.0" y1="545.0" x2="330.0" y2="583.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="325.0" y="555.0" width="10" height="16.0" fill="#c00"/>
|
||||
<line x1="350.0" y1="561.0" x2="350.0" y2="603.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="345.0" y="571.0" width="10" height="20.0" fill="#c00"/>
|
||||
<line x1="370.0" y1="581.0" x2="370.0" y2="619.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="365.0" y="591.0" width="10" height="16.0" fill="#c00"/>
|
||||
<line x1="390.0" y1="597.0" x2="390.0" y2="635.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="385.0" y="607.0" width="10" height="16.0" fill="#c00"/>
|
||||
<line x1="410.0" y1="613.0" x2="410.0" y2="647.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="405.0" y="623.0" width="10" height="12.0" fill="#c00"/>
|
||||
<line x1="430.0" y1="625.0" x2="430.0" y2="659.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="425.0" y="635.0" width="10" height="12.0" fill="#c00"/>
|
||||
<line x1="450.0" y1="637.0" x2="450.0" y2="671.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="445.0" y="647.0" width="10" height="12.0" fill="#c00"/>
|
||||
<line x1="470.0" y1="649.0" x2="470.0" y2="683.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="465.0" y="659.0" width="10" height="12.0" fill="#c00"/>
|
||||
<line x1="370.0" y1="435.0" x2="314.1" y2="528.1" stroke="#c00" stroke-width="1.8"/>
|
||||
<polygon points="310.0,535.0 310.7,526.1 317.5,530.2" fill="#c00"/>
|
||||
<text x="370.0" y="416.0" fill="#c00" text-anchor="middle" style="font-weight:bold">NU — doji la 592.50, cu 2.50 deasupra zonei:</text>
|
||||
<text x="370.0" y="430.0" fill="#c00" text-anchor="middle" style="font-weight:bold">M nu e complet, deci nu e trigger</text>
|
||||
<line x1="500.0" y1="721.0" x2="336.1" y2="582.2" stroke="#c00" stroke-width="1.8"/>
|
||||
<polygon points="330.0,577.0 338.7,579.1 333.5,585.2" fill="#c00"/>
|
||||
<text x="500.0" y="735.0" fill="#c00" text-anchor="middle" style="font-weight:bold">stopul de sub el, 592.05, e lovit</text>
|
||||
<text x="500.0" y="749.0" fill="#c00" text-anchor="middle" style="font-weight:bold">chiar de candela următoare</text>
|
||||
<text x="24" y="788" fill="#555">Ce deosebește cele două candele nu e forma, ci unde stă prețul când apar.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.9 KiB |
313
gen/strategii/mdsrt_zona.py
Normal file
@@ -0,0 +1,313 @@
|
||||
"""MDSRT, Pasul 1 — nivelul trăiește pe TF-ul mare, trigger-ul pe cel mic.
|
||||
|
||||
Un singur rând: daily (stânga) → 60 min (dreapta). Graficul din dreapta NU e
|
||||
o serie care vine după cel din stânga: e **descompunerea reală** a ultimelor
|
||||
două candele daily. O zi de bursă are 7 bare de 60 de minute (ședința
|
||||
9:30-16:00 are 6 ore și jumătate — ultima bară a zilei e de 30 de minute),
|
||||
deci 2 candele daily = 14 bare de 60 de minute, cu open, close, max(high) și
|
||||
min(low) care coincid — verificat bară cu bară prin assert.
|
||||
|
||||
Sursa de adevăr e seria fină; candelele daily se calculează din ea prin
|
||||
agregare. Pivotul monthly (76.00) e desenat pe amândouă panourile, cu același
|
||||
număr de ambele părți, și legat printr-un conector — scările au pante
|
||||
diferite, deci același preț cade la înălțimi diferite: e o lupă, nu o eroare.
|
||||
|
||||
Prețurile sunt ale altui simbol decât exemplul din ceilalți pași (care e pe
|
||||
SPY, 5 min); regulile sunt aceleași. Toate cifrele din desen ies din serii.
|
||||
|
||||
Rulează: python3 gen/strategii/mdsrt_zona.py
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
W = 720
|
||||
MARJA = 0.10 # aceeași marjă de stop ca în tot capitolul
|
||||
PIVOT = 76.00 # pivot monthly — nivelul de pe TF-ul mare
|
||||
K = 7 # 7 bare de 60 min pe zi
|
||||
NZ = 2 # 2 candele daily mărite
|
||||
|
||||
# --- seria fină (60 min): (open, high, low, close) --------------------------
|
||||
# 0-6 = ziua 1: coborârea spre pivot; bara 4 = piciorul 1 (low 76.05, ține nivelul)
|
||||
# 7-13 = ziua 2: piciorul 2 rupe pivotul (bara 10, hammer), apoi intrarea
|
||||
FINE = [
|
||||
(77.40, 77.55, 77.05, 77.15), (77.15, 77.30, 76.80, 76.90),
|
||||
(76.90, 77.00, 76.50, 76.60), (76.60, 76.75, 76.30, 76.45),
|
||||
(76.45, 76.55, 76.05, 76.20), # 4: piciorul 1, low 76.05
|
||||
(76.20, 76.60, 76.15, 76.50), (76.50, 76.65, 76.25, 76.35),
|
||||
(76.35, 76.45, 76.05, 76.15), (76.15, 76.25, 75.90, 75.95),
|
||||
(75.95, 76.05, 75.85, 75.95),
|
||||
(75.95, 76.20, 75.70, 76.10), # 10: piciorul 2, hammer (low 75.70)
|
||||
(76.10, 76.40, 76.05, 76.30), # 11: intrarea (close peste high-ul 76.20)
|
||||
(76.30, 76.75, 76.20, 76.60), (76.60, 77.15, 76.55, 77.05),
|
||||
]
|
||||
# --- candelele daily dinaintea casetei de lupă ------------------------------
|
||||
BASE = [
|
||||
(86.00, 86.60, 84.20, 84.60), (84.60, 85.20, 83.00, 83.40),
|
||||
(83.40, 84.60, 82.80, 84.00), (84.00, 84.40, 81.50, 81.90),
|
||||
(81.90, 82.40, 80.20, 80.60), (80.60, 81.20, 79.00, 79.40),
|
||||
(79.40, 80.40, 78.20, 79.60), (79.60, 80.00, 77.20, 77.40),
|
||||
]
|
||||
LEG1, LEG2, ENTRY_I = 4, 10, 11
|
||||
|
||||
|
||||
def aggregate(fine, k, n):
|
||||
out_ = []
|
||||
for j in range(n):
|
||||
part = fine[j * k:(j + 1) * k]
|
||||
out_.append((part[0][0], max(b[1] for b in part),
|
||||
min(b[2] for b in part), part[-1][3]))
|
||||
return out_
|
||||
|
||||
|
||||
def eq(a, b):
|
||||
return abs(a - b) < 0.005
|
||||
|
||||
|
||||
zoom = aggregate(FINE, K, NZ)
|
||||
big = BASE + zoom
|
||||
|
||||
# ------------------------------------------------------------- assert-urile
|
||||
for name, bars in (("daily", big), ("60 min", FINE)):
|
||||
for i, (o, h, l, c) in enumerate(bars):
|
||||
assert h >= max(o, c) and l <= min(o, c), f"{name}[{i}] h/l incoerent"
|
||||
if i:
|
||||
assert eq(o, bars[i - 1][3]), f"{name}[{i}] open != close precedent"
|
||||
assert len(FINE) == K * NZ
|
||||
assert eq(FINE[0][0], BASE[-1][3]), "lupa nu se leagă de ultima candelă daily"
|
||||
# 1. proprietăți pe care textul le pretinde (nu recalculul agregării)
|
||||
assert LEG1 // K == 0 and LEG2 // K == 1, "cele două picioare nu cad în zile diferite"
|
||||
assert LEG2 - LEG1 >= 5, "sub minimul de 5 bare între punctele divergenței"
|
||||
leg1_l, leg2_l = FINE[LEG1][2], FINE[LEG2][2]
|
||||
assert leg1_l == 76.05 > PIVOT, leg1_l
|
||||
assert leg2_l == 75.70 < PIVOT, leg2_l
|
||||
assert leg2_l == min(b[2] for b in FINE), "piciorul 2 nu e minimul zonei mărite"
|
||||
assert leg1_l == min(b[2] for b in FINE[:K]), "piciorul 1 nu e minimul zilei 1"
|
||||
# 2. ziua a doua, ca o singură candelă daily, NU arată piciorul 2 ca minim propriu
|
||||
assert eq(zoom[1][2], leg2_l), "low-ul zilei 2 nu e low-ul piciorului 2"
|
||||
assert zoom[1][3] > PIVOT, "ziua 2 nu se închide peste pivot"
|
||||
# 3. hammer-ul: corp mic sus, coadă lungă în jos, close înapoi peste pivot
|
||||
o, h, l, c = FINE[LEG2]
|
||||
assert abs(o - c) <= 0.5 * (h - l) and min(o, c) - l > abs(o - c), (o, h, l, c)
|
||||
assert c > PIVOT, c
|
||||
# 4. trade-ul, cu regulile capitolului
|
||||
low4 = min(b[2] for b in FINE[ENTRY_I - 3:ENTRY_I + 1])
|
||||
assert eq(low4, leg2_l), low4
|
||||
sl = round(low4 - MARJA, 2)
|
||||
entry = FINE[ENTRY_I][3]
|
||||
assert entry > FINE[LEG2][1], "intrarea nu sparge high-ul candelei-trigger"
|
||||
risk = round(entry - sl, 2)
|
||||
tp = round(entry + risk, 2)
|
||||
first = next(i for i in range(ENTRY_I + 1, len(FINE)) if FINE[i][1] >= tp - 1e-9)
|
||||
assert (sl, entry, risk, tp, first) == (75.60, 76.30, 0.70, 77.00, 13), \
|
||||
(sl, entry, risk, tp, first)
|
||||
# 5. stopul măsurat pe daily (sub low-ul zilei 2) e de câteva ori mai larg
|
||||
b_sl = round(zoom[1][2] - MARJA, 2)
|
||||
b_entry = zoom[1][3]
|
||||
b_risk = round(b_entry - b_sl, 2)
|
||||
ratio = (b_risk / b_entry) / (risk / entry)
|
||||
assert 1.8 <= ratio <= 2.5, ratio
|
||||
|
||||
# --- desen ------------------------------------------------------------------
|
||||
GREEN, RED, GRAY, INK, BLUE = "#188a3e", "#c00", "#888", "#333", "#1a5fb4"
|
||||
LINK = "#aaa"
|
||||
PLOT_H = 190
|
||||
BX0, BGAP = 105, 15
|
||||
SX0, SGAP = 372, 15
|
||||
BODY_W = 9
|
||||
FRAME_L = SX0 - 9
|
||||
COL_X = 600
|
||||
MIDX = FRAME_L - 20
|
||||
PAD = 0.06
|
||||
|
||||
out, LABELS = [], []
|
||||
|
||||
|
||||
def text(x, y, s, fill=INK, anchor="start", bold=False, size=12):
|
||||
st = [f"font-size:{size}px"] + (["font-weight:bold"] if bold else [])
|
||||
a = f' text-anchor="{anchor}"' if anchor != "start" else ""
|
||||
w = len(s) * (5.7 if size >= 12 else size * 0.5)
|
||||
x0 = x if anchor == "start" else (x - w / 2 if anchor == "middle" else x - w)
|
||||
assert 4 <= x0 and x0 + w <= W - 4, f"text iese din viewBox: {s!r} ({x0:.0f}..{x0 + w:.0f})"
|
||||
LABELS.append((x0, x0 + w, y, s))
|
||||
out.append(f'<text x="{x:.1f}" y="{y:.1f}" fill="{fill}"{a} style="{";".join(st)}">{s}</text>')
|
||||
|
||||
|
||||
def hline(x1, x2, y, color, dash, width=1.5):
|
||||
out.append(f'<line x1="{x1:.1f}" y1="{y:.1f}" x2="{x2:.1f}" y2="{y:.1f}" '
|
||||
f'stroke="{color}" stroke-width="{width}" stroke-dasharray="{dash}"/>')
|
||||
|
||||
|
||||
def line(x1, y1, x2, y2, color, dash="", width=1.2, marker=""):
|
||||
d = f' stroke-dasharray="{dash}"' if dash else ""
|
||||
m = f' marker-end="url(#{marker})"' if marker else ""
|
||||
out.append(f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{x2:.1f}" y2="{y2:.1f}" '
|
||||
f'stroke="{color}" stroke-width="{width}"{d}{m}/>')
|
||||
|
||||
|
||||
def rect(x0_, y0_, x1, y1, color, fill_op=0.10, dash=""):
|
||||
d = f' stroke-dasharray="{dash}"' if dash else ""
|
||||
out.append(f'<rect x="{x0_:.1f}" y="{y0_:.1f}" width="{x1 - x0_:.1f}" '
|
||||
f'height="{y1 - y0_:.1f}" fill="{color}" fill-opacity="{fill_op}" '
|
||||
f'stroke="{color}" stroke-width="1.2"{d}/>')
|
||||
|
||||
|
||||
def candles(bars, x0, gap, yf):
|
||||
for i, (o_, h_, l_, c_) in enumerate(bars):
|
||||
cx = x0 + i * gap
|
||||
line(cx, yf(h_), cx, yf(l_), "#1a1a1a", width=1.2)
|
||||
top_ = yf(max(o_, c_))
|
||||
hh = max(yf(min(o_, c_)) - top_, 1.6)
|
||||
out.append(f'<rect x="{cx - BODY_W / 2:.1f}" y="{top_:.1f}" width="{BODY_W}" '
|
||||
f'height="{hh:.1f}" fill="{GREEN if c_ >= o_ else RED}"/>')
|
||||
|
||||
|
||||
def seg_dist(p, a, b):
|
||||
(px, py), (ax, ay), (bx, by) = p, a, b
|
||||
dx, dy = bx - ax, by - ay
|
||||
t = 0.0 if dx == dy == 0 else max(0.0, min(1.0, ((px - ax) * dx + (py - ay) * dy)
|
||||
/ (dx * dx + dy * dy)))
|
||||
return ((px - ax - t * dx) ** 2 + (py - ay - t * dy) ** 2) ** 0.5
|
||||
|
||||
|
||||
out.append('<defs><marker id="pt-red" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" '
|
||||
'markerHeight="7" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#c00"/></marker>'
|
||||
'</defs>')
|
||||
text(20, 22, "Pasul 1 — nivelul se citește pe daily, trigger-ul se ia pe 60 min",
|
||||
bold=True, size=13)
|
||||
text(20, 40, "Graficul din dreapta e aceeași bucată de piață, mărită: 2 candele daily = 14 bare "
|
||||
"de 60 min", fill="#555", size=11)
|
||||
|
||||
top = 76
|
||||
text(20, top - 8, "daily: unde e nivelul", fill="#555", size=11)
|
||||
text(FRAME_L, top - 8, "60 min: descompunerea ultimelor 2 candele daily", fill="#555", size=11)
|
||||
|
||||
zlo_, zhi_ = sl, max(b[1] for b in FINE)
|
||||
pad = PAD * (zhi_ - zlo_)
|
||||
lo, hi = zlo_ - pad, zhi_ + pad
|
||||
bmax = max(b[1] for b in big)
|
||||
bmin = min(min(b[2] for b in big), lo)
|
||||
bs, ss = PLOT_H / (bmax - bmin), PLOT_H / (hi - lo)
|
||||
yb = lambda p: top + (bmax - p) * bs # noqa: E731
|
||||
ys = lambda p: top + (hi - p) * ss # noqa: E731
|
||||
|
||||
# ---- panoul daily ----------------------------------------------------------
|
||||
lx0, lx1 = BX0 + len(BASE) * BGAP - 6, BX0 + (len(big) - 1) * BGAP + 9
|
||||
ly0, ly1 = yb(hi), yb(lo)
|
||||
rect(lx0, ly0, lx1, ly1, BLUE, fill_op=0.06, dash="4 3")
|
||||
hline(BX0 - 15, lx1, yb(PIVOT), BLUE, "4 3")
|
||||
text(30, yb(PIVOT) + 12, "pivot monthly", fill=BLUE, size=11)
|
||||
text(30, yb(PIVOT) + 26, f"{PIVOT:.2f}", fill=BLUE, size=11, bold=True)
|
||||
candles(big, BX0, BGAP, yb)
|
||||
# zona de evidențiere: ultimele candele daily, acolo unde prețul ajunge la nivel
|
||||
zx0, zx1 = BX0 + (len(BASE) - 2) * BGAP - 8, lx0 - 3
|
||||
rect(zx0, yb(big[-3][1]) - 4, zx1, yb(PIVOT) + 10, GREEN, fill_op=0.10)
|
||||
text(BX0 - 15, top + PLOT_H + 20, "downtrend care se oprește la un nivel:", fill=GREEN,
|
||||
size=11, bold=True)
|
||||
text(BX0 - 15, top + PLOT_H + 34, "fără nivelul de dedesubt e doar downtrend", fill=GREEN,
|
||||
size=11, bold=True)
|
||||
text(BX0 - 15, top + PLOT_H + 48, "care continuă — nu ai unde pune stopul", fill=GREEN,
|
||||
size=11, bold=True)
|
||||
# pe daily nu ai unde să intri mai devreme de close-ul zilei: stopul e același
|
||||
# (low-ul zilei = low-ul piciorului 2), dar intrarea e cu o zi întreagă mai sus
|
||||
line(BX0 - 19, yb(b_entry), lx1, yb(b_entry), GREEN, dash="6 3", width=1.3)
|
||||
text(30, yb(b_entry) - 20, f"intrare pe daily {b_entry:.2f} = close-ul zilei", fill=GREEN, size=10)
|
||||
text(30, yb(b_entry) - 6, "(mai devreme n-ai ce citi pe daily)", fill=GREEN, size=10)
|
||||
|
||||
# ---- ghidajele de lupă -----------------------------------------------------
|
||||
guides = [((lx1, ly0), (FRAME_L, top)), ((lx1, ly1), (FRAME_L, top + PLOT_H))]
|
||||
for a_, b_ in guides:
|
||||
line(a_[0], a_[1], b_[0], b_[1], BLUE, dash="5 3", width=1.1)
|
||||
|
||||
# ---- conectorul nivelului comun -------------------------------------------
|
||||
ycb, ycs = yb(PIVOT), ys(PIVOT)
|
||||
|
||||
|
||||
def clearance(mx):
|
||||
conn = [((lx1, ycb), (mx, ycb)), ((mx, ycb), (mx, ycs)), ((mx, ycs), (FRAME_L, ycs))]
|
||||
pts = [(sx + (ex - sx) * t / 24, sy + (ey - sy) * t / 24)
|
||||
for (sx, sy), (ex, ey) in conn for t in range(25)]
|
||||
return min(seg_dist(q, ga, gb) for q in pts if q[0] >= lx1 + 10 for ga, gb in guides)
|
||||
|
||||
|
||||
mid = max(range(int(lx1) + 14, int(FRAME_L) - 13), key=clearance)
|
||||
# pivotul e aproape de marginea de jos a lupei, deci conectorul are de mers
|
||||
# printr-un coridor îngust între cele două ghidaje; 8 px e minimul la care
|
||||
# linia lui punctată se citește încă separat de ghidaj.
|
||||
assert clearance(mid) > 8, f"conectorul trece la {clearance(mid):.1f} px de un ghidaj"
|
||||
out.append(f'<path d="M{lx1:.1f},{ycb:.1f} H{mid:.1f} V{ycs:.1f} H{FRAME_L:.1f}" '
|
||||
f'fill="none" stroke={LINK!r} stroke-width="1.0" stroke-dasharray="3 3"/>')
|
||||
text(min(mid + 5, FRAME_L - 58), (ycb + ycs) / 2 + 4, "același nivel", fill="#888", size=10)
|
||||
|
||||
# ---- panoul 60 min ---------------------------------------------------------
|
||||
y_e, y_sl, y_tp, y_p = ys(entry), ys(sl), ys(tp), ys(PIVOT)
|
||||
assert abs((y_sl - y_e) / (y_e - y_tp) - 1) < 1e-6, "SL-intrare != intrare-TP1 în px"
|
||||
assert top + PLOT_H - y_sl > 6, "linia de stop e lipită de marginea cadrului"
|
||||
frame_r = SX0 + (len(FINE) - 1) * SGAP + 9
|
||||
rect(FRAME_L, top, frame_r, top + PLOT_H, BLUE, fill_op=0.03)
|
||||
# zona verde peste piciorul 2 + intrare
|
||||
sx0, sx1 = SX0 + LEG2 * SGAP - 9, SX0 + ENTRY_I * SGAP + 9
|
||||
rect(sx0, y_e - 6, sx1, ys(leg2_l) + 4, GREEN)
|
||||
hline(FRAME_L, frame_r, y_p, BLUE, "4 3")
|
||||
hline(FRAME_L, frame_r, y_e, GREEN, "6 3")
|
||||
hline(FRAME_L, frame_r, y_sl, RED, "6 3")
|
||||
hline(FRAME_L, frame_r, y_tp, GREEN, "2 3")
|
||||
candles(FINE, SX0, SGAP, ys)
|
||||
# linia care desparte cele două zile
|
||||
xd = SX0 + (K - 0.5) * SGAP
|
||||
line(xd, top + 2, xd, top + PLOT_H - 2, "#bbb", dash="2 4", width=1)
|
||||
text(SX0 + 3 * SGAP, top + 12, "ziua 1", fill="#999", anchor="middle", size=10)
|
||||
text(SX0 + 10 * SGAP, top + 12, "ziua 2", fill="#999", anchor="middle", size=10)
|
||||
# etichetele coloanei din dreapta, fiecare legată de linia ei
|
||||
for y, lines_, fill in [(y_tp + 4, [f"TP1 {tp:.2f} = 1:1"], GREEN),
|
||||
(y_e + 4, [f"intrare {entry:.2f}"], GREEN),
|
||||
(y_p + 4, [f"pivot monthly {PIVOT:.2f}"], BLUE),
|
||||
(y_sl + 4, [f"stop {sl:.2f}", f"= {risk / entry * 100:.2f} %".replace(".", ","),
|
||||
"0.10 sub piciorul 2"], RED)]:
|
||||
line(frame_r + 2, y - 4, COL_X - 4, y - 4, fill, width=0.8)
|
||||
for j, s in enumerate(lines_):
|
||||
text(COL_X, y + j * 14, s, fill=fill, size=10)
|
||||
# marcaje pe cele două picioare
|
||||
line(SX0 + LEG1 * SGAP, ys(leg1_l) + 4, SX0 + LEG1 * SGAP, top + PLOT_H + 8, GRAY, width=1)
|
||||
text(SX0 + LEG1 * SGAP, top + PLOT_H + 20, f"piciorul 1: {leg1_l:.2f}", fill="#666",
|
||||
anchor="middle", size=10)
|
||||
text(SX0 + LEG1 * SGAP, top + PLOT_H + 34, "ține pivotul", fill="#666", anchor="middle", size=10)
|
||||
line(SX0 + LEG2 * SGAP, ys(leg2_l) + 4, SX0 + LEG2 * SGAP, top + PLOT_H + 46, RED, width=1)
|
||||
text(frame_r, top + PLOT_H + 58, f"piciorul 2: {leg2_l:.2f} — rupe pivotul și se închide", fill=RED,
|
||||
anchor="end", size=10)
|
||||
text(frame_r, top + PLOT_H + 72, "înapoi peste el: acolo sunt măturate stopurile", fill=RED,
|
||||
anchor="end", size=10)
|
||||
|
||||
# săgeata de comparație a stopurilor
|
||||
ya = top + PLOT_H + 92
|
||||
line(BX0 - 19, ya, SX0 + ENTRY_I * SGAP, ya, RED, width=1.6, marker="pt-red")
|
||||
text(20, ya + 18, f"același stop, două intrări: pe daily riști {b_risk / b_entry * 100:.2f} %, "
|
||||
f"pe 60 min {risk / entry * 100:.2f} % — de {ratio:.1f} ori mai puțin,".replace(".", ","),
|
||||
fill=RED, size=11, bold=True)
|
||||
text(20, ya + 32, "pentru că pe TF-ul mic intri lângă minim, nu la close-ul zilei", fill=RED,
|
||||
size=11, bold=True)
|
||||
|
||||
H = ya + 44
|
||||
for a in range(len(LABELS)):
|
||||
for b in range(a + 1, len(LABELS)):
|
||||
xa0, xa1, ya_, sa = LABELS[a]
|
||||
xb0, xb1, yb_, sb = LABELS[b]
|
||||
assert not (abs(ya_ - yb_) < 13.5 and xa0 < xb1 - 4 and xb0 < xa1 - 4), \
|
||||
f"etichete suprapuse: {sa!r} / {sb!r}"
|
||||
assert 0 < LABELS[a][2] < H, f"etichetă în afara înălțimii: {LABELS[a][3]!r}"
|
||||
# nivelul comun apare cu același număr pe ambele panouri
|
||||
v = f"{PIVOT:.2f}"
|
||||
assert any(v in s and x0 < MIDX for x0, _x1, _y, s in LABELS), "pivotul lipsește de pe panoul mare"
|
||||
assert any(v in s and x0 >= MIDX for x0, _x1, _y, s in LABELS), "pivotul lipsește de pe panoul mic"
|
||||
# niciun preț al panoului mic pe panoul mare și invers (în afara nivelului comun)
|
||||
for x0, _x1, _y, s in LABELS:
|
||||
rau = [b_entry] if x0 >= MIDX else [entry, sl, tp, leg1_l, leg2_l]
|
||||
for val in rau:
|
||||
assert f"{val:.2f}" not in s, f"eticheta {s!r} poartă prețul {val:.2f} al celuilalt panou"
|
||||
|
||||
svg = (f'<svg viewBox="0 0 {W} {H:.0f}" xmlns="http://www.w3.org/2000/svg" '
|
||||
f'style="width:100%;height:auto;font:12px sans-serif">\n ' + "\n ".join(out) + "\n</svg>")
|
||||
assert "\n\n" not in svg
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT.name}: pivot {PIVOT:.2f}, picior 1 {leg1_l:.2f} / picior 2 {leg2_l:.2f}, "
|
||||
f"intrare {entry:.2f}, SL {sl:.2f} (risc {risk:.2f}), TP1 {tp:.2f} la bara {first}; "
|
||||
f"stop daily {b_sl:.2f} = x{ratio:.2f}")
|
||||
98
gen/strategii/mdsrt_zona.svg
Normal file
@@ -0,0 +1,98 @@
|
||||
<svg viewBox="0 0 720 402" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<defs><marker id="pt-red" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#c00"/></marker></defs>
|
||||
<text x="20.0" y="22.0" fill="#333" style="font-size:13px;font-weight:bold">Pasul 1 — nivelul se citește pe daily, trigger-ul se ia pe 60 min</text>
|
||||
<text x="20.0" y="40.0" fill="#555" style="font-size:11px">Graficul din dreapta e aceeași bucată de piață, mărită: 2 candele daily = 14 bare de 60 min</text>
|
||||
<text x="20.0" y="68.0" fill="#555" style="font-size:11px">daily: unde e nivelul</text>
|
||||
<text x="363.0" y="68.0" fill="#555" style="font-size:11px">60 min: descompunerea ultimelor 2 candele daily</text>
|
||||
<rect x="219.0" y="228.7" width="30.0" height="37.3" fill="#1a5fb4" fill-opacity="0.06" stroke="#1a5fb4" stroke-width="1.2" stroke-dasharray="4 3"/>
|
||||
<line x1="90.0" y1="257.2" x2="249.0" y2="257.2" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30.0" y="269.2" fill="#1a5fb4" style="font-size:11px">pivot monthly</text>
|
||||
<text x="30.0" y="283.2" fill="#1a5fb4" style="font-size:11px;font-weight:bold">76.00</text>
|
||||
<line x1="105.0" y1="76.0" x2="105.0" y2="117.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="100.5" y="86.3" width="9" height="23.9" fill="#c00"/>
|
||||
<line x1="120.0" y1="99.9" x2="120.0" y2="137.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="115.5" y="110.2" width="9" height="20.5" fill="#c00"/>
|
||||
<line x1="135.0" y1="110.2" x2="135.0" y2="140.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="130.5" y="120.4" width="9" height="10.3" fill="#188a3e"/>
|
||||
<line x1="150.0" y1="113.6" x2="150.0" y2="163.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="145.5" y="120.4" width="9" height="35.9" fill="#c00"/>
|
||||
<line x1="165.0" y1="147.8" x2="165.0" y2="185.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="160.5" y="156.3" width="9" height="22.2" fill="#c00"/>
|
||||
<line x1="180.0" y1="168.3" x2="180.0" y2="205.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="175.5" y="178.5" width="9" height="20.5" fill="#c00"/>
|
||||
<line x1="195.0" y1="182.0" x2="195.0" y2="219.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="190.5" y="195.6" width="9" height="3.4" fill="#188a3e"/>
|
||||
<line x1="210.0" y1="188.8" x2="210.0" y2="236.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="205.5" y="195.6" width="9" height="37.6" fill="#c00"/>
|
||||
<line x1="225.0" y1="230.7" x2="225.0" y2="256.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="220.5" y="233.2" width="9" height="17.9" fill="#c00"/>
|
||||
<line x1="240.0" y1="237.5" x2="240.0" y2="262.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="235.5" y="239.2" width="9" height="12.0" fill="#188a3e"/>
|
||||
<rect x="187.0" y="184.8" width="29.0" height="82.4" fill="#188a3e" fill-opacity="0.1" stroke="#188a3e" stroke-width="1.2"/>
|
||||
<text x="90.0" y="286.0" fill="#188a3e" style="font-size:11px;font-weight:bold">downtrend care se oprește la un nivel:</text>
|
||||
<text x="90.0" y="300.0" fill="#188a3e" style="font-size:11px;font-weight:bold">fără nivelul de dedesubt e doar downtrend</text>
|
||||
<text x="90.0" y="314.0" fill="#188a3e" style="font-size:11px;font-weight:bold">care continuă — nu ai unde pune stopul</text>
|
||||
<line x1="86.0" y1="239.2" x2="249.0" y2="239.2" stroke="#188a3e" stroke-width="1.3" stroke-dasharray="6 3"/>
|
||||
<text x="30.0" y="219.2" fill="#188a3e" style="font-size:10px">intrare pe daily 77.05 = close-ul zilei</text>
|
||||
<text x="30.0" y="233.2" fill="#188a3e" style="font-size:10px">(mai devreme n-ai ce citi pe daily)</text>
|
||||
<line x1="249.0" y1="228.7" x2="363.0" y2="76.0" stroke="#1a5fb4" stroke-width="1.1" stroke-dasharray="5 3"/>
|
||||
<line x1="249.0" y1="266.0" x2="363.0" y2="266.0" stroke="#1a5fb4" stroke-width="1.1" stroke-dasharray="5 3"/>
|
||||
<path d="M249.0,257.2 H266.0 V221.0 H363.0" fill="none" stroke='#aaa' stroke-width="1.0" stroke-dasharray="3 3"/>
|
||||
<text x="271.0" y="243.1" fill="#888" style="font-size:10px">același nivel</text>
|
||||
<rect x="363.0" y="76.0" width="213.0" height="190.0" fill="#1a5fb4" fill-opacity="0.03" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<rect x="513.0" y="188.9" width="33.0" height="62.2" fill="#188a3e" fill-opacity="0.1" stroke="#188a3e" stroke-width="1.2"/>
|
||||
<line x1="363.0" y1="221.0" x2="576.0" y2="221.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<line x1="363.0" y1="194.9" x2="576.0" y2="194.9" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/>
|
||||
<line x1="363.0" y1="255.8" x2="576.0" y2="255.8" stroke="#c00" stroke-width="1.5" stroke-dasharray="6 3"/>
|
||||
<line x1="363.0" y1="134.0" x2="576.0" y2="134.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="2 3"/>
|
||||
<line x1="372.0" y1="86.2" x2="372.0" y2="129.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="367.5" y="99.2" width="9" height="21.7" fill="#c00"/>
|
||||
<line x1="387.0" y1="107.9" x2="387.0" y2="151.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="382.5" y="121.0" width="9" height="21.7" fill="#c00"/>
|
||||
<line x1="402.0" y1="134.0" x2="402.0" y2="177.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="397.5" y="142.7" width="9" height="26.1" fill="#c00"/>
|
||||
<line x1="417.0" y1="155.8" x2="417.0" y2="194.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="412.5" y="168.8" width="9" height="13.0" fill="#c00"/>
|
||||
<line x1="432.0" y1="173.2" x2="432.0" y2="216.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="427.5" y="181.9" width="9" height="21.7" fill="#c00"/>
|
||||
<line x1="447.0" y1="168.8" x2="447.0" y2="208.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="442.5" y="177.5" width="9" height="26.1" fill="#188a3e"/>
|
||||
<line x1="462.0" y1="164.5" x2="462.0" y2="199.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="457.5" y="177.5" width="9" height="13.0" fill="#c00"/>
|
||||
<line x1="477.0" y1="181.9" x2="477.0" y2="216.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="472.5" y="190.6" width="9" height="17.4" fill="#c00"/>
|
||||
<line x1="492.0" y1="199.3" x2="492.0" y2="229.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="487.5" y="208.0" width="9" height="17.4" fill="#c00"/>
|
||||
<line x1="507.0" y1="216.7" x2="507.0" y2="234.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="502.5" y="225.4" width="9" height="1.6" fill="#188a3e"/>
|
||||
<line x1="522.0" y1="203.6" x2="522.0" y2="247.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="517.5" y="212.3" width="9" height="13.0" fill="#188a3e"/>
|
||||
<line x1="537.0" y1="186.2" x2="537.0" y2="216.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="532.5" y="194.9" width="9" height="17.4" fill="#188a3e"/>
|
||||
<line x1="552.0" y1="155.8" x2="552.0" y2="203.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="547.5" y="168.8" width="9" height="26.1" fill="#188a3e"/>
|
||||
<line x1="567.0" y1="121.0" x2="567.0" y2="173.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="562.5" y="129.7" width="9" height="39.1" fill="#188a3e"/>
|
||||
<line x1="469.5" y1="78.0" x2="469.5" y2="264.0" stroke="#bbb" stroke-width="1" stroke-dasharray="2 4"/>
|
||||
<text x="417.0" y="88.0" fill="#999" text-anchor="middle" style="font-size:10px">ziua 1</text>
|
||||
<text x="522.0" y="88.0" fill="#999" text-anchor="middle" style="font-size:10px">ziua 2</text>
|
||||
<line x1="578.0" y1="134.0" x2="596.0" y2="134.0" stroke="#188a3e" stroke-width="0.8"/>
|
||||
<text x="600.0" y="138.0" fill="#188a3e" style="font-size:10px">TP1 77.00 = 1:1</text>
|
||||
<line x1="578.0" y1="194.9" x2="596.0" y2="194.9" stroke="#188a3e" stroke-width="0.8"/>
|
||||
<text x="600.0" y="198.9" fill="#188a3e" style="font-size:10px">intrare 76.30</text>
|
||||
<line x1="578.0" y1="221.0" x2="596.0" y2="221.0" stroke="#1a5fb4" stroke-width="0.8"/>
|
||||
<text x="600.0" y="225.0" fill="#1a5fb4" style="font-size:10px">pivot monthly 76.00</text>
|
||||
<line x1="578.0" y1="255.8" x2="596.0" y2="255.8" stroke="#c00" stroke-width="0.8"/>
|
||||
<text x="600.0" y="259.8" fill="#c00" style="font-size:10px">stop 75.60</text>
|
||||
<text x="600.0" y="273.8" fill="#c00" style="font-size:10px">= 0,92 %</text>
|
||||
<text x="600.0" y="287.8" fill="#c00" style="font-size:10px">0.10 sub piciorul 2</text>
|
||||
<line x1="432.0" y1="220.7" x2="432.0" y2="274.0" stroke="#888" stroke-width="1"/>
|
||||
<text x="432.0" y="286.0" fill="#666" text-anchor="middle" style="font-size:10px">piciorul 1: 76.05</text>
|
||||
<text x="432.0" y="300.0" fill="#666" text-anchor="middle" style="font-size:10px">ține pivotul</text>
|
||||
<line x1="522.0" y1="251.1" x2="522.0" y2="312.0" stroke="#c00" stroke-width="1"/>
|
||||
<text x="576.0" y="324.0" fill="#c00" text-anchor="end" style="font-size:10px">piciorul 2: 75.70 — rupe pivotul și se închide</text>
|
||||
<text x="576.0" y="338.0" fill="#c00" text-anchor="end" style="font-size:10px">înapoi peste el: acolo sunt măturate stopurile</text>
|
||||
<line x1="86.0" y1="358.0" x2="537.0" y2="358.0" stroke="#c00" stroke-width="1.6" marker-end="url(#pt-red)"/>
|
||||
<text x="20.0" y="376.0" fill="#c00" style="font-size:11px;font-weight:bold">același stop, două intrări: pe daily riști 1,88 %, pe 60 min 0,92 % — de 2,1 ori mai puțin,</text>
|
||||
<text x="20.0" y="390.0" fill="#c00" style="font-size:11px;font-weight:bold">pentru că pe TF-ul mic intri lângă minim, nu la close-ul zilei</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.1 KiB |
111
summaries/17_STRATEGII/fise/07_mdsrt_surse.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Surse — 7. MDSRT
|
||||
|
||||
Trimiterile la material pentru [`07_mdsrt.md`](../07_mdsrt.md). Stau aici, nu
|
||||
în capitol: în corpul tutorialului îngreunează cititul, dar fără ele nu se mai
|
||||
poate verifica nimic. Cifrele sunt linii din fișierele de sumarizare, nu din
|
||||
transcrieri.
|
||||
|
||||
Textul fără trimitere e explicația mea și nu adaugă reguli; ce completez eu
|
||||
începe cu **Completare proprie**. Toate diagramele sunt exemple construite, cu
|
||||
o excepție: la „Exemplul real" nivelurile (622.40, 622.00, 621.40, 622.60) și
|
||||
cele 8 candele dintre picioare sunt citite din sesiunea de întrebări, iar
|
||||
intrarea, stopul și ținta sunt construcția mea.
|
||||
|
||||
**Prescurtări:**
|
||||
`mdsrt` = [`02_strategia_5_mdsrt.md`](../../05_MODUL_4/02_strategia_5_mdsrt.md)
|
||||
(lecția principală; acoperă M și A integral, iar P doar parțial — transcrierea
|
||||
se întrerupe în mijlocul frazei despre plan, `mdsrt:325-327`) ·
|
||||
`power` = [`09_indicatorul_power.md`](../../03_MODUL_2/09_indicatorul_power.md) ·
|
||||
`rs` = [`06_indicatorul_de_performanta.md`](../../03_MODUL_2/06_indicatorul_de_performanta.md) ·
|
||||
`m2d` = [`14_strategia_1_m2d.md`](../../03_MODUL_2/14_strategia_1_m2d.md)
|
||||
(Bull Trail / Bear Trail) ·
|
||||
`atr` = [`05_volatilitatea_beta_atr_vix.md`](../../03_MODUL_2/05_volatilitatea_beta_atr_vix.md) ·
|
||||
`selectia` = [`11_selectia_simbolului.md`](../../08_ANALIZA_ZILNICA/11_selectia_simbolului.md) ·
|
||||
`fisa` = [`fise/mdsrt.md`](mdsrt.md) (fișa lungă a strategiei, cu toate
|
||||
citatele) ·
|
||||
fișierele datate sunt sesiuni Q&A din `../../09_QA/`.
|
||||
|
||||
**Nivelul 1 (ce face strategia, structura M → A → P)** — `mdsrt`: 3-9, 19-32,
|
||||
76-88 · `08_2026-01-20`: 21, 40-58 (M.A.P.) · `power`: 11-14 (Power e cel mai
|
||||
rapid indicator leading) · `mdsrt`: 4 (descompunerea acronimului, în care
|
||||
litera M nu apare — vezi nota din `fisa`).
|
||||
|
||||
**Pasul 1 — candidatul și zona** — `mdsrt`: 79-84, 420-429, 435-438, 446-448 ·
|
||||
`28_2025-05-27`: 360-361, 372-380, 397-402 · `10_2025-12-02`: 759-761
|
||||
(`close > 10` la short) · `18_2025-09-23`: 163-226 (Radar Screen, refresh) ·
|
||||
`selectia`: 639-657 (sectorul) · `rs`: 1-11 (cadranele) · `mdsrt`: 67-71
|
||||
(cadranul 1-2, pe monthly/quarterly).
|
||||
|
||||
**Pasul 2 — al doilea picior** — `19_2025-09-08`: 158-196 (mecanica short
|
||||
squeeze-ului, buy to cover, condiția de nivel dedesubt) · `15_2025-10-14`:
|
||||
130-153 (al doilea picior, DA/NU, stop sub low-ul piciorului) ·
|
||||
`24_2025-07-15`: 16-22 (ce face mulțimea pe breakdown), 140-141 (regula de
|
||||
invalidare — marcată la sursă drept completare a autorului, nu citat).
|
||||
|
||||
**Pasul 3 — divergența** — `mdsrt`: 34-42, 59-61, 71-74, 85-88, 432-434 (Power
|
||||
obligatoriu; Volume sau RS; Trinity) · `24_2025-07-15`: 151-162 (60 de candele
|
||||
în spate, minimum 5 între puncte, perechea se mută) · `23_2025-07-29`: 869-874
|
||||
(„pe 3 candele nu e") · `19_2025-09-08`: 168-177 (lower low pe preț, higher low
|
||||
pe volum) · `power`: 11-14.
|
||||
|
||||
**Pasul 4 — trigger-ul** — `mdsrt`: 27-32, 179-185, 246, 249-311 (DA/NU, doji
|
||||
la 592.50 față de zona 590.00) · `01_2026-08-25`: 272-275 (primele semnale) ·
|
||||
`mdsrt`: 166-177 (intrarea la spargerea maximului candelei-trigger, în exemplul
|
||||
construit al autorului sumarului).
|
||||
|
||||
**Pasul 5 — stopul și mărimea** — `mdsrt`: 159-164 (stop puțin sub minimul
|
||||
structurii), 313-320 (cele două variante: extrema ultimelor N candele sau ATR)
|
||||
· `atr` (cursul trimite acolo fără să repete formula) · `10_2025-12-02`:
|
||||
756-757 (N = 4 la alte strategii mecanice) · `15_2025-10-14`: 140-145 (stop sub
|
||||
low-ul piciorului 2) · `19_2025-09-08`: 204-218 (2 % pe tranzacție; procentul
|
||||
stopului nu e riscul) · `mdsrt`: 173-177 (riscul 0.80 din exemplul construit).
|
||||
Marja de 0.10 sub minim e regula acestui capitol, nu a cursului.
|
||||
|
||||
**Pasul 6 — ieșirea** — `mdsrt`: 322-327 (țintă simetrică, trail pe Bull Trail
|
||||
sau swing low, „sau, sau, sau și și"), 325-327 (transcrierea se întrerupe:
|
||||
numărul de tranșe lipsește) · `m2d`: 74-79 (definiția Bull Trail) ·
|
||||
`24_2025-07-15`: 166-176 (breakeven după ce prețul a trecut de peste 50 % din
|
||||
distanța stopului) · `01_2026-08-25`: 226-227 (trail-ul se citește pe candelă
|
||||
închisă).
|
||||
|
||||
**Oglinda pe short** — `mdsrt`: 330 și urm. (transcrierea numește triggerele de
|
||||
short, apoi se oprește) · `28_2025-05-27`: 397-402 (nimic sub 10 $) ·
|
||||
`10_2025-12-02`: 759-761. Regulile M/A/P de short din capitol sunt
|
||||
reconstrucție prin oglindire, marcate ca atare.
|
||||
|
||||
**A+ și Trinity** — `mdsrt`: 6-8, 34-42, 79-88, 179-185, 435-438 ·
|
||||
`19_2025-09-08`: 193-195 · `15_2025-10-14`: 125-127 (pullback față de breakout:
|
||||
risc 2.50 → 5R vs. risc 9.50 → 0.6R), 138-149 · `24_2025-07-15`: 140-141 ·
|
||||
`selectia`: 612-627 (celălalt sens al lui „Trinity").
|
||||
|
||||
**Exemplul real (SPY 5 min)** — `24_2025-07-15`: 12-14, 26-29, 121-128
|
||||
(„este MDSRT pă 5 minute"; picior 1 = 622.40, pivot daily 622.00, picior 2 =
|
||||
621.40, Buy Hammer care închide 622.60, 8 candele între picioare) ·
|
||||
`19_2025-09-08`: 168-177 (divergența pe volum). Intrarea 623.00, stopul 621.30
|
||||
și ținta 624.70 sunt construcția mea, pe regulile capitolului.
|
||||
|
||||
**Scanerul și Radar Screen** — `mdsrt`: 420-429, 446-448 · `28_2025-05-27`:
|
||||
382-393 (candelă închisă, timeframe manual) · `18_2025-09-23`: 220-226 (fără
|
||||
refresh vezi un M care nu mai există) · `16_2025-10-07`: 83-106 (orice filtru
|
||||
peste o strategie mecanică o face discreționară — spus despre MP², aplicat aici
|
||||
prin analogie, deducție proprie).
|
||||
|
||||
**Transfer (prop și BVB)** — `19_2025-09-08`: 204-218 (singura regulă de risc
|
||||
din material) · `power`: 1-14 (Power e proprietar) · `rs`: 1-11 ·
|
||||
`09_2025-12-09`: 1177-1180 (pivoții clasici se calculează „1 la 1" și fără
|
||||
TradeStation) · `selectia`: 639-657. Restul secțiunii — profilul de prop,
|
||||
pragurile în RON, universul BET, procentul de 35-40 % care supraviețuiește — e
|
||||
judecata mea, nu material de curs.
|
||||
|
||||
**Contradicții** — pragul coborârii: `mdsrt`: 79-82 față de `28_2025-05-27`:
|
||||
360-361 · „Trinity": `mdsrt`: 34-42 față de `selectia`: 612-627 · stopul:
|
||||
`mdsrt`: 313-320 · tranșele: `mdsrt`: 325-327 · intrarea: `mdsrt`: 166-177
|
||||
față de 246. Toate, la un loc, în
|
||||
[`A2_contradictii.md`](../A2_contradictii.md).
|
||||
|
||||
**Generatoarele diagramelor** (cifrele din desene ies din serii, prin assert):
|
||||
`gen/strategii/mdsrt_ansamblu.py` ține seria canonică a capitolului și regulile
|
||||
numerice (marja de 0.10, intrarea la spargerea maximului, ținta 1:1); `picior`,
|
||||
`trigger`, `stop`, `iesire` și `short` o importă de acolo, ca să nu existe două
|
||||
reguli diferite în același capitol. `zona` desface două candele daily în 14
|
||||
bare de 60 de minute, cu agregare verificată bară cu bară.
|
||||