Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -131,8 +131,11 @@ async def fetch_ohlcv(session, tools, symbol, timeframe, exchange, total):
|
|
| 131 |
while got < total:
|
| 132 |
oldest = frames[-1]["ts"].iloc[0]
|
| 133 |
end_ms = int((oldest - epoch) // pd.Timedelta("1ms")) - 1
|
| 134 |
-
|
| 135 |
-
|
|
|
|
|
|
|
|
|
|
| 136 |
if res is None or (isinstance(res, dict) and "error" in res):
|
| 137 |
break
|
| 138 |
try:
|
|
@@ -302,32 +305,44 @@ IND_NAMES = [
|
|
| 302 |
]
|
| 303 |
|
| 304 |
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
|
|
|
|
|
|
|
|
|
| 309 |
kw = dict(symbol=symbol, timeframe=timeframe, exchange=exchange, limit=limit, include_series=True)
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
except Exception: # noqa: BLE001
|
| 314 |
-
res = None
|
| 315 |
-
if isinstance(res, dict) and "error" not in res and extract_series(res, 0):
|
| 316 |
-
out["by_indicator"]["batch"] = res
|
| 317 |
-
out["mode"] = "batch"
|
| 318 |
-
return out
|
| 319 |
-
out["mode"] = "single"
|
| 320 |
-
out["batch_error"] = _strip_series(res) if isinstance(res, dict) else None
|
| 321 |
-
for name in IND_NAMES:
|
| 322 |
try:
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 331 |
return out
|
| 332 |
|
| 333 |
|
|
@@ -800,6 +815,7 @@ def predict(df: pd.DataFrame, horizon: int, fee: float = 0.0006, n_folds: int =
|
|
| 800 |
|
| 801 |
# ----------------------------------------------------------------- Ana akış
|
| 802 |
async def run_async(symbol, timeframe, exchange, horizon, limit):
|
|
|
|
| 803 |
async with stdio_client(SERVER) as (r, w):
|
| 804 |
async with ClientSession(r, w) as session:
|
| 805 |
await session.initialize()
|
|
@@ -811,13 +827,13 @@ async def run_async(symbol, timeframe, exchange, horizon, limit):
|
|
| 811 |
if isinstance(ohlcv, dict) and "error" in ohlcv:
|
| 812 |
raise RuntimeError(ohlcv["error"])
|
| 813 |
|
| 814 |
-
#
|
| 815 |
-
deep =
|
| 816 |
-
|
| 817 |
-
|
| 818 |
-
|
| 819 |
-
|
| 820 |
-
|
| 821 |
for name in EXTRA_TOOLS:
|
| 822 |
if name not in tools:
|
| 823 |
continue
|
|
@@ -830,11 +846,19 @@ async def run_async(symbol, timeframe, exchange, horizon, limit):
|
|
| 830 |
ci = tools.get("compute_indicators")
|
| 831 |
if ci is not None: # gerçek gösterge adlarını görebilmek için araç açıklaması
|
| 832 |
extra["_compute_indicators_description"] = (getattr(ci, "description", "") or "")[:4000]
|
| 833 |
-
|
| 834 |
-
|
| 835 |
-
|
| 836 |
-
|
| 837 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 838 |
return ohlcv, deep, ind, extra
|
| 839 |
|
| 840 |
|
|
@@ -861,7 +885,13 @@ def run(symbol, timeframe, exchange, horizon, limit, use_deriv=True, max_feat=40
|
|
| 861 |
except BaseException as e: # noqa: BLE001
|
| 862 |
import traceback
|
| 863 |
traceback.print_exc()
|
| 864 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 865 |
|
| 866 |
p, thr, bt = res["p_up"], res["thr"], res["bt"]
|
| 867 |
signal = "LONG" if p > thr else "SHORT" if p < 1 - thr else "NÖTR"
|
|
@@ -953,4 +983,3 @@ with gr.Blocks(title="Tickscope Tahmin") as demo:
|
|
| 953 |
|
| 954 |
if __name__ == "__main__":
|
| 955 |
demo.launch()
|
| 956 |
-
|
|
|
|
| 131 |
while got < total:
|
| 132 |
oldest = frames[-1]["ts"].iloc[0]
|
| 133 |
end_ms = int((oldest - epoch) // pd.Timedelta("1ms")) - 1
|
| 134 |
+
try:
|
| 135 |
+
res = await call_tool(session, tools, "get_ohlcv", symbol=symbol, timeframe=timeframe,
|
| 136 |
+
exchange=exchange, limit=page, until=end_ms)
|
| 137 |
+
except Exception: # noqa: BLE001 (ör. Connection closed) -> eldeki sayfalarla devam
|
| 138 |
+
break
|
| 139 |
if res is None or (isinstance(res, dict) and "error" in res):
|
| 140 |
break
|
| 141 |
try:
|
|
|
|
| 305 |
]
|
| 306 |
|
| 307 |
|
| 308 |
+
IND_CHUNK = 6
|
| 309 |
+
|
| 310 |
+
|
| 311 |
+
async def fetch_indicators(symbol, timeframe, exchange, limit):
|
| 312 |
+
"""Göstergeleri KÜÇÜK PARÇALAR halinde (her parça birkaç gösterge), ana oturumdan AYRI bir Tickscope sürecinde çeker.
|
| 313 |
+
Bir parça sunucuyu çökertirse ("Connection closed") yeni süreç açılır, o parçanın adları atlanır, kalanlarla devam edilir."""
|
| 314 |
+
out = {"by_indicator": {}, "failed": [], "mode": "chunked", "reconnects": 0, "last_error": None}
|
| 315 |
kw = dict(symbol=symbol, timeframe=timeframe, exchange=exchange, limit=limit, include_series=True)
|
| 316 |
+
chunks = [IND_NAMES[i:i + IND_CHUNK] for i in range(0, len(IND_NAMES), IND_CHUNK)]
|
| 317 |
+
i = 0
|
| 318 |
+
while i < len(chunks):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
try:
|
| 320 |
+
async with stdio_client(SERVER) as (r, w):
|
| 321 |
+
async with ClientSession(r, w) as session:
|
| 322 |
+
await session.initialize()
|
| 323 |
+
tools = {t.name: t for t in (await session.list_tools()).tools}
|
| 324 |
+
if "compute_indicators" not in tools:
|
| 325 |
+
return None
|
| 326 |
+
while i < len(chunks):
|
| 327 |
+
names = chunks[i]
|
| 328 |
+
res = await call_tool(session, tools, "compute_indicators", indicators=names, **kw)
|
| 329 |
+
if isinstance(res, dict) and "error" not in res and extract_series(res, 0):
|
| 330 |
+
out["by_indicator"][f"c{i}"] = res
|
| 331 |
+
else: # parçada geçersiz ad var: tek tek dene
|
| 332 |
+
for name in names:
|
| 333 |
+
r1 = await call_tool(session, tools, "compute_indicators", indicators=[name], **kw)
|
| 334 |
+
if r1 is None or (isinstance(r1, dict) and "error" in r1):
|
| 335 |
+
out["failed"].append(name)
|
| 336 |
+
else:
|
| 337 |
+
out["by_indicator"][name] = r1
|
| 338 |
+
i += 1
|
| 339 |
+
except Exception as e: # noqa: BLE001
|
| 340 |
+
out["reconnects"] += 1
|
| 341 |
+
out["last_error"] = _root(e)
|
| 342 |
+
out["failed"] += [n for n in chunks[i] if n not in out["by_indicator"]] # çökertene dokunma, atla
|
| 343 |
+
i += 1
|
| 344 |
+
if out["reconnects"] > 6:
|
| 345 |
+
break
|
| 346 |
return out
|
| 347 |
|
| 348 |
|
|
|
|
| 815 |
|
| 816 |
# ----------------------------------------------------------------- Ana akış
|
| 817 |
async def run_async(symbol, timeframe, exchange, horizon, limit):
|
| 818 |
+
extra = {}
|
| 819 |
async with stdio_client(SERVER) as (r, w):
|
| 820 |
async with ClientSession(r, w) as session:
|
| 821 |
await session.initialize()
|
|
|
|
| 827 |
if isinstance(ohlcv, dict) and "error" in ohlcv:
|
| 828 |
raise RuntimeError(ohlcv["error"])
|
| 829 |
|
| 830 |
+
# Buradan sonrası opsiyonel: sunucu çökse bile elimizdeki mum verisiyle devam edilir
|
| 831 |
+
deep = None
|
| 832 |
+
try:
|
| 833 |
+
deep = await call_tool(session, tools, "deep_analyze", symbol=symbol,
|
| 834 |
+
timeframe=timeframe, exchange=exchange)
|
| 835 |
+
except Exception as e: # noqa: BLE001
|
| 836 |
+
extra["deep_analyze_error"] = _root(e)
|
| 837 |
for name in EXTRA_TOOLS:
|
| 838 |
if name not in tools:
|
| 839 |
continue
|
|
|
|
| 846 |
ci = tools.get("compute_indicators")
|
| 847 |
if ci is not None: # gerçek gösterge adlarını görebilmek için araç açıklaması
|
| 848 |
extra["_compute_indicators_description"] = (getattr(ci, "description", "") or "")[:4000]
|
| 849 |
+
|
| 850 |
+
# Göstergeler: ayrı Tickscope süreçleri (ana oturum kapandıktan sonra; DuckDB kilidi çakışmasın)
|
| 851 |
+
ind = None
|
| 852 |
+
try:
|
| 853 |
+
ind = await fetch_indicators(symbol, timeframe, exchange, int(limit))
|
| 854 |
+
except Exception as e: # noqa: BLE001
|
| 855 |
+
extra["indicators_error"] = _root(e)
|
| 856 |
+
if isinstance(ind, dict):
|
| 857 |
+
ser = extract_series(ind, 0)
|
| 858 |
+
extra["_ts_diag"] = {"seri_sayisi": len(ser),
|
| 859 |
+
"seri_uzunluklari": sorted({len(v) for v in ser.values()})[:10],
|
| 860 |
+
"yeniden_baglanma": ind.get("reconnects"), "son_hata": ind.get("last_error"),
|
| 861 |
+
"calismayan_adlar": ind.get("failed")}
|
| 862 |
return ohlcv, deep, ind, extra
|
| 863 |
|
| 864 |
|
|
|
|
| 885 |
except BaseException as e: # noqa: BLE001
|
| 886 |
import traceback
|
| 887 |
traceback.print_exc()
|
| 888 |
+
msg = _root(e)
|
| 889 |
+
hint = ""
|
| 890 |
+
if "closed" in msg.lower():
|
| 891 |
+
hint = ("\n\nMCP süreci kapandı. Terminaldeki Tickscope/uvx hata çıktısına bakın; "
|
| 892 |
+
"ayrıca aynı anda açık başka bir Tickscope süreci DuckDB kilidini tutuyor olabilir "
|
| 893 |
+
"(eski `uvx tickscope-mcp` süreçlerini kapatıp tekrar deneyin).")
|
| 894 |
+
return f"**Hata:** {msg}{hint}", None, ""
|
| 895 |
|
| 896 |
p, thr, bt = res["p_up"], res["thr"], res["bt"]
|
| 897 |
signal = "LONG" if p > thr else "SHORT" if p < 1 - thr else "NÖTR"
|
|
|
|
| 983 |
|
| 984 |
if __name__ == "__main__":
|
| 985 |
demo.launch()
|
|
|