新增实盘策略:ITrendStrategy(SA)
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -6,7 +6,7 @@ from typing import Optional, Any, List, Dict
|
||||
|
||||
from src.core_data import Bar, Order
|
||||
from src.indicators.base_indicators import Indicator
|
||||
from src.indicators.indicators import Empty
|
||||
from src.indicators.indicators import Empty, ADX
|
||||
from src.strategies.base_strategy import Strategy
|
||||
|
||||
|
||||
@@ -97,6 +97,8 @@ class DualModeKalmanStrategy(Strategy):
|
||||
bar_history = self.get_bar_history()
|
||||
if len(bar_history) < max(self.atr_period, self.atr_lookback) + 2: return
|
||||
|
||||
self.cancel_all_pending_orders(symbol)
|
||||
|
||||
# --- 通用数据计算 ---
|
||||
highs = np.array([b.high for b in bar_history], dtype=float)
|
||||
lows = np.array([b.low for b in bar_history], dtype=float)
|
||||
@@ -196,6 +198,7 @@ class DualModeKalmanStrategy(Strategy):
|
||||
def evaluate_entry_signal(self, current_bar: Bar, kalman_price: float, current_atr: float):
|
||||
deviation = current_bar.close - kalman_price
|
||||
deviation_in_atr = deviation / current_atr
|
||||
self.log(f'deviation_in_atr: {deviation_in_atr:.4f}')
|
||||
|
||||
direction = None
|
||||
|
||||
@@ -219,7 +222,7 @@ class DualModeKalmanStrategy(Strategy):
|
||||
|
||||
if direction:
|
||||
self.log(
|
||||
f"{self.strategy_mode} Mode: Catalyst Fired. Direction: {direction}. Deviation: {deviation_in_atr:.2f} ATRs.")
|
||||
f"{self.strategy_mode} Mode: Catalyst Fired. Direction: {direction}. Deviation: {deviation_in_atr:.2f} ATRs., entry_threshold_atr: {self.entry_threshold_atr}")
|
||||
entry_price = current_bar.close + (1 if direction == "BUY" else -1)
|
||||
stop_loss_price = entry_price - self.initial_stop_atr_multiplier * current_atr if direction in ["BUY",
|
||||
"CLOSE_SHORT"] else entry_price + self.initial_stop_atr_multiplier * current_atr
|
||||
|
||||
@@ -1,177 +1,221 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import talib
|
||||
from collections import deque
|
||||
from typing import Optional, Any, List, Dict
|
||||
|
||||
from src.core_data import Bar, Order
|
||||
from src.indicators.base_indicators import Indicator
|
||||
from src.indicators.indicators import Empty
|
||||
from src.strategies.base_strategy import Strategy
|
||||
|
||||
|
||||
class TVDZScoreStrategy(Strategy):
|
||||
class DualModeKalmanStrategy(Strategy):
|
||||
"""
|
||||
内嵌 TVD (Condat 算法) + Z-Score ATR 的趋势突破策略。
|
||||
无任何外部依赖(如 pytv),纯 NumPy 实现。
|
||||
基于卡尔曼因子对称性的双模自适应策略
|
||||
|
||||
因子定义: Deviation = (Current_Close - Kalman_Price) / ATR
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
context: Any,
|
||||
main_symbol: str,
|
||||
enable_log: bool,
|
||||
trade_volume: int,
|
||||
tvd_lam: float = 50.0,
|
||||
atr_window: int = 14,
|
||||
z_window: int = 100,
|
||||
vol_threshold: float = -0.5,
|
||||
entry_threshold_atr: float = 3.0,
|
||||
stop_atr_multiplier: float = 3.0,
|
||||
order_direction: Optional[List[str]] = None,
|
||||
self,
|
||||
context: Any,
|
||||
main_symbol: str,
|
||||
enable_log: bool,
|
||||
trade_volume: int,
|
||||
strategy_mode: str = 'TREND', # 'TREND' 或 'REVERSION'
|
||||
kalman_process_noise: float = 0.01,
|
||||
kalman_measurement_noise: float = 0.5,
|
||||
atr_period: int = 23,
|
||||
atr_lookback: int = 100,
|
||||
atr_percentile_threshold: float = 25.0,
|
||||
entry_threshold_atr: float = 2.5, # 入场偏离倍数
|
||||
stop_loss_atr: float = 2.0, # 保护性硬止损倍数
|
||||
trend_trailing_atr: float = 2.5, # 趋势模式下卡尔曼轨道的宽度
|
||||
order_direction=None,
|
||||
indicators: Optional[List[Indicator]] = None,
|
||||
):
|
||||
super().__init__(context, main_symbol, enable_log)
|
||||
self.trade_volume = trade_volume
|
||||
self.order_direction = order_direction or ["BUY", "SELL"]
|
||||
self.tvd_lam = tvd_lam
|
||||
self.atr_window = atr_window
|
||||
self.z_window = z_window
|
||||
self.vol_threshold = vol_threshold
|
||||
self.entry_threshold_atr = entry_threshold_atr
|
||||
self.stop_atr_multiplier = stop_atr_multiplier
|
||||
|
||||
if order_direction is None:
|
||||
order_direction = ['BUY', 'SELL']
|
||||
self.strategy_mode = strategy_mode.upper()
|
||||
self.trade_volume = trade_volume
|
||||
self.atr_period = atr_period
|
||||
self.atr_lookback = atr_lookback
|
||||
self.atr_percentile_threshold = atr_percentile_threshold
|
||||
self.entry_threshold_atr = entry_threshold_atr
|
||||
self.stop_loss_atr = stop_loss_atr
|
||||
self.trend_trailing_atr = entry_threshold_atr
|
||||
|
||||
# 卡尔曼状态
|
||||
self.Q = kalman_process_noise
|
||||
self.R = kalman_measurement_noise
|
||||
self.P = 1.0
|
||||
self.x_hat = 0.0
|
||||
self.kalman_initialized = False
|
||||
|
||||
self._atr_history: deque = deque(maxlen=self.atr_lookback)
|
||||
self.position_meta: Dict[str, Any] = self.context.load_state()
|
||||
self.main_symbol = main_symbol
|
||||
self.order_id_counter = 0
|
||||
|
||||
self.log(f"TVDZScoreStrategy Initialized | λ={tvd_lam}, VolThresh={vol_threshold}")
|
||||
self.order_direction = order_direction
|
||||
if indicators is None:
|
||||
self.indicators = [Empty(), Empty()]
|
||||
else:
|
||||
self.indicators = indicators
|
||||
|
||||
@staticmethod
|
||||
def _tvd_condat(y, lam):
|
||||
"""Condat's O(N) TVD algorithm."""
|
||||
n = y.size
|
||||
if n == 0:
|
||||
return y.copy()
|
||||
x = y.astype(np.float64)
|
||||
k = 0
|
||||
k0 = 0
|
||||
vmin = x[0] - lam
|
||||
vmax = x[0] + lam
|
||||
for i in range(1, n):
|
||||
if x[i] < vmin:
|
||||
while k < i:
|
||||
x[k] = vmin
|
||||
k += 1
|
||||
k0 = i
|
||||
vmin = x[i] - lam
|
||||
vmax = x[i] + lam
|
||||
elif x[i] > vmax:
|
||||
while k < i:
|
||||
x[k] = vmax
|
||||
k += 1
|
||||
k0 = i
|
||||
vmin = x[i] - lam
|
||||
vmax = x[i] + lam
|
||||
else:
|
||||
vmin = max(vmin, x[i] - lam)
|
||||
vmax = min(vmax, x[i] + lam)
|
||||
if vmin > vmax:
|
||||
k = k0
|
||||
s = np.sum(x[k0:i+1])
|
||||
s /= (i - k0 + 1)
|
||||
x[k0:i+1] = s
|
||||
k = i + 1
|
||||
k0 = k
|
||||
if k0 < n:
|
||||
vmin = x[k0] - lam
|
||||
vmax = x[k0] + lam
|
||||
while k < n:
|
||||
x[k] = vmin
|
||||
k += 1
|
||||
return x
|
||||
|
||||
def _compute_zscore_atr_last(self, high, low, close) -> float:
|
||||
n = len(close)
|
||||
min_req = self.atr_window + self.z_window - 1
|
||||
if n < min_req:
|
||||
return np.nan
|
||||
start = max(0, n - (self.z_window + self.atr_window))
|
||||
seg_h, seg_l, seg_c = high[start:], low[start:], close[start:]
|
||||
atr_full = talib.ATR(seg_h, seg_l, seg_c, timeperiod=self.atr_window)
|
||||
atr_valid = atr_full[self.atr_window - 1:]
|
||||
if len(atr_valid) < self.z_window:
|
||||
return np.nan
|
||||
window_atr = atr_valid[-self.z_window:]
|
||||
mu = np.mean(window_atr)
|
||||
sigma = np.std(window_atr)
|
||||
last_atr = window_atr[-1]
|
||||
return (last_atr - mu) / sigma if sigma > 1e-12 else 0.0
|
||||
self.log(f"Initialized [{self.strategy_mode}] Mode with Kalman Symmetry.")
|
||||
|
||||
def on_open_bar(self, open_price: float, symbol: str):
|
||||
self.symbol = symbol
|
||||
bar_history = self.get_bar_history()
|
||||
if len(bar_history) < max(100, self.atr_window + self.z_window):
|
||||
return
|
||||
if len(bar_history) < max(self.atr_period, self.atr_lookback) + 2: return
|
||||
|
||||
closes = np.array([b.close for b in bar_history], dtype=np.float64)
|
||||
highs = np.array([b.high for b in bar_history], dtype=np.float64)
|
||||
lows = np.array([b.low for b in bar_history], dtype=np.float64)
|
||||
self.cancel_all_pending_orders(symbol)
|
||||
|
||||
# === TVD 平滑 ===
|
||||
tvd_prices = self._tvd_condat(closes, self.tvd_lam)
|
||||
tvd_price = tvd_prices[-1]
|
||||
# 1. 计算核心指标
|
||||
highs = np.array([b.high for b in bar_history], dtype=float)
|
||||
lows = np.array([b.low for b in bar_history], dtype=float)
|
||||
closes = np.array([b.close for b in bar_history], dtype=float)
|
||||
|
||||
# === Z-Score ATR ===
|
||||
current_atr = talib.ATR(highs, lows, closes, timeperiod=self.atr_window)[-1]
|
||||
if current_atr <= 0:
|
||||
return
|
||||
current_atr = talib.ATR(highs, lows, closes, self.atr_period)[-1]
|
||||
self._atr_history.append(current_atr)
|
||||
|
||||
deviation = closes[-1] - tvd_price
|
||||
deviation_in_atr = deviation / current_atr
|
||||
if current_atr <= 0 or len(self._atr_history) < self.atr_lookback: return
|
||||
|
||||
# 2. 更新卡尔曼滤波器
|
||||
if not self.kalman_initialized:
|
||||
self.x_hat = closes[-1]
|
||||
self.kalman_initialized = True
|
||||
|
||||
x_hat_minus = self.x_hat
|
||||
P_minus = self.P + self.Q
|
||||
K = P_minus / (P_minus + self.R)
|
||||
self.x_hat = x_hat_minus + K * (closes[-1] - x_hat_minus)
|
||||
self.P = (1 - K) * P_minus
|
||||
|
||||
kalman_price = self.x_hat
|
||||
# 3. 计算对称性因子:偏离度 (Deviation in ATR)
|
||||
deviation_in_atr = (closes[-1] - kalman_price) / current_atr
|
||||
|
||||
# 4. 状态校验与持仓管理
|
||||
position_volume = self.get_current_positions().get(self.symbol, 0)
|
||||
if position_volume != 0:
|
||||
self.manage_open_position(position_volume, bar_history[-1], current_atr, tvd_price)
|
||||
if self.trading:
|
||||
if position_volume != 0:
|
||||
self.manage_logic(position_volume, bar_history[-1], current_atr, kalman_price, deviation_in_atr)
|
||||
else:
|
||||
# 波动率过滤:只在波动率处于自身中高水平时入场
|
||||
# atr_threshold = np.percentile(list(self._atr_history), self.atr_percentile_threshold)
|
||||
# if current_atr >= atr_threshold:
|
||||
self.evaluate_entry_signal(bar_history[-1], deviation_in_atr, current_atr, open_price)
|
||||
|
||||
def manage_logic(self, volume: int, current_bar: Bar, current_atr: float, kalman_price: float, dev: float):
|
||||
"""
|
||||
基于对称因子的出场逻辑
|
||||
"""
|
||||
meta = self.position_meta.get(self.symbol)
|
||||
if not meta: return
|
||||
|
||||
# A. 保护性硬止损 (防止跳空或极端行情)
|
||||
initial_stop = meta.get('initial_stop_price', 0)
|
||||
if (volume > 0 and current_bar.low <= initial_stop) or (volume < 0 and current_bar.high >= initial_stop):
|
||||
self.log(f"Hard Stop Hit. Price: {current_bar.close}")
|
||||
self.close_position("CLOSE_LONG" if volume > 0 else "CLOSE_SHORT", abs(volume))
|
||||
return
|
||||
|
||||
# B. 对称因子出场逻辑
|
||||
if self.strategy_mode == 'TREND':
|
||||
if volume > 0:
|
||||
trend_floor = kalman_price - self.trend_trailing_atr * current_atr
|
||||
if dev < 0:
|
||||
self.log(f"TREND: Structural Floor Hit at {trend_floor:.4f}")
|
||||
self.close_position("CLOSE_LONG", abs(volume))
|
||||
else:
|
||||
trend_ceiling = kalman_price + self.trend_trailing_atr * current_atr
|
||||
if dev > 0:
|
||||
self.log(f"TREND: Structural Ceiling Hit at {trend_ceiling:.4f}")
|
||||
self.close_position("CLOSE_SHORT", abs(volume))
|
||||
|
||||
elif self.strategy_mode == 'REVERSION':
|
||||
# 回归模式:出场基于“均值修复成功”或“偏离失控止损”
|
||||
# 1. 目标达成:回归到均值附近 (止盈)
|
||||
if volume > 0:
|
||||
trend_floor = kalman_price - self.trend_trailing_atr * current_atr
|
||||
if dev > 0:
|
||||
self.log(f"TREND: Structural Floor Hit at {trend_floor:.4f}")
|
||||
self.close_position("CLOSE_LONG", abs(volume))
|
||||
else:
|
||||
trend_ceiling = kalman_price + self.trend_trailing_atr * current_atr
|
||||
if dev < 0:
|
||||
self.log(f"TREND: Structural Ceiling Hit at {trend_ceiling:.4f}")
|
||||
self.close_position("CLOSE_SHORT", abs(volume))
|
||||
|
||||
|
||||
def evaluate_entry_signal(self, current_bar: Bar, dev: float, current_atr: float, open_price: float):
|
||||
"""
|
||||
基于对称因子的入场逻辑
|
||||
"""
|
||||
direction = None
|
||||
if "BUY" in self.order_direction and deviation_in_atr > self.entry_threshold_atr:
|
||||
direction = "BUY"
|
||||
elif "SELL" in self.order_direction and deviation_in_atr < -self.entry_threshold_atr:
|
||||
direction = "SELL"
|
||||
|
||||
if self.strategy_mode == 'TREND':
|
||||
# 趋势:顺着偏离方向入场
|
||||
if dev > self.entry_threshold_atr and self.indicators[0].is_condition_met(*self.get_indicator_tuple()):
|
||||
direction = "BUY"
|
||||
elif dev < -self.entry_threshold_atr and self.indicators[1].is_condition_met(*self.get_indicator_tuple()):
|
||||
direction = "SELL"
|
||||
|
||||
elif self.strategy_mode == 'REVERSION':
|
||||
# 回归:逆着偏离方向入场
|
||||
if dev > self.entry_threshold_atr and self.indicators[1].is_condition_met(*self.get_indicator_tuple()):
|
||||
direction = "SELL" # 超买做空
|
||||
elif dev < -self.entry_threshold_atr and self.indicators[0].is_condition_met(*self.get_indicator_tuple()):
|
||||
direction = "BUY" # 超卖做多
|
||||
|
||||
if direction:
|
||||
self.log(f"Signal Fired | Dir: {direction}, Dev: {deviation_in_atr:.2f} ATR")
|
||||
entry_price = closes[-1]
|
||||
stop_loss = (
|
||||
entry_price - self.stop_atr_multiplier * current_atr
|
||||
if direction == "BUY"
|
||||
else entry_price + self.stop_atr_multiplier * current_atr
|
||||
)
|
||||
meta = {"entry_price": entry_price, "stop_loss": stop_loss}
|
||||
self.send_market_order(direction, self.trade_volume, "OPEN", meta)
|
||||
self.save_state(self.position_meta)
|
||||
# 使用最小变动单位修正价格(此处假设最小变动为0.5,实盘应从context获取)
|
||||
tick_size = 1
|
||||
entry_price = open_price
|
||||
|
||||
def manage_open_position(self, volume: int, current_bar: Bar, current_atr: float, tvd_price: float):
|
||||
meta = self.position_meta.get(self.symbol)
|
||||
if not meta:
|
||||
return
|
||||
stop_loss = meta["stop_loss"]
|
||||
if (volume > 0 and current_bar.low <= stop_loss) or (volume < 0 and current_bar.high >= stop_loss):
|
||||
self.log(f"Stop Loss Hit at {stop_loss:.4f}")
|
||||
self.close_position("CLOSE_LONG" if volume > 0 else "CLOSE_SHORT", abs(volume))
|
||||
# 设置保护性硬止损
|
||||
stop_offset = self.stop_loss_atr * current_atr
|
||||
stop_price = entry_price - stop_offset if direction == "BUY" else entry_price + stop_offset
|
||||
|
||||
meta = {'entry_price': entry_price, 'initial_stop_price': stop_price}
|
||||
self.log(f"Entry Signal: {self.strategy_mode} | {direction} | Dev: {dev:.2f}")
|
||||
self.send_custom_order(entry_price, direction, self.trade_volume, "OPEN", meta)
|
||||
|
||||
# --- 辅助函数 ---
|
||||
|
||||
def send_custom_order(self, price: float, direction: str, volume: int, offset: str, meta: Dict):
|
||||
self.position_meta[self.symbol] = meta
|
||||
order_type = "LIMIT"
|
||||
order_id = f"{self.symbol}_{direction}_{order_type}_{self.order_id_counter}"
|
||||
self.order_id_counter += 1
|
||||
|
||||
order = Order(
|
||||
id=order_id, symbol=self.symbol, direction=direction,
|
||||
volume=volume, price_type=order_type,
|
||||
submitted_time=self.get_current_time(), offset=offset, limit_price=price
|
||||
)
|
||||
self.send_order(order)
|
||||
self.save_state(self.position_meta)
|
||||
|
||||
def close_position(self, direction: str, volume: int):
|
||||
self.send_market_order(direction, volume, offset="CLOSE")
|
||||
if self.symbol in self.position_meta:
|
||||
del self.position_meta[self.symbol]
|
||||
self.save_state(self.position_meta)
|
||||
|
||||
def send_market_order(self, direction: str, volume: int, offset: str, meta: Optional[Dict] = None):
|
||||
if offset == "OPEN" and meta:
|
||||
self.position_meta[self.symbol] = meta
|
||||
order_id = f"{self.symbol}_{direction}_MARKET_{self.order_id_counter}"
|
||||
self.order_id_counter += 1
|
||||
order = Order(id=order_id, symbol=self.symbol, direction=direction, volume=volume,
|
||||
price_type="MARKET", submitted_time=self.get_current_time(), offset=offset)
|
||||
order = Order(
|
||||
id=order_id, symbol=self.symbol, direction=direction,
|
||||
volume=volume, price_type="MARKET",
|
||||
submitted_time=self.get_current_time(), offset="CLOSE"
|
||||
)
|
||||
self.send_order(order)
|
||||
self.position_meta.pop(self.symbol, None)
|
||||
self.save_state(self.position_meta)
|
||||
|
||||
def on_rollover(self, old_symbol: str, new_symbol: str):
|
||||
super().on_rollover(old_symbol, new_symbol)
|
||||
self.position_meta = {}
|
||||
self.log("Rollover: Strategy state reset.")
|
||||
self.kalman_initialized = False
|
||||
self._atr_history.clear()
|
||||
self.log("Rollover: States Reset.")
|
||||
|
||||
@@ -1,246 +0,0 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import talib
|
||||
from collections import deque
|
||||
from typing import Optional, Any, List, Dict, Tuple
|
||||
|
||||
from src.core_data import Bar, Order
|
||||
from src.indicators.base_indicators import Indicator
|
||||
from src.indicators.indicators import Empty
|
||||
from src.strategies.base_strategy import Strategy
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 策略实现 (ImbalanceZFlowStrategy)
|
||||
# =============================================================================
|
||||
|
||||
class ImbalanceZFlowStrategy(Strategy):
|
||||
"""
|
||||
一个基于稳态核心指标“Z-Flow”的纯粹动量策略。
|
||||
|
||||
核心哲学:
|
||||
1. 根本性解决稳态问题:先将原始imbalance序列通过Z-Score转化为
|
||||
稳态序列Z_I(t),所有后续分析都基于此坚实基础。
|
||||
2. 核心驱动 Z_Flow: 对稳态的Z_I(t)序列计算MACD,以度量“统计
|
||||
显著性”的动量,形成一个高质量的稳态振荡器。
|
||||
3. 真实的回测逻辑:所有开仓和风险计算都严格基于当前bar的open_price,
|
||||
杜绝前视偏差。
|
||||
4. 极致简洁:策略由单一指标、两个对称阈值驱动,逻辑纯粹,鲁棒性强。
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
context: Any,
|
||||
main_symbol: str,
|
||||
enable_log: bool,
|
||||
trade_volume: int,
|
||||
# --- 【霍克斯过程参数】 ---
|
||||
hawkes_lookback: int = 60,
|
||||
hawkes_alpha: float = 0.8,
|
||||
hawkes_beta: float = 0.2,
|
||||
# --- 【Z-Score 标准化参数】 ---
|
||||
z_score_period: int = 200,
|
||||
# --- 【Z-Flow 指标参数】 ---
|
||||
z_flow_fast_ema_period: int = 12,
|
||||
z_flow_slow_ema_period: int = 26,
|
||||
# --- 【交易阈值】 ---
|
||||
entry_threshold: float = 0.5,
|
||||
exit_threshold: float = 0.1,
|
||||
# --- 【风险管理】 ---
|
||||
atr_period: int = 20,
|
||||
stop_loss_atr_multiplier: float = 3.0,
|
||||
# --- 其他 ---
|
||||
order_direction: Optional[List[str]] = None,
|
||||
indicators: Optional[List[Indicator]] = None,
|
||||
):
|
||||
super().__init__(context, main_symbol, enable_log)
|
||||
if order_direction is None: order_direction = ['BUY', 'SELL']
|
||||
|
||||
# --- 参数赋值 ---
|
||||
self.trade_volume = trade_volume
|
||||
self.hawkes_lookback = hawkes_lookback
|
||||
self.hawkes_alpha = hawkes_alpha
|
||||
self.hawkes_beta = hawkes_beta
|
||||
self.z_score_period = z_score_period
|
||||
self.z_flow_fast_ema_period = z_flow_fast_ema_period
|
||||
self.z_flow_slow_ema_period = z_flow_slow_ema_period
|
||||
self.entry_threshold = entry_threshold
|
||||
self.exit_threshold = exit_threshold
|
||||
self.atr_period = atr_period
|
||||
self.stop_loss_atr_multiplier = stop_loss_atr_multiplier
|
||||
self.order_direction = order_direction
|
||||
|
||||
# --- 内部状态变量 ---
|
||||
self._imbalance_history: deque = deque(maxlen=self.z_score_period + self.z_flow_slow_ema_period)
|
||||
|
||||
# 核心指标
|
||||
self.z_flow = 0.0
|
||||
self.prev_z_flow = 0.0
|
||||
|
||||
self.position_meta: Dict[str, Any] = self.context.load_state()
|
||||
self.main_symbol = main_symbol
|
||||
self.order_id_counter = 0
|
||||
|
||||
if indicators is None: indicators = [Empty(), Empty()]
|
||||
self.indicators = indicators
|
||||
|
||||
self.log(f"ImbalanceZFlowStrategy Initialized")
|
||||
|
||||
def on_init(self):
|
||||
super().on_init()
|
||||
self.cancel_all_pending_orders(self.main_symbol)
|
||||
self.position_meta = self.context.load_state()
|
||||
|
||||
def on_open_bar(self, open_price: float, symbol: str):
|
||||
self.symbol = symbol
|
||||
bar_history = self.get_bar_history()
|
||||
required_bars = self._imbalance_history.maxlen + self.hawkes_lookback + 5
|
||||
if len(bar_history) < required_bars:
|
||||
return
|
||||
|
||||
self.prev_z_flow = self.z_flow
|
||||
|
||||
self._update_indicators_and_state(bar_history)
|
||||
|
||||
position_volume = self.get_current_positions().get(self.symbol, 0)
|
||||
self._sync_position_state(position_volume, symbol)
|
||||
|
||||
if not self.trading: return
|
||||
|
||||
if position_volume != 0:
|
||||
self.manage_open_position(position_volume, bar_history[-1])
|
||||
else:
|
||||
self.evaluate_entry_signal(open_price, bar_history) # 传入open_price
|
||||
|
||||
def _update_indicators_and_state(self, bar_history: List[Bar]):
|
||||
"""核心计算函数:I(t) -> Z_I(t) -> Z_Flow(t)"""
|
||||
# --- 1. 计算瞬时不均衡力量 I(t) ---
|
||||
long_events, short_events = [], []
|
||||
lookback_bars = bar_history[-self.hawkes_lookback:]
|
||||
for i, bar in enumerate(lookback_bars):
|
||||
event_age = len(lookback_bars) - 1 - i
|
||||
mark = (bar.high - bar.low) * bar.volume
|
||||
if mark > 0:
|
||||
if bar.close > bar.open:
|
||||
long_events.append({'age': event_age, 'mark': mark})
|
||||
elif bar.close < bar.open:
|
||||
short_events.append({'age': event_age, 'mark': mark})
|
||||
|
||||
lambda_long = sum(self.hawkes_alpha * e['mark'] * np.exp(-self.hawkes_beta * e['age']) for e in long_events)
|
||||
lambda_short = sum(self.hawkes_alpha * e['mark'] * np.exp(-self.hawkes_beta * e['age']) for e in short_events)
|
||||
imbalance = lambda_long - lambda_short
|
||||
self._imbalance_history.append(imbalance)
|
||||
|
||||
if len(self._imbalance_history) < self.z_score_period:
|
||||
self.z_flow = 0.0
|
||||
return
|
||||
|
||||
imbalance_series = pd.Series(list(self._imbalance_history))
|
||||
|
||||
# --- 2. Z-Score 标准化,得到稳态序列 Z_I(t) ---
|
||||
rolling_mean = imbalance_series.rolling(window=self.z_score_period).mean()
|
||||
rolling_std = imbalance_series.rolling(window=self.z_score_period).std()
|
||||
|
||||
# 避免除以零,并处理初始NaN值
|
||||
if rolling_std.iloc[-1] > 1e-9:
|
||||
z_score_series = (imbalance_series - rolling_mean) / rolling_std
|
||||
else:
|
||||
z_score_series = pd.Series(0.0, index=imbalance_series.index)
|
||||
|
||||
z_score_series.fillna(0.0, inplace=True)
|
||||
|
||||
# --- 3. 对稳态序列 Z_I(t) 计算MACD,得到 Z_Flow ---
|
||||
fast_ema = z_score_series.ewm(span=self.z_flow_fast_ema_period, adjust=False).mean()
|
||||
slow_ema = z_score_series.ewm(span=self.z_flow_slow_ema_period, adjust=False).mean()
|
||||
self.z_flow = fast_ema.iloc[-1] - slow_ema.iloc[-1]
|
||||
|
||||
def manage_open_position(self, volume: int, current_bar: Bar):
|
||||
"""由Z-Flow驱动的统一平仓逻辑,并辅以价格止损。"""
|
||||
meta = self.position_meta.get(self.symbol)
|
||||
if not meta: return
|
||||
|
||||
is_long = volume > 0
|
||||
|
||||
# 1. 价格硬止损
|
||||
stop_loss_price = meta['stop_loss_price']
|
||||
if (is_long and current_bar.low <= stop_loss_price) or \
|
||||
(not is_long and current_bar.high >= stop_loss_price):
|
||||
self.log(f"ATR Stop Loss Hit at {stop_loss_price:.4f}")
|
||||
self.close_position("CLOSE_LONG" if is_long else "CLOSE_SHORT", abs(volume))
|
||||
return
|
||||
|
||||
# 2. Z_Flow 驱动的平仓 (动能耗散)
|
||||
exit_triggered = False
|
||||
if is_long and self.z_flow < self.exit_threshold:
|
||||
exit_triggered = True
|
||||
elif not is_long and self.z_flow > -self.exit_threshold:
|
||||
exit_triggered = True
|
||||
|
||||
if exit_triggered:
|
||||
self.log(f"Z-Flow Dissipation Exit. Direction: {'LONG' if is_long else 'SHORT'}. "
|
||||
f"Z-Flow ({self.z_flow:.2f}) returned to neutral zone.")
|
||||
self.close_position("CLOSE_LONG" if is_long else "CLOSE_SHORT", abs(volume))
|
||||
|
||||
def evaluate_entry_signal(self, open_price: float, bar_history: List[Bar]):
|
||||
"""当Z-Flow穿越入场阈值时,在open_price开仓。"""
|
||||
direction = None
|
||||
if "BUY" in self.order_direction and self.prev_z_flow < self.entry_threshold <= self.z_flow:
|
||||
direction = "BUY"
|
||||
elif "SELL" in self.order_direction and self.prev_z_flow > -self.entry_threshold >= self.z_flow:
|
||||
direction = "SELL"
|
||||
|
||||
if direction:
|
||||
self.log(
|
||||
f"Z-Flow Signal: {direction}. Z-Flow: {self.z_flow:.2f} crossed threshold. Entry on Open: {open_price}")
|
||||
|
||||
# 使用完整的bar_history计算ATR
|
||||
highs = np.array([b.high for b in bar_history], dtype=float)
|
||||
lows = np.array([b.low for b in bar_history], dtype=float)
|
||||
closes = np.array([b.close for b in bar_history], dtype=float)
|
||||
current_atr = talib.ATR(highs, lows, closes, self.atr_period)[-1]
|
||||
|
||||
if current_atr <= 0: return
|
||||
|
||||
# ** 关键修正:基于 open_price 计算止损 **
|
||||
stop_loss_price = open_price - self.stop_loss_atr_multiplier * current_atr if direction == "BUY" \
|
||||
else open_price + self.stop_loss_atr_multiplier * current_atr
|
||||
|
||||
# ** 关键修正:记录 open_price 为入场价 **
|
||||
meta = {'entry_price': open_price, 'stop_loss_price': stop_loss_price}
|
||||
|
||||
self.send_market_order(direction, self.trade_volume, "OPEN", meta)
|
||||
self.save_state(self.position_meta)
|
||||
|
||||
# ... (辅助函数保持不变) ...
|
||||
def _sync_position_state(self, position_volume, symbol):
|
||||
meta = self.position_meta.get(symbol)
|
||||
if position_volume != 0 and not meta:
|
||||
self.log(f"警告:持仓({position_volume})与策略状态不一致!将强制平仓。", level='WARNING')
|
||||
self.close_position("CLOSE_LONG" if position_volume > 0 else "CLOSE_SHORT", abs(position_volume))
|
||||
return
|
||||
if position_volume == 0 and meta:
|
||||
self.log(f"信息:清理过时的策略状态。", level='INFO')
|
||||
self.position_meta.pop(symbol, None)
|
||||
self.save_state(self.position_meta)
|
||||
|
||||
def close_position(self, direction: str, volume: int):
|
||||
self.send_market_order(direction, volume, offset="CLOSE")
|
||||
if self.symbol in self.position_meta:
|
||||
self.position_meta.pop(self.symbol, None)
|
||||
self.save_state(self.position_meta)
|
||||
|
||||
def send_market_order(self, direction: str, volume: int, offset: str, meta: Optional[Dict] = None):
|
||||
if offset == "OPEN" and meta: self.position_meta[self.symbol] = meta
|
||||
order_id = f"{self.symbol}_{direction}_MARKET_{self.order_id_counter}"
|
||||
self.order_id_counter += 1
|
||||
order = Order(id=order_id, symbol=self.symbol, direction=direction, volume=volume, price_type="MARKET",
|
||||
submitted_time=self.get_current_time(), offset=offset)
|
||||
self.send_order(order)
|
||||
|
||||
def on_rollover(self, old_symbol: str, new_symbol: str):
|
||||
super().on_rollover(old_symbol, new_symbol)
|
||||
self.position_meta = {}
|
||||
self._imbalance_history.clear()
|
||||
self.z_flow = 0.0
|
||||
self.prev_z_flow = 0.0
|
||||
self.log("Rollover detected. All strategy states have been reset.")
|
||||
@@ -5,8 +5,8 @@
|
||||
"id": "522f09ca7b3fe929",
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-10-19T06:30:07.814040Z",
|
||||
"start_time": "2025-10-19T06:30:06.968311Z"
|
||||
"end_time": "2025-12-17T13:57:21.148878Z",
|
||||
"start_time": "2025-12-17T13:57:21.108622Z"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
@@ -23,15 +23,15 @@
|
||||
"\n"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 1
|
||||
"execution_count": 2
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"id": "c00ccfeec592844c",
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-10-19T06:30:08.226844Z",
|
||||
"start_time": "2025-10-19T06:30:07.822511Z"
|
||||
"end_time": "2025-12-17T13:57:21.519369Z",
|
||||
"start_time": "2025-12-17T13:57:21.150889Z"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
@@ -51,15 +51,15 @@
|
||||
"data_file_path = '/mnt/d/PyProject/NewQuant/data/data/KQ_m@SHFE_rb/KQ_m@SHFE_rb_min15.csv'\n"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 2
|
||||
"execution_count": 3
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"id": "7599fa7cd2cb3d45",
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-10-19T06:30:08.276053Z",
|
||||
"start_time": "2025-10-19T06:30:08.233422Z"
|
||||
"end_time": "2025-12-17T13:57:21.542513Z",
|
||||
"start_time": "2025-12-17T13:57:21.519369Z"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
@@ -76,8 +76,8 @@
|
||||
"# start_time = datetime(2021, 1, 1)\n",
|
||||
"# end_time = datetime(2025, 1, 1)\n",
|
||||
"\n",
|
||||
"start_time = datetime(2025, 6, 1)\n",
|
||||
"end_time = datetime(2025, 10, 1)\n",
|
||||
"start_time = datetime(2025, 10, 1)\n",
|
||||
"end_time = datetime(2025, 12, 1)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"indicators = INDICATOR_LIST\n",
|
||||
@@ -87,15 +87,15 @@
|
||||
"# data_manager.reset() # 首次运行不需要重置"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 3
|
||||
"execution_count": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"id": "f903fd2761d446cd",
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-10-19T06:30:51.160327Z",
|
||||
"start_time": "2025-10-19T06:30:08.282837Z"
|
||||
"end_time": "2025-12-17T13:57:22.373414Z",
|
||||
"start_time": "2025-12-17T13:57:21.550522Z"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
@@ -153,8 +153,6 @@
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/home/liaozhaorun/miniconda3/envs/quant/lib/python3.12/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).\n",
|
||||
" warnings.warn(\n",
|
||||
"在使用天勤量化之前,默认您已经知晓并同意以下免责条款,如果不同意请立即停止使用:https://www.shinnytech.com/blog/disclaimer/\n"
|
||||
]
|
||||
},
|
||||
@@ -162,236 +160,29 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"初始化数据管理器...\n",
|
||||
"数据加载成功: /mnt/d/PyProject/NewQuant/data/data/KQ_m@SHFE_rb/KQ_m@SHFE_rb_min15.csv\n",
|
||||
"数据范围从 2020-12-31 14:45:00 到 2025-08-14 09:30:00\n",
|
||||
"总计 25470 条记录。\n",
|
||||
"\n",
|
||||
"初始化回测引擎...\n",
|
||||
" INFO - TqSdk free 版剩余 0 天到期,如需续费或升级请访问 https://account.shinnytech.com/ 或联系相关工作人员。\n",
|
||||
"\n",
|
||||
"初始化 Tqsdk 回测引擎...\n",
|
||||
"内存仓储已初始化,管理ID: 'src.strategies.HawkesStrategy.KalmanStrategy2.DualModeKalmanStrategy_c7bd93715d42fbef1ec746ee2635a5d3'\n",
|
||||
"TqsdkContext: 初始化完成。\n",
|
||||
"TqsdkContext: 已设置引擎引用。\n",
|
||||
"TqsdkEngine: 初始化完成。\n",
|
||||
"\n",
|
||||
"开始运行回测...\n",
|
||||
"TqsdkEngine: 开始运行回测,从 2025-06-01 00:00:00 到 2025-10-01 00:00:00\n",
|
||||
"DualModeKalmanStrategy 策略初始化回调被调用。\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='BUY', volume=1, id='SHFE.rb2510_BUY_MARKET_0', price_type='LIMIT', limit_price=2995, stop_price=None, submitted_time=Timestamp('2025-06-26 22:30:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='BUY', volume=1, id='SHFE.rb2510_BUY_MARKET_0', price_type='LIMIT', limit_price=2995, stop_price=None, submitted_time=Timestamp('2025-06-26 22:30:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_insert_6d002815bde371e9679eeff6ab3a2913: 时间: 2025-06-26 22:30:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 2995.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_insert_6d002815bde371e9679eeff6ab3a2913: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='CLOSE_LONG', volume=1, id='SHFE.rb2510_CLOSE_LONG_MARKET_1', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-06-30 21:15:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='CLOSE_LONG', volume=1, id='SHFE.rb2510_CLOSE_LONG_MARKET_1', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-06-30 21:15:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_target_beee6bfdba88ae99ca624cd9f3ce2f3b: 时间: 2025-06-30 21:15:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 2987.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_target_beee6bfdba88ae99ca624cd9f3ce2f3b: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='BUY', volume=1, id='SHFE.rb2510_BUY_MARKET_2', price_type='LIMIT', limit_price=3014, stop_price=None, submitted_time=Timestamp('2025-07-01 21:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='BUY', volume=1, id='SHFE.rb2510_BUY_MARKET_2', price_type='LIMIT', limit_price=3014, stop_price=None, submitted_time=Timestamp('2025-07-01 21:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_insert_6dd75ae79e4ba3b47455ae5c7e77b734: 时间: 2025-07-01 21:15:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 3014.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_insert_6dd75ae79e4ba3b47455ae5c7e77b734: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='CLOSE_LONG', volume=1, id='SHFE.rb2510_CLOSE_LONG_MARKET_3', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-07-15 13:30:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='CLOSE_LONG', volume=1, id='SHFE.rb2510_CLOSE_LONG_MARKET_3', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-07-15 13:30:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_target_65fa28a9de53ea759cef7a640c9f33bb: 时间: 2025-07-15 13:30:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 3108.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_target_65fa28a9de53ea759cef7a640c9f33bb: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='BUY', volume=1, id='SHFE.rb2510_BUY_MARKET_4', price_type='LIMIT', limit_price=3180, stop_price=None, submitted_time=Timestamp('2025-07-18 21:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='BUY', volume=1, id='SHFE.rb2510_BUY_MARKET_4', price_type='LIMIT', limit_price=3180, stop_price=None, submitted_time=Timestamp('2025-07-18 21:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_insert_89a26adf3a52ec844c1e57271d827611: 时间: 2025-07-18 21:15:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 3180.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_insert_89a26adf3a52ec844c1e57271d827611: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='CLOSE_LONG', volume=1, id='SHFE.rb2510_CLOSE_LONG_MARKET_5', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-07-28 09:00:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='CLOSE_LONG', volume=1, id='SHFE.rb2510_CLOSE_LONG_MARKET_5', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-07-28 09:00:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_target_d6bf6ea9c1cbed5a7728d70d7c08c101: 时间: 2025-07-28 09:00:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 3249.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_target_d6bf6ea9c1cbed5a7728d70d7c08c101: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='BUY', volume=1, id='SHFE.rb2510_BUY_MARKET_6', price_type='LIMIT', limit_price=3320, stop_price=None, submitted_time=Timestamp('2025-07-29 11:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='BUY', volume=1, id='SHFE.rb2510_BUY_MARKET_6', price_type='LIMIT', limit_price=3320, stop_price=None, submitted_time=Timestamp('2025-07-29 11:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_insert_b61fde38f971505d50c793a95595d09b: 时间: 2025-07-29 11:15:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 3320.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_insert_b61fde38f971505d50c793a95595d09b: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='CLOSE_LONG', volume=1, id='SHFE.rb2510_CLOSE_LONG_MARKET_7', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-07-30 14:15:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='CLOSE_LONG', volume=1, id='SHFE.rb2510_CLOSE_LONG_MARKET_7', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-07-30 14:15:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_target_cd809e06343bde100900018193c8007c: 时间: 2025-07-30 14:15:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 3294.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_target_cd809e06343bde100900018193c8007c: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='SELL', volume=1, id='SHFE.rb2510_SELL_MARKET_8', price_type='LIMIT', limit_price=3278, stop_price=None, submitted_time=Timestamp('2025-07-30 21:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='SELL', volume=1, id='SHFE.rb2510_SELL_MARKET_8', price_type='LIMIT', limit_price=3278, stop_price=None, submitted_time=Timestamp('2025-07-30 21:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_insert_c4cd5e82c45ddd980c03c798dd7dfd57: 时间: 2025-07-30 21:15:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: SELL, 手数: 1, 价格: 3278.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_insert_c4cd5e82c45ddd980c03c798dd7dfd57: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='CLOSE_SHORT', volume=1, id='SHFE.rb2510_CLOSE_SHORT_MARKET_9', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-08-05 21:00:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='CLOSE_SHORT', volume=1, id='SHFE.rb2510_CLOSE_SHORT_MARKET_9', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-08-05 21:00:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_target_7cc7c97528cd3275b65f4b0d59e11b2d: 时间: 2025-08-05 21:00:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: BUY, 手数: 1, 价格: 3234.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_target_7cc7c97528cd3275b65f4b0d59e11b2d: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='SELL', volume=1, id='SHFE.rb2510_SELL_MARKET_10', price_type='LIMIT', limit_price=3209, stop_price=None, submitted_time=Timestamp('2025-08-13 21:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='SELL', volume=1, id='SHFE.rb2510_SELL_MARKET_10', price_type='LIMIT', limit_price=3209, stop_price=None, submitted_time=Timestamp('2025-08-13 21:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_insert_c1967ceb33977250525c7b5d50362f0f: 时间: 2025-08-13 21:15:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: SELL, 手数: 1, 价格: 3209.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_insert_c1967ceb33977250525c7b5d50362f0f: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2510', direction='CLOSE_SHORT', volume=1, id='SHFE.rb2510_CLOSE_SHORT_MARKET_11', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-08-22 21:30:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2510', direction='CLOSE_SHORT', volume=1, id='SHFE.rb2510_CLOSE_SHORT_MARKET_11', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-08-22 21:30:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_target_ef23037e39ab68f8630f354b07558822: 时间: 2025-08-22 21:30:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: BUY, 手数: 1, 价格: 3144.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_target_ef23037e39ab68f8630f354b07558822: 全部成交\n",
|
||||
"TqsdkEngine: 检测到换月信号!从 SHFE.rb2601 切换到 SHFE.rb2601\n",
|
||||
"回测结束:没有需要平仓的持仓。\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2601', direction='BUY', volume=1, id='SHFE.rb2601_BUY_MARKET_12', price_type='LIMIT', limit_price=3141, stop_price=None, submitted_time=Timestamp('2025-09-05 14:00:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2601', direction='BUY', volume=1, id='SHFE.rb2601_BUY_MARKET_12', price_type='LIMIT', limit_price=3141, stop_price=None, submitted_time=Timestamp('2025-09-05 14:00:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_insert_61c801ceffcb4703782d6de986bf3cd0: 时间: 2025-09-05 14:00:00.000000, 合约: SHFE.rb2601, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 3141.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_insert_61c801ceffcb4703782d6de986bf3cd0: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2601', direction='CLOSE_LONG', volume=1, id='SHFE.rb2601_CLOSE_LONG_MARKET_13', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-09-05 22:30:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2601', direction='CLOSE_LONG', volume=1, id='SHFE.rb2601_CLOSE_LONG_MARKET_13', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-09-05 22:30:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_target_989107326c47cd316aaea3e417db5127: 时间: 2025-09-05 22:30:00.000000, 合约: SHFE.rb2601, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 3121.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_target_989107326c47cd316aaea3e417db5127: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2601', direction='SELL', volume=1, id='SHFE.rb2601_SELL_MARKET_14', price_type='LIMIT', limit_price=3094, stop_price=None, submitted_time=Timestamp('2025-09-09 21:30:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2601', direction='SELL', volume=1, id='SHFE.rb2601_SELL_MARKET_14', price_type='LIMIT', limit_price=3094, stop_price=None, submitted_time=Timestamp('2025-09-09 21:30:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_insert_7393718e06ba6c2d616e278a16bddf3b: 时间: 2025-09-09 21:30:00.000000, 合约: SHFE.rb2601, 开平: OPEN, 方向: SELL, 手数: 1, 价格: 3094.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_insert_7393718e06ba6c2d616e278a16bddf3b: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2601', direction='CLOSE_SHORT', volume=1, id='SHFE.rb2601_CLOSE_SHORT_MARKET_15', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-09-10 09:45:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2601', direction='CLOSE_SHORT', volume=1, id='SHFE.rb2601_CLOSE_SHORT_MARKET_15', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-09-10 09:45:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_target_10f32ba307f98d1fae1a4d20dd088491: 时间: 2025-09-10 09:45:00.000000, 合约: SHFE.rb2601, 开平: CLOSETODAY, 方向: BUY, 手数: 1, 价格: 3110.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_target_10f32ba307f98d1fae1a4d20dd088491: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2601', direction='BUY', volume=1, id='SHFE.rb2601_BUY_MARKET_16', price_type='LIMIT', limit_price=3115, stop_price=None, submitted_time=Timestamp('2025-09-12 11:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2601', direction='BUY', volume=1, id='SHFE.rb2601_BUY_MARKET_16', price_type='LIMIT', limit_price=3115, stop_price=None, submitted_time=Timestamp('2025-09-12 11:15:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_insert_a9c25f5eca9c0209be2fb2c388cb2af3: 时间: 2025-09-12 11:15:00.000000, 合约: SHFE.rb2601, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 3115.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_insert_a9c25f5eca9c0209be2fb2c388cb2af3: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2601', direction='CLOSE_LONG', volume=1, id='SHFE.rb2601_CLOSE_LONG_MARKET_17', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-09-18 10:45:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2601', direction='CLOSE_LONG', volume=1, id='SHFE.rb2601_CLOSE_LONG_MARKET_17', price_type='MARKET', limit_price=None, stop_price=None, submitted_time=Timestamp('2025-09-18 10:45:00+0800', tz='Asia/Shanghai'), offset='CLOSE')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_target_09fedfe7f7f15b9362444fcd8ee381ca: 时间: 2025-09-18 10:45:00.000000, 合约: SHFE.rb2601, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 3134.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_target_09fedfe7f7f15b9362444fcd8ee381ca: 全部成交\n",
|
||||
"Context: 订单已加入队列: Order(symbol='SHFE.rb2601', direction='SELL', volume=1, id='SHFE.rb2601_SELL_MARKET_18', price_type='LIMIT', limit_price=3113, stop_price=None, submitted_time=Timestamp('2025-09-26 21:00:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
"Engine: 处理订单请求: Order(symbol='SHFE.rb2601', direction='SELL', volume=1, id='SHFE.rb2601_SELL_MARKET_18', price_type='LIMIT', limit_price=3113, stop_price=None, submitted_time=Timestamp('2025-09-26 21:00:00+0800', tz='Asia/Shanghai'), offset='OPEN')\n",
|
||||
" INFO - 模拟交易下单 TQSIM, PYSDK_insert_2f97ffcd51216e6c3767b412a2aac199: 时间: 2025-09-26 21:00:00.000000, 合约: SHFE.rb2601, 开平: OPEN, 方向: SELL, 手数: 1, 价格: 3113.0\n",
|
||||
" INFO - 模拟交易委托单 TQSIM, PYSDK_insert_2f97ffcd51216e6c3767b412a2aac199: 全部成交\n",
|
||||
" INFO - 回测结束\n",
|
||||
" INFO - 模拟交易成交记录, 账户: TQSIM\n",
|
||||
" INFO - 时间: 2025-06-26 22:30:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 2995.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-06-30 21:15:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 2987.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-07-01 21:15:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 3014.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-07-15 13:30:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 3108.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-07-18 21:15:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 3180.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-07-28 09:00:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 3249.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-07-29 11:15:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 3320.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-07-30 14:15:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 3294.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-07-30 21:15:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: SELL, 手数: 1, 价格: 3278.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-08-05 21:00:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: BUY, 手数: 1, 价格: 3234.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-08-13 21:15:00.000000, 合约: SHFE.rb2510, 开平: OPEN, 方向: SELL, 手数: 1, 价格: 3209.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-08-22 21:30:00.000000, 合约: SHFE.rb2510, 开平: CLOSE, 方向: BUY, 手数: 1, 价格: 3144.000,手续费: 2.98\n",
|
||||
" INFO - 时间: 2025-09-05 14:00:00.000000, 合约: SHFE.rb2601, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 3141.000,手续费: 3.05\n",
|
||||
" INFO - 时间: 2025-09-05 22:30:00.000000, 合约: SHFE.rb2601, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 3121.000,手续费: 3.05\n",
|
||||
" INFO - 时间: 2025-09-09 21:30:00.000000, 合约: SHFE.rb2601, 开平: OPEN, 方向: SELL, 手数: 1, 价格: 3094.000,手续费: 3.05\n",
|
||||
" INFO - 时间: 2025-09-10 09:45:00.000000, 合约: SHFE.rb2601, 开平: CLOSETODAY, 方向: BUY, 手数: 1, 价格: 3110.000,手续费: 3.05\n",
|
||||
" INFO - 时间: 2025-09-12 11:15:00.000000, 合约: SHFE.rb2601, 开平: OPEN, 方向: BUY, 手数: 1, 价格: 3115.000,手续费: 3.05\n",
|
||||
" INFO - 时间: 2025-09-18 10:45:00.000000, 合约: SHFE.rb2601, 开平: CLOSE, 方向: SELL, 手数: 1, 价格: 3134.000,手续费: 3.05\n",
|
||||
" INFO - 时间: 2025-09-26 21:00:00.000000, 合约: SHFE.rb2601, 开平: OPEN, 方向: SELL, 手数: 1, 价格: 3113.000,手续费: 3.05\n",
|
||||
" INFO - 模拟交易账户资金, 账户: TQSIM\n",
|
||||
" INFO - 日期: 2025-06-02, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-03, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-04, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-05, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-06, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-09, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-10, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-11, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-12, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-13, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-16, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-17, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-18, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-19, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-20, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-23, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-24, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-25, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-26, 账户权益: 10000000.00, 可用资金: 10000000.00, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-06-27, 账户权益: 9999997.03, 可用资金: 9997617.03, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 2.98, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-06-30, 账户权益: 10000017.03, 可用资金: 9997637.03, 浮动盈亏: 20.00, 持仓盈亏: 20.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-01, 账户权益: 9999914.05, 可用资金: 9999914.05, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: -100.00, 市值: 0.00, 保证金: 0.00, 手续费: 2.98, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-07-02, 账户权益: 10000421.08, 可用资金: 9998041.08, 浮动盈亏: 510.00, 持仓盈亏: 510.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 2.98, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-03, 账户权益: 10000531.08, 可用资金: 9998151.08, 浮动盈亏: 620.00, 持仓盈亏: 110.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-04, 账户权益: 10000491.08, 可用资金: 9998111.08, 浮动盈亏: 580.00, 持仓盈亏: -40.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-07, 账户权益: 10000381.08, 可用资金: 9998001.08, 浮动盈亏: 470.00, 持仓盈亏: -110.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-08, 账户权益: 10000401.08, 可用资金: 9998021.08, 浮动盈亏: 490.00, 持仓盈亏: 20.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-09, 账户权益: 10000401.08, 可用资金: 9998021.08, 浮动盈亏: 490.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-10, 账户权益: 10001001.08, 可用资金: 9998621.08, 浮动盈亏: 1090.00, 持仓盈亏: 600.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-11, 账户权益: 10001101.08, 可用资金: 9998721.08, 浮动盈亏: 1190.00, 持仓盈亏: 100.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-14, 账户权益: 10001151.08, 可用资金: 9998771.08, 浮动盈亏: 1240.00, 持仓盈亏: 50.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-15, 账户权益: 10000848.10, 可用资金: 10000848.10, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: -300.00, 市值: 0.00, 保证金: 0.00, 手续费: 2.98, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-07-16, 账户权益: 10000848.10, 可用资金: 10000848.10, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-07-17, 账户权益: 10000848.10, 可用资金: 10000848.10, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-07-18, 账户权益: 10000848.10, 可用资金: 10000848.10, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-07-21, 账户权益: 10001285.13, 可用资金: 9998905.13, 浮动盈亏: 440.00, 持仓盈亏: 440.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 2.98, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-22, 账户权益: 10002115.13, 可用资金: 9999735.13, 浮动盈亏: 1270.00, 持仓盈亏: 830.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-23, 账户权益: 10001785.13, 可用资金: 9999405.13, 浮动盈亏: 940.00, 持仓盈亏: -330.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-24, 账户权益: 10001985.13, 可用资金: 9999605.13, 浮动盈亏: 1140.00, 持仓盈亏: 200.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-25, 账户权益: 10002605.13, 可用资金: 10000225.13, 浮动盈亏: 1760.00, 持仓盈亏: 620.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-28, 账户权益: 10001532.15, 可用资金: 10001532.15, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: -1070.00, 市值: 0.00, 保证金: 0.00, 手续费: 2.98, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-07-29, 账户权益: 10001799.18, 可用资金: 9999419.18, 浮动盈亏: 270.00, 持仓盈亏: 270.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 2.98, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-07-30, 账户权益: 10001266.20, 可用资金: 10001266.20, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: -530.00, 市值: 0.00, 保证金: 0.00, 手续费: 2.98, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-07-31, 账户权益: 10001993.23, 可用资金: 9999613.23, 浮动盈亏: 730.00, 持仓盈亏: 730.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 2.98, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-08-01, 账户权益: 10002013.23, 可用资金: 9999633.23, 浮动盈亏: 750.00, 持仓盈亏: 20.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-08-04, 账户权益: 10002003.23, 可用资金: 9999623.23, 浮动盈亏: 740.00, 持仓盈亏: -10.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-08-05, 账户权益: 10001713.23, 可用资金: 9999333.23, 浮动盈亏: 450.00, 持仓盈亏: -290.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-08-06, 账户权益: 10001700.25, 可用资金: 10001700.25, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: -10.00, 市值: 0.00, 保证金: 0.00, 手续费: 2.98, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-08-07, 账户权益: 10001700.25, 可用资金: 10001700.25, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-08-08, 账户权益: 10001700.25, 可用资金: 10001700.25, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-08-11, 账户权益: 10001700.25, 可用资金: 10001700.25, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-08-12, 账户权益: 10001700.25, 可用资金: 10001700.25, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-08-13, 账户权益: 10001700.25, 可用资金: 10001700.25, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-08-14, 账户权益: 10001897.28, 可用资金: 9999517.28, 浮动盈亏: 200.00, 持仓盈亏: 200.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 2.98, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-08-15, 账户权益: 10001907.28, 可用资金: 9999527.28, 浮动盈亏: 210.00, 持仓盈亏: 10.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-08-18, 账户权益: 10002237.28, 可用资金: 9999857.28, 浮动盈亏: 540.00, 持仓盈亏: 330.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-08-19, 账户权益: 10002527.28, 可用资金: 10000147.28, 浮动盈亏: 830.00, 持仓盈亏: 290.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-08-20, 账户权益: 10002467.28, 可用资金: 10000087.28, 浮动盈亏: 770.00, 持仓盈亏: -60.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-08-21, 账户权益: 10002577.28, 可用资金: 10000197.28, 浮动盈亏: 880.00, 持仓盈亏: 110.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-08-22, 账户权益: 10002597.28, 可用资金: 10000217.28, 浮动盈亏: 900.00, 持仓盈亏: 20.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2380.00, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-08-25, 账户权益: 10002344.30, 可用资金: 10002344.30, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: -250.00, 市值: 0.00, 保证金: 0.00, 手续费: 2.98, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-08-26, 账户权益: 10002344.30, 可用资金: 10002344.30, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-08-27, 账户权益: 10002344.30, 可用资金: 10002344.30, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-08-28, 账户权益: 10002344.30, 可用资金: 10002344.30, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-08-29, 账户权益: 10002344.30, 可用资金: 10002344.30, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-01, 账户权益: 10002344.30, 可用资金: 10002344.30, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-02, 账户权益: 10002344.30, 可用资金: 10002344.30, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-03, 账户权益: 10002344.30, 可用资金: 10002344.30, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-04, 账户权益: 10002344.30, 可用资金: 10002344.30, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-05, 账户权益: 10002361.25, 可用资金: 9999924.45, 浮动盈亏: 20.00, 持仓盈亏: 20.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2436.80, 手续费: 3.05, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-09-08, 账户权益: 10002138.21, 可用资金: 10002138.21, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: -220.00, 市值: 0.00, 保证金: 0.00, 手续费: 3.05, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-09, 账户权益: 10002138.21, 可用资金: 10002138.21, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-10, 账户权益: 10001972.12, 可用资金: 10001972.12, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: -160.00, 市值: 0.00, 保证金: 0.00, 手续费: 6.09, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-11, 账户权益: 10001972.12, 可用资金: 10001972.12, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-12, 账户权益: 10002089.07, 可用资金: 9999652.27, 浮动盈亏: 120.00, 持仓盈亏: 120.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2436.80, 手续费: 3.05, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-09-15, 账户权益: 10002179.07, 可用资金: 9999742.27, 浮动盈亏: 210.00, 持仓盈亏: 90.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2436.80, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-09-16, 账户权益: 10002479.07, 可用资金: 10000042.27, 浮动盈亏: 510.00, 持仓盈亏: 300.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2436.80, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-09-17, 账户权益: 10002499.07, 可用资金: 10000062.27, 浮动盈亏: 530.00, 持仓盈亏: 20.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2436.80, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-09-18, 账户权益: 10002156.02, 可用资金: 10002156.02, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: -340.00, 市值: 0.00, 保证金: 0.00, 手续费: 3.05, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-19, 账户权益: 10002156.02, 可用资金: 10002156.02, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-22, 账户权益: 10002156.02, 可用资金: 10002156.02, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-23, 账户权益: 10002156.02, 可用资金: 10002156.02, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-24, 账户权益: 10002156.02, 可用资金: 10002156.02, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-25, 账户权益: 10002156.02, 可用资金: 10002156.02, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-26, 账户权益: 10002156.02, 可用资金: 10002156.02, 浮动盈亏: 0.00, 持仓盈亏: 0.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 0.00, 手续费: 0.00, 风险度: 0.00%\n",
|
||||
" INFO - 日期: 2025-09-29, 账户权益: 10002312.98, 可用资金: 9999876.18, 浮动盈亏: 160.00, 持仓盈亏: 160.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2436.80, 手续费: 3.05, 风险度: 0.02%\n",
|
||||
" INFO - 日期: 2025-09-30, 账户权益: 10002562.98, 可用资金: 10000126.18, 浮动盈亏: 410.00, 持仓盈亏: 250.00, 平仓盈亏: 0.00, 市值: 0.00, 保证金: 2436.80, 手续费: 0.00, 风险度: 0.02%\n",
|
||||
" INFO - 胜率: 55.56%, 盈亏额比例: 3.33, 收益率: 0.03%, 年化收益率: 0.07%, 最大回撤: 0.01%, 年化夏普率: -63.7079,年化索提诺比率: -15.3458\n",
|
||||
"回测结束:开始平仓所有剩余持仓...\n",
|
||||
"TqsdkEngine: 回测运行完毕。\n",
|
||||
"TqsdkEngine: API 已关闭。\n",
|
||||
"\n",
|
||||
"回测运行完毕。\n"
|
||||
"初始化数据管理器...\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "KeyError",
|
||||
"evalue": "'initial_capital'",
|
||||
"ename": "FileNotFoundError",
|
||||
"evalue": "数据文件未找到: /mnt/d/PyProject/NewQuant/data/data/KQ_m@SHFE_rb/KQ_m@SHFE_rb_min15.csv",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001B[31m---------------------------------------------------------------------------\u001B[39m",
|
||||
"\u001B[31mKeyError\u001B[39m Traceback (most recent call last)",
|
||||
"\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[4]\u001B[39m\u001B[32m, line 47\u001B[39m\n\u001B[32m 45\u001B[39m portfolio_snapshots = results[\u001B[33m\"\u001B[39m\u001B[33mportfolio_snapshots\u001B[39m\u001B[33m\"\u001B[39m]\n\u001B[32m 46\u001B[39m trade_history = results[\u001B[33m\"\u001B[39m\u001B[33mtrade_history\u001B[39m\u001B[33m\"\u001B[39m]\n\u001B[32m---> \u001B[39m\u001B[32m47\u001B[39m initial_capital_result = \u001B[43mresults\u001B[49m\u001B[43m[\u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43minitial_capital\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m]\u001B[49m\n\u001B[32m 48\u001B[39m bars = results[\u001B[33m\"\u001B[39m\u001B[33mall_bars\u001B[39m\u001B[33m\"\u001B[39m]\n",
|
||||
"\u001B[31mKeyError\u001B[39m: 'initial_capital'"
|
||||
"\u001B[31mFileNotFoundError\u001B[39m Traceback (most recent call last)",
|
||||
"\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[5]\u001B[39m\u001B[32m, line 7\u001B[39m\n\u001B[32m 5\u001B[39m \u001B[38;5;66;03m# --- 1. 初始化数据管理器 ---\u001B[39;00m\n\u001B[32m 6\u001B[39m \u001B[38;5;28mprint\u001B[39m(\u001B[33m\"\u001B[39m\u001B[33m初始化数据管理器...\u001B[39m\u001B[33m\"\u001B[39m)\n\u001B[32m----> \u001B[39m\u001B[32m7\u001B[39m data_manager = \u001B[43mDataManager\u001B[49m\u001B[43m(\u001B[49m\u001B[43mfile_path\u001B[49m\u001B[43m=\u001B[49m\u001B[43mdata_file_path\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43msymbol\u001B[49m\u001B[43m=\u001B[49m\u001B[43mglobal_config\u001B[49m\u001B[43m[\u001B[49m\u001B[33;43m'\u001B[39;49m\u001B[33;43msymbol\u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstart_time\u001B[49m\u001B[43m=\u001B[49m\u001B[43mstart_time\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 8\u001B[39m \u001B[43m \u001B[49m\u001B[43mend_time\u001B[49m\u001B[43m=\u001B[49m\u001B[43mend_time\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 10\u001B[39m strategy_parameters = {\n\u001B[32m 11\u001B[39m \u001B[33m'\u001B[39m\u001B[33mmain_symbol\u001B[39m\u001B[33m'\u001B[39m: \u001B[33m'\u001B[39m\u001B[33mrb\u001B[39m\u001B[33m'\u001B[39m, \u001B[38;5;66;03m# <-- 替换为你的交易品种代码,例如 'GC=F' (黄金期货), 'ZC=F' (玉米期货)\u001B[39;00m\n\u001B[32m 12\u001B[39m \u001B[33m'\u001B[39m\u001B[33mtrade_volume\u001B[39m\u001B[33m'\u001B[39m: \u001B[32m1\u001B[39m,\n\u001B[32m (...)\u001B[39m\u001B[32m 15\u001B[39m \u001B[33m'\u001B[39m\u001B[33menable_log\u001B[39m\u001B[33m'\u001B[39m: \u001B[38;5;28;01mFalse\u001B[39;00m\n\u001B[32m 16\u001B[39m }\n\u001B[32m 20\u001B[39m \u001B[38;5;66;03m# --- 2. 初始化回测引擎并运行 ---\u001B[39;00m\n",
|
||||
"\u001B[36mFile \u001B[39m\u001B[32mD:\\PyProject\\NewQuant\\src\\data_manager.py:22\u001B[39m, in \u001B[36mDataManager.__init__\u001B[39m\u001B[34m(self, file_path, symbol, tz, start_time, end_time)\u001B[39m\n\u001B[32m 20\u001B[39m \u001B[38;5;28mself\u001B[39m.file_path = file_path\n\u001B[32m 21\u001B[39m \u001B[38;5;28mself\u001B[39m.tz = tz\n\u001B[32m---> \u001B[39m\u001B[32m22\u001B[39m \u001B[38;5;28mself\u001B[39m.raw_df = \u001B[43mload_raw_data\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mfile_path\u001B[49m\u001B[43m)\u001B[49m \u001B[38;5;66;03m# 调用函数式加载数据\u001B[39;00m\n\u001B[32m 24\u001B[39m \u001B[38;5;28mself\u001B[39m.start_time = start_time\n\u001B[32m 25\u001B[39m \u001B[38;5;28mself\u001B[39m.end_time = end_time\n",
|
||||
"\u001B[36mFile \u001B[39m\u001B[32mD:\\PyProject\\NewQuant\\src\\data_processing.py:28\u001B[39m, in \u001B[36mload_raw_data\u001B[39m\u001B[34m(file_path)\u001B[39m\n\u001B[32m 11\u001B[39m \u001B[38;5;250m\u001B[39m\u001B[33;03m\"\"\"\u001B[39;00m\n\u001B[32m 12\u001B[39m \u001B[33;03m从 CSV 文件加载原始数据,并进行初步的数据类型处理。\u001B[39;00m\n\u001B[32m 13\u001B[39m \u001B[33;03m假设 datetime 列已经是北京时间,无需额外时区转换或本地化。\u001B[39;00m\n\u001B[32m (...)\u001B[39m\u001B[32m 25\u001B[39m \u001B[33;03m KeyError: 如果CSV中缺少必要的列。\u001B[39;00m\n\u001B[32m 26\u001B[39m \u001B[33;03m\"\"\"\u001B[39;00m\n\u001B[32m 27\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m os.path.exists(file_path):\n\u001B[32m---> \u001B[39m\u001B[32m28\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mFileNotFoundError\u001B[39;00m(\u001B[33mf\u001B[39m\u001B[33m\"\u001B[39m\u001B[33m数据文件未找到: \u001B[39m\u001B[38;5;132;01m{\u001B[39;00mfile_path\u001B[38;5;132;01m}\u001B[39;00m\u001B[33m\"\u001B[39m)\n\u001B[32m 30\u001B[39m \u001B[38;5;66;03m# 定义期望的列名,用于检查和选择\u001B[39;00m\n\u001B[32m 31\u001B[39m expected_cols = [\u001B[33m'\u001B[39m\u001B[33mdatetime\u001B[39m\u001B[33m'\u001B[39m, \u001B[33m'\u001B[39m\u001B[33mopen\u001B[39m\u001B[33m'\u001B[39m, \u001B[33m'\u001B[39m\u001B[33mhigh\u001B[39m\u001B[33m'\u001B[39m, \u001B[33m'\u001B[39m\u001B[33mlow\u001B[39m\u001B[33m'\u001B[39m, \u001B[33m'\u001B[39m\u001B[33mclose\u001B[39m\u001B[33m'\u001B[39m, \u001B[33m'\u001B[39m\u001B[33mvolume\u001B[39m\u001B[33m'\u001B[39m, \u001B[33m'\u001B[39m\u001B[33mopen_oi\u001B[39m\u001B[33m'\u001B[39m, \u001B[33m'\u001B[39m\u001B[33mclose_oi\u001B[39m\u001B[33m'\u001B[39m, \u001B[33m'\u001B[39m\u001B[33munderlying_symbol\u001B[39m\u001B[33m'\u001B[39m]\n",
|
||||
"\u001B[31mFileNotFoundError\u001B[39m: 数据文件未找到: /mnt/d/PyProject/NewQuant/data/data/KQ_m@SHFE_rb/KQ_m@SHFE_rb_min15.csv"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 4
|
||||
"execution_count": 5
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-10-19T06:30:51.251633200Z",
|
||||
"end_time": "2025-12-17T13:57:22.378533300Z",
|
||||
"start_time": "2025-10-17T14:27:25.613908Z"
|
||||
}
|
||||
},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -57,8 +57,10 @@ def run_single_backtest(
|
||||
if 'kalman_measurement_noise' in common_config:
|
||||
strategy_parameters['kalman_measurement_noise'] = common_config['kalman_measurement_noise']
|
||||
|
||||
if 'entry_threshold_atr' in common_config:
|
||||
if 'entry_threshold_atr' in common_config and 'entry_threshold_atr' not in strategy_parameters:
|
||||
strategy_parameters['entry_threshold_atr'] = common_config['entry_threshold_atr']
|
||||
elif 'entry_threshold_atr' not in strategy_parameters:
|
||||
strategy_parameters['entry_threshold_atr'] = strategy_parameters['structural_stop_atr_multiplier']
|
||||
|
||||
# 打印当前进程正在处理的组合信息
|
||||
# 注意:多进程打印会交错显示
|
||||
|
||||
Reference in New Issue
Block a user