Files
atm-curs-dl/gen/strategii/atmi_risc.py
Claude Agent c08c857274 atmi: diagramele refacute, cinci noi, si fisa de surse
Noi: pivoti (PPQ/SQ calculati din trimestrul precedent, cu formula pe
desen), perechi_tf (weekly -> daily ca descompunere reala, cu caseta,
ghidaje si PPQ pe ambele panouri), trigger (BIM apoi verde, fata de
verde inainte de BIM — cutitul in cadere), risc (ce inseamna "fara
stop": 24 de bare sub apa, -20 % pe pozitie), reinvestire (ciclul
banilor pe trei cicluri).

aplus devine corectie: diagrama arata un prag de corectie, nu un setup
A+, si numele vechi trimitea la altceva.

Trei bug-uri reale: exemplul era etichetat weekly cu 20 de bare, dar
textul spunea "un an mai tarziu" — trecut pe monthly cu assert pe numarul
de luni; ansamblul avea o trimitere fisier:linie desenata in SVG; si
benzile PPQ/SQ erau inversate ca sens, cu SQ fix pe intrare.

PPQ 95.80 si SQ 90.80 sunt completare proprie — cursul spune explicit ca
nu da valorile; derivate cu formula standard, cu assert.

Textul capitolului e neatins — agentul a atins pragul de context.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
2026-09-20 12:46:55 +00:00

101 lines
4.9 KiB
Python

"""ATMI — Pasul 5: ce înseamnă „fără stop-loss", desenat.
Același trade ca în restul capitolului (intrare 96.00, țintă +10 % = 105.60),
dar arătând drumul, nu doar capetele: între intrare și țintă poziția trece
printr-un drawdown — pierdere flotantă — de 20 % pe poziție, fără ca nimic
să te scoată din ea. Cifra de 20-30 % pe poziție fără levier e a cursului
(COVID 2020, 2018); traseul barelor e construit de mine.
Coloana din dreapta traduce aceeași cădere de 20 % a indicelui în pierdere
pe poziție, pe trei variante de instrument — calculul e în cod.
Rulează: python3 gen/strategii/atmi_risc.py
"""
import sys
from pathlib import Path
sys.path.insert(0, "/workspace/atm-curs-dl")
from svg_candles import Chart, Level, Mark, from_closes # noqa: E402
OUT = Path(__file__).resolve().parent / "atmi_risc.svg"
GRAY, RED, GREEN, BLUE, INK, PURPLE = "#777", "#c00", "#188a3e", "#1a5fb4", "#333", "#7b2fbf"
ENTRY, TP, PPQ = 96.00, 105.60, 95.80
DD_PCT = 20.0 # drawdown pe poziție, fără levier
FUND = round(ENTRY * (1 - DD_PCT / 100), 2) # 76.80
# 3 bare de context + intrarea + 14 bare în jos + 17 bare de revenire
CLOSES = ([98.20, 97.10, 96.40, ENTRY]
+ [94.60, 92.80, 90.90, 89.40, 90.70, 88.60, 86.30, 84.40,
85.60, 83.10, 81.00, 79.20, 78.10, FUND]
+ [78.40, 80.60, 82.90, 84.50, 86.80, 88.40, 90.10, 92.30,
94.00, ENTRY, 97.80, 99.40, 100.90, 102.20, 103.40, 104.50, TP])
ENTRY_I, FUND_I, BE_I, TP_I = 3, 17, 27, len(CLOSES) - 1
assert CLOSES[ENTRY_I] == ENTRY and CLOSES[FUND_I] == FUND
assert CLOSES[BE_I] == ENTRY and CLOSES[TP_I] == TP
wicks = [(0.35, 0.35)] * len(CLOSES)
wicks[ENTRY_I] = (0.30, 0.10)
wicks[FUND_I] = (0.30, 0.00) # fundul e exact -20 %
wicks[FUND_I + 1] = (0.35, 0.00) # nicio bară de după nu coboară sub fund
wicks[TP_I] = (0.00, 0.35) # ținta e exact maximul seriei
cds = from_closes(CLOSES, wicks=wicks, vols=[44 + (i * 11) % 41 for i in range(len(CLOSES))],
start=98.90)
# --- ce susține textul -----------------------------------------------------
fund = round(min(c.l for c in cds), 2)
assert fund == FUND, fund
assert round((ENTRY - fund) / ENTRY * 100, 1) == DD_PCT
assert round(max(c.h for c in cds), 2) == TP
assert round(TP / ENTRY, 3) == 1.100
assert cds[FUND_I].l == fund and all(c.l >= fund for c in cds)
assert FUND < PPQ, "fundul trebuie să fie sub pivotul pe care ai cumpărat"
assert BE_I > FUND_I and CLOSES[BE_I] == ENTRY, "lipsește revenirea pe zero"
DURATA_JOS = BE_I - ENTRY_I # câte bare stai sub prețul de intrare
assert DURATA_JOS == 24, DURATA_JOS
# aceeași cădere de 20 % pe indice, tradusă pe trei instrumente
VARIANTE = [("ETF simplu (SPY)", 1), ("ETF cu levier 2x", 2), ("ETF cu levier 3x (SPXL)", 3)]
PIERDERI = [(n, round(DD_PCT * k, 1)) for n, k in VARIANTE]
assert PIERDERI[-1][1] == 60.0, PIERDERI
COVID = 34.0 # SPY în 2020, cifra cursului
assert round(COVID * 3, 1) > 100.0, "3x pe -34 % trebuie să treacă de -100 %"
levels = [
Level(TP, f"TP +10 % = {TP:.2f}", BLUE),
Level(ENTRY, f"intrare {ENTRY:.2f}", GREEN, label_at="right"),
Level(fund, f"fund {fund:.2f} = -{DD_PCT:.0f} % pe poziție", RED, label_at="left"),
]
marks = [
Mark(FUND_I, f"-{DD_PCT:.0f} %: nimic nu te scoate", RED, "below"),
Mark(BE_I, "abia aici ești pe zero", GRAY, "above", dy=-22),
Mark(TP_I, "TP", BLUE, "below"),
]
ch = Chart(candles=cds, levels=levels, marks=marks,
scale=5.6, gap=16, body_w=9, left=56, width=720, vol_h=60, top=152,
label_gap=46,
caption="Cifra de 20-30 % pe poziție fără levier e a cursului; traseul barelor "
"e construit de mine, ca să se vadă cât durează.")
svg = ch.render()
titlu = ('<text x="24" y="24" fill="#333" style="font-weight:bold">'
'SPY — daily: fără stop, între intrare și țintă treci prin toată căderea</text>')
sub = (f'<text x="24" y="42" fill="#555" style="font-size:11px">'
f'{DURATA_JOS} de bare sub prețul de intrare, fără niciun ordin care să te scoată '
f'— ăsta e costul regulii „fără stop-loss".</text>')
box = [f'<rect x="424" y="58" width="284" height="76" fill="#fff4f4" stroke="{RED}" '
f'stroke-opacity="0.5"/>',
f'<text x="436" y="76" fill="{RED}" style="font-size:11px;font-weight:bold">'
f'aceeași cădere de {DD_PCT:.0f} % pe indice, pe poziție:</text>']
for i, (nume, pct) in enumerate(PIERDERI):
box.append(f'<text x="436" y="{94 + i * 15}" fill="{INK}" style="font-size:11px">'
f'{nume}: -{pct:.0f} %</text>')
i = svg.index(">") + 1
svg = svg[:i] + "\n " + "\n ".join([titlu, sub] + box) + svg[i:]
assert "\n\n" not in svg and ".md:" not in svg
OUT.write_text(svg)
print(f"scris {OUT.name}: intrare {ENTRY} fund {fund} (-{DD_PCT} %) TP {TP}, "
f"{DURATA_JOS} bare sub apă")