예제 #1
0
    def calculate_realized_vol(self,
                               asset,
                               spot_df=None,
                               returns_df=None,
                               tenor_label="ON",
                               freq='daily',
                               freq_min_mult=1,
                               hour_of_day=10,
                               minute_of_day=0,
                               field='close',
                               returns_calc='simple',
                               timezone_hour_minute='America/New_York'):
        """Calculates rolling realized vol with daily cutoffs either using daily spot data or intraday spot data
        (which is assumed to be in UTC timezone)

        Parameters
        ----------
        asset : str
            asset to be calculated

        spot_df : pd.DataFrame
            minute spot returns (freq_min_mult should be the same as the frequency and should have timezone set)

        tenor_label : str
            tenor to calculate

        freq_min_mult : int
            frequency multiply for data (1 = 1 min)

        hour_of_day : closing time of data in the timezone specified
            eg. 10 which is 1000 time (default = 10)

        minute_of_day : closing time of data in the timezone specified
            eg. 0 which is 0 time (default = 0)

        field : str
            By default 'close'

        returns_calc : str
            'simple' calculate simple returns
            'log' calculate log returns

        timezone_hour_minute : str
            The timezone for the closing hour/minute (default: 'America/New_York')

        Returns
        -------
        pd.DataFrame of realized volatility
        """

        if returns_df is None:
            if spot_df is None:

                if freq == 'daily':
                    spot_df = self._market_df[asset + "." + field]
                else:
                    spot_df = self._intraday_spot_df[asset + "." + field]

            if returns_calc == 'simple':
                returns_df = self._calculations.calculate_returns(spot_df)
            else:
                returns_df = self._calculations.calculate_log_returns(spot_df)

        cal = Calendar()
        tenor_days = cal.get_business_days_tenor(tenor_label)

        if freq == 'intraday':
            # Annualization factor (1440 is number of minutes in the day)
            mult = int(1440.0 / float(freq_min_mult))

            realized_rolling = self._calculations.rolling_volatility(
                returns_df, tenor_days * mult, obs_in_year=252 * mult)

            # Convert to NYC time (or whatever timezone hour is specified in)
            realized_rolling = self._timezone.convert_index_aware_to_alt(
                realized_rolling, timezone_hour_minute)

            realized_vol = self._filter.filter_time_series_by_time_of_day(
                hour_of_day, minute_of_day, realized_rolling)
            realized_vol = self._timezone.convert_index_aware_to_UTC_time(
                realized_vol)
            realized_vol = self._timezone.set_as_no_timezone(realized_vol)
        elif freq == 'daily':
            realized_vol = self._calculations.rolling_volatility(
                spot_df, tenor_days, obs_in_year=252)

        # Strip the time off the date
        realized_vol.index = realized_vol.index.date
        realized_vol = pd.DataFrame(realized_vol)

        realized_vol.columns = [asset + 'H' + tenor_label + '.close']

        return realized_vol
예제 #2
0
    def calculate_vol_risk_premium(self,
                                   asset,
                                   tenor_label="ON",
                                   implied_vol=None,
                                   realized_vol=None,
                                   field='close',
                                   adj_ON_friday=False):
        """Calculates volatility risk premium given implied and realized quotes (ie. implied - realized) and tenor

        Calculates both a version which is aligned (VRP), where the implied and realized volatilities cover
        the same period (note: you will have a gap for recent points, where you can't grab future implied volatilities),
        and an unaligned version (VRPV), which is the typical one used in the market

        Parameters
        ----------
        asset : str
            asset to calculate value for

        tenor_label : str
            tenor to calculate

        implied_vol : pd.DataFrame
            implied vol quotes where columns are of the form eg. EURUSDV1M.close

        realized_vol : pd.DataFrame
            realized vol eg. EURUSDH1M.close

        field : str
            the field of the data to use (default: 'close')

        Returns
        -------
        pd.DataFrame of vrp (both lagged - VRPV & contemporanous - VRP)
        """

        cal = Calendar()
        tenor_days = cal.get_business_days_tenor(tenor_label)

        if tenor_label == 'ON' and adj_ON_friday:
            implied_vol = self.adjust_implied_ON_fri_vol(implied_vol)

        # Add x business days to implied_vol to make it equivalent to realized_vol (better than "shift")
        # approximation for options which are not ON or 1W
        # bday = CustomBusinessDay(weekmask='Mon Tue Wed Thu Fri')
        implied_vol = implied_vol.copy(deep=True)

        implied_unaligned = implied_vol.copy(deep=True)
        cols_to_change = implied_vol.columns.values

        new_cols = []

        for i in range(0, len(cols_to_change)):
            temp_col = list(cols_to_change[i])
            temp_col[6] = 'U'

            new_cols.append(''.join(temp_col))

        implied_vol.columns = new_cols

        ## Construct volatility risk premium such that implied covers the same period as realized
        # Add by number of days (note: for overnight tenors/1 week in FX we can add business days like this)
        # For because they are always +1 business days, +5 business days (exc. national holidays and only including
        # weekend). For longer dates like 1 month this is an approximation
        implied_vol.index = [
            pd.Timestamp(x) + pd.tseries.offsets.BDay(tenor_days)
            for x in implied_vol.index
        ]

        vrp = implied_vol.join(realized_vol, how='outer')
        vrp[asset + "VRP" + tenor_label + ".close"] = vrp[asset + "U" + tenor_label + "." + field] \
                                                      - vrp[asset + "H" + tenor_label + "." + field]

        ## Construct "traditional" volatility risk premium,
        # so implied does not cover the same period as realized volatility
        vrp = vrp.join(implied_unaligned, how='outer')

        vrp[asset + "VRPV" + tenor_label + ".close"] = \
            vrp[asset + "V" + tenor_label + "." + field] - vrp[asset + "H" + tenor_label + "." + field]

        return vrp