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
@@ -1,6 +1,6 @@
|
||||
"""Diagrama de ansamblu ATMI (strategii/05_atmi.md, marcajul `ansamblu`).
|
||||
|
||||
„SPY — daily: corecție ≥4 % → SQ/PPQ → BIM + verde → intrare → TP +10 %".
|
||||
„SPY — daily: corecție ≥4 % → zona PPQ → BIM + verde → intrare → TP +10 %".
|
||||
|
||||
Structura seriei și nivelurile vin din spec-ul
|
||||
`gen/strategii/atmi_ansamblu.spec.txt`. Toate cifrele desenate (100.00 swing
|
||||
@@ -27,29 +27,32 @@ PURPLE = "#7b2fbf" # folosit în materialul de curs pentru PPQ
|
||||
# ---------------------------------------------------------------- seria (33 bare)
|
||||
# 15 bare de urcare ~88 -> 100, 8 de corecție 100 -> 96 (ultima = intrarea),
|
||||
# 10 de urcare 96 -> 105.60. open-ul fiecărei bare = close-ul precedentei.
|
||||
UP_A = [88.2, 88.8, 89.5, 90.1, 90.8, 91.6, 92.5, 93.3, 94.2, 95.1,
|
||||
96.0, 96.9, 97.8, 98.9, 100.00] # 0-14
|
||||
CORR = [99.3, 98.5, 97.8, 97.2, 96.7, 96.3, 96.00, 96.00] # 15-22
|
||||
UP_B = [96.6, 97.2, 97.9, 98.6, 99.4, 100.3, 101.4, 102.6, 104.0, 105.60] # 23-32
|
||||
UP_A = [96.60, 97.10, 97.60, 98.00, 98.50, 98.20, 98.70, 99.20,
|
||||
99.60, 99.30, 99.70, 100.00] # 0-11
|
||||
CORR = [99.30, 98.50, 97.80, 97.20, 96.70, 96.30, 95.90, 96.00] # 12-19 (18 = BIM)
|
||||
UP_B = [96.60, 97.20, 97.90, 98.60, 99.40, 100.30, 101.40, 102.60,
|
||||
103.40, 104.20, 104.90, 105.60] # 20-31
|
||||
CLOSES = UP_A + CORR + UP_B
|
||||
assert len(CLOSES) == 33, len(CLOSES)
|
||||
PEAK, BIM, ENTRY, LAST = 14, 21, 22, 32
|
||||
assert len(CLOSES) == 32, len(CLOSES)
|
||||
PEAK, BIM, ENTRY, LAST = 11, 18, 19, 31
|
||||
|
||||
# fitile (sus, jos) per bară; jos pe corecție ținut ≥ 0 ca minimul să fie fix 96.00
|
||||
WICKS = ([(0.30, 0.30)] * 14
|
||||
+ [(0.00, 0.30)] # 14: vârful atinge exact 100.00
|
||||
+ [(0.00, 0.00), (0.05, 0.10), (0.05, 0.10), (0.05, 0.15),
|
||||
(0.05, 0.15), (0.05, 0.20), (0.05, 0.00), (0.12, 0.00)] # 15-22
|
||||
+ [(0.25, 0.25)] * 9
|
||||
+ [(0.00, 0.20)]) # 32: închide/atinge exact 105.60
|
||||
assert len(WICKS) == len(CLOSES)
|
||||
WICKS = ([(0.25, 0.25)] * 11
|
||||
+ [(0.00, 0.25)] # 11: vârful atinge exact 100.00
|
||||
+ [(0.00, 0.20), (0.05, 0.20), (0.05, 0.20), (0.05, 0.20),
|
||||
(0.05, 0.20), (0.05, 0.20),
|
||||
(0.05, 0.35), # 18: bara de BIM, fundul la 95.55
|
||||
(0.15, 0.05)] # 19: candela verde de intrare
|
||||
+ [(0.25, 0.00)] + [(0.25, 0.25)] * 10
|
||||
+ [(0.00, 0.20)]) # 31: închide/atinge exact 105.60
|
||||
assert len(WICKS) == len(CLOSES), (len(WICKS), len(CLOSES))
|
||||
|
||||
VOLS = ([44, 47, 42, 50, 45, 41, 48, 43, 46, 51, 44, 49, 46, 52, 58] # 0-14 urcare
|
||||
+ [64, 70, 66, 61, 58, 74, 96, 88] # 15-22 corecție + BIM/intrare
|
||||
+ [55, 58, 52, 60, 57, 63, 59, 66, 72, 84]) # 23-32 urcare spre TP
|
||||
assert len(VOLS) == len(CLOSES)
|
||||
VOLS = ([44, 47, 42, 50, 45, 41, 48, 43, 46, 51, 44, 58] # 0-11 urcare
|
||||
+ [64, 70, 66, 61, 58, 74, 96, 88] # 12-19 corecție + BIM/intrare
|
||||
+ [55, 58, 52, 60, 57, 63, 59, 66, 70, 74, 78, 84]) # 20-31 urcare spre TP
|
||||
assert len(VOLS) == len(CLOSES), (len(VOLS), len(CLOSES))
|
||||
|
||||
cds = from_closes(CLOSES, wicks=WICKS, vols=VOLS, start=88.0)
|
||||
cds = from_closes(CLOSES, wicks=WICKS, vols=VOLS, start=96.20)
|
||||
|
||||
# ---------------------------------------------------------------- assert-urile din spec
|
||||
high = 100.00
|
||||
@@ -58,9 +61,9 @@ tp = cds[LAST].h
|
||||
assert abs((high - 96.00) / high * 100 - 4.0) < 0.05 # corecția e 4.0 %
|
||||
assert abs(entry - 96.00) < 0.05 # intrarea = close-ul candelei verzi
|
||||
assert abs(tp / entry - 1.10) < 0.005 # TP = +10 %
|
||||
assert abs(tp - max(c.h for c in cds[-10:])) < 1e-9 # TP atins la final, e maximul barelor
|
||||
assert abs(tp - max(c.h for c in cds[-12:])) < 1e-9 # TP atins la final, e maximul barelor
|
||||
assert BIM < ENTRY # BIM înainte de candela verde
|
||||
assert abs(min(c.l for c in cds[15:23]) - 96.00) < 1e-9 # minimul corecției = 96.00
|
||||
assert abs(min(c.l for c in cds[12:20]) - 95.55) < 1e-9 # fundul corecției = 95.55
|
||||
assert cds[ENTRY].c >= cds[ENTRY].o # candela de intrare e verde
|
||||
assert abs(cds[PEAK].h - high) < 1e-9 # swing high = 100.00
|
||||
assert abs(cds[LAST].c - tp) < 1e-9 # ultima bară închide pe TP
|
||||
@@ -75,16 +78,17 @@ assert all("stop" not in lv.text.lower() for lv in levels)
|
||||
assert all(lv.price >= entry - 1e-9 for lv in levels)
|
||||
|
||||
marks = [
|
||||
Mark(15, "corecție 4.0 %", ORANGE, "above"),
|
||||
Mark(BIM, "BIM", ORANGE, "above"),
|
||||
Mark(ENTRY, "BIM + candelă verde → intrare", GREEN, "below", dy=20),
|
||||
Mark(13, "corecție 4,0 %", ORANGE, "below", dy=26),
|
||||
Mark(BIM, "BIM", "#0a7f9e", "above"),
|
||||
Mark(ENTRY, "prima candelă verde → intrare", GREEN, "below", dy=30),
|
||||
Mark(LAST, "ieși cu tot", BLUE, "below", dy=22),
|
||||
]
|
||||
|
||||
ch = Chart(candles=cds, levels=levels, marks=marks,
|
||||
mas=[MA(20, ORANGE, dash="4 3", text="SMA-20 (ilustrativ)")],
|
||||
scale=18.0, gap=16, body_w=9, left=44, width=720, vol_h=70, top=70,
|
||||
scale=22.0, gap=17, body_w=9, left=44, width=720, vol_h=70, vol_gap=72, top=88,
|
||||
vol_label="volum",
|
||||
caption="Niveluri (100.00 / 96.00 / 105.60) din curs; PPQ/SQ schematice, fără cifre în material.")
|
||||
caption="100.00 / 96.00 / 105.60 sunt cifrele exemplului din curs; PPQ 95.80 e calculat "
|
||||
"în diagrama pasului 1 (cursul nu dă valorile pivoților).")
|
||||
|
||||
svg = ch.render()
|
||||
|
||||
@@ -98,26 +102,30 @@ def band(price: float, half: float, color: str, label: str) -> str:
|
||||
y_top, y_bot = ch._y(price + half), ch._y(price - half)
|
||||
return (f'<rect x="24" y="{y_top:.1f}" width="{ch.width - 38}" '
|
||||
f'height="{y_bot - y_top:.1f}" fill="{color}" opacity="0.10"/>'
|
||||
f'<text x="28" y="{y_top - 4:.1f}" fill="{color}">{label}</text>')
|
||||
f'<text x="28" y="{y_bot + 14:.1f}" fill="{color}">{label}</text>')
|
||||
|
||||
|
||||
# SQ e zona joasă (intrarea exact pe ea), PPQ zona mai sus, retragere mai mică
|
||||
assert (entry + 1.60 - 0.35) > (entry + 0.35), "benzile SQ și PPQ nu se suprapun"
|
||||
sq = band(entry, 0.35, GREEN, "SQ — zonă quarterly")
|
||||
ppq = band(entry + 1.60, 0.35, PURPLE, "PPQ — zonă quarterly")
|
||||
# PPQ 95.80 e pivotul trimestrial calculat în diagrama pasului 1; banda e
|
||||
# zona de cumpărare din jurul lui. SQ 90.80 e sub scara acestui desen, deci
|
||||
# nu se desenează aici — apare pe diagrama pasului 1.
|
||||
PPQ = 95.80
|
||||
assert abs(min(c.l for c in cds) - 95.55) < 1e-9
|
||||
assert PPQ - 0.30 <= min(c.l for c in cds) <= PPQ + 0.30, "fundul nu cade în banda PPQ"
|
||||
assert entry > PPQ, "candela verde trebuie să închidă peste pivot"
|
||||
ppq = band(PPQ, 0.30, PURPLE, f"zona PPQ {PPQ:.2f} — aici cumperi")
|
||||
sq = ""
|
||||
# „fără stop-loss standard" stă sub zona de intrare, unde nu are candele
|
||||
no_sl = (f'<text x="{ch._cx(ENTRY):.0f}" y="{ch._y(entry) + 63:.1f}" fill="{RED}" '
|
||||
f'text-anchor="middle">fără stop-loss standard</text>'
|
||||
f'<text x="{ch._cx(ENTRY):.0f}" y="{ch._y(entry) + 76:.1f}" fill="{GRAY}" '
|
||||
f'text-anchor="middle">(03_strategia_2_atmi.md:164-169)</text>')
|
||||
no_sl = (f'<text x="{ch._cx(ENTRY):.0f}" y="{ch._y(entry) + 46:.1f}" fill="{RED}" '
|
||||
f'text-anchor="middle">fără stop-loss standard — nicio linie sub intrare</text>')
|
||||
# titlul e injectat deasupra, ca rând separat de eticheta TP (care stă chiar
|
||||
# sub marginea de sus a panoului); altfel cele două texte se calcă la dreapta
|
||||
titlu = ('<text x="24" y="26" fill="#333" style="font-weight:bold">'
|
||||
'SPY — daily: corecție ≥4 % → SQ/PPQ → BIM + verde → intrare → TP +10 %</text>')
|
||||
'SPY — daily: corecție ≥4 % → zona PPQ → BIM + verde → intrare → TP +10 %</text>')
|
||||
|
||||
i = svg.index(">") + 1
|
||||
svg = svg[:i] + "\n " + "\n ".join([sq, ppq, no_sl, titlu]) + svg[i:]
|
||||
svg = svg[:i] + "\n " + "\n ".join([ppq, no_sl, titlu]) + svg[i:]
|
||||
|
||||
assert svg.count("\n\n") == 0, "linie goală în SVG rupe blocul din markdown"
|
||||
assert ".md:" not in svg, "trimitere fișier:linie în SVG"
|
||||
OUT.write_text(svg)
|
||||
print(f"scris {OUT.name}: {len(cds)} candele, intrare {entry:.2f}, TP {tp:.2f}")
|
||||
|
||||
@@ -1,119 +1,114 @@
|
||||
<svg viewBox="0 0 720 530" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<rect x="24" y="236.5" width="682" height="12.6" fill="#188a3e" opacity="0.10"/><text x="28" y="232.5" fill="#188a3e">SQ — zonă quarterly</text>
|
||||
<rect x="24" y="207.7" width="682" height="12.6" fill="#7b2fbf" opacity="0.10"/><text x="28" y="203.7" fill="#7b2fbf">PPQ — zonă quarterly</text>
|
||||
<text x="396" y="305.8" fill="#c00" text-anchor="middle">fără stop-loss standard</text><text x="396" y="318.8" fill="#777" text-anchor="middle">(03_strategia_2_atmi.md:164-169)</text>
|
||||
<text x="24" y="26" fill="#333" style="font-weight:bold">SPY — daily: corecție ≥4 % → SQ/PPQ → BIM + verde → intrare → TP +10 %</text>
|
||||
<line x1="24" y1="170.8" x2="706" y2="170.8" stroke="#333" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="164.8" fill="#333">100.00 — swing high recent</text>
|
||||
<line x1="24" y1="242.8" x2="706" y2="242.8" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="692" y="236.8" fill="#188a3e" text-anchor="end">intrare 96.00</text>
|
||||
<line x1="24" y1="70.0" x2="706" y2="70.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="692" y="64.0" fill="#1a5fb4" text-anchor="end">TP +10 % = 105.60</text>
|
||||
<polyline points="348.0,266.9 364.0,259.6 380.0,253.1 396.0,247.3 412.0,241.4 428.0,235.7 444.0,230.0 460.0,224.5 476.0,219.0 492.0,213.5 508.0,207.9 524.0,201.9 540.0,195.5 556.0,188.5" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="562" y="182" fill="#b06000">SMA-20 (ilustrativ)</text>
|
||||
<line x1="44.0" y1="377.8" x2="44.0" y2="392.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="39.5" y="383.2" width="9" height="3.6" fill="#188a3e"/>
|
||||
<line x1="60.0" y1="367.0" x2="60.0" y2="388.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="55.5" y="372.4" width="9" height="10.8" fill="#188a3e"/>
|
||||
<line x1="76.0" y1="354.4" x2="76.0" y2="377.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="71.5" y="359.8" width="9" height="12.6" fill="#188a3e"/>
|
||||
<line x1="92.0" y1="343.6" x2="92.0" y2="365.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="87.5" y="349.0" width="9" height="10.8" fill="#188a3e"/>
|
||||
<line x1="108.0" y1="331.0" x2="108.0" y2="354.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="103.5" y="336.4" width="9" height="12.6" fill="#188a3e"/>
|
||||
<line x1="124.0" y1="316.6" x2="124.0" y2="341.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="119.5" y="322.0" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="140.0" y1="300.4" x2="140.0" y2="327.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="135.5" y="305.8" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="156.0" y1="286.0" x2="156.0" y2="311.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="151.5" y="291.4" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="172.0" y1="269.8" x2="172.0" y2="296.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="167.5" y="275.2" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="188.0" y1="253.6" x2="188.0" y2="280.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="183.5" y="259.0" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="204.0" y1="237.4" x2="204.0" y2="264.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="199.5" y="242.8" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="220.0" y1="221.2" x2="220.0" y2="248.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="215.5" y="226.6" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="236.0" y1="205.0" x2="236.0" y2="232.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="231.5" y="210.4" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="252.0" y1="185.2" x2="252.0" y2="215.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="247.5" y="190.6" width="9" height="19.8" fill="#188a3e"/>
|
||||
<line x1="268.0" y1="170.8" x2="268.0" y2="196.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="263.5" y="170.8" width="9" height="19.8" fill="#188a3e"/>
|
||||
<line x1="284.0" y1="170.8" x2="284.0" y2="183.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="279.5" y="170.8" width="9" height="12.6" fill="#c00"/>
|
||||
<line x1="300.0" y1="182.5" x2="300.0" y2="199.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="295.5" y="183.4" width="9" height="14.4" fill="#c00"/>
|
||||
<line x1="316.0" y1="196.9" x2="316.0" y2="212.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="311.5" y="197.8" width="9" height="12.6" fill="#c00"/>
|
||||
<line x1="332.0" y1="209.5" x2="332.0" y2="223.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="327.5" y="210.4" width="9" height="10.8" fill="#c00"/>
|
||||
<line x1="348.0" y1="220.3" x2="348.0" y2="232.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="343.5" y="221.2" width="9" height="9.0" fill="#c00"/>
|
||||
<line x1="364.0" y1="229.3" x2="364.0" y2="241.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="359.5" y="230.2" width="9" height="7.2" fill="#c00"/>
|
||||
<line x1="380.0" y1="236.5" x2="380.0" y2="242.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="375.5" y="237.4" width="9" height="5.4" fill="#c00"/>
|
||||
<line x1="396.0" y1="240.6" x2="396.0" y2="242.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="391.5" y="242.8" width="9" height="1.6" fill="#188a3e"/>
|
||||
<line x1="412.0" y1="227.5" x2="412.0" y2="247.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="407.5" y="232.0" width="9" height="10.8" fill="#188a3e"/>
|
||||
<line x1="428.0" y1="216.7" x2="428.0" y2="236.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="423.5" y="221.2" width="9" height="10.8" fill="#188a3e"/>
|
||||
<line x1="444.0" y1="204.1" x2="444.0" y2="225.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="439.5" y="208.6" width="9" height="12.6" fill="#188a3e"/>
|
||||
<line x1="460.0" y1="191.5" x2="460.0" y2="213.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="455.5" y="196.0" width="9" height="12.6" fill="#188a3e"/>
|
||||
<line x1="476.0" y1="177.1" x2="476.0" y2="200.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="471.5" y="181.6" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="492.0" y1="160.9" x2="492.0" y2="186.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="487.5" y="165.4" width="9" height="16.2" fill="#188a3e"/>
|
||||
<line x1="508.0" y1="141.1" x2="508.0" y2="169.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="503.5" y="145.6" width="9" height="19.8" fill="#188a3e"/>
|
||||
<line x1="524.0" y1="119.5" x2="524.0" y2="150.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="519.5" y="124.0" width="9" height="21.6" fill="#188a3e"/>
|
||||
<line x1="540.0" y1="94.3" x2="540.0" y2="128.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="535.5" y="98.8" width="9" height="25.2" fill="#188a3e"/>
|
||||
<line x1="556.0" y1="70.0" x2="556.0" y2="102.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="551.5" y="70.0" width="9" height="28.8" fill="#188a3e"/>
|
||||
<line x1="24" y1="488.2" x2="706" y2="488.2" stroke="#888"/>
|
||||
<rect x="39.5" y="456.1" width="9" height="32.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="55.5" y="453.9" width="9" height="34.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="71.5" y="457.6" width="9" height="30.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="87.5" y="451.7" width="9" height="36.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="103.5" y="455.4" width="9" height="32.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="119.5" y="458.3" width="9" height="29.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="135.5" y="453.2" width="9" height="35.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="151.5" y="456.8" width="9" height="31.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="167.5" y="454.7" width="9" height="33.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="183.5" y="451.0" width="9" height="37.2" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="199.5" y="456.1" width="9" height="32.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="215.5" y="452.5" width="9" height="35.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="231.5" y="454.7" width="9" height="33.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="247.5" y="450.3" width="9" height="37.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="263.5" y="445.9" width="9" height="42.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="279.5" y="441.5" width="9" height="46.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="295.5" y="437.2" width="9" height="51.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="311.5" y="440.1" width="9" height="48.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="327.5" y="443.7" width="9" height="44.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="343.5" y="445.9" width="9" height="42.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="359.5" y="434.2" width="9" height="54.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="375.5" y="418.2" width="9" height="70.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="391.5" y="424.0" width="9" height="64.2" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="407.5" y="448.1" width="9" height="40.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="423.5" y="445.9" width="9" height="42.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="439.5" y="450.3" width="9" height="37.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="455.5" y="444.4" width="9" height="43.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="471.5" y="446.6" width="9" height="41.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="487.5" y="442.3" width="9" height="45.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="503.5" y="445.2" width="9" height="43.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="519.5" y="440.1" width="9" height="48.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="535.5" y="435.7" width="9" height="52.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="551.5" y="426.9" width="9" height="61.2" fill="#188a3e" opacity="0.55"/>
|
||||
<text x="24" y="412.2" fill="#555">volum</text>
|
||||
<text x="284.0" y="160.8" fill="#b06000" text-anchor="middle" style="font-weight:bold">corecție 4.0 %</text>
|
||||
<text x="380.0" y="226.5" fill="#b06000" text-anchor="middle" style="font-weight:bold">BIM</text>
|
||||
<text x="396.0" y="282.8" fill="#188a3e" text-anchor="middle" style="font-weight:bold">BIM + candelă verde → intrare</text>
|
||||
<text x="24" y="518" fill="#555">Niveluri (100.00 / 96.00 / 105.60) din curs; PPQ/SQ schematice, fără cifre în material.</text>
|
||||
<svg viewBox="0 0 720 493" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<rect x="24" y="297.0" width="682" height="13.2" fill="#7b2fbf" opacity="0.10"/><text x="28" y="324.2" fill="#7b2fbf">zona PPQ 95.80 — aici cumperi</text>
|
||||
<text x="367" y="345.2" fill="#c00" text-anchor="middle">fără stop-loss standard — nicio linie sub intrare</text>
|
||||
<text x="24" y="26" fill="#333" style="font-weight:bold">SPY — daily: corecție ≥4 % → zona PPQ → BIM + verde → intrare → TP +10 %</text>
|
||||
<line x1="24" y1="211.2" x2="706" y2="211.2" stroke="#333" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="205.2" fill="#333">100.00 — swing high recent</text>
|
||||
<line x1="24" y1="299.2" x2="706" y2="299.2" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="692" y="293.2" fill="#188a3e" text-anchor="end">intrare 96.00</text>
|
||||
<line x1="24" y1="88.0" x2="706" y2="88.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="692" y="82.0" fill="#1a5fb4" text-anchor="end">TP +10 % = 105.60</text>
|
||||
<line x1="44.0" y1="280.5" x2="44.0" y2="300.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="39.5" y="286.0" width="9" height="8.8" fill="#188a3e"/>
|
||||
<line x1="61.0" y1="269.5" x2="61.0" y2="291.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="56.5" y="275.0" width="9" height="11.0" fill="#188a3e"/>
|
||||
<line x1="78.0" y1="258.5" x2="78.0" y2="280.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="73.5" y="264.0" width="9" height="11.0" fill="#188a3e"/>
|
||||
<line x1="95.0" y1="249.7" x2="95.0" y2="269.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="90.5" y="255.2" width="9" height="8.8" fill="#188a3e"/>
|
||||
<line x1="112.0" y1="238.7" x2="112.0" y2="260.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="107.5" y="244.2" width="9" height="11.0" fill="#188a3e"/>
|
||||
<line x1="129.0" y1="238.7" x2="129.0" y2="256.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="124.5" y="244.2" width="9" height="6.6" fill="#c00"/>
|
||||
<line x1="146.0" y1="234.3" x2="146.0" y2="256.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="141.5" y="239.8" width="9" height="11.0" fill="#188a3e"/>
|
||||
<line x1="163.0" y1="223.3" x2="163.0" y2="245.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="158.5" y="228.8" width="9" height="11.0" fill="#188a3e"/>
|
||||
<line x1="180.0" y1="214.5" x2="180.0" y2="234.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="175.5" y="220.0" width="9" height="8.8" fill="#188a3e"/>
|
||||
<line x1="197.0" y1="214.5" x2="197.0" y2="232.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="192.5" y="220.0" width="9" height="6.6" fill="#c00"/>
|
||||
<line x1="214.0" y1="212.3" x2="214.0" y2="232.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="209.5" y="217.8" width="9" height="8.8" fill="#188a3e"/>
|
||||
<line x1="231.0" y1="211.2" x2="231.0" y2="223.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="226.5" y="211.2" width="9" height="6.6" fill="#188a3e"/>
|
||||
<line x1="248.0" y1="211.2" x2="248.0" y2="231.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="243.5" y="211.2" width="9" height="15.4" fill="#c00"/>
|
||||
<line x1="265.0" y1="225.5" x2="265.0" y2="248.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="260.5" y="226.6" width="9" height="17.6" fill="#c00"/>
|
||||
<line x1="282.0" y1="243.1" x2="282.0" y2="264.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="277.5" y="244.2" width="9" height="15.4" fill="#c00"/>
|
||||
<line x1="299.0" y1="258.5" x2="299.0" y2="277.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="294.5" y="259.6" width="9" height="13.2" fill="#c00"/>
|
||||
<line x1="316.0" y1="271.7" x2="316.0" y2="288.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="311.5" y="272.8" width="9" height="11.0" fill="#c00"/>
|
||||
<line x1="333.0" y1="282.7" x2="333.0" y2="297.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="328.5" y="283.8" width="9" height="8.8" fill="#c00"/>
|
||||
<line x1="350.0" y1="291.5" x2="350.0" y2="309.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="345.5" y="292.6" width="9" height="8.8" fill="#c00"/>
|
||||
<line x1="367.0" y1="295.9" x2="367.0" y2="302.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="362.5" y="299.2" width="9" height="2.2" fill="#188a3e"/>
|
||||
<line x1="384.0" y1="280.5" x2="384.0" y2="299.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="379.5" y="286.0" width="9" height="13.2" fill="#188a3e"/>
|
||||
<line x1="401.0" y1="267.3" x2="401.0" y2="291.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="396.5" y="272.8" width="9" height="13.2" fill="#188a3e"/>
|
||||
<line x1="418.0" y1="251.9" x2="418.0" y2="278.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="413.5" y="257.4" width="9" height="15.4" fill="#188a3e"/>
|
||||
<line x1="435.0" y1="236.5" x2="435.0" y2="262.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="430.5" y="242.0" width="9" height="15.4" fill="#188a3e"/>
|
||||
<line x1="452.0" y1="218.9" x2="452.0" y2="247.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="447.5" y="224.4" width="9" height="17.6" fill="#188a3e"/>
|
||||
<line x1="469.0" y1="199.1" x2="469.0" y2="229.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="464.5" y="204.6" width="9" height="19.8" fill="#188a3e"/>
|
||||
<line x1="486.0" y1="174.9" x2="486.0" y2="210.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="481.5" y="180.4" width="9" height="24.2" fill="#188a3e"/>
|
||||
<line x1="503.0" y1="148.5" x2="503.0" y2="185.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="498.5" y="154.0" width="9" height="26.4" fill="#188a3e"/>
|
||||
<line x1="520.0" y1="130.9" x2="520.0" y2="159.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="515.5" y="136.4" width="9" height="17.6" fill="#188a3e"/>
|
||||
<line x1="537.0" y1="113.3" x2="537.0" y2="141.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="532.5" y="118.8" width="9" height="17.6" fill="#188a3e"/>
|
||||
<line x1="554.0" y1="97.9" x2="554.0" y2="124.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="549.5" y="103.4" width="9" height="15.4" fill="#188a3e"/>
|
||||
<line x1="571.0" y1="88.0" x2="571.0" y2="107.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="566.5" y="88.0" width="9" height="15.4" fill="#188a3e"/>
|
||||
<line x1="24" y1="451.1" x2="706" y2="451.1" stroke="#888"/>
|
||||
<rect x="39.5" y="419.0" width="9" height="32.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="56.5" y="416.8" width="9" height="34.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="73.5" y="420.5" width="9" height="30.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="90.5" y="414.6" width="9" height="36.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="107.5" y="418.3" width="9" height="32.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="124.5" y="421.2" width="9" height="29.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="141.5" y="416.1" width="9" height="35.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="158.5" y="419.7" width="9" height="31.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="175.5" y="417.6" width="9" height="33.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="192.5" y="413.9" width="9" height="37.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="209.5" y="419.0" width="9" height="32.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="226.5" y="408.8" width="9" height="42.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="243.5" y="404.4" width="9" height="46.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="260.5" y="400.1" width="9" height="51.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="277.5" y="403.0" width="9" height="48.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="294.5" y="406.6" width="9" height="44.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="311.5" y="408.8" width="9" height="42.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="328.5" y="397.1" width="9" height="54.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="345.5" y="381.1" width="9" height="70.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="362.5" y="386.9" width="9" height="64.2" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="379.5" y="411.0" width="9" height="40.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="396.5" y="408.8" width="9" height="42.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="413.5" y="413.2" width="9" height="37.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="430.5" y="407.3" width="9" height="43.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="447.5" y="409.5" width="9" height="41.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="464.5" y="405.2" width="9" height="45.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="481.5" y="408.1" width="9" height="43.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="498.5" y="403.0" width="9" height="48.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="515.5" y="400.1" width="9" height="51.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="532.5" y="397.1" width="9" height="54.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="549.5" y="394.2" width="9" height="56.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="566.5" y="389.8" width="9" height="61.2" fill="#188a3e" opacity="0.55"/>
|
||||
<text x="24" y="375.1" fill="#555">volum</text>
|
||||
<text x="265.0" y="294.6" fill="#b06000" text-anchor="middle" style="font-weight:bold">corecție 4,0 %</text>
|
||||
<text x="350.0" y="281.5" fill="#0a7f9e" text-anchor="middle" style="font-weight:bold">BIM</text>
|
||||
<text x="367.0" y="323.1" fill="#188a3e" text-anchor="middle" style="font-weight:bold">prima candelă verde → intrare</text>
|
||||
<text x="571.0" y="149.8" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">ieși cu tot</text>
|
||||
<text x="24" y="481" fill="#555">100.00 / 96.00 / 105.60 sunt cifrele exemplului din curs; PPQ 95.80 e calculat în diagrama pasului 1 (cursul nu dă valorile pivoților).</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.3 KiB |
@@ -1,6 +1,6 @@
|
||||
"""ATMI — aceeași corecție: 4.0 % (DA) vs. 3.9 % (NU; cursul zice „3.93 %").
|
||||
|
||||
Citește specificația `gen/strategii/atmi_aplus.spec.txt`.
|
||||
Citește specificația `gen/strategii/atmi_corectie.spec.txt`.
|
||||
|
||||
O singură serie de 32 de candele daily (open-ul fiecărei bare = close-ul
|
||||
precedentei, deci seria e continuă), care urmează calea DA: urcare la swing
|
||||
@@ -19,6 +19,7 @@ sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
from svg_candles import Chart, Level, Mark, from_closes # noqa: E402
|
||||
|
||||
GRAY, RED, GREEN, BLUE, ORANGE, INK = "#777", "#c00", "#188a3e", "#1a5fb4", "#b06000", "#333"
|
||||
PURPLE = "#7b2fbf"
|
||||
|
||||
# --- seria: 32 de close-uri, structura din specificație ----------------------
|
||||
# 0-11 urcare 90.00 -> 100.00 (swing high la bara 11)
|
||||
@@ -38,7 +39,7 @@ assert len(closes) == 32
|
||||
# wick-uri (sus, jos): implicite (0.25, 0.30), cu excepțiile care fixează nivelurile
|
||||
wicks = [(0.25, 0.30)] * 32
|
||||
wicks[11] = (0.00, 0.30) # swing high: high = close = 100.00
|
||||
wicks[18] = (0.20, 0.45) # BIM: codiță lungă în jos (hammer)
|
||||
wicks[18] = (0.20, 0.43) # BIM: codiță lungă în jos, fundul la 95.55
|
||||
wicks[19] = (0.20, 0.15) # candela de intrare
|
||||
wicks[31] = (0.00, 0.30) # TP: high = close = 105.60
|
||||
|
||||
@@ -115,7 +116,7 @@ ch = Chart(
|
||||
Mark(BIM_I, "BIM", GREEN, "above", dy=-2),
|
||||
Mark(ENTRY_I, "candelă verde → trigger", GREEN, "below", dy=20),
|
||||
],
|
||||
scale=18.0, gap=16, body_w=9, left=44, width=680, vol_h=70,
|
||||
scale=21.0, gap=16, body_w=9, left=44, width=680, vol_h=70,
|
||||
vol_label="volum", title="SPY — daily: aceeași corecție, 4.0 % (DA) vs. 3.9 % (NU)",
|
||||
caption="Calea DA (candele): 4.0 % la 96.00. Calea NU (punctat): 3.9 % („3.93 %” în curs) — fără intrare.",
|
||||
)
|
||||
@@ -123,9 +124,14 @@ svg = ch.render()
|
||||
|
||||
# --- elemente suplimentare, pe coordonatele graficului -----------------------
|
||||
x0, x1 = 24, ch.width - 14
|
||||
band_top, band_bot = ch._y(96.40), ch._y(95.40)
|
||||
PPQ = 95.80 # pivotul trimestrial, calculat în atmi_pivoti.py
|
||||
FUND = round(min(c.l for c in cds[12:20]), 2)
|
||||
assert FUND == 95.55, FUND
|
||||
assert PPQ - 0.30 <= FUND <= PPQ + 0.30, "fundul căii DA nu cade în banda PPQ"
|
||||
assert NU_STOP >= PPQ + 0.30, "calea NU ar coborî în zona de cumpărare"
|
||||
band_top, band_bot = ch._y(PPQ + 0.30), ch._y(PPQ - 0.30)
|
||||
band = (f'<rect x="{x0}" y="{band_top:.1f}" width="{x1 - x0}" height="{band_bot - band_top:.1f}" '
|
||||
f'fill="{GRAY}" opacity="0.10"/>')
|
||||
f'fill="{PURPLE}" opacity="0.12"/>')
|
||||
|
||||
nu_line = ('<polyline points="' + " ".join(f"{ch._cx(i):.1f},{ch._y(p):.1f}" for i, p in nu_pts) + '" '
|
||||
f'fill="none" stroke="{RED}" stroke-width="1.8" stroke-dasharray="5 4"/>')
|
||||
@@ -135,15 +141,15 @@ nu_hline = (f'<line x1="24" y1="{ch._y(NU_STOP):.1f}" x2="{ch.width - 14}" y2="{
|
||||
# punctul de oprire al traseului NU (96.10, strict deasupra pragului de 4 %)
|
||||
stop_dot = (f'<circle cx="{ch._cx(17):.1f}" cy="{ch._y(NU_STOP):.1f}" r="3.5" fill="{RED}"/>')
|
||||
# eticheta traseului NU, sub linia 96.10 (nu se suprapune cu eticheta verde de 96.00)
|
||||
nu_lab = (f'<text x="{ch.width - 28}" y="{ch._y(NU_STOP) + 12:.1f}" fill="{RED}" text-anchor="end">'
|
||||
f'96.10 = 3.9 % — NU, sub prag</text>')
|
||||
nu_lab = (f'<text x="30" y="{ch._y(NU_STOP) - 8:.1f}" fill="{RED}">'
|
||||
f'{NU_STOP:.2f} = 3.9 % — NU, sub prag</text>')
|
||||
# eticheta zonei quarterly, sub banda (fără cifre: cursul nu le dă)
|
||||
zone_lab = (f'<text x="{ch.width - 28}" y="{ch._y(95.40) + 13:.1f}" fill="{GRAY}" text-anchor="end">'
|
||||
f'zonă quarterly</text>')
|
||||
zone_lab = (f'<text x="30" y="{ch._y(PPQ - 0.30) + 34:.1f}" fill="{PURPLE}">'
|
||||
f'zona PPQ {PPQ:.2f} — aici cumperi</text>')
|
||||
# legende scurte ale celor două trasee
|
||||
da_lab = (f'<text x="24" y="{ch._y(98.50):.1f}" fill="{GREEN}" '
|
||||
da_lab = (f'<text x="24" y="{ch._y(97.60):.1f}" fill="{GREEN}" '
|
||||
f'style="font-weight:bold">calea DA (candelele)</text>')
|
||||
nu_leg = (f'<text x="{ch._cx(25):.1f}" y="{ch._y(94.45) + 16:.1f}" fill="{RED}" '
|
||||
nu_leg = (f'<text x="{ch._cx(25):.1f}" y="{ch._y(94.45) + 30:.1f}" fill="{RED}" '
|
||||
f'style="font-weight:bold">calea NU (continuă în jos)</text>')
|
||||
|
||||
overlay = [nu_line, nu_hline, stop_dot, nu_lab, zone_lab, da_lab, nu_leg]
|
||||
@@ -151,8 +157,9 @@ svg = svg.replace(">", ">\n " + band, 1) # ban
|
||||
svg = svg.replace("\n</svg>", "\n " + "\n ".join(overlay) + "\n</svg>") # traseele, peste
|
||||
|
||||
assert "\n\n" not in svg, "linie goală în SVG"
|
||||
assert ".md:" not in svg, "trimitere fișier:linie în SVG"
|
||||
assert "</svg>" in svg and "stroke-dasharray=\"5 4\"" in svg, "traseul NU nu a fost inserat"
|
||||
|
||||
with open("/workspace/atm-curs-dl/gen/strategii/atmi_aplus.svg", "w") as f:
|
||||
with open("/workspace/atm-curs-dl/gen/strategii/atmi_corectie.svg", "w") as f:
|
||||
f.write(svg)
|
||||
print("scris gen/strategii/atmi_aplus.svg")
|
||||
print("scris gen/strategii/atmi_corectie.svg")
|
||||
|
||||
119
gen/strategii/atmi_corectie.svg
Normal file
@@ -0,0 +1,119 @@
|
||||
<svg viewBox="0 0 680 557" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<rect x="24" y="233.5" width="642" height="12.6" fill="#7b2fbf" opacity="0.12"/>
|
||||
<text x="24" y="48" fill="#333" style="font-weight:bold">SPY — daily: aceeași corecție, 4.0 % (DA) vs. 3.9 % (NU)</text>
|
||||
<line x1="24" y1="173.6" x2="666" y2="173.6" stroke="#333" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="652" y="167.6" fill="#333" text-anchor="end">100.00 — swing high</text>
|
||||
<line x1="24" y1="257.6" x2="666" y2="257.6" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="652" y="251.6" fill="#188a3e" text-anchor="end">96.00 = 4.0 % — DA, intri</text>
|
||||
<line x1="24" y1="56.0" x2="666" y2="56.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="652" y="50.0" fill="#1a5fb4" text-anchor="end">TP +10 % = 105.60</text>
|
||||
<line x1="44.0" y1="378.3" x2="44.0" y2="402.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="39.5" y="383.6" width="9" height="12.6" fill="#188a3e"/>
|
||||
<line x1="60.0" y1="359.4" x2="60.0" y2="389.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="55.5" y="364.7" width="9" height="18.9" fill="#188a3e"/>
|
||||
<line x1="76.0" y1="342.6" x2="76.0" y2="371.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="71.5" y="347.9" width="9" height="16.8" fill="#188a3e"/>
|
||||
<line x1="92.0" y1="327.9" x2="92.0" y2="354.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="87.5" y="333.2" width="9" height="14.7" fill="#188a3e"/>
|
||||
<line x1="108.0" y1="311.1" x2="108.0" y2="339.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="103.5" y="316.4" width="9" height="16.8" fill="#188a3e"/>
|
||||
<line x1="124.0" y1="294.3" x2="124.0" y2="322.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="119.5" y="299.6" width="9" height="16.8" fill="#188a3e"/>
|
||||
<line x1="140.0" y1="279.6" x2="140.0" y2="305.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="135.5" y="284.9" width="9" height="14.7" fill="#188a3e"/>
|
||||
<line x1="156.0" y1="264.9" x2="156.0" y2="291.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="151.5" y="270.2" width="9" height="14.7" fill="#188a3e"/>
|
||||
<line x1="172.0" y1="250.2" x2="172.0" y2="276.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="167.5" y="255.5" width="9" height="14.7" fill="#188a3e"/>
|
||||
<line x1="188.0" y1="231.3" x2="188.0" y2="261.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="183.5" y="236.6" width="9" height="18.9" fill="#188a3e"/>
|
||||
<line x1="204.0" y1="204.0" x2="204.0" y2="242.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="199.5" y="209.3" width="9" height="27.3" fill="#188a3e"/>
|
||||
<line x1="220.0" y1="173.6" x2="220.0" y2="215.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="215.5" y="173.6" width="9" height="35.7" fill="#188a3e"/>
|
||||
<line x1="236.0" y1="168.3" x2="236.0" y2="194.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="231.5" y="173.6" width="9" height="14.7" fill="#c00"/>
|
||||
<line x1="252.0" y1="183.0" x2="252.0" y2="211.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="247.5" y="188.3" width="9" height="16.8" fill="#c00"/>
|
||||
<line x1="268.0" y1="199.8" x2="268.0" y2="228.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="263.5" y="205.1" width="9" height="16.8" fill="#c00"/>
|
||||
<line x1="284.0" y1="216.6" x2="284.0" y2="240.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="279.5" y="221.9" width="9" height="12.6" fill="#c00"/>
|
||||
<line x1="300.0" y1="229.2" x2="300.0" y2="251.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="295.5" y="234.5" width="9" height="10.5" fill="#c00"/>
|
||||
<line x1="316.0" y1="239.8" x2="316.0" y2="259.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="311.5" y="245.0" width="9" height="8.4" fill="#c00"/>
|
||||
<line x1="332.0" y1="249.2" x2="332.0" y2="267.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="327.5" y="253.4" width="9" height="4.6" fill="#c00"/>
|
||||
<line x1="348.0" y1="253.4" x2="348.0" y2="261.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="343.5" y="257.6" width="9" height="1.6" fill="#188a3e"/>
|
||||
<line x1="364.0" y1="231.3" x2="364.0" y2="263.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="359.5" y="236.6" width="9" height="21.0" fill="#188a3e"/>
|
||||
<line x1="380.0" y1="212.4" x2="380.0" y2="242.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="375.5" y="217.7" width="9" height="18.9" fill="#188a3e"/>
|
||||
<line x1="396.0" y1="193.5" x2="396.0" y2="224.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="391.5" y="198.8" width="9" height="18.9" fill="#188a3e"/>
|
||||
<line x1="412.0" y1="174.6" x2="412.0" y2="205.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="407.5" y="179.9" width="9" height="18.9" fill="#188a3e"/>
|
||||
<line x1="428.0" y1="157.8" x2="428.0" y2="186.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="423.5" y="163.1" width="9" height="16.8" fill="#188a3e"/>
|
||||
<line x1="444.0" y1="141.0" x2="444.0" y2="169.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="439.5" y="146.3" width="9" height="16.8" fill="#188a3e"/>
|
||||
<line x1="460.0" y1="124.2" x2="460.0" y2="152.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="455.5" y="129.5" width="9" height="16.8" fill="#188a3e"/>
|
||||
<line x1="476.0" y1="107.4" x2="476.0" y2="135.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="471.5" y="112.7" width="9" height="16.8" fill="#188a3e"/>
|
||||
<line x1="492.0" y1="90.6" x2="492.0" y2="119.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="487.5" y="95.9" width="9" height="16.8" fill="#188a3e"/>
|
||||
<line x1="508.0" y1="73.8" x2="508.0" y2="102.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="503.5" y="79.1" width="9" height="16.8" fill="#188a3e"/>
|
||||
<line x1="524.0" y1="61.2" x2="524.0" y2="85.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="519.5" y="66.5" width="9" height="12.6" fill="#188a3e"/>
|
||||
<line x1="540.0" y1="56.0" x2="540.0" y2="72.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="535.5" y="56.0" width="9" height="10.5" fill="#188a3e"/>
|
||||
<line x1="24" y1="498.5" x2="666" y2="498.5" stroke="#888"/>
|
||||
<rect x="39.5" y="460.3" width="9" height="38.2" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="55.5" y="458.7" width="9" height="39.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="71.5" y="461.9" width="9" height="36.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="87.5" y="457.1" width="9" height="41.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="103.5" y="455.5" width="9" height="43.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="119.5" y="458.7" width="9" height="39.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="135.5" y="454.0" width="9" height="44.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="151.5" y="457.1" width="9" height="41.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="167.5" y="452.4" width="9" height="46.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="183.5" y="450.8" width="9" height="47.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="199.5" y="447.6" width="9" height="50.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="215.5" y="441.2" width="9" height="57.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="231.5" y="442.8" width="9" height="55.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="247.5" y="439.6" width="9" height="58.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="263.5" y="436.5" width="9" height="62.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="279.5" y="433.3" width="9" height="65.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="295.5" y="430.1" width="9" height="68.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="311.5" y="434.9" width="9" height="63.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="327.5" y="431.7" width="9" height="66.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="343.5" y="428.5" width="9" height="70.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="359.5" y="441.2" width="9" height="57.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="375.5" y="446.0" width="9" height="52.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="391.5" y="449.2" width="9" height="49.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="407.5" y="452.4" width="9" height="46.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="423.5" y="455.5" width="9" height="43.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="439.5" y="458.7" width="9" height="39.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="455.5" y="461.9" width="9" height="36.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="471.5" y="449.2" width="9" height="49.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="487.5" y="444.4" width="9" height="54.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="503.5" y="441.2" width="9" height="57.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="519.5" y="436.5" width="9" height="62.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="535.5" y="430.1" width="9" height="68.4" fill="#188a3e" opacity="0.55"/>
|
||||
<text x="24" y="422.5" fill="#555">volum</text>
|
||||
<text x="332.0" y="237.2" fill="#188a3e" text-anchor="middle" style="font-weight:bold">BIM</text>
|
||||
<text x="348.0" y="301.2" fill="#188a3e" text-anchor="middle" style="font-weight:bold">candelă verde → trigger</text>
|
||||
<text x="24" y="520.5" fill="#188a3e">Regula e pe procent, nu pe cât de dramatică arată linia: calea NU pare o cădere mare, dar e 3.9 %.</text>
|
||||
<text x="24" y="545" fill="#555">Calea DA (candele): 4.0 % la 96.00. Calea NU (punctat): 3.9 % („3.93 %” în curs) — fără intrare.</text>
|
||||
<polyline points="220.0,151.6 236.0,164.2 252.0,179.9 268.0,194.6 284.0,207.2 300.0,218.8 316.0,233.5 332.0,241.9 348.0,249.2 380.0,257.6 412.0,263.9 444.0,268.1" fill="none" stroke="#c00" stroke-width="1.8" stroke-dasharray="5 4"/>
|
||||
<line x1="24" y1="233.5" x2="666" y2="233.5" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<circle cx="316.0" cy="233.5" r="3.5" fill="#c00"/>
|
||||
<text x="30" y="225.5" fill="#c00">96.10 = 3.9 % — NU, sub prag</text>
|
||||
<text x="30" y="280.1" fill="#7b2fbf">zona PPQ 95.80 — aici cumperi</text>
|
||||
<text x="24" y="202.0" fill="#188a3e" style="font-weight:bold">calea DA (candelele)</text>
|
||||
<text x="444.0" y="298.1" fill="#c00" style="font-weight:bold">calea NU (continuă în jos)</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.8 KiB |
@@ -24,10 +24,10 @@ ENTRY = 117.43 # 04_MODUL_3/03_strategia_2_atmi.md:358-363
|
||||
TP = 129.17 # TP1 = +10 % pe 117.43 → 129.17 (":170-171, 358-363")
|
||||
SWING_HIGH = 123.00 # construit de mine ca să conțină corecția ≥4 %
|
||||
ENTRY_I = 17 # candela de intrare (verde, precedată de BIM)
|
||||
TP_I = 37 # ultima candelă: TP1 atins
|
||||
TP_I = 30 # ultima candelă: TP1 atins
|
||||
BIM_I = ENTRY_I - 1 # BIM (bară de inversare bearish) înaintea candelei verzi
|
||||
|
||||
# ── structura seriei: 12 sus → 6 corecție → intrare → 20 spre TP ───────────
|
||||
# ── structura seriei: 12 sus → 5 corecție → intrare → 13 luni spre TP ─────
|
||||
closes = [
|
||||
# ~12 candele de urcare spre swing high ~123.00
|
||||
115.80, 116.50, 117.20, 117.90, 117.60, 118.30,
|
||||
@@ -35,13 +35,11 @@ closes = [
|
||||
# ~6 candele de corecție, de la 123.00 în zona de intrare
|
||||
122.00, 121.10, 120.10, 119.00, 117.00,
|
||||
117.43, # candela de intrare (verde)
|
||||
# ~20 candele de urcare de la 117.43 spre 129.17
|
||||
118.00, 118.55, 119.05, 119.50, 119.95,
|
||||
120.40, 120.85, 121.25, 121.65, 122.10,
|
||||
122.50, 122.95, 123.40, 123.85, 124.30,
|
||||
125.00, 126.00, 127.10, 128.40, 129.17,
|
||||
# 13 candele lunare de urcare de la 117.43 spre 129.17 — „aproximativ un an"
|
||||
118.20, 119.10, 119.90, 120.60, 121.50, 122.40, 123.30,
|
||||
124.20, 125.30, 126.40, 127.40, 128.30, 129.17,
|
||||
]
|
||||
assert len(closes) == 38, len(closes)
|
||||
assert len(closes) == 31, len(closes)
|
||||
|
||||
wicks = [(0.25, 0.30)] * len(closes)
|
||||
wicks[0] = (0.35, 0.35)
|
||||
@@ -53,8 +51,8 @@ wicks[TP_I] = (0.00, 0.30) # high = 129.17 exact, ca TP să fie max(high)
|
||||
vols = [42, 40, 44, 47, 39, 45, 48, 52, 50, 55, 58, 62,
|
||||
57, 61, 66, 72, 84,
|
||||
70,
|
||||
58, 55, 53, 57, 54, 56, 59, 55, 57, 60, 58, 61,
|
||||
63, 60, 64, 66, 68, 72, 76, 88]
|
||||
58, 55, 53, 57, 54, 56, 59, 62, 64, 68, 72, 78, 88]
|
||||
assert len(vols) == len(closes), (len(vols), len(closes))
|
||||
|
||||
cds = from_closes(closes, wicks=wicks, vols=vols, start=115.30)
|
||||
|
||||
@@ -68,7 +66,7 @@ assert abs(tp - 129.17) < 0.05, tp
|
||||
assert abs(tp / entry - 1.10) < 0.005, tp / entry
|
||||
assert (swing_high - entry) / swing_high >= 0.04, (swing_high, entry)
|
||||
assert abs(entry - cds[ENTRY_I].c) < 0.05
|
||||
assert abs(max(c.h for c in cds[-10:]) - tp) < 0.05, max(c.h for c in cds[-10:])
|
||||
assert abs(max(c.h for c in cds[-13:]) - tp) < 0.05, max(c.h for c in cds[-13:])
|
||||
|
||||
# structura care susține afirmațiile din text
|
||||
assert abs(swing_high - SWING_HIGH) < 0.05, swing_high
|
||||
@@ -76,14 +74,15 @@ assert cds[ENTRY_I].c > cds[ENTRY_I].o, "candela de intrare trebuie să fie verd
|
||||
assert cds[BIM_I].c < cds[BIM_I].o, "BIM-ul dinaintea intrării trebuie să fie bearish"
|
||||
assert any(c.vol is not None for c in cds), "lipsește panoul de volum"
|
||||
|
||||
n_entry_to_tp = TP_I - ENTRY_I + 1
|
||||
assert 18 <= n_entry_to_tp <= 23, n_entry_to_tp
|
||||
LUNI = TP_I - ENTRY_I # câte candele lunare de la intrare la TP1
|
||||
assert 12 <= LUNI <= 14, LUNI # „aproximativ un an" din material
|
||||
|
||||
TP_LABEL = "TP1 atins ~1 an mai târziu (data exactă neclară în transcriere — ASR)"
|
||||
assert "~1 an" in TP_LABEL
|
||||
TP_LABEL = f"TP1 atins {LUNI} luni mai târziu — „aproximativ un an\" în material "\
|
||||
"(ziua exactă e neclară în transcriere)"
|
||||
assert "aproximativ un an" in TP_LABEL
|
||||
|
||||
levels = [
|
||||
Level(ENTRY, "intrare 117.43", "#188a3e", label_at="left"),
|
||||
Level(ENTRY, "intrare 117.43", "#188a3e", label_at="right"),
|
||||
Level(TP, "TP1 129.17 (+10 %)", "#1a5fb4"),
|
||||
]
|
||||
|
||||
@@ -101,6 +100,8 @@ assert len(levels) == 2, "doar intrare și TP; strategic nu există stop standar
|
||||
|
||||
# etichetele lungi merg ca linii de text sub grafic, ca să nu se bată cu
|
||||
# candelele din dreapta-sus (unde urcarea spre TP nu lasă loc liber)
|
||||
cds[TP_I - 2].note = ("trigger-ul (BIM + candela verde daily) se petrece în interiorul "
|
||||
"lunii de intrare — vezi diagrama pasului 4")
|
||||
cds[TP_I - 1].note = "după TP: capital + profit → cash până la următorul trigger valid"
|
||||
cds[TP_I].note = TP_LABEL
|
||||
|
||||
@@ -110,16 +111,17 @@ ch = Chart(
|
||||
marks=marks,
|
||||
mas=[MA(20, "#b06000", dash="4 3")],
|
||||
scale=9.5, width=660, gap=15, body_w=9, left=40, vol_h=70,
|
||||
vol_label="volum", title="SPY — weekly: intrare 117.43 (27.01.2005) → TP +10 % = 129.17",
|
||||
caption="Swing high ~123.00 construit de mine; cifrele de intrare/TP sunt din material.",
|
||||
vol_label="volum", title="SPY — monthly: intrare ianuarie 2005 la 117.43 → TP1 +10 % = 129.17",
|
||||
caption="Grafic lunar, ca să încapă orizontul poziției. Swing high-ul e al meu; "
|
||||
"intrarea și ținta sunt din material.",
|
||||
)
|
||||
|
||||
svg = ch.render()
|
||||
assert svg.count("\n\n") == 0, "linie goală în SVG — rupe markdown-ul"
|
||||
OUT.write_text(svg)
|
||||
|
||||
print(f"serie {len(cds)} candele | entry {entry:.2f} @ {ENTRY_I} | "
|
||||
print(f"serie {len(cds)} candele lunare | entry {entry:.2f} @ {ENTRY_I} | "
|
||||
f"tp {tp:.2f} @ {TP_I} | swing high {swing_high:.2f} "
|
||||
f"(corecție {(swing_high - entry) / swing_high * 100:.2f} %) | "
|
||||
f"entry→TP {n_entry_to_tp} candele (~1 an)")
|
||||
f"entry→TP {LUNI} luni")
|
||||
print(f"scris {OUT}")
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<svg viewBox="0 0 660 363" 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">SPY — weekly: intrare 117.43 (27.01.2005) → TP +10 % = 129.17</text>
|
||||
<svg viewBox="0 0 660 380" 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">SPY — monthly: intrare ianuarie 2005 la 117.43 → TP1 +10 % = 129.17</text>
|
||||
<line x1="24" y1="167.5" x2="646" y2="167.5" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="161.5" fill="#188a3e">intrare 117.43</text>
|
||||
<text x="632" y="161.5" fill="#188a3e" text-anchor="end">intrare 117.43</text>
|
||||
<line x1="24" y1="56.0" x2="646" y2="56.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="632" y="50.0" fill="#1a5fb4" text-anchor="end">TP1 129.17 (+10 %)</text>
|
||||
<polyline points="325.0,152.1 340.0,150.6 355.0,149.2 370.0,147.9 385.0,146.7 400.0,145.1 415.0,143.7 430.0,142.5 445.0,141.3 460.0,140.3 475.0,139.4 490.0,138.6 505.0,138.1 520.0,137.0 535.0,135.1 550.0,132.3 565.0,128.5 580.0,123.1 595.0,117.5" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<polyline points="325.0,151.8 340.0,149.8 355.0,147.9 370.0,145.9 385.0,143.7 400.0,141.0 415.0,138.2 430.0,135.2 445.0,132.0 460.0,128.7 475.0,125.2 490.0,121.7" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<line x1="40.0" y1="179.7" x2="40.0" y2="191.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="35.5" y="183.0" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="55.0" y1="174.0" x2="55.0" y2="185.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
@@ -41,46 +41,32 @@
|
||||
<rect x="275.5" y="152.6" width="9" height="19.0" fill="#c00"/>
|
||||
<line x1="295.0" y1="165.6" x2="295.0" y2="175.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="290.5" y="167.5" width="9" height="4.1" fill="#188a3e"/>
|
||||
<line x1="310.0" y1="159.7" x2="310.0" y2="170.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="305.5" y="162.1" width="9" height="5.4" fill="#188a3e"/>
|
||||
<line x1="325.0" y1="154.5" x2="325.0" y2="165.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="320.5" y="156.9" width="9" height="5.2" fill="#188a3e"/>
|
||||
<line x1="340.0" y1="149.8" x2="340.0" y2="159.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="335.5" y="152.1" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="355.0" y1="145.5" x2="355.0" y2="155.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="350.5" y="147.9" width="9" height="4.3" fill="#188a3e"/>
|
||||
<line x1="370.0" y1="141.2" x2="370.0" y2="150.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="365.5" y="143.6" width="9" height="4.3" fill="#188a3e"/>
|
||||
<line x1="385.0" y1="136.9" x2="385.0" y2="146.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="380.5" y="139.3" width="9" height="4.3" fill="#188a3e"/>
|
||||
<line x1="400.0" y1="132.7" x2="400.0" y2="142.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="395.5" y="135.0" width="9" height="4.3" fill="#188a3e"/>
|
||||
<line x1="415.0" y1="128.9" x2="415.0" y2="137.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="410.5" y="131.2" width="9" height="3.8" fill="#188a3e"/>
|
||||
<line x1="430.0" y1="125.1" x2="430.0" y2="134.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="425.5" y="127.4" width="9" height="3.8" fill="#188a3e"/>
|
||||
<line x1="445.0" y1="120.8" x2="445.0" y2="130.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="440.5" y="123.2" width="9" height="4.3" fill="#188a3e"/>
|
||||
<line x1="460.0" y1="117.0" x2="460.0" y2="126.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="455.5" y="119.4" width="9" height="3.8" fill="#188a3e"/>
|
||||
<line x1="475.0" y1="112.7" x2="475.0" y2="122.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="470.5" y="115.1" width="9" height="4.3" fill="#188a3e"/>
|
||||
<line x1="490.0" y1="108.4" x2="490.0" y2="117.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="485.5" y="110.8" width="9" height="4.3" fill="#188a3e"/>
|
||||
<line x1="505.0" y1="104.2" x2="505.0" y2="113.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="500.5" y="106.5" width="9" height="4.3" fill="#188a3e"/>
|
||||
<line x1="520.0" y1="99.9" x2="520.0" y2="109.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="515.5" y="102.3" width="9" height="4.3" fill="#188a3e"/>
|
||||
<line x1="535.0" y1="93.2" x2="535.0" y2="105.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="530.5" y="95.6" width="9" height="6.7" fill="#188a3e"/>
|
||||
<line x1="550.0" y1="83.7" x2="550.0" y2="98.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="545.5" y="86.1" width="9" height="9.5" fill="#188a3e"/>
|
||||
<line x1="565.0" y1="73.3" x2="565.0" y2="89.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="560.5" y="75.7" width="9" height="10.4" fill="#188a3e"/>
|
||||
<line x1="580.0" y1="60.9" x2="580.0" y2="78.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="575.5" y="63.3" width="9" height="12.4" fill="#188a3e"/>
|
||||
<line x1="595.0" y1="56.0" x2="595.0" y2="66.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="590.5" y="56.0" width="9" height="7.3" fill="#188a3e"/>
|
||||
<line x1="310.0" y1="157.8" x2="310.0" y2="170.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="305.5" y="160.2" width="9" height="7.3" fill="#188a3e"/>
|
||||
<line x1="325.0" y1="149.3" x2="325.0" y2="163.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="320.5" y="151.7" width="9" height="8.5" fill="#188a3e"/>
|
||||
<line x1="340.0" y1="141.7" x2="340.0" y2="154.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="335.5" y="144.1" width="9" height="7.6" fill="#188a3e"/>
|
||||
<line x1="355.0" y1="135.0" x2="355.0" y2="146.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="350.5" y="137.4" width="9" height="6.6" fill="#188a3e"/>
|
||||
<line x1="370.0" y1="126.5" x2="370.0" y2="140.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="365.5" y="128.9" width="9" height="8.6" fill="#188a3e"/>
|
||||
<line x1="385.0" y1="117.9" x2="385.0" y2="131.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="380.5" y="120.3" width="9" height="8.6" fill="#188a3e"/>
|
||||
<line x1="400.0" y1="109.4" x2="400.0" y2="123.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="395.5" y="111.8" width="9" height="8.5" fill="#188a3e"/>
|
||||
<line x1="415.0" y1="100.8" x2="415.0" y2="114.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="410.5" y="103.2" width="9" height="8.6" fill="#188a3e"/>
|
||||
<line x1="430.0" y1="90.4" x2="430.0" y2="106.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="425.5" y="92.8" width="9" height="10.4" fill="#188a3e"/>
|
||||
<line x1="445.0" y1="79.9" x2="445.0" y2="95.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="440.5" y="82.3" width="9" height="10.5" fill="#188a3e"/>
|
||||
<line x1="460.0" y1="70.4" x2="460.0" y2="85.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="455.5" y="72.8" width="9" height="9.5" fill="#188a3e"/>
|
||||
<line x1="475.0" y1="61.9" x2="475.0" y2="75.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="470.5" y="64.3" width="9" height="8.6" fill="#188a3e"/>
|
||||
<line x1="490.0" y1="56.0" x2="490.0" y2="67.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="485.5" y="56.0" width="9" height="8.3" fill="#188a3e"/>
|
||||
<line x1="24" y1="287.1" x2="646" y2="287.1" stroke="#888"/>
|
||||
<rect x="35.5" y="253.7" width="9" height="33.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="50.5" y="255.3" width="9" height="31.8" fill="#188a3e" opacity="0.55"/>
|
||||
@@ -107,25 +93,19 @@
|
||||
<rect x="365.5" y="244.1" width="9" height="43.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="380.5" y="242.5" width="9" height="44.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="395.5" y="240.2" width="9" height="46.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="410.5" y="243.3" width="9" height="43.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="425.5" y="241.7" width="9" height="45.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="440.5" y="239.4" width="9" height="47.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="455.5" y="241.0" width="9" height="46.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="470.5" y="238.6" width="9" height="48.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="485.5" y="237.0" width="9" height="50.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="500.5" y="239.4" width="9" height="47.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="515.5" y="236.2" width="9" height="50.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="530.5" y="234.6" width="9" height="52.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="545.5" y="233.0" width="9" height="54.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="560.5" y="229.8" width="9" height="57.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="575.5" y="226.6" width="9" height="60.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="590.5" y="217.1" width="9" height="70.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="410.5" y="237.8" width="9" height="49.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="425.5" y="236.2" width="9" height="50.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="440.5" y="233.0" width="9" height="54.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="455.5" y="229.8" width="9" height="57.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="470.5" y="225.0" width="9" height="62.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="485.5" y="217.1" width="9" height="70.0" fill="#188a3e" opacity="0.55"/>
|
||||
<text x="24" y="211.1" fill="#555">volum</text>
|
||||
<text x="205.0" y="104.6" fill="#c00" text-anchor="middle" style="font-weight:bold">swing high ~123.00</text>
|
||||
<text x="280.0" y="141.2" fill="#777" text-anchor="middle" style="font-weight:bold">BIM</text>
|
||||
<text x="295.0" y="195.4" fill="#188a3e" text-anchor="middle" style="font-weight:bold">27.01.2005</text>
|
||||
<text x="607.0" y="86.2" fill="#1a5fb4" text-anchor="end" style="font-weight:bold">TP1</text>
|
||||
<text x="24" y="309.1" fill="#188a3e">după TP: capital + profit → cash până la următorul trigger valid</text>
|
||||
<text x="24" y="326.1" fill="#188a3e">TP1 atins ~1 an mai târziu (data exactă neclară în transcriere — ASR)</text>
|
||||
<text x="24" y="351" fill="#555">Swing high ~123.00 construit de mine; cifrele de intrare/TP sunt din material.</text>
|
||||
<text x="490.0" y="87.1" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">TP1</text>
|
||||
<text x="24" y="309.1" fill="#188a3e">trigger-ul (BIM + candela verde daily) se petrece în interiorul lunii de intrare — vezi diagrama pasului 4</text>
|
||||
<text x="24" y="326.1" fill="#188a3e">după TP: capital + profit → cash până la următorul trigger valid</text>
|
||||
<text x="24" y="343.1" fill="#188a3e">TP1 atins 13 luni mai târziu — „aproximativ un an" în material (ziua exactă e neclară în transcriere)</text>
|
||||
<text x="24" y="368" fill="#555">Grafic lunar, ca să încapă orizontul poziției. Swing high-ul e al meu; intrarea și ținta sunt din material.</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 9.2 KiB |
260
gen/strategii/atmi_perechi_tf.py
Normal file
@@ -0,0 +1,260 @@
|
||||
#!/usr/bin/env python3
|
||||
"""ATMI — Pasul 3: nivelul trăiește pe weekly, declanșatorul pe daily.
|
||||
|
||||
Panoul din stânga (weekly) arată de unde pleacă corecția și unde stă zona de
|
||||
cumpărare. Panoul din dreapta NU e o serie care vine după el: e
|
||||
**descompunerea reală** a ultimelor 3 candele weekly — fiecare candelă
|
||||
weekly = 5 bare daily, cu open, close, max(high) și min(low) care coincid,
|
||||
verificat bară cu bară.
|
||||
|
||||
Sursa de adevăr e seria daily (`FINE`); candelele weekly din casetă se
|
||||
calculează din ea prin agregare, deci corespondența nu poate rămâne în urmă.
|
||||
|
||||
Nivelul comun e PPQ 95.80 (calculat în `atmi_pivoti.py`): e desenat pe
|
||||
ambele panouri, cu același număr, și legat printr-un conector — scările au
|
||||
pante diferite, e o lupă, deci același preț cade la înălțimi diferite.
|
||||
|
||||
Rulare: python3 gen/strategii/atmi_perechi_tf.py
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
W = 720
|
||||
K = 5 # 5 zile de bursă într-o săptămână
|
||||
NZ = 3 # câte candele weekly se sparg în dreapta
|
||||
PPQ, SQ = 95.80, 90.80 # din atmi_pivoti.py
|
||||
SWING = 100.00
|
||||
|
||||
GREEN, RED, GRAY, INK, BLUE = "#188a3e", "#c00", "#888", "#333", "#1a5fb4"
|
||||
PURPLE, CYAN, LINK = "#7b2fbf", "#0a7f9e", "#aaa"
|
||||
|
||||
# --- seria daily: 15 bare = 3 săptămâni ------------------------------------
|
||||
D_CLOSES = [98.60, 98.20, 97.90, 97.60, 97.90, # săptămâna 1
|
||||
97.50, 97.10, 96.80, 97.00, 96.60, # săptămâna 2
|
||||
96.30, 96.00, 95.90, 95.70, 96.00] # săptămâna 3 (13 = BIM, 14 = intrare)
|
||||
D_START = 98.90
|
||||
BIM_I, ENTRY_I = 13, 14
|
||||
|
||||
wick = [(0.15, 0.15)] * 15
|
||||
wick[BIM_I] = (0.10, 0.15) # bara de BIM coboară sub PPQ: 95.70 - 0.15 = 95.55
|
||||
wick[ENTRY_I] = (0.15, 0.05)
|
||||
|
||||
FINE, o = [], D_START
|
||||
for i, c in enumerate(D_CLOSES):
|
||||
wu, wd = wick[i]
|
||||
FINE.append((o, max(o, c) + wu, min(o, c) - wd, c))
|
||||
o = c
|
||||
|
||||
# --- barele weekly dinaintea lupei ----------------------------------------
|
||||
# (open, high, low, close); ultima închide exact pe open-ul primei bare daily
|
||||
BASE = [(93.60, 94.80, 93.30, 94.50), (94.50, 95.90, 94.20, 95.60),
|
||||
(95.60, 97.10, 95.30, 96.80), (96.80, 98.30, 96.50, 98.00),
|
||||
(98.00, 99.50, 97.70, 99.20), (99.20, 100.00, 98.90, 100.00),
|
||||
(100.00, 100.00, 98.60, 98.90)]
|
||||
SWING_I = 5
|
||||
|
||||
|
||||
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_
|
||||
|
||||
|
||||
ZOOM = aggregate(FINE, K, NZ)
|
||||
BIG = BASE + ZOOM
|
||||
|
||||
# --- ce trebuie să fie adevărat -------------------------------------------
|
||||
eq = lambda a, b: abs(a - b) < 0.005 # noqa: E731
|
||||
assert len(FINE) == K * NZ
|
||||
for name, bars in (("weekly", BIG), ("daily", 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"
|
||||
# lupa se leagă de restul graficului mare
|
||||
assert eq(FINE[0][0], BASE[-1][3]), "open-ul primei bare daily != close-ul ultimei weekly"
|
||||
# ce pretinde textul: corecția se întinde peste mai multe candele weekly, iar
|
||||
# trigger-ul cade în ultima
|
||||
assert eq(max(b[1] for b in BASE), SWING), max(b[1] for b in BASE)
|
||||
assert BIM_I // K == ENTRY_I // K == NZ - 1, "BIM și intrarea nu cad în aceeași săptămână"
|
||||
assert (BIM_I // K) > 0, "trigger-ul ar încăpea în prima candelă weekly a lupei"
|
||||
ENTRY = FINE[ENTRY_I][3]
|
||||
assert eq(ENTRY, 96.00) and eq((SWING - ENTRY) / SWING * 100, 4.0), ENTRY
|
||||
assert FINE[ENTRY_I][3] > FINE[ENTRY_I][0], "candela de intrare nu e verde"
|
||||
assert FINE[BIM_I][2] < PPQ < ENTRY, "prețul nu intră în zona PPQ înainte de intrare"
|
||||
assert eq(ZOOM[-1][3], ENTRY), "close-ul săptămânii = close-ul barei daily de intrare"
|
||||
assert eq(ZOOM[-1][2], FINE[BIM_I][2]), "low-ul săptămânii != low-ul barei de BIM"
|
||||
assert min(b[2] for b in BIG) > SQ, "seria desenată atinge deja SQ"
|
||||
# cât de aproape e fundul de PPQ, în procente — asta face zona „atinsă"
|
||||
DIST = abs(FINE[BIM_I][2] - PPQ) / PPQ * 100
|
||||
assert DIST < 0.5, DIST
|
||||
|
||||
# --- desen -----------------------------------------------------------------
|
||||
PLOT_H = 190
|
||||
BX0, BGAP = 132, 16
|
||||
SX0, SGAP = 392, 14
|
||||
BODY_W = 9
|
||||
FRAME_L = SX0 - 12
|
||||
COL_X = 608
|
||||
MIDX = FRAME_L - 20
|
||||
PAD = 0.07
|
||||
|
||||
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) * (size * 0.5 if size < 12 else 5.7)
|
||||
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="{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}"/>')
|
||||
|
||||
|
||||
out.append('<defs><marker id="pt" 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, "Nivelul trăiește pe weekly, declanșatorul pe daily", bold=True, size=13)
|
||||
text(20, 38, f"Fiecare candelă weekly din casetă = {K} bare daily (o săptămână de bursă):",
|
||||
fill="#555", size=11)
|
||||
text(20, 52, "același open, același close, max(high) și min(low) identice.",
|
||||
fill="#555", size=11)
|
||||
|
||||
top = 104
|
||||
text(20, top - 12, "weekly: de unde pleacă corecția", fill="#555", size=11)
|
||||
text(FRAME_L, top - 12, f"daily: ultimele {NZ} candele weekly, desfăcute", fill="#555", size=11)
|
||||
|
||||
zlo_, zhi_ = min(b[2] for b in FINE), max(b[1] for b in FINE)
|
||||
pad = PAD * (zhi_ - zlo_)
|
||||
lo, hi = zlo_ - pad, zhi_ + pad
|
||||
|
||||
bmax, bmin = max(b[1] for b in BIG), min(min(b[2] for b in BIG), SQ, 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 weekly ---------------------------------------------------------
|
||||
lx0, lx1 = BX0 + len(BASE) * BGAP - 7, 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 - 22, lx1, yb(PPQ), PURPLE, "4 3")
|
||||
hline(BX0 - 22, lx1, yb(SQ), GREEN, "4 3")
|
||||
hline(BX0 - 22, lx1, yb(SWING), "#555", "3 3", width=1.0)
|
||||
text(24, yb(SWING) + 13, f"swing high {SWING:.2f}", fill="#555", size=11)
|
||||
text(24, yb(PPQ) - 6, f"PPQ {PPQ:.2f}", fill=PURPLE, size=11, bold=True)
|
||||
text(24, yb(SQ) - 6, f"SQ {SQ:.2f}", fill=GREEN, size=11, bold=True)
|
||||
text(24, yb(SQ) + 13, "zona 2, dacă", fill=GREEN, size=10)
|
||||
text(24, yb(SQ) + 25, "panica merge", fill=GREEN, size=10)
|
||||
text(24, yb(SQ) + 37, "mai jos", fill=GREEN, size=10)
|
||||
candles(BIG, BX0, BGAP, yb)
|
||||
# paranteza corecției: de la swing high până la intrare, pe panoul mare
|
||||
brx = BX0 - 16
|
||||
out.append(f'<path d="M{brx + 5:.1f},{yb(SWING):.1f} H{brx:.1f} V{yb(ENTRY):.1f} '
|
||||
f'H{brx + 5:.1f}" fill="none" stroke="{RED}" stroke-width="1.6"/>')
|
||||
text(brx - 3, (yb(SWING) + yb(ENTRY)) / 2 + 4,
|
||||
f"-{(SWING - ENTRY) / SWING * 100:.1f} %".replace(".", ","),
|
||||
fill=RED, anchor="end", bold=True, size=11)
|
||||
text(BX0 + 2 * BGAP, top + PLOT_H + 20,
|
||||
"corecția de minim 4 % se măsoară aici, pe weekly", fill=RED, size=11)
|
||||
|
||||
# ---- 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(PPQ), ys(PPQ)
|
||||
mid = (lx1 + FRAME_L) / 2
|
||||
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}" stroke-width="1.0" stroke-dasharray="3 3"/>')
|
||||
text(mid + 4, (ycb + ycs) / 2 + 4, "același", fill="#999", size=10)
|
||||
text(mid + 4, (ycb + ycs) / 2 + 16, "preț", fill="#999", size=10)
|
||||
|
||||
# ---- panoul daily ----------------------------------------------------------
|
||||
frame_r = SX0 + (len(FINE) - 1) * SGAP + 10
|
||||
rect(FRAME_L, top, frame_r, top + PLOT_H, BLUE, fill_op=0.03)
|
||||
y_ppq, y_e = ys(PPQ), ys(ENTRY)
|
||||
assert top + PLOT_H - ys(zlo_) > 6, "minimul e lipit de marginea de jos a cadrului"
|
||||
assert ys(zhi_) - top > 6, "maximul e lipit de marginea de sus a cadrului"
|
||||
# zona de decizie: bara de BIM + candela verde
|
||||
sx0, sx1 = SX0 + BIM_I * SGAP - 10, SX0 + ENTRY_I * SGAP + 10
|
||||
rect(sx0, ys(FINE[ENTRY_I][1]) - 6, sx1, ys(min(b[2] for b in FINE)) + 6, GREEN)
|
||||
hline(FRAME_L, frame_r, y_ppq, PURPLE, "4 3")
|
||||
hline(FRAME_L, frame_r, y_e, GREEN, "6 3")
|
||||
candles(FINE, SX0, SGAP, ys)
|
||||
text(COL_X, y_ppq + 4, f"PPQ {PPQ:.2f}", fill=PURPLE, size=10, bold=True)
|
||||
text(COL_X, y_ppq + 16, "același nivel,", fill=PURPLE, size=10)
|
||||
text(COL_X, y_ppq + 28, "văzut de aproape", fill=PURPLE, size=10)
|
||||
text(COL_X, y_e - 8, f"intrare {ENTRY:.2f}", fill=GREEN, size=10, bold=True)
|
||||
line(SX0 + BIM_I * SGAP, ys(FINE[BIM_I][2]) + 4, SX0 + BIM_I * SGAP,
|
||||
top + PLOT_H + 14, CYAN, width=1)
|
||||
text(SX0 + BIM_I * SGAP - 6, top + PLOT_H + 28, "BIM: aici se oprește vânzarea",
|
||||
fill=CYAN, anchor="middle", size=11, bold=True)
|
||||
text(SX0 + BIM_I * SGAP - 6, top + PLOT_H + 42,
|
||||
f"(fundul e la {DIST:.2f} % de PPQ)".replace(".", ","),
|
||||
fill=CYAN, anchor="middle", size=10)
|
||||
text(20, top + PLOT_H + 58,
|
||||
"Pe weekly nu vezi unde s-a oprit căderea; pe daily, da — de aceea intri de aici.",
|
||||
fill="#555", size=11)
|
||||
|
||||
# --- prețurile rămân fiecare pe panoul lui, cu excepția nivelului comun ----
|
||||
COMUN = {f"{PPQ:.2f}"}
|
||||
MARE = {f"{SWING:.2f}", f"{SQ:.2f}"} - COMUN
|
||||
MIC = {f"{ENTRY:.2f}"} - COMUN
|
||||
for x0_, _x1, _y, s_ in LABELS:
|
||||
rau = MARE if x0_ >= MIDX else MIC
|
||||
for v in rau:
|
||||
assert v not in s_, f"eticheta {s_!r} poartă prețul {v} al celuilalt panou"
|
||||
st_ = [s for x0_, _x1, _y, s in LABELS if f"{PPQ:.2f}" in s and x0_ < MIDX]
|
||||
dr_ = [s for x0_, _x1, _y, s in LABELS if f"{PPQ:.2f}" in s and x0_ >= MIDX]
|
||||
assert st_ and dr_, f"nivelul comun {PPQ} lipsește de pe un panou ({st_} / {dr_})"
|
||||
|
||||
H = top + PLOT_H + 76
|
||||
for i in range(len(LABELS)):
|
||||
for j in range(i + 1, len(LABELS)):
|
||||
xa0, xa1, ya, sa = LABELS[i]
|
||||
xb0, xb1, yb_, sb = LABELS[j]
|
||||
assert not (abs(ya - yb_) < 12 and xa0 < xb1 - 4 and xb0 < xa1 - 4), \
|
||||
f"etichete suprapuse: {sa!r} / {sb!r}"
|
||||
assert 0 < LABELS[i][2] < H, f"etichetă în afara înălțimii: {LABELS[i][3]!r}"
|
||||
|
||||
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 and ".md:" not in svg
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"weekly {len(BIG)} bare (ultimele {NZ} = {len(FINE)} daily) | swing {SWING:.2f} "
|
||||
f"| PPQ {PPQ} | intrare {ENTRY:.2f} | fund {min(b[2] for b in FINE):.2f} "
|
||||
f"({DIST:.2f} % sub PPQ) | scris {OUT.name} ({W}x{H:.0f})")
|
||||
88
gen/strategii/atmi_perechi_tf.svg
Normal file
@@ -0,0 +1,88 @@
|
||||
<svg viewBox="0 0 720 370" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<defs><marker id="pt" 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">Nivelul trăiește pe weekly, declanșatorul pe daily</text>
|
||||
<text x="20.0" y="38.0" fill="#555" style="font-size:11px">Fiecare candelă weekly din casetă = 5 bare daily (o săptămână de bursă):</text>
|
||||
<text x="20.0" y="52.0" fill="#555" style="font-size:11px">același open, același close, max(high) și min(low) identice.</text>
|
||||
<text x="20.0" y="92.0" fill="#555" style="font-size:11px">weekly: de unde pleacă corecția</text>
|
||||
<text x="380.0" y="92.0" fill="#555" style="font-size:11px">daily: ultimele 3 candele weekly, desfăcute</text>
|
||||
<rect x="237.0" y="118.6" width="48.0" height="82.4" fill="#1a5fb4" fill-opacity="0.06" stroke="#1a5fb4" stroke-width="1.2" stroke-dasharray="4 3"/>
|
||||
<line x1="110.0" y1="190.7" x2="285.0" y2="190.7" stroke="#7b2fbf" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<line x1="110.0" y1="294.0" x2="285.0" y2="294.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<line x1="110.0" y1="104.0" x2="285.0" y2="104.0" stroke="#555" stroke-width="1.0" stroke-dasharray="3 3"/>
|
||||
<text x="24.0" y="117.0" fill="#555" style="font-size:11px">swing high 100.00</text>
|
||||
<text x="24.0" y="184.7" fill="#7b2fbf" style="font-size:11px;font-weight:bold">PPQ 95.80</text>
|
||||
<text x="24.0" y="288.0" fill="#188a3e" style="font-size:11px;font-weight:bold">SQ 90.80</text>
|
||||
<text x="24.0" y="307.0" fill="#188a3e" style="font-size:10px">zona 2, dacă</text>
|
||||
<text x="24.0" y="319.0" fill="#188a3e" style="font-size:10px">panica merge</text>
|
||||
<text x="24.0" y="331.0" fill="#188a3e" style="font-size:10px">mai jos</text>
|
||||
<line x1="132.0" y1="211.4" x2="132.0" y2="242.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="127.5" y="217.6" width="9" height="18.6" fill="#188a3e"/>
|
||||
<line x1="148.0" y1="188.7" x2="148.0" y2="223.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="143.5" y="194.9" width="9" height="22.7" fill="#188a3e"/>
|
||||
<line x1="164.0" y1="163.9" x2="164.0" y2="201.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="159.5" y="170.1" width="9" height="24.8" fill="#188a3e"/>
|
||||
<line x1="180.0" y1="139.1" x2="180.0" y2="176.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="175.5" y="145.3" width="9" height="24.8" fill="#188a3e"/>
|
||||
<line x1="196.0" y1="114.3" x2="196.0" y2="151.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="191.5" y="120.5" width="9" height="24.8" fill="#188a3e"/>
|
||||
<line x1="212.0" y1="104.0" x2="212.0" y2="126.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="207.5" y="104.0" width="9" height="16.5" fill="#188a3e"/>
|
||||
<line x1="228.0" y1="104.0" x2="228.0" y2="132.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="223.5" y="104.0" width="9" height="22.7" fill="#c00"/>
|
||||
<line x1="244.0" y1="123.6" x2="244.0" y2="156.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="239.5" y="126.7" width="9" height="20.7" fill="#c00"/>
|
||||
<line x1="260.0" y1="144.3" x2="260.0" y2="177.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="255.5" y="147.4" width="9" height="26.8" fill="#c00"/>
|
||||
<line x1="276.0" y1="171.1" x2="276.0" y2="195.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="271.5" y="174.2" width="9" height="12.4" fill="#c00"/>
|
||||
<path d="M121.0,104.0 H116.0 V186.6 H121.0" fill="none" stroke="#c00" stroke-width="1.6"/>
|
||||
<text x="113.0" y="149.3" fill="#c00" text-anchor="end" style="font-size:11px;font-weight:bold">-4,0 %</text>
|
||||
<text x="164.0" y="314.0" fill="#c00" style="font-size:11px">corecția de minim 4 % se măsoară aici, pe weekly</text>
|
||||
<line x1="285.0" y1="118.6" x2="380.0" y2="104.0" stroke="#1a5fb4" stroke-width="1.1" stroke-dasharray="5 3"/>
|
||||
<line x1="285.0" y1="201.0" x2="380.0" y2="294.0" stroke="#1a5fb4" stroke-width="1.1" stroke-dasharray="5 3"/>
|
||||
<path d="M285.0,190.7 H332.5 V270.4 H380.0" fill="none" stroke="#aaa" stroke-width="1.0" stroke-dasharray="3 3"/>
|
||||
<text x="336.5" y="234.6" fill="#999" style="font-size:10px">același</text>
|
||||
<text x="336.5" y="246.6" fill="#999" style="font-size:10px">preț</text>
|
||||
<rect x="380.0" y="104.0" width="218.0" height="190.0" fill="#1a5fb4" fill-opacity="0.03" stroke="#1a5fb4" stroke-width="1.2"/>
|
||||
<rect x="564.0" y="247.8" width="34.0" height="40.6" fill="#188a3e" fill-opacity="0.1" stroke="#188a3e" stroke-width="1.2"/>
|
||||
<line x1="380.0" y1="270.4" x2="598.0" y2="270.4" stroke="#7b2fbf" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<line x1="380.0" y1="260.9" x2="598.0" y2="260.9" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="6 3"/>
|
||||
<line x1="392.0" y1="115.7" x2="392.0" y2="144.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="387.5" y="122.8" width="9" height="14.3" fill="#c00"/>
|
||||
<line x1="406.0" y1="130.0" x2="406.0" y2="163.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="401.5" y="137.1" width="9" height="19.0" fill="#c00"/>
|
||||
<line x1="420.0" y1="149.0" x2="420.0" y2="177.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="415.5" y="156.1" width="9" height="14.3" fill="#c00"/>
|
||||
<line x1="434.0" y1="163.3" x2="434.0" y2="191.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="429.5" y="170.4" width="9" height="14.3" fill="#c00"/>
|
||||
<line x1="448.0" y1="163.3" x2="448.0" y2="191.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="443.5" y="170.4" width="9" height="14.3" fill="#188a3e"/>
|
||||
<line x1="462.0" y1="163.3" x2="462.0" y2="196.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="457.5" y="170.4" width="9" height="19.0" fill="#c00"/>
|
||||
<line x1="476.0" y1="182.3" x2="476.0" y2="215.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="471.5" y="189.5" width="9" height="19.0" fill="#c00"/>
|
||||
<line x1="490.0" y1="201.4" x2="490.0" y2="230.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="485.5" y="208.5" width="9" height="14.3" fill="#c00"/>
|
||||
<line x1="504.0" y1="206.1" x2="504.0" y2="230.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="499.5" y="213.3" width="9" height="9.5" fill="#188a3e"/>
|
||||
<line x1="518.0" y1="206.1" x2="518.0" y2="239.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="513.5" y="213.3" width="9" height="19.0" fill="#c00"/>
|
||||
<line x1="532.0" y1="225.2" x2="532.0" y2="253.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="527.5" y="232.3" width="9" height="14.3" fill="#c00"/>
|
||||
<line x1="546.0" y1="239.5" x2="546.0" y2="268.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="541.5" y="246.6" width="9" height="14.3" fill="#c00"/>
|
||||
<line x1="560.0" y1="253.8" x2="560.0" y2="272.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="555.5" y="260.9" width="9" height="4.8" fill="#c00"/>
|
||||
<line x1="574.0" y1="260.9" x2="574.0" y2="282.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="569.5" y="265.7" width="9" height="9.5" fill="#c00"/>
|
||||
<line x1="588.0" y1="253.8" x2="588.0" y2="277.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="583.5" y="260.9" width="9" height="14.3" fill="#188a3e"/>
|
||||
<text x="608.0" y="274.4" fill="#7b2fbf" style="font-size:10px;font-weight:bold">PPQ 95.80</text>
|
||||
<text x="608.0" y="286.4" fill="#7b2fbf" style="font-size:10px">același nivel,</text>
|
||||
<text x="608.0" y="298.4" fill="#7b2fbf" style="font-size:10px">văzut de aproape</text>
|
||||
<text x="608.0" y="252.9" fill="#188a3e" style="font-size:10px;font-weight:bold">intrare 96.00</text>
|
||||
<line x1="574.0" y1="286.3" x2="574.0" y2="308.0" stroke="#0a7f9e" stroke-width="1"/>
|
||||
<text x="568.0" y="322.0" fill="#0a7f9e" text-anchor="middle" style="font-size:11px;font-weight:bold">BIM: aici se oprește vânzarea</text>
|
||||
<text x="568.0" y="336.0" fill="#0a7f9e" text-anchor="middle" style="font-size:10px">(fundul e la 0,26 % de PPQ)</text>
|
||||
<text x="20.0" y="352.0" fill="#555" style="font-size:11px">Pe weekly nu vezi unde s-a oprit căderea; pe daily, da — de aceea intri de aici.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.9 KiB |
117
gen/strategii/atmi_pivoti.py
Normal file
@@ -0,0 +1,117 @@
|
||||
"""ATMI — Pasul 1: PPQ și SQ, calculați din trimestrul precedent.
|
||||
|
||||
Un singur grafic daily care acoperă sfârșitul trimestrului precedent (zona
|
||||
gri) și începutul celui nou. Din H/L/C-ul trimestrului precedent ies, prin
|
||||
formula standard de pivot point, cele două niveluri pe care ATMI cumpără:
|
||||
PPQ (pivotul trimestrial) și SQ (suportul trimestrial, S1). Liniile se
|
||||
prelungesc peste trimestrul nou — acolo le folosești.
|
||||
|
||||
Cifrele PPQ/SQ sunt COMPLETARE PROPRIE: cursul spune explicit că nu dă
|
||||
valorile lor. Formula e cea confirmată „1 la 1" în material. Aici sunt
|
||||
calculate în cod din seria desenată, nu scrise de mână.
|
||||
|
||||
Rulează: python3 gen/strategii/atmi_pivoti.py
|
||||
"""
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
from svg_candles import Chart, Level, Mark, Zone, Arrow, from_closes # noqa: E402
|
||||
|
||||
OUT = Path(__file__).resolve().parent / "atmi_pivoti.svg"
|
||||
GRAY, RED, GREEN, BLUE, ORANGE, INK = "#777", "#c00", "#188a3e", "#1a5fb4", "#b06000", "#333"
|
||||
PURPLE = "#7b2fbf"
|
||||
|
||||
# --- seria: 22 de bare din trimestrul precedent + 12 din cel nou -----------
|
||||
# Trimestrul precedent trebuie să aibă H = 100.80, L = 90.40, C = 96.20.
|
||||
Q_PREV = [95.40, 94.10, 93.00, 92.10, 90.90, 90.70, 92.20, 93.60, 95.00, 96.40,
|
||||
97.90, 99.20, 100.40, 99.80, 98.60, 97.40, 96.20, 95.10, 95.90, 96.80,
|
||||
97.30, 96.20]
|
||||
Q_NOU = [97.00, 97.70, 98.40, 99.00, 99.60, 100.00, 99.20, 98.30, 97.40, 96.90,
|
||||
96.50, 96.20]
|
||||
CLOSES = Q_PREV + Q_NOU
|
||||
NP = len(Q_PREV)
|
||||
assert len(CLOSES) == 34
|
||||
|
||||
wicks = [(0.25, 0.25)] * len(CLOSES)
|
||||
wicks[4] = (0.20, 0.50) # minimul trimestrului precedent: 90.90 - 0.50 = 90.40
|
||||
wicks[12] = (0.40, 0.20) # maximul trimestrului precedent: 100.40 + 0.40 = 100.80
|
||||
wicks[NP - 1] = (0.20, 0.20)
|
||||
wicks[NP] = (0.25, 0.00) # prima bară a trimestrului nou pleacă de pe close-ul C
|
||||
wicks[NP + 5] = (0.00, 0.25) # swing high-ul trimestrului nou: exact 100.00
|
||||
wicks[NP + 6] = (0.00, 0.25) # nicio bară de după nu depășește swing high-ul
|
||||
wicks[-3] = (0.20, 0.00)
|
||||
wicks[-2] = (0.20, 0.00)
|
||||
wicks[-1] = (0.15, 0.20) # low-ul ultimei bare: 96.20 - 0.20 = 96.00
|
||||
|
||||
cds = from_closes(CLOSES, wicks=wicks,
|
||||
vols=[40 + (i * 7) % 33 for i in range(len(CLOSES))], start=96.00)
|
||||
|
||||
# --- pivoții, calculați din seria desenată ---------------------------------
|
||||
H = round(max(c.h for c in cds[:NP]), 2)
|
||||
L = round(min(c.l for c in cds[:NP]), 2)
|
||||
C = round(cds[NP - 1].c, 2)
|
||||
PP = round((H + L + C) / 3, 2)
|
||||
S1 = round(2 * PP - H, 2)
|
||||
R1 = round(2 * PP - L, 2)
|
||||
|
||||
assert (H, L, C) == (100.80, 90.40, 96.20), (H, L, C)
|
||||
assert PP == 95.80, PP
|
||||
assert S1 == 90.80, S1
|
||||
assert R1 == 101.20, R1
|
||||
assert S1 < PP < R1
|
||||
assert abs(S1 - L) > 0.3, "S1 a ieșit chiar pe low — ar părea o coincidență, nu un calcul"
|
||||
|
||||
# ce afirmă textul capitolului despre trimestrul NOU
|
||||
SWING = round(max(c.h for c in cds[NP:]), 2)
|
||||
FUND = round(min(c.l for c in cds[NP:]), 2)
|
||||
assert abs(SWING - 100.00) < 1e-9, SWING
|
||||
ZONA = (PP - 0.30, PP + 0.30) # banda de cumpărare din jurul pivotului
|
||||
assert abs(FUND - 96.00) < 1e-9, FUND
|
||||
assert ZONA[0] <= FUND <= ZONA[1], (FUND, ZONA) # ultima bară intră în zona PPQ
|
||||
assert abs((SWING - 96.00) / SWING * 100 - 4.0) < 0.05 # corecție de exact 4,0 %
|
||||
assert all(c.l > S1 for c in cds[NP:]), "trimestrul nou nu trebuie să atingă SQ"
|
||||
|
||||
levels = [
|
||||
Level(PP, f"PPQ {PP:.2f} — zona 1", PURPLE),
|
||||
Level(S1, f"SQ {S1:.2f} — zona 2", GREEN),
|
||||
]
|
||||
marks = [
|
||||
Mark(12, f"H {H:.2f}", INK, "above"),
|
||||
Mark(4, f"L {L:.2f}", INK, "below"),
|
||||
Mark(NP - 1, f"C {C:.2f}", INK, "above", dy=-16),
|
||||
Mark(NP + 5, f"swing high {SWING:.2f}", RED, "above"),
|
||||
Mark(len(cds) - 4, "corecție 4,0 % — prețul intră în zona PPQ: treci la pasul 2",
|
||||
PURPLE, "below", dy=34),
|
||||
]
|
||||
arrows = []
|
||||
zones = [Zone(0, NP - 1, "", GRAY), Zone(NP, len(cds) - 1, "", BLUE)]
|
||||
|
||||
ch = Chart(candles=cds, levels=levels, marks=marks, zones=zones, arrows=arrows,
|
||||
scale=13.0, gap=16, body_w=9, left=52, width=720, vol_h=60, top=124,
|
||||
label_gap=54,
|
||||
caption="Cifrele PPQ/SQ sunt completarea mea: cursul dă regula, nu valorile. "
|
||||
"Formula e cea standard, confirmată în material pentru pivoți.")
|
||||
svg = ch.render()
|
||||
|
||||
# formula, scrisă cu cifrele desenului, ca să nu rămână o regulă abstractă
|
||||
form = [f"PP = (H + L + C) / 3 = ({H:.2f} + {L:.2f} + {C:.2f}) / 3 = {PP:.2f} → PPQ",
|
||||
f"S1 = 2 x PP - H = 2 x {PP:.2f} - {H:.2f} = {S1:.2f} → SQ",
|
||||
f"R1 = 2 x PP - L = 2 x {PP:.2f} - {L:.2f} = {R1:.2f}"]
|
||||
box = [f'<text x="24" y="22" fill="{INK}" style="font-weight:bold">'
|
||||
f'SPY — daily: pivoții trimestrului nou, calculați din trimestrul precedent</text>',
|
||||
f'<rect x="24" y="34" width="430" height="54" fill="#f4f4f8" stroke="#ccc"/>',
|
||||
f'<text x="46" y="110" fill="{GRAY}" style="font-size:11px;font-weight:bold">'
|
||||
f'trimestrul precedent</text>',
|
||||
f'<text x="446" y="110" fill="{BLUE}" style="font-size:11px;font-weight:bold">'
|
||||
f'trimestrul nou: aici tranzacționezi</text>']
|
||||
for i, s in enumerate(form):
|
||||
box.append(f'<text x="34" y="{50 + i * 15}" fill="{INK}" '
|
||||
f'style="font-family:monospace;font-size:11px">{s}</text>')
|
||||
|
||||
i = svg.index(">") + 1
|
||||
svg = svg[:i] + "\n " + "\n ".join(box) + svg[i:]
|
||||
assert "\n\n" not in svg
|
||||
assert ".md:" not in svg
|
||||
OUT.write_text(svg)
|
||||
print(f"scris {OUT.name}: H {H} L {L} C {C} -> PPQ {PP}, SQ {S1}, R1 {R1}")
|
||||
125
gen/strategii/atmi_pivoti.svg
Normal file
@@ -0,0 +1,125 @@
|
||||
<svg viewBox="0 0 720 401" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<text x="24" y="22" fill="#333" style="font-weight:bold">SPY — daily: pivoții trimestrului nou, calculați din trimestrul precedent</text>
|
||||
<rect x="24" y="34" width="430" height="54" fill="#f4f4f8" stroke="#ccc"/>
|
||||
<text x="46" y="110" fill="#777" style="font-size:11px;font-weight:bold">trimestrul precedent</text>
|
||||
<text x="446" y="110" fill="#1a5fb4" style="font-size:11px;font-weight:bold">trimestrul nou: aici tranzacționezi</text>
|
||||
<text x="34" y="50" fill="#333" style="font-family:monospace;font-size:11px">PP = (H + L + C) / 3 = (100.80 + 90.40 + 96.20) / 3 = 95.80 → PPQ</text>
|
||||
<text x="34" y="65" fill="#333" style="font-family:monospace;font-size:11px">S1 = 2 x PP - H = 2 x 95.80 - 100.80 = 90.80 → SQ</text>
|
||||
<text x="34" y="80" fill="#333" style="font-family:monospace;font-size:11px">R1 = 2 x PP - L = 2 x 95.80 - 90.40 = 101.20</text>
|
||||
<rect x="42.5" y="116.0" width="355.0" height="151.2" fill="#777" fill-opacity="0.08" stroke="#777" stroke-width="1"/>
|
||||
<rect x="394.5" y="126.4" width="195.0" height="68.0" fill="#1a5fb4" fill-opacity="0.08" stroke="#1a5fb4" stroke-width="1"/>
|
||||
<line x1="24" y1="189.0" x2="706" y2="189.0" stroke="#7b2fbf" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="692" y="183.0" fill="#7b2fbf" text-anchor="end">PPQ 95.80 — zona 1</text>
|
||||
<line x1="24" y1="254.0" x2="706" y2="254.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="692" y="248.0" fill="#188a3e" text-anchor="end">SQ 90.80 — zona 2</text>
|
||||
<line x1="52.0" y1="183.2" x2="52.0" y2="197.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="47.5" y="186.4" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="68.0" y1="191.0" x2="68.0" y2="214.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="63.5" y="194.2" width="9" height="16.9" fill="#c00"/>
|
||||
<line x1="84.0" y1="207.9" x2="84.0" y2="228.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="79.5" y="211.1" width="9" height="14.3" fill="#c00"/>
|
||||
<line x1="100.0" y1="222.2" x2="100.0" y2="240.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="95.5" y="225.4" width="9" height="11.7" fill="#c00"/>
|
||||
<line x1="116.0" y1="234.5" x2="116.0" y2="259.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="111.5" y="237.1" width="9" height="15.6" fill="#c00"/>
|
||||
<line x1="132.0" y1="249.5" x2="132.0" y2="258.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="127.5" y="252.7" width="9" height="2.6" fill="#c00"/>
|
||||
<line x1="148.0" y1="232.6" x2="148.0" y2="258.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="143.5" y="235.8" width="9" height="19.5" fill="#188a3e"/>
|
||||
<line x1="164.0" y1="214.4" x2="164.0" y2="239.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="159.5" y="217.6" width="9" height="18.2" fill="#188a3e"/>
|
||||
<line x1="180.0" y1="196.2" x2="180.0" y2="220.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="175.5" y="199.4" width="9" height="18.2" fill="#188a3e"/>
|
||||
<line x1="196.0" y1="178.0" x2="196.0" y2="202.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="191.5" y="181.2" width="9" height="18.2" fill="#188a3e"/>
|
||||
<line x1="212.0" y1="158.5" x2="212.0" y2="184.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="207.5" y="161.7" width="9" height="19.5" fill="#188a3e"/>
|
||||
<line x1="228.0" y1="141.6" x2="228.0" y2="165.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="223.5" y="144.8" width="9" height="16.9" fill="#188a3e"/>
|
||||
<line x1="244.0" y1="124.0" x2="244.0" y2="147.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="239.5" y="129.2" width="9" height="15.6" fill="#188a3e"/>
|
||||
<line x1="260.0" y1="126.0" x2="260.0" y2="140.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="255.5" y="129.2" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="276.0" y1="133.8" x2="276.0" y2="155.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="271.5" y="137.0" width="9" height="15.6" fill="#c00"/>
|
||||
<line x1="292.0" y1="149.4" x2="292.0" y2="171.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="287.5" y="152.6" width="9" height="15.6" fill="#c00"/>
|
||||
<line x1="308.0" y1="165.0" x2="308.0" y2="187.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="303.5" y="168.2" width="9" height="15.6" fill="#c00"/>
|
||||
<line x1="324.0" y1="180.6" x2="324.0" y2="201.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="319.5" y="183.8" width="9" height="14.3" fill="#c00"/>
|
||||
<line x1="340.0" y1="184.5" x2="340.0" y2="201.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="335.5" y="187.7" width="9" height="10.4" fill="#188a3e"/>
|
||||
<line x1="356.0" y1="172.8" x2="356.0" y2="191.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="351.5" y="176.0" width="9" height="11.7" fill="#188a3e"/>
|
||||
<line x1="372.0" y1="166.3" x2="372.0" y2="179.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="367.5" y="169.5" width="9" height="6.5" fill="#188a3e"/>
|
||||
<line x1="388.0" y1="166.9" x2="388.0" y2="186.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="383.5" y="169.5" width="9" height="14.3" fill="#c00"/>
|
||||
<line x1="404.0" y1="170.2" x2="404.0" y2="183.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="399.5" y="173.4" width="9" height="10.4" fill="#188a3e"/>
|
||||
<line x1="420.0" y1="161.1" x2="420.0" y2="176.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="415.5" y="164.3" width="9" height="9.1" fill="#188a3e"/>
|
||||
<line x1="436.0" y1="152.0" x2="436.0" y2="167.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="431.5" y="155.2" width="9" height="9.1" fill="#188a3e"/>
|
||||
<line x1="452.0" y1="144.2" x2="452.0" y2="158.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="447.5" y="147.4" width="9" height="7.8" fill="#188a3e"/>
|
||||
<line x1="468.0" y1="136.4" x2="468.0" y2="150.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="463.5" y="139.6" width="9" height="7.8" fill="#188a3e"/>
|
||||
<line x1="484.0" y1="134.4" x2="484.0" y2="142.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="479.5" y="134.4" width="9" height="5.2" fill="#188a3e"/>
|
||||
<line x1="500.0" y1="134.4" x2="500.0" y2="148.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="495.5" y="134.4" width="9" height="10.4" fill="#c00"/>
|
||||
<line x1="516.0" y1="141.6" x2="516.0" y2="159.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="511.5" y="144.8" width="9" height="11.7" fill="#c00"/>
|
||||
<line x1="532.0" y1="153.3" x2="532.0" y2="171.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="527.5" y="156.5" width="9" height="11.7" fill="#c00"/>
|
||||
<line x1="548.0" y1="165.6" x2="548.0" y2="174.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="543.5" y="168.2" width="9" height="6.5" fill="#c00"/>
|
||||
<line x1="564.0" y1="172.1" x2="564.0" y2="179.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="559.5" y="174.7" width="9" height="5.2" fill="#c00"/>
|
||||
<line x1="580.0" y1="178.0" x2="580.0" y2="186.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="575.5" y="179.9" width="9" height="3.9" fill="#c00"/>
|
||||
<line x1="24" y1="359.2" x2="706" y2="359.2" stroke="#888"/>
|
||||
<rect x="47.5" y="325.9" width="9" height="33.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="63.5" y="320.0" width="9" height="39.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="79.5" y="314.2" width="9" height="45.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="95.5" y="308.4" width="9" height="50.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="111.5" y="302.5" width="9" height="56.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="127.5" y="324.2" width="9" height="35.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="143.5" y="318.4" width="9" height="40.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="159.5" y="312.5" width="9" height="46.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="175.5" y="306.7" width="9" height="52.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="191.5" y="300.9" width="9" height="58.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="207.5" y="322.5" width="9" height="36.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="223.5" y="316.7" width="9" height="42.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="239.5" y="310.9" width="9" height="48.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="255.5" y="305.0" width="9" height="54.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="271.5" y="299.2" width="9" height="60.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="287.5" y="320.9" width="9" height="38.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="303.5" y="315.0" width="9" height="44.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="319.5" y="309.2" width="9" height="50.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="335.5" y="303.4" width="9" height="55.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="351.5" y="325.0" width="9" height="34.2" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="367.5" y="319.2" width="9" height="40.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="383.5" y="313.4" width="9" height="45.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="399.5" y="307.5" width="9" height="51.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="415.5" y="301.7" width="9" height="57.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="431.5" y="323.4" width="9" height="35.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="447.5" y="317.5" width="9" height="41.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="463.5" y="311.7" width="9" height="47.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="479.5" y="305.9" width="9" height="53.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="495.5" y="300.0" width="9" height="59.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="511.5" y="321.7" width="9" height="37.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="527.5" y="315.9" width="9" height="43.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="543.5" y="310.0" width="9" height="49.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="559.5" y="304.2" width="9" height="55.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="575.5" y="325.9" width="9" height="33.3" fill="#c00" opacity="0.55"/>
|
||||
<text x="24" y="293.2" fill="#555">volum</text>
|
||||
<text x="244.0" y="114.0" fill="#333" text-anchor="middle" style="font-weight:bold">H 100.80</text>
|
||||
<text x="116.0" y="273.2" fill="#333" text-anchor="middle" style="font-weight:bold">L 90.40</text>
|
||||
<text x="388.0" y="140.9" fill="#333" text-anchor="middle" style="font-weight:bold">C 96.20</text>
|
||||
<text x="484.0" y="124.4" fill="#c00" text-anchor="middle" style="font-weight:bold">swing high 100.00</text>
|
||||
<text x="532.0" y="225.5" fill="#7b2fbf" text-anchor="middle" style="font-weight:bold">corecție 4,0 % — prețul intră în zona PPQ: treci la pasul 2</text>
|
||||
<text x="24" y="389" fill="#555">Cifrele PPQ/SQ sunt completarea mea: cursul dă regula, nu valorile. Formula e cea standard, confirmată în material pentru pivoți.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
134
gen/strategii/atmi_reinvestire.py
Normal file
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
"""ATMI — Pasul 6: ieșirea la +10 %, cash, apoi reinvestirea integrală.
|
||||
|
||||
Nu e un grafic de preț: e ciclul banilor. Trei cicluri, fiecare cu aceeași
|
||||
regulă — ieși cu TOATĂ poziția la +10 %, banii stau în cash până la
|
||||
următorul trigger valid, iar acolo intră înapoi integral, plus contribuția
|
||||
nouă. Coloana din dreapta arată ce iese dacă reinvestești doar contribuțiile
|
||||
și lași profitul deoparte: aceeași sumă pusă, mai puțin la final.
|
||||
|
||||
Contribuția de 600 $/trimestru e cifra cursului („1 unitate SPY"); ținta de
|
||||
+10 % e regula lui. Suma finală e calculată aici, nu preluată din backtest —
|
||||
backtest-ul cursului (~16.300 $ → ~52-53.000 $ în 20 de ani) are alt
|
||||
orizont și e citat în text, nu desenat.
|
||||
|
||||
Rulează: python3 gen/strategii/atmi_reinvestire.py
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
W = 700
|
||||
CONTRIB, TINTA = 600.0, 0.10
|
||||
N = 3
|
||||
|
||||
GREEN, RED, BLUE, INK, GRAY, PURPLE = "#188a3e", "#c00", "#1a5fb4", "#333", "#777", "#7b2fbf"
|
||||
|
||||
# --- cele două scenarii ----------------------------------------------------
|
||||
cicluri, capital = [], 0.0
|
||||
for i in range(N):
|
||||
intrat = round(capital + CONTRIB, 2)
|
||||
iesit = round(intrat * (1 + TINTA), 2)
|
||||
cicluri.append((i + 1, intrat, iesit))
|
||||
capital = iesit
|
||||
|
||||
fara = round(N * CONTRIB * (1 + TINTA), 2) # fiecare contribuție câștigă 10 % o dată
|
||||
pus = round(N * CONTRIB, 2)
|
||||
|
||||
assert cicluri[0] == (1, 600.00, 660.00), cicluri[0]
|
||||
assert cicluri[1] == (2, 1260.00, 1386.00), cicluri[1]
|
||||
assert cicluri[2] == (3, 1986.00, 2184.60), cicluri[2]
|
||||
assert fara == 1980.00 and pus == 1800.00
|
||||
CASTIG = round(cicluri[-1][2] - fara, 2)
|
||||
assert CASTIG == 204.60, CASTIG
|
||||
# fiecare ciclu intră cu exact ce a ieșit din precedentul plus contribuția
|
||||
for (_, intr, _), (_, _, ies) in zip(cicluri[1:], cicluri):
|
||||
assert round(intr - ies, 2) == CONTRIB
|
||||
assert all(round(ies / intr, 3) == 1.100 for _, intr, ies in cicluri)
|
||||
|
||||
# --- desen -----------------------------------------------------------------
|
||||
out, LABELS = [], []
|
||||
BASE_Y = 250 # linia de zero a coloanelor
|
||||
PXPU = 0.072 # px per dolar
|
||||
COL_W, X0, STEP = 46, 60, 190
|
||||
assert cicluri[-1][2] * PXPU < BASE_Y - 80, "coloana cea mai înaltă iese din desen"
|
||||
|
||||
|
||||
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) * (size * 0.52)
|
||||
x0 = x if anchor == "start" else (x - w / 2 if anchor == "middle" else x - w)
|
||||
assert 2 <= x0 and x0 + w <= W - 2, f"text iese din panză: {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="{st}">{s}</text>')
|
||||
|
||||
|
||||
def bar(x, val, color, label, sub):
|
||||
h = val * PXPU
|
||||
out.append(f'<rect x="{x:.1f}" y="{BASE_Y - h:.1f}" width="{COL_W}" height="{h:.1f}" '
|
||||
f'fill="{color}" fill-opacity="0.85"/>')
|
||||
text(x + COL_W / 2, BASE_Y - h - 8, label, fill=color, anchor="middle", bold=True, size=11)
|
||||
text(x + COL_W / 2, BASE_Y + 15, sub, fill=GRAY, anchor="middle", size=10)
|
||||
|
||||
|
||||
out.append('<defs><marker id="ar" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" '
|
||||
f'markerHeight="7" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="{BLUE}"/></marker>'
|
||||
'</defs>')
|
||||
text(20, 22, "Ciclul ATMI: ieși cu tot la +10 %, stai în cash, reintri cu tot plus contribuția",
|
||||
bold=True, size=13)
|
||||
text(20, 40, f"Contribuție {CONTRIB:.0f} $ la fiecare trigger valid; ținta +10 % pe poziție.",
|
||||
fill="#555", size=11)
|
||||
|
||||
for i, (nr, intrat, iesit) in enumerate(cicluri):
|
||||
xa = X0 + i * STEP
|
||||
xb = xa + COL_W + 26
|
||||
text(xa, 72, f"ciclul {nr}", fill=INK, bold=True, size=12)
|
||||
bar(xa, intrat, BLUE, f"{intrat:,.0f} $".replace(",", "."), "intri cu tot")
|
||||
bar(xb, iesit, GREEN, f"{iesit:,.2f} $".replace(",", "x").replace(".", ",").replace("x", "."),
|
||||
"ieși la +10 %")
|
||||
# săgeata dintre intrare și ieșire (ce face trade-ul)
|
||||
out.append(f'<line x1="{xa + COL_W + 4:.1f}" y1="{BASE_Y - 30:.1f}" x2="{xb - 6:.1f}" '
|
||||
f'y2="{BASE_Y - 30:.1f}" stroke="{GREEN}" stroke-width="1.4" '
|
||||
f'marker-end="url(#ar)"/>')
|
||||
if i + 1 < len(cicluri):
|
||||
# săgeata spre ciclul următor: cash + contribuție nouă
|
||||
xn = X0 + (i + 1) * STEP
|
||||
y = BASE_Y + 46
|
||||
out.append(f'<path d="M{xb + COL_W / 2:.1f},{BASE_Y + 22:.1f} V{y:.1f} '
|
||||
f'H{xn + COL_W / 2:.1f} V{BASE_Y + 22:.1f}" fill="none" stroke="{BLUE}" '
|
||||
f'stroke-width="1.4" stroke-dasharray="4 3" marker-end="url(#ar)"/>')
|
||||
text((xb + xn) / 2 + COL_W / 2, y + 16,
|
||||
f"cash, apoi + {CONTRIB:.0f} $ nou", fill=BLUE,
|
||||
anchor="middle", size=11, bold=True)
|
||||
|
||||
out.append(f'<line x1="24" y1="{BASE_Y:.1f}" x2="{W - 24}" y2="{BASE_Y:.1f}" stroke="#bbb"/>')
|
||||
|
||||
# comparația de la final
|
||||
yc = BASE_Y + 92
|
||||
out.append(f'<rect x="24" y="{yc - 16:.0f}" width="{W - 48}" height="56" fill="#f6f6f9" '
|
||||
f'stroke="#ccc"/>')
|
||||
text(34, yc, f"Ai pus în total {pus:,.0f} $".replace(",", ".") + ", în trei contribuții egale.",
|
||||
fill=INK, size=11, bold=True)
|
||||
text(34, yc + 17, f"Cu reinvestire integrală: "
|
||||
f"{cicluri[-1][2]:,.2f} $".replace(",", "x").replace(".", ",").replace("x", ".")
|
||||
+ f" · dacă lași profitul deoparte: {fara:,.0f} $".replace(",", ".")
|
||||
+ f" · diferența: {CASTIG:,.2f} $".replace(",", "x").replace(".", ",").replace("x", "."),
|
||||
fill=INK, size=11)
|
||||
text(34, yc + 34, "Cifrele astea sunt calculul meu pe trei cicluri, nu backtest-ul cursului.",
|
||||
fill=GRAY, size=10)
|
||||
|
||||
H = yc + 56
|
||||
for i in range(len(LABELS)):
|
||||
for j in range(i + 1, len(LABELS)):
|
||||
xa0, xa1, ya, sa = LABELS[i]
|
||||
xb0, xb1, yb_, sb = LABELS[j]
|
||||
assert not (abs(ya - yb_) < 12 and xa0 < xb1 - 4 and xb0 < xa1 - 4), \
|
||||
f"etichete suprapuse: {sa!r} / {sb!r}"
|
||||
assert 0 < LABELS[i][2] < H, f"etichetă în afara înălțimii: {LABELS[i][3]!r}"
|
||||
|
||||
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 and ".md:" not in svg
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(" | ".join(f"c{n}: {a:.0f} -> {b:.2f}" for n, a, b in cicluri)
|
||||
+ f" | fără reinvestire {fara:.0f} | diferență {CASTIG:.2f} | scris {OUT.name} ({W}x{H:.0f})")
|
||||
38
gen/strategii/atmi_reinvestire.svg
Normal file
@@ -0,0 +1,38 @@
|
||||
<svg viewBox="0 0 700 398" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<defs><marker id="ar" 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="#1a5fb4"/></marker></defs>
|
||||
<text x="20.0" y="22.0" fill="#333" style="font-size:13px;font-weight:bold">Ciclul ATMI: ieși cu tot la +10 %, stai în cash, reintri cu tot plus contribuția</text>
|
||||
<text x="20.0" y="40.0" fill="#555" style="font-size:11px">Contribuție 600 $ la fiecare trigger valid; ținta +10 % pe poziție.</text>
|
||||
<text x="60.0" y="72.0" fill="#333" style="font-size:12px;font-weight:bold">ciclul 1</text>
|
||||
<rect x="60.0" y="206.8" width="46" height="43.2" fill="#1a5fb4" fill-opacity="0.85"/>
|
||||
<text x="83.0" y="198.8" fill="#1a5fb4" text-anchor="middle" style="font-size:11px;font-weight:bold">600 $</text>
|
||||
<text x="83.0" y="265.0" fill="#777" text-anchor="middle" style="font-size:10px">intri cu tot</text>
|
||||
<rect x="132.0" y="202.5" width="46" height="47.5" fill="#188a3e" fill-opacity="0.85"/>
|
||||
<text x="155.0" y="194.5" fill="#188a3e" text-anchor="middle" style="font-size:11px;font-weight:bold">660,00 $</text>
|
||||
<text x="155.0" y="265.0" fill="#777" text-anchor="middle" style="font-size:10px">ieși la +10 %</text>
|
||||
<line x1="110.0" y1="220.0" x2="126.0" y2="220.0" stroke="#188a3e" stroke-width="1.4" marker-end="url(#ar)"/>
|
||||
<path d="M155.0,272.0 V296.0 H273.0 V272.0" fill="none" stroke="#1a5fb4" stroke-width="1.4" stroke-dasharray="4 3" marker-end="url(#ar)"/>
|
||||
<text x="214.0" y="312.0" fill="#1a5fb4" text-anchor="middle" style="font-size:11px;font-weight:bold">cash, apoi + 600 $ nou</text>
|
||||
<text x="250.0" y="72.0" fill="#333" style="font-size:12px;font-weight:bold">ciclul 2</text>
|
||||
<rect x="250.0" y="159.3" width="46" height="90.7" fill="#1a5fb4" fill-opacity="0.85"/>
|
||||
<text x="273.0" y="151.3" fill="#1a5fb4" text-anchor="middle" style="font-size:11px;font-weight:bold">1.260 $</text>
|
||||
<text x="273.0" y="265.0" fill="#777" text-anchor="middle" style="font-size:10px">intri cu tot</text>
|
||||
<rect x="322.0" y="150.2" width="46" height="99.8" fill="#188a3e" fill-opacity="0.85"/>
|
||||
<text x="345.0" y="142.2" fill="#188a3e" text-anchor="middle" style="font-size:11px;font-weight:bold">1.386,00 $</text>
|
||||
<text x="345.0" y="265.0" fill="#777" text-anchor="middle" style="font-size:10px">ieși la +10 %</text>
|
||||
<line x1="300.0" y1="220.0" x2="316.0" y2="220.0" stroke="#188a3e" stroke-width="1.4" marker-end="url(#ar)"/>
|
||||
<path d="M345.0,272.0 V296.0 H463.0 V272.0" fill="none" stroke="#1a5fb4" stroke-width="1.4" stroke-dasharray="4 3" marker-end="url(#ar)"/>
|
||||
<text x="404.0" y="312.0" fill="#1a5fb4" text-anchor="middle" style="font-size:11px;font-weight:bold">cash, apoi + 600 $ nou</text>
|
||||
<text x="440.0" y="72.0" fill="#333" style="font-size:12px;font-weight:bold">ciclul 3</text>
|
||||
<rect x="440.0" y="107.0" width="46" height="143.0" fill="#1a5fb4" fill-opacity="0.85"/>
|
||||
<text x="463.0" y="99.0" fill="#1a5fb4" text-anchor="middle" style="font-size:11px;font-weight:bold">1.986 $</text>
|
||||
<text x="463.0" y="265.0" fill="#777" text-anchor="middle" style="font-size:10px">intri cu tot</text>
|
||||
<rect x="512.0" y="92.7" width="46" height="157.3" fill="#188a3e" fill-opacity="0.85"/>
|
||||
<text x="535.0" y="84.7" fill="#188a3e" text-anchor="middle" style="font-size:11px;font-weight:bold">2.184,60 $</text>
|
||||
<text x="535.0" y="265.0" fill="#777" text-anchor="middle" style="font-size:10px">ieși la +10 %</text>
|
||||
<line x1="490.0" y1="220.0" x2="506.0" y2="220.0" stroke="#188a3e" stroke-width="1.4" marker-end="url(#ar)"/>
|
||||
<line x1="24" y1="250.0" x2="676" y2="250.0" stroke="#bbb"/>
|
||||
<rect x="24" y="326" width="652" height="56" fill="#f6f6f9" stroke="#ccc"/>
|
||||
<text x="34.0" y="342.0" fill="#333" style="font-size:11px;font-weight:bold">Ai pus în total 1.800 $, în trei contribuții egale.</text>
|
||||
<text x="34.0" y="359.0" fill="#333" style="font-size:11px">Cu reinvestire integrală: 2.184,60 $ · dacă lași profitul deoparte: 1.980 $ · diferența: 204,60 $</text>
|
||||
<text x="34.0" y="376.0" fill="#777" style="font-size:10px">Cifrele astea sunt calculul meu pe trei cicluri, nu backtest-ul cursului.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
100
gen/strategii/atmi_risc.py
Normal file
@@ -0,0 +1,100 @@
|
||||
"""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ă")
|
||||
126
gen/strategii/atmi_risc.svg
Normal file
@@ -0,0 +1,126 @@
|
||||
<svg viewBox="0 0 720 441" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<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>
|
||||
<text x="24" y="42" fill="#555" style="font-size:11px">24 de bare sub prețul de intrare, fără niciun ordin care să te scoată — ăsta e costul regulii „fără stop-loss".</text>
|
||||
<rect x="424" y="58" width="284" height="76" fill="#fff4f4" stroke="#c00" stroke-opacity="0.5"/>
|
||||
<text x="436" y="76" fill="#c00" style="font-size:11px;font-weight:bold">aceeași cădere de 20 % pe indice, pe poziție:</text>
|
||||
<text x="436" y="94" fill="#333" style="font-size:11px">ETF simplu (SPY): -20 %</text>
|
||||
<text x="436" y="109" fill="#333" style="font-size:11px">ETF cu levier 2x: -40 %</text>
|
||||
<text x="436" y="124" fill="#333" style="font-size:11px">ETF cu levier 3x (SPXL): -60 %</text>
|
||||
<line x1="24" y1="152.0" x2="706" y2="152.0" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="692" y="146.0" fill="#1a5fb4" text-anchor="end">TP +10 % = 105.60</text>
|
||||
<line x1="24" y1="205.8" x2="706" y2="205.8" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="692" y="199.8" fill="#188a3e" text-anchor="end">intrare 96.00</text>
|
||||
<line x1="24" y1="313.3" x2="706" y2="313.3" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="307.3" fill="#c00">fund 76.80 = -20 % pe poziție</text>
|
||||
<line x1="56.0" y1="187.6" x2="56.0" y2="195.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="51.5" y="189.5" width="9" height="3.9" fill="#c00"/>
|
||||
<line x1="72.0" y1="191.5" x2="72.0" y2="201.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="67.5" y="193.4" width="9" height="6.2" fill="#c00"/>
|
||||
<line x1="88.0" y1="197.6" x2="88.0" y2="205.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="83.5" y="199.6" width="9" height="3.9" fill="#c00"/>
|
||||
<line x1="104.0" y1="201.8" x2="104.0" y2="206.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="99.5" y="203.5" width="9" height="2.2" fill="#c00"/>
|
||||
<line x1="120.0" y1="203.8" x2="120.0" y2="215.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="115.5" y="205.8" width="9" height="7.8" fill="#c00"/>
|
||||
<line x1="136.0" y1="211.6" x2="136.0" y2="225.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="131.5" y="213.6" width="9" height="10.1" fill="#c00"/>
|
||||
<line x1="152.0" y1="221.7" x2="152.0" y2="236.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="147.5" y="223.7" width="9" height="10.6" fill="#c00"/>
|
||||
<line x1="168.0" y1="232.4" x2="168.0" y2="244.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="163.5" y="234.3" width="9" height="8.4" fill="#c00"/>
|
||||
<line x1="184.0" y1="233.5" x2="184.0" y2="244.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="179.5" y="235.4" width="9" height="7.3" fill="#188a3e"/>
|
||||
<line x1="200.0" y1="233.5" x2="200.0" y2="249.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="195.5" y="235.4" width="9" height="11.8" fill="#c00"/>
|
||||
<line x1="216.0" y1="245.2" x2="216.0" y2="262.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="211.5" y="247.2" width="9" height="12.9" fill="#c00"/>
|
||||
<line x1="232.0" y1="258.1" x2="232.0" y2="272.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="227.5" y="260.1" width="9" height="10.6" fill="#c00"/>
|
||||
<line x1="248.0" y1="262.0" x2="248.0" y2="272.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="243.5" y="264.0" width="9" height="6.7" fill="#188a3e"/>
|
||||
<line x1="264.0" y1="262.0" x2="264.0" y2="280.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="259.5" y="264.0" width="9" height="14.0" fill="#c00"/>
|
||||
<line x1="280.0" y1="276.0" x2="280.0" y2="291.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="275.5" y="278.0" width="9" height="11.8" fill="#c00"/>
|
||||
<line x1="296.0" y1="287.8" x2="296.0" y2="301.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="291.5" y="289.8" width="9" height="10.1" fill="#c00"/>
|
||||
<line x1="312.0" y1="297.9" x2="312.0" y2="308.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="307.5" y="299.8" width="9" height="6.2" fill="#c00"/>
|
||||
<line x1="328.0" y1="304.3" x2="328.0" y2="313.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="323.5" y="306.0" width="9" height="7.3" fill="#c00"/>
|
||||
<line x1="344.0" y1="302.4" x2="344.0" y2="313.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="339.5" y="304.3" width="9" height="9.0" fill="#188a3e"/>
|
||||
<line x1="360.0" y1="290.0" x2="360.0" y2="306.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="355.5" y="292.0" width="9" height="12.3" fill="#188a3e"/>
|
||||
<line x1="376.0" y1="277.2" x2="376.0" y2="294.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="371.5" y="279.1" width="9" height="12.9" fill="#188a3e"/>
|
||||
<line x1="392.0" y1="268.2" x2="392.0" y2="281.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="387.5" y="270.2" width="9" height="9.0" fill="#188a3e"/>
|
||||
<line x1="408.0" y1="255.3" x2="408.0" y2="272.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="403.5" y="257.3" width="9" height="12.9" fill="#188a3e"/>
|
||||
<line x1="424.0" y1="246.4" x2="424.0" y2="259.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="419.5" y="248.3" width="9" height="9.0" fill="#188a3e"/>
|
||||
<line x1="440.0" y1="236.8" x2="440.0" y2="250.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="435.5" y="238.8" width="9" height="9.5" fill="#188a3e"/>
|
||||
<line x1="456.0" y1="224.5" x2="456.0" y2="240.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="451.5" y="226.5" width="9" height="12.3" fill="#188a3e"/>
|
||||
<line x1="472.0" y1="215.0" x2="472.0" y2="228.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="467.5" y="217.0" width="9" height="9.5" fill="#188a3e"/>
|
||||
<line x1="488.0" y1="203.8" x2="488.0" y2="218.9" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="483.5" y="205.8" width="9" height="11.2" fill="#188a3e"/>
|
||||
<line x1="504.0" y1="193.7" x2="504.0" y2="207.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="499.5" y="195.7" width="9" height="10.1" fill="#188a3e"/>
|
||||
<line x1="520.0" y1="184.8" x2="520.0" y2="197.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="515.5" y="186.7" width="9" height="9.0" fill="#188a3e"/>
|
||||
<line x1="536.0" y1="176.4" x2="536.0" y2="188.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="531.5" y="178.3" width="9" height="8.4" fill="#188a3e"/>
|
||||
<line x1="552.0" y1="169.1" x2="552.0" y2="180.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="547.5" y="171.0" width="9" height="7.3" fill="#188a3e"/>
|
||||
<line x1="568.0" y1="162.4" x2="568.0" y2="173.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="563.5" y="164.3" width="9" height="6.7" fill="#188a3e"/>
|
||||
<line x1="584.0" y1="156.2" x2="584.0" y2="166.3" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="579.5" y="158.2" width="9" height="6.2" fill="#188a3e"/>
|
||||
<line x1="600.0" y1="152.0" x2="600.0" y2="160.1" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="595.5" y="152.0" width="9" height="6.2" fill="#188a3e"/>
|
||||
<line x1="24" y1="399.3" x2="706" y2="399.3" stroke="#888"/>
|
||||
<rect x="51.5" y="367.9" width="9" height="31.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="67.5" y="360.0" width="9" height="39.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="83.5" y="352.1" width="9" height="47.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="99.5" y="344.3" width="9" height="55.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="115.5" y="365.7" width="9" height="33.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="131.5" y="357.9" width="9" height="41.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="147.5" y="350.0" width="9" height="49.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="163.5" y="342.1" width="9" height="57.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="179.5" y="363.6" width="9" height="35.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="195.5" y="355.7" width="9" height="43.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="211.5" y="347.9" width="9" height="51.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="227.5" y="340.0" width="9" height="59.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="243.5" y="361.4" width="9" height="37.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="259.5" y="353.6" width="9" height="45.7" fill="#c00" opacity="0.55"/>
|
||||
<rect x="275.5" y="345.7" width="9" height="53.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="291.5" y="367.1" width="9" height="32.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="307.5" y="359.3" width="9" height="40.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="323.5" y="351.4" width="9" height="47.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="339.5" y="343.6" width="9" height="55.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="355.5" y="365.0" width="9" height="34.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="371.5" y="357.1" width="9" height="42.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="387.5" y="349.3" width="9" height="50.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="403.5" y="341.4" width="9" height="57.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="419.5" y="362.9" width="9" height="36.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="435.5" y="355.0" width="9" height="44.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="451.5" y="347.1" width="9" height="52.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="467.5" y="339.3" width="9" height="60.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="483.5" y="360.7" width="9" height="38.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="499.5" y="352.9" width="9" height="46.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="515.5" y="345.0" width="9" height="54.3" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="531.5" y="366.4" width="9" height="32.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="547.5" y="358.6" width="9" height="40.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="563.5" y="350.7" width="9" height="48.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="579.5" y="342.9" width="9" height="56.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="595.5" y="364.3" width="9" height="35.0" fill="#188a3e" opacity="0.55"/>
|
||||
<text x="24" y="333.3" fill="#555">volum</text>
|
||||
<text x="328.0" y="327.3" fill="#c00" text-anchor="middle" style="font-weight:bold">-20 %: nimic nu te scoate</text>
|
||||
<text x="488.0" y="171.8" fill="#777" text-anchor="middle" style="font-weight:bold">abia aici ești pe zero</text>
|
||||
<text x="600.0" y="180.1" fill="#1a5fb4" text-anchor="middle" style="font-weight:bold">TP</text>
|
||||
<text x="24" y="429" fill="#555">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ă.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
187
gen/strategii/atmi_trigger.py
Normal file
@@ -0,0 +1,187 @@
|
||||
#!/usr/bin/env python3
|
||||
"""ATMI — Pasul 4: trigger-ul. DA (BIM, apoi candela verde) vs. NU (verde fără BIM).
|
||||
|
||||
Două panouri, unul sub altul, cu exact aceleași patru bare de corecție. Sus:
|
||||
prețul intră în zona PPQ, apare săgeata BIM, iar prima candelă verde daily de
|
||||
după ea închide la 96.00 — acolo intri. Jos: candela verde vine ÎNAINTE de
|
||||
orice BIM, deci nu e trigger; prețul continuă să cadă spre SQ — „cuțitul în
|
||||
cădere" din curs.
|
||||
|
||||
Numerele sunt cele ale capitolului: PPQ 95.80, SQ 90.80 (calculate în
|
||||
`atmi_pivoti.py`), intrare 96.00 la close-ul candelei verzi.
|
||||
|
||||
Rulare: python3 gen/strategii/atmi_trigger.py
|
||||
"""
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
from svg_candles import Arrow, Chart, from_closes # noqa: E402
|
||||
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
W = 660
|
||||
SCALE = 46.0
|
||||
LEFT, GAP = 66, 44
|
||||
RED, GREEN, BLUE, GREY, CYAN, PURPLE = "#c00", "#188a3e", "#1a5fb4", "#555", "#0a7f9e", "#7b2fbf"
|
||||
|
||||
PPQ, SQ, ENTRY = 95.80, 90.80, 96.00
|
||||
|
||||
COMUN = [98.60, 97.80, 97.00, 96.40] # corecția, identică pe ambele panouri
|
||||
CLOSES_DA = COMUN + [95.70, 96.00, 96.60] # 4: BIM 5: prima verde = intrare
|
||||
CLOSES_NU = COMUN + [96.80, 96.10, 95.10, 94.00, 92.90] # 4: verde fără BIM
|
||||
|
||||
w_da = [(0.15, 0.15)] * len(CLOSES_DA)
|
||||
w_da[4] = (0.10, 0.15) # bara BIM coboară sub PPQ: 95.55
|
||||
w_da[5] = (0.10, 0.10)
|
||||
w_nu = [(0.15, 0.15)] * len(CLOSES_NU)
|
||||
w_nu[4] = (0.10, 0.10)
|
||||
|
||||
START = COMUN[0] + 0.30
|
||||
cds_da = from_closes(CLOSES_DA, wicks=w_da, start=START)
|
||||
cds_nu = from_closes(CLOSES_NU, wicks=w_nu, start=START)
|
||||
|
||||
BIM_I, VERDE_DA, VERDE_NU = 4, 5, 4
|
||||
|
||||
# --- ce trebuie să fie adevărat ca desenul să susțină textul ---------------
|
||||
ser = lambda c: (round(c.o, 2), round(c.h, 2), round(c.l, 2), round(c.c, 2)) # noqa: E731
|
||||
assert [ser(c) for c in cds_da[:4]] == [ser(c) for c in cds_nu[:4]], \
|
||||
"panourile nu pleacă din aceeași corecție"
|
||||
# DA: BIM înainte de verde; verdele e chiar verde; close-ul lui = intrarea
|
||||
assert BIM_I < VERDE_DA
|
||||
assert cds_da[BIM_I].c < cds_da[BIM_I].o, "bara de BIM e bara de epuizare, roșie"
|
||||
assert cds_da[VERDE_DA].c > cds_da[VERDE_DA].o, "candela de intrare nu e verde"
|
||||
assert abs(cds_da[VERDE_DA].c - ENTRY) < 1e-9, cds_da[VERDE_DA].c
|
||||
# criteriul A+: candela de intrare închide DEASUPRA pivotului
|
||||
assert cds_da[VERDE_DA].c > PPQ, "candela de intrare nu închide peste PPQ"
|
||||
# prețul a intrat efectiv în zona PPQ (a coborât sub pivot și a fost respins)
|
||||
assert cds_da[BIM_I].l < PPQ < cds_da[VERDE_DA].c, (cds_da[BIM_I].l, PPQ)
|
||||
assert min(c.l for c in cds_da) == cds_da[BIM_I].l, "fundul nu e pe bara de BIM"
|
||||
# NU: verdele vine primul, și după el prețul face minime tot mai joase
|
||||
assert cds_nu[VERDE_NU].c > cds_nu[VERDE_NU].o, "bara 4 de pe panoul NU nu e verde"
|
||||
lows = [c.l for c in cds_nu[VERDE_NU + 1:]]
|
||||
assert all(b < a for a, b in zip(lows, lows[1:])), "cuțitul nu cade continuu"
|
||||
assert cds_nu[-1].c < PPQ - 2.5, "căderea de pe panoul NU e prea mică ca să se vadă"
|
||||
assert min(c.l for c in cds_nu) > SQ, "căderea desenată trece deja de SQ"
|
||||
# cele două panouri au aceeași scară, deci căderile se compară cu ochiul
|
||||
PIERDERE = round((cds_nu[-1].c - cds_nu[VERDE_NU].c) / cds_nu[VERDE_NU].c * 100, 1)
|
||||
assert PIERDERE < -3.0, PIERDERE
|
||||
|
||||
ch_da = Chart(
|
||||
candles=cds_da,
|
||||
marks=[],
|
||||
arrows=[
|
||||
Arrow(BIM_I, "BIM: săgeata indicatorului\ncyan = momentul în care\ntrendul se schimbă",
|
||||
where="below", color=CYAN),
|
||||
Arrow(VERDE_DA, f"AICI INTRI, la close {ENTRY:.2f}\nînchide peste pivot, deci\n"
|
||||
f"cumpărătorii au ținut zona",
|
||||
price=ENTRY, where="right", color=GREEN, dx=18, dy=40),
|
||||
],
|
||||
scale=SCALE, gap=GAP, body_w=13, left=LEFT, width=W,
|
||||
title="DA — BIM, apoi prima candelă verde daily",
|
||||
)
|
||||
ch_nu = Chart(
|
||||
candles=cds_nu,
|
||||
marks=[],
|
||||
arrows=[
|
||||
Arrow(VERDE_NU, "aici NU intri: verdele a venit\nînainte de BIM, deci nimic\n"
|
||||
"nu confirmă că vânzarea s-a oprit",
|
||||
where="below", color=RED, dx=40),
|
||||
Arrow(len(cds_nu) - 1, f"căderea continuă: {abs(PIERDERE):.1f} % mai jos\nde la candela verde —\n"
|
||||
f"„cuțitul prins în cădere”",
|
||||
where="below", color=RED, dx=-30),
|
||||
],
|
||||
scale=SCALE, gap=GAP, body_w=13, left=LEFT, width=W,
|
||||
title="NU — candelă verde înainte de BIM",
|
||||
)
|
||||
|
||||
|
||||
def panel(ch):
|
||||
svg = ch._render()
|
||||
m = re.search(r'viewBox="0 0 ([\d.]+) ([\d.]+)"', svg)
|
||||
assert float(m.group(1)) == W, f"o etichetă iese din {W}px"
|
||||
return svg[svg.index(">") + 1:svg.rindex("</svg>")], float(m.group(2))
|
||||
|
||||
|
||||
def level(ch, price, text, color, below=False):
|
||||
y = ch._y(price)
|
||||
out = [f'<line x1="24" y1="{y:.1f}" x2="{W - 14}" y2="{y:.1f}" stroke="{color}" '
|
||||
f'stroke-width="1.5" stroke-dasharray="4 3"/>']
|
||||
for k, s in enumerate(text):
|
||||
ty = (y + 15 + 14 * k) if below else (y - 6 - 14 * (len(text) - 1 - k))
|
||||
out.append(f'<text x="30" y="{ty:.1f}" fill="{color}" style="font-weight:bold">{s}</text>')
|
||||
return out
|
||||
|
||||
|
||||
def zone(ch, i0, i1, label, color, lift=0.0):
|
||||
cds = ch.candles[i0:i1 + 1]
|
||||
x0, x1 = ch._cx(i0) - 17, ch._cx(i1) + 17
|
||||
y0 = ch._y(max(c.h for c in cds)) - 8 - lift
|
||||
y1 = ch._y(min(c.l for c in cds)) + 8
|
||||
return [f'<rect x="{x0:.1f}" y="{y0:.1f}" width="{x1 - x0:.1f}" height="{y1 - y0:.1f}" '
|
||||
f'fill="{color}" fill-opacity="0.12" stroke="{color}" stroke-width="1"/>',
|
||||
f'<text x="{x0 + 6:.1f}" y="{y0 - 7:.1f}" fill="{color}" '
|
||||
f'style="font-weight:bold">{label}</text>']
|
||||
|
||||
|
||||
body_da, h_da = panel(ch_da)
|
||||
body_nu, h_nu = panel(ch_nu)
|
||||
|
||||
extra_da = (zone(ch_da, BIM_I, VERDE_DA, "zona de decizie: BIM + verde", BLUE, lift=16)
|
||||
+ level(ch_da, PPQ, [f"PPQ {PPQ:.2f} — pivotul trimestrial"], PURPLE, below=True))
|
||||
extra_nu = (zone(ch_nu, VERDE_NU, len(cds_nu) - 1, "fără BIM, nimic nu confirmă", RED, lift=16)
|
||||
+ level(ch_nu, PPQ, [f"PPQ {PPQ:.2f} — pivotul trimestrial"], PURPLE, below=True))
|
||||
|
||||
CAP = ["Aceleași patru bare de corecție pe ambele panouri, aceeași scară.",
|
||||
"PPQ 95.80 e calculat în diagrama pasului 1; intrarea 96.00 e close-ul candelei verzi."]
|
||||
assert all(len(s) * 6.3 < W - 40 for s in CAP), "caption prea lung"
|
||||
cap_top = h_da + h_nu + 20
|
||||
H = cap_top + 24
|
||||
|
||||
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">',
|
||||
f'<g transform="translate(0,0)">{"".join(extra_da)}{body_da}</g>',
|
||||
f'<g transform="translate(0,{h_da:.0f})">{"".join(extra_nu)}{body_nu}</g>',
|
||||
f'<text x="24" y="{cap_top:.0f}" fill="{GREY}">{CAP[0]}</text>',
|
||||
f'<text x="24" y="{cap_top + 16:.0f}" fill="{GREY}">{CAP[1]}</text>',
|
||||
"</svg>"])
|
||||
assert "\n\n" not in svg and ".md:" not in svg
|
||||
|
||||
TEXT = re.compile(r'<text x="([-\d.]+)" y="([-\d.]+)"([^>]*)>(.*?)</text>', re.S)
|
||||
|
||||
|
||||
def labels(body, y_off, tag):
|
||||
out = []
|
||||
for m in TEXT.finditer(body):
|
||||
x, y, attrs, s = float(m.group(1)), float(m.group(2)) + y_off, m.group(3), m.group(4)
|
||||
anchor = "end" if 'text-anchor="end"' in attrs else (
|
||||
"middle" if 'text-anchor="middle"' in attrs else "start")
|
||||
w = len(s) * 12 * (0.62 if "bold" in attrs else 0.52)
|
||||
lf = x - w if anchor == "end" else (x - w / 2 if anchor == "middle" else x)
|
||||
out.append((lf, lf + w, y, s, tag))
|
||||
return out
|
||||
|
||||
|
||||
LB = (labels(body_da + "".join(extra_da), 0.0, "DA")
|
||||
+ labels(body_nu + "".join(extra_nu), h_da, "NU"))
|
||||
for lf, rt, y, s, tag in LB:
|
||||
assert -2 <= lf and rt <= W + 2, f"[{tag}] text iese din panză: {s!r}"
|
||||
assert 0 <= y <= H, f"[{tag}] text în afara înălțimii: {s!r}"
|
||||
for i in range(len(LB)):
|
||||
for j in range(i + 1, len(LB)):
|
||||
li, ri, yi, si, ti = LB[i]
|
||||
lj, rj, yj, sj, tj = LB[j]
|
||||
assert not (ti == tj and abs(yi - yj) < 12 and li < rj - 4 and lj < ri - 4), \
|
||||
f"[{ti}] texte suprapuse: {si!r} / {sj!r}"
|
||||
|
||||
# niciun preț scris într-o etichetă care nu e un nivel desenat pe panoul lui
|
||||
for lf, rt, y, s, tag in LB:
|
||||
for p in re.findall(r"\d+\.\d\d", s):
|
||||
assert float(p) in (PPQ, ENTRY), f"[{tag}] prețul {p} din {s!r} nu e un nivel desenat"
|
||||
|
||||
OUT.write_text(svg)
|
||||
print(f"DA: BIM la {BIM_I} (low {cds_da[BIM_I].l:.2f} < PPQ {PPQ}), intrare {ENTRY:.2f}")
|
||||
print(f"NU: verde la {VERDE_NU} fără BIM, apoi {PIERDERE:.1f} % în jos "
|
||||
f"(ultimul close {cds_nu[-1].c:.2f}, peste SQ {SQ})")
|
||||
print(f"scris {OUT.name} ({W}x{H:.0f})")
|
||||
62
gen/strategii/atmi_trigger.svg
Normal file
@@ -0,0 +1,62 @@
|
||||
<svg viewBox="0 0 660 821" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<g transform="translate(0,0)"><rect x="225.0" y="149.3" width="78.0" height="75.7" fill="#1a5fb4" fill-opacity="0.12" stroke="#1a5fb4" stroke-width="1"/><text x="231.0" y="142.3" fill="#1a5fb4" style="font-weight:bold">zona de decizie: BIM + verde</text><line x1="24" y1="205.5" x2="646" y2="205.5" stroke="#7b2fbf" stroke-width="1.5" stroke-dasharray="4 3"/><text x="30" y="220.5" fill="#7b2fbf" style="font-weight:bold">PPQ 95.80 — pivotul trimestrial</text>
|
||||
<text x="24" y="48" fill="#333" style="font-weight:bold">DA — BIM, apoi prima candelă verde daily</text>
|
||||
<line x1="66.0" y1="56.0" x2="66.0" y2="83.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="59.5" y="62.9" width="13" height="13.8" fill="#c00"/>
|
||||
<line x1="110.0" y1="69.8" x2="110.0" y2="120.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="103.5" y="76.7" width="13" height="36.8" fill="#c00"/>
|
||||
<line x1="154.0" y1="106.6" x2="154.0" y2="157.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="147.5" y="113.5" width="13" height="36.8" fill="#c00"/>
|
||||
<line x1="198.0" y1="143.4" x2="198.0" y2="184.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="191.5" y="150.3" width="13" height="27.6" fill="#c00"/>
|
||||
<line x1="242.0" y1="173.3" x2="242.0" y2="217.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="235.5" y="177.9" width="13" height="32.2" fill="#c00"/>
|
||||
<line x1="286.0" y1="191.7" x2="286.0" y2="214.7" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="279.5" y="196.3" width="13" height="13.8" fill="#188a3e"/>
|
||||
<line x1="330.0" y1="161.8" x2="330.0" y2="203.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="323.5" y="168.7" width="13" height="27.6" fill="#188a3e"/>
|
||||
<line x1="242.0" y1="247.0" x2="242.0" y2="229.0" stroke="#0a7f9e" stroke-width="1.8"/>
|
||||
<polygon points="242.0,221.0 246.0,229.0 238.0,229.0" fill="#0a7f9e"/>
|
||||
<text x="242.0" y="261.0" fill="#0a7f9e" text-anchor="middle" style="font-weight:bold">BIM: săgeata indicatorului</text>
|
||||
<text x="242.0" y="275.0" fill="#0a7f9e" text-anchor="middle" style="font-weight:bold">cyan = momentul în care</text>
|
||||
<text x="242.0" y="289.0" fill="#0a7f9e" text-anchor="middle" style="font-weight:bold">trendul se schimbă</text>
|
||||
<line x1="344.5" y1="236.3" x2="302.6" y2="201.4" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<polygon points="296.5,196.3 305.2,198.3 300.1,204.5" fill="#188a3e"/>
|
||||
<text x="348.5" y="226.3" fill="#188a3e" text-anchor="start" style="font-weight:bold">AICI INTRI, la close 96.00</text>
|
||||
<text x="348.5" y="240.3" fill="#188a3e" text-anchor="start" style="font-weight:bold">închide peste pivot, deci</text>
|
||||
<text x="348.5" y="254.3" fill="#188a3e" text-anchor="start" style="font-weight:bold">cumpărătorii au ținut zona</text>
|
||||
</g>
|
||||
<g transform="translate(0,324)"><rect x="225.0" y="128.6" width="210.0" height="225.2" fill="#c00" fill-opacity="0.12" stroke="#c00" stroke-width="1"/><text x="231.0" y="121.6" fill="#c00" style="font-weight:bold">fără BIM, nimic nu confirmă</text><line x1="24" y1="205.5" x2="646" y2="205.5" stroke="#7b2fbf" stroke-width="1.5" stroke-dasharray="4 3"/><text x="30" y="220.5" fill="#7b2fbf" style="font-weight:bold">PPQ 95.80 — pivotul trimestrial</text>
|
||||
<text x="24" y="48" fill="#333" style="font-weight:bold">NU — candelă verde înainte de BIM</text>
|
||||
<line x1="66.0" y1="56.0" x2="66.0" y2="83.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="59.5" y="62.9" width="13" height="13.8" fill="#c00"/>
|
||||
<line x1="110.0" y1="69.8" x2="110.0" y2="120.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="103.5" y="76.7" width="13" height="36.8" fill="#c00"/>
|
||||
<line x1="154.0" y1="106.6" x2="154.0" y2="157.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="147.5" y="113.5" width="13" height="36.8" fill="#c00"/>
|
||||
<line x1="198.0" y1="143.4" x2="198.0" y2="184.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="191.5" y="150.3" width="13" height="27.6" fill="#c00"/>
|
||||
<line x1="242.0" y1="154.9" x2="242.0" y2="182.5" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="235.5" y="159.5" width="13" height="18.4" fill="#188a3e"/>
|
||||
<line x1="286.0" y1="152.6" x2="286.0" y2="198.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="279.5" y="159.5" width="13" height="32.2" fill="#c00"/>
|
||||
<line x1="330.0" y1="184.8" x2="330.0" y2="244.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="323.5" y="191.7" width="13" height="46.0" fill="#c00"/>
|
||||
<line x1="374.0" y1="230.8" x2="374.0" y2="295.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="367.5" y="237.7" width="13" height="50.6" fill="#c00"/>
|
||||
<line x1="418.0" y1="281.4" x2="418.0" y2="345.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="411.5" y="288.3" width="13" height="50.6" fill="#c00"/>
|
||||
<line x1="282.0" y1="303.2" x2="244.6" y2="194.1" stroke="#c00" stroke-width="1.8"/>
|
||||
<polygon points="242.0,186.5 248.4,192.8 240.8,195.4" fill="#c00"/>
|
||||
<text x="282.0" y="317.2" fill="#c00" text-anchor="middle" style="font-weight:bold">aici NU intri: verdele a venit</text>
|
||||
<text x="282.0" y="331.2" fill="#c00" text-anchor="middle" style="font-weight:bold">înainte de BIM, deci nimic</text>
|
||||
<text x="282.0" y="345.2" fill="#c00" text-anchor="middle" style="font-weight:bold">nu confirmă că vânzarea s-a oprit</text>
|
||||
<line x1="388.0" y1="375.8" x2="412.0" y2="355.0" stroke="#c00" stroke-width="1.8"/>
|
||||
<polygon points="418.0,349.8 414.6,358.1 409.3,352.0" fill="#c00"/>
|
||||
<text x="388.0" y="389.8" fill="#c00" text-anchor="middle" style="font-weight:bold">căderea continuă: 4.0 % mai jos</text>
|
||||
<text x="388.0" y="403.8" fill="#c00" text-anchor="middle" style="font-weight:bold">de la candela verde —</text>
|
||||
<text x="388.0" y="417.8" fill="#c00" text-anchor="middle" style="font-weight:bold">„cuțitul prins în cădere”</text>
|
||||
</g>
|
||||
<text x="24" y="797" fill="#555">Aceleași patru bare de corecție pe ambele panouri, aceeași scară.</text>
|
||||
<text x="24" y="813" fill="#555">PPQ 95.80 e calculat în diagrama pasului 1; intrarea 96.00 e close-ul candelei verzi.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
@@ -1,5 +1,9 @@
|
||||
"""Buy hammer — diagrama de ansamblu (daily, ticker ilustrativ XYZ).
|
||||
|
||||
Seria de aici e SURSA UNICĂ a trade-ului din Partea A: `hammer_mbt10_bh_stop`
|
||||
și `hammer_mbt10_bh_iesire` importă `serie()` și pornesc din aceleași bare
|
||||
(hammer 63.30 / 62.10, intrare 63.35, SL 62.05, TP 65.95 = 2R).
|
||||
|
||||
Citește specificația `gen/strategii/hammer_mbt10_bh_ansamblu.spec.txt`.
|
||||
Seria de 34 de candele e construită din lista de close-uri dată, cu open-ul
|
||||
fiecărei bare = close-ul precedentului; wick-urile sunt fixate ca nivelurile
|
||||
@@ -10,109 +14,117 @@ import re
|
||||
import sys; sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
from svg_candles import Chart, Level, Mark, from_closes
|
||||
|
||||
# --- seria: 34 de close-uri, exact ca în specificație ------------------------
|
||||
closes = [
|
||||
72.00, 71.20, 71.50, 70.40, 69.60, 70.00, 68.90, 68.10, 68.40, 67.30, # 0-9
|
||||
66.50, 66.80, 65.70, 64.90, 65.20, 64.10, 63.40, 63.70, 63.05, # 10-18
|
||||
63.30, # 19 = hammer: o 63.05, c/h 63.30, l 62.10 (H = C, fitil sus 0)
|
||||
63.35, # 20 = confirmare: close peste 63.30 => intrare
|
||||
63.80, 64.20, 64.60, 64.40, 64.90, 65.20, 65.50, 65.80, 66.10, # 21-29
|
||||
66.00, 65.70, 65.40, 65.60, # 30-33
|
||||
]
|
||||
assert len(closes) == 34
|
||||
def serie():
|
||||
"""Cele 34 de bare ale trade-ului XYZ, cu verificările specificației."""
|
||||
# --- seria: 34 de close-uri, exact ca în specificație ------------------------
|
||||
closes = [
|
||||
72.00, 71.20, 71.50, 70.40, 69.60, 70.00, 68.90, 68.10, 68.40, 67.30, # 0-9
|
||||
66.50, 66.80, 65.70, 64.90, 65.20, 64.10, 63.40, 63.70, 63.05, # 10-18
|
||||
63.30, # 19 = hammer: o 63.05, c/h 63.30, l 62.10 (H = C, fitil sus 0)
|
||||
63.35, # 20 = confirmare: close peste 63.30 => intrare
|
||||
63.80, 64.20, 64.60, 64.40, 64.90, 65.20, 65.50, 65.80, 66.10, # 21-29
|
||||
66.00, 65.70, 65.40, 65.60, # 30-33
|
||||
]
|
||||
assert len(closes) == 34
|
||||
|
||||
# wick-uri: (up, down) implicite (0.25, 0.30) + excepțiile din specificație
|
||||
wicks = [(0.25, 0.30)] * 34
|
||||
wicks[19] = (0.00, 0.95) # hammer: high 63.30 (= close), low 62.10
|
||||
# bara 20: wu=0.15 => high 63.50. Spec-ul dă wd=0.15 cu „low 63.20", dar
|
||||
# wd se măsoară de la min(o,c)=63.30, deci 0.15 dă 63.15; folosim tuplul
|
||||
# literal din specificație (0.15, 0.15), low-ul barei 20 nu e etichetat.
|
||||
wicks[20] = (0.15, 0.15)
|
||||
# wick-uri: (up, down) implicite (0.25, 0.30) + excepțiile din specificație
|
||||
wicks = [(0.25, 0.30)] * 34
|
||||
wicks[19] = (0.00, 0.95) # hammer: high 63.30 (= close), low 62.10
|
||||
# bara 20: wu=0.15 => high 63.50. Spec-ul dă wd=0.15 cu „low 63.20", dar
|
||||
# wd se măsoară de la min(o,c)=63.30, deci 0.15 dă 63.15; folosim tuplul
|
||||
# literal din specificație (0.15, 0.15), low-ul barei 20 nu e etichetat.
|
||||
wicks[20] = (0.15, 0.15)
|
||||
|
||||
# volum relativ ales de generator (materialul nu dă volum pe exemplul construit):
|
||||
# normal pe downtrend, în creștere pe hammer (19) și pe confirmare (20), normal după
|
||||
vols = [50, 48, 47, 46, 45, 46, 44, 43, 45, 42,
|
||||
41, 43, 40, 39, 41, 38, 37, 39, 55,
|
||||
90, 95,
|
||||
58, 55, 53, 50, 52, 54, 56, 60, 64,
|
||||
58, 55, 52, 50]
|
||||
assert len(vols) == 34
|
||||
media_vol = sum(vols) / len(vols)
|
||||
assert vols[19] > media_vol and vols[20] > media_vol, "volum peste medie pe hammer/confirmare"
|
||||
# volum relativ ales de generator (materialul nu dă volum pe exemplul construit):
|
||||
# normal pe downtrend, în creștere pe hammer (19) și pe confirmare (20), normal după
|
||||
vols = [50, 48, 47, 46, 45, 46, 44, 43, 45, 42,
|
||||
41, 43, 40, 39, 41, 38, 37, 39, 55,
|
||||
90, 95,
|
||||
58, 55, 53, 50, 52, 54, 56, 60, 64,
|
||||
58, 55, 52, 50]
|
||||
assert len(vols) == 34
|
||||
media_vol = sum(vols) / len(vols)
|
||||
assert vols[19] > media_vol and vols[20] > media_vol, "volum peste medie pe hammer/confirmare"
|
||||
|
||||
cds = from_closes(closes, wicks=wicks, vols=vols, start=72.00)
|
||||
cds = from_closes(closes, wicks=wicks, vols=vols, start=72.00)
|
||||
|
||||
hammer, conf = cds[19], cds[20]
|
||||
# confirmarea o punem ca notă sub grafic: un Mark deasupra barei 20 s-ar
|
||||
# suprapune cu fitilul lung al hammer-ului (bara 19)
|
||||
conf.note = "bara 20: confirmare — close 63.35 peste high-ul hammer-ului 63.30 (intrare)"
|
||||
intrare, sl, tp = 63.35, 62.05, 65.95
|
||||
hammer, conf = cds[19], cds[20]
|
||||
# confirmarea o punem ca notă sub grafic: un Mark deasupra barei 20 s-ar
|
||||
# suprapune cu fitilul lung al hammer-ului (bara 19)
|
||||
conf.note = "bara 20: confirmare — close 63.35 peste high-ul hammer-ului 63.30 (intrare)"
|
||||
intrare, sl, tp = 63.35, 62.05, 65.95
|
||||
|
||||
# --- cele 8 assert-uri cerute de specificație -------------------------------
|
||||
# 1. hammer: H = C = 63.30, L = 62.10
|
||||
assert abs(cds[19].c - 63.30) < 1e-9 and abs(cds[19].h - 63.30) < 1e-9, "H != C la hammer"
|
||||
assert abs(cds[19].l - 62.10) < 1e-9, f"low[19]={cds[19].l} != 62.10"
|
||||
# 2. open[19] = close[18]; corp 0.25; fitil jos 0.95 >= 2*0.25
|
||||
assert abs(cds[19].o - cds[18].c) < 1e-9 and abs(cds[19].o - 63.05) < 1e-9, "open[19] != close[18]"
|
||||
corp = hammer.c - hammer.o
|
||||
fitil_jos = hammer.o - hammer.l
|
||||
assert abs(corp - 0.25) < 1e-9, f"corp={corp} != 0.25"
|
||||
assert abs(fitil_jos - 0.95) < 1e-9, f"fitil jos={fitil_jos} != 0.95"
|
||||
assert fitil_jos >= 2 * corp, "fitilul nu e cel puțin dublul corpului"
|
||||
# 3. confirmarea închide peste high-ul hammer-ului
|
||||
assert abs(conf.c - intrare) < 1e-9, f"close[20]={conf.c} != 63.35"
|
||||
assert conf.c > hammer.h and abs(hammer.h - 63.30) < 1e-9, "close[20] nu e peste high[19]"
|
||||
# 4. SL = low-ul hammer-ului - 0.05
|
||||
assert abs(sl - (cds[19].l - 0.05)) < 1e-9, "SL != low[19] - 0.05"
|
||||
# 5. risc 1.30, TP 2.60 = 2R exact
|
||||
assert abs(abs(intrare - sl) - 1.30) < 1e-9, "risc != 1.30"
|
||||
assert abs(abs(tp - intrare) - 2.60) < 1e-9, "TP != 2R exact"
|
||||
# 6. primul high >= TP e bara 28 (65.80 + wick 0.25 = 66.05)
|
||||
primul_tp = next(i for i in range(21, len(cds)) if cds[i].h >= tp)
|
||||
assert primul_tp == 28, f"TP 65.95 atins întâi la bara {primul_tp}, nu 28"
|
||||
# 7. downtrend vizibil
|
||||
assert cds[18].c < cds[0].c - 8, "downtrend prea mic"
|
||||
# 8. ordinea nivelurilor
|
||||
assert sl < intrare < tp, "SL / intrare / TP nu sunt în ordine"
|
||||
# --- cele 8 assert-uri cerute de specificație -------------------------------
|
||||
# 1. hammer: H = C = 63.30, L = 62.10
|
||||
assert abs(cds[19].c - 63.30) < 1e-9 and abs(cds[19].h - 63.30) < 1e-9, "H != C la hammer"
|
||||
assert abs(cds[19].l - 62.10) < 1e-9, f"low[19]={cds[19].l} != 62.10"
|
||||
# 2. open[19] = close[18]; corp 0.25; fitil jos 0.95 >= 2*0.25
|
||||
assert abs(cds[19].o - cds[18].c) < 1e-9 and abs(cds[19].o - 63.05) < 1e-9, "open[19] != close[18]"
|
||||
corp = hammer.c - hammer.o
|
||||
fitil_jos = hammer.o - hammer.l
|
||||
assert abs(corp - 0.25) < 1e-9, f"corp={corp} != 0.25"
|
||||
assert abs(fitil_jos - 0.95) < 1e-9, f"fitil jos={fitil_jos} != 0.95"
|
||||
assert fitil_jos >= 2 * corp, "fitilul nu e cel puțin dublul corpului"
|
||||
# 3. confirmarea închide peste high-ul hammer-ului
|
||||
assert abs(conf.c - intrare) < 1e-9, f"close[20]={conf.c} != 63.35"
|
||||
assert conf.c > hammer.h and abs(hammer.h - 63.30) < 1e-9, "close[20] nu e peste high[19]"
|
||||
# 4. SL = low-ul hammer-ului - 0.05
|
||||
assert abs(sl - (cds[19].l - 0.05)) < 1e-9, "SL != low[19] - 0.05"
|
||||
# 5. risc 1.30, TP 2.60 = 2R exact
|
||||
assert abs(abs(intrare - sl) - 1.30) < 1e-9, "risc != 1.30"
|
||||
assert abs(abs(tp - intrare) - 2.60) < 1e-9, "TP != 2R exact"
|
||||
# 6. primul high >= TP e bara 28 (65.80 + wick 0.25 = 66.05)
|
||||
primul_tp = next(i for i in range(21, len(cds)) if cds[i].h >= tp)
|
||||
assert primul_tp == 28, f"TP 65.95 atins întâi la bara {primul_tp}, nu 28"
|
||||
# 7. downtrend vizibil
|
||||
assert cds[18].c < cds[0].c - 8, "downtrend prea mic"
|
||||
# 8. ordinea nivelurilor
|
||||
assert sl < intrare < tp, "SL / intrare / TP nu sunt în ordine"
|
||||
|
||||
print(f"hammer H/C {hammer.h:.2f} L {hammer.l:.2f} intrare {conf.c:.2f} "
|
||||
f"SL {sl:.2f} TP {tp:.2f} = {abs(tp-intrare)/abs(intrare-sl):.1f}R "
|
||||
f"TP atins la bara {primul_tp} (high {cds[primul_tp].h:.2f})")
|
||||
print(f"hammer H/C {hammer.h:.2f} L {hammer.l:.2f} intrare {conf.c:.2f} "
|
||||
f"SL {sl:.2f} TP {tp:.2f} = {abs(tp-intrare)/abs(intrare-sl):.1f}R "
|
||||
f"TP atins la bara {primul_tp} (high {cds[primul_tp].h:.2f})")
|
||||
return cds, hammer, conf
|
||||
|
||||
# --- desenul ----------------------------------------------------------------
|
||||
ch = Chart(
|
||||
candles=cds,
|
||||
levels=[
|
||||
Level(sl, "SL 62.05 — sub low-ul hammer-ului", "#c00", label_at="left"),
|
||||
Level(intrare, "intrare 63.35", "#188a3e"),
|
||||
Level(tp, "TP 65.95 = 2R", "#1a5fb4"),
|
||||
],
|
||||
marks=[
|
||||
Mark(19, "hammer 63.30 / 62.10", "#b06000", "below"),
|
||||
],
|
||||
scale=32.0, gap=15, body_w=9, left=44, width=720, vol_h=70,
|
||||
vol_label="volum", title="Buy hammer — daily (ticker ilustrativ XYZ, din lecția de pattern)",
|
||||
caption="", # legenda e pusă manual, pe două rânduri, ca să nu iasă din pânză
|
||||
)
|
||||
|
||||
svg = ch.render()
|
||||
assert "<svg" in svg and "\n\n" not in svg, "linie goală în SVG"
|
||||
if __name__ == "__main__":
|
||||
cds, hammer, conf = serie()
|
||||
intrare, sl, tp = 63.35, 62.05, 65.95
|
||||
|
||||
# legenda din specificație e mai lată decât pânza: o rupem pe două rânduri și
|
||||
# extindem viewBox-ul ca să nu fie tăiată
|
||||
m = re.search(r'viewBox="0 0 (\d+) (\d+)"', svg)
|
||||
W, H = int(m.group(1)), int(m.group(2))
|
||||
legenda = [
|
||||
"Exemplu ilustrativ (XYZ) din lecția de pattern (01_MODUL_1/05_patternuri_candele.md:210-215);",
|
||||
"prețurile sunt cele ale lecției, structura barelor dintre ele e construită.",
|
||||
]
|
||||
extra = 16 * len(legenda) + 6
|
||||
svg = svg.replace(f'viewBox="0 0 {W} {H}"', f'viewBox="0 0 {W} {H + extra}"')
|
||||
svg = svg.replace("</svg>", "".join(
|
||||
f'<text x="24" y="{H + 12 + 16 * i}" fill="#555">{t}</text>'
|
||||
for i, t in enumerate(legenda)) + "</svg>")
|
||||
assert "\n\n" not in svg, "linie goală în SVG după legendă"
|
||||
# --- desenul ----------------------------------------------------------------
|
||||
ch = Chart(
|
||||
candles=cds,
|
||||
levels=[
|
||||
Level(sl, "SL 62.05 — sub low-ul hammer-ului", "#c00", label_at="left"),
|
||||
Level(intrare, "intrare 63.35", "#188a3e"),
|
||||
Level(tp, "TP 65.95 = 2R", "#1a5fb4"),
|
||||
],
|
||||
marks=[
|
||||
Mark(19, "hammer 63.30 / 62.10", "#b06000", "below"),
|
||||
],
|
||||
scale=32.0, gap=15, body_w=9, left=44, width=720, vol_h=70,
|
||||
vol_label="volum", title="Buy hammer — daily (ticker ilustrativ XYZ, din lecția de pattern)",
|
||||
caption="", # legenda e pusă manual, pe două rânduri, ca să nu iasă din pânză
|
||||
)
|
||||
|
||||
with open("/workspace/atm-curs-dl/gen/strategii/hammer_mbt10_bh_ansamblu.svg", "w") as f:
|
||||
f.write(svg)
|
||||
print("scris gen/strategii/hammer_mbt10_bh_ansamblu.svg")
|
||||
svg = ch.render()
|
||||
assert "<svg" in svg and "\n\n" not in svg, "linie goală în SVG"
|
||||
|
||||
# legenda din specificație e mai lată decât pânza: o rupem pe două rânduri și
|
||||
# extindem viewBox-ul ca să nu fie tăiată
|
||||
m = re.search(r'viewBox="0 0 (\d+) (\d+)"', svg)
|
||||
W, H = int(m.group(1)), int(m.group(2))
|
||||
legenda = [
|
||||
"Exemplu ilustrativ (XYZ) din lecția de pattern (01_MODUL_1/05_patternuri_candele.md:210-215);",
|
||||
"prețurile sunt cele ale lecției, structura barelor dintre ele e construită.",
|
||||
]
|
||||
extra = 16 * len(legenda) + 6
|
||||
svg = svg.replace(f'viewBox="0 0 {W} {H}"', f'viewBox="0 0 {W} {H + extra}"')
|
||||
svg = svg.replace("</svg>", "".join(
|
||||
f'<text x="24" y="{H + 12 + 16 * i}" fill="#555">{t}</text>'
|
||||
for i, t in enumerate(legenda)) + "</svg>")
|
||||
assert "\n\n" not in svg, "linie goală în SVG după legendă"
|
||||
|
||||
with open("/workspace/atm-curs-dl/gen/strategii/hammer_mbt10_bh_ansamblu.svg", "w") as f:
|
||||
f.write(svg)
|
||||
print("scris gen/strategii/hammer_mbt10_bh_ansamblu.svg")
|
||||
@@ -1,166 +1,203 @@
|
||||
"""Diagrama de ansamblu MDSRT long (strategii, marcajul `ansamblu`).
|
||||
"""MDSRT — diagrama de ansamblu (Nivelul 1) și seria canonică a capitolului.
|
||||
|
||||
„SPY — 5 min: al doilea picior mai jos la 589.80, sub suportul 590.00 →
|
||||
divergență bull (M) preț-vs-volum → candela-trigger Buy Hammer/Doji →
|
||||
intrare 590.20 → SL 589.40 (risc 0.80) → TP1 591.00 (1:1) → poziția rămasă
|
||||
pe trail, ieșire la close 592.40 (≈ 2.75R)."
|
||||
Aici trăiește singurul exemplu construit al capitolului: SPY pe 5 minute,
|
||||
suport/pivot daily 590.00, piciorul 1 la 590.10 (ține nivelul), piciorul 2 la
|
||||
589.50 (îl rupe, cu divergență pe volum), candela-trigger = Buy Hammer,
|
||||
intrare 590.20, SL 589.40, risc 0.80, TP1 591.00 (1:1), ieșire pe trail la
|
||||
592.40 (2.75R).
|
||||
|
||||
Toate close-urile, wick-urile speciale și nivelurile vin din
|
||||
`gen/strategii/mdsrt_ansamblu.spec.txt`. Structura M→A→P, suportul 590.00,
|
||||
minimul 589.80 și riscul 0.80 sunt din exemplul cursului
|
||||
(`05_MODUL_4/02_strategia_5_mdsrt.md:159-177, 246, 308-311`). Intrare/SL/TP
|
||||
sunt exemplul construit al autorului sumarului, marcat explicit ca NU citat
|
||||
din curs (`...:166-177, 439-445`); transcrierea se întrerupe înainte de
|
||||
planul numeric. Volumele sunt relative, alese de generator (materialul nu dă
|
||||
volum pentru acest exemplu).
|
||||
Celelalte generatoare de preț ale capitolului (picior, trigger, stop, iesire)
|
||||
IMPORTĂ seria de aici. Așa o regulă numerică — marja stopului, distanța până
|
||||
la țintă — nu poate să difere de la o diagramă la alta.
|
||||
|
||||
Rulează:
|
||||
python3 gen/strategii/mdsrt_ansamblu.py
|
||||
Scrie lângă el `mdsrt_ansamblu.svg`.
|
||||
Regulile numerice ale capitolului, definite o singură dată, aici:
|
||||
MARJA = 0.10 — stopul stă cu atât sub low-ul piciorului 2
|
||||
intrarea = close-ul candelei care sparge high-ul candelei-trigger
|
||||
TP1 = intrare + (intrare − SL)
|
||||
|
||||
Ce e din curs și ce nu: structura M→A→P e a cursului; suportul 590.00 și
|
||||
minimul piciorului 2 vin din exemplul construit al autorului sumarului
|
||||
(`05_MODUL_4/02_strategia_5_mdsrt.md:166-177, 439-445`), nu din transcriere —
|
||||
transcrierea se întrerupe înainte de planul numeric.
|
||||
|
||||
Rulează: python3 gen/strategii/mdsrt_ansamblu.py
|
||||
"""
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
from svg_candles import Chart, Level, Mark, MA, from_closes # noqa: E402
|
||||
from svg_candles import Chart, Level, Mark, MA, Zone, Arrow, from_closes # noqa: E402
|
||||
|
||||
OUT = Path(__file__).resolve().parent / "mdsrt_ansamblu.svg"
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
|
||||
GRAY, RED, GREEN, BLUE, ORANGE = "#777", "#c00", "#188a3e", "#1a5fb4", "#b06000"
|
||||
|
||||
# ---------------------------------------------------------------- seria (30 bare)
|
||||
# ------------------------------------------------- regulile numerice ale capitolului
|
||||
MARJA = 0.10 # stopul, sub low-ul piciorului 2
|
||||
SUPORT = 590.00 # pivotul daily (nivelul de pe TF-ul mare)
|
||||
LEG1, TRIG, CONF = 10, 18, 19 # indicii: piciorul 1, candela-trigger, candela de intrare
|
||||
STOP_BARS = 4 # low-ul se caută pe ultimele 4 candele, ca la Buy Doji
|
||||
|
||||
CLOSES = [
|
||||
596.00, 595.20, 595.60, 594.80, 594.10, 593.40, 593.70, 592.90, # 0-7
|
||||
592.20, 591.60, 591.90, 591.30, 590.80, 590.30, 590.55, 590.10, # 8-15
|
||||
589.85, 590.05, # 16-17
|
||||
589.80, # 18 = al doilea picior mai jos + candela-trigger (hammer)
|
||||
590.20, # 19 = intrare (close = entry; sparge high-ul trigger-ului)
|
||||
590.60, 590.90, 591.00, # 20-22 (22 = TP1 1:1)
|
||||
592.20, 591.60,
|
||||
590.40, # 10 = piciorul 1
|
||||
590.90, 591.40, 591.10, 591.30, 590.90, 590.50, 590.05, # 11-17
|
||||
589.80, # 18 = piciorul 2 (Buy Hammer)
|
||||
590.20, # 19 = intrarea
|
||||
590.60, 590.90, 591.00, # 20-22 (22 = TP1)
|
||||
591.30, 591.10, 591.45, 591.70, 591.95, 592.15, # 23-28
|
||||
592.40, # 29 = ieșire pe trail (close)
|
||||
592.80, 593.10, 592.90, # 29-31 = ultimul impuls
|
||||
592.40, # 32 = ieșire pe trail
|
||||
]
|
||||
assert len(CLOSES) == 30, len(CLOSES)
|
||||
WICKS = [(0.25, 0.30)] * 33
|
||||
WICKS[LEG1] = (0.25, 0.30) # piciorul 1: low 590.10, deasupra suportului
|
||||
WICKS[16] = (0.20, 0.15)
|
||||
WICKS[17] = (0.15, 0.10) # low 589.95 — prețul intră în zonă, fără să facă minim nou
|
||||
WICKS[TRIG] = (0.10, 0.30) # hammer: high 590.15, low 589.50
|
||||
WICKS[CONF] = (0.10, 0.05)
|
||||
WICKS[20] = (0.25, 0.15) # retestul nivelului ține: low 590.05, peste pivot
|
||||
WICKS[21] = (0.05, 0.15) # high 590.95 < TP1: ținta e atinsă prima dată la bara 22
|
||||
|
||||
# fitile (sus, jos): (0.25, 0.30) peste tot, cu excepțiile din spec.
|
||||
WICKS = [(0.25, 0.30)] * 30
|
||||
WICKS[18] = (0.10, 0.40) # hammer: high 590.15, low 589.40 (= SL)
|
||||
WICKS[19] = (0.10, 0.05) # intrare: high 590.30, low 589.75
|
||||
# bara 21 coborâtă sub TP1 (high 590.95 < 591.00), ca TP1 să fie atins exact
|
||||
# prima dată la bara 22 (altfel assert-ul 5 ar pica pe „primul high").
|
||||
WICKS[21] = (0.05, 0.30)
|
||||
|
||||
# volum relativ (ales de generator): 16-19 crescător, 18-19 peste medie,
|
||||
# vol[18] > vol[10] (higher low pe volum la lower low pe preț).
|
||||
VOLS = [
|
||||
48, 46, 44, 45, 43, 41, 40, 42, 44, 46, # 0-9
|
||||
52, 38, 40, 42, 39, 44, # 10-15
|
||||
50, 58, 72, 85, # 16-19 absorbție la minim
|
||||
70, 64, 58, 60, 55, 52, 50, 48, 46, 44, # 20-29
|
||||
48, 46, 44, 45, 43, 41, 40, 42, 44, 46, # 0-9
|
||||
52, # 10 = volumul piciorului 1
|
||||
38, 40, 42, 39, 44, 50, 58, # 11-17
|
||||
88, 80, # 18-19 absorbție la minim
|
||||
70, 64, 58, 60, 55, 52, 50, 48, 46, # 20-28
|
||||
52, 48, 42, 46, # 29-32
|
||||
]
|
||||
assert len(VOLS) == 30, len(VOLS)
|
||||
assert len(CLOSES) == len(WICKS) == len(VOLS) == 33
|
||||
|
||||
cds = from_closes(CLOSES, wicks=WICKS, vols=VOLS, start=596.60)
|
||||
|
||||
# ---------------------------------------------------------------- assert-urile din spec
|
||||
entry = cds[19].c
|
||||
sl = cds[18].l
|
||||
tp1 = cds[22].c
|
||||
EXIT_I = 32 # bara pe care se închide poziția, sub linia de trail
|
||||
|
||||
# 1. minimul și SL-ul pe bara 18
|
||||
assert cds[18].c == 589.80, cds[18].c
|
||||
assert cds[18].l == 589.40, cds[18].l
|
||||
# 2. al doilea picior rupe suportul/pivotul 590.00
|
||||
assert cds[18].l < 590.00, cds[18].l
|
||||
# 3. intrarea = close-ul barei 19 și sparge high-ul trigger-ului
|
||||
assert cds[19].c == 590.20, cds[19].c
|
||||
assert cds[19].c == entry
|
||||
assert cds[19].c > cds[18].h, (cds[19].c, cds[18].h)
|
||||
# 4. TP1 exact 1:1
|
||||
assert abs((entry - sl) - (tp1 - entry)) < 1e-9, (entry - sl, tp1 - entry)
|
||||
assert abs((entry - sl) - 0.80) < 1e-9
|
||||
# 5. TP1 atins la bara 22 (și nu mai devreme)
|
||||
assert cds[22].c == 591.00, cds[22].c
|
||||
assert cds[22].c == tp1
|
||||
assert max(c.h for c in cds[20:22]) < tp1, [c.h for c in cds[20:22]]
|
||||
# 6. ieșirea pe trail e pe profit
|
||||
assert cds[29].c == 592.40, cds[29].c
|
||||
assert cds[29].c > entry, (cds[29].c, entry)
|
||||
# 7. hammer: corp mic, coadă lungă în jos
|
||||
body = abs(cds[18].o - cds[18].c)
|
||||
rng = cds[18].h - cds[18].l
|
||||
tail = min(cds[18].o, cds[18].c) - cds[18].l
|
||||
assert body == 0.25, body
|
||||
assert body <= 0.5 * rng, (body, rng)
|
||||
assert tail > body, (tail, body)
|
||||
# 8. downtrend vizibil
|
||||
assert cds[13].c < cds[0].c - 5, (cds[13].c, cds[0].c)
|
||||
# 9. divergență pe volum: lower low pe preț, higher low pe volum
|
||||
assert cds[18].l < cds[10].l, (cds[18].l, cds[10].l)
|
||||
assert VOLS[18] > VOLS[10], (VOLS[18], VOLS[10])
|
||||
# barele 16-19 au volum crescător; 18-19 peste media seriei
|
||||
assert VOLS[16] < VOLS[17] < VOLS[18] < VOLS[19], VOLS[16:20]
|
||||
avg_vol = sum(VOLS) / len(VOLS)
|
||||
assert VOLS[18] > avg_vol and VOLS[19] > avg_vol, (VOLS[18], VOLS[19], avg_vol)
|
||||
# 10. fiecare open == close-ul barei anterioare
|
||||
for a, b in zip(cds, cds[1:]):
|
||||
assert a.c == b.o, (a.c, b.o)
|
||||
|
||||
r_mult = (cds[29].c - entry) / (entry - sl)
|
||||
assert abs(r_mult - 2.75) < 1e-9, r_mult
|
||||
def bull_trail(cds, start):
|
||||
"""Bull Trail, definiția cursului: low-ul fiecărei candele care se închide
|
||||
peste high-ul candelei dinainte; linia urcă, nu coboară niciodată.
|
||||
Întoarce lista [(index, nivel)] de la bara `start` încolo."""
|
||||
out, cur = [], None
|
||||
for i in range(start, len(cds)):
|
||||
if cds[i].c > cds[i - 1].h:
|
||||
cur = round(cds[i].l, 2) if cur is None else max(cur, round(cds[i].l, 2))
|
||||
if cur is not None:
|
||||
out.append((i, cur))
|
||||
return out
|
||||
|
||||
# ---------------------------------------------------------------- niveluri, marks
|
||||
levels = [
|
||||
Level(590.00, "suport / pivot 590.00", BLUE, label_at="left"),
|
||||
Level(sl, f"SL {sl:.2f} — risc 0.80", RED, label_at="left"),
|
||||
# stânga: altfel eticheta din dreapta se calcă pe textul „SMA-20" al mediei
|
||||
Level(tp1, f"TP1 {tp1:.2f} = 1:1", GREEN, label_at="left"),
|
||||
]
|
||||
|
||||
marks = [
|
||||
Mark(18, f"minim 589.80 — divergență (M)", RED, "below"),
|
||||
# ridicat deasupra vârfurilor candelelor de urcare (altfel textul cade peste
|
||||
# fitilele barelor 20-22) — bara 19 e totuși exact sub el
|
||||
Mark(19, f"intrare {entry:.2f}", GREEN, "above", dy=-46),
|
||||
Mark(29, f"ieșire trail {cds[29].c:.2f}", GREEN, "above"),
|
||||
]
|
||||
def serie():
|
||||
"""Seria canonică a capitolului, 33 de candele de 5 minute."""
|
||||
return from_closes(CLOSES, wicks=WICKS, vols=VOLS, start=596.60)
|
||||
|
||||
# titlul e injectat pe două linii: textul din spec (82 caractere) nu încape
|
||||
# pe un singur rând în 640 px fără să fie tăiat la margine
|
||||
TITLE = ["SPY — 5 min (exemplu construit pe scara lecției;",
|
||||
"cifrele planului nu vin din curs)"]
|
||||
|
||||
ch = Chart(
|
||||
candles=cds, levels=levels, marks=marks,
|
||||
mas=[MA(20, ORANGE, dash="4 3", text="SMA-20")],
|
||||
scale=48.0, gap=15, body_w=9, left=44, width=640, top=64, vol_h=70,
|
||||
vol_label="volum",
|
||||
title="", caption="",
|
||||
)
|
||||
svg = ch.render()
|
||||
title_svg = "\n ".join(
|
||||
f'<text x="24" y="{26 + 18 * i}" fill="#333" style="font-weight:bold">{t}</text>'
|
||||
for i, t in enumerate(TITLE))
|
||||
i = svg.index(">") + 1
|
||||
svg = svg[:i] + "\n " + title_svg + svg[i:]
|
||||
cds = serie()
|
||||
leg1_l = cds[LEG1].l
|
||||
leg2_l = cds[TRIG].l
|
||||
ENTRY = cds[CONF].c
|
||||
SL = round(leg2_l - MARJA, 2)
|
||||
R = round(ENTRY - SL, 2)
|
||||
TP1 = round(ENTRY + R, 2)
|
||||
|
||||
# ---------------------------------------------------------------- legenda (onestitate)
|
||||
m = re.search(r'viewBox="0 0 (\d+) ([0-9.]+)"', svg)
|
||||
W, H0 = int(m.group(1)), float(m.group(2))
|
||||
legend = [
|
||||
"Legendă: entry/SL/TP/trail sunt exemplul construit al autorului sumarului,",
|
||||
"nu citate din curs (transcrierea se întrerupe înainte de planul numeric).",
|
||||
]
|
||||
legend_svg = [f'<text x="24" y="{H0 + 16 + 17 * i:.1f}" fill="#555">{t}</text>'
|
||||
for i, t in enumerate(legend)]
|
||||
new_h = H0 + 16 + 17 * (len(legend) - 1) + 14
|
||||
svg = re.sub(r'(viewBox="0 0 \d+ )[0-9.]+(")',
|
||||
lambda mm: mm.group(1) + f"{new_h:.0f}" + mm.group(2), svg, count=1)
|
||||
svg = svg.replace("\n</svg>", "\n " + "\n ".join(legend_svg) + "\n</svg>")
|
||||
# ------------------------------------------------------------------ assert-urile
|
||||
for i, c in enumerate(cds):
|
||||
assert c.h >= max(c.o, c.c) and c.l <= min(c.o, c.c), f"bara {i}: h/l incoerent"
|
||||
if i:
|
||||
assert abs(c.o - cds[i - 1].c) < 1e-9, f"open[{i}] != close[{i-1}]"
|
||||
|
||||
assert svg.count("\n\n") == 0, "linie goală în SVG rupe blocul din markdown"
|
||||
assert f"TP1 {tp1:.2f}" in svg and f"intrare {entry:.2f}" in svg
|
||||
OUT.write_text(svg)
|
||||
print(f"scris {OUT.name}: {len(cds)} candele, suport 590.00, minim {cds[18].l:.2f}, "
|
||||
f"intrare {entry:.2f}, SL {sl:.2f} (risc 0.80), TP1 {tp1:.2f} (1:1), "
|
||||
f"ieșire {cds[29].c:.2f} = {r_mult:.2f}R, vol[18]={VOLS[18]} > vol[10]={VOLS[10]}")
|
||||
# 1. piciorul 1 ține nivelul, piciorul 2 îl rupe — asta e povestea capitolului
|
||||
assert leg1_l == 590.10 and leg1_l > SUPORT, leg1_l
|
||||
assert leg2_l == 589.50 and leg2_l < SUPORT, leg2_l
|
||||
assert leg2_l < leg1_l, (leg2_l, leg1_l)
|
||||
# 2. cele două picioare sunt minimele locale, nu doar două bare oarecare
|
||||
assert leg1_l == min(c.l for c in cds[:LEG1 + 6]), "piciorul 1 nu e minimul zonei lui"
|
||||
assert leg2_l == min(c.l for c in cds), "piciorul 2 nu e minimul seriei"
|
||||
# 3. distanța dintre picioare depășește minimul de 5 candele cerut de curs
|
||||
assert TRIG - LEG1 == 8, TRIG - LEG1
|
||||
# 4. hammer: corp mic sus, coadă lungă în jos
|
||||
body = abs(cds[TRIG].o - cds[TRIG].c)
|
||||
rng = cds[TRIG].h - cds[TRIG].l
|
||||
tail = min(cds[TRIG].o, cds[TRIG].c) - cds[TRIG].l
|
||||
assert body <= 0.5 * rng and tail > body, (body, rng, tail)
|
||||
# 5. intrarea sparge high-ul candelei-trigger (regula de intrare a capitolului)
|
||||
assert ENTRY == 590.20 and ENTRY > cds[TRIG].h, (ENTRY, cds[TRIG].h)
|
||||
# 6. stopul: marja sub cel mai jos low din ultimele 4 candele
|
||||
low4 = min(c.l for c in cds[CONF - STOP_BARS + 1:CONF + 1])
|
||||
assert low4 == leg2_l, (low4, leg2_l)
|
||||
assert SL == 589.40 and R == 0.80, (SL, R)
|
||||
# 7. TP1 e 1:1 exact și e atins prima dată la bara 22
|
||||
assert abs((ENTRY - SL) - (TP1 - ENTRY)) < 1e-9
|
||||
assert TP1 == 591.00
|
||||
assert next(i for i in range(CONF + 1, len(cds)) if cds[i].h >= TP1 - 1e-9) == 22
|
||||
# 8. downtrend vizibil înainte de piciorul 1
|
||||
assert cds[LEG1].c < cds[0].c - 5, (cds[LEG1].c, cds[0].c)
|
||||
# 9. divergența: lower low pe preț, higher low pe volum
|
||||
assert cds[TRIG].l < cds[LEG1].l and VOLS[TRIG] > VOLS[LEG1]
|
||||
assert VOLS[16] < VOLS[17] < VOLS[TRIG] == max(VOLS)
|
||||
# 10. după intrare, retestul ține: nicio bară nu mai închide sub pivot
|
||||
assert all(c.c > SUPORT for c in cds[CONF + 1:]), "prețul recade sub pivot după intrare"
|
||||
assert min(c.l for c in cds[CONF + 1:]) > SUPORT, "o bară de după intrare rupe iar pivotul"
|
||||
# 11. ieșirea pe trail: ultimul swing low înainte de întoarcere e linia de trail,
|
||||
# iar bara de ieșire e prima care se închide sub ea
|
||||
_trail = bull_trail(cds, CONF)
|
||||
TRAIL = dict(_trail)[EXIT_I] # nivelul liniei de trail când vine bara de ieșire
|
||||
assert TRAIL == 592.50, TRAIL
|
||||
assert [p for _, p in _trail] == sorted(p for _, p in _trail), "linia de trail coboară"
|
||||
assert all(cds[i].c > p for i, p in _trail if i < EXIT_I), "trail-ul era rupt mai devreme"
|
||||
assert cds[EXIT_I].c == 592.40 < TRAIL, (cds[EXIT_I].c, TRAIL)
|
||||
r_mult = round((cds[EXIT_I].c - ENTRY) / R, 2)
|
||||
assert r_mult == 2.75, r_mult
|
||||
|
||||
if __name__ == "__main__":
|
||||
levels = [
|
||||
Level(SUPORT, f"pivot daily {SUPORT:.2f} — zona (M)", BLUE, label_at="left"),
|
||||
Level(SL, f"SL {SL:.2f} = 0.10 sub piciorul 2 (risc {R:.2f})", RED),
|
||||
Level(TP1, f"TP1 {TP1:.2f} = 1:1", GREEN, label_at="left"),
|
||||
]
|
||||
marks = [
|
||||
Mark(LEG1, f"piciorul 1: low {leg1_l:.2f}", GRAY, "below"),
|
||||
Mark(TRIG, f"piciorul 2: low {leg2_l:.2f}", RED, "below", dy=16),
|
||||
|
||||
]
|
||||
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",
|
||||
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),
|
||||
Arrow(EXIT_I, f"ieșire pe trail {cds[EXIT_I].c:.2f} = {r_mult:.2f}R\nprima închidere sub linia de trail",
|
||||
where="right", color=GREEN, dy=-6),
|
||||
]
|
||||
ch = Chart(
|
||||
candles=cds, levels=levels, marks=marks, zones=[
|
||||
Zone(LEG1, CONF, "M (zonă + divergență) → A (trigger) → P (plan)", BLUE)],
|
||||
arrows=arrows,
|
||||
mas=[MA(20, ORANGE, dash="4 3", text="SMA-20")],
|
||||
scale=48.0, gap=15, body_w=9, left=44, width=660, top=74, vol_h=70,
|
||||
vol_label="volum: la piciorul 2, volum mai mare decât la piciorul 1 = divergență",
|
||||
)
|
||||
svg = ch.render()
|
||||
TITLE = ["SPY — 5 min (exemplu construit pe scara lecției;",
|
||||
"cifrele planului nu vin din curs)"]
|
||||
title_svg = "\n ".join(
|
||||
f'<text x="24" y="{26 + 18 * i}" fill="#333" style="font-weight:bold">{t}</text>'
|
||||
for i, t in enumerate(TITLE))
|
||||
i = svg.index(">") + 1
|
||||
svg = svg[:i] + "\n " + title_svg + svg[i:]
|
||||
|
||||
m = re.search(r'viewBox="0 0 (\d+) ([0-9.]+)"', svg)
|
||||
W, H0 = int(m.group(1)), float(m.group(2))
|
||||
legend = [
|
||||
"Legendă: structura M → A → P e a cursului; nivelurile (590.00, 589.50) și planul",
|
||||
"(intrare, SL, TP) sunt exemplul construit al autorului sumarului, nu citate din curs.",
|
||||
]
|
||||
legend_svg = [f'<text x="24" y="{H0 + 16 + 17 * i:.1f}" fill="#555">{t}</text>'
|
||||
for i, t in enumerate(legend)]
|
||||
new_h = H0 + 16 + 17 * (len(legend) - 1) + 14
|
||||
svg = re.sub(r'(viewBox="0 0 \d+ )[0-9.]+(")',
|
||||
lambda mm: mm.group(1) + f"{new_h:.0f}" + mm.group(2), svg, count=1)
|
||||
svg = svg.replace("\n</svg>", "\n " + "\n ".join(legend_svg) + "\n</svg>")
|
||||
assert "\n\n" not in svg, "linie goală în SVG"
|
||||
OUT.write_text(svg)
|
||||
print(f"scris {OUT.name}: picior 1 {leg1_l:.2f} / picior 2 {leg2_l:.2f} sub {SUPORT:.2f}, "
|
||||
f"intrare {ENTRY:.2f}, SL {SL:.2f} (risc {R:.2f}), TP1 {TP1:.2f}, ieșire {r_mult:.2f}R")
|
||||
|
||||
@@ -1,109 +1,132 @@
|
||||
<svg viewBox="0 0 640 591" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<svg viewBox="0 0 785 735" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<text x="24" y="26" fill="#333" style="font-weight:bold">SPY — 5 min (exemplu construit pe scara lecției;</text>
|
||||
<text x="24" y="44" fill="#333" style="font-weight:bold">cifrele planului nu vin din curs)</text>
|
||||
<line x1="24" y1="392.8" x2="626" y2="392.8" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="386.8" fill="#1a5fb4">suport / pivot 590.00</text>
|
||||
<line x1="24" y1="421.6" x2="626" y2="421.6" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="415.6" fill="#c00">SL 589.40 — risc 0.80</text>
|
||||
<line x1="24" y1="344.8" x2="626" y2="344.8" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="338.8" fill="#188a3e">TP1 591.00 = 1:1</text>
|
||||
<polyline points="329.0,286.4 344.0,299.3 359.0,309.6 374.0,320.7 389.0,329.1 404.0,336.3 419.0,341.0 434.0,345.8 449.0,348.0 464.0,348.2 479.0,346.2" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="485" y="340" fill="#b06000">SMA-20</text>
|
||||
<line x1="44.0" y1="64.0" x2="44.0" y2="119.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="39.5" y="76.0" width="9" height="28.8" fill="#c00"/>
|
||||
<line x1="59.0" y1="92.8" x2="59.0" y2="157.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="54.5" y="104.8" width="9" height="38.4" fill="#c00"/>
|
||||
<line x1="74.0" y1="112.0" x2="74.0" y2="157.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="69.5" y="124.0" width="9" height="19.2" fill="#188a3e"/>
|
||||
<line x1="89.0" y1="112.0" x2="89.0" y2="176.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="84.5" y="124.0" width="9" height="38.4" fill="#c00"/>
|
||||
<line x1="104.0" y1="150.4" x2="104.0" y2="210.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="99.5" y="162.4" width="9" height="33.6" fill="#c00"/>
|
||||
<line x1="119.0" y1="184.0" x2="119.0" y2="244.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="114.5" y="196.0" width="9" height="33.6" fill="#c00"/>
|
||||
<line x1="134.0" y1="203.2" x2="134.0" y2="244.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="129.5" y="215.2" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="149.0" y1="203.2" x2="149.0" y2="268.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="144.5" y="215.2" width="9" height="38.4" fill="#c00"/>
|
||||
<line x1="164.0" y1="241.6" x2="164.0" y2="301.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="159.5" y="253.6" width="9" height="33.6" fill="#c00"/>
|
||||
<line x1="179.0" y1="275.2" x2="179.0" y2="330.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="174.5" y="287.2" width="9" height="28.8" fill="#c00"/>
|
||||
<line x1="194.0" y1="289.6" x2="194.0" y2="330.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="189.5" y="301.6" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="209.0" y1="289.6" x2="209.0" y2="344.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="204.5" y="301.6" width="9" height="28.8" fill="#c00"/>
|
||||
<line x1="224.0" y1="318.4" x2="224.0" y2="368.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="219.5" y="330.4" width="9" height="24.0" fill="#c00"/>
|
||||
<line x1="239.0" y1="342.4" x2="239.0" y2="392.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="234.5" y="354.4" width="9" height="24.0" fill="#c00"/>
|
||||
<line x1="254.0" y1="354.4" x2="254.0" y2="392.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="249.5" y="366.4" width="9" height="12.0" fill="#188a3e"/>
|
||||
<line x1="269.0" y1="354.4" x2="269.0" y2="402.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="264.5" y="366.4" width="9" height="21.6" fill="#c00"/>
|
||||
<line x1="284.0" y1="376.0" x2="284.0" y2="414.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="279.5" y="388.0" width="9" height="12.0" fill="#c00"/>
|
||||
<line x1="299.0" y1="378.4" x2="299.0" y2="414.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="294.5" y="390.4" width="9" height="9.6" fill="#188a3e"/>
|
||||
<line x1="314.0" y1="385.6" x2="314.0" y2="421.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="309.5" y="390.4" width="9" height="12.0" fill="#c00"/>
|
||||
<line x1="329.0" y1="378.4" x2="329.0" y2="404.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="324.5" y="383.2" width="9" height="19.2" fill="#188a3e"/>
|
||||
<line x1="344.0" y1="352.0" x2="344.0" y2="397.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="339.5" y="364.0" width="9" height="19.2" fill="#188a3e"/>
|
||||
<line x1="359.0" y1="347.2" x2="359.0" y2="378.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="354.5" y="349.6" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="374.0" y1="332.8" x2="374.0" y2="364.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="369.5" y="344.8" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="389.0" y1="318.4" x2="389.0" y2="359.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="384.5" y="330.4" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="404.0" y1="318.4" x2="404.0" y2="354.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="399.5" y="330.4" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="419.0" y1="311.2" x2="419.0" y2="354.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="414.5" y="323.2" width="9" height="16.8" fill="#188a3e"/>
|
||||
<line x1="434.0" y1="299.2" x2="434.0" y2="337.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="429.5" y="311.2" width="9" height="12.0" fill="#188a3e"/>
|
||||
<line x1="449.0" y1="287.2" x2="449.0" y2="325.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="444.5" y="299.2" width="9" height="12.0" fill="#188a3e"/>
|
||||
<line x1="464.0" y1="277.6" x2="464.0" y2="313.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="459.5" y="289.6" width="9" height="9.6" fill="#188a3e"/>
|
||||
<line x1="479.0" y1="265.6" x2="479.0" y2="304.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="474.5" y="277.6" width="9" height="12.0" fill="#188a3e"/>
|
||||
<line x1="24" y1="517.6" x2="626" y2="517.6" stroke="#888"/>
|
||||
<rect x="39.5" y="478.1" width="9" height="39.5" fill="#c00" opacity="0.55"/>
|
||||
<rect x="54.5" y="479.7" width="9" height="37.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="69.5" y="481.4" width="9" height="36.2" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="84.5" y="480.5" width="9" height="37.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="99.5" y="482.2" width="9" height="35.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="114.5" y="483.8" width="9" height="33.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="129.5" y="484.7" width="9" height="32.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="144.5" y="483.0" width="9" height="34.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="159.5" y="481.4" width="9" height="36.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="174.5" y="479.7" width="9" height="37.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="189.5" y="474.8" width="9" height="42.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="204.5" y="486.3" width="9" height="31.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="219.5" y="484.7" width="9" height="32.9" fill="#c00" opacity="0.55"/>
|
||||
<rect x="234.5" y="483.0" width="9" height="34.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="249.5" y="485.5" width="9" height="32.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="264.5" y="481.4" width="9" height="36.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="279.5" y="476.4" width="9" height="41.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="294.5" y="469.8" width="9" height="47.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="309.5" y="458.3" width="9" height="59.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="324.5" y="447.6" width="9" height="70.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="339.5" y="460.0" width="9" height="57.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="354.5" y="464.9" width="9" height="52.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="369.5" y="469.8" width="9" height="47.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="384.5" y="468.2" width="9" height="49.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="399.5" y="472.3" width="9" height="45.3" fill="#c00" opacity="0.55"/>
|
||||
<rect x="414.5" y="474.8" width="9" height="42.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="429.5" y="476.4" width="9" height="41.2" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="444.5" y="478.1" width="9" height="39.5" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="459.5" y="479.7" width="9" height="37.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="474.5" y="481.4" width="9" height="36.2" fill="#188a3e" opacity="0.55"/>
|
||||
<text x="24" y="441.6" fill="#555">volum</text>
|
||||
<text x="314.0" y="435.6" fill="#c00" text-anchor="middle" style="font-weight:bold">minim 589.80 — divergență (M)</text>
|
||||
<text x="329.0" y="322.4" fill="#188a3e" text-anchor="middle" style="font-weight:bold">intrare 590.20</text>
|
||||
<text x="479.0" y="255.6" fill="#188a3e" text-anchor="middle" style="font-weight:bold">ieșire trail 592.40</text>
|
||||
<text x="24" y="560.0" fill="#555">Legendă: entry/SL/TP/trail sunt exemplul construit al autorului sumarului,</text>
|
||||
<text x="24" y="577.0" fill="#555">nu citate din curs (transcrierea se întrerupe înainte de planul numeric).</text>
|
||||
<rect x="184.5" y="306.0" width="154.0" height="128.8" fill="#1a5fb4" fill-opacity="0.08" stroke="#1a5fb4" stroke-width="1"/>
|
||||
<text x="184.5" y="278.6" fill="#1a5fb4" style="font-weight:bold">M (zonă + divergență) → A (trigger) → P (plan)</text>
|
||||
<line x1="24" y1="402.8" x2="771" y2="402.8" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="396.8" fill="#1a5fb4">pivot daily 590.00 — zona (M)</text>
|
||||
<line x1="24" y1="431.6" x2="771" y2="431.6" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="757" y="425.6" fill="#c00" text-anchor="end">SL 589.40 = 0.10 sub piciorul 2 (risc 0.80)</text>
|
||||
<line x1="24" y1="354.8" x2="771" y2="354.8" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="348.8" fill="#188a3e">TP1 591.00 = 1:1</text>
|
||||
<polyline points="329.0,292.3 344.0,305.2 359.0,315.6 374.0,326.6 389.0,335.0 404.0,342.2 419.0,346.9 434.0,351.7 449.0,354.0 464.0,354.1 479.0,351.2 494.0,344.7 509.0,339.9 524.0,337.5" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="530" y="332" fill="#b06000">SMA-20</text>
|
||||
<line x1="44.0" y1="74.0" x2="44.0" y2="129.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="39.5" y="86.0" width="9" height="28.8" fill="#c00"/>
|
||||
<line x1="59.0" y1="102.8" x2="59.0" y2="167.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="54.5" y="114.8" width="9" height="38.4" fill="#c00"/>
|
||||
<line x1="74.0" y1="122.0" x2="74.0" y2="167.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="69.5" y="134.0" width="9" height="19.2" fill="#188a3e"/>
|
||||
<line x1="89.0" y1="122.0" x2="89.0" y2="186.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="84.5" y="134.0" width="9" height="38.4" fill="#c00"/>
|
||||
<line x1="104.0" y1="160.4" x2="104.0" y2="220.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="99.5" y="172.4" width="9" height="33.6" fill="#c00"/>
|
||||
<line x1="119.0" y1="194.0" x2="119.0" y2="254.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="114.5" y="206.0" width="9" height="33.6" fill="#c00"/>
|
||||
<line x1="134.0" y1="213.2" x2="134.0" y2="254.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="129.5" y="225.2" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="149.0" y1="213.2" x2="149.0" y2="278.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="144.5" y="225.2" width="9" height="38.4" fill="#c00"/>
|
||||
<line x1="164.0" y1="251.6" x2="164.0" y2="311.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="159.5" y="263.6" width="9" height="33.6" fill="#c00"/>
|
||||
<line x1="179.0" y1="285.2" x2="179.0" y2="340.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="174.5" y="297.2" width="9" height="28.8" fill="#c00"/>
|
||||
<line x1="194.0" y1="314.0" x2="194.0" y2="398.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="189.5" y="326.0" width="9" height="57.6" fill="#c00"/>
|
||||
<line x1="209.0" y1="347.6" x2="209.0" y2="398.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="204.5" y="359.6" width="9" height="24.0" fill="#188a3e"/>
|
||||
<line x1="224.0" y1="323.6" x2="224.0" y2="374.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="219.5" y="335.6" width="9" height="24.0" fill="#188a3e"/>
|
||||
<line x1="239.0" y1="323.6" x2="239.0" y2="364.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="234.5" y="335.6" width="9" height="14.4" fill="#c00"/>
|
||||
<line x1="254.0" y1="328.4" x2="254.0" y2="364.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="249.5" y="340.4" width="9" height="9.6" fill="#188a3e"/>
|
||||
<line x1="269.0" y1="328.4" x2="269.0" y2="374.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="264.5" y="340.4" width="9" height="19.2" fill="#c00"/>
|
||||
<line x1="284.0" y1="350.0" x2="284.0" y2="386.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="279.5" y="359.6" width="9" height="19.2" fill="#c00"/>
|
||||
<line x1="299.0" y1="371.6" x2="299.0" y2="405.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="294.5" y="378.8" width="9" height="21.6" fill="#c00"/>
|
||||
<line x1="314.0" y1="395.6" x2="314.0" y2="426.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="309.5" y="400.4" width="9" height="12.0" fill="#c00"/>
|
||||
<line x1="329.0" y1="388.4" x2="329.0" y2="414.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="324.5" y="393.2" width="9" height="19.2" fill="#188a3e"/>
|
||||
<line x1="344.0" y1="362.0" x2="344.0" y2="400.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="339.5" y="374.0" width="9" height="19.2" fill="#188a3e"/>
|
||||
<line x1="359.0" y1="357.2" x2="359.0" y2="381.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="354.5" y="359.6" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="374.0" y1="342.8" x2="374.0" y2="374.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="369.5" y="354.8" width="9" height="4.8" fill="#188a3e"/>
|
||||
<line x1="389.0" y1="328.4" x2="389.0" y2="369.2" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="384.5" y="340.4" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="404.0" y1="328.4" x2="404.0" y2="364.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="399.5" y="340.4" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="419.0" y1="321.2" x2="419.0" y2="364.4" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="414.5" y="333.2" width="9" height="16.8" fill="#188a3e"/>
|
||||
<line x1="434.0" y1="309.2" x2="434.0" y2="347.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="429.5" y="321.2" width="9" height="12.0" fill="#188a3e"/>
|
||||
<line x1="449.0" y1="297.2" x2="449.0" y2="335.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="444.5" y="309.2" width="9" height="12.0" fill="#188a3e"/>
|
||||
<line x1="464.0" y1="287.6" x2="464.0" y2="323.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="459.5" y="299.6" width="9" height="9.6" fill="#188a3e"/>
|
||||
<line x1="479.0" y1="256.4" x2="479.0" y2="314.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="474.5" y="268.4" width="9" height="31.2" fill="#188a3e"/>
|
||||
<line x1="494.0" y1="242.0" x2="494.0" y2="282.8" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="489.5" y="254.0" width="9" height="14.4" fill="#188a3e"/>
|
||||
<line x1="509.0" y1="242.0" x2="509.0" y2="278.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="504.5" y="254.0" width="9" height="9.6" fill="#c00"/>
|
||||
<line x1="524.0" y1="251.6" x2="524.0" y2="302.0" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
<rect x="519.5" y="263.6" width="9" height="24.0" fill="#c00"/>
|
||||
<line x1="24" y1="661.8" x2="771" y2="661.8" stroke="#888"/>
|
||||
<rect x="39.5" y="623.6" width="9" height="38.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="54.5" y="625.2" width="9" height="36.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="69.5" y="626.8" width="9" height="35.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="84.5" y="626.0" width="9" height="35.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="99.5" y="627.6" width="9" height="34.2" fill="#c00" opacity="0.55"/>
|
||||
<rect x="114.5" y="629.2" width="9" height="32.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="129.5" y="630.0" width="9" height="31.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="144.5" y="628.4" width="9" height="33.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="159.5" y="626.8" width="9" height="35.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="174.5" y="625.2" width="9" height="36.6" fill="#c00" opacity="0.55"/>
|
||||
<rect x="189.5" y="620.4" width="9" height="41.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="204.5" y="631.6" width="9" height="30.2" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="219.5" y="630.0" width="9" height="31.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="234.5" y="628.4" width="9" height="33.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="249.5" y="630.8" width="9" height="31.0" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="264.5" y="626.8" width="9" height="35.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="279.5" y="622.0" width="9" height="39.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="294.5" y="615.7" width="9" height="46.1" fill="#c00" opacity="0.55"/>
|
||||
<rect x="309.5" y="591.8" width="9" height="70.0" fill="#c00" opacity="0.55"/>
|
||||
<rect x="324.5" y="598.2" width="9" height="63.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="339.5" y="606.1" width="9" height="55.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="354.5" y="610.9" width="9" height="50.9" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="369.5" y="615.7" width="9" height="46.1" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="384.5" y="614.1" width="9" height="47.7" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="399.5" y="618.1" width="9" height="43.8" fill="#c00" opacity="0.55"/>
|
||||
<rect x="414.5" y="620.4" width="9" height="41.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="429.5" y="622.0" width="9" height="39.8" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="444.5" y="623.6" width="9" height="38.2" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="459.5" y="625.2" width="9" height="36.6" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="474.5" y="620.4" width="9" height="41.4" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="489.5" y="623.6" width="9" height="38.2" fill="#188a3e" opacity="0.55"/>
|
||||
<rect x="504.5" y="628.4" width="9" height="33.4" fill="#c00" opacity="0.55"/>
|
||||
<rect x="519.5" y="625.2" width="9" height="36.6" fill="#c00" opacity="0.55"/>
|
||||
<text x="24" y="585.8" fill="#555">volum: la piciorul 2, volum mai mare decât la piciorul 1 = divergență</text>
|
||||
<text x="194.0" y="418.0" fill="#777" text-anchor="middle" style="font-weight:bold">piciorul 1: low 590.10</text>
|
||||
<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="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"/>
|
||||
<polygon points="329.0,384.4 326.7,375.8 334.5,377.4" fill="#188a3e"/>
|
||||
<text x="369.0" y="171.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">intrare 590.20: intri abia aici,</text>
|
||||
<text x="369.0" y="185.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">la close peste high-ul candelei-trigger</text>
|
||||
<line x1="562.5" y1="281.6" x2="540.3" y2="286.0" stroke="#188a3e" stroke-width="1.8"/>
|
||||
<polygon points="532.5,287.6 539.6,282.1 541.1,290.0" fill="#188a3e"/>
|
||||
<text x="566.5" y="278.6" fill="#188a3e" text-anchor="start" style="font-weight:bold">ieșire pe trail 592.40 = 2.75R</text>
|
||||
<text x="566.5" y="292.6" fill="#188a3e" text-anchor="start" style="font-weight:bold">prima închidere sub linia de trail</text>
|
||||
<text x="24" y="704.0" fill="#555">Legendă: structura M → A → P e a cursului; nivelurile (590.00, 589.50) și planul</text>
|
||||
<text x="24" y="721.0" fill="#555">(intrare, SL, TP) sunt exemplul construit al autorului sumarului, nu citate din curs.</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 11 KiB |
@@ -30,9 +30,10 @@ GRAY, RED, GREEN, BLUE, ORANGE = "#777", "#c00", "#188a3e", "#1a5fb4", "#b06000"
|
||||
PIVOT = 622.00 # pivot daily, suportul
|
||||
LEG1 = 622.40 # swing low picior 1
|
||||
LEG2 = 621.40 # picior 2 (mai jos, rupe pivotul)
|
||||
ENTRY = 622.60 # close-ul Buy Hammer (construit)
|
||||
HAMMER_C = 622.60 # close-ul Buy Hammer — cifră reală, din sesiunea Q&A
|
||||
ENTRY = 623.00 # close-ul candelei care sparge high-ul hammer-ului (construit)
|
||||
SL = 621.30 # 0.10 sub low-ul piciorului 2 (construit)
|
||||
TP1 = 623.90 # entry + risc = 1:1 (construit)
|
||||
TP1 = 624.70 # entry + risc = 1:1 (construit)
|
||||
|
||||
# ── seria: 30 de close-uri, exact ca în specificație ───────────────────────
|
||||
CLOSES = [
|
||||
@@ -100,11 +101,13 @@ assert abs(corp - 0.30) < 1e-9, corp
|
||||
assert abs(coada - 0.90) < 1e-9, coada
|
||||
assert coada > corp, (coada, corp)
|
||||
|
||||
# 6. entry = close-ul trigger-ului (construit), SL 0.10 sub low-ul piciorului 2
|
||||
assert cds[18].c == ENTRY
|
||||
# 6. regula de intrare a capitolului: close-ul candelei care sparge high-ul
|
||||
# candelei-trigger (aici bara 19), nu close-ul hammer-ului însuși
|
||||
assert cds[18].c == HAMMER_C
|
||||
assert cds[19].c == ENTRY and cds[19].c > cds[18].h, (cds[19].c, cds[18].h)
|
||||
assert abs(cds[18].l - SL - 0.10) < 1e-9, (cds[18].l, SL)
|
||||
risk = ENTRY - SL
|
||||
assert abs(risk - 1.30) < 1e-9, risk
|
||||
risk = round(ENTRY - SL, 2)
|
||||
assert risk == 1.70, risk
|
||||
|
||||
# 7. TP1 simetric 1:1
|
||||
assert abs((ENTRY - SL) - (TP1 - ENTRY)) < 1e-9
|
||||
@@ -112,9 +115,9 @@ assert abs((ENTRY - SL) - (TP1 - ENTRY)) < 1e-9
|
||||
# 8. după trigger, primul close care atinge 623.90 e bara 21 (nu mai devreme).
|
||||
# Seria pornește la 627.00, deci „atinge" se citește de jos în sus, din zona
|
||||
# picioarelor: barele 10-20 rămân sub TP1, bara 21 îl atinge.
|
||||
assert all(c.c < TP1 for c in cds[10:21]), [c.c for c in cds[10:21]]
|
||||
assert max(c.h for c in cds[19:21]) < TP1, [c.h for c in cds[19:21]]
|
||||
assert cds[21].c == TP1, cds[21].c
|
||||
assert max(c.h for c in cds[19:25]) < TP1, [c.h for c in cds[19:25]]
|
||||
assert cds[25].h >= TP1 > cds[25].o, (cds[25].h, cds[25].o)
|
||||
TP_BAR = 25
|
||||
|
||||
# 9. divergență: lower low pe preț, higher low pe volum
|
||||
assert cds[18].l < cds[10].l, (cds[18].l, cds[10].l)
|
||||
@@ -136,9 +139,8 @@ def cx(i: int) -> float:
|
||||
levels = [
|
||||
Level(PIVOT, "pivot daily 622.00", ORANGE, label_at="left"),
|
||||
Level(SL, "SL 621.30 (construit)", RED, label_at="left"),
|
||||
Level(ENTRY, "intrare 622.60 (construit)", GREEN, label_at="left"),
|
||||
Level(TP1, "TP1 623.90 = 1:1 (construit)", GREEN, label_at="left"),
|
||||
Level(LEG1, "picior 1 = 622.40", BLUE, label_at="right"),
|
||||
Level(ENTRY, "intrare 623.00 (construit)", GREEN, label_at="right"),
|
||||
Level(TP1, "TP1 624.70 = 1:1 (construit)", GREEN, label_at="left"),
|
||||
]
|
||||
|
||||
# dy-uri calculate manual ca etichetele „below" să nu calce linia pivotului
|
||||
@@ -146,7 +148,8 @@ levels = [
|
||||
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=-20),
|
||||
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),
|
||||
]
|
||||
|
||||
ch = Chart(
|
||||
@@ -162,7 +165,7 @@ svg = ch.render()
|
||||
# ── legenda de onestitate (assert 11): ce e real, ce e construit ───────────
|
||||
legend = [
|
||||
"Legendă: nivelurile 622.40 / 622.00 / 621.40 / 622.60 și cele 8 candele dintre",
|
||||
"picioare sunt reale, din curs. Intrarea 622.60, SL-ul 621.30 și TP-ul 623.90",
|
||||
"picioare sunt reale, din curs. Intrarea 623.00, SL-ul 621.30 și TP-ul 624.70",
|
||||
"sunt construcția mea — materialul nu le dă.",
|
||||
]
|
||||
m = re.search(r'viewBox="0 0 (\d+) ([0-9.]+)"', svg)
|
||||
@@ -182,8 +185,8 @@ 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",
|
||||
"intrare 622.60 (construit)", "SL 621.30 (construit)",
|
||||
"TP1 623.90 = 1:1 (construit)"):
|
||||
"intrare 623.00 (construit)", "SL 621.30 (construit)",
|
||||
"TP1 624.70 = 1:1 (construit)"):
|
||||
assert eticheta in svg, f"lipsește eticheta: {eticheta!r}"
|
||||
assert "SPY — 5 min" in svg, "lipsește titlul"
|
||||
|
||||
@@ -218,5 +221,5 @@ OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT.name}: {len(cds)} candele | picior 1 {cds[10].l:.2f} (close "
|
||||
f"{cds[10].c:.2f}) | picior 2 {cds[18].l:.2f} (mai jos) | hammer închide "
|
||||
f"{cds[18].c:.2f} | intrare {ENTRY:.2f} | SL {SL:.2f} (risc {risk:.2f}) | "
|
||||
f"TP1 {TP1:.2f} = {(TP1 - ENTRY) / risk:.2f}:1 la bara 21 | "
|
||||
f"TP1 {TP1:.2f} = {(TP1 - ENTRY) / risk:.2f}:1 la bara {TP_BAR} | "
|
||||
f"vol[18]={VOLS[18]} > vol[10]={VOLS[10]}")
|
||||
|
||||
@@ -4,12 +4,10 @@
|
||||
<text x="30" y="367.4" fill="#b06000">pivot daily 622.00</text>
|
||||
<line x1="24" y1="416.8" x2="626" y2="416.8" stroke="#c00" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="410.8" fill="#c00">SL 621.30 (construit)</text>
|
||||
<line x1="24" y1="336.2" x2="626" y2="336.2" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="330.2" fill="#188a3e">intrare 622.60 (construit)</text>
|
||||
<line x1="24" y1="255.6" x2="626" y2="255.6" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="249.6" fill="#188a3e">TP1 623.90 = 1:1 (construit)</text>
|
||||
<line x1="24" y1="348.6" x2="626" y2="348.6" stroke="#1a5fb4" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="612" y="342.6" fill="#1a5fb4" text-anchor="end">picior 1 = 622.40</text>
|
||||
<line x1="24" y1="311.4" x2="626" y2="311.4" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="612" y="305.4" fill="#188a3e" text-anchor="end">intrare 623.00 (construit)</text>
|
||||
<line x1="24" y1="206.0" x2="626" y2="206.0" stroke="#188a3e" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="30" y="200.0" fill="#188a3e">TP1 624.70 = 1:1 (construit)</text>
|
||||
<polyline points="329.0,253.2 344.0,264.3 359.0,272.1 374.0,279.8 389.0,286.0 404.0,289.1 419.0,289.1 434.0,286.6 449.0,281.1 464.0,274.5 479.0,265.6" fill="none" stroke="#b06000" stroke-width="1.5" stroke-dasharray="4 3"/>
|
||||
<text x="485" y="260" fill="#b06000">SMA-20</text>
|
||||
<line x1="44.0" y1="57.2" x2="44.0" y2="69.6" stroke="#1a1a1a" stroke-width="1.2"/>
|
||||
@@ -106,8 +104,9 @@
|
||||
<text x="24" y="436.8" fill="#555">volum</text>
|
||||
<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="300.0" fill="#188a3e" text-anchor="middle" style="font-weight:bold">hammer închide 622.60, înapoi peste pivot</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="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 622.60, SL-ul 621.30 și TP-ul 623.90</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>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
@@ -113,12 +113,7 @@ add(W / 2, 468,
|
||||
add(W / 2, 486,
|
||||
"aliniere în cadranul 1, nu divergență (contradicția 2.4).",
|
||||
13, "normal", GRAY)
|
||||
add(W / 2, 512,
|
||||
"Sursa: 05_MODUL_4/02_strategia_5_mdsrt.md:6-8, 34-42, 59-61, 85-88;",
|
||||
13, "normal", GRAY)
|
||||
add(W / 2, 530,
|
||||
"08_ANALIZA_ZILNICA/11_selectia_simbolului.md:612-627.",
|
||||
13, "normal", GRAY)
|
||||
# trimiterile la material stau în fișa de surse a capitolului, nu pe desen
|
||||
|
||||
# --------------------------------------------------------------- emitere
|
||||
head = (f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" '
|
||||
@@ -127,6 +122,7 @@ head = (f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" '
|
||||
f'Volume sau Relative Strength; varianta Trinity are toți trei '
|
||||
f'indicatori în divergență simultan, pe aceeași zonă de preț">')
|
||||
parts.insert(0, f'<rect x="0" y="0" width="{W}" height="{H}" fill="#ffffff"/>')
|
||||
assert ".md:" not in "".join(parts), "trimiteri fișier:linie pe desen"
|
||||
parts.insert(0, head)
|
||||
|
||||
body = []
|
||||
|
||||
@@ -25,6 +25,4 @@
|
||||
<text x="350.0" y="448.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">La MDSRT, „Trinity” se folosește local cu sensul „toți trei în divergență”.</text>
|
||||
<text x="350.0" y="468.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">Lecția de selecție dă aceluiași cuvânt alt sens:</text>
|
||||
<text x="350.0" y="486.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">aliniere în cadranul 1, nu divergență (contradicția 2.4).</text>
|
||||
<text x="350.0" y="512.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">Sursa: 05_MODUL_4/02_strategia_5_mdsrt.md:6-8, 34-42, 59-61, 85-88;</text>
|
||||
<text x="350.0" y="530.0" font-size="13" font-weight="normal" fill="#777777" text-anchor="middle">08_ANALIZA_ZILNICA/11_selectia_simbolului.md:612-627.</text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.6 KiB |
@@ -389,7 +389,7 @@ formulă de tip „risc % din cont"** în material pentru ATMI.
|
||||
|
||||
Aceeași corecție, două deznodăminte. Diagrama le pune alături.
|
||||
|
||||
<!-- DIAGRAMA: aplus -->
|
||||
<!-- DIAGRAMA: corectie -->
|
||||
<svg viewBox="0 0 680 508" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:auto;font:12px sans-serif">
|
||||
<rect x="24" y="221.6" width="642" height="18.0" fill="#777" opacity="0.10"/>
|
||||
<text x="24" y="48" fill="#333" style="font-weight:bold">SPY — daily: aceeași corecție, 4.0 % (DA) vs. 3.9 % (NU)</text>
|
||||
@@ -509,7 +509,7 @@ Aceeași corecție, două deznodăminte. Diagrama le pune alături.
|
||||
<text x="24" y="183.8" fill="#188a3e" style="font-weight:bold">calea DA (candelele)</text>
|
||||
<text x="444.0" y="272.7" fill="#c00" style="font-weight:bold">calea NU (continuă în jos)</text>
|
||||
</svg>
|
||||
<!-- /DIAGRAMA: aplus -->
|
||||
<!-- /DIAGRAMA: corectie -->
|
||||
|
||||
| | **A+** | **Mediocru / NU** |
|
||||
|---|---|---|
|
||||
|
||||
94
summaries/17_STRATEGII/fise/05_atmi_surse.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Surse — 5. ATMI
|
||||
|
||||
Trimiterile la material pentru [`05_atmi.md`](../05_atmi.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:
|
||||
din curs vin regulile (corecție minim 4 %, zona quarterly, BIM înainte de
|
||||
candela verde, ținta +10 %, fără stop) și cifrele exemplului SPY 2005
|
||||
(117.43 → 129.17). Valorile pivoților — **PPQ 95.80, SQ 90.80** — sunt
|
||||
calculate de mine cu formula standard, pentru că materialul spune explicit că
|
||||
nu le dă.
|
||||
|
||||
**Prescurtări:**
|
||||
`main` = [`03_strategia_2_atmi.md`](../../04_MODUL_3/03_strategia_2_atmi.md)
|
||||
(lecția principală, integral) ·
|
||||
`bim` = [`10_buysell_momentum_trigger.md`](../../03_MODUL_2/10_buysell_momentum_trigger.md)
|
||||
(definiția indicatorului BIM) ·
|
||||
`tf` = [`03_timeframes_set_up.md`](../../03_MODUL_2/03_timeframes_set_up.md)
|
||||
(pivoți quarterly) ·
|
||||
`filtre` = [`01_filtre_scaner_bull_bear_reversal_pp.md`](../../04_MODUL_3/01_filtre_scaner_bull_bear_reversal_pp.md)
|
||||
(câmpul de scaner „PP or Support") ·
|
||||
`DECIZII` = [`triaj/DECIZII.md`](../../../triaj/DECIZII.md) (registrul de triaj
|
||||
al materialului) ·
|
||||
fișierele datate sunt sesiuni Q&A din `../../09_QA/`.
|
||||
|
||||
**Nivelul 1 — ce face strategia** — `main`: 4-5, 5-6, 26-29, 31-45, 39-45,
|
||||
164-169, 170-179, 505-508 · `27_2025-05-28`: 466-467.
|
||||
|
||||
**Pasul 1 — instrumentul, trimestrul și pivoții** — `main`: 6-8, 26-29,
|
||||
47-54 (formula nu e explicitată cifric), 143 (cursul nu dă cifrele PPQ/SQ),
|
||||
146-154 · `tf`: 73-79 · `filtre`: 29-34 · `14_2025-10-21`: 501-535
|
||||
(indici precalculați în TradeStation) · `27_2025-05-28`: 466-467
|
||||
(~2 tranzacții pe trimestru) · `09_2025-12-09`: 1177-1180 (pivoții clasici,
|
||||
confirmați „1 la 1").
|
||||
|
||||
**Pasul 2 — corecția de minim 4 %** — `main`: 153-154, 249-319 (cazul de
|
||||
3,93 % / 3,9 %), 502-504.
|
||||
|
||||
**Pasul 3 — zona SQ / PPQ** — `main`: 146-149 (intrarea sub SQ, rară, doar
|
||||
în crize reale), 146-154, 151-179 (harta MAPP) · `12_2025-11-18`: 294-296 ·
|
||||
`25_2025-07-08`: 840-843 · `13_2025-10-28`: 104 · `DECIZII`: 234, 324.
|
||||
|
||||
**Pasul 4 — BIM, apoi prima candelă verde** — `main`: 156-159 (verdele de
|
||||
dinainte de BIM nu e trigger), 156-162, 159-162 (ideal închide deasupra
|
||||
pivotului), 16-21 (ATMI trimite la BIM fără să-l definească), 497-501
|
||||
(„cuțitul prins în cădere") · `bim`: 3-12 (definiția: `jbv2`, două moving
|
||||
averages, săgeți cyan/crimson).
|
||||
|
||||
**Pasul 5 — fără stop, mărimea contribuției** — `main`: 10-11, 164-169
|
||||
(absența stopului e regulă), 166-169 (opțional -100 % pe poziție), 173-175
|
||||
(1 unitate SPY ≈ 600 $, ajustabil 0.2-0.5), 470-489 (levierul), 491-494
|
||||
(drawdown 20-30 % pe poziție, ~3 momente în 20 de ani), 509-512 ·
|
||||
`11_2025-11-25`: 489-500, 498-500 (dimensionezi ca și cum poți pierde 100 %) ·
|
||||
`04_2026-08-04`: 194-195 (lichiditatea ETF-urilor cu levier), 217-220
|
||||
(riscul e emoțional, nu matematic) · `13_2025-10-28`: 69-72 (CFD-urile, doar
|
||||
1-3 zile).
|
||||
|
||||
**Pasul 6 — ieșirea la +10 % și reinvestirea** — `main`: 170-171 (ieși cu
|
||||
toată poziția), 176-177 (cash până la următorul trigger), 178-179
|
||||
(reinvestești tot + contribuția nouă), 321-356 (dobânda compusă), 349-356
|
||||
(poziții în paralel, cu maturități diferite), 465-468 (backtest: ~16.300 $ în
|
||||
20 de ani → ~52-53.000 $) · `27_2025-05-28`: 456-467, 462-467 (aceleași cifre,
|
||||
altă formulare; estimarea de 16.000 → 100.000 după a doua reinvestire).
|
||||
|
||||
**A+ vs. mediocru** — `main`: 31-45 (mecanismul Buffett), 146-154, 156-162,
|
||||
159-162, 185-247 (exemplul „DA"), 249-319 (exemplul „NU"), 39-45, 505-508 ·
|
||||
`DECIZII`: 234, 324.
|
||||
|
||||
**Exemplul real (SPY 2005)** — `main`: 358-363 (intrare 117.43, TP1 +10 % =
|
||||
129.17, atins „aproximativ un an mai târziu"; ziua exactă e neclară în
|
||||
transcriere), 164-171, 465-468.
|
||||
|
||||
**Transfer pe prop** — `26_2025-06-11`: 214-222 (limita zilnică se calculează
|
||||
și pe pozițiile deschise; cazul participantului căruia i s-au închis
|
||||
tranzacții aflate în profit), 216-222, 225-227 (varianta „swing, 2 săptămâni",
|
||||
pentru calificare — vezi contradicția 1) · `main`: 470-494.
|
||||
|
||||
**Transfer pe BVB** — `09_2025-12-09`: 1177-1180 (pivoții clasici, „1 la 1") ·
|
||||
`28_2025-05-27`: 374-377 (pragurile US de lichiditate: volum > 500k, preț
|
||||
> 30-40 $) · `main`: 39-45, 505-508 (premisa cade pe acțiuni individuale),
|
||||
497-501 (fără BIM, trigger-ul devine cuțitul în cădere).
|
||||
|
||||
**Contradicții și puncte neclare** — (1) orizontul: `main`: 26-29, 358-363
|
||||
vs. `26_2025-06-11`: 225-227; (2) aritmetica contribuției: `main`: 173-175 vs.
|
||||
465-468; (3) formula PPQ/SQ, nedată cifric: `main`: 47-54, 143; (4) trailing /
|
||||
tranșe / ieșire anticipată, neacoperite: `main`: 170-179; (5) data exactă a
|
||||
atingerii TP1 (ASR): `main`: 358-363; (6) extinderea acronimului „ATMI" nu
|
||||
apare nicăieri în material.
|
||||
|
||||
**Legături** — `26_2025-06-11`: 915-917 (autorul recomandă combinarea ATMI cu
|
||||
MP² la suport/pivot important).
|
||||