增加k线图
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user