GoshawkVortexAI commited on
Commit
a0044f2
·
verified ·
1 Parent(s): 234605d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +69 -40
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
- res = await call_tool(session, tools, "get_ohlcv", symbol=symbol, timeframe=timeframe,
135
- exchange=exchange, limit=page, until=end_ms)
 
 
 
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
- async def fetch_indicators(session, tools, symbol, timeframe, exchange, limit):
306
- """Önce hepsini tek çağrıda dener; geçersiz ad yüzünden hata olursa her göstergeyi ayrı çağırıp çalışanları toplar."""
307
- if "compute_indicators" not in tools:
308
- return None
 
 
 
309
  kw = dict(symbol=symbol, timeframe=timeframe, exchange=exchange, limit=limit, include_series=True)
310
- out = {"by_indicator": {}, "failed": [], "mode": None}
311
- try:
312
- res = await call_tool(session, tools, "compute_indicators", indicators=IND_NAMES, **kw)
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
- r = await call_tool(session, tools, "compute_indicators", indicators=[name], **kw)
324
- except Exception: # noqa: BLE001
325
- out["failed"].append(name)
326
- continue
327
- if r is None or (isinstance(r, dict) and "error" in r):
328
- out["failed"].append(name)
329
- continue
330
- out["by_indicator"][name] = r
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- # Tickscope'un kendi analizleri (opsiyonel, hata verirse atla)
815
- deep = await call_tool(session, tools, "deep_analyze", symbol=symbol,
816
- timeframe=timeframe, exchange=exchange)
817
- ind = await fetch_indicators(session, tools, symbol, timeframe, exchange, int(limit))
818
-
819
- # Tickscope'un diğer tüm analiz/piyasa araçları (canlı bağlam; şema uyuşmazsa hata olarak kaydedilir)
820
- extra = {}
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
- if isinstance(ind, dict):
834
- ser = extract_series(ind, 0)
835
- extra["_ts_diag"] = {"mod": ind.get("mode"), "seri_sayisi": len(ser),
836
- "seri_uzunluklari": sorted({len(v) for v in ser.values()})[:10],
837
- "calismayan_adlar": ind.get("failed")}
 
 
 
 
 
 
 
 
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
- return f"**Hata:** {_root(e)}", None, ""
 
 
 
 
 
 
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()