refactor QMT client and optimize API

This commit is contained in:
2026-08-28 22:46:04 +08:00
parent d09f271569
commit 29fee85b3d
18 changed files with 1239 additions and 519 deletions

View File

@@ -2,23 +2,25 @@
# -*- coding: utf-8 -*-
import logging as log
from logging.handlers import TimedRotatingFileHandler
import os
import sys
import time
import config
from dataclasses import dataclass
import yaml
import httpx
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
GLOBAL_CONFIG_PATH = os.path.join(PROJECT_ROOT, "etc", "_global.yaml")
if PROJECT_ROOT not in sys.path:
sys.path.insert(0, PROJECT_ROOT)
from sdk import Client
from sdk import APIError, Client
from strategy.trend.boot import StartTrend
@dataclass(frozen=True)
@dataclass(frozen=True, slots=True)
class StrategyDefinition:
mutex_scope: str
start_strategy: object
@@ -56,24 +58,47 @@ def check_single_instance(project_root: str) -> bool:
return False
def ping_api_host(
rpc_host: str,
retry_interval: float = 5.0,
connect_timeout: float = 3.0,
) -> None:
def wait_for_qmt_api(retry_interval: float = 5.0) -> None:
"""循环检查 API 地址,连通后才返回。"""
client = Client(config.global_config.qmt_base_url, config.global_config.qmt_token, config.HTTP_TIMEOUT)
while True:
retry_event = __import__("threading").Event()
while not retry_event.is_set():
try:
assets = client.assets()
client.assets()
log.info(f"API 服务已连通:{config.global_config.qmt_base_url}")
client.close()
return
except:
except (APIError, httpx.RequestError) as exc:
log.warning(
f"API 服务未就绪:{config.global_config.qmt_base_url}{retry_interval:g} 秒后重试"
"API 服务未就绪:%s%g 秒后重试%s",
config.global_config.qmt_base_url,
retry_interval,
exc,
)
time.sleep(retry_interval)
retry_event.wait(retry_interval)
def configure_logging(data_dir: str) -> None:
"""同时输出控制台日志和按天轮转的文本日志。"""
log_dir = os.path.join(data_dir, "logs")
os.makedirs(log_dir, exist_ok=True)
root = log.getLogger()
root.setLevel(log.INFO)
formatter = log.Formatter("%(asctime)s [%(levelname)s] %(message)s")
if not root.handlers:
console = log.StreamHandler()
console.setFormatter(formatter)
root.addHandler(console)
file_handler = TimedRotatingFileHandler(
os.path.join(log_dir, "py-client.log"),
when="midnight",
interval=1,
backupCount=30,
encoding="utf-8",
)
file_handler.setFormatter(formatter)
root.addHandler(file_handler)
def wait_for_any_key() -> None:
print("按任意键退出...", flush=True)
@@ -96,12 +121,12 @@ def main() -> int:
config.load()
if config.global_config is None or config.account_config is None:
raise RuntimeError("配置尚未加载,请先调用 config.load()")
ping_api_host(config.global_config.qmt_base_url)
configure_logging(config.global_config.qmt_data_dir)
wait_for_qmt_api()
STRATEGIES[config.account_config.strategy].start_strategy()
return 0
except (OSError, yaml.YAMLError, ValueError) as exc:
except (OSError, yaml.YAMLError, ValueError, RuntimeError, KeyError) as exc:
print(f"启动失败: {exc}", file=sys.stderr, flush=True)
wait_for_any_key()
return 1