docstr: Public API method that returns a dataframe containing the requested
  history window.  Data is fully adjusted.
  
  Parameters
  ----------
  assets : list[TradingPair]
      The assets whose data is desired.
  
  end_dt: datetime
      The date of the last bar.
  
  bar_count: int
      The number of bars desired.
  
  frequency: string
      "1d" or "1m"
  
  field: string
      The desired field of the asset.
  
  data_frequency: string
      The frequency of the data to query; i.e. whether the data is
      'daily' or 'minute' bars.
  
  # TODO: fill how?
  ffill: boolean
      Forward-fill missing values. Only has effect if field
      is 'price'.
  
  Returns
  -------
  DataFrame
      A dataframe containing the requested data.
docstr_tok: ["Public","API","method","that","returns","a","dataframe","containing","the","requested","history","window",".","Data","is","fully","adjusted",".","Parameters","--","--","--","--","--","assets",":","list","[","TradingPair","]","The","assets","whose","data","is","desired",".","end_dt",":","datetime","The","date","of","the","last","bar",".","bar_count",":","int","The","number","of","bars","desired",".","frequency",":","string","``","1d","''","or","``","1m","''","field",":","string","The","desired","field","of","the","asset",".","data_frequency",":","string","The","frequency","of","the","data","to","query",";","i.e",".","whether","the","data","is","'daily","'","or","'minute","'","bars",".","#","TODO",":","fill","how","?","ffill",":","boolean","Forward-fill","missing","values",".","Only","has","effect","if","field","is","'price","'",".","Returns","--","--","--","-","DataFrame","A","dataframe","containing","the","requested","data","."]
code: def get_history_window_with_bundle(
      self,
      assets,
      end_dt,
      bar_count,
      frequency,
      field,
      data_frequency=None,
      ffill=True,
      force_auto_ingest=False,
  ):
      """
      Public API method that returns a dataframe containing the requested
      history window.  Data is fully adjusted.
  
      Parameters
      ----------
      assets : list[TradingPair]
          The assets whose data is desired.
  
      end_dt: datetime
          The date of the last bar.
  
      bar_count: int
          The number of bars desired.
  
      frequency: string
          "1d" or "1m"
  
      field: string
          The desired field of the asset.
  
      data_frequency: string
          The frequency of the data to query; i.e. whether the data is
          'daily' or 'minute' bars.
  
      # TODO: fill how?
      ffill: boolean
          Forward-fill missing values. Only has effect if field
          is 'price'.
  
      Returns
      -------
      DataFrame
          A dataframe containing the requested data.
  
      """
      # TODO: this function needs some work,
      # we're currently using it just for benchmark data
      freq, candle_size, unit, data_frequency = get_frequency(
          frequency, data_frequency, supported_freqs=["T", "D"]
      )
      adj_bar_count = candle_size * bar_count
      try:
          series = self.bundle.get_history_window_series_and_load(
              assets=assets,
              end_dt=end_dt,
              bar_count=adj_bar_count,
              field=field,
              data_frequency=data_frequency,
              force_auto_ingest=force_auto_ingest,
          )
  
      except (PricingDataNotLoadedError, NoDataAvailableOnExchange):
          series = dict()
  
      for asset in assets:
          if asset not in series or series[asset].index[-1] < end_dt:
              # Adding bars too recent to be contained in the consolidated
              # exchanges bundles. We go directly against the exchange
              # to retrieve the candles.
              start_dt = get_start_dt(
                  end_dt, adj_bar_count, data_frequency
              )
              trailing_dt = (
                  series[asset].index[-1] + get_delta(1, data_frequency)
                  if asset in series
                  else start_dt
              )
  
              # The get_history method supports multiple asset
              # Use the original frequency to let each api optimize
              # the size of result sets
              trailing_bars = get_periods(trailing_dt, end_dt, freq)
              candles = self.get_candles(
                  freq=freq,
                  assets=asset,
                  end_dt=end_dt,
                  bar_count=trailing_bars
                  if trailing_bars < 500
                  else 500,
              )
  
              last_value = (
                  series[asset].iloc(0) if asset in series else np.nan
              )
  
              # Create a series with the common data_frequency, ffill
              # missing values
              candle_series = self.get_series_from_candles(
                  candles=candles,
                  start_dt=trailing_dt,
                  end_dt=end_dt,
                  data_frequency=data_frequency,
                  field=field,
                  previous_value=last_value,
              )
  
              if asset in series:
                  series[asset].append(candle_series)
  
              else:
                  series[asset] = candle_series
  
      df = resample_history_df(pd.DataFrame(series), freq, field)
      # TODO: consider this more carefully
      df.dropna(inplace=True)
  
      return df
  
imports: import abc
  from abc import ABCMeta, abstractmethod, abstractproperty
  from datetime import timedelta
  from time import sleep
  import numpy
  import pandas
  from catalyst.constants import LOG_LEVEL
  from catalyst.data.data_portal import BASE_FIELDS
  from catalyst.exchange.exchange_bundle import ExchangeBundle
  from catalyst.exchange.exchange_errors import MismatchingQuoteCurrencies, SymbolNotFoundOnExchange, PricingDataNotLoadedError, NoDataAvailableOnExchange, NoValueForField, NoCandlesReceivedFromExchange, TickerNotFoundError, NotEnoughCashError
  from catalyst.exchange.utils.datetime_utils import get_delta, get_periods_range, get_periods, get_start_dt, get_frequency, get_candles_number_from_minutes
  from catalyst.exchange.utils.exchange_utils import get_exchange_symbols, resample_history_df, has_bundle, get_candles_df
  from logbook import Logger
label_desc: Use image node_id 18 for calling the Exchange obj's underlying member method code with example usage: obj.get_history_window_with_bundle(assets, end_dt, bar_count, frequency, field, data_frequency, ffill, force_auto_ingest) and returns: df