当前位置: 首页>>代码示例>>C++>>正文


C++ CommonVars类代码示例

本文整理汇总了C++中CommonVars的典型用法代码示例。如果您正苦于以下问题:C++ CommonVars类的具体用法?C++ CommonVars怎么用?C++ CommonVars使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了CommonVars类的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: BOOST_TEST_MESSAGE

void SwapTest::testCachedValue() {

    BOOST_TEST_MESSAGE("Testing vanilla-swap calculation against cached value...");

    CommonVars vars;

    vars.today = Date(17,June,2002);
    Settings::instance().evaluationDate() = vars.today;
    vars.settlement =
        vars.calendar.advance(vars.today,vars.settlementDays,Days);
    vars.termStructure.linkTo(flatRate(vars.settlement,0.05,Actual365Fixed()));

    boost::shared_ptr<VanillaSwap> swap = vars.makeSwap(10, 0.06, 0.001);
    #ifndef QL_USE_INDEXED_COUPON
    Real cachedNPV   = -5.872863313209;
    #else
    Real cachedNPV   = -5.872342992212;
    #endif

    if (std::fabs(swap->NPV()-cachedNPV) > 1.0e-11)
        BOOST_ERROR("failed to reproduce cached swap value:\n"
                    << QL_FIXED << std::setprecision(12)
                    << "    calculated: " << swap->NPV() << "\n"
                    << "    expected:   " << cachedNPV);
}
开发者ID:androidYibo,项目名称:documents,代码行数:25,代码来源:swap.cpp

示例2: BOOST_TEST_MESSAGE

void OvernightIndexedSwapTest::testSeasonedSwaps() {

    BOOST_TEST_MESSAGE("Testing seasoned Eonia-swap calculation...");

    CommonVars vars;

    Period lengths[] = { 1*Years, 2*Years, 5*Years, 10*Years, 20*Years };
    Spread spreads[] = { -0.001, -0.01, 0.0, 0.01, 0.001 };

    Date effectiveDate = Date(2, February, 2009);

    vars.eoniaIndex->addFixing(Date(2,February,2009), 0.0010); // fake fixing values
    vars.eoniaIndex->addFixing(Date(3,February,2009), 0.0011);
    vars.eoniaIndex->addFixing(Date(4,February,2009), 0.0012);
    vars.eoniaIndex->addFixing(Date(5,February,2009), 0.0013);

    for (Size i=0; i<LENGTH(lengths); i++) {
        for (Size j=0; j<LENGTH(spreads); j++) {

            shared_ptr<OvernightIndexedSwap> swap =
                vars.makeSwap(lengths[i],0.0,spreads[j],false,effectiveDate);
            shared_ptr<OvernightIndexedSwap> swap2 =
                vars.makeSwap(lengths[i],0.0,spreads[j],true,effectiveDate);
            if (std::fabs(swap->NPV() - swap2->NPV()) > 1.0e-10) {
                BOOST_ERROR("swap npv is different:\n"
                            << std::setprecision(2)
                            << "    length: " << lengths[i] << " \n"
                            << "    floating spread: "
                            << io::rate(spreads[j]) << "\n"
                            << "    swap value (non telescopic value dates): " << swap->NPV()
                            << "\n    swap value (telescopic value dates    ): " << swap2->NPV());
            }
        }
    }
}
开发者ID:SePTimO7,项目名称:QuantLib,代码行数:35,代码来源:overnightindexedswap.cpp

示例3: BOOST_TEST_MESSAGE

void CapFloorTest::testATMRate() {

    BOOST_TEST_MESSAGE("Testing cap/floor ATM rate...");

    CommonVars vars;

    Integer lengths[] = { 1, 2, 3, 5, 7, 10, 15, 20 };
    Rate strikes[] = { 0., 0.03, 0.04, 0.05, 0.06, 0.07 };
    Volatility vols[] = { 0.01, 0.05, 0.10, 0.15, 0.20 };

    Date startDate = vars.termStructure->referenceDate();

    for (Size i=0; i<LENGTH(lengths); i++) {
        Leg leg = vars.makeLeg(startDate,lengths[i]);
        Date maturity = vars.calendar.advance(startDate,lengths[i],Years,
                                  vars.convention);
        Schedule schedule(startDate,maturity,
                          Period(vars.frequency),vars.calendar,
                          vars.convention,vars.convention,
                          DateGeneration::Forward,false);

        for (Size j=0; j<LENGTH(strikes); j++) {
            for (Size k=0; k<LENGTH(vols); k++) {
                boost::shared_ptr<CapFloor> cap =
                    vars.makeCapFloor(CapFloor::Cap, leg, strikes[j],vols[k]);
                boost::shared_ptr<CapFloor> floor =
                    vars.makeCapFloor(CapFloor::Floor, leg, strikes[j],vols[k]);
                Rate capATMRate = cap->atmRate(**vars.termStructure);
                Rate floorATMRate = floor->atmRate(**vars.termStructure);
                if (!checkAbsError(floorATMRate, capATMRate, 1.0e-10))
                    BOOST_FAIL(
                      "Cap ATM Rate and floor ATM Rate should be equal :\n"
                      << "   length:        " << lengths[i] << " years\n"
                      << "   volatility:    " << io::volatility(vols[k]) << "\n"
                      << "   strike:        " << io::rate(strikes[j]) << "\n"
                      << "   cap ATM rate:  " << capATMRate << "\n"
                      << "   floor ATM rate:" << floorATMRate << "\n"
                      << "   relative Error:"
                      << relativeError(capATMRate, floorATMRate,
                                       capATMRate)*100 << "%" );
                VanillaSwap swap(VanillaSwap::Payer, vars.nominals[0],
                                 schedule, floorATMRate,
                                 vars.index->dayCounter(),
                                 schedule, vars.index, 0.0,
                                 vars.index->dayCounter());
                swap.setPricingEngine(boost::shared_ptr<PricingEngine>(
                              new DiscountingSwapEngine(vars.termStructure)));
                Real swapNPV = swap.NPV();
                if (!checkAbsError(swapNPV, 0, 1.0e-10))
                    BOOST_FAIL(
                      "the NPV of a Swap struck at ATM rate "
                      "should be equal to 0:\n"
                      << "   length:        " << lengths[i] << " years\n"
                      << "   volatility:    " << io::volatility(vols[k]) << "\n"
                      << "   ATM rate:      " << io::rate(floorATMRate) << "\n"
                      << "   swap NPV:      " << swapNPV);
        }
      }
    }
}
开发者ID:21hub,项目名称:QuantLib,代码行数:60,代码来源:capfloor.cpp

示例4: BOOST_TEST_MESSAGE

void OptionletStripperTest::testFlatTermVolatilityStripping1() {

    BOOST_TEST_MESSAGE(
        "Testing forward/forward vol stripping from flat term vol "
        "surface using OptionletStripper1 class...");

    CommonVars vars;
    Settings::instance().evaluationDate() = Date(28, October, 2013);

    vars.setFlatTermVolSurface();

    shared_ptr<IborIndex> iborIndex(new Euribor6M(vars.yieldTermStructure));

    boost::shared_ptr<OptionletStripper> optionletStripper1(new
        OptionletStripper1(vars.flatTermVolSurface,
                           iborIndex,
                           Null<Rate>(),
                           vars.accuracy));

    boost::shared_ptr<StrippedOptionletAdapter> strippedOptionletAdapter(new
        StrippedOptionletAdapter(optionletStripper1));

    Handle<OptionletVolatilityStructure> vol(strippedOptionletAdapter);

    vol->enableExtrapolation();

    boost::shared_ptr<BlackCapFloorEngine> strippedVolEngine(new
        BlackCapFloorEngine(vars.yieldTermStructure,
                            vol));

    boost::shared_ptr<CapFloor> cap;
    for (Size tenorIndex=0; tenorIndex<vars.optionTenors.size(); ++tenorIndex) {
        for (Size strikeIndex=0; strikeIndex<vars.strikes.size(); ++strikeIndex) {
            cap = MakeCapFloor(CapFloor::Cap,
                               vars.optionTenors[tenorIndex],
                               iborIndex,
                               vars.strikes[strikeIndex],
                               0*Days)
                  .withPricingEngine(strippedVolEngine);

            Real priceFromStrippedVolatility = cap->NPV();

            boost::shared_ptr<PricingEngine> blackCapFloorEngineConstantVolatility(new
                BlackCapFloorEngine(vars.yieldTermStructure,
                                    vars.termV[tenorIndex][strikeIndex]));

            cap->setPricingEngine(blackCapFloorEngineConstantVolatility);
            Real priceFromConstantVolatility = cap->NPV();

            Real error = std::fabs(priceFromStrippedVolatility - priceFromConstantVolatility);
            if (error>vars.tolerance)
                BOOST_FAIL("\noption tenor:       " << vars.optionTenors[tenorIndex] <<
                           "\nstrike:             " << io::rate(vars.strikes[strikeIndex]) <<
                           "\nstripped vol price: " << io::rate(priceFromStrippedVolatility) <<
                           "\nconstant vol price: " << io::rate(priceFromConstantVolatility) <<
                           "\nerror:              " << io::rate(error) <<
                           "\ntolerance:          " << io::rate(vars.tolerance));
            }
    }
}
开发者ID:scitao,项目名称:quantlib,代码行数:60,代码来源:optionletstripper.cpp

示例5: BOOST_TEST_MESSAGE

void OvernightIndexedSwapTest::testFairSpread() {

    BOOST_TEST_MESSAGE("Testing Eonia-swap calculation of "
                       "fair floating spread...");

    CommonVars vars;

    Period lengths[] = { 1*Years, 2*Years, 5*Years, 10*Years, 20*Years };
    Rate rates[] = { 0.04, 0.05, 0.06, 0.07 };

    for (Size i=0; i<LENGTH(lengths); i++) {
        for (Size j=0; j<LENGTH(rates); j++) {

            shared_ptr<OvernightIndexedSwap> swap =
                vars.makeSwap(lengths[i], rates[j], 0.0);
            Spread fairSpread = swap->fairSpread();
            swap = vars.makeSwap(lengths[i], rates[j], fairSpread);

            if (std::fabs(swap->NPV()) > 1.0e-10) {
                BOOST_ERROR("\nrecalculating with implied spread:" <<
                            std::setprecision(2) <<
                            "\n     length: " << lengths[i] <<
                            "\n fixed rate: " << io::rate(rates[j]) <<
                            "\nfair spread: " << io::rate(fairSpread) <<
                            "\n swap value: " << swap->NPV());
            }
        }
    }

}
开发者ID:Bernd8,项目名称:quantlib,代码行数:30,代码来源:overnightindexedswap.cpp

示例6: BOOST_MESSAGE

void SwaptionTest::testCachedValue() {

    BOOST_MESSAGE("Testing swaption value against cached value...");

    CommonVars vars;

    vars.today = Date(13, March, 2002);
    vars.settlement = Date(15, March, 2002);
    Settings::instance().evaluationDate() = vars.today;
    vars.termStructure.linkTo(flatRate(vars.settlement, 0.05, Actual365Fixed()));
    Date exerciseDate = vars.calendar.advance(vars.settlement, 5*Years);
    Date startDate = vars.calendar.advance(exerciseDate,
                                           vars.settlementDays, Days);
    boost::shared_ptr<VanillaSwap> swap =
        MakeVanillaSwap(10*Years, vars.index, 0.06)
        .withEffectiveDate(startDate);

    boost::shared_ptr<Swaption> swaption =
        vars.makeSwaption(swap, exerciseDate, 0.20);
    #ifndef QL_USE_INDEXED_COUPON
    Real cachedNPV = 0.036418158579;
    #else
    Real cachedNPV = 0.036421429684;
    #endif

    // FLOATING_POINT_EXCEPTION
    if (std::fabs(swaption->NPV()-cachedNPV) > 1.0e-12)
        BOOST_ERROR("failed to reproduce cached swaption value:\n" <<
                    QL_FIXED << std::setprecision(12) <<
                    "\ncalculated: " << swaption->NPV() <<
                    "\nexpected:   " << cachedNPV);
}
开发者ID:mahantaratan,项目名称:Quantlib,代码行数:32,代码来源:swaption.cpp

示例7: BOOST_TEST_MESSAGE

void SwaptionVolatilityMatrixTest::testSwaptionVolMatrixCoherence() {

    BOOST_TEST_MESSAGE("Testing swaption volatility matrix...");

    CommonVars vars;

    boost::shared_ptr<SwaptionVolatilityMatrix> vol;
    std::string description;

    //floating reference date, floating market data
    description = "floating reference date, floating market data";
    vol = boost::shared_ptr<SwaptionVolatilityMatrix>(new
        SwaptionVolatilityMatrix(vars.conventions.calendar,
                                 vars.conventions.optionBdc,
                                 vars.atm.tenors.options,
                                 vars.atm.tenors.swaps,
                                 vars.atm.volsHandle,
                                 vars.conventions.dayCounter));
    vars.makeCoherenceTest(description, vol);

    //fixed reference date, floating market data
    description = "fixed reference date, floating market data";
    vol = boost::shared_ptr<SwaptionVolatilityMatrix>(new
        SwaptionVolatilityMatrix(Settings::instance().evaluationDate(),
                                 vars.conventions.calendar,
                                 vars.conventions.optionBdc,
                                 vars.atm.tenors.options,
                                 vars.atm.tenors.swaps,
                                 vars.atm.volsHandle,
                                 vars.conventions.dayCounter));
    vars.makeCoherenceTest(description, vol);

    // floating reference date, fixed market data
    description = "floating reference date, fixed market data";
    vol = boost::shared_ptr<SwaptionVolatilityMatrix>(new
        SwaptionVolatilityMatrix(vars.conventions.calendar,
                                 vars.conventions.optionBdc,
                                 vars.atm.tenors.options,
                                 vars.atm.tenors.swaps,
                                 vars.atm.volsHandle,
                                 vars.conventions.dayCounter));
    vars.makeCoherenceTest(description, vol);

    // fixed reference date, fixed market data
    description = "fixed reference date, fixed market data";
    vol = boost::shared_ptr<SwaptionVolatilityMatrix>(new
        SwaptionVolatilityMatrix(Settings::instance().evaluationDate(),
                                 vars.conventions.calendar,
                                 vars.conventions.optionBdc,
                                 vars.atm.tenors.options,
                                 vars.atm.tenors.swaps,
                                 vars.atm.volsHandle,
                                 vars.conventions.dayCounter));
    vars.makeCoherenceTest(description, vol);
}
开发者ID:21hub,项目名称:QuantLib,代码行数:55,代码来源:swaptionvolatilitymatrix.cpp

示例8: in_arrear_floorlet

double in_arrear_floorlet(const Date& todaysDate_,
	double start,
	double length,
	Rate spot_,
	Rate strike,
	Volatility volatility
	)
{
	CommonVars vars;

	try{
		vars.makeIndex(todaysDate_,spot_);
	
		Leg leg = vars.makeLeg(start,length);

		boost::shared_ptr<Instrument> floor = vars.makeCapFloor(CapFloor::Floor, leg, strike, volatility);
	
		return floor->NPV();
	}
	catch (std::exception& e) {
		std::cerr << e.what() << std::endl;
		return 1;
	}
}
开发者ID:calvin456,项目名称:intro_derivative_pricing,代码行数:24,代码来源:caplet_in_arrear.cpp

示例9: BOOST_MESSAGE

void BermudanSwaptionTest::testCachedValues() {

    BOOST_MESSAGE("Testing Bermudan swaption against cached values...");

    CommonVars vars;

    vars.today = Date(15, February, 2002);

    Settings::instance().evaluationDate() = vars.today;

    vars.settlement = Date(19, February, 2002);
    // flat yield term structure impling 1x5 swap at 5%
    vars.termStructure.linkTo(flatRate(vars.settlement,
                                          0.04875825,
                                          Actual365Fixed()));

    Rate atmRate = vars.makeSwap(0.0)->fairRate();

    boost::shared_ptr<VanillaSwap> itmSwap = vars.makeSwap(0.8*atmRate);
    boost::shared_ptr<VanillaSwap> atmSwap = vars.makeSwap(atmRate);
    boost::shared_ptr<VanillaSwap> otmSwap = vars.makeSwap(1.2*atmRate);

    Real a = 0.048696, sigma = 0.0058904;
    boost::shared_ptr<ShortRateModel> model(new HullWhite(vars.termStructure,
                                                          a, sigma));
    std::vector<Date> exerciseDates;
    const Leg& leg = atmSwap->fixedLeg();
    for (Size i=0; i<leg.size(); i++) {
        boost::shared_ptr<Coupon> coupon =
            boost::dynamic_pointer_cast<Coupon>(leg[i]);
        exerciseDates.push_back(coupon->accrualStartDate());
    }
    boost::shared_ptr<Exercise> exercise(new BermudanExercise(exerciseDates));

    boost::shared_ptr<PricingEngine> engine(new TreeSwaptionEngine(model, 50));

    #if defined(QL_USE_INDEXED_COUPON)
    Real itmValue = 42.2413, atmValue = 12.8789, otmValue = 2.4759;
    #else
    Real itmValue = 42.2470, atmValue = 12.8826, otmValue = 2.4769;
    #endif

    Real tolerance = 1.0e-4;

    Swaption swaption(itmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-itmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached in-the-money swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << itmValue);
    swaption = Swaption(atmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-atmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached at-the-money swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << atmValue);
    swaption = Swaption(otmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-otmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached out-of-the-money "
                    << "swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << otmValue);

    for (Size j=0; j<exerciseDates.size(); j++)
        exerciseDates[j] = vars.calendar.adjust(exerciseDates[j]-10);
    exercise =
        boost::shared_ptr<Exercise>(new BermudanExercise(exerciseDates));

    #if defined(QL_USE_INDEXED_COUPON)
    itmValue = 42.1917; atmValue = 12.7788; otmValue = 2.4388;
    #else
    itmValue = 42.1974; atmValue = 12.7825; otmValue = 2.4399;
    #endif

    swaption = Swaption(itmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-itmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached in-the-money swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << itmValue);
    swaption = Swaption(atmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-atmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached at-the-money swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << atmValue);
    swaption = Swaption(otmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-otmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached out-of-the-money "
                    << "swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << otmValue);
}
开发者ID:lab616,项目名称:third_party,代码行数:95,代码来源:bermudanswaption.cpp

示例10: BOOST_MESSAGE

void InflationCapFlooredCouponTest::testInstrumentEquality() {

    BOOST_MESSAGE("Testing inflation capped/floored coupon against inflation capfloor instrument...");

    CommonVars vars;

    Integer lengths[] = { 1, 2, 3, 5, 7, 10, 15, 20 };
    // vol is low ...
    Rate strikes[] = { 0.01, 0.025, 0.029, 0.03, 0.031, 0.035, 0.07 };
    // yoy inflation vol is generally very low
    Volatility vols[] = { 0.001, 0.005, 0.010, 0.015, 0.020 };

    // this is model independent
    // capped coupon = fwd - cap, and fwd = swap(0)
    // floored coupon = fwd + floor
    for (Size whichPricer = 0; whichPricer < 3; whichPricer++) {
        for (Size i=0; i<LENGTH(lengths); i++) {
            for (Size j=0; j<LENGTH(strikes); j++) {
                for (Size k=0; k<LENGTH(vols); k++) {

                    Leg leg = vars.makeYoYLeg(vars.evaluationDate,lengths[i]);

                    boost::shared_ptr<Instrument> cap
                    = vars.makeYoYCapFloor(YoYInflationCapFloor::Cap,
                                           leg, strikes[j], vols[k], whichPricer);

                    boost::shared_ptr<Instrument> floor
                    = vars.makeYoYCapFloor(YoYInflationCapFloor::Floor,
                                           leg, strikes[j], vols[k], whichPricer);

                    Date from = vars.nominalTS->referenceDate();
                    Date to = from+lengths[i]*Years;
                    Schedule yoySchedule = MakeSchedule().from(from).to(to)
                    .withTenor(1*Years)
                    .withCalendar(UnitedKingdom())
                    .withConvention(Unadjusted)
                    .backwards()
                    ;

                    YearOnYearInflationSwap swap(YearOnYearInflationSwap::Payer,
                                                    1000000.0,
                                                    yoySchedule,//fixed schedule, but same as yoy
                                                    0.0,//strikes[j],
                                                    vars.dc,
                                                    yoySchedule,
                                                    vars.iir,
                                                    vars.observationLag,
                                                    0.0,        //spread on index
                                                    vars.dc,
                                                    UnitedKingdom());

                    Handle<YieldTermStructure> hTS(vars.nominalTS);
                    boost::shared_ptr<PricingEngine> sppe(new DiscountingSwapEngine(hTS));
                    swap.setPricingEngine(sppe);

                    Leg leg2 = vars.makeYoYCapFlooredLeg(whichPricer, from,
                                                         lengths[i],
                                                         std::vector<Rate>(lengths[i],strikes[j]),//cap
                                                         std::vector<Rate>(),//floor
                                                         vols[k],
                                                         1.0,   // gearing
                                                         0.0);// spread

                    Leg leg3 = vars.makeYoYCapFlooredLeg(whichPricer, from,
                                                         lengths[i],
                                                         std::vector<Rate>(),// cap
                                                         std::vector<Rate>(lengths[i],strikes[j]),//floor
                                                         vols[k],
                                                         1.0,   // gearing
                                                         0.0);// spread

                    // N.B. nominals are 10e6
                    Real capped = CashFlows::npv(leg2,(**vars.nominalTS),false);
                    if ( fabs(capped - (swap.NPV() - cap->NPV())) > 1.0e-6) {
                        BOOST_FAIL(
                                   "capped coupon != swap(0) - cap:\n"
                                   << "    length:      " << lengths[i] << " years\n"
                                   << "    volatility:  " << io::volatility(vols[k]) << "\n"
                                   << "    strike:      " << io::rate(strikes[j]) << "\n"
                                   << "    cap value:   " << cap->NPV() << "\n"
                                   << "    swap value:  " << swap.NPV() << "\n"
                                   << "   capped coupon " << capped);
                    }


                    // N.B. nominals are 10e6
                    Real floored = CashFlows::npv(leg3,(**vars.nominalTS),false);
                    if ( fabs(floored - (swap.NPV() + floor->NPV())) > 1.0e-6) {
                        BOOST_FAIL(
                                   "floored coupon != swap(0) + floor :\n"
                                   << "    length:      " << lengths[i] << " years\n"
                                   << "    volatility:  " << io::volatility(vols[k]) << "\n"
                                   << "    strike:      " << io::rate(strikes[j]) << "\n"
                                   << "    floor value: " << floor->NPV() << "\n"
                                   << "    swap value:  " << swap.NPV() << "\n"
                                   << "  floored coupon " << floored);
                    }

                }
            }
//.........这里部分代码省略.........
开发者ID:mahantaratan,项目名称:Quantlib,代码行数:101,代码来源:inflationcapflooredcoupon.cpp


注:本文中的CommonVars类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。