# src/strategies/simple_limit_buy_strategy.py (修改部分)

from typing import Dict, Any, Optional
import pandas as pd

# 导入 Strategy 抽象基类
from .base_strategy import Strategy
# 导入核心数据类
from ..core_data import Bar, Order, Trade


class TestStrategy(Strategy):
    """
    一个简单的限价买入策略：
    在每根Bar线上，如果当前没有持仓，且没有待处理的买入订单，则尝试下一个限价多单。
    如果在当前Bar之前有未成交的买入订单，则撤销该订单。
    确保在任意时间点，最多只有一笔限价买入订单在市场中。
    """

    def __init__(self, context: Any, **parameters: Any):  # context 类型提示可以为 BacktestContext
        super().__init__(context, **parameters)
        self.trade_volume = 1
        self.order_id_counter = 0
        self.limit_price_factor = parameters.get('limit_price_factor', 0.999)  # 限价因子
        self.max_position = parameters.get('max_position', self.trade_volume)  # 最大持仓量

        self._last_order_id: Optional[str] = None  # 跟踪上一根Bar发出的订单ID
        self._current_long_position: int = 0  # 策略内部维护的当前持仓

    def on_init(self):
        super().on_init()
        # 确保初始状态正确
        self._last_order_id = None
        self._current_long_position = 0  # 或者从模拟器获取初始持仓

    def on_trade(self, trade: Trade):
        """
        当模拟器成功执行一笔交易时调用。
        更新策略内部持仓状态。
        """
        super().on_trade(trade)  # 调用父类方法
        # 简单起见，这里假设只交易self.symbol
        if trade.symbol == self.symbol:
            if trade.direction == "BUY":
                self._current_long_position += trade.volume
            elif trade.direction == "SELL":  # 可能是平多或开空
                self._current_long_position -= trade.volume  # 卖出量为正值，所以是减

        # 如果成交的是我们之前提交的订单，清空_last_order_id
        if self._last_order_id == trade.order_id:
            self._last_order_id = None

        # 打印当前持仓
        # print(f"[{trade.fill_time}] 策略内部持仓更新: {self.symbol} -> {self._current_long_position}")

    def on_bar(self, bar: Bar):
        """
        每接收到一根Bar时，执行策略逻辑。
        """
        current_portfolio_value = self.context.get_account_cash()
        # print(f"[{bar.datetime}] Strategy processing Bar. Current close price: {bar.close:.2f}. Current Portfolio Value: {current_portfolio_value:.2f}")

        # 1. 撤销上一根K线未成交的订单
        if self._last_order_id:
            # 检查这个订单是否仍然在待处理订单列表中
            pending_orders = self.get_pending_orders()  # 直接访问模拟器，或者通过context提供接口
            if self._last_order_id in pending_orders:
                success = self.cancel_order(self._last_order_id)
                # 这里发送的“撤单订单”会被simulator的send_order处理，并调用simulator.cancel_order
                if success:  # simulator.send_order返回Trade或None，这里我们用一个特殊处理
                    # Simulator的send_order返回的是Trade，如果实现撤单，最好Simulator的cancel_order返回bool
                    print(f"[{bar.datetime}] 策略: 成功撤销上一根K线未成交订单 {self._last_order_id}")
                else:
                    print(f"[{bar.datetime}] 策略: 尝试撤销订单 {self._last_order_id} 失败（可能已成交或不存在）")

                # 无论撤销成功与否，既然我们尝试了撤销，就清除记录
                self._last_order_id = None
            else:
                # 订单不在待处理列表中，说明它可能已经成交了 (在on_trade中已处理)
                # 或者在上一根K线已经被取消/过期
                self._last_order_id = None  # 清理状态
                # print(f"[{bar.datetime}] 订单 {self._last_order_id} 不在待处理列表，无需撤销。")

        # 2. 判断是否需要下单
        # 如果当前没有多头持仓，并且没有待处理的买入订单
        # (注: _last_order_id被清除后，_last_order_id为None表示当前没有待处理的我们发出的买单)
        current_positions = self.context.get_current_positions()
        self._current_long_position = current_positions.get(self.symbol, 0)  # 从模拟器获取最新持仓

        if self._current_long_position == 0 and self._last_order_id is None:  # 确保只有一笔买单
            # 计算限价价格
            limit_price = bar.open * self.limit_price_factor
            trade_volume = self.trade_volume

            # 生成唯一的订单ID
            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="MARKET",
                # limit_price=limit_price,
                submitted_time=bar.datetime
            )

            # 通过上下文发送订单
            # trade = self.send_order(order)
            # if trade:
            #     print(
            #         f"[{bar.datetime}] 策略: 发送并立即成交限价买单 {trade.volume} 股 (open:{bar.open}, close:{bar.close}) (订单ID: {order.id})")
            #     # 如果立即成交，_last_order_id 仍然保持 None
            # else:
            #     # 如果未立即成交，将订单ID记录下来，以便下一根Bar撤销
            #     self._last_order_id = order.id
            #     print(
            #         f"[{bar.datetime}] 策略: 发送限价买单 {trade_volume} 股 @ {limit_price:.2f} (未成交，订单ID: {order.id} 已挂单)")
            order = self.send_order(order)
            if order:
                print(f"[{bar.datetime}]发送订单 {order.id}, direction {order.direction}")
        else:
            # print(f"[{bar.datetime}] 策略: 当前已有持仓或有未成交订单，不重复下单。")
            pass