예제 #1
0
    def calc(self, risk_measure: Union[RiskMeasure, Iterable[RiskMeasure]], fn=None)\
            -> Union[DataFrameWithInfo, ErrorValue, FloatWithInfo, PriceableImpl, PricingFuture,
                     SeriesWithInfo, Tuple[MarketDataCoordinate, ...]]:
        """
        Calculate the value of the risk_measure

        :param risk_measure: the risk measure to compute, e.g. IRDelta (from gs_quant.risk)
        :param fn: post-processing function (optional)
        :return: a float or dataframe, depending on whether the value is scalar or structured, or a future thereof
        (depending on how PricingContext is being used)

        **Examples**

        >>> from gs_quant.instrument import IRCap
        >>> from gs_quant.risk import IRDelta
        >>>
        >>> cap = IRCap('1y', 'USD')
        >>> delta = cap.calc(IRDelta)

        delta is a dataframe

        >>> from gs_quant.instrument import EqOption
        >>> from gs_quant.risk import EqDelta
        >>>
        >>> option = EqOption('.SPX', '3m', 'ATMF', 'Call', 'European')
        >>> delta = option.calc(EqDelta)

        delta is a float

        >>> from gs_quant.markets import PricingContext
        >>>
        >>> cap_usd = IRCap('1y', 'USD')
        >>> cap_eur = IRCap('1y', 'EUR')

        >>> with PricingContext():
        >>>     usd_delta_f = cap_usd.calc(IRDelta)
        >>>     eur_delta_f = cap_eur.calc(IRDelta)
        >>>
        >>> usd_delta = usd_delta_f.result()
        >>> eur_delta = eur_delta_f.result()

        usd_delta_f and eur_delta_f are futures, usd_delta and eur_delta are dataframes
        """
        futures = {r: r.pricing_context.calc(self, r)
                   for r in ((risk_measure,) if isinstance(risk_measure, RiskMeasure) else risk_measure)}
        future = MultipleRiskMeasureFuture(futures) if len(futures) > 1 else futures[risk_measure]

        if fn is not None:
            ret = PricingFuture()

            def cb(f):
                try:
                    ret.set_result(fn(f.result()))
                except Exception as e:
                    ret.set_exception(e)

            future.add_done_callback(cb)
            future = ret

        return future.result() if not (PricingContext.current.is_entered or PricingContext.current.is_async) else future
예제 #2
0
    def calc(self, priceable: Priceable, risk_measure: Union[RiskMeasure, Iterable[RiskMeasure]])\
            -> Union[list, DataFrameWithInfo, ErrorValue, FloatWithInfo, Future, MultipleRiskMeasureFuture,
                     SeriesWithInfo]:
        """
        Calculate the risk measure for the priceable instrument. Do not use directly, use via instruments

        :param priceable: The priceable (e.g. instrument)
        :param risk_measure: The measure we wish to calculate
        :return: A float, Dataframe, Series or Future (depending on is_async or whether the context is entered)

        **Examples**

        >>> from gs_quant.instrument import IRSwap
        >>> from gs_quant.risk import IRDelta
        >>>
        >>> swap = IRSwap('Pay', '10y', 'USD', fixed_rate=0.01)
        >>> delta = swap.calc(IRDelta)
        """
        position = RiskPosition(priceable, priceable.get_quantity())
        multiple_measures = not isinstance(risk_measure, RiskMeasure)
        futures = {}
        active_context_lock = self.__active_context.__lock if self.__active_context != self else nullcontext(
        )

        with self.__lock, active_context_lock:
            for measure in risk_measure if multiple_measures else (
                    risk_measure, ):
                scenario = self.__scenario
                measure_future = self.__active_context.__futures.get(
                    (scenario, measure), {}).get(position)

                if measure_future is None:
                    measure_future = PricingFuture(self.__active_context)
                    if self.__use_cache:
                        cached_result = PricingCache.get(
                            priceable, risk_measure)
                        if cached_result:
                            measure_future.set_result(cached_result)

                    if not measure_future.done():
                        self.__risk_measures_in_scenario_by_provider_and_position.setdefault(
                            priceable.provider(),
                            {}).setdefault(position,
                                           {}).setdefault(scenario,
                                                          set()).add(measure)
                        self.__active_context.__futures.setdefault(
                            (scenario, measure), {})[position] = measure_future

                futures[measure] = measure_future

        future = MultipleRiskMeasureFuture(futures, result_future=PricingFuture(self.__active_context))\
            if multiple_measures else futures[risk_measure]

        if not (self.is_entered or self.__is_async):
            if not future.done():
                self._calc()

            return future.result()
        else:
            return future
예제 #3
0
    def calc(self, priceable: Priceable, risk_measure: Union[RiskMeasure, Iterable[RiskMeasure]])\
            -> Union[dict, float, str, pd.DataFrame, pd.Series, Future]:
        """
        Calculate the risk measure for the priceable instrument. Do not use directly, use via instruments

        :param priceable: The priceable (e.g. instrument)
        :param risk_measure: The measure we wish to calculate
        :return: A float, Dataframe, Series or Future (depending on is_async or whether the context is entered)

        **Examples**

        >>> from gs_quant.instrument import IRSwap
        >>> from gs_quant.risk import IRDelta
        >>>
        >>> swap = IRSwap('Pay', '10y', 'USD', fixed_rate=0.01)
        >>> delta = swap.calc(IRDelta)
        """
        from gs_quant.risk.results import MultipleRiskMeasureFuture

        position = RiskPosition(priceable, priceable.get_quantity())
        multiple_measures = not isinstance(risk_measure, RiskMeasure)
        futures = {}

        for measure in risk_measure if multiple_measures else (risk_measure, ):
            measure_future = self.__futures.get(measure, {}).get(position)

            if measure_future is None:
                measure_future = Future()
                if self.__use_cache:
                    cached_result = PricingCache.get(priceable,
                                                     self.market_data_location,
                                                     risk_measure,
                                                     self.pricing_date)
                    if cached_result:
                        measure_future.set_result(cached_result)

                if not measure_future.done():
                    self.__risk_measures_by_provider_and_position.setdefault(
                        priceable.provider(),
                        {}).setdefault(position, set()).add(measure)
                    self.__futures.setdefault(measure,
                                              {})[position] = measure_future

            futures[measure] = measure_future

        future = MultipleRiskMeasureFuture(
            futures) if multiple_measures else futures[risk_measure]

        if not (self._is_entered or self.__is_async):
            if not future.done():
                self._calc()

            return future.result()
        else:
            return future
예제 #4
0
    def calc(self, priceable: Priceable, risk_measure: Union[RiskMeasure, Iterable[RiskMeasure]])\
            -> Union[list, DataFrameWithInfo, ErrorValue, FloatWithInfo, Future, MultipleRiskMeasureFuture,
                     SeriesWithInfo]:
        """
        Calculate the risk measure for the priceable instrument. Do not use directly, use via instruments

        :param priceable: The priceable (e.g. instrument)
        :param risk_measure: The measure we wish to calculate
        :return: A float, Dataframe, Series or Future (depending on is_async or whether the context is entered)

        **Examples**

        >>> from gs_quant.instrument import IRSwap
        >>> from gs_quant.risk import IRDelta
        >>>
        >>> swap = IRSwap('Pay', '10y', 'USD', fixed_rate=0.01)
        >>> delta = swap.calc(IRDelta)
        """
        futures = {}

        with self.__active_context.__lock:
            for risk_measure in (risk_measure, ) if isinstance(
                    risk_measure, RiskMeasure) else risk_measure:
                risk_key = self.__risk_key(risk_measure, priceable.provider())
                future = self.__active_context.__pending.get(
                    (risk_key, priceable))
                cached_result = PricingCache.get(
                    risk_key, priceable) if self.use_cache else None

                if future is None:
                    future = PricingFuture(self.__active_context)
                    if cached_result is not None:
                        future.set_result(cached_result)
                    else:
                        self.__active_context.__pending[(risk_key,
                                                         priceable)] = future

                futures[risk_measure] = future

        future = MultipleRiskMeasureFuture(futures, result_future=self._result_future())\
            if len(futures) > 1 else futures[risk_measure]

        return self._return_calc_result(future)
예제 #5
0
파일: core.py 프로젝트: xuover/gs-quant
    def calc(self, risk_measure: Union[RiskMeasure, Iterable[RiskMeasure]], fn=None) \
            -> Union[DataFrameWithInfo, ErrorValue, FloatWithInfo, PriceableImpl, PricingFuture,
                     SeriesWithInfo, Tuple[MarketDataCoordinate, ...]]:
        """
        Calculate the value of the risk_measure

        :param risk_measure: the risk measure to compute, e.g. IRDelta (from gs_quant.risk)
        :param fn: post-processing function (optional)
        :return: a float or dataframe, depending on whether the value is scalar or structured, or a future thereof
        (depending on how PricingContext is being used)

        **Examples**

        >>> from gs_quant.instrument import IRCap
        >>> from gs_quant.risk import IRDelta
        >>>
        >>> cap = IRCap('1y', 'USD')
        >>> delta = cap.calc(IRDelta)

        delta is a dataframe

        >>> from gs_quant.instrument import EqOption
        >>> from gs_quant.risk import EqDelta
        >>>
        >>> option = EqOption('.SPX', '3m', 'ATMF', 'Call', 'European')
        >>> delta = option.calc(EqDelta)

        delta is a float

        >>> from gs_quant.markets import PricingContext
        >>>
        >>> cap_usd = IRCap('1y', 'USD')
        >>> cap_eur = IRCap('1y', 'EUR')

        >>> with PricingContext():
        >>>     usd_delta_f = cap_usd.calc(IRDelta)
        >>>     eur_delta_f = cap_eur.calc(IRDelta)
        >>>
        >>> usd_delta = usd_delta_f.result()
        >>> eur_delta = eur_delta_f.result()

        usd_delta_f and eur_delta_f are futures, usd_delta and eur_delta are dataframes
        """
        single_measure = isinstance(risk_measure, RiskMeasure)
        with self._pricing_context:
            future = risk_measure.pricing_context.calc(self, risk_measure) if single_measure else \
                MultipleRiskMeasureFuture(self, {r: r.pricing_context.calc(self, r) for r in risk_measure})

        # Warn on use of deprecated measures
        def warning_on_one_line(msg, category, _filename, _lineno, _file=None, _line=None):
            return f'{category.__name__}:{msg}'

        for measure in (risk_measure,) if single_measure else risk_measure:
            if measure.name in DEPRECATED_MEASURES.keys():
                message = '{0} risk measure is deprecated. Please use {1} instead and pass in arguments to describe ' \
                          'risk measure specifics.\n'.format(measure.name, DEPRECATED_MEASURES[measure.name])
                warnings.simplefilter('once')
                warnings.formatwarning = warning_on_one_line
                warnings.warn(message, DeprecationWarning)
                warnings.simplefilter('ignore')

        if fn is not None:
            ret = PricingFuture()

            def cb(f):
                try:
                    ret.set_result(fn(f.result()))
                except Exception as e:
                    ret.set_exception(e)

            future.add_done_callback(cb)
            future = ret

        return future if self._return_future else future.result()