增加k线图

This commit is contained in:
dekun
2026-05-22 13:47:27 +08:00
parent ee621976db
commit 74f98af40d
13 changed files with 543 additions and 8 deletions
+108
View File
@@ -46,6 +46,28 @@ def init_db() -> None:
success INTEGER NOT NULL,
message TEXT
);
CREATE TABLE IF NOT EXISTS daily_klines (
symbol TEXT NOT NULL,
open_time INTEGER NOT NULL,
open REAL NOT NULL,
high REAL NOT NULL,
low REAL NOT NULL,
close REAL NOT NULL,
volume REAL NOT NULL,
quote_volume REAL NOT NULL DEFAULT 0,
updated_at TEXT NOT NULL,
PRIMARY KEY (symbol, open_time)
);
CREATE INDEX IF NOT EXISTS idx_daily_klines_symbol
ON daily_klines(symbol, open_time);
CREATE TABLE IF NOT EXISTS kline_meta (
symbol TEXT PRIMARY KEY,
last_fetch_at TEXT NOT NULL,
bar_count INTEGER NOT NULL
);
"""
)
@@ -108,6 +130,92 @@ def log_push(period_start: str, period_end: str, success: bool, message: str = "
)
def save_daily_klines(symbol: str, candles: list[dict[str, Any]]) -> None:
sym = symbol.upper()
now = datetime.now().isoformat()
with get_conn() as conn:
for c in candles:
conn.execute(
"""
INSERT INTO daily_klines (
symbol, open_time, open, high, low, close, volume, quote_volume, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(symbol, open_time) DO UPDATE SET
open = excluded.open,
high = excluded.high,
low = excluded.low,
close = excluded.close,
volume = excluded.volume,
quote_volume = excluded.quote_volume,
updated_at = excluded.updated_at
""",
(
sym,
int(c["time"]),
float(c["open"]),
float(c["high"]),
float(c["low"]),
float(c["close"]),
float(c.get("volume", 0)),
float(c.get("quote_volume", 0)),
now,
),
)
conn.execute(
"""
INSERT INTO kline_meta (symbol, last_fetch_at, bar_count)
VALUES (?, ?, ?)
ON CONFLICT(symbol) DO UPDATE SET
last_fetch_at = excluded.last_fetch_at,
bar_count = excluded.bar_count
""",
(sym, now, len(candles)),
)
def get_daily_klines_from_db(symbol: str, limit: int) -> list[dict[str, Any]]:
sym = symbol.upper()
with get_conn() as conn:
rows = conn.execute(
"""
SELECT open_time, open, high, low, close, volume, quote_volume
FROM daily_klines
WHERE symbol = ?
ORDER BY open_time DESC
LIMIT ?
""",
(sym, limit),
).fetchall()
rows = list(reversed(rows))
return [
{
"time": int(r["open_time"]),
"open": float(r["open"]),
"high": float(r["high"]),
"low": float(r["low"]),
"close": float(r["close"]),
"volume": float(r["volume"]),
"quote_volume": float(r["quote_volume"]),
}
for r in rows
]
def get_kline_meta(symbol: str) -> dict[str, Any] | None:
sym = symbol.upper()
with get_conn() as conn:
row = conn.execute(
"SELECT last_fetch_at, bar_count FROM kline_meta WHERE symbol = ?",
(sym,),
).fetchone()
if not row:
return None
return {
"last_fetch_at": row["last_fetch_at"],
"bar_count": row["bar_count"],
}
def was_pushed_today(period_start: str, period_end: str) -> bool:
with get_conn() as conn:
row = conn.execute(