refactor: 将共用代码迁入 lib/ 模块化目录

统一 strategy、key_monitor、trade、hub 等共用库到 lib/ 子包,并补充 lib-structure 文档,便于四所与中控维护。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-02 16:23:09 +08:00
parent 4742a0bb9d
commit 5797d49d8a
190 changed files with 27946 additions and 27499 deletions
+102 -102
View File
@@ -1,102 +1,102 @@
"""档案交易:strategy_trade_snapshots 补全 gate_bot 漏记。"""
from __future__ import annotations
import sqlite3
import tempfile
from datetime import datetime, timedelta
from pathlib import Path
from hub_trades_lib import fetch_trades_for_archive
def _init_db(path: Path) -> sqlite3.Connection:
conn = sqlite3.connect(str(path))
conn.row_factory = sqlite3.Row
conn.execute(
"""
CREATE TABLE trade_records (
id INTEGER PRIMARY KEY,
symbol TEXT,
direction TEXT,
result TEXT,
pnl_amount REAL,
opened_at TEXT,
closed_at TEXT,
opened_at_ms INTEGER,
closed_at_ms INTEGER,
created_at TEXT,
trend_plan_id INTEGER
)
"""
)
conn.execute(
"""
CREATE TABLE strategy_trade_snapshots (
id INTEGER PRIMARY KEY,
strategy_type TEXT,
source_id INTEGER,
symbol TEXT,
direction TEXT,
result_label TEXT,
status_at_close TEXT,
opened_at TEXT,
closed_at TEXT,
pnl_amount REAL,
snapshot_json TEXT,
created_at TEXT
)
"""
)
return conn
def test_merge_snapshot_when_trade_record_missing():
with tempfile.TemporaryDirectory() as td:
conn = _init_db(Path(td) / "t.db")
closed = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S")
conn.execute(
"""
INSERT INTO strategy_trade_snapshots (
id, strategy_type, source_id, symbol, direction,
result_label, opened_at, closed_at, pnl_amount, snapshot_json, created_at
) VALUES (?,?,?,?,?,?,?,?,?,?,?)
""",
(7, "trend_pullback", 42, "ONDO/USDT", "long", "止损", closed, closed, -1.2, "{}", closed),
)
conn.commit()
trades = fetch_trades_for_archive(conn, days=30, limit=50)
conn.close()
assert len(trades) == 1
assert trades[0]["symbol"] == "ONDO/USDT"
assert trades[0]["id"] == -7
assert trades[0].get("from_snapshot") is True
def test_skip_snapshot_when_trade_record_exists():
with tempfile.TemporaryDirectory() as td:
conn = _init_db(Path(td) / "t.db")
closed = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S")
conn.execute(
"""
INSERT INTO trade_records (
id, symbol, direction, result, pnl_amount,
opened_at, closed_at, opened_at_ms, closed_at_ms, created_at, trend_plan_id
) VALUES (?,?,?,?,?,?,?,?,?,?,?)
""",
(1, "ONDO/USDT", "long", "止损", -1.2, closed, closed, 1, 2, closed, 42),
)
conn.execute(
"""
INSERT INTO strategy_trade_snapshots (
id, strategy_type, source_id, symbol, direction,
result_label, opened_at, closed_at, pnl_amount, snapshot_json, created_at
) VALUES (?,?,?,?,?,?,?,?,?,?,?)
""",
(7, "trend_pullback", 42, "ONDO/USDT", "long", "止损", closed, closed, -1.2, "{}", closed),
)
conn.commit()
trades = fetch_trades_for_archive(conn, days=30, limit=50)
conn.close()
assert len(trades) == 1
assert trades[0]["id"] == 1
"""档案交易:strategy_trade_snapshots 补全 gate_bot 漏记。"""
from __future__ import annotations
import sqlite3
import tempfile
from datetime import datetime, timedelta
from pathlib import Path
from lib.hub.hub_trades_lib import fetch_trades_for_archive
def _init_db(path: Path) -> sqlite3.Connection:
conn = sqlite3.connect(str(path))
conn.row_factory = sqlite3.Row
conn.execute(
"""
CREATE TABLE trade_records (
id INTEGER PRIMARY KEY,
symbol TEXT,
direction TEXT,
result TEXT,
pnl_amount REAL,
opened_at TEXT,
closed_at TEXT,
opened_at_ms INTEGER,
closed_at_ms INTEGER,
created_at TEXT,
trend_plan_id INTEGER
)
"""
)
conn.execute(
"""
CREATE TABLE strategy_trade_snapshots (
id INTEGER PRIMARY KEY,
strategy_type TEXT,
source_id INTEGER,
symbol TEXT,
direction TEXT,
result_label TEXT,
status_at_close TEXT,
opened_at TEXT,
closed_at TEXT,
pnl_amount REAL,
snapshot_json TEXT,
created_at TEXT
)
"""
)
return conn
def test_merge_snapshot_when_trade_record_missing():
with tempfile.TemporaryDirectory() as td:
conn = _init_db(Path(td) / "t.db")
closed = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S")
conn.execute(
"""
INSERT INTO strategy_trade_snapshots (
id, strategy_type, source_id, symbol, direction,
result_label, opened_at, closed_at, pnl_amount, snapshot_json, created_at
) VALUES (?,?,?,?,?,?,?,?,?,?,?)
""",
(7, "trend_pullback", 42, "ONDO/USDT", "long", "止损", closed, closed, -1.2, "{}", closed),
)
conn.commit()
trades = fetch_trades_for_archive(conn, days=30, limit=50)
conn.close()
assert len(trades) == 1
assert trades[0]["symbol"] == "ONDO/USDT"
assert trades[0]["id"] == -7
assert trades[0].get("from_snapshot") is True
def test_skip_snapshot_when_trade_record_exists():
with tempfile.TemporaryDirectory() as td:
conn = _init_db(Path(td) / "t.db")
closed = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S")
conn.execute(
"""
INSERT INTO trade_records (
id, symbol, direction, result, pnl_amount,
opened_at, closed_at, opened_at_ms, closed_at_ms, created_at, trend_plan_id
) VALUES (?,?,?,?,?,?,?,?,?,?,?)
""",
(1, "ONDO/USDT", "long", "止损", -1.2, closed, closed, 1, 2, closed, 42),
)
conn.execute(
"""
INSERT INTO strategy_trade_snapshots (
id, strategy_type, source_id, symbol, direction,
result_label, opened_at, closed_at, pnl_amount, snapshot_json, created_at
) VALUES (?,?,?,?,?,?,?,?,?,?,?)
""",
(7, "trend_pullback", 42, "ONDO/USDT", "long", "止损", closed, closed, -1.2, "{}", closed),
)
conn.commit()
trades = fetch_trades_for_archive(conn, days=30, limit=50)
conn.close()
assert len(trades) == 1
assert trades[0]["id"] == 1