class_docstr: Motivation:
      PortfolioMetrics is for supporting portfolio related metrics.
  
  Implementation:
  
      daily portfolio metrics of the account
      contain those followings: return, cost, turnover, account, cash, bench, value
      For each step(bar/day/minute), each column represents
      - return: the return of the portfolio generated by strategy **without transaction fee**.
      - cost: the transaction fee and slippage.
      - account: the total value of assets(cash and securities are both included) in user account based on the close price of each step.
      - cash: the amount of cash in user's account.
      - bench: the return of the benchmark
      - value: the total value of securities/stocks/instruments (cash is excluded).
  
      update report
class_docstr_tok: ["Motivation",":","PortfolioMetrics","is","for","supporting","portfolio","related","metrics",".","Implementation",":","daily","portfolio","metrics","of","the","account","contain","those","followings",":","return",",","cost",",","turnover",",","account",",","cash",",","bench",",","value","For","each","step","(","bar\/day\/minute",")",",","each","column","represents","-","return",":","the","return","of","the","portfolio","generated","by","strategy","*","*","without","transaction","fee","*","*",".","-","cost",":","the","transaction","fee","and","slippage",".","-","account",":","the","total","value","of","assets","(","cash","and","securities","are","both","included",")","in","user","account","based","on","the","close","price","of","each","step",".","-","cash",":","the","amount","of","cash","in","user","'s","account",".","-","bench",":","the","return","of","the","benchmark","-","value",":","the","total","value","of","securities\/stocks\/instruments","(","cash","is","excluded",")",".","update","report"]
code: def update_portfolio_metrics_record(
      self,
      trade_start_time: Union[str, pd.Timestamp] = None,
      trade_end_time: Union[str, pd.Timestamp] = None,
      account_value: float | None = None,
      cash: float | None = None,
      return_rate: float | None = None,
      total_turnover: float | None = None,
      turnover_rate: float | None = None,
      total_cost: float | None = None,
      cost_rate: float | None = None,
      stock_value: float | None = None,
      bench_value: float | None = None,
  ) -> None:
      # check data
      if None in [
          trade_start_time,
          account_value,
          cash,
          return_rate,
          total_turnover,
          turnover_rate,
          total_cost,
          cost_rate,
          stock_value,
      ]:
          raise ValueError(
              "None in [trade_start_time, account_value, cash, return_rate, total_turnover, turnover_rate, "
              "total_cost, cost_rate, stock_value]",
          )
  
      if trade_end_time is None and bench_value is None:
          raise ValueError(
              "Both trade_end_time and bench_value is None, benchmark is not usable."
          )
      elif bench_value is None:
          bench_value = self._sample_benchmark(
              self.bench, trade_start_time, trade_end_time
          )
  
      # update pm data
      self.accounts[trade_start_time] = account_value
      self.returns[trade_start_time] = return_rate
      self.total_turnovers[trade_start_time] = total_turnover
      self.turnovers[trade_start_time] = turnover_rate
      self.total_costs[trade_start_time] = total_cost
      self.costs[trade_start_time] = cost_rate
      self.values[trade_start_time] = stock_value
      self.cashes[trade_start_time] = cash
      self.benches[trade_start_time] = bench_value
      # update pm
      self.latest_pm_time = trade_start_time
  
imports: from __future__ import annotations
  import pathlib
  from collections import OrderedDict
  from typing import Any, Dict, List, Optional, Text, Tuple, Type, Union, cast
  import numpy
  import pandas
  import qlib.utils.index_data
  from qlib.backtest.decision import BaseTradeDecision, Order, OrderDir
  from qlib.backtest.exchange import Exchange
  from ..tests.config import CSI300_BENCH
  from ..utils.resam import get_higher_eq_freq_feature, resam_ts_data
  from .high_performance_ds import BaseOrderIndicator, BaseSingleMetric, NumpyOrderIndicator
label_desc: Use image node_id 11 for calling the PortfolioMetrics obj's underlying member method code with example usage: obj.update_portfolio_metrics_record(trade_start_time, trade_end_time, account_value, cash, return_rate, total_turnover, turnover_rate, total_cost, cost_rate, stock_value, bench_value) without return types