feat: data-layering 第二批消费层读DB(divergence/staleness/accumulation/collect_eval/strategy_review/mo_provider/multi_timeframe/chip_factors)
This commit is contained in:
@@ -181,53 +181,38 @@ class MoDataProvider:
|
||||
|
||||
return None
|
||||
|
||||
# ── 分钟级 K 线 ──────────────────────────────────────────────
|
||||
|
||||
_last_minute_call = 0 # 限流时间戳
|
||||
# ── K 线(日级,读 DB stock_daily)────────────────────────────
|
||||
|
||||
def get_minute_kline(self, code: str, count: int = 60) -> list | None:
|
||||
"""获取1分钟K线数据(东方财富 push2)。
|
||||
|
||||
限流保护:每次调用间隔至少1秒,批量查询间隔2秒。
|
||||
"""获取K线数据(读 DB stock_daily,2026-08-26 分层铁律:消费层不直连东财push2)。
|
||||
|
||||
Args:
|
||||
code: 股票代码(6位,如'600519')
|
||||
count: 获取条数(最大240,约4小时)
|
||||
code: 股票代码(6位,如'600519';港股5位如'00700')
|
||||
count: 获取条数(最大240)
|
||||
|
||||
Returns:
|
||||
[{"time":"09:31","open":xx,"close":xx,"high":xx,"low":xx,"volume":xx,"amount":xx}, ...]
|
||||
[{"time":"YYYY-MM-DD","open":xx,"close":xx,"high":xx,"low":xx,"volume":xx,"amount":xx}, ...]
|
||||
或 None
|
||||
"""
|
||||
import time, urllib.request
|
||||
now = time.time()
|
||||
elapsed = now - self._last_minute_call
|
||||
if elapsed < 1.0:
|
||||
time.sleep(1.0 - elapsed)
|
||||
|
||||
# A股secid: 1.上海 0.深圳
|
||||
secid = f"1.{code}" if code.startswith(('6','5')) else f"0.{code}"
|
||||
url = (f"https://push2.eastmoney.com/api/qt/stock/kline/get"
|
||||
f"?secid={secid}&fields1=f1,f2,f3&fields2=f51,f52,f53,f54,f55,f56,f57"
|
||||
f"&klt=1&fqt=1&end=20500101&lmt={min(count, 240)}")
|
||||
|
||||
try:
|
||||
req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
|
||||
resp = urllib.request.urlopen(req, timeout=8)
|
||||
data = json.loads(resp.read())["data"]["klines"]
|
||||
import sqlite3
|
||||
conn = sqlite3.connect('/home/hmo/MoFin/data/mofin.db', timeout=5)
|
||||
rows = conn.execute(
|
||||
"SELECT date, open, close, high, low, volume, amount FROM stock_daily "
|
||||
"WHERE code=? ORDER BY date DESC LIMIT ?", (str(code), min(count, 240))
|
||||
).fetchall()
|
||||
conn.close()
|
||||
result = []
|
||||
for line in data:
|
||||
parts = line.split(",")
|
||||
if len(parts) >= 6:
|
||||
result.append({
|
||||
"time": parts[0][-5:], # "2026-07-01 09:31" → "09:31"
|
||||
"open": float(parts[1]),
|
||||
"close": float(parts[2]),
|
||||
"high": float(parts[3]),
|
||||
"low": float(parts[4]),
|
||||
"volume": int(parts[5]),
|
||||
"amount": float(parts[6]) if len(parts) > 6 else 0,
|
||||
})
|
||||
self._last_minute_call = time.time()
|
||||
for r in rows:
|
||||
result.append({
|
||||
"time": str(r[0]),
|
||||
"open": float(r[1]),
|
||||
"close": float(r[2]),
|
||||
"high": float(r[3]),
|
||||
"low": float(r[4]),
|
||||
"volume": int(r[5] or 0),
|
||||
"amount": float(r[6] or 0),
|
||||
})
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.warning("get_minute_kline(%s) 失败: %s", code, e)
|
||||
|
||||
Reference in New Issue
Block a user