class_docstr: Enhanced Indexing Strategy
  
  Enhanced indexing combines the arts of active management and passive management,
  with the aim of outperforming a benchmark index (e.g., S&P 500) in terms of
  portfolio return while controlling the risk exposure (a.k.a. tracking error).
  
  Users need to prepare their risk model data like below:
  
  .. code-block:: text
  
      ├── /path/to/riskmodel
      ├──── 20210101
      ├────── factor_exp.{csv|pkl|h5}
      ├────── factor_cov.{csv|pkl|h5}
      ├────── specific_risk.{csv|pkl|h5}
      ├────── blacklist.{csv|pkl|h5}  # optional
  
  The risk model data can be obtained from risk data provider. You can also use
  `qlib.model.riskmodel.structured.StructuredCovEstimator` to prepare these data.
  
  Args:
      riskmodel_path (str): risk model path
      name_mapping (dict): alternative file names
code: def get_risk_data(self, date):
      if date in self._riskdata_cache:
          return self._riskdata_cache[date]
  
      root = self.riskmodel_root + "/" + date.strftime("%Y%m%d")
      if not os.path.exists(root):
          return None
  
      factor_exp = load_dataset(
          root + "/" + self.factor_exp_path, index_col=[0]
      )
      factor_cov = load_dataset(
          root + "/" + self.factor_cov_path, index_col=[0]
      )
      specific_risk = load_dataset(
          root + "/" + self.specific_risk_path, index_col=[0]
      )
  
      if not factor_exp.index.equals(specific_risk.index):
          # NOTE: for stocks missing specific_risk, we always assume it has the highest volatility
          specific_risk = specific_risk.reindex(
              factor_exp.index, fill_value=specific_risk.max()
          )
  
      universe = factor_exp.index.tolist()
  
      blacklist = []
      if os.path.exists(root + "/" + self.blacklist_path):
          blacklist = load_dataset(
              root + "/" + self.blacklist_path
          ).index.tolist()
  
      self._riskdata_cache[date] = (
          factor_exp.values,
          factor_cov.values,
          specific_risk.values,
          universe,
          blacklist,
      )
  
      return self._riskdata_cache[date]
  
imports: import os
  import copy
  import warnings
  import numpy
  import pandas
  from typing import Dict, List, Text, Tuple, Union
  from abc import ABC
  from qlib.data import D
  from qlib.data.dataset import Dataset
  from qlib.model.base import BaseModel
  from qlib.strategy.base import BaseStrategy
  from qlib.backtest.position import Position
  from qlib.backtest.signal import Signal, create_signal_from
  from qlib.backtest.decision import Order, OrderDir, TradeDecisionWO
  from qlib.log import get_module_logger
  from qlib.utils import get_pre_trading_date, load_dataset
  from qlib.contrib.strategy.order_generator import OrderGenerator, OrderGenWOInteract
  from qlib.contrib.strategy.optimizer import EnhancedIndexingOptimizer
label_desc: Use image node_id 2 for calling the EnhancedIndexingStrategy obj's underlying member method code with example usage: obj.get_risk_data(date) and returns: self, self, None