diff --git a/ChangeLog.txt b/ChangeLog.txt index cf233da4f..f5ddee7b6 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,159 +1,82 @@ -commit 1ab2e71de4384e1a431dbcaa0226ec216320dc9f -Author: Andrea Maggiulli -Date: Wed, 5 Mar 2014 18:54:43 +0100 - - Enable new Pricing Engines - -commit c717f91876d97d0b4dbad2e3cf2573b510ce89d2 -Author: Andrea Maggiulli -Date: Wed, 5 Mar 2014 17:55:46 +0100 - - New vanilla pricing engines :AnalyticDividendEuropeanEngine,FDDividendAmericanEngine,FDDividendEuropeanEngine ...with tests. - -commit 40586b45c6629b3009435a71b906adbd307755b2 -Merge: b468bb4 1dafb00 -Author: Andrea Maggiulli -Date: Mon, 2 Dec 2013 03:29:18 -0800 - - Merge pull request #4 from qusma/Ver-1.3.0.0 - - Moved Easter Monday offsets to a field, greatly improving performance of the easterMonday() functions. - Thanks qusma. - -commit 1dafb003cc494738a830f2825723c581f8578f89 -Author: qusma -Date: Mon, 2 Dec 2013 01:43:14 +0200 - - Moved Easter Monday offsets to a field, greatly improving performance of the easterMonday() functions. - -commit b468bb41a285d60e4190e8e2e283f212d360050e -Author: a.maggiulli -Date: Fri, 29 Nov 2013 17:19:11 +0100 - - ZeroCouponInflationSwap update. - -commit 3cf271c1f576aa1c2953eec4f95cf9c54b8b7e0b -Author: a.maggiulli -Date: Tue, 26 Nov 2013 16:44:37 +0100 - - formatting - -commit 3c8ee280a214b3066859dfacbcd7f3949372223d -Author: a.maggiulli -Date: Tue, 26 Nov 2013 16:38:51 +0100 - - New instruments : Italian BTP (Buoni Poliennali del Tesoro), Italian CCTEU (Certificato di credito del tesoro) - -commit 35e1d42bd3b243d4be7100f59f9e71ad1fcfff20 -Author: a.maggiulli -Date: Tue, 26 Nov 2013 16:35:36 +0100 - - Fix Calendar comparison bug - -commit d9b263287280c9c10c5b57b152bb45f06ef54bbf -Author: a.maggiulli -Date: Wed, 20 Nov 2013 17:55:22 +0100 - - old code removed - -commit a76410c70fe25d0119dd122ff5e6b35020b55cb2 -Author: a.maggiulli -Date: Wed, 20 Nov 2013 16:43:00 +0100 - - Termstructure update, start credit implementation, various fixes - -commit d67e5938d5d74684c277c9454d92ab48a653e85e -Author: a.maggiulli -Date: Wed, 6 Nov 2013 11:39:42 +0100 - - Update some base class : Event , CashFlow , Settings - -commit fa47b02aaa93d9acd44e5b0edff0be5a401baaa3 -Author: a.maggiulli -Date: Tue, 5 Nov 2013 14:17:28 +0100 - - Remove IndexHistoryCleaner from T_AssetSwap tests ( it make fail tests when run all together ) - -commit 466967174cb3ac05b7287337e24f6bc424698b9a -Author: a.maggiulli -Date: Mon, 4 Nov 2013 15:45:51 +0100 - - New Instrument : AssetSwap ( with tests ) - -commit fdf772f12997ae71bd0004a3281f1dacd32fa789 -Author: a.maggiulli -Date: Thu, 31 Oct 2013 14:18:57 +0100 - - Swap Update + cleanup commented code - -commit 81a0a11c2444eb78800acfeba259c9beee213c66 -Author: a.maggiulli -Date: Thu, 31 Oct 2013 12:36:38 +0100 - - Bond Update - -commit d2950f7fe69916f9b9c84021ce1503326fd03866 -Author: a.maggiulli -Date: Wed, 30 Oct 2013 17:21:12 +0100 - - Cashflows functions update - -commit 884a155a1338ced42c7cd22103048dcdbb2905a4 -Author: a.maggiulli -Date: Fri, 30 Aug 2013 14:37:37 +0200 - - Fix compilation Warnings - -commit 64cdeca5b0d465d1c9a198abe218ea500a5b5b96 -Author: a.maggiulli -Date: Fri, 30 Aug 2013 11:30:30 +0200 - - Fix compilation Warnings ( Observer interface ) - -commit 55071b5b1fa4d8dd36c82a2900af3ac340ada996 -Author: a.maggiulli -Date: Fri, 30 Aug 2013 11:14:11 +0200 - - Fix compilation Warnings - -commit 811b627162da5a4a38c9e9f1ba4467e2c47efff3 -Author: a.maggiulli -Date: Thu, 29 Aug 2013 16:15:44 +0200 - - Fix compilation Warnings - -commit 2a497c4f06405566c0e18215dd60dcb707603428 -Author: a.maggiulli -Date: Thu, 29 Aug 2013 14:52:40 +0200 - - Fix compilation Warnings - -commit 60afe4f5c5457075e46f8b72450be987adda2ca9 -Author: a.maggiulli -Date: Thu, 29 Aug 2013 14:49:55 +0200 - - Add Akima Interpolation - -commit c661fbfa8255711fbd299058b7b56c646f0a1a29 -Author: a.maggiulli -Date: Thu, 29 Aug 2013 14:46:41 +0200 - - Fix several compiler warnings - -commit 9bcde34582d95dc4787069a49e903bf8fde3b3ff -Author: a.maggiulli -Date: Sun, 25 Aug 2013 19:07:07 +0200 - - Update holidays for 2013. - -commit 63bc1992dfc5d5c8b53fb16dc10df100be1102c1 -Author: a.maggiulli -Date: Sun, 25 Aug 2013 19:06:19 +0200 - - Update Version info - -commit 063fdcabc6c8cf85a56497567f8598c9a93ce3f7 -Author: a.maggiulli -Date: Sun, 25 Aug 2013 17:58:03 +0200 - - Update QLNet information. \ No newline at end of file +Commits on Aug 20, 2015 + @amaggiulli amaggiulli Update version 0f35442 + @amaggiulli amaggiulli Update version bc6f14f +Commits on Aug 21, 2015 + @amaggiulli amaggiulli Merge pull request #53 from amaggiulli/master + +Fix Vanilla Swap Pricer - thanks OfirMarom dc3892e +Commits on Aug 24, 2015 + @amaggiulli amaggiulli Merge pull request #56 from amaggiulli/master + +Merge fix on branch 1.5 e78dc6f + @amaggiulli amaggiulli Update Asia Currencies 5495847 + @amaggiulli amaggiulli Add Shibor Index a2af90a + @amaggiulli amaggiulli Added China Inter-Bank calendar 65b75e6 + @amaggiulli amaggiulli Added half-month modified following convention 4482e3b + @amaggiulli amaggiulli Added a few more historical closings for NYSE. bed2e9f + @amaggiulli amaggiulli Updated the Hong Kong calendar for 2014-2015. 3222f8b + @amaggiulli amaggiulli Updated India calendar for 2014. 710231d + @amaggiulli amaggiulli Updated Indonesia calendar for 2014. 12588f0 + @amaggiulli amaggiulli Updated Singapore calendar for 2014. 15eb039 + @amaggiulli amaggiulli Updated SouthKorea calendar for 2014. 701dbd5 + @amaggiulli amaggiulli Updated Taiwan,Turkey calendars for 2014. e7681bd + @amaggiulli amaggiulli Added Ukraine calendar f33ea96 +Commits on Aug 25, 2015 + @amaggiulli amaggiulli Added ECB reserve maintenance dates with tests. ef0b0bc + @amaggiulli amaggiulli Add FedFunds index. 940bf03 + @amaggiulli amaggiulli Added Sonia (Sterling Overnight Index Average) index. 8449a21 +Commits on Aug 26, 2015 + @amaggiulli amaggiulli Fix Barone-Adesi and Whaley approximation for r=0.0 3807747 + @amaggiulli amaggiulli fixed behavior of the Bjerksund Stensland engine for very small d0ec0dd +Commits on Aug 27, 2015 + @amaggiulli amaggiulli Bond : added cashflow lists Stable Sort 56464f9 +Commits on Aug 30, 2015 + @amaggiulli amaggiulli AmortizingFixedRateBond minor fix and a new test. 934024e +Commits on Sep 04, 2015 + @amaggiulli amaggiulli Fix Factorial bug - tabulated length 814096d +Commits on Sep 07, 2015 + @amaggiulli amaggiulli QL_EPSILON refactoring to upper case. 986e967 + @amaggiulli amaggiulli Added modified Bessel functions with Tests. 9a77fa9 + @amaggiulli amaggiulli Update QLNet project URL. 10ed135 +Commits on Sep 09, 2015 + @igitur igitur Fix indentation of Schedule.cs c0e7d68 + @igitur igitur Extend schedule constructor in line with QuantLib 4620d41 + @igitur igitur avoided degenerate schedules; ignored EndOfMonth for tenor below 1M 1cef439 + @igitur igitur Add degenerate schedule check 046cfa8 +Commits on Sep 16, 2015 + @amaggiulli amaggiulli Move class TqrEigenDecomposition to right folder 8089d5c + @amaggiulli amaggiulli Move class TqrEigenDecomposition to right folder a824265 +Commits on Sep 28, 2015 + @amaggiulli amaggiulli Added SABRInterpolation with tests ( also fix a bug in Constraint.cs ) 6b3dd1e +Commits on Oct 09, 2015 + @igitur igitur Check for null ccc91df + @igitur igitur Reformat file 10e2662 + @igitur igitur Merge pull request #57 from igitur/extend-schedule-constructor e379aa3 + @igitur igitur Add new Schedule tests e3a6f1c + @igitur igitur Port fix of lballabio/quantlib@054efcb f465920 +Commits on Oct 12, 2015 + @igitur igitur Fix default isRegular value 9a9050b + @igitur igitur Merge pull request #58 from igitur/add_schedule_tests 67af2bd + @igitur igitur Reformat file a61727b + @igitur igitur Add bond test for South African R2048 which requires Schedule from cu e3a44b2 + @igitur igitur Merge pull request #59 from igitur/add-R2048-ZA-bond-test ff887fa + @amaggiulli amaggiulli Fix compilation warning e39048d +Commits on Oct 13, 2015 + @amaggiulli amaggiulli Fix MatrixUtilities ( qrDecomposition , qrSolve ) with tests. 33b452d + @amaggiulli amaggiulli Added Kernel Interpolation with tests c608668 + @amaggiulli amaggiulli Added KernelInterpolation2D with test. 1839ad4 +Commits on Oct 14, 2015 + @amaggiulli amaggiulli Added BicubicSpline Interpolation with test. 34d645c + @amaggiulli amaggiulli Test Bicubic splines update. 7913b16 + @amaggiulli amaggiulli Added Richardson Extrapolation with test. 351f115 + @amaggiulli amaggiulli test sabr single cases 48797ef +Commits on Nov 16, 2015 + @amaggiulli amaggiulli Fixed MCDiscreteAveragingAsianEngine ctor , fixed testSpecializedBond 154f733 + @amaggiulli amaggiulli Fixed Bond ctor wrong check. cea55f2 + @amaggiulli amaggiulli Fixed SmileSection,SabrSmileSection,FlatSmileSection, ctor's 22fe490 + @amaggiulli amaggiulli Cleanup LfmHullWhiteParameterization integratedCovariance function. 02cec14 +Commits on Nov 17, 2015 + @amaggiulli amaggiulli Fixed india calendar bug ( cov 33751 ). b925e56 + @amaggiulli amaggiulli Fixed dead code in SouthKorea Calendar( cov 32789 ) d0922da + @amaggiulli amaggiulli Fix Bond ctor ( cov 32792 ) 92bc4c9 + @amaggiulli amaggiulli Avoid possible division by zero ( cov 32791 ) 846a25a \ No newline at end of file diff --git a/QLNet/Cashflow.cs b/QLNet/Cashflow.cs index 55af9bd68..ea82db953 100644 Binary files a/QLNet/Cashflow.cs and b/QLNet/Cashflow.cs differ diff --git a/QLNet/Cashflows/CPICoupon.cs b/QLNet/Cashflows/CPICoupon.cs index a06281357..71727655e 100644 --- a/QLNet/Cashflows/CPICoupon.cs +++ b/QLNet/Cashflows/CPICoupon.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -117,7 +117,7 @@ public CPICoupon(double baseCPI, // user provided, could be arbitrary baseCPI_ = baseCPI; fixedRate_ = fixedRate; spread_ = spread; - observationInterpolation_ = observationInterpolation; + observationInterpolation_ = observationInterpolation; Utils.QL_REQUIRE( Math.Abs( baseCPI_ ) > 1e-16, () => "|baseCPI_| < 1e-16, future divide-by-zero problem" ); } @@ -255,7 +255,7 @@ public CPILeg(Schedule schedule, baseCPI_ = baseCPI; observationLag_ = observationLag; paymentDayCounter_ = new Thirty360(); - paymentAdjustment_ = BusinessDayConvention.ModifiedFollowing; + paymentAdjustment_ = BusinessDayConvention.ModifiedFollowing; paymentCalendar_ = schedule.calendar(); fixingDays_ = new List() { 0 }; observationInterpolation_ = InterpolationType.AsIndex; @@ -282,17 +282,17 @@ public override List value() { refStart = start = schedule_.date(i); refEnd = end = schedule_.date(i + 1); - Date paymentDate = paymentCalendar_.adjust(end, paymentAdjustment_); - - Date exCouponDate = null; - if (exCouponPeriod_ != null) - { - exCouponDate = exCouponCalendar_.advance(paymentDate, - -exCouponPeriod_, - exCouponAdjustment_, - exCouponEndOfMonth_); - } - + Date paymentDate = paymentCalendar_.adjust(end, paymentAdjustment_); + + Date exCouponDate = null; + if (exCouponPeriod_ != null) + { + exCouponDate = exCouponCalendar_.advance(paymentDate, + -exCouponPeriod_, + exCouponAdjustment_, + exCouponEndOfMonth_); + } + if (i == 0 && !schedule_.isRegular(i + 1)) { BusinessDayConvention bdc = schedule_.businessDayConvention(); diff --git a/QLNet/Cashflows/CPICouponPricer.cs b/QLNet/Cashflows/CPICouponPricer.cs index 04a54daf7..608e16f3b 100644 --- a/QLNet/Cashflows/CPICouponPricer.cs +++ b/QLNet/Cashflows/CPICouponPricer.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011 , 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -45,7 +45,7 @@ public virtual Handle capletVolatility() } public virtual void setCapletVolatility(Handle capletVol) - { + { Utils.QL_REQUIRE( !capletVol.empty(), () => "empty capletVol handle" ); capletVol_ = capletVol; capletVol_.registerWith(update); @@ -130,7 +130,7 @@ protected virtual double optionletPrice(Option.Type optionType, double effStrike } else { - // not yet determined, use Black/DD1/Bachelier/whatever from Impl + // not yet determined, use Black/DD1/Bachelier/whatever from Impl Utils.QL_REQUIRE( !capletVolatility().empty(), () => "missing optionlet volatility" ); double stdDev = Math.Sqrt(capletVolatility().link.totalVariance(fixingDate, effStrike)); double fixing = optionletPriceImp(optionType, diff --git a/QLNet/Cashflows/CappedFlooredCoupon.cs b/QLNet/Cashflows/CappedFlooredCoupon.cs index ea5bb4c47..8c407f781 100644 --- a/QLNet/Cashflows/CappedFlooredCoupon.cs +++ b/QLNet/Cashflows/CappedFlooredCoupon.cs @@ -3,7 +3,7 @@ Copyright (C) 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/CappedFlooredYoYInflationCoupon.cs b/QLNet/Cashflows/CappedFlooredYoYInflationCoupon.cs index ae7bbc63d..a1d7227bc 100644 --- a/QLNet/Cashflows/CappedFlooredYoYInflationCoupon.cs +++ b/QLNet/Cashflows/CappedFlooredYoYInflationCoupon.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -121,11 +121,11 @@ public override double rate() if(isFloored_ || isCapped_) { if (underlying_ != null) - { + { Utils.QL_REQUIRE( underlying_.pricer() != null, () => "pricer not set" ); } else - { + { Utils.QL_REQUIRE( pricer_ != null, () => "pricer not set" ); } } diff --git a/QLNet/Cashflows/CashFlows.cs b/QLNet/Cashflows/CashFlows.cs index 84df68aa7..362b24ec4 100644 --- a/QLNet/Cashflows/CashFlows.cs +++ b/QLNet/Cashflows/CashFlows.cs @@ -2,7 +2,7 @@ Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -53,7 +53,7 @@ private static double aggregateRate(Leg leg,CashFlow cf) if (firstCouponFound) { Utils.QL_REQUIRE(nominal == cp.nominal() && - accrualPeriod == cp.accrualPeriod() && + accrualPeriod == cp.accrualPeriod() && dc == cp.dayCounter(), () => "cannot aggregate two different coupons on " + paymentDate); @@ -67,8 +67,8 @@ private static double aggregateRate(Leg leg,CashFlow cf) } result += cp.rate(); } - } - + } + Utils.QL_REQUIRE( firstCouponFound, () => "no coupon paid at cashflow date " + paymentDate ); return result; } @@ -96,10 +96,10 @@ public static double simpleDuration(Leg leg,InterestRate y, bool includeSettleme if (leg[i].hasOccurred(settlementDate, includeSettlementDateFlows)) continue; - double c = leg[i].amount(); - if (leg[i].tradingExCoupon(settlementDate)) - { - c = 0.0; + double c = leg[i].amount(); + if (leg[i].tradingExCoupon(settlementDate)) + { + c = 0.0; } Date couponDate = leg[i].date(); Coupon coupon = leg[i] as Coupon; @@ -161,10 +161,10 @@ public static double modifiedDuration(Leg leg,InterestRate y, bool includeSettle if (leg[i].hasOccurred(settlementDate, includeSettlementDateFlows)) continue; - double c = leg[i].amount(); - if (leg[i].tradingExCoupon(settlementDate)) - { - c = 0.0; + double c = leg[i].amount(); + if (leg[i].tradingExCoupon(settlementDate)) + { + c = 0.0; } Date couponDate = leg[i].date(); Coupon coupon = leg[i] as Coupon; @@ -223,7 +223,7 @@ public static double modifiedDuration(Leg leg,InterestRate y, bool includeSettle public static double macaulayDuration(Leg leg,InterestRate y, bool includeSettlementDateFlows, Date settlementDate, Date npvDate) - { + { Utils.QL_REQUIRE( y.compounding() == Compounding.Compounded, () => "compounded rate required" ); return (1.0+y.rate()/(int)y.frequency()) * @@ -286,8 +286,8 @@ private void checkSign() int lastSign = Math.Sign(-npv_), signChanges = 0; for (int i = 0; i < leg_.Count; ++i) - { - if (!leg_[i].hasOccurred(settlementDate_, includeSettlementDateFlows_) && + { + if (!leg_[i].hasOccurred(settlementDate_, includeSettlementDateFlows_) && !leg_[i].tradingExCoupon(settlementDate_)) { int thisSign = Math.Sign(leg_[i].amount()); @@ -297,7 +297,7 @@ private void checkSign() if (thisSign != 0) lastSign = thisSign; } - } + } Utils.QL_REQUIRE( signChanges > 0, () => "the given cash flows cannot result in the given market " + "price due to their sign"); @@ -386,7 +386,7 @@ public void visit(CashFlow cf) #region Date functions public static Date startDate(Leg leg) - { + { Utils.QL_REQUIRE( !leg.empty(), () => "empty leg" ); Date d = Date.maxDate(); for (int i=0; i "empty leg" ); Date d = Date.minDate(); for (int i = 0; i < leg.Count; ++i) @@ -619,8 +619,8 @@ public static double accruedPeriod(Leg leg, bool includeSettlementDateFlows, Dat return 0; } public static int accruedDays(Leg leg, bool includeSettlementDateFlows,Date settlementDate = null) - { - if ( settlementDate == null ) + { + if ( settlementDate == null ) settlementDate = Settings.evaluationDate(); CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); @@ -636,8 +636,8 @@ public static int accruedDays(Leg leg, bool includeSettlementDateFlows,Date sett return 0; } public static double accruedAmount(Leg leg, bool includeSettlementDateFlows,Date settlementDate = null) - { - if ( settlementDate == null ) + { + if ( settlementDate == null ) settlementDate = Settings.evaluationDate(); CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); @@ -713,8 +713,8 @@ public static double bps(Leg leg, YieldTermStructure discountCurve, bool include BPSCalculator calc = new BPSCalculator(discountCurve); for (int i = 0; i < leg.Count; ++i) - { - if (!leg[i].hasOccurred(settlementDate, includeSettlementDateFlows) && + { + if (!leg[i].hasOccurred(settlementDate, includeSettlementDateFlows) && !leg[i].tradingExCoupon(settlementDate)) leg[i].accept(calc); } @@ -735,8 +735,8 @@ public static void npvbps(Leg leg,YieldTermStructure discountCurve, bool include BPSCalculator calc = new BPSCalculator(discountCurve); for (int i=0; i "null bps: impossible atm rate" ); return targetNpv.Value/bps; @@ -819,10 +819,10 @@ public static double npv(Leg leg, InterestRate yield, bool includeSettlementDate continue; Date couponDate = leg[i].date(); - double amount = leg[i].amount(); - if (leg[i].tradingExCoupon(settlementDate)) - { - amount = 0.0; + double amount = leg[i].amount(); + if (leg[i].tradingExCoupon(settlementDate)) + { + amount = 0.0; } Coupon coupon = leg[i] as Coupon; if (coupon != null ) @@ -1039,10 +1039,10 @@ public static double convexity(Leg leg, InterestRate yield, bool includeSettleme if (leg[i].hasOccurred(settlementDate,includeSettlementDateFlows)) continue; - double c = leg[i].amount(); - if (leg[i].tradingExCoupon(settlementDate)) - { - c = 0.0; + double c = leg[i].amount(); + if (leg[i].tradingExCoupon(settlementDate)) + { + c = 0.0; } Date couponDate = leg[i].date(); Coupon coupon = leg[i] as Coupon; diff --git a/QLNet/Cashflows/Cashflowvectors.cs b/QLNet/Cashflows/Cashflowvectors.cs index 956222009..083df4182 100644 --- a/QLNet/Cashflows/Cashflowvectors.cs +++ b/QLNet/Cashflows/Cashflowvectors.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -91,7 +91,7 @@ public static List FloatingLeg FloatingLeg yoyInflationLeg(List notionals_, if (notionals_.Count > n) throw new ApplicationException("too many nominals (" + notionals_.Count + - "), only " + n + " required"); + "), only " + n + " required"); if ( gearings_ != null && gearings_.Count > n ) throw new ApplicationException("too many gearings (" + gearings_.Count + - "), only " + n + " required"); - + "), only " + n + " required"); + if ( spreads_ != null && spreads_.Count > n ) throw new ApplicationException("too many spreads (" + spreads_.Count + - "), only " + n + " required"); - + "), only " + n + " required"); + if ( caps_ != null && caps_.Count > n ) throw new ApplicationException("too many caps (" + caps_.Count + - "), only " + n + " required"); - + "), only " + n + " required"); + if ( floors_ != null && floors_.Count > n ) throw new ApplicationException("too many floors (" + floors_.Count + "), only " + n + " required"); diff --git a/QLNet/Cashflows/CmsCoupon.cs b/QLNet/Cashflows/CmsCoupon.cs index a06d06ebd..be1c00145 100644 --- a/QLNet/Cashflows/CmsCoupon.cs +++ b/QLNet/Cashflows/CmsCoupon.cs @@ -3,7 +3,7 @@ Copyright (C) 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/ConundrumPricer.cs b/QLNet/Cashflows/ConundrumPricer.cs index b0f9750f9..9f83bd77f 100644 --- a/QLNet/Cashflows/ConundrumPricer.cs +++ b/QLNet/Cashflows/ConundrumPricer.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -543,7 +543,7 @@ protected HaganPricer(Handle swaptionVol, GFunction } public override void initialize(FloatingRateCoupon coupon) { - coupon_ = coupon as CmsCoupon; + coupon_ = coupon as CmsCoupon; Utils.QL_REQUIRE( coupon_ != null, () => "CMS coupon needed" ); gearing_ = coupon_.gearing(); spread_ = coupon_.spread(); diff --git a/QLNet/Cashflows/Coupon.cs b/QLNet/Cashflows/Coupon.cs index 5453ac2d2..b2a9e9b15 100644 Binary files a/QLNet/Cashflows/Coupon.cs and b/QLNet/Cashflows/Coupon.cs differ diff --git a/QLNet/Cashflows/CouponPricer.cs b/QLNet/Cashflows/CouponPricer.cs index 4d642e97a..e2664a14d 100644 --- a/QLNet/Cashflows/CouponPricer.cs +++ b/QLNet/Cashflows/CouponPricer.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/DigitalCmsCoupon.cs b/QLNet/Cashflows/DigitalCmsCoupon.cs index 75d4e2d07..33eb2f5a0 100644 --- a/QLNet/Cashflows/DigitalCmsCoupon.cs +++ b/QLNet/Cashflows/DigitalCmsCoupon.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/DigitalCoupon.cs b/QLNet/Cashflows/DigitalCoupon.cs index 7bddc134f..c1ef9eb4d 100644 --- a/QLNet/Cashflows/DigitalCoupon.cs +++ b/QLNet/Cashflows/DigitalCoupon.cs @@ -3,7 +3,7 @@ Copyright (C) 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/DigitalIborCoupon.cs b/QLNet/Cashflows/DigitalIborCoupon.cs index 16320a32f..aad7ee3ea 100644 --- a/QLNet/Cashflows/DigitalIborCoupon.cs +++ b/QLNet/Cashflows/DigitalIborCoupon.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/Dividend.cs b/QLNet/Cashflows/Dividend.cs index 6d4ead2e4..5229ff350 100644 --- a/QLNet/Cashflows/Dividend.cs +++ b/QLNet/Cashflows/Dividend.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/FixedRateCoupon.cs b/QLNet/Cashflows/FixedRateCoupon.cs index 5ef9ed51a..3b20eabe4 100644 --- a/QLNet/Cashflows/FixedRateCoupon.cs +++ b/QLNet/Cashflows/FixedRateCoupon.cs @@ -2,7 +2,7 @@ Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/FloatingRateCoupon.cs b/QLNet/Cashflows/FloatingRateCoupon.cs index 386000169..362187f34 100644 --- a/QLNet/Cashflows/FloatingRateCoupon.cs +++ b/QLNet/Cashflows/FloatingRateCoupon.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/Iborcoupon.cs b/QLNet/Cashflows/Iborcoupon.cs index f8eb740d5..dc3bf3df3 100644 --- a/QLNet/Cashflows/Iborcoupon.cs +++ b/QLNet/Cashflows/Iborcoupon.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/IndexedCashFlow.cs b/QLNet/Cashflows/IndexedCashFlow.cs index b22e70221..589c69d9b 100644 --- a/QLNet/Cashflows/IndexedCashFlow.cs +++ b/QLNet/Cashflows/IndexedCashFlow.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/InflationCoupon.cs b/QLNet/Cashflows/InflationCoupon.cs index 61e36798e..a091c6973 100644 --- a/QLNet/Cashflows/InflationCoupon.cs +++ b/QLNet/Cashflows/InflationCoupon.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/InflationCouponPricer.cs b/QLNet/Cashflows/InflationCouponPricer.cs index 8f8afa102..9b5eb274d 100644 --- a/QLNet/Cashflows/InflationCouponPricer.cs +++ b/QLNet/Cashflows/InflationCouponPricer.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/OvernightIndexedCoupon.cs b/QLNet/Cashflows/OvernightIndexedCoupon.cs index 12be2cf1d..7df45be25 100644 --- a/QLNet/Cashflows/OvernightIndexedCoupon.cs +++ b/QLNet/Cashflows/OvernightIndexedCoupon.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/Principal.cs b/QLNet/Cashflows/Principal.cs index 63040deb1..30b53a6da 100644 --- a/QLNet/Cashflows/Principal.cs +++ b/QLNet/Cashflows/Principal.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/PrincipalLegBase.cs b/QLNet/Cashflows/PrincipalLegBase.cs index 7ab52a917..b5874c33e 100644 --- a/QLNet/Cashflows/PrincipalLegBase.cs +++ b/QLNet/Cashflows/PrincipalLegBase.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/RateLegBase.cs b/QLNet/Cashflows/RateLegBase.cs index 0992df760..a96f70680 100644 --- a/QLNet/Cashflows/RateLegBase.cs +++ b/QLNet/Cashflows/RateLegBase.cs @@ -2,7 +2,7 @@ Copyright (C) 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -27,7 +27,7 @@ public abstract class RateLegBase { protected Schedule schedule_; protected List notionals_; protected DayCounter paymentDayCounter_; - protected BusinessDayConvention paymentAdjustment_; + protected BusinessDayConvention paymentAdjustment_; public static implicit operator List(RateLegBase o) { return o.value(); } public abstract List value(); @@ -233,14 +233,14 @@ public CPILegBase withPaymentDayCounter(DayCounter dayCounter) { paymentDayCounter_ = dayCounter; return this; - } - - public CPILegBase withPaymentCalendar(Calendar cal) - { - paymentCalendar_ = cal; - return this; - } - + } + + public CPILegBase withPaymentCalendar(Calendar cal) + { + paymentCalendar_ = cal; + return this; + } + public CPILegBase withFixingDays(int fixingDays) { @@ -288,15 +288,15 @@ public CPILegBase withFloors(List floors) { floors_ = floors; return this; - } - - public CPILegBase withExCouponPeriod(Period period, Calendar cal, BusinessDayConvention convention, bool endOfMonth = false) - { - exCouponPeriod_ = period; - exCouponCalendar_ = cal; - exCouponAdjustment_ = convention; - exCouponEndOfMonth_ = endOfMonth; - return this; + } + + public CPILegBase withExCouponPeriod(Period period, Calendar cal, BusinessDayConvention convention, bool endOfMonth = false) + { + exCouponPeriod_ = period; + exCouponCalendar_ = cal; + exCouponAdjustment_ = convention; + exCouponEndOfMonth_ = endOfMonth; + return this; } protected ZeroInflationIndex index_; @@ -307,13 +307,13 @@ public CPILegBase withExCouponPeriod(Period period, Calendar cal, BusinessDayCon protected InterpolationType observationInterpolation_; protected bool subtractInflationNominal_; protected List spreads_; - protected List caps_, floors_; - protected Calendar paymentCalendar_; - - protected Period exCouponPeriod_; - protected Calendar exCouponCalendar_; - protected BusinessDayConvention exCouponAdjustment_; - protected bool exCouponEndOfMonth_; + protected List caps_, floors_; + protected Calendar paymentCalendar_; + + protected Period exCouponPeriod_; + protected Calendar exCouponCalendar_; + protected BusinessDayConvention exCouponAdjustment_; + protected bool exCouponEndOfMonth_; } diff --git a/QLNet/Cashflows/Replication.cs b/QLNet/Cashflows/Replication.cs index bf9f56c41..d430c8e18 100644 --- a/QLNet/Cashflows/Replication.cs +++ b/QLNet/Cashflows/Replication.cs @@ -3,7 +3,7 @@ Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/SimpleCashFlow.cs b/QLNet/Cashflows/SimpleCashFlow.cs index 251dbb67f..b7153b5a7 100644 --- a/QLNet/Cashflows/SimpleCashFlow.cs +++ b/QLNet/Cashflows/SimpleCashFlow.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/YoYInflationCoupon.cs b/QLNet/Cashflows/YoYInflationCoupon.cs index e70bf685b..16d8ae2c0 100644 --- a/QLNet/Cashflows/YoYInflationCoupon.cs +++ b/QLNet/Cashflows/YoYInflationCoupon.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Cashflows/averagebmacoupon.cs b/QLNet/Cashflows/averagebmacoupon.cs index 96f954b3e..4d4514d37 100644 --- a/QLNet/Cashflows/averagebmacoupon.cs +++ b/QLNet/Cashflows/averagebmacoupon.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Currencies/Africa.cs b/QLNet/Currencies/Africa.cs index 8ea9f6775..72eccb69e 100644 --- a/QLNet/Currencies/Africa.cs +++ b/QLNet/Currencies/Africa.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Currencies/America.cs b/QLNet/Currencies/America.cs index e3ab5ef19..9746601cc 100644 Binary files a/QLNet/Currencies/America.cs and b/QLNet/Currencies/America.cs differ diff --git a/QLNet/Currencies/Asia.cs b/QLNet/Currencies/Asia.cs index 4e4d7a9dd..16c94e647 100644 --- a/QLNet/Currencies/Asia.cs +++ b/QLNet/Currencies/Asia.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -20,13 +20,179 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - /// - /// Japanese yen - /// The ISO three-letter code is JPY; the numeric code is 392. - /// It is divided into 100 sen. - /// - public class JPYCurrency : Currency - { - public JPYCurrency() : base("Japanese yen", "JPY", 392, "\xA5", "", 100, new Rounding(), "%3% %1$.0f") { } - } + //! Bangladesh taka + /*! The ISO three-letter code is BDT; the numeric code is 50. + It is divided in 100 paisa. + \ingroup currencies + */ + public class BDTCurrency : Currency + { + public BDTCurrency() : base("Bangladesh taka", "BDT", 50,"Bt", "", 100,new Rounding(), "%3% %1$.2f"){} + } + + //! Chinese yuan + /*! The ISO three-letter code is CNY; the numeric code is 156. + It is divided in 100 fen. + + \ingroup currencies + */ + public class CNYCurrency : Currency + { + public CNYCurrency() :base("Chinese yuan", "CNY", 156, "Y", "", 100, new Rounding(), "%3% %1$.2f"){} + } + + //! Hong Kong dollar + /*! The ISO three-letter code is HKD; the numeric code is 344. + It is divided in 100 cents. + + \ingroup currencies + */ + public class HKDCurrency : Currency + { + public HKDCurrency() : base( "Hong Kong dollar", "HKD", 344, "HK$", "", 100, new Rounding(), "%3% %1$.2f" ) { } + } + + //! Israeli shekel + /*! The ISO three-letter code is ILS; the numeric code is 376. + It is divided in 100 agorot. + + \ingroup currencies + */ + public class ILSCurrency : Currency + { + public ILSCurrency() : base( "Israeli shekel", "ILS", 376, "NIS", "", 100, new Rounding(), "%1$.2f %3%" ) { } + } + + //! Indian rupee + /*! The ISO three-letter code is INR; the numeric code is 356. + It is divided in 100 paise. + + \ingroup currencies + */ + public class INRCurrency : Currency + { + public INRCurrency() + : base( "Indian rupee", "INR", 356, "Rs", "", 100,new Rounding(), "%3% %1$.2f" ) { } + } + + //! Iraqi dinar + /*! The ISO three-letter code is IQD; the numeric code is 368. + It is divided in 1000 fils. + + \ingroup currencies + */ + public class IQDCurrency : Currency + { + public IQDCurrency() + : base( "Iraqi dinar", "IQD", 368,"ID", "", 1000,new Rounding(), "%2% %1$.3f" ) { } + } + + //! Iranian rial + /*! The ISO three-letter code is IRR; the numeric code is 364. + It has no subdivisions. + + \ingroup currencies + */ + public class IRRCurrency : Currency + { + public IRRCurrency() : base( "Iranian rial", "IRR", 364, "Rls", "", 1,new Rounding(), "%3% %1$.2f" ) { } + } + + /// + /// Japanese yen + /// The ISO three-letter code is JPY; the numeric code is 392. + /// It is divided into 100 sen. + /// + public class JPYCurrency : Currency + { + public JPYCurrency() : base("Japanese yen", "JPY", 392, "\xA5", "", 100, new Rounding(), "%3% %1$.0f") { } + } + + //! South-Korean won + /*! The ISO three-letter code is KRW; the numeric code is 410. + It is divided in 100 chon. + + \ingroup currencies + */ + public class KRWCurrency : Currency + { + public KRWCurrency() : base( "South-Korean won", "KRW", 410, "W", "", 100,new Rounding(), "%3% %1$.0f" ) { } + } + + //! Kuwaiti dinar + /*! The ISO three-letter code is KWD; the numeric code is 414. + It is divided in 1000 fils. + + \ingroup currencies + */ + public class KWDCurrency : Currency + { + public KWDCurrency() : base("Kuwaiti dinar", "KWD", 414,"KD", "", 1000,new Rounding(),"%3% %1$.3f"){} + } + + //! Nepal rupee + /*! The ISO three-letter code is NPR; the numeric code is 524. + It is divided in 100 paise. + + \ingroup currencies + */ + public class NPRCurrency : Currency + { + public NPRCurrency() : base("Nepal rupee", "NPR", 524, "NRs", "", 100, new Rounding(),"%3% %1$.2f"){} + } + + //! Pakistani rupee + /*! The ISO three-letter code is PKR; the numeric code is 586. + It is divided in 100 paisa. + + \ingroup currencies + */ + public class PKRCurrency : Currency + { + public PKRCurrency() : base("Pakistani rupee", "PKR", 586, "Rs", "", 100,new Rounding(),"%3% %1$.2f"){} + } + + //! Saudi riyal + /*! The ISO three-letter code is SAR; the numeric code is 682. + It is divided in 100 halalat. + + \ingroup currencies + */ + public class SARCurrency : Currency + { + public SARCurrency() : base("Saudi riyal", "SAR", 682, "SRls", "", 100,new Rounding(),"%3% %1$.2f"){} + } + + //! %Singapore dollar + /*! The ISO three-letter code is SGD; the numeric code is 702. + It is divided in 100 cents. + + \ingroup currencies + */ + public class SGDCurrency : Currency + { + public SGDCurrency() : base("Singapore dollar", "SGD", 702, "S$", "", 100, new Rounding(),"%3% %1$.2f"){} + } + + //! Thai baht + /*! The ISO three-letter code is THB; the numeric code is 764. + It is divided in 100 stang. + + \ingroup currencies + */ + public class THBCurrency : Currency + { + public THBCurrency() : base("Thai baht", "THB", 764, "Bht", "", 100,new Rounding(), "%1$.2f %3%"){} + } + + //! %Taiwan dollar + /*! The ISO three-letter code is TWD; the numeric code is 901. + It is divided in 100 cents. + + \ingroup currencies + */ + public class TWDCurrency : Currency + { + public TWDCurrency() : base( "Taiwan dollar", "TWD", 901, "NT$", "", 100, new Rounding(), "%3% %1$.2f" ) { } + } } diff --git a/QLNet/Currencies/Currency.cs b/QLNet/Currencies/Currency.cs index e82db60fd..887546287 100644 Binary files a/QLNet/Currencies/Currency.cs and b/QLNet/Currencies/Currency.cs differ diff --git a/QLNet/Currencies/Europe.cs b/QLNet/Currencies/Europe.cs index f22cf9c9a..5bfd84851 100644 Binary files a/QLNet/Currencies/Europe.cs and b/QLNet/Currencies/Europe.cs differ diff --git a/QLNet/Currencies/ExchangeRate.cs b/QLNet/Currencies/ExchangeRate.cs index b9f08153a..264e1a048 100644 --- a/QLNet/Currencies/ExchangeRate.cs +++ b/QLNet/Currencies/ExchangeRate.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Currencies/ExchangeRateManager.cs b/QLNet/Currencies/ExchangeRateManager.cs index bfe135252..f05267366 100644 --- a/QLNet/Currencies/ExchangeRateManager.cs +++ b/QLNet/Currencies/ExchangeRateManager.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Currencies/Oceania.cs b/QLNet/Currencies/Oceania.cs index a184db5cf..f3f214fef 100644 --- a/QLNet/Currencies/Oceania.cs +++ b/QLNet/Currencies/Oceania.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Error.cs b/QLNet/Error.cs index f4e5f9864..1e96f671c 100644 --- a/QLNet/Error.cs +++ b/QLNet/Error.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Event.cs b/QLNet/Event.cs index 1657bfad0..dd564b4b6 100644 Binary files a/QLNet/Event.cs and b/QLNet/Event.cs differ diff --git a/QLNet/Exercise.cs b/QLNet/Exercise.cs index d286d5c61..99e778a5f 100644 --- a/QLNet/Exercise.cs +++ b/QLNet/Exercise.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Handle.cs b/QLNet/Handle.cs index 901d60184..d6089cba8 100644 --- a/QLNet/Handle.cs +++ b/QLNet/Handle.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -54,12 +54,12 @@ public T link { public bool empty() { return link_.empty(); } #region operator overload - public static bool operator ==(Handle here, Handle there) { - if ( System.Object.ReferenceEquals( here, there ) ) return true; + public static bool operator ==(Handle here, Handle there) { + if ( System.Object.ReferenceEquals( here, there ) ) return true; else if ( (object)here == null || (object)there == null ) return false; else return here.Equals(there); } - public static bool operator !=(Handle here, Handle there) { + public static bool operator !=(Handle here, Handle there) { return !( here == there ); } public override bool Equals(object o) { diff --git a/QLNet/Index.cs b/QLNet/Index.cs index 52e59130f..6b4da5fb0 100644 --- a/QLNet/Index.cs +++ b/QLNet/Index.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/IBORIndex.cs b/QLNet/Indexes/IBORIndex.cs index 37a03e566..226f37b6e 100644 --- a/QLNet/Indexes/IBORIndex.cs +++ b/QLNet/Indexes/IBORIndex.cs @@ -3,7 +3,7 @@ Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Audlibor.cs b/QLNet/Indexes/Ibor/Audlibor.cs index cb3973bee..9d0d1c492 100644 --- a/QLNet/Indexes/Ibor/Audlibor.cs +++ b/QLNet/Indexes/Ibor/Audlibor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Cadlibor.cs b/QLNet/Indexes/Ibor/Cadlibor.cs index d94e14269..c1861f42a 100644 --- a/QLNet/Indexes/Ibor/Cadlibor.cs +++ b/QLNet/Indexes/Ibor/Cadlibor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Cdor.cs b/QLNet/Indexes/Ibor/Cdor.cs index ec372eafd..c469cf0d2 100644 --- a/QLNet/Indexes/Ibor/Cdor.cs +++ b/QLNet/Indexes/Ibor/Cdor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Chflibor.cs b/QLNet/Indexes/Ibor/Chflibor.cs index 009464060..0d64a4f8d 100644 --- a/QLNet/Indexes/Ibor/Chflibor.cs +++ b/QLNet/Indexes/Ibor/Chflibor.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Dkklibor.cs b/QLNet/Indexes/Ibor/Dkklibor.cs index 547f2f1ee..13d6fc3a0 100644 --- a/QLNet/Indexes/Ibor/Dkklibor.cs +++ b/QLNet/Indexes/Ibor/Dkklibor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Eonia.cs b/QLNet/Indexes/Ibor/Eonia.cs index d279c01df..6c52cceb1 100644 --- a/QLNet/Indexes/Ibor/Eonia.cs +++ b/QLNet/Indexes/Ibor/Eonia.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Euribor.cs b/QLNet/Indexes/Ibor/Euribor.cs index d7e09896c..d1ca23aba 100644 --- a/QLNet/Indexes/Ibor/Euribor.cs +++ b/QLNet/Indexes/Ibor/Euribor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Eurlibor.cs b/QLNet/Indexes/Ibor/Eurlibor.cs index b73348be5..584ca4098 100644 --- a/QLNet/Indexes/Ibor/Eurlibor.cs +++ b/QLNet/Indexes/Ibor/Eurlibor.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/FedFunds.cs b/QLNet/Indexes/Ibor/FedFunds.cs new file mode 100644 index 000000000..0c74aa100 --- /dev/null +++ b/QLNet/Indexes/Ibor/FedFunds.cs @@ -0,0 +1,33 @@ +/* + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + public class FedFunds : OvernightIndex + { + public FedFunds(Handle h = null) + :base("FedFunds", 0, new USDCurrency(), new UnitedStates(UnitedStates.Market.Settlement), + new Actual360(), h == null ? new Handle() : h) {} + } +} diff --git a/QLNet/Indexes/Ibor/Gbplibor.cs b/QLNet/Indexes/Ibor/Gbplibor.cs index 0561c8ddf..0c8b0940e 100644 --- a/QLNet/Indexes/Ibor/Gbplibor.cs +++ b/QLNet/Indexes/Ibor/Gbplibor.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Jibar.cs b/QLNet/Indexes/Ibor/Jibar.cs index 769d16856..397164107 100644 --- a/QLNet/Indexes/Ibor/Jibar.cs +++ b/QLNet/Indexes/Ibor/Jibar.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Jpylibor.cs b/QLNet/Indexes/Ibor/Jpylibor.cs index a17ab43bb..90c954136 100644 --- a/QLNet/Indexes/Ibor/Jpylibor.cs +++ b/QLNet/Indexes/Ibor/Jpylibor.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Libor.cs b/QLNet/Indexes/Ibor/Libor.cs index be29c4b21..e8a1f5b97 100644 --- a/QLNet/Indexes/Ibor/Libor.cs +++ b/QLNet/Indexes/Ibor/Libor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Nzdlibor.cs b/QLNet/Indexes/Ibor/Nzdlibor.cs index e2239eae5..54e99ae8d 100644 --- a/QLNet/Indexes/Ibor/Nzdlibor.cs +++ b/QLNet/Indexes/Ibor/Nzdlibor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Seklibor.cs b/QLNet/Indexes/Ibor/Seklibor.cs index 13d826a34..ad08fe203 100644 --- a/QLNet/Indexes/Ibor/Seklibor.cs +++ b/QLNet/Indexes/Ibor/Seklibor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Shibor.cs b/QLNet/Indexes/Ibor/Shibor.cs new file mode 100644 index 000000000..6f357350a --- /dev/null +++ b/QLNet/Indexes/Ibor/Shibor.cs @@ -0,0 +1,52 @@ +/* + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + public class Shibor : IborIndex + { + private static BusinessDayConvention shiborConvention(Period p) + { + switch (p.units()) { + case TimeUnit.Days: + case TimeUnit.Weeks: + return BusinessDayConvention.Following; + case TimeUnit.Months: + case TimeUnit.Years: + return BusinessDayConvention.ModifiedFollowing; + default: + Utils.QL_FAIL("invalid time units"); + return BusinessDayConvention.Unadjusted; + } + } + + public Shibor( Period tenor ) + :this(tenor , new Handle()) {} + + public Shibor( Period tenor, Handle h ) + :base("Shibor", tenor, (tenor == new Period(1,TimeUnit.Days)? 0 : 1), new CNYCurrency(), + new China(China.Market.IB), shiborConvention(tenor), false, + new Actual360(), h) {} + } +} diff --git a/QLNet/Indexes/Ibor/Sonia.cs b/QLNet/Indexes/Ibor/Sonia.cs new file mode 100644 index 000000000..102504f5d --- /dev/null +++ b/QLNet/Indexes/Ibor/Sonia.cs @@ -0,0 +1,33 @@ +/* + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + public class Sonia : OvernightIndex + { + //! %Sonia (Sterling Overnight Index Average) rate. + public Sonia(Handle h = null) + :base("Sonia", 0, new GBPCurrency(), new UnitedKingdom(UnitedKingdom.Market.Exchange), + new Actual365Fixed(), h == null ? new Handle():h) {} + } +} diff --git a/QLNet/Indexes/Ibor/Tibor.cs b/QLNet/Indexes/Ibor/Tibor.cs index 8afef8b82..b883817e2 100644 --- a/QLNet/Indexes/Ibor/Tibor.cs +++ b/QLNet/Indexes/Ibor/Tibor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Trylibor.cs b/QLNet/Indexes/Ibor/Trylibor.cs index bc6dfabb1..0b6e50d13 100644 --- a/QLNet/Indexes/Ibor/Trylibor.cs +++ b/QLNet/Indexes/Ibor/Trylibor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Usdlibor.cs b/QLNet/Indexes/Ibor/Usdlibor.cs index eb3b8a721..4d9ce5e5d 100644 --- a/QLNet/Indexes/Ibor/Usdlibor.cs +++ b/QLNet/Indexes/Ibor/Usdlibor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Ibor/Zibor.cs b/QLNet/Indexes/Ibor/Zibor.cs index 7232d84bd..b8844f13c 100644 --- a/QLNet/Indexes/Ibor/Zibor.cs +++ b/QLNet/Indexes/Ibor/Zibor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Indexmanager.cs b/QLNet/Indexes/Indexmanager.cs index 92596752f..1cb0d8883 100644 --- a/QLNet/Indexes/Indexmanager.cs +++ b/QLNet/Indexes/Indexmanager.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Inflation/AUCPI.cs b/QLNet/Indexes/Inflation/AUCPI.cs index 9d2cce961..b9e2936fb 100644 --- a/QLNet/Indexes/Inflation/AUCPI.cs +++ b/QLNet/Indexes/Inflation/AUCPI.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Inflation/EUHICP.cs b/QLNet/Indexes/Inflation/EUHICP.cs index 587aea20f..f5736ed77 100644 --- a/QLNet/Indexes/Inflation/EUHICP.cs +++ b/QLNet/Indexes/Inflation/EUHICP.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Inflation/FRHICP.cs b/QLNet/Indexes/Inflation/FRHICP.cs index 011ad6274..de35b89d6 100644 --- a/QLNet/Indexes/Inflation/FRHICP.cs +++ b/QLNet/Indexes/Inflation/FRHICP.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Inflation/UKRPI.cs b/QLNet/Indexes/Inflation/UKRPI.cs index af17e7f53..58432772a 100644 --- a/QLNet/Indexes/Inflation/UKRPI.cs +++ b/QLNet/Indexes/Inflation/UKRPI.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Inflation/USCPI.cs b/QLNet/Indexes/Inflation/USCPI.cs index 98d4a1f34..645a7697a 100644 --- a/QLNet/Indexes/Inflation/USCPI.cs +++ b/QLNet/Indexes/Inflation/USCPI.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Inflation/ZACPI.cs b/QLNet/Indexes/Inflation/ZACPI.cs index af8e6bd62..62f8f9f88 100644 --- a/QLNet/Indexes/Inflation/ZACPI.cs +++ b/QLNet/Indexes/Inflation/ZACPI.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/InflationIndex.cs b/QLNet/Indexes/InflationIndex.cs index e4695d5e4..ae55b00a1 100644 --- a/QLNet/Indexes/InflationIndex.cs +++ b/QLNet/Indexes/InflationIndex.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -170,7 +170,7 @@ public ZeroInflationIndex(string familyName, frequency, availabilityLag, currency) { zeroInflation_ = ts; - zeroInflation_.registerWith (update); + zeroInflation_.registerWith (update); } /*! \warning the forecastTodaysFixing parameter (required by @@ -191,8 +191,8 @@ public override double fixing(Date aFixingDate, bool forecastTodaysFixing) // fixings stored flat & for every day Date fixingDate2 = aFixingDate + new Period(frequency_); if (!IndexManager.instance().getHistory(name()).value().ContainsKey(fixingDate2)) - throw new ApplicationException("Missing " + name() + " fixing for " + fixingDate2); - + throw new ApplicationException("Missing " + name() + " fixing for " + fixingDate2); + double pastFixing2 = IndexManager.instance().getHistory(name()).value()[fixingDate2]; // now linearly interpolate @@ -207,26 +207,26 @@ public override double fixing(Date aFixingDate, bool forecastTodaysFixing) { return forecastFixing(aFixingDate); } - } - - bool needsForecast(Date fixingDate) - { + } + + bool needsForecast(Date fixingDate) + { // Stored fixings are always non-interpolated. // If an interpolated fixing is required then // the availability lag + one inflation period // must have passed to use historical fixings // (because you need the next one to interpolate). - // The interpolation is calculated (linearly) on demand. - - Date today = Settings.evaluationDate(); - Date todayMinusLag = today - availabilityLag_; - + // The interpolation is calculated (linearly) on demand. + + Date today = Settings.evaluationDate(); + Date todayMinusLag = today - availabilityLag_; + Date historicalFixingKnown = Utils.inflationPeriod(todayMinusLag, frequency_).Key - 1; Date latestNeededDate = fixingDate; if (interpolated_) { // might need the next one too KeyValuePair p = Utils.inflationPeriod(fixingDate, frequency_); - if (fixingDate > p.Key) + if (fixingDate > p.Key) latestNeededDate = latestNeededDate + new Period(frequency_); } @@ -241,7 +241,7 @@ bool needsForecast(Date fixingDate) } else { // we're not sure, but the fixing might be there so we // check. Todo: check which fixings are not possible, to - // avoid using fixings in the future + // avoid using fixings in the future return IndexManager.instance().getHistory(name()).value().ContainsKey(latestNeededDate); } } @@ -261,7 +261,7 @@ public ZeroInflationIndex clone(Handle h) private double forecastFixing(Date fixingDate) { // the term structure is relative to the fixing value at the base date. - Date baseDate = zeroInflation_.link.baseDate(); + Date baseDate = zeroInflation_.link.baseDate(); Utils.QL_REQUIRE( !needsForecast( baseDate ), () => name() + " index fixing at base date is not available" ); double baseFixing = fixing(baseDate, false); Date effectiveFixingDate; @@ -288,7 +288,7 @@ private double forecastFixing(Date fixingDate) return baseFixing * Math.Pow(1.0 + zero, t); } - private Handle zeroInflation_; + private Handle zeroInflation_; }; //! Base class for year-on-year inflation indices. diff --git a/QLNet/Indexes/InterestRateIndex.cs b/QLNet/Indexes/InterestRateIndex.cs index dbcdd2dfc..b668bec65 100644 --- a/QLNet/Indexes/InterestRateIndex.cs +++ b/QLNet/Indexes/InterestRateIndex.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/Region.cs b/QLNet/Indexes/Region.cs index e9836e9fd..c1c43aeeb 100644 --- a/QLNet/Indexes/Region.cs +++ b/QLNet/Indexes/Region.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -53,9 +53,9 @@ public Data(string Name, string Code) protected Data data_; public static bool operator ==(Region r1, Region r2) - { - if ( System.Object.ReferenceEquals( r1, r2 ) ) return true; - else if ( (object)r1 == null || (object)r2 == null ) return false; + { + if ( System.Object.ReferenceEquals( r1, r2 ) ) return true; + else if ( (object)r1 == null || (object)r2 == null ) return false; else return r1.Equals( r2 ); } @@ -121,21 +121,21 @@ public UKRegion() public class USRegion : Region { public USRegion() - { - Data USdata = new Data( "USA", "US" ); + { + Data USdata = new Data( "USA", "US" ); data_ = USdata; } } - //! South Africa as geographical/economic region - public class ZARegion : Region - { - public ZARegion() - { - Data ZAdata = new Data("South Africa", "ZA"); - data_ = ZAdata; - - } + //! South Africa as geographical/economic region + public class ZARegion : Region + { + public ZARegion() + { + Data ZAdata = new Data("South Africa", "ZA"); + data_ = ZAdata; + + } } } diff --git a/QLNet/Indexes/Swapindex.cs b/QLNet/Indexes/Swapindex.cs index c6f283f4d..f3e518bb4 100644 --- a/QLNet/Indexes/Swapindex.cs +++ b/QLNet/Indexes/Swapindex.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -80,7 +80,7 @@ public override Date maturityDate(Date valueDate) public Period fixedLegTenor() { return fixedLegTenor_; } public BusinessDayConvention fixedLegConvention() { return fixedLegConvention_; } public IborIndex iborIndex() { return iborIndex_; } - public Handle forwardingTermStructure() { return iborIndex_.forwardingTermStructure();} + public Handle forwardingTermStructure() { return iborIndex_.forwardingTermStructure();} public Handle discountingTermStructure() { return discount_; } public bool exogenousDiscount() { return exogenousDiscount_; } // \warning Relinking the term structure underlying the index will not have effect on the returned swap. @@ -136,45 +136,45 @@ public virtual SwapIndex clone(Handle forwarding) fixedLegConvention(), dayCounter(), iborIndex_.clone(forwarding)); - } - //! returns a copy of itself linked to a different curves - public virtual SwapIndex clone( Handle forwarding, Handle discounting ) - { - return new SwapIndex( familyName(), - tenor(), - fixingDays(), - currency(), - fixingCalendar(), - fixedLegTenor(), - fixedLegConvention(), - dayCounter(), - iborIndex_.clone( forwarding ), - discounting ); - } - //! returns a copy of itself linked to a different tenor - public virtual SwapIndex clone( Period tenor ) - { - if ( exogenousDiscount_ ) - return new SwapIndex( familyName(), - tenor, - fixingDays(), - currency(), - fixingCalendar(), - fixedLegTenor(), - fixedLegConvention(), - dayCounter(), - iborIndex(), - discountingTermStructure() ); - else - return new SwapIndex( familyName(), - tenor, - fixingDays(), - currency(), - fixingCalendar(), - fixedLegTenor(), - fixedLegConvention(), - dayCounter(), - iborIndex() ); + } + //! returns a copy of itself linked to a different curves + public virtual SwapIndex clone( Handle forwarding, Handle discounting ) + { + return new SwapIndex( familyName(), + tenor(), + fixingDays(), + currency(), + fixingCalendar(), + fixedLegTenor(), + fixedLegConvention(), + dayCounter(), + iborIndex_.clone( forwarding ), + discounting ); + } + //! returns a copy of itself linked to a different tenor + public virtual SwapIndex clone( Period tenor ) + { + if ( exogenousDiscount_ ) + return new SwapIndex( familyName(), + tenor, + fixingDays(), + currency(), + fixingCalendar(), + fixedLegTenor(), + fixedLegConvention(), + dayCounter(), + iborIndex(), + discountingTermStructure() ); + else + return new SwapIndex( familyName(), + tenor, + fixingDays(), + currency(), + fixingCalendar(), + fixedLegTenor(), + fixedLegConvention(), + dayCounter(), + iborIndex() ); } // @} protected override double forecastFixing(Date fixingDate) diff --git a/QLNet/Indexes/bmaindex.cs b/QLNet/Indexes/bmaindex.cs index 611e4f3e3..5a37c6ba5 100644 --- a/QLNet/Indexes/bmaindex.cs +++ b/QLNet/Indexes/bmaindex.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/swap/ChfLiborSwap.cs b/QLNet/Indexes/swap/ChfLiborSwap.cs index 0f93a9895..6daf29e81 100644 --- a/QLNet/Indexes/swap/ChfLiborSwap.cs +++ b/QLNet/Indexes/swap/ChfLiborSwap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/swap/EurLiborSwap.cs b/QLNet/Indexes/swap/EurLiborSwap.cs index 8c2136e0b..d6742f777 100644 --- a/QLNet/Indexes/swap/EurLiborSwap.cs +++ b/QLNet/Indexes/swap/EurLiborSwap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/swap/EuriborSwap.cs b/QLNet/Indexes/swap/EuriborSwap.cs index 6155465c1..f0d1b1459 100644 --- a/QLNet/Indexes/swap/EuriborSwap.cs +++ b/QLNet/Indexes/swap/EuriborSwap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/swap/GbpLiborSwap.cs b/QLNet/Indexes/swap/GbpLiborSwap.cs index a6b59c74f..367df5a56 100644 --- a/QLNet/Indexes/swap/GbpLiborSwap.cs +++ b/QLNet/Indexes/swap/GbpLiborSwap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/swap/JpyLiborSwap.cs b/QLNet/Indexes/swap/JpyLiborSwap.cs index 4a07154b9..57d5a7fd9 100644 --- a/QLNet/Indexes/swap/JpyLiborSwap.cs +++ b/QLNet/Indexes/swap/JpyLiborSwap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Indexes/swap/UsdLiborSwap.cs b/QLNet/Indexes/swap/UsdLiborSwap.cs index 50685de7a..8d2ae4573 100644 --- a/QLNet/Indexes/swap/UsdLiborSwap.cs +++ b/QLNet/Indexes/swap/UsdLiborSwap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/AsianOption.cs b/QLNet/Instruments/AsianOption.cs index ea8db841b..62e969918 100644 --- a/QLNet/Instruments/AsianOption.cs +++ b/QLNet/Instruments/AsianOption.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/AssetSwap.cs b/QLNet/Instruments/AssetSwap.cs index 83cce6666..8acbcd15b 100644 --- a/QLNet/Instruments/AssetSwap.cs +++ b/QLNet/Instruments/AssetSwap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -69,8 +69,8 @@ public AssetSwap(bool payBondCoupon, BusinessDayConvention paymentAdjustment = BusinessDayConvention.Following; Date finalDate = schedule.calendar().adjust(schedule.endDate(), paymentAdjustment); - Date adjBondMaturityDate = schedule.calendar().adjust(bond_.maturityDate(), paymentAdjustment); - + Date adjBondMaturityDate = schedule.calendar().adjust(bond_.maturityDate(), paymentAdjustment); + Utils.QL_REQUIRE( finalDate == adjBondMaturityDate, () => "adjusted schedule end date (" + finalDate + @@ -113,8 +113,8 @@ then scaled by the full price. */ bool upfrontDateBondFlows = false; if (!(c.hasOccurred(upfrontDate_, upfrontDateBondFlows))) legs_[0].Add(c); - } - + } + Utils.QL_REQUIRE( !legs_[0].empty(), () => "empty bond leg to start with" ); // special flows @@ -135,8 +135,8 @@ then scaled by the full price. */ // final notional exchange CashFlow finalCashFlow = new SimpleCashFlow(notional, finalDate); legs_[1].Add(finalCashFlow); - } - + } + Utils.QL_REQUIRE( !legs_[0].empty(), () => "empty bond leg" ); foreach (CashFlow c in legs_[0]) @@ -182,12 +182,12 @@ public AssetSwap(bool parAssetSwap, false); // endOfMonth if (dealMaturity == null) - dealMaturity = bond_.maturityDate(); - + dealMaturity = bond_.maturityDate(); + Utils.QL_REQUIRE( dealMaturity <= tempSch.dates().Last(), () => "deal maturity " + dealMaturity + " cannot be later than (adjusted) bond maturity " + - tempSch.dates().Last()); + tempSch.dates().Last()); Utils.QL_REQUIRE( dealMaturity > tempSch.dates()[0], () => "deal maturity " + dealMaturity + " must be later than swap start date " + @@ -254,8 +254,8 @@ then scaled by the full price. */ } // add the nonParRepayment_ CashFlow nonParRepaymentFlow = new SimpleCashFlow(nonParRepayment_, finalDate); - legs_[0].Add(nonParRepaymentFlow); - + legs_[0].Add(nonParRepaymentFlow); + Utils.QL_REQUIRE( !legs_[0].empty(), () => "empty bond leg to start with" ); // special flows @@ -276,8 +276,8 @@ then scaled by the full price. */ // final notional exchange CashFlow finalCashFlow = new SimpleCashFlow(notional, finalDate); legs_[1].Add(finalCashFlow); - } - + } + Utils.QL_REQUIRE( !legs_[0].empty(), () => "empty bond leg" ); foreach (CashFlow c in legs_[0]) @@ -319,14 +319,14 @@ public double fairSpread() public double floatingLegBPS() { - calculate(); + calculate(); Utils.QL_REQUIRE( legBPS_.Count > 1 && legBPS_[1] != null, () => "floating-leg BPS not available" ); return legBPS_[1].GetValueOrDefault(); } public double floatingLegNPV() { - calculate(); + calculate(); Utils.QL_REQUIRE( legNPV_.Count > 1 && legNPV_[1] != null, () => "floating-leg NPV not available" ); return legNPV_[1].GetValueOrDefault(); } @@ -339,7 +339,7 @@ public double fairCleanPrice() return fairCleanPrice_.Value; } else - { + { Utils.QL_REQUIRE( startDiscounts_[1] != null, () => "fair clean price not available for seasoned deal" ); double notional = bond_.notional(upfrontDate_); if (parSwap_) @@ -367,7 +367,7 @@ public double fairNonParRepayment() return fairNonParRepayment_.Value; } else - { + { Utils.QL_REQUIRE( endDiscounts_[1] != null, () => "fair non par repayment not available for expired leg" ); double notional = bond_.notional(upfrontDate_); fairNonParRepayment_ = nonParRepayment_ - payer_[0] * @@ -475,22 +475,22 @@ public Arguments() {} public List floatingPayDates; public List floatingSpreads; public override void validate() - { + { Utils.QL_REQUIRE( fixedResetDates.Count == fixedPayDates.Count, () => "number of fixed start dates different from " + - "number of fixed payment dates"); + "number of fixed payment dates"); Utils.QL_REQUIRE( fixedPayDates.Count == fixedCoupons.Count, () => "number of fixed payment dates different from " + - "number of fixed coupon amounts"); + "number of fixed coupon amounts"); Utils.QL_REQUIRE( floatingResetDates.Count == floatingPayDates.Count, () => "number of floating start dates different from " + - "number of floating payment dates"); + "number of floating payment dates"); Utils.QL_REQUIRE( floatingFixingDates.Count == floatingPayDates.Count, () => "number of floating fixing dates different from " + - "number of floating payment dates"); + "number of floating payment dates"); Utils.QL_REQUIRE( floatingAccrualTimes.Count == floatingPayDates.Count, () => "number of floating accrual times different from " + - "number of floating payment dates"); + "number of floating payment dates"); Utils.QL_REQUIRE( floatingSpreads.Count == floatingPayDates.Count, () => "number of floating spreads different from " + "number of floating payment dates"); diff --git a/QLNet/Instruments/AverageType.cs b/QLNet/Instruments/AverageType.cs index 5b4485e90..d8015f04d 100644 --- a/QLNet/Instruments/AverageType.cs +++ b/QLNet/Instruments/AverageType.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/BarrierOption.cs b/QLNet/Instruments/BarrierOption.cs index 71c46e742..3514394ce 100644 --- a/QLNet/Instruments/BarrierOption.cs +++ b/QLNet/Instruments/BarrierOption.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/BarrierType.cs b/QLNet/Instruments/BarrierType.cs index a69adc5be..ffcacc81c 100644 --- a/QLNet/Instruments/BarrierType.cs +++ b/QLNet/Instruments/BarrierType.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/BasisSwap.cs b/QLNet/Instruments/BasisSwap.cs index bb7b687aa..321fcb043 100644 --- a/QLNet/Instruments/BasisSwap.cs +++ b/QLNet/Instruments/BasisSwap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - * This file is part of QLNet Project http://qlnet.sourceforge.net/ + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/BasketOption.cs b/QLNet/Instruments/BasketOption.cs index 38f4d7355..78421870e 100644 --- a/QLNet/Instruments/BasketOption.cs +++ b/QLNet/Instruments/BasketOption.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/Bond.cs b/QLNet/Instruments/Bond.cs index 4e0b2ab79..5e021c34e 100644 --- a/QLNet/Instruments/Bond.cs +++ b/QLNet/Instruments/Bond.cs @@ -2,7 +2,7 @@ Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -53,7 +53,7 @@ public Bond(int settlementDays, Calendar calendar, Date issueDate = null, List "issue date (" + issueDate_ + ") must be earlier than first payment date (" + @@ -83,15 +83,15 @@ public Bond(int settlementDays, Calendar calendar, double faceAmount, Date matur maturityDate_ = maturityDate; issueDate_ = issueDate; - if (cashflows.Count != 0) + if (cashflows_.Count != 0) { cashflows_.Sort(0, cashflows_.Count - 1, null); if (maturityDate_ ==null) - maturityDate_ = CashFlows.maturityDate(cashflows); + maturityDate_ = CashFlows.maturityDate(cashflows_); if (issueDate_ != null) - { + { Utils.QL_REQUIRE( issueDate_ < cashflows_[0].date(), () => "issue date (" + issueDate_ + ") must be earlier than first payment date (" + @@ -165,7 +165,7 @@ public virtual double notional(Date d = null) public List redemptions() { return redemptions_; } // returns the redemption, if only one is defined public CashFlow redemption() - { + { Utils.QL_REQUIRE( redemptions_.Count == 1, () => "multiple redemption cash flows given" ); return redemptions_.Last(); } @@ -216,7 +216,7 @@ public double dirtyPrice() public double settlementValue() { - calculate(); + calculate(); Utils.QL_REQUIRE( settlementValue_ != null, () => "settlement value not provided" ); return settlementValue_.Value; } @@ -327,7 +327,7 @@ protected override void setupExpired() public override void setupArguments(IPricingEngineArguments args) { - Bond.Arguments arguments = args as Bond.Arguments; + Bond.Arguments arguments = args as Bond.Arguments; Utils.QL_REQUIRE( arguments != null, () => "wrong argument type" ); arguments.settlementDate = settlementDate(); @@ -339,7 +339,7 @@ public override void fetchResults(IPricingEngineResults r) { base.fetchResults(r); - Bond.Results results = r as Bond.Results; + Bond.Results results = r as Bond.Results; Utils.QL_REQUIRE( results != null, () => "wrong result type" ); settlementValue_ = results.settlementValue; @@ -385,9 +385,9 @@ protected void addRedemptionsToCashflows(List redemptions = null) cashflows_.Add(payment); redemptions_.Add(payment); } - // stable_sort now moves the redemptions to the right places + // stable_sort now moves the AmortizingPayment and Redemptions to the right places // while ensuring that they follow coupons with the same date. - cashflows_.Sort(); + cashflows_ = cashflows_.OrderBy( x => x.date() ).ToList(); } /*! This method can be called by derived classes in order to @@ -446,7 +446,7 @@ protected void calculateNotionalsFromCashflows() } else if (!Utils.close(notional, notionals_.Last())) { - // ...or if it has changed. + // ...or if it has changed. Utils.QL_REQUIRE( notional < notionals_.Last(), () => "increasing coupon notionals" ); notionals_.Add(coupon.nominal()); // in this case, we also add the last valid date for @@ -462,7 +462,7 @@ protected void calculateNotionalsFromCashflows() lastPaymentDate = coupon.date(); } - } + } Utils.QL_REQUIRE( !notionals_.empty(), () => "no coupons provided" ); notionals_.Add(0.0); notionalSchedule_.Add(lastPaymentDate); @@ -501,10 +501,10 @@ public class Arguments : IPricingEngineArguments public Calendar calendar; public virtual void validate() - { - Utils.QL_REQUIRE( settlementDate != null, () => "no settlement date provided" ); + { + Utils.QL_REQUIRE( settlementDate != null, () => "no settlement date provided" ); Utils.QL_REQUIRE( !cashflows.empty(), () => "no cash flow provided" ); - for (int i = 0; i < cashflows.Count; ++i) + for (int i = 0; i < cashflows.Count; ++i) Utils.QL_REQUIRE( cashflows[i] != null, () => "null cash flow provided" ); } } diff --git a/QLNet/Instruments/Bonds/AmortizingBond.cs b/QLNet/Instruments/Bonds/AmortizingBond.cs index ef67d7126..f43a880b4 100644 --- a/QLNet/Instruments/Bonds/AmortizingBond.cs +++ b/QLNet/Instruments/Bonds/AmortizingBond.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/Bonds/AmortizingCmsRateBond.cs b/QLNet/Instruments/Bonds/AmortizingCmsRateBond.cs index 5e0584127..3896ff9b1 100644 --- a/QLNet/Instruments/Bonds/AmortizingCmsRateBond.cs +++ b/QLNet/Instruments/Bonds/AmortizingCmsRateBond.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -61,8 +61,8 @@ public AmortizingCmsRateBond( int settlementDays, .withNotionals(notionals) .withPaymentAdjustment(paymentConvention); - addRedemptionsToCashflows(); - + addRedemptionsToCashflows(); + Utils.QL_REQUIRE( !cashflows().empty(), () => "bond with no cashflows!" ); index.registerWith(update); diff --git a/QLNet/Instruments/Bonds/AmortizingFixedRateBond.cs b/QLNet/Instruments/Bonds/AmortizingFixedRateBond.cs index 3fbe600af..662fb4be4 100644 --- a/QLNet/Instruments/Bonds/AmortizingFixedRateBond.cs +++ b/QLNet/Instruments/Bonds/AmortizingFixedRateBond.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -74,6 +74,11 @@ public AmortizingFixedRateBond( frequency_ = sinkingFrequency; dayCounter_ = accrualDayCounter; + Utils.QL_REQUIRE( bondTenor.length() > 0,() => + "bond tenor must be positive. " + + bondTenor + " is not allowed." ); + + maturityDate_ = startDate + bondTenor; maturityDate_ = startDate + bondTenor; schedule_ = sinkingSchedule(startDate, bondTenor, sinkingFrequency, calendar); cashflows_ = new FixedRateLeg(schedule_) @@ -108,8 +113,8 @@ protected List sinkingNotionals(Period maturityTenor, { Period freqPeriod = new Period(sinkingFrequency); int nPeriods = 0; - if(!isSubPeriod(freqPeriod, maturityTenor, out nPeriods)) - throw new ApplicationException("Bond frequency is incompatible with the maturity tenor"); + Utils.QL_REQUIRE(isSubPeriod(freqPeriod, maturityTenor, out nPeriods),() => + "Bond frequency is incompatible with the maturity tenor"); List notionals = new InitializedList(nPeriods+1); notionals[0] = initialNotional; @@ -119,13 +124,20 @@ protected List sinkingNotionals(Period maturityTenor, for(int i = 0; i < (int)nPeriods-1; ++i) { compoundedInterest *= (1.0 + coupon); - double currentNotional = - initialNotional*(compoundedInterest - (compoundedInterest-1.0)/(1.0 - 1.0/totalValue)); + double currentNotional = 0.0; + if(coupon < 1.0e-12) { + currentNotional = + initialNotional*(1.0 - (i+1.0)/nPeriods); + } + else { + currentNotional = + initialNotional*(compoundedInterest - (compoundedInterest-1.0)/(1.0 - 1.0/totalValue)); + } notionals[i+1] = currentNotional; } notionals[notionals.Count-1] = 0.0; return notionals; - } + } protected bool isSubPeriod(Period subPeriod,Period superPeriod,out int numSubPeriods) { diff --git a/QLNet/Instruments/Bonds/AmortizingFloatingRateBond.cs b/QLNet/Instruments/Bonds/AmortizingFloatingRateBond.cs index d64acb573..4869b4925 100644 --- a/QLNet/Instruments/Bonds/AmortizingFloatingRateBond.cs +++ b/QLNet/Instruments/Bonds/AmortizingFloatingRateBond.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -69,8 +69,8 @@ public AmortizingFloatingRateBond(int settlementDays, .withPaymentAdjustment(paymentConvention) .withNotionals(notionals).value(); - addRedemptionsToCashflows(); - + addRedemptionsToCashflows(); + Utils.QL_REQUIRE( !cashflows().empty(), () => "bond with no cashflows!" ); index.registerWith(update); diff --git a/QLNet/Instruments/Bonds/BTP.cs b/QLNet/Instruments/Bonds/BTP.cs index 2e40d1c79..ea212cf6f 100644 --- a/QLNet/Instruments/Bonds/BTP.cs +++ b/QLNet/Instruments/Bonds/BTP.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -121,15 +121,15 @@ public RendistatoBasket(List btps, List outstandings, List "empty RendistatoCalculator Basket" ); - int k = btps_.Count; - + int k = btps_.Count; + Utils.QL_REQUIRE( outstandings_.Count == k, () => "mismatch between number of BTPs (" + k + ") and number of outstandings (" + - outstandings_.Count + ")"); + outstandings_.Count + ")"); Utils.QL_REQUIRE( quotes_.Count == k, () => "mismatch between number of BTPs (" + k + ") and number of clean prices quotes (" + @@ -137,15 +137,15 @@ public RendistatoBasket(List btps, List outstandings, List= 0, () => "negative outstanding for " + i + " bond, maturity " + btps[i].maturityDate()); // add check for prices ?? } - // TODO: filter out expired bonds, zero outstanding bond, etc - + // TODO: filter out expired bonds, zero outstanding bond, etc + Utils.QL_REQUIRE( !btps_.empty(), () => "invalid bonds only in RendistatoCalculator Basket" ); n_ = btps_.Count; diff --git a/QLNet/Instruments/Bonds/BondFactory.cs b/QLNet/Instruments/Bonds/BondFactory.cs index 7b43c1d5f..188ac9546 100644 --- a/QLNet/Instruments/Bonds/BondFactory.cs +++ b/QLNet/Instruments/Bonds/BondFactory.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/Bonds/CPIBond.cs b/QLNet/Instruments/Bonds/CPIBond.cs index 0f754cc6b..183400717 100644 --- a/QLNet/Instruments/Bonds/CPIBond.cs +++ b/QLNet/Instruments/Bonds/CPIBond.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -60,22 +60,22 @@ public CPIBond(int settlementDays, maturityDate_ = schedule.endDate(); - // a CPIleg know about zero legs and inclusion of base inflation notional - cashflows_ = new CPILeg(schedule, cpiIndex_, - baseCPI_, observationLag_) - .withSubtractInflationNominal(growthOnly_) - .withObservationInterpolation(observationInterpolation_) - .withPaymentDayCounter(accrualDayCounter) - .withFixedRates(fixedRate) - .withPaymentCalendar(calendar_) - .withExCouponPeriod(exCouponPeriod, - exCouponCalendar, - exCouponConvention, - exCouponEndOfMonth) - .withNotionals(faceAmount) - .withPaymentAdjustment(paymentConvention); - - + // a CPIleg know about zero legs and inclusion of base inflation notional + cashflows_ = new CPILeg(schedule, cpiIndex_, + baseCPI_, observationLag_) + .withSubtractInflationNominal(growthOnly_) + .withObservationInterpolation(observationInterpolation_) + .withPaymentDayCounter(accrualDayCounter) + .withFixedRates(fixedRate) + .withPaymentCalendar(calendar_) + .withExCouponPeriod(exCouponPeriod, + exCouponCalendar, + exCouponConvention, + exCouponEndOfMonth) + .withNotionals(faceAmount) + .withPaymentAdjustment(paymentConvention); + + calculateNotionalsFromCashflows(); cpiIndex_.registerWith(update); diff --git a/QLNet/Instruments/Bonds/CallableBond.cs b/QLNet/Instruments/Bonds/CallableBond.cs index 06696397f..a980f45ff 100644 --- a/QLNet/Instruments/Bonds/CallableBond.cs +++ b/QLNet/Instruments/Bonds/CallableBond.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/Bonds/CmsRateBond.cs b/QLNet/Instruments/Bonds/CmsRateBond.cs index a0b701280..ed3cb6a37 100644 --- a/QLNet/Instruments/Bonds/CmsRateBond.cs +++ b/QLNet/Instruments/Bonds/CmsRateBond.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/Bonds/ConvertibleBond.cs b/QLNet/Instruments/Bonds/ConvertibleBond.cs index 9e97ba151..0d674c7d9 100644 --- a/QLNet/Instruments/Bonds/ConvertibleBond.cs +++ b/QLNet/Instruments/Bonds/ConvertibleBond.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -67,22 +67,22 @@ public arguments() public double? redemption; public override void validate() { - base.validate(); - - Utils.QL_REQUIRE( conversionRatio != null, () => "null conversion ratio" ); - Utils.QL_REQUIRE( conversionRatio > 0.0, () => "positive conversion ratio required: " + conversionRatio + " not allowed" ); - - Utils.QL_REQUIRE( redemption != null, () => "null redemption" ); - Utils.QL_REQUIRE( redemption >= 0.0, () => "positive redemption required: " + redemption + " not allowed" ); - - Utils.QL_REQUIRE( settlementDate != null, () => "null settlement date" ); - - Utils.QL_REQUIRE( settlementDays != null, () => "null settlement days" ); - - Utils.QL_REQUIRE( callabilityDates.Count == callabilityTypes.Count, () => "different number of callability dates and types" ); - Utils.QL_REQUIRE( callabilityDates.Count == callabilityPrices.Count, () => "different number of callability dates and prices" ); - Utils.QL_REQUIRE( callabilityDates.Count == callabilityTriggers.Count, () => "different number of callability dates and triggers" ); - + base.validate(); + + Utils.QL_REQUIRE( conversionRatio != null, () => "null conversion ratio" ); + Utils.QL_REQUIRE( conversionRatio > 0.0, () => "positive conversion ratio required: " + conversionRatio + " not allowed" ); + + Utils.QL_REQUIRE( redemption != null, () => "null redemption" ); + Utils.QL_REQUIRE( redemption >= 0.0, () => "positive redemption required: " + redemption + " not allowed" ); + + Utils.QL_REQUIRE( settlementDate != null, () => "null settlement date" ); + + Utils.QL_REQUIRE( settlementDays != null, () => "null settlement days" ); + + Utils.QL_REQUIRE( callabilityDates.Count == callabilityTypes.Count, () => "different number of callability dates and types" ); + Utils.QL_REQUIRE( callabilityDates.Count == callabilityPrices.Count, () => "different number of callability dates and prices" ); + Utils.QL_REQUIRE( callabilityDates.Count == callabilityTriggers.Count, () => "different number of callability dates and triggers" ); + Utils.QL_REQUIRE( couponDates.Count == couponAmounts.Count, () => "different number of coupon dates and amounts" ); } @@ -120,7 +120,7 @@ public override void setupArguments(IPricingEngineArguments args) { base.setupArguments(args); - ConvertibleBond.option.arguments moreArgs = args as ConvertibleBond.option.arguments; + ConvertibleBond.option.arguments moreArgs = args as ConvertibleBond.option.arguments; Utils.QL_REQUIRE( moreArgs != null, () => "wrong argument type" ); moreArgs.conversionRatio = conversionRatio_; @@ -224,7 +224,7 @@ protected ConvertibleBond( Exercise exercise, maturityDate_ = schedule.endDate(); if (!callability.empty()) - { + { Utils.QL_REQUIRE( callability.Last().date() <= maturityDate_, () => "last callability date (" + callability.Last().date() @@ -307,8 +307,8 @@ public ConvertibleFixedCouponBond( Exercise exercise, .withNotionals(100.0) .withPaymentAdjustment(schedule.businessDayConvention()); - addRedemptionsToCashflows(new List(){redemption}); - + addRedemptionsToCashflows(new List(){redemption}); + Utils.QL_REQUIRE( redemptions_.Count == 1, () => "multiple redemptions created" ); option_ = new option(this, exercise, conversionRatio, dividends, callability, creditSpread, cashflows_, dayCounter, schedule, @@ -348,8 +348,8 @@ public ConvertibleFloatingRateBond( Exercise exercise, .withNotionals(100.0) .withPaymentAdjustment(schedule.businessDayConvention()); - addRedemptionsToCashflows(new List{redemption}); - + addRedemptionsToCashflows(new List{redemption}); + Utils.QL_REQUIRE( redemptions_.Count == 1, () => "multiple redemptions created" ); option_ = new option(this, exercise, conversionRatio, dividends, callability, creditSpread, cashflows_, dayCounter, schedule, diff --git a/QLNet/Instruments/Bonds/Fixedratebond.cs b/QLNet/Instruments/Bonds/Fixedratebond.cs index a364f5f12..2735eea8a 100644 --- a/QLNet/Instruments/Bonds/Fixedratebond.cs +++ b/QLNet/Instruments/Bonds/Fixedratebond.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/Bonds/FloatingRateBond.cs b/QLNet/Instruments/Bonds/FloatingRateBond.cs index 4ec1ef8a5..d30793440 100644 --- a/QLNet/Instruments/Bonds/FloatingRateBond.cs +++ b/QLNet/Instruments/Bonds/FloatingRateBond.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/Bonds/PSACurve.cs b/QLNet/Instruments/Bonds/PSACurve.cs index 55aaec9f0..6e9d169b6 100644 --- a/QLNet/Instruments/Bonds/PSACurve.cs +++ b/QLNet/Instruments/Bonds/PSACurve.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/Bonds/Zerocouponbond.cs b/QLNet/Instruments/Bonds/Zerocouponbond.cs index 50858646e..1b11a3105 100644 --- a/QLNet/Instruments/Bonds/Zerocouponbond.cs +++ b/QLNet/Instruments/Bonds/Zerocouponbond.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/Callability.cs b/QLNet/Instruments/Callability.cs index 05b2807ab..34727e9fc 100644 --- a/QLNet/Instruments/Callability.cs +++ b/QLNet/Instruments/Callability.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -44,7 +44,7 @@ public Price(double amount, Type type) } public double amount() - { + { Utils.QL_REQUIRE( amount_ != null, () => "no amount given" ); return amount_.Value; } @@ -65,7 +65,7 @@ public Callability(Price price, Type type, Date date) date_=date; } public Price price() - { + { Utils.QL_REQUIRE( price_ != null, () => "no price given" ); return price_; } diff --git a/QLNet/Instruments/CapFloor.cs b/QLNet/Instruments/CapFloor.cs index 66d4ac178..cd39bef15 100644 --- a/QLNet/Instruments/CapFloor.cs +++ b/QLNet/Instruments/CapFloor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/Claim.cs b/QLNet/Instruments/Claim.cs index 077ea0b71..1a8c52597 100644 --- a/QLNet/Instruments/Claim.cs +++ b/QLNet/Instruments/Claim.cs @@ -1,20 +1,20 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; using System.Collections.Generic; @@ -58,31 +58,31 @@ protected void notifyObservers() public abstract double amount(Date defaultDate,double notional,double recoveryRate) ; } - - //! Claim on a notional - public class FaceValueClaim : Claim + + //! Claim on a notional + public class FaceValueClaim : Claim { public override double amount(Date d, double notional, double recoveryRate) { return notional * (1.0 - recoveryRate); - } + } } - //! Claim on the notional of a reference security, including accrual - public class FaceValueAccrualClaim : Claim + //! Claim on the notional of a reference security, including accrual + public class FaceValueAccrualClaim : Claim { public FaceValueAccrualClaim(Bond referenceSecurity) { referenceSecurity_ = referenceSecurity; referenceSecurity.registerWith(update); - } - public override double amount(Date d,double notional,double recoveryRate) + } + public override double amount(Date d,double notional,double recoveryRate) { double accrual = referenceSecurity_.accruedAmount(d) / referenceSecurity_.notional(d); - return notional * (1.0 - recoveryRate - accrual); - } - private Bond referenceSecurity_; + return notional * (1.0 - recoveryRate - accrual); + } + private Bond referenceSecurity_; } } diff --git a/QLNet/Instruments/CreditDefaultSwap.cs b/QLNet/Instruments/CreditDefaultSwap.cs index 4e4f023ec..e261c9f44 100644 --- a/QLNet/Instruments/CreditDefaultSwap.cs +++ b/QLNet/Instruments/CreditDefaultSwap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -15,19 +15,19 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace QLNet -{ +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ public struct Protection { public enum Side { Buyer, Seller }; - }; - - //! Credit default swap + }; + + //! Credit default swap /*! \note This instrument currently assumes that the issuer did not default until today's date. @@ -38,9 +38,9 @@ NPV and therefore affect the fair-spread calculation. This might not be what you want. \ingroup instruments - */ - public class CreditDefaultSwap : Instrument - { + */ + public class CreditDefaultSwap : Instrument + { //! \name ructors //@{ //! CDS quoted as running-spread only @@ -60,27 +60,27 @@ due in the event of a default. the accrual period. @param protectionStart The first date where a default event will trigger the contract. - */ - public CreditDefaultSwap(Protection.Side side, - double notional, - double spread, - Schedule schedule, - BusinessDayConvention convention, - DayCounter dayCounter, - bool settlesAccrual = true, - bool paysAtDefaultTime = true, - Date protectionStart = null, - Claim claim = null) - { + */ + public CreditDefaultSwap(Protection.Side side, + double notional, + double spread, + Schedule schedule, + BusinessDayConvention convention, + DayCounter dayCounter, + bool settlesAccrual = true, + bool paysAtDefaultTime = true, + Date protectionStart = null, + Claim claim = null) + { side_ = side; notional_ = notional; upfront_ = null; runningSpread_ = spread; settlesAccrual_ =settlesAccrual; paysAtDefaultTime_ = paysAtDefaultTime; - claim_ = claim; - protectionStart_ = protectionStart == null ? schedule[0] : protectionStart; - + claim_ = claim; + protectionStart_ = protectionStart == null ? schedule[0] : protectionStart; + Utils.QL_REQUIRE( protectionStart_ <= schedule[0], () => "protection can not start after accrual" ); leg_ = new FixedRateLeg(schedule) .withCouponRates(spread, dayCounter) @@ -90,9 +90,9 @@ public CreditDefaultSwap(Protection.Side side, upfrontPayment_ = new SimpleCashFlow(0.0, schedule[0]); if (claim_ == null ) - claim_ = new FaceValueClaim(); - - claim_.registerWith(update); + claim_ = new FaceValueClaim(); + + claim_.registerWith(update); } //! CDS quoted as upfront and running spread /*! @param side Whether the protection is bought or sold. @@ -113,20 +113,20 @@ the accrual period. @param protectionStart The first date where a default event will trigger the contract. @param upfrontDate Settlement date for the upfront payment. - */ - public CreditDefaultSwap(Protection.Side side, - double notional, - double upfront, - double runningSpread, - Schedule schedule, - BusinessDayConvention convention, - DayCounter dayCounter, - bool settlesAccrual = true, - bool paysAtDefaultTime = true, - Date protectionStart = null, - Date upfrontDate = null, - Claim claim = null) - { + */ + public CreditDefaultSwap(Protection.Side side, + double notional, + double upfront, + double runningSpread, + Schedule schedule, + BusinessDayConvention convention, + DayCounter dayCounter, + bool settlesAccrual = true, + bool paysAtDefaultTime = true, + Date protectionStart = null, + Date upfrontDate = null, + Claim claim = null) + { side_ = side; notional_ = notional; @@ -134,9 +134,9 @@ public CreditDefaultSwap(Protection.Side side, runningSpread_ = runningSpread; settlesAccrual_ =settlesAccrual; paysAtDefaultTime_ = paysAtDefaultTime; - claim_ = claim; - protectionStart_ = protectionStart == null ? schedule[0] : protectionStart; - + claim_ = claim; + protectionStart_ = protectionStart == null ? schedule[0] : protectionStart; + Utils.QL_REQUIRE( protectionStart_ <= schedule[0], () => "protection can not start after accrual" ); leg_ = new FixedRateLeg(schedule) .withCouponRates(runningSpread, dayCounter) @@ -144,45 +144,45 @@ public CreditDefaultSwap(Protection.Side side, .withPaymentAdjustment(convention); Date d = upfrontDate == null ? schedule[0] : upfrontDate; - upfrontPayment_ = new SimpleCashFlow(notional*upfront, d); + upfrontPayment_ = new SimpleCashFlow(notional*upfront, d); Utils.QL_REQUIRE( upfrontPayment_.date() >= protectionStart_, () => "upfront can not be due before contract start" ); if (claim_ == null) - claim_ = new FaceValueClaim(); - claim_.registerWith(update); + claim_ = new FaceValueClaim(); + claim_.registerWith(update); } //@} //! \name Instrument interface - //@{ - public override bool isExpired() - { - for (int i = leg_.Count; i > 0; --i) - if (!leg_[i - 1].hasOccurred()) - return false; - return true; - } - - public override void setupArguments(IPricingEngineArguments args) - { - CreditDefaultSwap.Arguments arguments = args as CreditDefaultSwap.Arguments; - Utils.QL_REQUIRE( arguments != null, () => "wrong argument type" ); - - arguments.side = side_; - arguments.notional = notional_; - arguments.leg = leg_; - arguments.upfrontPayment = upfrontPayment_; - arguments.settlesAccrual = settlesAccrual_; - arguments.paysAtDefaultTime = paysAtDefaultTime_; - arguments.claim = claim_; - arguments.upfront = upfront_; - arguments.spread = runningSpread_; - arguments.protectionStart = protectionStart_; - } - - public override void fetchResults(IPricingEngineResults r) - { + //@{ + public override bool isExpired() + { + for (int i = leg_.Count; i > 0; --i) + if (!leg_[i - 1].hasOccurred()) + return false; + return true; + } + + public override void setupArguments(IPricingEngineArguments args) + { + CreditDefaultSwap.Arguments arguments = args as CreditDefaultSwap.Arguments; + Utils.QL_REQUIRE( arguments != null, () => "wrong argument type" ); + + arguments.side = side_; + arguments.notional = notional_; + arguments.leg = leg_; + arguments.upfrontPayment = upfrontPayment_; + arguments.settlesAccrual = settlesAccrual_; + arguments.paysAtDefaultTime = paysAtDefaultTime_; + arguments.claim = claim_; + arguments.upfront = upfront_; + arguments.spread = runningSpread_; + arguments.protectionStart = protectionStart_; + } + + public override void fetchResults(IPricingEngineResults r) + { base.fetchResults(r); - CreditDefaultSwap.Results results = r as CreditDefaultSwap.Results; + CreditDefaultSwap.Results results = r as CreditDefaultSwap.Results; Utils.QL_REQUIRE( results != null, () => "wrong result type" ); fairSpread_ = results.fairSpread; @@ -191,19 +191,19 @@ public override void fetchResults(IPricingEngineResults r) couponLegNPV_ = results.couponLegNPV; defaultLegNPV_ = results.defaultLegNPV; upfrontNPV_ = results.upfrontNPV; - upfrontBPS_ = results.upfrontBPS; + upfrontBPS_ = results.upfrontBPS; } //@} //! \name Inspectors - //@{ - public Protection.Side side() { return side_; } - public double? notional() { return notional_; } - public double runningSpread() { return runningSpread_; } - public double? upfront() { return upfront_; } - public bool settlesAccrual() { return settlesAccrual_; } - public bool paysAtDefaultTime() { return paysAtDefaultTime_; } + //@{ + public Protection.Side side() { return side_; } + public double? notional() { return notional_; } + public double runningSpread() { return runningSpread_; } + public double? upfront() { return upfront_; } + public bool settlesAccrual() { return settlesAccrual_; } + public bool paysAtDefaultTime() { return paysAtDefaultTime_; } public List coupons() { return leg_; } - //! The first date for which defaults will trigger the contract + //! The first date for which defaults will trigger the contract public Date protectionStartDate() { return protectionStart_; } //! The last date for which defaults will trigger the contract public Date protectionEndDate() {return ((Coupon)(leg_.Last())).accrualEndDate();} @@ -213,61 +213,61 @@ public override void fetchResults(IPricingEngineResults r) /*! Returns the upfront spread that, given the running spread and the quoted recovery rate, will make the instrument have an NPV of 0. - */ - public double fairUpfront() - { - calculate(); - Utils.QL_REQUIRE( fairUpfront_ != null, () => "fair upfront not available" ); - return fairUpfront_.Value; + */ + public double fairUpfront() + { + calculate(); + Utils.QL_REQUIRE( fairUpfront_ != null, () => "fair upfront not available" ); + return fairUpfront_.Value; } /*! Returns the running spread that, given the quoted recovery rate, will make the running-only CDS have an NPV of 0. \note This calculation does not take any upfront into account, even if one was given. - */ - public double fairSpread() - { - calculate(); - Utils.QL_REQUIRE( fairSpread_ != null, () => "fair spread not available" ); - return fairSpread_.Value; + */ + public double fairSpread() + { + calculate(); + Utils.QL_REQUIRE( fairSpread_ != null, () => "fair spread not available" ); + return fairSpread_.Value; } /*! Returns the variation of the fixed-leg value given a one-basis-point change in the running spread. - */ - public double couponLegBPS() - { - calculate(); - Utils.QL_REQUIRE( couponLegBPS_ != null, () => "coupon-leg BPS not available" ); - return couponLegBPS_.Value; - } - - public double upfrontBPS() - { - calculate(); - Utils.QL_REQUIRE( upfrontBPS_ != null, () => "upfront BPS not available" ); - return upfrontBPS_.Value; - } - - public double couponLegNPV() - { - calculate(); - Utils.QL_REQUIRE( couponLegNPV_ != null, () => "coupon-leg NPV not available" ); - return couponLegNPV_.Value; - } - - public double defaultLegNPV() - { - calculate(); - Utils.QL_REQUIRE( defaultLegNPV_ != null, () => "default-leg NPV not available" ); - return defaultLegNPV_.Value; - } - - public double upfrontNPV() - { - calculate(); - Utils.QL_REQUIRE( upfrontNPV_ != null, () => "upfront NPV not available" ); - return upfrontNPV_.Value; + */ + public double couponLegBPS() + { + calculate(); + Utils.QL_REQUIRE( couponLegBPS_ != null, () => "coupon-leg BPS not available" ); + return couponLegBPS_.Value; + } + + public double upfrontBPS() + { + calculate(); + Utils.QL_REQUIRE( upfrontBPS_ != null, () => "upfront BPS not available" ); + return upfrontBPS_.Value; + } + + public double couponLegNPV() + { + calculate(); + Utils.QL_REQUIRE( couponLegNPV_ != null, () => "coupon-leg NPV not available" ); + return couponLegNPV_.Value; + } + + public double defaultLegNPV() + { + calculate(); + Utils.QL_REQUIRE( defaultLegNPV_ != null, () => "default-leg NPV not available" ); + return defaultLegNPV_.Value; + } + + public double upfrontNPV() + { + calculate(); + Utils.QL_REQUIRE( upfrontNPV_ != null, () => "upfront NPV not available" ); + return upfrontNPV_.Value; } //! Implied hazard rate calculation @@ -286,7 +286,7 @@ contract cashflows. - The CDS should pay accrued and mature on standard IMM dates, settle on trade date +1 and upfront settle on trade date +3. - */ + */ private class ObjectiveFunction : ISolver1d { public ObjectiveFunction(double target, SimpleQuote quote,IPricingEngine engine,CreditDefaultSwap.Results results) @@ -295,8 +295,8 @@ public ObjectiveFunction(double target, SimpleQuote quote,IPricingEngine engine, quote_ = quote; engine_ = engine; results_ = results; - } - + } + public override double value(double guess) { quote_.setValue(guess); @@ -309,13 +309,13 @@ public override double value(double guess) private IPricingEngine engine_; private CreditDefaultSwap.Results results_; - } - public double impliedHazardRate(double targetNPV, - Handle discountCurve, - DayCounter dayCounter, - double recoveryRate = 0.4, - double accuracy = 1.0e-6) - { + } + public double impliedHazardRate(double targetNPV, + Handle discountCurve, + DayCounter dayCounter, + double recoveryRate = 0.4, + double accuracy = 1.0e-6) + { SimpleQuote flatRate = new SimpleQuote(0.0); Handle probability = new Handle( @@ -329,7 +329,7 @@ public double impliedHazardRate(double targetNPV, double guess = 0.001; double step = guess*0.1; - return new Brent().solve(f, accuracy, guess, step); + return new Brent().solve(f, accuracy, guess, step); } //! Conventional/standard upfront-to-spread conversion @@ -362,11 +362,11 @@ contract cashflows. - The CDS should pay accrued and mature on standard IMM dates, settle on trade date +1 and upfront settle on trade date +3. - */ - public double? conventionalSpread(double conventionalRecovery, - Handle discountCurve, - DayCounter dayCounter) - { + */ + public double? conventionalSpread(double conventionalRecovery, + Handle discountCurve, + DayCounter dayCounter) + { double flatHazardRate = impliedHazardRate(0.0, discountCurve, dayCounter, @@ -377,14 +377,14 @@ settle on trade date +3. MidPointCdsEngine engine = new MidPointCdsEngine(probability, conventionalRecovery, discountCurve, true); setupArguments(engine.getArguments()); - engine.calculate(); + engine.calculate(); CreditDefaultSwap.Results results = engine.getResults() as CreditDefaultSwap.Results; - return results.fairSpread; + return results.fairSpread; } //@} //! \name Instrument interface - //@{ - protected override void setupExpired() + //@{ + protected override void setupExpired() { base.setupExpired(); fairSpread_ = fairUpfront_ = 0.0; @@ -408,16 +408,16 @@ protected override void setupExpired() protected double? couponLegBPS_, couponLegNPV_; protected double? upfrontBPS_, upfrontNPV_; protected double? defaultLegNPV_; - - + + public class Arguments : IPricingEngineArguments - { - public Arguments() - { + { + public Arguments() + { side = (Protection.Side)(-1); - notional = null; - spread = null; + notional = null; + spread = null; } public Protection.Side side; @@ -429,45 +429,45 @@ public Arguments() public bool settlesAccrual; public bool paysAtDefaultTime; public Claim claim; - public Date protectionStart; - public void validate() - { - Utils.QL_REQUIRE( side != (Protection.Side)( -1 ), () => "side not set" ); - Utils.QL_REQUIRE( notional != null, () => "notional not set" ); - Utils.QL_REQUIRE( notional != 0.0, () => "null notional set" ); - Utils.QL_REQUIRE( spread != null, () => "spread not set" ); - Utils.QL_REQUIRE( !leg.empty(), () => "coupons not set" ); - Utils.QL_REQUIRE( upfrontPayment != null, () => "upfront payment not set" ); - Utils.QL_REQUIRE( claim != null, () => "claim not set" ); - Utils.QL_REQUIRE( protectionStart != null, () => "protection start date not set" ); + public Date protectionStart; + public void validate() + { + Utils.QL_REQUIRE( side != (Protection.Side)( -1 ), () => "side not set" ); + Utils.QL_REQUIRE( notional != null, () => "notional not set" ); + Utils.QL_REQUIRE( notional != 0.0, () => "null notional set" ); + Utils.QL_REQUIRE( spread != null, () => "spread not set" ); + Utils.QL_REQUIRE( !leg.empty(), () => "coupons not set" ); + Utils.QL_REQUIRE( upfrontPayment != null, () => "upfront payment not set" ); + Utils.QL_REQUIRE( claim != null, () => "claim not set" ); + Utils.QL_REQUIRE( protectionStart != null, () => "protection start date not set" ); } - } - - + } + + public new class Results : Instrument.Results - { - public double? fairSpread; - public double? fairUpfront; - public double? couponLegBPS; - public double? couponLegNPV; - public double? defaultLegNPV; - public double? upfrontBPS; - public double? upfrontNPV; - public override void reset() - { + { + public double? fairSpread; + public double? fairUpfront; + public double? couponLegBPS; + public double? couponLegNPV; + public double? defaultLegNPV; + public double? upfrontBPS; + public double? upfrontNPV; + public override void reset() + { base.reset(); - fairSpread = null; - fairUpfront = null; - couponLegBPS = null; - couponLegNPV = null; - defaultLegNPV = null; - upfrontBPS = null; - upfrontNPV = null; + fairSpread = null; + fairUpfront = null; + couponLegBPS = null; + couponLegNPV = null; + defaultLegNPV = null; + upfrontBPS = null; + upfrontNPV = null; } - } - - public abstract class Engine : GenericEngine - {} - - } -} + } + + public abstract class Engine : GenericEngine + {} + + } +} diff --git a/QLNet/Instruments/DividendSchedule.cs b/QLNet/Instruments/DividendSchedule.cs index 5226843bb..047049dc1 100644 --- a/QLNet/Instruments/DividendSchedule.cs +++ b/QLNet/Instruments/DividendSchedule.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/DividendVanillaOption.cs b/QLNet/Instruments/DividendVanillaOption.cs index 9082f78fe..ff359c027 100644 --- a/QLNet/Instruments/DividendVanillaOption.cs +++ b/QLNet/Instruments/DividendVanillaOption.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -16,7 +16,7 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ +*/ using System; using System.Collections.Generic; using System.Linq; @@ -38,33 +38,33 @@ public DividendVanillaOption(StrikedTypePayoff payoff, Exercise exercise, /*! \warning see VanillaOption for notes on implied-volatility calculation. */ - public double impliedVolatility(double targetValue, GeneralizedBlackScholesProcess process, - double accuracy = 1.0e-4, int maxEvaluations = 100, double minVol = 1.0e-7, double maxVol = 4.0) + public double impliedVolatility(double targetValue, GeneralizedBlackScholesProcess process, + double accuracy = 1.0e-4, int maxEvaluations = 100, double minVol = 1.0e-7, double maxVol = 4.0) { - if (isExpired()) throw new ApplicationException("option expired"); - - SimpleQuote volQuote = new SimpleQuote(); - - GeneralizedBlackScholesProcess newProcess = ImpliedVolatilityHelper.clone(process, volQuote); - - // engines are built-in for the time being - IPricingEngine engine; - switch (exercise_.type()) - { - case Exercise.Type.European: - engine = new AnalyticDividendEuropeanEngine(newProcess); - break; - case Exercise.Type.American: - engine = new FDDividendAmericanEngine(newProcess); - break; - case Exercise.Type.Bermudan: - throw new ApplicationException("engine not available for Bermudan option with dividends"); - default: - throw new ArgumentException("unknown exercise type"); - } - - return ImpliedVolatilityHelper.calculate(this, engine, volQuote, targetValue, accuracy, + if (isExpired()) throw new ApplicationException("option expired"); + + SimpleQuote volQuote = new SimpleQuote(); + + GeneralizedBlackScholesProcess newProcess = ImpliedVolatilityHelper.clone(process, volQuote); + + // engines are built-in for the time being + IPricingEngine engine; + switch (exercise_.type()) + { + case Exercise.Type.European: + engine = new AnalyticDividendEuropeanEngine(newProcess); + break; + case Exercise.Type.American: + engine = new FDDividendAmericanEngine(newProcess); + break; + case Exercise.Type.Bermudan: + throw new ApplicationException("engine not available for Bermudan option with dividends"); + default: + throw new ArgumentException("unknown exercise type"); + } + + return ImpliedVolatilityHelper.calculate(this, engine, volQuote, targetValue, accuracy, maxEvaluations, minVol, maxVol); } diff --git a/QLNet/Instruments/EuropeanOption.cs b/QLNet/Instruments/EuropeanOption.cs index 94e72db52..38750843e 100644 --- a/QLNet/Instruments/EuropeanOption.cs +++ b/QLNet/Instruments/EuropeanOption.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/ImpliedVolatility.cs b/QLNet/Instruments/ImpliedVolatility.cs index 0e14c7307..c790f2459 100644 --- a/QLNet/Instruments/ImpliedVolatility.cs +++ b/QLNet/Instruments/ImpliedVolatility.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/InflationCapFloor.cs b/QLNet/Instruments/InflationCapFloor.cs index 44174f0be..4c72c6c3e 100644 --- a/QLNet/Instruments/InflationCapFloor.cs +++ b/QLNet/Instruments/InflationCapFloor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -72,7 +72,7 @@ public YoYInflationCapFloor(CapFloorType type, List yoyLeg, List yoyLeg, List infIndex_.availabilityLag(), () => "inconsistency between swap observation of index " + observationLag_ + " index availability " + infIndex_.availabilityLag() + @@ -103,7 +103,7 @@ public ZeroCouponInflationSwap(Type type, " need (obsLag-index period) > availLag"); } else - { + { Utils.QL_REQUIRE( infIndex_.availabilityLag() < observationLag_, () => "index tries to observe inflation fixings that do not yet exist: " + " availability lag " + infIndex_.availabilityLag() @@ -206,13 +206,13 @@ public override void fetchResults(IPricingEngineResults r) public double fixedLegNPV() { - calculate(); + calculate(); Utils.QL_REQUIRE( legNPV_[0] != null, () => "result not available" ); return legNPV_[0].Value; } public double inflationLegNPV() { - calculate(); + calculate(); Utils.QL_REQUIRE( legNPV_[1] != null, () => "result not available" ); return legNPV_[1].Value; } @@ -223,7 +223,7 @@ public double fairRate() // if it was created with _this_ rate // _knowing_ the time from base to obs (etc). - IndexedCashFlow icf = legs_[1][0] as IndexedCashFlow; + IndexedCashFlow icf = legs_[1][0] as IndexedCashFlow; Utils.QL_REQUIRE( icf != null, () => "failed to downcast to IndexedCashFlow in ::fairRate()" ); // +1 because the IndexedCashFlow has growthOnly=true @@ -265,8 +265,8 @@ public override void validate() base.validate(); // you don't actually need to do anything else because it is so simple } - } - + } + public class Engine : GenericEngine { }; } diff --git a/QLNet/Instruments/bmaswap.cs b/QLNet/Instruments/bmaswap.cs index b218fcfa5..a27791318 100644 --- a/QLNet/Instruments/bmaswap.cs +++ b/QLNet/Instruments/bmaswap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/fixedratebondforward.cs b/QLNet/Instruments/fixedratebondforward.cs index d8fc5798d..1c45377c9 100644 --- a/QLNet/Instruments/fixedratebondforward.cs +++ b/QLNet/Instruments/fixedratebondforward.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/forward.cs b/QLNet/Instruments/forward.cs index 0b11ee2f0..410e834ce 100644 --- a/QLNet/Instruments/forward.cs +++ b/QLNet/Instruments/forward.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/forwardrateagreement.cs b/QLNet/Instruments/forwardrateagreement.cs index dd777f7f3..79c66dc7c 100644 --- a/QLNet/Instruments/forwardrateagreement.cs +++ b/QLNet/Instruments/forwardrateagreement.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Instruments/payoffs.cs b/QLNet/Instruments/payoffs.cs index 90a53d662..b0ba38085 100644 --- a/QLNet/Instruments/payoffs.cs +++ b/QLNet/Instruments/payoffs.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/InterestRate.cs b/QLNet/InterestRate.cs index 7f0ca36f0..6c80a0425 100644 Binary files a/QLNet/InterestRate.cs and b/QLNet/InterestRate.cs differ diff --git a/QLNet/Math/Comparison.cs b/QLNet/Math/Comparison.cs index 2a793d1ef..49d23de1e 100644 --- a/QLNet/Math/Comparison.cs +++ b/QLNet/Math/Comparison.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Andrea Maggiulli - * This file is part of QLNet Project http://qlnet.sourceforge.net/ + * This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -34,7 +34,7 @@ public static partial class Utils { \f$ n \f$ equals 42 if not given. */ public static bool close(double x, double y) { return close(x, y, 42); } public static bool close(double x, double y, int n) { - double diff = System.Math.Abs(x - y), tolerance = n * Const.QL_Epsilon; + double diff = System.Math.Abs(x - y), tolerance = n * Const.QL_EPSILON; return diff <= tolerance * System.Math.Abs(x) && diff <= tolerance * System.Math.Abs(y); } @@ -47,7 +47,7 @@ public static bool close_enough(double x, double y) { } public static bool close_enough(double x, double y, int n) { - double diff = Math.Abs(x-y), tolerance = n*Const.QL_Epsilon; + double diff = Math.Abs(x-y), tolerance = n*Const.QL_EPSILON; return diff <= tolerance*Math.Abs(x) || diff <= tolerance*Math.Abs(y); } diff --git a/QLNet/Math/CostFunction.cs b/QLNet/Math/CostFunction.cs index 7f841bdd6..b9755d13b 100644 --- a/QLNet/Math/CostFunction.cs +++ b/QLNet/Math/CostFunction.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Distributions/GammaDistribution.cs b/QLNet/Math/Distributions/GammaDistribution.cs index 2723481b7..ea7c32507 100644 --- a/QLNet/Math/Distributions/GammaDistribution.cs +++ b/QLNet/Math/Distributions/GammaDistribution.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -55,13 +55,13 @@ public double value(double x) { double an = -1.0*n*(n-a_); b += 2.0; d = an*d + b; - if (Math.Abs(d) < Const.QL_Epsilon) d = Const.QL_Epsilon; + if (Math.Abs(d) < Const.QL_EPSILON) d = Const.QL_EPSILON; c = b + an/c; - if (Math.Abs(c) < Const.QL_Epsilon) c = Const.QL_Epsilon; + if (Math.Abs(c) < Const.QL_EPSILON) c = Const.QL_EPSILON; d = 1.0/d; double del = d*c; h *= del; - if (Math.Abs(del - 1.0)0.0)) throw new ApplicationException("positive argument required"); + public static double logValue( double x ) + { + if ( !( x > 0.0 ) ) throw new ApplicationException( "positive argument required" ); - double temp = x + 5.5; - temp -= (x + 0.5)*Math.Log(temp); - double ser=1.000000000190015; - ser += c1_/(x + 1.0); - ser += c2_/(x + 2.0); - ser += c3_/(x + 3.0); - ser += c4_/(x + 4.0); - ser += c5_/(x + 5.0); - ser += c6_/(x + 6.0); + double temp = x + 5.5; + temp -= ( x + 0.5 ) * Math.Log( temp ); + double ser = 1.000000000190015; + ser += c1_ / ( x + 1.0 ); + ser += c2_ / ( x + 2.0 ); + ser += c3_ / ( x + 3.0 ); + ser += c4_ / ( x + 4.0 ); + ser += c5_ / ( x + 5.0 ); + ser += c6_ / ( x + 6.0 ); - return -temp + Math.Log(2.5066282746310005 * ser / x); - } + return -temp + Math.Log( 2.5066282746310005 * ser / x ); + } + + public static double value( double x ) + { + if ( x >= 1.0 ) + { + return Math.Exp( logValue( x ) ); + } + else + { + if ( x > -20.0 ) + { + // \Gamma(x) = \frac{\Gamma(x+1)}{x} + return value( x + 1.0 ) / x; + } + else + { + // \Gamma(-x) = -\frac{\pi}{\Gamma(x)\sin(\pi x) x} + return -Const.M_PI / ( value( -x ) * x * Math.Sin( Const.M_PI * x ) ); + } + } + } } } diff --git a/QLNet/Math/Distributions/NormalDistribution.cs b/QLNet/Math/Distributions/NormalDistribution.cs index 9329f5ace..569acf024 100644 --- a/QLNet/Math/Distributions/NormalDistribution.cs +++ b/QLNet/Math/Distributions/NormalDistribution.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -104,7 +104,7 @@ public double value(double z) { g *= y; ++i; a = Math.Abs(a); - } while (lasta > a && a >= Math.Abs(sum * Const.QL_Epsilon)); + } while (lasta > a && a >= Math.Abs(sum * Const.QL_EPSILON)); result = -gaussian_.value(z) / z * sum; } return result; @@ -221,7 +221,7 @@ public double derivative(double x) { * erfc/erf(NaN) is NaN */ - const double tiny = Const.QL_Epsilon, + const double tiny = Const.QL_EPSILON, one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ /* c = (float)0.84506291151 */ erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ @@ -404,7 +404,7 @@ public double value(double x) { // try to recover if due to numerical error if (Utils.close_enough(x, 1.0)) { x = 1.0; - } else if (Math.Abs(x) < Const.QL_Epsilon) { + } else if (Math.Abs(x) < Const.QL_EPSILON) { x = 0.0; } else { throw new ApplicationException("InverseCumulativeNormal(" + x + ") undefined: must be 0 < x < 1"); diff --git a/QLNet/Math/Distributions/binomialdistribution.cs b/QLNet/Math/Distributions/binomialdistribution.cs index 922be5a66..2ce1973da 100644 --- a/QLNet/Math/Distributions/binomialdistribution.cs +++ b/QLNet/Math/Distributions/binomialdistribution.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Distributions/chisquaredistribution.cs b/QLNet/Math/Distributions/chisquaredistribution.cs index 5e18b126f..b4fc86b9b 100644 --- a/QLNet/Math/Distributions/chisquaredistribution.cs +++ b/QLNet/Math/Distributions/chisquaredistribution.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -60,8 +60,8 @@ public double value(double x) double f_x_2n = df_ - x; double t = 0.0; - if (f2 * Const.QL_Epsilon > 0.125 && - Math.Abs(x2-f2) < Math.Sqrt(Const.QL_Epsilon)*f2) { + if (f2 * Const.QL_EPSILON > 0.125 && + Math.Abs(x2-f2) < Math.Sqrt(Const.QL_EPSILON)*f2) { t = Math.Exp((1 - t) * (2 - t / (f2 + 1))) / Math.Sqrt(2.0 * Const.M_PI * (f2 + 1.0)); } diff --git a/QLNet/Math/Distributions/poissondistribution.cs b/QLNet/Math/Distributions/poissondistribution.cs index 72206913b..5e27efa94 100644 --- a/QLNet/Math/Distributions/poissondistribution.cs +++ b/QLNet/Math/Distributions/poissondistribution.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Interpolation.cs b/QLNet/Math/Interpolation.cs index 55e1b1844..d00f81af9 100644 --- a/QLNet/Math/Interpolation.cs +++ b/QLNet/Math/Interpolation.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Interpolations/BicubicSplineInterpolation.cs b/QLNet/Math/Interpolations/BicubicSplineInterpolation.cs new file mode 100644 index 000000000..f9a9e608d --- /dev/null +++ b/QLNet/Math/Interpolations/BicubicSplineInterpolation.cs @@ -0,0 +1,183 @@ +/* + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + public interface IBicubicSplineDerivatives + { + double derivativeX( double x, double y ); + double derivativeY( double x, double y ); + double derivativeXY( double x, double y ); + double secondDerivativeX( double x, double y ); + double secondDerivativeY( double x, double y ); + } + + public class BicubicSplineImpl : Interpolation2D.templateImpl,IBicubicSplineDerivatives + { + public BicubicSplineImpl(List xBegin, int size, List yBegin,int ySize,Matrix zData) + : base(xBegin,size, yBegin,ySize,zData) + { + calculate(); + } + + public override void calculate() + { + splines_ = new List (this.zData_.rows()); + for (int i=0; i<(this.zData_.rows()); ++i) + splines_.Add( new CubicInterpolation( this.xBegin_, this.xSize_, this.zData_.row(i), + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); + + } + + public override double value(double x, double y) + { + List section = new InitializedList( splines_.Count ); + for (int i=0; i section = new InitializedList(this.zData_.columns()); + for (int i=0; i < section.Count; ++i) + { + section[i] = value(this.xBegin_[i], y); + } + + return new CubicInterpolation( this.xBegin_, this.xSize_, section, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0).derivative(x); + } + + + public double secondDerivativeX(double x, double y) + { + List section = new InitializedList( this.zData_.columns() ); + for (int i=0; i < section.Count; ++i) + { + section[i] = value(this.xBegin_[i], y); + } + + return new CubicInterpolation( this.xBegin_, this.xSize_, section, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0).secondDerivative(x); + } + + + public double derivativeY(double x, double y) + { + List section = new InitializedList( splines_.Count ); + for (int i=0; i section = new InitializedList( splines_.Count ); + for (int i=0; i section = new InitializedList( this.zData_.columns() ); + for (int i=0; i < section.Count; ++i) + { + section[i] = derivativeY(this.xBegin_[i], y); + } + + return new CubicInterpolation( this.xBegin_, this.xSize_, section, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0).derivative(x); + } + + + private List splines_; + + } + + + //! bicubic-spline interpolation between discrete points + /*! \todo revise end conditions */ + public class BicubicSpline : Interpolation2D + { + /*! \pre the \f$ x \f$ and \f$ y \f$ values must be sorted. */ + public BicubicSpline( List xBegin, int size, List yBegin,int ySize,Matrix zData) + { + impl_ = new BicubicSplineImpl(xBegin, size, yBegin, ySize, zData); + } + + public double derivativeX(double x, double y) { + return ((IBicubicSplineDerivatives)impl_).derivativeX(x, y); + } + + public double derivativeY(double x, double y) { + return ( (IBicubicSplineDerivatives)impl_ ).derivativeY( x, y ); + } + + public double secondDerivativeX(double x, double y) { + return ( (IBicubicSplineDerivatives)impl_ ).secondDerivativeX( x, y ); + } + + public double secondDerivativeY(double x, double y) { + return ( (IBicubicSplineDerivatives)impl_ ).secondDerivativeY( x, y ); + } + + public double derivativeXY( double x, double y ) + { + return ( (IBicubicSplineDerivatives)impl_ ).derivativeXY( x, y ); + } + } + + //! bicubic-spline-interpolation factory + public class Bicubic + { + public Interpolation2D interpolate(List xBegin, int size, List yBegin,int ySize,Matrix zData) + { + return new BicubicSpline( xBegin, size, yBegin, ySize, zData ); + } + } + +} diff --git a/QLNet/Math/Interpolations/CubicInterpolation.cs b/QLNet/Math/Interpolations/CubicInterpolation.cs index 6079fa417..6758a6820 100644 --- a/QLNet/Math/Interpolations/CubicInterpolation.cs +++ b/QLNet/Math/Interpolations/CubicInterpolation.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Interpolations/Extrapolator.cs b/QLNet/Math/Interpolations/Extrapolator.cs index 2272f9dd1..e6cb17bba 100644 Binary files a/QLNet/Math/Interpolations/Extrapolator.cs and b/QLNet/Math/Interpolations/Extrapolator.cs differ diff --git a/QLNet/Math/Interpolations/KernelInterpolation.cs b/QLNet/Math/Interpolations/KernelInterpolation.cs new file mode 100644 index 000000000..1fb9fe325 --- /dev/null +++ b/QLNet/Math/Interpolations/KernelInterpolation.cs @@ -0,0 +1,159 @@ +/* + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + + public class KernelInterpolationImpl : Interpolation.templateImpl where Kernel: IKernelFunction + { + public KernelInterpolationImpl(List xBegin, int size, List yBegin,Kernel kernel) + :base( xBegin, size, yBegin ) + { + xSize_ = size; + invPrec_ = 1.0e-7; + M_ = new Matrix(xSize_,xSize_); + alphaVec_ = new Vector(xSize_); + yVec_ = new Vector(xSize_); + kernel_ = kernel; + } + + public override void update() + { + updateAlphaVec(); + } + + public override double value(double x) + { + double res=0.0; + for( int i=0; i< xSize_;++i) + { + res+=alphaVec_[i]*kernelAbs(x,this.xBegin_[i]); + } + return res/gammaFunc(x); + } + + public override double primitive(double d) + { + Utils.QL_FAIL("Primitive calculation not implemented for kernel interpolation"); + return 0; + } + + public override double derivative(double d) + { + Utils.QL_FAIL("First derivative calculation not implemented for kernel interpolation"); + return 0; + } + + public override double secondDerivative(double d) + { + Utils.QL_FAIL("Second derivative calculation not implemented for kernel interpolation"); + return 0; + } + + // the calculation will solve y=M*a for a. Due to + // singularity or rounding errors the recalculation + // M*a may not give y. Here, a failure will be thrown if + // |M*a-y|>=invPrec_ + + public void setInverseResultPrecision(double invPrec) { invPrec_=invPrec; } + + private double kernelAbs(double x1, double x2){ return kernel_.value(Math.Abs(x1-x2)); } + + private double gammaFunc(double x) + { + double res=0.0; + + for(int i=0; i< xSize_;++i) + { + res+=kernelAbs(x,this.xBegin_[i]); + } + return res; + } + + private void updateAlphaVec() + { + // Function calculates the alpha vector with given + // fixed pillars+values + + // Write Matrix M + double tmp=0.0; + + for(int rowIt=0; rowIt + "Inversion failed in 1d kernel interpolation"); + } + + } + + private int xSize_; + private double invPrec_; + private Matrix M_; + private Vector alphaVec_, yVec_; + private Kernel kernel_; + + } + + //! Kernel interpolation between discrete points + /*! Implementation of the kernel interpolation approach, which can + be found in "Foreign Exchange Risk" by Hakala, Wystup page + 256. + + The kernel in the implementation is kept general, although a Gaussian + is considered in the cited text. + */ + public class KernelInterpolation : Interpolation + { + + /*! \pre the \f$ x \f$ values must be sorted. + \pre kernel needs a Real operator()(Real x) implementation + */ + public KernelInterpolation(List xBegin, int size, List yBegin,IKernelFunction kernel) + { + impl_ = new KernelInterpolationImpl( xBegin, size, yBegin, kernel ); + impl_.update(); + } + }; + + +} diff --git a/QLNet/Math/Interpolations/KernelInterpolation2D.cs b/QLNet/Math/Interpolations/KernelInterpolation2D.cs new file mode 100644 index 000000000..5cc42e694 --- /dev/null +++ b/QLNet/Math/Interpolations/KernelInterpolation2D.cs @@ -0,0 +1,205 @@ +/* + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + /* + Grid Explanation: + + Grid=[ (x1,y1) (x1,y2) (x1,y3)... (x1,yM); + (x2,y1) (x2,y2) (x2,y3)... (x2,yM); + . + . + . + (xN,y1) (xN,y2) (xN,y3)... (xN,yM); + ] + + The Passed variables are: + - x which is N dimensional + - y which is M dimensional + - zData which is NxM dimensional and has the z values + corresponding to the grid above. + - kernel is a template which needs a Real operator()(Real x) implementation + */ + public class KernelInterpolation2DImpl : Interpolation2D.templateImpl where Kernel: IKernelFunction + { + public KernelInterpolation2DImpl(List xBegin, int size, List yBegin,int ySize, + Matrix zData, Kernel kernel) + :base( xBegin, size, yBegin,ySize,zData ) + { + xSize_ = size; + ySize_ = yBegin.Count; + xySize_ = xSize_*ySize_; + invPrec_ = 1.0e-10; + alphaVec_ = new Vector(xySize_); + yVec_ = new Vector(xySize_); + M_ = new Matrix(xySize_,xySize_); + kernel_ = kernel; + + Utils.QL_REQUIRE(zData.rows()==xSize_,()=> + "Z value matrix has wrong number of rows"); + Utils.QL_REQUIRE( zData.columns() == ySize_, () => + "Z value matrix has wrong number of columns"); + } + + public override void calculate() { updateAlphaVec(); } + + public override double value(double x1, double x2) + { + double res=0.0; + + Vector X = new Vector(2),Xn = new Vector(2); + X[0]=x1;X[1]=x2; + + int cnt=0; // counter + + for( int j=0; j< ySize_;++j){ + for( int i=0; i< xSize_;++i) + { + Xn[0]=this.xBegin_[i]; + Xn[1]=this.yBegin_[j]; + res+=alphaVec_[cnt]*kernelAbs(X,Xn); + cnt++; + } + } + return res/gammaFunc(X); + } + + // the calculation will solve y=M*a for a. Due to + // singularity or rounding errors the recalculation + // M*a may not give y. Here, a failure will be thrown if + // |M*a-y|>=invPrec_ + void setInverseResultPrecision(double invPrec){invPrec_=invPrec;} + + + // returns K(||X-Y||) where X,Y are vectors + private double kernelAbs(Vector X, Vector Y) + { + return kernel_.value( vecNorm( X - Y ) ); + } + + private double vecNorm(Vector X) + { + return Math.Sqrt(Vector.DotProduct(X,X)); + } + + private double gammaFunc(Vector X) + { + double res=0.0; + Vector Xn = new Vector(X.size()); + + for(int j=0; j< ySize_;++j) + { + for(int i=0; i< xSize_;++i) + { + Xn[0]=this.xBegin_[i]; + Xn[1]=this.yBegin_[j]; + res+=kernelAbs(X,Xn); + } + } + + return res; + } + + private void updateAlphaVec() + { + // Function calculates the alpha vector with given + // fixed pillars+values + + Vector Xk = new Vector(2),Xn = new Vector(2); + + int rowCnt=0,colCnt=0; + double tmpVar=0.0; + + // write y-vector and M-Matrix + for(int j=0; j< ySize_;++j) + { + for(int i=0; i< xSize_;++i) + { + yVec_[rowCnt]=this.zData_[i,j]; + // calculate X_k + Xk[0]=this.xBegin_[i]; + Xk[1]=this.yBegin_[j]; + + tmpVar=1/gammaFunc(Xk); + colCnt=0; + + for(int jM=0; jM< ySize_;++jM) + { + for(int iM=0; iM< xSize_;++iM) + { + Xn[0]=this.xBegin_[iM]; + Xn[1]=this.yBegin_[jM]; + M_[rowCnt,colCnt]=kernelAbs(Xk,Xn)*tmpVar; + colCnt++; // increase column counter + }// end iM + }// end jM + rowCnt++; // increase row counter + } // end i + }// end j + + alphaVec_= MatrixUtilities.qrSolve(M_, yVec_); + + // check if inversion worked up to a reasonable precision. + // I've chosen not to check determinant(M_)!=0 before solving + + Vector diffVec=Vector.Abs(M_*alphaVec_ - yVec_); + for (int i=0; i + "inversion failed in 2d kernel interpolation"); + } + } + + private int xySize_; // xSize_,ySize_, + private double invPrec_; + private Vector alphaVec_, yVec_; + private Matrix M_; + private Kernel kernel_; + +} + + /*! Implementation of the 2D kernel interpolation approach, which + can be found in "Foreign Exchange Risk" by Hakala, Wystup page + 256. + + The kernel in the implementation is kept general, although a + Gaussian is considered in the cited text. + */ + public class KernelInterpolation2D : Interpolation2D + { + + /*! \pre the \f$ x \f$ values must be sorted. + \pre kernel needs a Real operator()(Real x) implementation + + */ + + + public KernelInterpolation2D(List xBegin, int size, List yBegin,int ySize, + Matrix zData, IKernelFunction kernel) + { + + impl_ = new KernelInterpolation2DImpl( xBegin, size, yBegin, ySize, zData, kernel ); + this.update(); + } + } +} diff --git a/QLNet/Math/Interpolations/Linearinterpolation.cs b/QLNet/Math/Interpolations/Linearinterpolation.cs index da5a57acf..dcf046f3e 100644 --- a/QLNet/Math/Interpolations/Linearinterpolation.cs +++ b/QLNet/Math/Interpolations/Linearinterpolation.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Interpolations/Loginterpolation.cs b/QLNet/Math/Interpolations/Loginterpolation.cs index 554d9f507..470ee9b20 100644 --- a/QLNet/Math/Interpolations/Loginterpolation.cs +++ b/QLNet/Math/Interpolations/Loginterpolation.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Interpolations/XABRInterpolation.cs b/QLNet/Math/Interpolations/XABRInterpolation.cs new file mode 100644 index 000000000..a20d88a64 --- /dev/null +++ b/QLNet/Math/Interpolations/XABRInterpolation.cs @@ -0,0 +1,326 @@ +/* + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + public interface IWrapper + { + double volatility( double x ); + } + + public interface IModel + { + //IModel modelInstance_ { get; set; } + void defaultValues( List param, List b, double forward, double expiryTIme ); + double dilationFactor(); + int dimension(); + Vector direct( Vector x, List b, List c, double d ); + double eps1(); + double eps2(); + void guess( Vector values, List paramIsFixed, double forward, double expiryTime, List r ); + IWrapper instance( double t, double forward, List param ); + Vector inverse( Vector y, List b, List c, double d ); + //double volatility( double x ); + } + + public class XABRCoeffHolder where Model : IModel, new() + { + public XABRCoeffHolder( double t, double forward, List _params, List paramIsFixed ) + { + t_ = t; + forward_ = forward; + params_ = _params; + paramIsFixed_ = new InitializedList( paramIsFixed.Count, false ); + weights_ = new List(); + error_ = null; + maxError_ = null; + XABREndCriteria_ = EndCriteria.Type.None; + + Utils.QL_REQUIRE( t > 0.0, () => "expiry time must be positive: " + t + " not allowed" ); + Utils.QL_REQUIRE( _params.Count == new Model().dimension(), () => + "wrong number of parameters (" + _params.Count + + "), should be " + + new Model().dimension() ); + Utils.QL_REQUIRE( paramIsFixed.Count == new Model().dimension(), () => + "wrong number of fixed parameters flags (" + paramIsFixed.Count + "), should be " + + new Model().dimension() ); + + for ( int i = 0; i < _params.Count; ++i ) + { + if ( _params[i] != null ) + paramIsFixed_[i] = paramIsFixed[i]; + } + new Model().defaultValues( params_, paramIsFixed_, forward_, t_ ); + updateModelInstance(); + } + + public void updateModelInstance() + { + // forward might have changed + Utils.QL_REQUIRE( forward_ > 0.0, () => "forward must be positive: " + forward_ + " not allowed" ); + modelInstance_ = new Model().instance( t_, forward_, params_ ); + model_ = new Model(); + } + + /*! Expiry, Forward */ + public double t_; + public double forward_; + /*! Parameters */ + public List params_; + public List paramIsFixed_; + public List weights_; + /*! Interpolation results */ + public double? error_, maxError_; + public EndCriteria.Type XABREndCriteria_; + /*! Model instance (if required) */ + public IWrapper modelInstance_; + public IModel model_; + + } + + //template + public class XABRInterpolationImpl : Interpolation.templateImpl where Model : IModel, new() + { + public XABRInterpolationImpl( List xBegin, int size, List yBegin, double t, + double forward, List _params, + List paramIsFixed, bool vegaWeighted, + EndCriteria endCriteria, + OptimizationMethod optMethod, + double errorAccept, bool useMaxError, int maxGuesses ) + : base( xBegin, size, yBegin ) + { + // XABRCoeffHolder(t, forward, params, paramIsFixed), + endCriteria_ = endCriteria; + optMethod_ = optMethod; + errorAccept_ = errorAccept; + useMaxError_ = useMaxError; + maxGuesses_ = maxGuesses; + forward_ = forward; + vegaWeighted_ = vegaWeighted; + + // if no optimization method or endCriteria is provided, we provide one + if (optMethod_ == null) + optMethod_ = new LevenbergMarquardt(1e-8, 1e-8, 1e-8); + // optMethod_ = boost::shared_ptr(new + // Simplex(0.01)); + if (endCriteria_ == null) + { + endCriteria_ = new EndCriteria(60000, 100, 1e-8, 1e-8, 1e-8); + } + coeff_ = new XABRCoeffHolder( t, forward, _params, paramIsFixed ); + this.coeff_.weights_ = new InitializedList( size, 1.0 / size ); + } + + public override void update() + { + this.coeff_.updateModelInstance(); + + // we should also check that y contains positive values only + + // we must update weights if it is vegaWeighted + if (vegaWeighted_) + { + coeff_.weights_.Clear(); + double weightsSum = 0.0; + + for ( int i = 0; i < xBegin_.Count; i++ ) + { + double stdDev = Math.Sqrt( ( yBegin_[i] ) * ( yBegin_[i] ) * this.coeff_.t_ ); + coeff_.weights_.Add( Utils.blackFormulaStdDevDerivative( xBegin_[i], forward_, stdDev ) ); + weightsSum += coeff_.weights_.Last(); + } + + // weight normalization + for( int i = 0 ; i < coeff_.weights_.Count; i++ ) + coeff_.weights_[i] /= weightsSum; + } + + // there is nothing to optimize + if ( coeff_.paramIsFixed_.Aggregate( ( a, b ) => b & a ) ) + { + coeff_.error_ = interpolationError(); + coeff_.maxError_ = interpolationMaxError(); + coeff_.XABREndCriteria_ = EndCriteria.Type.None; + return; + } + else + { + XABRError costFunction = new XABRError( this ); + + Vector guess = new Vector( coeff_.model_.dimension() ); + for ( int i = 0; i < guess.size(); ++i ) + guess[i] = coeff_.params_[i].Value; + + int iterations = 0; + int freeParameters = 0; + double bestError = double.MaxValue; + Vector bestParameters = new Vector(); + for (int i = 0; i < coeff_.model_.dimension(); ++i) + if (!coeff_.paramIsFixed_[i]) + ++freeParameters; + HaltonRsg halton = new HaltonRsg(freeParameters, 42); + EndCriteria.Type tmpEndCriteria; + double tmpInterpolationError; + + do { + + if (iterations > 0) { + Sample > s = halton.nextSequence(); + coeff_.model_.guess(guess, coeff_.paramIsFixed_, forward_, coeff_.t_, s.value); + for (int i = 0; i < coeff_.paramIsFixed_.Count; ++i) + if (coeff_.paramIsFixed_[i]) + guess[i] = coeff_.params_[i].Value; + } + + Vector inversedTransformatedGuess = new Vector(coeff_.model_.inverse(guess, coeff_.paramIsFixed_, coeff_.params_, forward_)); + + ProjectedCostFunction rainedXABRError = new ProjectedCostFunction(costFunction, inversedTransformatedGuess, + coeff_.paramIsFixed_); + + Vector projectedGuess = new Vector(rainedXABRError.project(inversedTransformatedGuess)); + + NoConstraint raint = new NoConstraint(); + Problem problem = new Problem(rainedXABRError, raint, projectedGuess); + tmpEndCriteria = optMethod_.minimize(problem, endCriteria_); + // TEST + // coeff_.params_[3] = 0.0099999966589763966; + // TEST + Vector projectedResult = new Vector(problem.currentValue()); + Vector transfResult = new Vector(rainedXABRError.include(projectedResult)); + //transfResult[3] = 0.0099999966589763966; ; + Vector result = coeff_.model_.direct( transfResult, coeff_.paramIsFixed_, coeff_.params_, forward_ ); + //result[3] = 0.0099999966589763966; + tmpInterpolationError = useMaxError_ ? interpolationMaxError() + : interpolationError(); + + if (tmpInterpolationError < bestError) + { + bestError = tmpInterpolationError; + bestParameters = result; + coeff_.XABREndCriteria_ = tmpEndCriteria; + } + + } while (++iterations < maxGuesses_ && + tmpInterpolationError > errorAccept_); + + for (int i = 0; i < bestParameters.size(); ++i) + coeff_.params_[i] = bestParameters[i]; + + coeff_.error_ = interpolationError(); + coeff_.maxError_ = interpolationMaxError(); + } + } + + public override double value( double x ) + { + Utils.QL_REQUIRE( x > 0.0, () => "strike must be positive: " + x + " not allowed" ); + return coeff_.modelInstance_.volatility( x ); + } + + public override double primitive( double d ) { Utils.QL_FAIL( "XABR primitive not implemented" ); return 0; } + public override double derivative( double d ) { Utils.QL_FAIL( "XABR derivative not implemented" ); return 0; } + public override double secondDerivative( double d ) { Utils.QL_FAIL( "XABR secondDerivative not implemented" ); return 0; } + + // calculate total squared weighted difference (L2 norm) + public double interpolationSquaredError() + { + double error, totalError = 0.0; + for ( int i = 0; i < xBegin_.Count; i++ ) + { + error = ( value( xBegin_[i] ) - yBegin_[i] ); + totalError += error * error * ( coeff_.weights_[i] ); + } + return totalError; + } + + // calculate weighted differences + public Vector interpolationErrors( Vector v ) + { + Vector results = new Vector(xBegin_.Count); + + for ( int i = 0 ; i < xBegin_.Count ; i++) + results[i] = (value(xBegin_[i]) - yBegin_[i]) * Math.Sqrt(coeff_.weights_[i]); + + return results; + + + } + + public double interpolationError() + { + int n = xBegin_.Count; + double squaredError = interpolationSquaredError(); + return Math.Sqrt(n * squaredError / (n - 1)); + } + + public double interpolationMaxError() + { + double error, maxError = Double.MinValue; + + for ( int i = 0 ; i < xBegin_.Count ; i++) + { + error = Math.Abs(value(xBegin_[i]) - yBegin_[i]); + maxError = Math.Max(maxError, error); + } + + return maxError; + } + + + private class XABRError : CostFunction + { + public XABRError( XABRInterpolationImpl xabr ) { xabr_ = xabr; } + + public override double value( Vector x ) + { + Vector y = new Model().direct( x, xabr_.coeff_.paramIsFixed_, xabr_.coeff_.params_, xabr_.forward_ ); + for ( int i = 0; i < xabr_.coeff_.params_.Count; ++i ) + xabr_.coeff_.params_[i] = y[i]; + xabr_.coeff_.updateModelInstance(); + return xabr_.interpolationSquaredError(); + } + + public override Vector values( Vector x ) + { + Vector y = new Model().direct( x, xabr_.coeff_.paramIsFixed_, xabr_.coeff_.params_, xabr_.forward_ ); + for ( int i = 0; i < xabr_.coeff_.params_.Count; ++i ) + xabr_.coeff_.params_[i] = y[i]; + xabr_.coeff_.updateModelInstance(); + return xabr_.interpolationErrors( x ); + } + + private XABRInterpolationImpl xabr_; + } + + private EndCriteria endCriteria_; + private OptimizationMethod optMethod_; + private double errorAccept_; + private bool useMaxError_; + private int maxGuesses_; + private double forward_; + private bool vegaWeighted_; + //private NoConstraint constraint_; + public XABRCoeffHolder coeff_; + }; + +} diff --git a/QLNet/Math/Interpolations/backwardflatinterpolation.cs b/QLNet/Math/Interpolations/backwardflatinterpolation.cs index 238967646..8f6d51ae5 100644 --- a/QLNet/Math/Interpolations/backwardflatinterpolation.cs +++ b/QLNet/Math/Interpolations/backwardflatinterpolation.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -69,7 +69,7 @@ public BackwardFlatInterpolation(List xBegin, int size, List yBe //! Backward-flat interpolation factory and traits public class BackwardFlat : IInterpolationFactory { - public Interpolation interpolate(List xBegin, int size, List yBegin) { + public Interpolation interpolate(List xBegin, int size, List yBegin) { return new BackwardFlatInterpolation( xBegin, size, yBegin ); } public bool global { get { return false; } } diff --git a/QLNet/Math/Interpolations/bilinearinterpolation.cs b/QLNet/Math/Interpolations/bilinearinterpolation.cs index 499e87b17..9293aa9c2 100644 --- a/QLNet/Math/Interpolations/bilinearinterpolation.cs +++ b/QLNet/Math/Interpolations/bilinearinterpolation.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Interpolations/convexmonotoneinterpolation.cs b/QLNet/Math/Interpolations/convexmonotoneinterpolation.cs index 2917bf4d1..f5b4c4393 100644 --- a/QLNet/Math/Interpolations/convexmonotoneinterpolation.cs +++ b/QLNet/Math/Interpolations/convexmonotoneinterpolation.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Interpolations/forwardflatinterpolation.cs b/QLNet/Math/Interpolations/forwardflatinterpolation.cs index 8c17e1b3e..a39133211 100644 --- a/QLNet/Math/Interpolations/forwardflatinterpolation.cs +++ b/QLNet/Math/Interpolations/forwardflatinterpolation.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Interpolations/interpolation2d.cs b/QLNet/Math/Interpolations/interpolation2d.cs index 6a3a37415..981532803 100644 --- a/QLNet/Math/Interpolations/interpolation2d.cs +++ b/QLNet/Math/Interpolations/interpolation2d.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Interpolations/multicubicspline.cs b/QLNet/Math/Interpolations/multicubicspline.cs index 4a80d4f7d..f34e702a7 100644 --- a/QLNet/Math/Interpolations/multicubicspline.cs +++ b/QLNet/Math/Interpolations/multicubicspline.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Interpolations/sabrinterpolation.cs b/QLNet/Math/Interpolations/sabrinterpolation.cs index 4047524a4..2840efdf7 100644 --- a/QLNet/Math/Interpolations/sabrinterpolation.cs +++ b/QLNet/Math/Interpolations/sabrinterpolation.cs @@ -1,7 +1,7 @@ /* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -15,11 +15,203 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + public class SABRWrapper : IWrapper + { + public SABRWrapper( double t, double forward, List param ) + { + t_ = t; + forward_ = forward; + params_ = param; + Utils.validateSabrParameters( param[0].Value, param[1].Value, param[2].Value, param[3].Value ); + } + public double volatility( double x ) + { + return Utils.sabrVolatility( x, forward_, t_, params_[0].Value, params_[1].Value, params_[2].Value, params_[3].Value ); + } + + private double t_, forward_; + private List params_; + } + + public struct SABRSpecs : IModel + { + //private SABRWrapper wrapper; + + public int dimension() { return 4; } + public void defaultValues( List param, List b, double forward, double expiryTIme ) + { + if ( param[1] == null ) + param[1] = 0.5; + if ( param[0] == null ) + // adapt alpha to beta level + param[0] = 0.2 * ( param[1] < 0.9999 ? Math.Pow( forward, 1.0 - param[1].Value ) : 1.0 ); + if ( param[2] == null ) + param[2] = Math.Sqrt( 0.4 ); + if ( param[3] == null ) + param[3] = 0.0; + } + + public void guess( Vector values, List paramIsFixed, double forward, double expiryTime, List r ) + { + int j = 0; + if ( !paramIsFixed[1] ) + values[1] = ( 1.0 - 2E-6 ) * r[j++] + 1E-6; + if ( !paramIsFixed[0] ) + { + values[0] = ( 1.0 - 2E-6 ) * r[j++] + 1E-6; // lognormal vol guess + // adapt this to beta level + if ( values[1] < 0.999 ) + values[0] *= Math.Pow( forward, 1.0 - values[1] ); + } + if ( !paramIsFixed[2] ) + values[2] = 1.5 * r[j++] + 1E-6; + if ( !paramIsFixed[3] ) + values[3] = ( 2.0 * r[j++] - 1.0 ) * ( 1.0 - 1E-6 ); + } + + public double eps1() { return .0000001; } + public double eps2() { return .9999; } + public double dilationFactor() { return 0.001; } + public Vector inverse( Vector y, List b, List c, double d ) + { + Vector x = new Vector( 4 ); + x[0] = y[0] < 25.0 + eps1() ? Math.Sqrt( y[0] - eps1() ) + : ( y[0] - eps1() + 25.0 ) / 10.0; + // y_[1] = std::tan(M_PI*(x[1] - 0.5))/dilationFactor(); + x[1] = Math.Sqrt( -Math.Log( y[1] ) ); + x[2] = y[2] < 25.0 + eps1() ? Math.Sqrt( y[2] - eps1() ) + : ( y[2] - eps1() + 25.0 ) / 10.0; + x[3] = Math.Asin( y[3] / eps2() ); + return x; + } + public Vector direct( Vector x, List b, List c, double d ) + { + Vector y = new Vector( 4 ); + y[0] = Math.Abs( x[0] ) < 5.0 + ? x[0] * x[0] + eps1() + : ( 10.0 * Math.Abs( x[0] ) - 25.0 ) + eps1(); + // y_[1] = std::atan(dilationFactor_*x[1])/M_PI + 0.5; + y[1] = Math.Abs( x[1] ) < Math.Sqrt( -Math.Log( eps1() ) ) + ? Math.Exp( -( x[1] * x[1] ) ) + : eps1(); + y[2] = Math.Abs( x[2] ) < 5.0 + ? x[2] * x[2] + eps1() + : ( 10.0 * Math.Abs( x[2] ) - 25.0 ) + eps1(); + y[3] = Math.Abs( x[3] ) < 2.5 * Const.M_PI + ? eps2() * Math.Sin( x[3] ) + : eps2() * ( x[3] > 0.0 ? 1.0 : ( -1.0 ) ); + return y; + } + public IWrapper instance( double t, double forward, List param ) + { + return new SABRWrapper( t, forward, param ); + } + public SABRWrapper modelInstance_ { get; set; } + } + + //! %SABR smile interpolation between discrete volatility points. + public class SABRInterpolation : Interpolation + { + public SABRInterpolation( List xBegin, // x = strikes + int xEnd, + List yBegin, // y = volatilities + double t, // option expiry + double forward, + double? alpha, + double? beta, + double? nu, + double? rho, + bool alphaIsFixed, + bool betaIsFixed, + bool nuIsFixed, + bool rhoIsFixed, + bool vegaWeighted = true, + EndCriteria endCriteria = null, + OptimizationMethod optMethod = null, + double errorAccept = 0.0020, + bool useMaxError = false, + int maxGuesses = 50 ) + { -namespace QLNet { + impl_ = new XABRInterpolationImpl( + xBegin, xEnd, yBegin, t, forward, + new List(){alpha,beta,nu,rho}, + //boost::assign::list_of(alpha)(beta)(nu)(rho), + new List(){alphaIsFixed,betaIsFixed,nuIsFixed,rhoIsFixed}, + //boost::assign::list_of(alphaIsFixed)(betaIsFixed)(nuIsFixed)(rhoIsFixed), + vegaWeighted, endCriteria, optMethod, errorAccept, useMaxError, + maxGuesses); + coeffs_ = (impl_ as XABRInterpolationImpl).coeff_; + } + public double expiry() { return coeffs_.t_; } + public double forward() { return coeffs_.forward_; } + public double alpha() { return coeffs_.params_[0].Value; } + public double beta() { return coeffs_.params_[1].Value; } + public double nu() { return coeffs_.params_[2].Value; } + public double rho() { return coeffs_.params_[3].Value; } + public double rmsError() { return coeffs_.error_.Value; } + public double maxError() { return coeffs_.maxError_.Value; } + public List interpolationWeights() { return coeffs_.weights_; } + public EndCriteria.Type endCriteria() { return coeffs_.XABREndCriteria_; } + + private XABRCoeffHolder coeffs_; + } + + //! %SABR interpolation factory and traits + public class SABR + { + public SABR(double t, double forward, double alpha, double beta, double nu, double rho, + bool alphaIsFixed, bool betaIsFixed, bool nuIsFixed, bool rhoIsFixed, + bool vegaWeighted = false, + EndCriteria endCriteria = null, + OptimizationMethod optMethod = null, + double errorAccept = 0.0020, bool useMaxError = false,int maxGuesses = 50) + { + t_ = t; + forward_ = forward; + alpha_ = alpha; + beta_ = beta; + nu_ = nu; + rho_ = rho; + alphaIsFixed_ = alphaIsFixed; + betaIsFixed_ = betaIsFixed; + nuIsFixed_ = nuIsFixed; + rhoIsFixed_ = rhoIsFixed; + vegaWeighted_ = vegaWeighted; + endCriteria_ = endCriteria; + optMethod_ = optMethod; + errorAccept_ = errorAccept; + useMaxError_ = useMaxError; + maxGuesses_ = maxGuesses; + } + + Interpolation interpolate(List xBegin, int xEnd,List yBegin) + { + return new SABRInterpolation( xBegin, xEnd, yBegin, t_, forward_, alpha_, beta_, nu_, rho_, + alphaIsFixed_, betaIsFixed_, nuIsFixed_, rhoIsFixed_, vegaWeighted_, + endCriteria_, optMethod_, errorAccept_, useMaxError_, maxGuesses_); + } + public static bool global = true; + + + private double t_; + private double forward_; + private double alpha_, beta_, nu_, rho_; + private bool alphaIsFixed_, betaIsFixed_, nuIsFixed_, rhoIsFixed_; + private bool vegaWeighted_; + private EndCriteria endCriteria_; + private OptimizationMethod optMethod_; + private double errorAccept_; + private bool useMaxError_; + private int maxGuesses_; + } } + diff --git a/QLNet/Math/KernelFunctions.cs b/QLNet/Math/KernelFunctions.cs new file mode 100644 index 000000000..e9794d822 --- /dev/null +++ b/QLNet/Math/KernelFunctions.cs @@ -0,0 +1,70 @@ +/* + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + /*! Kernel function in the statistical sense, e.g. a nonnegative, + real-valued function which integrates to one and is symmetric. + + Derived classes will serve as functors. + */ + + public interface IKernelFunction + { + double value(double x) ; + } + + + //! Gaussian kernel function + public class GaussianKernel : IKernelFunction + { + public GaussianKernel(double average, double sigma) + { + nd_ = new NormalDistribution(average,sigma); + cnd_ = new CumulativeNormalDistribution(average,sigma); + // normFact is \sqrt{2*\pi}. + normFact_ = Const.M_SQRT2*Const.M_SQRTPI; + } + + public double value( double x ) + { + return nd_.value(x)*normFact_; + } + + public double derivative( double x ) + { + return nd_.derivative(x)*normFact_; + } + + public double primitive( double x ) + { + return cnd_.value(x)*normFact_; + } + + private NormalDistribution nd_; + private CumulativeNormalDistribution cnd_; + private double normFact_; + + } + +} diff --git a/QLNet/Math/Matrix.cs b/QLNet/Math/Matrix.cs index cd7161cc1..fb52bd82c 100644 --- a/QLNet/Math/Matrix.cs +++ b/QLNet/Math/Matrix.cs @@ -1,7 +1,8 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -15,7 +16,7 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ +*/ using System; using System.Linq; using System.Collections.Generic; @@ -180,6 +181,19 @@ public void swap(int i1, int j1, int i2, int j2) { double t = this[i2, j2]; this[i2, j2] = this[i1, j1]; this[i1, j1] = t; + } + + public override string ToString() + { + String to = string.Empty; + for (int i=0; i + { + T weightSmallX( T x ); + T weight1LargeX( T x ); + T weight2LargeX( T x ); + } + + public class doubleUnweighted : Weight + { + public double weightSmallX( double x ) { return 1.0; } + public double weight1LargeX( double x ) { return Math.Exp( x ); } + public double weight2LargeX( double x ) { return Math.Exp( -x ); } + } + + public class complexUnweighted : Weight + { + public Complex weightSmallX( Complex x ) { return 1.0; } + public Complex weight1LargeX( Complex x ) { return Complex.Exp( x ); } + public Complex weight2LargeX( Complex x ) { return Complex.Exp( -x ); } + } + + public class doubleExponentiallyWeighted : Weight + { + public double weightSmallX( double x ) { return Math.Exp( -x ); } + public double weight1LargeX( double x ) { return 1.0; } + public double weight2LargeX( double x ) { return Math.Exp( -2.0 * x ); } + } + + public class complexExponentiallyWeighted : Weight + { + public Complex weightSmallX( Complex x ) { return Complex.Exp( -x ); } + public Complex weight1LargeX( Complex x ) { return 1.0; } + public Complex weight2LargeX( Complex x ) { return Complex.Exp( -2.0 * x ); } + } + + public interface baseValue + { + T value(); + } + + public class doubleValue : baseValue + { + public double value() { return 0.0; } + } + + public class complexValue : baseValue + { + public Complex value() { return new Complex( 0.0, 1.0 ); } + } + + // Implementation + + public static double modifiedBesselFunction_i( double nu, double x ) + { + Utils.QL_REQUIRE( x >= 0.0, () => "negative argument requires complex version of modifiedBesselFunction" ); + return modifiedBesselFunction_i_impl( nu, x ); + } + + public static Complex modifiedBesselFunction_i( double nu, Complex z ) + { + return modifiedBesselFunction_i_impl( nu, z ); + } + + public static double modifiedBesselFunction_k( double nu, double x ) + { + return modifiedBesselFunction_k_impl( nu, x ); + } + + public static Complex modifiedBesselFunction_k(double nu, Complex z) + { + return modifiedBesselFunction_k_impl( nu, z ); + } + + public static double modifiedBesselFunction_i_exponentiallyWeighted(double nu, double x) + { + Utils.QL_REQUIRE(x >= 0.0, ()=>"negative argument requires complex version of modifiedBesselFunction"); + return modifiedBesselFunction_i_impl( nu, x ); + } + + public static Complex modifiedBesselFunction_i_exponentiallyWeighted(double nu, Complex z) + { + return modifiedBesselFunction_i_impl( nu, z ); + } + + public static double modifiedBesselFunction_k_exponentiallyWeighted( double nu, double x ) + { + return modifiedBesselFunction_k_impl( nu, x ); + } + + public static Complex modifiedBesselFunction_k_exponentiallyWeighted(double nu, Complex z) + { + return modifiedBesselFunction_k_impl( nu, z ); + } + + public static double modifiedBesselFunction_i_impl( double nu, double x ) + where T : Weight, new() + where I : baseValue, new() + { + if ( Math.Abs( x ) < 13.0 ) + { + double alpha = Math.Pow( 0.5 * x, nu ) / GammaFunction.value( 1.0 + nu ); + double Y = 0.25 * x * x; + int k = 1; + double sum = alpha, B_k = alpha; + + while ( Math.Abs( B_k *= Y / ( k * ( k + nu ) ) ) > Math.Abs( sum ) * Const.QL_EPSILON ) + { + sum += B_k; + Utils.QL_REQUIRE( ++k < 1000, () => "max iterations exceeded" ); + } + return sum * new T().weightSmallX( x ); + } + else + { + double na_k = 1.0, sign = 1.0; + double da_k = 1.0; + + double s1 = 1.0, s2 = 1.0; + for ( int k = 1; k < 30; ++k ) + { + sign *= -1; + na_k *= ( 4.0 * nu * nu - + ( 2.0 * k - 1.0 ) * + ( 2.0 * k - 1.0 ) ); + da_k *= ( 8.0 * k ) * x; + double a_k = na_k / da_k; + + s2 += a_k; + s1 += sign * a_k; + } + + double i = new I().value(); + return 1.0 / Math.Sqrt( 2 * M_PI * x ) * + ( new T().weight1LargeX( x ) * s1 + + i * Math.Exp( i * nu * M_PI ) * new T().weight2LargeX( x ) * s2 ); + } + } + + public static Complex modifiedBesselFunction_i_impl( double nu, Complex x ) + where T : Weight, new() + where I : baseValue, new() + { + if ( Complex.Abs( x ) < 13.0 ) + { + Complex alpha = Complex.Pow( 0.5 * x, nu ) / GammaFunction.value( 1.0 + nu ); + Complex Y = 0.25 * x * x; + int k = 1; + Complex sum = alpha, B_k = alpha; + + while ( Complex.Abs( B_k *= Y / ( k * ( k + nu ) ) ) > Complex.Abs( sum ) * Const.QL_EPSILON ) + { + sum += B_k; + Utils.QL_REQUIRE( ++k < 1000, () => "max iterations exceeded" ); + } + return sum * new T().weightSmallX( x ); + } + else + { + double na_k = 1.0, sign = 1.0; + Complex da_k = new Complex( 1.0, 0.0 ); + + Complex s1 = new Complex( 1.0, 0.0 ), s2 = new Complex( 1.0, 0.0 ); + for ( int k = 1; k < 30; ++k ) + { + sign *= -1; + na_k *= ( 4.0 * nu * nu - + ( 2.0 * (double)k - 1.0 ) * + ( 2.0 * (double)k - 1.0 ) ); + da_k *= ( 8.0 * k ) * x; + Complex a_k = na_k / da_k; + + s2 += a_k; + s1 += sign * a_k; + } + + Complex i = new I().value(); + return 1.0 / Complex.Sqrt( 2 * M_PI * x ) * + ( new T().weight1LargeX( x ) * s1 + + i * Complex.Exp( i * nu * M_PI ) * new T().weight2LargeX( x ) * s2 ); + } + } + + public static double modifiedBesselFunction_k_impl( double nu, double x ) + where T : Weight, new() + where I : baseValue, new() + { + return Const.M_PI_2 * ( modifiedBesselFunction_i_impl( -nu, x ) - + modifiedBesselFunction_i_impl( nu, x ) ) / + Math.Sin( Const.M_PI * nu ); + } + + + public static Complex modifiedBesselFunction_k_impl( double nu, Complex x ) + where T : Weight, new() + where I : baseValue, new() + { + return Const.M_PI_2 * ( modifiedBesselFunction_i_impl( -nu, x ) - + modifiedBesselFunction_i_impl( nu, x ) ) / + Math.Sin( Const.M_PI * nu ); + } + } +} diff --git a/QLNet/Math/Optimization/ArmijoLineSearch.cs b/QLNet/Math/Optimization/ArmijoLineSearch.cs index b08a671b9..acf96104b 100644 --- a/QLNet/Math/Optimization/ArmijoLineSearch.cs +++ b/QLNet/Math/Optimization/ArmijoLineSearch.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Optimization/ConjugateGradient.cs b/QLNet/Math/Optimization/ConjugateGradient.cs index dcd1c386c..49cd9ec8d 100644 --- a/QLNet/Math/Optimization/ConjugateGradient.cs +++ b/QLNet/Math/Optimization/ConjugateGradient.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Optimization/Constraint.cs b/QLNet/Math/Optimization/Constraint.cs index 7665a64ed..3d6b8a9ec 100644 --- a/QLNet/Math/Optimization/Constraint.cs +++ b/QLNet/Math/Optimization/Constraint.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -37,7 +37,7 @@ public Constraint(IConstraint impl) { impl_ = impl; } - public double update(Vector p, Vector direction, double beta) { + public double update(ref Vector p, Vector direction, double beta) { double diff=beta; Vector newParams = p + diff * direction; bool valid = test(newParams); diff --git a/QLNet/Math/Optimization/EndCriteria.cs b/QLNet/Math/Optimization/EndCriteria.cs index a69ea703c..b8498e57b 100644 --- a/QLNet/Math/Optimization/EndCriteria.cs +++ b/QLNet/Math/Optimization/EndCriteria.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Optimization/LeastSquareProblem.cs b/QLNet/Math/Optimization/LeastSquareProblem.cs index bb88f3956..f8bac7431 100644 --- a/QLNet/Math/Optimization/LeastSquareProblem.cs +++ b/QLNet/Math/Optimization/LeastSquareProblem.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Optimization/LineSearch.cs b/QLNet/Math/Optimization/LineSearch.cs index 143933bf0..d20bae70d 100644 --- a/QLNet/Math/Optimization/LineSearch.cs +++ b/QLNet/Math/Optimization/LineSearch.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Optimization/LineSearchBasedMethod.cs b/QLNet/Math/Optimization/LineSearchBasedMethod.cs index 12ce86470..b213f0582 100644 --- a/QLNet/Math/Optimization/LineSearchBasedMethod.cs +++ b/QLNet/Math/Optimization/LineSearchBasedMethod.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Optimization/ProjectedCostFunction.cs b/QLNet/Math/Optimization/ProjectedCostFunction.cs index df6390a77..9ce6ea7d6 100644 --- a/QLNet/Math/Optimization/ProjectedCostFunction.cs +++ b/QLNet/Math/Optimization/ProjectedCostFunction.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Optimization/Simplex.cs b/QLNet/Math/Optimization/Simplex.cs index 802530076..63f5d829e 100644 --- a/QLNet/Math/Optimization/Simplex.cs +++ b/QLNet/Math/Optimization/Simplex.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -49,131 +49,137 @@ public class Simplex : OptimizationMethod public Simplex(double lambda) { lambda_ = lambda; - } - public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) - { - // set up of the problem - //double ftol = endCriteria.functionEpsilon(); // end criteria on f(x) (see Numerical Recipes in C++, p.410) - double xtol = endCriteria.rootEpsilon(); // end criteria on x (see GSL v. 1.9, http://www.gnu.org/software/gsl/) - int maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); - EndCriteria.Type ecType = EndCriteria.Type.None; - P.reset(); - Vector x_ = P.currentValue(); - int iterationNumber_ = 0; - - // Initialize vertices of the simplex - bool end = false; - int n = x_.Count; - vertices_ = new InitializedList(n + 1, x_); - for (int i = 0; i < n; i++) - { - Vector direction = new Vector(n, 0.0); - direction[i] = 1.0; - P.constraint().update(vertices_[i + 1], direction, lambda_); - } - // Initialize function values at the vertices of the simplex - values_ = new Vector(n + 1, 0.0); - for (int i = 0; i <= n; i++) - values_[i] = P.value(vertices_[i]); - // Loop looking for minimum - do - { - sum_ = new Vector(n, 0.0); - for (int i = 0; i <= n; i++) - sum_ += vertices_[i]; - // Determine the best (iLowest), worst (iHighest) - // and 2nd worst (iNextHighest) vertices - int iLowest = 0; - int iHighest; - int iNextHighest; - if (values_[0] < values_[1]) - { - iHighest = 1; - iNextHighest = 0; - } - else - { - iHighest = 0; - iNextHighest = 1; - } - for (int i = 1; i <= n; i++) - { - if (values_[i] > values_[iHighest]) - { - iNextHighest = iHighest; - iHighest = i; - } - else - { - if ((values_[i] > values_[iNextHighest]) && i != iHighest) - iNextHighest = i; - } - if (values_[i] < values_[iLowest]) - iLowest = i; - } - // Now compute accuracy, update iteration number and check end criteria - //// Numerical Recipes exit strategy on fx (see NR in C++, p.410) - //double low = values_[iLowest]; - //double high = values_[iHighest]; - //double rtol = 2.0*std::fabs(high - low)/ - // (std::fabs(high) + std::fabs(low) + QL_EPSILON); - //++iterationNumber_; - //if (rtol < ftol || - // endCriteria.checkMaxIterations(iterationNumber_, ecType)) { - // GSL exit strategy on x (see GSL v. 1.9, http://www.gnu.org/software/gsl - double simplexSize = Utils.computeSimplexSize(vertices_); - ++iterationNumber_; - if (simplexSize < xtol || endCriteria.checkMaxIterations(iterationNumber_, ref ecType)) - { - endCriteria.checkStationaryPoint(0.0, 0.0, ref maxStationaryStateIterations_, ref ecType); - endCriteria.checkMaxIterations(iterationNumber_, ref ecType); - x_ = vertices_[iLowest]; - double low = values_[iLowest]; - P.setFunctionValue(low); - P.setCurrentValue(x_); - return ecType; - } - // If end criteria is not met, continue - double factor = -1.0; - double vTry = extrapolate(ref P, iHighest, ref factor); - if ((vTry <= values_[iLowest]) && (factor == -1.0)) - { - factor = 2.0; - extrapolate(ref P, iHighest, ref factor); - } else if (Math.Abs(factor) > Const.QL_Epsilon) { - if (vTry >= values_[iNextHighest]) - { - double vSave = values_[iHighest]; - factor = 0.5; - vTry = extrapolate(ref P, iHighest, ref factor); - if (vTry >= vSave && Math.Abs(factor) > Const.QL_Epsilon) { - for (int i = 0; i <= n; i++) - { - if (i != iLowest) - { - #if QL_ARRAY_EXPRESSIONS + } + public override EndCriteria.Type minimize( Problem P, EndCriteria endCriteria ) + { + // set up of the problem + //double ftol = endCriteria.functionEpsilon(); // end criteria on f(x) (see Numerical Recipes in C++, p.410) + double xtol = endCriteria.rootEpsilon(); // end criteria on x (see GSL v. 1.9, http://www.gnu.org/software/gsl/) + int maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); + EndCriteria.Type ecType = EndCriteria.Type.None; + P.reset(); + Vector x_ = P.currentValue(); + int iterationNumber_ = 0; + + // Initialize vertices of the simplex + bool end = false; + int n = x_.Count; + vertices_ = new InitializedList( n + 1, x_ ); + for ( int i = 0; i < n; i++ ) + { + Vector direction = new Vector( n, 0.0 ); + Vector vertice = vertices_[i + 1]; + direction[i] = 1.0; + P.constraint().update( ref vertice, direction, lambda_ ); + vertices_[i + 1] = vertice; + } + // Initialize function values at the vertices of the simplex + values_ = new Vector( n + 1, 0.0 ); + for ( int i = 0; i <= n; i++ ) + values_[i] = P.value( vertices_[i] ); + // Loop looking for minimum + do + { + sum_ = new Vector( n, 0.0 ); + for ( int i = 0; i <= n; i++ ) + sum_ += vertices_[i]; + // Determine the best (iLowest), worst (iHighest) + // and 2nd worst (iNextHighest) vertices + int iLowest = 0; + int iHighest; + int iNextHighest; + if ( values_[0] < values_[1] ) + { + iHighest = 1; + iNextHighest = 0; + } + else + { + iHighest = 0; + iNextHighest = 1; + } + for ( int i = 1; i <= n; i++ ) + { + if ( values_[i] > values_[iHighest] ) + { + iNextHighest = iHighest; + iHighest = i; + } + else + { + if ( ( values_[i] > values_[iNextHighest] ) && i != iHighest ) + iNextHighest = i; + } + if ( values_[i] < values_[iLowest] ) + iLowest = i; + } + // Now compute accuracy, update iteration number and check end criteria + //// Numerical Recipes exit strategy on fx (see NR in C++, p.410) + //double low = values_[iLowest]; + //double high = values_[iHighest]; + //double rtol = 2.0*std::fabs(high - low)/ + // (std::fabs(high) + std::fabs(low) + QL_EPSILON); + //++iterationNumber_; + //if (rtol < ftol || + // endCriteria.checkMaxIterations(iterationNumber_, ecType)) { + // GSL exit strategy on x (see GSL v. 1.9, http://www.gnu.org/software/gsl + double simplexSize = Utils.computeSimplexSize( vertices_ ); + ++iterationNumber_; + if ( simplexSize < xtol || endCriteria.checkMaxIterations( iterationNumber_, ref ecType ) ) + { + endCriteria.checkStationaryPoint( 0.0, 0.0, ref maxStationaryStateIterations_, ref ecType ); + endCriteria.checkMaxIterations( iterationNumber_, ref ecType ); + x_ = vertices_[iLowest]; + double low = values_[iLowest]; + P.setFunctionValue( low ); + P.setCurrentValue( x_ ); + return ecType; + } + // If end criteria is not met, continue + double factor = -1.0; + double vTry = extrapolate( ref P, iHighest, ref factor ); + if ( ( vTry <= values_[iLowest] ) && ( factor == -1.0 ) ) + { + factor = 2.0; + extrapolate( ref P, iHighest, ref factor ); + } + else if ( Math.Abs( factor ) > Const.QL_EPSILON ) + { + if ( vTry >= values_[iNextHighest] ) + { + double vSave = values_[iHighest]; + factor = 0.5; + vTry = extrapolate( ref P, iHighest, ref factor ); + if ( vTry >= vSave && Math.Abs( factor ) > Const.QL_EPSILON ) + { + for ( int i = 0; i <= n; i++ ) + { + if ( i != iLowest ) + { +#if QL_ARRAY_EXPRESSIONS vertices_[i] = 0.5 * (vertices_[i] + vertices_[iLowest]); - #else - vertices_[i] += vertices_[iLowest]; - vertices_[i] *= 0.5; - #endif - values_[i] = P.value(vertices_[i]); - } - } - } - } - } - // If can't extrapolate given the constraints, exit - if (Math.Abs(factor) <= Const.QL_Epsilon) { - x_ = vertices_[iLowest]; - double low = values_[iLowest]; - P.setFunctionValue(low); - P.setCurrentValue(x_); - return EndCriteria.Type.StationaryFunctionValue; - } - } while (end == false); - throw new ApplicationException("optimization failed: unexpected behaviour"); - } +#else + vertices_[i] += vertices_[iLowest]; + vertices_[i] *= 0.5; +#endif + values_[i] = P.value( vertices_[i] ); + } + } + } + } + } + // If can't extrapolate given the constraints, exit + if ( Math.Abs( factor ) <= Const.QL_EPSILON ) + { + x_ = vertices_[iLowest]; + double low = values_[iLowest]; + P.setFunctionValue( low ); + P.setCurrentValue( x_ ); + return EndCriteria.Type.StationaryFunctionValue; + } + } while ( end == false ); + throw new ApplicationException( "optimization failed: unexpected behaviour" ); + } private double extrapolate(ref Problem P, int iHighest, ref double factor) { @@ -192,8 +198,8 @@ private double extrapolate(ref Problem P, int iHighest, ref double factor) // pTry -= vertices_[iHighest] * factor2; //#endif factor *= 0.5; - } while (!P.constraint().test(pTry) && Math.Abs(factor) > Const.QL_Epsilon); - if (Math.Abs(factor) <= Const.QL_Epsilon) { + } while (!P.constraint().test(pTry) && Math.Abs(factor) > Const.QL_EPSILON); + if (Math.Abs(factor) <= Const.QL_EPSILON) { return values_[iHighest]; } factor *= 2.0; diff --git a/QLNet/Math/Optimization/SteepestDescent.cs b/QLNet/Math/Optimization/SteepestDescent.cs index 03bbe8627..8e0392e5b 100644 --- a/QLNet/Math/Optimization/SteepestDescent.cs +++ b/QLNet/Math/Optimization/SteepestDescent.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Optimization/levenbergmarquardt.cs b/QLNet/Math/Optimization/levenbergmarquardt.cs index 9be2cb328..1ac46d088 100644 --- a/QLNet/Math/Optimization/levenbergmarquardt.cs +++ b/QLNet/Math/Optimization/levenbergmarquardt.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Optimization/lmdif.cs b/QLNet/Math/Optimization/lmdif.cs index 45f1dc627..f95255de5 100644 --- a/QLNet/Math/Optimization/lmdif.cs +++ b/QLNet/Math/Optimization/lmdif.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Optimization/method.cs b/QLNet/Math/Optimization/method.cs index d5dfa97f5..0aa70fe1b 100644 --- a/QLNet/Math/Optimization/method.cs +++ b/QLNet/Math/Optimization/method.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Optimization/problem.cs b/QLNet/Math/Optimization/problem.cs index 3a7bcf7a8..0b884328b 100644 --- a/QLNet/Math/Optimization/problem.cs +++ b/QLNet/Math/Optimization/problem.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/PrimeNumbers.cs b/QLNet/Math/PrimeNumbers.cs index a89cdc06f..8ada6851d 100644 --- a/QLNet/Math/PrimeNumbers.cs +++ b/QLNet/Math/PrimeNumbers.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/RichardsonExtrapolation.cs b/QLNet/Math/RichardsonExtrapolation.cs new file mode 100644 index 000000000..4e14fc56f --- /dev/null +++ b/QLNet/Math/RichardsonExtrapolation.cs @@ -0,0 +1,112 @@ +/* + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + //! Richardson Extrapolation + /*! Richardson Extrapolation is a sequence acceleration technique for + \f[ + f(\Delta h) = f_0 + \alpha\cdot (\Delta h)^n + O((\Delta h)^{n+1}) + \f] + */ + + /*! References: + http://en.wikipedia.org/wiki/Richardson_extrapolation + */ + + public class RichardsonEqn : ISolver1d + { + public RichardsonEqn(double fh, double ft, double fs, double t, double s) + { + fdelta_h_ = fh; + ft_ = ft; + fs_ = fs; + t_ = t; + s_ = s; + } + + public override double value(double k) + { + return ft_ + (ft_-fdelta_h_)/(Math.Pow(t_, k)-1.0) + - ( fs_ + (fs_-fdelta_h_)/(Math.Pow(s_, k)-1.0)); + } + + private double fdelta_h_, ft_, fs_, t_, s_; + } + + public class RichardsonExtrapolation + { + /*! Richardon Extrapolation + \param f function to be extrapolated to delta_h -> 0 + \param delta_h step size + \param n if known, n is the order of convergence + */ + public delegate double function(double num); + + public RichardsonExtrapolation( function f, double delta_h, double? n = null ) + { + delta_h_ = delta_h; + fdelta_h_ = f(delta_h); + n_ = n; + f_ = f; + } + + /*! Extrapolation for known order of convergence + \param t scaling factor for the step size + */ + public double value( double t = 2.0 ) + { + Utils.QL_REQUIRE(t > 1, ()=> "scaling factor must be greater than 1"); + Utils.QL_REQUIRE(n_ != null, ()=> "order of convergence must be known"); + + double tk = Math.Pow(t, n_.Value); + + return (tk*f_(delta_h_/t)-fdelta_h_)/(tk-1.0); + } + + /*! Extrapolation for unknown order of convergence + \param t first scaling factor for the step size + \param s second scaling factor for the step size + */ + public double value( double t, double s ) + { + Utils.QL_REQUIRE(t > 1 && s > 1, ()=>"scaling factors must be greater than 1"); + Utils.QL_REQUIRE(t > s, ()=> "t must be greater than s"); + + double ft = f_(delta_h_/t); + double fs = f_(delta_h_/s); + + double k = new Brent().solve(new RichardsonEqn(fdelta_h_, ft, fs, t, s), + 1e-8, 0.05, 10); + + double ts = Math.Pow(s, k); + + return (ts*fs-fdelta_h_)/(ts-1.0); + } + + private double delta_h_; + private double fdelta_h_; + private double? n_; + private function f_; + } +} diff --git a/QLNet/Math/Rounding.cs b/QLNet/Math/Rounding.cs index 48b589319..a1ebbdf18 100644 Binary files a/QLNet/Math/Rounding.cs and b/QLNet/Math/Rounding.cs differ diff --git a/QLNet/Math/SampledCurve.cs b/QLNet/Math/SampledCurve.cs index d6d1aca32..026330c3a 100644 --- a/QLNet/Math/SampledCurve.cs +++ b/QLNet/Math/SampledCurve.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Solver1d.cs b/QLNet/Math/Solver1d.cs index 8b33dc4c4..cd58b525c 100644 --- a/QLNet/Math/Solver1d.cs +++ b/QLNet/Math/Solver1d.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -61,7 +61,7 @@ public double solve(ISolver1d f, double accuracy, double guess, double step) { throw new ArgumentException("accuracy (" + accuracy + ") must be positive"); // check whether we really want to use epsilon - accuracy = Math.Max(accuracy, Const.QL_Epsilon); + accuracy = Math.Max(accuracy, Const.QL_EPSILON); const double growthFactor = 1.6; int flipflop = -1; @@ -129,7 +129,7 @@ public double solve(ISolver1d f, double accuracy, double guess, double xMin, dou throw new ArgumentException("accuracy (" + accuracy + ") must be positive"); // check whether we really want to use epsilon - accuracy = Math.Max(accuracy, Const.QL_Epsilon); + accuracy = Math.Max(accuracy, Const.QL_EPSILON); xMin_ = xMin; xMax_ = xMax; diff --git a/QLNet/Math/Solvers1d/Bisection.cs b/QLNet/Math/Solvers1d/Bisection.cs index d199c934f..bd3ba525a 100644 --- a/QLNet/Math/Solvers1d/Bisection.cs +++ b/QLNet/Math/Solvers1d/Bisection.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Solvers1d/Brent.cs b/QLNet/Math/Solvers1d/Brent.cs index 68311ab44..b05a04e30 100644 --- a/QLNet/Math/Solvers1d/Brent.cs +++ b/QLNet/Math/Solvers1d/Brent.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -52,7 +52,7 @@ protected override double solveImpl(ISolver1d f, double xAccuracy) { fxMax_ = fxMin_; } // Convergence check - xAcc1 = 2.0 * Const.QL_Epsilon * Math.Abs(root_) + 0.5 * xAccuracy; + xAcc1 = 2.0 * Const.QL_EPSILON * Math.Abs(root_) + 0.5 * xAccuracy; xMid = (xMax_ - root_) / 2.0; if (Math.Abs(xMid) <= xAcc1 || froot == 0.0) return root_; diff --git a/QLNet/Math/Solvers1d/FalsePosition.cs b/QLNet/Math/Solvers1d/FalsePosition.cs index 64242887f..2a4ddfaef 100644 --- a/QLNet/Math/Solvers1d/FalsePosition.cs +++ b/QLNet/Math/Solvers1d/FalsePosition.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Solvers1d/FiniteDifferenceNewtonSafe.cs b/QLNet/Math/Solvers1d/FiniteDifferenceNewtonSafe.cs index 227872f0b..ca21a4026 100644 --- a/QLNet/Math/Solvers1d/FiniteDifferenceNewtonSafe.cs +++ b/QLNet/Math/Solvers1d/FiniteDifferenceNewtonSafe.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -15,16 +15,16 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace QLNet -{ - public class FiniteDifferenceNewtonSafe : Solver1D - { +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + public class FiniteDifferenceNewtonSafe : Solver1D + { protected override double solveImpl(ISolver1d f, double xAccuracy) { // Orient the search so that f(xl) < 0 @@ -74,10 +74,10 @@ protected override double solveImpl(ISolver1d f, double xAccuracy) xl=root_; else xh=root_; - } - + } + throw new ArgumentException( "maximum number of function evaluations (" + maxEvaluations_ + ") exceeded" ); - } - } -} + } + } +} diff --git a/QLNet/Math/Solvers1d/Newton.cs b/QLNet/Math/Solvers1d/Newton.cs index c6faf4b7e..1c830e7ce 100644 --- a/QLNet/Math/Solvers1d/Newton.cs +++ b/QLNet/Math/Solvers1d/Newton.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Solvers1d/Newtonsafe.cs b/QLNet/Math/Solvers1d/Newtonsafe.cs index 9fc86639b..44f818c54 100644 --- a/QLNet/Math/Solvers1d/Newtonsafe.cs +++ b/QLNet/Math/Solvers1d/Newtonsafe.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Solvers1d/Ridder.cs b/QLNet/Math/Solvers1d/Ridder.cs index d6d5cbed9..05cac6115 100644 --- a/QLNet/Math/Solvers1d/Ridder.cs +++ b/QLNet/Math/Solvers1d/Ridder.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Solvers1d/Secant.cs b/QLNet/Math/Solvers1d/Secant.cs index 3146fa4a7..f5bb4b8f3 100644 --- a/QLNet/Math/Solvers1d/Secant.cs +++ b/QLNet/Math/Solvers1d/Secant.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/Vector.cs b/QLNet/Math/Vector.cs index 2cb6b8e49..9e2d84d42 100644 --- a/QLNet/Math/Vector.cs +++ b/QLNet/Math/Vector.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -64,18 +64,18 @@ public Vector(List from) : this(from.Count) { //Array& operator=(const Disposable&); public Object Clone() { return this.MemberwiseClone(); } - public static bool operator ==(Vector to, Vector from) { - - if ( System.Object.ReferenceEquals( to, from ) ) return true; - else if ( (object)to == null || (object)from == null ) return false; - else - { - if ( from.Count != to.Count ) return false; - - for ( int i = 0; i < from.Count; i++ ) - if ( from[i] != to[i] ) return false; - - return true; + public static bool operator ==(Vector to, Vector from) { + + if ( System.Object.ReferenceEquals( to, from ) ) return true; + else if ( (object)to == null || (object)from == null ) return false; + else + { + if ( from.Count != to.Count ) return false; + + for ( int i = 0; i < from.Count; i++ ) + if ( from[i] != to[i] ) return false; + + return true; } } public static bool operator !=(Vector to, Vector from) { return (!(to == from)); } @@ -146,6 +146,13 @@ public static Vector Sqrt(Vector v) { Vector result = new Vector(v.size()); result.ForEach((i, x) => result[i] = Math.Sqrt(v[i])); return result; + } + + public static Vector Abs( Vector v ) + { + Vector result = new Vector( v.size() ); + result.ForEach( ( i, x ) => result[i] = Math.Abs( v[i] ) ); + return result; } public void swap(int i1, int i2) { diff --git a/QLNet/Math/beta.cs b/QLNet/Math/beta.cs index 9f7af20af..e036d82d9 100644 --- a/QLNet/Math/beta.cs +++ b/QLNet/Math/beta.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -39,8 +39,8 @@ public static double betaContinuedFraction(double a, double b, double x, double double qam = a-1.0; double c = 1.0; double d = 1.0-qab*x/qap; - if (Math.Abs(d) < Const.QL_Epsilon) - d = Const.QL_Epsilon; + if (Math.Abs(d) < Const.QL_EPSILON) + d = Const.QL_EPSILON; d = 1.0/d; double result = d; @@ -49,16 +49,16 @@ public static double betaContinuedFraction(double a, double b, double x, double m2=2*m; aa=m*(b-m)*x/((qam+m2)*(a+m2)); d=1.0+aa*d; - if (Math.Abs(d) < Const.QL_Epsilon) d=Const.QL_Epsilon; + if (Math.Abs(d) < Const.QL_EPSILON) d=Const.QL_EPSILON; c=1.0+aa/c; - if (Math.Abs(c) < Const.QL_Epsilon) c=Const.QL_Epsilon; + if (Math.Abs(c) < Const.QL_EPSILON) c=Const.QL_EPSILON; d=1.0/d; result *= d*c; aa = -(a+m)*(qab+m)*x/((a+m2)*(qap+m2)); d=1.0+aa*d; - if (Math.Abs(d) < Const.QL_Epsilon) d=Const.QL_Epsilon; + if (Math.Abs(d) < Const.QL_EPSILON) d=Const.QL_EPSILON; c=1.0+aa/c; - if (Math.Abs(c) < Const.QL_Epsilon) c=Const.QL_Epsilon; + if (Math.Abs(c) < Const.QL_EPSILON) c=Const.QL_EPSILON; d=1.0/d; del=d*c; result *= del; diff --git a/QLNet/Math/factorial.cs b/QLNet/Math/factorial.cs index 225a65581..c4593106a 100644 --- a/QLNet/Math/factorial.cs +++ b/QLNet/Math/factorial.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -60,6 +60,6 @@ public static double ln(int i) { 403291461126605635584000000.0, 10888869450418352160768000000.0 }; - static int tabulated = firstFactorials.Length; + static int tabulated = firstFactorials.Length - 1; } } diff --git a/QLNet/Math/integrals/GaussianQuadratures.cs b/QLNet/Math/integrals/GaussianQuadratures.cs index f1a58d566..ac6afea6d 100644 --- a/QLNet/Math/integrals/GaussianQuadratures.cs +++ b/QLNet/Math/integrals/GaussianQuadratures.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -246,15 +246,15 @@ public class TabulatedGaussLegendre //} public double value (Func f) - { - Utils.QL_REQUIRE( w_ != null, () => "Null weights" ); + { + Utils.QL_REQUIRE( w_ != null, () => "Null weights" ); Utils.QL_REQUIRE( x_ != null, () => "Null abscissas" ); int startIdx; double val; int isOrderOdd = order_ & 1; - if (isOrderOdd > 0) { + if (isOrderOdd > 0) { Utils.QL_REQUIRE( ( n_ > 0 ), () => "assume at least 1 point in quadrature" ); val = w_[0]*f(x_[0]); startIdx=1; diff --git a/QLNet/Math/integrals/Integral.cs b/QLNet/Math/integrals/Integral.cs index 843d44e1e..07c724337 100644 --- a/QLNet/Math/integrals/Integral.cs +++ b/QLNet/Math/integrals/Integral.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/integrals/Kronrodintegral.cs b/QLNet/Math/integrals/Kronrodintegral.cs index 308fd41bd..47acfb480 100644 --- a/QLNet/Math/integrals/Kronrodintegral.cs +++ b/QLNet/Math/integrals/Kronrodintegral.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/integrals/Segmentintegral.cs b/QLNet/Math/integrals/Segmentintegral.cs index a09c42bf7..6712a4af4 100644 --- a/QLNet/Math/integrals/Segmentintegral.cs +++ b/QLNet/Math/integrals/Segmentintegral.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/integrals/gaussianorthogonalpolynomial.cs b/QLNet/Math/integrals/gaussianorthogonalpolynomial.cs index 1a6371b93..9396b7462 100644 --- a/QLNet/Math/integrals/gaussianorthogonalpolynomial.cs +++ b/QLNet/Math/integrals/gaussianorthogonalpolynomial.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/integrals/simpsonintegral.cs b/QLNet/Math/integrals/simpsonintegral.cs index 73b7cb761..9a962dbc5 100644 --- a/QLNet/Math/integrals/simpsonintegral.cs +++ b/QLNet/Math/integrals/simpsonintegral.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/integrals/trapezoidintegral.cs b/QLNet/Math/integrals/trapezoidintegral.cs index 76d730293..5e4fcd313 100644 --- a/QLNet/Math/integrals/trapezoidintegral.cs +++ b/QLNet/Math/integrals/trapezoidintegral.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/linearleastsquaresregression.cs b/QLNet/Math/linearleastsquaresregression.cs index 8bc78b40d..61f49728d 100644 --- a/QLNet/Math/linearleastsquaresregression.cs +++ b/QLNet/Math/linearleastsquaresregression.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -69,7 +69,7 @@ public LinearLeastSquaresRegression(List x, List y, List threshold) { diff --git a/QLNet/Math/Interpolations/TqrEigenDecomposition.cs b/QLNet/Math/matrixutilities/TqrEigenDecomposition.cs similarity index 98% rename from QLNet/Math/Interpolations/TqrEigenDecomposition.cs rename to QLNet/Math/matrixutilities/TqrEigenDecomposition.cs index cc339aba1..3661d5201 100644 --- a/QLNet/Math/Interpolations/TqrEigenDecomposition.cs +++ b/QLNet/Math/matrixutilities/TqrEigenDecomposition.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -63,8 +63,8 @@ public TqrEigenDecomposition(Vector diag, Vector sub, EigenVectorCalculation cal ev_ = new Matrix(row, d_.size(), 0.0); - int n = diag.size(); - + int n = diag.size(); + Utils.QL_REQUIRE( n == sub.size() + 1, () => "Wrong dimensions" ); Vector e = new Vector(sub); diff --git a/QLNet/Math/matrixutilities/choleskydecomposition.cs b/QLNet/Math/matrixutilities/choleskydecomposition.cs index 7a4639c01..cada635d0 100644 --- a/QLNet/Math/matrixutilities/choleskydecomposition.cs +++ b/QLNet/Math/matrixutilities/choleskydecomposition.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/matrixutilities/pseudosqrt.cs b/QLNet/Math/matrixutilities/pseudosqrt.cs index 8a1262bc0..b47afd4be 100644 --- a/QLNet/Math/matrixutilities/pseudosqrt.cs +++ b/QLNet/Math/matrixutilities/pseudosqrt.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/matrixutilities/qrdecomposition.cs b/QLNet/Math/matrixutilities/qrdecomposition.cs index 9e8bb7723..081ed5633 100644 --- a/QLNet/Math/matrixutilities/qrdecomposition.cs +++ b/QLNet/Math/matrixutilities/qrdecomposition.cs @@ -1,7 +1,8 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -15,7 +16,7 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ +*/ using System; using System.Collections.Generic; using System.Linq; @@ -42,7 +43,7 @@ Column j of p is column ipvt(j) of the identity matrix. See lmdiff.cpp for further details. */ //public static List qrDecomposition(Matrix A, Matrix q, Matrix r, bool pivot = true) { - public static List qrDecomposition(Matrix M, Matrix q, Matrix r, bool pivot) { + public static List qrDecomposition(Matrix M, ref Matrix q, ref Matrix r, bool pivot) { Matrix mT = Matrix.transpose(M); int m = M.rows(); int n = M.columns(); @@ -57,14 +58,10 @@ public static List qrDecomposition(Matrix M, Matrix q, Matrix r, bool pivot r = new Matrix(n, n); for (int i=0; i < n; ++i) { - // std::fill(r.row_begin(i), r.row_begin(i)+i, 0.0); r[i, i] = rdiag[i]; - if (i < m) { - // std::copy(mT.column_begin(i)+i+1, mT.column_end(i), - // r.row_begin(i)+i+1); - } - else { - // std::fill(r.row_begin(i)+i+1, r.row_end(i), 0.0); + if (i < m) { + for ( int j = i; j < mT.rows()-1; j++ ) + r[i, j + 1] = mT[j+1, i]; } } @@ -72,35 +69,40 @@ public static List qrDecomposition(Matrix M, Matrix q, Matrix r, bool pivot q = new Matrix(m, n); Vector w = new Vector(m); - //for (int k=0; k < m; ++k) { - // std::fill(w.begin(), w.end(), 0.0); - // w[k] = 1.0; - - // for (int j=0; j < Math.Min(n, m); ++j) { - // double t3 = mT[j,j]; - // if (t3 != 0.0) { - // double t - // = std::inner_product(mT.row_begin(j)+j, mT.row_end(j), - // w.begin()+j, 0.0)/t3; - // for (int i=j; i ipvt = new InitializedList(n); - //if (pivot) { - // std::copy(lipvt.get(), lipvt.get()+n, ipvt.begin()); - //} - //else { - // for (int i=0; i < n; ++i) - // ipvt[i] = i; - //} - - return ipvt; + for (int k=0; k < m; ++k) + { + w.Erase(); + w[k] = 1.0; + + for (int j=0; j < Math.Min(n, m); ++j) + { + double t3 = mT[j,j]; + if (t3 != 0.0) + { + double t = 0; + for ( int kk = j ; kk < mT.columns(); kk++ ) + t += ( mT[j,kk] * w[kk] ) / t3 ; + + for (int i=j; i ipvt = new InitializedList(n); + if (pivot) { + for ( int i = 0; i < n; ++i ) + ipvt[i] = lipvt[i]; + } + else { + for (int i=0; i < n; ++i) + ipvt[i] = i; + } + + return ipvt; } //! QR Solve @@ -120,40 +122,41 @@ d is an input array of length n which must contain the diagonal elements of the matrix d. See lmdiff.cpp for further details. - */ - //public Vector qrSolve(Matrix a, Vector b, bool pivot = true, Vector d = Array()) { - //public Vector qrSolve(Matrix a, Vector b, bool pivot, Vector d) { - // int m = a.rows(); - // int n = a.columns(); - - // QL_REQUIRE(b.size() == m, "dimensions of A and b don't match"); - // QL_REQUIRE(d.size() == n || d.empty(), - // "dimensions of A and d don't match"); - - // Matrix q(m, n), r(n, n); - - // std::vector lipvt = qrDecomposition(a, q, r, pivot); - // boost::scoped_array ipvt(new int[n]); - // std::copy(lipvt.begin(), lipvt.end(), ipvt.get()); - - // Matrix aT = Matrix.transpose(a); - // Matrix rT = Matrix.transpose(r); - - // boost::scoped_array sdiag(new double[n]); - // boost::scoped_array wa(new double[n]); - - // Array ld(n, 0.0); - // if (!d.empty()) { - // std::copy(d.begin(), d.end(), ld.begin()); - // } - // Array x(n); - // Array qtb = transpose(q)*b; - - // MINPACK.qrsolv(n, rT.begin(), n, ipvt.get(), - // ld.begin(), qtb.begin(), - // x.begin(), sdiag.get(), wa.get()); - - // return x; - //} + */ + public static Vector qrSolve( Matrix a, Vector b, bool pivot = true, Vector d = null ) + { + int m = a.rows(); + int n = a.columns(); + if ( d == null ) d = new Vector(); + Utils.QL_REQUIRE( b.Count == m, () => "dimensions of A and b don't match" ); + Utils.QL_REQUIRE( d.Count == n || d.empty(), () => "dimensions of A and d don't match" ); + + Matrix q = new Matrix( m, n ), r = new Matrix( n, n ); + + List lipvt = MatrixUtilities.qrDecomposition( a, ref q, ref r, pivot ); + List ipvt = new List( n ); + ipvt = lipvt; + + //std::copy(lipvt.begin(), lipvt.end(), ipvt.get()); + + Matrix aT = Matrix.transpose( a ); + Matrix rT = Matrix.transpose( r ); + + Vector sdiag = new Vector( n ); + Vector wa = new Vector( n ); + + Vector ld = new Vector( n, 0.0 ); + if ( !d.empty() ) + { + ld = d; + //std::copy(d.begin(), d.end(), ld.begin()); + } + Vector x = new Vector( n ); + Vector qtb = Matrix.transpose( q ) * b; + + MINPACK.qrsolv( n, rT, n, ipvt, ld, qtb, x, sdiag, wa ); + + return x; + } } } \ No newline at end of file diff --git a/QLNet/Math/matrixutilities/svd.cs b/QLNet/Math/matrixutilities/svd.cs index 564f6a0a2..76834edb0 100644 --- a/QLNet/Math/matrixutilities/svd.cs +++ b/QLNet/Math/matrixutilities/svd.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/matrixutilities/symmetricschurdecomposition.cs b/QLNet/Math/matrixutilities/symmetricschurdecomposition.cs index b4aea5b1a..185d2562d 100644 --- a/QLNet/Math/matrixutilities/symmetricschurdecomposition.cs +++ b/QLNet/Math/matrixutilities/symmetricschurdecomposition.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/randomnumbers/Haltonrsg.cs b/QLNet/Math/randomnumbers/Haltonrsg.cs index 8999b1094..f9c956b3c 100644 --- a/QLNet/Math/randomnumbers/Haltonrsg.cs +++ b/QLNet/Math/randomnumbers/Haltonrsg.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/randomnumbers/inversecumulativerng.cs b/QLNet/Math/randomnumbers/inversecumulativerng.cs index 62d05fe5d..25570978f 100644 --- a/QLNet/Math/randomnumbers/inversecumulativerng.cs +++ b/QLNet/Math/randomnumbers/inversecumulativerng.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/randomnumbers/inversecumulativersg.cs b/QLNet/Math/randomnumbers/inversecumulativersg.cs index 2aff8fb0f..636428f7c 100644 --- a/QLNet/Math/randomnumbers/inversecumulativersg.cs +++ b/QLNet/Math/randomnumbers/inversecumulativersg.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/randomnumbers/mt19937uniformrng.cs b/QLNet/Math/randomnumbers/mt19937uniformrng.cs index 0f132c3ec..9b6417846 100644 --- a/QLNet/Math/randomnumbers/mt19937uniformrng.cs +++ b/QLNet/Math/randomnumbers/mt19937uniformrng.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/randomnumbers/primitivepolynomials.cs b/QLNet/Math/randomnumbers/primitivepolynomials.cs index 2d7fb81cf..310d4af8d 100644 --- a/QLNet/Math/randomnumbers/primitivepolynomials.cs +++ b/QLNet/Math/randomnumbers/primitivepolynomials.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/randomnumbers/randomsequencegenerator.cs b/QLNet/Math/randomnumbers/randomsequencegenerator.cs index 7faf9855f..26c4235f1 100644 --- a/QLNet/Math/randomnumbers/randomsequencegenerator.cs +++ b/QLNet/Math/randomnumbers/randomsequencegenerator.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/randomnumbers/rngtraits.cs b/QLNet/Math/randomnumbers/rngtraits.cs index d69f98b46..45f58a9ef 100644 --- a/QLNet/Math/randomnumbers/rngtraits.cs +++ b/QLNet/Math/randomnumbers/rngtraits.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/randomnumbers/seedgenerator.cs b/QLNet/Math/randomnumbers/seedgenerator.cs index a34ee7ba1..2422e7b11 100644 --- a/QLNet/Math/randomnumbers/seedgenerator.cs +++ b/QLNet/Math/randomnumbers/seedgenerator.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/randomnumbers/sobolrsg.cs b/QLNet/Math/randomnumbers/sobolrsg.cs index 1f695ec00..a92f473ec 100644 --- a/QLNet/Math/randomnumbers/sobolrsg.cs +++ b/QLNet/Math/randomnumbers/sobolrsg.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/randomnumbers/sobolrsg2.cs b/QLNet/Math/randomnumbers/sobolrsg2.cs index 2f33d2547..5249850e7 100644 --- a/QLNet/Math/randomnumbers/sobolrsg2.cs +++ b/QLNet/Math/randomnumbers/sobolrsg2.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/statistics/DiscrepancyStatistics.cs b/QLNet/Math/statistics/DiscrepancyStatistics.cs index 401a9cc9a..1a83385ce 100644 --- a/QLNet/Math/statistics/DiscrepancyStatistics.cs +++ b/QLNet/Math/statistics/DiscrepancyStatistics.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -113,7 +113,8 @@ public override void reset(int dimension){ public double discrepancy() { - int N = samples(); + int N = samples(); + if ( N == 0 ) return 0; /* Size i; Real r_ik, r_jk, cdiscr = adiscr = 0.0, temp = 1.0; diff --git a/QLNet/Math/statistics/convergencestatistics.cs b/QLNet/Math/statistics/convergencestatistics.cs index 1663e7805..e6ad8c7f6 100644 --- a/QLNet/Math/statistics/convergencestatistics.cs +++ b/QLNet/Math/statistics/convergencestatistics.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/statistics/gaussianstatistics.cs b/QLNet/Math/statistics/gaussianstatistics.cs index 09f83da2c..847cc963b 100644 --- a/QLNet/Math/statistics/gaussianstatistics.cs +++ b/QLNet/Math/statistics/gaussianstatistics.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/statistics/generalstatistics.cs b/QLNet/Math/statistics/generalstatistics.cs index 16a77ca1a..4b6467521 100644 --- a/QLNet/Math/statistics/generalstatistics.cs +++ b/QLNet/Math/statistics/generalstatistics.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/statistics/incrementalstatistics.cs b/QLNet/Math/statistics/incrementalstatistics.cs index 768fc43ed..5990ba320 100644 --- a/QLNet/Math/statistics/incrementalstatistics.cs +++ b/QLNet/Math/statistics/incrementalstatistics.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/statistics/riskstatistics.cs b/QLNet/Math/statistics/riskstatistics.cs index 43cedab13..bf3b5addf 100644 --- a/QLNet/Math/statistics/riskstatistics.cs +++ b/QLNet/Math/statistics/riskstatistics.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/statistics/sequencestatistics.cs b/QLNet/Math/statistics/sequencestatistics.cs index 3317a2d89..8c533dd24 100644 --- a/QLNet/Math/statistics/sequencestatistics.cs +++ b/QLNet/Math/statistics/sequencestatistics.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Math/transformedgrid.cs b/QLNet/Math/transformedgrid.cs index 77108ab52..d277186ea 100644 --- a/QLNet/Math/transformedgrid.cs +++ b/QLNet/Math/transformedgrid.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/AmericanCondition.cs b/QLNet/Methods/Finitedifferences/AmericanCondition.cs index 6d1f0c3a8..cff69449e 100644 --- a/QLNet/Methods/Finitedifferences/AmericanCondition.cs +++ b/QLNet/Methods/Finitedifferences/AmericanCondition.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/BoundaryCondition.cs b/QLNet/Methods/Finitedifferences/BoundaryCondition.cs index ad95344f4..b78e5d8d4 100644 --- a/QLNet/Methods/Finitedifferences/BoundaryCondition.cs +++ b/QLNet/Methods/Finitedifferences/BoundaryCondition.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/DPlusDMinus.cs b/QLNet/Methods/Finitedifferences/DPlusDMinus.cs index e9046dece..17f73592c 100644 --- a/QLNet/Methods/Finitedifferences/DPlusDMinus.cs +++ b/QLNet/Methods/Finitedifferences/DPlusDMinus.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/OperatorFactory.cs b/QLNet/Methods/Finitedifferences/OperatorFactory.cs index 2044ce426..48f276bf4 100644 --- a/QLNet/Methods/Finitedifferences/OperatorFactory.cs +++ b/QLNet/Methods/Finitedifferences/OperatorFactory.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/ParallelEvolver.cs b/QLNet/Methods/Finitedifferences/ParallelEvolver.cs index 425fda3fe..b03608ef5 100644 --- a/QLNet/Methods/Finitedifferences/ParallelEvolver.cs +++ b/QLNet/Methods/Finitedifferences/ParallelEvolver.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/ShoutCondition.cs b/QLNet/Methods/Finitedifferences/ShoutCondition.cs index 96495b123..d72a580ba 100644 --- a/QLNet/Methods/Finitedifferences/ShoutCondition.cs +++ b/QLNet/Methods/Finitedifferences/ShoutCondition.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/StepCondition.cs b/QLNet/Methods/Finitedifferences/StepCondition.cs index fc0bb7763..78221385b 100644 --- a/QLNet/Methods/Finitedifferences/StepCondition.cs +++ b/QLNet/Methods/Finitedifferences/StepCondition.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/TridiagonalOperator.cs b/QLNet/Methods/Finitedifferences/TridiagonalOperator.cs index 73f890424..982402bf8 100644 --- a/QLNet/Methods/Finitedifferences/TridiagonalOperator.cs +++ b/QLNet/Methods/Finitedifferences/TridiagonalOperator.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/bsmoperator.cs b/QLNet/Methods/Finitedifferences/bsmoperator.cs index 5d68c03d4..f7e4cb53d 100644 --- a/QLNet/Methods/Finitedifferences/bsmoperator.cs +++ b/QLNet/Methods/Finitedifferences/bsmoperator.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/cranknicolson.cs b/QLNet/Methods/Finitedifferences/cranknicolson.cs index 37203cdbe..2cdf6e809 100644 --- a/QLNet/Methods/Finitedifferences/cranknicolson.cs +++ b/QLNet/Methods/Finitedifferences/cranknicolson.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/dzero.cs b/QLNet/Methods/Finitedifferences/dzero.cs index 18809ef40..727c3e3d6 100644 --- a/QLNet/Methods/Finitedifferences/dzero.cs +++ b/QLNet/Methods/Finitedifferences/dzero.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/finitedifferencemodel.cs b/QLNet/Methods/Finitedifferences/finitedifferencemodel.cs index 1e9cc4038..798911a8f 100644 --- a/QLNet/Methods/Finitedifferences/finitedifferencemodel.cs +++ b/QLNet/Methods/Finitedifferences/finitedifferencemodel.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/mixedscheme.cs b/QLNet/Methods/Finitedifferences/mixedscheme.cs index d2fbd3895..c9f40940c 100644 --- a/QLNet/Methods/Finitedifferences/mixedscheme.cs +++ b/QLNet/Methods/Finitedifferences/mixedscheme.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/pde.cs b/QLNet/Methods/Finitedifferences/pde.cs index be8f252ff..103e42cdf 100644 --- a/QLNet/Methods/Finitedifferences/pde.cs +++ b/QLNet/Methods/Finitedifferences/pde.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/pdebsm.cs b/QLNet/Methods/Finitedifferences/pdebsm.cs index c7c93aa5b..d02697b40 100644 --- a/QLNet/Methods/Finitedifferences/pdebsm.cs +++ b/QLNet/Methods/Finitedifferences/pdebsm.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/Finitedifferences/pdeshortrate.cs b/QLNet/Methods/Finitedifferences/pdeshortrate.cs index 2393d9fe5..812fdad78 100644 --- a/QLNet/Methods/Finitedifferences/pdeshortrate.cs +++ b/QLNet/Methods/Finitedifferences/pdeshortrate.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/lattices/binominaltree.cs b/QLNet/Methods/lattices/binominaltree.cs index 73da48e1f..de12ef500 100644 --- a/QLNet/Methods/lattices/binominaltree.cs +++ b/QLNet/Methods/lattices/binominaltree.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/lattices/bsmlattice.cs b/QLNet/Methods/lattices/bsmlattice.cs index a0a98f2d8..c0665b54d 100644 --- a/QLNet/Methods/lattices/bsmlattice.cs +++ b/QLNet/Methods/lattices/bsmlattice.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/lattices/lattice.cs b/QLNet/Methods/lattices/lattice.cs index 3d0380bc0..99be67fdb 100644 --- a/QLNet/Methods/lattices/lattice.cs +++ b/QLNet/Methods/lattices/lattice.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/lattices/lattice1d.cs b/QLNet/Methods/lattices/lattice1d.cs index abcb11357..1b3f9251d 100644 --- a/QLNet/Methods/lattices/lattice1d.cs +++ b/QLNet/Methods/lattices/lattice1d.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/lattices/lattice2d.cs b/QLNet/Methods/lattices/lattice2d.cs index 4ccbe6167..48b6aa03b 100644 --- a/QLNet/Methods/lattices/lattice2d.cs +++ b/QLNet/Methods/lattices/lattice2d.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/lattices/tree.cs b/QLNet/Methods/lattices/tree.cs index 588f08f93..f3d0bc834 100644 --- a/QLNet/Methods/lattices/tree.cs +++ b/QLNet/Methods/lattices/tree.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/lattices/trinomialtree.cs b/QLNet/Methods/lattices/trinomialtree.cs index 950db06ac..3ce3d7dfc 100644 --- a/QLNet/Methods/lattices/trinomialtree.cs +++ b/QLNet/Methods/lattices/trinomialtree.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/montecarlo/brownianbridge.cs b/QLNet/Methods/montecarlo/brownianbridge.cs index 3d6c46f5c..253d10994 100644 --- a/QLNet/Methods/montecarlo/brownianbridge.cs +++ b/QLNet/Methods/montecarlo/brownianbridge.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/montecarlo/earlyexercisepathpricer.cs b/QLNet/Methods/montecarlo/earlyexercisepathpricer.cs index 2324307b2..f3014d183 100644 --- a/QLNet/Methods/montecarlo/earlyexercisepathpricer.cs +++ b/QLNet/Methods/montecarlo/earlyexercisepathpricer.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/montecarlo/longstaffschwartzpathpricer.cs b/QLNet/Methods/montecarlo/longstaffschwartzpathpricer.cs index 1bfa12a60..62bf22fa4 100644 --- a/QLNet/Methods/montecarlo/longstaffschwartzpathpricer.cs +++ b/QLNet/Methods/montecarlo/longstaffschwartzpathpricer.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/montecarlo/lsmbasissystem.cs b/QLNet/Methods/montecarlo/lsmbasissystem.cs index c13949846..95fe147b3 100644 --- a/QLNet/Methods/montecarlo/lsmbasissystem.cs +++ b/QLNet/Methods/montecarlo/lsmbasissystem.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -19,7 +19,7 @@ under the terms of the QLNet license. You should have received a /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -117,7 +117,7 @@ public static List> multiPathBasisSystem(int dim, int order // find duplicates for (k = 0; k < ret.Count; ++k) { - if (v.First(xx => (Math.Abs(v[k] - xx) <= 10*v[k]*Const.QL_Epsilon)) == v.First() + k) { + if (v.First(xx => (Math.Abs(v[k] - xx) <= 10*v[k]*Const.QL_EPSILON)) == v.First() + k) { // don't remove this item, it's unique! rm[k] = false; } diff --git a/QLNet/Methods/montecarlo/mctraits.cs b/QLNet/Methods/montecarlo/mctraits.cs index 6f10ffb50..138ac6d03 100644 --- a/QLNet/Methods/montecarlo/mctraits.cs +++ b/QLNet/Methods/montecarlo/mctraits.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/montecarlo/montecarlomodel.cs b/QLNet/Methods/montecarlo/montecarlomodel.cs index aefd5d2eb..de6c9665c 100644 --- a/QLNet/Methods/montecarlo/montecarlomodel.cs +++ b/QLNet/Methods/montecarlo/montecarlomodel.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/montecarlo/multipath.cs b/QLNet/Methods/montecarlo/multipath.cs index 969c551ba..cafcb5cb1 100644 --- a/QLNet/Methods/montecarlo/multipath.cs +++ b/QLNet/Methods/montecarlo/multipath.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/montecarlo/multipathgenerator.cs b/QLNet/Methods/montecarlo/multipathgenerator.cs index 66c6d410e..bcfa3ae52 100644 --- a/QLNet/Methods/montecarlo/multipathgenerator.cs +++ b/QLNet/Methods/montecarlo/multipathgenerator.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/montecarlo/path.cs b/QLNet/Methods/montecarlo/path.cs index fc304593f..4ca933c1f 100644 --- a/QLNet/Methods/montecarlo/path.cs +++ b/QLNet/Methods/montecarlo/path.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/montecarlo/pathgenerator.cs b/QLNet/Methods/montecarlo/pathgenerator.cs index 4e3b5839d..73a02b61d 100644 --- a/QLNet/Methods/montecarlo/pathgenerator.cs +++ b/QLNet/Methods/montecarlo/pathgenerator.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/montecarlo/pathpricer.cs b/QLNet/Methods/montecarlo/pathpricer.cs index 23e15a449..414408b06 100644 --- a/QLNet/Methods/montecarlo/pathpricer.cs +++ b/QLNet/Methods/montecarlo/pathpricer.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Methods/montecarlo/sample.cs b/QLNet/Methods/montecarlo/sample.cs index 74a79451d..4034c68b2 100644 --- a/QLNet/Methods/montecarlo/sample.cs +++ b/QLNet/Methods/montecarlo/sample.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Models/CalibrationHelper.cs b/QLNet/Models/CalibrationHelper.cs index 3232b10a5..f8c8e7f52 100644 --- a/QLNet/Models/CalibrationHelper.cs +++ b/QLNet/Models/CalibrationHelper.cs @@ -1,21 +1,21 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; using System.Collections.Generic; @@ -44,15 +44,15 @@ public CalibrationHelper( Handle volatility, termStructure_.registerWith( update ); } - protected override void performCalculations() - { - marketValue_ = blackPrice(volatility_.link.value()); + protected override void performCalculations() + { + marketValue_ = blackPrice(volatility_.link.value()); } //! returns the volatility Handle public Handle volatility() { return volatility_; } - //! returns the actual price of the instrument (from volatility) + //! returns the actual price of the instrument (from volatility) public double marketValue() { calculate(); return marketValue_; } //! returns the price of the instrument according to the model @@ -93,7 +93,7 @@ public virtual double calibrationError() break; } - return error; + return error; } @@ -142,4 +142,4 @@ public override double value( double x ) } } -} +} diff --git a/QLNet/Models/Parameter.cs b/QLNet/Models/Parameter.cs index 58d4278b0..ad0fd35ad 100644 --- a/QLNet/Models/Parameter.cs +++ b/QLNet/Models/Parameter.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Models/Shortrate/OneFactorModel.cs b/QLNet/Models/Shortrate/OneFactorModel.cs index b43f325d1..83cbffb58 100644 --- a/QLNet/Models/Shortrate/OneFactorModel.cs +++ b/QLNet/Models/Shortrate/OneFactorModel.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Models/Shortrate/Onefactormodels/blackkarasinski.cs b/QLNet/Models/Shortrate/Onefactormodels/blackkarasinski.cs index 0bce84b30..ba4a66b67 100644 --- a/QLNet/Models/Shortrate/Onefactormodels/blackkarasinski.cs +++ b/QLNet/Models/Shortrate/Onefactormodels/blackkarasinski.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Models/Shortrate/Onefactormodels/coxingersollross.cs b/QLNet/Models/Shortrate/Onefactormodels/coxingersollross.cs index 2c7cc9482..a46cf3ee2 100644 --- a/QLNet/Models/Shortrate/Onefactormodels/coxingersollross.cs +++ b/QLNet/Models/Shortrate/Onefactormodels/coxingersollross.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -71,7 +71,7 @@ public override double discountBondOption(Option.Type type, double discountT = discountBond(0.0, maturity, x0()); double discountS = discountBond(0.0, bondMaturity, x0()); - if (maturity < Const.QL_Epsilon) + if (maturity < Const.QL_EPSILON) { switch (type){ case Option.Type.Call: diff --git a/QLNet/Models/Shortrate/Onefactormodels/hullwhite.cs b/QLNet/Models/Shortrate/Onefactormodels/hullwhite.cs index 595cad61f..ec425255c 100644 --- a/QLNet/Models/Shortrate/Onefactormodels/hullwhite.cs +++ b/QLNet/Models/Shortrate/Onefactormodels/hullwhite.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -102,7 +102,7 @@ public override double discountBondOption(Option.Type type, double bondMaturity){ double _a = a(); double v; - if (_a < Math.Sqrt(Const.QL_Epsilon)) + if (_a < Math.Sqrt(Const.QL_EPSILON)) { v = sigma() * B(maturity, bondMaturity) * Math.Sqrt(maturity); } else { @@ -229,7 +229,7 @@ public Impl(Handle termStructure, public override double value(Vector v, double t) { double forwardRate = termStructure_.link.forwardRate(t, t, Compounding.Continuous, Frequency.NoFrequency).rate(); - double temp = a_ < Math.Sqrt(Const.QL_Epsilon) ? + double temp = a_ < Math.Sqrt(Const.QL_EPSILON) ? sigma_*t : sigma_*(1.0 - Math.Exp(-a_*t))/a_; return (forwardRate + 0.5*temp*temp); diff --git a/QLNet/Models/Shortrate/Onefactormodels/vasicek.cs b/QLNet/Models/Shortrate/Onefactormodels/vasicek.cs index 26e0238eb..0757a9dcd 100644 --- a/QLNet/Models/Shortrate/Onefactormodels/vasicek.cs +++ b/QLNet/Models/Shortrate/Onefactormodels/vasicek.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -75,10 +75,10 @@ public override double discountBondOption(Option.Type type, double bondMaturity) { double v; double _a = a(); - if (Math.Abs(maturity) < Const.QL_Epsilon){ + if (Math.Abs(maturity) < Const.QL_EPSILON){ v = 0.0; } - else if (_a < Math.Sqrt(Const.QL_Epsilon)){ + else if (_a < Math.Sqrt(Const.QL_EPSILON)){ v = sigma()*B(maturity, bondMaturity)* Math.Sqrt(maturity); } else { v = sigma()*B(maturity, bondMaturity)* @@ -96,7 +96,7 @@ public override ShortRateDynamics dynamics(){ protected override double A(double t, double T){ double _a = a(); - if (_a < Math.Sqrt(Const.QL_Epsilon)) + if (_a < Math.Sqrt(Const.QL_EPSILON)) { return 0.0; } else { @@ -110,7 +110,7 @@ protected override double A(double t, double T){ protected override double B(double t, double T){ double _a = a(); - if (_a < Math.Sqrt(Const.QL_Epsilon)) + if (_a < Math.Sqrt(Const.QL_EPSILON)) return (T - t); else return (1.0 - Math.Exp(-_a*(T - t)))/_a; diff --git a/QLNet/Models/Shortrate/Twofactorsmodels/g2.cs b/QLNet/Models/Shortrate/Twofactorsmodels/g2.cs index a7de71311..25cc7b4bb 100644 --- a/QLNet/Models/Shortrate/Twofactorsmodels/g2.cs +++ b/QLNet/Models/Shortrate/Twofactorsmodels/g2.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe double (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Models/Shortrate/calibrationhelpers/caphelper.cs b/QLNet/Models/Shortrate/calibrationhelpers/caphelper.cs index 1600f6f5f..6737c2c4f 100644 --- a/QLNet/Models/Shortrate/calibrationhelpers/caphelper.cs +++ b/QLNet/Models/Shortrate/calibrationhelpers/caphelper.cs @@ -1,28 +1,28 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace QLNet +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet { public class CapHelper : CalibrationHelper { @@ -37,9 +37,9 @@ public CapHelper( Period length, CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError) : base( volatility, termStructure, errorType ) { - length_ = length; - index_ = index; - fixedLegFrequency_ = fixedLegFrequency; + length_ = length; + index_ = index; + fixedLegFrequency_ = fixedLegFrequency; fixedLegDayCounter_ = fixedLegDayCounter; includeFirstSwaplet_ = includeFirstSwaplet; @@ -140,5 +140,5 @@ protected override void performCalculations() private Frequency fixedLegFrequency_; private DayCounter fixedLegDayCounter_; private bool includeFirstSwaplet_; - } -} + } +} diff --git a/QLNet/Models/Shortrate/calibrationhelpers/swaptionhelper.cs b/QLNet/Models/Shortrate/calibrationhelpers/swaptionhelper.cs index 101445114..13275a552 100644 --- a/QLNet/Models/Shortrate/calibrationhelpers/swaptionhelper.cs +++ b/QLNet/Models/Shortrate/calibrationhelpers/swaptionhelper.cs @@ -1,21 +1,21 @@ -/* - Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) + Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; using System.Collections.Generic; @@ -39,14 +39,14 @@ public SwaptionHelper( Period maturity, double nominal = 1.0 ) : base( volatility, termStructure, errorType ) { - exerciseDate_ = null; - endDate_ = null; - maturity_ = maturity; - length_ = length; - fixedLegTenor_ = fixedLegTenor; - index_ = index; - fixedLegDayCounter_ = fixedLegDayCounter; - floatingLegDayCounter_ = floatingLegDayCounter; + exerciseDate_ = null; + endDate_ = null; + maturity_ = maturity; + length_ = length; + fixedLegTenor_ = fixedLegTenor; + index_ = index; + fixedLegDayCounter_ = fixedLegDayCounter; + floatingLegDayCounter_ = floatingLegDayCounter; strike_ = strike; nominal_ = nominal; @@ -80,16 +80,16 @@ public SwaptionHelper( Period maturity, index_.registerWith( update ); } - SwaptionHelper( Date exerciseDate, - Date endDate, - Handle volatility, - IborIndex index, - Period fixedLegTenor, - DayCounter fixedLegDayCounter, - DayCounter floatingLegDayCounter, - Handle termStructure, + SwaptionHelper( Date exerciseDate, + Date endDate, + Handle volatility, + IborIndex index, + Period fixedLegTenor, + DayCounter fixedLegDayCounter, + DayCounter floatingLegDayCounter, + Handle termStructure, CalibrationErrorType errorType = CalibrationErrorType.RelativePriceError, - double? strike =null, + double? strike =null, double nominal = 1.0) : base( volatility, termStructure, errorType ) { @@ -142,66 +142,66 @@ public override double blackPrice( double sigma ) return value; } - public VanillaSwap underlyingSwap() { calculate(); return swap_; } + public VanillaSwap underlyingSwap() { calculate(); return swap_; } public Swaption swaption() { calculate(); return swaption_; } protected override void performCalculations() { - Calendar calendar = index_.fixingCalendar(); - int fixingDays = index_.fixingDays(); - - Date exerciseDate = exerciseDate_; - if (exerciseDate == null) - exerciseDate = calendar.advance(termStructure_.link.referenceDate(), - maturity_, - index_.businessDayConvention()); - - Date startDate = calendar.advance(exerciseDate, - fixingDays, TimeUnit.Days, - index_.businessDayConvention()); - - Date endDate = endDate_; - if (endDate == null) - endDate = calendar.advance(startDate, length_, - index_.businessDayConvention()); - - Schedule fixedSchedule = new Schedule(startDate, endDate, fixedLegTenor_, calendar, - index_.businessDayConvention(), - index_.businessDayConvention(), - DateGeneration.Rule.Forward, false); - Schedule floatSchedule = new Schedule(startDate, endDate, index_.tenor(), calendar, - index_.businessDayConvention(), - index_.businessDayConvention(), - DateGeneration.Rule.Forward, false); - - IPricingEngine swapEngine = new DiscountingSwapEngine(termStructure_, false); - - VanillaSwap.Type type = VanillaSwap.Type.Receiver; - - VanillaSwap temp = new VanillaSwap(VanillaSwap.Type.Receiver, nominal_, - fixedSchedule, 0.0, fixedLegDayCounter_, - floatSchedule, index_, 0.0, floatingLegDayCounter_); - temp.setPricingEngine(swapEngine); - double forward = temp.fairRate(); - if(! strike_.HasValue) - { - exerciseRate_ = forward; - } - else - { - exerciseRate_ = strike_.Value; - type = strike_ <= forward ? VanillaSwap.Type.Receiver : VanillaSwap.Type.Payer; - // ensure that calibration instrument is out of the money - } - swap_ = new VanillaSwap(type, nominal_, - fixedSchedule, exerciseRate_, fixedLegDayCounter_, - floatSchedule, index_, 0.0, floatingLegDayCounter_); - swap_.setPricingEngine(swapEngine); - - Exercise exercise = new EuropeanExercise(exerciseDate); - - swaption_ = new Swaption(swap_, exercise); - + Calendar calendar = index_.fixingCalendar(); + int fixingDays = index_.fixingDays(); + + Date exerciseDate = exerciseDate_; + if (exerciseDate == null) + exerciseDate = calendar.advance(termStructure_.link.referenceDate(), + maturity_, + index_.businessDayConvention()); + + Date startDate = calendar.advance(exerciseDate, + fixingDays, TimeUnit.Days, + index_.businessDayConvention()); + + Date endDate = endDate_; + if (endDate == null) + endDate = calendar.advance(startDate, length_, + index_.businessDayConvention()); + + Schedule fixedSchedule = new Schedule(startDate, endDate, fixedLegTenor_, calendar, + index_.businessDayConvention(), + index_.businessDayConvention(), + DateGeneration.Rule.Forward, false); + Schedule floatSchedule = new Schedule(startDate, endDate, index_.tenor(), calendar, + index_.businessDayConvention(), + index_.businessDayConvention(), + DateGeneration.Rule.Forward, false); + + IPricingEngine swapEngine = new DiscountingSwapEngine(termStructure_, false); + + VanillaSwap.Type type = VanillaSwap.Type.Receiver; + + VanillaSwap temp = new VanillaSwap(VanillaSwap.Type.Receiver, nominal_, + fixedSchedule, 0.0, fixedLegDayCounter_, + floatSchedule, index_, 0.0, floatingLegDayCounter_); + temp.setPricingEngine(swapEngine); + double forward = temp.fairRate(); + if(! strike_.HasValue) + { + exerciseRate_ = forward; + } + else + { + exerciseRate_ = strike_.Value; + type = strike_ <= forward ? VanillaSwap.Type.Receiver : VanillaSwap.Type.Payer; + // ensure that calibration instrument is out of the money + } + swap_ = new VanillaSwap(type, nominal_, + fixedSchedule, exerciseRate_, fixedLegDayCounter_, + floatSchedule, index_, 0.0, floatingLegDayCounter_); + swap_.setPricingEngine(swapEngine); + + Exercise exercise = new EuropeanExercise(exerciseDate); + + swaption_ = new Swaption(swap_, exercise); + base.performCalculations(); } @@ -215,4 +215,4 @@ protected override void performCalculations() private VanillaSwap swap_; private Swaption swaption_; } -} +} diff --git a/QLNet/Models/Shortrate/twofactormodel.cs b/QLNet/Models/Shortrate/twofactormodel.cs index fa1861b56..bfa3e611b 100644 --- a/QLNet/Models/Shortrate/twofactormodel.cs +++ b/QLNet/Models/Shortrate/twofactormodel.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Models/model.cs b/QLNet/Models/model.cs index 224266887..a8528fdfe 100644 --- a/QLNet/Models/model.cs +++ b/QLNet/Models/model.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Money.cs b/QLNet/Money.cs index 0ee24f610..2c234af5e 100644 --- a/QLNet/Money.cs +++ b/QLNet/Money.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Option.cs b/QLNet/Option.cs index ffa1f2149..5c71513b8 100644 Binary files a/QLNet/Option.cs and b/QLNet/Option.cs differ diff --git a/QLNet/Patterns/LazyObject.cs b/QLNet/Patterns/LazyObject.cs index d248a5074..cdee51e36 100644 Binary files a/QLNet/Patterns/LazyObject.cs and b/QLNet/Patterns/LazyObject.cs differ diff --git a/QLNet/Patterns/Observer.cs b/QLNet/Patterns/Observer.cs index a626bcbf0..f51420004 100644 --- a/QLNet/Patterns/Observer.cs +++ b/QLNet/Patterns/Observer.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Patterns/Visitor.cs b/QLNet/Patterns/Visitor.cs index 1b735cec1..dada4450b 100644 Binary files a/QLNet/Patterns/Visitor.cs and b/QLNet/Patterns/Visitor.cs differ diff --git a/QLNet/Patterns/observablevalue.cs b/QLNet/Patterns/observablevalue.cs index edcac3579..e400c13c6 100644 --- a/QLNet/Patterns/observablevalue.cs +++ b/QLNet/Patterns/observablevalue.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/PricingEngine.cs b/QLNet/PricingEngine.cs index 7c1508c32..b49fad51a 100644 Binary files a/QLNet/PricingEngine.cs and b/QLNet/PricingEngine.cs differ diff --git a/QLNet/Pricingengines/Americanpayoffatexpiry.cs b/QLNet/Pricingengines/Americanpayoffatexpiry.cs index c61d08a74..9603fb932 100644 --- a/QLNet/Pricingengines/Americanpayoffatexpiry.cs +++ b/QLNet/Pricingengines/Americanpayoffatexpiry.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -105,7 +105,7 @@ public AmericanPayoffAtExpiry(double spot, double discount, double dividendDisco double n_d2; double cum_d1_; double cum_d2_; - if (variance_ >= Const.QL_Epsilon) { + if (variance_ >= Const.QL_EPSILON) { D1_ = log_H_S_ / stdDev_ + mu_ * stdDev_; D2_ = D1_ - 2.0 * mu_ * stdDev_; CumulativeNormalDistribution f = new CumulativeNormalDistribution(); diff --git a/QLNet/Pricingengines/Americanpayoffathit.cs b/QLNet/Pricingengines/Americanpayoffathit.cs index d58e2a516..ee1be3bf0 100644 --- a/QLNet/Pricingengines/Americanpayoffathit.cs +++ b/QLNet/Pricingengines/Americanpayoffathit.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -85,7 +85,7 @@ public AmericanPayoffAtHit(double spot, double discount, double dividendDiscount double n_d2; double cum_d1_; double cum_d2_; - if (variance_ >= Const.QL_Epsilon) { + if (variance_ >= Const.QL_EPSILON) { if (discount_ == 0.0 && dividendDiscount_ == 0.0) { mu_ = -0.5; lambda_ = 0.5; diff --git a/QLNet/Pricingengines/BlackCalculator.cs b/QLNet/Pricingengines/BlackCalculator.cs index c746985ab..6aaf8cea5 100644 --- a/QLNet/Pricingengines/BlackCalculator.cs +++ b/QLNet/Pricingengines/BlackCalculator.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -51,7 +51,7 @@ public BlackCalculator(StrikedTypePayoff payoff, double forward, double stdDev, if (!(discount>0.0)) throw new ApplicationException("positive discount required: " + discount + " not allowed"); - if (stdDev_>=Const.QL_Epsilon) { + if (stdDev_>=Const.QL_EPSILON) { if (strike_==0.0) { n_d1_ = 0.0; n_d2_ = 0.0; @@ -149,9 +149,9 @@ underlying forward price. */ public double elasticityForward() { double val = value(); double del = deltaForward(); - if (val > Const.QL_Epsilon) + if (val > Const.QL_EPSILON) return del/val*forward_; - else if (Math.Abs(del)0.0) return double.MaxValue; @@ -164,9 +164,9 @@ underlying spot price. */ public virtual double elasticity(double spot) { double val = value(); double del = delta(spot); - if (val>Const.QL_Epsilon) + if (val>Const.QL_EPSILON) return del/val*spot; - else if (Math.Abs(del) < Const.QL_Epsilon) + else if (Math.Abs(del) < Const.QL_EPSILON) return 0.0; else if (del>0.0) return double.MaxValue; diff --git a/QLNet/Pricingengines/Blackscholescalculator.cs b/QLNet/Pricingengines/Blackscholescalculator.cs index e196f40a5..c335237e0 100644 --- a/QLNet/Pricingengines/Blackscholescalculator.cs +++ b/QLNet/Pricingengines/Blackscholescalculator.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/Bond/BlackCallableBondEngine.cs b/QLNet/Pricingengines/Bond/BlackCallableBondEngine.cs index 84a41aae6..33580b148 100644 --- a/QLNet/Pricingengines/Bond/BlackCallableBondEngine.cs +++ b/QLNet/Pricingengines/Bond/BlackCallableBondEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -60,11 +60,11 @@ public BlackCallableFixedRateBondEngine(Handle public override void calculate() { - // validate args for Black engine + // validate args for Black engine Utils.QL_REQUIRE( arguments_.putCallSchedule.Count == 1, () => "Must have exactly one call/put date to use Black Engine" ); Date settle = arguments_.settlementDate; - Date exerciseDate = arguments_.callabilityDates[0]; + Date exerciseDate = arguments_.callabilityDates[0]; Utils.QL_REQUIRE( exerciseDate >= settle, () => "must have exercise Date >= settlement Date" ); List fixedLeg = arguments_.cashflows; diff --git a/QLNet/Pricingengines/Bond/BondFunctions.cs b/QLNet/Pricingengines/Bond/BondFunctions.cs index e10fcb69b..e6d6ea0c4 100644 --- a/QLNet/Pricingengines/Bond/BondFunctions.cs +++ b/QLNet/Pricingengines/Bond/BondFunctions.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -121,8 +121,8 @@ public static double nextCouponRate(Bond bond, Date settlementDate = null) public static Date accrualStartDate(Bond bond, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -132,8 +132,8 @@ public static Date accrualStartDate(Bond bond, Date settlementDate = null) public static Date accrualEndDate(Bond bond, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -143,8 +143,8 @@ public static Date accrualEndDate(Bond bond, Date settlementDate = null) public static Date referencePeriodStart(Bond bond, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -154,8 +154,8 @@ public static Date referencePeriodStart(Bond bond, Date settlementDate = null) public static Date referencePeriodEnd(Bond bond, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -165,8 +165,8 @@ public static Date referencePeriodEnd(Bond bond, Date settlementDate = null) public static double accrualPeriod(Bond bond, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -176,8 +176,8 @@ public static double accrualPeriod(Bond bond, Date settlementDate = null) public static int accrualDays(Bond bond, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -187,8 +187,8 @@ public static int accrualDays(Bond bond, Date settlementDate = null) public static double accruedPeriod(Bond bond, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -198,8 +198,8 @@ public static double accruedPeriod(Bond bond, Date settlementDate = null) public static double accruedDays(Bond bond, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -209,8 +209,8 @@ public static double accruedDays(Bond bond, Date settlementDate = null) public static double accruedAmount(Bond bond, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -225,8 +225,8 @@ public static double accruedAmount(Bond bond, Date settlementDate = null) public static double cleanPrice(Bond bond, YieldTermStructure discountCurve, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " settlementDate date (maturity being " + @@ -239,8 +239,8 @@ public static double cleanPrice(Bond bond, YieldTermStructure discountCurve, Dat public static double bps(Bond bond, YieldTermStructure discountCurve, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -250,8 +250,8 @@ public static double bps(Bond bond, YieldTermStructure discountCurve, Date settl public static double atmRate(Bond bond, YieldTermStructure discountCurve, Date settlementDate = null, double? cleanPrice = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -265,8 +265,8 @@ public static double atmRate(Bond bond, YieldTermStructure discountCurve, Date s #endregion - #region Yield (a.k.a. Internal Rate of Return, i.e. IRR) functions - + #region Yield (a.k.a. Internal Rate of Return, i.e. IRR) functions + public static double cleanPrice(Bond bond, InterestRate yield, Date settlementDate = null) { return dirtyPrice(bond, yield, settlementDate) - bond.accruedAmount(settlementDate); @@ -275,30 +275,30 @@ public static double cleanPrice(Bond bond, double yield, DayCounter dayCounter, Date settlementDate = null) { return cleanPrice(bond, new InterestRate(yield, dayCounter, compounding, frequency), settlementDate); - } - public static double dirtyPrice(Bond bond, InterestRate yield, Date settlementDate = null) - { - if (settlementDate == null) - settlementDate = bond.settlementDate(); - - Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => - "non tradable at " + settlementDate + - " (maturity being " + bond.maturityDate() + ")"); - - double dirtyPrice = CashFlows.npv(bond.cashflows(), yield, false, settlementDate) * - 100.0 / bond.notional(settlementDate); - return dirtyPrice; - } - public static double dirtyPrice(Bond bond, double yield, DayCounter dayCounter, Compounding compounding, Frequency frequency, - Date settlementDate = null) - { - return dirtyPrice(bond, new InterestRate(yield, dayCounter, compounding, frequency), settlementDate); - } + } + public static double dirtyPrice(Bond bond, InterestRate yield, Date settlementDate = null) + { + if (settlementDate == null) + settlementDate = bond.settlementDate(); + + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => + "non tradable at " + settlementDate + + " (maturity being " + bond.maturityDate() + ")"); + + double dirtyPrice = CashFlows.npv(bond.cashflows(), yield, false, settlementDate) * + 100.0 / bond.notional(settlementDate); + return dirtyPrice; + } + public static double dirtyPrice(Bond bond, double yield, DayCounter dayCounter, Compounding compounding, Frequency frequency, + Date settlementDate = null) + { + return dirtyPrice(bond, new InterestRate(yield, dayCounter, compounding, frequency), settlementDate); + } public static double bps(Bond bond, InterestRate yield, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -315,8 +315,8 @@ public static double yield(Bond bond, double cleanPrice, DayCounter dayCounter, Date settlementDate = null, double accuracy = 1.0e-10, int maxIterations = 100, double guess = 0.05) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -333,8 +333,8 @@ public static double duration(Bond bond, InterestRate yield, Duration.Type type Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -349,8 +349,8 @@ public static double duration(Bond bond, double yield, DayCounter dayCounter, Co public static double convexity(Bond bond, InterestRate yield, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -365,8 +365,8 @@ public static double convexity(Bond bond, double yield, DayCounter dayCounter, C public static double basisPointValue(Bond bond, InterestRate yield, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -382,8 +382,8 @@ public static double basisPointValue(Bond bond, double yield, DayCounter dayCoun public static double yieldValueBasisPoint(Bond bond, InterestRate yield, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -404,8 +404,8 @@ public static double cleanPrice(Bond bond, YieldTermStructure discount, double z Frequency frequency, Date settlementDate = null) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); @@ -419,8 +419,8 @@ public static double zSpread(Bond bond, double cleanPrice, YieldTermStructure di double guess = 0.0) { if (settlementDate == null) - settlementDate = bond.settlementDate(); - + settlementDate = bond.settlementDate(); + Utils.QL_REQUIRE( BondFunctions.isTradable( bond, settlementDate ), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); diff --git a/QLNet/Pricingengines/Bond/Discountingbondengine.cs b/QLNet/Pricingengines/Bond/Discountingbondengine.cs index 503f75c6b..7db0abe92 100644 --- a/QLNet/Pricingengines/Bond/Discountingbondengine.cs +++ b/QLNet/Pricingengines/Bond/Discountingbondengine.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -37,7 +37,7 @@ public DiscountingBondEngine(Handle discountCurve, bool? inc } public override void calculate() - { + { Utils.QL_REQUIRE( !discountCurve_.empty(), () => "discounting term structure handle is empty" ); results_.valuationDate = discountCurve_.link.referenceDate(); diff --git a/QLNet/Pricingengines/Bond/TreeCallableBondEngine.cs b/QLNet/Pricingengines/Bond/TreeCallableBondEngine.cs index 2babaa3fd..8aeee9bb2 100644 --- a/QLNet/Pricingengines/Bond/TreeCallableBondEngine.cs +++ b/QLNet/Pricingengines/Bond/TreeCallableBondEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -53,7 +53,7 @@ public TreeCallableFixedRateBondEngine(ShortRateModel model, TimeGrid timeGrid, } //@} public override void calculate() - { + { Utils.QL_REQUIRE( model_ != null, () => "no model specified" ); Date referenceDate; diff --git a/QLNet/Pricingengines/CapFloor/analyticcapfloorengine.cs b/QLNet/Pricingengines/CapFloor/analyticcapfloorengine.cs index c921fc08c..18f22db37 100644 --- a/QLNet/Pricingengines/CapFloor/analyticcapfloorengine.cs +++ b/QLNet/Pricingengines/CapFloor/analyticcapfloorengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/CapFloor/discretizedcapfloor.cs b/QLNet/Pricingengines/CapFloor/discretizedcapfloor.cs index befefb26d..27ab430a8 100644 --- a/QLNet/Pricingengines/CapFloor/discretizedcapfloor.cs +++ b/QLNet/Pricingengines/CapFloor/discretizedcapfloor.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/Greeks.cs b/QLNet/Pricingengines/Greeks.cs index 3d9c63543..fb6bcff19 100644 --- a/QLNet/Pricingengines/Greeks.cs +++ b/QLNet/Pricingengines/Greeks.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/Loan/DiscountingLoanEngine.cs b/QLNet/Pricingengines/Loan/DiscountingLoanEngine.cs index 51124cdeb..258de2e9b 100644 --- a/QLNet/Pricingengines/Loan/DiscountingLoanEngine.cs +++ b/QLNet/Pricingengines/Loan/DiscountingLoanEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/Swap/DiscountingBasisSwapEngine.cs b/QLNet/Pricingengines/Swap/DiscountingBasisSwapEngine.cs index 2c916f1e9..e82d0f395 100644 --- a/QLNet/Pricingengines/Swap/DiscountingBasisSwapEngine.cs +++ b/QLNet/Pricingengines/Swap/DiscountingBasisSwapEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/Swap/Discountingswapengine.cs b/QLNet/Pricingengines/Swap/Discountingswapengine.cs index 96f690450..6f4a78955 100644 --- a/QLNet/Pricingengines/Swap/Discountingswapengine.cs +++ b/QLNet/Pricingengines/Swap/Discountingswapengine.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -42,7 +42,7 @@ public DiscountingSwapEngine(Handle discountCurve,bool? incl // Instrument interface public override void calculate() - { + { Utils.QL_REQUIRE( !discountCurve_.empty(), () => "discounting term structure handle is empty" ); results_.value = results_.cash = 0; @@ -56,7 +56,7 @@ public override void calculate() settlementDate = refDate; } else - { + { Utils.QL_REQUIRE( settlementDate >= refDate, () => "settlement date (" + settlementDate + ") before " + "discount curve reference date (" + refDate + ")"); @@ -68,7 +68,7 @@ public override void calculate() results_.valuationDate = refDate; } else - { + { Utils.QL_REQUIRE( npvDate_ >= refDate, () => "npv date (" + npvDate_ + ") before "+ "discount curve reference date (" + refDate + ")"); diff --git a/QLNet/Pricingengines/Swap/discretizedswap.cs b/QLNet/Pricingengines/Swap/discretizedswap.cs index 73fce7746..ac492ae5b 100644 --- a/QLNet/Pricingengines/Swap/discretizedswap.cs +++ b/QLNet/Pricingengines/Swap/discretizedswap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/Swap/treeswapengine.cs b/QLNet/Pricingengines/Swap/treeswapengine.cs index de20f1869..62f593261 100644 --- a/QLNet/Pricingengines/Swap/treeswapengine.cs +++ b/QLNet/Pricingengines/Swap/treeswapengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/asian/analytic_cont_geom_av_price.cs b/QLNet/Pricingengines/asian/analytic_cont_geom_av_price.cs index 19be5d6f2..5327d11d0 100644 --- a/QLNet/Pricingengines/asian/analytic_cont_geom_av_price.cs +++ b/QLNet/Pricingengines/asian/analytic_cont_geom_av_price.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/asian/analytic_discr_geom_av_price.cs b/QLNet/Pricingengines/asian/analytic_discr_geom_av_price.cs index b023950da..8f9f84673 100644 --- a/QLNet/Pricingengines/asian/analytic_discr_geom_av_price.cs +++ b/QLNet/Pricingengines/asian/analytic_discr_geom_av_price.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -147,7 +147,7 @@ public override void calculate() double Nx_1, nx_1; CumulativeNormalDistribution CND = new CumulativeNormalDistribution(); NormalDistribution ND = new NormalDistribution(); - if (sigG > Const.QL_Epsilon) { + if (sigG > Const.QL_EPSILON) { double x_1 = (muG-Math.Log(payoff.strike())+variance)/sigG; Nx_1 = CND.value(x_1); nx_1 = ND.value( x_1); diff --git a/QLNet/Pricingengines/asian/mc_discr_arith_av_price.cs b/QLNet/Pricingengines/asian/mc_discr_arith_av_price.cs index 09edb4c2a..c7fca70e5 100644 --- a/QLNet/Pricingengines/asian/mc_discr_arith_av_price.cs +++ b/QLNet/Pricingengines/asian/mc_discr_arith_av_price.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -198,14 +198,14 @@ public MakeMCDiscreteArithmeticAPEngine withBrownianBridge(){ return withBrownianBridge(true); } - public MakeMCDiscreteArithmeticAPEngine withSamples(int samples){ + public MakeMCDiscreteArithmeticAPEngine withSamples(int samples){ Utils.QL_REQUIRE( tolerance_ == null, () => "tolerance already set" ); samples_ = samples; return this; } public MakeMCDiscreteArithmeticAPEngine withTolerance(double tolerance) - { + { Utils.QL_REQUIRE( samples_ == null, () => "number of samples already set" ); if ((new RNG().allowsErrorEstimate == 0)) throw new ApplicationException("chosen random generator policy " + diff --git a/QLNet/Pricingengines/asian/mc_discr_arith_av_strike.cs b/QLNet/Pricingengines/asian/mc_discr_arith_av_strike.cs index 5cf3f6a0e..4de2f05f6 100644 --- a/QLNet/Pricingengines/asian/mc_discr_arith_av_strike.cs +++ b/QLNet/Pricingengines/asian/mc_discr_arith_av_strike.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -141,15 +141,15 @@ public MakeMCDiscreteArithmeticASEngine withBrownianBridge(){ } public MakeMCDiscreteArithmeticASEngine withSamples(int samples) - { + { Utils.QL_REQUIRE( tolerance_ == null, () => "tolerance already set" ); samples_ = samples; return this; } public MakeMCDiscreteArithmeticASEngine withTolerance(double tolerance) - { - + { + Utils.QL_REQUIRE( samples_ == null, () => "number of samples already set" ); if ((new RNG().allowsErrorEstimate == 0)) throw new ApplicationException("chosen random generator policy " + diff --git a/QLNet/Pricingengines/asian/mc_discr_geom_av_price.cs b/QLNet/Pricingengines/asian/mc_discr_geom_av_price.cs index e79112b54..2598f16da 100644 --- a/QLNet/Pricingengines/asian/mc_discr_geom_av_price.cs +++ b/QLNet/Pricingengines/asian/mc_discr_geom_av_price.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -176,13 +176,13 @@ public MakeMCDiscreteGeometricAPEngine withBrownianBridge(){ return withBrownianBridge(true); } - public MakeMCDiscreteGeometricAPEngine withSamples(int samples){ + public MakeMCDiscreteGeometricAPEngine withSamples(int samples){ Utils.QL_REQUIRE( tolerance_ == null, () => "tolerance already set" ); samples_ = samples; return this; } - public MakeMCDiscreteGeometricAPEngine withTolerance(double tolerance){ + public MakeMCDiscreteGeometricAPEngine withTolerance(double tolerance){ Utils.QL_REQUIRE( samples_ == null, () => "number of samples already set" ); if ((new RNG().allowsErrorEstimate == 0)) throw new ApplicationException("chosen random generator policy " + diff --git a/QLNet/Pricingengines/asian/mcdiscreteasianengine.cs b/QLNet/Pricingengines/asian/mcdiscreteasianengine.cs index 97bfee99b..75a87ea13 100644 --- a/QLNet/Pricingengines/asian/mcdiscreteasianengine.cs +++ b/QLNet/Pricingengines/asian/mcdiscreteasianengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -62,7 +62,7 @@ public MCDiscreteAveragingAsianEngine( int requiredSamples, double requiredTolerance, int maxSamples, - ulong seed) : base(controlVariate,antitheticVariate) + ulong seed) : base(antitheticVariate, controlVariate) { process_=process; maxTimeStepsPerYear_ = maxTimeStepsPerYear; diff --git a/QLNet/Pricingengines/barrier/AnalyticBarrierEngine.cs b/QLNet/Pricingengines/barrier/AnalyticBarrierEngine.cs index 551698c08..5e1791491 100644 --- a/QLNet/Pricingengines/barrier/AnalyticBarrierEngine.cs +++ b/QLNet/Pricingengines/barrier/AnalyticBarrierEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/blackformula.cs b/QLNet/Pricingengines/blackformula.cs index c196dd139..367cda2f6 100644 --- a/QLNet/Pricingengines/blackformula.cs +++ b/QLNet/Pricingengines/blackformula.cs @@ -1,21 +1,21 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; using System.Collections.Generic; @@ -24,9 +24,9 @@ under the terms of the QLNet license. You should have received a namespace QLNet { - /*! Black 1976 formula - \warning instead of volatility it uses standard deviation, - i.e. volatility*sqrt(timeToMaturity) + /*! Black 1976 formula + \warning instead of volatility it uses standard deviation, + i.e. volatility*sqrt(timeToMaturity) */ public partial class Utils { @@ -125,12 +125,12 @@ public static double blackFormulaStdDevDerivative( double strike, return discount * forward * phi.derivative( d1 ); } - /*! Black style formula when forward is normal rather than - log-normal. This is essentially the model of Bachelier. - - \warning Bachelier model needs absolute volatility, not - percentage volatility. Standard deviation is - absoluteVolatility*sqrt(timeToMaturity) + /*! Black style formula when forward is normal rather than + log-normal. This is essentially the model of Bachelier. + + \warning Bachelier model needs absolute volatility, not + percentage volatility. Standard deviation is + absoluteVolatility*sqrt(timeToMaturity) */ public static double bachelierBlackFormula( Option.Type optionType, double strike, @@ -185,12 +185,12 @@ public static double bachelierBlackFormula( PlainVanillaPayoff payoff, } - /*! Approximated Bachelier implied volatility - - It is calculated using the analytic implied volatility approximation - of J. Choi, K Kim and M. Kwak (2009), “Numerical Approximation of the - Implied Volatility Under Arithmetic Brownian Motion”, - Applied Math. Finance, 16(3), pp. 261-268. + /*! Approximated Bachelier implied volatility + + It is calculated using the analytic implied volatility approximation + of J. Choi, K Kim and M. Kwak (2009), “Numerical Approximation of the + Implied Volatility Under Arithmetic Brownian Motion”, + Applied Math. Finance, 16(3), pp. 261-268. */ public static double bachelierBlackFormulaImpliedVol( Option.Type optionType, double strike, @@ -199,73 +199,73 @@ public static double bachelierBlackFormulaImpliedVol( Option.Type optionType, double bachelierPrice, double discount = 1.0 ) { - double SQRT_QL_EPSILON = Math.Sqrt( Const.QL_Epsilon); - - Utils.QL_REQUIRE( tte > 0.0, () => "tte (" + tte + ") must be positive" ); - - double forwardPremium = bachelierPrice/discount; - - double straddlePremium; - if (optionType==Option.Type.Call) - { - straddlePremium = 2.0 * forwardPremium - (forward - strike); - } - else - { - straddlePremium = 2.0 * forwardPremium + (forward - strike); - } - + double SQRT_QL_EPSILON = Math.Sqrt( Const.QL_EPSILON); + + Utils.QL_REQUIRE( tte > 0.0, () => "tte (" + tte + ") must be positive" ); + + double forwardPremium = bachelierPrice/discount; + + double straddlePremium; + if (optionType==Option.Type.Call) + { + straddlePremium = 2.0 * forwardPremium - (forward - strike); + } + else + { + straddlePremium = 2.0 * forwardPremium + (forward - strike); + } + double nu = (forward - strike) / straddlePremium; Utils.QL_REQUIRE( nu <= 1.0, () => "nu (" + nu + ") must be <= 1.0" ); - Utils.QL_REQUIRE( nu >= -1.0, () => "nu (" + nu + ") must be >= -1.0" ); - - nu = Math.Max(-1.0 + Const.QL_Epsilon, Math.Min(nu,1.0 - Const.QL_Epsilon)); - + Utils.QL_REQUIRE( nu >= -1.0, () => "nu (" + nu + ") must be >= -1.0" ); + + nu = Math.Max(-1.0 + Const.QL_EPSILON, Math.Min(nu,1.0 - Const.QL_EPSILON)); + // nu / arctanh(nu) -> 1 as nu -> 0 double atanh = ( Math.Log( 1 + nu ) - Math.Log( 1 - nu ) ) / 2; // c# dont have atanh - double eta = ( Math.Abs( nu ) < SQRT_QL_EPSILON ) ? 1.0 : nu / atanh; - - double heta = h(eta); - - double impliedBpvol = Math.Sqrt(M_PI / (2 * tte)) * straddlePremium * heta; - - return impliedBpvol; + double eta = ( Math.Abs( nu ) < SQRT_QL_EPSILON ) ? 1.0 : nu / atanh; + + double heta = h(eta); + + double impliedBpvol = Math.Sqrt(M_PI / (2 * tte)) * straddlePremium * heta; + + return impliedBpvol; } - private static double h(double eta) - { - const double A0 = 3.994961687345134e-1; - const double A1 = 2.100960795068497e+1; - const double A2 = 4.980340217855084e+1; - const double A3 = 5.988761102690991e+2; - const double A4 = 1.848489695437094e+3; - const double A5 = 6.106322407867059e+3; - const double A6 = 2.493415285349361e+4; - const double A7 = 1.266458051348246e+4; - - const double B0 = 1.000000000000000e+0; - const double B1 = 4.990534153589422e+1; - const double B2 = 3.093573936743112e+1; - const double B3 = 1.495105008310999e+3; - const double B4 = 1.323614537899738e+3; - const double B5 = 1.598919697679745e+4; - const double B6 = 2.392008891720782e+4; - const double B7 = 3.608817108375034e+3; - const double B8 = -2.067719486400926e+2; + private static double h(double eta) + { + const double A0 = 3.994961687345134e-1; + const double A1 = 2.100960795068497e+1; + const double A2 = 4.980340217855084e+1; + const double A3 = 5.988761102690991e+2; + const double A4 = 1.848489695437094e+3; + const double A5 = 6.106322407867059e+3; + const double A6 = 2.493415285349361e+4; + const double A7 = 1.266458051348246e+4; + + const double B0 = 1.000000000000000e+0; + const double B1 = 4.990534153589422e+1; + const double B2 = 3.093573936743112e+1; + const double B3 = 1.495105008310999e+3; + const double B4 = 1.323614537899738e+3; + const double B5 = 1.598919697679745e+4; + const double B6 = 2.392008891720782e+4; + const double B7 = 3.608817108375034e+3; + const double B8 = -2.067719486400926e+2; const double B9 = 1.174240599306013e+1; - Utils.QL_REQUIRE( eta >= 0.0, () => "eta (" + eta + ") must be non-negative" ); - - double num = A0 + eta * (A1 + eta * (A2 + eta * (A3 + eta * (A4 + eta - * (A5 + eta * (A6 + eta * A7)))))); - - double den = B0 + eta * (B1 + eta * (B2 + eta * (B3 + eta * (B4 + eta - * (B5 + eta * (B6 + eta * (B7 + eta * (B8 + eta * B9)))))))); - - return Math.Sqrt(eta) * (num / den); - + Utils.QL_REQUIRE( eta >= 0.0, () => "eta (" + eta + ") must be non-negative" ); + + double num = A0 + eta * (A1 + eta * (A2 + eta * (A3 + eta * (A4 + eta + * (A5 + eta * (A6 + eta * A7)))))); + + double den = B0 + eta * (B1 + eta * (B2 + eta * (B3 + eta * (B4 + eta + * (B5 + eta * (B6 + eta * (B7 + eta * (B8 + eta * B9)))))))); + + return Math.Sqrt(eta) * (num / den); + } } -} +} diff --git a/QLNet/Pricingengines/credit/IntegralCdsEngine.cs b/QLNet/Pricingengines/credit/IntegralCdsEngine.cs index 2078cedd3..9fcb6049a 100644 --- a/QLNet/Pricingengines/credit/IntegralCdsEngine.cs +++ b/QLNet/Pricingengines/credit/IntegralCdsEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -15,35 +15,35 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace QLNet -{ - public class IntegralCdsEngine : CreditDefaultSwap.Engine - { - const double basisPoint = 1.0e-4; - - public IntegralCdsEngine(Period step, Handle probability, - double recoveryRate, Handle discountCurve, bool? includeSettlementDateFlows = null) - { +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + public class IntegralCdsEngine : CreditDefaultSwap.Engine + { + const double basisPoint = 1.0e-4; + + public IntegralCdsEngine(Period step, Handle probability, + double recoveryRate, Handle discountCurve, bool? includeSettlementDateFlows = null) + { integrationStep_ = step ; probability_ = probability; recoveryRate_ = recoveryRate; - discountCurve_ = discountCurve; - includeSettlementDateFlows_ = includeSettlementDateFlows; - - probability_.registerWith(update); - discountCurve_.registerWith(update); - } - - public override void calculate() - { - Utils.QL_REQUIRE( integrationStep_ != null, () => "null period set" ); - Utils.QL_REQUIRE( !discountCurve_.empty(), () => "no discount term structure set" ); + discountCurve_ = discountCurve; + includeSettlementDateFlows_ = includeSettlementDateFlows; + + probability_.registerWith(update); + discountCurve_.registerWith(update); + } + + public override void calculate() + { + Utils.QL_REQUIRE( integrationStep_ != null, () => "null period set" ); + Utils.QL_REQUIRE( !discountCurve_.empty(), () => "no discount term structure set" ); Utils.QL_REQUIRE( !probability_.empty(), () => "no probability term structure set" ); Date today = Settings.evaluationDate(); @@ -186,13 +186,13 @@ public override void calculate() results_.upfrontBPS = null; } } - - - - private Period integrationStep_; - private Handle probability_; - private double recoveryRate_; - private Handle discountCurve_; - private bool? includeSettlementDateFlows_; - } -} + + + + private Period integrationStep_; + private Handle probability_; + private double recoveryRate_; + private Handle discountCurve_; + private bool? includeSettlementDateFlows_; + } +} diff --git a/QLNet/Pricingengines/credit/MidPointCdsEngine.cs b/QLNet/Pricingengines/credit/MidPointCdsEngine.cs index 329efb110..311ed893b 100644 --- a/QLNet/Pricingengines/credit/MidPointCdsEngine.cs +++ b/QLNet/Pricingengines/credit/MidPointCdsEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -15,35 +15,35 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace QLNet -{ - public class MidPointCdsEngine : CreditDefaultSwap.Engine - { - const double basisPoint = 1.0e-4; - - public MidPointCdsEngine(Handle probability, - double recoveryRate, - Handle discountCurve, - bool? includeSettlementDateFlows = null) - { +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + public class MidPointCdsEngine : CreditDefaultSwap.Engine + { + const double basisPoint = 1.0e-4; + + public MidPointCdsEngine(Handle probability, + double recoveryRate, + Handle discountCurve, + bool? includeSettlementDateFlows = null) + { probability_ = probability; recoveryRate_ = recoveryRate; - discountCurve_ = discountCurve; - includeSettlementDateFlows_ = includeSettlementDateFlows; - - probability_.registerWith(update); - discountCurve_.registerWith(update); - } - - public override void calculate() - { - Utils.QL_REQUIRE( !discountCurve_.empty(), () => "no discount term structure set" ); + discountCurve_ = discountCurve; + includeSettlementDateFlows_ = includeSettlementDateFlows; + + probability_.registerWith(update); + discountCurve_.registerWith(update); + } + + public override void calculate() + { + Utils.QL_REQUIRE( !discountCurve_.empty(), () => "no discount term structure set" ); Utils.QL_REQUIRE( !probability_.empty(), () => "no probability term structure set" ); Date today = Settings.evaluationDate(); @@ -186,12 +186,12 @@ public override void calculate() results_.upfrontBPS =null; } } - + private Handle probability_; private double recoveryRate_; private Handle discountCurve_; - private bool? includeSettlementDateFlows_; - } -} + private bool? includeSettlementDateFlows_; + } +} diff --git a/QLNet/Pricingengines/genericmodelengine.cs b/QLNet/Pricingengines/genericmodelengine.cs index fda810419..9d689b893 100644 --- a/QLNet/Pricingengines/genericmodelengine.cs +++ b/QLNet/Pricingengines/genericmodelengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/inflation/InflationCapFloorEngines.cs b/QLNet/Pricingengines/inflation/InflationCapFloorEngines.cs index 1239184b9..7b283f698 100644 --- a/QLNet/Pricingengines/inflation/InflationCapFloorEngines.cs +++ b/QLNet/Pricingengines/inflation/InflationCapFloorEngines.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/latticeshortratemodelengine.cs b/QLNet/Pricingengines/latticeshortratemodelengine.cs index 9585bc8ad..dde51f389 100644 --- a/QLNet/Pricingengines/latticeshortratemodelengine.cs +++ b/QLNet/Pricingengines/latticeshortratemodelengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/mclongstaffschwartzengine.cs b/QLNet/Pricingengines/mclongstaffschwartzengine.cs index ec26c2932..f298ef127 100644 --- a/QLNet/Pricingengines/mclongstaffschwartzengine.cs +++ b/QLNet/Pricingengines/mclongstaffschwartzengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/mcsimulation.cs b/QLNet/Pricingengines/mcsimulation.cs index c5f9e9326..59f3165f1 100644 --- a/QLNet/Pricingengines/mcsimulation.cs +++ b/QLNet/Pricingengines/mcsimulation.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/swaption/blackswaptionengine.cs b/QLNet/Pricingengines/swaption/blackswaptionengine.cs index 7a4e7c708..714356390 100644 --- a/QLNet/Pricingengines/swaption/blackswaptionengine.cs +++ b/QLNet/Pricingengines/swaption/blackswaptionengine.cs @@ -2,7 +2,7 @@ Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/swaption/discretizedswaption.cs b/QLNet/Pricingengines/swaption/discretizedswaption.cs index f0bed7445..42247719a 100644 --- a/QLNet/Pricingengines/swaption/discretizedswaption.cs +++ b/QLNet/Pricingengines/swaption/discretizedswaption.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/swaption/g2swaptionengine.cs b/QLNet/Pricingengines/swaption/g2swaptionengine.cs index 16f9d33ee..3c0f3d53b 100644 --- a/QLNet/Pricingengines/swaption/g2swaptionengine.cs +++ b/QLNet/Pricingengines/swaption/g2swaptionengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/swaption/jamshidianswaptionengine.cs b/QLNet/Pricingengines/swaption/jamshidianswaptionengine.cs index b2b747a26..4b078b6c6 100644 --- a/QLNet/Pricingengines/swaption/jamshidianswaptionengine.cs +++ b/QLNet/Pricingengines/swaption/jamshidianswaptionengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/swaption/treeswaptionengine.cs b/QLNet/Pricingengines/swaption/treeswaptionengine.cs index dd9134935..5aaff84de 100644 --- a/QLNet/Pricingengines/swaption/treeswaptionengine.cs +++ b/QLNet/Pricingengines/swaption/treeswaptionengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/AnalyticDividendEuropeanEngine.cs b/QLNet/Pricingengines/vanilla/AnalyticDividendEuropeanEngine.cs index d1713d108..83722d5b2 100644 --- a/QLNet/Pricingengines/vanilla/AnalyticDividendEuropeanEngine.cs +++ b/QLNet/Pricingengines/vanilla/AnalyticDividendEuropeanEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/AnalyticEuropeanEngine.cs b/QLNet/Pricingengines/vanilla/AnalyticEuropeanEngine.cs index 9f49f398e..8e8093904 100644 --- a/QLNet/Pricingengines/vanilla/AnalyticEuropeanEngine.cs +++ b/QLNet/Pricingengines/vanilla/AnalyticEuropeanEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/FDAmericanEngine.cs b/QLNet/Pricingengines/vanilla/FDAmericanEngine.cs index 6ff024f6e..4060e33d6 100644 --- a/QLNet/Pricingengines/vanilla/FDAmericanEngine.cs +++ b/QLNet/Pricingengines/vanilla/FDAmericanEngine.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/FDBermudanEngine.cs b/QLNet/Pricingengines/vanilla/FDBermudanEngine.cs index 81b655060..74e0a2a81 100644 --- a/QLNet/Pricingengines/vanilla/FDBermudanEngine.cs +++ b/QLNet/Pricingengines/vanilla/FDBermudanEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/FDConditions.cs b/QLNet/Pricingengines/vanilla/FDConditions.cs index deb5241cd..197bf19dd 100644 --- a/QLNet/Pricingengines/vanilla/FDConditions.cs +++ b/QLNet/Pricingengines/vanilla/FDConditions.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/FDDividendAmericanEngine.cs b/QLNet/Pricingengines/vanilla/FDDividendAmericanEngine.cs index 7be07f6dd..98a349bfd 100644 --- a/QLNet/Pricingengines/vanilla/FDDividendAmericanEngine.cs +++ b/QLNet/Pricingengines/vanilla/FDDividendAmericanEngine.cs @@ -2,7 +2,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/FDDividendEngine.cs b/QLNet/Pricingengines/vanilla/FDDividendEngine.cs index 650ef299d..2038ec87c 100644 --- a/QLNet/Pricingengines/vanilla/FDDividendEngine.cs +++ b/QLNet/Pricingengines/vanilla/FDDividendEngine.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/FDDividendEuropeanEngine.cs b/QLNet/Pricingengines/vanilla/FDDividendEuropeanEngine.cs index 88222143b..62641f31d 100644 --- a/QLNet/Pricingengines/vanilla/FDDividendEuropeanEngine.cs +++ b/QLNet/Pricingengines/vanilla/FDDividendEuropeanEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/FDEuropeanEngine.cs b/QLNet/Pricingengines/vanilla/FDEuropeanEngine.cs index ae4f86867..98f63805e 100644 --- a/QLNet/Pricingengines/vanilla/FDEuropeanEngine.cs +++ b/QLNet/Pricingengines/vanilla/FDEuropeanEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/FDMultiPeriodEngine.cs b/QLNet/Pricingengines/vanilla/FDMultiPeriodEngine.cs index 2782a4b9b..f3479eaaa 100644 --- a/QLNet/Pricingengines/vanilla/FDMultiPeriodEngine.cs +++ b/QLNet/Pricingengines/vanilla/FDMultiPeriodEngine.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -16,7 +16,7 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ +*/ using System; using System.Collections.Generic; using System.Linq; @@ -34,9 +34,9 @@ public FDMultiPeriodEngine() { } //protected FDMultiPeriodEngine(GeneralizedBlackScholesProcess process, // int gridPoints = 100, int timeSteps = 100, bool timeDependent = false) - protected FDMultiPeriodEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) - : base(process, timeSteps, gridPoints, timeDependent) - { + protected FDMultiPeriodEngine(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) + : base(process, timeSteps, gridPoints, timeDependent) + { timeStepPerPeriod_ = timeSteps; } diff --git a/QLNet/Pricingengines/vanilla/FDShoutEngine.cs b/QLNet/Pricingengines/vanilla/FDShoutEngine.cs index fb327b48a..b9c101b00 100644 --- a/QLNet/Pricingengines/vanilla/FDShoutEngine.cs +++ b/QLNet/Pricingengines/vanilla/FDShoutEngine.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/FDStepConditionEngine.cs b/QLNet/Pricingengines/vanilla/FDStepConditionEngine.cs index 4044a5c95..bba0133b7 100644 --- a/QLNet/Pricingengines/vanilla/FDStepConditionEngine.cs +++ b/QLNet/Pricingengines/vanilla/FDStepConditionEngine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/FDVanillaEngine.cs b/QLNet/Pricingengines/vanilla/FDVanillaEngine.cs index 9fa50978e..ff9e8474d 100644 --- a/QLNet/Pricingengines/vanilla/FDVanillaEngine.cs +++ b/QLNet/Pricingengines/vanilla/FDVanillaEngine.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/Integralengine.cs b/QLNet/Pricingengines/vanilla/Integralengine.cs index 4c3c875b3..47164949c 100644 --- a/QLNet/Pricingengines/vanilla/Integralengine.cs +++ b/QLNet/Pricingengines/vanilla/Integralengine.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/Juquadraticengine.cs b/QLNet/Pricingengines/vanilla/Juquadraticengine.cs index abc46113f..9ab2d16b8 100644 --- a/QLNet/Pricingengines/vanilla/Juquadraticengine.cs +++ b/QLNet/Pricingengines/vanilla/Juquadraticengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/baroneadesiwhaleyengine.cs b/QLNet/Pricingengines/vanilla/baroneadesiwhaleyengine.cs index 195784b5e..d08be0eaf 100644 --- a/QLNet/Pricingengines/vanilla/baroneadesiwhaleyengine.cs +++ b/QLNet/Pricingengines/vanilla/baroneadesiwhaleyengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -76,8 +76,11 @@ public static double criticalPrice(StrikedTypePayoff payoff, double riskFreeDisc double d1 = (Math.Log(forwardSi/payoff.strike()) + 0.5*variance) / Math.Sqrt(variance); CumulativeNormalDistribution cumNormalDist = new CumulativeNormalDistribution(); - double K = (riskFreeDiscount!=1.0 ? -2.0*Math.Log(riskFreeDiscount)/ - (variance*(1.0-riskFreeDiscount)) : 0.0); + double K = ( !Utils.close( riskFreeDiscount, 1.0, 1000 ) ) + ? -2.0 * Math.Log( riskFreeDiscount ) + / ( variance * ( 1.0 - riskFreeDiscount ) ) + : 2.0 / variance; + double temp = Utils.blackFormula(payoff.optionType(), payoff.strike(), forwardSi, Math.Sqrt(variance))*riskFreeDiscount; switch (payoff.optionType()) { @@ -186,8 +189,10 @@ public override void calculate() { double d1 = (Math.Log(forwardSk/payoff.strike()) + 0.5*variance) /Math.Sqrt(variance); double n = 2.0*Math.Log(dividendDiscount/riskFreeDiscount)/variance; - double K = -2.0*Math.Log(riskFreeDiscount)/ - (variance*(1.0-riskFreeDiscount)); + double K = ( !Utils.close( riskFreeDiscount, 1.0, 1000 ) ) + ? -2.0 * Math.Log( riskFreeDiscount ) + / ( variance * ( 1.0 - riskFreeDiscount ) ) + : 2.0 / variance; double Q, a; switch (payoff.optionType()) { case Option.Type.Call: diff --git a/QLNet/Pricingengines/vanilla/binomialengine.cs b/QLNet/Pricingengines/vanilla/binomialengine.cs index 417969564..c9302c980 100644 --- a/QLNet/Pricingengines/vanilla/binomialengine.cs +++ b/QLNet/Pricingengines/vanilla/binomialengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/bjerksundstenslandengine.cs b/QLNet/Pricingengines/vanilla/bjerksundstenslandengine.cs index 7fd64ac34..8615eced3 100644 --- a/QLNet/Pricingengines/vanilla/bjerksundstenslandengine.cs +++ b/QLNet/Pricingengines/vanilla/bjerksundstenslandengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -108,8 +108,9 @@ double phi(double S, double gamma, double H, double I, double rT, double bT, dou double lambda = (-rT + gamma * bT + 0.5 * gamma * (gamma - 1.0) * variance); double d = -(Math.Log(S / H) + (bT + (gamma - 0.5) * variance) ) / Math.Sqrt(variance); double kappa = 2.0 * bT / variance + (2.0 * gamma - 1.0); - return Math.Exp(lambda) * Math.Pow(S, gamma) * (cumNormalDist.value(d) - Math.Pow((I / S), kappa) * - cumNormalDist.value(d - 2.0 * Math.Log(I/S) / Math.Sqrt(variance))); + return Math.Exp(lambda) * (cumNormalDist.value(d) + - Math.Pow((I / S), kappa) * + cumNormalDist.value(d - 2.0 * Math.Log(I/S) / Math.Sqrt(variance))); } @@ -133,10 +134,10 @@ double americanCallApproximation(double S, double X, double rfD, double dD, doub } else { // investigate what happen to alpha for dD->0.0 double alpha = (I - X) * Math.Pow(I, (-beta)); - return alpha * Math.Pow(S, beta) - - alpha * phi(S, beta, I, I, rT, bT, variance) - + phi(S, 1.0, I, I, rT, bT, variance) - - phi(S, 1.0, X, I, rT, bT, variance) + return (I - X) * Math.Pow(S/I, beta) + *(1 - phi(S, beta, I, I, rT, bT, variance)) + + S * phi(S, 1.0, I, I, rT, bT, variance) + - S * phi(S, 1.0, X, I, rT, bT, variance) - X * phi(S, 0.0, I, I, rT, bT, variance) + X * phi(S, 0.0, X, I, rT, bT, variance); } diff --git a/QLNet/Pricingengines/vanilla/discretizedvanillaoption.cs b/QLNet/Pricingengines/vanilla/discretizedvanillaoption.cs index 9a315a9fe..19ae8e2b4 100644 --- a/QLNet/Pricingengines/vanilla/discretizedvanillaoption.cs +++ b/QLNet/Pricingengines/vanilla/discretizedvanillaoption.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/mcamericanengine.cs b/QLNet/Pricingengines/vanilla/mcamericanengine.cs index 2e9d57379..a0ec32d22 100644 --- a/QLNet/Pricingengines/vanilla/mcamericanengine.cs +++ b/QLNet/Pricingengines/vanilla/mcamericanengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/mceuropeanengine.cs b/QLNet/Pricingengines/vanilla/mceuropeanengine.cs index 8d00192dc..828066efa 100644 --- a/QLNet/Pricingengines/vanilla/mceuropeanengine.cs +++ b/QLNet/Pricingengines/vanilla/mceuropeanengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Pricingengines/vanilla/mcvanillaengine.cs b/QLNet/Pricingengines/vanilla/mcvanillaengine.cs index 499d6623c..24f7a4a25 100644 --- a/QLNet/Pricingengines/vanilla/mcvanillaengine.cs +++ b/QLNet/Pricingengines/vanilla/mcvanillaengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Properties/AssemblyInfo.cs b/QLNet/Properties/AssemblyInfo.cs index f99342d6f..1a7a0547c 100644 --- a/QLNet/Properties/AssemblyInfo.cs +++ b/QLNet/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // // È possibile specificare tutti i valori o impostare come predefiniti i valori Numero revisione e Numero build // utilizzando l'asterisco (*) come descritto di seguito: -[assembly: AssemblyVersion("1.4.0.4")] -[assembly: AssemblyFileVersion("1.4.0.4")] +[assembly: AssemblyVersion( "1.5.0.0" )] +[assembly: AssemblyFileVersion( "1.5.0.0" )] diff --git a/QLNet/QLNet.csproj b/QLNet/QLNet.csproj index 9b1b62673..f7e319c3a 100644 --- a/QLNet/QLNet.csproj +++ b/QLNet/QLNet.csproj @@ -15,7 +15,7 @@ 3.5 - v3.5 + v4.0 publish\ true Disk @@ -31,6 +31,7 @@ false false true + true @@ -42,6 +43,7 @@ 4 false AllRules.ruleset + false pdbonly @@ -51,6 +53,7 @@ prompt 4 AllRules.ruleset + false @@ -58,6 +61,7 @@ 3.5 + @@ -115,12 +119,15 @@ + + + @@ -232,6 +239,7 @@ + @@ -239,11 +247,15 @@ + + - + + + @@ -251,6 +263,7 @@ + @@ -276,6 +289,7 @@ + @@ -531,6 +545,7 @@ + @@ -544,6 +559,7 @@ + @@ -571,11 +587,11 @@ - \ No newline at end of file diff --git a/QLNet/Quotes/CompositeQuote.cs b/QLNet/Quotes/CompositeQuote.cs index 3ccd55275..07d45b5c6 100644 --- a/QLNet/Quotes/CompositeQuote.cs +++ b/QLNet/Quotes/CompositeQuote.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2009 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Quotes/DerivedQuote.cs b/QLNet/Quotes/DerivedQuote.cs index cbd9d469e..2ff7fa255 100644 --- a/QLNet/Quotes/DerivedQuote.cs +++ b/QLNet/Quotes/DerivedQuote.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2009 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Quotes/LastFixingQuote.cs b/QLNet/Quotes/LastFixingQuote.cs index b46275c91..9c3dfc001 100644 --- a/QLNet/Quotes/LastFixingQuote.cs +++ b/QLNet/Quotes/LastFixingQuote.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008,2009 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Quotes/Quote.cs b/QLNet/Quotes/Quote.cs index 71ebb470e..6a9f3e767 100644 --- a/QLNet/Quotes/Quote.cs +++ b/QLNet/Quotes/Quote.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Quotes/SimpleQuote.cs b/QLNet/Quotes/SimpleQuote.cs index 43ea02062..8d82cea2e 100644 --- a/QLNet/Quotes/SimpleQuote.cs +++ b/QLNet/Quotes/SimpleQuote.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Settings.cs b/QLNet/Settings.cs index d9409c10d..367ce86ca 100644 --- a/QLNet/Settings.cs +++ b/QLNet/Settings.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/StochasticProcess.cs b/QLNet/StochasticProcess.cs index c60d45a25..599ae36f6 100644 --- a/QLNet/StochasticProcess.cs +++ b/QLNet/StochasticProcess.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Bootstraperror.cs b/QLNet/Termstructures/Bootstraperror.cs index 453521ae4..9169f3ef7 100644 --- a/QLNet/Termstructures/Bootstraperror.cs +++ b/QLNet/Termstructures/Bootstraperror.cs @@ -3,7 +3,7 @@ Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -17,19 +17,19 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - +*/ + namespace QLNet { - //! bootstrap error - public class BootstrapError : ISolver1d - where T : Curve - where U : TermStructure + //! bootstrap error + public class BootstrapError : ISolver1d + where T : Curve + where U : TermStructure { - private T curve_; + private T curve_; private BootstrapHelper helper_; - private int segment_; - + private int segment_; + public BootstrapError( T curve, BootstrapHelper helper, int segment ) { curve_ = curve; diff --git a/QLNet/Termstructures/Bootstraphelper.cs b/QLNet/Termstructures/Bootstraphelper.cs index 9d9714668..84fcf29ec 100644 --- a/QLNet/Termstructures/Bootstraphelper.cs +++ b/QLNet/Termstructures/Bootstraphelper.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Credit/FlatHazardRate.cs b/QLNet/Termstructures/Credit/FlatHazardRate.cs index c01c774f0..972fe92ed 100644 --- a/QLNet/Termstructures/Credit/FlatHazardRate.cs +++ b/QLNet/Termstructures/Credit/FlatHazardRate.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Credit/HazardRateStructure.cs b/QLNet/Termstructures/Credit/HazardRateStructure.cs index f4ca5305a..b11960071 100644 --- a/QLNet/Termstructures/Credit/HazardRateStructure.cs +++ b/QLNet/Termstructures/Credit/HazardRateStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Credit/InterpolatedHazardRateCurve.cs b/QLNet/Termstructures/Credit/InterpolatedHazardRateCurve.cs index cfdb49dbf..eb2555d76 100644 --- a/QLNet/Termstructures/Credit/InterpolatedHazardRateCurve.cs +++ b/QLNet/Termstructures/Credit/InterpolatedHazardRateCurve.cs @@ -1,20 +1,20 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; using System.Collections.Generic; @@ -39,12 +39,12 @@ public InterpolatedHazardRateCurve( List dates, List hazardRates, else interpolator_ = interpolator; - initialize(); - } - - public InterpolatedHazardRateCurve( List dates,List hazardRates,DayCounter dayCounter,Calendar calendar, - Interpolator interpolator) - :base(dates[0], calendar, dayCounter) + initialize(); + } + + public InterpolatedHazardRateCurve( List dates,List hazardRates,DayCounter dayCounter,Calendar calendar, + Interpolator interpolator) + :base(dates[0], calendar, dayCounter) { dates_ = dates; times_ = new List(); @@ -53,7 +53,7 @@ public InterpolatedHazardRateCurve( List dates,List hazardRates,Da interpolator_ = new Interpolator(); else interpolator_ = interpolator; - initialize(); + initialize(); } public InterpolatedHazardRateCurve( List dates, List hazardRates, DayCounter dayCounter, Interpolator interpolator ) @@ -89,9 +89,9 @@ protected InterpolatedHazardRateCurve( int settlementDays, Calendar cal, DayCoun List jumpDates = null, Interpolator interpolator = default(Interpolator) ) : base( settlementDays, cal, dc, jumps, jumpDates ) - {} - - //! \name DefaultProbabilityTermStructure implementation + {} + + //! \name DefaultProbabilityTermStructure implementation //@{ protected override double hazardRateImpl( double t ) { @@ -103,42 +103,42 @@ protected override double hazardRateImpl( double t ) } protected override double survivalProbabilityImpl( double t ) { - if (t == 0.0) - return 1.0; - - double integral; - if (t <= this.times_.Last()) - { - integral = this.interpolation_.primitive(t, true); - } - else - { - // flat hazard rate extrapolation - integral = this.interpolation_.primitive(this.times_.Last(), true) - + this.data_.Last()*(t - this.times_.Last()); - } + if (t == 0.0) + return 1.0; + + double integral; + if (t <= this.times_.Last()) + { + integral = this.interpolation_.primitive(t, true); + } + else + { + // flat hazard rate extrapolation + integral = this.interpolation_.primitive(this.times_.Last(), true) + + this.data_.Last()*(t - this.times_.Last()); + } return Math.Exp(-integral); - } + } //@} private void initialize() { Utils.QL_REQUIRE( dates_.Count >= interpolator_.requiredPoints, () => "not enough input dates given" ); - Utils.QL_REQUIRE( this.data_.Count == dates_.Count, () => "dates/data count mismatch" ); - - //this.times_ = new List(dates_.Count); - this.times_.Add(0.0); - for (int i=1; i "dates/data count mismatch" ); + + //this.times_ = new List(dates_.Count); + this.times_.Add(0.0); + for (int i=1; i dates_[i - 1], () => "invalid date (" + dates_[i] + ", vs " + dates_[i - 1] + ")" ); this.times_.Add( dayCounter().yearFraction( dates_[0], dates_[i] ) ); - Utils.QL_REQUIRE( !Utils.close( this.times_[i], this.times_[i - 1] ), () => "two dates correspond to the same time " + + Utils.QL_REQUIRE( !Utils.close( this.times_[i], this.times_[i - 1] ), () => "two dates correspond to the same time " + "under this curve's day count convention"); - Utils.QL_REQUIRE( this.data_[i] >= 0.0, () => "negative hazard rate" ); + Utils.QL_REQUIRE( this.data_[i] >= 0.0, () => "negative hazard rate" ); } - setupInterpolation(); + setupInterpolation(); this.interpolation_.update(); } diff --git a/QLNet/Termstructures/Credit/ProbabilityTraits.cs b/QLNet/Termstructures/Credit/ProbabilityTraits.cs index db45e076d..2a3feeecd 100644 --- a/QLNet/Termstructures/Credit/ProbabilityTraits.cs +++ b/QLNet/Termstructures/Credit/ProbabilityTraits.cs @@ -17,7 +17,7 @@ public class SurvivalProbability : ITraits public double minValueAfter(int s, List l) { // replace with Epsilon - return Const.QL_Epsilon; + return Const.QL_EPSILON; } public double maxValueAfter(int i, List data) { diff --git a/QLNet/Termstructures/Curve.cs b/QLNet/Termstructures/Curve.cs index a381e2780..ac28f4a45 100644 --- a/QLNet/Termstructures/Curve.cs +++ b/QLNet/Termstructures/Curve.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/DefaultProbabilityTermStructure.cs b/QLNet/Termstructures/DefaultProbabilityTermStructure.cs index 6f95b9320..107ac8404 100644 --- a/QLNet/Termstructures/DefaultProbabilityTermStructure.cs +++ b/QLNet/Termstructures/DefaultProbabilityTermStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -31,8 +31,8 @@ credit structures which will be derived from this one. */ public class DefaultProbabilityTermStructure : TermStructure { - #region Constructors - + #region Constructors + public DefaultProbabilityTermStructure() {} public DefaultProbabilityTermStructure(DayCounter dc = null,List > jumps = null,List jumpDates = null) @@ -118,9 +118,9 @@ public double survivalProbability(double t, bool extrapolate = false) if (!jumps_.empty()) { double jumpEffect = 1.0; - for (int i=0; i "invalid " + ( i + 1 ) + " jump quote" ); - double thisJump = jumps_[i].link.value(); + double thisJump = jumps_[i].link.value(); Utils.QL_REQUIRE( thisJump > 0.0 && thisJump <= 1.0, () => "invalid " + ( i + 1 ) + " jump value: " + thisJump ); jumpEffect *= thisJump; } @@ -152,14 +152,14 @@ public double defaultProbability(double t,bool extrapolate = false) //! probability of default between two given dates public double defaultProbability(Date d1,Date d2, bool extrapolate = false) - { + { Utils.QL_REQUIRE( d1 <= d2, () => "initial date (" + d1 + ") later than final date (" + d2 + ")" ); double p1 = d1 < referenceDate() ? 0.0 : defaultProbability(d1,extrapolate), p2 = defaultProbability(d2,extrapolate); return p2 - p1; } //! probability of default between two given times public double defaultProbability(double t1, double t2, bool extrapo = false) - { + { Utils.QL_REQUIRE( t1 <= t2, () => "initial time (" + t1 + ") later than final time (" + t2 + ")" ); double p1 = t1 < 0.0 ? 0.0 : defaultProbability(t1,extrapolate), p2 = defaultProbability(t2,extrapolate); return p2 - p1; @@ -260,7 +260,7 @@ private void setJumps() } else { - // fixed dats + // fixed dats Utils.QL_REQUIRE( jumpDates_.Count == nJumps_, () => "mismatch between number of jumps (" + nJumps_ + ") and jump dates (" + jumpDates_.Count + ")"); diff --git a/QLNet/Termstructures/Inflation/InflationHelpers.cs b/QLNet/Termstructures/Inflation/InflationHelpers.cs index ffc0f7e16..5b72d7f22 100644 --- a/QLNet/Termstructures/Inflation/InflationHelpers.cs +++ b/QLNet/Termstructures/Inflation/InflationHelpers.cs @@ -1,89 +1,89 @@ -/* - Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace QLNet -{ - //! Zero-coupon inflation-swap bootstrap helper - public class ZeroCouponInflationSwapHelper : BootstrapHelper - { - public ZeroCouponInflationSwapHelper( - Handle quote, - Period swapObsLag, // lag on swap observation of index - Date maturity, - Calendar calendar, // index may have null calendar as valid on every day - BusinessDayConvention paymentConvention, - DayCounter dayCounter, - ZeroInflationIndex zii) - : base(quote) - { - swapObsLag_ = swapObsLag; - maturity_ = maturity; - calendar_ = calendar; - paymentConvention_ = paymentConvention; - dayCounter_ = dayCounter; - zii_ = zii; - - if (zii_.interpolated()) - { - // if interpolated then simple - earliestDate_ = maturity_ - swapObsLag_; - latestDate_ = maturity_ - swapObsLag_; - } - else - { - // but if NOT interpolated then the value is valid - // for every day in an inflation period so you actually - // get an extended validity, however for curve building - // just put the first date because using that convention - // for the base date throughout - KeyValuePair limStart = Utils.inflationPeriod(maturity_ - swapObsLag_, - zii_.frequency()); - earliestDate_ = limStart.Key; - latestDate_ = limStart.Key; - } - - // check that the observation lag of the swap - // is compatible with the availability lag of the index AND - // it's interpolation (assuming the start day is spot) - if (zii_.interpolated()) - { - Period pShift = new Period(zii_.frequency()); - if ( (swapObsLag_ - pShift) <= zii_.availabilityLag()) - throw new ApplicationException( - "inconsistency between swap observation of index " - + swapObsLag_ + - " index availability " + zii_.availabilityLag() + - " index period " + pShift + - " and index availability " + zii_.availabilityLag() + - " need (obsLag-index period) > availLag"); - - } - Settings.registerWith(update); - } - - - public override void setTermStructure(ZeroInflationTermStructure z) +/* + Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + //! Zero-coupon inflation-swap bootstrap helper + public class ZeroCouponInflationSwapHelper : BootstrapHelper + { + public ZeroCouponInflationSwapHelper( + Handle quote, + Period swapObsLag, // lag on swap observation of index + Date maturity, + Calendar calendar, // index may have null calendar as valid on every day + BusinessDayConvention paymentConvention, + DayCounter dayCounter, + ZeroInflationIndex zii) + : base(quote) + { + swapObsLag_ = swapObsLag; + maturity_ = maturity; + calendar_ = calendar; + paymentConvention_ = paymentConvention; + dayCounter_ = dayCounter; + zii_ = zii; + + if (zii_.interpolated()) + { + // if interpolated then simple + earliestDate_ = maturity_ - swapObsLag_; + latestDate_ = maturity_ - swapObsLag_; + } + else + { + // but if NOT interpolated then the value is valid + // for every day in an inflation period so you actually + // get an extended validity, however for curve building + // just put the first date because using that convention + // for the base date throughout + KeyValuePair limStart = Utils.inflationPeriod(maturity_ - swapObsLag_, + zii_.frequency()); + earliestDate_ = limStart.Key; + latestDate_ = limStart.Key; + } + + // check that the observation lag of the swap + // is compatible with the availability lag of the index AND + // it's interpolation (assuming the start day is spot) + if (zii_.interpolated()) + { + Period pShift = new Period(zii_.frequency()); + if ( (swapObsLag_ - pShift) <= zii_.availabilityLag()) + throw new ApplicationException( + "inconsistency between swap observation of index " + + swapObsLag_ + + " index availability " + zii_.availabilityLag() + + " index period " + pShift + + " and index availability " + zii_.availabilityLag() + + " need (obsLag-index period) > availLag"); + + } + Settings.registerWith(update); + } + + + public override void setTermStructure(ZeroInflationTermStructure z) { base.setTermStructure( z ); @@ -108,28 +108,28 @@ public override void setTermStructure(ZeroInflationTermStructure z) new_zii, swapObsLag_ ); // Because very simple instrument only takes // standard discounting swap engine. - zciis_.setPricingEngine( new DiscountingSwapEngine( z.nominalTermStructure() ) ); - } - - public override double impliedQuote() - { - // what does the term structure imply? - // in this case just the same value ... trivial case - // (would not be so for an inflation-linked bond) - zciis_.recalculate(); - return zciis_.fairRate(); - } - - - protected Period swapObsLag_; - protected Date maturity_; - protected Calendar calendar_; - protected BusinessDayConvention paymentConvention_; - protected DayCounter dayCounter_; - protected ZeroInflationIndex zii_; - protected ZeroCouponInflationSwap zciis_; - } - + zciis_.setPricingEngine( new DiscountingSwapEngine( z.nominalTermStructure() ) ); + } + + public override double impliedQuote() + { + // what does the term structure imply? + // in this case just the same value ... trivial case + // (would not be so for an inflation-linked bond) + zciis_.recalculate(); + return zciis_.fairRate(); + } + + + protected Period swapObsLag_; + protected Date maturity_; + protected Calendar calendar_; + protected BusinessDayConvention paymentConvention_; + protected DayCounter dayCounter_; + protected ZeroInflationIndex zii_; + protected ZeroCouponInflationSwap zciis_; + } + //! Year-on-year inflation-swap bootstrap helper public class YearOnYearInflationSwapHelper : BootstrapHelper { @@ -249,6 +249,6 @@ public override double impliedQuote() protected DayCounter dayCounter_; protected YoYInflationIndex yii_; protected YearOnYearInflationSwap yyiis_; - } - -} + } + +} diff --git a/QLNet/Termstructures/Inflation/InflationTraits.cs b/QLNet/Termstructures/Inflation/InflationTraits.cs index 7ea56643e..c852f44e0 100644 --- a/QLNet/Termstructures/Inflation/InflationTraits.cs +++ b/QLNet/Termstructures/Inflation/InflationTraits.cs @@ -2,7 +2,7 @@ Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Inflation/InterpolatedZeroInflationCurve.cs b/QLNet/Termstructures/Inflation/InterpolatedZeroInflationCurve.cs index 7e87265c8..9d4223e37 100644 --- a/QLNet/Termstructures/Inflation/InterpolatedZeroInflationCurve.cs +++ b/QLNet/Termstructures/Inflation/InterpolatedZeroInflationCurve.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Inflation/PiecewiseYoYInflationCurve.cs b/QLNet/Termstructures/Inflation/PiecewiseYoYInflationCurve.cs index 04c942fb7..0ffcbc813 100644 --- a/QLNet/Termstructures/Inflation/PiecewiseYoYInflationCurve.cs +++ b/QLNet/Termstructures/Inflation/PiecewiseYoYInflationCurve.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Inflation/PiecewiseZeroInflationCurve.cs b/QLNet/Termstructures/Inflation/PiecewiseZeroInflationCurve.cs index 3b989d231..6b3f4516c 100644 --- a/QLNet/Termstructures/Inflation/PiecewiseZeroInflationCurve.cs +++ b/QLNet/Termstructures/Inflation/PiecewiseZeroInflationCurve.cs @@ -2,7 +2,7 @@ Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Inflation/Seasonality.cs b/QLNet/Termstructures/Inflation/Seasonality.cs index 94f49aa7c..615877f9c 100644 --- a/QLNet/Termstructures/Inflation/Seasonality.cs +++ b/QLNet/Termstructures/Inflation/Seasonality.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/InflationTermStructure.cs b/QLNet/Termstructures/InflationTermStructure.cs index a3e32a08b..e34443ffa 100644 --- a/QLNet/Termstructures/InflationTermStructure.cs +++ b/QLNet/Termstructures/InflationTermStructure.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Iterativebootstrap.cs b/QLNet/Termstructures/Iterativebootstrap.cs index 4b64903c2..2b9f1f93b 100644 --- a/QLNet/Termstructures/Iterativebootstrap.cs +++ b/QLNet/Termstructures/Iterativebootstrap.cs @@ -1,29 +1,29 @@ -/* - Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2014 Edem Dawui (edawui@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace QLNet +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet { public interface IBootStrap { @@ -50,15 +50,15 @@ public class IterativeBootstrapForYoYInflation : IterativeBootstrap:IBootStrap where T : Curve, new() - where U : TermStructure - { - private bool validCurve_ = false; + where U : TermStructure + { + private bool validCurve_ = false; private T ts_; private int n_; private Brent firstSolver_ = new Brent(); @@ -120,23 +120,23 @@ private void initialize() } initialized_ = true; - } - - public void setup(T ts) - { - ts_ = ts; - + } + + public void setup(T ts) + { + ts_ = ts; + n_ = ts_.instruments_.Count; - Utils.QL_REQUIRE( n_ > 0, () => "no bootstrap helpers given" ); - - if (!(n_+1 >= ts_.interpolator_.requiredPoints)) - throw new ArgumentException("not enough instruments: " + n_ + " provided, " + - (ts_.interpolator_.requiredPoints-1) + " required"); - - ts_.instruments_.ForEach(x => ts_.registerWith(x)); - } - - public void calculate() + Utils.QL_REQUIRE( n_ > 0, () => "no bootstrap helpers given" ); + + if (!(n_+1 >= ts_.interpolator_.requiredPoints)) + throw new ArgumentException("not enough instruments: " + n_ + " provided, " + + (ts_.interpolator_.requiredPoints-1) + " required"); + + ts_.instruments_.ForEach(x => ts_.registerWith(x)); + } + + public void calculate() { // we might have to call initialize even if the curve is initialized // and not moving, just because helpers might be date relative and change @@ -163,8 +163,8 @@ public void calculate() List times = ts_.times_; List data = ts_.data_; double accuracy = ts_.accuracy_; - int maxIterations = ts_.maxIterations() - 1; - + int maxIterations = ts_.maxIterations() - 1; + for (int iteration = 0; ; ++iteration) { previousData_ = ts_.data_; @@ -247,8 +247,8 @@ public void calculate() ", required accuracy " + accuracy ); } validCurve_ = true; - - } - } - -} + + } + } + +} diff --git a/QLNet/Termstructures/TermStructure.cs b/QLNet/Termstructures/TermStructure.cs index 616a62940..23dc0d178 100644 --- a/QLNet/Termstructures/TermStructure.cs +++ b/QLNet/Termstructures/TermStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -111,7 +111,7 @@ public virtual Date referenceDate() public virtual Calendar calendar() {return calendar_;} //! the settlementDays used for reference date calculation public virtual int settlementDays() - { + { Utils.QL_REQUIRE( settlementDays_ != null, () => "settlement days not provided for this instance" ); return settlementDays_.Value; } @@ -138,10 +138,10 @@ public override void update() //! date-range check protected virtual void checkRange(Date d, bool extrapolate) - { + { Utils.QL_REQUIRE( d >= referenceDate(), () => "date (" + d + ") before reference date (" + - referenceDate() + ")"); + referenceDate() + ")"); Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || d <= maxDate(), () => "date (" + d + ") is past max curve date (" + maxDate() + ")"); @@ -149,10 +149,10 @@ protected virtual void checkRange(Date d, bool extrapolate) //! time-range check protected void checkRange(double t, bool extrapolate) - { + { Utils.QL_REQUIRE( t >= 0.0, () => "negative time (" + t + ") given"); - Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || t <= maxTime() || Utils.close_enough( t, maxTime() ), () => "time (" + t + ") is past max curve time (" + maxTime() + ")"); diff --git a/QLNet/Termstructures/Volatility/Bond/CallableBondConstantVolatility.cs b/QLNet/Termstructures/Volatility/Bond/CallableBondConstantVolatility.cs index ddb3d2d6f..7e520f552 100644 --- a/QLNet/Termstructures/Volatility/Bond/CallableBondConstantVolatility.cs +++ b/QLNet/Termstructures/Volatility/Bond/CallableBondConstantVolatility.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/Bond/CallableBondVolatilityStructure.cs b/QLNet/Termstructures/Volatility/Bond/CallableBondVolatilityStructure.cs index f220ada27..95bb2f036 100644 --- a/QLNet/Termstructures/Volatility/Bond/CallableBondVolatilityStructure.cs +++ b/QLNet/Termstructures/Volatility/Bond/CallableBondVolatilityStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -138,7 +138,7 @@ public virtual double maxBondLength() //! implements the conversion between dates and times public virtual KeyValuePair convertDates(Date optionDate, Period bondTenor) { - Date end = optionDate + bondTenor; + Date end = optionDate + bondTenor; Utils.QL_REQUIRE( end > optionDate, () => "negative bond tenor (" + bondTenor + ") given"); double optionTime = timeFromReference(optionDate); @@ -169,14 +169,14 @@ protected virtual double volatilityImpl(Date optionDate, Period bondTenor, doubl } protected void checkRange(double optionTime, double bondLength, double k, bool extrapolate) { - base.checkRange(optionTime, extrapolate); + base.checkRange(optionTime, extrapolate); Utils.QL_REQUIRE( bondLength >= 0.0, () => "negative bondLength (" + bondLength + ") given"); - Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || bondLength <= maxBondLength(), () => "bondLength (" + bondLength + ") is past max curve bondLength (" + maxBondLength() + ")"); - Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || ( k >= minStrike() && k <= maxStrike() ), () => "strike (" + k + ") is outside the curve domain [" + minStrike() + "," + maxStrike()+ "]"); @@ -184,14 +184,14 @@ protected void checkRange(double optionTime, double bondLength, double k, bool e protected void checkRange(Date optionDate, Period bondTenor, double k, bool extrapolate) { base.checkRange(timeFromReference(optionDate), - extrapolate); + extrapolate); Utils.QL_REQUIRE( bondTenor.length() > 0, () => "negative bond tenor (" + bondTenor + ") given"); - Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || bondTenor <= maxBondTenor(), () => "bond tenor (" + bondTenor + ") is past max tenor (" + maxBondTenor() + ")"); - Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || ( k >= minStrike() && k <= maxStrike() ), () => "strike (" + k + ") is outside the curve domain [" + minStrike() + "," + maxStrike()+ "]"); diff --git a/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolatilityStructure.cs b/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolatilityStructure.cs index a7ec51fec..dec915c8e 100644 --- a/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolatilityStructure.cs +++ b/QLNet/Termstructures/Volatility/CapFloor/CapFloorTermVolatilityStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/CapFloor/ConstantCapFloorTermVolatility.cs b/QLNet/Termstructures/Volatility/CapFloor/ConstantCapFloorTermVolatility.cs index 9aaf620ff..78105e3ed 100644 --- a/QLNet/Termstructures/Volatility/CapFloor/ConstantCapFloorTermVolatility.cs +++ b/QLNet/Termstructures/Volatility/CapFloor/ConstantCapFloorTermVolatility.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/FlatSmileSection.cs b/QLNet/Termstructures/Volatility/FlatSmileSection.cs index f588fa3d8..1d9383c8a 100644 --- a/QLNet/Termstructures/Volatility/FlatSmileSection.cs +++ b/QLNet/Termstructures/Volatility/FlatSmileSection.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -24,20 +24,20 @@ under the terms of the QLNet license. You should have received a namespace QLNet { public class FlatSmileSection : SmileSection { private double vol_; - private double atmLevel_; - public override double atmLevel() { return atmLevel_; } - + private double? atmLevel_; + public override double atmLevel() + { + Utils.QL_REQUIRE( atmLevel_.HasValue, () => "FlatSmileSection.atmLevel is null" ); + return atmLevel_.Value; + } - // public FlatSmileSection(Date d, double vol, DayCounter dc, Date referenceDate = Date(), double atmLevel = Null()); - public FlatSmileSection(Date d, double vol, DayCounter dc, Date referenceDate) : this(d, vol, dc, referenceDate, 0) { } - public FlatSmileSection(Date d, double vol, DayCounter dc, Date referenceDate, double atmLevel) + public FlatSmileSection(Date d, double vol, DayCounter dc, Date referenceDate = null, double? atmLevel = null) : base(d, dc, referenceDate) { vol_ = vol; atmLevel_ = atmLevel; } - public FlatSmileSection(double exerciseTime, double vol, DayCounter dc) : this(exerciseTime, vol, dc, 0) { } - public FlatSmileSection(double exerciseTime, double vol, DayCounter dc, double atmLevel) + public FlatSmileSection(double exerciseTime, double vol, DayCounter dc, double? atmLevel = null) : base(exerciseTime, dc) { vol_ = vol; atmLevel_ = atmLevel; diff --git a/QLNet/Termstructures/Volatility/Inflation/CPIVolatilitySurface.cs b/QLNet/Termstructures/Volatility/Inflation/CPIVolatilitySurface.cs index 0451a9fc0..bb64e75cb 100644 --- a/QLNet/Termstructures/Volatility/Inflation/CPIVolatilitySurface.cs +++ b/QLNet/Termstructures/Volatility/Inflation/CPIVolatilitySurface.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010, 2011 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -209,26 +209,26 @@ public virtual double timeFromBase(Date maturityDate, Period obsLag = null) //@} protected virtual void checkRange(Date d, double strike, bool extrapolate) - { + { Utils.QL_REQUIRE( d >= baseDate(), () => - "date (" + d + ") is before base date"); + "date (" + d + ") is before base date"); Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || d <= maxDate(), () => "date (" + d + ") is past max curve date (" + maxDate() + ")"); - Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || ( strike >= minStrike() && strike <= maxStrike() ), () => "strike (" + strike + ") is outside the curve domain [" + minStrike() + "," + maxStrike() + "]] at date = " + d); } protected virtual void checkRange(double t, double strike, bool extrapolate) - { + { Utils.QL_REQUIRE( t >= timeFromReference( baseDate() ), () => - "time (" + t + ") is before base date"); + "time (" + t + ") is before base date"); Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || t <= maxTime(), () => "time (" + t + ") is past max curve time (" + maxTime() + ")"); - Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || ( strike >= minStrike() && strike <= maxStrike() ), () => "strike (" + strike + ") is outside the curve domain [" + minStrike() + "," + maxStrike() + "] at time = " + t); diff --git a/QLNet/Termstructures/Volatility/Inflation/yoyinflationoptionletvolatilitystructure.cs b/QLNet/Termstructures/Volatility/Inflation/yoyinflationoptionletvolatilitystructure.cs index cc769dba9..2b84615f6 100644 --- a/QLNet/Termstructures/Volatility/Inflation/yoyinflationoptionletvolatilitystructure.cs +++ b/QLNet/Termstructures/Volatility/Inflation/yoyinflationoptionletvolatilitystructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -280,50 +280,50 @@ protected virtual void checkRange(double t, double strike,bool extrapolate) protected bool indexIsInterpolated_; } - //! Constant surface, no K or T dependence. - public class ConstantYoYOptionletVolatility : YoYOptionletVolatilitySurface - { - - //! \name Constructor - //@{ - //! calculate the reference date based on the global evaluation date - public ConstantYoYOptionletVolatility(double v, - int settlementDays, - Calendar cal, - BusinessDayConvention bdc, - DayCounter dc, - Period observationLag, - Frequency frequency, - bool indexIsInterpolated, - double minStrike = -1.0, // -100% - double maxStrike = 100.0) // +10,000% - :base(settlementDays, cal, bdc, dc, observationLag, frequency, indexIsInterpolated) - { - volatility_ = v; - minStrike_ = minStrike; - maxStrike_ = maxStrike; - } - - //@} - - //! \name Limits - //@{ - public override Date maxDate() { return Date.maxDate(); } - //! the minimum strike for which the term structure can return vols - public override double minStrike() { return minStrike_; } - //! the maximum strike for which the term structure can return vols - public override double maxStrike() { return maxStrike_; } - //@} - - - //! implements the actual volatility calculation in derived classes - protected override double volatilityImpl( double length, double strike ) - { - return volatility_; - } - - protected double volatility_; - protected double minStrike_, maxStrike_; - }; + //! Constant surface, no K or T dependence. + public class ConstantYoYOptionletVolatility : YoYOptionletVolatilitySurface + { + + //! \name Constructor + //@{ + //! calculate the reference date based on the global evaluation date + public ConstantYoYOptionletVolatility(double v, + int settlementDays, + Calendar cal, + BusinessDayConvention bdc, + DayCounter dc, + Period observationLag, + Frequency frequency, + bool indexIsInterpolated, + double minStrike = -1.0, // -100% + double maxStrike = 100.0) // +10,000% + :base(settlementDays, cal, bdc, dc, observationLag, frequency, indexIsInterpolated) + { + volatility_ = v; + minStrike_ = minStrike; + maxStrike_ = maxStrike; + } + + //@} + + //! \name Limits + //@{ + public override Date maxDate() { return Date.maxDate(); } + //! the minimum strike for which the term structure can return vols + public override double minStrike() { return minStrike_; } + //! the maximum strike for which the term structure can return vols + public override double maxStrike() { return maxStrike_; } + //@} + + + //! implements the actual volatility calculation in derived classes + protected override double volatilityImpl( double length, double strike ) + { + return volatility_; + } + + protected double volatility_; + protected double minStrike_, maxStrike_; + }; } diff --git a/QLNet/Termstructures/Volatility/Optionlet/ConstantOptionletVolatility.cs b/QLNet/Termstructures/Volatility/Optionlet/ConstantOptionletVolatility.cs index 66b5fa1db..54848b748 100644 --- a/QLNet/Termstructures/Volatility/Optionlet/ConstantOptionletVolatility.cs +++ b/QLNet/Termstructures/Volatility/Optionlet/ConstantOptionletVolatility.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/Optionlet/OptionletVolatilityStructure.cs b/QLNet/Termstructures/Volatility/Optionlet/OptionletVolatilityStructure.cs index 53a885163..dea9251b7 100644 --- a/QLNet/Termstructures/Volatility/Optionlet/OptionletVolatilityStructure.cs +++ b/QLNet/Termstructures/Volatility/Optionlet/OptionletVolatilityStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/Optionlet/capletvariancecurve.cs b/QLNet/Termstructures/Volatility/Optionlet/capletvariancecurve.cs index b4268be0f..cd6d63155 100644 --- a/QLNet/Termstructures/Volatility/Optionlet/capletvariancecurve.cs +++ b/QLNet/Termstructures/Volatility/Optionlet/capletvariancecurve.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/Sabr.cs b/QLNet/Termstructures/Volatility/Sabr.cs index 6a4ae442b..dc766d20c 100644 --- a/QLNet/Termstructures/Volatility/Sabr.cs +++ b/QLNet/Termstructures/Volatility/Sabr.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -51,7 +51,7 @@ public static double unsafeSabrVolatility(double strike, double forward, double // computations become precise enough if the square of z worth slightly more than the precision machine (hence the m) const double m = 10; - if (Math.Abs(z * z) > Const.QL_Epsilon * m) + if (Math.Abs(z * z) > Const.QL_EPSILON * m) multiplier = z/xx; else { alpha = (0.5-rho*rho)/(1.0-rho); diff --git a/QLNet/Termstructures/Volatility/SmileSection.cs b/QLNet/Termstructures/Volatility/SmileSection.cs index b30664c12..780791817 100644 --- a/QLNet/Termstructures/Volatility/SmileSection.cs +++ b/QLNet/Termstructures/Volatility/SmileSection.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -38,11 +38,8 @@ public abstract class SmileSection : IObservable, IObserver { public double exerciseTime() { return exerciseTime_; } #region ctors - public SmileSection() {} - // public SmileSection(Date d, DayCounter dc = DayCounter(), Date referenceDate = Date()) - public SmileSection(Date d, DayCounter dc) : this(d, dc, null) { } - public SmileSection(Date d, DayCounter dc, Date referenceDate) { + public SmileSection(Date d, DayCounter dc = null, Date referenceDate = null) { exerciseDate_ = d; dc_ = dc; @@ -57,8 +54,7 @@ public SmileSection(Date d, DayCounter dc, Date referenceDate) { initializeExerciseTime(); } - public SmileSection(double exerciseTime) : this(exerciseTime, new DayCounter()) { } - public SmileSection(double exerciseTime, DayCounter dc) { + public SmileSection(double exerciseTime, DayCounter dc = null) { isFloating_ = false; dc_ = dc; exerciseTime_ = exerciseTime; @@ -138,9 +134,8 @@ public SabrSmileSection(double timeToExpiry, double forward, List sabrPa Utils.validateSabrParameters(alpha_, beta_, nu_, rho_); } - // public SabrSmileSection(Date d, double forward, List sabrParameters, DayCounter dc = Actual365Fixed()); - public SabrSmileSection(Date d, double forward, List sabrParams, DayCounter dc) - : base(d, dc) { + public SabrSmileSection( Date d, double forward, List sabrParams, DayCounter dc = null ) + : base(d, dc == null ? new Actual365Fixed() : dc) { forward_ = forward; alpha_ = sabrParams[0]; diff --git a/QLNet/Termstructures/Volatility/equityfx/BlackConstantVol.cs b/QLNet/Termstructures/Volatility/equityfx/BlackConstantVol.cs index 42f4465ea..509d4f7ee 100644 --- a/QLNet/Termstructures/Volatility/equityfx/BlackConstantVol.cs +++ b/QLNet/Termstructures/Volatility/equityfx/BlackConstantVol.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/equityfx/BlackVarianceCurve.cs b/QLNet/Termstructures/Volatility/equityfx/BlackVarianceCurve.cs index c3fb805da..7495decf5 100644 --- a/QLNet/Termstructures/Volatility/equityfx/BlackVarianceCurve.cs +++ b/QLNet/Termstructures/Volatility/equityfx/BlackVarianceCurve.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/equityfx/BlackVolTermStructure.cs b/QLNet/Termstructures/Volatility/equityfx/BlackVolTermStructure.cs index faa096739..72ebd2781 100644 --- a/QLNet/Termstructures/Volatility/equityfx/BlackVolTermStructure.cs +++ b/QLNet/Termstructures/Volatility/equityfx/BlackVolTermStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -101,7 +101,7 @@ public double blackVariance(double maturity, double strike, bool extrapolate = f //! forward (at-the-money) volatility public double blackForwardVol(Date date1,Date date2, double strike,bool extrapolate = false) { - // (redundant) date-based checks + // (redundant) date-based checks Utils.QL_REQUIRE( date1 <= date2, () => date1 + " later than " + date2 ); checkRange(date2, extrapolate); @@ -113,7 +113,7 @@ public double blackForwardVol(Date date1,Date date2, double strike,bool extrapol //! forward (at-the-money) volatility public double blackForwardVol(double time1, double time2, double strike, bool extrapolate = false) - { + { Utils.QL_REQUIRE( time1 <= time2, () => time1 + " later than " + time2 ); checkRange(time2, extrapolate); checkStrike(strike, extrapolate); @@ -129,7 +129,7 @@ public double blackForwardVol(double time1, double time2, double strike, bool ex { double epsilon = Math.Min(1.0e-5, time1); double var1 = blackVarianceImpl(time1-epsilon, strike); - double var2 = blackVarianceImpl(time1+epsilon, strike); + double var2 = blackVarianceImpl(time1+epsilon, strike); Utils.QL_REQUIRE( var2 >= var1, () => "variances must be non-decreasing" ); return Math.Sqrt((var2-var1)/(2*epsilon)); } @@ -137,7 +137,7 @@ public double blackForwardVol(double time1, double time2, double strike, bool ex else { double var1 = blackVarianceImpl(time1, strike); - double var2 = blackVarianceImpl(time2, strike); + double var2 = blackVarianceImpl(time2, strike); Utils.QL_REQUIRE( var2 >= var1, () => "variances must be non-decreasing" ); return Math.Sqrt((var2-var1)/(time2-time1)); } @@ -146,7 +146,7 @@ public double blackForwardVol(double time1, double time2, double strike, bool ex //! forward (at-the-money) variance public double blackForwardVariance(Date date1, Date date2, double strike,bool extrapolate = false) { - // (redundant) date-based checks + // (redundant) date-based checks Utils.QL_REQUIRE( date1 <= date2, () => date1 + " later than " + date2 ); checkRange(date2, extrapolate); @@ -158,12 +158,12 @@ public double blackForwardVariance(Date date1, Date date2, double strike,bool e //! forward (at-the-money) variance public double blackForwardVariance(double time1, double time2, double strike, bool extrapolate = false) - { + { Utils.QL_REQUIRE( time1 <= time2, () => time1 + " later than " + time2 ); checkRange(time2, extrapolate); checkStrike(strike, extrapolate); double v1 = blackVarianceImpl(time1, strike); - double v2 = blackVarianceImpl(time2, strike); + double v2 = blackVarianceImpl(time2, strike); Utils.QL_REQUIRE( v2 >= v1, () => "variances must be non-decreasing" ); return v2-v1; } diff --git a/QLNet/Termstructures/Volatility/equityfx/LocalConstantVol.cs b/QLNet/Termstructures/Volatility/equityfx/LocalConstantVol.cs index 965a879e1..69479c63d 100644 --- a/QLNet/Termstructures/Volatility/equityfx/LocalConstantVol.cs +++ b/QLNet/Termstructures/Volatility/equityfx/LocalConstantVol.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/equityfx/LocalVolCurve.cs b/QLNet/Termstructures/Volatility/equityfx/LocalVolCurve.cs index 42443aa8b..1f95dfd12 100644 --- a/QLNet/Termstructures/Volatility/equityfx/LocalVolCurve.cs +++ b/QLNet/Termstructures/Volatility/equityfx/LocalVolCurve.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/equityfx/LocalVolSurface.cs b/QLNet/Termstructures/Volatility/equityfx/LocalVolSurface.cs index 4752fe43e..527ad8ee4 100644 --- a/QLNet/Termstructures/Volatility/equityfx/LocalVolSurface.cs +++ b/QLNet/Termstructures/Volatility/equityfx/LocalVolSurface.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/equityfx/LocalVolTermStructure.cs b/QLNet/Termstructures/Volatility/equityfx/LocalVolTermStructure.cs index d945b734e..bd40312b6 100644 --- a/QLNet/Termstructures/Volatility/equityfx/LocalVolTermStructure.cs +++ b/QLNet/Termstructures/Volatility/equityfx/LocalVolTermStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityStructure.cs b/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityStructure.cs index 44e8ef17b..2af994d6f 100644 --- a/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityStructure.cs +++ b/QLNet/Termstructures/Volatility/swaption/SwaptionVolatilityStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -196,7 +196,7 @@ public SmileSection smileSection(double optionTime, double swapLength, bool extr //! implements the conversion between swap tenor and swap (time) length public double swapLength(Period swapTenor) - { + { Utils.QL_REQUIRE( swapTenor.length() > 0, () => "non-positive swap tenor (" + swapTenor + ") given" ); switch (swapTenor.units()) { @@ -212,7 +212,7 @@ public double swapLength(Period swapTenor) //! implements the conversion between swap dates and swap (time) length public double swapLength(Date start, Date end) - { + { Utils.QL_REQUIRE( end > start, () => "swap end date (" + end + ") must be greater than start (" + start + ")" ); double result = (end - start) / 365.25 * 12.0; // month unit result = new ClosestRounding(0).Round(result); @@ -235,15 +235,15 @@ protected virtual double volatilityImpl(Date optionDate, Period swapTenor, doubl protected virtual double volatilityImpl(double optionTime, double swapLength, double strike) { throw new NotSupportedException(); } protected void checkSwapTenor(Period swapTenor, bool extrapolate) - { - Utils.QL_REQUIRE( swapTenor.length() > 0, () => "non-positive swap tenor (" + swapTenor + ") given" ); + { + Utils.QL_REQUIRE( swapTenor.length() > 0, () => "non-positive swap tenor (" + swapTenor + ") given" ); Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || swapTenor <= maxSwapTenor(), () => "swap tenor (" + swapTenor + ") is past max tenor (" + maxSwapTenor() + ")"); } protected void checkSwapTenor(double swapLength, bool extrapolate) - { - Utils.QL_REQUIRE( swapLength > 0.0, () => "non-positive swap length (" + swapLength + ") given" ); + { + Utils.QL_REQUIRE( swapLength > 0.0, () => "non-positive swap length (" + swapLength + ") given" ); Utils.QL_REQUIRE( extrapolate || allowsExtrapolation() || swapLength <= maxSwapLength(), () => "swap tenor (" + swapLength + ") is past max tenor (" + maxSwapLength() + ")"); } diff --git a/QLNet/Termstructures/Volatility/swaption/swaptionconstantvol.cs b/QLNet/Termstructures/Volatility/swaption/swaptionconstantvol.cs index 920521d7d..c3546b500 100644 --- a/QLNet/Termstructures/Volatility/swaption/swaptionconstantvol.cs +++ b/QLNet/Termstructures/Volatility/swaption/swaptionconstantvol.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/swaption/swaptionvoldiscrete.cs b/QLNet/Termstructures/Volatility/swaption/swaptionvoldiscrete.cs index 9d4dfddd9..1782bfc7a 100644 --- a/QLNet/Termstructures/Volatility/swaption/swaptionvoldiscrete.cs +++ b/QLNet/Termstructures/Volatility/swaption/swaptionvoldiscrete.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Volatility/swaption/swaptionvolmatrix.cs b/QLNet/Termstructures/Volatility/swaption/swaptionvolmatrix.cs index a48eb3053..8176316e6 100644 --- a/QLNet/Termstructures/Volatility/swaption/swaptionvolmatrix.cs +++ b/QLNet/Termstructures/Volatility/swaption/swaptionvolmatrix.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Yield/Bondhelpers.cs b/QLNet/Termstructures/Yield/Bondhelpers.cs index 500952380..007ec40bc 100644 --- a/QLNet/Termstructures/Yield/Bondhelpers.cs +++ b/QLNet/Termstructures/Yield/Bondhelpers.cs @@ -2,7 +2,7 @@ Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -28,10 +28,10 @@ namespace QLNet { does not change between calls of setTermStructure(). */ public class BondHelper : RelativeDateRateHelper { - protected Bond bond_; + protected Bond bond_; protected bool useCleanPrice_; - public Bond bond() { return bond_; } - + public Bond bond() { return bond_; } + // need to init this because it is used before the handle has any link, i.e. setTermStructure will be used after ctor RelinkableHandle termStructureHandle_ = new RelinkableHandle(); @@ -49,8 +49,8 @@ public BondHelper(Handle price, Bond bond, bool useCleanPrice = true) : b initializeDates(); IPricingEngine bondEngine = new DiscountingBondEngine(termStructureHandle_); - bond_.setPricingEngine(bondEngine); - + bond_.setPricingEngine(bondEngine); + useCleanPrice_ = useCleanPrice; } @@ -65,11 +65,11 @@ public override void setTermStructure(YieldTermStructure t) { public override double impliedQuote() { if (termStructure_ == null) throw new ApplicationException("term structure not set"); - // we didn't register as observers - force calculation - bond_.recalculate(); - if (useCleanPrice_) - return bond_.cleanPrice(); - else + // we didn't register as observers - force calculation + bond_.recalculate(); + if (useCleanPrice_) + return bond_.cleanPrice(); + else return bond_.dirtyPrice(); } @@ -90,37 +90,37 @@ public class FixedRateBondHelper : BondHelper { // double redemption = 100.0, // Date issueDate = null); public FixedRateBondHelper(Handle price, int settlementDays, double faceAmount, Schedule schedule, - List coupons, DayCounter dayCounter, BusinessDayConvention paymentConvention, + List coupons, DayCounter dayCounter, BusinessDayConvention paymentConvention, double redemption, Date issueDate, Calendar paymentCalendar = null, Period exCouponPeriod = null, Calendar exCouponCalendar = null, BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, bool exCouponEndOfMonth = false, bool useCleanPrice = true) : base(price, new FixedRateBond(settlementDays, faceAmount, schedule, - coupons, dayCounter, paymentConvention, - redemption, issueDate, paymentCalendar, - exCouponPeriod, exCouponCalendar, exCouponConvention, exCouponEndOfMonth), useCleanPrice) + coupons, dayCounter, paymentConvention, + redemption, issueDate, paymentCalendar, + exCouponPeriod, exCouponCalendar, exCouponConvention, exCouponEndOfMonth), useCleanPrice) { fixedRateBond_ = bond_ as FixedRateBond; } - } - - public class CPIBondHelper : BondHelper - { - protected CPIBond cpiBond_; - public CPIBond cpiBond() { return cpiBond_; } - - public CPIBondHelper(Handle price, int settlementDays, double faceAmount, bool growthOnly, double baseCPI, - Period observationLag, ZeroInflationIndex cpiIndex, InterpolationType observationInterpolation, - Schedule schedule, List fixedRate, DayCounter dayCounter, BusinessDayConvention paymentConvention, - double redemption, Date issueDate, Calendar paymentCalendar = null, - Period exCouponPeriod = null, Calendar exCouponCalendar = null, - BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, bool exCouponEndOfMonth = false, - bool useCleanPrice = true) - : base(price, new CPIBond(settlementDays, faceAmount, growthOnly, baseCPI, observationLag, cpiIndex, observationInterpolation, schedule, - fixedRate, dayCounter, paymentConvention, issueDate, paymentCalendar, exCouponPeriod, exCouponCalendar, - exCouponConvention, exCouponEndOfMonth), useCleanPrice) - { - cpiBond_ = bond_ as CPIBond; - } - } + } + + public class CPIBondHelper : BondHelper + { + protected CPIBond cpiBond_; + public CPIBond cpiBond() { return cpiBond_; } + + public CPIBondHelper(Handle price, int settlementDays, double faceAmount, bool growthOnly, double baseCPI, + Period observationLag, ZeroInflationIndex cpiIndex, InterpolationType observationInterpolation, + Schedule schedule, List fixedRate, DayCounter dayCounter, BusinessDayConvention paymentConvention, + double redemption, Date issueDate, Calendar paymentCalendar = null, + Period exCouponPeriod = null, Calendar exCouponCalendar = null, + BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, bool exCouponEndOfMonth = false, + bool useCleanPrice = true) + : base(price, new CPIBond(settlementDays, faceAmount, growthOnly, baseCPI, observationLag, cpiIndex, observationInterpolation, schedule, + fixedRate, dayCounter, paymentConvention, issueDate, paymentCalendar, exCouponPeriod, exCouponCalendar, + exCouponConvention, exCouponEndOfMonth), useCleanPrice) + { + cpiBond_ = bond_ as CPIBond; + } + } } diff --git a/QLNet/Termstructures/Yield/Bootstraptraits.cs b/QLNet/Termstructures/Yield/Bootstraptraits.cs index d56d4ef3e..c43d60cff 100644 --- a/QLNet/Termstructures/Yield/Bootstraptraits.cs +++ b/QLNet/Termstructures/Yield/Bootstraptraits.cs @@ -3,7 +3,7 @@ Copyright (C) 2014 Edem Dawui (edawui@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -64,7 +64,7 @@ public class Discount : ITraits public double minValueAfter( int s, List l ) { // replace with Epsilon - return Const.QL_Epsilon; + return Const.QL_EPSILON; } public double maxValueAfter( int i, List data ) { @@ -154,7 +154,7 @@ public double minValueAfter( int s, List l ) // We choose as min a value very unlikely to be exceeded. return -3.0; #else - return Const.QL_Epsilon; + return Const.QL_EPSILON; #endif } public double maxValueAfter( int i, List data ) @@ -213,7 +213,7 @@ public double minValueAfter( int i, InterpolatedCurve c, bool validData, int f ) // We choose as min a value very unlikely to be exceeded. return -maxRate; #else - return Const.QL_Epsilon; + return Const.QL_EPSILON; #endif @@ -254,7 +254,7 @@ public double guess( YieldTermStructure c, Date d ) return c.forwardRate( d, d, c.dayCounter(), Compounding.Continuous, Frequency.Annual, true ).rate(); } // possible constraints based on previous values - public double minValueAfter( int v, List l ) { return Const.QL_Epsilon; } + public double minValueAfter( int v, List l ) { return Const.QL_EPSILON; } public double maxValueAfter( int v, List l ) { // no constraints. @@ -319,7 +319,7 @@ public double minValueAfter( int i, InterpolatedCurve c, bool validData, int f ) // We choose as min a value very unlikely to be exceeded. return -maxRate; #else - return Const.QL_Epsilon; + return Const.QL_EPSILON; #endif } diff --git a/QLNet/Termstructures/Yield/DiscountCurve.cs b/QLNet/Termstructures/Yield/DiscountCurve.cs index 0801c0539..2b4c9432b 100644 --- a/QLNet/Termstructures/Yield/DiscountCurve.cs +++ b/QLNet/Termstructures/Yield/DiscountCurve.cs @@ -1,20 +1,20 @@ -/* - Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; using System.Collections.Generic; diff --git a/QLNet/Termstructures/Yield/Flatforward.cs b/QLNet/Termstructures/Yield/Flatforward.cs index 03b7fe724..8fd056a0d 100644 --- a/QLNet/Termstructures/Yield/Flatforward.cs +++ b/QLNet/Termstructures/Yield/Flatforward.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Yield/ForwardCurve.cs b/QLNet/Termstructures/Yield/ForwardCurve.cs index 7eeca13d9..5a223aef3 100644 --- a/QLNet/Termstructures/Yield/ForwardCurve.cs +++ b/QLNet/Termstructures/Yield/ForwardCurve.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Yield/ForwardSpreadedTermStructure.cs b/QLNet/Termstructures/Yield/ForwardSpreadedTermStructure.cs index e0eb082ce..841eb5d12 100644 --- a/QLNet/Termstructures/Yield/ForwardSpreadedTermStructure.cs +++ b/QLNet/Termstructures/Yield/ForwardSpreadedTermStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Yield/ForwardStructure.cs b/QLNet/Termstructures/Yield/ForwardStructure.cs index 6ba6a6003..b0a402f77 100644 --- a/QLNet/Termstructures/Yield/ForwardStructure.cs +++ b/QLNet/Termstructures/Yield/ForwardStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Yield/ImpliedTermStructure.cs b/QLNet/Termstructures/Yield/ImpliedTermStructure.cs index e440edd3b..6063926cf 100644 --- a/QLNet/Termstructures/Yield/ImpliedTermStructure.cs +++ b/QLNet/Termstructures/Yield/ImpliedTermStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Yield/InterpolatedPiecewiseZeroSpreadedTermStructure.cs b/QLNet/Termstructures/Yield/InterpolatedPiecewiseZeroSpreadedTermStructure.cs index ec06b94ca..b352e1bb1 100644 --- a/QLNet/Termstructures/Yield/InterpolatedPiecewiseZeroSpreadedTermStructure.cs +++ b/QLNet/Termstructures/Yield/InterpolatedPiecewiseZeroSpreadedTermStructure.cs @@ -1,20 +1,20 @@ -/* - Copyright (C) 2015 Francois Botha - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2015 Francois Botha + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; using System.Collections.Generic; diff --git a/QLNet/Termstructures/Yield/OISRateHelper.cs b/QLNet/Termstructures/Yield/OISRateHelper.cs index d7c943506..a4cb8e5f3 100644 --- a/QLNet/Termstructures/Yield/OISRateHelper.cs +++ b/QLNet/Termstructures/Yield/OISRateHelper.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Yield/PiecewiseYieldCurve.cs b/QLNet/Termstructures/Yield/PiecewiseYieldCurve.cs index 9b410c2ab..8b81fcee2 100644 --- a/QLNet/Termstructures/Yield/PiecewiseYieldCurve.cs +++ b/QLNet/Termstructures/Yield/PiecewiseYieldCurve.cs @@ -3,7 +3,7 @@ Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -17,46 +17,46 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ +*/ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace QLNet { - // this is an abstract class to give access to all properties and methods of PiecewiseYieldCurve and avoiding generics - public class PiecewiseYieldCurve : YieldTermStructure, InterpolatedCurve, Curve - { - # region new fields: Curve - - public double initialValue() { return _traits_.initialValue( this ); } - public Date initialDate() { return _traits_.initialDate( this ); } - public void registerWith( BootstrapHelper helper ) - { - helper.registerWith( this.update ); - } - public new bool moving_ - { - get { return base.moving_; } - set { base.moving_ = value; } - } - public void setTermStructure( BootstrapHelper helper ) - { - helper.setTermStructure( this ); - } - protected ITraits _traits_ = null;//todo define with the trait for yield curve - public ITraits traits_ - { - get - { - return _traits_; - } - } - public double minValueAfter( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.minValueAfter( i, c, validData, first ); } - public double maxValueAfter( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.maxValueAfter( i, c, validData, first ); } - public double guess( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.guess( i, c, validData, first ); } - - # endregion + // this is an abstract class to give access to all properties and methods of PiecewiseYieldCurve and avoiding generics + public class PiecewiseYieldCurve : YieldTermStructure, InterpolatedCurve, Curve + { + # region new fields: Curve + + public double initialValue() { return _traits_.initialValue( this ); } + public Date initialDate() { return _traits_.initialDate( this ); } + public void registerWith( BootstrapHelper helper ) + { + helper.registerWith( this.update ); + } + public new bool moving_ + { + get { return base.moving_; } + set { base.moving_ = value; } + } + public void setTermStructure( BootstrapHelper helper ) + { + helper.setTermStructure( this ); + } + protected ITraits _traits_ = null;//todo define with the trait for yield curve + public ITraits traits_ + { + get + { + return _traits_; + } + } + public double minValueAfter( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.minValueAfter( i, c, validData, first ); } + public double maxValueAfter( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.maxValueAfter( i, c, validData, first ); } + public double guess( int i, InterpolatedCurve c, bool validData, int first ) { return traits_.guess( i, c, validData, first ); } + + # endregion #region InterpolatedCurve public List times_ { get; set; } @@ -119,28 +119,28 @@ protected override double discountImpl(double t) { public double forwardImpl(Interpolation i, double t) { throw new NotSupportedException(); } #endregion - #region Properties - - protected double _accuracy_;//= 1.0e-12; - public double accuracy_ - { - get { return _accuracy_; } - set { _accuracy_ = value; } - } - - protected List _instruments_ = new List(); - public List> instruments_ - { - get - { - //todo edem - List> instruments = new List>(); - _instruments_.ForEach( x => instruments.Add( x ) ); - return instruments; - } - } - - protected IBootStrap bootstrap_; + #region Properties + + protected double _accuracy_;//= 1.0e-12; + public double accuracy_ + { + get { return _accuracy_; } + set { _accuracy_ = value; } + } + + protected List _instruments_ = new List(); + public List> instruments_ + { + get + { + //todo edem + List> instruments = new List>(); + _instruments_.ForEach( x => instruments.Add( x ) ); + return instruments; + } + } + + protected IBootStrap bootstrap_; #endregion @@ -151,17 +151,17 @@ public PiecewiseYieldCurve(Date referenceDate, Calendar cal, DayCounter dc, {} public PiecewiseYieldCurve(int settlementDays, Calendar cal, DayCounter dc, List> jumps = null, List jumpDates = null) - : base(settlementDays, cal, dc,jumps,jumpDates) - {} - public PiecewiseYieldCurve() - : base() + : base(settlementDays, cal, dc,jumps,jumpDates) + {} + public PiecewiseYieldCurve() + : base() {} } - - public class PiecewiseYieldCurve : PiecewiseYieldCurve + + public class PiecewiseYieldCurve : PiecewiseYieldCurve where Traits : ITraits, new() - where Interpolator : IInterpolationFactory, new() - where BootStrap : IBootStrap, new() + where Interpolator : IInterpolationFactory, new() + where BootStrap : IBootStrap, new() { #region Constructors @@ -234,8 +234,8 @@ protected override void performCalculations() } } - // Allows for optional 3rd generic parameter defaulted to IterativeBootstrap - public class PiecewiseYieldCurve : PiecewiseYieldCurve + // Allows for optional 3rd generic parameter defaulted to IterativeBootstrap + public class PiecewiseYieldCurve : PiecewiseYieldCurve where Traits : ITraits, new() where Interpolator : IInterpolationFactory, new() { diff --git a/QLNet/Termstructures/Yield/Ratehelpers.cs b/QLNet/Termstructures/Yield/Ratehelpers.cs index f62da0ae1..7ee4d9349 100644 --- a/QLNet/Termstructures/Yield/Ratehelpers.cs +++ b/QLNet/Termstructures/Yield/Ratehelpers.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Yield/ZeroCurve.cs b/QLNet/Termstructures/Yield/ZeroCurve.cs index e07c92535..ffc37a99e 100644 --- a/QLNet/Termstructures/Yield/ZeroCurve.cs +++ b/QLNet/Termstructures/Yield/ZeroCurve.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Yield/ZeroSpreadedTermStructure.cs b/QLNet/Termstructures/Yield/ZeroSpreadedTermStructure.cs index b2cbf356d..9ac82b5cd 100644 --- a/QLNet/Termstructures/Yield/ZeroSpreadedTermStructure.cs +++ b/QLNet/Termstructures/Yield/ZeroSpreadedTermStructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/Yield/Zeroyieldstructure.cs b/QLNet/Termstructures/Yield/Zeroyieldstructure.cs index 05ec7a176..12a3e602f 100644 --- a/QLNet/Termstructures/Yield/Zeroyieldstructure.cs +++ b/QLNet/Termstructures/Yield/Zeroyieldstructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/YieldTermStructure.cs b/QLNet/Termstructures/YieldTermStructure.cs index ab155686a..35c177df9 100644 --- a/QLNet/Termstructures/YieldTermStructure.cs +++ b/QLNet/Termstructures/YieldTermStructure.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/interpolatedcurve.cs b/QLNet/Termstructures/interpolatedcurve.cs index e35696e6f..6f8e5d27f 100644 --- a/QLNet/Termstructures/interpolatedcurve.cs +++ b/QLNet/Termstructures/interpolatedcurve.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Termstructures/localbootstrap.cs b/QLNet/Termstructures/localbootstrap.cs index 9ff5ced6b..84a2af315 100644 --- a/QLNet/Termstructures/localbootstrap.cs +++ b/QLNet/Termstructures/localbootstrap.cs @@ -3,7 +3,7 @@ Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2014 Edem Dawui (edawui@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -17,25 +17,25 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ +*/ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace QLNet -{ - public class LocalBootstrapForYield : LocalBootstrap - { - public LocalBootstrapForYield() - : base() - {} +{ + public class LocalBootstrapForYield : LocalBootstrap + { + public LocalBootstrapForYield() + : base() + {} } - // penalty function class for solving using a multi-dimensional solver - public class PenaltyFunction : CostFunction - where T : Curve, new() - where U : TermStructure + // penalty function class for solving using a multi-dimensional solver + public class PenaltyFunction : CostFunction + where T : Curve, new() + where U : TermStructure { //typedef typename Curve::traits_type Traits; //typedef typename Traits::helper helper; @@ -43,9 +43,9 @@ public class PenaltyFunction : CostFunction private T curve_; private int initialIndex_; - private int localisation_, start_, end_; - private List> rateHelpers_; - + private int localisation_, start_, end_; + private List> rateHelpers_; + public PenaltyFunction( T curve, int initialIndex, List> rateHelpers, int start, int end ) { curve_ = curve; @@ -94,8 +94,8 @@ approximation. This restricts the risk profile s.t. the risk whilst using a smoother interpolation method. Particularly good for the convex-monotone spline method. */ - public class LocalBootstrap :IBootStrap - where T : Curve, new() + public class LocalBootstrap :IBootStrap + where T : Curve, new() where U : TermStructure { //typedef typename Curve::traits_type Traits; @@ -124,7 +124,7 @@ public void setup(T ts) { if (!(n > localisation_)) throw new ApplicationException("not enough instruments: " + n + " provided, " + localisation_ + " required."); - //ts_.instruments_.ForEach(i => i.registerWith(ts_.update)); + //ts_.instruments_.ForEach(i => i.registerWith(ts_.update)); ts_.instruments_.ForEach( x => ts_.registerWith( x ) ); } @@ -199,14 +199,14 @@ public void calculate() { ts_.interpolation_ = (ts_.interpolator_ as ConvexMonotone).localInterpolate(ts_.times_, iInst + 2, ts_.data_, localisation_, ts_.interpolation_ as ConvexMonotoneInterpolation, nInsts + 1); - if (iInst >= localisation_) { + if (iInst >= localisation_) { startArray[localisation_ - dataAdjust] = ts_.guess( iInst, ts_, false, 0 ); } else { startArray[localisation_-dataAdjust] = ts_.data_[0]; - } - - var currentCost = new PenaltyFunction( ts_, initialDataPt, ts_.instruments_, - iInst - localisation_ + 1, iInst + 1 ); + } + + var currentCost = new PenaltyFunction( ts_, initialDataPt, ts_.instruments_, + iInst - localisation_ + 1, iInst + 1 ); Problem toSolve = new Problem( currentCost, solverConstraint, startArray ); EndCriteria.Type endType = solver.minimize(toSolve, endCriteria); diff --git a/QLNet/Termstructures/voltermstructure.cs b/QLNet/Termstructures/voltermstructure.cs index 49f88f8a6..57cad736d 100644 --- a/QLNet/Termstructures/voltermstructure.cs +++ b/QLNet/Termstructures/voltermstructure.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -75,7 +75,7 @@ public Date optionDateFromTenor(Period p) //! strike-range check protected void checkStrike(double k, bool extrapolate) { - Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || + Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || ( k >= minStrike() && k <= maxStrike() ), () => "strike (" + k + ") is outside the curve domain [" + minStrike() + "," + maxStrike() + "]"); diff --git a/QLNet/Time/Calendar.cs b/QLNet/Time/Calendar.cs index 3bf8e5870..b20a00e00 100644 --- a/QLNet/Time/Calendar.cs +++ b/QLNet/Time/Calendar.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -113,20 +113,27 @@ public virtual bool isBusinessDay(Date d) { /// Adjusts a non-business day to the appropriate near business day with respect /// to the given convention. /// - public Date adjust(Date d) { return adjust(d, BusinessDayConvention.Following); } - public Date adjust(Date d, BusinessDayConvention c) + public Date adjust( Date d, BusinessDayConvention c = BusinessDayConvention.Following ) { if (d == null) throw new ArgumentException("null date"); if (c == BusinessDayConvention.Unadjusted) return d; Date d1 = d; - if (c == BusinessDayConvention.Following || c == BusinessDayConvention.ModifiedFollowing) + if (c == BusinessDayConvention.Following || c == BusinessDayConvention.ModifiedFollowing || + c == BusinessDayConvention.HalfMonthModifiedFollowing) { while (isHoliday(d1)) d1++; - if (c == BusinessDayConvention.ModifiedFollowing) + if ( c == BusinessDayConvention.ModifiedFollowing || c == BusinessDayConvention.HalfMonthModifiedFollowing ) { if (d1.Month != d.Month) return adjust(d, BusinessDayConvention.Preceding); + if ( c == BusinessDayConvention.HalfMonthModifiedFollowing ) + { + if ( d.Day <= 15 && d1.Day > 15 ) + { + return adjust( d, BusinessDayConvention.Preceding ); + } + } } } else if (c == BusinessDayConvention.Preceding || c == BusinessDayConvention.ModifiedPreceding) @@ -145,9 +152,7 @@ public Date adjust(Date d, BusinessDayConvention c) /// returns the result. /// /// The input date is not modified - public Date advance(Date d, int n, TimeUnit unit) { return advance(d, n, unit, BusinessDayConvention.Following, false); } - public Date advance(Date d, int n, TimeUnit unit, BusinessDayConvention c) { return advance(d, n, unit, c, false); } - public Date advance(Date d, int n, TimeUnit unit, BusinessDayConvention c, bool endOfMonth) + public Date advance( Date d, int n, TimeUnit unit, BusinessDayConvention c = BusinessDayConvention.Following, bool endOfMonth = false ) { if (d == null) throw new ArgumentException("null date"); if (n == 0) @@ -195,9 +200,7 @@ public Date advance(Date d, int n, TimeUnit unit, BusinessDayConvention c, bool /// returns the result. /// /// The input date is not modified. - public Date advance(Date d, Period p) { return advance(d, p, BusinessDayConvention.Following, false); } - public Date advance(Date d, Period p, BusinessDayConvention c) { return advance(d, p, c, false); } - public Date advance(Date d, Period p, BusinessDayConvention c, bool endOfMonth) + public Date advance( Date d, Period p, BusinessDayConvention c = BusinessDayConvention.Following, bool endOfMonth = false) { return advance(d, p.length(), p.units(), c, endOfMonth); } @@ -206,9 +209,7 @@ public Date advance(Date d, Period p, BusinessDayConvention c, bool endOfMonth) /// Calculates the number of business days between two given /// dates and returns the result. /// - public int businessDaysBetween(Date from, Date to) { return businessDaysBetween(from, to, true, false); } - public int businessDaysBetween(Date from, Date to, bool includeFirst) { return businessDaysBetween(from, to, includeFirst, false); } - public int businessDaysBetween(Date from, Date to, bool includeFirst, bool includeLast) + public int businessDaysBetween(Date from, Date to, bool includeFirst = true, bool includeLast = false) { int wd = 0; if (from != to) @@ -271,11 +272,7 @@ public void removeHoliday(Date d) { /// /// Returns the holidays between two dates /// - public static List holidayList(Calendar calendar, Date from, Date to) { - return holidayList(calendar, from, to, false); - } - - public static List holidayList(Calendar calendar, Date from, Date to, bool includeWeekEnds) { + public static List holidayList(Calendar calendar, Date from, Date to, bool includeWeekEnds = false) { if (to <= from) { throw new Exception("'from' date (" + from + ") must be earlier than 'to' date (" + to + ")"); diff --git a/QLNet/Time/Calendars/JointCalendar.cs b/QLNet/Time/Calendars/JointCalendar.cs index 01433e3bf..8a0d3cf59 100644 --- a/QLNet/Time/Calendars/JointCalendar.cs +++ b/QLNet/Time/Calendars/JointCalendar.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/TARGET.cs b/QLNet/Time/Calendars/TARGET.cs index b3ff9b9ce..5ae8dad4f 100644 --- a/QLNet/Time/Calendars/TARGET.cs +++ b/QLNet/Time/Calendars/TARGET.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/Ukraine.cs b/QLNet/Time/Calendars/Ukraine.cs new file mode 100644 index 000000000..a39276e2e --- /dev/null +++ b/QLNet/Time/Calendars/Ukraine.cs @@ -0,0 +1,106 @@ +/* + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + //! Ukrainian calendars + /*! Holidays for the Ukrainian stock exchange + (data from ): +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's Day, January 1st
  • +
  • Orthodox Christmas, January 7th
  • +
  • International Women's Day, March 8th
  • +
  • Easter Monday
  • +
  • Holy Trinity Day, 50 days after Easter
  • +
  • International Workers' Solidarity Days, May 1st and 2nd
  • +
  • Victory Day, May 9th
  • +
  • Constitution Day, June 28th
  • +
  • Independence Day, August 24th
  • +
+ Holidays falling on a Saturday or Sunday are moved to the + following Monday. + + \ingroup calendars + */ + public class Ukraine : Calendar + { + public Ukraine(Market m = Market.USE ) + { + // all calendar instances on the same market share the same implementation instance + switch ( m ) + { + case Market.USE: + calendar_ = Impl.Singleton; + break; + default: + throw new ApplicationException( "unknown market" ); + } + } + + public enum Market { USE //!< Ukrainian stock exchange + }; + + class Impl : Calendar.OrthodoxImpl + { + public static readonly Impl Singleton = new Impl(); + private Impl() { } + + public override string name() { return "Ukrainian stock exchange"; } + public override bool isBusinessDay( Date date ) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day, dd = date.DayOfYear; + Month m = (Month)date.Month; + int y = date.Year; + int em = easterMonday( y ); + + if ( isWeekend( w ) + // New Year's Day (possibly moved to Monday) + || ( ( d == 1 || ( ( d == 2 || d == 3 ) && w == DayOfWeek.Monday ) ) + && m == Month.January ) + // Orthodox Christmas + || ( ( d == 7 || ( ( d == 8 || d == 9 ) && w == DayOfWeek.Monday ) ) + && m == Month.January ) + // Women's Day + || ( ( d == 8 || ( ( d == 9 || d == 10 ) && w == DayOfWeek.Monday ) ) + && m == Month.March ) + // Orthodox Easter Monday + || ( dd == em ) + // Holy Trinity Day + || ( dd == em + 49 ) + // Workers' Solidarity Days + || ( ( d == 1 || d == 2 || ( d == 3 && w == DayOfWeek.Monday ) ) && m == Month.May ) + // Victory Day + || ( ( d == 9 || ( ( d == 10 || d == 11 ) && w == DayOfWeek.Monday ) ) && m == Month.May ) + // Constitution Day + || ( d == 28 && m == Month.June ) + // Independence Day + || ( d == 24 && m == Month.August ) ) + return false; + return true; + } + }; + } +} diff --git a/QLNet/Time/Calendars/UnitedKingdom.cs b/QLNet/Time/Calendars/UnitedKingdom.cs index 5c3cf0bcf..4c08e21be 100644 --- a/QLNet/Time/Calendars/UnitedKingdom.cs +++ b/QLNet/Time/Calendars/UnitedKingdom.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/UnitedStates.cs b/QLNet/Time/Calendars/UnitedStates.cs index 8c091bfca..5679bc78a 100644 --- a/QLNet/Time/Calendars/UnitedStates.cs +++ b/QLNet/Time/Calendars/UnitedStates.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -209,44 +209,60 @@ public override bool isBusinessDay(Date date) { (d == 24 && w == DayOfWeek.Friday)) && m == Month.December) ) return false; - if (y >= 1998) { - if (// Martin Luther King's birthday (third Monday in January) - ((d >= 15 && d <= 21) && w == DayOfWeek.Monday && m == Month.January) - // President Reagan's funeral - || (y == 2004 && m == Month.June && d == 11) - // September 11, 2001 - || (y == 2001 && m == Month.September && (11 <= d && d <= 14)) - // President Ford's funeral - || (y == 2007 && m == Month.January && d == 2) - ) return false; - } else if (y <= 1980) { - if (// Presidential election days - ((y % 4 == 0) && m == Month.November && d <= 7 && w == DayOfWeek.Tuesday) - // 1977 Blackout - || (y == 1977 && m == Month.July && d == 14) - // Funeral of former President Lyndon B. Johnson. - || (y == 1973 && m == Month.January && d == 25) - // Funeral of former President Harry S. Truman - || (y == 1972 && m == Month.December && d == 28) - // National Day of Participation for the lunar exploration. - || (y == 1969 && m == Month.July && d == 21) - // Funeral of former President Eisenhower. - || (y == 1969 && m == Month.March && d == 31) - // Closed all day - heavy snow. - || (y == 1969 && m == Month.February && d == 10) - // Day after Independence Day. - || (y == 1968 && m == Month.July && d == 5) - // June 12-Dec. 31, 1968 - // Four day week (closed on Wednesdays) - Paperwork Crisis - || (y == 1968 && dd >= 163 && w == DayOfWeek.Wednesday) - ) return false; - } else { - if (// Nixon's funeral - (y == 1994 && m == Month.April && d == 27) - ) return false; - } - return true; + if ( y >= 1998 && ( d >= 15 && d <= 21 ) && w == DayOfWeek.Monday && m == Month.January ) + // Martin Luther King's birthday (third Monday in January) + return false; + + if ( ( y <= 1968 || ( y <= 1980 && y % 4 == 0 ) ) && m == Month.November + && d <= 7 && w == DayOfWeek.Tuesday ) + // Presidential election days + return false; + + // Special closings + if (// Hurricane Sandy + ( y == 2012 && m == Month.October && ( d == 29 || d == 30 ) ) + // President Ford's funeral + || ( y == 2007 && m == Month.January && d == 2 ) + // President Reagan's funeral + || ( y == 2004 && m == Month.June && d == 11 ) + // September 11-14, 2001 + || ( y == 2001 && m == Month.September && ( 11 <= d && d <= 14 ) ) + // President Nixon's funeral + || ( y == 1994 && m == Month.April && d == 27 ) + // Hurricane Gloria + || ( y == 1985 && m == Month.September && d == 27 ) + // 1977 Blackout + || ( y == 1977 && m == Month.July && d == 14 ) + // Funeral of former President Lyndon B. Johnson. + || ( y == 1973 && m == Month.January && d == 25 ) + // Funeral of former President Harry S. Truman + || ( y == 1972 && m == Month.December && d == 28 ) + // National Day of Participation for the lunar exploration. + || ( y == 1969 && m == Month.July && d == 21 ) + // Funeral of former President Eisenhower. + || ( y == 1969 && m == Month.March && d == 31 ) + // Closed all day - heavy snow. + || ( y == 1969 && m == Month.February && d == 10 ) + // Day after Independence Day. + || ( y == 1968 && m == Month.July && d == 5 ) + // June 12-Dec. 31, 1968 + // Four day week (closed on Wednesdays) - Paperwork Crisis + || ( y == 1968 && dd >= 163 && w == DayOfWeek.Wednesday ) + // Day of mourning for Martin Luther King Jr. + || ( y == 1968 && m == Month.April && d == 9 ) + // Funeral of President Kennedy + || ( y == 1963 && m == Month.November && d == 25 ) + // Day before Decoration Day + || ( y == 1961 && m == Month.May && d == 29 ) + // Day after Christmas + || ( y == 1958 && m == Month.December && d == 26 ) + // Christmas Eve + || ((y == 1954 || y == 1956 || y == 1965) + && m == Month.December && d == 24 ) + ) + return false; + return true; } } private class GovernmentBond : Calendar.WesternImpl { diff --git a/QLNet/Time/Calendars/WeekendsOnly.cs b/QLNet/Time/Calendars/WeekendsOnly.cs index d5c0249d1..e0e94fd1e 100644 --- a/QLNet/Time/Calendars/WeekendsOnly.cs +++ b/QLNet/Time/Calendars/WeekendsOnly.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/argentina.cs b/QLNet/Time/Calendars/argentina.cs index 1327979c6..d62e17626 100644 --- a/QLNet/Time/Calendars/argentina.cs +++ b/QLNet/Time/Calendars/argentina.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/australia.cs b/QLNet/Time/Calendars/australia.cs index 447abfea6..71850f7d7 100644 --- a/QLNet/Time/Calendars/australia.cs +++ b/QLNet/Time/Calendars/australia.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/bespokecalendar.cs b/QLNet/Time/Calendars/bespokecalendar.cs index c7fab7409..14a681c4d 100644 --- a/QLNet/Time/Calendars/bespokecalendar.cs +++ b/QLNet/Time/Calendars/bespokecalendar.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/brazil.cs b/QLNet/Time/Calendars/brazil.cs index f9c3e1850..5d3aba403 100644 --- a/QLNet/Time/Calendars/brazil.cs +++ b/QLNet/Time/Calendars/brazil.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/canada.cs b/QLNet/Time/Calendars/canada.cs index 8ebe989c6..48b3e5c24 100644 --- a/QLNet/Time/Calendars/canada.cs +++ b/QLNet/Time/Calendars/canada.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/china.cs b/QLNet/Time/Calendars/china.cs index 934501556..dbe53f69e 100644 --- a/QLNet/Time/Calendars/china.cs +++ b/QLNet/Time/Calendars/china.cs @@ -1,135 +1,293 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - Copyright (C) 2008 Alessandro Duci - Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace QLNet { - //! Chinese calendar - /*! Holidays: -
    -
  • Saturdays
  • -
  • Sundays
  • -
  • New Year's day, January 1st (possibly followed by one or - two more holidays)
  • -
  • Labour Day, first week in May
  • -
  • National Day, one week from October 1st
  • -
- - Other holidays for which no rule is given (data available for - 2004-2013 only): -
    -
  • Chinese New Year
  • -
  • Ching Ming Festival
  • -
  • Tuen Ng Festival
  • -
  • Mid-Autumn Festival
  • -
- - Data from - - \ingroup calendars - */ - public class China : Calendar { - public China() : base(Impl.Singleton) { } - - class Impl : Calendar { - public static readonly Impl Singleton = new Impl(); - private Impl() { } - - public override string name() { return "Shanghai stock exchange"; } - public override bool isWeekend(DayOfWeek w) { - return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; - } - public override bool isBusinessDay(Date date) { - DayOfWeek w = date.DayOfWeek; - int d = date.Day; - Month m = (Month)date.Month; - int y = date.Year; - - if (isWeekend(w) - // New Year's Day - || (d == 1 && m == Month.January) - || (y == 2005 && d == 3 && m == Month.January) - || (y == 2006 && (d == 2 || d == 3) && m == Month.January) - || (y == 2007 && d <= 3 && m == Month.January) - || (y == 2007 && d == 31 && m == Month.December) - || (y == 2009 && d == 2 && m == Month.January) - || (y == 2011 && d == 3 && m == Month.January) - || (y == 2012 && (d == 2 || d == 3) && m == Month.January) - || (y == 2013 && d <= 3 && m == Month.January) - // Chinese New Year - || (y == 2004 && d >= 19 && d <= 28 && m == Month.January) - || (y == 2005 && d >= 7 && d <= 15 && m == Month.February) - || (y == 2006 && ((d >= 26 && m == Month.January) || - (d <= 3 && m == Month.February))) - || (y == 2007 && d >= 17 && d <= 25 && m == Month.February) - || (y == 2008 && d >= 6 && d <= 12 && m == Month.February) - || (y == 2009 && d >= 26 && d <= 30 && m == Month.January) - || (y == 2010 && d >= 15 && d <= 19 && m == Month.January) - || (y == 2011 && d >= 2 && d <= 8 && m == Month.February) - || (y == 2012 && d >= 23 && d <= 28 && m == Month.January) - || (y == 2013 && d >= 11 && d <= 15 && m == Month.February) - // Ching Ming Festival - || (y <= 2008 && d == 4 && m == Month.April) - || (y == 2009 && d == 6 && m == Month.April) - || (y == 2010 && d == 5 && m == Month.April) - || (y == 2011 && d >= 3 && d <= 5 && m == Month.April) - || (y == 2012 && d >= 2 && d <= 4 && m == Month.April) - || (y == 2013 && d >= 4 && d <= 5 && m == Month.April) - // Labor Day - || (y <= 2007 && d >= 1 && d <= 7 && m == Month.May) - || (y == 2008 && d >= 1 && d <= 2 && m == Month.May) - || (y == 2009 && d == 1 && m == Month.May) - || (y == 2010 && d == 3 && m == Month.May) - || (y == 2011 && d == 2 && m == Month.May) - || (y == 2012 && ((d == 30 && m == Month.April) || (d == 1 && m == Month.May))) - || (y == 2013 && ((d >= 29 && m == Month.April) || (d == 1 && m == Month.May))) - // Tuen Ng Festival - || (y <= 2008 && d == 9 && m == Month.June) - || (y == 2009 && (d == 28 || d == 29) && m == Month.May) - || (y == 2010 && d >= 14 && d <= 16 && m == Month.June) - || (y == 2011 && d >= 4 && d <= 6 && m == Month.June) - || (y == 2012 && d >= 22 && d <= 24 && m == Month.June) - || (y == 2013 && d >= 10 && d <= 12 && m == Month.June) - // Mid-Autumn Festival - || (y <= 2008 && d == 15 && m == Month.September) - || (y == 2010 && d >= 22 && d <= 24 && m == Month.September) - || (y == 2011 && d >= 10 && d <= 12 && m == Month.September) - || (y == 2012 && d == 30 && m == Month.September) - || (y == 2013 && d >= 19 && d <= 20 && m == Month.September) - // National Day - || (y <= 2007 && d >= 1 && d <= 7 && m == Month.October) - || (y == 2008 && ((d >= 29 && m == Month.September) || - (d <= 3 && m == Month.October))) - || (y == 2009 && d >= 1 && d <= 8 && m == Month.October) - || (y == 2010 && d >= 1 && d <= 7 && m == Month.October) - || (y == 2011 && d >= 1 && d <= 7 && m == Month.October) - || (y == 2012 && d >= 1 && d <= 7 && m == Month.October) - || (y == 2013 && d >= 1 && d <= 7 && m == Month.October) - ) - return false; - return true; - } - } - } -} - +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + Copyright (C) 2008 Alessandro Duci + Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace QLNet +{ + //! Chinese calendar + /*! Holidays: +
    +
  • Saturdays
  • +
  • Sundays
  • +
  • New Year's day, January 1st (possibly followed by one or + two more holidays)
  • +
  • Labour Day, first week in May
  • +
  • National Day, one week from October 1st
  • +
+ + Other holidays for which no rule is given (data available for + 2004-2015 only): +
    +
  • Chinese New Year
  • +
  • Ching Ming Festival
  • +
  • Tuen Ng Festival
  • +
  • Mid-Autumn Festival
  • +
+ + SSE data from + IB data from + + \ingroup calendars + */ + public class China : Calendar + { + public enum Market + { + SSE, //!< Shanghai stock exchange + IB //!< Interbank calendar + }; + + public China( Market market = Market.SSE ) + { + + // all calendar instances on the same market share the same implementation instance + switch ( market ) + { + case Market.SSE: + calendar_ = SseImpl.Singleton; + break; + case Market.IB: + calendar_ = IbImpl.Singleton; + break; + default: + Utils.QL_FAIL( "unknown market" ); + break; + } + } + + private class SseImpl : Calendar + { + public static readonly SseImpl Singleton = new SseImpl(); + private SseImpl() { } + public override string name() { return "Shanghai stock exchange"; } + + public override bool isWeekend( DayOfWeek w ) + { + return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; + } + + public override bool isBusinessDay( Date date ) + { + DayOfWeek w = date.DayOfWeek; + int d = date.Day; + Month m = (Month)date.Month; + int y = date.Year; + + if ( isWeekend( w ) + // New Year's Day + || ( d == 1 && m == Month.January ) + || ( y == 2005 && d == 3 && m == Month.January ) + || ( y == 2006 && ( d == 2 || d == 3 ) && m == Month.January ) + || ( y == 2007 && d <= 3 && m == Month.January ) + || ( y == 2007 && d == 31 && m == Month.December ) + || ( y == 2009 && d == 2 && m == Month.January ) + || ( y == 2011 && d == 3 && m == Month.January ) + || ( y == 2012 && ( d == 2 || d == 3 ) && m == Month.January ) + || ( y == 2013 && d <= 3 && m == Month.January ) + || ( y == 2014 && d == 1 && m == Month.January ) + || ( y == 2015 && d <= 3 && m == Month.January ) + // Chinese New Year + || ( y == 2004 && d >= 19 && d <= 28 && m == Month.January ) + || ( y == 2005 && d >= 7 && d <= 15 && m == Month.February ) + || ( y == 2006 && ( ( d >= 26 && m == Month.January ) || + ( d <= 3 && m == Month.February ) ) ) + || ( y == 2007 && d >= 17 && d <= 25 && m == Month.February ) + || ( y == 2008 && d >= 6 && d <= 12 && m == Month.February ) + || ( y == 2009 && d >= 26 && d <= 30 && m == Month.January ) + || ( y == 2010 && d >= 15 && d <= 19 && m == Month.January ) + || ( y == 2011 && d >= 2 && d <= 8 && m == Month.February ) + || ( y == 2012 && d >= 23 && d <= 28 && m == Month.January ) + || ( y == 2013 && d >= 11 && d <= 15 && m == Month.February ) + || ( y == 2014 && d >= 31 && m == Month.January ) + || ( y == 2014 && d <= 6 && m == Month.February ) + || ( y == 2015 && d >= 18 && d <= 24 && m == Month.February ) + // Ching Ming Festival + || ( y <= 2008 && d == 4 && m == Month.April ) + || ( y == 2009 && d == 6 && m == Month.April ) + || ( y == 2010 && d == 5 && m == Month.April ) + || ( y == 2011 && d >= 3 && d <= 5 && m == Month.April ) + || ( y == 2012 && d >= 2 && d <= 4 && m == Month.April ) + || ( y == 2013 && d >= 4 && d <= 5 && m == Month.April ) + || ( y == 2014 && d == 7 && m == Month.April ) + || ( y == 2015 && d >= 5 && d <= 6 && m == Month.April ) + // Labor Day + || ( y <= 2007 && d >= 1 && d <= 7 && m == Month.May ) + || ( y == 2008 && d >= 1 && d <= 2 && m == Month.May ) + || ( y == 2009 && d == 1 && m == Month.May ) + || ( y == 2010 && d == 3 && m == Month.May ) + || ( y == 2011 && d == 2 && m == Month.May ) + || ( y == 2012 && ( ( d == 30 && m == Month.April ) || + ( d == 1 && m == Month.May ) ) ) + || ( y == 2013 && ( ( d >= 29 && m == Month.April ) || + ( d == 1 && m == Month.May ) ) ) + || ( y == 2014 && d >= 1 && d <= 3 && m == Month.May ) + || ( y == 2015 && d == 1 && m == Month.May ) + // Tuen Ng Festival + || ( y <= 2008 && d == 9 && m == Month.June ) + || ( y == 2009 && ( d == 28 || d == 29 ) && m == Month.May ) + || ( y == 2010 && d >= 14 && d <= 16 && m == Month.June ) + || ( y == 2011 && d >= 4 && d <= 6 && m == Month.June ) + || ( y == 2012 && d >= 22 && d <= 24 && m == Month.June ) + || ( y == 2013 && d >= 10 && d <= 12 && m == Month.June ) + || ( y == 2014 && d == 2 && m == Month.June ) + || ( y == 2015 && d == 22 && m == Month.June ) + // Mid-Autumn Festival + || ( y <= 2008 && d == 15 && m == Month.September ) + || ( y == 2010 && d >= 22 && d <= 24 && m == Month.September ) + || ( y == 2011 && d >= 10 && d <= 12 && m == Month.September ) + || ( y == 2012 && d == 30 && m == Month.September ) + || ( y == 2013 && d >= 19 && d <= 20 && m == Month.September ) + || ( y == 2014 && d == 8 && m == Month.September ) + || ( y == 2015 && d == 27 && m == Month.September ) + // National Day + || ( y <= 2007 && d >= 1 && d <= 7 && m == Month.October ) + || ( y == 2008 && ( ( d >= 29 && m == Month.September ) || + ( d <= 3 && m == Month.October ) ) ) + || ( y == 2009 && d >= 1 && d <= 8 && m == Month.October ) + || ( y == 2010 && d >= 1 && d <= 7 && m == Month.October ) + || ( y == 2011 && d >= 1 && d <= 7 && m == Month.October ) + || ( y == 2012 && d >= 1 && d <= 7 && m == Month.October ) + || ( y == 2013 && d >= 1 && d <= 7 && m == Month.October ) + || ( y == 2014 && d >= 1 && d <= 7 && m == Month.October ) + || ( y == 2015 && d >= 1 && d <= 7 && m == Month.October ) + ) + return false; + return true; + + } + } + + private class IbImpl : Calendar + { + public static readonly IbImpl Singleton = new IbImpl(); + + public IbImpl() + { + sseImpl = new China( Market.SSE ); + } + + public override string name() { return "China inter bank market"; } + + public override bool isWeekend( DayOfWeek w ) { return w == DayOfWeek.Saturday || w == DayOfWeek.Sunday; } + public override bool isBusinessDay( Date date ) + { + + List working_weekends = new List{ + // 2005 + new Date(5, Month.February, 2005), + new Date(6, Month.February, 2005), + new Date(30, Month.April, 2005), + new Date(8, Month.May, 2005), + new Date(8, Month.October, 2005), + new Date(9, Month.October, 2005), + new Date(31, Month.December, 2005), + //2006 + new Date(28, Month.January, 2006), + new Date(29, Month.April, 2006), + new Date(30, Month.April, 2006), + new Date(30, Month.September, 2006), + new Date(30, Month.December, 2006), + new Date(31, Month.December, 2006), + // 2007 + new Date(17, Month.February, 2007), + new Date(25, Month.February, 2007), + new Date(28, Month.April, 2007), + new Date(29, Month.April, 2007), + new Date(29, Month.September, 2007), + new Date(30, Month.September, 2007), + new Date(29, Month.December, 2007), + // 2008 + new Date(2, Month.February, 2008), + new Date(3, Month.February, 2008), + new Date(4, Month.May, 2008), + new Date(27, Month.September, 2008), + new Date(28, Month.September, 2008), + // 2009 + new Date(4, Month.January, 2009), + new Date(24, Month.January, 2009), + new Date(1, Month.February, 2009), + new Date(31, Month.May, 2009), + new Date(27, Month.September, 2009), + new Date(10, Month.October, 2009), + // 2010 + new Date(20, Month.February, 2010), + new Date(21, Month.February, 2010), + new Date(12, Month.June, 2010), + new Date(13, Month.June, 2010), + new Date(19, Month.September, 2010), + new Date(25, Month.September, 2010), + new Date(26, Month.September, 2010), + new Date(9, Month.October, 2010), + // 2011 + new Date(30, Month.January, 2011), + new Date(12, Month.February, 2011), + new Date(2, Month.April, 2011), + new Date(8, Month.October, 2011), + new Date(9, Month.October, 2011), + new Date(31, Month.December, 2011), + // 2012 + new Date(21, Month.January, 2012), + new Date(29, Month.January, 2012), + new Date(31, Month.March, 2012), + new Date(1, Month.April, 2012), + new Date(28, Month.April, 2012), + new Date(29, Month.September, 2012), + // 2013 + new Date(5,Month.January,2013), + new Date(6,Month.January,2013), + new Date(16,Month.February,2013), + new Date(17,Month.February,2013), + new Date(7,Month.April,2013), + new Date(27,Month.April,2013), + new Date(28,Month.April,2013), + new Date(8,Month.June,2013), + new Date(9,Month.June,2013), + new Date(22,Month.September,2013), + new Date(29,Month.September,2013), + new Date(12,Month.October,2013), + // 2014 + new Date(26,Month.January,2014), + new Date(8,Month.February,2014), + new Date(4,Month.May,2014), + new Date(28,Month.September,2014), + new Date(11,Month.October,2014), + // 2015 + new Date(4,Month.January,2015), + new Date(15,Month.February,2015), + new Date(28,Month.February,2015), + new Date(10,Month.October,2015) + }; + + // If it is already a SSE business day, it must be a IB business day + return sseImpl.isBusinessDay( date ) || working_weekends.Contains( date ); + + } + + private Calendar sseImpl; + + }; + + } +} + diff --git a/QLNet/Time/Calendars/czechrepublic.cs b/QLNet/Time/Calendars/czechrepublic.cs index 344527095..85712ea6b 100644 --- a/QLNet/Time/Calendars/czechrepublic.cs +++ b/QLNet/Time/Calendars/czechrepublic.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/denmark.cs b/QLNet/Time/Calendars/denmark.cs index ac901daf8..648474627 100644 --- a/QLNet/Time/Calendars/denmark.cs +++ b/QLNet/Time/Calendars/denmark.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/finland.cs b/QLNet/Time/Calendars/finland.cs index 34bf8e31a..0e3df41d4 100644 --- a/QLNet/Time/Calendars/finland.cs +++ b/QLNet/Time/Calendars/finland.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/germany.cs b/QLNet/Time/Calendars/germany.cs index b678cd09f..8c74f653a 100644 --- a/QLNet/Time/Calendars/germany.cs +++ b/QLNet/Time/Calendars/germany.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/hongkong.cs b/QLNet/Time/Calendars/hongkong.cs index 62860bf96..c2b677b4a 100644 --- a/QLNet/Time/Calendars/hongkong.cs +++ b/QLNet/Time/Calendars/hongkong.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -249,7 +249,39 @@ public override bool isBusinessDay(Date date) { // Chung Yeung festival || (d == 14 && m == Month.October)) return false; - } + } + + if ( y == 2014 ) + { + if (// Lunar New Year + ( ( d == 31 && m == Month.January ) || ( d <= 3 && m == Month.February ) ) + // Buddha's birthday + || ( d == 6 && m == Month.May ) + // Tuen Ng festival + || ( d == 2 && m == Month.June ) + // Mid-autumn festival + || ( d == 9 && m == Month.September ) + // Chung Yeung festival + || ( d == 2 && m == Month.October ) ) + return false; + } + + if ( y == 2015 ) + { + if (// Lunar New Year + ( ( d == 19 && m == Month.February ) || ( d == 20 && m == Month.February ) ) + // The day following Easter Monday + || ( d == 7 && m == Month.April ) + // Buddha's birthday + || ( d == 25 && m == Month.May ) + // Tuen Ng festival + || ( d == 20 && m == Month.June ) + // Mid-autumn festival + || ( d == 28 && m == Month.September ) + // Chung Yeung festival + || ( d == 21 && m == Month.October ) ) + return false; + } return true; } } diff --git a/QLNet/Time/Calendars/hungary.cs b/QLNet/Time/Calendars/hungary.cs index 8a466940b..13be63b9a 100644 --- a/QLNet/Time/Calendars/hungary.cs +++ b/QLNet/Time/Calendars/hungary.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/iceland.cs b/QLNet/Time/Calendars/iceland.cs index 9fc6aed67..e7cbbf2fd 100644 --- a/QLNet/Time/Calendars/iceland.cs +++ b/QLNet/Time/Calendars/iceland.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/india.cs b/QLNet/Time/Calendars/india.cs index 42ef7d6a9..0e14d03a8 100644 --- a/QLNet/Time/Calendars/india.cs +++ b/QLNet/Time/Calendars/india.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -279,27 +279,54 @@ public override bool isBusinessDay(Date date) { || (d == 28 && m == Month.November) ) return false; + } + + if ( y == 2013 ) + { + if (// Holi + ( d == 27 && m == Month.March ) + // Ram Navmi + || ( d == 19 && m == Month.April ) + // Mahavir Jayanti + || ( d == 24 && m == Month.April ) + // Ramzan Id + || ( d == 9 && m == Month.August ) + // Ganesh Chaturthi + || ( d == 9 && m == Month.September ) + // Bakri Id + || ( d == 16 && m == Month.October ) + // Diwali - Balipratipada + || ( d == 4 && m == Month.November ) + // Moharram + || ( d == 14 && m == Month.November ) + ) + return false; } - if (y == 2013) { - if (// Holi - (d == 27 && m == Month.March) - // Ram Navmi - || (d == 19 && m == Month.April) - // Mahavir Jayanti - || (d == 24 && m == Month.April) - // Ramzan Id - || (d == 9 && m == Month.August) - // Ganesh Chaturthi - || (d == 9 && m == Month.September) - // Bakri Id - || (d == 16 && m == Month.October) - // Diwali - Balipratipada - || (d == 4 && m == Month.November) - // Moharram - || (d == 14 && m == Month.November) - ) - return false; + if ( y == 2014 ) + { + if (// Mahashivratri + ( d == 27 && m == Month.February ) + // Holi + || ( d == 17 && m == Month.March ) + // Ram Navmi + || ( d == 8 && m == Month.April ) + // Ramzan Id + || ( d == 29 && m == Month.July ) + // Ganesh Chaturthi + || ( d == 29 && m == Month.August ) + // Dasera + || ( d == 3 && m == Month.October ) + // Bakri Id + || ( d == 6 && m == Month.October ) + // Diwali - Balipratipada + || ( d == 24 && m == Month.October ) + // Moharram + || ( d == 4 && m == Month.November ) + // Gurunank Jayanti + || ( d == 6 && m == Month.November ) + ) + return false; } return true; } diff --git a/QLNet/Time/Calendars/indonesia.cs b/QLNet/Time/Calendars/indonesia.cs index 2e46e0853..a3c77b7f1 100644 --- a/QLNet/Time/Calendars/indonesia.cs +++ b/QLNet/Time/Calendars/indonesia.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -295,7 +295,20 @@ public override bool isBusinessDay(Date date) { || (d == 31 && m == Month.December) ) return false; - } + } + if (y == 2014) { + if (// Lunar New Year + ( ( d == 31 && m == Month.January ) || ( d <= 3 && m == Month.February ) ) + // Buddha's birthday + || ( d == 6 && m == Month.May ) + // Tuen Ng festival + || ( d == 2 && m == Month.June ) + // Mid-autumn festival + || ( d == 9 && m == Month.September ) + // Chung Yeung festival + || ( d == 2 && m == Month.October ) ) + return false; + } return true; } } diff --git a/QLNet/Time/Calendars/italy.cs b/QLNet/Time/Calendars/italy.cs index 3737ce11c..13fd75484 100644 --- a/QLNet/Time/Calendars/italy.cs +++ b/QLNet/Time/Calendars/italy.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/japan.cs b/QLNet/Time/Calendars/japan.cs index 02fdbb82d..99b1f9082 100644 --- a/QLNet/Time/Calendars/japan.cs +++ b/QLNet/Time/Calendars/japan.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/mexico.cs b/QLNet/Time/Calendars/mexico.cs index 15b5e06d9..71baec981 100644 --- a/QLNet/Time/Calendars/mexico.cs +++ b/QLNet/Time/Calendars/mexico.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/newzealand.cs b/QLNet/Time/Calendars/newzealand.cs index 307d033c4..145e2bb72 100644 --- a/QLNet/Time/Calendars/newzealand.cs +++ b/QLNet/Time/Calendars/newzealand.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/norway.cs b/QLNet/Time/Calendars/norway.cs index 806bf4809..e3ff19fe1 100644 --- a/QLNet/Time/Calendars/norway.cs +++ b/QLNet/Time/Calendars/norway.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/nullcalendar.cs b/QLNet/Time/Calendars/nullcalendar.cs index 6d0da1768..98d0b8bf3 100644 --- a/QLNet/Time/Calendars/nullcalendar.cs +++ b/QLNet/Time/Calendars/nullcalendar.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/poland.cs b/QLNet/Time/Calendars/poland.cs index 0365afb55..ce859d88f 100644 --- a/QLNet/Time/Calendars/poland.cs +++ b/QLNet/Time/Calendars/poland.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/saudiarabia.cs b/QLNet/Time/Calendars/saudiarabia.cs index b4971750b..8a429a206 100644 --- a/QLNet/Time/Calendars/saudiarabia.cs +++ b/QLNet/Time/Calendars/saudiarabia.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010, 2011 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/singapore.cs b/QLNet/Time/Calendars/singapore.cs index 02e808da3..31e7fba94 100644 --- a/QLNet/Time/Calendars/singapore.cs +++ b/QLNet/Time/Calendars/singapore.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -86,7 +86,9 @@ public override bool isBusinessDay(Date date) { || ((d == 26 || d == 27) && m == Month.January && y == 2009) || ((d == 15 || d == 16) && m == Month.January && y == 2010) || ((d == 23 || d == 24) && m == Month.January && y == 2012) - || ((d == 11 || d == 12) && m == Month.February && y == 2013) + || ((d == 11 || d == 12) && m == Month.February && y == 2013) + || ( d == 31 && m == Month.January && y == 2014 ) + || ( d == 1 && m == Month.February && y == 2014 ) // Hari Raya Haji || ((d == 1 || d == 2) && m == Month.February && y == 2004) @@ -98,7 +100,8 @@ public override bool isBusinessDay(Date date) { || (d == 27 && m == Month.November && y == 2009) || (d == 17 && m == Month.November && y == 2010) || (d == 26 && m == Month.October && y == 2012) - || (d == 15 && m == Month.October && y == 2013) + || (d == 15 && m == Month.October && y == 2013) + || ( d == 6 && m == Month.October && y == 2014 ) // Vesak Poya Day || (d == 2 && m == Month.June && y == 2004) @@ -109,7 +112,8 @@ public override bool isBusinessDay(Date date) { || (d == 9 && m == Month.May && y == 2009) || (d == 28 && m == Month.May && y == 2010) || (d == 5 && m == Month.May && y == 2012) - || (d == 24 && m == Month.May && y == 2013) + || (d == 24 && m == Month.May && y == 2013) + || ( d == 13 && m == Month.May && y == 2014 ) // Deepavali || (d == 11 && m == Month.November && y == 2004) @@ -118,7 +122,8 @@ public override bool isBusinessDay(Date date) { || (d == 16 && m == Month.November && y == 2009) || (d == 5 && m == Month.November && y == 2010) || (d == 13 && m == Month.November && y == 2012) - || (d == 2 && m == Month.November && y == 2013) + || (d == 2 && m == Month.November && y == 2013) + || ( d == 23 && m == Month.October && y == 2014 ) // Diwali || (d == 1 && m == Month.November && y == 2005) @@ -132,7 +137,8 @@ public override bool isBusinessDay(Date date) { || (d == 21 && m == Month.September && y == 2009) || (d == 10 && m == Month.September && y == 2010) || (d == 20 && m == Month.August && y == 2012) - || (d == 8 && m == Month.August && y == 2013) + || (d == 8 && m == Month.August && y == 2013) + || ( d == 28 && m == Month.July && y == 2014 ) ) return false; return true; diff --git a/QLNet/Time/Calendars/slovakia.cs b/QLNet/Time/Calendars/slovakia.cs index e65331077..89976ea5b 100644 --- a/QLNet/Time/Calendars/slovakia.cs +++ b/QLNet/Time/Calendars/slovakia.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/southafrica.cs b/QLNet/Time/Calendars/southafrica.cs index 279f19688..bdcd34bc2 100644 --- a/QLNet/Time/Calendars/southafrica.cs +++ b/QLNet/Time/Calendars/southafrica.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/southkorea.cs b/QLNet/Time/Calendars/southkorea.cs index d697dfa0c..8eca1a911 100644 --- a/QLNet/Time/Calendars/southkorea.cs +++ b/QLNet/Time/Calendars/southkorea.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -132,6 +132,7 @@ public override bool isBusinessDay(Date date) { || ((d == 2 || d == 3 || d == 4) && m == Month.February && y == 2011) || ((d == 23 || d == 24) && m == Month.January && y == 2012) || (d == 11 && m == Month.February && y == 2013) + || ( ( d == 30 || d == 31 ) && m == Month.January && y == 2014 ) // Election Days || (d == 15 && m == Month.April && y == 2004) // National Assembly || (d == 31 && m == Month.May && y == 2006) // Regional election @@ -140,10 +141,11 @@ public override bool isBusinessDay(Date date) { || (d == 2 && m == Month.June && y == 2010) // Local election || (d == 11 && m == Month.April && y == 2012) // National Assembly || (d == 19 && m == Month.December && y == 2012) // Presidency + || ( d == 4 && m == Month.June && y == 2014 ) // Local election // Buddha's birthday || (d == 26 && m == Month.May && y == 2004) - || (d == 15 && m == Month.May && y == 2005) - || (d == 5 && m == Month.May && y == 2006) + || (d == 15 && m == Month.May && y == 2005) + // || (d == 5 && m == Month.May && y == 2006) dead code , 5 May always holiday ( Children's Day) || (d == 24 && m == Month.May && y == 2007) || (d == 12 && m == Month.May && y == 2008) || (d == 2 && m == Month.May && y == 2009) @@ -151,6 +153,7 @@ public override bool isBusinessDay(Date date) { || (d == 10 && m == Month.May && y == 2011) || (d == 28 && m == Month.May && y == 2012) || (d == 17 && m == Month.May && y == 2013) + || ( d == 6 && m == Month.May && y == 2014 ) // Harvest Moon Day || ((d == 27 || d == 28 || d == 29) && m == Month.September && y == 2004) || ((d == 17 || d == 18 || d == 19) && m == Month.September && y == 2005) @@ -162,8 +165,10 @@ public override bool isBusinessDay(Date date) { || ((d == 12 || d == 13) && m == Month.September && y == 2011) || (d == 1 && m == Month.October && y == 2012) || ((d == 18 || d == 19 || d == 20) && m == Month.September && y == 2013) + || ( ( d == 8 || d == 9 || d == 10 ) && m == Month.September && y == 2014 ) // Hangul Proclamation of Korea - || (d == 9 && m == Month.October && y == 2013) + || (d == 9 && m == Month.October && y == 2013) + || ( d == 9 && m == Month.October && y == 2014 ) ) return false; diff --git a/QLNet/Time/Calendars/sweden.cs b/QLNet/Time/Calendars/sweden.cs index 9a7f8b9f4..39d3bc611 100644 --- a/QLNet/Time/Calendars/sweden.cs +++ b/QLNet/Time/Calendars/sweden.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/switzerland.cs b/QLNet/Time/Calendars/switzerland.cs index 1b6cd34cc..82dbdad6a 100644 --- a/QLNet/Time/Calendars/switzerland.cs +++ b/QLNet/Time/Calendars/switzerland.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Calendars/taiwan.cs b/QLNet/Time/Calendars/taiwan.cs index 67c5663f4..9ae6a584b 100644 --- a/QLNet/Time/Calendars/taiwan.cs +++ b/QLNet/Time/Calendars/taiwan.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008, 2009 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -245,6 +245,26 @@ public override bool isBusinessDay(Date date) { || (d >= 19 && d <= 20 && m == Month.September) ) return false; + } + + if ( y == 2014 ) + { + if (// Lunar New Year + ( d >= 28 && d <= 30 && m == Month.January ) + // Spring Festival + || ( ( d == 31 && m == Month.January ) || ( d <= 4 && m == Month.February ) ) + // Children's Day + || ( d == 4 && m == Month.April ) + // Tomb Sweeping Day + || ( d == 5 && m == Month.April ) + // Labour Day + || ( d == 1 && m == Month.May ) + // Dragon Boat Festival + || ( d == 2 && m == Month.June ) + // Mid-Autumn Festival + || ( d == 8 && m == Month.September ) + ) + return false; } return true; diff --git a/QLNet/Time/Calendars/turkey.cs b/QLNet/Time/Calendars/turkey.cs index fc0c164ea..70a3b618e 100644 --- a/QLNet/Time/Calendars/turkey.cs +++ b/QLNet/Time/Calendars/turkey.cs @@ -3,7 +3,7 @@ Copyright (C) 2008 Alessandro Duci Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -148,6 +148,16 @@ public override bool isBusinessDay(Date date) { || (m == Month.October && d == 28)) return false; } + else if ( y == 2014 ) + { + // Ramadan + if ( ( m == Month.July && d >= 27 && d <= 30 ) + // Kurban + || ( m == Month.October && d >= 4 && d <= 7 ) + // additional holiday for Republic Day + || ( m == Month.October && d == 29 ) ) + return false; + } return true; } }; diff --git a/QLNet/Time/Date.cs b/QLNet/Time/Date.cs index d54af7a54..c4d6c4849 100644 --- a/QLNet/Time/Date.cs +++ b/QLNet/Time/Date.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008 Toyin Akin (toyin_akin@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -125,8 +125,8 @@ public static Date advance(Date d, int n, TimeUnit u) { public string ToLongDateString() { return date.ToLongDateString(); } public string ToShortDateString() { return date.ToShortDateString(); } public override string ToString() { return this.ToShortDateString(); } - public string ToString(IFormatProvider provider) { return date.ToString(provider); } - public string ToString(string format) { return date.ToString(format); } + public string ToString(IFormatProvider provider) { return date.ToString(provider); } + public string ToString(string format) { return date.ToString(format); } public string ToString(string format, IFormatProvider provider) { return date.ToString(format, provider); } public override bool Equals(object o) { return (this == (Date)o); } public override int GetHashCode() { return 0; } diff --git a/QLNet/Time/DayCounter.cs b/QLNet/Time/DayCounter.cs index fde8f6617..1640bf2f6 100644 --- a/QLNet/Time/DayCounter.cs +++ b/QLNet/Time/DayCounter.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/DayCounters/Actual360.cs b/QLNet/Time/DayCounters/Actual360.cs index 51687ed69..297561c97 100644 --- a/QLNet/Time/DayCounters/Actual360.cs +++ b/QLNet/Time/DayCounters/Actual360.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/DayCounters/Actual365Fixed.cs b/QLNet/Time/DayCounters/Actual365Fixed.cs index 1a26cac44..2726a8562 100644 --- a/QLNet/Time/DayCounters/Actual365Fixed.cs +++ b/QLNet/Time/DayCounters/Actual365Fixed.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/DayCounters/Actual365NoLeap.cs b/QLNet/Time/DayCounters/Actual365NoLeap.cs index 6f2666113..05935025b 100644 --- a/QLNet/Time/DayCounters/Actual365NoLeap.cs +++ b/QLNet/Time/DayCounters/Actual365NoLeap.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -15,14 +15,14 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace QLNet -{ +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ //! Actual/365 (No Leap) day count convention /*! "Actual/365 (No Leap)" day count convention, also known as "Act/365 (NL)", "NL/365", or "Actual/365 (JGB)". @@ -35,7 +35,7 @@ public Actual365NoLeap() : base(Impl.Singleton) { } class Impl : DayCounter { - public static readonly Impl Singleton = new Impl(); + public static readonly Impl Singleton = new Impl(); private static int[] MonthOffset = { 0, 31, 59, 90, 120, 151, // Jan - Jun 181, 212, 243, 273, 304, 334 // Jun - Dec }; @@ -68,4 +68,4 @@ public override double yearFraction(Date d1, Date d2, Date refPeriodStart, Date } } } -} +} diff --git a/QLNet/Time/DayCounters/ActualActual.cs b/QLNet/Time/DayCounters/ActualActual.cs index 3942791ea..e330721ce 100644 --- a/QLNet/Time/DayCounters/ActualActual.cs +++ b/QLNet/Time/DayCounters/ActualActual.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/DayCounters/Business252.cs b/QLNet/Time/DayCounters/Business252.cs index de1cdc706..30ccee8ee 100644 Binary files a/QLNet/Time/DayCounters/Business252.cs and b/QLNet/Time/DayCounters/Business252.cs differ diff --git a/QLNet/Time/DayCounters/OneDayCounter.cs b/QLNet/Time/DayCounters/OneDayCounter.cs index 2839604ca..955efe0fe 100644 --- a/QLNet/Time/DayCounters/OneDayCounter.cs +++ b/QLNet/Time/DayCounters/OneDayCounter.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/DayCounters/SimpleDayCounter.cs b/QLNet/Time/DayCounters/SimpleDayCounter.cs index 971af784f..34dc002bd 100644 --- a/QLNet/Time/DayCounters/SimpleDayCounter.cs +++ b/QLNet/Time/DayCounters/SimpleDayCounter.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/DayCounters/Thirty360.cs b/QLNet/Time/DayCounters/Thirty360.cs index 787c0d67a..55389bbbf 100644 --- a/QLNet/Time/DayCounters/Thirty360.cs +++ b/QLNet/Time/DayCounters/Thirty360.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/ECB.cs b/QLNet/Time/ECB.cs new file mode 100644 index 000000000..87e291578 --- /dev/null +++ b/QLNet/Time/ECB.cs @@ -0,0 +1,296 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QLNet +{ + //! European Central Bank reserve maintenance dates + public struct ECB + { + static List knownDateSet = new List(); + public static List knownDates() + { + // one-off inizialization + int[] knownDatesArray = + { + 38371, 38391, 38420, 38455, 38483, 38511, 38546, 38574, 38602, 38637, 38665, 38692 // 2005 + , 38735, 38756, 38784, 38819, 38847, 38883, 38910, 38938, 38966, 39001, 39029, 39064 // 2006 + , 39099, 39127, 39155, 39190, 39217, 39246, 39274, 39302, 39337, 39365, 39400, 39428 // 2007 + , 39463, 39491, 39519, 39554, 39582, 39610, 39638, 39673, 39701, 39729, 39764, 39792 // 2008 + , 39834, 39855, 39883, 39911, 39946, 39974, 40002, 40037, 40065, 40100, 40128, 40155 // 2009 + , 40198, 40219, 40247, 40282, 40310, 40345, 40373, 40401, 40429, 40464, 40492, 40520 // 2010 + , 40562, 40583, 40611, 40646, 40674, 40709, 40737, 40765, 40800, 40828, 40856, 40891 // 2011 + // http://www.ecb.europa.eu/press/pr/date/2011/html/pr110520.en.html + , 40926, 40954, 40982, 41010, 41038, 41073, 41101, 41129, 41164, 41192, 41227, 41255 // 2012 + , 41290, 41318, 41346, 41374, 41402, 41437, 41465, 41493, 41528, 41556, 41591, 41619 // 2013 + // http://www.ecb.europa.eu/press/pr/date/2013/html/pr130610.en.html + , 41654, 41682, 41710, 41738, 41773, 41801, 41829, 41864, 41892, 41920, 41955, 41983 // 2014 + // http://www.ecb.europa.eu/press/pr/date/2014/html/pr140717_1.en.html + , 42032, 42074, 42116, 42165, 42207, 42256, 42305, 42347// 2015 + , 42395, 42445 //2016 + + }; + + if (knownDateSet.empty()) + { + for ( int i = 0; i < knownDatesArray.Count(); ++i ) + { + knownDateSet.Add(new Date(knownDatesArray[i])); + } + } + + return knownDateSet; + + } + + public static void addDate( Date d ) + { + knownDates(); // just to ensure inizialization + knownDateSet.Add( d ); + knownDateSet.Sort(); + } + + public static void removeDate( Date d ) + { + knownDates(); // just to ensure inizialization + knownDateSet.Remove( d ); + } + + //! maintenance period start date in the given month/year + public static Date date( Month m, int y ) { return nextDate( new Date( 1, m, y ) - 1 ); } + + /*! returns the ECB date for the given ECB code + (e.g. March xxth, 2013 for MAR10). + + \warning It raises an exception if the input + string is not an ECB code + */ + public static Date date( string ecbCode, Date refDate = null ) + { + Utils.QL_REQUIRE(isECBcode(ecbCode),() => ecbCode + " is not a valid ECB code"); + + string code = ecbCode.ToUpper(); + string monthString = code.Substring(0, 3); + Month m = Month.Jan; + if (monthString=="JAN") m = Month.January; + else if (monthString=="FEB") m = Month.February; + else if (monthString=="MAR") m = Month.March; + else if (monthString=="APR") m = Month.April; + else if (monthString=="MAY") m = Month.May; + else if (monthString=="JUN") m = Month.June; + else if (monthString=="JUL") m = Month.July; + else if (monthString=="AUG") m = Month.August; + else if (monthString=="SEP") m = Month.September; + else if (monthString=="OCT") m = Month.October; + else if (monthString=="NOV") m = Month.November; + else if (monthString=="DEC") m = Month.December; + else Utils.QL_FAIL("not an ECB month (and it should have been)"); + + // lexical_cast causes compilation errors with x64 + //Year y = boost::lexical_cast(code.substr(3, 2)); + + int y = int.Parse(code.Substring(3, 2)); + Date referenceDate = (refDate != null ? + refDate : + new Date(Settings.evaluationDate())); + int referenceYear = (referenceDate.year() % 100); + y += referenceDate.year() - referenceYear; + if (y ecbDate + " is not a valid ECB date"); + + string ECBcode = string.Empty; + int y = ecbDate.year() % 100; + string padding = string.Empty; + if (y < 10) + padding = "0"; + switch(ecbDate.month()) { + case (int)Month.January: + ECBcode += "JAN" + padding + y; + break; + case (int)Month.February: + ECBcode += "FEB" + padding + y; + break; + case (int)Month.March: + ECBcode += "MAR" + padding + y; + break; + case (int)Month.April: + ECBcode += "APR" + padding + y; + break; + case (int)Month.May: + ECBcode += "MAY" + padding + y; + break; + case (int)Month.June: + ECBcode += "JUN" + padding + y; + break; + case (int)Month.July: + ECBcode += "JUL" + padding + y; + break; + case (int)Month.August: + ECBcode += "AUG" + padding + y; + break; + case (int)Month.September: + ECBcode += "SEP" + padding + y; + break; + case (int)Month.October: + ECBcode += "OCT" + padding + y; + break; + case (int)Month.November: + ECBcode += "NOV" + padding + y; + break; + case (int)Month.December: + ECBcode += "DEC" + padding + y; + break; + default: + Utils.QL_FAIL("not an ECB month (and it should have been)"); + break; + } + + #if(QL_EXTRA_SAFETY_CHECKS) + QL_ENSURE(isECBcode(ECBcode.str()), + "the result " << ECBcode.str() << + " is an invalid ECB code"); + #endif + return ECBcode; + } + + //! next maintenance period start date following the given date + public static Date nextDate( Date date = null ) + { + Date d = (date == null ? + Settings.evaluationDate() : + date); + + int i = knownDates().FindIndex( x => x > d ); + + Utils.QL_REQUIRE(i!=-1,() => + "ECB dates after " + knownDates().Last() + " are unknown"); + return knownDates()[i]; + } + + //! next maintenance period start date following the given ECB code + public static Date nextDate( string ecbCode, Date referenceDate = null ) + { + return nextDate(date(ecbCode, referenceDate)); + } + + //! next maintenance period start dates following the given date + public static List nextDates( Date date = null ) + { + Date d = (date == null ? + Settings.evaluationDate() : + date); + + int i = knownDates(). FindIndex(x => x > d ); + + Utils.QL_REQUIRE(i != -1 ,() => + "ECB dates after " + knownDates().Last() + " are unknown"); + + return new List(knownDates().GetRange(i, knownDates().Count - i )); + } + + //! next maintenance period start dates following the given code + public static List nextDates( string ecbCode, Date referenceDate = null ) + { + return nextDates(date(ecbCode, referenceDate)); + } + + /*! returns whether or not the given date is + a maintenance period start date */ + public static bool isECBdate( Date d ) + { + Date date = nextDate(d-1); + return d==date; + } + + //! returns whether or not the given string is an ECB code + public static bool isECBcode( String ecbCode ) + { + if (ecbCode.Length != 5) + return false; + + String code = ecbCode.ToUpper(); + + String str1 = "0123456789"; + if ( !str1.Contains(code.Substring(3, 1))) + return false; + if (!str1.Contains(code.Substring(4, 1))) + return false; + + string monthString = code.Substring(0, 3); + if (monthString=="JAN") return true; + else if (monthString=="FEB") return true; + else if (monthString=="MAR") return true; + else if (monthString=="APR") return true; + else if (monthString=="MAY") return true; + else if (monthString=="JUN") return true; + else if (monthString=="JUL") return true; + else if (monthString=="AUG") return true; + else if (monthString=="SEP") return true; + else if (monthString=="OCT") return true; + else if (monthString=="NOV") return true; + else if (monthString=="DEC") return true; + else return false; + } + + //! next ECB code following the given date + static string nextCode(Date d = null) { + return code(nextDate(d)); + } + + //! next ECB code following the given code + public static string nextCode( String ecbCode ) + { + Utils.QL_REQUIRE(isECBcode(ecbCode),() => + ecbCode + " is not a valid ECB code"); + + String code = ecbCode.ToUpper(); + String result = String.Empty; + + string monthString = code.Substring(0, 3); + if (monthString=="JAN") result += "FEB" + code.Substring(3, 2); + else if (monthString=="FEB") result += "MAR" + code.Substring(3, 2); + else if (monthString=="MAR") result += "APR" + code.Substring(3, 2); + else if (monthString=="APR") result += "MAY" + code.Substring(3, 2); + else if (monthString=="MAY") result += "JUN" + code.Substring(3, 2); + else if (monthString=="JUN") result += "JUL" + code.Substring(3, 2); + else if (monthString=="JUL") result += "AUG" + code.Substring(3, 2); + else if (monthString=="AUG") result += "SEP" + code.Substring(3, 2); + else if (monthString=="SEP") result += "OCT" + code.Substring(3, 2); + else if (monthString=="OCT") result += "NOV" + code.Substring(3, 2); + else if (monthString=="NOV") result += "DEC" + code.Substring(3, 2); + else if (monthString=="DEC") { + // lexical_cast causes compilation errors with x64 + //Year y = boost::lexical_cast(code.substr(3, 2)); + int y = (int.Parse(code.Substring(3, 2)) + 1) % 100; + String padding = String.Empty; + if (y < 10) + padding = "0"; + + result += "JAN" + padding + y; + } else Utils.QL_FAIL("not an ECB month (and it should have been)"); + + + #if QL_EXTRA_SAFETY_CHECKS + QL_ENSURE(isECBcode(result.str()), + "the result " << result.str() << + " is an invalid ECB code"); + #endif + return result; + } + + }; +} diff --git a/QLNet/Time/Imm.cs b/QLNet/Time/Imm.cs index 738e1dd1a..17f704d5a 100644 --- a/QLNet/Time/Imm.cs +++ b/QLNet/Time/Imm.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Period.cs b/QLNet/Time/Period.cs index 2da621132..795608c13 100644 --- a/QLNet/Time/Period.cs +++ b/QLNet/Time/Period.cs @@ -2,7 +2,7 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/Time/Schedule.cs b/QLNet/Time/Schedule.cs index 5d57303cd..407995267 100644 --- a/QLNet/Time/Schedule.cs +++ b/QLNet/Time/Schedule.cs @@ -1,18 +1,19 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ + Copyright (C) 2015 Francois Botha (igitur@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is + copy of the license along with this program; if not, license is available online at . - + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -24,20 +25,20 @@ under the terms of the QLNet license. You should have received a namespace QLNet { //! Payment schedule - public class Schedule + public class Schedule { #region Properties - private bool fullInterface_; private Period tenor_; private Calendar calendar_; - private BusinessDayConvention convention_, terminationDateConvention_; - private DateGeneration.Rule rule_; - private bool endOfMonth_; + private BusinessDayConvention convention_; + private BusinessDayConvention? terminationDateConvention_; + private DateGeneration.Rule? rule_; + private bool? endOfMonth_; private Date firstDate_, nextToLastDate_; private List dates_ = new List(); - private List isRegular_ = new List(); + private IList isRegular_ = new List(); #endregion @@ -45,91 +46,106 @@ public class Schedule public Schedule() { } - public Schedule(List dates, Calendar calendar = null, BusinessDayConvention convention = BusinessDayConvention.Unadjusted) + public Schedule(List dates, Calendar calendar = null, BusinessDayConvention convention = BusinessDayConvention.Unadjusted, + BusinessDayConvention? terminationDateConvention = null, Period tenor = null, DateGeneration.Rule? rule = null, + bool? endOfMonth = null, IList isRegular = null) { if (calendar == null) calendar_ = new NullCalendar(); else calendar_ = calendar; - fullInterface_ = false; - tenor_ = new Period(); + tenor_ = tenor; convention_ = convention; - terminationDateConvention_ = convention; - rule_ = DateGeneration.Rule.Forward; - endOfMonth_ = false; + terminationDateConvention_ = terminationDateConvention; + rule_ = rule; + endOfMonth_ = (tenor != null && tenor < new Period(1, TimeUnit.Months)) ? false : endOfMonth; dates_ = dates; + + if (isRegular == null) + isRegular_ = new List(); + else + isRegular_ = isRegular; + + Utils.QL_REQUIRE( + isRegular_.Count == 0 || isRegular_.Count() == dates.Count() - 1, + () => string.Format("isRegular size ({0}) must be zero or equal to the number of dates minus 1 ({1})", isRegular_.Count, dates.Count - 1)); } - public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calendar calendar, - BusinessDayConvention convention, BusinessDayConvention terminationDateConvention, - DateGeneration.Rule rule, bool endOfMonth, Date firstDate = null, Date nextToLastDate = null) + public Schedule(Date effectiveDate, Date terminationDate, Period tenor, Calendar calendar, + BusinessDayConvention convention, BusinessDayConvention terminationDateConvention, + DateGeneration.Rule rule, bool endOfMonth, Date firstDate = null, Date nextToLastDate = null) { // first save the properties - fullInterface_ = true; - tenor_ = tenor; - if ( calendar == null ) - calendar_ = new NullCalendar(); - else - calendar_ = calendar; + tenor_ = tenor; + if ( calendar == null ) + calendar_ = new NullCalendar(); + else + calendar_ = calendar; convention_ = convention; terminationDateConvention_ = terminationDateConvention; rule_ = rule; - endOfMonth_ = endOfMonth; + endOfMonth_ = (tenor != null && tenor < new Period(1, TimeUnit.Months)) ? false : endOfMonth; if ( firstDate == effectiveDate ) firstDate_ = null; else firstDate_ = firstDate; - + if ( nextToLastDate == terminationDate ) nextToLastDate_ = null; else nextToLastDate_ = nextToLastDate; - // sanity checks + // sanity checks Utils.QL_REQUIRE( terminationDate != null, () => "null termination date" ); - + // in many cases (e.g. non-expired bonds) the effective date is not // really necessary. In these cases a decent placeholder is enough - if ( effectiveDate == null && firstDate == null && rule== DateGeneration.Rule.Backward) + if ( effectiveDate == null && firstDate == null && rule== DateGeneration.Rule.Backward) { - Date evalDate = Settings.evaluationDate(); + Date evalDate = Settings.evaluationDate(); Utils.QL_REQUIRE( evalDate < terminationDate, () => "null effective date" ); int y; - if (nextToLastDate != null) + if (nextToLastDate != null) { y = (nextToLastDate - evalDate)/366 + 1; effectiveDate = nextToLastDate - new Period(y,TimeUnit.Years); - } - else + } + else { y = (terminationDate - evalDate)/366 + 1; effectiveDate = terminationDate - new Period(y,TimeUnit.Years); } - } - else - Utils.QL_REQUIRE( effectiveDate != null, () => "null effective date" ); + } + else + Utils.QL_REQUIRE( effectiveDate != null, () => "null effective date" ); + + Utils.QL_REQUIRE(effectiveDate < terminationDate, () => + "effective date (" + effectiveDate + + ") later than or equal to termination date (" + + terminationDate + ")" + ); if (tenor_.length() == 0) rule_ = DateGeneration.Rule.Zero; - else + else Utils.QL_REQUIRE( tenor.length() > 0, () => "non positive tenor (" + tenor + ") not allowed" ); if (firstDate_ != null) { - switch (rule_) + switch (rule_.Value) { case DateGeneration.Rule.Backward: case DateGeneration.Rule.Forward: - Utils.QL_REQUIRE(firstDate_ > effectiveDate && + Utils.QL_REQUIRE(firstDate_ > effectiveDate && firstDate_ < terminationDate, () => "first date (" + firstDate_ + ") out of effective-termination date range [" + effectiveDate + ", " + terminationDate + ")"); // we should ensure that the above condition is still verified after adjustment break; - case DateGeneration.Rule.ThirdWednesday: + case DateGeneration.Rule.ThirdWednesday: Utils.QL_REQUIRE( IMM.isIMMdate( firstDate_, false ), () => "first date (" + firstDate_ + ") is not an IMM date" ); break; case DateGeneration.Rule.Zero: @@ -137,38 +153,38 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda case DateGeneration.Rule.TwentiethIMM: case DateGeneration.Rule.OldCDS: case DateGeneration.Rule.CDS: - Utils.QL_FAIL("first date incompatible with " + rule_ + " date generation rule"); + Utils.QL_FAIL("first date incompatible with " + rule_.Value + " date generation rule"); break; default: - Utils.QL_FAIL("unknown rule (" + rule_ + ")"); + Utils.QL_FAIL("unknown rule (" + rule_.Value + ")"); break; } } if (nextToLastDate_ != null) { - switch (rule_) + switch (rule_.Value) { case DateGeneration.Rule.Backward: - case DateGeneration.Rule.Forward: + case DateGeneration.Rule.Forward: Utils.QL_REQUIRE( nextToLastDate_ > effectiveDate && nextToLastDate_ < terminationDate, () => "next to last date (" + nextToLastDate_ + ") out of effective-termination date range (" + effectiveDate + ", " + terminationDate + "]"); // we should ensure that the above condition is still verified after adjustment break; - case DateGeneration.Rule.ThirdWednesday: + case DateGeneration.Rule.ThirdWednesday: Utils.QL_REQUIRE( IMM.isIMMdate( nextToLastDate_, false ), () => "next-to-last date (" + nextToLastDate_ + - ") is not an IMM date"); + ") is not an IMM date"); break; case DateGeneration.Rule.Zero: case DateGeneration.Rule.Twentieth: case DateGeneration.Rule.TwentiethIMM: case DateGeneration.Rule.OldCDS: case DateGeneration.Rule.CDS: - Utils.QL_FAIL("next to last date incompatible with " + rule_ + " date generation rule"); + Utils.QL_FAIL("next to last date incompatible with " + rule_.Value + " date generation rule"); break; default: - Utils.QL_FAIL("unknown rule (" + rule_ + ")"); + Utils.QL_FAIL("unknown rule (" + rule_.Value + ")"); break; } } @@ -176,8 +192,8 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda // calendar needed for endOfMonth adjustment Calendar nullCalendar = new NullCalendar(); int periods = 1; - Date seed = new Date() , exitDate; - switch (rule_) + Date seed = new Date() , exitDate = new Date(); + switch (rule_.Value) { case DateGeneration.Rule.Zero: tenor_ = new Period(0, TimeUnit.Years); @@ -193,7 +209,7 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda if (nextToLastDate_ != null) { dates_.Insert(0, nextToLastDate_); - Date temp = nullCalendar.advance(seed, -periods * tenor_, convention_, endOfMonth_); + Date temp = nullCalendar.advance(seed, -periods * tenor_, convention_, endOfMonth_.Value); if (temp != nextToLastDate_) isRegular_.Insert(0, false); else @@ -206,7 +222,7 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda while (true) { - Date temp = nullCalendar.advance(seed, -periods * tenor_, convention_, endOfMonth_); + Date temp = nullCalendar.advance(seed, -periods * tenor_, convention_, endOfMonth_.Value); if (temp < exitDate) { if (firstDate_ != null && (calendar_.adjust(dates_.First(), convention_) != @@ -242,12 +258,12 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda case DateGeneration.Rule.TwentiethIMM: case DateGeneration.Rule.ThirdWednesday: case DateGeneration.Rule.OldCDS: - case DateGeneration.Rule.CDS: - Utils.QL_REQUIRE( !endOfMonth, () => "endOfMonth convention incompatible with " + rule_ + " date generation rule" ); + case DateGeneration.Rule.CDS: + Utils.QL_REQUIRE( !endOfMonth, () => "endOfMonth convention incompatible with " + rule_.Value + " date generation rule" ); goto case DateGeneration.Rule.Forward; // fall through case DateGeneration.Rule.Forward: - if (rule_ == DateGeneration.Rule.CDS) + if (rule_.Value == DateGeneration.Rule.CDS) { dates_.Add(previousTwentieth(effectiveDate, DateGeneration.Rule.CDS)); } @@ -260,19 +276,19 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda if (firstDate_ != null) { dates_.Add(firstDate_); - Date temp = nullCalendar.advance(seed, periods * tenor_, convention_, endOfMonth_); + Date temp = nullCalendar.advance(seed, periods * tenor_, convention_, endOfMonth_.Value); if (temp != firstDate_) isRegular_.Add(false); else isRegular_.Add(true); seed = firstDate_; } - else if (rule_ == DateGeneration.Rule.Twentieth || - rule_ == DateGeneration.Rule.TwentiethIMM || - rule_ == DateGeneration.Rule.OldCDS || - rule_ == DateGeneration.Rule.CDS) + else if (rule_.Value == DateGeneration.Rule.Twentieth || + rule_.Value == DateGeneration.Rule.TwentiethIMM || + rule_.Value == DateGeneration.Rule.OldCDS || + rule_.Value == DateGeneration.Rule.CDS) { - Date next20th = nextTwentieth(effectiveDate, rule_); + Date next20th = nextTwentieth(effectiveDate, rule_.Value); if (rule_ == DateGeneration.Rule.OldCDS) { // distance rule inforced in natural days @@ -280,7 +296,7 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda if (next20th - effectiveDate < stubDays) { // +1 will skip this one and get the next - next20th = nextTwentieth(next20th + 1, rule_); + next20th = nextTwentieth(next20th + 1, rule_.Value); } } if (next20th != effectiveDate) @@ -296,7 +312,7 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda exitDate = nextToLastDate_; while (true) { - Date temp = nullCalendar.advance(seed, periods * tenor_, convention_, endOfMonth_); + Date temp = nullCalendar.advance(seed, periods * tenor_, convention_, endOfMonth_.Value); if (temp > exitDate) { if (nextToLastDate_ != null && @@ -320,15 +336,15 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda } } - if (calendar_.adjust(dates_.Last(), terminationDateConvention_) != - calendar_.adjust(terminationDate, terminationDateConvention_)) + if (calendar_.adjust(dates_.Last(), terminationDateConvention_.Value) != + calendar_.adjust(terminationDate, terminationDateConvention_.Value)) { - if (rule_ == DateGeneration.Rule.Twentieth || - rule_ == DateGeneration.Rule.TwentiethIMM || - rule_ == DateGeneration.Rule.OldCDS || - rule_ == DateGeneration.Rule.CDS) + if (rule_.Value == DateGeneration.Rule.Twentieth || + rule_.Value == DateGeneration.Rule.TwentiethIMM || + rule_.Value == DateGeneration.Rule.OldCDS || + rule_.Value == DateGeneration.Rule.CDS) { - dates_.Add(nextTwentieth(terminationDate, rule_)); + dates_.Add(nextTwentieth(terminationDate, rule_.Value)); isRegular_.Add(true); } else @@ -340,7 +356,7 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda break; default: - Utils.QL_FAIL("unknown rule (" + rule_ + ")"); + Utils.QL_FAIL("unknown rule (" + rule_.Value + ")"); break; } @@ -354,16 +370,28 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda // adjust to end of month if (convention_ == BusinessDayConvention.Unadjusted) { - for (int i = 0; i < dates_.Count-1; ++i) + for (int i = 1; i < dates_.Count-1; ++i) dates_[i] = Date.endOfMonth(dates_[i]); } else { - for (int i = 0; i < dates_.Count-1; ++i) + for (int i = 1; i < dates_.Count-1; ++i) dates_[i] = calendar_.endOfMonth(dates_[i]); } - if (terminationDateConvention_ != BusinessDayConvention.Unadjusted) - dates_[dates_.Count - 1] = calendar_.endOfMonth(dates_.Last()); + if (terminationDateConvention_ != BusinessDayConvention.Unadjusted) + { + dates_[0] = calendar_.endOfMonth(dates_.First()); + dates_[dates_.Count - 1] = calendar_.endOfMonth(dates_.Last()); + } + else + { + // the termination date is the first if going backwards, + // the last otherwise. + if (rule_ == DateGeneration.Rule.Backward) + dates_[dates_.Count - 1] = Date.endOfMonth(dates_.Last()); + else + dates_[0] = Date.endOfMonth(dates_.First()); + } } else { @@ -375,24 +403,43 @@ public Schedule( Date effectiveDate, Date terminationDate, Period tenor, Calenda // termination date is NOT adjusted as per ISDA specifications, unless otherwise specified in the // confirmation of the deal or unless we're creating a CDS schedule - if (terminationDateConvention_ != BusinessDayConvention.Unadjusted - || rule_ == DateGeneration.Rule.Twentieth - || rule_ == DateGeneration.Rule.TwentiethIMM - || rule_ == DateGeneration.Rule.OldCDS - || rule_ == DateGeneration.Rule.CDS) - dates_[dates_.Count - 1] = calendar_.adjust(dates_.Last(), terminationDateConvention_); + if (terminationDateConvention_.Value != BusinessDayConvention.Unadjusted + || rule_.Value == DateGeneration.Rule.Twentieth + || rule_.Value == DateGeneration.Rule.TwentiethIMM + || rule_.Value == DateGeneration.Rule.OldCDS + || rule_.Value == DateGeneration.Rule.CDS) + dates_[dates_.Count - 1] = calendar_.adjust(dates_.Last(), terminationDateConvention_.Value); } - // final safety check to remove duplicated last dates, if any + // final safety checks to remove duplicated last dates, if any // it can happen if EOM is applied to two near dates if (dates_.Count >= 2 && dates_[dates_.Count - 2] >= dates_.Last()) { isRegular_[dates_.Count() - 2] = (dates_[dates_.Count() - 2] == dates_.Last()); dates_[dates_.Count() - 2] = dates_.Last(); - + dates_.RemoveAt(dates_.Count - 1); isRegular_.RemoveAt(isRegular_.Count - 1); - } + } + + if (dates_.Count >= 2 && dates_[1] <= dates_.First()) + { + isRegular_[1] = (dates_[1] == dates_.First()); + dates_[1] = dates_.First(); + dates_.RemoveAt(0); + isRegular_.RemoveAt(0); + } + + Utils.QL_REQUIRE(dates_.Count > 1, + () => "degenerate single date (" + dates_[0] + ") schedule" + + "\n seed date: " + seed + + "\n exit date: " + exitDate + + "\n effective date: " + effectiveDate + + "\n first date: " + firstDate + + "\n next to last date: " + nextToLastDate + + "\n termination date: " + terminationDate + + "\n generation rule: " + rule_.Value + + "\n end of month: " + endOfMonth_.Value); } #endregion @@ -428,11 +475,17 @@ public Date nextDate(Date d) } public List dates() { return dates_; } public bool isRegular(int i) - { - Utils.QL_REQUIRE( fullInterface_, () => "full interface not available" ); + { + Utils.QL_REQUIRE(isRegular_.Count() > 0, () => "full interface (isRegular) not available"); Utils.QL_REQUIRE( i <= isRegular_.Count() && i > 0, () => "index (" + i + ") must be in [1, " + isRegular_.Count() + "]" ); return isRegular_[i - 1]; } + + public IList isRegular() + { + Utils.QL_REQUIRE(isRegular_.Count() > 0, () => "full interface (isRegular) not available"); + return isRegular_; + } //@} //! \name Other inspectors @@ -440,20 +493,34 @@ public bool isRegular(int i) public bool empty() { return dates_.Count == 0; } public Calendar calendar() { return calendar_; } public Date startDate() { return dates_.First(); } - public Date endDate() { return dates_.Last(); } - public Period tenor() { Utils.QL_REQUIRE( fullInterface_, () => "full interface not available" ); return tenor_; } - public BusinessDayConvention businessDayConvention() { return convention_; } - public BusinessDayConvention terminationDateBusinessDayConvention() { Utils.QL_REQUIRE( fullInterface_, () => "full interface not available" ); return terminationDateConvention_; } - public DateGeneration.Rule rule() { Utils.QL_REQUIRE( fullInterface_, () => "full interface not available" ); return rule_; } - public bool endOfMonth() { Utils.QL_REQUIRE( fullInterface_, () => "full interface not available" ); return endOfMonth_; } + public Date endDate() { return dates_.Last(); } + public Period tenor() { + Utils.QL_REQUIRE( tenor_ != null, () => "full interface (tenor) not available" ); + return tenor_; + } + public BusinessDayConvention businessDayConvention() { + return convention_; + } + public BusinessDayConvention terminationDateBusinessDayConvention() { + Utils.QL_REQUIRE(terminationDateConvention_.HasValue, () => "full interface (termination date business day convention) not available" ); + return terminationDateConvention_.Value; + } + public DateGeneration.Rule rule() { + Utils.QL_REQUIRE( rule_.HasValue, () => "full interface (rule) not available" ); + return rule_.Value; + } + public bool endOfMonth() { + Utils.QL_REQUIRE( endOfMonth_.HasValue, () => "full interface (end of month) not available" ); + return endOfMonth_.Value; + } //@} //@{ //! truncated schedule public Schedule until(Date truncationDate) { - Schedule result = (Schedule)this.MemberwiseClone(); - + Schedule result = (Schedule)this.MemberwiseClone(); + Utils.QL_REQUIRE( truncationDate > result.dates_[0], () => "truncation date " + truncationDate + " must be later than schedule first date " + @@ -529,7 +596,7 @@ Date previousTwentieth(Date d, DateGeneration.Rule rule) public int Count { get { return dates_.Count; } } - } + } //! helper class /*! This class provides a more comfortable interface to the argument list of Schedule's constructor. */ @@ -550,31 +617,31 @@ public MakeSchedule from(Date effectiveDate) return this; } - public MakeSchedule to(Date terminationDate) + public MakeSchedule to(Date terminationDate) { terminationDate_ = terminationDate; return this; } - public MakeSchedule withTenor(Period tenor) + public MakeSchedule withTenor(Period tenor) { tenor_ = tenor; return this; } - public MakeSchedule withFrequency(Frequency frequency) + public MakeSchedule withFrequency(Frequency frequency) { tenor_ = new Period(frequency); return this; } - public MakeSchedule withCalendar(Calendar calendar) + public MakeSchedule withCalendar(Calendar calendar) { calendar_ = calendar; return this; } - public MakeSchedule withConvention(BusinessDayConvention conv) + public MakeSchedule withConvention(BusinessDayConvention conv) { convention_ = conv; return this; @@ -635,7 +702,7 @@ public MakeSchedule withNextToLastDate(Date d) // firstDate_ = nextToLastDate_ = null; //} - public Schedule value() + public Schedule value() { // check for mandatory arguments @@ -646,14 +713,14 @@ public Schedule value() if ((object)tenor_ == null) throw new ApplicationException("tenor/frequency not provided"); - // if no calendar was set... - if (calendar_ == null) - { - // ...we use a null one. - calendar_ = new NullCalendar(); + // if no calendar was set... + if (calendar_ == null) + { + // ...we use a null one. + calendar_ = new NullCalendar(); } - // set dynamic defaults: + // set dynamic defaults: BusinessDayConvention convention; // if a convention was set, we use it. if (convention_ != null ) @@ -691,4 +758,4 @@ public Schedule value() rule_, endOfMonth_, firstDate_, nextToLastDate_); } } -} \ No newline at end of file +} diff --git a/QLNet/Types.cs b/QLNet/Types.cs index 5ad263170..66ab02271 100644 --- a/QLNet/Types.cs +++ b/QLNet/Types.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -26,9 +26,11 @@ public interface IValue { } public struct Const { - public const double QL_Epsilon = 2.2204460492503131e-016; - - public const double M_SQRT_2 = 0.7071067811865475244008443621048490392848359376887; + public const double QL_EPSILON = 2.2204460492503131e-016; + + public const double M_SQRT2 = 1.41421356237309504880; + public const double M_SQRT_2 = 0.7071067811865475244008443621048490392848359376887; + public const double M_SQRTPI = 1.77245385090551602792981; public const double M_1_SQRTPI = 0.564189583547756286948; public const double M_LN2 = 0.693147180559945309417; @@ -101,7 +103,13 @@ the given holiday unless it belongs to a different month, in which case choose the first business day after the holiday. */ - Unadjusted /*!< Do not adjust. */ + Unadjusted, /*!< Do not adjust. */ + HalfMonthModifiedFollowing /*!< Choose the first business day after + the given holiday unless that day + crosses the mid-month (15th) or the + end of month, in which case choose + the first business day before the + holiday. */ }; //! Units used to describe time periods diff --git a/QLNet/Utils.cs b/QLNet/Utils.cs index 6c2284458..0ea798eb9 100644 --- a/QLNet/Utils.cs +++ b/QLNet/Utils.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -75,23 +75,23 @@ public static double Pow(double x, int y) { } } - public static void QL_REQUIRE( bool condition, Func message ) - { - if ( !condition ) - throw new ApplicationException( message.Invoke() ); + public static void QL_REQUIRE( bool condition, Func message ) + { + if ( !condition ) + throw new ApplicationException( message.Invoke() ); } public static void QL_FAIL(string message) { throw new ApplicationException(message); - } - - public static bool is_QL_NEGATIVE_RATES() - { - #if QL_NEGATIVE_RATES - return true; - #else - return false; - #endif + } + + public static bool is_QL_NEGATIVE_RATES() + { + #if QL_NEGATIVE_RATES + return true; + #else + return false; + #endif } } diff --git a/QLNet/discretizedasset.cs b/QLNet/discretizedasset.cs index 6478c5cc4..30b32a422 100644 --- a/QLNet/discretizedasset.cs +++ b/QLNet/discretizedasset.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/grid.cs b/QLNet/grid.cs index da827de4c..0b68c1cdc 100644 --- a/QLNet/grid.cs +++ b/QLNet/grid.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/legacy/libormarketmodels/lfmcovarparam.cs b/QLNet/legacy/libormarketmodels/lfmcovarparam.cs index c21744e52..13dfa2d79 100644 --- a/QLNet/legacy/libormarketmodels/lfmcovarparam.cs +++ b/QLNet/legacy/libormarketmodels/lfmcovarparam.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -69,22 +69,14 @@ public virtual Matrix covariance(double t, Vector x) { return result; } - public virtual Matrix integratedCovariance(double t){ - return integratedCovariance(t, null); - } - public virtual Matrix integratedCovariance(double t, Vector x) { + public virtual Matrix integratedCovariance(double t, Vector x = null) { // this implementation is not intended for production. // because it is too slow and too inefficient. // This method is useful for testing and R&D. // Please overload the method within derived classes. - //QL_REQUIRE(x.empty(), "can not handle given x here"); - try { - if (!(x.empty())) - throw new ApplicationException("can not handle given x here"); - } - catch { } //x is empty or null + Utils.QL_REQUIRE(x == null ,()=> "can not handle given x here"); Matrix tmp= new Matrix(size_, size_,0.0); diff --git a/QLNet/legacy/libormarketmodels/lfmcovarproxy.cs b/QLNet/legacy/libormarketmodels/lfmcovarproxy.cs index 04673b5ca..71653e1f1 100644 --- a/QLNet/legacy/libormarketmodels/lfmcovarproxy.cs +++ b/QLNet/legacy/libormarketmodels/lfmcovarproxy.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/legacy/libormarketmodels/lfmhullwhiteparam.cs b/QLNet/legacy/libormarketmodels/lfmhullwhiteparam.cs index 596affc04..00dbc2a8b 100644 --- a/QLNet/legacy/libormarketmodels/lfmhullwhiteparam.cs +++ b/QLNet/legacy/libormarketmodels/lfmhullwhiteparam.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -127,11 +127,8 @@ public override Matrix covariance(double t, Vector x) { return tmp; } - public override Matrix integratedCovariance(double t){ - return integratedCovariance(t, null); - } - public override Matrix integratedCovariance(double t, Vector x) { + public override Matrix integratedCovariance(double t, Vector x = null) { Matrix tmp=new Matrix(size_, size_, 0.0); int last = fixingTimes_.BinarySearch(t); if (last < 0) diff --git a/QLNet/legacy/libormarketmodels/lfmprocess.cs b/QLNet/legacy/libormarketmodels/lfmprocess.cs index a3d0272db..308061dc2 100644 --- a/QLNet/legacy/libormarketmodels/lfmprocess.cs +++ b/QLNet/legacy/libormarketmodels/lfmprocess.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/legacy/libormarketmodels/lfmswaptionengine.cs b/QLNet/legacy/libormarketmodels/lfmswaptionengine.cs index 29e56edef..6b4645fc0 100644 --- a/QLNet/legacy/libormarketmodels/lfmswaptionengine.cs +++ b/QLNet/legacy/libormarketmodels/lfmswaptionengine.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/QLNet/legacy/libormarketmodels/liborforwardmodel.cs b/QLNet/legacy/libormarketmodels/liborforwardmodel.cs index b34a1cdb5..1f77de6e9 100644 --- a/QLNet/legacy/libormarketmodels/liborforwardmodel.cs +++ b/QLNet/legacy/libormarketmodels/liborforwardmodel.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -97,8 +97,8 @@ List accrualEndTimes i = Math.Max(Math.Min(i, accrualStartTimes.Count - 1), 0); if (!(i. + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -180,7 +180,8 @@ The following values were replicated only up to the second digit new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.25, 3.3226) , new AmericanOptionData(Option.Type.Put, 100.00, 90.00, 0.10, 0.10, 0.50, 0.35, 14.6945) , new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.10, 0.10, 0.50, 0.35, 9.5104) , - new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 5.8823)}; + new AmericanOptionData(Option.Type.Put, 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 5.8823), + new AmericanOptionData(Option.Type.Put, 100.00, 100.00, 0.00, 0.00, 0.50, 0.15, 4.22949)}; Date today = Date.Today; DayCounter dc = new Actual360(); @@ -235,7 +236,18 @@ public void testBjerksundStenslandValues() { // from "Option pricing formulas", Haug, McGraw-Hill 1998, pag 27 new AmericanOptionData(Option.Type.Call, 40.00, 42.00, 0.08, 0.04, 0.75, 0.35, 5.2704), // from "Option pricing formulas", Haug, McGraw-Hill 1998, VBA code - new AmericanOptionData(Option.Type.Put, 40.00, 36.00, 0.00, 0.06, 1.00, 0.20, 4.4531) + new AmericanOptionData(Option.Type.Put, 40.00, 36.00, 0.00, 0.06, 1.00, 0.20, 4.4531), + // ATM option with very small volatility, reference value taken from R + new AmericanOptionData( Option.Type.Call, 100, 100, 0.05, 0.05, 1.0, 0.0021, 0.08032314 ), + // ATM option with very small volatility, + // reference value taken from Barone-Adesi and Whaley Approximation + new AmericanOptionData( Option.Type.Call, 100, 100, 0.05, 0.05, 1.0, 0.0001, 0.003860656 ), + new AmericanOptionData( Option.Type.Call, 100, 99.99, 0.05, 0.05, 1.0, 0.0001, 0.00081 ), + // ITM option with a very small volatility + new AmericanOptionData( Option.Type.Call, 100, 110, 0.05, 0.05, 1.0, 0.0001, 10.0 ), + new AmericanOptionData( Option.Type.Put, 110, 100, 0.05, 0.05, 1.0, 0.0001, 10.0 ), + // ATM option with a very large volatility + new AmericanOptionData( Option.Type.Put, 100, 110, 0.05, 0.05, 1.0, 10, 94.89543 ) }; Date today = Date.Today; @@ -249,7 +261,7 @@ public void testBjerksundStenslandValues() { SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); - double tolerance = 3.0e-3; + double tolerance = 5.0e-5; for (int i=0; i. + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_AssetSwap.cs b/Test/T_AssetSwap.cs index d579c925d..46da5fa28 100644 --- a/Test/T_AssetSwap.cs +++ b/Test/T_AssetSwap.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -3644,7 +3644,7 @@ public void testSpecializedBondVsGenericBondUsingAsw() zeroCpnSpecializedBondAssetSwap2.fairCleanPrice(); double error15 = Math.Abs(zeroCpnBondAssetSwapPrice2 -zeroCpnSpecializedBondAssetSwapPrice2); - if (error8>tolerance) { + if (error15>tolerance) { Assert.Fail("wrong clean price for zerocpn bond:" + "\n generic zero cpn bond's clean price: " + zeroCpnBondAssetSwapPrice2 diff --git a/Test/T_Bermudanswaption.cs b/Test/T_Bermudanswaption.cs index 9e3bf2e2c..86dced54e 100644 --- a/Test/T_Bermudanswaption.cs +++ b/Test/T_Bermudanswaption.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_BlackFormula.cs b/Test/T_BlackFormula.cs index 087307c85..f1625e0eb 100644 --- a/Test/T_BlackFormula.cs +++ b/Test/T_BlackFormula.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -15,20 +15,20 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using QLNet; - -namespace TestSuite -{ - [TestClass()] - public class T_BlackFormula - { - [TestMethod()] +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using QLNet; + +namespace TestSuite +{ + [TestClass()] + public class T_BlackFormula + { + [TestMethod()] public void testBachelierImpliedVol() { // Testing Bachelier implied vol... @@ -53,6 +53,6 @@ public void testBachelierImpliedVol() } } return; - } - } -} + } + } +} diff --git a/Test/T_Bonds.cs b/Test/T_Bonds.cs index 81da927c0..994d7aefe 100644 --- a/Test/T_Bonds.cs +++ b/Test/T_Bonds.cs @@ -1,18 +1,18 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is + copy of the license along with this program; if not, license is available online at . - + QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ The QuantLib license is available online at http://quantlib.org/license.shtml. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. @@ -696,7 +696,7 @@ public void testBrazilianCached() double faceAmount = 1000.0; double redemption = 100.0; - Date issueDate = new Date(1,Month.January,2007); + Date issueDate = new Date(1, Month.January, 2007); Date today = new Date(6, Month.June, 2007); Settings.setEvaluationDate(today); @@ -801,7 +801,7 @@ public void testAmortizingFixedBond() double[] notionals = {400000000,367573428,334984723,302233075,269317669,236237685,202992302,169580691,136002023, 102255461,68340166,34255295,0 }; - // test total cashflow count + // test total cashflow count Assert.AreEqual(bond.cashflows().Count, totCashflow, "Cashflow size different"); // test notional cashflow count @@ -817,9 +817,9 @@ public void testAmortizingFixedBond() double cash = bond.CASH(); Assert.AreEqual(cash - amount, PVDifference, 0.1, "PV Difference wrong"); - } - - + } + + [TestMethod()] public void testMBSFixedBondCached() { @@ -1051,7 +1051,7 @@ public void testAmortizingBond1() issueDate, maturirtyDate, tradeDate, paymentFrequency, dc, AmortizingMethod.EffectiveInterestRate); // Amortizing Yield ( Effective Rate ) - double y1 = bond.Yield() ; + double y1 = bond.Yield(); Assert.AreEqual(-0.0236402, y1, 0.001, "Amortizing Yield is different"); // Amortized Cost at Date @@ -1104,5 +1104,151 @@ public void testAmortizingBond2() } + [TestMethod()] + public void testAmortizingFixedRateBond() + { + // Testing amortizing fixed rate bond + + /* + * Following data is generated from Excel using function pmt with Nper = 360, PV = 100.0 + */ + + double[] rates = { 0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12 }; + double[] amounts = {0.277777778, 0.321639520, 0.369619473, 0.421604034, + 0.477415295, 0.536821623, 0.599550525, + 0.665302495, 0.733764574, 0.804622617, + 0.877571570, 0.952323396, 1.028612597}; + + Frequency freq = Frequency.Monthly; + + Date refDate = Date.Today; + + double tolerance = 1.0e-6; + + for (int i = 0; i < rates.Length; ++i) + { + AmortizingFixedRateBond myBond = new AmortizingFixedRateBond(0, + new NullCalendar(), 100.0, refDate, new Period(30, TimeUnit.Years), freq, rates[i], new ActualActual(ActualActual.Convention.ISMA)); + + List cashflows = myBond.cashflows(); + + List notionals = myBond.notionals(); + + for (int k = 0; k < cashflows.Count / 2; ++k) + { + double coupon = cashflows[2 * k].amount(); + double principal = cashflows[2 * k + 1].amount(); + double totalAmount = coupon + principal; + + // Check the amount is same as pmt returned + + double error = Math.Abs(totalAmount - amounts[i]); + if (error > tolerance) + { + Assert.Fail(" Rate: " + rates[i] + + " " + k + "th cash flow " + + " Failed!" + + " Expected Amount: " + amounts[i] + + " Calculated Amount: " + totalAmount); + } + + // Check the coupon result + double expectedCoupon = notionals[k] * rates[i] / (int)freq; + error = Math.Abs(coupon - expectedCoupon); + + if (error > tolerance) + { + Assert.Fail(" Rate: " + rates[i] + + " " + k + "th cash flow " + + " Failed!" + + " Expected Coupon: " + expectedCoupon + + " Calculated Coupon: " + coupon); + } + + } + } + } + + /// + /// Test calculation of South African R2048 bond + /// This requires the use of the Schedule to be constructed + /// with a custom date vector + /// + [TestMethod()] + public void testBondFromScheduleWithDateVector() + { + // Testing South African R2048 bond price using Schedule constructor with Date vector + SavedSettings backup = new SavedSettings(); + + //When pricing bond from Yield To Maturity, use NullCalendar() + Calendar calendar = new NullCalendar(); + + int settlementDays = 3; + + Date issueDate = new Date(29, Month.June, 2012); + Date today = new Date(7, Month.September, 2015); + Date evaluationDate = calendar.adjust(today); + Date settlementDate = calendar.advance(evaluationDate, new Period(settlementDays, TimeUnit.Days)); + Settings.setEvaluationDate(evaluationDate); + + // For the schedule to generate correctly for Feb-28's, make maturity date on Feb 29 + Date maturityDate = new Date(29, Month.February, 2048); + + double coupon = 0.0875; + Compounding comp = Compounding.Compounded; + Frequency freq = Frequency.Semiannual; + DayCounter dc = new ActualActual(ActualActual.Convention.Bond); + + // Yield as quoted in market + InterestRate yield = new InterestRate(0.09185, dc, comp, freq); + + Period tenor = new Period(6, TimeUnit.Months); + Period exCouponPeriod = new Period(10, TimeUnit.Days); + + // Generate coupon dates for 31 Aug and end of Feb each year + // For leap years, this will generate 29 Feb, but the bond + // actually pays coupons on 28 Feb, regardsless of whether + // it is a leap year or not. + Schedule schedule = new Schedule(issueDate, maturityDate, tenor, + new NullCalendar(), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, + DateGeneration.Rule.Backward, true); + + // Adjust the 29 Feb's to 28 Feb + List dates = new List(); + for (int i = 0; i < schedule.Count; ++i) + { + Date d = schedule.date(i); + if (d.Month == 2 && d.Day == 29) + dates.Add(new Date(28, Month.February, d.Year)); + else + dates.Add(d); + } + + schedule = new Schedule(dates, + schedule.calendar(), + schedule.businessDayConvention(), + schedule.terminationDateBusinessDayConvention(), + schedule.tenor(), + schedule.rule(), + schedule.endOfMonth(), + schedule.isRegular()); + + FixedRateBond bond = new FixedRateBond( + 0, + 100.0, + schedule, + new List() { coupon }, + dc, BusinessDayConvention.Following, 100.0, + issueDate, calendar, + exCouponPeriod, calendar, BusinessDayConvention.Unadjusted, false); + + double calculatedPrice = BondFunctions.dirtyPrice(bond, yield, settlementDate); + double expectedPrice = 95.75706; + double tolerance = 1e-5; + if (Math.Abs(calculatedPrice - expectedPrice) > tolerance) + { + Assert.Fail(string.Format("failed to reproduce R2048 dirty price\nexpected: {0}\ncalculated: {1}", expectedPrice, calculatedPrice)); + } + } } } diff --git a/Test/T_Calendars.cs b/Test/T_Calendars.cs index 64aa06322..c468a567c 100644 --- a/Test/T_Calendars.cs +++ b/Test/T_Calendars.cs @@ -2,12 +2,12 @@ Copyright (C) 2008 Andrea Maggiulli Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -249,11 +249,15 @@ public void testUSNewYorkStockExchange() { " calculated holidays"); List histClose = new List(); + histClose.Add(new Date(30, Month.October, 2012)); // Hurricane Sandy + histClose.Add(new Date(29, Month.October, 2012)); // Hurricane Sandy histClose.Add(new Date(11, Month.June, 2004)); // Reagan's funeral histClose.Add(new Date(14, Month.September, 2001));// September 11, 2001 histClose.Add(new Date(13, Month.September, 2001));// September 11, 2001 histClose.Add(new Date(12, Month.September, 2001));// September 11, 2001 histClose.Add(new Date(11, Month.September, 2001));// September 11, 2001 + histClose.Add(new Date(27, Month.April, 1994 ) ); // Nixon's funeral. + histClose.Add(new Date(27, Month.September,1985)); // Hurricane Gloria histClose.Add(new Date(14, Month.July, 1977)); // 1977 Blackout histClose.Add(new Date(25, Month.January, 1973)); // Johnson's funeral. histClose.Add(new Date(28, Month.December, 1972)); // Truman's funeral @@ -261,6 +265,13 @@ public void testUSNewYorkStockExchange() { histClose.Add(new Date(31, Month.March, 1969)); // Eisenhower's funeral histClose.Add(new Date(10, Month.February, 1969)); // heavy snow histClose.Add(new Date(5, Month.July, 1968)); // Day after Independence Day + histClose.Add( new Date( 9, Month.April, 1968 ) ); // Mourning for MLK + histClose.Add( new Date( 24, Month.December, 1965 ) ); // Christmas Eve + histClose.Add( new Date( 25, Month.November, 1963 ) ); // Kennedy's funeral + histClose.Add( new Date( 29, Month.May, 1961 ) ); // Day before Decoration Day + histClose.Add( new Date( 26, Month.December, 1958 ) ); // Day after Christmas + histClose.Add( new Date( 24, Month.December, 1956 ) ); // Christmas Eve + histClose.Add( new Date( 24, Month.December, 1954 ) ); // Christmas Eve // June 12-Dec. 31, 1968 // Four day week (closed on Wednesdays) - Paperwork Crisis histClose.Add(new Date(12, Month.Jun, 1968)); diff --git a/Test/T_CapFloor.cs b/Test/T_CapFloor.cs index 406993137..61eb2affc 100644 --- a/Test/T_CapFloor.cs +++ b/Test/T_CapFloor.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_CreditDefaultSwap.cs b/Test/T_CreditDefaultSwap.cs index 1abdc1ada..8877a0a31 100644 --- a/Test/T_CreditDefaultSwap.cs +++ b/Test/T_CreditDefaultSwap.cs @@ -1,20 +1,20 @@ -/* - Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; using System.Collections.Generic; @@ -29,239 +29,239 @@ namespace TestSuite public class T_CreditDefaultSwap { [TestMethod()] - public void testCachedValue() - { - // Testing credit-default swap against cached values... - - SavedSettings backup = new SavedSettings(); - - // Initialize curves - Settings.setEvaluationDate(new Date(9,Month.June,2006)); - Date today = Settings.evaluationDate(); - Calendar calendar = new TARGET(); - - Handle hazardRate = new Handle(new SimpleQuote(0.01234)); - RelinkableHandle probabilityCurve = new RelinkableHandle(); - probabilityCurve.linkTo(new FlatHazardRate(0, calendar, hazardRate, new Actual360())); - - RelinkableHandle discountCurve = new RelinkableHandle(); - - discountCurve.linkTo(new FlatForward(today,0.06,new Actual360())); - - // Build the schedule - Date issueDate = calendar.advance(today, -1, TimeUnit.Years); - Date maturity = calendar.advance(issueDate, 10, TimeUnit.Years); - Frequency frequency = Frequency.Semiannual; - BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing; - - Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar, - convention, convention, DateGeneration.Rule.Forward, false); - - // Build the CDS - double fixedRate = 0.0120; - DayCounter dayCount = new Actual360(); - double notional = 10000.0; - double recoveryRate = 0.4; - - CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate, - schedule, convention, dayCount, true, true); - cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve,recoveryRate,discountCurve)); - - double npv = 295.0153398; - double fairRate = 0.007517539081; - - double calculatedNpv = cds.NPV(); - double calculatedFairRate = cds.fairSpread(); - double tolerance = 1.0e-7; - - if (Math.Abs(calculatedNpv - npv) > tolerance) - Assert.Fail( - "Failed to reproduce NPV with mid-point engine\n" - + " calculated NPV: " + calculatedNpv + "\n" - + " expected NPV: " + npv); - - if (Math.Abs(calculatedFairRate - fairRate) > tolerance) - Assert.Fail( - "Failed to reproduce fair rate with mid-point engine\n" - + " calculated fair rate: " + calculatedFairRate + "\n" - + " expected fair rate: " + fairRate); - - cds.setPricingEngine(new IntegralCdsEngine(new Period(1,TimeUnit.Days),probabilityCurve, - recoveryRate,discountCurve)); - - calculatedNpv = cds.NPV(); - calculatedFairRate = cds.fairSpread(); - tolerance = 1.0e-5; - - if (Math.Abs(calculatedNpv - npv) > notional*tolerance*10) - Assert.Fail( - "Failed to reproduce NPV with integral engine " - + "(step = 1 day)\n" - + " calculated NPV: " + calculatedNpv + "\n" - + " expected NPV: " + npv); - - if (Math.Abs(calculatedFairRate - fairRate) > tolerance) - Assert.Fail( - "Failed to reproduce fair rate with integral engine " - + "(step = 1 day)\n" - + " calculated fair rate: " + calculatedFairRate + "\n" - + " expected fair rate: " + fairRate); - - cds.setPricingEngine(new IntegralCdsEngine(new Period(1,TimeUnit.Weeks),probabilityCurve,recoveryRate,discountCurve)); - - calculatedNpv = cds.NPV(); - calculatedFairRate = cds.fairSpread(); - tolerance = 1.0e-5; - - if (Math.Abs(calculatedNpv - npv) > notional*tolerance*10) - Assert.Fail( - "Failed to reproduce NPV with integral engine " - +"(step = 1 week)\n" - + " calculated NPV: " + calculatedNpv + "\n" - + " expected NPV: " + npv); - - if (Math.Abs(calculatedFairRate - fairRate) > tolerance) - Assert.Fail( - "Failed to reproduce fair rate with integral engine " - +"(step = 1 week)\n" - + " calculated fair rate: " + calculatedFairRate + "\n" - + " expected fair rate: " + fairRate); - } - - [TestMethod()] - public void testCachedMarketValue() - { - // Testing credit-default swap against cached market values... - - SavedSettings backup = new SavedSettings(); - - Settings.setEvaluationDate(new Date(9,Month.June,2006)); - Date evalDate = Settings.evaluationDate(); - Calendar calendar = new UnitedStates(); - - List discountDates = new List(); - discountDates.Add(evalDate); - discountDates.Add(calendar.advance(evalDate, 1, TimeUnit.Weeks, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 1, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 2, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 3, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 6, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate,12, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 2, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 3, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 4, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 5, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 6, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 7, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 8, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate, 9, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate,10, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - discountDates.Add(calendar.advance(evalDate,15, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - - List dfs = new List(); - dfs.Add(1.0); - dfs.Add(0.9990151375768731); - dfs.Add(0.99570502636871183); - dfs.Add(0.99118260474528685); - dfs.Add(0.98661167950906203); - dfs.Add(0.9732592953359388 ); - dfs.Add(0.94724424481038083); - dfs.Add(0.89844996737120875 ); - dfs.Add(0.85216647839921411 ); - dfs.Add(0.80775477692556874 ); - dfs.Add(0.76517289234200347 ); - dfs.Add(0.72401019553182933 ); - dfs.Add(0.68503909569219212 ); - dfs.Add(0.64797499814013748 ); - dfs.Add(0.61263171936255534 ); - dfs.Add(0.5791942350748791 ); - dfs.Add(0.43518868769953606 ); - - DayCounter curveDayCounter = new Actual360(); - + public void testCachedValue() + { + // Testing credit-default swap against cached values... + + SavedSettings backup = new SavedSettings(); + + // Initialize curves + Settings.setEvaluationDate(new Date(9,Month.June,2006)); + Date today = Settings.evaluationDate(); + Calendar calendar = new TARGET(); + + Handle hazardRate = new Handle(new SimpleQuote(0.01234)); + RelinkableHandle probabilityCurve = new RelinkableHandle(); + probabilityCurve.linkTo(new FlatHazardRate(0, calendar, hazardRate, new Actual360())); + RelinkableHandle discountCurve = new RelinkableHandle(); - discountCurve.linkTo( new InterpolatedDiscountCurve( discountDates, dfs, curveDayCounter,null,null,null,new LogLinear() ) ); - - DayCounter dayCounter = new Thirty360(); - List dates = new List(); - dates.Add(evalDate); - dates.Add(calendar.advance(evalDate, 6, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); - dates.Add(calendar.advance(evalDate, 1, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - dates.Add(calendar.advance(evalDate, 2, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - dates.Add(calendar.advance(evalDate, 3, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - dates.Add(calendar.advance(evalDate, 4, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - dates.Add(calendar.advance(evalDate, 5, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - dates.Add(calendar.advance(evalDate, 7, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - dates.Add(calendar.advance(evalDate,10, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); - - List defaultProbabilities = new List(); - defaultProbabilities.Add(0.0000); - defaultProbabilities.Add(0.0047); - defaultProbabilities.Add(0.0093); - defaultProbabilities.Add(0.0286); - defaultProbabilities.Add(0.0619); - defaultProbabilities.Add(0.0953); - defaultProbabilities.Add(0.1508); - defaultProbabilities.Add(0.2288); - defaultProbabilities.Add(0.3666); - - List hazardRates = new List(); - hazardRates.Add(0.0); - for (int i=1; i piecewiseFlatHazardRate = new RelinkableHandle(); - piecewiseFlatHazardRate.linkTo(new InterpolatedHazardRateCurve(dates,hazardRates,new Thirty360())); - - // Testing credit default swap - - // Build the schedule - Date issueDate = new Date(20, Month.March, 2006); - Date maturity = new Date(20, Month.June, 2013); - Frequency cdsFrequency = Frequency.Semiannual; - BusinessDayConvention cdsConvention = BusinessDayConvention.ModifiedFollowing; - - Schedule schedule = new Schedule(issueDate, maturity, new Period(cdsFrequency), calendar, - cdsConvention, cdsConvention, - DateGeneration.Rule.Forward, false); - - // Build the CDS - double recoveryRate = 0.25; - double fixedRate=0.0224; - DayCounter dayCount= new Actual360(); - double cdsNotional=100.0; - - CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, cdsNotional, fixedRate, - schedule, cdsConvention, dayCount, true, true); - cds.setPricingEngine(new MidPointCdsEngine(piecewiseFlatHazardRate, recoveryRate,discountCurve)); - - double calculatedNpv = cds.NPV(); - double calculatedFairRate = cds.fairSpread(); - - double npv = -1.364048777; // from Bloomberg we have 98.15598868 - 100.00; - double fairRate = 0.0248429452; // from Bloomberg we have 0.0258378; - - double tolerance = 1e-9; - - if (Math.Abs(npv - calculatedNpv) > tolerance) - Assert.Fail( - "Failed to reproduce the npv for the given credit-default swap\n" - + " computed NPV: " + calculatedNpv + "\n" + + discountCurve.linkTo(new FlatForward(today,0.06,new Actual360())); + + // Build the schedule + Date issueDate = calendar.advance(today, -1, TimeUnit.Years); + Date maturity = calendar.advance(issueDate, 10, TimeUnit.Years); + Frequency frequency = Frequency.Semiannual; + BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing; + + Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar, + convention, convention, DateGeneration.Rule.Forward, false); + + // Build the CDS + double fixedRate = 0.0120; + DayCounter dayCount = new Actual360(); + double notional = 10000.0; + double recoveryRate = 0.4; + + CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate, + schedule, convention, dayCount, true, true); + cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve,recoveryRate,discountCurve)); + + double npv = 295.0153398; + double fairRate = 0.007517539081; + + double calculatedNpv = cds.NPV(); + double calculatedFairRate = cds.fairSpread(); + double tolerance = 1.0e-7; + + if (Math.Abs(calculatedNpv - npv) > tolerance) + Assert.Fail( + "Failed to reproduce NPV with mid-point engine\n" + + " calculated NPV: " + calculatedNpv + "\n" + + " expected NPV: " + npv); + + if (Math.Abs(calculatedFairRate - fairRate) > tolerance) + Assert.Fail( + "Failed to reproduce fair rate with mid-point engine\n" + + " calculated fair rate: " + calculatedFairRate + "\n" + + " expected fair rate: " + fairRate); + + cds.setPricingEngine(new IntegralCdsEngine(new Period(1,TimeUnit.Days),probabilityCurve, + recoveryRate,discountCurve)); + + calculatedNpv = cds.NPV(); + calculatedFairRate = cds.fairSpread(); + tolerance = 1.0e-5; + + if (Math.Abs(calculatedNpv - npv) > notional*tolerance*10) + Assert.Fail( + "Failed to reproduce NPV with integral engine " + + "(step = 1 day)\n" + + " calculated NPV: " + calculatedNpv + "\n" + + " expected NPV: " + npv); + + if (Math.Abs(calculatedFairRate - fairRate) > tolerance) + Assert.Fail( + "Failed to reproduce fair rate with integral engine " + + "(step = 1 day)\n" + + " calculated fair rate: " + calculatedFairRate + "\n" + + " expected fair rate: " + fairRate); + + cds.setPricingEngine(new IntegralCdsEngine(new Period(1,TimeUnit.Weeks),probabilityCurve,recoveryRate,discountCurve)); + + calculatedNpv = cds.NPV(); + calculatedFairRate = cds.fairSpread(); + tolerance = 1.0e-5; + + if (Math.Abs(calculatedNpv - npv) > notional*tolerance*10) + Assert.Fail( + "Failed to reproduce NPV with integral engine " + +"(step = 1 week)\n" + + " calculated NPV: " + calculatedNpv + "\n" + + " expected NPV: " + npv); + + if (Math.Abs(calculatedFairRate - fairRate) > tolerance) + Assert.Fail( + "Failed to reproduce fair rate with integral engine " + +"(step = 1 week)\n" + + " calculated fair rate: " + calculatedFairRate + "\n" + + " expected fair rate: " + fairRate); + } + + [TestMethod()] + public void testCachedMarketValue() + { + // Testing credit-default swap against cached market values... + + SavedSettings backup = new SavedSettings(); + + Settings.setEvaluationDate(new Date(9,Month.June,2006)); + Date evalDate = Settings.evaluationDate(); + Calendar calendar = new UnitedStates(); + + List discountDates = new List(); + discountDates.Add(evalDate); + discountDates.Add(calendar.advance(evalDate, 1, TimeUnit.Weeks, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 1, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 2, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 3, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 6, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate,12, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 2, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 3, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 4, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 5, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 6, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 7, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 8, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate, 9, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate,10, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + discountDates.Add(calendar.advance(evalDate,15, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + + List dfs = new List(); + dfs.Add(1.0); + dfs.Add(0.9990151375768731); + dfs.Add(0.99570502636871183); + dfs.Add(0.99118260474528685); + dfs.Add(0.98661167950906203); + dfs.Add(0.9732592953359388 ); + dfs.Add(0.94724424481038083); + dfs.Add(0.89844996737120875 ); + dfs.Add(0.85216647839921411 ); + dfs.Add(0.80775477692556874 ); + dfs.Add(0.76517289234200347 ); + dfs.Add(0.72401019553182933 ); + dfs.Add(0.68503909569219212 ); + dfs.Add(0.64797499814013748 ); + dfs.Add(0.61263171936255534 ); + dfs.Add(0.5791942350748791 ); + dfs.Add(0.43518868769953606 ); + + DayCounter curveDayCounter = new Actual360(); + + RelinkableHandle discountCurve = new RelinkableHandle(); + discountCurve.linkTo( new InterpolatedDiscountCurve( discountDates, dfs, curveDayCounter,null,null,null,new LogLinear() ) ); + + DayCounter dayCounter = new Thirty360(); + List dates = new List(); + dates.Add(evalDate); + dates.Add(calendar.advance(evalDate, 6, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing)); + dates.Add(calendar.advance(evalDate, 1, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + dates.Add(calendar.advance(evalDate, 2, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + dates.Add(calendar.advance(evalDate, 3, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + dates.Add(calendar.advance(evalDate, 4, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + dates.Add(calendar.advance(evalDate, 5, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + dates.Add(calendar.advance(evalDate, 7, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + dates.Add(calendar.advance(evalDate,10, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing)); + + List defaultProbabilities = new List(); + defaultProbabilities.Add(0.0000); + defaultProbabilities.Add(0.0047); + defaultProbabilities.Add(0.0093); + defaultProbabilities.Add(0.0286); + defaultProbabilities.Add(0.0619); + defaultProbabilities.Add(0.0953); + defaultProbabilities.Add(0.1508); + defaultProbabilities.Add(0.2288); + defaultProbabilities.Add(0.3666); + + List hazardRates = new List(); + hazardRates.Add(0.0); + for (int i=1; i piecewiseFlatHazardRate = new RelinkableHandle(); + piecewiseFlatHazardRate.linkTo(new InterpolatedHazardRateCurve(dates,hazardRates,new Thirty360())); + + // Testing credit default swap + + // Build the schedule + Date issueDate = new Date(20, Month.March, 2006); + Date maturity = new Date(20, Month.June, 2013); + Frequency cdsFrequency = Frequency.Semiannual; + BusinessDayConvention cdsConvention = BusinessDayConvention.ModifiedFollowing; + + Schedule schedule = new Schedule(issueDate, maturity, new Period(cdsFrequency), calendar, + cdsConvention, cdsConvention, + DateGeneration.Rule.Forward, false); + + // Build the CDS + double recoveryRate = 0.25; + double fixedRate=0.0224; + DayCounter dayCount= new Actual360(); + double cdsNotional=100.0; + + CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, cdsNotional, fixedRate, + schedule, cdsConvention, dayCount, true, true); + cds.setPricingEngine(new MidPointCdsEngine(piecewiseFlatHazardRate, recoveryRate,discountCurve)); + + double calculatedNpv = cds.NPV(); + double calculatedFairRate = cds.fairSpread(); + + double npv = -1.364048777; // from Bloomberg we have 98.15598868 - 100.00; + double fairRate = 0.0248429452; // from Bloomberg we have 0.0258378; + + double tolerance = 1e-9; + + if (Math.Abs(npv - calculatedNpv) > tolerance) + Assert.Fail( + "Failed to reproduce the npv for the given credit-default swap\n" + + " computed NPV: " + calculatedNpv + "\n" + " Given NPV: " + npv); if ( Math.Abs( fairRate - calculatedFairRate ) > tolerance ) Assert.Fail( "Failed to reproduce the fair rate for the given credit-default swap\n" + " computed fair rate: " + calculatedFairRate + "\n" + " Given fair rate: " + fairRate ); - } - - [TestMethod()] + } + + [TestMethod()] public void testImpliedHazardRate() { // Testing implied hazard-rate for credit-default swaps... diff --git a/Test/T_Dates.cs b/Test/T_Dates.cs index 473a4bd01..9a607245b 100644 --- a/Test/T_Dates.cs +++ b/Test/T_Dates.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a @@ -28,6 +28,58 @@ namespace TestSuite [TestClass()] public class T_Dates { + [TestMethod()] + public void testECBDates() + { + // Testing ECB dates + + List knownDates = ECB.knownDates(); + if (knownDates.empty()) + Assert.Fail("Empty EBC date vector"); + + int n = ECB.nextDates(Date.minDate()).Count; + + if (n != knownDates.Count) + Assert.Fail("NextDates(minDate) returns " + n + + " instead of " + knownDates.Count + " dates"); + + Date previousEcbDate = Date.minDate(), + currentEcbDate, ecbDateMinusOne; + + for (int i=0; i. + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_DefaultProbabilityCurves.cs b/Test/T_DefaultProbabilityCurves.cs index 213b38885..ae49bb7d4 100644 --- a/Test/T_DefaultProbabilityCurves.cs +++ b/Test/T_DefaultProbabilityCurves.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_DividendOption.cs b/Test/T_DividendOption.cs index 2a70a6d25..f215bc757 100644 --- a/Test/T_DividendOption.cs +++ b/Test/T_DividendOption.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008-2013 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_EuropeanOption.cs b/Test/T_EuropeanOption.cs index f8cf395eb..49ad402c4 100644 --- a/Test/T_EuropeanOption.cs +++ b/Test/T_EuropeanOption.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_ExchangeRate.cs b/Test/T_ExchangeRate.cs index a954aea2d..a9e8292a6 100644 --- a/Test/T_ExchangeRate.cs +++ b/Test/T_ExchangeRate.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_Functions.cs b/Test/T_Functions.cs new file mode 100644 index 000000000..55c815c2a --- /dev/null +++ b/Test/T_Functions.cs @@ -0,0 +1,295 @@ +/* + Copyright (C) 2008, 2015 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using QLNet; +using System.Numerics; + +namespace TestSuite +{ + [TestClass()] + public class T_Functions + { + [TestMethod()] + public void testFactorial() + { + // Testing factorial numbers + + double expected = 1.0; + double calculated = Factorial.get(0); + if (calculated!=expected) + Assert.Fail("Factorial(0) = " + calculated); + + for (uint i=1; i<171; ++i) + { + expected *= i; + calculated = Factorial.get(i); + if (Math.Abs(calculated-expected)/expected > 1.0e-9) + Assert.Fail("Factorial(" + i + ")" + + "\n calculated: " + calculated + + "\n expected: " + expected + + "\n rel. error: " + + Math.Abs(calculated-expected)/expected); + } + } + + [TestMethod()] + public void testGammaFunction() + { + // Testing Gamma function + + double expected = 0.0; + double calculated = GammaFunction.logValue(1); + if (Math.Abs(calculated) > 1.0e-15) + Assert.Fail("GammaFunction(1)\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected); + + for (int i=2; i<9000; i++) + { + expected += Math.Log(i); + calculated = GammaFunction.logValue((i+1)); + if (Math.Abs(calculated-expected)/expected > 1.0e-9) + Assert.Fail("GammaFunction(" + i + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " rel. error: " + + Math.Abs(calculated-expected)/expected); + } + } + + [TestMethod()] + public void testGammaValues() + { + // Testing Gamma values + + // reference results are calculated with R + double[][] tasks = { + new double[3] { 0.0001, 9999.422883231624, 1e3}, + new double[3] { 1.2, 0.9181687423997607, 1e3}, + new double[3] { 7.3, 1271.4236336639089586, 1e3}, + new double[3] {-1.1, 9.7148063829028946, 1e3}, + new double[3] {-4.001,-41.6040228304425312, 1e3}, + new double[3] {-4.999, -8.347576090315059, 1e3}, + new double[3] {-19.000001, 8.220610833201313e-12, 1e8}, + new double[3] {-19.5, 5.811045977502255e-18, 1e3}, + new double[3] {-21.000001, 1.957288098276488e-14, 1e8}, + new double[3] {-21.5, 1.318444918321553e-20, 1e6} + }; + + for (int i=0; i < tasks.Length; ++i) + { + double x = tasks[i][0]; + double expected = tasks[i][1]; + double calculated = GammaFunction.value(x); + double tol = tasks[i][2] * Const.QL_EPSILON*Math.Abs(expected); + + if (Math.Abs(calculated - expected) > tol) + { + Assert.Fail("GammaFunction(" + x + ")\n" + + " calculated: " + calculated + "\n" + + " expected: " + expected + "\n" + + " rel. error: " + + Math.Abs(calculated-expected)/expected); + + } + } + } + + [TestMethod()] + public void testModifiedBesselFunctions() + { + // Testing modified Bessel function of first and second kind + + /* reference values are computed with R and the additional package Bessel + * http://cran.r-project.org/web/packages/Bessel + */ + + double[][] r = { + new double[4] {-1.3, 2.0, 1.2079888436539505, 0.1608243636110430}, + new double[4] { 1.3, 2.0, 1.2908192151358788, 0.1608243636110430}, + new double[4] { 0.001, 2.0, 2.2794705965773794, 0.1138938963603362}, + new double[4] { 1.2, 0.5, 0.1768918783499572, 2.1086579232338192}, + new double[4] { 2.3, 0.1, 0.00037954958988425198, 572.096866928290183}, + new double[4] {-2.3, 1.1, 1.07222017902746969, 1.88152553684107371}, + new double[4] {-10.0001, 1.1, 13857.7715614282552, 69288858.9474423379} + }; + + for (int i=0; i < r.Length; ++i) + { + double nu = r[i][0]; + double x = r[i][1]; + double expected_i = r[i][2]; + double expected_k = r[i][3]; + double tol_i = 5e4 * Const.QL_EPSILON*Math.Abs(expected_i); + double tol_k = 5e4 * Const.QL_EPSILON*Math.Abs(expected_k); + + double calculated_i = Utils.modifiedBesselFunction_i(nu, x); + double calculated_k = Utils.modifiedBesselFunction_k(nu, x); + + if (Math.Abs(expected_i - calculated_i) > tol_i) { + Assert.Fail("failed to reproduce modified Bessel " + + "function of first kind" + + "\n order : " + nu + + "\n argument : " + x + + "\n calculated: " + calculated_i + + "\n expected : " + expected_i); + } + if (Math.Abs(expected_k - calculated_k) > tol_k) { + Assert.Fail("failed to reproduce modified Bessel " + + "function of second kind" + + "\n order : " + nu + + "\n argument : " + x + + "\n calculated: " + calculated_k + + "\n expected : " + expected_k); + } + } + + double[][] c = { + new double[7] {-1.3, 2.0, 0.0, 1.2079888436539505, 0.0, 0.1608243636110430, 0.0}, + new double[7] { 1.2, 1.5, 0.3, 0.7891550871263575, 0.2721408731632123, 0.275126507673411, -0.1316314405663727}, + new double[7] { 1.2, -1.5,0.0,-0.6650597524355781, -0.4831941938091643, -0.251112360556051, -2.400130904230102}, + new double[7] {-11.2, 1.5, 0.3,12780719.20252659, 16401053.26770633, -34155172.65672453, -43830147.36759921}, + new double[7] { 1.2, -1.5,2.0,-0.3869803778520574, 0.9756701796853728, -3.111629716783005, 0.6307859871879062}, + new double[7] { 1.2, 0.0, 9.9999,-0.03507838078252647, 0.1079601550451466, -0.05979939995451453, 0.3929814473878203}, + new double[7] { 1.2, 0.0, 10.1, -0.02782046891519293, 0.08562259917678558, -0.02035685034691133, 0.3949834389686676}, + new double[7] { 1.2, 0.0, 12.1, 0.07092110620741207, -0.2182727210128104, 0.3368505862966958, -0.1299038064313366}, + new double[7] { 1.2, 0.0, 14.1,-0.03014378676768797, 0.09277303628303372, -0.237531022649052, -0.2351923034581644}, + new double[7] { 1.2, 0.0, 16.1,-0.03823210284792657, 0.1176663135266562, -0.1091239402448228, 0.2930535651966139}, + new double[7] { 1.2, 0.0, 18.1,0.05626742394733754, -0.173173324361983, 0.2941636588154642, -0.02023355577954348}, + new double[7] { 1.2, 0.0, 180.1,-0.001230682086826484, 0.003787649998122361,0.02284509628723454, 0.09055419580980778}, + new double[7] { 1.2, 0.0, 21.0,-0.04746415965014021, 0.1460796627610969,-0.2693825171336859, -0.04830804448126782}, + new double[7] { 1.2, 10.0, 0.0, 2609.784936867044, 0, 1.904394919838336e-05, 0}, + new double[7] { 1.2, 14.0, 0.0, 122690.4873454286, 0, 2.902060692576643e-07, 0}, + new double[7] { 1.2, 20.0, 10.0, -37452017.91168936, -13917587.22151363, -3.821534367487143e-10, 4.083211255351664e-10}, + new double[7] { 1.2, 9.0, 9.0, -621.7335051293694, 618.1455736670332, -4.480795479964915e-05, -3.489034389148745e-08} + }; + + for (int i=0; i < c.Length; ++i) + { + double nu = c[i][0]; + Complex z = new Complex(c[i][1], c[i][2]); + Complex expected_i = new Complex(c[i][3],c[i][4]); + Complex expected_k = new Complex(c[i][5],c[i][6]); + + double tol_i = 5e4*Const.QL_EPSILON*Complex.Abs(expected_i); + double tol_k = 1e6*Const.QL_EPSILON*Complex.Abs(expected_k); + + Complex calculated_i= Utils.modifiedBesselFunction_i(nu, z); + Complex calculated_k= Utils.modifiedBesselFunction_k(nu, z); + + if (Complex.Abs(expected_i - calculated_i) > tol_i) + { + Assert.Fail("failed to reproduce modified Bessel " + + "function of first kind" + + "\n order : " + nu + + "\n argument : " + z + + "\n calculated: " + calculated_i + + "\n expected : " + expected_i); + } + + if ( Complex.Abs(expected_k) > 1e-4 // do not check small values + && Complex.Abs(expected_k - calculated_k) > tol_k) + { + Assert.Fail("failed to reproduce modified Bessel " + + "function of second kind" + + "\n order : " + nu + + "\n argument : " + z + + "\n diff : " + (calculated_k-expected_k) + + "\n calculated: " + calculated_k + + "\n expected : " + expected_k); + } + } + } + + [TestMethod()] + public void testWeightedModifiedBesselFunctions() + { + // Testing weighted modified Bessel functions + double nu = -5.0; + while (nu <= 5.0) + { + double x = 0.1; + while (x <= 15.0) + { + double vi = Utils.modifiedBesselFunction_i_exponentiallyWeighted(nu, x); + double wi = Utils.modifiedBesselFunction_i(nu, x) * Math.Exp(-x); + double vk = Utils.modifiedBesselFunction_k_exponentiallyWeighted(nu, x); + double wk = Const.M_PI_2 * (Utils.modifiedBesselFunction_i(-nu,x)*Math.Exp(-x)- + Utils.modifiedBesselFunction_i(nu,x)*Math.Exp(-x)) / Math.Sin(Const.M_PI*nu); + if (Math.Abs((vi - wi) / (Math.Max(Math.Exp(x), 1.0) * vi)) > 1E3 * Const.QL_EPSILON) + Assert.Fail("failed to verify exponentially weighted" + + "modified Bessel function of first kind" + + "\n order : " + nu + "\n argument : " + + x + "\n calcuated : " + vi + + "\n expecetd : " + wi); + + if (Math.Abs((vk - wk) / (Math.Max(Math.Exp(x), 1.0) * vk)) > 1E3 * Const.QL_EPSILON) + Assert.Fail("failed to verify exponentially weighted" + + "modified Bessel function of second kind" + + "\n order : " + nu + "\n argument : " + + x + "\n calcuated : " + vk + + "\n expecetd : " + wk); + x += 0.5; + } + nu += 0.5; + } + nu = -5.0; + while (nu <= 5.0) + { + double x = -5.0; + while (x <= 5.0) { + double y = -5.0; + while (y <= 5.0) + { + Complex z = new Complex(x, y); + Complex vi = Utils.modifiedBesselFunction_i_exponentiallyWeighted(nu, z); + Complex wi = Utils.modifiedBesselFunction_i(nu, z) * Complex.Exp(-z); + Complex vk = Utils.modifiedBesselFunction_k_exponentiallyWeighted(nu, z); + Complex wk = Const.M_PI_2 * (Utils.modifiedBesselFunction_i(-nu, z) * Complex.Exp(-z) - + Utils.modifiedBesselFunction_i(nu, z) * Complex.Exp(-z)) / + Math.Sin(Const.M_PI * nu); + if (Complex.Abs((vi - wi) / vi) > 1E3 * Const.QL_EPSILON) + Assert.Fail("failed to verify exponentially weighted" + + "modified Bessel function of first kind" + + "\n order : " + nu + + "\n argument : " + z + + "\n calcuated: " + + vi + "\n expecetd : " + wi); + if (Complex.Abs((vk - wk) / vk) > 1E3 * Const.QL_EPSILON) + Assert.Fail("failed to verify exponentially weighted" + + "modified Bessel function of second kind" + + "\n order : " + nu + + "\n argument : " + z + + "\n calcuated: " + + vk + "\n expecetd : " + wk); + y += 0.5; + } + x += 0.5; + } + nu += 0.5; + } + + } + + } +} diff --git a/Test/T_Inflation.cs b/Test/T_Inflation.cs index 3efb856c9..4dee32396 100644 --- a/Test/T_Inflation.cs +++ b/Test/T_Inflation.cs @@ -1,71 +1,71 @@ -/* - Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using QLNet; - -namespace TestSuite -{ - struct Datum - { - public Date date; - public double rate; - public Datum(Date d , double r ) - { - date = d; - rate = r; - } - }; - - //=========================================================================================== - // zero inflation tests, index, termstructure, and swaps - //=========================================================================================== - - [TestClass()] - public class T_Inflation - { - - private YieldTermStructure nominalTermStructure() - { - Date evaluationDate = new Date(13, Month.August, 2007); - return new FlatForward(evaluationDate, 0.05, new Actual360()); - } - - private List> makeHelpers(Datum[] iiData, int N, - ZeroInflationIndex ii, Period observationLag, - Calendar calendar, - BusinessDayConvention bdc, - DayCounter dc) - { - List > instruments = new List>(); - for (int i = 0; i < N; i++) - { - Date maturity = iiData[i].date; - Handle quote = new Handle(new SimpleQuote(iiData[i].rate / 100.0)); - BootstrapHelper anInstrument = new ZeroCouponInflationSwapHelper(quote, observationLag, maturity, - calendar, bdc, dc, ii); - instruments.Add(anInstrument); - } - return instruments; +/* + Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using QLNet; + +namespace TestSuite +{ + struct Datum + { + public Date date; + public double rate; + public Datum(Date d , double r ) + { + date = d; + rate = r; + } + }; + + //=========================================================================================== + // zero inflation tests, index, termstructure, and swaps + //=========================================================================================== + + [TestClass()] + public class T_Inflation + { + + private YieldTermStructure nominalTermStructure() + { + Date evaluationDate = new Date(13, Month.August, 2007); + return new FlatForward(evaluationDate, 0.05, new Actual360()); + } + + private List> makeHelpers(Datum[] iiData, int N, + ZeroInflationIndex ii, Period observationLag, + Calendar calendar, + BusinessDayConvention bdc, + DayCounter dc) + { + List > instruments = new List>(); + for (int i = 0; i < N; i++) + { + Date maturity = iiData[i].date; + Handle quote = new Handle(new SimpleQuote(iiData[i].rate / 100.0)); + BootstrapHelper anInstrument = new ZeroCouponInflationSwapHelper(quote, observationLag, maturity, + calendar, bdc, dc, ii); + instruments.Add(anInstrument); + } + return instruments; } private List> makeHelpers( Datum[] iiData, int N, YoYInflationIndex ii, Period observationLag, @@ -83,98 +83,98 @@ private List> makeHelpers( Datum[] ii instruments.Add( anInstrument ); } return instruments; - } - - [TestMethod()] - public void testZeroIndex() - { - // Testing zero inflation indices... - EUHICP euhicp = new EUHICP(true); - - if (euhicp.name() != "EU HICP" - || euhicp.frequency() != Frequency.Monthly - || euhicp.revised() - || !euhicp.interpolated() - || euhicp.availabilityLag() != new Period(1, TimeUnit.Months)) - { - Assert.Fail("wrong EU HICP data (" - + euhicp.name() + ", " - + euhicp.frequency() + ", " - + euhicp.revised() + ", " - + euhicp.interpolated() + ", " - + euhicp.availabilityLag() + ")"); - } - - UKRPI ukrpi = new UKRPI(false); - if (ukrpi.name() != "UK RPI" - || ukrpi.frequency() != Frequency.Monthly - || ukrpi.revised() - || ukrpi.interpolated() - || ukrpi.availabilityLag() != new Period(1, TimeUnit.Months)) - { - Assert.Fail("wrong UK RPI data (" - + ukrpi.name() + ", " - + ukrpi.frequency() + ", " - + ukrpi.revised() + ", " - + ukrpi.interpolated() + ", " - + ukrpi.availabilityLag() + ")"); - } - - - // Retrieval test. - //---------------- - // make sure of the evaluation date - Date evaluationDate = new Date(13, Month.August, 2007); - evaluationDate = new UnitedKingdom().adjust(evaluationDate); - Settings.setEvaluationDate(evaluationDate); - - // fixing data - Date from = new Date(1, Month.January, 2005); - Date to = new Date(13, Month.August, 2007); - Schedule rpiSchedule = new MakeSchedule().from(from).to(to) - .withTenor(new Period(1, TimeUnit.Months)) - .withCalendar(new UnitedKingdom()) - .withConvention(BusinessDayConvention.ModifiedFollowing) - .value(); - - double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, - 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, - 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, - 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, - 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, - 207.3, 206.1, -999.0 }; - - bool interp = false; - UKRPI iir = new UKRPI(interp); - - for (int i = 0; i < rpiSchedule.Count - 1; i++) - { - iir.addFixing(rpiSchedule[i], fixData[i]); - } - - Date todayMinusLag = evaluationDate - iir.availabilityLag(); - KeyValuePair lim1 = Utils.inflationPeriod(todayMinusLag, iir.frequency()); - todayMinusLag = lim1.Key; - - double eps = 1.0e-8; - - // -1 because last value not yet available, - // (no TS so can't forecast). - for (int i = 0; i < rpiSchedule.Count - 1; i++) - { - KeyValuePair lim = Utils.inflationPeriod(rpiSchedule[i], - iir.frequency()); - for (Date d = lim.Key; d <= lim.Value; d++) - { - if (d < Utils.inflationPeriod(todayMinusLag, iir.frequency()).Key) - { - if (Math.Abs(iir.fixing(d) - fixData[i]) > eps) - Assert.Fail("Fixings not constant within a period: " - + iir.fixing(d) - + ", should be " + fixData[i]); - } - } - } + } + + [TestMethod()] + public void testZeroIndex() + { + // Testing zero inflation indices... + EUHICP euhicp = new EUHICP(true); + + if (euhicp.name() != "EU HICP" + || euhicp.frequency() != Frequency.Monthly + || euhicp.revised() + || !euhicp.interpolated() + || euhicp.availabilityLag() != new Period(1, TimeUnit.Months)) + { + Assert.Fail("wrong EU HICP data (" + + euhicp.name() + ", " + + euhicp.frequency() + ", " + + euhicp.revised() + ", " + + euhicp.interpolated() + ", " + + euhicp.availabilityLag() + ")"); + } + + UKRPI ukrpi = new UKRPI(false); + if (ukrpi.name() != "UK RPI" + || ukrpi.frequency() != Frequency.Monthly + || ukrpi.revised() + || ukrpi.interpolated() + || ukrpi.availabilityLag() != new Period(1, TimeUnit.Months)) + { + Assert.Fail("wrong UK RPI data (" + + ukrpi.name() + ", " + + ukrpi.frequency() + ", " + + ukrpi.revised() + ", " + + ukrpi.interpolated() + ", " + + ukrpi.availabilityLag() + ")"); + } + + + // Retrieval test. + //---------------- + // make sure of the evaluation date + Date evaluationDate = new Date(13, Month.August, 2007); + evaluationDate = new UnitedKingdom().adjust(evaluationDate); + Settings.setEvaluationDate(evaluationDate); + + // fixing data + Date from = new Date(1, Month.January, 2005); + Date to = new Date(13, Month.August, 2007); + Schedule rpiSchedule = new MakeSchedule().from(from).to(to) + .withTenor(new Period(1, TimeUnit.Months)) + .withCalendar(new UnitedKingdom()) + .withConvention(BusinessDayConvention.ModifiedFollowing) + .value(); + + double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, + 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, + 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, + 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, + 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, + 207.3, 206.1, -999.0 }; + + bool interp = false; + UKRPI iir = new UKRPI(interp); + + for (int i = 0; i < rpiSchedule.Count - 1; i++) + { + iir.addFixing(rpiSchedule[i], fixData[i]); + } + + Date todayMinusLag = evaluationDate - iir.availabilityLag(); + KeyValuePair lim1 = Utils.inflationPeriod(todayMinusLag, iir.frequency()); + todayMinusLag = lim1.Key; + + double eps = 1.0e-8; + + // -1 because last value not yet available, + // (no TS so can't forecast). + for (int i = 0; i < rpiSchedule.Count - 1; i++) + { + KeyValuePair lim = Utils.inflationPeriod(rpiSchedule[i], + iir.frequency()); + for (Date d = lim.Key; d <= lim.Value; d++) + { + if (d < Utils.inflationPeriod(todayMinusLag, iir.frequency()).Key) + { + if (Math.Abs(iir.fixing(d) - fixData[i]) > eps) + Assert.Fail("Fixings not constant within a period: " + + iir.fixing(d) + + ", should be " + fixData[i]); + } + } + } } [TestMethod()] @@ -200,11 +200,11 @@ public void testZeroTermStructure() .withConvention( BusinessDayConvention.ModifiedFollowing ) .value(); - double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, - 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, - 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, - 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, - 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, + double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, + 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, + 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, + 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, + 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, 207.3, 206.1, -999.0 }; RelinkableHandle hz = new RelinkableHandle(); @@ -222,20 +222,20 @@ public void testZeroTermStructure() // now build the zero inflation curve - Datum[] zcData = { - new Datum( new Date(13, Month.August, 2008), 2.93 ), - new Datum( new Date(13, Month.August, 2009), 2.95 ), - new Datum( new Date(13, Month.August, 2010), 2.965 ), - new Datum( new Date(15, Month.August, 2011), 2.98 ), - new Datum( new Date(13, Month.August, 2012), 3.0 ), - new Datum( new Date(13, Month.August, 2014), 3.06 ), - new Datum( new Date(13, Month.August, 2017), 3.175 ), - new Datum( new Date(13, Month.August, 2019), 3.243 ), - new Datum( new Date(15, Month.August, 2022), 3.293 ), - new Datum( new Date(14, Month.August, 2027), 3.338 ), - new Datum( new Date(13, Month.August, 2032), 3.348 ), - new Datum( new Date(15, Month.August, 2037), 3.348 ), - new Datum( new Date(13, Month.August, 2047), 3.308 ), + Datum[] zcData = { + new Datum( new Date(13, Month.August, 2008), 2.93 ), + new Datum( new Date(13, Month.August, 2009), 2.95 ), + new Datum( new Date(13, Month.August, 2010), 2.965 ), + new Datum( new Date(15, Month.August, 2011), 2.98 ), + new Datum( new Date(13, Month.August, 2012), 3.0 ), + new Datum( new Date(13, Month.August, 2014), 3.06 ), + new Datum( new Date(13, Month.August, 2017), 3.175 ), + new Datum( new Date(13, Month.August, 2019), 3.243 ), + new Datum( new Date(15, Month.August, 2022), 3.293 ), + new Datum( new Date(14, Month.August, 2027), 3.338 ), + new Datum( new Date(13, Month.August, 2032), 3.348 ), + new Datum( new Date(15, Month.August, 2037), 3.348 ), + new Datum( new Date(13, Month.August, 2047), 3.308 ), new Datum( new Date(13, Month.August, 2057), 3.228 )}; @@ -936,6 +936,6 @@ public void testYYTermStructure() hy.linkTo( new YoYInflationTermStructure()); } - - } -} + + } +} diff --git a/Test/T_InflationCapFloorTest.cs b/Test/T_InflationCapFloorTest.cs index 371295c45..b7579b5ff 100644 --- a/Test/T_InflationCapFloorTest.cs +++ b/Test/T_InflationCapFloorTest.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_InflationCapFlooredCouponTest.cs b/Test/T_InflationCapFlooredCouponTest.cs index 5c6a2e9f4..bc2504635 100644 --- a/Test/T_InflationCapFlooredCouponTest.cs +++ b/Test/T_InflationCapFlooredCouponTest.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_Instruments.cs b/Test/T_Instruments.cs index 6ae56dcbb..36ed02fda 100644 --- a/Test/T_Instruments.cs +++ b/Test/T_Instruments.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_InterestRate.cs b/Test/T_InterestRate.cs index df098e1ad..9e85ccb3a 100644 --- a/Test/T_InterestRate.cs +++ b/Test/T_InterestRate.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_Interpolations.cs b/Test/T_Interpolations.cs index f04ab1eb1..b51963f02 100644 --- a/Test/T_Interpolations.cs +++ b/Test/T_Interpolations.cs @@ -1,12 +1,13 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -23,1052 +24,1467 @@ under the terms of the QLNet license. You should have received a using Microsoft.VisualStudio.TestTools.UnitTesting; using QLNet; -namespace TestSuite { - [TestClass()] - public class T_Interpolations { - - /* See J. M. Hyman, "Accurate monotonicity preserving cubic interpolation" - SIAM J. of Scientific and Statistical Computing, v. 4, 1983, pp. 645-654. - http://math.lanl.gov/~mac/papers/numerics/H83.pdf - */ - [TestMethod()] - public void testSplineErrorOnGaussianValues() { - - //("Testing spline approximation on Gaussian data sets..."); - - int[] points = { 5, 9, 17, 33 }; - - // complete spline data from the original 1983 Hyman paper - double[] tabulatedErrors = { 3.5e-2, 2.0e-3, 4.0e-5, 1.8e-6 }; - double[] toleranceOnTabErr = { 0.1e-2, 0.1e-3, 0.1e-5, 0.1e-6 }; - - // (complete) MC spline data from the original 1983 Hyman paper - // NB: with the improved Hyman filter from the Dougherty, Edelman, and - // Hyman 1989 paper the n=17 nonmonotonicity is not filtered anymore - // so the error agrees with the non MC method. - double[] tabulatedMCErrors = { 1.7e-2, 2.0e-3, 4.0e-5, 1.8e-6 }; - double[] toleranceOnTabMCErr = { 0.1e-2, 0.1e-3, 0.1e-5, 0.1e-6 }; - - SimpsonIntegral integral = new SimpsonIntegral(1e-12, 10000); - - // still unexplained scale factor needed to obtain the numerical - // results from the paper - double scaleFactor = 1.9; - - for (int i=0; i x = xRange(-1.7, 1.9, n); - List y = gaussian(x); - - // Not-a-knot - CubicInterpolation f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - double result = Math.Sqrt(integral.value(make_error_function(f).value, -1.7, 1.9)); - result /= scaleFactor; - if (Math.Abs(result-tabulatedErrors[i]) > toleranceOnTabErr[i]) - Assert.Fail("Not-a-knot spline interpolation " - + "\n sample points: " + n - + "\n norm of difference: " + result - + "\n it should be: " + tabulatedErrors[i]); - - // MC not-a-knot - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - result = Math.Sqrt(integral.value(make_error_function(f).value, -1.7, 1.9)); - result /= scaleFactor; - if (Math.Abs(result-tabulatedMCErrors[i]) > toleranceOnTabMCErr[i]) - Assert.Fail("MC Not-a-knot spline interpolation " - + "\n sample points: " + n - + "\n norm of difference: " + result - + "\n it should be: " - + tabulatedMCErrors[i]); - } - } - - /* See J. M. Hyman, "Accurate monotonicity preserving cubic interpolation" - SIAM J. of Scientific and Statistical Computing, v. 4, 1983, pp. 645-654. - http://math.lanl.gov/~mac/papers/numerics/H83.pdf - */ - [TestMethod()] - public void testSplineOnGaussianValues() { - - //("Testing spline interpolation on a Gaussian data set..."); - - double interpolated, interpolated2; - int n = 5; - - List x = new InitializedList(n), y = new InitializedList(n); - double x1_bad=-1.7, x2_bad=1.7; - - for (double start = -1.9, j=0; j<2; start+=0.2, j++) { - x = xRange(start, start+3.6, n); - y = gaussian(x); - - // Not-a-knot spline - CubicInterpolation f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - checkValues("Not-a-knot spline", f, x, y); - checkNotAKnotCondition("Not-a-knot spline", f); - // bad performance - interpolated = f.value(x1_bad); - interpolated2= f.value(x2_bad); - if (interpolated>0.0 && interpolated2>0.0 ) { - Assert.Fail("Not-a-knot spline interpolation " - + "bad performance unverified" - + "\nat x = " + x1_bad - + " interpolated value: " + interpolated - + "\nat x = " + x2_bad - + " interpolated value: " + interpolated - + "\n at least one of them was expected to be < 0.0"); - } - - // MC not-a-knot spline - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - checkValues("MC not-a-knot spline", f, x, y); - // good performance - interpolated = f.value(x1_bad); - if (interpolated<0.0) { - Assert.Fail("MC not-a-knot spline interpolation " - + "good performance unverified\n" - + "at x = " + x1_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value > 0.0"); - } - interpolated = f.value(x2_bad); - if (interpolated<0.0) { - Assert.Fail("MC not-a-knot spline interpolation " - + "good performance unverified\n" - + "at x = " + x2_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value > 0.0"); - } - } - } - - /* See J. M. Hyman, "Accurate monotonicity preserving cubic interpolation" - SIAM J. of Scientific and Statistical Computing, v. 4, 1983, pp. 645-654. - http://math.lanl.gov/~mac/papers/numerics/H83.pdf - */ - [TestMethod()] - public void testSplineOnRPN15AValues() { - - //("Testing spline interpolation on RPN15A data set..."); - - List RPN15A_x = new List() { - 7.99, 8.09, 8.19, 8.7, - 9.2, 10.0, 12.0, 15.0, 20.0 - }; - List RPN15A_y = new List() { - 0.0, 2.76429e-5, 4.37498e-5, 0.169183, - 0.469428, 0.943740, 0.998636, 0.999919, 0.999994 - }; - - double interpolated; - - // Natural spline - CubicInterpolation f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); - f.update(); - checkValues("Natural spline", f, RPN15A_x, RPN15A_y); - check2ndDerivativeValue("Natural spline", f, RPN15A_x.First(), 0.0); - check2ndDerivativeValue("Natural spline", f, RPN15A_x.Last(), 0.0); - // poor performance - double x_bad = 11.0; - interpolated = f.value(x_bad); - if (interpolated<1.0) { - Assert.Fail("Natural spline interpolation " - + "poor performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value > 1.0"); - } - - - // Clamped spline - f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0, - CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0); - f.update(); - checkValues("Clamped spline", f, RPN15A_x, RPN15A_y); - check1stDerivativeValue("Clamped spline", f, RPN15A_x.First(), 0.0); - check1stDerivativeValue("Clamped spline", f, RPN15A_x.Last(), 0.0); - // poor performance - interpolated = f.value(x_bad); - if (interpolated<1.0) { - Assert.Fail("Clamped spline interpolation " - + "poor performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value > 1.0"); - } - - - // Not-a-knot spline - f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.NotAKnot, 0.0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0.0); - - f.update(); - checkValues("Not-a-knot spline", f, RPN15A_x, RPN15A_y); - checkNotAKnotCondition("Not-a-knot spline", f); - // poor performance - interpolated = f.value(x_bad); - if (interpolated<1.0) { - Assert.Fail("Not-a-knot spline interpolation " - + "poor performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value > 1.0"); - } - - - // MC natural spline values - f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); - f.update(); - checkValues("MC natural spline", f, RPN15A_x, RPN15A_y); - // good performance - interpolated = f.value(x_bad); - if (interpolated>1.0) { - Assert.Fail("MC natural spline interpolation " - + "good performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value < 1.0"); - } - - - // MC clamped spline values - f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0, - CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0); - f.update(); - checkValues("MC clamped spline", f, RPN15A_x, RPN15A_y); - check1stDerivativeValue("MC clamped spline", f, RPN15A_x.First(), 0.0); - check1stDerivativeValue("MC clamped spline", f, RPN15A_x.Last(), 0.0); - - // good performance - interpolated = f.value(x_bad); - if (interpolated>1.0) { - Assert.Fail("MC clamped spline interpolation " - + "good performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value < 1.0"); - } - - - // MC not-a-knot spline values - f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0.0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0.0); - f.update(); - checkValues("MC not-a-knot spline", f, RPN15A_x, RPN15A_y); - // good performance - interpolated = f.value(x_bad); - if (interpolated>1.0) { - Assert.Fail("MC clamped spline interpolation " - + "good performance unverified\n" - + "at x = " + x_bad - + "\ninterpolated value: " + interpolated - + "\nexpected value < 1.0"); - } - } - - /* Blossey, Frigyik, Farnum "A Note On CubicSpline Splines" - Applied Linear Algebra and Numerical Analysis AMATH 352 Lecture Notes - http://www.amath.washington.edu/courses/352-winter-2002/spline_note.pdf - */ - [TestMethod()] - public void testSplineOnGenericValues() { - - //("Testing spline interpolation on generic values..."); - - List generic_x = new List() { 0.0, 1.0, 3.0, 4.0 }; - List generic_y = new List() { 0.0, 0.0, 2.0, 2.0 }; - List generic_natural_y2 = new List() { 0.0, 1.5, -1.5, 0.0 }; - - double interpolated, error; - int i, n = generic_x.Count; - List x35 = new InitializedList(3); - - // Natural spline - CubicInterpolation f = new CubicInterpolation(generic_x, generic_x.Count, generic_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, - generic_natural_y2[0], - CubicInterpolation.BoundaryCondition.SecondDerivative, - generic_natural_y2[n-1]); - f.update(); - checkValues("Natural spline", f, generic_x, generic_y); - // cached second derivative - for (i=0; i3e-16) { - Assert.Fail("Natural spline interpolation " - + "second derivative failed at x=" + generic_x[i] - + "\ninterpolated value: " + interpolated - + "\nexpected value: " + generic_natural_y2[i] - + "\nerror: " + error); - } - } - x35[1] = f.value(3.5); - - - // Clamped spline - double y1a = 0.0, y1b = 0.0; - f = new CubicInterpolation(generic_x, generic_x.Count, generic_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.FirstDerivative, y1a, - CubicInterpolation.BoundaryCondition.FirstDerivative, y1b); - f.update(); - checkValues("Clamped spline", f, generic_x, generic_y); - check1stDerivativeValue("Clamped spline", f, generic_x.First(), 0.0); - check1stDerivativeValue("Clamped spline", f, generic_x.Last(), 0.0); - x35[0] = f.value(3.5); - - - // Not-a-knot spline - f = new CubicInterpolation(generic_x, generic_x.Count, generic_y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - checkValues("Not-a-knot spline", f, generic_x, generic_y); - checkNotAKnotCondition("Not-a-knot spline", f); - - x35[2] = f.value(3.5); - - if (x35[0]>x35[1] || x35[1]>x35[2]) { - Assert.Fail("Spline interpolation failure" - + "\nat x = " + 3.5 - + "\nclamped spline " + x35[0] - + "\nnatural spline " + x35[1] - + "\nnot-a-knot spline " + x35[2] - + "\nvalues should be in increasing order"); - } - } - - [TestMethod()] - public void testSimmetricEndConditions() { - - //("Testing symmetry of spline interpolation end-conditions..."); - - int n = 9; - - List x, y; - x = xRange(-1.8, 1.8, n); - y = gaussian(x); - - // Not-a-knot spline - CubicInterpolation f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, false, +namespace TestSuite +{ + + [TestClass()] + public class T_Interpolations + { + + /* See J. M. Hyman, "Accurate monotonicity preserving cubic interpolation" + SIAM J. of Scientific and Statistical Computing, v. 4, 1983, pp. 645-654. + http://math.lanl.gov/~mac/papers/numerics/H83.pdf + */ + [TestMethod()] + public void testSplineErrorOnGaussianValues() + { + //("Testing spline approximation on Gaussian data sets..."); + + int[] points = { 5, 9, 17, 33 }; + + // complete spline data from the original 1983 Hyman paper + double[] tabulatedErrors = { 3.5e-2, 2.0e-3, 4.0e-5, 1.8e-6 }; + double[] toleranceOnTabErr = { 0.1e-2, 0.1e-3, 0.1e-5, 0.1e-6 }; + + // (complete) MC spline data from the original 1983 Hyman paper + // NB: with the improved Hyman filter from the Dougherty, Edelman, and + // Hyman 1989 paper the n=17 nonmonotonicity is not filtered anymore + // so the error agrees with the non MC method. + double[] tabulatedMCErrors = { 1.7e-2, 2.0e-3, 4.0e-5, 1.8e-6 }; + double[] toleranceOnTabMCErr = { 0.1e-2, 0.1e-3, 0.1e-5, 0.1e-6 }; + + SimpsonIntegral integral = new SimpsonIntegral(1e-12, 10000); + + // still unexplained scale factor needed to obtain the numerical + // results from the paper + double scaleFactor = 1.9; + + for (int i=0; i x = xRange(-1.7, 1.9, n); + List y = gaussian(x); + + // Not-a-knot + CubicInterpolation f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + double result = Math.Sqrt(integral.value(make_error_function(f).value, -1.7, 1.9)); + result /= scaleFactor; + if (Math.Abs(result-tabulatedErrors[i]) > toleranceOnTabErr[i]) + Assert.Fail("Not-a-knot spline interpolation " + + "\n sample points: " + n + + "\n norm of difference: " + result + + "\n it should be: " + tabulatedErrors[i]); + + // MC not-a-knot + f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + result = Math.Sqrt(integral.value(make_error_function(f).value, -1.7, 1.9)); + result /= scaleFactor; + if (Math.Abs(result-tabulatedMCErrors[i]) > toleranceOnTabMCErr[i]) + Assert.Fail("MC Not-a-knot spline interpolation " + + "\n sample points: " + n + + "\n norm of difference: " + result + + "\n it should be: " + + tabulatedMCErrors[i]); + } + } + + /* See J. M. Hyman, "Accurate monotonicity preserving cubic interpolation" + SIAM J. of Scientific and Statistical Computing, v. 4, 1983, pp. 645-654. + http://math.lanl.gov/~mac/papers/numerics/H83.pdf + */ + [TestMethod()] + public void testSplineOnGaussianValues() { + + //("Testing spline interpolation on a Gaussian data set..."); + + double interpolated, interpolated2; + int n = 5; + + List x = new InitializedList(n), y = new InitializedList(n); + double x1_bad=-1.7, x2_bad=1.7; + + for (double start = -1.9, j=0; j<2; start+=0.2, j++) { + x = xRange(start, start+3.6, n); + y = gaussian(x); + + // Not-a-knot spline + CubicInterpolation f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + checkValues("Not-a-knot spline", f, x, y); + checkNotAKnotCondition("Not-a-knot spline", f); + // bad performance + interpolated = f.value(x1_bad); + interpolated2= f.value(x2_bad); + if (interpolated>0.0 && interpolated2>0.0 ) { + Assert.Fail("Not-a-knot spline interpolation " + + "bad performance unverified" + + "\nat x = " + x1_bad + + " interpolated value: " + interpolated + + "\nat x = " + x2_bad + + " interpolated value: " + interpolated + + "\n at least one of them was expected to be < 0.0"); + } + + // MC not-a-knot spline + f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + checkValues("MC not-a-knot spline", f, x, y); + // good performance + interpolated = f.value(x1_bad); + if (interpolated<0.0) { + Assert.Fail("MC not-a-knot spline interpolation " + + "good performance unverified\n" + + "at x = " + x1_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value > 0.0"); + } + interpolated = f.value(x2_bad); + if (interpolated<0.0) { + Assert.Fail("MC not-a-knot spline interpolation " + + "good performance unverified\n" + + "at x = " + x2_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value > 0.0"); + } + } + } + + /* See J. M. Hyman, "Accurate monotonicity preserving cubic interpolation" + SIAM J. of Scientific and Statistical Computing, v. 4, 1983, pp. 645-654. + http://math.lanl.gov/~mac/papers/numerics/H83.pdf + */ + [TestMethod()] + public void testSplineOnRPN15AValues() { + + //("Testing spline interpolation on RPN15A data set..."); + + List RPN15A_x = new List() { + 7.99, 8.09, 8.19, 8.7, + 9.2, 10.0, 12.0, 15.0, 20.0 + }; + List RPN15A_y = new List() { + 0.0, 2.76429e-5, 4.37498e-5, 0.169183, + 0.469428, 0.943740, 0.998636, 0.999919, 0.999994 + }; + + double interpolated; + + // Natural spline + CubicInterpolation f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); + f.update(); + checkValues("Natural spline", f, RPN15A_x, RPN15A_y); + check2ndDerivativeValue("Natural spline", f, RPN15A_x.First(), 0.0); + check2ndDerivativeValue("Natural spline", f, RPN15A_x.Last(), 0.0); + // poor performance + double x_bad = 11.0; + interpolated = f.value(x_bad); + if (interpolated<1.0) { + Assert.Fail("Natural spline interpolation " + + "poor performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value > 1.0"); + } + + + // Clamped spline + f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0, + CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0); + f.update(); + checkValues("Clamped spline", f, RPN15A_x, RPN15A_y); + check1stDerivativeValue("Clamped spline", f, RPN15A_x.First(), 0.0); + check1stDerivativeValue("Clamped spline", f, RPN15A_x.Last(), 0.0); + // poor performance + interpolated = f.value(x_bad); + if (interpolated<1.0) { + Assert.Fail("Clamped spline interpolation " + + "poor performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value > 1.0"); + } + + + // Not-a-knot spline + f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0.0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0.0); + + f.update(); + checkValues("Not-a-knot spline", f, RPN15A_x, RPN15A_y); + checkNotAKnotCondition("Not-a-knot spline", f); + // poor performance + interpolated = f.value(x_bad); + if (interpolated<1.0) { + Assert.Fail("Not-a-knot spline interpolation " + + "poor performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value > 1.0"); + } + + + // MC natural spline values + f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); + f.update(); + checkValues("MC natural spline", f, RPN15A_x, RPN15A_y); + // good performance + interpolated = f.value(x_bad); + if (interpolated>1.0) { + Assert.Fail("MC natural spline interpolation " + + "good performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value < 1.0"); + } + + + // MC clamped spline values + f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0, + CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0); + f.update(); + checkValues("MC clamped spline", f, RPN15A_x, RPN15A_y); + check1stDerivativeValue("MC clamped spline", f, RPN15A_x.First(), 0.0); + check1stDerivativeValue("MC clamped spline", f, RPN15A_x.Last(), 0.0); + + // good performance + interpolated = f.value(x_bad); + if (interpolated>1.0) { + Assert.Fail("MC clamped spline interpolation " + + "good performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value < 1.0"); + } + + + // MC not-a-knot spline values + f = new CubicInterpolation(RPN15A_x, RPN15A_x.Count, RPN15A_y, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.NotAKnot, 0.0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0.0); + f.update(); + checkValues("MC not-a-knot spline", f, RPN15A_x, RPN15A_y); + // good performance + interpolated = f.value(x_bad); + if (interpolated>1.0) { + Assert.Fail("MC clamped spline interpolation " + + "good performance unverified\n" + + "at x = " + x_bad + + "\ninterpolated value: " + interpolated + + "\nexpected value < 1.0"); + } + } + + /* Blossey, Frigyik, Farnum "A Note On CubicSpline Splines" + Applied Linear Algebra and Numerical Analysis AMATH 352 Lecture Notes + http://www.amath.washington.edu/courses/352-winter-2002/spline_note.pdf + */ + [TestMethod()] + public void testSplineOnGenericValues() { + + //("Testing spline interpolation on generic values..."); + + List generic_x = new List() { 0.0, 1.0, 3.0, 4.0 }; + List generic_y = new List() { 0.0, 0.0, 2.0, 2.0 }; + List generic_natural_y2 = new List() { 0.0, 1.5, -1.5, 0.0 }; + + double interpolated, error; + int i, n = generic_x.Count; + List x35 = new InitializedList(3); + + // Natural spline + CubicInterpolation f = new CubicInterpolation(generic_x, generic_x.Count, generic_y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, + generic_natural_y2[0], + CubicInterpolation.BoundaryCondition.SecondDerivative, + generic_natural_y2[n-1]); + f.update(); + checkValues("Natural spline", f, generic_x, generic_y); + // cached second derivative + for (i=0; i3e-16) { + Assert.Fail("Natural spline interpolation " + + "second derivative failed at x=" + generic_x[i] + + "\ninterpolated value: " + interpolated + + "\nexpected value: " + generic_natural_y2[i] + + "\nerror: " + error); + } + } + x35[1] = f.value(3.5); + + + // Clamped spline + double y1a = 0.0, y1b = 0.0; + f = new CubicInterpolation(generic_x, generic_x.Count, generic_y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.FirstDerivative, y1a, + CubicInterpolation.BoundaryCondition.FirstDerivative, y1b); + f.update(); + checkValues("Clamped spline", f, generic_x, generic_y); + check1stDerivativeValue("Clamped spline", f, generic_x.First(), 0.0); + check1stDerivativeValue("Clamped spline", f, generic_x.Last(), 0.0); + x35[0] = f.value(3.5); + + + // Not-a-knot spline + f = new CubicInterpolation(generic_x, generic_x.Count, generic_y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + checkValues("Not-a-knot spline", f, generic_x, generic_y); + checkNotAKnotCondition("Not-a-knot spline", f); + + x35[2] = f.value(3.5); + + if (x35[0]>x35[1] || x35[1]>x35[2]) { + Assert.Fail("Spline interpolation failure" + + "\nat x = " + 3.5 + + "\nclamped spline " + x35[0] + + "\nnatural spline " + x35[1] + + "\nnot-a-knot spline " + x35[2] + + "\nvalues should be in increasing order"); + } + } + + [TestMethod()] + public void testSimmetricEndConditions() { + + //("Testing symmetry of spline interpolation end-conditions..."); + + int n = 9; + + List x, y; + x = xRange(-1.8, 1.8, n); + y = gaussian(x); + + // Not-a-knot spline + CubicInterpolation f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + checkValues("Not-a-knot spline", f, x, y); + checkNotAKnotCondition("Not-a-knot spline", f); + checkSymmetry("Not-a-knot spline", f, x[0]); + + + // MC not-a-knot spline + f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.NotAKnot, 0, CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - checkValues("Not-a-knot spline", f, x, y); - checkNotAKnotCondition("Not-a-knot spline", f); - checkSymmetry("Not-a-knot spline", f, x[0]); + f.update(); + checkValues("MC not-a-knot spline", f, x, y); + checkSymmetry("MC not-a-knot spline", f, x[0]); + } + [TestMethod()] + public void testDerivativeEndConditions() { - // MC not-a-knot spline - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - checkValues("MC not-a-knot spline", f, x, y); - checkSymmetry("MC not-a-knot spline", f, x[0]); - } + //("Testing derivative end-conditions for spline interpolation..."); - [TestMethod()] - public void testDerivativeEndConditions() { + int n = 4; - //("Testing derivative end-conditions for spline interpolation..."); + List x, y; + x = xRange(-2.0, 2.0, n); + y = parabolic(x); - int n = 4; + // Not-a-knot spline + CubicInterpolation f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + checkValues("Not-a-knot spline", f, x, y); + check1stDerivativeValue("Not-a-knot spline", f, x[0], 4.0); + check1stDerivativeValue("Not-a-knot spline", f, x[n-1], -4.0); + check2ndDerivativeValue("Not-a-knot spline", f, x[0], -2.0); + check2ndDerivativeValue("Not-a-knot spline", f, x[n-1], -2.0); - List x, y; - x = xRange(-2.0, 2.0, n); - y = parabolic(x); - // Not-a-knot spline - CubicInterpolation f = new CubicInterpolation(x, x.Count, y, + // Clamped spline + f = new CubicInterpolation(x, x.Count, y, CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, + CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); + f.update(); + checkValues("Clamped spline", f, x, y); + check1stDerivativeValue("Clamped spline", f, x[0], 4.0); + check1stDerivativeValue("Clamped spline", f, x[n-1], -4.0); + check2ndDerivativeValue("Clamped spline", f, x[0], -2.0); + check2ndDerivativeValue("Clamped spline", f, x[n-1], -2.0); + + + // SecondDerivative spline + f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, false, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); + + f.update(); + checkValues("SecondDerivative spline", f, x, y); + check1stDerivativeValue("SecondDerivative spline", f, x[0], 4.0); + check1stDerivativeValue("SecondDerivative spline", f, x[n-1], -4.0); + check2ndDerivativeValue("SecondDerivative spline", f, x[0], -2.0); + check2ndDerivativeValue("SecondDerivative spline", f, x[n-1], -2.0); + + // MC Not-a-knot spline + f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.NotAKnot, 0, CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - checkValues("Not-a-knot spline", f, x, y); - check1stDerivativeValue("Not-a-knot spline", f, x[0], 4.0); - check1stDerivativeValue("Not-a-knot spline", f, x[n-1], -4.0); - check2ndDerivativeValue("Not-a-knot spline", f, x[0], -2.0); - check2ndDerivativeValue("Not-a-knot spline", f, x[n-1], -2.0); - - - // Clamped spline - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, - CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); - f.update(); - checkValues("Clamped spline", f, x, y); - check1stDerivativeValue("Clamped spline", f, x[0], 4.0); - check1stDerivativeValue("Clamped spline", f, x[n-1], -4.0); - check2ndDerivativeValue("Clamped spline", f, x[0], -2.0); - check2ndDerivativeValue("Clamped spline", f, x[n-1], -2.0); - - - // SecondDerivative spline - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, false, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); - - f.update(); - checkValues("SecondDerivative spline", f, x, y); - check1stDerivativeValue("SecondDerivative spline", f, x[0], 4.0); - check1stDerivativeValue("SecondDerivative spline", f, x[n-1], -4.0); - check2ndDerivativeValue("SecondDerivative spline", f, x[0], -2.0); - check2ndDerivativeValue("SecondDerivative spline", f, x[n-1], -2.0); - - // MC Not-a-knot spline - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - - f.update(); - checkValues("MC Not-a-knot spline", f, x, y); - check1stDerivativeValue("MC Not-a-knot spline", f, x[0], 4.0); - check1stDerivativeValue("MC Not-a-knot spline", f, x[n-1], -4.0); - check2ndDerivativeValue("MC Not-a-knot spline", f, x[0], -2.0); - check2ndDerivativeValue("MC Not-a-knot spline", f, x[n-1], -2.0); - - - // MC Clamped spline - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, - CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); - - f.update(); - checkValues("MC Clamped spline", f, x, y); - check1stDerivativeValue("MC Clamped spline", f, x[0], 4.0); - check1stDerivativeValue("MC Clamped spline", f, x[n-1], -4.0); - check2ndDerivativeValue("MC Clamped spline", f, x[0], -2.0); - check2ndDerivativeValue("MC Clamped spline", f, x[n-1], -2.0); - - // MC SecondDerivative spline - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); - - f.update(); - checkValues("MC SecondDerivative spline", f, x, y); - check1stDerivativeValue("MC SecondDerivative spline", f, x[0], 4.0); - check1stDerivativeValue("MC SecondDerivative spline", f, x[n-1], -4.0); - check2ndDerivativeValue("MC SecondDerivative spline", f, x[0], -2.0); - check2ndDerivativeValue("MC SecondDerivative spline", f, x[n-1], -2.0); - } - - /* See R. L. Dougherty, A. Edelman, J. M. Hyman, - "Nonnegativity-, Monotonicity-, or Convexity-Preserving CubicSpline and Quintic - Hermite Interpolation" - Mathematics Of Computation, v. 52, n. 186, April 1989, pp. 471-494. - */ - [TestMethod()] - public void testNonRestrictiveHymanFilter() { - - //("Testing non-restrictive Hyman filter..."); - - int n = 4; - - List x, y; - x = xRange(-2.0, 2.0, n); - y = parabolic(x); - double zero=0.0, interpolated, expected=0.0; - - // MC Not-a-knot spline - CubicInterpolation f = new CubicInterpolation(x, x.Count, y, + f.update(); + checkValues("MC Not-a-knot spline", f, x, y); + check1stDerivativeValue("MC Not-a-knot spline", f, x[0], 4.0); + check1stDerivativeValue("MC Not-a-knot spline", f, x[n-1], -4.0); + check2ndDerivativeValue("MC Not-a-knot spline", f, x[0], -2.0); + check2ndDerivativeValue("MC Not-a-knot spline", f, x[n-1], -2.0); + + + // MC Clamped spline + f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, + CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); + + f.update(); + checkValues("MC Clamped spline", f, x, y); + check1stDerivativeValue("MC Clamped spline", f, x[0], 4.0); + check1stDerivativeValue("MC Clamped spline", f, x[n-1], -4.0); + check2ndDerivativeValue("MC Clamped spline", f, x[0], -2.0); + check2ndDerivativeValue("MC Clamped spline", f, x[n-1], -2.0); + + + // MC SecondDerivative spline + f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); + + f.update(); + checkValues("MC SecondDerivative spline", f, x, y); + check1stDerivativeValue("MC SecondDerivative spline", f, x[0], 4.0); + check1stDerivativeValue("MC SecondDerivative spline", f, x[n-1], -4.0); + check2ndDerivativeValue("MC SecondDerivative spline", f, x[0], -2.0); + check2ndDerivativeValue("MC SecondDerivative spline", f, x[n-1], -2.0); + } + + /* See R. L. Dougherty, A. Edelman, J. M. Hyman, + "Nonnegativity-, Monotonicity-, or Convexity-Preserving CubicSpline and Quintic + Hermite Interpolation" + Mathematics Of Computation, v. 52, n. 186, April 1989, pp. 471-494. + */ + [TestMethod()] + public void testNonRestrictiveHymanFilter() { + + //("Testing non-restrictive Hyman filter..."); + + int n = 4; + + List x, y; + x = xRange(-2.0, 2.0, n); + y = parabolic(x); + double zero=0.0, interpolated, expected=0.0; + + // MC Not-a-knot spline + CubicInterpolation f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.NotAKnot, 0, + CubicInterpolation.BoundaryCondition.NotAKnot, 0); + f.update(); + interpolated = f.value(zero); + if (Math.Abs(interpolated-expected)>1e-15) { + Assert.Fail("MC not-a-knot spline" + + " interpolation failed at x = " + zero + + "\n interpolated value: " + interpolated + + "\n expected value: " + expected + + "\n error: " + + Math.Abs(interpolated-expected)); + } + + + // MC Clamped spline + f = new CubicInterpolation(x, x.Count, y, CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.NotAKnot, 0, - CubicInterpolation.BoundaryCondition.NotAKnot, 0); - f.update(); - interpolated = f.value(zero); - if (Math.Abs(interpolated-expected)>1e-15) { - Assert.Fail("MC not-a-knot spline" - + " interpolation failed at x = " + zero - + "\n interpolated value: " + interpolated - + "\n expected value: " + expected - + "\n error: " - + Math.Abs(interpolated-expected)); + CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, + CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); + f.update(); + interpolated = f.value(zero); + if (Math.Abs(interpolated-expected)>1e-15) { + Assert.Fail("MC clamped spline" + + " interpolation failed at x = " + zero + + "\n interpolated value: " + interpolated + + "\n expected value: " + expected + + "\n error: " + + Math.Abs(interpolated-expected)); + } + + + // MC SecondDerivative spline + f = new CubicInterpolation(x, x.Count, y, + CubicInterpolation.DerivativeApprox.Spline, true, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, + CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); + f.update(); + interpolated = f.value(zero); + if (Math.Abs(interpolated-expected)>1e-15) { + Assert.Fail("MC SecondDerivative spline" + + " interpolation failed at x = " + zero + + "\n interpolated value: " + interpolated + + "\n expected value: " + expected + + "\n error: " + + Math.Abs(interpolated-expected)); + } + + } + + + //[TestMethod()] + //public void testMultiSpline() + //{ + // // Testing N-dimensional cubic spline... + + // List dim = new List() { 6, 5, 5, 6, 4 }; + + // List args = new InitializedList(5), + // offsets = new List() { 1.005, 14.0, 33.005, 35.025, 19.025 }; + + // double s = args[0] = offsets[0], + // t = args[1] = offsets[1], + // u = args[2] = offsets[2], + // v = args[3] = offsets[3], + // w = args[4] = offsets[4]; + + // int i, j, k, l, m; + + // SplineGrid grid = new SplineGrid(5); + + // double r = 0.15; + + // for (i = 0; i < 5; ++i) { + // double temp = offsets[i]; + // for (j = 0; j < dim[i]; temp += r, ++j) + // grid[i].Add(temp); + // } + + // r = 0.01; + + // MultiCubicSpline<5>::data_table y5(dim); + + // for (i = 0; i < dim[0]; ++i) + // for (j = 0; j < dim[1]; ++j) + // for (k = 0; k < dim[2]; ++k) + // for (l = 0; l < dim[3]; ++l) + // for (m = 0; m < dim[4]; ++m) + // y5[i][j][k][l][m] = + // multif(grid[0][i], grid[1][j], grid[2][k], + // grid[3][l], grid[4][m]); + + // MultiCubicSpline<5> cs(grid, y5); + // /* it would fail with + // for (i = 0; i < dim[0]; ++i) + // for (j = 0; j < dim[1]; ++j) + // for (k = 0; k < dim[2]; ++k) + // for (l = 0; l < dim[3]; ++l) + // for (m = 0; m < dim[4]; ++m) { + // */ + // for (i = 1; i < dim[0]-1; ++i) + // for (j = 1; j < dim[1]-1; ++j) + // for (k = 1; k < dim[2]-1; ++k) + // for (l = 1; l < dim[3]-1; ++l) + // for (m = 1; m < dim[4]-1; ++m) { + // s = grid[0][i]; + // t = grid[1][j]; + // u = grid[2][k]; + // v = grid[3][l]; + // w = grid[4][m]; + // double interpolated = cs(args); + // double expected = y5[i][j][k][l][m]; + // double error = Math.Abs(interpolated-expected); + // double tolerance = 1e-16; + // if (error > tolerance) { + // Assert.Fail( + // "\n At (" + // + s + "," + t + "," + u + "," + // + v + "," + w + "):" + // + "\n interpolated: " + interpolated + // + "\n actual value: " + expected + // + "\n error: " + error + // + "\n tolerance: " + tolerance); + // } + // } + + + // ulong seed = 42; + // SobolRsg rsg = new SobolRsg(5, seed); + + // double tolerance = 1.7e-4; + // // actually tested up to 2^21-1=2097151 Sobol draws + // for (i = 0; i < 1023; ++i) { + // List next = rsg.nextSequence().value; + // s = grid[0].front() + next[0]*(grid[0].back()-grid[0].front()); + // t = grid[1].front() + next[1]*(grid[1].back()-grid[1].front()); + // u = grid[2].front() + next[2]*(grid[2].back()-grid[2].front()); + // v = grid[3].front() + next[3]*(grid[3].back()-grid[3].front()); + // w = grid[4].front() + next[4]*(grid[4].back()-grid[4].front()); + // double interpolated = cs(args), expected = multif(s, t, u, v, w); + // double error = Math.Abs(interpolated-expected); + // if (error > tolerance) { + // Assert.Fail( + // "\n At (" + // + s + "," + t + "," + u + "," + v + "," + w + "):" + // + "\n interpolated: " + interpolated + // + "\n actual value: " + expected + // + "\n error: " + error + // + "\n tolerance: " + tolerance); + // } + // } + //} + + class NotThrown : ApplicationException { } + + [TestMethod()] + public void testAsFunctor() { + + //("Testing use of interpolations as functors..."); + + List x = new List() { 0.0, 1.0, 2.0, 3.0, 4.0 }; + List y = new List() { 5.0, 4.0, 3.0, 2.0, 1.0 }; + + Interpolation f = new LinearInterpolation(x, x.Count, y); + f.update(); + + List x2 = new List() { -2.0, -1.0, 0.0, 1.0, 3.0, 4.0, 5.0, 6.0, 7.0 }; + int N = x2.Count; + List y2 = new InitializedList(N); + double tolerance = 1.0e-12; + + // case 1: extrapolation not allowed + try { + y2 = x2.ConvertAll(f.value); + throw new NotThrown(); + } catch (NotThrown) { + throw new ApplicationException("failed to throw exception when trying to extrapolate"); + } catch { } + + // case 2: enable extrapolation + f.enableExtrapolation(); + y2 = new InitializedList(N); + y2 = x2.ConvertAll(f.value); + for (int i=0; i tolerance) + Assert.Fail( + "failed to reproduce " + (i+1) + " expected datum" + + "\n expected: " + expected + + "\n calculated: " + y2[i] + + "\n error: " + Math.Abs(y2[i]-expected)); + } + } + + [TestMethod()] + public void testBackwardFlat() { + + //("Testing backward-flat interpolation..."); + + List x = new List() { 0.0, 1.0, 2.0, 3.0, 4.0 }; + List y = new List() { 5.0, 4.0, 3.0, 2.0, 1.0 }; + + Interpolation f = new BackwardFlatInterpolation(x, x.Count, y); + f.update(); + + int N = x.Count; + int i; + double tolerance = 1.0e-12, p, calculated, expected; + + // at original points + for (i=0; i tolerance) + Assert.Fail( + "failed to reproduce " + (i+1) + " datum" + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + } + + // at middle points + for (i=0; i tolerance) + Assert.Fail( + "failed to interpolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + } + + // outside the original range + f.enableExtrapolation(); + + p = x[0] - 0.5; + calculated = f.value(p); + expected = y[0]; + if (Math.Abs(expected-calculated) > tolerance) + Assert.Fail( + "failed to extrapolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + + p = x[N-1] + 0.5; + calculated = f.value(p); + expected = y[N-1]; + if (Math.Abs(expected-calculated) > tolerance) + Assert.Fail( + "failed to extrapolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + + // primitive at original points + calculated = f.primitive(x[0]); + expected = 0.0; + if (Math.Abs(expected-calculated) > tolerance) + Assert.Fail( + "failed to calculate primitive at " + x[0] + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + + double sum = 0.0; + for (i=1; i tolerance) + Assert.Fail( + "failed to calculate primitive at " + x[i] + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + } + + // primitive at middle points + sum = 0.0; + for (i=0; i tolerance) + Assert.Fail( + "failed to calculate primitive at " + x[i] + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + } + + } + + [TestMethod()] + public void testForwardFlat() { + + //("Testing forward-flat interpolation..."); + + List x = new List() { 0.0, 1.0, 2.0, 3.0, 4.0 }; + List y = new List() { 5.0, 4.0, 3.0, 2.0, 1.0 }; + + Interpolation f = new ForwardFlatInterpolation(x, x.Count, y); + f.update(); + + int N = x.Count; + int i; + double tolerance = 1.0e-12, p, calculated, expected; + + // at original points + for (i=0; i tolerance) + Assert.Fail( + "failed to reproduce " + (i+1) + " datum" + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + } + + // at middle points + for (i=0; i tolerance) + Assert.Fail( + "failed to interpolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + } + + // outside the original range + f.enableExtrapolation(); + + p = x[0] - 0.5; + calculated = f.value(p); + expected = y[0]; + if (Math.Abs(expected-calculated) > tolerance) + Assert.Fail( + "failed to extrapolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + + p = x[N-1] + 0.5; + calculated = f.value(p); + expected = y[N-1]; + if (Math.Abs(expected-calculated) > tolerance) + Assert.Fail( + "failed to extrapolate correctly at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + + // primitive at original points + calculated = f.primitive(x[0]); + expected = 0.0; + if (Math.Abs(expected-calculated) > tolerance) + Assert.Fail( + "failed to calculate primitive at " + x[0] + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + + double sum = 0.0; + for (i=1; i tolerance) + Assert.Fail( + "failed to calculate primitive at " + x[i] + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + } + + // primitive at middle points + sum = 0.0; + for (i=0; i tolerance) + Assert.Fail( + "failed to calculate primitive at " + p + + "\n expected: " + expected + + "\n calculated: " + calculated + + "\n error: " + Math.Abs(calculated-expected)); + } + } + + [TestMethod()] + public void testSabrInterpolation() + { + // Testing Sabr interpolation... + + // Test SABR function against input volatilities + double tolerance = 1.0e-12; + List strikes = new InitializedList(31); + List volatilities = new InitializedList( 31 ); + // input strikes + strikes[0] = 0.03 ; strikes[1] = 0.032 ; strikes[2] = 0.034 ; + strikes[3] = 0.036 ; strikes[4] = 0.038 ; strikes[5] = 0.04 ; + strikes[6] = 0.042 ; strikes[7] = 0.044 ; strikes[8] = 0.046 ; + strikes[9] = 0.048 ; strikes[10] = 0.05 ; strikes[11] = 0.052 ; + strikes[12] = 0.054 ; strikes[13] = 0.056 ; strikes[14] = 0.058 ; + strikes[15] = 0.06 ; strikes[16] = 0.062 ; strikes[17] = 0.064 ; + strikes[18] = 0.066 ; strikes[19] = 0.068 ; strikes[20] = 0.07 ; + strikes[21] = 0.072 ; strikes[22] = 0.074 ; strikes[23] = 0.076 ; + strikes[24] = 0.078 ; strikes[25] = 0.08 ; strikes[26] = 0.082 ; + strikes[27] = 0.084 ; strikes[28] = 0.086 ; strikes[29] = 0.088; + strikes[30] = 0.09; + // input volatilities + volatilities[0] = 1.16725837321531 ; volatilities[1] = 1.15226075991385 ; volatilities[2] = 1.13829711098834 ; + volatilities[3] = 1.12524190877505 ; volatilities[4] = 1.11299079244474 ; volatilities[5] = 1.10145609357162 ; + volatilities[6] = 1.09056348513411 ; volatilities[7] = 1.08024942745106 ; volatilities[8] = 1.07045919457758 ; + volatilities[9] = 1.06114533019077 ; volatilities[10] = 1.05226642581503 ; volatilities[11] = 1.04378614411707 ; + volatilities[12] = 1.03567243073732 ; volatilities[13] = 1.0278968727451 ; volatilities[14] = 1.02043417226345 ; + volatilities[15] = 1.01326171139321 ; volatilities[16] = 1.00635919013311 ; volatilities[17] = 0.999708323124949 ; + volatilities[18] = 0.993292584155381 ; volatilities[19] = 0.987096989695393 ; volatilities[20] = 0.98110791455717 ; + volatilities[21] = 0.975312934134512 ; volatilities[22] = 0.969700688771689 ; volatilities[23] = 0.964260766651027; + volatilities[24] = 0.958983602256592 ; volatilities[25] = 0.953860388001395 ; volatilities[26] = 0.948882997029509 ; + volatilities[27] = 0.944043915545469 ; volatilities[28] = 0.939336183299237 ; volatilities[29] = 0.934753341079515 ; + volatilities[30] = 0.930289384251337; + + double expiry = 1.0; + double forward = 0.039; + // input SABR coefficients (corresponding to the vols above) + double initialAlpha = 0.3; + double initialBeta = 0.6; + double initialNu = 0.02; + double initialRho = 0.01; + // calculate SABR vols and compare with input vols + for(int i=0; i< strikes.Count; i++) + { + double calculatedVol = Utils.sabrVolatility(strikes[i], forward, expiry, + initialAlpha, initialBeta, + initialNu, initialRho); + if (Math.Abs(volatilities[i]-calculatedVol) > tolerance) + Assert.Fail( "failed to calculate Sabr function at strike " + strikes[i] + + "\n expected: " + volatilities[i] + + "\n calculated: " + calculatedVol + + "\n error: " + Math.Abs(calculatedVol-volatilities[i])); + } + + // Test SABR calibration against input parameters + // Use default values (but not null, since then parameters + // will then not be fixed during optimization, see the + // interpolation constructor, thus rendering the test cases + // with fixed parameters non-sensical) + double alphaGuess = Math.Sqrt(0.2); + double betaGuess = 0.5; + double nuGuess = Math.Sqrt(0.4); + double rhoGuess = 0.0; + + bool[] vegaWeighted= {true, false}; + bool[] isAlphaFixed= {true, false}; + bool[] isBetaFixed= {true, false}; + bool[] isNuFixed= {true, false}; + bool[] isRhoFixed= {true, false}; + + double calibrationTolerance = 5.0e-8; + // initialize optimization methods + List methods_ = new List(); + methods_.Add( new Simplex(0.01)); + methods_.Add( new LevenbergMarquardt(1e-8, 1e-8, 1e-8)); + // Initialize end criteria + EndCriteria endCriteria = new EndCriteria(100000, 100, 1e-8, 1e-8, 1e-8); + // Test looping over all possibilities + for (int j=0; j calibrationTolerance) { + Assert.Fail("\nfailed to calibrate alpha Sabr parameter:" + + "\n expected: " + initialAlpha + + "\n calibrated: " + calibratedAlpha + + "\n error: " + error); + failed = true; + } + // Beta + error = Math.Abs(initialBeta-calibratedBeta); + if (error > calibrationTolerance) { + Assert.Fail("\nfailed to calibrate beta Sabr parameter:" + + "\n expected: " + initialBeta + + "\n calibrated: " + calibratedBeta + + "\n error: " + error); + failed = true; + } + // Nu + error = Math.Abs(initialNu-calibratedNu); + if (error > calibrationTolerance) { + Assert.Fail("\nfailed to calibrate nu Sabr parameter:" + + "\n expected: " + initialNu + + "\n calibrated: " + calibratedNu + + "\n error: " + error); + failed = true; + } + // Rho + error = Math.Abs(initialRho-calibratedRho); + if (error > calibrationTolerance) { + Assert.Fail("\nfailed to calibrate rho Sabr parameter:" + + "\n expected: " + initialRho + + "\n calibrated: " + calibratedRho + + "\n error: " + error); + failed = true; + } + + if (failed) + Assert.Fail("\nSabr calibration failure:" + + "\n isAlphaFixed: " + isAlphaFixed[k_a] + + "\n isBetaFixed: " + isBetaFixed[k_b] + + "\n isNuFixed: " + isNuFixed[k_n] + + "\n isRhoFixed: " + isRhoFixed[k_r] + + "\n vegaWeighted[i]: " + vegaWeighted[i]); + } + } + } + } } - - - // MC Clamped spline - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.FirstDerivative, 4.0, - CubicInterpolation.BoundaryCondition.FirstDerivative, -4.0); - f.update(); - interpolated = f.value(zero); - if (Math.Abs(interpolated-expected)>1e-15) { - Assert.Fail("MC clamped spline" - + " interpolation failed at x = " + zero - + "\n interpolated value: " + interpolated - + "\n expected value: " + expected - + "\n error: " - + Math.Abs(interpolated-expected)); + } + } + + [TestMethod()] + public void testKernelInterpolation() + { + + // Testing kernel 1D interpolation + + List deltaGrid = new InitializedList(5); // x-values, here delta in FX + deltaGrid[0]=0.10; deltaGrid[1]=0.25; deltaGrid[2]=0.50; + deltaGrid[3]=0.75; deltaGrid[4]=0.90; + + List yd1 = new InitializedList( deltaGrid.Count ); // test y-values 1 + yd1[0]=11.275; yd1[1]=11.125; yd1[2]=11.250; + yd1[3]=11.825; yd1[4]=12.625; + + List yd2 = new InitializedList( deltaGrid.Count ); // test y-values 2 + yd2[0]=16.025; yd2[1]=13.450; yd2[2]=11.350; + yd2[3]=10.150; yd2[4]=10.075; + + List yd3 = new InitializedList( deltaGrid.Count ); // test y-values 3 + yd3[0]=10.3000; yd3[1]=9.6375; yd3[2]=9.2000; + yd3[3]=9.1125; yd3[4]=9.4000; + + List > yd = new List>(); + yd.Add(yd1); + yd.Add(yd2); + yd.Add(yd3); + + List lambdaVec = new InitializedList( 5 ); + lambdaVec[0]=0.05; lambdaVec[1]=0.50; lambdaVec[2]=0.75; + lambdaVec[3]=1.65; lambdaVec[4]=2.55; + + double tolerance = 2.0e-5; + + double expectedVal; + double calcVal; + + // Check that y-values at knots are exactly the feeded y-values, + // irrespective of kernel parameters + for (int i=0; i currY = yd[j]; + KernelInterpolation f = new KernelInterpolation(deltaGrid, deltaGrid.Count,currY, myKernel); + f.update(); + + for (int dIt=0; dIt< deltaGrid.Count; ++dIt) + { + expectedVal=currY[dIt]; + calcVal=f.value(deltaGrid[dIt]); + + if (Math.Abs(expectedVal-calcVal)>tolerance) + { + + Assert.Fail("Kernel interpolation failed at x = " + + deltaGrid[dIt] + + "\n interpolated value: " + calcVal + + "\n expected value: " + expectedVal + + "\n error: " + + Math.Abs(expectedVal-calcVal)); + + } + } } + } + List testDeltaGrid = new InitializedList( deltaGrid.Count ); + testDeltaGrid[0]=0.121; testDeltaGrid[1]=0.279; testDeltaGrid[2]=0.678; + testDeltaGrid[3]=0.790; testDeltaGrid[4]=0.980; - // MC SecondDerivative spline - f = new CubicInterpolation(x, x.Count, y, - CubicInterpolation.DerivativeApprox.Spline, true, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, -2.0); - f.update(); - interpolated = f.value(zero); - if (Math.Abs(interpolated-expected)>1e-15) { - Assert.Fail("MC SecondDerivative spline" - + " interpolation failed at x = " + zero - + "\n interpolated value: " + interpolated - + "\n expected value: " + expected - + "\n error: " - + Math.Abs(interpolated-expected)); - } + // Gaussian Kernel values for testDeltaGrid with a standard + // deviation of 2.05 (the value is arbitrary.) Source: parrallel + // implementation in R, no literature sources found - } + List ytd1 = new InitializedList( testDeltaGrid.Count ); + ytd1[0]=11.23847; ytd1[1]=11.12003; ytd1[2]=11.58932; + ytd1[3]=11.99168; ytd1[4]=13.29650; - //[TestMethod()] - //public void testMultiSpline() { - // //("Testing N-dimensional cubic spline..."); - - // List dim = new List() { 6, 5, 5, 6, 4 }; - - // List args = new InitializedList(5), - // offsets = new List() { 1.005, 14.0, 33.005, 35.025, 19.025 }; - - // double s = args[0] = offsets[0], - // t = args[1] = offsets[1], - // u = args[2] = offsets[2], - // v = args[3] = offsets[3], - // w = args[4] = offsets[4]; - - // int i, j, k, l, m; - - // SplineGrid grid = new SplineGrid(5); - - // double r = 0.15; - - // for (i = 0; i < 5; ++i) { - // double temp = offsets[i]; - // for (j = 0; j < dim[i]; temp += r, ++j) - // grid[i].Add(temp); - // } - - // r = 0.01; - - // MultiCubicSpline<5>::data_table y5(dim); - - // for (i = 0; i < dim[0]; ++i) - // for (j = 0; j < dim[1]; ++j) - // for (k = 0; k < dim[2]; ++k) - // for (l = 0; l < dim[3]; ++l) - // for (m = 0; m < dim[4]; ++m) - // y5[i][j][k][l][m] = - // multif(grid[0][i], grid[1][j], grid[2][k], - // grid[3][l], grid[4][m]); - - // MultiCubicSpline<5> cs(grid, y5); - // /* it would fail with - // for (i = 0; i < dim[0]; ++i) - // for (j = 0; j < dim[1]; ++j) - // for (k = 0; k < dim[2]; ++k) - // for (l = 0; l < dim[3]; ++l) - // for (m = 0; m < dim[4]; ++m) { - // */ - // for (i = 1; i < dim[0]-1; ++i) - // for (j = 1; j < dim[1]-1; ++j) - // for (k = 1; k < dim[2]-1; ++k) - // for (l = 1; l < dim[3]-1; ++l) - // for (m = 1; m < dim[4]-1; ++m) { - // s = grid[0][i]; - // t = grid[1][j]; - // u = grid[2][k]; - // v = grid[3][l]; - // w = grid[4][m]; - // double interpolated = cs(args); - // double expected = y5[i][j][k][l][m]; - // double error = Math.Abs(interpolated-expected); - // double tolerance = 1e-16; - // if (error > tolerance) { - // Assert.Fail( - // "\n At (" - // + s + "," + t + "," + u + "," - // + v + "," + w + "):" - // + "\n interpolated: " + interpolated - // + "\n actual value: " + expected - // + "\n error: " + error - // + "\n tolerance: " + tolerance); - // } - // } - - - // ulong seed = 42; - // SobolRsg rsg = new SobolRsg(5, seed); - - // double tolerance = 1.7e-4; - // // actually tested up to 2^21-1=2097151 Sobol draws - // for (i = 0; i < 1023; ++i) { - // List next = rsg.nextSequence().value; - // s = grid[0].front() + next[0]*(grid[0].back()-grid[0].front()); - // t = grid[1].front() + next[1]*(grid[1].back()-grid[1].front()); - // u = grid[2].front() + next[2]*(grid[2].back()-grid[2].front()); - // v = grid[3].front() + next[3]*(grid[3].back()-grid[3].front()); - // w = grid[4].front() + next[4]*(grid[4].back()-grid[4].front()); - // double interpolated = cs(args), expected = multif(s, t, u, v, w); - // double error = Math.Abs(interpolated-expected); - // if (error > tolerance) { - // Assert.Fail( - // "\n At (" - // + s + "," + t + "," + u + "," + v + "," + w + "):" - // + "\n interpolated: " + interpolated - // + "\n actual value: " + expected - // + "\n error: " + error - // + "\n tolerance: " + tolerance); - // } - // } - //} - - class NotThrown : ApplicationException { } - - [TestMethod()] - public void testAsFunctor() { - - //("Testing use of interpolations as functors..."); - - List x = new List() { 0.0, 1.0, 2.0, 3.0, 4.0 }; - List y = new List() { 5.0, 4.0, 3.0, 2.0, 1.0 }; - - Interpolation f = new LinearInterpolation(x, x.Count, y); - f.update(); + List ytd2 = new InitializedList( testDeltaGrid.Count ); + ytd2[0]=15.55922; ytd2[1]=13.11088; ytd2[2]=10.41615; + ytd2[3]=10.05153; ytd2[4]=10.50741; - List x2 = new List() { -2.0, -1.0, 0.0, 1.0, 3.0, 4.0, 5.0, 6.0, 7.0 }; - int N = x2.Count; - List y2 = new InitializedList(N); - double tolerance = 1.0e-12; - - // case 1: extrapolation not allowed - try { - y2 = x2.ConvertAll(f.value); - throw new NotThrown(); - } catch (NotThrown) { - throw new ApplicationException("failed to throw exception when trying to extrapolate"); - } catch { } - - // case 2: enable extrapolation - f.enableExtrapolation(); - y2 = new InitializedList(N); - y2 = x2.ConvertAll(f.value); - for (int i=0; i tolerance) - Assert.Fail( - "failed to reproduce " + (i+1) + " expected datum" - + "\n expected: " + expected - + "\n calculated: " + y2[i] - + "\n error: " + Math.Abs(y2[i]-expected)); - } - } + List ytd3 = new InitializedList( testDeltaGrid.Count ); + ytd3[0]= 10.17473; ytd3[1]= 9.557842; ytd3[2]= 9.09339; + ytd3[3]= 9.149687; ytd3[4]= 9.779971; - [TestMethod()] - public void testBackwardFlat() { + List > ytd = new List>(); + ytd.Add(ytd1); + ytd.Add(ytd2); + ytd.Add(ytd3); - //("Testing backward-flat interpolation..."); + GaussianKernel myKernel2 = new GaussianKernel(0,2.05); - List x = new List() { 0.0, 1.0, 2.0, 3.0, 4.0 }; - List y = new List() { 5.0, 4.0, 3.0, 2.0, 1.0 }; + for (int j=0; j< ytd.Count; ++j) + { + List currY=yd[j]; + List currTY=ytd[j]; - Interpolation f = new BackwardFlatInterpolation(x, x.Count, y); + // Build interpolation according to original grid + y-values + KernelInterpolation f = new KernelInterpolation(deltaGrid, deltaGrid.Count,currY, myKernel2); f.update(); - int N = x.Count; - int i; - double tolerance = 1.0e-12, p, calculated, expected; - - // at original points - for (i=0; i tolerance) - Assert.Fail( - "failed to reproduce " + (i+1) + " datum" - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + // test values at test Grid + for (int dIt=0; dIt< testDeltaGrid.Count; ++dIt) + { + expectedVal=currTY[dIt]; + f.enableExtrapolation();// allow extrapolation + + calcVal=f.value(testDeltaGrid[dIt]); + if (Math.Abs(expectedVal-calcVal)>tolerance) + { + + Assert.Fail("Kernel interpolation failed at x = " + + deltaGrid[dIt] + + "\n interpolated value: " + calcVal + + "\n expected value: " + expectedVal + + "\n error: " + + Math.Abs(expectedVal-calcVal)); + } } - - // at middle points - for (i=0; i tolerance) - Assert.Fail( - "failed to interpolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + + } + + } + + [TestMethod()] + public void testKernelInterpolation2D() + { + // No test values known from the literature. + // Testing for consistency of input output data + // at the nodes + + // Testing kernel 2D interpolation... + + double mean=0.0, var=0.18; + GaussianKernel myKernel = new GaussianKernel(mean,var); + + List xVec = new InitializedList(10); + xVec[0] = 0.10; xVec[1] = 0.20; xVec[2] = 0.30; xVec[3] = 0.40; + xVec[4] = 0.50; xVec[5] = 0.60; xVec[6] = 0.70; xVec[7] = 0.80; + xVec[8] = 0.90; xVec[9] = 1.00; + + List yVec = new InitializedList( 3 ); + yVec[0] = 1.0; yVec[1] = 2.0; yVec[2] = 3.5; + + Matrix M = new Matrix(xVec.Count,yVec.Count); + + M[0,0]=0.25; M[1,0]=0.24; M[2,0]=0.23; M[3,0]=0.20; M[4,0]=0.19; + M[5,0]=0.20; M[6,0]=0.21; M[7,0]=0.22; M[8,0]=0.26; M[9,0]=0.29; + + M[0,1]=0.27; M[1,1]=0.26; M[2,1]=0.25; M[3,1]=0.22; M[4,1]=0.21; + M[5,1]=0.22; M[6,1]=0.23; M[7,1]=0.24; M[8,1]=0.28; M[9,1]=0.31; + + M[0,2]=0.21; M[1,2]=0.22; M[2,2]=0.27; M[3,2]=0.29; M[4,2]=0.24; + M[5,2]=0.28; M[6,2]=0.25; M[7,2]=0.22; M[8,2]=0.29; M[9,2]=0.30; + + KernelInterpolation2D kernel2D = new KernelInterpolation2D(xVec,xVec.Count, yVec,yVec.Count,M,myKernel); + + double calcVal,expectedVal; + double tolerance = 1.0e-10; + + for(int i=0;itolerance){ + + Assert.Fail("2D Kernel interpolation failed at x = " + xVec[i] + + ", y = " + yVec[j] + + "\n interpolated value: " + calcVal + + "\n expected value: " + expectedVal + + "\n error: " + + Math.Abs(expectedVal-calcVal)); + } } - - // outside the original range - f.enableExtrapolation(); - - p = x[0] - 0.5; - calculated = f.value(p); - expected = y[0]; - if (Math.Abs(expected-calculated) > tolerance) - Assert.Fail( - "failed to extrapolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - - p = x[N-1] + 0.5; - calculated = f.value(p); - expected = y[N-1]; - if (Math.Abs(expected-calculated) > tolerance) - Assert.Fail( - "failed to extrapolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - - // primitive at original points - calculated = f.primitive(x[0]); - expected = 0.0; - if (Math.Abs(expected-calculated) > tolerance) - Assert.Fail( - "failed to calculate primitive at " + x[0] - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - - double sum = 0.0; - for (i=1; i tolerance) - Assert.Fail( - "failed to calculate primitive at " + x[i] - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + } + + // alternative data set + List xVec1 = new InitializedList(4); + xVec1[0] = 80.0; xVec1[1] = 90.0; xVec1[2] = 100.0; xVec1[3] = 110.0; + + List yVec1 = new InitializedList(8); + yVec1[0] = 0.5; yVec1[1] = 0.7; yVec1[2] = 1.0; yVec1[3] = 2.0; + yVec1[4] = 3.5; yVec1[5] = 4.5; yVec1[6] = 5.5; yVec1[7] = 6.5; + + Matrix M1 = new Matrix(xVec1.Count,yVec1.Count); + M1[0,0]=10.25; M1[1,0]=12.24;M1[2,0]=14.23;M1[3,0]=17.20; + M1[0,1]=12.25; M1[1,1]=15.24;M1[2,1]=16.23;M1[3,1]=16.20; + M1[0,2]=12.25; M1[1,2]=13.24;M1[2,2]=13.23;M1[3,2]=17.20; + M1[0,3]=13.25; M1[1,3]=15.24;M1[2,3]=12.23;M1[3,3]=19.20; + M1[0,4]=14.25; M1[1,4]=16.24;M1[2,4]=13.23;M1[3,4]=12.20; + M1[0,5]=15.25; M1[1,5]=17.24;M1[2,5]=14.23;M1[3,5]=12.20; + M1[0,6]=16.25; M1[1,6]=13.24;M1[2,6]=15.23;M1[3,6]=10.20; + M1[0,7]=14.25; M1[1,7]=14.24;M1[2,7]=16.23;M1[3,7]=19.20; + + // test with another kernel + KernelInterpolation2D kernel2DEp = new KernelInterpolation2D( xVec1, xVec1.Count, yVec1, yVec1.Count, M1, new epanechnikovKernel() ); + for(int i=0;itolerance){ + + Assert.Fail("2D Epanechnkikov Kernel interpolation failed at x = " + xVec1[i] + + ", y = " + yVec1[j] + + "\n interpolated value: " + calcVal + + "\n expected value: " + expectedVal + + "\n error: " + + Math.Abs(expectedVal-calcVal)); + } } + } - // primitive at middle points - sum = 0.0; - for (i=0; i tolerance) - Assert.Fail( - "failed to calculate primitive at " + x[i] - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - } + // test updating mechanism by changing initial variables + xVec1[0] = 60.0; xVec1[1] = 95.0; xVec1[2] = 105.0; xVec1[3] = 135.0; - } + yVec1[0] = 12.5; yVec1[1] = 13.7; yVec1[2] = 15.0; yVec1[3] = 19.0; + yVec1[4] = 26.5; yVec1[5] = 27.5; yVec1[6] = 29.2; yVec1[7] = 36.5; - [TestMethod()] - public void testForwardFlat() { + kernel2DEp.update(); - //("Testing forward-flat interpolation..."); + for(int i=0;i x = new List() { 0.0, 1.0, 2.0, 3.0, 4.0 }; - List y = new List() { 5.0, 4.0, 3.0, 2.0, 1.0 }; + calcVal=kernel2DEp.value(xVec1[i],yVec1[j]); + expectedVal=M1[i,j]; - Interpolation f = new ForwardFlatInterpolation(x, x.Count, y); - f.update(); + if(Math.Abs(expectedVal-calcVal)>tolerance){ - int N = x.Count; - int i; - double tolerance = 1.0e-12, p, calculated, expected; - - // at original points - for (i=0; i tolerance) - Assert.Fail( - "failed to reproduce " + (i+1) + " datum" - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); + Assert.Fail("2D Epanechnkikov Kernel updated interpolation failed at x = " + xVec1[i] + + ", y = " + yVec1[j] + + "\n interpolated value: " + calcVal + + "\n expected value: " + expectedVal + + "\n error: " + + Math.Abs(expectedVal-calcVal)); + } } + } + } + + [TestMethod()] + public void testBicubicDerivatives() + { + // Testing bicubic spline derivatives... + + List x = new InitializedList(100), y = new InitializedList(100); + for (int i=0; i < 100; ++i) + { + x[i] = y[i] = i/20.0; + } + + Matrix f = new Matrix(100, 100); + for (int i=0; i < 100; ++i) + for (int j=0; j < 100; ++j) + f[i,j] = y[i]/10*Math.Sin(x[j])+Math.Cos(y[i]); + + double tol=0.005; + BicubicSpline spline = new BicubicSpline(x, x.Count, y, y.Count, f); + + for (int i=5; i < 95; i+=10) + { + for (int j=5; j < 95; j+=10) + { + double f_x = spline.derivativeX(x[j],y[i]); + double f_xx = spline.secondDerivativeX(x[j],y[i]); + double f_y = spline.derivativeY(x[j],y[i]); + double f_yy = spline.secondDerivativeY(x[j],y[i]); + double f_xy = spline.derivativeXY(x[j],y[i]); + + if (Math.Abs(f_x - y[i]/10*Math.Cos(x[j])) > tol) { + Assert.Fail("Failed to reproduce f_x"); + } + if (Math.Abs(f_xx + y[i]/10*Math.Sin(x[j])) > tol) { + Assert.Fail("Failed to reproduce f_xx"); + } + if (Math.Abs(f_y - (Math.Sin(x[j])/10-Math.Sin(y[i]))) > tol) { + Assert.Fail("Failed to reproduce f_y"); + } + if (Math.Abs(f_yy + Math.Cos(y[i])) > tol) { + Assert.Fail("Failed to reproduce f_yy"); + } + if (Math.Abs(f_xy - Math.Cos(x[j])/10) > tol) { + Assert.Fail("Failed to reproduce f_xy"); + } + } + } + } + + [TestMethod()] + public void testBicubicUpdate() + { + // Testing that bicubic splines actually update... + int N=6; + List x = new InitializedList(N), y = new InitializedList(N); + for (int i=0; i < N; ++i) + { + x[i] = y[i] = i*0.2; + } + + Matrix f = new Matrix(N, N); + for (int i=0; i < N; ++i) + for (int j=0; j < N; ++j) + f[i,j] = x[j]*(x[j] + y[i]); + + BicubicSpline spline = new BicubicSpline(x, x.Count , y, y.Count, f); + + double old_result = spline.value(x[2]+0.1, y[4]); + + // modify input matrix and update. + f[4,3] += 1.0; + spline.update(); + + double new_result = spline.value(x[2]+0.1, y[4]); + if (Math.Abs(old_result-new_result) < 0.5) + Assert.Fail("Failed to update bicubic spline"); +} + + [TestMethod()] + public void testRichardsonExtrapolation() + { + // Testing Richardson extrapolation... + + /* example taken from + * http://www.ipvs.uni-stuttgart.de/abteilungen/bv/lehre/ + * lehrveranstaltungen/vorlesungen/WS0910/ + * NSG_termine/dateien/Richardson.pdf + */ + + double stepSize = 0.1; + double orderOfConvergence = 1.0; + + RichardsonExtrapolation.function f = delegate( double h ) + { + return Math.Pow( 1.0 + h, 1 / h ); + }; + + RichardsonExtrapolation extrap = new RichardsonExtrapolation(f, stepSize, orderOfConvergence); + + double tol = 0.00002; + double expected = 2.71285; + + double scalingFactor = 2.0; + double calculated = extrap.value(scalingFactor); + + if (Math.Abs(expected-calculated) > tol) { + Assert.Fail("failed to reproduce Richardson extrapolation"); + } + + calculated = extrap.value(); + if (Math.Abs(expected-calculated) > tol) { + Assert.Fail("failed to reproduce Richardson extrapolation"); + } + + expected = 2.721376; + const double scalingFactor2 = 4.0; + calculated = extrap.value(scalingFactor2, scalingFactor); + + if (Math.Abs(expected-calculated) > tol) { + Assert.Fail("failed to reproduce Richardson extrapolation"); + } +} - // at middle points - for (i=0; i tolerance) - Assert.Fail( - "failed to interpolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - } + + [TestMethod()] + public void testSabrSingleCases() + { + // Testing Sabr calibration single cases... - // outside the original range - f.enableExtrapolation(); - - p = x[0] - 0.5; - calculated = f.value(p); - expected = y[0]; - if (Math.Abs(expected-calculated) > tolerance) - Assert.Fail( - "failed to extrapolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - - p = x[N-1] + 0.5; - calculated = f.value(p); - expected = y[N-1]; - if (Math.Abs(expected-calculated) > tolerance) - Assert.Fail( - "failed to extrapolate correctly at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - - // primitive at original points - calculated = f.primitive(x[0]); - expected = 0.0; - if (Math.Abs(expected-calculated) > tolerance) - Assert.Fail( - "failed to calculate primitive at " + x[0] - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - - double sum = 0.0; - for (i=1; i tolerance) - Assert.Fail( - "failed to calculate primitive at " + x[i] - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - } + List strikes = new List(){ 0.01, 0.01125, 0.0125, 0.01375, 0.0150}; + List vols = new List(){0.1667, 0.2020, 0.2785, 0.3279, 0.3727}; + - // primitive at middle points - sum = 0.0; - for (i=0; i tolerance) - Assert.Fail( - "failed to calculate primitive at " + p - + "\n expected: " + expected - + "\n calculated: " + calculated - + "\n error: " + Math.Abs(calculated-expected)); - } - } + double tte = 0.3833; + double forward = 0.011025; - //[TestMethod()] - //public void testSabrInterpolation(){ - - // //("Testing Sabr interpolation..."); - - // // Test SABR function against input volatilities - // double tolerance = 2.0e-13; - // List strikes = new InitializedList(31); - // // input strikes - // strikes[0] = 0.03 ; strikes[1] = 0.032 ; strikes[2] = 0.034 ; - // strikes[3] = 0.036 ; strikes[4] = 0.038 ; strikes[5] = 0.04 ; - // strikes[6] = 0.042 ; strikes[7] = 0.044 ; strikes[8] = 0.046 ; - // strikes[9] = 0.048 ; strikes[10] = 0.05 ; strikes[11] = 0.052 ; - // strikes[12] = 0.054 ; strikes[13] = 0.056 ; strikes[14] = 0.058 ; - // strikes[15] = 0.06 ; strikes[16] = 0.062 ; strikes[17] = 0.064 ; - // strikes[18] = 0.066 ; strikes[19] = 0.068 ; strikes[20] = 0.07 ; - // strikes[21] = 0.072 ; strikes[22] = 0.074 ; strikes[23] = 0.076 ; - // strikes[24] = 0.078 ; strikes[25] = 0.08 ; strikes[26] = 0.082 ; - // strikes[27] = 0.084 ; strikes[28] = 0.086 ; strikes[29] = 0.088; - // strikes[30] = 0.09; - - // // input volatilities - // List volatilities = new InitializedList(31); - // volatilities[0] = 1.16725837321531 ; volatilities[1] = 1.15226075991385 ; volatilities[2] = 1.13829711098834 ; - // volatilities[3] = 1.12524190877505 ; volatilities[4] = 1.11299079244474 ; volatilities[5] = 1.10145609357162 ; - // volatilities[6] = 1.09056348513411 ; volatilities[7] = 1.08024942745106 ; volatilities[8] = 1.07045919457758 ; - // volatilities[9] = 1.06114533019077 ; volatilities[10] = 1.05226642581503 ; volatilities[11] = 1.04378614411707 ; - // volatilities[12] = 1.03567243073732 ; volatilities[13] = 1.0278968727451 ; volatilities[14] = 1.02043417226345 ; - // volatilities[15] = 1.01326171139321 ; volatilities[16] = 1.00635919013311 ; volatilities[17] = 0.999708323124949 ; - // volatilities[18] = 0.993292584155381 ; volatilities[19] = 0.987096989695393 ; volatilities[20] = 0.98110791455717 ; - // volatilities[21] = 0.975312934134512 ; volatilities[22] = 0.969700688771689 ; volatilities[23] = 0.964260766651027; - // volatilities[24] = 0.958983602256592 ; volatilities[25] = 0.953860388001395 ; volatilities[26] = 0.948882997029509 ; - // volatilities[27] = 0.944043915545469 ; volatilities[28] = 0.939336183299237 ; volatilities[29] = 0.934753341079515 ; - // volatilities[30] = 0.930289384251337; - - // double expiry = 1.0; - // double forward = 0.039; - // // input SABR coefficients (corresponding to the vols above) - // double initialAlpha = 0.3; - // double initialBeta = 0.6; - // double initialNu = 0.02; - // double initialRho = 0.01; - // // calculate SABR vols and compare with input vols - // for(int i=0; i< strikes.size(); i++){ - // double calculatedVol = sabrVolatility(strikes[i], forward, expiry, - // initialAlpha, initialBeta, - // initialNu, initialRho); - // if (Math.Abs(volatilities[i]-calculatedVol) > tolerance) - // Assert.Fail( - // "failed to calculate Sabr function at strike " + strikes[i] - // + "\n expected: " + volatilities[i] - // + "\n calculated: " + calculatedVol - // + "\n error: " + Math.Abs(calculatedVol-volatilities[i])); - // } - - // // Test SABR calibration against input parameters - // // Initial null guesses (uses default values) - // double? alphaGuess = null; - // double? betaGuess = null; - // double? nuGuess = null; - // double? rhoGuess = null; - - // const bool[] vegaWeighted= {true, false}; - // const bool[] isAlphaFixed= {true, false}; - // const bool[] isBetaFixed= {true, false}; - // const bool[] isNuFixed= {true, false}; - // const bool[] isRhoFixed= {true, false}; - - // double calibrationTolerance = 5.0e-8; - // // initialize optimization methods - // List methods_ = new List(); - // methods_.Add(new Simplex(0.01)); - // methods_.Add(new LevenbergMarquardt(1e-8, 1e-8, 1e-8)); - // // Initialize end criteria - // EndCriteria endCriteria = new EndCriteria(100000, 100, 1e-8, 1e-8, 1e-8); - // // Test looping over all possibilities - // for (int j=0; j calibrationTolerance) { - // Assert.Fail("\nfailed to calibrate alpha Sabr parameter:" + - // "\n expected: " + initialAlpha + - // "\n calibrated: " + calibratedAlpha + - // "\n error: " + error); - // failed = true; - // } - // // Beta - // error = Math.Abs(initialBeta-calibratedBeta); - // if (error > calibrationTolerance) { - // Assert.Fail("\nfailed to calibrate beta Sabr parameter:" + - // "\n expected: " + initialBeta + - // "\n calibrated: " + calibratedBeta + - // "\n error: " + error); - // failed = true; - // } - // // Nu - // error = Math.Abs(initialNu-calibratedNu); - // if (error > calibrationTolerance) { - // Assert.Fail("\nfailed to calibrate nu Sabr parameter:" + - // "\n expected: " + initialNu + - // "\n calibrated: " + calibratedNu + - // "\n error: " + error); - // failed = true; - // } - // // Rho - // error = Math.Abs(initialRho-calibratedRho); - // if (error > calibrationTolerance) { - // Assert.Fail("\nfailed to calibrate rho Sabr parameter:" + - // "\n expected: " + initialRho + - // "\n calibrated: " + calibratedRho + - // "\n error: " + error); - // failed = true; - // } - - // if (failed) - // Assert.Fail("\nSabr calibration failure:" + - // "\n isAlphaFixed: " + isAlphaFixed[k_a] + - // "\n isBetaFixed: " + isBetaFixed[k_b] + - // "\n isNuFixed: " + isNuFixed[k_n] + - // "\n isRhoFixed: " + isRhoFixed[k_r] + - // "\n vegaWeighted[i]: " + vegaWeighted[i]); - - // } - // } - // } - // } - // } - // } - //} - - - #region Functions + SABRInterpolation s0 = new SABRInterpolation(strikes, strikes.Count, vols, tte, forward, + null, 0.25, null, null, + false, true, false, false); + s0.update(); + + if (s0.maxError() > 0.01 || s0.rmsError() > 0.01) + { + Assert.Fail("Sabr case #1 failed with max error (" + + s0.maxError() + ") and rms error (" + s0.rmsError() + + "), both should be < 0.01"); + + } + } + + + #region Functions List xRange(double start, double finish, int points) { List x = new InitializedList(points); double dx = (finish - start) / (points - 1); @@ -1187,6 +1603,25 @@ double multif(double s, double t, double u, double v, double w) { Math.Exp(Math.Sin(u) * Math.Sin(3 * v)) + Math.Sinh(Math.Log(v * w))); } + + // Note : a better solution will be an anonymous type casted to IKernelFunction + class epanechnikovKernel : IKernelFunction + { + public double value( double u ) + { + if ( Math.Abs( u ) <= 1 ) + { + return ( 3.0 / 4.0 ) * ( 1 - u * u ); + } + else + { + return 0.0; + } + } + } + + #endregion - } + + } } diff --git a/Test/T_LiborMarketModel.cs b/Test/T_LiborMarketModel.cs index 34f450b5e..02ce647f9 100644 --- a/Test/T_LiborMarketModel.cs +++ b/Test/T_LiborMarketModel.cs @@ -2,12 +2,12 @@ Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -16,8 +16,8 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - +*/ + using System; using System.Collections.Generic; using System.Linq; @@ -80,8 +80,8 @@ OptionletVolatilityStructure makeCapVolCurve(Date todaysDate) return new CapletVarianceCurve(todaysDate, dates, capletVols,new Actual360()); - } - + } + [TestCategory( "LongRun" ), TestMethod()] public void testSimpleCovarianceModels() { @@ -153,8 +153,8 @@ public void testSimpleCovarianceModels() + "\n expected: " + expected); } } - } - + } + [TestCategory( "LongRun" ), TestMethod()] public void testCapletPricing() { @@ -268,7 +268,7 @@ public void testCalibration() CalibrationHelper swaptionHelper = new SwaptionHelper(maturity, len, swaptionVol, index, index.tenor(), dayCounter, - index.dayCounter(), + index.dayCounter(), termStructure, CalibrationHelper.CalibrationErrorType.ImpliedVolError ); swaptionHelper.setPricingEngine(new LfmSwaptionEngine(model,termStructure)); diff --git a/Test/T_LiborMarketModelProcess.cs b/Test/T_LiborMarketModelProcess.cs index 35d1666e5..60302e46a 100644 --- a/Test/T_LiborMarketModelProcess.cs +++ b/Test/T_LiborMarketModelProcess.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -179,8 +179,8 @@ public void testLambdaBootstrapping() for (int t=0; t. + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_Matrices.cs b/Test/T_Matrices.cs index 6cd35c631..60d988ca8 100644 --- a/Test/T_Matrices.cs +++ b/Test/T_Matrices.cs @@ -1,12 +1,13 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) + Copyright (C) 2008-2015 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -15,7 +16,7 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ +*/ using System; using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -209,41 +210,118 @@ public void testSVD() { } } - //[TestMethod()] - public void testQRDecomposition() { - - //BOOST_MESSAGE("Testing QR decomposition..."); - - setup(); - - double tol = 1.0e-12; - Matrix[] testMatrices = { M1, M2, I, - M3, Matrix.transpose(M3), M4, Matrix.transpose(M4), M5 }; - - for (int j = 0; j < testMatrices.Length; j++) { - Matrix Q = new Matrix(), R = new Matrix(); - bool pivot = true; - Matrix A = testMatrices[j]; - List ipvt = MatrixUtilities.qrDecomposition(A, Q, R, pivot); - - Matrix P = new Matrix(A.columns(), A.columns(), 0.0); - - // reverse column pivoting - for (int i=0; i < P.columns(); ++i) { - P[ipvt[i],i] = 1.0; - } - - if (norm(Q*R - A*P) > tol) - Assert.Fail("Q*R does not match matrix A*P (norm = " - + norm(Q*R-A*P) + ")"); - - pivot = false; - MatrixUtilities.qrDecomposition(A, Q, R, pivot); - - if (norm(Q*R - A) > tol) - Assert.Fail("Q*R does not match matrix A (norm = " - + norm(Q*R-A) + ")"); - } - } + [TestMethod()] + public void testQRDecomposition() + { + + // Testing QR decomposition... + + setup(); + + double tol = 1.0e-12; + Matrix[] testMatrices = { M1, M2, I, + M3, Matrix.transpose(M3), M4, Matrix.transpose(M4), M5 }; + + for (int j = 0; j < testMatrices.Length; j++) { + Matrix Q = new Matrix(), R = new Matrix(); + bool pivot = true; + Matrix A = testMatrices[j]; + List ipvt = MatrixUtilities.qrDecomposition(A, ref Q, ref R, pivot); + + Matrix P = new Matrix(A.columns(), A.columns(), 0.0); + + // reverse column pivoting + for (int i=0; i < P.columns(); ++i) { + P[ipvt[i],i] = 1.0; + } + + if (norm(Q*R - A*P) > tol) + Assert.Fail("Q*R does not match matrix A*P (norm = " + + norm(Q*R-A*P) + ")"); + + pivot = false; + MatrixUtilities.qrDecomposition(A, ref Q, ref R, pivot); + + if (norm(Q*R - A) > tol) + Assert.Fail("Q*R does not match matrix A (norm = " + + norm(Q*R-A) + ")"); + + } + } + + [TestMethod()] + public void testQRSolve() + { + // Testing QR solve... + setup(); + + double tol = 1.0e-12; + MersenneTwisterUniformRng rng = new MersenneTwisterUniformRng( 1234 ); + Matrix bigM = new Matrix( 50, 100, 0.0 ); + for ( int i = 0; i < Math.Min( bigM.rows(), bigM.columns() ); ++i ) + { + bigM[i, i] = i + 1.0; + } + Matrix[] testMatrices = { M1, M2, M3, Matrix.transpose(M3), + M4, Matrix.transpose(M4), M5, I, M7, bigM, Matrix.transpose(bigM) }; + + for ( int j = 0; j < testMatrices.Length; j++ ) + { + Matrix A = testMatrices[j]; + Vector b = new Vector( A.rows() ); + + for ( int k = 0; k < 10; ++k ) + { + for ( int i = 0; i < b.Count; ++i ) + { + b[i] = rng.next().value; + } + Vector x = MatrixUtilities.qrSolve( A, b, true ); + + if ( A.columns() >= A.rows() ) + { + if ( norm( A * x - b ) > tol ) + Assert.Fail( "A*x does not match vector b (norm = " + + norm( A * x - b ) + ")" ); + } + else + { + // use the SVD to calculate the reference values + int n = A.columns(); + Vector xr = new Vector( n, 0.0 ); + + SVD svd = new SVD( A ); + Matrix V = svd.V(); + Matrix U = svd.U(); + Vector w = svd.singularValues(); + double threshold = n * Const.QL_EPSILON; + + for ( int i = 0; i < n; ++i ) + { + if ( w[i] > threshold ) + { + double u = 0; + int zero = 0; + for ( int kk = 0; kk < U.rows(); kk++ ) + u += ( U[kk, i] * b[zero++] ) / w[i]; + + for ( int jj = 0; jj < n; ++jj ) + { + xr[jj] += u * V[jj, i]; + } + } + } + + if ( norm( xr - x ) > tol ) + { + Assert.Fail( "least square solution does not match (norm = " + + norm( x - xr ) + ")" ); + + } + } + } + } + } + } } diff --git a/Test/T_Money.cs b/Test/T_Money.cs index 13a002c4c..98f2452ee 100644 --- a/Test/T_Money.cs +++ b/Test/T_Money.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_Operators.cs b/Test/T_Operators.cs index 523da68aa..41628ffab 100644 --- a/Test/T_Operators.cs +++ b/Test/T_Operators.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_Optimizers.cs b/Test/T_Optimizers.cs index 77e25d8cd..e0b4a1a4f 100644 --- a/Test/T_Optimizers.cs +++ b/Test/T_Optimizers.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_OvernightIndexedSwap.cs b/Test/T_OvernightIndexedSwap.cs index 48175f6a5..261221f6e 100644 --- a/Test/T_OvernightIndexedSwap.cs +++ b/Test/T_OvernightIndexedSwap.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) * - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_PSACurve.cs b/Test/T_PSACurve.cs index ff76be050..f2051d0e8 100644 --- a/Test/T_PSACurve.cs +++ b/Test/T_PSACurve.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008, 2009 , 2010, 2011, 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_PathGenerator.cs b/Test/T_PathGenerator.cs index 3f608b7f1..2c24aae8e 100644 --- a/Test/T_PathGenerator.cs +++ b/Test/T_PathGenerator.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_PiecewiseZeroSpreadedTermStructure.cs b/Test/T_PiecewiseZeroSpreadedTermStructure.cs index 618e0eb2a..1d7b5d6d5 100644 --- a/Test/T_PiecewiseZeroSpreadedTermStructure.cs +++ b/Test/T_PiecewiseZeroSpreadedTermStructure.cs @@ -1,18 +1,18 @@ -/* - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. +/* + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. */ using System; diff --git a/Test/T_Piecewiseyieldcurve.cs b/Test/T_Piecewiseyieldcurve.cs index ac04bc4d7..e27b74d00 100644 --- a/Test/T_Piecewiseyieldcurve.cs +++ b/Test/T_Piecewiseyieldcurve.cs @@ -2,12 +2,12 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -226,12 +226,12 @@ public CommonVars() { public void testLogCubicDiscountConsistency() { // "Testing consistency of piecewise-log-cubic discount curve..."); - CommonVars vars = new CommonVars(); - + CommonVars vars = new CommonVars(); + testCurveConsistency( vars, new LogCubic(CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); testBMACurveConsistency( vars, new LogCubic(CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, @@ -242,9 +242,9 @@ public void testLogCubicDiscountConsistency() { public void testLogLinearDiscountConsistency() { // "Testing consistency of piecewise-log-linear discount curve..."); - CommonVars vars = new CommonVars(); - - testCurveConsistency( vars ); + CommonVars vars = new CommonVars(); + + testCurveConsistency( vars ); testBMACurveConsistency( vars ); } @@ -252,24 +252,24 @@ public void testLogLinearDiscountConsistency() { public void testLinearDiscountConsistency() { // "Testing consistency of piecewise-linear discount curve..." - CommonVars vars = new CommonVars(); - - testCurveConsistency( vars ); + CommonVars vars = new CommonVars(); + + testCurveConsistency( vars ); testBMACurveConsistency( vars ); } [TestMethod()] public void testLogLinearZeroConsistency() { - // "Testing consistency of piecewise-log-linear zero-yield curve..."); + // "Testing consistency of piecewise-log-linear zero-yield curve..."); // if rates can be negative it makes no sense to interpolate loglinearly if ( Utils.is_QL_NEGATIVE_RATES() ) return; else { - CommonVars vars = new CommonVars(); - - testCurveConsistency( vars ); + CommonVars vars = new CommonVars(); + + testCurveConsistency( vars ); testBMACurveConsistency( vars ); } } @@ -278,9 +278,9 @@ public void testLogLinearZeroConsistency() { public void testLinearZeroConsistency() { // "Testing consistency of piecewise-linear zero-yield curve..."); - CommonVars vars = new CommonVars(); - - testCurveConsistency( vars ); + CommonVars vars = new CommonVars(); + + testCurveConsistency( vars ); testBMACurveConsistency( vars ); } @@ -289,13 +289,13 @@ public void testSplineZeroConsistency() { //"Testing consistency of piecewise-cubic zero-yield curve..."); - CommonVars vars = new CommonVars(); - + CommonVars vars = new CommonVars(); + testCurveConsistency( vars, new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); testBMACurveConsistency( vars, new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, @@ -307,9 +307,9 @@ public void testSplineZeroConsistency() { public void testLinearForwardConsistency() { // "Testing consistency of piecewise-linear forward-rate curve..."); - CommonVars vars = new CommonVars(); - - testCurveConsistency( vars ); + CommonVars vars = new CommonVars(); + + testCurveConsistency( vars ); testBMACurveConsistency( vars ); } @@ -318,9 +318,9 @@ public void testFlatForwardConsistency() { //"Testing consistency of piecewise-flat forward-rate curve..."); - CommonVars vars = new CommonVars(); - - testCurveConsistency( vars ); + CommonVars vars = new CommonVars(); + + testCurveConsistency( vars ); testBMACurveConsistency( vars ); } @@ -329,13 +329,13 @@ public void testSplineForwardConsistency() { //"Testing consistency of piecewise-cubic forward-rate curve..."); - CommonVars vars = new CommonVars(); - + CommonVars vars = new CommonVars(); + testCurveConsistency( vars, new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, - CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); + CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); testBMACurveConsistency( vars, new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, @@ -347,8 +347,8 @@ public void testSplineForwardConsistency() { public void testConvexMonotoneForwardConsistency() { //"Testing consistency of convex monotone forward-rate curve..."); - CommonVars vars = new CommonVars(); - + CommonVars vars = new CommonVars(); + testCurveConsistency( vars ); testBMACurveConsistency(vars); } @@ -357,8 +357,8 @@ public void testConvexMonotoneForwardConsistency() { public void testLocalBootstrapConsistency() { //"Testing consistency of local-bootstrap algorithm..."); - CommonVars vars = new CommonVars(); - testCurveConsistency( vars, new ConvexMonotone(), 1.0e-7 ); + CommonVars vars = new CommonVars(); + testCurveConsistency( vars, new ConvexMonotone(), 1.0e-7 ); testBMACurveConsistency( vars, new ConvexMonotone(), 1.0e-9 ); } @@ -588,18 +588,18 @@ public void testZeroCopy() { } - public void testCurveConsistency(CommonVars vars) + public void testCurveConsistency(CommonVars vars) where T : ITraits, new() - where I : IInterpolationFactory, new() + where I : IInterpolationFactory, new() where B : IBootStrap, new() { testCurveConsistency( vars, new I(), 1.0e-9 ); } - public void testCurveConsistency(CommonVars vars, I interpolator) + public void testCurveConsistency(CommonVars vars, I interpolator) where T : ITraits, new() - where I : IInterpolationFactory, new() + where I : IInterpolationFactory, new() where B : IBootStrap, new() { testCurveConsistency( vars, new I(), 1.0e-9 ); } - public void testCurveConsistency(CommonVars vars, I interpolator, double tolerance) + public void testCurveConsistency(CommonVars vars, I interpolator, double tolerance) where T : ITraits, new() - where I : IInterpolationFactory, new() - where B : IBootStrap, new() + where I : IInterpolationFactory, new() + where B : IBootStrap, new() { vars.termStructure = new PiecewiseYieldCurve(vars.settlement, vars.instruments, @@ -701,18 +701,18 @@ public void testCurveConsistency(CommonVars vars, I interpolator, doubl } } - public void testBMACurveConsistency(CommonVars vars) + public void testBMACurveConsistency(CommonVars vars) where T : ITraits, new() - where I : IInterpolationFactory, new() + where I : IInterpolationFactory, new() where B : IBootStrap, new() { testBMACurveConsistency( vars, new I(), 1.0e-7 ); } - public void testBMACurveConsistency(CommonVars vars, I interpolator) + public void testBMACurveConsistency(CommonVars vars, I interpolator) where T : ITraits, new() - where I : IInterpolationFactory, new() + where I : IInterpolationFactory, new() where B : IBootStrap, new() { testBMACurveConsistency( vars, interpolator, 1.0e-7 ); } - public void testBMACurveConsistency(CommonVars vars, I interpolator, double tolerance) + public void testBMACurveConsistency(CommonVars vars, I interpolator, double tolerance) where T : ITraits, new() - where I : IInterpolationFactory, new() - where B : IBootStrap, new() + where I : IInterpolationFactory, new() + where B : IBootStrap, new() { // readjust settlement @@ -795,12 +795,12 @@ public void testBMACurveConsistency(CommonVars vars, I interpolator, do IndexManager.instance().clearHistories(); } - public void testCurveCopy(CommonVars vars) + public void testCurveCopy(CommonVars vars) where T : ITraits, new() where I : IInterpolationFactory, new() { testCurveCopy(vars, new I()); } - public void testCurveCopy(CommonVars vars, I interpolator) + public void testCurveCopy(CommonVars vars, I interpolator) where T : ITraits, new() where I : IInterpolationFactory, new() { diff --git a/Test/T_Quotes.cs b/Test/T_Quotes.cs index 544142bf1..c0de82660 100644 --- a/Test/T_Quotes.cs +++ b/Test/T_Quotes.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008-2009 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_RNGTraits.cs b/Test/T_RNGTraits.cs index 4d7a0ed24..7ff40132d 100644 --- a/Test/T_RNGTraits.cs +++ b/Test/T_RNGTraits.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_RiskStats.cs b/Test/T_RiskStats.cs index a3d599373..950bb9099 100644 --- a/Test/T_RiskStats.cs +++ b/Test/T_RiskStats.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_Rounding.cs b/Test/T_Rounding.cs index e34b2d281..571928d58 100644 --- a/Test/T_Rounding.cs +++ b/Test/T_Rounding.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Andrea Maggiulli - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_SampledCurve.cs b/Test/T_SampledCurve.cs index b0ccc7065..6b83408d2 100644 --- a/Test/T_SampledCurve.cs +++ b/Test/T_SampledCurve.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_Schedule.cs b/Test/T_Schedule.cs index c9b1528b3..519c0f770 100644 --- a/Test/T_Schedule.cs +++ b/Test/T_Schedule.cs @@ -1,141 +1,256 @@ -/* - Copyright (C) 2012 Andrea Maggiulli (a.maggiulli@gmail.com) - - This file is part of QLNet Project http://qlnet.sourceforge.net/ - - QLNet is free software: you can redistribute it and/or modify it - under the terms of the QLNet license. You should have received a - copy of the license along with this program; if not, license is - available online at . - - QLNet is a based on QuantLib, a free-software/open-source library - for financial quantitative analysts and developers - http://quantlib.org/ - The QuantLib license is available online at http://quantlib.org/license.shtml. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the license for more details. -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using QLNet; - -namespace TestSuite -{ - [TestClass()] - public class T_Schedule - { - void check_dates(Schedule s, List expected) - { - if (s.Count != expected.Count) - { - Assert.Fail("expected " + expected.Count + " dates, " + "found " + s.Count); - } - - for (int i=0; i expected = new List(6); - // The schedule should skip Saturday 21st and Sunday 22rd. - // Previously, it would adjust them to Friday 20th, resulting - // in three copies of the same date. - expected.Add(new Date(17,Month.January,2012)); - expected.Add(new Date(18,Month.January,2012)); - expected.Add(new Date(19,Month.January,2012)); - expected.Add(new Date(20,Month.January,2012)); - expected.Add(new Date(23,Month.January,2012)); - expected.Add(new Date(24,Month.January,2012)); - - check_dates(s, expected); - } - - [TestMethod()] - public void testEndDateWithEomAdjustment() - { - // Testing end date for schedule with end-of-month adjustment - - Schedule s = new MakeSchedule().from(new Date(30, Month.September, 2009)) - .to(new Date(15, Month.June, 2012)) - .withCalendar(new Japan()) - .withTenor(new Period(6, TimeUnit.Months)) - .withConvention(BusinessDayConvention.Following) - .withTerminationDateConvention(BusinessDayConvention.Following) - .forwards() - .endOfMonth().value(); - +/* + Copyright (C) 2012 Andrea Maggiulli (a.maggiulli@gmail.com) + + This file is part of QLNet Project https://github.com/amaggiulli/qlnet + + QLNet is free software: you can redistribute it and/or modify it + under the terms of the QLNet license. You should have received a + copy of the license along with this program; if not, license is + available online at . + + QLNet is a based on QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + The QuantLib license is available online at http://quantlib.org/license.shtml. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using QLNet; + +namespace TestSuite +{ + [TestClass()] + public class T_Schedule + { + void check_dates(Schedule s, List expected) + { + if (s.Count != expected.Count) + { + Assert.Fail("expected " + expected.Count + " dates, " + "found " + s.Count); + } + + for (int i = 0; i < expected.Count; ++i) + { + if (s[i] != expected[i]) + { + Assert.Fail("expected " + expected[i] + " at index " + i + ", " + "found " + s[i]); + + } + } + } + + [TestMethod()] + public void testDailySchedule() + { + // Testing schedule with daily frequency + + Date startDate = new Date(17, Month.January, 2012); + + Schedule s = new MakeSchedule().from(startDate).to(startDate + 7) + .withCalendar(new TARGET()) + .withConvention(BusinessDayConvention.Preceding) + .withFrequency(Frequency.Daily).value(); + + List expected = new List(6); + // The schedule should skip Saturday 21st and Sunday 22rd. + // Previously, it would adjust them to Friday 20th, resulting + // in three copies of the same date. + expected.Add(new Date(17, Month.January, 2012)); + expected.Add(new Date(18, Month.January, 2012)); + expected.Add(new Date(19, Month.January, 2012)); + expected.Add(new Date(20, Month.January, 2012)); + expected.Add(new Date(23, Month.January, 2012)); + expected.Add(new Date(24, Month.January, 2012)); + + check_dates(s, expected); + } + + [TestMethod()] + public void testEndDateWithEomAdjustment() + { + // Testing end date for schedule with end-of-month adjustment + + Schedule s = new MakeSchedule().from(new Date(30, Month.September, 2009)) + .to(new Date(15, Month.June, 2012)) + .withCalendar(new Japan()) + .withTenor(new Period(6, TimeUnit.Months)) + .withConvention(BusinessDayConvention.Following) + .withTerminationDateConvention(BusinessDayConvention.Following) + .forwards() + .endOfMonth().value(); + + List expected = new List(); + // The end date is adjusted, so it should also be moved to the end + // of the month. + expected.Add(new Date(30, Month.September, 2009)); + expected.Add(new Date(31, Month.March, 2010)); + expected.Add(new Date(30, Month.September, 2010)); + expected.Add(new Date(31, Month.March, 2011)); + expected.Add(new Date(30, Month.September, 2011)); + expected.Add(new Date(30, Month.March, 2012)); + expected.Add(new Date(29, Month.June, 2012)); + + check_dates(s, expected); + + // now with unadjusted termination date... + s = new MakeSchedule().from(new Date(30, Month.September, 2009)) + .to(new Date(15, Month.June, 2012)) + .withCalendar(new Japan()) + .withTenor(new Period(6, TimeUnit.Months)) + .withConvention(BusinessDayConvention.Following) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .forwards() + .endOfMonth().value(); + // ...which should leave it alone. + expected[6] = new Date(15, Month.June, 2012); + + check_dates(s, expected); + } + + [TestMethod()] + public void testDatesPastEndDateWithEomAdjustment() + { + + Schedule s = new MakeSchedule().from(new Date(28, Month.March, 2013)) + .to(new Date(30, Month.March, 2015)) + .withCalendar(new TARGET()) + .withTenor(new Period(1, TimeUnit.Years)) + .withConvention(BusinessDayConvention.Unadjusted) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .forwards() + .endOfMonth().value(); + + List expected = new List(); + expected.Add(new Date(31, Month.March, 2013)); + expected.Add(new Date(31, Month.March, 2014)); + // March 31st 2015, coming from the EOM adjustment of March 28th, + // should be discarded as past the end date. + expected.Add(new Date(30, Month.March, 2015)); + + check_dates(s, expected); + } + + + [TestMethod()] + public void testForwardDatesWithEomAdjustment() + { + // Testing that the last date is not adjusted for EOM when termination date convention is unadjusted + + Schedule s = new MakeSchedule().from(new Date(31, Month.August, 1996)) + .to(new Date(15, Month.September, 1997)) + .withCalendar(new UnitedStates(UnitedStates.Market.GovernmentBond)) + .withTenor(new Period(6, TimeUnit.Months)) + .withConvention(BusinessDayConvention.Unadjusted) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .forwards() + .endOfMonth().value(); + List expected = new List(); - // The end date is adjusted, so it should also be moved to the end - // of the month. - expected.Add(new Date(30, Month.September, 2009)); - expected.Add(new Date(31, Month.March, 2010)); - expected.Add(new Date(30, Month.September, 2010)); - expected.Add(new Date(31, Month.March, 2011)); - expected.Add(new Date(30, Month.September, 2011)); - expected.Add(new Date(30, Month.March, 2012)); - expected.Add(new Date(29, Month.June, 2012)); - - check_dates(s, expected); - - // now with unadjusted termination date... - s = new MakeSchedule().from(new Date(30, Month.September, 2009)) - .to(new Date(15, Month.June, 2012)) - .withCalendar(new Japan()) - .withTenor(new Period(6 , TimeUnit.Months)) - .withConvention(BusinessDayConvention.Following) - .withTerminationDateConvention(BusinessDayConvention.Unadjusted) - .forwards() - .endOfMonth().value(); - // ...which should leave it alone. - expected[6] = new Date(15, Month.June, 2012); - - check_dates(s, expected); - } - - [TestMethod()] - public void testDatesPastEndDateWithEomAdjustment() - { - - Schedule s = new MakeSchedule().from(new Date(28,Month.March,2013)) - .to(new Date(30,Month.March,2015)) - .withCalendar(new TARGET()) - .withTenor(new Period(1,TimeUnit.Years)) - .withConvention(BusinessDayConvention.Unadjusted) - .withTerminationDateConvention(BusinessDayConvention.Unadjusted) - .forwards() - .endOfMonth().value(); - + expected.Add(new Date(31, Month.August, 1996)); + expected.Add(new Date(28, Month.February, 1997)); + expected.Add(new Date(31, Month.August, 1997)); + expected.Add(new Date(15, Month.September, 1997)); + + check_dates(s, expected); + } + + [TestMethod()] + public void testBackwardDatesWithEomAdjustment() + { + // Testing that the first date is not adjusted for EOM going backward when termination date convention is unadjusted + + Schedule s = new MakeSchedule().from(new Date(22, Month.August, 1996)) + .to(new Date(31, Month.August, 1997)) + .withCalendar(new UnitedStates(UnitedStates.Market.GovernmentBond)) + .withTenor(new Period(6, TimeUnit.Months)) + .withConvention(BusinessDayConvention.Unadjusted) + .withTerminationDateConvention(BusinessDayConvention.Unadjusted) + .backwards() + .endOfMonth().value(); + List expected = new List(); - expected.Add(new Date(31,Month.March,2013)); - expected.Add(new Date(31,Month.March,2014)); - // March 31st 2015, coming from the EOM adjustment of March 28th, - // should be discarded as past the end date. - expected.Add(new Date(30,Month.March,2015)); - - check_dates(s, expected); -} - - } - -} + expected.Add(new Date(22, Month.August, 1996)); + expected.Add(new Date(31, Month.August, 1996)); + expected.Add(new Date(28, Month.February, 1997)); + expected.Add(new Date(31, Month.August, 1997)); + + check_dates(s, expected); + } + + [TestMethod()] + public void testDoubleFirstDateWithEomAdjustment() + { + // Testing that the first date is not duplicated due to EOM convention when going backwards + + Schedule s = new MakeSchedule().from(new Date(22, Month.August, 1996)) + .to(new Date(31, Month.August, 1997)) + .withCalendar(new UnitedStates(UnitedStates.Market.GovernmentBond)) + .withTenor(new Period(6, TimeUnit.Months)) + .withConvention(BusinessDayConvention.Following) + .withTerminationDateConvention(BusinessDayConvention.Following) + .backwards() + .endOfMonth().value(); + + List expected = new List(); + expected.Add(new Date(30, Month.August, 1996)); + expected.Add(new Date(28, Month.February, 1997)); + expected.Add(new Date(29, Month.August, 1997)); + + check_dates(s, expected); + } + + [TestMethod()] + public void testDateConstructor() + { + // Testing the constructor taking a vector of dates and possibly additional meta information + + List dates = new List(); + dates.Add(new Date(16, Month.May, 2015)); + dates.Add(new Date(18, Month.May, 2015)); + dates.Add(new Date(18, Month.May, 2016)); + dates.Add(new Date(31, Month.December, 2017)); + + // schedule without any additional information + Schedule schedule1 = new Schedule(dates); + if (schedule1.Count != dates.Count) + Assert.Fail("schedule1 has size {0}, expected {1}", schedule1.Count, dates.Count); + for (int i = 0; i < dates.Count; ++i) + if (schedule1[i] != dates[i]) + Assert.Fail("schedule1 has {0} at position {1}, expected {2}", schedule1[i], i, dates[i]); + if (schedule1.calendar() != new NullCalendar()) + Assert.Fail("schedule1 has calendar {0}, expected null calendar", schedule1.calendar().name()); + if (schedule1.businessDayConvention() != BusinessDayConvention.Unadjusted) + Assert.Fail("schedule1 has convention {0}, expected unadjusted", schedule1.businessDayConvention()); + + // schedule with metadata + List regular = new List(); + regular.Add(false); + regular.Add(true); + regular.Add(false); + + Schedule schedule2 = new Schedule(dates, new TARGET(), BusinessDayConvention.Following, BusinessDayConvention.ModifiedPreceding, new Period(1, TimeUnit.Years), + DateGeneration.Rule.Backward, true, regular); + for (int i = 1; i < dates.Count; ++i) + if (schedule2.isRegular(i) != regular[i - 1]) + Assert.Fail("schedule2 has a {0} period at position {1}, expected {2}", (schedule2.isRegular(i) ? "regular" : "irregular"), i, (regular[i - 1] ? "regular" : "irregular")); + if (schedule2.calendar() != new TARGET()) + Assert.Fail("schedule1 has calendar {0}, expected TARGET", schedule2.calendar().name()); + if (schedule2.businessDayConvention() != BusinessDayConvention.Following) + Assert.Fail("schedule2 has convention {0}, expected Following", schedule2.businessDayConvention()); + if (schedule2.terminationDateBusinessDayConvention() != BusinessDayConvention.ModifiedPreceding) + Assert.Fail("schedule2 has convention {0}, expected Modified Preceding", schedule2.terminationDateBusinessDayConvention()); + if (schedule2.tenor() != new Period(1, TimeUnit.Years)) + Assert.Fail("schedule2 has tenor {0}, expected 1Y", schedule2.tenor()); + if (schedule2.rule() != DateGeneration.Rule.Backward) + Assert.Fail("schedule2 has rule {0}, expected Backward", schedule2.rule()); + if (schedule2.endOfMonth() != true) + Assert.Fail("schedule2 has end of month flag false, expected true"); + } + } +} diff --git a/Test/T_ShortRateModels.cs b/Test/T_ShortRateModels.cs index ded25e169..c69e56245 100644 --- a/Test/T_ShortRateModels.cs +++ b/Test/T_ShortRateModels.cs @@ -2,12 +2,12 @@ Copyright (C) 2010 Philippe Real (ph_real@hotmail.com) Copyright (C) 2008-2014 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -16,8 +16,8 @@ under the terms of the QLNet license. You should have received a This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. -*/ - +*/ + using System; using System.Collections.Generic; using System.Linq; diff --git a/Test/T_Solvers.cs b/Test/T_Solvers.cs index 7ce88b38a..14c11a07e 100644 --- a/Test/T_Solvers.cs +++ b/Test/T_Solvers.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_Stats.cs b/Test/T_Stats.cs index 925d86d9f..09a85eaf2 100644 --- a/Test/T_Stats.cs +++ b/Test/T_Stats.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_Swaps.cs b/Test/T_Swaps.cs index 074a087de..997ff7bc0 100644 --- a/Test/T_Swaps.cs +++ b/Test/T_Swaps.cs @@ -1,7 +1,7 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a diff --git a/Test/T_Swaption.cs b/Test/T_Swaption.cs index 30ffb9b10..66fbb25cf 100644 --- a/Test/T_Swaption.cs +++ b/Test/T_Swaption.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_SwaptionVolatilitymatrix.cs b/Test/T_SwaptionVolatilitymatrix.cs index d361c08c0..6b2d624d6 100644 --- a/Test/T_SwaptionVolatilitymatrix.cs +++ b/Test/T_SwaptionVolatilitymatrix.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2009 Philippe Real (ph_real@hotmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/T_TermStructures.cs b/Test/T_TermStructures.cs index 03630adc5..12195e951 100644 --- a/Test/T_TermStructures.cs +++ b/Test/T_TermStructures.cs @@ -2,12 +2,12 @@ Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) Copyright (C) 2008, 2009 , 2010 Andrea Maggiulli (a.maggiulli@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ diff --git a/Test/Test.csproj b/Test/Test.csproj index fa06b0996..04773267d 100644 --- a/Test/Test.csproj +++ b/Test/Test.csproj @@ -32,6 +32,7 @@ 1.0.0.%2a false true + true @@ -42,6 +43,7 @@ prompt 4 AllRules.ruleset + false pdbonly @@ -51,6 +53,7 @@ prompt 4 AllRules.ruleset + false @@ -59,9 +62,11 @@ 3.5 + + diff --git a/Test/Utilities.cs b/Test/Utilities.cs index 2ef9d207c..f94478c33 100644 --- a/Test/Utilities.cs +++ b/Test/Utilities.cs @@ -1,12 +1,12 @@ /* Copyright (C) 2008 Siarhei Novik (snovik@gmail.com) - This file is part of QLNet Project http://qlnet.sourceforge.net/ + This file is part of QLNet Project https://github.com/amaggiulli/qlnet QLNet is free software: you can redistribute it and/or modify it under the terms of the QLNet license. You should have received a copy of the license along with this program; if not, license is - available online at . + available online at . QLNet is a based on QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/