# src/strategies/simple_limit_buy_strategy.py

from .base_strategy import Strategy
from ..core_data import Bar, Order
from typing import Optional, Dict, Any
from collections import deque


class SimpleLimitBuyStrategyLong(Strategy):
    """
    一个基于当前K线Open、前1根和前7根K线Range计算优势价格进行限价买入的策略。
    具备以下特点：
    - 每根K线开始时取消上一根K线未成交的订单。
    - 最多只能有一个开仓挂单和一个持仓。
    - 包含简单的止损和止盈逻辑。
    """

    def __init__(
        self,
        context: Any,
        symbol: str,
        enable_log: bool,
        trade_volume: int,
        open_range_factor_1_ago: float,
        open_range_factor_7_ago: float,
        max_position: int,
        stop_loss_points: float = 10,  # 新增：止损点数
        take_profit_points: float = 10,
    ):  # 新增：止盈点数
        """
        初始化策略。
        Args:
            context: 模拟器实例。
            symbol (str): 交易合约代码。
            trade_volume (int): 单笔交易量。
            open_range_factor_1_ago (float): 前1根K线Range的权重因子，用于从Open价向下偏移。
            open_range_factor_7_ago (float): 前7根K线Range的权重因子，用于从Open价向下偏移。
            max_position (int): 最大持仓量（此处为1，因为只允许一个持仓）。
            stop_loss_points (float): 止损点数（例如，亏损达到此点数则止损）。
            take_profit_points (float): 止盈点数（例如，盈利达到此点数则止盈）。
        """
        super().__init__(context, symbol, enable_log)
        self.trade_volume = trade_volume
        self.open_range_factor_1_ago = open_range_factor_1_ago
        self.open_range_factor_7_ago = open_range_factor_7_ago
        self.max_position = max_position  # 理论上这里应为1
        self.stop_loss_points = stop_loss_points
        self.take_profit_points = take_profit_points

        self.order_id_counter = 0

        self._last_order_id: Optional[str] = None  # 用于跟踪上一根K线发出的订单ID

        self.log(
            f"策略初始化: symbol={self.symbol}, trade_volume={self.trade_volume}, "
            f"open_range_factor_1_ago={self.open_range_factor_1_ago}, "
            f"open_range_factor_7_ago={self.open_range_factor_7_ago}, "
            f"max_position={self.max_position}, "
            f"止损点={self.stop_loss_points}, 止盈点={self.take_profit_points}"
        )

    def on_open_bar(self, bar: Bar, next_bar_open: Optional[float] = None):
        """
        每当新的K线数据到来时调用。
        Args:
            bar (Bar): 当前的K线数据对象。
            next_bar_open (Optional[float]): 下一根K线的开盘价，此处策略未使用。
        """
        current_datetime = bar.datetime  # 获取当前K线时间
        self.symbol = bar.symbol

        # --- 1. 撤销上一根K线未成交的订单 ---
        # 检查是否记录了上一笔订单ID，并且该订单仍然在待处理列表中
        if self._last_order_id:
            pending_orders = self.get_pending_orders()
            if self._last_order_id in pending_orders:
                success = self.cancel_order(
                    self._last_order_id
                )  # 直接调用基类的取消方法
                if success:
                    self.log(
                        f"[{current_datetime}] 策略: 成功撤销上一根K线未成交订单 {self._last_order_id}"
                    )
                else:
                    self.log(
                        f"[{current_datetime}] 策略: 尝试撤销订单 {self._last_order_id} 失败（可能已成交或不存在）"
                    )
            # 无论撤销成功与否，既然我们尝试了撤销，就清除记录
            self._last_order_id = None
        # else:
        # self.log(f"[{current_datetime}] 策略: 无上一根K线未成交订单需要撤销。")

        # 2. 更新K线历史
        trade_volume = self.trade_volume

        # 获取当前持仓和未决订单（在取消之后获取，确保是最新的状态）
        current_positions = self.get_current_positions()
        current_pos_volume = current_positions.get(self.symbol, 0)
        pending_orders_after_cancel = (
            self.get_pending_orders()
        )  # 再次获取，此时应已取消旧订单

        # --- 3. 平仓逻辑 (止损/止盈) ---
        # 只有当有持仓时才考虑平仓
        if current_pos_volume > 0:  # 假设只做多，所以持仓量 > 0
            avg_entry_price = self.get_average_position_price(self.symbol)
            if avg_entry_price is not None:
                pnl_per_unit = (
                    bar.open - avg_entry_price
                )  # 当前浮动盈亏（以收盘价计算）

                # 止盈条件
                if pnl_per_unit >= self.take_profit_points:
                    self.log(
                        f"[{current_datetime}] 止盈信号 - PnL per unit: {pnl_per_unit:.2f}, 目标: {self.take_profit_points:.2f}"
                    )

                    order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
                    self.order_id_counter += 1

                    # 创建一个限价多单
                    order = Order(
                        id=order_id,
                        symbol=self.symbol,
                        direction="CLOSE_LONG",
                        volume=trade_volume,
                        price_type="MARKET",
                        # limit_price=limit_price,
                        submitted_time=bar.datetime,
                        offset="CLOSE",
                    )
                    trade = self.send_order(order)
                    return  # 平仓后本K线不再进行开仓判断

                # 止损条件
                elif pnl_per_unit <= -self.stop_loss_points:
                    self.log(
                        f"[{current_datetime}] 止损信号 - PnL per unit: {pnl_per_unit:.2f}, 目标: {-self.stop_loss_points:.2f}"
                    )
                    # 发送市价卖出订单平仓，确保立即成交
                    order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
                    self.order_id_counter += 1

                    # 创建一个限价多单
                    order = Order(
                        id=order_id,
                        symbol=self.symbol,
                        direction="CLOSE_LONG",
                        volume=trade_volume,
                        price_type="MARKET",
                        # limit_price=limit_price,
                        submitted_time=bar.datetime,
                        offset="CLOSE",
                    )
                    trade = self.send_order(order)
                    return  # 平仓后本K线不再进行开仓判断

        # --- 4. 开仓逻辑 (只考虑做多 BUY 方向) ---
        # 只有在没有持仓 (current_pos_volume == 0) 且没有待处理订单 (not pending_orders_after_cancel)
        # 且K线历史足够长时才考虑开仓
        bar_history = self.get_bar_history()
        if current_pos_volume == 0 and len(bar_history) > 10:

            # 获取前1根K线 (倒数第二根) 和前7根K线 (队列中最老的一根)
            bar_1_ago = bar_history[-2]
            bar_7_ago = bar_history[-8]

            # 计算历史 K 线的 Range
            range_1_ago = bar_1_ago.high - bar_1_ago.low
            range_7_ago = bar_7_ago.high - bar_7_ago.low

            # 根据策略逻辑计算目标买入价格
            # 目标买入价 = 当前K线Open - (前1根Range * 因子1 + 前7根Range * 因子2)
            self.log(
                bar.open,
                range_1_ago * self.open_range_factor_1_ago,
                range_7_ago * self.open_range_factor_7_ago,
            )
            target_buy_price = bar.open - (
                range_1_ago * self.open_range_factor_1_ago
                + range_7_ago * self.open_range_factor_7_ago
            )

            # 确保目标买入价格有效，例如不能是负数
            target_buy_price = max(0.01, target_buy_price)

            self.log(
                f"[{current_datetime}] 开多仓信号 - 当前Open={bar.open:.2f}, "
                f"前1Range={range_1_ago:.2f}, 前7Range={range_7_ago:.2f}, "
                f"计算目标买入价={target_buy_price:.2f}"
            )

            order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
            self.order_id_counter += 1

            # 创建一个限价多单
            order = Order(
                id=order_id,
                symbol=self.symbol,
                direction="BUY",
                volume=trade_volume,
                price_type="LIMIT",
                limit_price=target_buy_price,
                submitted_time=bar.datetime,
            )
            new_order = self.send_order(order)
            # 记录下这个订单的ID，以便在下一根K线开始时进行撤销
            if new_order:
                self._last_order_id = new_order.id
                self.log(
                    f"[{current_datetime}] 策略: 发送限价买入订单 {self._last_order_id} @ {target_buy_price:.2f}"
                )
            else:
                self.log(f"[{current_datetime}] 策略: 发送订单失败。")

        # else:
        # self.log(f"[{current_datetime}] 不满足开仓条件：持仓={current_pos_volume}, 待处理订单={len(pending_orders_after_cancel)}, K线历史长度={len(bar_history)}")

    def on_close_bar(self, bar: Bar, next_bar_open: Optional[float] = None):
        self.cancel_all_pending_orders()

    def on_rollover(self, old_symbol: str, new_symbol: str):
        """
        在合约换月时清空历史K线数据和上次订单ID，避免使用旧合约数据进行计算。
        """
        super().on_rollover(old_symbol, new_symbol)  # 调用基类方法打印日志
        self._last_order_id = None  # 清空上次订单ID，因为旧合约订单已取消

        self.log(f"换月完成，清空历史K线数据和上次订单ID，准备新合约交易。")


class SimpleLimitBuyStrategyShort(Strategy):
    """
    一个基于当前K线Open、前1根和前7根K线Range计算优势价格进行限价买入的策略。
    具备以下特点：
    - 每根K线开始时取消上一根K线未成交的订单。
    - 最多只能有一个开仓挂单和一个持仓。
    - 包含简单的止损和止盈逻辑。
    """

    def __init__(
        self,
        context: Any,
        symbol: str,
        enable_log: bool,
        trade_volume: int,
        open_range_factor_1_ago: float,
        open_range_factor_7_ago: float,
        max_position: int,
        stop_loss_points: float = 10,  # 新增：止损点数
        take_profit_points: float = 10,
    ):  # 新增：止盈点数
        """
        初始化策略。
        Args:
            context: 模拟器实例。
            symbol (str): 交易合约代码。
            trade_volume (int): 单笔交易量。
            open_range_factor_1_ago (float): 前1根K线Range的权重因子，用于从Open价向下偏移。
            open_range_factor_7_ago (float): 前7根K线Range的权重因子，用于从Open价向下偏移。
            max_position (int): 最大持仓量（此处为1，因为只允许一个持仓）。
            stop_loss_points (float): 止损点数（例如，亏损达到此点数则止损）。
            take_profit_points (float): 止盈点数（例如，盈利达到此点数则止盈）。
        """
        super().__init__(context, symbol, enable_log)
        self.trade_volume = trade_volume
        self.open_range_factor_1_ago = open_range_factor_1_ago
        self.open_range_factor_7_ago = open_range_factor_7_ago
        self.max_position = max_position  # 理论上这里应为1
        self.stop_loss_points = stop_loss_points
        self.take_profit_points = take_profit_points

        self.order_id_counter = 0
        self.last_buy_price = 0
        self.last_sell_price = 0

        bar_history: deque[Bar] = deque(maxlen=10)
        self._last_order_id: Optional[str] = None  # 用于跟踪上一根K线发出的订单ID

        self.log(
            f"策略初始化: symbol={self.symbol}, trade_volume={self.trade_volume}, "
            f"open_range_factor_1_ago={self.open_range_factor_1_ago}, "
            f"open_range_factor_7_ago={self.open_range_factor_7_ago}, "
            f"max_position={self.max_position}, "
            f"止损点={self.stop_loss_points}, 止盈点={self.take_profit_points}"
        )

    def on_open_bar(self, bar: Bar, next_bar_open: Optional[float] = None):
        """
        每当新的K线数据到来时调用。
        Args:
            bar (Bar): 当前的K线数据对象。
            next_bar_open (Optional[float]): 下一根K线的开盘价，此处策略未使用。
        """
        current_datetime = bar.datetime  # 获取当前K线时间
        self.symbol = bar.symbol

        # --- 1. 撤销上一根K线未成交的订单 ---
        # 检查是否记录了上一笔订单ID，并且该订单仍然在待处理列表中
        if self._last_order_id:
            pending_orders = self.get_pending_orders()
            if self._last_order_id in pending_orders:
                success = self.cancel_order(
                    self._last_order_id
                )  # 直接调用基类的取消方法
                if success:
                    self.log(
                        f"[{current_datetime}] 策略: 成功撤销上一根K线未成交订单 {self._last_order_id}"
                    )
                else:
                    self.log(
                        f"[{current_datetime}] 策略: 尝试撤销订单 {self._last_order_id} 失败（可能已成交或不存在）"
                    )
            # 无论撤销成功与否，既然我们尝试了撤销，就清除记录
            self._last_order_id = None
        # else:
        # self.log(f"[{current_datetime}] 策略: 无上一根K线未成交订单需要撤销。")

        # 2. 更新K线历史
        trade_volume = self.trade_volume

        # 获取当前持仓和未决订单（在取消之后获取，确保是最新的状态）
        current_positions = self.get_current_positions()
        current_pos_volume = current_positions.get(self.symbol, 0)
        pending_orders_after_cancel = (
            self.get_pending_orders()
        )  # 再次获取，此时应已取消旧订单

        # --- 3. 平仓逻辑 (止损/止盈) ---
        # 只有当有持仓时才考虑平仓
        if current_pos_volume < 0:  # 假设只做多，所以持仓量 > 0
            avg_entry_price = self.get_average_position_price(self.symbol)
            self.log(f'avg_entry_price {avg_entry_price}, bar.open {bar.open}')

            if avg_entry_price is not None:
                pnl_per_unit = (
                    avg_entry_price - bar.open
                )  # 当前浮动盈亏（以收盘价计算）

                # 止盈条件
                if pnl_per_unit >= self.take_profit_points:
                    self.log(
                        f"[{current_datetime}] 止盈信号 - PnL per unit: {pnl_per_unit:.2f}, 目标: {self.take_profit_points:.2f}"
                    )

                    order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
                    self.order_id_counter += 1

                    # 创建一个限价多单
                    order = Order(
                        id=order_id,
                        symbol=self.symbol,
                        direction="CLOSE_SHORT",
                        volume=trade_volume,
                        price_type="MARKET",
                        # limit_price=limit_price,
                        submitted_time=bar.datetime,
                        offset="CLOSE",
                    )
                    trade = self.send_order(order)
                    return  # 平仓后本K线不再进行开仓判断

                # 止损条件
                elif pnl_per_unit <= -self.stop_loss_points:
                    self.log(
                        f"[{current_datetime}] 止损信号 - PnL per unit: {pnl_per_unit:.2f}, 目标: {-self.stop_loss_points:.2f}"
                    )
                    # 发送市价卖出订单平仓，确保立即成交
                    order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
                    self.order_id_counter += 1

                    # 创建一个限价多单
                    order = Order(
                        id=order_id,
                        symbol=self.symbol,
                        direction="CLOSE_SHORT",
                        volume=trade_volume,
                        price_type="MARKET",
                        # limit_price=limit_price,
                        submitted_time=bar.datetime,
                        offset="CLOSE",
                    )
                    trade = self.send_order(order)
                    return  # 平仓后本K线不再进行开仓判断

        # --- 4. 开仓逻辑 (只考虑做多 BUY 方向) ---
        # 只有在没有持仓 (current_pos_volume == 0) 且没有待处理订单 (not pending_orders_after_cancel)
        # 且K线历史足够长时才考虑开仓
        bar_history = self.get_bar_history()
        if current_pos_volume == 0 and len(bar_history) > 10:

            # 获取前1根K线 (倒数第二根) 和前7根K线 (队列中最老的一根)
            bar_1_ago = bar_history[-2]
            bar_7_ago = bar_history[-8]

            # 计算历史 K 线的 Range
            range_1_ago = bar_1_ago.high - bar_1_ago.low
            range_7_ago = bar_7_ago.high - bar_7_ago.low

            # 根据策略逻辑计算目标买入价格
            # 目标买入价 = 当前K线Open - (前1根Range * 因子1 + 前7根Range * 因子2)
            self.log(
                bar.open,
                range_1_ago * self.open_range_factor_1_ago,
                range_7_ago * self.open_range_factor_7_ago,
            )
            target_buy_price = bar.open + (
                range_1_ago * self.open_range_factor_1_ago
                + range_7_ago * self.open_range_factor_7_ago
            )

            # 确保目标买入价格有效，例如不能是负数
            target_buy_price = max(0.01, target_buy_price)

            self.log(
                f"[{current_datetime}] 开多仓信号 - 当前Open={bar.open:.2f}, "
                f"前1Range={range_1_ago:.2f}, 前7Range={range_7_ago:.2f}, "
                f"计算目标买入价={target_buy_price:.2f}"
            )

            order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
            self.order_id_counter += 1

            # 创建一个限价多单
            order = Order(
                id=order_id,
                symbol=self.symbol,
                direction="SELL",
                volume=trade_volume,
                price_type="LIMIT",
                limit_price=target_buy_price,
                submitted_time=bar.datetime,
            )
            new_order = self.send_order(order)
            # 记录下这个订单的ID，以便在下一根K线开始时进行撤销
            if new_order:
                self._last_order_id = new_order.id
                self.log(
                    f"[{current_datetime}] 策略: 发送限价买入订单 {self._last_order_id} @ {target_buy_price:.2f}"
                )
            else:
                self.log(f"[{current_datetime}] 策略: 发送订单失败。")

        # else:
        # self.log(f"[{current_datetime}] 不满足开仓条件：持仓={current_pos_volume}, 待处理订单={len(pending_orders_after_cancel)}, K线历史长度={len(bar_history)}")

    def on_rollover(self, old_symbol: str, new_symbol: str):
        """
        在合约换月时清空历史K线数据和上次订单ID，避免使用旧合约数据进行计算。
        """
        super().on_rollover(old_symbol, new_symbol)  # 调用基类方法打印日志
        # bar_history.clear() # 清空历史K线
        self._last_order_id = None  # 清空上次订单ID，因为旧合约订单已取消

        self.log(f"换月完成，清空历史K线数据和上次订单ID，准备新合约交易。")


class SimpleLimitBuyStrategy(Strategy):
    """
    一个基于当前K线Open、前1根和前7根K线Range计算优势价格进行限价买入的策略。
    具备以下特点：
    - 每根K线开始时取消上一根K线未成交的订单。
    - 最多只能有一个开仓挂单和一个持仓。
    - 包含简单的止损和止盈逻辑。
    """

    def __init__(
        self,
        context: Any,
        symbol: str,
        enable_log: bool,
        trade_volume: int,
        open_range_factor_1_long: float,
        open_range_factor_7_long: float,
        open_range_factor_1_short: float,
        open_range_factor_7_short: float,
        max_position: int,
        stop_loss_points: float = 10,  # 新增：止损点数
        take_profit_points: float = 10,
    ):  # 新增：止盈点数
        """
        初始化策略。
        Args:
            context: 模拟器实例。
            symbol (str): 交易合约代码。
            trade_volume (int): 单笔交易量。
            open_range_factor_1_ago (float): 前1根K线Range的权重因子，用于从Open价向下偏移。
            open_range_factor_7_ago (float): 前7根K线Range的权重因子，用于从Open价向下偏移。
            max_position (int): 最大持仓量（此处为1，因为只允许一个持仓）。
            stop_loss_points (float): 止损点数（例如，亏损达到此点数则止损）。
            take_profit_points (float): 止盈点数（例如，盈利达到此点数则止盈）。
        """
        super().__init__(context, symbol, enable_log)
        self.last_buy_price = 0
        self.last_sell_price = 0
        self.trade_volume = trade_volume
        self.open_range_factor_1_long = open_range_factor_1_long
        self.open_range_factor_7_long = open_range_factor_7_long
        self.open_range_factor_1_short = open_range_factor_1_short
        self.open_range_factor_7_short = open_range_factor_7_short
        self.max_position = max_position  # 理论上这里应为1
        self.stop_loss_points = stop_loss_points
        self.take_profit_points = take_profit_points

        self.order_id_counter = 0

        self._last_order_id: Optional[str] = None  # 用于跟踪上一根K线发出的订单ID

        self.log(
            f"策略初始化: symbol={self.symbol}, trade_volume={self.trade_volume}, "
            f"max_position={self.max_position}, "
            f"止损点={self.stop_loss_points}, 止盈点={self.take_profit_points}"
        )

    def on_open_bar(self, bar: Bar, next_bar_open: Optional[float] = None):
        """
        每当新的K线数据到来时调用。
        Args:
            bar (Bar): 当前的K线数据对象。
            next_bar_open (Optional[float]): 下一根K线的开盘价，此处策略未使用。
        """
        current_datetime = bar.datetime  # 获取当前K线时间
        self.symbol = bar.symbol

        # --- 1. 撤销上一根K线未成交的订单 ---
        # 检查是否记录了上一笔订单ID，并且该订单仍然在待处理列表中
        if self._last_order_id:
            pending_orders = self.get_pending_orders()
            # if self._last_order_id in pending_orders:
            #     success = self.cancel_order(self._last_order_id) # 直接调用基类的取消方法
            #     if success:
            #         self.log(f"[{current_datetime}] 策略: 成功撤销上一根K线未成交订单 {self._last_order_id}")
            #     else:
            #         self.log(f"[{current_datetime}] 策略: 尝试撤销订单 {self._last_order_id} 失败（可能已成交或不存在）")
            # # 无论撤销成功与否，既然我们尝试了撤销，就清除记录
            # self._last_order_id = None
            self.cancel_all_pending_orders()
        # else:
        # self.log(f"[{current_datetime}] 策略: 无上一根K线未成交订单需要撤销。")

        # 2. 更新K线历史
        trade_volume = self.trade_volume

        # 获取当前持仓和未决订单（在取消之后获取，确保是最新的状态）
        current_positions = self.get_current_positions()
        current_pos_volume = current_positions.get(self.symbol, 0)
        pending_orders_after_cancel = (
            self.get_pending_orders()
        )  # 再次获取，此时应已取消旧订单

        # --- 3. 平仓逻辑 (止损/止盈) ---
        # 只有当有持仓时才考虑平仓
        self.log(current_positions, self.symbol)
        if current_pos_volume < 0:  # 假设只做多，所以持仓量 > 0
            avg_entry_price = self.get_average_position_price(self.symbol)
            avg_entry_price = self.last_sell_price
            if avg_entry_price is not None:
                pnl_per_unit = (
                    avg_entry_price - bar.open
                )  # 当前浮动盈亏（以收盘价计算）

                # 止盈条件
                if pnl_per_unit >= self.take_profit_points:
                    self.log(
                        f"[{current_datetime}] 止盈信号 - PnL per unit: {pnl_per_unit:.2f}, 目标: {self.take_profit_points:.2f}"
                    )

                    order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
                    self.order_id_counter += 1

                    # 创建一个限价多单
                    order = Order(
                        id=order_id,
                        symbol=self.symbol,
                        direction="CLOSE_SHORT",
                        volume=trade_volume,
                        price_type="MARKET",
                        # limit_price=limit_price,
                        submitted_time=bar.datetime,
                        offset="CLOSE",
                    )
                    trade = self.send_order(order)
                    return  # 平仓后本K线不再进行开仓判断

                # 止损条件
                elif pnl_per_unit <= -self.stop_loss_points:
                    self.log(
                        f"[{current_datetime}] 止损信号 - PnL per unit: {pnl_per_unit:.2f}, 目标: {-self.stop_loss_points:.2f}"
                    )
                    # 发送市价卖出订单平仓，确保立即成交
                    order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
                    self.order_id_counter += 1

                    # 创建一个限价多单
                    order = Order(
                        id=order_id,
                        symbol=self.symbol,
                        direction="CLOSE_SHORT",
                        volume=trade_volume,
                        price_type="MARKET",
                        # limit_price=limit_price,
                        submitted_time=bar.datetime,
                        offset="CLOSE",
                    )
                    trade = self.send_order(order)
                    return  # 平仓后本K线不再进行开仓判断

        if current_pos_volume > 0:  # 假设只做多，所以持仓量 > 0
            avg_entry_price = self.get_average_position_price(self.symbol)
            avg_entry_price = self.last_buy_price
            if avg_entry_price is not None:
                pnl_per_unit = (
                    bar.open - avg_entry_price
                )  # 当前浮动盈亏（以收盘价计算）

                # 止盈条件
                if pnl_per_unit >= self.take_profit_points:
                    self.log(
                        f"[{current_datetime}] 止盈信号 - PnL per unit: {pnl_per_unit:.2f}, 目标: {self.take_profit_points:.2f}"
                    )

                    order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
                    self.order_id_counter += 1

                    # 创建一个限价多单
                    order = Order(
                        id=order_id,
                        symbol=self.symbol,
                        direction="CLOSE_LONG",
                        volume=trade_volume,
                        price_type="MARKET",
                        # limit_price=limit_price,
                        submitted_time=bar.datetime,
                        offset="CLOSE",
                    )
                    trade = self.send_order(order)
                    return  # 平仓后本K线不再进行开仓判断

                # 止损条件
                elif pnl_per_unit <= -self.stop_loss_points:
                    self.log(
                        f"[{current_datetime}] 止损信号 - PnL per unit: {pnl_per_unit:.2f}, 目标: {-self.stop_loss_points:.2f}"
                    )
                    # 发送市价卖出订单平仓，确保立即成交
                    order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
                    self.order_id_counter += 1

                    # 创建一个限价多单
                    order = Order(
                        id=order_id,
                        symbol=self.symbol,
                        direction="CLOSE_LONG",
                        volume=trade_volume,
                        price_type="MARKET",
                        # limit_price=limit_price,
                        submitted_time=bar.datetime,
                        offset="CLOSE",
                    )
                    trade = self.send_order(order)
                    return  # 平仓后本K线不再进行开仓判断

        bar_history = self.get_bar_history()
        if current_pos_volume == 0 and len(bar_history) > 10:

            # 获取前1根K线 (倒数第二根) 和前7根K线 (队列中最老的一根)
            bar_1_ago = bar_history[-2]
            bar_7_ago = bar_history[-8]

            print(bar_1_ago, bar_7_ago)

            # 计算历史 K 线的 Range
            range_1_ago = bar_1_ago.high - bar_1_ago.low
            range_7_ago = bar_7_ago.high - bar_7_ago.low

            # 根据策略逻辑计算目标买入价格
            # 目标买入价 = 当前K线Open - (前1根Range * 因子1 + 前7根Range * 因子2)
            target_buy_price = bar.open + (
                range_1_ago * self.open_range_factor_1_short
                + range_7_ago * self.open_range_factor_7_short
            )

            # 确保目标买入价格有效，例如不能是负数
            target_buy_price = max(0.01, target_buy_price)

            order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
            self.order_id_counter += 1

            # 创建一个限价多单
            order = Order(
                id=order_id,
                symbol=bar.symbol,
                direction="SELL",
                volume=trade_volume,
                price_type="LIMIT",
                limit_price=target_buy_price,
                submitted_time=bar.datetime,
            )
            self.last_sell_price = target_buy_price
            new_order = self.send_order(order)
            # 记录下这个订单的ID，以便在下一根K线开始时进行撤销
            if new_order:
                self._last_order_id = new_order.id
                self.log(
                    f"[{current_datetime}] 策略: 发送限价SELL订单 {self._last_order_id} @ {target_buy_price:.2f}"
                )
            else:
                self.log(f"[{current_datetime}] 策略: 发送订单失败。")

            target_buy_price = bar.open - (
                range_1_ago * self.open_range_factor_1_long
                + range_7_ago * self.open_range_factor_7_long
            )
            # 确保目标买入价格有效，例如不能是负数
            target_buy_price = max(0.01, target_buy_price)

            order_id = f"{self.symbol}_BUY_{bar.datetime.strftime('%Y%m%d%H%M%S')}_{self.order_id_counter}"
            self.order_id_counter += 1

            # 创建一个限价多单
            order = Order(
                id=order_id,
                symbol=bar.symbol,
                direction="BUY",
                volume=trade_volume,
                price_type="LIMIT",
                limit_price=target_buy_price,
                submitted_time=bar.datetime,
            )
            new_order = self.send_order(order)
            self.last_buy_price = target_buy_price
            # 记录下这个订单的ID，以便在下一根K线开始时进行撤销
            if new_order:
                self._last_order_id = new_order.id
                self.log(
                    f"[{current_datetime}] 策略: 发送限价BUY订单 {self._last_order_id} @ {target_buy_price:.2f}"
                )
            else:
                self.log(f"[{current_datetime}] 策略: 发送订单失败。")

        # else:
        # self.log(f"[{current_datetime}] 不满足开仓条件：持仓={current_pos_volume}, 待处理订单={len(pending_orders_after_cancel)}, K线历史长度={len(bar_history)}")


    def on_close_bar(self, bar):
        self.log('on close bar!')
        self.log(self.get_pending_orders())
        self.cancel_all_pending_orders()

    def on_rollover(self, old_symbol: str, new_symbol: str):
        """
        在合约换月时清空历史K线数据和上次订单ID，避免使用旧合约数据进行计算。
        """
        super().on_rollover(old_symbol, new_symbol)  # 调用基类方法打印日志
        self._last_order_id = None  # 清空上次订单ID，因为旧合约订单已取消

        self.log(f"换月完成，清空历史K线数据和上次订单ID，准备新合约交易。")
