GoshawkVortexAI commited on
Commit
b0e14ac
·
verified ·
1 Parent(s): 02ce192

Delete knn_calibrate.py

Browse files
Files changed (1) hide show
  1. knn_calibrate.py +0 -128
knn_calibrate.py DELETED
@@ -1,128 +0,0 @@
1
- """
2
- KNN KALİBRASYON — walk-forward (seçim / test ayrımlı) parametre taraması.
3
-
4
- Kullanım (app.py ile aynı klasörde, internet gerekir):
5
- python knn_calibrate.py # BTC-USDT 1H, son 4000 bar
6
- python knn_calibrate.py BTC-USDT 1H 6000
7
-
8
- Mantık:
9
- 1) OKX history-candles ile uzun geçmiş indirilir (yalnızca kapanmış mumlar).
10
- 2) Parametre ızgarası: K, edge eşiği, ileri bar, SL/TP (ATR) çarpanları.
11
- 3) Skor aralığının İLK %60'ı = SEÇİM, SON %40'ı = TEST (hiç görülmemiş veri).
12
- Parametreler yalnızca seçim dilimindeki sonuca göre sıralanır; TEST dilimi sadece raporlanır.
13
- 4) Her satırda "başa baş win rate" gösterilir: SL/(SL+TP). Win rate bunun üstünde değilse yüksek win rate kâr demek DEĞİLDİR.
14
- """
15
- import itertools
16
- import os
17
- import sys
18
- import time
19
-
20
- os.environ["APP_NO_LAUNCH"] = "1"
21
- import numpy as np
22
- import pandas as pd
23
-
24
- import app
25
-
26
- GRID_K = (9, 15, 25)
27
- GRID_EDGE = (0.15, 0.30, 0.50)
28
- GRID_FWD = (3, 5, 8)
29
- GRID_SLTP = ((1.5, 2.5), (2.0, 2.0), (2.5, 1.5), (3.0, 1.0)) # (SL, TP) ATR
30
- MIN_TRADES = 20 # seçim diliminde en az bu kadar işlem yoksa satır sıralamaya girmez
31
- SPLIT = 0.60
32
-
33
-
34
- def fetch_history(inst_id="BTC-USDT", bar="1H", total=4000):
35
- rows, after = [], None
36
- while len(rows) < total:
37
- p = {"instId": inst_id, "bar": bar, "limit": 100}
38
- if after:
39
- p["after"] = after
40
- raw = app._get("/api/v5/market/history-candles", p)
41
- if not raw:
42
- break
43
- rows += raw
44
- after = raw[-1][0] # en eski mumun zamanı -> bir sonraki sayfa daha eskiyi getirir
45
- time.sleep(0.12)
46
- cols = ["ts", "o", "h", "l", "c", "vol", "volCcy", "volCcyQuote", "confirm"]
47
- df = pd.DataFrame(rows, columns=cols).drop_duplicates("ts")
48
- for c in ["o", "h", "l", "c", "vol"]:
49
- df[c] = df[c].astype(float)
50
- df["confirm"] = df["confirm"].astype(int)
51
- df["ts"] = pd.to_datetime(df["ts"].astype(np.int64), unit="ms")
52
- df = df[df["confirm"] == 1].sort_values("ts").reset_index(drop=True)
53
- return df.tail(total).reset_index(drop=True)
54
-
55
-
56
- def _stats(trades, sl, tp):
57
- if not trades:
58
- return None
59
- pnl = np.array([t["pnl"] for t in trades])
60
- r = np.array([t["r"] for t in trades])
61
- gl = abs(pnl[pnl <= 0].sum())
62
- return {"n": len(trades), "wr": float((pnl > 0).mean()),
63
- "pf": float(pnl[pnl > 0].sum() / gl) if gl > 0 else float("inf"),
64
- "exp_r": float(r.mean()), "be_wr": sl / (sl + tp)}
65
-
66
-
67
- def run(df):
68
- n = len(df)
69
- results = []
70
- for fwd in GRID_FWD:
71
- app.KNN_FORWARD = fwd
72
- for K, edge in itertools.product(GRID_K, GRID_EDGE):
73
- app.KNN_K = K
74
- app.KNN_MIN_EDGE = edge
75
- app.KNN_TIERS = (edge, min(edge + 0.15, 0.85), min(edge + 0.35, 0.90), min(edge + 0.55, 0.95))
76
- ind = app.compute_indicators(df)
77
- ind["_arr"]["knn_y"] = app.knn_labels(df, ind, forward=fwd)
78
- start = app.WARMUP_BARS + app.KNN_MIN_POOL + fwd
79
- scores = [app._score_at(ind, i) for i in range(start, n)]
80
- cut = start + int((n - start) * SPLIT)
81
- for sl, tp in GRID_SLTP:
82
- app.SL_ATR, app.TP_ATR = sl, tp
83
- trades = app.simulate_trades(df, ind, start, scores)
84
- sel = _stats([t for t in trades if t["signal_i"] < cut], sl, tp)
85
- tst = _stats([t for t in trades if t["signal_i"] >= cut], sl, tp)
86
- results.append({"K": K, "edge": edge, "fwd": fwd, "sl": sl, "tp": tp, "sel": sel, "test": tst})
87
- return results
88
-
89
-
90
- def _row(r):
91
- f = lambda s: " — " if not s else f"n={s['n']:<3d} WR=%{s['wr'] * 100:4.1f} PF={min(s['pf'], 99):4.2f} R={s['exp_r']:+.2f}"
92
- return (f"K={r['K']:<2d} edge={r['edge']:.2f} fwd={r['fwd']} SL/TP={r['sl']}/{r['tp']} (başa baş WR %{r['sel']['be_wr'] * 100:.0f}) | "
93
- f"SEÇİM {f(r['sel'])} | TEST {f(r['test'])}")
94
-
95
-
96
- def report(results):
97
- ok = [r for r in results if r["sel"] and r["sel"]["n"] >= MIN_TRADES]
98
- print(f"\nToplam kombinasyon: {len(results)} · seçim diliminde ≥{MIN_TRADES} işlemli: {len(ok)}")
99
- if not ok:
100
- print("Yeterli işlem üreten kombinasyon yok — daha çok bar indirin.")
101
- return
102
- print("\n── Seçim diliminde PROFIT FACTOR'e göre ilk 5 (test dilimi hiç görülmedi) ──")
103
- for r in sorted(ok, key=lambda r: -r["sel"]["pf"])[:5]:
104
- print(" ", _row(r))
105
- hi = [r for r in ok if r["sel"]["pf"] >= 1.0]
106
- print("\n── Seçimde PF ≥ 1 olanlar içinde WIN RATE'e göre ilk 5 ──")
107
- for r in sorted(hi, key=lambda r: -r["sel"]["wr"])[:5]:
108
- print(" ", _row(r))
109
- tests = [r for r in ok if r["test"] and r["test"]["n"] >= 10]
110
- best = max(tests, key=lambda r: r["test"]["wr"], default=None)
111
- print("\n── DÜRÜST ÖZET ──")
112
- if best:
113
- print(f"Test diliminde (≥10 işlem) görülen en yüksek win rate: %{best['test']['wr'] * 100:.1f} (bu satır test sonucuna bakılarak seçildi → iyimser)")
114
- top = sorted(ok, key=lambda r: -r["sel"]["pf"])[0]
115
- if top["test"]:
116
- t = top["test"]
117
- print(f"Seçimde en iyi parametrenin TEST sonucu: WR %{t['wr'] * 100:.1f}, PF {min(t['pf'], 99):.2f}, ort. R {t['exp_r']:+.2f} ({t['n']} işlem)")
118
- print("→ %80 hedefi tutuyorsa hem test win rate'i hem PF > 1 olmalı; yalnızca win rate yüksek ama PF < 1 ise parametre zarar ettiriyor demektir.")
119
-
120
-
121
- if __name__ == "__main__":
122
- inst = sys.argv[1] if len(sys.argv) > 1 else "BTC-USDT"
123
- bar = sys.argv[2] if len(sys.argv) > 2 else "1H"
124
- total = int(sys.argv[3]) if len(sys.argv) > 3 else 4000
125
- print(f"{inst} {bar} için {total} bar indiriliyor...")
126
- data = fetch_history(inst, bar, total)
127
- print(f"{len(data)} bar: {data['ts'].iloc[0]} → {data['ts'].iloc[-1]}")
128
- report(run(data))