hammer_mbt10: noua diagrame noi (textul urmeaza)
Buy hammer: forma (patru candele cu aceeasi inaltime, DA/limita/NU), trend (aceeasi bara dupa scadere e hammer, dupa urcare e hanging man — verificat prin assert), locatie, trigger in trei panouri, stop, iesire, si oglinda pe short obtinuta prin oglindire bara cu bara. MBT-10: confluente si close peste pivotul daily. Doua serii partajate (bh_ansamblu si mbt_confluente expun serie()), ca sa nu existe doua variante ale aceluiasi trade. Capitolul se imparte in doua proceduri separate, nu una amestecata: partea A buy hammer in 5 pasi cu oglinda pe short, partea B MBT-10 in 5 pasi, cu nivelul 1 comun. Textul 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
This commit is contained in:
86
gen/strategii/hammer_mbt10_bh_sell.py
Normal file
86
gen/strategii/hammer_mbt10_bh_sell.py
Normal file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Sell hammer — oglinda pe short a trade-ului din Partea A.
|
||||
|
||||
Seria e chiar trade-ul long, oglindit în jurul lui K = 162.30: fiecare preț
|
||||
p devine K - p, iar fitilele se inversează. Așa, hammer-ul 63.30 / 62.10
|
||||
devine 99.00 / 100.20, intrarea 63.35 devine 98.95, stopul 62.05 devine
|
||||
100.25 și ținta 65.95 devine 96.35 — riscul rămâne exact 1.30, deci cele
|
||||
două diagrame nu se pot contrazice la cifre. Oglindirea e verificată bară
|
||||
cu bară prin assert.
|
||||
|
||||
Rulare: python3 gen/strategii/hammer_mbt10_bh_sell.py
|
||||
"""
|
||||
import re
|
||||
import sys; sys.path.insert(0, "/workspace/atm-curs-dl")
|
||||
sys.path.insert(0, "/workspace/atm-curs-dl/gen/strategii")
|
||||
from pathlib import Path
|
||||
from hammer_mbt10_bh_ansamblu import serie
|
||||
from svg_candles import Arrow, Candle, Chart, Level
|
||||
|
||||
OUT = Path(__file__).with_suffix(".svg")
|
||||
GREEN, RED, BLUE, ORANGE, GREY = "#188a3e", "#c00", "#1a5fb4", "#b06000", "#555"
|
||||
|
||||
K = 162.30
|
||||
lung, ham_l, conf_l = serie()
|
||||
conf_l.note = ""
|
||||
cds = [Candle(K - c.o, K - c.l, K - c.h, K - c.c, vol=c.vol) for c in lung]
|
||||
ham, conf = cds[19], cds[20]
|
||||
INTRARE, SL, TP = round(K - 63.35, 2), round(K - 62.05, 2), round(K - 65.95, 2)
|
||||
R = round(SL - INTRARE, 2)
|
||||
|
||||
# --- verificări -------------------------------------------------------------
|
||||
for i, (a, b) in enumerate(zip(lung, cds)):
|
||||
assert abs(b.o - (K - a.o)) < 1e-9 and abs(b.c - (K - a.c)) < 1e-9, i
|
||||
assert abs(b.h - (K - a.l)) < 1e-9 and abs(b.l - (K - a.h)) < 1e-9, f"bara {i}: fitil neoglindit"
|
||||
assert b.l <= min(b.o, b.c) and b.h >= max(b.o, b.c), f"bara {i}: h/l nu cuprind o/c"
|
||||
for i in range(1, len(cds)):
|
||||
assert abs(cds[i].o - cds[i - 1].c) < 1e-9, f"open[{i}] != close[{i-1}]"
|
||||
assert (round(ham.l, 2), round(ham.h, 2)) == (99.00, 100.20), ham
|
||||
corp, sus = ham.o - ham.c, ham.h - ham.o
|
||||
assert sus >= 2 * corp, "bara 19 nu e sell hammer (fitilul de sus sub dublul corpului)"
|
||||
assert abs(ham.l - ham.c) < 1e-9, "corpul nu se sprijină pe low: fitil de jos inexistent"
|
||||
assert cds[18].c > cds[0].c + 8, "urcarea dinainte nu se vede"
|
||||
assert conf.c < ham.l and round(conf.c, 2) == INTRARE, "confirmarea nu închide sub low-ul lui"
|
||||
assert round(SL, 2) == round(ham.h + 0.05, 2), "SL nu e la 5 cenți peste high-ul sell hammer-ului"
|
||||
assert R == 1.30 and round(INTRARE - TP, 2) == 2 * R, (R, TP)
|
||||
assert TP < INTRARE < SL, "ordinea nivelurilor e greșită pe short"
|
||||
prim_tp = next(i for i in range(21, len(cds)) if cds[i].l <= TP)
|
||||
assert prim_tp == 28, prim_tp
|
||||
assert max(c.h for c in cds[21:prim_tp + 1]) < SL, "stopul ar fi fost atins înainte de țintă"
|
||||
|
||||
ch = Chart(
|
||||
candles=cds,
|
||||
levels=[Level(SL, "SL 100.25 — peste high-ul sell hammer-ului", RED),
|
||||
Level(INTRARE, "intrare short 98.95", GREEN, label_at="left"),
|
||||
Level(TP, "TP 96.35 = 2R", BLUE)],
|
||||
arrows=[
|
||||
Arrow(19, "sell hammer 99.00 / 100.20:\ncorp mic jos, fitil lung în sus",
|
||||
where="left", color=ORANGE, dx=-8, dy=-30),
|
||||
Arrow(20, "close 98.95, sub low-ul lui 99.00:\naici vinzi în lipsă",
|
||||
where="below", color=GREEN, dx=-120, dy=40),
|
||||
Arrow(prim_tp, "ținta 96.35: aceeași distanță\nca la long, dar în jos",
|
||||
price=TP, where="below", color=BLUE, dx=-60, dy=30),
|
||||
],
|
||||
scale=32.0, gap=15, body_w=9, left=44, width=720, top=56, vol_h=70, vol_label="volum",
|
||||
title="Sell hammer — oglinda pe short (daily, exemplu construit)",
|
||||
)
|
||||
svg = ch.render()
|
||||
m = re.search(r'viewBox="0 0 (\d+) (\d+)"', svg)
|
||||
W, H = int(m.group(1)), int(m.group(2))
|
||||
linii = [
|
||||
("Totul e întors: urcare înainte, corp mic jos și fitil lung în sus, intrarea la o "
|
||||
"închidere SUB", "#333"),
|
||||
("low-ul candelei, stopul PESTE high-ul ei, ținta la aceeași distanță în jos.", "#333"),
|
||||
("Completare proprie: cursul numește Sell Hammer ca simetric al lui Buy Hammer, dar "
|
||||
"nu-i scrie", GREY),
|
||||
("regulile separat. Seria e trade-ul long oglindit, deci riscul e tot 1.30.", GREY),
|
||||
]
|
||||
add = 16 * len(linii) + 10
|
||||
svg = svg.replace(f'viewBox="0 0 {W} {H}"', f'viewBox="0 0 {W} {H + add}"')
|
||||
svg = svg.replace("</svg>", "".join(
|
||||
f'<text x="24" y="{H + 10 + 16 * i}" fill="{c}">{t}</text>'
|
||||
for i, (t, c) in enumerate(linii)) + "</svg>")
|
||||
assert "\n\n" not in svg, "linie goală în SVG"
|
||||
OUT.write_text(svg, encoding="utf-8")
|
||||
print(f"scris {OUT.name} ({W}x{H + add}); intrare {INTRARE} SL {SL} TP {TP} R {R}, "
|
||||
f"țintă atinsă la bara {prim_tp}")
|
||||
Reference in New Issue
Block a user