Files
auv/backend/services/mootdx.py
T
SakurasanandClaude 90569918a3 refactor: 删除板块资金流向,题材板块功能更全
- 删除前端 /sectors 页面、首页入口按钮、stock-api 板块类型与 fetchSectors
- 删除后端 /api/sectors 路由,main.py 移除注册
- eastmoney.py 移除板块数据段(_fetch_push2/_fetch_akshare/UT令牌管理),
  清理重复 import 与无用 datetime 子导入
- mootdx.py 移除板块降级方案(fetch_sector_list)
- routeTree.gen.ts 由 build 自动重新生成,移除 sectors 路由

题材热点/热点穿透/核心股已覆盖板块能力,功能更全,板块资金流向不再需要

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-11 18:50:54 +08:00

71 lines
2.1 KiB
Python

"""通达信数据源(mootdx TCP直连通达信服务器)
通过 TCP 协议直连通达信行情服务器,不走 HTTP,不会被限流。
主要用途:
- K线数据:主数据源(稳定可靠)
"""
import asyncio
from typing import Optional, List
def _get_market(code: str) -> str:
return "sh" if code.startswith("6") else "sz"
def _create_client():
from mootdx.quotes import Quotes
return Quotes.factory(market="std", multithread=True, heartbeat=True)
def _sync_fetch_kline(code: str, days: int) -> Optional[list]:
client = _create_client()
klines = client.bars(symbol=code, frequency=9, offset=min(days, 800))
if klines is None or len(klines) == 0:
return None
result = []
prev_close = 0.0
for bar in reversed(klines):
close = float(bar.close)
change_pct = 0
if prev_close > 0:
change_pct = (close - prev_close) / prev_close * 100
result.append(
{
"date": (
bar.datetime.strftime("%Y-%m-%d")
if hasattr(bar.datetime, "strftime")
else str(bar.datetime)[:10]
),
"open": float(bar.open),
"close": close,
"high": float(bar.high),
"low": float(bar.low),
"volume": int(bar.vol) if hasattr(bar, "vol") else 0,
"turnover": (
float(bar.amount) if hasattr(bar, "amount") and bar.amount else 0
),
"changePercent": round(change_pct, 2),
}
)
prev_close = close
result.sort(key=lambda x: x["date"])
return result
async def fetch_kline_history(code: str, days: int = 90) -> Optional[List[dict]]:
"""获取日K线(TCP直连通达信,主数据源)"""
try:
loop = asyncio.get_event_loop()
return await loop.run_in_executor(None, _sync_fetch_kline, code, days)
except ImportError:
return None
except Exception as e:
print(f"[mootdx] fetch_kline error: {e}")
return None