feat: 手续费仅CTP每日后台同步入库,前端只读展示
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+62
-63
@@ -1,4 +1,4 @@
|
||||
"""期货手续费:优先 CTP 柜台费率,本地/AKShare 为离线兜底。"""
|
||||
"""期货手续费:仅 CTP 柜台同步入库,前端只读展示。"""
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
@@ -37,6 +37,26 @@ def _get_db():
|
||||
return connect_db()
|
||||
|
||||
|
||||
def get_setting(key: str, default: str = "") -> str:
|
||||
conn = _get_db()
|
||||
row = conn.execute("SELECT value FROM settings WHERE key=?", (key,)).fetchone()
|
||||
conn.close()
|
||||
if not row:
|
||||
return default
|
||||
return (row["value"] or default) if row["value"] is not None else default
|
||||
|
||||
|
||||
def set_setting(key: str, value: str) -> None:
|
||||
conn = _get_db()
|
||||
conn.execute(
|
||||
"""INSERT INTO settings (key, value) VALUES (?,?)
|
||||
ON CONFLICT(key) DO UPDATE SET value=excluded.value""",
|
||||
(key, value),
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
def get_fee_multiplier() -> float:
|
||||
conn = _get_db()
|
||||
row = conn.execute(
|
||||
@@ -52,14 +72,20 @@ def get_fee_multiplier() -> float:
|
||||
|
||||
|
||||
def get_fee_source_mode() -> str:
|
||||
"""ctp=优先柜台同步费率;local=本地/AKShare 表。"""
|
||||
"""固定 CTP 柜台。"""
|
||||
return "ctp"
|
||||
|
||||
|
||||
def purge_non_ctp_fee_rates() -> int:
|
||||
"""删除非 CTP 来源的费率缓存。"""
|
||||
conn = _get_db()
|
||||
row = conn.execute(
|
||||
"SELECT value FROM settings WHERE key='fee_source_mode'"
|
||||
).fetchone()
|
||||
cur = conn.execute(
|
||||
"DELETE FROM fee_rates WHERE COALESCE(source, '') != 'ctp'"
|
||||
)
|
||||
n = cur.rowcount
|
||||
conn.commit()
|
||||
conn.close()
|
||||
mode = (row["value"] if row else "ctp") or "ctp"
|
||||
return mode if mode in ("ctp", "local") else "ctp"
|
||||
return n
|
||||
|
||||
|
||||
def _row_to_spec(row, mult: int) -> dict:
|
||||
@@ -84,46 +110,21 @@ def get_fee_spec(ths_code: str, *, trading_mode: str = "simulation") -> dict:
|
||||
return {**DEFAULT_FEE, "mult": spec["mult"], "product": "", "exchange": "", "source": "default"}
|
||||
|
||||
mult = get_contract_spec(ths_code)["mult"]
|
||||
source_mode = get_fee_source_mode()
|
||||
conn = _get_db()
|
||||
|
||||
if source_mode == "ctp":
|
||||
row = conn.execute(
|
||||
"SELECT * FROM fee_rates WHERE product=? AND source='ctp'",
|
||||
(product,),
|
||||
).fetchone()
|
||||
if not row:
|
||||
row = conn.execute(
|
||||
"SELECT * FROM fee_rates WHERE product=? ORDER BY CASE source WHEN 'ctp' THEN 0 ELSE 1 END",
|
||||
(product,),
|
||||
).fetchone()
|
||||
conn.close()
|
||||
if row:
|
||||
return _row_to_spec(row, mult)
|
||||
# 按需向 CTP 查询
|
||||
try:
|
||||
from ctp_fee_sync import sync_fee_for_symbol
|
||||
fields = sync_fee_for_symbol(trading_mode, ths_code)
|
||||
if fields:
|
||||
return {"product": product, **fields}
|
||||
except Exception:
|
||||
pass
|
||||
conn = _get_db()
|
||||
row = conn.execute(
|
||||
"SELECT * FROM fee_rates WHERE product=?", (product,)
|
||||
).fetchone()
|
||||
conn.close()
|
||||
if row:
|
||||
spec = _row_to_spec(row, mult)
|
||||
spec["source"] = spec.get("source") or "local_fallback"
|
||||
return spec
|
||||
else:
|
||||
row = conn.execute(
|
||||
"SELECT * FROM fee_rates WHERE product=?", (product,)
|
||||
).fetchone()
|
||||
conn.close()
|
||||
if row:
|
||||
return _row_to_spec(row, mult)
|
||||
row = conn.execute(
|
||||
"SELECT * FROM fee_rates WHERE product=? AND source='ctp'",
|
||||
(product,),
|
||||
).fetchone()
|
||||
conn.close()
|
||||
if row:
|
||||
return _row_to_spec(row, mult)
|
||||
try:
|
||||
from ctp_fee_sync import sync_fee_for_symbol
|
||||
fields = sync_fee_for_symbol(trading_mode, ths_code)
|
||||
if fields:
|
||||
return {"product": product, **fields}
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if product in _INDEX_PRODUCTS:
|
||||
return {
|
||||
@@ -287,6 +288,16 @@ def load_fee_rates_from_json(path: Optional[str] = None) -> int:
|
||||
return count
|
||||
|
||||
|
||||
def list_ctp_fee_rates() -> list:
|
||||
"""手续费页:仅展示 CTP 同步结果。"""
|
||||
conn = _get_db()
|
||||
rows = conn.execute(
|
||||
"SELECT * FROM fee_rates WHERE source='ctp' ORDER BY product"
|
||||
).fetchall()
|
||||
conn.close()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
def list_all_fee_rates() -> list:
|
||||
conn = _get_db()
|
||||
rows = conn.execute(
|
||||
@@ -297,28 +308,16 @@ def list_all_fee_rates() -> list:
|
||||
|
||||
|
||||
def list_fee_rates_for_ui() -> list:
|
||||
"""手续费页展示:CTP 模式下 ctp 来源优先排前。"""
|
||||
rows = list_all_fee_rates()
|
||||
if get_fee_source_mode() == "ctp":
|
||||
rows.sort(
|
||||
key=lambda r: (
|
||||
0 if (r.get("source") or "") == "ctp" else 1,
|
||||
r.get("product") or "",
|
||||
)
|
||||
)
|
||||
return rows
|
||||
return list_ctp_fee_rates()
|
||||
|
||||
|
||||
def count_fee_rates_by_source() -> dict[str, int]:
|
||||
conn = _get_db()
|
||||
rows = conn.execute(
|
||||
"SELECT source, COUNT(*) AS n FROM fee_rates GROUP BY source"
|
||||
).fetchall()
|
||||
n = conn.execute(
|
||||
"SELECT COUNT(*) FROM fee_rates WHERE source='ctp'"
|
||||
).fetchone()[0]
|
||||
conn.close()
|
||||
out: dict[str, int] = {}
|
||||
for row in rows:
|
||||
out[str(row["source"] or "local")] = int(row["n"] or 0)
|
||||
return out
|
||||
return {"ctp": int(n or 0)}
|
||||
|
||||
|
||||
def upsert_fee_rate(product: str, fields: dict) -> None:
|
||||
|
||||
Reference in New Issue
Block a user