GoshawkVortexAI commited on
Commit
f757a9f
·
verified ·
1 Parent(s): af140bb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -11
app.py CHANGED
@@ -28,6 +28,7 @@ SL_GRID = [0.8, 1.0, 1.2, 1.5, 1.8, 2.0, 2.5, 3.0]
28
  RR_GRID = [1.0, 1.25, 1.5, 2.0, 2.5, 3.0, 4.0]
29
  CLASSES = [-1, 0, 1]
30
  SIDE_MODES = ["Long + Short", "Sadece Long", "Sadece Short"]
 
31
 
32
  _CACHE = {}
33
  CACHE_TTL = 600 # saniye; Yahoo'yu gereksiz yere tekrar çağırmamak için
@@ -91,6 +92,53 @@ def make_features(df):
91
  return x.replace([np.inf, -np.inf], np.nan), atr
92
 
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  def regime_labels(features, ref_vol):
95
  # Volatilite kantilleri yalnızca geliştirme dönemi verisinden alınır (sızıntı yok).
96
  q1, q2 = ref_vol.dropna().quantile([0.33, 0.67])
@@ -292,7 +340,7 @@ TRADE_COLS = ["entry_date", "exit_date", "side", "entry_price", "exit_reason",
292
 
293
 
294
  # ---------------------------------------------------------------- grafikler
295
- def price_figure(df, ticker, trades_df, trade_ok, stop, target):
296
  w = df.tail(150)
297
  fig = go.Figure([go.Candlestick(x=w.index, open=w.Open, high=w.High, low=w.Low,
298
  close=w.Close, name=ticker)])
@@ -300,6 +348,13 @@ def price_figure(df, ticker, trades_df, trade_ok, stop, target):
300
  ema = df.Close.ewm(span=n, adjust=False).mean().tail(150)
301
  fig.add_trace(go.Scatter(x=w.index, y=ema, mode="lines", name=f"EMA{n}",
302
  line=dict(width=1.2, color=col)))
 
 
 
 
 
 
 
303
  if len(trades_df):
304
  t = trades_df[trades_df.entry_date.isin(w.index)]
305
  for side, sym, nm in [("LONG", "triangle-up", "OOS long"),
@@ -379,8 +434,7 @@ def mc_figure(mc):
379
  def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
380
  max_leverage, fee, slip, train_window,
381
  p_min, p_gap, flat_max, agree_min, bacc_min, min_trades,
382
- skip_overlap, whole_units):
383
- empty = (None, None, None, None, None, pd.DataFrame(), None)
384
  try:
385
  ticker = str(ticker).strip().upper()
386
  h = int(horizon)
@@ -419,6 +473,14 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
419
  "c": df.Close.to_numpy(float), "a": atr_all.to_numpy(float)}
420
  pos_of = lambda idx: df.index.get_indexer(idx)
421
 
 
 
 
 
 
 
 
 
422
  # --- K seçimi, kalibrasyon, güncel olasılık
423
  best_k, k_scores = tune_k(dev_X, dev_y, h)
424
  cal_n = min(120, max(45, int(len(dev_X)*0.20)))
@@ -440,21 +502,32 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
440
  side = -1
441
  else:
442
  side = 1 if p_up >= p_down else -1
 
 
443
  p_side, p_opp = (p_up, p_down) if side == 1 else (p_down, p_up)
444
 
445
  imp, scaler = cal_model.named_steps["imputer"], cal_model.named_steps["scale"]
446
  nn = NearestNeighbors(n_neighbors=best_k).fit(scaler.transform(imp.transform(fit_X)))
447
  _, idx = nn.kneighbors(scaler.transform(imp.transform(current_x)))
448
  agreement = float((fit_y.iloc[idx[0]].to_numpy() == side).mean())
 
 
449
 
450
  # --- yön bazlı TP/SL optimizasyonu (yalnızca geliştirme verisi)
451
  current_regime = str(regimes_all.iloc[-1])
452
  dev_pos = pos_of(dev_X.index)
453
  params, top, regime_used = {}, [], "—"
 
 
 
 
 
 
 
454
  for s in (1, -1):
455
  if allow[s]:
456
  sl_s, rr_s, top_s, used_s = optimize_barriers(
457
- A, dev_pos, reg_arr, s, cost, current_regime, h)
458
  params[s] = (sl_s, rr_s)
459
  if s == side:
460
  top, regime_used = top_s, used_s
@@ -466,12 +539,19 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
466
  oos_pred = pipe(best_k).fit(dev_X, dev_y).predict(oos_X)
467
  oos_bacc = float(balanced_accuracy_score(oos_y, oos_pred))
468
  oos_acc = float(accuracy_score(oos_y, oos_pred))
 
 
 
 
 
469
 
470
  rows, busy = [], -1
471
- for i, pred in zip(pos_of(oos_X.index), oos_pred):
472
  pred = int(pred)
473
  if pred == 0 or not allow[pred]:
474
  continue
 
 
475
  if skip_overlap and i <= busy:
476
  continue
477
  sl_p, rr_p = params[pred]
@@ -526,6 +606,14 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
526
  ("OOS işlem sayısı", f"{len(R)}", f"≥ {int(min_trades)}", len(R) >= int(min_trades)),
527
  ("OOS expectancy", f"{expectancy_r:.3f}R", "> 0", expectancy_r > 0),
528
  ]
 
 
 
 
 
 
 
 
529
  trade_ok = all(c[3] for c in checks)
530
  if trade_ok:
531
  signal = "LONG" if side == 1 else "SHORT"
@@ -560,6 +648,10 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
560
  f"%5 kuyruk max DD: {mc['dd95']:.2%} · "
561
  f"%50 sermaye altına inme frekansı: {mc['ruin']:.1%}"
562
  if mc else "Monte Carlo için yeterli OOS işlem yok.")
 
 
 
 
563
  k_text = " | ".join(f"K={k}: {s:.3f}" for s, k in sorted(k_scores, reverse=True)) or "—"
564
  overlap_note = ("tek pozisyon (çakışma yok)" if skip_overlap
565
  else "çakışan sinyaller bağımsız işlem sayıldı")
@@ -581,6 +673,9 @@ def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
581
 
582
  **K seçim skorları:** {k_text}
583
 
 
 
 
584
  ## TP / SL ({'LONG' if side == 1 else 'SHORT'} için optimize)
585
  | Parametre | Değer |
586
  |---|---:|
@@ -628,7 +723,8 @@ TP/SL optimizasyon rejimi: {regime_used}. Yeterli rejim örneği yoksa tüm geli
628
  csv_path = os.path.join(tempfile.gettempdir(), f"goshawk_{safe}_oos_trades.csv")
629
  trades_df.to_csv(csv_path, index=False)
630
 
631
- price_fig = price_figure(df, ticker, trades_df, trade_ok, stop, target)
 
632
  eq_fig = equity_figure(curve, dds) if len(R) else None
633
  pf_fig = pf_gauge(stats["pf"], stats["n"]) if stats else None
634
  mc_fig = mc_figure(mc) if mc else None
@@ -644,14 +740,15 @@ TP/SL optimizasyon rejimi: {regime_used}. Yeterli rejim örneği yoksa tüm geli
644
  "seri korelasyonunu ve rejim değişimini tam modellemez. Pozisyon hesabı spot miktar "
645
  "varsayar; CFD lot sözleşmesi, spread, funding, swap, komisyon, minimum lot, marjin ve "
646
  "broker fiyatı farklı olabilir. Gap ve kayma kaybı planlanan riskin üstüne çıkarabilir. "
647
- "Canlı hesap öncesi paper trading ve broker bazlı doğrulama zorunludur."
648
  )
649
  return (report, prob_figure(p_down, p_flat, p_up), price_fig, eq_fig, pf_fig, mc_fig,
650
  top_df, csv_path, disclaimer)
651
 
652
  except Exception as exc:
653
- return (f"# Hata\n{type(exc).__name__}: {exc}",) + empty[1:] + \
654
- ("Veri bağlantısını ve parametreleri kontrol edin.",)
 
655
 
656
 
657
  # ---------------------------------------------------------------- arayüz
@@ -668,6 +765,7 @@ with gr.Blocks(title=APP_TITLE, theme=gr.themes.Soft()) as demo:
668
  period = gr.Dropdown(["2y", "5y", "10y", "max"], value="5y", label="Veri geçmişi")
669
  horizon = gr.Dropdown([3, 5, 10], value=5, label="Tahmin ufku (gün)")
670
  side_mode = gr.Radio(SIDE_MODES, value="Long + Short", label="İzin verilen yön")
 
671
  train_window = gr.Slider(300, 1500, value=900, step=50, label="Maksimum eğitim penceresi")
672
  with gr.Column():
673
  equity = gr.Number(value=10000, label="Hesap büyüklüğü (USD)")
@@ -685,6 +783,11 @@ with gr.Blocks(title=APP_TITLE, theme=gr.themes.Soft()) as demo:
685
  agree_min = gr.Slider(0.30, 0.90, value=0.55, step=0.01, label="Min. komşu uyumu")
686
  bacc_min = gr.Slider(0.30, 0.60, value=0.36, step=0.01, label="Min. OOS balanced acc.")
687
  min_trades = gr.Slider(5, 50, value=15, step=1, label="Min. OOS işlem sayısı")
 
 
 
 
 
688
  with gr.Row():
689
  skip_overlap = gr.Checkbox(value=False, label="Açık pozisyon varken yeni sinyali atla (tek pozisyon)")
690
  whole_units = gr.Checkbox(value=False, label="Miktarı tam sayıya yuvarla (hisse)")
@@ -712,11 +815,10 @@ with gr.Blocks(title=APP_TITLE, theme=gr.themes.Soft()) as demo:
712
  inputs=[ticker, period, horizon, side_mode, equity, min_risk, max_risk,
713
  max_leverage, fee, slip, train_window,
714
  p_min, p_gap, flat_max, agree_min, bacc_min, min_trades,
715
- skip_overlap, whole_units],
716
  outputs=[output, prob_plot, chart, equity_plot, pf_plot, mc_plot, optimization,
717
  csv_file, disclaimer],
718
  )
719
 
720
  if __name__ == "__main__":
721
  demo.launch(server_name="0.0.0.0", server_port=7860)
722
- 0
 
28
  RR_GRID = [1.0, 1.25, 1.5, 2.0, 2.5, 3.0, 4.0]
29
  CLASSES = [-1, 0, 1]
30
  SIDE_MODES = ["Long + Short", "Sadece Long", "Sadece Short"]
31
+ IND_MODES = ["Kapalı", "Onay filtresi (KNN + ST/UT)", "Sadece indikatör"]
32
 
33
  _CACHE = {}
34
  CACHE_TTL = 600 # saniye; Yahoo'yu gereksiz yere tekrar çağırmamak için
 
92
  return x.replace([np.inf, -np.inf], np.nan), atr
93
 
94
 
95
+ def supertrend(df, period=10, mult=3.0):
96
+ """TradingView ta.supertrend portu. dir: +1 yükseliş, -1 düşüş."""
97
+ atr = calc_atr(df, period).to_numpy(float)
98
+ h, l, c = df.High.to_numpy(float), df.Low.to_numpy(float), df.Close.to_numpy(float)
99
+ hl2 = (h+l)/2
100
+ n = len(c)
101
+ up, dn = hl2-mult*atr, hl2+mult*atr
102
+ trend = np.ones(n, dtype=int)
103
+ for i in range(1, n):
104
+ if c[i-1] > up[i-1]:
105
+ up[i] = max(up[i], up[i-1])
106
+ if c[i-1] < dn[i-1]:
107
+ dn[i] = min(dn[i], dn[i-1])
108
+ trend[i] = trend[i-1]
109
+ if trend[i-1] == -1 and c[i] > dn[i-1]:
110
+ trend[i] = 1
111
+ elif trend[i-1] == 1 and c[i] < up[i-1]:
112
+ trend[i] = -1
113
+ return trend, np.where(trend == 1, up, dn)
114
+
115
+
116
+ def ut_bot(df, key=1.0, period=10):
117
+ """UT Bot Alerts (QuantNomad) portu. pos: +1 al, -1 sat, 0 henüz sinyal yok."""
118
+ c = df.Close.to_numpy(float)
119
+ nloss = key*calc_atr(df, period).to_numpy(float)
120
+ n = len(c)
121
+ stop, pos = np.zeros(n), np.zeros(n, dtype=int)
122
+ stop[0] = c[0]-nloss[0]
123
+ for i in range(1, n):
124
+ prev = stop[i-1]
125
+ if c[i] > prev and c[i-1] > prev:
126
+ stop[i] = max(prev, c[i]-nloss[i])
127
+ elif c[i] < prev and c[i-1] < prev:
128
+ stop[i] = min(prev, c[i]+nloss[i])
129
+ elif c[i] > prev:
130
+ stop[i] = c[i]-nloss[i]
131
+ else:
132
+ stop[i] = c[i]+nloss[i]
133
+ if c[i-1] < prev and c[i] > prev:
134
+ pos[i] = 1
135
+ elif c[i-1] > prev and c[i] < prev:
136
+ pos[i] = -1
137
+ else:
138
+ pos[i] = pos[i-1]
139
+ return pos, stop
140
+
141
+
142
  def regime_labels(features, ref_vol):
143
  # Volatilite kantilleri yalnızca geliştirme dönemi verisinden alınır (sızıntı yok).
144
  q1, q2 = ref_vol.dropna().quantile([0.33, 0.67])
 
340
 
341
 
342
  # ---------------------------------------------------------------- grafikler
343
+ def price_figure(df, ticker, trades_df, trade_ok, stop, target, ind=None):
344
  w = df.tail(150)
345
  fig = go.Figure([go.Candlestick(x=w.index, open=w.Open, high=w.High, low=w.Low,
346
  close=w.Close, name=ticker)])
 
348
  ema = df.Close.ewm(span=n, adjust=False).mean().tail(150)
349
  fig.add_trace(go.Scatter(x=w.index, y=ema, mode="lines", name=f"EMA{n}",
350
  line=dict(width=1.2, color=col)))
351
+ if ind is not None:
352
+ st_line, st_dir, ut_stop = (np.asarray(a)[-150:] for a in ind)
353
+ for d, col, nm in [(1, "#16a34a", "Supertrend ↑"), (-1, "#dc2626", "Supertrend ↓")]:
354
+ fig.add_trace(go.Scatter(x=w.index, y=np.where(st_dir == d, st_line, np.nan),
355
+ mode="lines", name=nm, line=dict(width=1.5, color=col)))
356
+ fig.add_trace(go.Scatter(x=w.index, y=ut_stop, mode="lines", name="UT trailing stop",
357
+ line=dict(width=1, dash="dot", color="#9333ea")))
358
  if len(trades_df):
359
  t = trades_df[trades_df.entry_date.isin(w.index)]
360
  for side, sym, nm in [("LONG", "triangle-up", "OOS long"),
 
434
  def run_engine(ticker, period, horizon, side_mode, equity, min_risk, max_risk,
435
  max_leverage, fee, slip, train_window,
436
  p_min, p_gap, flat_max, agree_min, bacc_min, min_trades,
437
+ skip_overlap, whole_units, ind_mode, st_period, st_mult, ut_key, ut_period):
 
438
  try:
439
  ticker = str(ticker).strip().upper()
440
  h = int(horizon)
 
473
  "c": df.Close.to_numpy(float), "a": atr_all.to_numpy(float)}
474
  pos_of = lambda idx: df.index.get_indexer(idx)
475
 
476
+ # --- indikatörler (Supertrend + UT Bot), tamamen Python'da
477
+ st_dir, st_line = supertrend(df, int(st_period), float(st_mult))
478
+ ut_pos, ut_stop = ut_bot(df, float(ut_key), int(ut_period))
479
+ ind_arr = np.where((st_dir == ut_pos) & (ut_pos != 0), ut_pos, 0).astype(int)
480
+ ind_only = ind_mode == "Sadece indikatör"
481
+ ind_confirm = ind_mode == IND_MODES[1]
482
+ ind_now = int(ind_arr[-1])
483
+
484
  # --- K seçimi, kalibrasyon, güncel olasılık
485
  best_k, k_scores = tune_k(dev_X, dev_y, h)
486
  cal_n = min(120, max(45, int(len(dev_X)*0.20)))
 
502
  side = -1
503
  else:
504
  side = 1 if p_up >= p_down else -1
505
+ if ind_only and ind_now != 0 and allow[ind_now]:
506
+ side = ind_now
507
  p_side, p_opp = (p_up, p_down) if side == 1 else (p_down, p_up)
508
 
509
  imp, scaler = cal_model.named_steps["imputer"], cal_model.named_steps["scale"]
510
  nn = NearestNeighbors(n_neighbors=best_k).fit(scaler.transform(imp.transform(fit_X)))
511
  _, idx = nn.kneighbors(scaler.transform(imp.transform(current_x)))
512
  agreement = float((fit_y.iloc[idx[0]].to_numpy() == side).mean())
513
+ if ind_only: # indikatör modunda: son 10 mumda yönün sürekliliği
514
+ agreement = float((ind_arr[-10:] == side).mean())
515
 
516
  # --- yön bazlı TP/SL optimizasyonu (yalnızca geliştirme verisi)
517
  current_regime = str(regimes_all.iloc[-1])
518
  dev_pos = pos_of(dev_X.index)
519
  params, top, regime_used = {}, [], "—"
520
+
521
+ def opt_pos(s_):
522
+ if ind_only or ind_confirm:
523
+ f_ = [i for i in dev_pos if ind_arr[i] == s_]
524
+ if len(f_) >= 35:
525
+ return f_
526
+ return dev_pos
527
  for s in (1, -1):
528
  if allow[s]:
529
  sl_s, rr_s, top_s, used_s = optimize_barriers(
530
+ A, opt_pos(s), reg_arr, s, cost, current_regime, h)
531
  params[s] = (sl_s, rr_s)
532
  if s == side:
533
  top, regime_used = top_s, used_s
 
539
  oos_pred = pipe(best_k).fit(dev_X, dev_y).predict(oos_X)
540
  oos_bacc = float(balanced_accuracy_score(oos_y, oos_pred))
541
  oos_acc = float(accuracy_score(oos_y, oos_pred))
542
+ oos_pos_arr = pos_of(oos_X.index)
543
+ if ind_only: # indikatör yönü OOS'ta tahmin yerine geçer
544
+ oos_pred = ind_arr[oos_pos_arr]
545
+ oos_bacc = float(balanced_accuracy_score(oos_y, oos_pred))
546
+ oos_acc = float(accuracy_score(oos_y, oos_pred))
547
 
548
  rows, busy = [], -1
549
+ for i, pred in zip(oos_pos_arr, oos_pred):
550
  pred = int(pred)
551
  if pred == 0 or not allow[pred]:
552
  continue
553
+ if ind_confirm and ind_arr[i] != pred:
554
+ continue
555
  if skip_overlap and i <= busy:
556
  continue
557
  sl_p, rr_p = params[pred]
 
606
  ("OOS işlem sayısı", f"{len(R)}", f"≥ {int(min_trades)}", len(R) >= int(min_trades)),
607
  ("OOS expectancy", f"{expectancy_r:.3f}R", "> 0", expectancy_r > 0),
608
  ]
609
+ dname = {1: "LONG ↑", -1: "SHORT ↓", 0: "belirsiz"}
610
+ ind_check = ("İndikatör yönü (ST + UT aynı)", dname[ind_now], "yönle aynı", ind_now == side)
611
+ if ind_only:
612
+ keep = ("Yön izni", "OOS balanced acc.", "OOS işlem sayısı", "OOS expectancy")
613
+ checks = [c for c in checks if c[0] in keep]
614
+ checks.insert(1, ind_check)
615
+ elif ind_confirm:
616
+ checks.insert(1, ind_check)
617
  trade_ok = all(c[3] for c in checks)
618
  if trade_ok:
619
  signal = "LONG" if side == 1 else "SHORT"
 
648
  f"%5 kuyruk max DD: {mc['dd95']:.2%} · "
649
  f"%50 sermaye altına inme frekansı: {mc['ruin']:.1%}"
650
  if mc else "Monte Carlo için yeterli OOS işlem yok.")
651
+ ind_md = md_table(["İndikatör", "Yön", "Seviye"], [
652
+ (f"Supertrend ({int(st_period)}, {float(st_mult):g})", dname[int(st_dir[-1])], fmt_p(float(st_line[-1]))),
653
+ (f"UT Bot ({float(ut_key):g}, {int(ut_period)})", dname[int(ut_pos[-1])], fmt_p(float(ut_stop[-1]))),
654
+ ("Bileşik (ikisi aynı yönde)", dname[ind_now], "—")])
655
  k_text = " | ".join(f"K={k}: {s:.3f}" for s, k in sorted(k_scores, reverse=True)) or "—"
656
  overlap_note = ("tek pozisyon (çakışma yok)" if skip_overlap
657
  else "çakışan sinyaller bağımsız işlem sayıldı")
 
673
 
674
  **K seçim skorları:** {k_text}
675
 
676
+ ## İndikatörler — mod: {ind_mode}
677
+ {ind_md}
678
+
679
  ## TP / SL ({'LONG' if side == 1 else 'SHORT'} için optimize)
680
  | Parametre | Değer |
681
  |---|---:|
 
723
  csv_path = os.path.join(tempfile.gettempdir(), f"goshawk_{safe}_oos_trades.csv")
724
  trades_df.to_csv(csv_path, index=False)
725
 
726
+ price_fig = price_figure(df, ticker, trades_df, trade_ok, stop, target,
727
+ ind=(st_line, st_dir, ut_stop))
728
  eq_fig = equity_figure(curve, dds) if len(R) else None
729
  pf_fig = pf_gauge(stats["pf"], stats["n"]) if stats else None
730
  mc_fig = mc_figure(mc) if mc else None
 
740
  "seri korelasyonunu ve rejim değişimini tam modellemez. Pozisyon hesabı spot miktar "
741
  "varsayar; CFD lot sözleşmesi, spread, funding, swap, komisyon, minimum lot, marjin ve "
742
  "broker fiyatı farklı olabilir. Gap ve kayma kaybı planlanan riskin üstüne çıkarabilir. "
743
+ "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. Canlı hesap öncesi paper trading ve broker bazlı doğrulama zorunludur."
744
  )
745
  return (report, prob_figure(p_down, p_flat, p_up), price_fig, eq_fig, pf_fig, mc_fig,
746
  top_df, csv_path, disclaimer)
747
 
748
  except Exception as exc:
749
+ return (f"# Hata\n{type(exc).__name__}: {exc}", None, None, None, None, None,
750
+ pd.DataFrame(), None,
751
+ "Veri bağlantısını ve parametreleri kontrol edin.")
752
 
753
 
754
  # ---------------------------------------------------------------- arayüz
 
765
  period = gr.Dropdown(["2y", "5y", "10y", "max"], value="5y", label="Veri geçmişi")
766
  horizon = gr.Dropdown([3, 5, 10], value=5, label="Tahmin ufku (gün)")
767
  side_mode = gr.Radio(SIDE_MODES, value="Long + Short", label="İzin verilen yön")
768
+ ind_mode = gr.Radio(IND_MODES, value="Kapalı", label="İndikatör modu (Supertrend + UT Bot)")
769
  train_window = gr.Slider(300, 1500, value=900, step=50, label="Maksimum eğitim penceresi")
770
  with gr.Column():
771
  equity = gr.Number(value=10000, label="Hesap büyüklüğü (USD)")
 
783
  agree_min = gr.Slider(0.30, 0.90, value=0.55, step=0.01, label="Min. komşu uyumu")
784
  bacc_min = gr.Slider(0.30, 0.60, value=0.36, step=0.01, label="Min. OOS balanced acc.")
785
  min_trades = gr.Slider(5, 50, value=15, step=1, label="Min. OOS işlem sayısı")
786
+ with gr.Row():
787
+ st_period = gr.Slider(5, 30, value=10, step=1, label="Supertrend ATR periyodu")
788
+ st_mult = gr.Slider(1.0, 6.0, value=3.0, step=0.1, label="Supertrend çarpanı")
789
+ ut_key = gr.Slider(0.5, 4.0, value=1.0, step=0.1, label="UT Bot key value")
790
+ ut_period = gr.Slider(5, 30, value=10, step=1, label="UT Bot ATR periyodu")
791
  with gr.Row():
792
  skip_overlap = gr.Checkbox(value=False, label="Açık pozisyon varken yeni sinyali atla (tek pozisyon)")
793
  whole_units = gr.Checkbox(value=False, label="Miktarı tam sayıya yuvarla (hisse)")
 
815
  inputs=[ticker, period, horizon, side_mode, equity, min_risk, max_risk,
816
  max_leverage, fee, slip, train_window,
817
  p_min, p_gap, flat_max, agree_min, bacc_min, min_trades,
818
+ skip_overlap, whole_units, ind_mode, st_period, st_mult, ut_key, ut_period],
819
  outputs=[output, prob_plot, chart, equity_plot, pf_plot, mc_plot, optimization,
820
  csv_file, disclaimer],
821
  )
822
 
823
  if __name__ == "__main__":
824
  demo.launch(server_name="0.0.0.0", server_port=7860)