feat: add quote sync command
This commit is contained in:
@@ -160,7 +160,7 @@ Redis 不可用时实测按设计降级放行;生产装配模式因本机 Milv
|
||||
3 warnings`,契约测试 `8 passed`,独立迁移库集成测试 `28 passed,1 skipped`,Ruff 和 MyPy 通过。
|
||||
真实验收:`159511` 与 `510500` 对比返回 `ready`、2 个产品和差异字段。实现提交:`b6429e0`。
|
||||
|
||||
阶段十六完成双源行情编排:新增 `MarketQuoteSyncService` 及三个行情健康/来源运行/告警表的 ORM
|
||||
阶段十六完成双源行情编排:新增 `MarketQuoteSyncService` 和 `tools/sync_advisor_market_quotes.py` 入口及三个行情健康/来源运行/告警表的 ORM
|
||||
映射,东方财富主源失败或部分返回时按优先级切换腾讯备用源;记录来源状态、连续失败次数、开放告警
|
||||
及恢复关闭,成功行情按字段精度量化后写入场内行情快照。真实独立库同步验证两源均失败时返回
|
||||
`degraded=true`、不写入伪行情并进入失败告警链路;本次无可用行情,推荐和动态配置继续失败关闭。
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
"""Refresh listed-fund quotes through the dual-source health pipeline."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import asyncio
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from app.service.market_quote_sync_service import MarketQuoteSyncService # noqa: E402
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="Sync listed Southern Fund market quotes")
|
||||
parser.add_argument(
|
||||
"--product-code", action="append", dest="product_codes",
|
||||
help="Limit sync to a product code; can be repeated",
|
||||
)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
async def run(args: argparse.Namespace) -> None:
|
||||
codes = tuple(args.product_codes) if args.product_codes else None
|
||||
result = await MarketQuoteSyncService().sync(product_codes=codes)
|
||||
print(
|
||||
f"sync_run_no={result['sync_run_no']} requested={result['requested_count']} "
|
||||
f"quotes={result['quote_count']} degraded={result['degraded']}"
|
||||
)
|
||||
for source in result["sources"]:
|
||||
print(
|
||||
f"source={source['source']} status={source['status']} "
|
||||
f"quotes={source['quote_count']} error={source['error_type']}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(run(parse_args()))
|
||||
Reference in New Issue
Block a user