Abstract Factory Design Pattern 7/1/2016 CS 631: Abstract Factory Pattern 1 Outline • Application – Measuring interest rates • Annual compounding • Other types of discrete compounding • Continuous compounding – Valuation factory • Abstract Factory – Design – Analysis – Implementation 7/1/2016 CS 631: Abstract Factory Pattern 2 Measuring Interest Rates: Compounding • A bank states the interest rate on 1-year deposits is 10% per annum. • The precise meaning of the statement depends on the way the interest rate is measured. – If it is quoted with annual compounding, $100 grows to: • $100 1.1 = $110 – If it is expressed with semiannual compounding, we earn 5% every 6 months; $100 grows to: • $100 1.05 1.05 =$110.25 – In case of quarterly compounding: • $100 1.0254 = $110.38 7/1/2016 CS 631: Abstract Factory Pattern 3 Compounding Frequency • Compounding frequency defines the units in which an interest rate is measured. – A rate expressed with one frequency can be converted into an equivalent rate with a different frequency. • For example, 10.25% with annual compounding is equivalent to 10% with semiannual compounding. – Two different compounding frequencies represent two different units of measurement. – Suppose that amount A is invested for n years at the interest rate 10% per annum. If the rate is compounded m times per annum, the final value of the investment is: R mn A(1 ) m 7/1/2016 CS 631: Abstract Factory Pattern 4 Continuous compounding • The limit as m tends to infinity is known as continuous compounding. It can be shown that A grows to: – A eRn – In our previous example A=$100, R=0.1, n=1; so A grows to: • $100 e0.1 = $110.52 • It is almost the same as daily compounding – Discounting (getting the present value) involves multiplying by e-Rn. – The interest rate with continuous compounding can be converted to the rate with "discrete" compounding. • Continuous compounding is widely used in valuing securities. 7/1/2016 CS 631: Abstract Factory Pattern 5 Valuation Factory • Consider a market simulator that needs to generate and evaluate instruments of the same type. • Such simulator depends on the following components: – Instrument, such as Bond, CD, etc. • The instrument needs to provide the list of payments (cash flows). – The discounting method used for valuation. • It is based on the compounding frequency. • The market simulator needs a way to randomly generate instruments and discounting. – ValuationFactory provides a way to generate instruments and discounting consistently. 7/1/2016 CS 631: Abstract Factory Pattern 6 Valuation Factory Design 7/1/2016 CS 631: Abstract Factory Pattern 7 Abstract Factory: Analysis • Intent – to provide interface for creating a family of related or dependent objects without specifying their concrete classes. • Applicability – when a system should be independent of how its components or products are created. – when a system should be configurable with one of multiple interchangeable families or products. – when a family of related products should not be mixed with similar products from different families. – when only interfaces of the products are exposed, while the implementation of the products is not revealed. 7/1/2016 CS 631: Abstract Factory Pattern 8 Abstract Factory Analysis (cont.) • Participants – AbstractFactory (ValuationFactory) • defines methods that create abstract products (createInstrument, createDiscounting). – ConcreteFactory (BondValuation, CDValuation) • implements the methods to create instances of ConcreteProduct. – AbstractProduct (Instrument, Discounting) • defines an interface for a type of product. – ConcreteProduct (Bond, ConinuousDscounting) • defines a product to be created by the corresponding concrete factory. – Client (MarketSimulator) • uses only AbstractFactory and AbstractProduct. 7/1/2016 CS 631: Abstract Factory Pattern 9 Implementation: MarketSimulator class MarketSimulator { public: void run(const ValuationFactory& factory) { Instrument* instr = factory.createInstrument(); Discounting* disc = factory.createDiscounting(); double price=0; for each payment in instr->getPayments() price += disc->price(payment.term, payment.amount); } ... }; class ValuationFactory { public: virtual Instrument* createInstrument() = 0; virtual Discounting* createDiscounting() = 0; }; 7/1/2016 CS 631: Abstract Factory Pattern 10 Implementation: BondValuation class BondValuation : public ValuationFactory { public: virtual Instrument* createInstrument() { ... randomly create principal ... ... randomly create coupon ... ... randomly create maturity ... ... randomly create interval ... return new Bond (principal, coupon, maturity, interval); } virtual Discounting* createDiscounting() { ... randomly generate interest rate ... return new ContinuousDiscounting(rate); } }; 7/1/2016 CS 631: Abstract Factory Pattern 11 Implementation: CDValuation class CDValuation : public ValuationFactory { public: virtual Instrument* createInstrument() { ... randomly create principal ... ... randomly create interest rate ... ... randomly create maturity ... return new CD(principal, rate, maturity); } virtual Discounting* createDiscounting() { ... randomly generate interest rate ... ... generate compounding frequency ... return new DiscreteDiscounting(frequency); } }; 7/1/2016 CS 631: Abstract Factory Pattern 12 Implementation: Instrument struct Payment { double term; double amount; }; class Instrument { public: Instrument(); virtual ~Instrument() {} virtual vector<Payment> getPayments() {return this->payments;} protected: vector<Payment> payments; }; 7/1/2016 CS 631: Abstract Factory Pattern 13 Implementation: CD class CD : public Instrument { public: CD(double principal, double rate, double maturity) { this->maturity = maturity; this->principal = principal; this->rate = rate; // A single payment at the end of maturity this->payments.push_back(Payment(this->maturity, this->principal*pow(1+this->rate,this->maturity)); ... } protected: double principal; double maturity; double rate; }; 7/1/2016 CS 631: Abstract Factory Pattern 14 Implementation: Discounting class Discounting { public: Discounting(double r) : rate(r) {} virtual double price(double amount, double term) = 0; protected: double rate; }; 7/1/2016 CS 631: Abstract Factory Pattern 15 Implementation: DiscreteDiscounting class DiscreteDiscounting { public: DiscreteDiscounting(double r, double f) : Discounting(r), frequency(f) {} virtual double price(double amount, double term) { return amount / ((1 + this->rate/this->frequency)^ (term * this->frequency); } protected: double frequency; }; 7/1/2016 CS 631: Abstract Factory Pattern 16