/* Copyright (C) 2016 -2017 Jerry Jin */ #include #include #include "calibrationhelpers.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../loop.hpp" void SwaptionHelperWorker::Execute(){ try{ // convert input datatypes to QuantLib datatypes QuantLib::Period OptionTenorLib; QuantLibAddin::cppToLibrary(mOptionTenor, OptionTenorLib); // convert input datatypes to QuantLib datatypes QuantLib::Period LengthLib; QuantLibAddin::cppToLibrary(mLength, LengthLib); // convert object IDs into library objects QuantLib::Handle VolatilityLibObj = ObjectHandler::convert2< QuantLib::Handle >(mVolatility, "Volatility"); // convert object IDs into library objects OH_GET_REFERENCE(IborIndexLibObjPtr, mIborIndex, QuantLibAddin::IborIndex, QuantLib::IborIndex) // convert input datatypes to QuantLib datatypes QuantLib::Period FixedLegTenorLib; QuantLibAddin::cppToLibrary(mFixedLegTenor, FixedLegTenorLib); // convert input datatypes to QuantLib enumerated datatypes QuantLib::DayCounter FixedLegDayCounterEnum = ObjectHandler::Create()(mFixedLegDayCounter); // convert input datatypes to QuantLib enumerated datatypes QuantLib::DayCounter FloatingLegDayCounterEnum = ObjectHandler::Create()(mFloatingLegDayCounter); // convert object IDs into library objects OH_GET_OBJECT(YieldCurveCoerce, mYieldCurve, ObjectHandler::Object) QuantLib::Handle YieldCurveLibObj = QuantLibAddin::CoerceHandle< QuantLibAddin::YieldTermStructure, QuantLib::YieldTermStructure>()( YieldCurveCoerce); // Construct the Value Object boost::shared_ptr valueObject( new QuantLibAddin::ValueObjects::qlSwaptionHelper( mObjectID, mOptionTenor, mLength, mVolatility, mIborIndex, mFixedLegTenor, mFixedLegDayCounter, mFloatingLegDayCounter, mYieldCurve, false )); // Construct the Object boost::shared_ptr object( new QuantLibAddin::SwaptionHelper( valueObject, OptionTenorLib, LengthLib, VolatilityLibObj, IborIndexLibObjPtr, FixedLegTenorLib, FixedLegDayCounterEnum, FloatingLegDayCounterEnum, YieldCurveLibObj, false )); // Store the Object in the Repository mReturnValue = ObjectHandler::Repository::instance().storeObject(mObjectID, object, false, valueObject); }catch(const std::exception &e){ mError = e.what(); }catch (...){ mError = "unkown error"; } } void SwaptionHelperWorker::HandleOKCallback(){ Nan::HandleScope scope; Local argv[2] = { Nan::New(mError).ToLocalChecked(), Nan::New(mReturnValue).ToLocalChecked() }; callback->Call(2, argv); } NAN_METHOD(QuantLibNode::SwaptionHelper) { // validate js arguments if (info.Length() == 0 || !info[0]->IsString()) { return Nan::ThrowError("ObjectID is required."); } if (info.Length() == 1 || !info[1]->IsString()) { return Nan::ThrowError("OptionTenor is required."); } if (info.Length() == 2 || !info[2]->IsString()) { return Nan::ThrowError("Length is required."); } if (info.Length() == 4 || !info[4]->IsString()) { return Nan::ThrowError("IborIndex is required."); } if (info.Length() == 5 || !info[5]->IsString()) { return Nan::ThrowError("FixedLegTenor is required."); } if (info.Length() == 6 || !info[6]->IsString()) { return Nan::ThrowError("FixedLegDayCounter is required."); } if (info.Length() == 7 || !info[7]->IsString()) { return Nan::ThrowError("FloatingLegDayCounter is required."); } // convert js argument to c++ type String::Utf8Value strObjectID(info[0]->ToString()); string ObjectIDCpp(strdup(*strObjectID)); // convert js argument to c++ type String::Utf8Value strOptionTenor(info[1]->ToString()); string OptionTenorCpp(strdup(*strOptionTenor)); // convert js argument to c++ type String::Utf8Value strLength(info[2]->ToString()); string LengthCpp(strdup(*strLength)); // convert js argument to c++ type ObjectHandler::property_t VolatilityCpp = ObjectHandler::property_t(static_cast(Nan::To(info[3]).FromJust())); // convert js argument to c++ type String::Utf8Value strIborIndex(info[4]->ToString()); string IborIndexCpp(strdup(*strIborIndex)); // convert js argument to c++ type String::Utf8Value strFixedLegTenor(info[5]->ToString()); string FixedLegTenorCpp(strdup(*strFixedLegTenor)); // convert js argument to c++ type String::Utf8Value strFixedLegDayCounter(info[6]->ToString()); string FixedLegDayCounterCpp(strdup(*strFixedLegDayCounter)); // convert js argument to c++ type String::Utf8Value strFloatingLegDayCounter(info[7]->ToString()); string FloatingLegDayCounterCpp(strdup(*strFloatingLegDayCounter)); // convert js argument to c++ type ObjectHandler::property_t YieldCurveCpp = ObjectHandler::property_t(static_cast(Nan::To(info[8]).FromJust())); // declare callback Nan::Callback *callback = new Nan::Callback(info[9].As()); // launch Async worker Nan::AsyncQueueWorker(new SwaptionHelperWorker( callback ,ObjectIDCpp ,OptionTenorCpp ,LengthCpp ,VolatilityCpp ,IborIndexCpp ,FixedLegTenorCpp ,FixedLegDayCounterCpp ,FloatingLegDayCounterCpp ,YieldCurveCpp )); } //SwaptionHelperWorker::~SwaptionHelperWorker(){ // //} //void SwaptionHelperWorker::Destroy(){ // //} void CalibrationHelperSetPricingEngineWorker::Execute(){ try{ // convert object IDs into library objects OH_GET_REFERENCE(PricingEngineLibObjPtr, mPricingEngine, QuantLibAddin::PricingEngine, QuantLib::PricingEngine) // convert object IDs into library objects OH_GET_REFERENCE(ObjectIDLibObjPtr, mObjectID, QuantLibAddin::CalibrationHelper, QuantLib::CalibrationHelper) // invoke the member function ObjectIDLibObjPtr->setPricingEngine( PricingEngineLibObjPtr ); }catch(const std::exception &e){ mError = e.what(); }catch (...){ mError = "unkown error"; } } void CalibrationHelperSetPricingEngineWorker::HandleOKCallback(){ Nan::HandleScope scope; Local argv[2] = { Nan::New(mError).ToLocalChecked(), Nan::Null() }; callback->Call(2, argv); } NAN_METHOD(QuantLibNode::CalibrationHelperSetPricingEngine) { // validate js arguments if (info.Length() == 0 || !info[0]->IsString()) { return Nan::ThrowError("ObjectID is required."); } if (info.Length() == 1 || !info[1]->IsString()) { return Nan::ThrowError("PricingEngine is required."); } // convert js argument to c++ type String::Utf8Value strObjectID(info[0]->ToString()); string ObjectIDCpp(strdup(*strObjectID)); // convert js argument to c++ type String::Utf8Value strPricingEngine(info[1]->ToString()); string PricingEngineCpp(strdup(*strPricingEngine)); // declare callback Nan::Callback *callback = new Nan::Callback(info[2].As()); // launch Async worker Nan::AsyncQueueWorker(new CalibrationHelperSetPricingEngineWorker( callback ,ObjectIDCpp ,PricingEngineCpp )); } //CalibrationHelperSetPricingEngineWorker::~CalibrationHelperSetPricingEngineWorker(){ // //} //void CalibrationHelperSetPricingEngineWorker::Destroy(){ // //} void CalibrationHelperImpliedVolatilityWorker::Execute(){ try{ // convert input datatypes to QuantLib datatypes // convert input datatypes to QuantLib datatypes // convert input datatypes to QuantLib datatypes QuantLib::Size MaxEvaluationsLib; QuantLibAddin::cppToLibrary(mMaxEvaluations, MaxEvaluationsLib); // convert object IDs into library objects OH_GET_REFERENCE(ObjectIDLibObjPtr, mObjectID, QuantLibAddin::CalibrationHelper, QuantLib::CalibrationHelper) // invoke the member function mReturnValue = ObjectIDLibObjPtr->impliedVolatility( mTargetValue , mAccuracy , MaxEvaluationsLib , mMinVol , mMaxVol ); }catch(const std::exception &e){ mError = e.what(); }catch (...){ mError = "unkown error"; } } void CalibrationHelperImpliedVolatilityWorker::HandleOKCallback(){ Nan::HandleScope scope; Local argv[2] = { Nan::New(mError).ToLocalChecked(), Nan::New(mReturnValue) }; callback->Call(2, argv); } NAN_METHOD(QuantLibNode::CalibrationHelperImpliedVolatility) { // validate js arguments if (info.Length() == 0 || !info[0]->IsString()) { return Nan::ThrowError("ObjectID is required."); } if (info.Length() == 1 || !info[1]->IsNumber()) { return Nan::ThrowError("TargetValue is required."); } if (info.Length() == 2 || !info[2]->IsNumber()) { return Nan::ThrowError("Accuracy is required."); } if (info.Length() == 3 || !info[3]->IsNumber()) { return Nan::ThrowError("MaxEvaluations is required."); } if (info.Length() == 4 || !info[4]->IsNumber()) { return Nan::ThrowError("MinVol is required."); } if (info.Length() == 5 || !info[5]->IsNumber()) { return Nan::ThrowError("MaxVol is required."); } // convert js argument to c++ type String::Utf8Value strObjectID(info[0]->ToString()); string ObjectIDCpp(strdup(*strObjectID)); // convert js argument to c++ type double TargetValueCpp = Nan::To(info[1]).FromJust(); // convert js argument to c++ type double AccuracyCpp = Nan::To(info[2]).FromJust(); // convert js argument to c++ type long MaxEvaluationsCpp = Nan::To(info[3]).FromJust(); // convert js argument to c++ type double MinVolCpp = Nan::To(info[4]).FromJust(); // convert js argument to c++ type double MaxVolCpp = Nan::To(info[5]).FromJust(); // declare callback Nan::Callback *callback = new Nan::Callback(info[6].As()); // launch Async worker Nan::AsyncQueueWorker(new CalibrationHelperImpliedVolatilityWorker( callback ,ObjectIDCpp ,TargetValueCpp ,AccuracyCpp ,MaxEvaluationsCpp ,MinVolCpp ,MaxVolCpp )); } //CalibrationHelperImpliedVolatilityWorker::~CalibrationHelperImpliedVolatilityWorker(){ // //} //void CalibrationHelperImpliedVolatilityWorker::Destroy(){ // //} void SwaptionHelperModelValueWorker::Execute(){ try{ // convert object IDs into library objects OH_GET_REFERENCE(ObjectIDLibObjPtr, mObjectID, QuantLibAddin::SwaptionHelper, QuantLib::SwaptionHelper) // invoke the member function mReturnValue = ObjectIDLibObjPtr->modelValue( ); }catch(const std::exception &e){ mError = e.what(); }catch (...){ mError = "unkown error"; } } void SwaptionHelperModelValueWorker::HandleOKCallback(){ Nan::HandleScope scope; Local argv[2] = { Nan::New(mError).ToLocalChecked(), Nan::New(mReturnValue) }; callback->Call(2, argv); } NAN_METHOD(QuantLibNode::SwaptionHelperModelValue) { // validate js arguments if (info.Length() == 0 || !info[0]->IsString()) { return Nan::ThrowError("ObjectID is required."); } // convert js argument to c++ type String::Utf8Value strObjectID(info[0]->ToString()); string ObjectIDCpp(strdup(*strObjectID)); // declare callback Nan::Callback *callback = new Nan::Callback(info[1].As()); // launch Async worker Nan::AsyncQueueWorker(new SwaptionHelperModelValueWorker( callback ,ObjectIDCpp )); } //SwaptionHelperModelValueWorker::~SwaptionHelperModelValueWorker(){ // //} //void SwaptionHelperModelValueWorker::Destroy(){ // //} void OneFactorAffineModelCalibrateWorker::Execute(){ try{ // convert object IDs into library objects std::vector< boost::shared_ptr > CalibrationHelpersLibObjPtr = ObjectHandler::getLibraryObjectVector(mCalibrationHelpers); // convert object IDs into library objects OH_GET_UNDERLYING_NONCONST(MethodLibObj, mMethod, QuantLibAddin::OptimizationMethod, QuantLib::OptimizationMethod) // convert object IDs into library objects OH_GET_UNDERLYING(EndCriteriaLibObj, mEndCriteria, QuantLibAddin::EndCriteria, QuantLib::EndCriteria) // convert object IDs into library objects OH_GET_UNDERLYING(ConstraintLibObj, mConstraint, QuantLibAddin::Constraint, QuantLib::Constraint) // convert input datatypes to QuantLib datatypes std::vector WeightsLib = QuantLibAddin::convertVector(mWeights); // convert object IDs into library objects OH_GET_REFERENCE(ObjectIDLibObjPtr, mObjectID, QuantLibAddin::OneFactorAffineModel, QuantLib::OneFactorAffineModel) // invoke the member function ObjectIDLibObjPtr->calibrate( CalibrationHelpersLibObjPtr , MethodLibObj , EndCriteriaLibObj , ConstraintLibObj , mWeights , mFixedCoeff ); }catch(const std::exception &e){ mError = e.what(); }catch (...){ mError = "unkown error"; } } void OneFactorAffineModelCalibrateWorker::HandleOKCallback(){ Nan::HandleScope scope; Local argv[2] = { Nan::New(mError).ToLocalChecked(), Nan::Null() }; callback->Call(2, argv); } NAN_METHOD(QuantLibNode::OneFactorAffineModelCalibrate) { // validate js arguments if (info.Length() == 0 || !info[0]->IsString()) { return Nan::ThrowError("ObjectID is required."); } if (info.Length() == 1 || !info[1]->IsArray()) { return Nan::ThrowError("CalibrationHelpers is required."); } if (info.Length() == 2 || !info[2]->IsString()) { return Nan::ThrowError("Method is required."); } if (info.Length() == 3 || !info[3]->IsString()) { return Nan::ThrowError("EndCriteria is required."); } if (info.Length() == 4 || !info[4]->IsString()) { return Nan::ThrowError("Constraint is required."); } if (info.Length() == 5 || !info[5]->IsArray()) { return Nan::ThrowError("Weights is required."); } if (info.Length() == 6 || !info[6]->IsArray()) { return Nan::ThrowError("FixedCoeff is required."); } // convert js argument to c++ type String::Utf8Value strObjectID(info[0]->ToString()); string ObjectIDCpp(strdup(*strObjectID)); // convert js argument to c++ type std::vectorCalibrationHelpersCpp; Local CalibrationHelpersArray = info[1].As(); for (unsigned int i = 0; i < CalibrationHelpersArray->Length(); i++){ String::Utf8Value strCalibrationHelpers(Nan::Get(CalibrationHelpersArray, i).ToLocalChecked()->ToString()); CalibrationHelpersCpp.push_back(strdup(*strCalibrationHelpers)); } // convert js argument to c++ type String::Utf8Value strMethod(info[2]->ToString()); string MethodCpp(strdup(*strMethod)); // convert js argument to c++ type String::Utf8Value strEndCriteria(info[3]->ToString()); string EndCriteriaCpp(strdup(*strEndCriteria)); // convert js argument to c++ type String::Utf8Value strConstraint(info[4]->ToString()); string ConstraintCpp(strdup(*strConstraint)); // convert js argument to c++ type std::vectorWeightsCpp; Local WeightsArray = info[5].As(); for (unsigned int i = 0; i < WeightsArray->Length(); i++){ WeightsCpp.push_back(Nan::To(Nan::Get(WeightsArray, i).ToLocalChecked()).FromJust()); } // convert js argument to c++ type std::vectorFixedCoeffCpp; Local FixedCoeffArray = info[6].As(); for (unsigned int i = 0; i < FixedCoeffArray->Length(); i++){ FixedCoeffCpp.push_back(Nan::To(Nan::Get(FixedCoeffArray, i).ToLocalChecked()).FromJust()); } // declare callback Nan::Callback *callback = new Nan::Callback(info[7].As()); // launch Async worker Nan::AsyncQueueWorker(new OneFactorAffineModelCalibrateWorker( callback ,ObjectIDCpp ,CalibrationHelpersCpp ,MethodCpp ,EndCriteriaCpp ,ConstraintCpp ,WeightsCpp ,FixedCoeffCpp )); } //OneFactorAffineModelCalibrateWorker::~OneFactorAffineModelCalibrateWorker(){ // //} //void OneFactorAffineModelCalibrateWorker::Destroy(){ // //} void ModelG2CalibrateWorker::Execute(){ try{ // convert object IDs into library objects std::vector< boost::shared_ptr > CalibrationHelpersLibObjPtr = ObjectHandler::getLibraryObjectVector(mCalibrationHelpers); // convert object IDs into library objects OH_GET_UNDERLYING_NONCONST(MethodLibObj, mMethod, QuantLibAddin::OptimizationMethod, QuantLib::OptimizationMethod) // convert object IDs into library objects OH_GET_UNDERLYING(EndCriteriaLibObj, mEndCriteria, QuantLibAddin::EndCriteria, QuantLib::EndCriteria) // convert object IDs into library objects OH_GET_UNDERLYING(ConstraintLibObj, mConstraint, QuantLibAddin::Constraint, QuantLib::Constraint) // convert input datatypes to QuantLib datatypes std::vector WeightsLib = QuantLibAddin::convertVector(mWeights); // convert object IDs into library objects OH_GET_REFERENCE(ObjectIDLibObjPtr, mObjectID, QuantLibAddin::G2, QuantLib::G2) // invoke the member function ObjectIDLibObjPtr->calibrate( CalibrationHelpersLibObjPtr , MethodLibObj , EndCriteriaLibObj , ConstraintLibObj , mWeights , mFixedCoeff ); }catch(const std::exception &e){ mError = e.what(); }catch (...){ mError = "unkown error"; } } void ModelG2CalibrateWorker::HandleOKCallback(){ Nan::HandleScope scope; Local argv[2] = { Nan::New(mError).ToLocalChecked(), Nan::Null() }; callback->Call(2, argv); } NAN_METHOD(QuantLibNode::ModelG2Calibrate) { // validate js arguments if (info.Length() == 0 || !info[0]->IsString()) { return Nan::ThrowError("ObjectID is required."); } if (info.Length() == 1 || !info[1]->IsArray()) { return Nan::ThrowError("CalibrationHelpers is required."); } if (info.Length() == 2 || !info[2]->IsString()) { return Nan::ThrowError("Method is required."); } if (info.Length() == 3 || !info[3]->IsString()) { return Nan::ThrowError("EndCriteria is required."); } if (info.Length() == 4 || !info[4]->IsString()) { return Nan::ThrowError("Constraint is required."); } if (info.Length() == 5 || !info[5]->IsArray()) { return Nan::ThrowError("Weights is required."); } if (info.Length() == 6 || !info[6]->IsArray()) { return Nan::ThrowError("FixedCoeff is required."); } // convert js argument to c++ type String::Utf8Value strObjectID(info[0]->ToString()); string ObjectIDCpp(strdup(*strObjectID)); // convert js argument to c++ type std::vectorCalibrationHelpersCpp; Local CalibrationHelpersArray = info[1].As(); for (unsigned int i = 0; i < CalibrationHelpersArray->Length(); i++){ String::Utf8Value strCalibrationHelpers(Nan::Get(CalibrationHelpersArray, i).ToLocalChecked()->ToString()); CalibrationHelpersCpp.push_back(strdup(*strCalibrationHelpers)); } // convert js argument to c++ type String::Utf8Value strMethod(info[2]->ToString()); string MethodCpp(strdup(*strMethod)); // convert js argument to c++ type String::Utf8Value strEndCriteria(info[3]->ToString()); string EndCriteriaCpp(strdup(*strEndCriteria)); // convert js argument to c++ type String::Utf8Value strConstraint(info[4]->ToString()); string ConstraintCpp(strdup(*strConstraint)); // convert js argument to c++ type std::vectorWeightsCpp; Local WeightsArray = info[5].As(); for (unsigned int i = 0; i < WeightsArray->Length(); i++){ WeightsCpp.push_back(Nan::To(Nan::Get(WeightsArray, i).ToLocalChecked()).FromJust()); } // convert js argument to c++ type std::vectorFixedCoeffCpp; Local FixedCoeffArray = info[6].As(); for (unsigned int i = 0; i < FixedCoeffArray->Length(); i++){ FixedCoeffCpp.push_back(Nan::To(Nan::Get(FixedCoeffArray, i).ToLocalChecked()).FromJust()); } // declare callback Nan::Callback *callback = new Nan::Callback(info[7].As()); // launch Async worker Nan::AsyncQueueWorker(new ModelG2CalibrateWorker( callback ,ObjectIDCpp ,CalibrationHelpersCpp ,MethodCpp ,EndCriteriaCpp ,ConstraintCpp ,WeightsCpp ,FixedCoeffCpp )); } //ModelG2CalibrateWorker::~ModelG2CalibrateWorker(){ // //} //void ModelG2CalibrateWorker::Destroy(){ // //}