Ejemplo n.º 1
0
def excess_returns_(
        price_series: pd.Series,
        currency: RiskFreeRateCurrency = RiskFreeRateCurrency.USD
) -> pd.Series:
    """
    Calculate excess returns

    :param price_series: price series
    :param currency: currency for risk-free rate, defaults to USD
    :return: excess returns

    **Usage**

    Given a price series P and risk-free rate R, excess returns E are defined as:

    :math:`E_t = E_{t-1} + P_t - P_{t-1} * (1 + R * (D_t - D_{t-1}) / 360)`

    The `Actual/360 <https://en.wikipedia.org/wiki/Day_count_convention#Actual/360>`_ day count convention is used.

    **Examples**

    Get excess returns from a price series.

    >>> er = excess_returns(generate_series(100), USD)
    """
    return excess_returns(price_series,
                          Currency(currency.value),
                          day_count_convention=DayCountConvention.ACTUAL_360)
Ejemplo n.º 2
0
def sharpe_ratio(series: pd.Series,
                 currency: RiskFreeRateCurrency,
                 rolling: int = 0,
                 curve_type: CurveType = CurveType.PRICES) -> pd.Series:
    """
    Calculate Sharpe ratio

    :param series: series of prices or excess returns for an asset
    :param currency: currency for risk-free rate
    :param curve_type: whether input series is of prices or excess returns
    :param rolling: rolling window to use
    :return: Sharpe ratio

    **Usage**

    Given a price series and risk-free rate (a number, currency, or cash asset), returns the rolling Sharpe ratio.

    For a fixed rate R, excess returns E are calculated as:

    :math:`E_t = E_{t-1} + P_t - P_{t-1} * (1 + R * DCF_{t-1,t})`

    Subscripts refers to dates in the price series.

    P is a point in the price series.

    DCF is the day count fraction using the Act/360 convention.
    """
    return _get_ratio(series,
                      Currency(currency.value),
                      rolling,
                      day_count_convention=DayCountConvention.ACTUAL_360,
                      curve_type=curve_type)
Ejemplo n.º 3
0
def excess_returns_(price_series: pd.Series,
                    currency: RiskFreeRateCurrency) -> pd.Series:
    """
    Calculate excess returns

    :param price_series: price series
    :param currency: currency for risk-free rate
    :return: excess returns

    **Usage**

    Given a price series P and risk-free rate R, excess returns E are defined as:

    :math:`E_t = E_{t-1} + P_t - P_{t-1} * (1 + R * DCF_{t-1,t})`

    where DCF is day count fraction between two points

    **Examples**

    Get excess returns from a price series.

    >>> er = excess_returns(generate_series(100), RiskFreeRateCurrency.USD)
    """
    return excess_returns(price_series,
                          Currency(currency.value),
                          day_count_convention=DayCountConvention.ACTUAL_360)
Ejemplo n.º 4
0
    def _create(self):
        # If a priceables portfolio, try resolving to MQ portfolio
        if self.__priceables:
            self.save()
            self.priceables = None
            return

        # If a positions portfolio, create using MQ API
        port = GsPortfolioApi.create_portfolio(
            portfolio=MQPortfolio(name=self.name,
                                  currency=self.currency,
                                  entitlements=self.entitlements.to_target()))
        PositionedEntity.__init__(self, port.id, EntityType.PORTFOLIO)
        Entity.__init__(self, port.id, EntityType.PORTFOLIO)
        self.__id = port.id
        self._PositionedEntity__entity_type = EntityType.PORTFOLIO
        self.entitlements = Entitlements.from_target(port.entitlements)
        self.currency = Currency(port.currency)

        # If the portfolio contains positions, upload them to the MQ portfolio and schedule reports
        if self.position_sets:
            position_sets = self.position_sets
            self.position_sets = None
            self.update_positions(position_sets, False)
            self._schedule_first_reports(
                [pos_set.date for pos_set in position_sets])
            self.position_sets = None
Ejemplo n.º 5
0
def sharpe_ratio(series: pd.Series,
                 currency: RiskFreeRateCurrency = RiskFreeRateCurrency.USD,
                 w: Union[Window, int, str] = None,
                 curve_type: CurveType = CurveType.PRICES,
                 method: Interpolate = Interpolate.NAN) -> pd.Series:
    """
    Calculate Sharpe ratio

    :param series: series of prices or excess returns for an asset
    :param currency: currency for risk-free rate, defaults to USD
    :param w: Window or int: size of window and ramp up to use. e.g. Window(22, 10) where 22 is the window size
              and 10 the ramp up value.  If w is a string, it should be a relative date like '1m', '1d', etc.
              Window size defaults to length of series.
    :param curve_type: whether input series is of prices or excess returns, defaults to prices
    :param method: interpolation method (default: nan). Used to calculate returns on dates without data (i.e. weekends)
              when window is a relative date. Defaults to no interpolation.
    :return: Sharpe ratio

    **Usage**

    Given a price series P, risk-free rate R, and window of size w returns the rolling
    `Sharpe ratio <https://en.wikipedia.org/wiki/Sharpe_ratio>`_ S:

    :math:`S_t = \\frac{(E_t / E_{t-w+1})^{365.25 / (D_t - D_{t-w})}-1}{volatility(E, w)_t}`

    Excess returns E are defined as:

    :math:`E_t = E_{t-1} + P_t - P_{t-1} * (1 + R * (D_t - D_{t-1}) / 360)`

    where D is the date for a data point. The
    `Actual/360 <https://en.wikipedia.org/wiki/Day_count_convention#Actual/360>`_ day count convention is used.

    **Examples**

    Get rolling sharpe ratio of a price series (with window of 22).

    >>> sr = sharpe_ratio(generate_series(365, END_TODAY), USD, 22, PRICES)

    **See also**

    :func:`volatility`
    """
    return _get_ratio(series,
                      Currency(currency.value),
                      w,
                      day_count_convention=DayCountConvention.ACTUAL_360,
                      curve_type=curve_type,
                      interpolation_method=method)
Ejemplo n.º 6
0
def sharpe_ratio(series: pd.Series,
                 currency: RiskFreeRateCurrency,
                 w: Union[Window, int] = None,
                 curve_type: CurveType = CurveType.PRICES) -> pd.Series:
    """
    Calculate Sharpe ratio

    :param series: series of prices or excess returns for an asset
    :param currency: currency for risk-free rate
    :param curve_type: whether input series is of prices or excess returns
    :param w: Window or int: size of window and ramp up to use. e.g. Window(22, 10) where 22 is the window size
              and 10 the ramp up value.
    :return: Sharpe ratio

    **Usage**

    Given a price series P, risk-free rate R, and window of size w returns the rolling
    `Sharpe ratio <https://en.wikipedia.org/wiki/Sharpe_ratio>`_ S:

    :math:`S_t = \\frac{(E_t / E_{t-w+1})^{365.25 / (D_t - D_{t-w} - 1)}}{volatility(E, w)_t}`

    Excess returns E are defined as:

    :math:`E_t = E_{t-1} + P_t - P_{t-1} * (1 + R * DCF_{t-1,t})`

    where D is the date for a data point and DCF is day count fraction between two points

    **Examples**

    Get rolling sharpe ratio of a price series (with window of 252).

    >>> sr = sharpe_ratio(generate_series(100), RiskFreeRateCurrency.USD, 252)

    **See also**

    :func:`volatility`
    """
    return _get_ratio(series,
                      Currency(currency.value),
                      w,
                      day_count_convention=DayCountConvention.ACTUAL_360,
                      curve_type=curve_type)
Ejemplo n.º 7
0
def swap_rate(asset: Asset,
              tenor: str,
              benchmark_type: BenchmarkType = None,
              floating_index: str = None,
              *,
              source: str = None,
              real_time: bool = False) -> Series:
    """
    GS end-of-day Fixed-Floating interest rate swap (IRS) curves across major currencies.

    :param asset: asset object loaded from security master
    :param tenor: relative date representation of expiration date e.g. 1m
    :param benchmark_type: benchmark type e.g. LIBOR
    :param floating_index: floating index rate
    :param source: name of function caller
    :param real_time: whether to retrieve intraday data instead of EOD
    :return: swap rate curve
    """
    if real_time:
        raise NotImplementedError('realtime swap_rate not implemented')

    currency = asset.get_identifier(AssetIdentifier.BLOOMBERG_ID)
    currency = Currency(currency)

    # default benchmark types
    if benchmark_type is None:
        if currency == Currency.EUR:
            benchmark_type = BenchmarkType.EURIBOR
        elif currency == Currency.SEK:
            benchmark_type = BenchmarkType.STIBOR
        else:
            benchmark_type = BenchmarkType.LIBOR

    over_nights = [BenchmarkType.OIS]

    # default floating index
    if floating_index is None:
        if benchmark_type in over_nights:
            floating_index = '1d'
        else:
            if currency in [Currency.USD]:
                floating_index = '3m'
            elif currency in [
                    Currency.GBP, Currency.EUR, Currency.CHF, Currency.SEK
            ]:
                floating_index = '6m'

    mdapi_divider = " " if benchmark_type in over_nights else "-"
    mdapi_floating_index = BenchmarkType.OIS.value if benchmark_type is BenchmarkType.OIS else floating_index
    mdapi = currency.value + mdapi_divider + mdapi_floating_index

    rate_mqid = GsAssetApi.map_identifiers(GsIdType.mdapi, GsIdType.id,
                                           [mdapi])[mdapi]

    _logger.debug('where tenor=%s, floatingIndex=%s', tenor, floating_index)

    q = GsDataApi.build_market_data_query([rate_mqid],
                                          QueryType.SWAP_RATE,
                                          where=FieldFilterMap(tenor=tenor),
                                          source=source,
                                          real_time=real_time)

    _logger.debug('q %s', q)
    df = _market_data_timed(q)
    return Series() if df.empty else df['swapRate']