CLEAN
Valuation library for mortgage-backed securities
structs.h
1 // -*-C++-*- make sure Emacs is in C++ mode
2 //
3 // ==================================================
4 // andrew_kalotay_associates/common/structs.h
5 // ==================================================
6 //
7 // :Version: 1.0.0
8 // :Date: 2020-6-1
9 //
10 // Copyright (c) 2008-COPYRIGHT, Andrew Kalotay Associates. All rights reserved.
11 // Consult your license for permissions and restrictions.
12 //
13 // Description:
14 // ++++++++++++
15 //
16 // - Data structs used for inputs to and outputs from
17 // classes.
18 // - Common structs are in main namespace.
19 // - Input structs are in namespace ``Input``.
20 // - Output structs are in namespace ``Output``.
21 //
22 // ------------------------------------------------------
23 //
24 #ifndef INCLUDED_ANDREW_KALOTAY_ASSOCIATES_COMMON_STRUCTS_H
25 #define INCLUDED_ANDREW_KALOTAY_ASSOCIATES_COMMON_STRUCTS_H
26 
27 // Include directives
28 // ++++++++++++++++++++
29 //
30 // `dll_macros`_ : needed for Windows API
31 // ---------------------------------------
32 //
33 // .. _`dll_macros`: dll_macros.html
34 //
35 #include "andrew_kalotay_associates/common/dll_macros.h"
36 
37 //
38 // `enums`_ used by structs below
39 // -------------------------------
40 //
41 // .. _`enums`: enums.html
42 //
43 #include "andrew_kalotay_associates/common/enums.h"
44 
45 //
46 // String_ and Array_ classes
47 // --------------------------
48 // .. _`String`: string.html
49 // .. _`Array`: array.html
50 //
51 #include "andrew_kalotay_associates/common/string.h"
52 #include "andrew_kalotay_associates/common/array.h"
53 
54 namespace AndrewKalotayAssociates
55 {
56  namespace Common
57  {
59  COMMON_API
60  double QuietNaN();
61 
63  COMMON_API
64  int IntMax();
65 
67  // IntMin()
68  // --------
69  COMMON_API
70  int IntMin();
71 
72  // Common structs
73  // +++++++++++++++
74  //
75  struct COMMON_API Date
76  {
77  long year;
78  long month;
79  long day;
80 
82  Date(long input_year = 0,
83  long input_month = 0,
84  long input_day = 0);
85 
87  long to_long() const;
88 
90  bool operator!() const;
91 
92  bool operator==(const Date& rhs) const;
93 
94  bool operator!=(const Date& rhs) const;
95 
96  bool operator<(const Date& rhs) const;
97 
98  bool is_before(const Date& rhs) const;
99 
100  bool operator>(const Date& rhs) const;
101 
102  bool operator<=(const Date& rhs) const;
103 
104  bool is_on_or_before(const Date& rhs) const;
105 
106  bool operator>=(const Date& rhs) const;
107 
108  Date add_months(int months) const;
109  Date add_days(int days) const;
110  };
111 
112 
113  struct COMMON_API CalendarPeriod
114  {
117 
120  };
121 
122  // TimeDifference
123  // ---------------
124  struct COMMON_API TimeDifference
125  {
127  long periods;
128 
130  CalendarUnits::type units;
131 
133  TimeDifference(long input_periods = IntMin(),
134  CalendarUnits::type input_units = CalendarUnits::unknown);
135 
136  bool operator==(const TimeDifference& rhs) const;
137 
138  bool operator!=(const TimeDifference& rhs) const;
139 
141  long months() const;
142 
145  double years() const;
146 
147  bool operator<(const TimeDifference& rhs) const;
148  bool operator>(const TimeDifference& rhs) const;
149  bool operator<=(const TimeDifference& rhs) const;
150  bool operator>=(const TimeDifference& rhs) const;
151  };
152 
153  namespace Input
154  {
155  //
156  // Structs for input data
157  // +++++++++++++++++++++++
158  //
159  // Input::Yield
160  // -------------
162  struct COMMON_API Yield
163  {
164  TimeDifference maturity;
165 
167  double rate;
168 
170  Yield(TimeDifference input_maturity = TimeDifference(),
171  double input_rate = QuietNaN());
172 
173  ~Yield();
174  };
175 
176  // Input::ForwardYield
177  // ---------------------
180  struct COMMON_API ForwardYield
181  {
184  Yield yield;
185 
188 
189  ForwardYield(const Date& input_date,
190  const Yield& input_yield);
191  };
192 
193  // Input::ParYieldCurve
194  // ---------------------
203  struct COMMON_API ParYieldCurve
204  {
207 
209  Daycount::type simple_daycount;
210 
212  Daycount::type par_daycount;
213 
216 
217  Array<Yield> simple_yields;
218  Array<ForwardYield> forward_yields;
219  Array<Yield> par_yields;
220 
221  ParYieldCurve()
222  :simple_business_day_convention(0),
223  simple_daycount(Daycount::actual_360),
224  par_daycount(Daycount::d30_360),
225  par_coupon_frequency(CalendarFrequency::semiannual)
226  {}
227 
228  bool operator!() const
229  {
230  return (0 == simple_yields.size()) &&
231  (0 == forward_yields.size()) &&
232  (0 == par_yields.size());
233  }
234  };
235 
236  //
237  // Input::SpotCurve
238  // ----------------
239  //
240  // - daycount = Daycount_ convention used for
241  // converting yields into future cashflows
242  // - compound_frequency = CalendarFrequency_
243  // used for compounding yields
244  // - spot_yields = Array of compounded zero coupon `Input::Yield`_
245  //
246  struct COMMON_API SpotCurve
247  {
248  Daycount::type daycount;
249  CalendarFrequency::type compound_frequency;
250  Array<Yield> yields;
251 
252  bool operator!() const;
253  };
254 
255  //
256  // Input::SpreadCurve
257  // -------------------
259  struct COMMON_API SpreadCurve
260  {
263  int sign;
264 
265  Array<Yield> spreads;
266 
267  SpreadCurve();
268  };
269 
270  // Input::DiscountFactor
271  // ----------------------
272  //
275  struct COMMON_API DiscountFactor
276  {
277  Date date;
278 
279  double factor;
280 
281  DiscountFactor(Date input_date = Date(),
282  double input_factor = QuietNaN());
283  };
284 
285  // Input::DiscountCurve
286  // ----------------------
288  struct COMMON_API DiscountCurve
289  {
290  Date settlement_date;
291  Array<DiscountFactor> discount_factors;
292  };
293 
294  // Input::CurrencyForward
295  // -------------------------
297  struct COMMON_API CurrencyForward
298  {
299  Date maturity;
300  double rate;
301 
302  CurrencyForward(Date input_maturity = Date(),
303  double input_rate = QuietNaN());
304  };
305 
306  // Input::CurrencyForwardCurve
307  // ---------------------------------
312  // forwards = Array_ of `Input::CurrencyForward`_
313  //
314  struct COMMON_API CurrencyForwardCurve
315  {
318  Array<CurrencyForward> forwards;
319  };
320 
321  // Input::IndexValue
322  // ----------------------------
324  struct COMMON_API IndexValue
325  {
326  Date date;
327  double index;
328 
329  IndexValue(Date input_date = Date(),
330  double input_index = QuietNaN());
331  };
332 
333  // Input::IndexHistory
334  // -----------------------
335  struct COMMON_API IndexHistory
336  {
337  Array<IndexValue> values;
338  };
339 
340  // Input::SwaptionVolatilityMatrix
341  // ---------------------------------
342  //
343  // option_maturities = Array_ of TimeDifference_
344  // representing swaption maturities
345  //
346  // swap_maturities = Array_ of TimeDifference_
347  // representing foward swap maturities
348  // (relative to option exercise date)
349  //
350  // volatilities = matrix of volatilities
351  // flattened into an Array_ of doubles.
352  // Each volatility is specified as an absolute double
353  // (0.10 = 10%)
354  //
355  // If
356  //
357  // - options_size = option_maturities.size()
358  // - swaps_size = swap_maturities.size()
359  // - 0 <= j < swaps_size
360  // - 0 <= i < options_size
361  //
362  // then
363  //
364  // volatilities[j + swaps_size * i] =
365  // volatility of a forward swap whose start
366  // is specified by option_maturities[i]
367  // and whose maturity (from start) is
368  // specified by swap_maturities[j]
369  //
370  struct COMMON_API SwaptionVolatilityMatrix
371  {
372  Array<TimeDifference> option_maturities;
373  Array<TimeDifference> swap_maturities;
374  Array<double> volatilities;
375  };
376 
377  //
378  // Input::CapVolatilityMatrix
379  // ----------------------------
380  //
381  // option_maturities = Array_ of TimeDifference_
382  // representing cap maturities
383  //
384  // - strikes = Array_ of double
385  // representing cap strikes (0.10 = 10%)
386  // - volatilities = matrix of volatilities
387  // flattened into an Array_ of doubles.
388  // Each volatility is specified as an absolute double
389  // (0.10 = 10%)
390  //
391  // If
392  //
393  // - options_size = option_maturities.size()
394  // - strikes_size = strikes.size()
395  // - 0 <= j < swaps_size
396  // - 0 <= i < options_size
397  //
398  // then
399  //
400  // volatilities[j + strikes_size * i] =
401  // volatility of a cap whose option_maturity
402  // is option_maturities[i] and whose strike
403  // is strikes[j].
404  //
405  struct COMMON_API CapVolatilityMatrix
406  {
407  Array<TimeDifference> option_maturities;
408  Array<double> strikes;
409  Array<double> volatilities;
410  };
411 
412  // Input::YieldParameters
413  // ------------------------
418  struct COMMON_API YieldParameters
419  {
420  Daycount::type daycount;
421  CalendarFrequency::type frequency;
422  double initial_guess;
423  double tolerance;
424  int iterations;
425  bool use_compounded_yield;
426 
428  :daycount(Daycount::d30_360),
430  initial_guess(0.05),
431  tolerance(1E-5),
432  iterations(10),
433  use_compounded_yield(false)
434  {}
435 
436  };
437 
438  //
439  // Security terms and conditions
440  // ++++++++++++++++++++++++++++++
441  //
442  // Input::CommonTerms
443  // --------------------
444  //
445  // - initial_principal = starting principal amount,
446  // usually set to 100
447  // - effective = start Date_ of bond or swap,
448  // also known as dated date
449  // - maturity = maturity Date_
450  //
451  struct COMMON_API CommonTerms
452  {
455 
458 
461 
464  :initial_principal(100)
465  {}
466 
467  };
468 
469  // Input::CouponTerms
470  // --------------------
471  struct COMMON_API CouponTerms
472  {
473  long ex_coupon_days;
474 
476  Daycount::type daycount;
477 
480 
483 
487 
492 
495 
498 
500  BusinessDayConvention::type business_day_convention;
501 
506  :ex_coupon_days(0),
507  daycount(Daycount::d30_360),
508  reset_frequency(CalendarFrequency::semiannual),
509  payment_frequency(CalendarFrequency::semiannual),
510  end_of_month(false),
511  in_arrears(false),
512  current_index(0),
513  business_day_convention(BusinessDayConvention::unadjusted)
514  {}
515  };
516 
517  // Input::CouponParameters
518  // ------------------------
519  struct COMMON_API CouponParameters
520  {
521  Date start;
522 
528 
529  enum type_type
530  {
531  standard = 0,
532  range_accrual = 1
533  };
534 
538  type_type type;
539 
542  double index_factor;
543 
546  double floor;
547 
550  double cap;
551 
554  :fixed_interest(0),
555  type(standard),
556  index_factor(0),
557  floor(0),
558  cap(0)
559  {}
560 
561  CouponParameters(const Date& input_start,
562  double input_fixed_interest,
563  double input_index_factor = 0,
564  type_type input_type = standard,
565  double input_floor = 0,
566  double input_cap = 0);
567  };
568 
569  // Input::PrincipalPayment
570  // -------------------------
572  struct COMMON_API PrincipalPayment
573  {
576 
578  double amount;
579 
581  PrincipalPayment(Date input_date = Date(), double input_amount = 0);
582  };
583 
584  //
585  // Input::BulletBond
586  // ------------------
588  struct COMMON_API BulletBond
589  {
592  BondType::type type;
593 
594  CommonTerms common_terms;
595  CouponTerms coupon_terms;
596 
599 
602 
615 
618 
621  :type(BondType::fixed)
622  {}
623 
624  };
625 
626  // Input::StrikeScheduleItem
627  // ------------------------------
629  struct COMMON_API StrikeScheduleItem
630  {
634 
636  double strike;
637 
639  StrikeScheduleItem(Date input_start = Date(),
640  double input_strike = 100.0);
641  };
642 
643  //
644  // Input::Option
645  // --------------
647  // - notice_period = TimeDifference_ specifying
648  // how far in advance one must announce that
649  // a put or call will be exercised
650  // - frequency = CalendarFrequency_ of option exercise
651  // opportunities.
652  //
653  // - Set to CalendarFrequency::zero if there is no option
654  // - Set to CalendarFrequency::custom for European option or
655  // a custom discrete exercise schedule
656  // - Set to CalendarFrequency::daily for American option
657  // - Set to appropriate value for Bermudan option
658  //
659  // - end = maturity Date for standard options or
660  // earlier date for canary options
661  //
662  struct COMMON_API Option
663  {
666 
670 
673 
677 
680  :frequency(CalendarFrequency::zero)
681  {}
682  };
683 
684  // Input::Security
685  // -----------------
686  // Template data struct for a fixed or floating rate security
687  // with or without a call or put
688  // template <class BondType>
689  // struct COMMON_API Security
690  // {
691  // typedef Security<BondType> this_type;
692  //
693  // BondType bond;
694  // Option call;
695  // Option put;
696  // };
697 
698  // Input::Quote
699  // --------------
701  struct COMMON_API Quote
702  {
705  {
706  unspecified = -1,
707  oas = 0, // Conforms with BondOAS value
708  clean_price = 1, // Conforms with BondOAS value
709  dirty_price = 10,
710  yield_to_maturity = 2, // Conforms with BondOAS value
711  yield_to_call = 3, // Conforms with BondOAS value
712  yield_to_worst = 9,
713  discount_margin = 20, // For floaters only
714  das = 100, // Used by DefaultAdjustedSpread library
715  };
716 
719 
721  double value;
722 
725  :type(unspecified),
726  value(QuietNaN())
727  {}
728 
729  bool is_price() const;
730  };
731  }
732 
733  //
734  // Output data structs
735  // +++++++++++++++++++++
736  //
737  // Returns error code and message String_
738  //
739  namespace Output
740  {
755  struct COMMON_API Status
756  {
757  int code;
758 
761 
765  {
766  ok = 0,
767  warning = 2,
768  no_lattice_model = 2*2,
769  fatal = 256,
770  invalid_license = 256*2,
771  no_curve_model= 256*4,
772  computation_failed = 256*8,
773  invalid_quote = 256*16,
774  no_default_model = 256*32,
775  no_stock_model = 256*64,
776  invalid_handle = 256*256*256
777  };
778 
779  bool operator!() const;
780 
782  Status(code_type this_code = ok,
783  const char* this_message = "");
784 
787 
789  void set_to_worst(int this_code = Status::ok);
790 
792  void set_message(const char* m);
793 
795  void set(int code = ok, const char* m = "");
796 
798  void set_to_worst(int code, const char* m);
799 
801  void set_to_worst(Status status);
802  };
803 
804  // Output::Price
805  // --------------
807  struct COMMON_API Price
808  {
809  double clean_price;
810  double accrued_interest;
811  double dirty_price;
812  double oas;
813 
814  double call_value;
815  double put_value;
816 
819  :clean_price(QuietNaN()),
820  accrued_interest(QuietNaN()),
821  dirty_price(QuietNaN()),
822  oas(QuietNaN()),
823  call_value(QuietNaN()),
824  put_value(QuietNaN())
825  {}
826 
827  const Status& status() const;
828 
830  void set(const Status& status);
833  const char* m);
834 
835  // private:
836  Status status_;
837  };
838 
839  // Output::Risk
840  // --------------
842  struct COMMON_API Risk
843  {
844  double duration;
845  double convexity;
846 
849  :duration(QuietNaN()),
850  convexity(QuietNaN())
851  {}
852 
853  };
854 
855  // Output::PartialDuration
856  // ------------------------
857  struct COMMON_API PartialDuration
858  {
859  TimeDifference maturity;
860  double duration;
861 
863  :duration(QuietNaN())
864  {}
865  };
866 
867  // Output::Yield
868  // --------------
870  struct COMMON_API Yield
871  {
872  double yield;
873  double clean_price;
874  double accrued_interest;
875  Date redemption_date;
876 
878  const Risk& modified_risk() const;
879 
880  const Status& status() const;
881 
884  :yield(QuietNaN()),
885  clean_price(QuietNaN()),
886  accrued_interest(QuietNaN())
887  {}
888 
890  void set(const Risk& modified_risk);
892  void set(const Status& status);
893 
894  // private:
895  Risk modified_risk_;
896  Status status_;
897  };
898 
899  // Output::Cashflow
900  // -----------------
901  struct COMMON_API Cashflow
902  {
903  double principal;
904  double interest;
905 
906  Cashflow()
907  :principal(QuietNaN()),
908  interest(QuietNaN())
909  {}
910 
911  };
912 
913  // Output::BondCashflow
914  // ---------------------
915  struct COMMON_API BondCashflow
916  {
917  Date date;
918  double principal;
919  double interest;
920 
921  BondCashflow()
922  :principal(QuietNaN()),
923  interest(QuietNaN())
924  {}
925  };
926  }
927  }
928 }
929 
930 
931 #endif
932 
933 // .. _`BondType`: enums.html#BondType
934 // .. _`CalendarUnits`: enums.html#CalendarUnits
935 // .. _`BusinessDayConvention`: enums.html#BusinessDayConvention
936 // .. _`BusinessCenter`: enums.html#BusinessCenter
937 // .. _`Daycount`: enums.html#Daycount
938 // .. _`CalendarFrequency`: enums.html#CalendarFrequency
@ semiannual
6 months
Definition: enums.h:122
Date end
Day after last day of period.
Definition: structs.h:119
Date start
Start of period.
Definition: structs.h:116
Date(long input_year=0, long input_month=0, long input_day=0)
Default constructor sets year, month, date to zero.
Terms of a bond without calls or puts.
Definition: structs.h:589
Array< PrincipalPayment > principal_payments
If sinking or amortizing bond, set up principal payment schedule.
Definition: structs.h:617
Date first_coupon_date
Start of second coupon period after issue.
Definition: structs.h:598
BulletBond()
Default constructor leaves everything uninitialized.
Definition: structs.h:620
Date penultimate_coupon_date
Start of last coupon period.
Definition: structs.h:601
Array< CouponParameters > coupon_schedule
Definition: structs.h:614
BondType::type type
Definition: structs.h:592
Date maturity
End of last coupon period.
Definition: structs.h:460
double initial_principal
Face value at issue. Leave at default value of 100.
Definition: structs.h:454
CommonTerms()
initial_principal initialized to 100, dates set to invalid values
Definition: structs.h:463
Date effective
Start of first coupon period.
Definition: structs.h:457
CouponParameters()
Default constructor assumes fixed coupon with rate equal to zero.
Definition: structs.h:553
double current_index
Unused.
Definition: structs.h:497
CalendarFrequency::type payment_frequency
How often is the coupon paid.
Definition: structs.h:482
Date last_reset_date
Unused.
Definition: structs.h:494
Daycount::type daycount
Daycount used to calculate cash flow from interest rate.
Definition: structs.h:476
BusinessDayConvention::type business_day_convention
Business day convention for payment date.
Definition: structs.h:500
CalendarFrequency::type reset_frequency
If floating, how often is the index reset.
Definition: structs.h:479
Date settlement_date
settlement_date of spot FX contract
Definition: structs.h:317
Forward currency rate.
Definition: structs.h:298
Discount factor curve.
Definition: structs.h:289
Date settlement_date
Settlement date of forward or futures contract.
Definition: structs.h:183
ForwardYield()
Default constructor initializes to invalid value.
Date_ and value of a floating index.
Definition: structs.h:325
Terms of a call or put option.
Definition: structs.h:663
Option()
Default constructor is no option.
Definition: structs.h:679
CalendarFrequency::type frequency
Definition: structs.h:669
Array< StrikeScheduleItem > strike_schedule
Definition: structs.h:676
Date end
Set to maturity date unless option ends before it.
Definition: structs.h:672
TimeDifference notice_period
How much advance notice must be given for a call or put.
Definition: structs.h:665
Daycount::type par_daycount
Daycount convention for par yield.
Definition: structs.h:212
long simple_business_day_convention
Business day convention for settlement and maturity date of simple yield.
Definition: structs.h:206
CalendarFrequency::type par_coupon_frequency
Coupon frequency of par bonds.
Definition: structs.h:215
Daycount::type simple_daycount
Daycount convention for simple yield.
Definition: structs.h:209
Used for sinking or amortizing bonds.
Definition: structs.h:573
double amount
Amount of principal payment.
Definition: structs.h:578
PrincipalPayment(Date input_date=Date(), double input_amount=0)
Default constructor sets to invalid values.
Date date
Date of principal payment.
Definition: structs.h:575
Bond price quote.
Definition: structs.h:702
double value
Quote value.
Definition: structs.h:721
Quote()
Default constructor leaves everything uninitialized.
Definition: structs.h:724
type_type type
Quote type.
Definition: structs.h:718
type_type
Enum of possible ways to quote a price.
Definition: structs.h:705
Spreads relative to a benchmark curve.
Definition: structs.h:260
Item in a call or put schedule, specifying a call or put price.
Definition: structs.h:630
double strike
Call or put price.
Definition: structs.h:636
StrikeScheduleItem(Date input_start=Date(), double input_strike=100.0)
Default constructor leaves everything uninitialized.
Used to specify a yield in a yield curve.
Definition: structs.h:163
Yield(TimeDifference input_maturity=TimeDifference(), double input_rate=QuietNaN())
Default value is an invalid value.
double rate
Yield in absolute terms (0.10 = 10%)
Definition: structs.h:167
Valuation without risk measures.
Definition: structs.h:808
Price()
Default constructor sets everything to a quiet NaN.
Definition: structs.h:818
void set_to_worst(Output::Status::code_type code, const char *m)
Internal use only.
void set(const Status &status)
Internal use only.
Duration and convexity.
Definition: structs.h:843
Risk()
Default constructor sets everything to a quiet NaN.
Definition: structs.h:848
String message
Error message if any.
Definition: structs.h:760
void set_to_worst(int code, const char *m)
Internal use only.
void set_message(const char *m)
Internal use only.
void set_to_worst(Status status)
Internal use only.
void set_to_worst(int this_code=Status::ok)
Internal use only.
void set(int code=ok, const char *m="")
Internal use only.
Status(code_type this_code=ok, const char *this_message="")
Internal use only.
YTM, YTW, or YTC report, including modified duration and convexity.
Definition: structs.h:871
void set(const Risk &modified_risk)
Internal use only.
Yield()
Default constructor sets everything to quiet NaN.
Definition: structs.h:883
const Risk & modified_risk() const
Modified duration and convexity.
void set(const Status &status)
Internal use only.
long months() const
Converts to number of months as an integer. Use only if units are either years or months.
long periods
Number of time periods.
Definition: structs.h:127
TimeDifference(long input_periods=IntMin(), CalendarUnits::type input_units=CalendarUnits::unknown)
Default constructor initializes to invalid values.
CalendarUnits::type units
Units of time.
Definition: structs.h:130