docstr: Parameters
  ----------
  start_time : pd.Timestamp
  end_time : pd.Timestamp
      Both sides (start_time, end_time) are closed
  
  Returns
  -------
  Tuple[pd.Timestamp, pd.Timestamp]:
      The tradable time range.
      - It is intersection of [start_time, end_time] and the rule of TradeRange itself
code: def clip_time_range(
      self, start_time: pd.Timestamp, end_time: pd.Timestamp
  ) -> Tuple[pd.Timestamp, pd.Timestamp]:
      """
      Parameters
      ----------
      start_time : pd.Timestamp
      end_time : pd.Timestamp
          Both sides (start_time, end_time) are closed
  
      Returns
      -------
      Tuple[pd.Timestamp, pd.Timestamp]:
          The tradable time range.
          - It is intersection of [start_time, end_time] and the rule of TradeRange itself
      """
      raise NotImplementedError(
          f"Please implement the `clip_time_range` method"
      )
  
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 2 for calling the TradeRange obj's underlying member method code with example usage: obj.clip_time_range(start_time, end_time) without return types