"""日内做 T 策略启动器。""" from __future__ import annotations import logging import time from datetime import datetime, time as clock_time import config from libs.calc import trading_time from libs.grid_take_profit import GridTrailingTracker from libs.market import market_allow_open from libs.signal import init_signals from sdk import Client from strategy.trend.order import OrderBook from strategy.trend.watch import DipWatch from .open import open_base from .positions import manage_positions from .runtime import Runtime from .state import TState def StartZT() -> None: client = Client(config.global_config.qmt_base_url, config.global_config.qmt_token, config.HTTP_TIMEOUT) orders = OrderBook() orders.refresh(client) _, positions = client.positions() state = TState.for_strategy(config.global_config.qmt_data_dir, config.account_config.strategy, config.account_config.account_id) state.reconcile(positions, orders.data, datetime.now().date().isoformat()) run = Runtime(client, config.global_config, config.account_config, state, orders, DipWatch(), GridTrailingTracker(config.account_config.grid_step_pct)) while True: started = time.monotonic() try: RunOnce(run) except Exception: logging.exception("ZT 策略本轮失败") time.sleep(max(0.0, 30.0 - (time.monotonic() - started))) def RunOnce(run: Runtime) -> None: if not trading_time(datetime.now()): return try: run.orders.refresh(run.client) assets = run.client.assets() position_codes, positions = run.client.positions() except Exception: logging.exception("[ZT] 刷新账户或订单失败") return today = datetime.now().date().isoformat() try: run.state.reconcile(positions, run.orders.data, today) except Exception: logging.exception("[ZT] 状态对账失败") return signals = init_signals(run.global_cfg, run.account_cfg.signal_allow) candidate_codes = [item.code for item in signals if item.code not in position_codes] codes = list(dict.fromkeys(position_codes + candidate_codes)) try: ticks = run.client.full_tick(codes) except Exception: logging.exception("[ZT] 获取行情失败") return market_ok = market_allow_open(run.global_cfg.api_host) if market_ok and assets.available >= assets.total * run.account_cfg.min_cash_ratio: open_base(run, ticks, signals) manage_positions( run, ticks, positions, assets.available, today, force_buy_back=datetime.now().time() >= clock_time(14, 50), )