Changeset 214
- Timestamp:
- 06/18/08 05:53:32 (3 months ago)
- Files:
-
- trunk/QLNet/QLNet/Cashflows/Coupon.cs (modified) (3 diffs)
- trunk/QLNet/QLNet/Cashflows/averagebmacoupon.cs (modified) (1 diff)
- trunk/QLNet/QLNet/Termstructures/Iterativebootstrap.cs (modified) (1 diff)
- trunk/QLNet/QLNet/Termstructures/Yield/PiecewiseYieldCurve.cs (modified) (5 diffs)
- trunk/QLNet/QLNet/Termstructures/localbootstrap.cs (modified) (5 diffs)
- trunk/QLNet/QLNet/Time/Schedule.cs (modified) (7 diffs)
- trunk/QLNet/QLNet/Utils.cs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/QLNet/QLNet/Cashflows/Coupon.cs
r62 r214 22 22 using QLNet; 23 23 24 namespace QLNet 25 { 24 namespace QLNet { 26 25 //! %coupon accruing over a fixed period 27 26 //! This class implements part of the CashFlow interface but it is 28 27 // still abstract and provides derived classes with methods for accrual period calculations. 29 public abstract class Coupon : CashFlow 30 { 28 public abstract class Coupon : CashFlow { 31 29 protected double nominal_; 32 30 protected Date paymentDate_, accrualStartDate_, accrualEndDate_, refPeriodStart_, refPeriodEnd_; … … 54 52 public Coupon(double nominal, Date paymentDate, Date accrualStartDate, Date accrualEndDate, Date refPeriodStart) : 55 53 this(nominal, paymentDate, accrualStartDate, accrualEndDate, refPeriodStart, null) { } 56 public Coupon(double nominal, Date paymentDate, Date accrualStartDate, Date accrualEndDate, Date refPeriodStart, Date refPeriodEnd) 57 { 54 public Coupon(double nominal, Date paymentDate, Date accrualStartDate, Date accrualEndDate, Date refPeriodStart, Date refPeriodEnd) { 58 55 nominal_ = nominal; 59 56 paymentDate_ = paymentDate; … … 67 64 } 68 65 69 public double accrualPeriod()70 { //! accrual period as fraction of year66 //! accrual period as fraction of year 67 public double accrualPeriod() { 71 68 return dayCounter().yearFraction(accrualStartDate_, accrualEndDate_, refPeriodStart_, refPeriodEnd_); 72 69 } 73 public int accrualDays 74 { //! accrual period in days 75 get { return dayCounter().dayCount(accrualStartDate_, accrualEndDate_); } 76 } 77 78 // recheck 79 //void Coupon::accept(AcyclicVisitor& v) { 80 // Visitor<Coupon>* v1 = dynamic_cast<Visitor<Coupon>*>(&v); 81 // if (v1 != 0) 82 // v1->visit(*this); 83 // else 84 // CashFlow::accept(v); 85 //} 70 //! accrual period in days 71 public int accrualDays() { return dayCounter().dayCount(accrualStartDate_, accrualEndDate_); } 86 72 } 87 73 } trunk/QLNet/QLNet/Cashflows/averagebmacoupon.cs
r62 r214 67 67 68 68 //! fixings of the underlying index to be averaged 69 public List<double> indexFixings() { 70 List<double> fixings = new List<double>(); 71 for (int i=0; i<fixings.Count; ++i) 72 fixings.Add(index_.fixing(fixingSchedule_.date(i))); 73 return fixings; 74 } 69 public List<double> indexFixings() { return fixingSchedule_.dates().Select(d => index_.fixing(d)).ToList(); } 75 70 76 71 public override double convexityAdjustment() { trunk/QLNet/QLNet/Termstructures/Iterativebootstrap.cs
r211 r214 56 56 57 57 // check that there is no instruments with invalid quote 58 i = ts_.instruments_.FindIndex(x => !x.quoteIsValid()); 59 if (i != -1) 58 if ((i = ts_.instruments_.FindIndex(x => !x.quoteIsValid())) != -1) 60 59 throw new ArgumentException("instrument " + i + " (maturity: " + ts_.instruments_[i].latestDate() + 61 60 ") has an invalid quote"); trunk/QLNet/QLNet/Termstructures/Yield/PiecewiseYieldCurve.cs
r211 r214 23 23 24 24 namespace QLNet { 25 // this is theabstract class to give access to all properties and methods of PiecewiseYieldCurve and avoiding generics25 // this is an abstract class to give access to all properties and methods of PiecewiseYieldCurve and avoiding generics 26 26 public abstract class IPiecewiseYieldCurve : YieldTermStructure, ITraits { 27 27 #region Properties … … 70 70 71 71 72 public class PiecewiseYieldCurve<Traits, Interpolator> 73 : PiecewiseYieldCurve<Traits, Interpolator, IterativeBootstrap> 72 public class PiecewiseYieldCurve<Traits, Interpolator> : PiecewiseYieldCurve<Traits, Interpolator, IterativeBootstrap> 74 73 where Traits : ITraits, new() 75 74 where Interpolator : IInterpolationFactory, new() { … … 99 98 100 99 101 public class PiecewiseYieldCurve<Traits, Interpolator, BootStrap> : IPiecewiseYieldCurve , ITraits100 public class PiecewiseYieldCurve<Traits, Interpolator, BootStrap> : IPiecewiseYieldCurve 102 101 where Traits : ITraits, new() 103 102 where Interpolator : IInterpolationFactory, new() … … 230 229 calculate(); 231 230 Dictionary<Date, double> results = new Dictionary<Date, double>(); 232 for (int i = 0; i < dates_.Count; ++i) 233 results.Add(dates_[i], data_[i]); 231 dates_.ForEach((i, x) => results.Add(x, data_[i])); 234 232 return results; 235 233 } … … 248 246 if (jumpDates_.Count != 0 && jumps_.Count != 0) { // turn of year dates 249 247 jumpDates_ = new InitializedList<Date>(nJumps_); 248 jumpDates_.ForEach((i, d) => jumpDates_[i] = new Date(31, Month.December, refDate.Year + i)); 249 250 250 jumpTimes_ = new InitializedList<double>(nJumps_); 251 for (int i=0; i<nJumps_; ++i)252 jumpDates_[i] = new Date(31, Month.December, refDate.Year + i);253 251 } else { // fixed dats 254 252 if (!(jumpDates_.Count == nJumps_)) trunk/QLNet/QLNet/Termstructures/localbootstrap.cs
r211 r214 44 44 45 45 public override double value(Vector x) { 46 int i = initialIndex_; 47 x.ForEach(z => { 48 curve_.updateGuess(curve_.data_, z, i); 49 ++i; 50 }); 46 x.ForEach((j, v) => curve_.updateGuess(curve_.data_, v, j + initialIndex_)); 51 47 52 48 curve_.interpolation_.update(); 53 49 54 double penalty = 0.0; 55 for(int j = start_; j < end_; j++) { 56 double quoteError = rateHelpers_[j].quoteError(); 57 penalty += Math.Abs(quoteError); 58 } 50 double penalty = rateHelpers_.GetRange(start_, localisation_) 51 .Aggregate(0.0, (acc, v) => Math.Abs(v.quoteError())); 59 52 return penalty; 60 53 } 61 54 62 55 public override Vector values(Vector x) { 63 int i = initialIndex_; 64 x.ForEach(z => { 65 curve_.updateGuess(curve_.data_, z, i); 66 ++i; 67 }); 56 x.ForEach((j, v) => curve_.updateGuess(curve_.data_, v, j + initialIndex_)); 68 57 69 58 curve_.interpolation_.update(); 70 59 71 Vector penalties = new Vector(localisation_); 72 var instIt = start_; 73 int penIt = 0; 74 while (instIt != end_) { 75 double quoteError = rateHelpers_[instIt].quoteError(); 76 penalties[penIt] = Math.Abs(quoteError); 77 ++instIt; 78 ++penIt; 79 } 80 return penalties; 60 var penalties = rateHelpers_.GetRange(start_, localisation_).Select(c => Math.Abs(c.quoteError())).ToList(); 61 return new Vector(penalties); 81 62 } 82 63 } … … 133 114 134 115 validCurve_ = false; 135 int nInsts = ts_.instruments_.Count ;116 int nInsts = ts_.instruments_.Count, i; 136 117 137 118 // ensure rate helpers are sorted … … 139 120 140 121 // check that there is no instruments with the same maturity 141 for (i nt i= 1; i < nInsts; ++i) {122 for (i = 1; i < nInsts; ++i) { 142 123 Date m1 = ts_.instruments_[i - 1].latestDate(), 143 124 m2 = ts_.instruments_[i].latestDate(); … … 146 127 147 128 // check that there is no instruments with invalid quote 148 for (int i = 0; i < nInsts; ++i) 149 if (!ts_.instruments_[i].quoteIsValid()) 150 throw new ArgumentException("instrument " + i + " (maturity: " + ts_.instruments_[i].latestDate() + 151 ") has an invalid quote"); 129 if ((i = ts_.instruments_.FindIndex(x => !x.quoteIsValid())) != -1) 130 throw new ArgumentException("instrument " + i + " (maturity: " + ts_.instruments_[i].latestDate() + 131 ") has an invalid quote"); 152 132 153 133 // setup instruments and register with them 154 ts_.instruments_.ForEach( i => i.setTermStructure(ts_));134 ts_.instruments_.ForEach(j => j.setTermStructure(ts_)); 155 135 156 136 // set initial guess only if the current curve cannot be used as guess … … 168 148 ts_.dates_[0] = ts_.initialDate(ts_); 169 149 ts_.times_[0] = ts_.timeFromReference(ts_.dates_[0]); 170 for (i nt i= 0; i < nInsts; ++i) {150 for (i = 0; i < nInsts; ++i) { 171 151 ts_.dates_[i + 1] = ts_.instruments_[i].latestDate(); 172 152 ts_.times_[i + 1] = ts_.timeFromReference(ts_.dates_[i + 1]); trunk/QLNet/QLNet/Time/Schedule.cs
r62 r214 53 53 private List<bool> isRegular_ = new List<bool>(); 54 54 55 public List<Date> dates() { 56 List<Date> result = new List<Date>(); 57 foreach(Date d in adjustedDates_) 58 result.Add(d); 59 return result; 60 } 55 public List<Date> dates() { return new List<Date>(adjustedDates_); } 61 56 public int Count { get { return adjustedDates_.Count; } } 62 57 … … 87 82 #endregion 88 83 89 // constructors84 #region Constructors 90 85 public Schedule() { } 91 public Schedule(List<Date> dates__, Calendar calendar__, BusinessDayConvention convention__) {92 fullInterface_ = false;93 tenor_ = new Period();94 calendar_ = calendar__;95 convention_ = convention__;96 terminationDateConvention_ = convention__;97 rule_ = DateGeneration.Rule.Forward;98 endOfMonth_ = false;86 public Schedule(List<Date> dates__, Calendar calendar__, BusinessDayConvention convention__) { 87 fullInterface_ = false; 88 tenor_ = new Period(); 89 calendar_ = calendar__; 90 convention_ = convention__; 91 terminationDateConvention_ = convention__; 92 rule_ = DateGeneration.Rule.Forward; 93 endOfMonth_ = false; 99 94 adjustedDates_ = dates__; 100 }95 } 101 96 public Schedule(Date effectiveDate__, Date terminationDate__, Period tenor__, Calendar calendar__, 102 97 BusinessDayConvention convention__, BusinessDayConvention terminationDateConvention__, … … 104 99 : this(effectiveDate__, terminationDate__, tenor__, calendar__, 105 100 convention__, terminationDateConvention__, rule__, endOfMonth__, null, null) { } 106 public Schedule(Date effectiveDate__, Date terminationDate__, Period tenor__, Calendar calendar__,101 public Schedule(Date effectiveDate__, Date terminationDate__, Period tenor__, Calendar calendar__, 107 102 BusinessDayConvention convention__, BusinessDayConvention terminationDateConvention__, 108 103 DateGeneration.Rule rule__, bool endOfMonth__, 109 104 Date firstDate__, Date nextToLastDate__) { 110 // first save the properties111 fullInterface_ = true;112 tenor_ = tenor__;113 calendar_ = calendar__;114 convention_ = convention__;115 terminationDateConvention_ = terminationDateConvention__;116 rule_ = rule__;117 endOfMonth_ = endOfMonth__;118 firstDate_ = firstDate__;119 nextToLastDate_ = nextToLastDate__;120 121 // sanity checks122 if (effectiveDate__ == null) throw new ArgumentException("Null effective date");123 if (terminationDate__ == null) throw new ArgumentException("Null termination date");124 if (effectiveDate__ >= terminationDate__) throw new ArgumentException("Effective date (" + effectiveDate__ +125 ") is later than or equal to termination date (" + terminationDate__ + ")");105 // first save the properties 106 fullInterface_ = true; 107 tenor_ = tenor__; 108 calendar_ = calendar__; 109 convention_ = convention__; 110 terminationDateConvention_ = terminationDateConvention__; 111 rule_ = rule__; 112 endOfMonth_ = endOfMonth__; 113 firstDate_ = firstDate__; 114 nextToLastDate_ = nextToLastDate__; 115 116 // sanity checks 117 if (effectiveDate__ == null) throw new ArgumentException("Null effective date"); 118 if (terminationDate__ == null) throw new ArgumentException("Null termination date"); 119 if (effectiveDate__ >= terminationDate__) throw new ArgumentException("Effective date (" + effectiveDate__ + 120 ") is later than or equal to termination date (" + terminationDate__ + ")"); 126 121 127 122 if (tenor_.units() == 0) 128 rule_ = DateGeneration.Rule.Zero;123 rule_ = DateGeneration.Rule.Zero; 129 124 else if (tenor_.units() < 0) 130 throw new ArgumentException("Non positive tenor (" + tenor_ + ") is not allowed");131 132 // though firstDate_ and nextToLastDate are always provided133 if (firstDate_ != null) {134 switch (rule_) {135 case DateGeneration.Rule.Backward:136 case DateGeneration.Rule.Forward:137 if (!(firstDate_ > effectiveDate__ && firstDate_ < terminationDate__))138 throw new ArgumentException("First date (" + firstDate_ + ") is out of range [effective date (" + effectiveDate__139 + "), termination date (" + terminationDate__ + ")]");140 break;141 case DateGeneration.Rule.Zero:142 case DateGeneration.Rule.ThirdWednesday:143 throw new ArgumentException("First date is incompatible with " + rule_ + " date generation rule");144 default:145 throw Error.UnknownDateGenerationRule(rule_);146 }147 }125 throw new ArgumentException("Non positive tenor (" + tenor_ + ") is not allowed"); 126 127 // though firstDate_ and nextToLastDate are always provided 128 if (firstDate_ != null) { 129 switch (rule_) { 130 case DateGeneration.Rule.Backward: 131 case DateGeneration.Rule.Forward: 132 if (!(firstDate_ > effectiveDate__ && firstDate_ < terminationDate__)) 133 throw new ArgumentException("First date (" + firstDate_ + ") is out of range [effective date (" + effectiveDate__ 134 + "), termination date (" + terminationDate__ + ")]"); 135 break; 136 case DateGeneration.Rule.Zero: 137 case DateGeneration.Rule.ThirdWednesday: 138 throw new ArgumentException("First date is incompatible with " + rule_ + " date generation rule"); 139 default: 140 throw Error.UnknownDateGenerationRule(rule_); 141 } 142 } 148 143 149 144 if (nextToLastDate_ != null) { 150 switch (rule_) {151 case DateGeneration.Rule.Backward:152 case DateGeneration.Rule.Forward:153 if (!(nextToLastDate_ > effectiveDate__ && nextToLastDate_ < terminationDate__))154 throw new ArgumentException("Next to last date (" + nextToLastDate_ + ") out of range [effective date (" + effectiveDate__155 + "), termination date (" + terminationDate__ + ")]");156 break;157 case DateGeneration.Rule.Zero:158 case DateGeneration.Rule.ThirdWednesday:159 throw new ArgumentException("Next to last date incompatible with " + rule_ + " date generation rule");160 default:161 throw Error.UnknownDateGenerationRule(rule_);162 }163 }164 165 // calendar needed for endOfMonth adjustment166 Calendar nullCalendar = new NullCalendar();167 int periods = 1;168 Date seed, exitDate;145 switch (rule_) { 146 case DateGeneration.Rule.Backward: 147 case DateGeneration.Rule.Forward: 148 if (!(nextToLastDate_ > effectiveDate__ && nextToLastDate_ < terminationDate__)) 149 throw new ArgumentException("Next to last date (" + nextToLastDate_ + ") out of range [effective date (" + effectiveDate__ 150 + "), termination date (" + terminationDate__ + ")]"); 151 break; 152 case DateGeneration.Rule.Zero: 153 case DateGeneration.Rule.ThirdWednesday: 154 throw new ArgumentException("Next to last date incompatible with " + rule_ + " date generation rule"); 155 default: 156 throw Error.UnknownDateGenerationRule(rule_); 157 } 158 } 159 160 // calendar needed for endOfMonth adjustment 161 Calendar nullCalendar = new NullCalendar(); 162 int periods = 1; 163 Date seed, exitDate; 169 164 switch (rule_) { 170 case DateGeneration.Rule.Zero:171 tenor_ = new Period(0, TimeUnit.Days);165 case DateGeneration.Rule.Zero: 166 tenor_ = new Period(0, TimeUnit.Days); 172 167 originalDates_.Add(effectiveDate__); 173 168 originalDates_.Add(terminationDate__); … … 175 170 break; 176 171 177 case DateGeneration.Rule.Backward:172 case DateGeneration.Rule.Backward: 178 173 originalDates_.Add(terminationDate__); 179 174 seed = terminationDate__; 180 if (nextToLastDate_ != null) {175 if (nextToLastDate_ != null) { 181 176 originalDates_.Insert(0, nextToLastDate_); 182 177 Date temp = nullCalendar.advance(seed, -periods * tenor_, convention_, endOfMonth_); 183 178 isRegular_.Insert(0, temp == nextToLastDate_); 184 179 seed = nextToLastDate_; 185 }186 exitDate = effectiveDate__;180 } 181 exitDate = effectiveDate__; 187 182 if (firstDate_ != null) 188 exitDate = firstDate_;189 while (true) {190 Date temp = nullCalendar.advance(seed, -periods*tenor_, convention_, endOfMonth_);191 if (temp < exitDate)192 break;193 else {183 exitDate = firstDate_; 184 while (true) { 185 Date temp = nullCalendar.advance(seed, -periods * tenor_, convention_, endOfMonth_); 186 if (temp < exitDate) 187 break; 188 else { 194 189 originalDates_.Insert(0, temp); 195 190 isRegular_.Insert(0, true); 196 191 ++periods; 197 }198 }199 if (endOfMonth_ && calendar_.isEndOfMonth(seed))200 convention_ = BusinessDayConvention.Preceding;192 } 193 } 194 if (endOfMonth_ && calendar_.isEndOfMonth(seed)) 195 convention_ = BusinessDayConvention.Preceding; 201 196 if (calendar_.adjust(originalDates_[0], convention_) != calendar_.adjust(effectiveDate__, convention_)) { 202 197 originalDates_.Insert(0, effectiveDate__); 203 198 isRegular_.Insert(0, false); 204 199 } 205 break;200 break; 206 201 207 202 case DateGeneration.Rule.ThirdWednesday: … … 209 204 goto case DateGeneration.Rule.Forward; // fall through 210 205 211 case DateGeneration.Rule.Forward:206 case DateGeneration.Rule.Forward: 212 207 originalDates_.Add(effectiveDate__); 213 208 seed = effectiveDate__; 214 if (firstDate_ != null) {209 if (firstDate_ != null) { 215 210 originalDates_.Add(firstDate_); 216 211 Date temp = nullCalendar.advance(seed, periods * tenor_, convention_, endOfMonth_); 217 212 isRegular_.Add(temp == firstDate_); 218 213 seed = firstDate_; 219 }220 exitDate = terminationDate__;221 if (nextToLastDate_ != null)222 exitDate = nextToLastDate_;223 while (true) {224 Date temp = nullCalendar.advance(seed, periods*tenor_, convention_, endOfMonth_);225 if (temp > exitDate)226 break;227 else {214 } 215 exitDate = terminationDate__; 216 if (nextToLastDate_ != null) 217 exitDate = nextToLastDate_; 218 while (true) { 219 Date temp = nullCalendar.advance(seed, periods * tenor_, convention_, endOfMonth_); 220 if (temp > exitDate) 221 break; 222 else { 228 223 originalDates_.Add(temp); 229 224 isRegular_.Add(true); 230 225 ++periods; 231 }232 }233 if (endOfMonth_ && calendar_.isEndOfMonth(seed))234 convention_ = BusinessDayConvention.Preceding;226 } 227 } 228 if (endOfMonth_ && calendar_.isEndOfMonth(seed)) 229 convention_ = BusinessDayConvention.Preceding; 235 230 if (calendar_.adjust(originalDates_.Last(), terminationDateConvention_) != calendar_.adjust(terminationDate__, terminationDateConvention_)) { 236 231 originalDates_.Add(terminationDate__); 237 232 isRegular_.Add(false); 238 233 } 239 break;240 241 default:242 throw Error.UnknownDateGenerationRule(rule_);243 }234 break; 235 236 default: 237 throw Error.UnknownDateGenerationRule(rule_); 238 } 244 239 245 240 // adjustments to holidays, etc. … … 248 243 originalDates_[i] = Date.nthWeekday(3, DayOfWeek.Wednesday, originalDates_[i].Month, originalDates_[i].Year); 249 244 250 foreach (Date d in originalDates_)245 foreach (Date d in originalDates_) 251 246 adjustedDates_.Add(calendar_.adjust(d, convention_)); 252 247 253 // termination date is NOT adjusted as per ISDA specifications unless otherwise specified in the confirmation of the deal254 if (terminationDateConvention_ != BusinessDayConvention.Unadjusted)248 // termination date is NOT adjusted as per ISDA specifications unless otherwise specified in the confirmation of the deal 249 if (terminationDateConvention_ != BusinessDayConvention.Unadjusted) 255 250 adjustedDates_[adjustedDates_.Count - 1] = calendar_.adjust(originalDates_.Last(), terminationDateConvention_); 256 } 251 } 252 #endregion 257 253 258 254 private void CheckInterface() { if (!fullInterface_) throw new ArgumentException("full interface not available"); } 259 255 256 // returns the period of the Schedule during which Date d happens 260 257 public int periodOfDate(Date d) { 261 258 int result = adjustedDates_.BinarySearch(d); … … 264 261 return result; 265 262 } 263 264 //// looks up the date of the previous period point relative to Date d 265 //public Date previousDate(Date d) { 266 // int i = periodOfDate(d); 267 // return this[i - 1]; 268 //} 269 270 //// looks up the date of the next period point relative to Date d 271 //public Date nextDate(Date d) { 272 // int i = periodOfDate(d); 273 // return this[i + 1]; 274 //} 266 275 267 276 // Iterator interface trunk/QLNet/QLNet/Utils.cs
r204 r214 23 23 24 24 namespace QLNet { 25 // here are extensions to IList to accomodate some QL functionality as well as have useful things for .net 25 26 public static partial class Utils { 27 // equivalent of ForEach but with the index 28 public static void ForEach<T>(this IList<T> items, Action<int, T> action) { 29 if (items != null && action != null) 30 for (int idx = 0; idx < items.Count; idx++) 31 action(idx, items[idx]); 32 } 33 34 // this is a version of element retrieval with some logic for default values 26 35 public static T Get<T>(this List<T> v, int i) { return Get(v, i, default(T)); } 27 36 public static T Get<T>(this List<T> v, int i, T defval) { … … 30 39 else return v[i]; 31 40 } 41 } 32 42 43 44 public static partial class Utils { 33 45 public static double effectiveFixedRate(List<double> spreads, List<double> caps, List<double> floors, int i) { 34 46 double result = Get(spreads, i);