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 generate_target_weight_position(
      self, score, current, trade_start_time, trade_end_time
  ):
      trade_date = trade_start_time
      pre_date = get_pre_trading_date(
          trade_date, future=True
      )  # previous trade date
  
      # load risk data
      outs = self.get_risk_data(pre_date)
      if outs is None:
          self.logger.warning(
              f"no risk data for {pre_date:%Y-%m-%d}, skip optimization"
          )
          return None
      factor_exp, factor_cov, specific_risk, universe, blacklist = outs
  
      # transform score
      # NOTE: for stocks missing score, we always assume they have the lowest score
      score = score.reindex(universe).fillna(score.min()).values
  
      # get current weight
      # NOTE: if a stock is not in universe, its current weight will be zero
      cur_weight = current.get_stock_weight_dict(only_stock=False)
      cur_weight = np.array(
          [cur_weight.get(stock, 0) for stock in universe]
      )
      assert all(cur_weight >= 0), "current weight has negative values"
      cur_weight = cur_weight / self.get_risk_degree(
          trade_date
      )  # sum of weight should be risk_degree
      if cur_weight.sum() > 1 and self.verbose:
          self.logger.warning(
              f"previous total holdings excess risk degree (current: {cur_weight.sum()})"
          )
  
      # load bench weight
      bench_weight = D.features(
          D.instruments("all"),
          [f"${self.market}_weight"],
          start_time=pre_date,
          end_time=pre_date,
      ).squeeze()
      bench_weight.index = bench_weight.index.droplevel(
          level="datetime"
      )
      bench_weight = bench_weight.reindex(universe).fillna(0).values
  
      # whether stock tradable
      # NOTE: currently we use last day volume to check whether tradable
      tradable = D.features(
          D.instruments("all"),
          ["$volume"],
          start_time=pre_date,
          end_time=pre_date,
      ).squeeze()
      tradable.index = tradable.index.droplevel(level="datetime")
      tradable = tradable.reindex(universe).gt(0).values
      mask_force_hold = ~tradable
  
      # mask force sell
      mask_force_sell = np.array(
          [stock in blacklist for stock in universe], dtype=bool
      )
  
      # optimize
      weight = self.optimizer(
          r=score,
          F=factor_exp,
          cov_b=factor_cov,
          var_u=specific_risk**2,
          w0=cur_weight,
          wb=bench_weight,
          mfh=mask_force_hold,
          mfs=mask_force_sell,
      )
  
      target_weight_position = {
          stock: weight
          for stock, weight in zip(universe, weight)
          if weight > 0
      }
  
      if self.verbose:
          self.logger.info("trade date: {:%Y-%m-%d}".format(trade_date))
          self.logger.info(
              "number of holding stocks: {}".format(
                  len(target_weight_position)
              )
          )
          self.logger.info(
              "total holding weight: {:.6f}".format(weight.sum())
          )
  
      return target_weight_position
  
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 3 for calling the EnhancedIndexingStrategy obj's underlying member method code with example usage: obj.generate_target_weight_position(score, current, trade_start_time, trade_end_time) and returns: target_weight_position, None