• C++ Programming for Financial Engineering
    Highly recommended by thousands of MFE students. Covers essential C++ topics with applications to financial engineering. Learn more Join!
    Python for Finance with Intro to Data Science
    Gain practical understanding of Python to read, understand, and write professional Python code for your first day on the job. Learn more Join!
    An Intuition-Based Options Primer for FE
    Ideal for entry level positions interviews and graduate studies, specializing in options trading arbitrage and options valuation models. Learn more Join!

SHOW ME THE CODE !

from long string to substrings:
    //split a long string into substrings
    // use of break and continue
    unsigned short nSubStrings {8};
    string* ayrFx = new string[nSubStrings + 1];
    string line;
    line = "       USD PEN     MXN    BRL   ARS    CLP    COP EUR";
    unsigned short j {0}, i{0};
    for (; i < line.length(); i++) {
        //cout << line[i] << " ";
        if (line[i] == ' ') continue;
        while(line[i]) {
            ayrFx[j] += line[i];
            i++;
            if (line[i] == ' ') break;
        }
        j++;
    }
 
    for (j = 1; j <= nSubStrings; j++) {
        cout << "\n\tj:" << j << "  " << ayrFx[j];
    }
 
    OUTPUT:
    j:1      USD
    j:2      PEN
    j:3      MXN
    j:4      BRL
    j:5      ARS
    j:6      CLP
    j:7      COP
    j:8      EU

REF:

Systematic Forex Trading

Do we not need to declare the variable “i” inside the for loop?

C++:
 for (int i = 0; …

Similarly,
C++:
 for (int j = 1; …

I remember, from the QuantNet course, that in C, if we declare the counter variable once, we don’t need to re-declare again.
 
Last edited:
1658671638231.png
 
exsan.h

C++ Standard Library Containers
C++ language is accompanied by a library called the C++ Standard Library. It is a collection of containers and useful functions that we access by including the proper header file. The containers and functions inside the C++ standard library are defined in the std namespace. The standard library is implemented through class templates.
Containers
A container is a place where we store our objects. There are different categories of containers, here we mention the two:
– Sequence containers: Sequential containers store objects in a sequence, one next to the other in memory.
– Associative containers
std:: vector , array, set, map, pair
Other Containers
There are other, less used containers in the standard library as well. We will mention a few of them:
a. std::forward_list – a singly linked list
b. std::list – a doubly linked list
c. std::deque – a double ended container that allows insertion and deletion at both ends
exsan.h is a universal container library I created and developed. It uses exsan abstract data structure, it has the ability to handle huge n-tuple. The master general template looks like:

template
< class A, class B, class C, class D, ... , class Z,
class AA, class AB, class AC, ... , class AZ,
class BA, class BB, class BC, ... , class BZ,
class CA, ... , class CZ,
...
class ZA, ... , class ZZ,
class ZZA, class ZZB, ... , class ZZZ, ... , ... > (just the way worksheet columns are organized)
Usage of exsan.h as a multimap
The following example the imput template looks like
<string, int, int, int, int, int, string, bool, int, int, float, char>
 
  • I just want to say one word to you.
  • Just one word.
  • Yes, sir.
  • Are you listening?
  • Yes, I am.
  • Concepts.
  • Exactly how do you mean?
  • There's a great future in C++ Concepts.
  • Think about it.
  • Will you think about it?

Stay tuned for BREAKING NEWS.
 
Today's exsan.h code
-Universal C++ "multimap" Container Library-
//Copy content of worksheet ppS to ppSout

C++:
    3 //Today's exsan.h CODE
    4 enum class varColsFrom {
    5    vTcpIp = 1, vTcpIp0, vTcpIp1, vTcpIp2, vTcpIp3, vTcpIp4, vName, vMale, vIndex, vAge, vValue, vGrade
    6 };
    7
    8 enum class varColsTo {
    9    vIndex = 1, vName, vMale, vAge, vValue, vGrade, vTcpIp, vTcpIp0, vTcpIp1, vTcpIp2, vTcpIp3, vTcpIp4
   10 };
   11 varColsTo vColTo;
   12 varColsFrom vColFrom;
   13 CELLPTR ptr, ptr2;
   14 for (unsigned short thisRow = 1; thisRow <= net->get_rows_in_page(ppString, 'w'); thisRow++) {
   15    ptr = net->point_to(net, ppString, thisRow, 1, 'w');
   16    for (int thisCol = vTcpIp; thisCol <= vGrade; thisCol++) {
   17       vColFrom = static_cast(thisCol);
   18       switch (vColFrom) {
   19       case varColsFrom::vTcpIp:
   20          ptr2 = net->point_to(net, ppStringOut, thisRow, (unsigned short)varColsTo::vTcpIp, 'w');
   21          ptr2->set_string(ppStringOut, ptr->get_string(ppString));
   22          break;
   23
   24       case varColsFrom::vTcpIp0:
   25          ptr2 = net->point_to(net, ppStringOut, thisRow, (unsigned short)varColsTo::vTcpIp0, 'w');
   26          ptr2->set_string(ppStringOut, ptr->get_string(ppString));
   27          break;
   30       case varColsFrom::vAge:
   31          ptr2 = net->point_to(net, ppStringOut, thisRow, (unsigned short)varColsTo::vAge, 'w');
   32          ptr2->set_string(ppStringOut, ptr->get_string(ppString));
   33          break;
   34        /// more code here for the rest of the template
   35       case varColsFrom::vIndex:
   36          ptr2 = net->point_to(net, ppStringOut, thisRow, (unsigned short)varColsTo::vIndex, 'w');
   37          ptr2->set_string(ppStringOut, ptr->get_string(ppString));
   38          break;
   39       }
   40       ptr = ptr->get_next_ptr();
   41    }
   42 }
   43
   44

301     Re Ordering Template From:
302     TcpIp , TcpIp0, TcpIp1, TcpIp2, TcpIp3, TcpIp4, Name, Male, Index, Age, Value, Grade
303    WORKSHEET 1  A[12, 12] STRING
304                              A   B   C    D    E      F    G    H   I   J   K  L
305         >------------------------------------<
306      1:194.73.69.98.6 194 73 69 98 6    Liam    1  1 48 35.78 C
307      2: 199.58.0.67.7 199 58  0 67 7      Noah   1   2  8 48.93 A
308      3:195.50.47.34.0 195 50 47 34 0    Oliver   1  3 63 59.46 A
309      4:196.61.94.55.8 196 61 94 55 8    Elijah    1  4 99 77.18 A
310      5:197.42.13.31.4 197 42 13 31 4   James    1  5 37 12.65 E
311      6:  197.58.1.7.2 197 58  1  7 2       William  1  6 15 80.97 C
312      7: 195.2.68.88.2 195  2 68 88 2     Benie     1  7 50 18.14 C
313      8:194.82.93.40.1 194 82 93 40 1   Lucas     1  8 15 70.94 E
314      9:198.81.35.94.5 198 81 35 94 5   Henry     1  9 80 66.71 C
315     10: 195.31.9.72.0 195 31  9 72 0    Theodor 1 10  5 66.08 E
316     11:193.68.12.65.9 193 68 12 65 9  Olivia     0 12 73 17.88 E
317     12:197.63.36.98.7 197 63 36 98 7   Emma    0 13 52 42.78 A
318         <------------------------------------>
319
320     Re Ordering Template To:
321     Index , Name, Male, Age, Value, Grade, TcpIp, TcpIp0, TcpIp1, TcpIp2, TcpIp3, TcpIp4
322    WORKSHEET 0  @[12, 12] STRING
323      A  B  C  D  E  F  G  H  I  J  K  L
324         >------------------------------------<
325      1: 1    Liam 1 48 35.78 C     194.73.69.98.6 194 73 69 98 6
326      2: 2    Noah 1  8 48.93 A     199.58.0.67.7 199 58  0 67    7
327      3: 3  Oliver 1 63 59.46 A      195.50.47.34.0 195 50 47 34 0
328      4: 4  Elijah 1 99 77.18 A       196.61.94.55.8 196 61 94 55 8
329      5: 5   James 1 37 12.65 E     197.42.13.31.4 197 42 13 31 4
330      6: 6 William 1 15 80.97 C     197.58.1.7.2 197 58  1  7      2
331      7: 7   Benie 1 50 18.14 C      195.2.68.88.2 195  2 68 88   2
332      8: 8   Lucas 1 15 70.94 E      194.82.93.40.1 194 82 93 40 1
333      9: 9   Henry 1 80 66.71 C     198.81.35.94.5 198 81 35 94 5
334     10:10 Theodor 1  5 66.08 E  195.31.9.72.0 195 31  9 72    0
335     11:12  Olivia 0 73 17.88 E     193.68.12.65.9 193 68 12 65 9
336     12:13    Emma 0 52 42.78 A  197.63.36.98.7 197 63 36 98 7
337         <------------------------------------>
338

Today's exsan.h code
-Universal C++ "multimap" Container Library-
//Copy content of worksheet ppS to ppSout
 
Last edited:
21st century C++: Design Pattterns, C++20 Concepts and multimethods

This code contains:

1. Visitor pattern based on C++20 Concepts (provide-requires contracts).
2. Multimethods (the Holy Grail) .. what C++ tried for 30 years.
3. Multimethods with variadic parameters, a) object with multiple visitors,
b) a visitor with multiple objects.


C++:
// TestGenericVisitorProtean.cpp

// DJD 2022-10-9 version 0.9 #6
// (C) Datasim Education BV 2022

/*
A really modern implementation of a generic Visitor pattern that is an improvement on other approaches in C++:

        1. std::visit() and std::variant()
        2. Traditional Acyclic Visitor using subtype polymorphism, dynamic casting and
        possibly multiple inheritance.

The proposed solution is more maintainable than solutions 1 and 2 while at the same time having better performance and reliability properties than solution 2. Our solution uses a combination of
template methods and C++ Concepts.

We take the well-known example of 2d shapes (Point, Line, Circle) that can be visited in different ways.
The two visitors represent new functionality for drawing and scaling these shapes.

We note that we do not have a class hierarchy nor virtual functions. All behaviour is compile-time driven as it were.

C++ Concepts is a game changer.

This code contains:

        1. Visitor pattern based on C++20 Concepts (provide-requires contracts).
        2. Multimethods (the Holy Grail) .. what C++ tried for 30 years.
        3. Multimethods with variadic parameters, a) object with multiple visitors,
        b) a visitor with multiple objects.

        WE GIVE A STRIPPED DOWN VERSION TO FIT ON PAGE
        More later.
*/

#include <iostream>

// Visitor with templates,V2
struct Point;

// Using C++20 Concepts to define contracts/protocols
// 1. The baseline contract between GOF Context and Visitor
template <typename Visitor, typename Context>
    concept IVisitor = requires (Visitor & v, Context & c)
{
    v.visit(c);
};

template <typename Visitor, typename Context>
    concept IAccept = requires (Visitor & v, Context & c)
 {
        c.accept(v);
 };
 
 template <typename Visitor, typename Context>
    concept IAcceptVisitor = IVisitor<Visitor, Context> && IAccept<Visitor, Context>;

// Specialisations of Concept interfaces (from 2 to 1 template parameter)
template <typename Visitor>
    concept IPointVisitor = IVisitor<Visitor, Point>;


/* End of Protocol definitions*/


struct Point
{
    double x;
    double y;

    Point() : x(0.0), y(0.0) {}
    Point(double X, double Y) : x(X), y(Y) {}

    template <typename T> requires IPointVisitor<T>
        void accept(T& t)
    {
        t.visit(*this);
    }
};


// Specific visitors (Draw and Scale)
struct Draw
{
    void visit(Point& p)
    {
        std::cout << "("<< p.x << ", " << p.y << ")\n";
    }
 
 
};


struct Scale
{
    double fac;
    Scale(double factor) : fac(factor) {}
    void visit(Point& p)
    {
        p.x *= fac;
        p.y *= fac;
    }
 
};

// Multimethods, the Holy Grail of C++
template <typename Visitor, typename Context>
    void multimethod(Visitor& v, Context& c) requires IAcceptVisitor<Visitor, Context>
{
        v.visit(c);
        c.accept(v);
}


// Command multipattern ... a list of objects on a single visitor
 template <typename T, typename Visitor>
    void command(Visitor v, T& c)
 {
       c.accept(v);
 }


template <typename T, typename Visitor, typename ... Types>
    void command(Visitor v , T& arg, Types& ... args)
{ // 1 visitor, multiple contexts

        command(v, arg);
        command(v, args...);
}

 // Command multipattern ... a list of visitors  on a single object
 template <typename T, typename Visitor>
    void command2(T& c, Visitor v)
  {
      //  c.accept(v);
        v.visit(c);
  }

template <typename T, typename Visitor, typename ... Types>
    void command2(T& arg, Visitor& v, Types& ... args)
{ // 1 context, multiple visitors

        command2(arg, v);
        command2(arg, args...);
 }


int main()
{
 
    // Contract with C++ 20 Concepts
    {
        std::cout << "Contracts, points and lines\n";
        Point p1(2.0, -3.0);
        Draw draw;
        Scale mod(0.5);

        p1.accept(mod);
        p1.accept(draw);
        mod.visit(p1);
        draw.visit(p1);
        p1.accept(mod);
        draw.visit(p1);  
    }

 
    {
        // multimethods
        std::cout << "Multimethod\n";
        Point p(2.0, 4.0); Point p2(20.0, 41.0);
        Point p3(-2.0, -4.0); Point p4(21.0, 42.0);
        Draw draw;
        Scale mod(0.5);

        // Magic
        multimethod(draw, p);
        multimethod(mod, p);
        multimethod(draw, p);

        std::cout << "variadics\n";
        command(draw, p);
        // Multimethods with variadic parameters
        command(draw, p, p2, p3, p4);

        // Object with multiple visitors
        command2(p, draw, mod, draw, mod, draw, mod, draw);
        command2(p2, draw, mod, draw);
    }
 }
 

Attachments

  • TestGenericVisitorProtean.cpp
    4.7 KB · Views: 4
Hi Daniel/all,

Today, I ordered from Amazon, a copy of the book - Numerical methods in Computational Finance. Amazon Poland should ship it to me by Tuesday. I am excited to start learning about financial PDEs, and hope to frequent here, posting/discussing code snippets. Would you all have any suggestions/tips to make the most out of this book?

Any other books/background reading to complement it, would also be fantastic.

Cheers,

Quasar.
 
Hi Daniel/all,

Today, I ordered from Amazon, a copy of the book - Numerical methods in Computational Finance. Amazon Poland should ship it to me by Tuesday. I am excited to start learning about financial PDEs, and hope to frequent here, posting/discussing code snippets. Would you all have any suggestions/tips to make the most out of this book?

Any other books/background reading to complement it, would also be fantastic.

Cheers,

Quasar.
Start with chapter 1, 2 up to 7. Try to program Black Scholes PDE.
Other books are referenced as needed.
Just start.
 
Last edited:
Smart pointers 101:
// Simple program to be proficient with smart pointers
// ref. Beginning C++20 from novice to professional
// Quasar C.
// 30.03.2023

#include <iostream>
#include <memory>
#include <vector>
#include <cmath>
#include <format>

double interpolate(double a, double b, double c, double d, double x_0)
{
    return (a + x_0*(b + x_0*(c + d*x_0)));
}

int main()
{
    //I have read that C^2 cubic spline interpolation suffers from the overshooting problem.
    // Basically if x_0 < x_1 < ... < x_n are the knot points and y_0,y_1,...,y_n are the corresponding ordinates
    // we find that sup f >  y_i's
    //
    //C^1 Akima interpolation is a rather simple method.
    //Akima splines are also cubic polynomials. This method has the advantage that it doesn't result in unphysical wiggles
    //if the there are large changes in the second-derivative.

    auto x{ std::make_unique<double[]>(8) };
    auto y{ std::make_unique<double[]>(8) };

    for (std::size_t i{}; i < 8; ++i)
    {
        x[i] = static_cast<double>(i + 1);
        y[i] = static_cast<double>((i + 1) * (i + 1));
    }

    //m_i := Slope of the chord between (x_i,y_i) and (x_{i+1},y_{i+1})
    auto m{ std::make_unique<double[]>(8) };

    for (std::size_t i{}; i < 8; ++i)
    {
        m[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]);
    }

    //s_i := Slope at point i of the resulting interpolant
    auto s{ std::make_unique<double[]>(8) };

    //We need a special prescription for the first two and the last two points

    s[0] = m[0];
    s[1] = (m[0] + m[1]) / 2.0;

    for (std::size_t i{ 2 }; i < 6; ++i)
    {
        double num{ abs(m[i + 1] - m[i]) * m[i - 1] + abs(m[i - 1] - m[i - 2]) * m[i] };
        double den{ abs(m[i + 1] - m[i]) + abs(m[i - 1] - m[i - 2]) };
        if (den == 0.)
        {
            s[i] = (m[i - 1] + m[i]) / 2.0;
        }
        else
        {
            s[i] = num / den;
        }
    }

    s[6] = (m[5] + m[6]) / 2.0;
    s[7] = m[6];


    //Coefficients
    auto a{ std::make_unique<double[]>(8) };
    auto b{ std::make_unique<double[]>(8) };
    auto c{ std::make_unique<double[]>(8) };
    auto d{ std::make_unique<double[]>(8) };

    for (size_t i{}; i < 8; ++i)
    {
        a[i] = y[i];
        b[i] = s[i];
        c[i] = (3 * m[i] - 2 * s[i] - s[i + 1]) / (x[i + 1] - x[i]);
        d[i] = (s[i] + s[i + 1] - 2 * m[i]) / pow((x[i + 1] - x[i]), 2.0);
    }

    //The interpolant is ready.
    // Let
    double test_x{ 6.5 };

    // Find the sub-interval [x_j,x_{j+1}] where the test point lies
    std::size_t j{};
    for (; j < 7; ++j)
    {
        if (x[j] <= test_x && test_x <= x[j + 1])
            break;
    }

    double test_y{ interpolate(a[j],b[j],c[j],d[j],(test_x - x[j])) };
    std::cout << std::format("x = {:<2.6f}, y = {:2.6f}", test_x, test_y);
    return 0;
}

x = 6.500000, y = 42.250000
 
Bjarne Stroustrup on C++ Concepts

My (DJD) 2 cents
This is a new idea for most C++ developers. It represents a shift in thinking from the traditional OOP subtype polymorphism mindset/way of life. It is essentially functional programming and I have subsumed Concepts into my own applications (domain architectures) and teaching (www.quantnet.com). You need to take concrete cases when embarking on Concepts and realising they are essentially the same as Haskell TYPECLASSEs and are a realisation of provides-requires interfaces as seen in Module Interface Languages (MIL), which were lost in action all those years.
With co-author Harold Kasperink we have subsumed 90% of the famous GOF patterns into a Concepts framework. I have posted examples thereof on LI in the last few weeks.
Concepts are a game changer. We have been waiting on them since 2004 (Domain Architectures Duffy 2004, Wiley UK). In a word, they are "Bridge++" pattern.


@APalley
 
Bjarne Stroustrup on C++ Concepts

My (DJD) 2 cents
This is a new idea for most C++ developers. It represents a shift in thinking from the traditional OOP subtype polymorphism mindset/way of life. It is essentially functional programming and I have subsumed Concepts into my own applications (domain architectures) and teaching (www.quantnet.com). You need to take concrete cases when embarking on Concepts and realising they are essentially the same as Haskell TYPECLASSEs and are a realisation of provides-requires interfaces as seen in Module Interface Languages (MIL), which were lost in action all those years.
With co-author Harold Kasperink we have subsumed 90% of the famous GOF patterns into a Concepts framework. I have posted examples thereof on LI in the last few weeks.
Concepts are a game changer. We have been waiting on them since 2004 (Domain Architectures Duffy 2004, Wiley UK). In a word, they are "Bridge++" pattern.


@APalley
Love this!
 
Following the critical path to studying PDEs in finance.

I coded up the most basic forward Euler scheme for initial-value problems; using some C++ lambdas. The aim is to merely understand how to map algorithms to C++ code and brush up ODEs before moving to PDEs.

Client Interface:
// ode_solvers.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>
#include "OdeSystem.h"
#include "EulerIVPOdeSolver.h"

int main()
{
    /* Let's try to solve the first order ODE given by
    *  x' = (1-2t)x
    */
    InitialConditionsType initialConditions{ {"x", 1.0} };
    StateVariablesType state{ initialConditions };
    ParametersType parameters{};
    OdeFunction odeFunc = [](double t, StateVariablesType state, ParametersType parameters) -> double {
        return (1 - 2 * t) * state["x"];
        };

    std::vector<OdeFunction> rhs{ odeFunc };
    const int dimension{ 1 };
    OdeSystem myOde{ rhs,initialConditions,dimension,parameters };

    std::unique_ptr<AbstractIVPOdeSolver> forwardEuler = std::make_unique<EulerIVPOdeSolver>();

    OdeSolution solution = forwardEuler->Solve(myOde, 0.0, 1.0, 0.1);

}
Link to the Git Repo.

Any other single-step solver must extend AbstractOneStepIVPOdeSolver and provide an implementation of the virtual method calculateNextYValue().

Next steps. Code a few more interesting solvers, understand the ideas of stability, consistency. Play around with boost::odeint, and reproduce these results, before moving to PDEs.
 
Last edited:
This code is difficult to read; it is not documented. Lots of automatic variables defined in calculateNextYValue().
BTW how's the performance? looks top-heavy at first glance.
Why not just post a zip file???
 
Last edited:
This code is difficult to read; it is not documented. Lots of automatic variables defined in calculateNextYValue().
BTW how's the performance? looks top-heavy at first glance.
Why not just post a zip file???
Cool, I made an edit. Posted the link to the Git Repo, instead of the word diarrhoea.

I will document the code properly, and maintain a folder structure, shortly. I am happy to learn from any code reviews.
 
Back
Top