© Carlos Oliveira 2020
C. OliveiraOptions and Derivatives Programming in C++20https://doi.org/10.1007/978-1-4842-6315-0_5

5. Design Patterns for Options Processing

Carlos Oliveira1 
(1)
Seattle, WA, USA
 

Design patterns are a set of common programming design elements that can be used to simplify the solution of recurring problems. With the use of OO techniques, design patterns can be cleanly implemented as a set of classes that work toward the solution of a common goal. These designs can then be reused and shared across applications.

Over the last few years, design patterns have been developed for common problems occurring in several areas of programming. When designing algorithms for options and other derivatives, design patterns can provide solutions that are elegant and reusable (when supporting libraries are employed). Thanks to the inherent ability of the C++ language to create efficient code, these solutions also have high performance.

In this chapter, you will learn about the most common design patterns employed when working with financial options and derivatives, with specific examples of their usage. The chapter covers the following topics:
  • Overview of design patterns: You will learn how design patterns can help in the development of complex applications, with the ability to reuse common patterns of programming behavior. Using design patterns can also make solutions more robust and easier to understand, because patterns provide a common language that allows developers to discuss complex problems. Such design techniques have also been made available through libraries that implement some of the best-known design patterns.

  • Factory method pattern: A factory method is a design pattern that allows objects to be created in a polymorphic way, so the client doesn’t need to know the exact type of the returned object, only the base class that provides the desired interface. It also helps to hide a complex set of creation steps to instantiate particular classes.

  • Singleton pattern: The singleton pattern is used to model situations in which you know that only one instance of a particular class can validly exist. This is a situation that occurs in several applications, and in finance, I present the example of a clearing house for options trading.

  • Observer pattern: Another common application of design patterns is in processing financial events such as trades. The observer design patterns allow you to decouple the classes that receive trading transactions from the classes that process the results, which are the observers. Through the observer design pattern, it is possible to simplify the logic and the amount of code necessary to support these common operations, such as the development of a trading ledger, for example.

  • Visitor pattern: We also investigate the visitor pattern that allows two or more class hierarchies to cooperate in performing dynamic method dispatching.

Introduction to Design Patterns

Design patterns have been introduced as a set of programming practices that simplify the implementation of common coding problems. As you study the behavior of OO applications, there are tasks and solution strategies that occur frequently and can be captured as a set of reusable classes.

Object-oriented programming provides a set of principles that can facilitate the development of computer software. Using OO programming techniques, you can easily organize your code and create high-level abstractions for application logic and commonly used component libraries. In this way, OO techniques can be used to improve and reuse existing components, as well as simplify the overall development. OO programming promotes a way of creating software that uses logical elements operating at a higher level of abstraction.

Here are some of the most common design patterns that can be used in software development in general and for algorithms to process options and derivatives in particular, as viewed in Figure 5-1:
  • Factory method: In the factory method design pattern, the objective is to hide the complexity and introduce indirection when creating an instance of a particular class. Instead of asking clients to perform the initialization steps, factory methods provide a simple interface that can be called to create the object and return a reference.

  • Singleton: A singleton is a class that can have at most one active instance. The singleton design pattern is used to control access to this single object and avoid creating copies of this unique instance.

  • Observer: The observer pattern allows objects to receive notifications for important events occurring in the system. This pattern also reduces the coupling between objects in the system, since the generator of notification events doesn’t need to know the details of the observers.

  • Visitor: The visitor pattern allows a member function of an object to be called in response to another dynamic invocation implemented in a separate class. The visitor pattern therefore provides the mechanism for dispatching messages based on a combination of two objects, instead of the single object-based dispatch that is common with OO languages.
    ../images/371837_2_En_5_Chapter/371837_2_En_5_Fig1_HTML.jpg
    Figure 5-1

    A few common design patterns used in OO programming

In the next few sections, you will see how these design patterns can be implemented in C++, with examples of how they occur in options and derivatives applications.

The Factory Method Design Pattern

A factory design pattern is a technique used to indirectly create objects of a particular class. This pattern is important because it is frequently useful to access newly allocated objects without having to directly perform the work necessary to create them. For example, using the factory method design pattern, it is possible to avoid the use of the new keyword to create an object, along with the parameters required by the constructor.

The factory design pattern allows an object to be created through a member function of the desired class, so that the client doesn’t need to create the object directly. This can be useful for the following reasons:
  • Most of the time, there is no need for the client to provide parameters for construction of the object. For example, if the objects require the allocation of additional resources, such as a file or a network connection, the client is relieved from acquiring these resources.

  • Sometimes the object depends on internal implementation details, such as a private class, that are not available to clients. In this case, providing a factory method is the only way to create new instances of the object.

  • The exact sequence of events necessary to create an object may change. In that case, it is better to provide a factory method that hides this complexity. Users of the class will not have to worry if the way the object is created is updated.

  • More importantly, factory methods can be used to simplify polymorphic object creation . For example, when an object is created using the new operator, the concrete type of the returned object has to be known by the client. On some applications, this might be undesirable, because the real type of the needed object could be any one within a set of derived classes. Using a factory method, it is possible to delegate the creation of the object so that the client code doesn’t need to know about the concrete type. As a result, the returned object may be any one of the subtypes of the original type.

Factory methods in C++ are declared as static member functions. Such a member function doesn’t depend on an instance of the class to be executed. The syntax for member functions is simply ClassName::functionName() , with parameters added as needed.

Note

The factory method design pattern is also used as a foundation for more complex design patterns. For example, you will notice that other patterns such as singleton use a factory method to control the creation of new instances of a particular class.

In options and derivatives applications, the factory method is commonly used. A situation where the use of a factory method is desirable is when you need to load data objects. The data source used can vary from a local file to a URL, and the parsing of that data is not an important part of the overall algorithm. In that case, abstracting the creation of the data source can be an important application of the factory method.

In the example that follows, you can see how a DataSource class can be implemented. The goal of this class is to hide the process of creating a new data source, so the clients have no access to the real constructor of the class. Instead, clients need to use a factory method, which is implemented as a static member function of the DataSource class.

When using factory methods, it is frequently useful to hide the real implementation of the constructor. This can be done through careful use of the private modifier. The goal is to grant access to the constructor only to the class itself (and to any declared friends of the class). This is done to the standard constructor as well as to the copy constructor.

The interface to the DataSource class is presented in Listing 5-1. Both constructors and the assignment operator are declared as private. The destructor, however, needs to be accessible so that the delete keyword can be called on allocated objects. The readData member function is an interface for the main responsibility attributed to this class, and its implementation will vary according to the read data source used. The createInstance member function is a static function that creates and returns new instances of the data type, functioning as the factory method.
//
//  DataSource.hpp
#ifndef DataSource_hpp
#define DataSource_hpp
#include <string>
class DataSource {
private:
    DataSource(const std::string &name);
    DataSource(const DataSource &p);
    DataSource &operator=(const DataSource &p);
public:
    ~DataSource();  // must be public so clients can use delete
    static DataSource *createInstance();
    void readData();
private:
    std::string m_dataName;
};
#endif
Listing 5-1

Declaration of the DataSource Class

The implementation of the DataSource class is shown in Listing 5-2. The constructors and destructor are standard, considering the fact that the constructor is private. The interesting part of the DataSource implementation is the getInstance method , which returns a new data source. This implementation receives only one parameter that is created by the method, but consider the general case in which a list of complex or implementation-dependent objects need to be retrieved in order to call the new operator for the DataSource class.

Note

At the end of getInstance, the member function returns a pointer to the newly created object. Another option is to return a smart pointer, such as std::shared_ptr, which would make it easier to manage the lifetime of the allocated object.

//
//  DataSource.cpp
#include "DataSource.hpp"
DataSource::DataSource(const std::string &name)
: m_dataName(name)
{
}
DataSource::DataSource(const DataSource &p)
: m_dataName(p.m_dataName)
{
}
DataSource &DataSource::operator=(const DataSource &p)
{
    if (this != &p)
    {
        m_dataName = p.m_dataName;
    }
    return *this;
}
DataSource::~DataSource()
{
}
DataSource *DataSource::createInstance()
{
    std::string sourceName;
    // Complex method used here to find sourceName and other construction parameters ...
    DataSource *ds = new DataSource(sourceName);
    return ds;
}
void DataSource::readData()
{
    // Read data here...
}
void useDataSource()
{
    // DataSource *source = new DataSource(""); // this will not work!
    DataSource *source = DataSource::createInstance();
    source->readData();
    // Do something else with data
    delete source;
}
Listing 5-2

Implementation of the DataSource Class

The Singleton Pattern

One of the simplest and most used design patterns is the singleton. With this design pattern, a single object is used to represent a whole class, so that there is a central location where services managed by that class can be directed.

Unlike standard classes, a singleton class represents a single resource that cannot be replicated. Because of this, the singleton pattern restricts the ability to create new objects of a particular class, using a few techniques that will be discussed later in this section. C++ provides all the features necessary to implement singleton patterns with high performance.

In programming, the notion of an entity that is unique across the application is frequently encountered. An example in options programming is an entity called a clearing house. A clearing house is an institution that provides clearing services for trades on options and derivatives. The clearing house makes sure that every trade has collateral so that counterpart risk is reduced, among other attributions. For example, if a trader sells options in a particular instrument, the clearing house will make sure that the trader has enough margin to satisfy the requirements of that particular trade.

While a clearing house provides important services in the trading industry, most applications need to connect to a single clearing house. Thus, creating a single object to represent the clearing house is an obvious implementation technique for this situation. Table 5-1 presents a few examples of objects that could be modeled using a singleton.
Table 5-1

Example Objects That Can Be Implemented As a Singleton Design Pattern

Object

Notes

Clearing house (finance)

A single clearing house is used for all trades.

Root window (GUI)

Each GUI application communicates with only one root window.

Operating system

An object representing operating system services is unique through the application.

Company CEO

An object representing the CEO has only one instance.

Memory allocator (system services)

Each application uses a single memory allocator, which can be represented by a singleton.

To implement a singleton in C++, the first step is to make sure that there is only one object of that class in the application. To do this, it is necessary to disallow the creation of new objects of that particular class. You can take advantage of the ability provided by C++ to make class members inaccessible to users of the class through the private keyword. Users then cannot use the new keyword to generate new objects of that particular class.

On the other hand, it is necessary to create some mechanism for clients to access an instance of the singleton class. This is usually done using a static member function that returns the single existing object or creates a new object if necessary before returning it. Using such an access member function, clients can access the public interface of the singleton object. At the same time, they’re not allowed to create or manage the lifecycle of that object.

Clearing House Implementation in C++

A possible implementation for the clearing house class using the singleton pattern is presented in Listings 5-1 and 5-2. The class has two parts: the first part deals with the management of the singleton object. This is done through the definition of private constructor and destructors, as well as the presence of a static member function getClearingHouse, which returns a reference to the singleton instance.

The second part of the implementation deals with the responsibilities of the clearing house, represented here as the member function clearTrade. This function receives as an argument a Trade object, which is not defined here but contains all the data associated with the transaction.

Listing 5-3 shows the interface, which follows the singleton design pattern. Listing 5-4 contains the implementation of the member functions declared in the class interface, as well as the static member variable s_clearingHouse.
//
//  DesignPatterns.hpp
//  CppOptions
#ifndef DesignPatterns_hpp
#define DesignPatterns_hpp
class Trade {
    //  ....
};
class ClearingHouse {
private:                   // These are all private because this is a singleton
    ClearingHouse();
    // The copy constructor is not implemented
    ClearingHouse(const ClearingHouse &p);
    ~ClearingHouse();
    // Assignment operator is not implemented
    ClearingHouse &operator=(const ClearingHouse &p);
public:
    static ClearingHouse &getClearingHouse();
    void clearTrade(const Trade &);
private:
    static ClearingHouse *s_clearingHouse;
};
#endif /* DesignPatterns_hpp */
Listing 5-3

Header File for the ClearingHouse Class, Which Implements the Singleton Design Pattern

The implementation file contains the member function ClearingHouse::getClearingHouse. This function first checks the static variable s_clearingHouse to determine if it has been previously allocated. If the object doesn’t exist, then the static function can create a new object, store it for further use, and return a reference.

The function useClearingHouse is an example of how the ClearingHouse class can be used. The first step is to have a variable hold a reference to the singleton object. Then, by calling the static function getClearingHouse, you can access the singleton. In this example, the singleton is used to process another trade through the member function clearTrade.
//
//  DesignPatterns.cpp
#include "DesignPatterns.hpp"
ClearingHouse *ClearingHouse::s_clearingHouse = nullptr;
ClearingHouse::ClearingHouse()   // private constructor, cannot be used by clients
{
}
ClearingHouse::~ClearingHouse()  // this is private and cannot be used by clients
{
}
ClearingHouse &ClearingHouse::getClearingHouse()
{
    if (!s_clearingHouse)
    {
        s_clearingHouse = new ClearingHouse();
    }
    return *s_clearingHouse;
}
void ClearingHouse::clearTrade(const Trade &t)
{
     // Trade is processed here
}
void useClearingHouse()
{
    Trade trade;
    ClearingHouse &ch = ClearingHouse::getClearingHouse();
    ch.clearTrade(trade) ;
}
Listing 5-4

Implementation File for ClearingHouse Class, Which Uses the Singleton Design Pattern

The Observer Design Pattern

A frequent situation that occurs in complex systems is the occurrence of events that trigger further actions. For example, an event that happens on financial systems is the completion of an options trade. When a new trade is completed, several actions need to be performed to update the system and reflect the new positions in the ledger.

The observer design pattern is a very powerful strategy to manage event updates, based on a standard technique that gives clients the ability to listen to events and updates to a particular object and react accordingly.

There are two parts of the observer design pattern (see Figure 5-2). First, there is an observer, which implements an abstract interface capable of receiving notifications. The abstract interface consists of a single member function, called notify . This member function is called by the second part of the design pattern, the Subject, when a new event occurs (the arrow between them means that the observer has a reference to the Subject object).
../images/371837_2_En_5_Chapter/371837_2_En_5_Fig2_HTML.jpg
Figure 5-2

Simplified scheme of the observer design pattern

The Subject class has at least three member functions that enable the functionality of the observer design pattern. The first function is addObserver, which takes as a parameter a reference to an observer object. The addObserver function maintains the reference in an internal list of objects that are interested in receiving notifications.

The second member function in the subject interface is removeObserver, which simply removes a given observer from the notification list. Finally, there is a member function called triggerNotifications that is used to send the notifications to all objects that registered with the Subject class.

The observer design pattern can readily be implemented in C++ using abstract classes. You can see a sample implementation in Listings 5-5 and 5-6. The first class that is considered is the Observer class. This class has the purpose of providing a simple interface for the observer. Its only nontrivial member function is notify, which is an abstract function called by the subject when a new event occurs. As a result, any class deriving from observer needs to process the notification in a user-defined way.

The interface is the following:
class Observer {
public:
    // Constructor and destructor definitions
    virtual void notify() = 0;
};
Note

Consider how the Observer class is independent of any implementation detail for the trading ledger system. This definition could be reused as part of a design pattern’s library. Similar techniques can be used to simplify the creation of other design patterns as well.

Next, it is necessary to define a class that implements the abstract observer interface. In this case, the goal is to implement a trade observer, which can be specified in the following way:
class TradeObserver : public Observer {
public:
    TradeObserver(TradingLedger *t);
    TradeObserver(const TradeObserver &p);
    ~TradeObserver();
    TradeObserver &operator=(const TradeObserver &p);
    void notify();
    void processNewTrade();
private:
    Trade m_trade;
    TradingLedger *m_ledger;
};
The constructor for this class receives as a parameter a pointer to the TradingLedger object , which will be defined later. The class provides an implementation for notifications and a member function to process new trades. These two member functions are implemented as follows:
void TradeObserver::notify()
{
    this->processNewTrade();
}
void TradeObserver::processNewTrade()
{
    m_trade = m_ledger->getLastTrade();
    // Do trading processing here
}

Here, the notification implementation just calls the processNewTrade function , which stores the trade returned by the ledger object.

Finally, you can also see a definition for the TradingLedger class. The class contains the three member functions that comply with the subject interface (addObserver, removeObserver, and triggerNotifications). The class also contains two simple member functions to add and return trades, as shown in the following definitions:
class TradingLedger {
public:
    TradingLedger();
    TradingLedger(const TradingLedger &p);
    ~TradingLedger();
    TradingLedger &operator=(const TradingLedger &p);
    void addObserver(std::shared_ptr<Observer> observer);
    void removeObserver(std::shared_ptr<Observer> observer);
    void triggerNotifications();
    void addTrade(const Trade &t);
    const Trade &getLastTrade();
private:
    std::set<std::shared_ptr<Observer>> m_observers;
    Trade m_trade;
};

The addObserver and removeObserver functions operate with std::shared_ptr templates for the observer object. The goal is to avoid unnecessary memory issues by delegating the memory deallocation to shared pointers from the standard library. These two functions operate as an interface to the internal m_observers container.

The triggerNotification function can be implemented as follows:
void TradingLedger::triggerNotifications()
{
    for (auto i : m_observers)
    {
        i->notify();
    }
}

It simply loops through all elements stored in the m_observers set and sends a notification to these registered objects. Each such object that implements the observer interface can now respond to the event as needed.

Complete Code

The complete example previously described can be seen in Listings 5-5 and 5-6. The first file contains only the interface for the main classes used in the system. Listing 5-6 shows the implementation of these classes, along with a sample main function that creates the ledger and two observer objects.
//
//  Observer.hpp
#ifndef Observer_hpp
#define Observer_hpp
#include <set>
#include <memory>
class Observer {
public:
    Observer();
    Observer(const Observer &p);
    ~Observer();
    Observer &operator=(const Observer &p); // not implemented
    virtual void notify() = 0;
};
class Trade {
    //
    // .... Implementation not shown here
};
class TradingLedger;
class TradeObserver : public Observer {
public:
    TradeObserver(TradingLedger *t);
    TradeObserver(const TradeObserver &p);
    ~TradeObserver();
    TradeObserver &operator=(const TradeObserver &p);
    void notify();
    void processNewTrade();
private:
    Trade m_trade;
    TradingLedger *m_ledger;
};
class TradingLedger {
public:
    TradingLedger();
    TradingLedger(const TradingLedger &p);
    ~TradingLedger();
    TradingLedger &operator=(const TradingLedger &p);
    void addObserver(std::shared_ptr<Observer> observer);
    void removeObserver(std::shared_ptr<Observer> observer);
    void triggerNotifications();
    void addTrade(const Trade &t);
    const Trade &getLastTrade();
private:
    std::set<std::shared_ptr<Observer>> m_observers;
    Trade m_trade;
};
#endif /* Observer_hpp */
Listing 5-5

Header File Containing Interfaces for the Observer Design Pattern

//
//  Observer.cpp
#include "Observer.hpp"
using std::shared_ptr;
typedef shared_ptr<Observer> PObserver;
typedef shared_ptr<TradeObserver> PTradeObserver;
Observer::Observer()
{
}
Observer::Observer(const Observer &p)
{
}
Observer::~Observer()
{
}
void Observer::notify()
{
}
TradeObserver::TradeObserver(TradingLedger *t)
: m_ledger(t)
{
}
TradeObserver::TradeObserver(const TradeObserver &p)
: m_trade(p.m_trade),
  m_ledger(p.m_ledger)
{
}
TradeObserver::~TradeObserver()
{
}
TradeObserver &TradeObserver::operator=(const TradeObserver &p)
{
    if (this != &p)
    {
        m_trade = p.m_trade ;
        m_ledger = p.m_ledger;
    }
    return *this;
}
void TradeObserver::notify()
{
    this->processNewTrade();
}
void TradeObserver::processNewTrade()
{
    m_trade = m_ledger->getLastTrade();
    // Do trading processing here
}
// -- TradingLedger implementation
TradingLedger::TradingLedger()
{
}
TradingLedger::TradingLedger(const TradingLedger &p)
: m_observers(p.m_observers),
  m_trade(p.m_trade)
{
}
TradingLedger::~TradingLedger()
{
}
TradingLedger &TradingLedger::operator=(const TradingLedger &p)
{
    if (this != &p)
    {
        m_observers = p.m_observers ;
        m_trade = p.m_trade;
    }
    return *this;
}
void TradingLedger::addObserver(PObserver observer)
{
    m_observers.insert(observer);
}
void TradingLedger::removeObserver(PObserver observer)
{
    if (m_observers.find(observer) != m_observers.end())
    {
        m_observers.erase(observer);
    }
}
void TradingLedger::triggerNotifications()
{
    for (auto i : m_observers)
    {
        i->notify();
    }
}
void TradingLedger::addTrade(const Trade &t)
{
    m_trade = t;
    this->triggerNotifications();
}
const Trade &TradingLedger::getLastTrade()
{
    return m_trade;
}
//
//  Simple test stub for the TradingLedger and TradeObserver classes .
int main()
{
    TradingLedger tl;
    PTradeObserver observer1 = PTradeObserver(new TradeObserver(&tl));
    PTradeObserver observer2 = PTradeObserver(new TradeObserver(&tl));
    tl.addObserver(observer1);
    tl.addObserver(observer2);
    // Perform trading system here
    Trade aTrade;
    tl.addTrade(aTrade);
    // Observers should receive a notification at this point
    return 0;
}
Listing 5-6

Implementation File with C++ Definitions for the Observer Design Pattern

The Visitor Pattern

Another useful pattern that has been used in several real-life applications is the visitor pattern. In this pattern, the goal is to allow dynamic dispatching of objects in two separate hierarchies of types. This design pattern has application in many common problems occurring in finance.

The problem solved by the visitor pattern is the application of dynamic rules to two or more polymorphic objects at the same time. This is necessary because C++, like some other object-oriented languages, uses single dispatch to process polymorphic calls.

Consider, for example, the case of a class representing derivative contracts. The class can have several polymorphic (virtual) methods, including one for displaying the profit/loss chart.

#include <list>
class ChartDisplay;
class SimpleDerivativeContract {
  public:
  virtual void chartProfitLoss(ChartDisplay *c);
};
class ChartDisplay {
public:
   virtual void displayContracts(
                 std::list<SimpleDerivativeContract*> &contracts);
   virtual void addToChart(SimpleDerivativeContract *c);
};

The SimpleDerivativeContract class has a virtual method that is able to present a chart with profit/loss for the position. But to do this, the derivative object needs to coordinate with a second class, called ChartDisplay. Both ChartDisplay and SimpleDerivativeContract have polymorphic methods that interact with each other, but in C++ the virtual dispatch is done in just a single method. For example, ChartDisplay might have specialized subclasses such as PDFChart and HTMLChart.

To make this possible, the visitor design pattern enables the dynamic interaction of two classes by the use of virtual methods that call each other. In summary, one of the objects becomes responsible to implement the visitation strategy, by which the virtual method on the second object is called. Here is the implementation of our example classes:
void ChartDisplay::displayContracts(
    std::list<SimpleDerivativeContract*> &contracts) {
    for (auto c : contracts) {
        c->chartProfitLoss(this);
    }
}
void SimpleDerivativeContract::chartProfitLoss(ChartDisplay *disp) {
      // ...
      // Use ChartDisplay virtual methods:
      disp->addToChart(this);
}
The first method, displayContracts , is responsible for displaying each of the contract objects stored in the container passed as parameter. To do this, the virtual method chartProfitLoss is called with the ChartDisplay as a parameter. On the other hand, the charProfitLoss of method also calls a virtual method from ChartDisplay: addToChart. This relation between the two methods is what makes the dual virtual dispatch to work, allowing two separate hierarchies to work together in a dynamic fashion:
class PDFDisplay : public ChartDisplay {
public:
    virtual void addToChart(SimpleDerivativeContract *c) {
        // Add contract to a PDF chart here
    }
};
class HTMLDisplay : public ChartDisplay {
public:
    virtual void addToChart(SimpleDerivativeContract *c) {
        // Add contract to an HTML chart here
    }
};

Conclusion

Design patterns are commonly used to develop reusable code, especially when OO techniques are employed. C++ provides strong support for the creation of classes that follow designed patterns such as the ones discussed in the preceding sections.

In this chapter, you saw examples and implementation in C++ for three common design patterns. First, I presented an overview of design patterns, listing some of the patterns that are most commonly used in the implementation of algorithms for options and derivatives. Then, you learned about the factory method design pattern, which is one of the easiest and most widely used patterns of OO programming.

The singleton pattern is used when it is necessary to enforce the existence of a single instance for a particular class. You saw the example of a clearing house implementation, where the single instance must be accessible to all clients in the application.

The observer pattern is a third example of how to implement such designs in C++. You saw how this pattern can be employed to solve the problem of trading processing. Using this design pattern, it is possible to decouple the classes that receive the events from specific classes that listen to the events and perform further processing.

While object-oriented design patterns provide several elegant solutions for commonly found problems in financial programming, there are situations in which a non-OO strategy may be a better solution. In these situations, C++ promotes the use of templates, an implementation technique in which the compiler is allowed to generate code based on parameterized types. In the next chapter, you will see several examples in which template-based algorithms can be used to improve the performance and flexibility of algorithms for options and derivatives trading.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.140.185.170