BlackLittermanPortfolio::BlackLittermanPortfolio(Matrix priceMatrix, Matrix Q, Matrix P, double tau, double riskAversion) { Matrix returnMatrix(priceMatrix.numRows() - 1, priceMatrix.numColumns()); for (unsigned int assetIndex = 0; assetIndex < returnMatrix.numColumns(); ++assetIndex) { for (unsigned int priceIndex = 0; priceIndex < returnMatrix.numRows(); ++priceIndex) { returnMatrix(priceIndex, assetIndex) = priceMatrix(priceIndex + 1, assetIndex) / priceMatrix(priceIndex, assetIndex) - 1.0; } } this->returnMatrix = returnMatrix; Matrix expectedReturns(returnMatrix.numColumns(), 1); for (unsigned int assetIndex = 0; assetIndex < returnMatrix.numColumns(); ++assetIndex) { for (unsigned int priceIndex = 0; priceIndex < returnMatrix.numRows(); ++priceIndex) { expectedReturns(assetIndex, 0) += returnMatrix(priceIndex, assetIndex); } } expectedReturns = expectedReturns * (1.0 / returnMatrix.numRows()); this->expectedReturns = expectedReturns; Matrix covMatrix(priceMatrix.numColumns(), priceMatrix.numColumns()); for (unsigned int i = 0; i < covMatrix.numRows(); ++i) { for (unsigned int j = i; j < covMatrix.numColumns(); ++j) { for (unsigned int k = 0; k < returnMatrix.numRows(); ++k) { covMatrix(i, j) += (returnMatrix(k, i) - expectedReturns(i, 0))*(returnMatrix(k, j) - expectedReturns(j, 0)) / (double)returnMatrix.numRows(); } covMatrix(j, i) = covMatrix(i, j); } } this->covMatrix = covMatrix; this->P = P; this->Q = Q; Matrix Omega = this->P * covMatrix * this->P.transpose(); this->Omega = Omega; this->riskAversion = riskAversion; this->tau = tau; this->Pi = riskAversion * this->covMatrix * this->getGobalMinimumVariancePortfolioWeights().transpose(); }
/* fonction de calcul de la matrice de variance-covariance d'un historique de taux */ DLLEXPORT xloper * xlCovarianceMatrixEWMA(const xloper * seriesId_, const double * decay_, const double * startDate_, const bool * norm_, const xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlCovarianceMatrixEWMA")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; /* déclaration du trigger */ ObjectHandler::validateRange(trigger_, "trigger") ; /* conversion des xloper */ std::vector<std::string> seriesId = ObjectHandler::operToVector<std::string>(* seriesId_, "seriesId") ; /* contrôle sur les dimensions */ QL_ENSURE(seriesId.size() >= 2, "unconsistent data set") ; /* on récupére les séries variationnelles */ std::vector<QuantLib::TimeSeries<double> > timeSeriesVector ; for (std::vector<std::string>::const_iterator It = seriesId.begin() ; It != seriesId.end() ; ++It) { OH_GET_REFERENCE(TimeSeriesPtr, * It, QuantLibAddin::TimeSeriesObject<double>, QuantLib::TimeSeries<double>) timeSeriesVector.push_back(* TimeSeriesPtr) ; } std::vector<QuantLib::TimeSeries<double> > nTimeSeriesVector ; /* selon le mode choisi */ if (* norm_ == true) { std::vector<QuantLib::TimeSeries<double> > deltaSeriesVector ; for (unsigned long i = 0 ; i < timeSeriesVector.size() ; i++) deltaSeriesVector.push_back( QuantLib::deltaTimeSeries<double>(timeSeriesVector[i])) ; /* création des vecteurs moyenne et std dev */ std::vector<double> mean ; std::vector<double> variance ; for (std::vector<QuantLib::TimeSeries<double> >::const_iterator It = deltaSeriesVector.begin() ; It < deltaSeriesVector.end() ; ++It) { variance.push_back(covarianceEWMA(* It, * It, QuantLib::Date(static_cast<QuantLib::BigInteger>(* startDate_)), decay_)) ; mean.push_back(meanEWMA(* It, QuantLib::Date(static_cast<QuantLib::BigInteger>(* startDate_)), decay_)) ; } /* Mode normé */ for (unsigned int i = 0 ; i < deltaSeriesVector.size() ; i++) { std::vector<double> tempValues ; std::vector<QuantLib::Date> tempDates ; for (QuantLib::TimeSeries<double>::const_iterator It = deltaSeriesVector[i].begin() ; It != deltaSeriesVector[i].end() ; ++It) { tempDates.push_back(It->first) ; tempValues.push_back((deltaSeriesVector[i][It->first] - mean[i]) / pow((deltaSeriesVector[i].size() + 1) * variance[i], 0.5)) ; } QuantLib::TimeSeries<double> tempSeries(tempDates.begin(), tempDates.end(), tempValues.begin()) ; nTimeSeriesVector.push_back(tempSeries) ; } } else { /* Mode non normé */ std::vector<double> mean ; for (std::vector<QuantLib::TimeSeries<double>>::const_iterator It = timeSeriesVector.begin() ; It < timeSeriesVector.end() ; ++It) mean.push_back(meanEWMA(* It, QuantLib::Date( static_cast<QuantLib::BigInteger>(* startDate_)), decay_)) ; /* on se contente de centrer les séries */ for (unsigned int i = 0 ; i < timeSeriesVector.size() ; i++) { std::vector<double> tempValues ; std::vector<QuantLib::Date> tempDates ; for (QuantLib::TimeSeries<double>::const_iterator It = timeSeriesVector[i].begin() ; It != timeSeriesVector[i].end() ; ++It) { tempDates.push_back(It->first) ; tempValues.push_back(timeSeriesVector[i][It->first] - mean[i]) ; } QuantLib::TimeSeries<double> tempSeries(tempDates.begin(), tempDates.end(), tempValues.begin()) ; nTimeSeriesVector.push_back(tempSeries) ; } } /* création de la matrice de retour */ QuantLib::Matrix returnMatrix( nTimeSeriesVector.size(), nTimeSeriesVector.size()) ; for (unsigned int i = 0 ; i < nTimeSeriesVector.size() ; i++) { for (unsigned int j = 0 ; j <= i ; j++) { returnMatrix[i][j] = covarianceEWMA(nTimeSeriesVector[i], nTimeSeriesVector[j], QuantLib::Date(static_cast<QuantLib::BigInteger>(* startDate_)), decay_) ; returnMatrix[j][i] = returnMatrix[i][j]; } } static OPER returnOper ; ObjectHandler::MatrixToOper(returnMatrix, returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; return 0 ; } }