コード例 #1
0
    def resolve(self, in_place: bool = True) -> Optional[dict]:
        with PricingContext.current if not PricingContext.current._is_entered else nullcontext(
        ):
            futures = [i.resolve(in_place) for i in self.__instruments]

        return dict(zip(self.__instruments,
                        (f.result()
                         for f in futures))) if not in_place else None
コード例 #2
0
 def calc(
     self, risk_measure: Union[RiskMeasure, Iterable[RiskMeasure]]
 ) -> PortfolioRiskResult:
     with PricingContext.current if not PricingContext.current._is_entered else nullcontext(
     ):
         return PortfolioRiskResult(
             self, (risk_measure, )
             if isinstance(risk_measure, RiskMeasure) else risk_measure,
             [p.calc(risk_measure) for p in self.__instruments])
コード例 #3
0
 def __pricing_context(self) -> PricingContext:
     return PricingContext.current if not PricingContext.current.is_entered else nullcontext(
     )
コード例 #4
0
 def _pricing_context(self) -> PricingContext:
     pricing_context = PricingContext.current
     return pricing_context if not (pricing_context.is_entered or pricing_context.is_async) else nullcontext()
コード例 #5
0
ファイル: core.py プロジェクト: qg0/gs-quant
    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)
                    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)) 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
コード例 #6
0
    def _calc(self):
        positions_by_provider = self.__active_context.__positions_by_provider
        session = GsSession.current
        batch_result = Future() if self.__is_batch else None
        batch_providers = set()
        batch_lock = Lock() if self.__is_batch else nullcontext()

        def handle_results(requests_to_results: Mapping[RiskRequest, dict]):
            for request_, result in requests_to_results.items():
                try:
                    self._handle_results(result, request_)
                except Exception as e:
                    try:
                        self._handle_results(e, request_)
                    except Exception as he:
                        _logger.error('Error setting error result: ' + str(he))

        def run_requests(requests_: Iterable[RiskRequest], provider_: RiskApi):
            try:
                with session:
                    results = provider_.calc_multi(requests_)
                    if self.__is_batch:
                        get_batch_results(dict(zip(results, requests_)),
                                          provider_)
                    else:
                        handle_results(dict(zip(requests_, results)))
            except Exception as e:
                handle_results({r: e for r in requests_})

        def get_batch_results(ids_to_requests: Mapping[str, RiskRequest],
                              provider_: RiskApi):
            def get_results():
                try:
                    with session:
                        return provider_.get_results(
                            ids_to_requests,
                            self.__poll_for_batch_results,
                            timeout=self.__batch_results_timeout)
                except Exception as be:
                    return {r: be for r in ids_to_requests.values()}

            def set_results(results: Mapping[RiskRequest, Union[Exception,
                                                                dict]]):
                handle_results(results)

                with batch_lock:
                    # Check if we're the last provide and signal done if so
                    batch_providers.remove(provider_)
                    if not batch_providers:
                        batch_result.set_result(True)

            if self.__is_async:
                batch_result_pool = ThreadPoolExecutor(1)
                batch_result_pool.submit(get_results).add_done_callback(
                    lambda f: set_results(f.result()))
                batch_result_pool.shutdown(wait=False)
            else:
                set_results(get_results())

        with self.__lock:
            # Group requests by risk_measures, positions, scenario - so we can create unique RiskRequest objects
            # Determine how many we will need
            while self.__risk_measures_in_scenario_by_provider_and_position:
                provider, risk_measures_by_scenario =\
                    self.__risk_measures_in_scenario_by_provider_and_position.popitem()
                for position, scenario_to_risk_measures in risk_measures_by_scenario.items(
                ):
                    for scenario, risk_measures in scenario_to_risk_measures.items(
                    ):
                        risk_measures = tuple(
                            sorted(
                                risk_measures,
                                key=lambda m: m.name or m.measure_type.value))
                        positions_by_provider.setdefault(provider, {}).setdefault((scenario, risk_measures), [])\
                            .append(position)

        if self.__positions_by_provider:
            num_providers = len(self.__positions_by_provider)
            request_pool = ThreadPoolExecutor(
                num_providers
            ) if num_providers > 1 or self.__is_async else None
            batch_providers = set(self.__positions_by_provider.keys())

            while self.__positions_by_provider:
                provider, positions_by_scenario_and_risk_measures = self.__positions_by_provider.popitem(
                )
                requests = [
                    RiskRequest(tuple(positions),
                                risk_measures,
                                parameters=self.__parameters,
                                wait_for_results=not self.__is_batch,
                                pricing_location=self.__market_data_location,
                                scenario=scenario,
                                pricing_and_market_data_as_of=self.
                                _pricing_market_data_as_of,
                                request_visible_to_gs=self.__visible_to_gs)
                    for (scenario, risk_measures), positions in
                    positions_by_scenario_and_risk_measures.items()
                ]

                if request_pool:
                    request_pool.submit(run_requests, requests, provider)
                else:
                    run_requests(requests, provider)

            if request_pool:
                request_pool.shutdown(wait=not self.__is_async)

            if batch_result and not self.__is_async:
                batch_result.result()