class_docstr: Trade decisions are made by strategy and executed by executor
  
  Motivation:
      Here are several typical scenarios for `BaseTradeDecision`
  
      Case 1:
      1. Outer strategy makes a decision. The decision is not available at the start of current interval
      2. After a period of time, the decision are updated and become available
      3. The inner strategy try to get the decision and start to execute the decision according to `get_range_limit`
      Case 2:
      1. The outer strategy's decision is available at the start of the interval
      2. Same as `case 1.3`
class_docstr_tok: ["Trade","decisions","are","made","by","strategy","and","executed","by","executor","Motivation",":","Here","are","several","typical","scenarios","for","`","BaseTradeDecision","`","Case","1",":","1",".","Outer","strategy","makes","a","decision",".","The","decision","is","not","available","at","the","start","of","current","interval","2",".","After","a","period","of","time",",","the","decision","are","updated","and","become","available","3",".","The","inner","strategy","try","to","get","the","decision","and","start","to","execute","the","decision","according","to","`","get_range_limit","`","Case","2",":","1",".","The","outer","strategy","'s","decision","is","available","at","the","start","of","the","interval","2",".","Same","as","`","case","1.3","`"]
docstr: Parameters
  ----------
  strategy : BaseStrategy
      The strategy who make the decision
  trade_range: Union[Tuple[int, int], Callable] (optional)
      The index range for underlying strategy.
  
      Here are two examples of trade_range for each type
  
      1) Tuple[int, int]
      start_index and end_index of the underlying strategy(both sides are closed)
  
      2) TradeRange
code: def __init__(
      self,
      strategy: BaseStrategy,
      trade_range: Union[Tuple[int, int], TradeRange, None] = None,
  ) -> None:
      """
      Parameters
      ----------
      strategy : BaseStrategy
          The strategy who make the decision
      trade_range: Union[Tuple[int, int], Callable] (optional)
          The index range for underlying strategy.
  
          Here are two examples of trade_range for each type
  
          1) Tuple[int, int]
          start_index and end_index of the underlying strategy(both sides are closed)
  
          2) TradeRange
  
      """
      self.strategy = strategy
      (
          self.start_time,
          self.end_time,
      ) = strategy.trade_calendar.get_step_time()
      # upper strategy has no knowledge about the sub executor before `_init_sub_trading`
      self.total_step: Optional[int] = None
      if isinstance(trade_range, tuple):
          # for Tuple[int, int]
          trade_range = IdxTradeRange(*trade_range)
      self.trade_range: Optional[TradeRange] = trade_range
  
imports: from __future__ import annotations
  from abc import abstractmethod
  from datetime import time
  from enum import IntEnum
  from typing import TYPE_CHECKING, Any, ClassVar, Generic, List, Optional, Tuple, TypeVar, Union, cast
  from qlib.backtest.utils import TradeCalendarManager
  from qlib.data.data import Cal
  from qlib.log import get_module_logger
  from qlib.utils.time import concat_date_time, epsilon_change
  from dataclasses import dataclass
  import numpy
  import pandas
label_desc: Use image node_id 1 to create a new BaseTradeDecision object from inherited base classes: Generic with example: obj = BaseTradeDecision(strategy, trade_range)