def get_futures_daily_close_data(tickers: list,
                                 start_date: datetime = None,
                                 end_date: datetime = None) -> pd.DataFrame:
    """
    Returns a DataFrame with the daily close of futures between start and end dates. N/A are rolled forward if they
    exists before the last observation date of the resp. futures contract.
    :param tickers: list of strings
    :param start_date: datetime
    :param end_date: datetime
    :return: DataFrame
    """
    # get the raw data from the financial database
    fin_db = FinancialDatabase(__MY_DATABASE_NAME__)
    raw_futures_data = fin_db.get_close_price_df(tickers, start_date, end_date)

    # clean the data by rolling N/A forward
    cleaned_futures_data = raw_futures_data.fillna(method='ffill')

    # get last observation date per ticker
    ticker_last_obs_date_dict = fin_db.get_ticker_underlying_attribute_dict(
        tickers, Underlying.latest_observation_date_with_values)

    # loop through each column and set each row to N/A if it is after the last observation date for the resp. ticker
    for col_i in range(cleaned_futures_data.shape[1]):
        last_obs_date = ticker_last_obs_date_dict[list(cleaned_futures_data)
                                                  [col_i]]
        try:
            last_obs_date_index = cleaned_futures_data.index.get_loc(
                last_obs_date)
        except KeyError:  # in case when the last observation period is after end_date
            last_obs_date_index = cleaned_futures_data.shape[0]
        cleaned_futures_data.iloc[last_obs_date_index + 1:, col_i] = np.nan
    return cleaned_futures_data
def get_expiry_date_dict(tickers: list) -> dict:
    """
    Return a dictionary: keys = tickers (str), values = expiry dates (datetime)
    :param tickers: list of strings
    :return: dictionary
    """
    fin_db = FinancialDatabase(__MY_DATABASE_NAME__)
    asset_class = fin_db.get_ticker_underlying_attribute_dict(
        tickers, Underlying.underlying_type)
    desc = fin_db.get_ticker_underlying_attribute_dict(tickers,
                                                       Underlying.description)
    result_dict = {}
    for ticker in tickers:
        if asset_class[ticker] == 'FUTURE':
            expiry_desc = desc[ticker]
            result_dict.update({
                ticker:
                datetime.strptime(expiry_desc.split()[1], '%Y-%m-%d')
            })
        else:
            logger.warning(
                '{} is of type {} and does not have a expiry date.'.format(
                    ticker, asset_class[ticker]))
    return result_dict