相關性對最佳彩虹選項的影響


2

編輯2:我發現了問題,現在價格似乎表現出預期。對於感興趣的任何人,在對模擬中使用的從屬隨機正態變量進行歸一化時都會出現錯誤,因此,儘管它們具有正確的相關性,其中一個的標準偏差為1,而另一個標準偏差遠大於1。即使相關性增加,也不會下降(甚至增加)。@ ir7建議的奇偶關係現在似乎保持不變,這使我充滿信心。

enter image description here

我正在使用蒙特卡洛模擬對rainbow option進行數值評估,並且得到了一些意想不到的結果。與我的直覺相反,最佳買入期權的價格隨著價格的上漲而一直在下降,直到相關的價格開始上升。最壞的選擇情況表現得比預期的要好得多,它是相關性的增加函數。由於我以幾乎相同的方式評估它們(只是在我的代碼中使用min(...)而不是max(...)),我對可能是錯誤的問題感到非常困惑,否則價格以這種方式表現?如果這是完全不合理的,那麼是否有人想對我的計算為什麼會隨著相關性的增加而中斷進行猜測呢?該程序是用C ++編寫的,因此,如果精通C ++的任何人都想看看我的代碼有什麼錯誤,我會很樂意將其發布。

enter image description here

編輯1:在@ ir7的幫助下進行了一些故障排除後,我的蒙特卡洛模擬似乎對某些資產有所欠缺(單個資產的情況很好)。在下面發布(一些)我的C ++代碼,以解決一個評估性能出色的選項的較簡單問題,該選項可以作為一種封閉形式的解決方案供他(以及任何其他想要這樣做的人)簽出並提供幫助。一旦相關性高於〜0.5,計算結果似乎再次崩潰,請參見下圖。enter image description here如果使用了一些函數調用讓您解釋或發布代碼,我很樂意這樣做,現在,我將嘗試使其保持某種裸露狀態:

進行實際評估的類和函數:

MonteCarloOutPerformanceOptionFunction::MonteCarloOutPerformanceOptionFunction(std::string uniqueIdentifier_, int nominal_, std::vector<double> S0_vect, std::vector<Wrapper<PayOff>> ThePayOffVect_, double r_, std::vector<double> d_vect_, std::vector<double> impvol_vect_, std::vector<std::vector<double>> covMatrix_, double TTM_, unsigned long numberOfPaths_)
    : r(r_), S_vect(S0_vect), ThePayOffVect(ThePayOffVect_), d_vect(d_vect_), covMatrix(covMatrix_), valuationFunction(uniqueIdentifier_, TTM_, nominal_), numberOfPaths(numberOfPaths_), impvol_vect(impvol_vect_)
{
    if (covMatrix.size() != S_vect.size())
        throw("Missmatched Covariance matrix and initial spot values array sizes in OutPerformance Option");
    if (2 != S_vect.size())
        throw("More than two equities specified in OutPerformance Option");
}


void MonteCarloOutPerformanceOptionFunction::ValueInstrument()
{
    std::vector<MJArray> correlatedNormVariates = GetArraysOfCorrelatedGauassiansByBoxMuller(numberOfPaths, covMatrix);
    std::vector<StatisticAllPaths> thesePathGatherers;
    for (unsigned long i = 0; i < S_vect.size(); i++)
    {
        StandardExcerciseOption thisOption(ThePayOffVect[i], TTM);
        StatisticAllPaths onePathGatherer;
        thesePathGatherers.push_back(onePathGatherer);
        OneStepMonteCarloValuation(thisOption, S_vect[i], impvol_vect[i], r, d_vect[i], numberOfPaths, correlatedNormVariates[i], thesePathGatherers[i]);
    }
    f = 0;
    for (unsigned long i = 0; i < numberOfPaths; i++)
    {
        std::vector<double> outcomes;
        outcomes.reserve(S_vect.size());
        for (unsigned long j = 0; j < S_vect.size(); j++)
        {
            outcomes.push_back(thesePathGatherers[j].GetOneValueFromResultsSoFar(i));
        }
        f += std::max(outcomes[0] - outcomes[1], 0.0);
    }
    f *= ((double)nominal / numberOfPaths);
    return;
}

OneStepMonteCarloValuation 處調用了蒙特卡羅模擬函數(對於單資產選項(例如,普通買入/賣出),這似乎工作正常)

void OneStepMonteCarloValuation(const StandardExcerciseOption& TheOption, double Spot, double Vol, double r, double d, unsigned long NumberOfPaths, MJArray normVariates, StatisticsMC& gatherer)
{
    if (normVariates.size() != NumberOfPaths)
        throw("mismatched number of paths and normal variates");
    //Pre-calculate as much as possible
    double Expiry = TheOption.GetExpiry();
    double variance = Vol * Vol * Expiry;
    double rootVariance = sqrt(variance);
    double itoCorrection = -0.5 * variance;
    double movedSpot = Spot * exp((r-d) * Expiry + itoCorrection);
    double thisSpot;
    double discounting = exp(-r * Expiry);
    for (unsigned long i = 0; i < NumberOfPaths; i++)
    {
        thisSpot = movedSpot * exp(rootVariance * normVariates[i]);
        double thisPayoff = TheOption.OptionPayOff(thisSpot);
        gatherer.DumpOneResult(discounting * thisPayoff);
    }
    return;
}

StatisticAllPaths 類在模擬中用作輸入,該類收集模擬的所有最終值

StatisticAllPaths::StatisticAllPaths(const unsigned long minimumNumberOfPaths) : PathsDone(0)
{
    ResultList.reserve(minimumNumberOfPaths);
}

void StatisticAllPaths::DumpOneResult(double result)
{
    ResultList.push_back(result);
    PathsDone++;
}

const double& StatisticAllPaths::GetOneValueFromResultsSoFar(unsigned long index) const
{
    return ResultList[index];
}

此處使用的PayOffVect用於獲取MC評估函數中每個路徑的收益,但是由於我們只是在這裡收集所有路徑並在以後處理它們(在主要評估類的最後一部分),因此在這裡什麼都沒做。在這種情況下,它僅用於通過該繼承的類使性能相對值:

PayOffRelPerformance::PayOffRelPerformance(double startValue_) : startValue(startValue_)
{
}

double PayOffRelPerformance::operator()(double spot) const
{
    return spot / startValue;
}

GetArraysOfCorrelatedGauassiansByBoxMuller完成生成將在模擬中使用的正態變量向量的工作。我已經檢查了Cholezky矩陣對於實際情況是否正確,並且我還檢查了輸出的正態變量實際上與協方差矩陣所隱含的相關性有關。

std::vector<MJArray> GetArraysOfCorrelatedGauassiansByBoxMuller(unsigned long numberOfVariates, std::vector<std::vector<double>> covMatrix)
{
    //Calculate the cholezky Matrix
    std::vector<std::vector<double>> cholezkyMatrix = Cholesky_Decomposition(covMatrix);
    //Fix the size of the arrays to contain correlated normal variates
    std::vector<MJArray> corrNormVariatesVector(cholezkyMatrix.size());
    for (unsigned long j = 0; j < corrNormVariatesVector.size(); j++) {
        corrNormVariatesVector[j].resize(numberOfVariates);
        corrNormVariatesVector[j] = 0;
    }
    //calculate correlated normal variates and fill the arrays with values
    MJArray NormVariates(cholezkyMatrix.size());
    for (unsigned long k = 0; k < numberOfVariates; k++) {
        for (unsigned long i = 0; i < cholezkyMatrix.size(); i++)
        {
            NormVariates[i] = GetOneGaussianByBoxMuller();
            for (unsigned long j = 0; j < cholezkyMatrix[i].size(); j++) {
                corrNormVariatesVector[i][k] += cholezkyMatrix[i][j] * NormVariates[j];
            }
            corrNormVariatesVector[i][k] /= cholezkyMatrix[i][i]; //normalize the random variates
        }
    }
    return corrNormVariatesVector;
}
3

Intuitively, they should both be short correlation, that is the less correlated the assets are the higher the value of the worst of/best of option.

The best of option payoff is sandwiched by an exchange option payoff (plus other vanilla forward/option payoffs on single stock, insensitive to correlation):

$$ X_T -K + (Y_T-X_T)^+ \leq \max(X_T - K ,Y_T - K,0) \leq (X_T-K)^+ + (Y_T-X_T)^+ $$

It is clear intuitively that the exchange option is short correlation (also explicitly seen in Margrabe's world).

Edit: For worst of option we have a similar relation:

$$ K-X_T + (X_T-Y_T)^+ \leq \max(K-X_T,K-Y_T,0) \leq (K-X_T)^+ + (X_T-Y_T)^+ $$

Edit2: You can look at the behaviour of the product packages I claim sandwich the rainbow, for various correlations. This could expose something quickly. Remember that those product packages need both MC prices (from the same loops you use for rainbows) and also have closed-form solutions (of course, vols are flat etc. in this debugging phase), so insert both versions in your comparisons.


1

Best-of + Worst-of = Call1 + Call2

The right hand side is independent of correlation (and you can check it in your model).

Therefore if Best-of is short correlation, worst-of must be long correlation.

Increasing correlation makes the two assets more similar and therefore makes the best-of more like a vanilla. This is why a best-of is short correlation.

(Hope I understood the question right!)