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
This commit is contained in:
Claude Agent
2026-09-20 12:50:01 +00:00
parent 7e5c7093fa
commit f8dd2f7bd0
19 changed files with 3840 additions and 1629 deletions

View 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})")