def covariance(risk_model_id: str,
               factor_name_1: str,
               factor_name_2: str,
               *,
               source: str = None,
               real_time: bool = False,
               request_id: Optional[str] = None) -> pd.Series:
    """
    Covariance time-series between two factors in a risk model

    :param risk_model_id: risk model entity
    :param factor_name_1: first factor name
    :param factor_name_2: second factor name
    :param source: name of function caller
    :param real_time: whether to retrieve intraday data instead of EOD
    :param request_id: server request id
    :return: Time-series of covariances between the two factors across available risk model dates
    """

    factor_1 = Factor(risk_model_id, factor_name_1)
    factor_2 = Factor(risk_model_id, factor_name_2)
    covariance_curve = factor_1.covariance(factor_2,
                                           DataContext.current.start_date,
                                           DataContext.current.end_date)
    return __format_plot_measure_results(covariance_curve,
                                         QueryType.COVARIANCE)
Esempio n. 2
0
def _get_factor_data(report_id: str, factor_name: str,
                     query_type: QueryType) -> pd.Series:
    # Check params
    report = RiskReport(report_id)
    if report.get_type() not in [
            ReportType.Portfolio_Factor_Risk, ReportType.Asset_Factor_Risk
    ]:
        raise MqValueError('This report is not a factor risk report')
    risk_model_id = report.get_risk_model_id()
    factor = Factor(risk_model_id, factor_name)
    if factor.factor is None:
        raise MqValueError(
            'Factor name requested is not available in the risk model associated with this report'
        )

    # Extract relevant data for each date
    col_name = query_type.value.replace(' ', '')
    col_name = col_name[0].lower() + col_name[1:]
    data_type = QUERY_TO_FIELD_MAP[query_type]

    factor_data = report.get_factor_data(factor=factor.get_name())
    factor_exposures = [{
        'date': data['date'],
        col_name: data[data_type]
    } for data in factor_data if data.get(data_type)]

    # Create and return timeseries
    df = pd.DataFrame(factor_exposures)
    df.set_index('date', inplace=True)
    df.index = pd.to_datetime(df.index)
    return _extract_series_from_df(df, query_type)
Esempio n. 3
0
    def get_factor(self, name: str) -> Factor:
        """ Get risk model factor from its name

        :param name: factor name associated with risk model

        :return: Factor object
        """
        name_matches = [
            f for f in self.get_factor_data(format=ReturnFormat.JSON)
            if f['name'] == name
        ]

        if not name_matches:
            raise MqValueError(
                f'Factor with name {name} does not in exist in risk model {self.id}'
            )

        factor = name_matches.pop()
        return Factor(risk_model_id=self.id,
                      id_=factor['identifier'],
                      type_=factor['type'],
                      name=factor.get('name'),
                      category=factor.get('factorCategory'),
                      tooltip=factor.get('tooltip'),
                      description=factor.get('description'),
                      glossary_description=factor.get('glossaryDescription'))
Esempio n. 4
0
def factor_zscore(asset: Asset, risk_model_id: str, factor_name: str, *,
                  source: str = None, real_time: bool = False, request_id: Optional[str] = None) -> pd.Series:
    """
    Asset factor exposure (in the form of z-scores) for a factor using specified risk model

    :param asset: asset object loaded from security master
    :param risk_model_id: requested risk model id
    :param factor_name: requested factor name
    :param source: name of function caller
    :param real_time: whether to retrieve intraday data instead of EOD
    :param request_id: service request id, if any
    :return: Time-series of asset factor exposure across available risk model dates
    """
    risk_model = FactorRiskModel(risk_model_id)
    factor = Factor(risk_model_id, factor_name)
    gsid = asset.get_identifier('GSID')

    # Query risk model data
    query_results = risk_model.get_data(
        measures=[Measure.Factor_Name, Measure.Universe_Factor_Exposure, Measure.Asset_Universe],
        start_date=DataContext.current.start_time,
        end_date=DataContext.current.end_time,
        assets=DataAssetsRequest(identifier=UniverseIdentifier.gsid, universe=[gsid])
    ).get('results', [])

    # Get the factor data from query results
    z_scores = {}
    for result in query_results:
        exposures = result.get('assetData', {}).get('factorExposure', [])
        if exposures:
            z_scores[result['date']] = exposures[0].get(factor.id)

    return __format_plot_measure_results(z_scores, QueryType.FACTOR_EXPOSURE)
Esempio n. 5
0
def factor_exposure(asset: Asset,
                    risk_model_id: str,
                    factor_name: str,
                    *,
                    source: str = None,
                    real_time: bool = False,
                    request_id: Optional[str] = None) -> pd.Series:
    """
    Asset factor Exposure (in the form of z-scores) for a factor using specified risk model

    :param asset: asset object loaded from security master
    :param risk_model_id: requested risk model id
    :param factor_name: requested factor name
    :param source: name of function caller
    :param real_time: whether to retrieve intraday data instead of EOD
    :param request_id: service request id, if any
    :return: Timeseries of asset factor exposure across available risk model dates
    """
    risk_model = RiskModel(risk_model_id)
    factor = Factor(risk_model_id, factor_name)
    if factor.factor is None or risk_model_id != factor.risk_model_id:
        raise MqValueError(
            'Requested factor not available in requested risk model')

    asset_gsid = asset.get_identifiers().get('GSID')

    # Establish date interval for data query
    dates = risk_model.get_dates()
    start_date = dt.datetime.strptime(min(dates),
                                      "%Y-%m-%d").date() if dates else None
    end_date = dt.datetime.strptime(max(dates),
                                    "%Y-%m-%d").date() if dates else None

    # Query data and append pull requested factor exposure
    all_exposures = []
    query_results = risk_model.get_data(
        measures=[
            Measure.Factor_Name, Measure.Universe_Factor_Exposure,
            Measure.Asset_Universe
        ],
        start_date=start_date,
        end_date=end_date,
        assets=DataAssetsRequest(identifier=AssetUniverseIdentifier.gsid,
                                 universe=[asset_gsid])).get('results', [])
    for result in query_results:
        if result.get('date') in dates:
            exposures = result.get('assetData', {}).get('factorExposure', [])
            if exposures:
                all_exposures.append({
                    'date':
                    result['date'],
                    'factorExposure':
                    exposures[0].get(factor.factor.identifier)
                })

    # Create and return timeseries
    df = pd.DataFrame(all_exposures)
    df.set_index('date', inplace=True)
    df.index = pd.to_datetime(df.index)
    return _extract_series_from_df(df, QueryType.FACTOR_EXPOSURE)
Esempio n. 6
0
def factor_volatility(risk_model_id: str, factor_name: str, *, source: str = None,
                      real_time: bool = False, request_id: Optional[str] = None) -> pd.Series:
    """
    Volatility timeseries for a factor in a risk model

    :param risk_model_id: risk model entity
    :param factor_name: factor name
    :param source: name of function caller
    :param real_time: whether to retrieve intra-day data instead of EOD
    :param request_id: server request id
    :return: Time-series of a factor's volatility across available risk model dates
    """
    factor = Factor(risk_model_id, factor_name)
    volatility = factor.volatility(DataContext.current.start_date,
                                   DataContext.current.end_date,
                                   ReturnFormat.JSON)
    return __format_plot_measure_results(volatility, QueryType.VOLATILITY, multiplier=100)
Esempio n. 7
0
 def get_many_factors(self):
     factors = self.get_factor_data(format=ReturnFormat.JSON)
     return [
         Factor(risk_model_id=self.id,
                id_=f['identifier'],
                type_=f['type'],
                name=f.get('name'),
                category=f.get('factorCategory'),
                tooltip=f.get('tooltip'),
                description=f.get('description'),
                glossary_description=f.get('glossaryDescription'))
         for f in factors
     ]
Esempio n. 8
0
def covariance(risk_model_id: str,
               factor_1: str,
               factor_2: str,
               *,
               source: str = None,
               real_time: bool = False,
               request_id: Optional[str] = None) -> pd.Series:
    """
    Covariance timeseries between two factors in a risk model

    :param risk_model_id: risk model entity
    :param factor_1: first factor name
    :param factor_2: second factor name
    :param source: name of function caller
    :param real_time: whether to retrieve intraday data instead of EOD
    :param request_id: server request id
    :return: Timeseries of covariances between the two factors across available risk model dates
    """
    model = RiskModel(risk_model_id)
    factor_1 = Factor(risk_model_id, factor_1)
    factor_2 = Factor(risk_model_id, factor_2)
    if None in [factor_1.factor, factor_2.factor]:
        raise MqValueError(
            'Factor names requested are not available for this risk model')

    # Find all covariances between two factors for date range
    dates = model.get_dates()

    start_date = dt.datetime.strptime(min(dates),
                                      '%Y-%m-%d') if dates else None
    end_date = dt.datetime.strptime(max(dates), '%Y-%m-%d') if dates else None
    covariances = factor_1.get_covariance(factor_2, start_date, end_date)

    # Create and return timeseries
    df = pd.DataFrame(covariances)
    df.set_index('date', inplace=True)
    df.index = pd.to_datetime(df.index)
    return _extract_series_from_df(df, QueryType.COVARIANCE)
Esempio n. 9
0
def _get_factor_data(report_id: str, factor_name: str,
                     query_type: QueryType) -> pd.Series:
    # Check params
    report = RiskReport(report_id)
    if report.get_type() not in [
            ReportType.Portfolio_Factor_Risk, ReportType.Asset_Factor_Risk
    ]:
        raise MqValueError('This report is not a factor risk report')
    risk_model_id = report.get_risk_model_id()
    if factor_name not in ['Factor', 'Specific', 'Total']:
        if query_type in [QueryType.DAILY_RISK, QueryType.ANNUAL_RISK]:
            raise MqValueError(
                'Please pick a factor name from the following: ["Total", "Factor", "Specific"]'
            )
        factor = Factor(risk_model_id, factor_name)
        factor_name = factor.name

    # Extract relevant data for each date
    col_name = query_type.value.replace(' ', '')
    col_name = decapitalize(col_name)
    data_type = decapitalize(
        col_name[6:]) if col_name.startswith('factor') else col_name

    factor_data = report.get_factor_data(
        factor=factor_name,
        start_date=DataContext.current.start_time,
        end_date=DataContext.current.end_time)
    factor_exposures = [{
        'date': data['date'],
        col_name: data[data_type]
    } for data in factor_data if data.get(data_type)]

    # Create and return timeseries
    df = pd.DataFrame(factor_exposures)
    if not df.empty:
        df.set_index('date', inplace=True)
        df.index = pd.to_datetime(df.index)
    return _extract_series_from_df(df, query_type)
Esempio n. 10
0
def factor_performance(risk_model_id: str,
                       factor_name: str,
                       *,
                       source: str = None,
                       real_time: bool = False,
                       request_id: Optional[str] = None) -> pd.Series:
    """
    Factor returns as a price time-series for a factor in a risk model

    :param risk_model_id: risk model entity
    :param factor_name: factor name
    :param source: name of function caller
    :param real_time: whether to retrieve intraday data instead of EOD
    :param request_id: server request id
    :return: Time-series of factor returns as a price series across available risk model dates
    """

    factor = Factor.get(risk_model_id, factor_name)
    factor_returns = factor.returns(DataContext.current.start_date,
                                    DataContext.current.end_date,
                                    ReturnFormat.JSON)
    factor_return_timeseries = pd.Series(factor_returns)
    return prices(factor_return_timeseries, 100)