This commit is contained in:
2026-08-31 15:33:39 +08:00
parent 1b6f5a9f03
commit 027d7e06eb
21 changed files with 208 additions and 84 deletions

View File

@@ -7,6 +7,7 @@ from __future__ import annotations
import logging
import time
from concurrent.futures import Future, ThreadPoolExecutor
from datetime import datetime
import config
@@ -25,9 +26,6 @@ from .positions import manage_positions
def Overview(assets, positions, account_cfg=None) -> None:
"""打印策略启动时的账户、资金和持仓概览。
该函数对应 Go 客户端 ``logic.Overview``。为便于单独测试,可以
显式传入账户配置;未传入时使用 ``config.account_config``。
"""
account_cfg = account_cfg or config.account_config
@@ -99,20 +97,24 @@ def StartTrend() -> None:
open_watch=DipWatch(),
add_watch=DipWatch(),
profit_tracker=GridTrailingTracker(config.account_config.grid_step_pct),
executor=ThreadPoolExecutor(max_workers=2, thread_name_prefix="trend"),
)
Overview(assets, positions, config.account_config)
while True:
started_at = time.monotonic()
try:
RunOnce(run, signals)
except Exception:
# 单轮错误只记录日志,下一轮仍继续运行。
logging.exception("趋势策略本轮执行失败")
try:
while True:
started_at = time.monotonic()
try:
RunOnce(run, signals)
except Exception:
# 单轮错误只记录日志,下一轮仍继续运行。
logging.exception("趋势策略本轮执行失败")
elapsed = time.monotonic() - started_at
time.sleep(max(0.0, 30.0 - elapsed))
elapsed = time.monotonic() - started_at
time.sleep(max(0.0, 30.0 - elapsed))
finally:
run.executor.shutdown(wait=True, cancel_futures=True)
def RunOnce(run: Runtime, signals:list[SignalItem]) -> None:
@@ -148,14 +150,7 @@ def RunOnce(run: Runtime, signals:list[SignalItem]) -> None:
logging.exception("获取持仓失败")
return
# 5. 更新状态机
try:
run.state.reconcile(positions, run.orders.data)
except Exception:
logging.exception("订单状态对账失败,本轮禁止自动交易")
return
# 6. 验证有效开仓信号:排除已有持仓和未决订单。
# 5. 验证有效开仓信号:排除已有持仓和未决订单。
allow_open: list[SignalItem] = []
allow_codes: list[str] = []
for signal in signals:
@@ -164,16 +159,48 @@ def RunOnce(run: Runtime, signals:list[SignalItem]) -> None:
allow_codes.append(signal.code)
# 6. 获取持仓和待开仓证券的实时行情 tick。
all_codes = allow_codes + position_codes
all_codes = list(dict.fromkeys(position_codes + allow_codes))
try:
ticks = run.client.full_tick(all_codes)
except Exception:
logging.exception("获取行情失败")
return
# 7. 执行开仓:必须同时存在有效信号且大盘允许开仓。
if allow_open and market_ok and allow_open_by_cash:
open_signal(run, ticks, allow_open)
# 7. 更新状态机
try:
run.state.reconcile(positions, run.orders.data)
except Exception:
logging.exception("订单状态对账失败,本轮禁止自动交易")
return
# 8. 持仓计算。当前 Go 版本的 managePositions 为空,保留扩展入口。
manage_positions(run, ticks, positions, market_ok,assets.available)
# 启动线程,开始计算
# 9. 持仓计算。
futures: list[tuple[str, Future]] = [
(
"持仓计算",
run.executor.submit(
manage_positions,
run,
ticks,
positions,
market_ok,
assets.available,
),
)
]
# 10. 开仓计算:必须同时存在有效信号且大盘允许开仓。
if allow_open and market_ok and allow_open_by_cash:
futures.append(("开仓计算", run.executor.submit(open_signal, run, ticks, allow_open)))
# 11. 开始执行
for name, future in futures:
_wait_worker(name, future)
def _wait_worker(name: str, future: Future) -> None:
"""保留单轮继续运行的语义,分别记录工作线程异常。"""
try:
future.result()
except Exception:
logging.exception("趋势策略%s线程失败", name)