docstr: A spot value for the exchange bundle. Try to ingest data if not in
  the bundle.
  
  Parameters
  ----------
  exchange_name: str
  assets: list[TradingPair]
  field: str
  dt: datetime
  data_frequency: str
  
  Returns
  -------
  float
docstr_tok: ["A","spot","value","for","the","exchange","bundle",".","Try","to","ingest","data","if","not","in","the","bundle",".","Parameters","--","--","--","--","--","exchange_name",":","str","assets",":","list","[","TradingPair","]","field",":","str","dt",":","datetime","data_frequency",":","str","Returns","--","--","--","-","float"]
code: def get_exchange_spot_value(
      self, exchange_name, assets, field, dt, data_frequency
  ):
      """
      A spot value for the exchange bundle. Try to ingest data if not in
      the bundle.
  
      Parameters
      ----------
      exchange_name: str
      assets: list[TradingPair]
      field: str
      dt: datetime
      data_frequency: str
  
      Returns
      -------
      float
  
      """
      bundle = self.exchange_bundles[exchange_name]
      if data_frequency == "daily":
          dt = dt.floor("1D")
      else:
          dt = dt.floor("1 min")
          # In order to align with the crypto left
          # bounded candles, we request the candle of the previous timestamp
          # (do not include the current minute)
          dt = dt - datetime.timedelta(minutes=1)
  
      if AUTO_INGEST:
          try:
              return bundle.get_spot_values(
                  assets, field, dt, data_frequency
              )
          except PricingDataNotLoadedError:
              log.info(
                  "pricing data for {symbol} not found on {dt}"
                  ", updating the bundles.".format(
                      symbol=[asset.symbol for asset in assets], dt=dt
                  )
              )
              bundle.ingest_assets(
                  assets=assets,
                  start_dt=self._first_trading_day,
                  end_dt=self._last_available_session,
                  data_frequency=data_frequency,
                  show_progress=True,
              )
              return bundle.get_spot_values(
                  assets, field, dt, data_frequency, True
              )
      else:
          return bundle.get_spot_values(
              assets, field, dt, data_frequency
          )
  
imports: import abc
  import datetime
  import numpy
  import pandas
  from catalyst.assets._assets import TradingPair
  from catalyst.constants import LOG_LEVEL, AUTO_INGEST
  from catalyst.data.data_portal import DataPortal
  from catalyst.exchange.exchange_bundle import ExchangeBundle
  from catalyst.exchange.exchange_errors import ExchangeRequestError, PricingDataNotLoadedError
  from catalyst.exchange.utils.exchange_utils import resample_history_df, group_assets_by_exchange
  from catalyst.exchange.utils.datetime_utils import get_frequency, get_start_dt
  from logbook import Logger
  from redo import retry
label_desc: Use image node_id 4 for calling the DataPortalExchangeBacktest obj's underlying member method code with example usage: obj.get_exchange_spot_value(exchange_name, assets, field, dt, data_frequency) and returns: bundle, bundle, bundle