Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -35,6 +35,7 @@ VP_MODES = ["Kapalı", "Onay filtresi (POC / Value Area)", "KNN özelliği + ona
|
|
| 35 |
GANN_MODES = ["Kapalı", "Onay filtresi (Gann Box %50)"]
|
| 36 |
SMC_MODES = ["Kapalı", "Onay filtresi (SMC yapı yönü)", "Sadece SMC (yapı kırılımı girişi)"]
|
| 37 |
SMC_SRC = ["Swing yapı", "Internal yapı"]
|
|
|
|
| 38 |
GANN_LEVELS = [0.0, 0.236, 0.382, 0.5, 0.618, 0.786, 1.0]
|
| 39 |
GANN_FAN = [(8, "8x1"), (4, "4x1"), (3, "3x1"), (2, "2x1"), (1, "1x1"),
|
| 40 |
(1/2, "1x2"), (1/3, "1x3"), (1/4, "1x4"), (1/8, "1x8")]
|
|
@@ -155,6 +156,18 @@ def ut_bot(df, key=1.0, period=10):
|
|
| 155 |
|
| 156 |
|
| 157 |
# ------------------------------------------- Smart Money Concepts (LuxAlgo) Python portu
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
def _smc_pivots(h, l, size):
|
| 159 |
"""Pine leg(size) mantığı: pivotlar `size` mum sonra doğrulanır (ileriye bakma yok).
|
| 160 |
Dönüş: {doğrulama_mumu: [("H"|"L", seviye, pivot_mumu)]}"""
|
|
@@ -176,14 +189,20 @@ def _smc_pivots(h, l, size):
|
|
| 176 |
return out
|
| 177 |
|
| 178 |
|
| 179 |
-
def smc_analyze(df, swing_len=50, int_len=5, eq_len=3, eq_thr=0.1, ob_keep=5
|
|
|
|
| 180 |
"""LuxAlgo 'Smart Money Concepts' göstergesinin Python portu: swing/internal yapı (BOS, CHoCH),
|
| 181 |
order block, EQH/EQL, Fair Value Gap, premium/discount ve strong/weak high-low.
|
| 182 |
Pine kaynağından birebir değil; her mum yalnızca kendisine kadarki veriyi kullanır."""
|
| 183 |
n = len(df)
|
| 184 |
o, h, l, c = (df[k].to_numpy(float) for k in ("Open", "High", "Low", "Close"))
|
| 185 |
atr = calc_atr(df, 200).to_numpy(float)
|
| 186 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
ph, pl = np.where(hv, l, h), np.where(hv, h, l)
|
| 188 |
swing_len = int(min(max(swing_len, 3), max(n//4, 3)))
|
| 189 |
int_len = int(min(max(int_len, 2), swing_len))
|
|
@@ -198,6 +217,13 @@ def smc_analyze(df, swing_len=50, int_len=5, eq_len=3, eq_thr=0.1, ob_keep=5):
|
|
| 198 |
st = it = 0
|
| 199 |
top, bot = h[0], l[0]
|
| 200 |
events, obs, points, eqs, fvgs = [], [], [], [], []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
prev_hi = prev_lo = np.nan
|
| 202 |
eq_h = eq_l = None
|
| 203 |
dsum = 0.0
|
|
@@ -228,15 +254,16 @@ def smc_analyze(df, swing_len=50, int_len=5, eq_len=3, eq_thr=0.1, ob_keep=5):
|
|
| 228 |
eqs.append(("EQL", eq_l[1], eq_l[0], bi, lvl, i))
|
| 229 |
eq_l = (lvl, bi)
|
| 230 |
# --- order block mitigasyonu (High/Low)
|
| 231 |
-
for ob in
|
| 232 |
if ob["on"] and ((ob["bull"] and l[i] < ob["lo"]) or (not ob["bull"] and h[i] > ob["hi"])):
|
| 233 |
ob["on"] = False
|
|
|
|
| 234 |
# --- yapı kırılımları
|
| 235 |
if i > 0:
|
| 236 |
for internal, hp, lp in ((True, ih, il), (False, sh, sl_)):
|
| 237 |
tr = it if internal else st
|
| 238 |
-
extra_u = (not internal) or (ih["lvl"] != sh["lvl"])
|
| 239 |
-
extra_d = (not internal) or (il["lvl"] != sl_["lvl"])
|
| 240 |
if (np.isfinite(hp["lvl"]) and not hp["crossed"] and c[i] > hp["lvl"] >= c[i-1]
|
| 241 |
and extra_u):
|
| 242 |
events.append({"i": i, "kind": "CHoCH" if tr == -1 else "BOS", "bull": True,
|
|
@@ -245,7 +272,7 @@ def smc_analyze(df, swing_len=50, int_len=5, eq_len=3, eq_thr=0.1, ob_keep=5):
|
|
| 245 |
seg = pl[hp["idx"]:i]
|
| 246 |
if len(seg):
|
| 247 |
j = hp["idx"] + int(np.argmin(seg))
|
| 248 |
-
|
| 249 |
"lo": float(pl[j]), "idx": j, "on": True})
|
| 250 |
if internal:
|
| 251 |
it = 1
|
|
@@ -259,7 +286,7 @@ def smc_analyze(df, swing_len=50, int_len=5, eq_len=3, eq_thr=0.1, ob_keep=5):
|
|
| 259 |
seg = ph[lp["idx"]:i]
|
| 260 |
if len(seg):
|
| 261 |
j = lp["idx"] + int(np.argmax(seg))
|
| 262 |
-
|
| 263 |
"lo": float(pl[j]), "idx": j, "on": True})
|
| 264 |
if internal:
|
| 265 |
it = -1
|
|
@@ -269,6 +296,8 @@ def smc_analyze(df, swing_len=50, int_len=5, eq_len=3, eq_thr=0.1, ob_keep=5):
|
|
| 269 |
top, bot = max(top, h[i]), min(bot, l[i])
|
| 270 |
top_a[i], bot_a[i] = top, bot
|
| 271 |
swh_a[i], swl_a[i] = sh["lvl"], sl_["lvl"]
|
|
|
|
|
|
|
| 272 |
# --- Fair Value Gap
|
| 273 |
if i >= 2:
|
| 274 |
delta = (c[i-1]-o[i-1])/(o[i-1]*100) if o[i-1] else 0.0
|
|
@@ -283,7 +312,7 @@ def smc_analyze(df, swing_len=50, int_len=5, eq_len=3, eq_thr=0.1, ob_keep=5):
|
|
| 283 |
fvgs.append({"bull": False, "top": float(l[i-2]), "bot": float(h[i]), "idx": i-1, "on": True})
|
| 284 |
live = lambda internal, bull: [o_ for o_ in obs if o_["on"] and o_["internal"] == internal
|
| 285 |
and o_["bull"] == bull][-int(ob_keep):]
|
| 286 |
-
return {"swing_trend": s_tr, "internal_trend": i_tr, "top": top_a, "bot": bot_a, "sw_hi": swh_a, "sw_lo": swl_a,
|
| 287 |
"events": events, "points": points, "eq": eqs,
|
| 288 |
"obs": live(True, True)+live(True, False)+live(False, True)+live(False, False),
|
| 289 |
"fvg": [g for g in fvgs if g["on"]][-8:], "strong_high": st == -1, "strong_low": st == 1}
|
|
@@ -334,6 +363,16 @@ def add_smc_traces(fig, S, index, last_n=150, kw=None):
|
|
| 334 |
textposition="top center" if kd == "H" else "bottom center",
|
| 335 |
textfont=dict(size=9, color="#475569"), showlegend=False,
|
| 336 |
hoverinfo="skip"), **kw)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 337 |
top, bot = float(S["top"][-1]), float(S["bot"][-1])
|
| 338 |
if np.isfinite(top) and np.isfinite(bot) and top > bot:
|
| 339 |
x0 = index[max(0, n-35)]
|
|
@@ -983,7 +1022,8 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
|
|
| 983 |
ldc_use_vol, ldc_use_regime, ldc_use_adx, ldc_kernel, ldc_exact,
|
| 984 |
combo_mode, combo_votes, ind_tpsl, tpsl_smin, tpsl_smax, tpsl_minrr,
|
| 985 |
gann_mode, gann_lb, gann_fan_on, gann_ext_on, gann_rev,
|
| 986 |
-
smc_mode, smc_src, smc_swing_len, smc_int_len, smc_zone, smc_draw
|
|
|
|
| 987 |
try:
|
| 988 |
ticker = str(ticker).strip().upper()
|
| 989 |
h = int(horizon)
|
|
@@ -1014,7 +1054,11 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
|
|
| 1014 |
GB = gann_box(df, int(gann_lb), bool(gann_rev))
|
| 1015 |
smc_on = smc_mode != SMC_MODES[0]
|
| 1016 |
smc_only = smc_mode == SMC_MODES[2]
|
| 1017 |
-
SM = smc_analyze(df, int(smc_swing_len), int(smc_int_len)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1018 |
smc_arr = np.zeros(len(df), dtype=int)
|
| 1019 |
if SM is not None:
|
| 1020 |
smc_arr = (SM["swing_trend"] if smc_src == SMC_SRC[0] else SM["internal_trend"]).copy()
|
|
@@ -1107,10 +1151,16 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
|
|
| 1107 |
cap_of = lambda d: np.where(d >= 1.0*a_, d, np.inf)
|
| 1108 |
lv_l = [st_line, ut_stop, vpl] + ([SM["sw_lo"]] if (smc_only and SM is not None) else [])
|
| 1109 |
lv_s = [st_line, ut_stop, vph] + ([SM["sw_hi"]] if (smc_only and SM is not None) else [])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1110 |
A["ind_sd"] = {1: sd_of(nearest(lv_l, 1)),
|
| 1111 |
-1: sd_of(nearest(lv_s, -1))}
|
| 1112 |
-
A["ind_cap"] = {1: cap_of(nearest(
|
| 1113 |
-
-1: cap_of(nearest(
|
| 1114 |
|
| 1115 |
# --- K seçimi, kalibrasyon, güncel olasılık
|
| 1116 |
best_k, k_scores = tune_k(dev_X, dev_y, h)
|
|
@@ -1262,6 +1312,10 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
|
|
| 1262 |
cands = {"Supertrend": float(st_line[-1]), "UT trailing stop": float(ut_stop[-1]),
|
| 1263 |
"VP " + ("VAL" if side == 1 else "VAH"):
|
| 1264 |
float((vp.val if side == 1 else vp.vah).iloc[-1])}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1265 |
if smc_only and SM is not None:
|
| 1266 |
cands["SMC swing " + ("low" if side == 1 else "high")] = float(SM["sw_lo" if side == 1 else "sw_hi"][-1])
|
| 1267 |
valid = {k_: side*(cl_-v_) for k_, v_ in cands.items() if np.isfinite(v_) and side*(cl_-v_) > 0}
|
|
@@ -1394,9 +1448,15 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
|
|
| 1394 |
("Strong/Weak High · Low", f"{'Strong' if SM['strong_high'] else 'Weak'} {fmt_p(tp_)} · "
|
| 1395 |
f"{'Strong' if SM['strong_low'] else 'Weak'} {fmt_p(bt_)}"),
|
| 1396 |
("Aktif swing OB (bull)", ob_txt(True)), ("Aktif swing OB (bear)", ob_txt(False)),
|
|
|
|
|
|
|
|
|
|
| 1397 |
("Açık FVG sayısı", len(SM["fvg"])), ("SMC yön onayı", dname[smc_now])])
|
| 1398 |
smc_note = (f"Swing {int(smc_swing_len)} · internal {int(smc_int_len)} mum"
|
| 1399 |
+ (" · premium/discount kapısı açık" if smc_zone else "")
|
|
|
|
|
|
|
|
|
|
| 1400 |
+ (" · Mod Kapalı: yalnızca bilgi/grafik." if not smc_on else "") + ".")
|
| 1401 |
else:
|
| 1402 |
smc_md, smc_note = "_Mod kapalı._", ""
|
|
@@ -1439,7 +1499,7 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
|
|
| 1439 |
tpsl_note = (f"SL: en yakın invalidasyon seviyesi — **{sl_name}** (+0,1 ATR tampon, "
|
| 1440 |
f"{float(tpsl_smin):g}–{float(tpsl_smax):g} ATR aralığına sıkıştırılır). "
|
| 1441 |
f"TP: {rr:.2f}R katı"
|
| 1442 |
-
+ (", önündeki
|
| 1443 |
+ ". Optimize edilen tek parametre R katıdır.\n\n")
|
| 1444 |
else:
|
| 1445 |
tp_title, tpsl_note = "optimize", ""
|
|
@@ -1559,7 +1619,7 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
|
|
| 1559 |
"seri korelasyonunu ve rejim değişimini tam modellemez. Pozisyon hesabı spot miktar "
|
| 1560 |
"varsayar; CFD lot sözleşmesi, spread, funding, swap, komisyon, minimum lot, marjin ve "
|
| 1561 |
"broker fiyatı farklı olabilir. Gap ve kayma kaybı planlanan riskin üstüne çıkarabilir. "
|
| 1562 |
-
"Supertrend ve UT Bot, TradingView formüllerinin Python portudur; ATR başlangıcı ve veri kaynağı yüzünden TV değerlerinden küçük sapmalar olabilir. Birleşik sinyal; ST+UT, Lorentzian ve Volume Profile oylarının birleşimidir. İndikatör bazlı TP/SL, en yakın ST/UT/VP seviyesini invalidasyon sayar ve ATR aralığına sıkıştırır. Lorentzian Classification, jdehorty'nin TradingView göstergesinin Python portudur (ANN komşu seçimi, filtreler ve kernel regresyon); Pine kaynağıyla birebir aynı sonuç vermeyebilir ve yalnızca günlük mumda çalışır. Volume Profile, günlük OHLCV'den (her mumun hacmi high–low aralığına eşit dağıtılarak) yaklaşık hesaplanır; TradingView VPVR'nin alt-zaman dilimi verisiyle birebir aynı olmaz. Gann Box, Zeiierman göstergesinin açıklamasına göre yazılmış bir Python portudur (Pine kaynağı birebir alınmadı); kutu son N mumun en yüksek/en düşük noktasından kurulur, Gann Fan 1x1 köşegeni ve katlarıyla çizilir, Gann Curves/Angles eklenmedi. Onay filtresi, kapanışın kutu %50 çizgisine göre konumuna bakar ve geçmişe bakan (kayan) pencere kullanır. SMC, LuxAlgo göstergesinin açıklamasına göre yazılmış bir Python portudur (Pine kaynağı birebir değil): swing/internal yapı, BOS/CHoCH, order block (high/low mitigasyonu), EQH/EQL, FVG ve premium/discount hesaplanır;
|
| 1563 |
)
|
| 1564 |
return (report, prob_figure(p_down, p_flat, p_up), price_fig, eq_fig, pf_fig, mc_fig,
|
| 1565 |
top_df, csv_path, disclaimer)
|
|
@@ -1648,6 +1708,10 @@ with gr.Blocks(title=APP_TITLE, theme=gr.themes.Soft()) as demo:
|
|
| 1648 |
smc_int_len = gr.Slider(3, 15, value=5, step=1, label="SMC internal yapı uzunluğu")
|
| 1649 |
smc_zone = gr.Checkbox(value=False, label="Premium/Discount kapısı (long=discount, short=premium)")
|
| 1650 |
smc_draw = gr.Checkbox(value=True, label="SMC katmanlarını grafikte göster")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1651 |
with gr.Row():
|
| 1652 |
skip_overlap = gr.Checkbox(value=False, label="Açık pozisyon varken yeni sinyali atla (tek pozisyon)")
|
| 1653 |
whole_units = gr.Checkbox(value=False, label="Miktarı tam sayıya yuvarla (hisse)")
|
|
@@ -1681,7 +1745,8 @@ with gr.Blocks(title=APP_TITLE, theme=gr.themes.Soft()) as demo:
|
|
| 1681 |
ldc_use_vol, ldc_use_regime, ldc_use_adx, ldc_kernel, ldc_exact,
|
| 1682 |
combo_mode, combo_votes, ind_tpsl, tpsl_smin, tpsl_smax, tpsl_minrr,
|
| 1683 |
gann_mode, gann_lb, gann_fan_on, gann_ext_on, gann_rev,
|
| 1684 |
-
smc_mode, smc_src, smc_swing_len, smc_int_len, smc_zone, smc_draw
|
|
|
|
| 1685 |
outputs=[output, prob_plot, chart, equity_plot, pf_plot, mc_plot, optimization,
|
| 1686 |
csv_file, disclaimer],
|
| 1687 |
)
|
|
|
|
| 35 |
GANN_MODES = ["Kapalı", "Onay filtresi (Gann Box %50)"]
|
| 36 |
SMC_MODES = ["Kapalı", "Onay filtresi (SMC yapı yönü)", "Sadece SMC (yapı kırılımı girişi)"]
|
| 37 |
SMC_SRC = ["Swing yapı", "Internal yapı"]
|
| 38 |
+
SMC_OBF = ["Atr", "Cumulative Mean Range"]
|
| 39 |
GANN_LEVELS = [0.0, 0.236, 0.382, 0.5, 0.618, 0.786, 1.0]
|
| 40 |
GANN_FAN = [(8, "8x1"), (4, "4x1"), (3, "3x1"), (2, "2x1"), (1, "1x1"),
|
| 41 |
(1/2, "1x2"), (1/3, "1x3"), (1/4, "1x4"), (1/8, "1x8")]
|
|
|
|
| 156 |
|
| 157 |
|
| 158 |
# ------------------------------------------- Smart Money Concepts (LuxAlgo) Python portu
|
| 159 |
+
def mtf_prev_levels(df):
|
| 160 |
+
"""Önceki gün / hafta / ay high-low (tamamlanmış dönem; ileriye bakma yok), mum bazında dizi."""
|
| 161 |
+
out = {}
|
| 162 |
+
for key, rule in (("d", "D"), ("w", "W"), ("m", "M")):
|
| 163 |
+
per = df.index.to_period(rule)
|
| 164 |
+
hi = df.High.groupby(per).max().shift(1)
|
| 165 |
+
lo = df.Low.groupby(per).min().shift(1)
|
| 166 |
+
out["p"+key+"h"] = hi.reindex(per).to_numpy(float)
|
| 167 |
+
out["p"+key+"l"] = lo.reindex(per).to_numpy(float)
|
| 168 |
+
return out
|
| 169 |
+
|
| 170 |
+
|
| 171 |
def _smc_pivots(h, l, size):
|
| 172 |
"""Pine leg(size) mantığı: pivotlar `size` mum sonra doğrulanır (ileriye bakma yok).
|
| 173 |
Dönüş: {doğrulama_mumu: [("H"|"L", seviye, pivot_mumu)]}"""
|
|
|
|
| 189 |
return out
|
| 190 |
|
| 191 |
|
| 192 |
+
def smc_analyze(df, swing_len=50, int_len=5, eq_len=3, eq_thr=0.1, ob_keep=5,
|
| 193 |
+
confluence=False, ob_filter="Atr"):
|
| 194 |
"""LuxAlgo 'Smart Money Concepts' göstergesinin Python portu: swing/internal yapı (BOS, CHoCH),
|
| 195 |
order block, EQH/EQL, Fair Value Gap, premium/discount ve strong/weak high-low.
|
| 196 |
Pine kaynağından birebir değil; her mum yalnızca kendisine kadarki veriyi kullanır."""
|
| 197 |
n = len(df)
|
| 198 |
o, h, l, c = (df[k].to_numpy(float) for k in ("Open", "High", "Low", "Close"))
|
| 199 |
atr = calc_atr(df, 200).to_numpy(float)
|
| 200 |
+
pc_ = np.r_[c[0], c[:-1]]
|
| 201 |
+
tr_ = np.maximum(h-l, np.maximum(np.abs(h-pc_), np.abs(l-pc_)))
|
| 202 |
+
vm = (np.cumsum(tr_)/np.arange(1, n+1)) if ob_filter == "Cumulative Mean Range" else atr
|
| 203 |
+
hv = (h-l) >= 2*vm # yüksek volatilite mumları: OB için high/low yer değiştirir
|
| 204 |
+
bull_bar = (h-np.maximum(c, o)) > np.minimum(c, o-l) if confluence else np.ones(n, bool)
|
| 205 |
+
bear_bar = (h-np.minimum(c, o)) > np.maximum(c, o-l) if confluence else np.ones(n, bool)
|
| 206 |
ph, pl = np.where(hv, l, h), np.where(hv, h, l)
|
| 207 |
swing_len = int(min(max(swing_len, 3), max(n//4, 3)))
|
| 208 |
int_len = int(min(max(int_len, 2), swing_len))
|
|
|
|
| 217 |
st = it = 0
|
| 218 |
top, bot = h[0], l[0]
|
| 219 |
events, obs, points, eqs, fvgs = [], [], [], [], []
|
| 220 |
+
act = []
|
| 221 |
+
ob_sup_a, ob_res_a = np.full(n, np.nan), np.full(n, np.nan)
|
| 222 |
+
def _new_ob(d):
|
| 223 |
+
obs.append(d)
|
| 224 |
+
act.append(d)
|
| 225 |
+
if len(act) > 60:
|
| 226 |
+
act.pop(0)
|
| 227 |
prev_hi = prev_lo = np.nan
|
| 228 |
eq_h = eq_l = None
|
| 229 |
dsum = 0.0
|
|
|
|
| 254 |
eqs.append(("EQL", eq_l[1], eq_l[0], bi, lvl, i))
|
| 255 |
eq_l = (lvl, bi)
|
| 256 |
# --- order block mitigasyonu (High/Low)
|
| 257 |
+
for ob in act:
|
| 258 |
if ob["on"] and ((ob["bull"] and l[i] < ob["lo"]) or (not ob["bull"] and h[i] > ob["hi"])):
|
| 259 |
ob["on"] = False
|
| 260 |
+
act[:] = [o_ for o_ in act if o_["on"]]
|
| 261 |
# --- yapı kırılımları
|
| 262 |
if i > 0:
|
| 263 |
for internal, hp, lp in ((True, ih, il), (False, sh, sl_)):
|
| 264 |
tr = it if internal else st
|
| 265 |
+
extra_u = (not internal) or (ih["lvl"] != sh["lvl"] and bool(bull_bar[i]))
|
| 266 |
+
extra_d = (not internal) or (il["lvl"] != sl_["lvl"] and bool(bear_bar[i]))
|
| 267 |
if (np.isfinite(hp["lvl"]) and not hp["crossed"] and c[i] > hp["lvl"] >= c[i-1]
|
| 268 |
and extra_u):
|
| 269 |
events.append({"i": i, "kind": "CHoCH" if tr == -1 else "BOS", "bull": True,
|
|
|
|
| 272 |
seg = pl[hp["idx"]:i]
|
| 273 |
if len(seg):
|
| 274 |
j = hp["idx"] + int(np.argmin(seg))
|
| 275 |
+
_new_ob({"bull": True, "internal": internal, "hi": float(ph[j]),
|
| 276 |
"lo": float(pl[j]), "idx": j, "on": True})
|
| 277 |
if internal:
|
| 278 |
it = 1
|
|
|
|
| 286 |
seg = ph[lp["idx"]:i]
|
| 287 |
if len(seg):
|
| 288 |
j = lp["idx"] + int(np.argmax(seg))
|
| 289 |
+
_new_ob({"bull": False, "internal": internal, "hi": float(ph[j]),
|
| 290 |
"lo": float(pl[j]), "idx": j, "on": True})
|
| 291 |
if internal:
|
| 292 |
it = -1
|
|
|
|
| 296 |
top, bot = max(top, h[i]), min(bot, l[i])
|
| 297 |
top_a[i], bot_a[i] = top, bot
|
| 298 |
swh_a[i], swl_a[i] = sh["lvl"], sl_["lvl"]
|
| 299 |
+
ob_sup_a[i] = max((o_["lo"] for o_ in act if o_["bull"] and o_["lo"] < c[i]), default=np.nan)
|
| 300 |
+
ob_res_a[i] = min((o_["hi"] for o_ in act if (not o_["bull"]) and o_["hi"] > c[i]), default=np.nan)
|
| 301 |
# --- Fair Value Gap
|
| 302 |
if i >= 2:
|
| 303 |
delta = (c[i-1]-o[i-1])/(o[i-1]*100) if o[i-1] else 0.0
|
|
|
|
| 312 |
fvgs.append({"bull": False, "top": float(l[i-2]), "bot": float(h[i]), "idx": i-1, "on": True})
|
| 313 |
live = lambda internal, bull: [o_ for o_ in obs if o_["on"] and o_["internal"] == internal
|
| 314 |
and o_["bull"] == bull][-int(ob_keep):]
|
| 315 |
+
return {"swing_trend": s_tr, "internal_trend": i_tr, "top": top_a, "bot": bot_a, "sw_hi": swh_a, "sw_lo": swl_a, "ob_sup": ob_sup_a, "ob_res": ob_res_a, **mtf_prev_levels(df),
|
| 316 |
"events": events, "points": points, "eq": eqs,
|
| 317 |
"obs": live(True, True)+live(True, False)+live(False, True)+live(False, False),
|
| 318 |
"fvg": [g for g in fvgs if g["on"]][-8:], "strong_high": st == -1, "strong_low": st == 1}
|
|
|
|
| 363 |
textposition="top center" if kd == "H" else "bottom center",
|
| 364 |
textfont=dict(size=9, color="#475569"), showlegend=False,
|
| 365 |
hoverinfo="skip"), **kw)
|
| 366 |
+
if S.get("show_mtf"):
|
| 367 |
+
for k_, nm_ in (("pdh", "PDH"), ("pdl", "PDL"), ("pwh", "PWH"), ("pwl", "PWL"),
|
| 368 |
+
("pmh", "PMH"), ("pml", "PML")):
|
| 369 |
+
y_ = S[k_][-1]
|
| 370 |
+
if np.isfinite(y_):
|
| 371 |
+
fig.add_trace(go.Scatter(x=[index[w0], index[-1]], y=[y_, y_], mode="lines+text",
|
| 372 |
+
text=["", nm_], textposition="top left",
|
| 373 |
+
line=dict(width=1, dash="dashdot", color="#0ea5e9"),
|
| 374 |
+
textfont=dict(size=9, color="#0ea5e9"), showlegend=False,
|
| 375 |
+
hoverinfo="skip"), **kw)
|
| 376 |
top, bot = float(S["top"][-1]), float(S["bot"][-1])
|
| 377 |
if np.isfinite(top) and np.isfinite(bot) and top > bot:
|
| 378 |
x0 = index[max(0, n-35)]
|
|
|
|
| 1022 |
ldc_use_vol, ldc_use_regime, ldc_use_adx, ldc_kernel, ldc_exact,
|
| 1023 |
combo_mode, combo_votes, ind_tpsl, tpsl_smin, tpsl_smax, tpsl_minrr,
|
| 1024 |
gann_mode, gann_lb, gann_fan_on, gann_ext_on, gann_rev,
|
| 1025 |
+
smc_mode, smc_src, smc_swing_len, smc_int_len, smc_zone, smc_draw,
|
| 1026 |
+
smc_conf, smc_obf, smc_lvl):
|
| 1027 |
try:
|
| 1028 |
ticker = str(ticker).strip().upper()
|
| 1029 |
h = int(horizon)
|
|
|
|
| 1054 |
GB = gann_box(df, int(gann_lb), bool(gann_rev))
|
| 1055 |
smc_on = smc_mode != SMC_MODES[0]
|
| 1056 |
smc_only = smc_mode == SMC_MODES[2]
|
| 1057 |
+
SM = smc_analyze(df, int(smc_swing_len), int(smc_int_len), confluence=bool(smc_conf),
|
| 1058 |
+
ob_filter=smc_obf) if (smc_on or smc_draw) else None
|
| 1059 |
+
smc_lvl_on = bool(smc_lvl) and SM is not None and smc_on
|
| 1060 |
+
if SM is not None:
|
| 1061 |
+
SM["show_mtf"] = bool(smc_lvl)
|
| 1062 |
smc_arr = np.zeros(len(df), dtype=int)
|
| 1063 |
if SM is not None:
|
| 1064 |
smc_arr = (SM["swing_trend"] if smc_src == SMC_SRC[0] else SM["internal_trend"]).copy()
|
|
|
|
| 1151 |
cap_of = lambda d: np.where(d >= 1.0*a_, d, np.inf)
|
| 1152 |
lv_l = [st_line, ut_stop, vpl] + ([SM["sw_lo"]] if (smc_only and SM is not None) else [])
|
| 1153 |
lv_s = [st_line, ut_stop, vph] + ([SM["sw_hi"]] if (smc_only and SM is not None) else [])
|
| 1154 |
+
cap_l, cap_s = [vpo, vph], [vpo, vpl]
|
| 1155 |
+
if smc_lvl_on: # Order Block + önceki D/W/M high-low: SL referansı ve TP sınırı
|
| 1156 |
+
lv_l += [SM["ob_sup"], SM["pdl"], SM["pwl"], SM["pml"]]
|
| 1157 |
+
lv_s += [SM["ob_res"], SM["pdh"], SM["pwh"], SM["pmh"]]
|
| 1158 |
+
cap_l += [SM["ob_res"], SM["pdh"], SM["pwh"], SM["pmh"]]
|
| 1159 |
+
cap_s += [SM["ob_sup"], SM["pdl"], SM["pwl"], SM["pml"]]
|
| 1160 |
A["ind_sd"] = {1: sd_of(nearest(lv_l, 1)),
|
| 1161 |
-1: sd_of(nearest(lv_s, -1))}
|
| 1162 |
+
A["ind_cap"] = {1: cap_of(nearest(cap_l, -1)),
|
| 1163 |
+
-1: cap_of(nearest(cap_s, 1))}
|
| 1164 |
|
| 1165 |
# --- K seçimi, kalibrasyon, güncel olasılık
|
| 1166 |
best_k, k_scores = tune_k(dev_X, dev_y, h)
|
|
|
|
| 1312 |
cands = {"Supertrend": float(st_line[-1]), "UT trailing stop": float(ut_stop[-1]),
|
| 1313 |
"VP " + ("VAL" if side == 1 else "VAH"):
|
| 1314 |
float((vp.val if side == 1 else vp.vah).iloc[-1])}
|
| 1315 |
+
if smc_lvl_on:
|
| 1316 |
+
kk_ = ("ob_sup", "pdl", "pwl", "pml") if side == 1 else ("ob_res", "pdh", "pwh", "pmh")
|
| 1317 |
+
for k_, nm_ in zip(kk_, ("SMC OB", "Önceki gün", "Önceki hafta", "Önceki ay")):
|
| 1318 |
+
cands[nm_] = float(SM[k_][-1])
|
| 1319 |
if smc_only and SM is not None:
|
| 1320 |
cands["SMC swing " + ("low" if side == 1 else "high")] = float(SM["sw_lo" if side == 1 else "sw_hi"][-1])
|
| 1321 |
valid = {k_: side*(cl_-v_) for k_, v_ in cands.items() if np.isfinite(v_) and side*(cl_-v_) > 0}
|
|
|
|
| 1448 |
("Strong/Weak High · Low", f"{'Strong' if SM['strong_high'] else 'Weak'} {fmt_p(tp_)} · "
|
| 1449 |
f"{'Strong' if SM['strong_low'] else 'Weak'} {fmt_p(bt_)}"),
|
| 1450 |
("Aktif swing OB (bull)", ob_txt(True)), ("Aktif swing OB (bear)", ob_txt(False)),
|
| 1451 |
+
("Önceki gün H / L", f"{fmt_p(SM['pdh'][-1])} / {fmt_p(SM['pdl'][-1])}"),
|
| 1452 |
+
("Önceki hafta H / L", f"{fmt_p(SM['pwh'][-1])} / {fmt_p(SM['pwl'][-1])}"),
|
| 1453 |
+
("Önceki ay H / L", f"{fmt_p(SM['pmh'][-1])} / {fmt_p(SM['pml'][-1])}"),
|
| 1454 |
("Açık FVG sayısı", len(SM["fvg"])), ("SMC yön onayı", dname[smc_now])])
|
| 1455 |
smc_note = (f"Swing {int(smc_swing_len)} · internal {int(smc_int_len)} mum"
|
| 1456 |
+ (" · premium/discount kapısı açık" if smc_zone else "")
|
| 1457 |
+
+ (" · internal confluence filtresi" if smc_conf else "")
|
| 1458 |
+
+ f" · OB filtresi: {smc_obf}"
|
| 1459 |
+
+ (" · OB + önceki D/W/M seviyeleri SL/TP'de" if smc_lvl_on else "")
|
| 1460 |
+ (" · Mod Kapalı: yalnızca bilgi/grafik." if not smc_on else "") + ".")
|
| 1461 |
else:
|
| 1462 |
smc_md, smc_note = "_Mod kapalı._", ""
|
|
|
|
| 1499 |
tpsl_note = (f"SL: en yakın invalidasyon seviyesi — **{sl_name}** (+0,1 ATR tampon, "
|
| 1500 |
f"{float(tpsl_smin):g}–{float(tpsl_smax):g} ATR aralığına sıkıştırılır). "
|
| 1501 |
f"TP: {rr:.2f}R katı"
|
| 1502 |
+
+ (", önündeki VA/POC/SMC OB/MTF seviyesinde sınırlandı" if capped else "")
|
| 1503 |
+ ". Optimize edilen tek parametre R katıdır.\n\n")
|
| 1504 |
else:
|
| 1505 |
tp_title, tpsl_note = "optimize", ""
|
|
|
|
| 1619 |
"seri korelasyonunu ve rejim değişimini tam modellemez. Pozisyon hesabı spot miktar "
|
| 1620 |
"varsayar; CFD lot sözleşmesi, spread, funding, swap, komisyon, minimum lot, marjin ve "
|
| 1621 |
"broker fiyatı farklı olabilir. Gap ve kayma kaybı planlanan riskin üstüne çıkarabilir. "
|
| 1622 |
+
"Supertrend ve UT Bot, TradingView formüllerinin Python portudur; ATR başlangıcı ve veri kaynağı yüzünden TV değerlerinden küçük sapmalar olabilir. Birleşik sinyal; ST+UT, Lorentzian ve Volume Profile oylarının birleşimidir. İndikatör bazlı TP/SL, en yakın ST/UT/VP seviyesini invalidasyon sayar ve ATR aralığına sıkıştırır. Lorentzian Classification, jdehorty'nin TradingView göstergesinin Python portudur (ANN komşu seçimi, filtreler ve kernel regresyon); Pine kaynağıyla birebir aynı sonuç vermeyebilir ve yalnızca günlük mumda çalışır. Volume Profile, günlük OHLCV'den (her mumun hacmi high–low aralığına eşit dağıtılarak) yaklaşık hesaplanır; TradingView VPVR'nin alt-zaman dilimi verisiyle birebir aynı olmaz. Gann Box, Zeiierman göstergesinin açıklamasına göre yazılmış bir Python portudur (Pine kaynağı birebir alınmadı); kutu son N mumun en yüksek/en düşük noktasından kurulur, Gann Fan 1x1 köşegeni ve katlarıyla çizilir, Gann Curves/Angles eklenmedi. Onay filtresi, kapanışın kutu %50 çizgisine göre konumuna bakar ve geçmişe bakan (kayan) pencere kullanır. SMC, LuxAlgo göstergesinin açıklamasına göre yazılmış bir Python portudur (Pine kaynağı birebir değil): swing/internal yapı, BOS/CHoCH, order block (high/low mitigasyonu), EQH/EQL, FVG ve premium/discount hesaplanır; mum boyama yoktur; internal confluence ve OB filtresi, Pine formüllerinin hafızadan yazılmış karşılığıdır. OB ve önceki gün/hafta/ay high-low seviyeleri, «TP/SL'i indikatörlerden türet» açıkken en yakın seviye SL referansı ve TP sınırı olarak backtest'e girer. Sadece SMC modunda işlemler yalnızca seçilen yapıdaki (swing/internal) BOS/CHoCH kırılım mumunda, kırılım yönünde açılır; SL en yakın ST/UT/VP/SMC swing seviyesinden, TP R katından türetilir; diğer sinyal modları devre dışıdır. Pivotlar pencere kadar mum sonra doğrulanır, bu yüzden sinyal geç gelir. SMC kavramlarının istatistiksel geçerliliği kanıtlı değildir; OOS sonuçlarıyla doğrulayın. Canlı hesap öncesi paper trading ve broker bazlı doğrulama zorunludur."
|
| 1623 |
)
|
| 1624 |
return (report, prob_figure(p_down, p_flat, p_up), price_fig, eq_fig, pf_fig, mc_fig,
|
| 1625 |
top_df, csv_path, disclaimer)
|
|
|
|
| 1708 |
smc_int_len = gr.Slider(3, 15, value=5, step=1, label="SMC internal yapı uzunluğu")
|
| 1709 |
smc_zone = gr.Checkbox(value=False, label="Premium/Discount kapısı (long=discount, short=premium)")
|
| 1710 |
smc_draw = gr.Checkbox(value=True, label="SMC katmanlarını grafikte göster")
|
| 1711 |
+
with gr.Row():
|
| 1712 |
+
smc_conf = gr.Checkbox(value=False, label="Internal confluence filtresi (zayıf kırılımları ele)")
|
| 1713 |
+
smc_obf = gr.Radio(SMC_OBF, value=SMC_OBF[0], label="Order Block volatilite filtresi")
|
| 1714 |
+
smc_lvl = gr.Checkbox(value=True, label="SMC seviyeleri TP/SL'de kullan (Order Block + önceki gün/hafta/ay H-L)")
|
| 1715 |
with gr.Row():
|
| 1716 |
skip_overlap = gr.Checkbox(value=False, label="Açık pozisyon varken yeni sinyali atla (tek pozisyon)")
|
| 1717 |
whole_units = gr.Checkbox(value=False, label="Miktarı tam sayıya yuvarla (hisse)")
|
|
|
|
| 1745 |
ldc_use_vol, ldc_use_regime, ldc_use_adx, ldc_kernel, ldc_exact,
|
| 1746 |
combo_mode, combo_votes, ind_tpsl, tpsl_smin, tpsl_smax, tpsl_minrr,
|
| 1747 |
gann_mode, gann_lb, gann_fan_on, gann_ext_on, gann_rev,
|
| 1748 |
+
smc_mode, smc_src, smc_swing_len, smc_int_len, smc_zone, smc_draw,
|
| 1749 |
+
smc_conf, smc_obf, smc_lvl],
|
| 1750 |
outputs=[output, prob_plot, chart, equity_plot, pf_plot, mc_plot, optimization,
|
| 1751 |
csv_file, disclaimer],
|
| 1752 |
)
|