code: def test_get_candles_df(self):
      assets = ["btc_usdt", "eth_usdt"]
  
      # test forward fill in the end
      candles = [
          {
              "high": 595,
              "volume": 10,
              "low": 594,
              "close": 595,
              "open": 594,
              "last_traded": Timestamp(
                  "2018-03-01 09:45:00+0000", tz="UTC"
              ),
          },
          {
              "high": 594,
              "volume": 108,
              "low": 592,
              "close": 593,
              "open": 592,
              "last_traded": Timestamp(
                  "2018-03-01 09:50:00+0000", tz="UTC"
              ),
          },
      ]
  
      expected = [
          {
              "high": 595.0,
              "volume": 10.0,
              "low": 594.0,
              "close": 595.0,
              "open": 594.0,
              "last_traded": Timestamp(
                  "2018-03-01 09:45:00+0000", tz="UTC"
              ),
          },
          {
              "high": 594.0,
              "volume": 108.0,
              "low": 592.0,
              "close": 593.0,
              "open": 592.0,
              "last_traded": Timestamp(
                  "2018-03-01 09:50:00+0000", tz="UTC"
              ),
          },
          {
              "high": 593.0,
              "volume": 0.0,
              "low": 593.0,
              "close": 593.0,
              "open": 593.0,
              "last_traded": Timestamp(
                  "2018-03-01 09:55:00+0000", tz="UTC"
              ),
          },
      ]
  
      periods = [
          Timestamp("2018-03-01 09:45:00+0000", tz="UTC"),
          Timestamp("2018-03-01 09:50:00+0000", tz="UTC"),
          Timestamp("2018-03-01 09:55:00+0000", tz="UTC"),
      ]
  
      expected_df = transform_candles_to_df(expected)
  
      self.verify_forward_fill_df_if_needed(
          candles, periods, expected_df
      )
      self.verify_get_candles_df(
          assets, candles, periods[2], expected_df, True
      )
  
      # test forward fill in the middle
      candles = [
          {
              "high": 595,
              "volume": 10,
              "low": 594,
              "close": 595,
              "open": 594,
              "last_traded": Timestamp(
                  "2018-03-01 09:45:00+0000", tz="UTC"
              ),
          },
          {
              "high": 594,
              "volume": 108,
              "low": 592,
              "close": 593,
              "open": 592,
              "last_traded": Timestamp(
                  "2018-03-01 09:55:00+0000", tz="UTC"
              ),
          },
      ]
  
      expected = [
          {
              "high": 595.0,
              "volume": 10.0,
              "low": 594.0,
              "close": 595.0,
              "open": 594.0,
              "last_traded": Timestamp(
                  "2018-03-01 09:45:00+0000", tz="UTC"
              ),
          },
          {
              "high": 595.0,
              "volume": 0.0,
              "low": 595.0,
              "close": 595.0,
              "open": 595.0,
              "last_traded": Timestamp(
                  "2018-03-01 09:50:00+0000", tz="UTC"
              ),
          },
          {
              "high": 594.0,
              "volume": 108.0,
              "low": 592.0,
              "close": 593.0,
              "open": 592.0,
              "last_traded": Timestamp(
                  "2018-03-01 09:55:00+0000", tz="UTC"
              ),
          },
      ]
  
      expected_df = transform_candles_to_df(expected)
      self.verify_forward_fill_df_if_needed(
          candles, periods, expected_df
      )
      self.verify_get_candles_df(
          assets, candles, periods[2], expected_df
      )
  
      # test "forward fill" at the beginning
      candles = [
          {
              "high": 595,
              "volume": 10,
              "low": 594,
              "close": 595,
              "open": 594,
              "last_traded": Timestamp(
                  "2018-03-01 09:50:00+0000", tz="UTC"
              ),
          },
          {
              "high": 594,
              "volume": 108,
              "low": 592,
              "close": 593,
              "open": 592,
              "last_traded": Timestamp(
                  "2018-03-01 09:55:00+0000", tz="UTC"
              ),
          },
      ]
  
      expected = [
          {
              "high": np.NaN,
              "volume": 0.0,
              "low": np.NaN,
              "close": np.NaN,
              "open": np.NaN,
              "last_traded": Timestamp(
                  "2018-03-01 09:45:00+0000", tz="UTC"
              ),
          },
          {
              "high": 595,
              "volume": 10,
              "low": 594,
              "close": 595,
              "open": 594,
              "last_traded": Timestamp(
                  "2018-03-01 09:50:00+0000", tz="UTC"
              ),
          },
          {
              "high": 594,
              "volume": 108,
              "low": 592,
              "close": 593,
              "open": 592,
              "last_traded": Timestamp(
                  "2018-03-01 09:55:00+0000", tz="UTC"
              ),
          },
      ]
  
      expected_df = transform_candles_to_df(expected)
      self.verify_forward_fill_df_if_needed(
          candles, periods, expected_df
      )
  
file_path: catalyst/tests/exchange/test_exchange_utils.py
imports: from catalyst.exchange.utils.exchange_utils import transform_candles_to_df, forward_fill_df_if_needed, get_candles_df
  from catalyst.testing.fixtures import WithLogger, CatalystTestCase
  from datetime import timedelta
  from pandas import Timestamp, DataFrame, concat
  import numpy
label_desc: Use image node_id 4 for calling the TestExchangeUtils obj's underlying member method code with example usage: obj.test_get_candles_df() without return types