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.
  
  is_current: bool
      Skip date filters when current data is requested (last few bars
      until now).
  
  Notes
  -----
  Catalysts requires an end data with bar count both CCXT wants a
  start data with bar count. Since we have to make calculations here,
  we ensure that the last candle match the end_dt parameter.
  
  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",".","is_current",":","bool","Skip","date","filters","when","current","data","is","requested","(","last","few","bars","until","now",")",".","Notes","--","--","-","Catalysts","requires","an","end","data","with","bar","count","both","CCXT","wants","a","start","data","with","bar","count",".","Since","we","have","to","make","calculations","here",",","we","ensure","that","the","last","candle","match","the","end_dt","parameter",".","Returns","--","--","--","-","DataFrame","A","dataframe","containing","the","requested","data","."]
code: def get_history_window(
      self,
      assets,
      end_dt,
      bar_count,
      frequency,
      field,
      data_frequency=None,
      is_current=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.
  
      is_current: bool
          Skip date filters when current data is requested (last few bars
          until now).
  
      Notes
      -----
      Catalysts requires an end data with bar count both CCXT wants a
      start data with bar count. Since we have to make calculations here,
      we ensure that the last candle match the end_dt parameter.
  
      Returns
      -------
      DataFrame
          A dataframe containing the requested data.
  
      """
      freq, candle_size, unit, data_frequency = get_frequency(
          frequency, data_frequency, supported_freqs=["T", "D", "H"]
      )
  
      # we want to avoid receiving empty candles
      # so we request more than needed
      # TODO: consider defining a const per asset
      # and/or some retry mechanism (in each iteration request more data)
      min_candles_number = get_candles_number_from_minutes(
          unit, candle_size, self.MIN_MINUTES_REQUESTED
      )
  
      requested_bar_count = bar_count
  
      if requested_bar_count < min_candles_number:
          requested_bar_count = min_candles_number
  
      # The get_history method supports multiple asset
      candles = self.get_candles(
          freq=freq,
          assets=assets,
          bar_count=requested_bar_count,
          end_dt=end_dt if not is_current else None,
      )
  
      # candles sanity check - verify no empty candles were received:
      for asset in candles:
          if not candles[asset]:
              raise NoCandlesReceivedFromExchange(
                  bar_count=requested_bar_count,
                  end_dt=end_dt,
                  asset=asset,
                  exchange=self.name,
              )
  
      # for avoiding unnecessary forward fill end_dt is taken back one second
      forward_fill_till_dt = end_dt - timedelta(seconds=1)
  
      series = get_candles_df(
          candles=candles,
          field=field,
          freq=frequency,
          bar_count=requested_bar_count,
          end_dt=forward_fill_till_dt,
      )
  
      # TODO: consider how to approach this edge case
      # delta_candle_size = candle_size * 60 if unit == 'H' else candle_size
      # Checking to make sure that the dates match
      # delta = get_delta(delta_candle_size, data_frequency)
      # adj_end_dt = end_dt - delta
      # last_traded = asset_series.index[-1]
      # if last_traded < adj_end_dt:
      #    raise LastCandleTooEarlyError(
      #        last_traded=last_traded,
      #        end_dt=adj_end_dt,
      #        exchange=self.name,
      #    )
  
      df = pd.DataFrame(series)
      df.dropna(inplace=True)
  
      return df.tail(bar_count)
  
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 17 for calling the Exchange obj's underlying member method code with example usage: obj.get_history_window(assets, end_dt, bar_count, frequency, field, data_frequency, is_current) and returns: df