freq_min_mult = 5 # Resample into 1 minute data and fill down all points implied_vol_df = market.fetch_market(md_request)[asset +'VON.open'].resample('1min').first().fillna(method='ffill') # Filter data by 1000 New York time, and return back to UTC, remove any out of trading hours # Then strip of time of day from the timestamp implied_vol_df = filter.filter_time_series_by_time_of_day_timezone(10, 0, implied_vol_df, timezone_of_snap='America/New_York') implied_vol_df = filter.remove_out_FX_out_of_hours(implied_vol_df) implied_vol_df.index = pd.to_datetime(implied_vol_df.index.date) implied_vol_df = pd.DataFrame(implied_vol_df) implied_vol_df.columns = [asset + 'VON.close'] # Download FX intraday spot data, which will be used to calculate realized volatility md_request.tickers = asset; md_request.vendor_tickers = asset + ' BGN Curncy' intraday_spot_df = market.fetch_market(md_request).resample(str(freq_min_mult) + 'min').first() intraday_spot_df = filter.remove_out_FX_out_of_hours(intraday_spot_df).dropna() intraday_spot_df.columns = [asset + '.close'] vol_stats = VolStats() # Calculate realized vol with the intraday data, with daily cutoffs realized_vol = vol_stats.calculate_realized_vol( asset, tenor_label='ON', spot_df=intraday_spot_df, hour_of_day=10, minute_of_day=0, freq='intraday', timezone_hour_minute='America/New_York', freq_min_mult=freq_min_mult) * 100.0 implied_vol_addon = vol_stats.calculate_implied_vol_addon(asset, implied_vol=implied_vol_df, tenor_label='ON', adj_ON_friday=True).dropna() vrp = vol_stats.calculate_vol_risk_premium(asset, tenor_label='ON', implied_vol=implied_vol_df, realized_vol=realized_vol, adj_ON_friday=True)
def fetch_continuous_time_series(self, md_request, market_data_generator, fx_vol_surface=None, enter_trading_dates=None, fx_options_trading_tenor=None, roll_days_before=None, roll_event=None, construct_via_currency=None, fx_options_tenor_for_interpolation=None, base_depos_tenor=None, roll_months=None, cum_index=None, strike=None, contract_type=None, premium_output=None, position_multiplier=None, depo_tenor_for_option=None, freeze_implied_vol=None, tot_label=None, cal=None, output_calculation_fields=None): if fx_vol_surface is None: fx_vol_surface = self._fx_vol_surface if enter_trading_dates is None: enter_trading_dates = self._enter_trading_dates if market_data_generator is None: market_data_generator = self._market_data_generator if fx_options_trading_tenor is None: fx_options_trading_tenor = self._fx_options_trading_tenor if roll_days_before is None: roll_days_before = self._roll_days_before if roll_event is None: roll_event = self._roll_event if construct_via_currency is None: construct_via_currency = self._construct_via_currency if fx_options_tenor_for_interpolation is None: fx_options_tenor_for_interpolation = self._fx_options_tenor_for_interpolation if base_depos_tenor is None: base_depos_tenor = self._base_depos_tenor if roll_months is None: roll_months = self._roll_months if strike is None: strike = self._strike if contract_type is None: contract_type = self._contact_type if premium_output is None: premium_output = self._premium_output if position_multiplier is None: position_multiplier = self._position_multiplier if depo_tenor_for_option is None: depo_tenor_for_option = self._depo_tenor_for_option if freeze_implied_vol is None: freeze_implied_vol = self._freeze_implied_vol if tot_label is None: tot_label = self._tot_label if cal is None: cal = self._cal if output_calculation_fields is None: output_calculation_fields = self._output_calculation_fields # Eg. we construct EURJPY via EURJPY directly (note: would need to have sufficient options/forward data for this) if construct_via_currency == 'no': if fx_vol_surface is None: # Download FX spot, FX forwards points and base depos etc. market = Market(market_data_generator=market_data_generator) md_request_download = MarketDataRequest(md_request=md_request) fx_conv = FXConv() # CAREFUL: convert the tickers to correct notation, eg. USDEUR => EURUSD, because our data # should be fetched in correct convention md_request_download.tickers = [ fx_conv.correct_notation(x) for x in md_request.tickers ] md_request_download.category = 'fx-vol-market' md_request_download.fields = 'close' md_request_download.abstract_curve = None md_request_download.fx_options_tenor = fx_options_tenor_for_interpolation md_request_download.base_depos_tenor = base_depos_tenor # md_request_download.base_depos_currencies = [] forwards_market_df = market.fetch_market(md_request_download) else: forwards_market_df = None # Now use the original tickers return self.construct_total_return_index( md_request.tickers, forwards_market_df, fx_vol_surface=fx_vol_surface, enter_trading_dates=enter_trading_dates, fx_options_trading_tenor=fx_options_trading_tenor, roll_days_before=roll_days_before, roll_event=roll_event, fx_options_tenor_for_interpolation= fx_options_tenor_for_interpolation, roll_months=roll_months, cum_index=cum_index, strike=strike, contract_type=contract_type, premium_output=premium_output, position_multiplier=position_multiplier, freeze_implied_vol=freeze_implied_vol, depo_tenor_for_option=depo_tenor_for_option, tot_label=tot_label, cal=cal, output_calculation_fields=output_calculation_fields) else: # eg. we calculate via your domestic currency such as USD, so returns will be in your domestic currency # Hence AUDJPY would be calculated via AUDUSD and JPYUSD (subtracting the difference in returns) total_return_indices = [] for tick in md_request.tickers: base = tick[0:3] terms = tick[3:6] md_request_base = MarketDataRequest(md_request=md_request) md_request_base.tickers = base + construct_via_currency md_request_terms = MarketDataRequest(md_request=md_request) md_request_terms.tickers = terms + construct_via_currency # Construct the base and terms separately (ie. AUDJPY => AUDUSD & JPYUSD) base_vals = self.fetch_continuous_time_series( md_request_base, market_data_generator, fx_vol_surface=fx_vol_surface, enter_trading_dates=enter_trading_dates, fx_options_trading_tenor=fx_options_trading_tenor, roll_days_before=roll_days_before, roll_event=roll_event, fx_options_tenor_for_interpolation= fx_options_tenor_for_interpolation, base_depos_tenor=base_depos_tenor, roll_months=roll_months, cum_index=cum_index, strike=strike, contract_type=contract_type, premium_output=premium_output, position_multiplier=position_multiplier, depo_tenor_for_option=depo_tenor_for_option, freeze_implied_vol=freeze_implied_vol, tot_label=tot_label, cal=cal, output_calculation_fields=output_calculation_fields, construct_via_currency='no') terms_vals = self.fetch_continuous_time_series( md_request_terms, market_data_generator, fx_vol_surface=fx_vol_surface, enter_trading_dates=enter_trading_dates, fx_options_trading_tenor=fx_options_trading_tenor, roll_days_before=roll_days_before, roll_event=roll_event, fx_options_tenor_for_interpolation= fx_options_tenor_for_interpolation, base_depos_tenor=base_depos_tenor, roll_months=roll_months, cum_index=cum_index, strike=strike, contract_type=contract_type, position_multiplier=position_multiplier, depo_tenor_for_option=depo_tenor_for_option, freeze_implied_vol=freeze_implied_vol, tot_label=tot_label, cal=cal, output_calculation_fields=output_calculation_fields, construct_via_currency='no') # Special case for USDUSD case (and if base or terms USD are USDUSD if base + terms == construct_via_currency + construct_via_currency: base_rets = self._calculations.calculate_returns(base_vals) cross_rets = pd.DataFrame(0, index=base_rets.index, columns=base_rets.columns) elif base + construct_via_currency == construct_via_currency + construct_via_currency: cross_rets = -self._calculations.calculate_returns( terms_vals) elif terms + construct_via_currency == construct_via_currency + construct_via_currency: cross_rets = self._calculations.calculate_returns( base_vals) else: base_rets = self._calculations.calculate_returns(base_vals) terms_rets = self._calculations.calculate_returns( terms_vals) cross_rets = base_rets.sub(terms_rets.iloc[:, 0], axis=0) # First returns of a time series will by NaN, given we don't know previous point cross_rets.iloc[0] = 0 cross_vals = self._calculations.create_mult_index(cross_rets) cross_vals.columns = [tick + '-option-tot.close'] total_return_indices.append(cross_vals) return self._calculations.join(total_return_indices, how='outer')
def fetch_continuous_time_series(self, md_request, market_data_generator, fx_forwards_trading_tenor=None, roll_date=None, construct_via_currency=None, fx_forwards_tenor=None, base_depos_tenor=None): if market_data_generator is None: market_data_generator = self._market_data_generator if fx_forwards_trading_tenor is None: fx_forwards_trading_tenor = self._fx_forwards_trading_tenor if roll_date is None: roll_date = self._roll_date if construct_via_currency is None: construct_via_currency = self._construct_via_currency if fx_forwards_tenor is None: fx_forwards_tenor = self._fx_forwards_tenor if base_depos_tenor is None: base_depos_tenor = self._base_depos_tenor # Eg. we construct EURJPY via EURJPY directly (note: would need to have sufficient forward data for this) if construct_via_currency == 'no': # Download FX spot, FX forwards points and base depos market = Market(market_data_generator=market_data_generator) md_request_download = MarketDataRequest(md_request=md_request) md_request_download.category = 'fx-forwards-market' md_request_download.fields = 'close' md_request_download.abstract_curve = None md_request_download.fx_forwards_tenor = fx_forwards_tenor md_request_download.base_depos_tenor = base_depos_tenor forwards_market_df = market.fetch_market(md_request_download) return self.construct_total_return_index( md_request.tickers, fx_forwards_trading_tenor, roll_date, forwards_market_df, fx_forwards_tenor=fx_forwards_tenor, base_depos_tenor=base_depos_tenor) else: # eg. we calculate via your domestic currency such as USD, so returns will be in your domestic currency # Hence AUDJPY would be calculated via AUDUSD and JPYUSD (subtracting the difference in returns) total_return_indices = [] for tick in md_request.tickers: base = tick[0:3] terms = tick[3:6] md_request_base = MarketDataRequest(md_request=md_request) md_request_base.tickers = base + construct_via_currency md_request_terms = MarketDataRequest(md_request=md_request) md_request_terms.tickers = terms + construct_via_currency base_vals = self.fetch_continuous_time_series( md_request_base, market_data_generator, construct_via_currency='no') terms_vals = self.fetch_continuous_time_series( md_request_terms, market_data_generator, construct_via_currency='no') # Special case for USDUSD case (and if base or terms USD are USDUSD if base + terms == 'USDUSD': base_rets = self._calculations.calculate_returns(base_vals) cross_rets = pd.DataFrame(0, index=base_rets.index, columns=base_rets.columns) elif base + 'USD' == 'USDUSD': cross_rets = -self._calculations.calculate_returns( terms_vals) elif terms + 'USD' == 'USDUSD': cross_rets = self._calculations.calculate_returns( base_vals) else: base_rets = self._calculations.calculate_returns(base_vals) terms_rets = self._calculations.calculate_returns( terms_vals) cross_rets = base_rets.sub(terms_rets.iloc[:, 0], axis=0) # First returns of a time series will by NaN, given we don't know previous point cross_rets.iloc[0] = 0 cross_vals = self._calculations.create_mult_index(cross_rets) cross_vals.columns = [tick + '-tot.close'] total_return_indices.append(cross_vals) return self._calculations.pandas_outer_join(total_return_indices)
# Resample into 1 minute data and fill down all points implied_vol_df = market.fetch_market(md_request)[ asset + 'VON.open'].resample('1min').first().fillna(method='ffill') # Filter data by 1000 New York time, and return back to UTC, remove any out of trading hours # Then strip of time of day from the timestamp implied_vol_df = filter.filter_time_series_by_time_of_day_timezone( 10, 0, implied_vol_df, timezone_of_snap='America/New_York') implied_vol_df = filter.remove_out_FX_out_of_hours(implied_vol_df) implied_vol_df.index = pd.to_datetime(implied_vol_df.index.date) implied_vol_df = pd.DataFrame(implied_vol_df) implied_vol_df.columns = [asset + 'VON.close'] # Download FX intraday spot data, which will be used to calculate realized volatility md_request.tickers = asset md_request.vendor_tickers = asset + ' BGN Curncy' intraday_spot_df = market.fetch_market(md_request).resample( str(freq_min_mult) + 'min').first() intraday_spot_df = filter.remove_out_FX_out_of_hours( intraday_spot_df).dropna() intraday_spot_df.columns = [asset + '.close'] vol_stats = VolStats() # Calculate realized vol with the intraday data, with daily cutoffs realized_vol = vol_stats.calculate_realized_vol( asset, tenor_label='ON', spot_df=intraday_spot_df, hour_of_day=10,
def fetch_continuous_time_series(self, md_request, market_data_generator, depo_tenor=None, construct_via_currency=None, output_calculation_fields=None): if market_data_generator is None: market_data_generator = self._market_data_generator if depo_tenor is None: depo_tenor = self._depo_tenor if construct_via_currency is None: construct_via_currency = self._construct_via_currency if output_calculation_fields is None: output_calculation_fields = self._output_calculation_fields # Eg. we construct AUDJPY via AUDJPY directly if construct_via_currency == 'no': base_depo_tickers = [ x[0:3] + self._depo_tenor for x in md_request.tickers ] terms_depo_tickers = [ x[3:6] + self._depo_tenor for x in md_request.tickers ] depo_tickers = list(set(base_depo_tickers + terms_depo_tickers)) market = Market(market_data_generator=market_data_generator) # Deposit data for base and terms currency md_request_download = MarketDataRequest(md_request=md_request) md_request_download.tickers = depo_tickers md_request_download.category = 'base-depos' md_request_download.fields = 'close' md_request_download.abstract_curve = None depo_df = market.fetch_market(md_request_download) # Spot data md_request_download.tickers = md_request.tickers md_request_download.category = 'fx' spot_df = market.fetch_market(md_request_download) return self.construct_total_return_index( md_request.tickers, self._calculations.pandas_outer_join([spot_df, depo_df]), depo_tenor=depo_tenor, output_calculation_fields=output_calculation_fields) else: # eg. we calculate via your domestic currency such as USD, so returns will be in your domestic currency # Hence AUDJPY would be calculated via AUDUSD and JPYUSD (subtracting the difference in returns) total_return_indices = [] for tick in md_request.tickers: base = tick[0:3] terms = tick[3:6] md_request_base = MarketDataRequest(md_request=md_request) md_request_base.tickers = base + construct_via_currency md_request_terms = MarketDataRequest(md_request=md_request) md_request_terms.tickers = terms + construct_via_currency base_vals = self.fetch_continuous_time_series( md_request_base, market_data_generator, construct_via_currency='no') terms_vals = self.fetch_continuous_time_series( md_request_terms, market_data_generator, construct_via_currency='no') # Special case for USDUSD case (and if base or terms USD are USDUSD if base + terms == construct_via_currency + construct_via_currency: base_rets = self._calculations.calculate_returns(base_vals) cross_rets = pd.DataFrame(0, index=base_rets.index, columns=base_rets.columns) elif base + construct_via_currency == construct_via_currency + construct_via_currency: cross_rets = -self._calculations.calculate_returns( terms_vals) elif terms + construct_via_currency == construct_via_currency + construct_via_currency: cross_rets = self._calculations.calculate_returns( base_vals) else: base_rets = self._calculations.calculate_returns(base_vals) terms_rets = self._calculations.calculate_returns( terms_vals) cross_rets = base_rets.sub(terms_rets.iloc[:, 0], axis=0) # First returns of a time series will by NaN, given we don't know previous point cross_rets.iloc[0] = 0 cross_vals = self._calculations.create_mult_index(cross_rets) cross_vals.columns = [tick + '-tot.close'] total_return_indices.append(cross_vals) return self._calculations.pandas_outer_join(total_return_indices)
vendor_fields=['close']) # Fill in your own API keys for Quandl and FRED here # md_request.QUANDL_API_KEY = "TYPE HERE" # md_request.FRED_API_KEY = "TYPE HERE" df_fx = market.fetch_market(md_request=md_request) ##### Download deposit rate data rates_tickers = ['USD3M', 'CAD3M', 'EUR3M', 'AUD3M', 'CHF3M', 'SEK3M', 'GBP3M', 'NOK3M', 'JPY3M', 'NZD3M'] rates_vendor_tickers = ['IR3TIB01USM156N', 'IR3TIB01CAM156N', 'IR3TIB01EZM156N', 'IR3TIB01AUM156N', 'IR3TIB01CHM156N', 'IR3TIB01SEM156N', 'IR3TIB01GBM156N', 'IR3TIB01NOM156N', 'IR3TIB01JPM156N', 'IR3TIB01NZM156N'] md_request.data_source = 'alfred' md_request.tickers = rates_tickers md_request.vendor_tickers = rates_vendor_tickers df_rates = market.fetch_market(md_request=md_request) df_rates = df_rates.resample('BM').last() df = df_fx.join(df_rates, how='left') df = df.fillna(method='ffill') df.to_csv("fx_rates.csv") ##### Download US stocks data equities_tickers = ['TWTR', 'GOOG', 'FB', 'AAPL', 'NFLX', 'AMZN', 'TSLA', 'S&P500'] equities_vendor_tickers = ['TWTR', 'GOOG', 'FB', 'AAPL', 'NFLX', 'AMZN', 'TSLA', '^GSPC'] md_request.data_source = 'yahoo' md_request.tickers = equities_tickers