# Path: OnePy/constants.py
# class ActionType(Enum):
# 
#     Buy = 'Buy'
#     Sell = 'Sell'
#     Short = 'Short'
#     Cover = 'Cover'
# 
#     Exit_all = 'Exit_all'
#     Cancel = 'Cancel'
# 
# class OrderStatus(Enum):
# 
#     Created = "Created"
#     Submitted = "Submitted"
#     Partial = "Partial"
#     Completed = "Completed"
#     Canceled = "Canceled"
#     Expired = "Expired"
#     Margin = "Margin"
#     Rejected = "Rejected"
#     Triggered = "Triggered"
# 
# Path: OnePy/sys_module/components/signal_generator.py
# class TriggeredSignalGenerator(OnePyEnvBase):
#     """为触发的挂单生成挂单触发信号"""
#     @classmethod
#     def _generate_bare_signal(cls, order) -> SignalByTrigger:
#         kwargs = {'action_type': order.action_type,
#                   'strategy_name': order.strategy_name,
#                   'size': order.size,
#                   'ticker': order.ticker,
#                   'execute_price': order.target_price,
#                   'first_cur_price': order.first_cur_price,
#                   'mkt_id': order.mkt_id,
#                   'order_type': order.order_type,
#                   'parent_order': order}
# 
#         return SignalByTrigger(**kwargs)
# 
#     @classmethod
#     def _generate_full_signal(cls, order) -> SignalByTrigger:
#         kwargs = {'action_type': order.action_type,
#                   'strategy_name': order.strategy_name,
#                   'size': order.size,
#                   'ticker': order.ticker,
#                   'execute_price': order.target_price,
#                   'price': None,
#                   'price_pct': None,
#                   'takeprofit': order.signal.takeprofit,
#                   'takeprofit_pct': order.signal.takeprofit_pct,
#                   'stoploss': order.signal.stoploss,
#                   'stoploss_pct': order.signal.stoploss_pct,
#                   'trailingstop': order.signal.trailingstop,
#                   'trailingstop_pct': order.signal.trailingstop_pct,
#                   'order_type': order.order_type}
# 
#         return SignalByTrigger(**kwargs)
# 
#     @classmethod
#     def generate_triggered_signal(cls, order: PendingOrderBase) -> Optional[Signal]:
#         if order.ticker not in cls.env.cur_suspended_tickers:
# 
#             if order.is_triggered:
#                 if order.is_with_mkt():
#                     return cls._generate_bare_signal(order)
# 
#                 return cls._generate_full_signal(order)
# 
# Path: OnePy/sys_module/metabase_env.py
# class OnePyEnvBase:
#     """作为基类，提供env共享单例给各个模块"""
#     env = Environment


from collections import defaultdict
from typing import Optional
from OnePy.constants import ActionType, OrderStatus
from OnePy.sys_module.components.signal_generator import \
    TriggeredSignalGenerator
from OnePy.sys_module.metabase_env import OnePyEnvBase



class PendingOrderChecker(OnePyEnvBase):
    def _check_orders_pending(self):
        for order in self.env.orders_pending[:]:
            if TriggeredSignalGenerator.generate_triggered_signal(order):
                order.status = OrderStatus.Triggered
                self.env.orders_pending.remove(order)  # 成交的单子需要删除

    def _check_orders_pending_with_mkt(self):
        # TODO: 有Flaw，当多个pending order同时触，只用了第一个

        for key in list(self.env.orders_child_of_mkt_dict):
            for order in self.env.orders_child_of_mkt_dict[key]:

                if TriggeredSignalGenerator.generate_triggered_signal(order):
                    order.status = OrderStatus.Triggered
                    del self.env.orders_child_of_mkt_dict[key]

                    break

    def run(self):
        self._check_orders_pending_with_mkt()
        self._check_orders_pending()



# Path: OnePy/constants.py
# class ActionType(Enum):
# 
#     Buy = 'Buy'
#     Sell = 'Sell'
#     Short = 'Short'
#     Cover = 'Cover'
# 
#     Exit_all = 'Exit_all'
#     Cancel = 'Cancel'
# 
# class OrderStatus(Enum):
# 
#     Created = "Created"
#     Submitted = "Submitted"
#     Partial = "Partial"
#     Completed = "Completed"
#     Canceled = "Canceled"
#     Expired = "Expired"
#     Margin = "Margin"
#     Rejected = "Rejected"
#     Triggered = "Triggered"
# 
# Path: OnePy/sys_module/components/signal_generator.py
# class TriggeredSignalGenerator(OnePyEnvBase):
#     """为触发的挂单生成挂单触发信号"""
#     @classmethod
#     def _generate_bare_signal(cls, order) -> SignalByTrigger:
#         kwargs = {'action_type': order.action_type,
#                   'strategy_name': order.strategy_name,
#                   'size': order.size,
#                   'ticker': order.ticker,
#                   'execute_price': order.target_price,
#                   'first_cur_price': order.first_cur_price,
#                   'mkt_id': order.mkt_id,
#                   'order_type': order.order_type,
#                   'parent_order': order}
# 
#         return SignalByTrigger(**kwargs)
# 
#     @classmethod
#     def _generate_full_signal(cls, order) -> SignalByTrigger:
#         kwargs = {'action_type': order.action_type,
#                   'strategy_name': order.strategy_name,
#                   'size': order.size,
#                   'ticker': order.ticker,
#                   'execute_price': order.target_price,
#                   'price': None,
#                   'price_pct': None,
#                   'takeprofit': order.signal.takeprofit,
#                   'takeprofit_pct': order.signal.takeprofit_pct,
#                   'stoploss': order.signal.stoploss,
#                   'stoploss_pct': order.signal.stoploss_pct,
#                   'trailingstop': order.signal.trailingstop,
#                   'trailingstop_pct': order.signal.trailingstop_pct,
#                   'order_type': order.order_type}
# 
#         return SignalByTrigger(**kwargs)
# 
#     @classmethod
#     def generate_triggered_signal(cls, order: PendingOrderBase) -> Optional[Signal]:
#         if order.ticker not in cls.env.cur_suspended_tickers:
# 
#             if order.is_triggered:
#                 if order.is_with_mkt():
#                     return cls._generate_bare_signal(order)
# 
#                 return cls._generate_full_signal(order)
# 
# Path: OnePy/sys_module/metabase_env.py
# class OnePyEnvBase:
#     """作为基类，提供env共享单例给各个模块"""
#     env = Environment


# Path: OnePy/sys_module/components/order_checker.py
from collections import defaultdict
from typing import Optional
from OnePy.constants import ActionType, OrderStatus
from OnePy.sys_module.components.signal_generator import \
    TriggeredSignalGenerator
from OnePy.sys_module.metabase_env import OnePyEnvBase




class PendingOrderChecker(OnePyEnvBase):
    def _check_orders_pending(self):
        for order in self.env.orders_pending[:]:
            if TriggeredSignalGenerator.generate_triggered_signal(order):
                order.status = OrderStatus.Triggered
                self.env.orders_pending.remove(order)  # 成交的单子需要删除

    def _check_orders_pending_with_mkt(self):
        # TODO: 有Flaw，当多个pending order同时触，只用了第一个

        for key in list(self.env.orders_child_of_mkt_dict):
            for order in self.env.orders_child_of_mkt_dict[key]:

                if TriggeredSignalGenerator.generate_triggered_signal(order):
                    order.status = OrderStatus.Triggered
                    del self.env.orders_child_of_mkt_dict[key]

                    break

    def run(self):
        self._check_orders_pending_with_mkt()
        self._check_orders_pending()



class SubmitOrderChecker(OnePyEnvBase):