mat33 randomInertiaMatrix() { // generate random valid inertia matrix by first getting valid components // along major axes and then rotating by random amount vec3 principal = randomInertiaPrincipal(); mat33 rot(transformX(randomFloat(-BT_ID_PI, BT_ID_PI)) * transformY(randomFloat(-BT_ID_PI, BT_ID_PI)) * transformZ(randomFloat(-BT_ID_PI, BT_ID_PI))); mat33 inertia; inertia(0, 0) = principal(0); inertia(0, 1) = 0; inertia(0, 2) = 0; inertia(1, 0) = 0; inertia(1, 1) = principal(1); inertia(1, 2) = 0; inertia(2, 0) = 0; inertia(2, 1) = 0; inertia(2, 2) = principal(2); return rot * inertia * rot.transpose(); }
void AnalyticCompoundOptionEngine::calculate() const { QL_REQUIRE(strikeDaughter()>0.0, "Daughter strike must be positive"); QL_REQUIRE(strikeMother()>0.0, "Mother strike must be positive"); QL_REQUIRE(spot() >= 0.0, "negative or null underlying given"); /* Solver Setup ***************************************************/ Date helpDate(process_->riskFreeRate()->referenceDate()); Date helpMaturity=helpDate+(maturityDaughter()-maturityMother())*Days; Real vol =process_->blackVolatility()->blackVol(helpMaturity, strikeDaughter()); Time helpTimeToMat=process_->time(helpMaturity); vol=vol*std::sqrt(helpTimeToMat); DiscountFactor dividendDiscount = process_->dividendYield()->discount(helpMaturity); DiscountFactor riskFreeDiscount = process_->riskFreeRate()->discount(helpMaturity); boost::shared_ptr<ImpliedSpotHelper> f( new ImpliedSpotHelper(dividendDiscount, riskFreeDiscount, vol, payoffDaughter(), strikeMother())); Brent solver; solver.setMaxEvaluations(1000); Real accuracy = 1.0e-6; Real X=0.0; Real sSolved=0.0; sSolved=solver.solve(*f, accuracy, strikeDaughter(), 1.0e-6, strikeDaughter()*1000.0); X=transformX(sSolved); // transform stock to return as in Wystup's book /* Solver Setup Finished*****************************************/ Real phi=typeDaughter(); // -1 or 1 Real w=typeMother(); // -1 or 1 Real rho=std::sqrt(residualTimeMother()/residualTimeDaughter()); BivariateCumulativeNormalDistributionDr78 N2(w*rho) ; DiscountFactor ddD=dividendDiscountDaughter(); DiscountFactor rdD=riskFreeDiscountDaughter(); //DiscountFactor ddM=dividendDiscountMother(); DiscountFactor rdM=riskFreeDiscountMother(); Real XmSM=X-stdDeviationMother(); Real S=spot(); Real dP=dPlus(); Real dPT12=dPlusTau12(sSolved); Real vD=volatilityDaughter(); Real dM=dMinus(); Real strD=strikeDaughter(); Real strM=strikeMother(); Real rTM=residualTimeMother(); Real rTD=residualTimeDaughter(); Real rD=riskFreeRateDaughter(); Real dD=dividendRateDaughter(); Real tempRes=0.0; Real tempDelta=0.0; Real tempGamma=0.0; Real tempVega=0.0; Real tempTheta=0.0; Real N2XmSM=N2(-phi*w*XmSM,phi*dP); Real N2X=N2(-phi*w*X,phi*dM); Real NeX=N_(-phi*w*e(X)); Real NX=N_(-phi*w*X); Real NT12=N_(phi*dPT12); Real ndP=n_(dP); Real nXm=n_(XmSM); Real invMTime=1/std::sqrt(rTM); Real invDTime=1/std::sqrt(rTD); tempRes=phi*w*S*ddD*N2XmSM-phi*w*strD*rdD*N2X-w*strM*rdM*NX; tempDelta=phi*w*ddD*N2XmSM; tempGamma=(ddD/(vD*S))*(invMTime*nXm*NT12+w*invDTime*ndP*NeX); tempVega=ddD*S*((1/invMTime)*nXm*NT12+w*(1/invDTime)*ndP*NeX); tempTheta+=phi*w*dD*S*ddD*N2XmSM-phi*w*rD*strD*rdD*N2X-w*rD*strM*rdM*NX; tempTheta-=0.5*vD*S*ddD*(invMTime*nXm*NT12+w*invDTime*ndP*NeX); results_.value=tempRes; results_.delta=tempDelta; results_.gamma=tempGamma; results_.vega=tempVega; results_.theta=tempTheta; }
QPointF ZStTransform::transform(const QPoint &pt) const { return QPointF(transformX(pt.x()), transformY(pt.y())); }
QRectF ZStTransform::transform(const QRectF &rect) const { return QRectF(transformX(rect.left()), transformY(rect.top()), rect.width() * getSx(), rect.height() * getSy()); }
ZPoint ZStTransform::transform(const ZPoint &pt) const { return ZPoint(transformX(pt.x()), transformY(pt.y()), transformZ(pt.z())); }