返回题库

固收 Z Spread 与 Oas

Fi Z Spread Vs Oas

专题
Algorithmic Programming / 算法编程
难度
L3
来源
MyntBit

题目详情

分析某 5 年期可赎回债券。当前收益率曲线向上倾斜。此可赎回债券的 Option-Adjusted Spread(OAS)与 Z-spread 通常有何差异?原因是什么?

任务:Z-spread 是包含嵌入期权价值的总利差;OAS 是剔除嵌入期权价值后的利差。对可赎回债券:Z-spread > OAS,因为 Z-spread 包含了赎回期权对投资者的不利价值(投资者卖出期权)。OAS = Z-spread - 期权价值利差。

英文原题

You are analyzing a 5-year callable bond. The current yield curve is upward sloping. How does the Option-Adjusted Spread (OAS) typically differ from the Z-spread for this callable bond, and why?

解析

问题分析

Z-spread(零波动率利差)是在基准收益率曲线上平行移动的固定利差,使债券现金流折现值等于市场价格。OAS(期权调整利差)进一步考虑了嵌入式期权的价值。两者之差反映了期权成本。

实现

class BondPricer {
    std::vector<double> spot_rates_;  // 各期限即期利率
public:
    double zSpread(const std::vector<double>& cashflows, 
                   const std::vector<double>& times, double price) {
        auto pv = [&] (\1) {
            double sum = 0;
            for (size_t i = 0; i < cashflows.size(); ++i)
                sum += cashflows[i] / std::pow(1 + spot_rates_[i] + spread, times[i]);
            return sum;
        };
        double lo = -0.10, hi = 0.50;  // [-10%, 50%]
        for (int iter = 0; iter < 50; ++iter) {
            double mid = (lo + hi) / 2;
            if (pv(mid) > price) lo = mid; else hi = mid;
        }
        return (lo + hi) / 2;
    }
};

复杂度与边界

  • 时间复杂度:O(N * 迭代次数),N 为现金流数
  • 空间复杂度:O(N)
  • 边界条件:(1) 价格<=0 无解 (2) 利差范围可能需扩展 (3) 负利差是合法的(债券优于基准)

英文解析

Analysis

The Z-spread (zero-volatility spread) is a constant spread added to each point on the benchmark spot curve such that the bond's discounted cash flows equal its market price. The OAS (Option-Adjusted Spread) additionally accounts for the value of embedded options by simulating interest rate paths and averaging the spread across all scenarios.

For a callable bond: Z-spread = OAS + option cost. The option cost represents the value of the call option held by the issuer. Since the call option reduces the bond's value, Z-spread > OAS for callable bonds.

Solution

class BondPricer {
    std::vector<double> spot_rates_;  // spot rates by maturity
public:
    double zSpread(const std::vector<double>& cashflows,
                   const std::vector<double>& times, double price) {
        auto pv = [&] (double spread) {
            double sum = 0;
            for (size_t i = 0; i < cashflows.size(); ++i)
                sum += cashflows[i] / std::pow(1 + spot_rates_[i] + spread, times[i]);
            return sum;
        };
        double lo = -0.10, hi = 0.50;
        for (int iter = 0; iter < 50; ++iter) {
            double mid = (lo + hi) / 2;
            if (pv(mid) > price) lo = mid; else hi = mid;
        }
        return (lo + hi) / 2;
    }

    double oas(const std::vector<double>& cashflows,
               const std::vector<double>& times, double price,
               int num_paths, double vol, double callPrice) {
        // Monte Carlo: simulate rate paths, compute average PV at each trial spread
        double best_oas = 0;
        for (double spread = -0.05; spread < 0.20; spread += 0.001) {
            double avg_pv = 0;
            for (int p = 0; p < num_paths; ++p) {
                double path_pv = 0;
                // simulate rate path with vol, apply call decision each period
                avg_pv += path_pv;
            }
            avg_pv /= num_paths;
            if (std::abs(avg_pv - price) < 0.01) { best_oas = spread; break; }
        }
        return best_oas;
    }
};

Relationship: Z-spread = OAS + Option Cost (for callable bonds)

Complexity & Edge Cases

  • Time complexity: O(N * iterations) for Z-spread binary search; O(N * paths * iterations) for OAS
  • Space complexity: O(N) for Z-spread; O(N * paths) for OAS
  • Edge cases: (1) Price <= 0 yields no valid spread. (2) Spread range may need expansion for distressed bonds. (3) Negative spreads are valid (bond outperforms benchmark). (4) Non-callable bonds: Z-spread = OAS (option cost = 0).

Verification

5-year callable bond, upward-sloping curve, Z-spread = 150bps:

  • If option cost = 50bps then OAS = 100bps
  • If rates drop then call probability rises then option cost increases then Z-spread widens relative to OAS
  • For a non-callable bond: Z-spread = OAS = 150bps

Key Considerations

  • OAS is the fair comparison metric for bonds with different embedded option structures
  • Z-spread overstates the "true" spread for callable/putable bonds because it ignores option risk
  • Option cost varies with rate levels: when rates are near call threshold, option cost is highest
  • OAS calculation requires an interest rate model (Hull-White, Black-Karasinski) and Monte Carlo simulation