fix trend,zt

This commit is contained in:
2026-09-06 13:12:48 +08:00
parent bcc6f02398
commit 2eafbb8303
15 changed files with 502 additions and 480 deletions

View File

@@ -13,36 +13,18 @@ from datetime import datetime
import config
from libs.calc import trading_time
from libs.market import market_allow_open
from libs.overview import Overview
from libs.signal import init_signals, SignalItem
from libs.collector import collector_push
from sdk import Client
from libs.grid_take_profit import GridTrailingTracker
from .order import OrderBook
from .watch import DipWatch
from .runtime import Runtime
from libs.order import OrderBook
from libs.watch import DipWatch
from libs.runtime import Runtime
from .open import open_signal
from .positions import manage_positions
def Overview(assets, positions, account_cfg=None) -> None:
"""记录策略启动时的账户、资金和持仓概览。"""
account_cfg = account_cfg or config.account_config
if account_cfg is not None:
log.info("[启动] 账户=%s,主机=%s,单笔金额=%.2f", account_cfg.account_id, account_cfg.host_key, account_cfg.buy_value)
if assets is not None:
log.info("[启动] 总资产=%.2f,可用资金=%.2f", assets.total, assets.available)
else:
log.warning("[启动] 获取资金概览失败")
for position in positions:
if position.volume <= 0:
continue
log.info("[启动] %s %s %s,持仓=%d,可用=%d,成本=%.2f(%.2f),现价=%.2f,盈亏=%.2f%%",position.trade_id, position.stock_code, position.stock_name, position.volume, position.can_use_volume, position.open_price,position.open_cost, position.last_price, position.profit_rate * 100)
def StartTrend() -> None:
"""初始化趋势策略,并以 30 秒间隔持续执行。"""
client = Client(
@@ -55,7 +37,7 @@ def StartTrend() -> None:
portfolio = client.portfolio()
assets = portfolio.assets
positions = list(portfolio.positions.values())
order_book = OrderBook()
order_book = OrderBook("trend")
order_book.refresh(client, portfolio.orders)
# 获取本策略的信号开仓数据
@@ -63,7 +45,12 @@ def StartTrend() -> None:
config.global_config,
config.account_config.signal_allow,
)
log.info("[启动] 趋势策略已启动,账户=%s,信号=%d,持仓=%d", config.account_config.account_id, len(signals), len(positions))
log.info(
"[启动] 趋势策略已启动,账户=%s,信号=%d,持仓=%d",
config.account_config.account_id,
len(signals),
len(positions),
)
executor = ThreadPoolExecutor(max_workers=3, thread_name_prefix="trend")
run = Runtime(
client=client,
@@ -101,7 +88,9 @@ def StartTrend() -> None:
try:
RunOnce(run, signals)
except Exception as e:
log.error(f"[Trend] 本 tick 执行失败,下一 tick 继续: {e}", exc_info=True)
log.error(
f"[Trend] 本 tick 执行失败,下一 tick 继续: {e}", exc_info=True
)
finally:
try:
if executor is not None:
@@ -110,13 +99,15 @@ def StartTrend() -> None:
client.close()
def RunOnce(run: Runtime, signals:list[SignalItem]) -> None:
def RunOnce(run: Runtime, signals: list[SignalItem]) -> None:
"""按固定步骤执行一轮趋势策略, ``RunOnce``。"""
if not trading_time(datetime.now()):
return
print("=" * 40 + f" Ticker {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} " +"=" * 40)
print(
"=" * 40 + f" Ticker {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} " + "=" * 40
)
started_at = time.monotonic()
# 1. 一次获取资产、持仓和订单,并清理过期订单。
@@ -131,21 +122,27 @@ def RunOnce(run: Runtime, signals:list[SignalItem]) -> None:
return
futures: list[tuple[str, Future]] = [
(
"数据提交",
run.executor.submit(
collector_push,
run.account_cfg.account_id,
assets,
positions,
),
)
]
(
"数据提交",
run.executor.submit(
collector_push,
run.account_cfg.account_id,
assets,
positions,
),
)
]
# 2. 验证可用资金;低于资金安全线时禁止开新仓。
allow_open_by_cash = assets.available >= assets.total * run.account_cfg.min_cash_ratio
allow_open_by_cash = (
assets.available >= assets.total * run.account_cfg.min_cash_ratio
)
if not allow_open_by_cash:
log.info("[Status] 禁止开仓:可用资金不足,可用=%.2f,总资产=%.2f", assets.available, assets.total)
log.info(
"[Status] 禁止开仓:可用资金不足,可用=%.2f,总资产=%.2f",
assets.available,
assets.total,
)
# 3. 获取大盘状态,只有大盘信号允许时才执行开仓。
market_ok = market_allow_open()
@@ -169,20 +166,37 @@ def RunOnce(run: Runtime, signals:list[SignalItem]) -> None:
log.exception("[行情] 获取行情失败,代码数量=%d", len(all_codes))
return
log.info("[RunOnce] 本轮就绪,持仓=%d,候选=%d,大盘允许=%s,资金允许=%s", len(positions), len(allow_open), market_ok, allow_open_by_cash)
log.info(
"[RunOnce] 本轮就绪,持仓=%d,候选=%d,大盘允许=%s,资金允许=%s",
len(positions),
len(allow_open),
market_ok,
allow_open_by_cash,
)
# 启动线程,开始计算
# 7. 持仓计算。
futures.append(("持仓计算",run.executor.submit(manage_positions,run,ticks,positions,market_ok,assets.available)))
futures.append(
(
"持仓计算",
run.executor.submit(
manage_positions, run, ticks, positions, market_ok, assets.available
),
)
)
# 8. 开仓计算:必须同时存在有效信号且大盘允许开仓。
if allow_open and market_ok and allow_open_by_cash:
futures.append(("开仓计算", run.executor.submit(open_signal, run, ticks, allow_open)))
futures.append(
("开仓计算", run.executor.submit(open_signal, run, ticks, allow_open))
)
# 9. 开始执行
for name, future in futures:
_wait_worker(name, future)
log.info("[RunOnce] 本轮完成,耗时=%d毫秒", int((time.monotonic() - started_at) * 1000))
log.info(
"[RunOnce] 本轮完成,耗时=%d毫秒", int((time.monotonic() - started_at) * 1000)
)
def _wait_worker(name: str, future: Future) -> None: