|
From: <s.i...@gm...> - 2009-09-25 15:14:27
|
Hi Dima,
Okay, the concept is to separate the dates that we need for our calculations from the market conventions required to calculate those dates. In other words, why should the instruments need to know the conventions that apply for a given market?
We could simply just pass the dates instead of the logic, but we can't do that in many instances (e.g. for market data purposes) or simply don't want to (calculating fixing dates, ex-div dates).
First, I'll show a few simple examples of the functionality that a DateOffset could do.
//base class
class DateOffset {
public:
virtual Date operator() (const Date&) const = 0;
virtual Date reversed(const Date& endDate) const {
Date workingDate(endDate);
while( operator()(workingDate) != endDate) {
--workingDate;
}
};
The reversed() function should also be overridden but below I've concentrated on the initial date offset operator.
//a trivial example - simply moves the original date by a set number of calendar days
class CalendarDaysOffset : public DateOffset {
public:
CalendarDaysOffset(Natural days) : days_(days) {}
virtual Date operator() (const Date& initialDate) const { //derived from the base class
return (initialDate + days_);
}
private:
Natural days_;
};
//a standard period, which can be adjusted using a calendar and a roll convention.
class StandardPeriodOffset : public DateOffset {
public:
StandardPeriodOffset(const Period& period,
const Calendar& calendar,
BusinessDayConvention convention)
: period_(period), calendar_(calendar), convention_(convention) {}
Date operator() (const Date& initialDate) const {
return ( calendar_.adjust(initialDate + period_, convention) );
}
private:
Period period_;
Calendar calendar_;
BusinessDayConvention convention_;
};
//a fixed date
class FixedDate : public DateOffset {
public:
FixedDate(const Date& fixedDate)
: fixedDate_(fixedDate) {}
Date operator() (const Date& ) {
return fixedDate_;
}
private:
Date fixedDate_;
};
//standard FX rule
class StandardFXSpotOffset : public DateOffset {
public:
StandardFXSpotOffset(const Calendar& firstCalendar,
const Calendar& secondCalendar,
Natural spotDays,
const Calendar& thirdCalendar = USDCalendar() )
: firstCalendar_(firstCalendar), secondCalendar_(secondCalendar), thirdCalendar_(thirdCalendar), spotDays_(spotDays) { }
Date operator() (const Date& initialDate) {
Date workingDate(initialDate);
Date spot2(initialDate);
workingDate = firstCalendar_.advance(workingDate, spotDays, Days);
spot2 = secondCalendar_.advance(spot2, spotDays, Days);
workingDate = spot2 > workingDate ? spot2 : workingDate;
while(!thirdCalendar_.isBusinessDay(workingDate) ) {
++workingDate;
}
return workingDate;
}
private:
Calendar firstCalendar_, secondCalendar_, thirdCalendar_;
Natural spotDays_;
};
//so that multiple rules can be applied consecutively.
class MultiOffset : public DateOffset {
public:
MultiOffset(const std::vector<boost::shared_ptr<DateOffset> >& dateOffsets)
: dateOffsets_(dateOffsets) {}
Date operator() (const Date& initialDate) {
Date workingDate = initialDate;
for(Size i=0; i < dateOffsets_.size(); ++i) {
workingDate = (*dateOffsets[i])(workingDate);
}
return workingDate;
}
private:
std::vector<boost::shared_ptr<DateOffset> > dateOffsets_;
};
Now, here's an example with a money-market instrument (I know there isn't one in QuantLib at the moment).
class CashMM : public Instrument {
public:
CashMM( const Date& tradeDate,
boost::shared_ptr<DateOffset>& spotOffset,
boost::shared_ptr<DateOffset>& maturityOffsetFromSpot,
Rate cashRate,
//+ other parameters);
};
The DateOffset class does not increase the current functionality as cash instruments have standard rules.
However, here's an example which would benefit from a more generic method as there are so many different rules for calculating the spot date and fixing dates within the FX market.
class FXNonDeliverable {
public:
FXNonDeliverable( const Date& tradeDate,
boost::shared_ptr<DateOffset>& spotOffset,
boost::shared_ptr<DateOffset>& maturityOffset,
boost::shared_ptr<DateOffset>& fixingOffset
Rate contractFX {
settlementDate_ = (*maturityOffset)(spotOffset(tradeDate));
fixingDate_ = fixingOffset->reversed(settlementDate);
}
};
And you can imagine a dynamically generated Schedule created from a generic set of rules, which would only need a single date as an input. This would mean that market data instruments could be regenerated extremely easily.
The final piece in the jigsaw would be to attach these DateOffset class objects to the markets whose conventions are represented.
eg. GBPEUR FX market uses the standard FX spot calculation with 2 spot days.
EURRUB FX market uses 1 spot day and the USD calendar is ignored.
leading to constructors such as:
EuropeanOption(const Date& expiryDate, const OptionMarket& optionMarket);
where from the expiryDate(or a tenor) the settlement date, the reference settlement date (for non-deliverables), the underlying period (for rates) etc. can all be calculated using the OptionMarket - which may be an EquityOptionMarket, a SwaptionMarket etc.
We do something very similar for indices - so why not extend the concept?
Simon
---
Sent from my BlackBerry® wireless device
-----Original Message-----
From: Dima <dim...@go...>
Date: Fri, 25 Sep 2009 14:42:00
To: <s.i...@gm...>
Cc: <qua...@li...>
Subject: Re: [Quantlib-dev] Dates
Simon. Can you give a little example how this could look like for a simple
class?
2009/9/25 <s.i...@gm...>
> Hi folks,
>
> I've been looking at the QuantLib constructors and have a feeling that
> something better could be done regarding periods.
>
> Lots of the constructors have elements that ask for "number of days" or
> "day offset", then date rule and holiday calendar - sometimes for several
> different days - that it becomes confusing.
>
> For bonds (which I've helped in developing) the rules for ex-div days are
> complicated. Also, for FX the rules for determining the spot date from
> today's date or the expiry date from the settlement date can be exceedingly
> complicated.
>
> Why don't we have a DateOffset class (a base class) that can act as this
> function?
>
> So, when we need to obtain one date from another, we simply apply the
> DateOffset (which can contain a holiday calendar / many holiday calendars)
> to the initial date and obtain the relevant date - without needing to know
> what those rules are.
>
> These DateOffset objects could then be obtained from a relevant market
> (such as the LiborIndex objects we already have) and applied to a given
> instrument. This would be particularly useful for interest-rate and FX
> markets. For equity / credit markets (where there are a huge number of
> underlyings) this information would have to be derived externally to
> QuantLib - but the interfaces would be much cleaner.
>
> In other words, we decouple the market conventions from the instruments
> that are traded on those markets.
>
> I know that this would be a major project to apply throughout QuantLib, but
> that's no reason not to create this functionality and to encourage its use
> in new developments / changes.
>
> Thoughts please?
>
> Cheers,
> Simon
>
>
> Sent from my BlackBerry® wireless device
>
> ------------------------------------------------------------------------------
> Come build with us! The BlackBerry® Developer Conference in SF, CA
> is the only developer event you need to attend this year. Jumpstart your
> developing skills, take BlackBerry mobile applications to market and stay
> ahead of the curve. Join us from November 9-12, 2009. Register now!
> http://p.sf.net/sfu/devconf
>_______________________________________________
> QuantLib-dev mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-dev
>
|