fix zt&state.py
This commit is contained in:
@@ -2,14 +2,11 @@
|
||||
|
||||
import logging as log
|
||||
import time
|
||||
from contextlib import closing
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from concurrent.futures import Future, ThreadPoolExecutor
|
||||
import config
|
||||
from libs.calc import trading_time
|
||||
from libs.collector import collector_push
|
||||
from libs.grid_take_profit import GridTrailingTracker
|
||||
from libs.market import market_allow_open
|
||||
from libs.order import OrderBook
|
||||
@@ -18,9 +15,9 @@ from libs.runtime import Runtime
|
||||
from libs.signal import SignalItem, init_signals
|
||||
from libs.state import State
|
||||
from libs.watch import DipWatch
|
||||
from sdk import Client, DealItem, PositionItem
|
||||
from sdk import Client
|
||||
from .open import open_signal
|
||||
from .positions import manage_positions, t_rounds
|
||||
from .positions import manage_positions
|
||||
from libs.snapshot import cache_portfolio
|
||||
|
||||
|
||||
@@ -32,38 +29,35 @@ def StartZT() -> None:
|
||||
)
|
||||
executor = None
|
||||
try:
|
||||
portfolio = client.portfolio()
|
||||
assets = portfolio.assets
|
||||
positions = list(portfolio.positions.values())
|
||||
|
||||
state = State(Path(config.global_config.qmt_data_dir) / f'zt_{config.account_config.account_id}_state.db')
|
||||
executor = ThreadPoolExecutor(max_workers=2, thread_name_prefix="zt")
|
||||
run = Runtime(
|
||||
client=client, global_cfg=config.global_config, account_cfg=config.account_config,
|
||||
orders=OrderBook('zt'), open_watch=DipWatch(), add_watch=DipWatch(),
|
||||
profit_tracker=GridTrailingTracker(config.account_config.grid_step_pct),
|
||||
executor=executor
|
||||
)
|
||||
|
||||
# 获取本策略的信号开仓数据
|
||||
# 获取本策略的信号开仓数据
|
||||
signals = init_signals(
|
||||
config.global_config,
|
||||
config.account_config.signal_allow,
|
||||
)
|
||||
log.info(
|
||||
"[启动] Trend策略已启动,账户=%s,信号=%d,持仓=%d",
|
||||
config.account_config.account_id,
|
||||
len(signals),
|
||||
len(positions),
|
||||
)
|
||||
|
||||
initialize = not state.state and not state.deals
|
||||
deals = client.deals()
|
||||
portfolio = client.portfolio()
|
||||
if initialize and {d.order_sys_id: d for d in deals} != {
|
||||
d.order_sys_id: d for d in client.deals()
|
||||
}:
|
||||
raise RuntimeError('ZT 初始化期间成交发生变化,请重新启动')
|
||||
assets = portfolio.assets
|
||||
positions = list(portfolio.positions.values())
|
||||
log.info('[启动] ZT策略已启动,账户=%s,信号=%d,持仓=%d',
|
||||
config.account_config.account_id, len(signals), len(positions))
|
||||
cache_portfolio(config.account_config.account_id, assets, positions, deals)
|
||||
state.load()
|
||||
state.sync_deals(deals)
|
||||
state.sync_state(positions)
|
||||
state.archiving()
|
||||
state.sync_account(positions, deals, initialize=initialize)
|
||||
run.orders.refresh(client, portfolio.orders)
|
||||
Overview(assets, positions, config.account_config)
|
||||
executor = ThreadPoolExecutor(max_workers=2, thread_name_prefix="zt")
|
||||
|
||||
DEFAULT_TICK_INTERVAL = 30
|
||||
while True:
|
||||
@@ -118,8 +112,7 @@ def RunOnce(run: Runtime, state: State, signals: list[SignalItem]) -> None:
|
||||
positions = list(portfolio.positions.values())
|
||||
position_codes = list(portfolio.positions)
|
||||
|
||||
state.sync_deals(deals)
|
||||
state.archiving()
|
||||
state.sync_account(positions, deals)
|
||||
run.orders.refresh(run.client, portfolio.orders)
|
||||
except Exception:
|
||||
log.exception("[Portfolio] 刷新账户快照失败")
|
||||
@@ -143,7 +136,7 @@ def RunOnce(run: Runtime, state: State, signals: list[SignalItem]) -> None:
|
||||
allow_open: list[SignalItem] = []
|
||||
allow_codes: list[str] = []
|
||||
for signal in signals:
|
||||
if signal.code not in portfolio.positions:
|
||||
if signal.code not in portfolio.positions and signal.code not in state.blocked_codes:
|
||||
allow_open.append(signal)
|
||||
allow_codes.append(signal.code)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""趋势策略持仓止盈与分级补仓。"""
|
||||
|
||||
from dataclasses import dataclass
|
||||
import math
|
||||
|
||||
from libs.calc import calc_buy_volume, calculate_min_profit_rate
|
||||
from libs.grid_take_profit import GridState
|
||||
@@ -45,9 +46,9 @@ def manage_positions(
|
||||
continue
|
||||
if (
|
||||
not code
|
||||
or position.open_price <= 0
|
||||
or position.volume <= 0
|
||||
or tick is None
|
||||
or not math.isfinite(tick.last_price)
|
||||
or tick.last_price <= 0
|
||||
):
|
||||
log.warning(
|
||||
@@ -57,16 +58,24 @@ def manage_positions(
|
||||
)
|
||||
continue
|
||||
|
||||
if code in state.blocked_codes:
|
||||
log.warning('[Position] %s 状态待核对,暂停该证券交易', code)
|
||||
continue
|
||||
|
||||
posState = state.get_by_code(position.stock_code)
|
||||
if not posState:
|
||||
continue
|
||||
|
||||
volume = position.can_use_volume
|
||||
target_qty = posState.get('base_qty', 0)
|
||||
cost_price = position.open_price
|
||||
if posState.get('added_qty',0) >=100:
|
||||
volume = posState.get('added_qty',0)
|
||||
if posState.get('added_qty', 0) > 0:
|
||||
target_qty = posState['added_qty']
|
||||
cost_price = posState.get('added_price',0)
|
||||
|
||||
# 在途股份不影响已有可卖库存;补仓、底仓均受柜台可卖上限约束。
|
||||
volume = max(0, min(target_qty, position.can_use_volume, position.volume))
|
||||
if not math.isfinite(cost_price) or cost_price <= 0:
|
||||
log.warning('[Position] %s 成本无效,暂停该证券交易', code)
|
||||
continue
|
||||
|
||||
pnl_rate = round(
|
||||
(tick.last_price - cost_price) / cost_price * 100,
|
||||
@@ -86,7 +95,8 @@ def manage_positions(
|
||||
if runtime.account_cfg.enable_loss_add_position and market_ok:
|
||||
loss_decision = handle_loss(
|
||||
runtime=runtime,
|
||||
position=position,
|
||||
stock_code=position.stock_code,
|
||||
volume=volume,
|
||||
tick=tick,
|
||||
pnl_rate=pnl_rate,
|
||||
available=available,
|
||||
@@ -99,7 +109,7 @@ def manage_positions(
|
||||
strTag = "-"
|
||||
if pnl_rate >= minimum_profit:
|
||||
strTag = "↑"
|
||||
elif pnl_rate< LOSS_TIERS[0]:
|
||||
elif pnl_rate< LOSS_TIERS:
|
||||
strTag = "↓"
|
||||
|
||||
if strTag != "-":
|
||||
@@ -148,9 +158,8 @@ def handle_profit(
|
||||
if runtime.orders.busy(stock_code, "SELL"):
|
||||
return TradeDecision(False, "卖出委托处理中")
|
||||
|
||||
volume = volume % 100
|
||||
if volume <= 0:
|
||||
return TradeDecision(False, "无可用整手持仓")
|
||||
return TradeDecision(False, "无可用持仓")
|
||||
order_id = runtime.orders.new_order_id("zt","SELL")
|
||||
request = PlaceOrderRequest(
|
||||
op=OP_SELL,
|
||||
@@ -199,7 +208,7 @@ def handle_loss(
|
||||
if not runtime.orders.place(runtime.client, request):
|
||||
return TradeDecision(False, "补仓订单委托失败")
|
||||
|
||||
runtime.add_watch.forget(position.stock_code)
|
||||
runtime.add_watch.forget(stock_code)
|
||||
return TradeDecision(True, f"[补仓买入] {volume} 股,订单={order_id}", amount)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user