# Path: OnePy/constants.py
# class ActionType(Enum):
# 
#     Buy = 'Buy'
#     Sell = 'Sell'
#     Short = 'Short'
#     Cover = 'Cover'
# 
#     Exit_all = 'Exit_all'
#     Cancel = 'Cancel'
# 
# Path: OnePy/sys_module/metabase_env.py
# class OnePyEnvBase:
#     """作为基类，提供env共享单例给各个模块"""
#     env = Environment
# 
# Path: OnePy/sys_module/models/base_log.py
# class TradeLogBase(OnePyEnvBase, abc.ABC):
# 
#     buy: float = None
#     sell: float = None
#     size: float = None
# 
#     entry_date: str = field(init=False)
#     exit_date: str = field(init=False)
# 
#     entry_price: float = field(init=False)
#     exit_price: float = field(init=False)
# 
#     entry_type: str = field(init=False)
#     exit_type: str = field(init=False)
# 
#     pl_points: float = field(init=False)
#     re_pnl: float = field(init=False)
# 
#     commission: float = field(init=False)
# 
#     @abc.abstractmethod
#     def generate(self):
#         raise NotImplementedError
# 
#     def _earn_short(self):
#         return -1 if self.buy.action_type == ActionType.Short else 1
# 
#     @staticmethod
#     def _get_order_type(order):
#         if isinstance(order.signal, SignalByTrigger):
#             return order.signal.order_type.value
#         else:
#             return order.order_type.value
# 
#     @abc.abstractmethod
#     def settle_left_trade(self):
#         raise NotImplementedError
# 
#     @property
#     def ticker(self):
#         return self.buy.ticker
# 
# Path: OnePy/sys_module/models/signals.py
# class SignalByTrigger(SignalForPending):
#     counter = count(1)
# 
#     order_type: OrderType = None
# 
#     mkt_id: int = None
#     trigger_key: str = None
# 
#     execute_price: float = None  # 用来确定是否是必成单,用于挂单
#     first_cur_price: float = None  # 记录挂单信号产生时候的价格
#     parent_order: str = None  # 其实不是str，是一个order对象
# 
#     def _save_signals(self):
#         self.env.signals_trigger_cur.append(self)
# 
#         if self.env.is_save_original:
#             self.env.signals_trigger.append(self)
# 
# Path: OnePy/utils/memo_for_cache.py
# def memo(key):
#     cache = Environment.cache
# 
#     def decorate(func):
#         @wraps(func)
#         def wrapper(*args, **kwargs):
#             if key not in cache:
#                 cache[key] = func(*args, **kwargs)
# 
#             return cache[key]
# 
#         return wrapper
# 
#     return decorate


from collections import defaultdict, deque
from OnePy.constants import ActionType
from OnePy.sys_module.metabase_env import OnePyEnvBase
from OnePy.sys_module.models.base_log import TradeLogBase
from OnePy.sys_module.models.signals import SignalByTrigger
from OnePy.utils.memo_for_cache import memo
import pandas as pd
            self._pair_one_by_one(order_list, sell_size, order, counteract)

    def _pair_order(self, long_or_short, order):  # order should be sell or short cover
        if long_or_short == 'long':
            log_pure = self.long_log_pure[order.ticker]
            log_with_trigger = self.long_log_with_trigger[order.ticker]
        elif long_or_short == 'short':
            log_pure = self.short_log_pure[order.ticker]
            log_with_trigger = self.short_log_with_trigger[order.ticker]

        sell_size = order.size

        if isinstance(order.signal, SignalByTrigger):
            self._search_father(order, log_with_trigger)

        else:

            try:
                self._pair_one_by_one(log_pure, sell_size, order)
            except IndexError:
                self._pair_one_by_one(log_with_trigger, sell_size, order, True)

    def match_order(self, order):
        if order.action_type == ActionType.Buy:
            order.track_size = order.size

            if order.is_pure():
                self.long_log_pure[order.ticker].append(order)
            else:
                self.long_log_with_trigger[order.ticker].append(order)

# Path: OnePy/constants.py
# class ActionType(Enum):
# 
#     Buy = 'Buy'
#     Sell = 'Sell'
#     Short = 'Short'
#     Cover = 'Cover'
# 
#     Exit_all = 'Exit_all'
#     Cancel = 'Cancel'
# 
# Path: OnePy/sys_module/metabase_env.py
# class OnePyEnvBase:
#     """作为基类，提供env共享单例给各个模块"""
#     env = Environment
# 
# Path: OnePy/sys_module/models/base_log.py
# class TradeLogBase(OnePyEnvBase, abc.ABC):
# 
#     buy: float = None
#     sell: float = None
#     size: float = None
# 
#     entry_date: str = field(init=False)
#     exit_date: str = field(init=False)
# 
#     entry_price: float = field(init=False)
#     exit_price: float = field(init=False)
# 
#     entry_type: str = field(init=False)
#     exit_type: str = field(init=False)
# 
#     pl_points: float = field(init=False)
#     re_pnl: float = field(init=False)
# 
#     commission: float = field(init=False)
# 
#     @abc.abstractmethod
#     def generate(self):
#         raise NotImplementedError
# 
#     def _earn_short(self):
#         return -1 if self.buy.action_type == ActionType.Short else 1
# 
#     @staticmethod
#     def _get_order_type(order):
#         if isinstance(order.signal, SignalByTrigger):
#             return order.signal.order_type.value
#         else:
#             return order.order_type.value
# 
#     @abc.abstractmethod
#     def settle_left_trade(self):
#         raise NotImplementedError
# 
#     @property
#     def ticker(self):
#         return self.buy.ticker
# 
# Path: OnePy/sys_module/models/signals.py
# class SignalByTrigger(SignalForPending):
#     counter = count(1)
# 
#     order_type: OrderType = None
# 
#     mkt_id: int = None
#     trigger_key: str = None
# 
#     execute_price: float = None  # 用来确定是否是必成单,用于挂单
#     first_cur_price: float = None  # 记录挂单信号产生时候的价格
#     parent_order: str = None  # 其实不是str，是一个order对象
# 
#     def _save_signals(self):
#         self.env.signals_trigger_cur.append(self)
# 
#         if self.env.is_save_original:
#             self.env.signals_trigger.append(self)
# 
# Path: OnePy/utils/memo_for_cache.py
# def memo(key):
#     cache = Environment.cache
# 
#     def decorate(func):
#         @wraps(func)
#         def wrapper(*args, **kwargs):
#             if key not in cache:
#                 cache[key] = func(*args, **kwargs)
# 
#             return cache[key]
# 
#         return wrapper
# 
#     return decorate


# Path: OnePy/sys_module/components/match_engine.py
from collections import defaultdict, deque
from OnePy.constants import ActionType
from OnePy.sys_module.metabase_env import OnePyEnvBase
from OnePy.sys_module.models.base_log import TradeLogBase
from OnePy.sys_module.models.signals import SignalByTrigger
from OnePy.utils.memo_for_cache import memo
import pandas as pd

            self._pair_one_by_one(order_list, sell_size, order, counteract)

    def _pair_order(self, long_or_short, order):  # order should be sell or short cover
        if long_or_short == 'long':
            log_pure = self.long_log_pure[order.ticker]
            log_with_trigger = self.long_log_with_trigger[order.ticker]
        elif long_or_short == 'short':
            log_pure = self.short_log_pure[order.ticker]
            log_with_trigger = self.short_log_with_trigger[order.ticker]

        sell_size = order.size

        if isinstance(order.signal, SignalByTrigger):
            self._search_father(order, log_with_trigger)

        else:

            try:
                self._pair_one_by_one(log_pure, sell_size, order)
            except IndexError:
                self._pair_one_by_one(log_with_trigger, sell_size, order, True)

    def match_order(self, order):
        if order.action_type == ActionType.Buy:
            order.track_size = order.size

            if order.is_pure():
                self.long_log_pure[order.ticker].append(order)
            else:
                self.long_log_with_trigger[order.ticker].append(order)

        elif order.action_type == ActionType.Short: