docstr: __init__
  :param freq:             frequency of data
  :param start_time:       closed start time for backtest
  :param end_time:         closed end time for backtest
  :param codes:            list stock_id list or a string of instruments(i.e. all, csi500, sse50)
  :param deal_price:      Union[str, Tuple[str, str], List[str]]
                          The `deal_price` supports following two types of input
                          - <deal_price> : str
                          - (<buy_price>, <sell_price>): Tuple[str] or List[str]
                          <deal_price>, <buy_price> or <sell_price> := <price>
                          <price> := str
                          - for example '$close', '$open', '$vwap' ("close" is OK. `Exchange` will help to prepend
                            "$" to the expression)
  :param subscribe_fields: list, subscribe fields. This expressions will be added to the query and `self.quote`.
                           It is useful when users want more fields to be queried
  :param limit_threshold: Union[Tuple[str, str], float, None]
                          1) `None`: no limitation
                          2) float, 0.1 for example, default None
                          3) Tuple[str, str]: (<the expression for buying stock limitation>,
                                               <the expression for sell stock limitation>)
                                              `False` value indicates the stock is tradable
                                              `True` value indicates the stock is limited and not tradable
  :param volume_threshold: Union[
                              Dict[
                                  "all": ("cum" or "current", limit_str),
                                  "buy": ("cum" or "current", limit_str),
                                  "sell":("cum" or "current", limit_str),
                              ],
                              ("cum" or "current", limit_str),
                           ]
                          1) ("cum" or "current", limit_str) denotes a single volume limit.
                              - limit_str is qlib data expression which is allowed to define your own Operator.
                              Please refer to qlib/contrib/ops/high_freq.py, here are any custom operator for
                              high frequency, such as DayCumsum. !!!NOTE: if you want you use the custom
                              operator, you need to register it in qlib_init.
                              - "cum" means that this is a cumulative value over time, such as cumulative market
                              volume. So when it is used as a volume limit, it is necessary to subtract the dealt
                              amount.
                              - "current" means that this is a real-time value and will not accumulate over time,
                              so it can be directly used as a capacity limit.
                              e.g. ("cum", "0.2 * DayCumsum($volume, '9:45', '14:45')"), ("current", "$bidV1")
                          2) "all" means the volume limits are both buying and selling.
                          "buy" means the volume limits of buying. "sell" means the volume limits of selling.
                          Different volume limits will be aggregated with min(). If volume_threshold is only
                          ("cum" or "current", limit_str) instead of a dict, the volume limits are for
                          both by default. In other words, it is same as {"all": ("cum" or "current", limit_str)}.
                          3) e.g. "volume_threshold": {
                                      "all": ("cum", "0.2 * DayCumsum($volume, '9:45', '14:45')"),
                                      "buy": ("current", "$askV1"),
                                      "sell": ("current", "$bidV1"),
                                  }
  :param open_cost:        cost rate for open, default 0.0015
  :param close_cost:       cost rate for close, default 0.0025
  :param trade_unit:       trade unit, 100 for China A market.
                           None for disable trade unit.
                           **NOTE**: `trade_unit` is included in the `kwargs`. It is necessary because we must
                           distinguish `not set` and `disable trade_unit`
  :param min_cost:         min cost, default 5
  :param impact_cost:     market impact cost rate (a.k.a. slippage). A recommended value is 0.1.
  :param extra_quote:     pandas, dataframe consists of
                              columns: like ['$vwap', '$close', '$volume', '$factor', 'limit_sell', 'limit_buy'].
                                      The limit indicates that the etf is tradable on a specific day.
                                      Necessary fields:
                                          $close is for calculating the total value at end of each day.
                                      Optional fields:
                                          $volume is only necessary when we limit the trade amount or calculate
                                          PA(vwap) indicator
                                          $vwap is only necessary when we use the $vwap price as the deal price
                                          $factor is for rounding to the trading unit
                                          limit_sell will be set to False by default (False indicates we can sell
                                          this target on this day).
                                          limit_buy will be set to False by default (False indicates we can buy
                                          this target on this day).
                              index: MultipleIndex(instrument, pd.Datetime)
docstr_tok: ["__init__",":","param","freq",":","frequency","of","data",":","param","start_time",":","closed","start","time","for","backtest",":","param","end_time",":","closed","end","time","for","backtest",":","param","codes",":","list","stock_id","list","or","a","string","of","instruments","(","i.e",".","all",",","csi500",",","sse50",")",":","param","deal_price",":","Union","[","str",",","Tuple","[","str",",","str","]",",","List","[","str","]","]","The","`","deal_price","`","supports","following","two","types","of","input","-","<","deal_price",">",":","str","-","(","<","buy_price",">",",","<","sell_price",">",")",":","Tuple","[","str","]","or","List","[","str","]","<","deal_price",">",",","<","buy_price",">","or","<","sell_price",">",":","=","<","price",">","<","price",">",":","=","str","-","for","example","'","$","close","'",",","'","$","open","'",",","'","$","vwap","'","(","``","close","''","is","OK.","`","Exchange","`","will","help","to","prepend","``","$","''","to","the","expression",")",":","param","subscribe_fields",":","list",",","subscribe","fields",".","This","expressions","will","be","added","to","the","query","and","`","self.quote","`",".","It","is","useful","when","users","want","more","fields","to","be","queried",":","param","limit_threshold",":","Union","[","Tuple","[","str",",","str","]",",","float",",","None","]","1",")","`","None","`",":","no","limitation","2",")","float",",","0.1","for","example",",","default","None","3",")","Tuple","[","str",",","str","]",":","(","<","the","expression","for","buying","stock","limitation",">",",","<","the","expression","for","sell","stock","limitation",">",")","`","False","`","value","indicates","the","stock","is","tradable","`","True","`","value","indicates","the","stock","is","limited","and","not","tradable",":","param","volume_threshold",":","Union","[","Dict","[","``","all","''",":","(","``","cum","''","or","``","current","''",",","limit_str",")",",","``","buy","''",":","(","``","cum","''","or","``","current","''",",","limit_str",")",",","``","sell","''",":","(","``","cum","''","or","``","current","''",",","limit_str",")",",","]",",","(","``","cum","''","or","``","current","''",",","limit_str",")",",","]","1",")","(","``","cum","''","or","``","current","''",",","limit_str",")","denotes","a","single","volume","limit",".","-","limit_str","is","qlib","data","expression","which","is","allowed","to","define","your","own","Operator",".","Please","refer","to","qlib\/contrib\/ops\/high_freq.py",",","here","are","any","custom","operator","for","high","frequency",",","such","as","DayCumsum",".","!","!","!","NOTE",":","if","you","want","you","use","the","custom","operator",",","you","need","to","register","it","in","qlib_init",".","-","``","cum","''","means","that","this","is","a","cumulative","value","over","time",",","such","as","cumulative","market","volume",".","So","when","it","is","used","as","a","volume","limit",",","it","is","necessary","to","subtract","the","dealt","amount",".","-","``","current","''","means","that","this","is","a","real-time","value","and","will","not","accumulate","over","time",",","so","it","can","be","directly","used","as","a","capacity","limit",".","e.g",".","(","``","cum","''",",","``","0.2","*","DayCumsum","(","$","volume",",","'","9:45","'",",","'14:45","'",")","''",")",",","(","``","current","''",",","``","$","bidV1","''",")","2",")","``","all","''","means","the","volume","limits","are","both","buying","and","selling",".","``","buy","''","means","the","volume","limits","of","buying",".","``","sell","''","means","the","volume","limits","of","selling",".","Different","volume","limits","will","be","aggregated","with","min","(",")",".","If","volume_threshold","is","only","(","``","cum","''","or","``","current","''",",","limit_str",")","instead","of","a","dict",",","the","volume","limits","are","for","both","by","default",".","In","other","words",",","it","is","same","as","{","``","all","''",":","(","``","cum","''","or","``","current","''",",","limit_str",")","}",".","3",")","e.g",".","``","volume_threshold","''",":","{","``","all","''",":","(","``","cum","''",",","``","0.2","*","DayCumsum","(","$","volume",",","'","9:45","'",",","'14:45","'",")","''",")",",","``","buy","''",":","(","``","current","''",",","``","$","askV1","''",")",",","``","sell","''",":","(","``","current","''",",","``","$","bidV1","''",")",",","}",":","param","open_cost",":","cost","rate","for","open",",","default","0.0015",":","param","close_cost",":","cost","rate","for","close",",","default","0.0025",":","param","trade_unit",":","trade","unit",",","100","for","China","A","market",".","None","for","disable","trade","unit",".","*","*","NOTE","*","*",":","`","trade_unit","`","is","included","in","the","`","kwargs","`",".","It","is","necessary","because","we","must","distinguish","`","not","set","`","and","`","disable","trade_unit","`",":","param","min_cost",":","min","cost",",","default","5",":","param","impact_cost",":","market","impact","cost","rate","(","a.k.a",".","slippage",")",".","A","recommended","value","is","0.1.",":","param","extra_quote",":","pandas",",","dataframe","consists","of","columns",":","like","[","'","$","vwap","'",",","'","$","close","'",",","'","$","volume","'",",","'","$","factor","'",",","'limit_sell","'",",","'limit_buy","'","]",".","The","limit","indicates","that","the","etf","is","tradable","on","a","specific","day",".","Necessary","fields",":","$","close","is","for","calculating","the","total","value","at","end","of","each","day",".","Optional","fields",":","$","volume","is","only","necessary","when","we","limit","the","trade","amount","or","calculate","PA","(","vwap",")","indicator","$","vwap","is","only","necessary","when","we","use","the","$","vwap","price","as","the","deal","price","$","factor","is","for","rounding","to","the","trading","unit","limit_sell","will","be","set","to","False","by","default","(","False","indicates","we","can","sell","this","target","on","this","day",")",".","limit_buy","will","be","set","to","False","by","default","(","False","indicates","we","can","buy","this","target","on","this","day",")",".","index",":","MultipleIndex","(","instrument",",","pd.Datetime",")"]
code: def __init__(
      self,
      freq: str = "day",
      start_time: Union[pd.Timestamp, str] = None,
      end_time: Union[pd.Timestamp, str] = None,
      codes: Union[list, str] = "all",
      deal_price: Union[str, Tuple[str, str], List[str], None] = None,
      subscribe_fields: list = [],
      limit_threshold: Union[Tuple[str, str], float, None] = None,
      volume_threshold: Union[tuple, dict, None] = None,
      open_cost: float = 0.0015,
      close_cost: float = 0.0025,
      min_cost: float = 5.0,
      impact_cost: float = 0.0,
      extra_quote: pd.DataFrame = None,
      quote_cls: Type[BaseQuote] = NumpyQuote,
      **kwargs: Any,
  ) -> None:
      """__init__
      :param freq:             frequency of data
      :param start_time:       closed start time for backtest
      :param end_time:         closed end time for backtest
      :param codes:            list stock_id list or a string of instruments(i.e. all, csi500, sse50)
      :param deal_price:      Union[str, Tuple[str, str], List[str]]
                              The `deal_price` supports following two types of input
                              - <deal_price> : str
                              - (<buy_price>, <sell_price>): Tuple[str] or List[str]
                              <deal_price>, <buy_price> or <sell_price> := <price>
                              <price> := str
                              - for example '$close', '$open', '$vwap' ("close" is OK. `Exchange` will help to prepend
                                "$" to the expression)
      :param subscribe_fields: list, subscribe fields. This expressions will be added to the query and `self.quote`.
                               It is useful when users want more fields to be queried
      :param limit_threshold: Union[Tuple[str, str], float, None]
                              1) `None`: no limitation
                              2) float, 0.1 for example, default None
                              3) Tuple[str, str]: (<the expression for buying stock limitation>,
                                                   <the expression for sell stock limitation>)
                                                  `False` value indicates the stock is tradable
                                                  `True` value indicates the stock is limited and not tradable
      :param volume_threshold: Union[
                                  Dict[
                                      "all": ("cum" or "current", limit_str),
                                      "buy": ("cum" or "current", limit_str),
                                      "sell":("cum" or "current", limit_str),
                                  ],
                                  ("cum" or "current", limit_str),
                               ]
                              1) ("cum" or "current", limit_str) denotes a single volume limit.
                                  - limit_str is qlib data expression which is allowed to define your own Operator.
                                  Please refer to qlib/contrib/ops/high_freq.py, here are any custom operator for
                                  high frequency, such as DayCumsum. !!!NOTE: if you want you use the custom
                                  operator, you need to register it in qlib_init.
                                  - "cum" means that this is a cumulative value over time, such as cumulative market
                                  volume. So when it is used as a volume limit, it is necessary to subtract the dealt
                                  amount.
                                  - "current" means that this is a real-time value and will not accumulate over time,
                                  so it can be directly used as a capacity limit.
                                  e.g. ("cum", "0.2 * DayCumsum($volume, '9:45', '14:45')"), ("current", "$bidV1")
                              2) "all" means the volume limits are both buying and selling.
                              "buy" means the volume limits of buying. "sell" means the volume limits of selling.
                              Different volume limits will be aggregated with min(). If volume_threshold is only
                              ("cum" or "current", limit_str) instead of a dict, the volume limits are for
                              both by default. In other words, it is same as {"all": ("cum" or "current", limit_str)}.
                              3) e.g. "volume_threshold": {
                                          "all": ("cum", "0.2 * DayCumsum($volume, '9:45', '14:45')"),
                                          "buy": ("current", "$askV1"),
                                          "sell": ("current", "$bidV1"),
                                      }
      :param open_cost:        cost rate for open, default 0.0015
      :param close_cost:       cost rate for close, default 0.0025
      :param trade_unit:       trade unit, 100 for China A market.
                               None for disable trade unit.
                               **NOTE**: `trade_unit` is included in the `kwargs`. It is necessary because we must
                               distinguish `not set` and `disable trade_unit`
      :param min_cost:         min cost, default 5
      :param impact_cost:     market impact cost rate (a.k.a. slippage). A recommended value is 0.1.
      :param extra_quote:     pandas, dataframe consists of
                                  columns: like ['$vwap', '$close', '$volume', '$factor', 'limit_sell', 'limit_buy'].
                                          The limit indicates that the etf is tradable on a specific day.
                                          Necessary fields:
                                              $close is for calculating the total value at end of each day.
                                          Optional fields:
                                              $volume is only necessary when we limit the trade amount or calculate
                                              PA(vwap) indicator
                                              $vwap is only necessary when we use the $vwap price as the deal price
                                              $factor is for rounding to the trading unit
                                              limit_sell will be set to False by default (False indicates we can sell
                                              this target on this day).
                                              limit_buy will be set to False by default (False indicates we can buy
                                              this target on this day).
                                  index: MultipleIndex(instrument, pd.Datetime)
      """
      self.freq = freq
      self.start_time = start_time
      self.end_time = end_time
  
      self.trade_unit = kwargs.pop("trade_unit", C.trade_unit)
      if len(kwargs) > 0:
          raise ValueError(f"Get Unexpected arguments {kwargs}")
  
      if limit_threshold is None:
          limit_threshold = C.limit_threshold
      if deal_price is None:
          deal_price = C.deal_price
  
      # we have some verbose information here. So logging is enabled
      self.logger = get_module_logger("online operator")
  
      # TODO: the quote, trade_dates, codes are not necessary.
      # It is just for performance consideration.
      self.limit_type = self._get_limit_type(limit_threshold)
      if limit_threshold is None:
          if C.region in [REG_CN, REG_TW]:
              self.logger.warning(
                  f"limit_threshold not set. The stocks hit the limit may be bought/sold"
              )
      elif (
          self.limit_type == self.LT_FLT
          and abs(cast(float, limit_threshold)) > 0.1
      ):
          if C.region in [REG_CN, REG_TW]:
              self.logger.warning(
                  f"limit_threshold may not be set to a reasonable value"
              )
  
      if isinstance(deal_price, str):
          if deal_price[0] != "$":
              deal_price = "$" + deal_price
          self.buy_price = self.sell_price = deal_price
      elif isinstance(deal_price, (tuple, list)):
          self.buy_price, self.sell_price = cast(
              Tuple[str, str], deal_price
          )
      else:
          raise NotImplementedError(
              f"This type of input is not supported"
          )
  
      if isinstance(codes, str):
          codes = D.instruments(codes)
      self.codes = codes
      # Necessary fields
      # $close is for calculating the total value at end of each day.
      # - if $close is None, the stock on that day is regarded as suspended.
      # $factor is for rounding to the trading unit
      # $change is for calculating the limit of the stock
  
      # 　get volume limit from kwargs
      (
          self.buy_vol_limit,
          self.sell_vol_limit,
          vol_lt_fields,
      ) = self._get_vol_limit(volume_threshold)
  
      necessary_fields = {
          self.buy_price,
          self.sell_price,
          "$close",
          "$change",
          "$factor",
          "$volume",
      }
      if self.limit_type == self.LT_TP_EXP:
          assert isinstance(limit_threshold, tuple)
          for exp in limit_threshold:
              necessary_fields.add(exp)
      all_fields = list(
          necessary_fields | set(vol_lt_fields) | set(subscribe_fields)
      )
  
      self.all_fields = all_fields
  
      self.open_cost = open_cost
      self.close_cost = close_cost
      self.min_cost = min_cost
      self.impact_cost = impact_cost
  
      self.limit_threshold: Union[
          Tuple[str, str], float, None
      ] = limit_threshold
      self.volume_threshold = volume_threshold
      self.extra_quote = extra_quote
      self.get_quote_from_qlib()
  
      # init quote by quote_df
      self.quote_cls = quote_cls
      self.quote: BaseQuote = self.quote_cls(self.quote_df, freq)
  
imports: from __future__ import annotations
  from collections import defaultdict
  from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, Union, cast
  from ..utils.index_data import IndexData
  import random
  import numpy
  import pandas
  from qlib.backtest.position import BasePosition
  from ..config import C
  from ..constant import REG_CN, REG_TW
  from ..data.data import D
  from ..log import get_module_logger
  from .decision import Order, OrderDir, OrderHelper
  from .high_performance_ds import BaseQuote, NumpyQuote
label_desc: Use image node_id 1 to create a new Exchange object  with example: obj = Exchange(freq, start_time, end_time, codes, deal_price, subscribe_fields, limit_threshold, volume_threshold, open_cost, close_cost, min_cost, impact_cost, extra_quote, quote_cls)