def _build_metadata(self): bbg = BBG() country = bbg.fetch_contract_parameter(self.comm_bbg_code + '1 Comdty', 'COUNTRY_ISO').iloc[0, 0].upper() self.fh_ticker = 'comm ' + country.lower( ) + ' ' + self.comm_bbg_code.lower() currency = bbg.fetch_contract_parameter( self.comm_bbg_code + '1 Comdty', 'CRNCY').iloc[0, 0].upper() df = pd.DataFrame(data={ 'fh_ticker': self.fh_ticker, 'asset_class': 'commodity', 'type': 'future', 'exchange_symbol': self.comm_bbg_code.upper(), 'currency': currency, 'country': country, 'sector': self.sector_dict[self.comm_bbg_code.upper()], 'roll_method': ' '.join(self.roll_schedule) }, index=[self.comm_bbg_code]) return df
def _grab_bbg_data(self): bbg = BBG() self.contract_list = bbg.fetch_futures_list( generic_ticker=self.comm_bbg_code + '1 Comdty') self.first_notice_dates = bbg.fetch_contract_parameter( securities=self.contract_list, field='FUT_NOTICE_FIRST').sort_values('FUT_NOTICE_FIRST') # Grab all contract series df_prices = bbg.fetch_series(securities=self.contract_list, fields='PX_LAST', startdate=self.start_date, enddate=self.end_date) self.prices = df_prices.fillna(method='ffill')
def __init__(self, bbg_ticker, price_field='PX_LAST'): """ Returns an object with the following attributes: - ticker: str with bloomberg ticker for the stock - dividends: DataFrame with dividend information. Its columns are 'Declared Date', 'Amount', 'Frequency', 'Type', 'Ex-Dividend Date', 'Payable Date', 'Record Date' - price: Series with the stock price - tr_index: Series with the total return index - quantity: amount of stocks held - ts_df: DataFrame with columns 'Price', 'Dividend', 'Quantity' and 'Total Return Index' :param bbg_ticker: str, Bloomberg ticker of the stock :param price_field: Price field to be used as settlement price """ bbg = BBG() self.bbg_ticker = bbg_ticker today = pd.to_datetime('today') self.dividends = self._get_dividends(today, bbg) start_date_div = self.dividends['Ex-Dividend Date'].min() start_date_prc = pd.to_datetime(bbg.fetch_contract_parameter(self.bbg_ticker, 'CALENDAR_START_DATE').values[0][0]) # Metadata to be saved self.country = bbg.fetch_contract_parameter(self.bbg_ticker, 'COUNTRY_ISO').iloc[0, 0].upper() self.exchange_symbol = bbg.fetch_contract_parameter(self.bbg_ticker, 'ID_EXCH_SYMBOL').iloc[0, 0] self.fh_ticker = 'eqs ' + self.country.lower() + ' ' + self.exchange_symbol.lower() self.asset_class = 'equity' self.type = 'stock' self.currency = bbg.fetch_contract_parameter(self.bbg_ticker, 'CRNCY').iloc[0, 0].upper() self.sector = bbg.fetch_contract_parameter(self.bbg_ticker, 'INDUSTRY_SECTOR').iloc[0, 0].lower() self.group = bbg.fetch_contract_parameter(self.bbg_ticker, 'INDUSTRY_GROUP').iloc[0, 0].lower() self.df_metadata = pd.DataFrame(data={'fh_ticker': self.fh_ticker, 'asset_class': self.asset_class, 'type': self.type, 'exchange_symbol': self.exchange_symbol, 'currency': self.currency, 'country': self.country, 'sector': self.sector, 'group': self.group}, index=[self.bbg_ticker]) if isinstance(start_date_div, NaTType): start_date = start_date_prc else: start_date = min(start_date_div, start_date_prc) self.price = bbg.fetch_series(securities=bbg_ticker, fields=price_field, startdate=start_date, enddate=today) df = self._get_total_return_index() self.price = df[self.bbg_ticker].rename('Price') df['Price'] = self.price self.tr_index = df['Total Return Index'].rename('TR Index') self.quantity = df['Quantity'].rename('Quantity') self.df_ts = df[['Price', 'Dividend', 'Quantity', 'Total Return Index']] self.df_tracker = self._get_tracker_melted()
def __init__(self, ticker, price_field='PX_LAST'): """ Returns an object with the following atributes: - ticker: str with bloomberg ticker for the stock - dividends: DataFrame with dividend information. Its columns are 'Declared Date', 'Amount', 'Frequency', 'Type', 'Ex-Dividend Date', 'Payable Date', 'Record Date' - price: Series with the stock price - tr_index: Series with the total return index - quantity: amount of stocks held - ts_df: DataFrame with columns 'Price', 'Dividend', 'Quantity' and 'Total Return Index' :param ticker: str, Bloomberg ticker of the stock :param price_field: Price field to be used as settlement price """ # TODO allow user to choose currency bbg = BBG() self.ticker = ticker today = pd.to_datetime('today') self.dividends = self._get_dividends(today, bbg) start_date_div = self.dividends['Ex-Dividend Date'].min() start_date_prc = pd.to_datetime( bbg.fetch_contract_parameter(self.ticker, 'CALENDAR_START_DATE').values[0][0]) if isinstance(start_date_div, NaTType): start_date = start_date_prc else: start_date = min(start_date_div, start_date_prc) self.price = bbg.fetch_series(securities=ticker, fields=price_field, startdate=start_date, enddate=today) df = self._get_total_return_index() self.price = df[self.ticker].rename('Price') df['Price'] = self.price self.tr_index = df['Total Return Index'].rename('TR Index') self.quantity = df['Quantity'].rename('Quantity') self.ts_df = df[[ 'Price', 'Dividend', 'Quantity', 'Total Return Index' ]]
enddate=end_date) print(df) # Grabs cashflow payments of corporate bonds df = bbg.fetch_cash_flow('EI1436001 Govt', pd.to_datetime('03-jul-2017')) print(df) # Grabs weights of the components of an index df = bbg.fetch_index_weights(index_name='IBOV Index', ref_date=pd.to_datetime('03-jul-2017')) print(df) print(df.sum()) # Grabs all the contracts from a generic series futures_list = bbg.fetch_futures_list(generic_ticker='TY1 Comdty') print(futures_list) # grabs the first notice date for each contract df_fn = bbg.fetch_contract_parameter(securities=futures_list, field='FUT_NOTICE_FIRST') print(df_fn) # fetches fields with bulk data df_bulk = bbg.fetch_bulk_data(index_name='AAPL US Equity', field='PG_REVENUE', ref_date=start_date) print(df_bulk) # fetches historical dividends df_div = bbg.fetch_dividends('AAPL US Equity', end_date)
class BuildBondFutureTracker(object): futures_ticker_dict = { 'US': 'TY', 'GE': 'RX', 'FR': 'OAT', 'IT': 'IK', 'JP': 'JB', 'AU': 'XM', 'UK': 'G ', 'CA': 'CN' } fx_dict = { 'GE': 'EURUSD Curncy', 'UK': 'GBPUSD Curncy', 'CA': 'CADUSD Curncy', 'JP': 'JPYUSD Curncy', 'AU': 'AUDUSD Curncy', 'FR': 'EURUSD Curncy', 'IT': 'EURUSD Curncy', 'US': 'USD Curncy' } def __init__(self, country, start_date, end_date): self.bbg = BBG() self.country = country self.start_date = self._assert_date_type(start_date) self.end_date = self._assert_date_type(end_date) self.generic_tickers = [ self.futures_ticker_dict[country] + str(x) + ' Comdty' for x in range(1, 4) ] self.df_generics = self._get_generic_future_series() self.df_uc = self._get_underlying_contracts() self.contract_list = self._get_contracts_list() self.df_fn = self._get_first_notice_dates() self.df_prices = self._get_all_prices() df_tracker = self._build_tracker() self.tr_index = df_tracker[['er_index']] self.df_roll_info = df_tracker[[ 'contract_rolling_out', 'roll_out_date', 'holdings' ]].dropna(how='any') def _get_generic_future_series(self): df = self.bbg.fetch_series(securities=self.generic_tickers, fields='PX_LAST', startdate=self.start_date, enddate=self.end_date) return df def _get_underlying_contracts(self): df = self.bbg.fetch_series(securities=self.generic_tickers, fields='FUT_CUR_GEN_TICKER', startdate=self.start_date, enddate=self.end_date) df = df.reindex(self.df_generics.index).fillna(method='ffill') return df def _get_contracts_list(self): contract_list = self.bbg.fetch_futures_list( generic_ticker=self.futures_ticker_dict[self.country] + '1 Comdty') return contract_list def _get_first_notice_dates(self): df = self.bbg.fetch_contract_parameter( securities=self.contract_list, field='FUT_NOTICE_FIRST').sort_values('FUT_NOTICE_FIRST') return df def _get_all_prices(self): tickers = self.contract_list + [self.fx_dict[self.country]] df = self.bbg.fetch_series(securities=tickers, fields='PX_LAST', startdate=self.start_date, enddate=self.end_date) df = df.reindex(self.df_generics.index).fillna(method='ffill') return df def _build_tracker(self): df_tracker = pd.DataFrame(index=self.df_generics.index, columns=[ 'contract_rolling_out', 'er_index', 'roll_out_date', 'holdings' ]) # set the values for the initial date dt_ini = self.df_uc.index[0] df_tracker.loc[dt_ini, 'er_index'] = 100 contract_rolling_out = self.df_uc.loc[ dt_ini, self.futures_ticker_dict[self.country] + '2 Comdty'] + ' Comdty' df_tracker.loc[dt_ini, 'contract_rolling_out'] = contract_rolling_out holdings = df_tracker.loc[dt_ini, 'er_index'] / ( self.df_generics.loc[ dt_ini, self.futures_ticker_dict[self.country] + '2 Comdty'] * self.df_prices[self.fx_dict[self.country]].loc[dt_ini]) df_tracker.loc[dt_ini, 'holdings'] = holdings roll_out_date = self.df_fn.loc[df_tracker.loc[dt_ini, 'contract_rolling_out'], 'FUT_NOTICE_FIRST'] - BDay(1) df_tracker.loc[dt_ini, 'roll_out_date'] = roll_out_date for d, dm1 in zip(df_tracker.index[1:], df_tracker.index[:-1]): df_tracker.loc[d, 'contract_rolling_out'] = contract_rolling_out price_dm1 = self.df_prices.loc[dm1, contract_rolling_out] price_d = self.df_prices.loc[d, contract_rolling_out] pnl = holdings * (price_d - price_dm1) * self.df_prices[ self.fx_dict[self.country]].loc[d] if math.isnan(pnl): pnl = 0 df_tracker.loc[d, 'er_index'] = df_tracker.loc[dm1, 'er_index'] + pnl if d >= roll_out_date.date(): contract_rolling_out = ( self.df_uc.loc[d, self.futures_ticker_dict[self.country] + '2 Comdty'] + ' Comdty') df_tracker.loc[d, 'contract_rolling_out'] = contract_rolling_out holdings = df_tracker.loc[d, 'er_index'] / ( self.df_generics.loc[ d, self.futures_ticker_dict[self.country] + '2 Comdty'] * self.df_prices[self.fx_dict[self.country]].loc[d]) df_tracker.loc[d, 'holdings'] = holdings roll_out_date = self.df_fn.loc[df_tracker.loc[ d, 'contract_rolling_out'], 'FUT_NOTICE_FIRST'] - BDay(1) df_tracker.loc[d, 'roll_out_date'] = roll_out_date return df_tracker @staticmethod def _assert_date_type(date): if type(date) is pd.Timestamp: date = date else: date = pd.to_datetime(date) return date
class FwdIRSTrackers(object): """ Class for creating excess return indices for rolling interest rate swaps using data from bloomberg. At the start date, we assume we trade 100 notional 1M forward starting swaps with user provided maturity. We mark-to-market the position over the month and then roll it into the new 1M forward at the end of the month """ # TODO: Include more currencies currency_bbg_code_dict = { 'AUD': 'AD', 'CAD': 'CD', 'CHF': 'SF', 'EUR': 'EU', 'GBP': 'BP', 'JPY': 'JY', 'NZD': 'ND', 'SEK': 'SK', 'USD': 'US' } # TODO: Check these are correct currency_calendar_dict = { 'USD': DayCounts('30E/360 ISDA', calendar='us_trading'), 'AUD': DayCounts('ACT/365', calendar='us_trading'), 'CAD': DayCounts('ACT/365', calendar='us_trading'), 'CHF': DayCounts('30A/360', calendar='us_trading'), 'EUR': DayCounts('30U/360', calendar='us_trading'), 'GBP': DayCounts('ACT/365', calendar='us_trading'), 'JPY': DayCounts('ACT/365F', calendar='us_trading'), 'NZD': DayCounts('ACT/365', calendar='us_trading'), 'SEK': DayCounts('30A/360', calendar='us_trading') } def __init__(self, ccy='USD', tenor=10, start_date='2004-01-05', end_date='today'): """ Returns an object with the following attributes: - spot_swap_rates: Series with the rate for the spot starting swaps - fwd_swap_rates: Series with the rate for the 1M forward starting swaps - er_index: Series with the excess return index :param ccy_symbol: str, Currency symbol :param tenor: int, Tenor for the swap :param start_date: str, when the tracker should start :param end_date: str, when the tracker should end """ self.ccy = ccy self.tenor = tenor self.start_date = (pd.to_datetime(start_date) + BDay(1)).date() self.end_date = pd.to_datetime(end_date).date() self.dc = self.currency_calendar_dict[ccy] self.bbg = BBG() self.spot_swap_rates = self._get_spot_swap_rates() self.fwd_swap_rates = self._get_1m_fwd_swap_rates() self.df_tracker = self._calculate_tr_index() self.country = self.bbg.fetch_contract_parameter( self.ticker_spot, 'COUNTRY_ISO').iloc[0, 0].upper() self.exchange_symbol = self.bbg.fetch_contract_parameter( self.ticker_fwd, 'TICKER').iloc[0, 0] self.fh_ticker = 'irs ' + self.country.lower() + ' ' + self.ccy.lower() self.df_metadata = pd.DataFrame(data={ 'fh_ticker': self.fh_ticker, 'asset_class': 'fixed income', 'type': 'swap', 'currency': self.ccy.upper(), 'country': self.country.upper(), 'maturity': self.tenor, 'roll_method': '1 month' }, index=[self.ticker_spot]) self.df_tracker = self._get_tracker_melted() def _calculate_tr_index(self): spot_rate_series = self.spot_swap_rates.iloc[:, 0].dropna() fwd_rate_series = self.fwd_swap_rates.iloc[:, 0].dropna() ts_df = pd.concat([ spot_rate_series.to_frame('spot'), fwd_rate_series.to_frame('fwd_1m') ], axis=1, sort=True).fillna(method='ffill').dropna() er_index = pd.Series(index=ts_df.index) er_index.iloc[0] = 100 start_date = er_index.index[0] fwd_swap_rate = ts_df.loc[start_date, 'fwd_1m'] / 100 ref_swap_rate_d_minus_1 = fwd_swap_rate roll_date = self.dc.busdateroll(start_date + relativedelta(months=1), 'modifiedfollowing') fwd_mat = self.dc.busdateroll( start_date + relativedelta(months=1 + self.tenor * 12), 'modifiedfollowing') for d in er_index.index[1:]: current_fwd_swap_rate = ts_df.loc[d, 'fwd_1m'] / 100 current_spot_swap_rate = ts_df.loc[d, 'spot'] / 100 curr_fwd_mat = self.dc.busdateroll( d + relativedelta(months=1 + self.tenor * 12), 'modifiedfollowing') curr_spot_mat = self.dc.busdateroll( d + relativedelta(months=self.tenor * 12), 'modifiedfollowing') w = 1 if d >= roll_date else self.dc.tf( curr_fwd_mat, fwd_mat) / self.dc.tf(curr_fwd_mat, curr_spot_mat) ref_swap_rate = w * current_spot_swap_rate + ( 1 - w) * current_fwd_swap_rate # This is the present value of a basis point # Using the interpolated forward swap rate as an internal rate of return pv01 = np.sum([(1 / 2) * ((1 + ref_swap_rate / 2)**(-i)) for i in range(1, self.tenor * 2 + 1)]) if np.isnan((ref_swap_rate_d_minus_1 - ref_swap_rate) * pv01): ret = 0 else: ret = (ref_swap_rate_d_minus_1 - ref_swap_rate) * pv01 er_index[d] = er_index[:d].iloc[-2] * (1 + ret) if d >= roll_date: roll_date = self.dc.busdateroll(d + relativedelta(months=1), 'modifiedfollowing') fwd_mat = self.dc.busdateroll( d + relativedelta(months=1 + self.tenor * 12), 'modifiedfollowing') ref_swap_rate_d_minus_1 = ts_df.loc[d, 'fwd_1m'] / 100 else: ref_swap_rate_d_minus_1 = ref_swap_rate return er_index.to_frame('er_index') def _get_spot_swap_rates(self): if self.ccy == 'EUR': ticker = self.currency_bbg_code_dict[self.ccy] + 'SA' + str( self.tenor) + ' Curncy' elif self.ccy == 'NZD': ticker = self.currency_bbg_code_dict[self.ccy] + 'SWAP' + str( self.tenor) + ' Curncy' else: # The AUD is using the 6M floating leg case as default to be consistent with the forward ticker # The correct ticker is ADSW10Q Curncy 3M floating leg but then # you cannot use S0302FS 1M10Y BLC Curncy for the forward swap ticker = self.currency_bbg_code_dict[self.ccy] + 'SW' + str( self.tenor) + ' Curncy' bbg_raw_spot_data = self.bbg.fetch_series(securities=ticker, fields='PX_LAST', startdate=self.start_date, enddate=self.end_date) self.ticker_spot = ticker bbg_raw_spot_data.columns = [self.ccy + str(self.tenor) + 'Y'] bbg_raw_spot_data.index = pd.to_datetime(bbg_raw_spot_data.index) return bbg_raw_spot_data.dropna(how='all') def _get_1m_fwd_swap_rates(self): if self.ccy == 'EUR': ticker = self.currency_bbg_code_dict[self.ccy] + 'SAA' + str( self.tenor).zfill(2) + ' Curncy' elif self.ccy == 'GBP': ticker = self.currency_bbg_code_dict[self.ccy] + 'SWA' + str( self.tenor).zfill(2) + ' Curncy' elif self.ccy == 'AUD': # The AUD is using the 6M floating leg case as default to be consistent with the forward ticker # The correct ticker is ADSW10Q Curncy 3M floating leg but then # you cannot use S0302FS 1M10Y BLC Curncy for the forward swap ticker = 'S0302FS 1M' + str(self.tenor) + 'Y BLC Curncy' elif self.ccy == 'USD': ticker = self.currency_bbg_code_dict[self.ccy] + 'FS0A' + str( self.tenor) + ' Curncy' else: ticker = self.currency_bbg_code_dict[self.ccy] + 'FS0A' + str( self.tenor).zfill(2) + ' Curncy' bbg_fwd_data = self.bbg.fetch_series(securities=ticker, fields='PX_LAST', startdate=self.start_date, enddate=self.end_date) self.ticker_fwd = ticker bbg_fwd_data.columns = [self.ccy + str(self.tenor) + 'Y'] bbg_fwd_data.index = pd.to_datetime(bbg_fwd_data.index) return bbg_fwd_data.dropna(how='all') def _get_tracker_melted(self): df = self.df_tracker[['er_index' ]].rename({'er_index': self.ticker_spot}, axis=1) df['time_stamp'] = df.index.to_series() df = df.melt(id_vars='time_stamp', var_name='fh_ticker', value_name='value') df = df.dropna() return df
'S0023Z 19Y BLC2 Curncy', 'S0023Z 23D BLC2 Curncy', 'S0023Z 9Y BLC2 Curncy', 'S0023Z 17M BLC2 Curncy', 'S0023Z 1I BLC2 Curncy', 'S0023Z 22Y BLC2 Curncy', 'S0023Z 28Y BLC2 Curncy', 'S0023Z 2I BLC2 Curncy', 'S0023Z 30Y BLC2 Curncy', 'S0023Z 31Y BLC2 Curncy', 'S0023Z 32Y BLC2 Curncy', 'S0023Z 38Y BLC2 Curncy', 'S0023Z 39Y BLC2 Curncy', 'S0023Z 40Y BLC2 Curncy', 'S0023Z 42D BLC2 Curncy', 'S0023Z 48Y BLC2 Curncy' ] df_bbg = bbg.fetch_series(tickers_zero_curve, "PX_LAST", startdate=pd.to_datetime('today'), enddate=pd.to_datetime('today')) df_bbg = df_bbg.transpose() df_bbg_m = bbg.fetch_contract_parameter(tickers_zero_curve, "MATURITY") '''' The Zero curve will be used on the interpolation, to discover the rate for a specific term. ''' # fazendo a curva zero zero_curve = pd.concat([df_bbg, df_bbg_m], axis=1, sort=True).set_index('MATURITY').sort_index() zero_curve = zero_curve.astype(float) zero_curve = zero_curve.interpolate(method='linear', axis=0, limit=None, inplace=False, limit_direction='backward', limit_area=None,
startdate=start_date, enddate=end_date) # underlying contracts df_uc = bbg.fetch_series(securities=['JB1 Comdty', 'JB2 Comdty', 'JB3 Comdty'], fields='FUT_CUR_GEN_TICKER', startdate=start_date, enddate=end_date) df_uc = df_uc.reindex(df_generics.index).fillna(method='ffill') # all contracts contract_list = bbg.fetch_futures_list(generic_ticker='JB1 Comdty') # first notice date for the contract df_fn = bbg.fetch_contract_parameter( securities=contract_list, field='FUT_NOTICE_FIRST').sort_values('FUT_NOTICE_FIRST') # Grab all contract series contract_list = contract_list + ['JPYUSD Curncy'] df_prices = bbg.fetch_series(securities=contract_list, fields='PX_LAST', startdate=start_date, enddate=end_date) df_prices = df_prices.reindex(df_generics.index).fillna(method='ffill') # sets up the dataframe that will hold our results df_tracker = pd.DataFrame( index=df_generics.index, columns=['contract_rolling_out', 'er_index', 'roll_out_date', 'holdings'])
class BondFutureTracker(object): futures_ticker_dict = { 'US': 'TY', 'DE': 'RX', 'FR': 'OAT', 'IT': 'IK', 'JP': 'JB', 'AU': 'XM', 'GB': 'G ', 'CA': 'CN' } fx_dict = { 'DE': 'EURUSD Curncy', 'GB': 'GBPUSD Curncy', 'CA': 'CADUSD Curncy', 'JP': 'JPYUSD Curncy', 'AU': 'AUDUSD Curncy', 'FR': 'EURUSD Curncy', 'IT': 'EURUSD Curncy', 'US': 'USD Curncy' } def __init__(self, country, start_date, end_date): assert country in list( self.futures_ticker_dict.keys()), 'Country not yet supported' self.bbg = BBG() self.country = country self.start_date = self._assert_date_type(start_date) self.end_date = self._assert_date_type(end_date) self.generic_tickers = [ self.futures_ticker_dict[country] + str(x) + ' Comdty' for x in range(1, 4) ] self.df_generics = self._get_generic_future_series() self.df_uc = self._get_underlying_contracts() self.contract_list = self._get_contracts_list() self.df_fn = self._get_first_notice_dates() self.df_prices = self._get_all_prices() self.df_tracker = self._build_tracker() self.tr_index = self.df_tracker[['er_index']] self.fh_ticker = 'fibf ' + self.country.lower() + ' 10y' self.df_roll_info = self.df_tracker[[ 'contract_rolling_out', 'roll_out_date', 'holdings' ]].dropna(how='any') self.df_metadata = self._get_metadata() self.df_tracker = self._get_tracker_melted() def _get_tracker_melted(self): df = self.df_tracker[['er_index']].rename({'er_index': self.fh_ticker}, axis=1) df['time_stamp'] = df.index.to_series() df = df.melt(id_vars='time_stamp', var_name='fh_ticker', value_name='value') df = df.dropna() return df def _get_generic_future_series(self): df = self.bbg.fetch_series(securities=self.generic_tickers, fields='PX_LAST', startdate=self.start_date, enddate=self.end_date) return df def _get_underlying_contracts(self): df = self.bbg.fetch_series(securities=self.generic_tickers, fields='FUT_CUR_GEN_TICKER', startdate=self.start_date, enddate=self.end_date) df = df.reindex(self.df_generics.index).fillna(method='ffill') return df def _get_contracts_list(self): contract_list = self.bbg.fetch_futures_list( generic_ticker=self.futures_ticker_dict[self.country] + '1 Comdty') return contract_list def _get_first_notice_dates(self): df = self.bbg.fetch_contract_parameter( securities=self.contract_list, field='FUT_NOTICE_FIRST').sort_values('FUT_NOTICE_FIRST') return df def _get_all_prices(self): tickers = self.contract_list + [self.fx_dict[self.country]] df = self.bbg.fetch_series(securities=tickers, fields='PX_LAST', startdate=self.start_date, enddate=self.end_date) df = df.reindex(self.df_generics.index).fillna(method='ffill') return df def _build_tracker(self): df_tracker = pd.DataFrame(index=self.df_generics.index, columns=[ 'contract_rolling_out', 'er_index', 'roll_out_date', 'holdings' ]) # set the values for the initial date dt_ini = self.df_uc.dropna(how='all').index[0] df_tracker.loc[dt_ini, 'er_index'] = 100 contract_rolling_out = self.df_uc.loc[ dt_ini, self.futures_ticker_dict[self.country] + '2 Comdty'] + ' Comdty' df_tracker.loc[dt_ini, 'contract_rolling_out'] = contract_rolling_out holdings = df_tracker.loc[dt_ini, 'er_index'] / ( self.df_generics.loc[ dt_ini, self.futures_ticker_dict[self.country] + '2 Comdty'] * self.df_prices[self.fx_dict[self.country]].loc[dt_ini]) df_tracker.loc[dt_ini, 'holdings'] = holdings roll_out_date = self.df_fn.loc[df_tracker.loc[dt_ini, 'contract_rolling_out'], 'FUT_NOTICE_FIRST'] - BDay(1) df_tracker.loc[dt_ini, 'roll_out_date'] = roll_out_date for d, dm1 in zip(df_tracker.index[1:], df_tracker.index[:-1]): df_tracker.loc[d, 'contract_rolling_out'] = contract_rolling_out price_dm1 = self.df_prices.loc[dm1, contract_rolling_out] price_d = self.df_prices.loc[d, contract_rolling_out] pnl = holdings * (price_d - price_dm1) * self.df_prices[ self.fx_dict[self.country]].loc[d] if math.isnan(pnl): pnl = 0 df_tracker.loc[d, 'er_index'] = df_tracker.loc[dm1, 'er_index'] + pnl if d >= roll_out_date: contract_rolling_out = ( self.df_uc.loc[d, self.futures_ticker_dict[self.country] + '2 Comdty'] + ' Comdty') df_tracker.loc[d, 'contract_rolling_out'] = contract_rolling_out holdings = df_tracker.loc[d, 'er_index'] / ( self.df_generics.loc[ d, self.futures_ticker_dict[self.country] + '2 Comdty'] * self.df_prices[self.fx_dict[self.country]].loc[d]) df_tracker.loc[d, 'holdings'] = holdings roll_out_date = self.df_fn.loc[df_tracker.loc[ d, 'contract_rolling_out'], 'FUT_NOTICE_FIRST'] - BDay(1) df_tracker.loc[d, 'roll_out_date'] = roll_out_date return df_tracker @staticmethod def _assert_date_type(date): if type(date) is pd.Timestamp: date = date else: date = pd.to_datetime(date) return date def _get_metadata(self): df = pd.DataFrame(index=[0], data={ 'fh_ticker': self.fh_ticker, 'asset_class': 'fixed income', 'type': 'bond future', 'exchange_symbol': self.futures_ticker_dict[self.country], 'currency': 'USD', 'country': self.country, 'maturity': 10 }) return df