C++ for Quantitative Finance: Hands-On - Setup, Configuration, Syntax and Debuging

APLIED COMPUTATIO, QUANT METHODS 

RELEVANT FOR QUANTITATIVE FINANCE

Basic notion of programming required 

 

This blog adopts a hands-on, laboratory-based approach: concepts are developed through direct implementation and problem solving. And practice with real data, implementing calculations and models. The objective is to accelerate the practical application of C++ in computational quantitative finance, emphasizing efficiency, numerical rigor, and real-world modeling. 

The content is organized as follows (click to be redirected):

  1. Setup and Configuration
  2. Language and Syntax (moderm C++, C++20)
  3. Debuging 
  4. Memory Management 
  5. Object-Oriented Programming (OOP) 
  6. Efective and Functional Programming 
  7. Generic Programming (GP)
  8. High Performance Computation 
  9. Applications in Computational Finance
    1. .
    2. .
    3. .
    4. .
  10. Data Strcutures and Algorithms
  11. Reference 

Each session have being public in a separate session due to the Blogger content volume restriction. 

Go to the main publication (click here). 

 

1 - Fast Setup and Configuration

Software

Standard Environment

It’s most efficient for the staff if everyone uses the same environment:

  • Compiling: gcc, g++
  • Debugging: gdb, some use valgrind
  • About IDEs for programing: If you prefer using a GUI—which is often beneficial—Visual Studio Code is a versatile option. You may also explore other alternatives if time permits. Regardless of the IDE, your code must run correctly and be properly tested across and in standard environments.

 Windows

  •  Use MSYS2 is a collection of tools. Or the most frequent necessary packages are available in cygwin (gcc-core, gcc-g++, gdb).
    •  Cywing : a large collection of GNU and Open Source tools which provide functionality similar to a Linux distribution on Windows.
    • Check your availability or version:
gcc --version
g++ --version
gdb --version

 Linux

  • In the case of linux the componenst are integrate in the build essential; and you will need gdb. If you use Visual Studio Code equally you can use the public intructions too.
sudo apt-get install build-essential #or equivalent.

sudo apt-get install build-essential gdb


Setup c++ standar to 20 (linux or windows)
    - Change the c_cpp_properties.json file with ["cppStandard": "gnu++20",] or add [-std=c++20], in task.json (thes files will be generate after the first execution or configuration).

    - Or change it int the C/C++: Edit Configuratinos (UI)

 
 
 
 
 


2 - C++ syntax

Don’t get lost in this session. Focus on the basic idea, the structure, and a few key terms (the ones shown in the examples). Then review some additional sample code and move directly to hands-on, coding is how you will truly learn.
 
Any basic C++ program structure generally will fallow [#include, main() and return 0]. In this way the key elements in C++ syntax are:
  • Library importation: # include
  • Execution starts (main function) and group of statement (scope or blocks): int  main () { }
  • In the scope will be the:
    • Variable declaration with  =  (using key words for the data types as int and dimension as long).
      • With variables you will use references (&) and pointers (*
    • Output definition (cout <<) and chaining (<<)
    • Input definition ( cint)
    • Return Statement (return 0;)
  • The required at end of statement; 
  • Comments in a single-lin (//) and multi-line (/*     */
  • You will have to add or use namespace, arithmetic operators,  auto, functions, class and identifiers.

I will recommend an overview of any C++ Style Guide as the Google of University of Pensilvania. But don't spend to much time or get lose on it now, we go to see it on session 4 that is focus on efective and functional programming.

Above I show a simple and complex samples. Start with the simple, change something in the code and execute (the best way to understand it quitkly) and then go to the more complex:

//simple
#include <iostream>
 
int main(){

    std::cout << "Hello Quant Finance C++ World!, year 2026";

    return 0;
}

 

//adding some elements and interation

#include <iostream>
#include <vector>
#include <string>

int main(){

    int year = 2026;
    int& ref = year;
    int* ptr = &year;
   
    const std::vector<std::string> message{
        "Hello",
        "Quant Finance",
        "C++",
        "World",
        "!"
    };

    for (const auto& word : message){
        std::cout << word << ' ';
    }
    std::cout << '\n';

    std::cout << "year: "                         << year << '\n';
    std::cout << "ref (alias of year): "          << ref << '\n';
    std::cout << "ptr (address of year): "        << ptr << '\n';
    std::cout << "*ptr (value at that address): " << *ptr << '\n';

    return 0;
}

 [I STEEL WORKING ON THE COMPLEX ILUSTRATIVE AND UNDERSTABLE SAMPLE]

 
 
Library (Header or Header files .h)
 
The C++ Standard Library is included via header files or at the beginning of a program. See above a header ilustration as in the previous code samples:
 
# include <iostream> // for standard I/O
# include <vector> // for std :: vector
// consult in cppreference what are thes two for: 
#include <string>
#include <ranges>
 
# include <map> // for std :: map
# include <set> // for std :: set
# include <algorithm> // for std :: sort , std :: accumulate
# include <functional> // for std :: function
# include <memory> // for smart pointers
# include <iterator> // for iterators
 
The standard library can be consulted in cppreference:
 
 
 
 
Data types and variables
 
Here I go to be focuses in the most relevant and regularly use in quantitative finance (base on consult reference). You can view in deep the data types in cppreference documentation.

 
 
 
    int i;
    using namespace std;
    cout << i;
    char ch = 'a';
    bool flag = true ;

    float f = 1.233f ;
    double d = 351.342 ;

    int arr[5] ;

    int arr1[5] {1, 2, 3, 4, 5} ;
 
 
Modifiers: signed, unsigned, short and long
 
 
/* FUNDAMENTAL (Built-in) data types */

| Category  | Type           | Size (64-bit) | Precision / Range                           | Description          | Finance Usage            |
| --------- | -------------- | ------------- | ------------------------------------------- | -------------------- | ------------------------ |
| Boolean   | `bool`         | 1 byte        | 1 bit (true/false)                          | true / false         | Flags, model conditions  |
| Character | `char`         | 1 byte        |128 to 127 (signed) | 0 to 255 (unsigned) | Single character     | Rare                     |
| Integer   | `short`        | 2 bytes       |32,768 to 32,767                           | Small integer        | Rare                     |
| Integer   | `int`          | 4 bytes       |2.1×10⁹ to 2.1×10⁹                         | Standard integer     | Counters                 |
| Integer   | `long`         | 8 bytes*      |9.2×10¹⁸ to 9.2×10¹⁸                       | Larger integer       | System dependent         |
| Integer   | `long long`    | 8 bytes       |9.2×10¹⁸ to 9.2×10¹⁸                       | Very large integer   | Timestamps               |
| Unsigned  | `unsigned int` | 4 bytes       | 0 to 4.29×10⁹                               | Non-negative integer | IDs                      |
| Floating  | `float`        | 4 bytes       | ~7 decimal digits                           | Single precision     | Avoid in pricing         |
| Floating  | `double`       | 8 bytes       | ~1516 decimal digits                       | Double precision     | **Standard for pricing** |
| Floating  | `long double`  | 816 bytes    | ~1821 decimal digits (platform dependent)  | Extended precision   | *Advanced models*        |
| Void      | `void`         | —             | —                                           | No value             | Function return type     |


 
 
 
The recomended for quant finance data type:
 
But there are to many options and convination posibiliities, in priority order in the contex of finance you can see:
 
 
And there are son type utilities in moderm c++ that will help:
 
| Feature            | Description                | Finance Application     |
| ------------------ | -------------------------- | ----------------------- |
| `auto`             | Automatic type deduction   | Clean code              |
| `decltype`         | Extract type of expression | Template programming    |
| `using`            | Type alias                 | Cleaner model code      |
| `std::optional<T>` | Nullable type              | Missing data            |
| `std::variant`     | Type-safe union            | Flexible pricing engine |


 

 
 
 
use getline to read entire lines of text from your data file, such as experiment descriptions.
 

Functions

 
Functions Basics: As your research project grows, your program will become more complex. Instead of writing one long block of code, you'll use functions to break down tasks. For instance, you might have a function 

 
The best practice in modern c++
 
In modern C++, declare functions in header files (.hpp) and define them in source files (.cpp). This allows the compiler to know about a function before it is used, keeps code organized, improves maintainability, and enables separate compilation.
 
// math_utils.hpp
int Add(int a, int b);


// math_utils.cpp
#include "math_utils.hpp"

int Add(int a, int b) {
    return a + b;
}


// main.cpp
#include "math_utils.hpp"

int main() {
    Add(2, 3);
}
 
 

For small single-file programs, place function declarations (prototypes) before main() and definitions after main() to keep the high-level program flow visible first.

Rule: A function must be declared before it is used; its definition can come later.

 

Initiatitalization

 
 
 
 
 
 
 
Operators and expressions
Control flow and loops
Arrays and data aggregates
 

 

Pointers and References

 

 

 --------------------- 
 
  •  
  • Address-of Operator (&): Understanding how to obtain the memory address of a variable.
  • Dereference Operator (*): Learning how to access the value stored at a memory address pointed to by a pointer.
  • Initialization and Value Management: Discussing how to declare, initialize, and manage the values associated with pointers, including troubleshooting common issues.
  •  

     

    Pointers (*p): a memory adress

     

     
     
    Pointers, ilustration debuging the code to show variables values.
      
     
    Null pointer
     
     
    By carrefult, initialize pointers and avoid pointer without initialization [int *point]. It may lead to serious problems, modified whatever is in that memory allocation (access violation, segmentation fault, etc..). 
     
    Pointer initialization:
     
     
     

    Reference (&ref): an alias

     
    Another name that allways need a initializaer 
     
     
     
     
     
     
      
     +
     
     
    You might also use a null pointer to indicate that a particular data structure or array hasn't been initialized yet, preventing accidental access to invalid memory locations. This is a crucial best practice for avoiding crashes in your research software.
     
    Pointers allow you to work with large datasets without unnecessary copying, leading to faster execution times and more optimized code. 
     
     

    Const Qualifiers 

     

     

     

    auto keyword

     

     

     For and Range-based For

    Loops are one of the most fundamental tools in C++. The choice between a traditional for loop and a range-based for depends on whether you need control over the position of elements or simply want to process each element in a container. Modern C++ generally favors range-based for for its readability, safety, and simplicity. In the following illustration presents a practical decision guide for choosing between a traditional for loop and a range-based for loop in Modern C++.

     Some code samples

    //Sample code:
    //Traditional for

    #include <iostream>
    #include <vector>

    int main() {
        std::vector<int> num_container {10, 20, 30, 40};

        for (size_t i = 0; i < num_container.size(); ++i) {
            std::cout << num_container[i] << '\n';
        }
    }


    /* ---------------------------------------------------------------- */

    for (size_t i = 0; i < num_container.size(); i += 2) {
        std::cout << num_container[i] << '\n';
    }

    /* ////////////////////////////////////////////////////////////////// */
    //Range-based for
    #include <iostream>
    #include <vector>

    int main() {
        std::vector<int> num_container {10, 20, 30, 40};

        for (int value : num_container) {
            std::cout << value << '\n';
        }
    }

    /* ---------------------------------------------------------------- */

    for (int &value : num_container) {
        value *= 2;
    }

    /* ---------------------------------------------------------------- */

    for (const int &value : num_container) {
        std::cout << value << '\n';
    }

    /* ---------------------------------------------------------------- */

    #include <iostream>
    #include <vector>

    int main() {
        std::vector<std::string> names {
            "Alice",
            "Bob",
            "Charlie"
        };

        for (const std::string &name : names) {
            std::cout << name << '\n';
        }
    }



     The internal iteration of a range loop

    This code demonstrates that a range-based for loop is syntactic sugar for an iterator-based loop.

     

     

     

     Functions

     

    Function Overloading

    Function overloading allows multiple functions to have the same name but different parameter lists (different number or types of parameters). 
     
    This allow us to permor similar operations on different data types, the C++ compiler automatically picks the correct version of the function base on the arguments provide. 
     
    //function overloading


    int Add(int a, int b) {
        return a + b;
    }

    double Add(double a, double b) {
        return a + b;
    }

    int Add(int a, int b, int c) {
        return a + b + c;
    }

    //Function overloading allows multiple functions
    //to have the same name but different parameter
    //lists (different number or types of parameters).

    Add(2, 3);        // int version
    Add(2.5, 3.1);    // double version
    Add(1, 2, 3);     // three-argument version
     

    Extern "C"

    extern "C" and function overloading do not mix.
    C linkage requires unique function names.
     
    Use extern "C" when C++ must interoperate with C code or C libraries. It controls linkage, not function behavior.
     

    extern "C" tells the C++ compiler to use C linkage for the enclosed functions.

    This disables name mangling, allowing C++ code to call functions compiled by a C compiler.

    A C linker cannot distinguish multiple functions with the same name. 

     
    //best practice
    extern "C" {
        double AddDouble(double a, double b);
        void Print(int*);
    }

     

    Default functions arguments

     

     Inline functions and macro

    Prefer inline functions over macros in C++. 
     
    /* INLINE FUNCTION */

    inline int squaret(int x) {
        return x * x;
    }

    /* MACRO */

    #define SQUARE(x) x * x

     

     

     Rule: In modern C++, use inline, constexpr, or templates instead of function-like macros.

    FeatureInline functionMacro
    Type checkingYesNo
    DebuggingEasierHarder
    Scope rulesRespectedNot respected
    Function overloadingSupportedNot supported
    Safer evaluationYesNo

     

    Function Pointer 

    A function pointer stores the address of a function, so you can call that function indirectly.
     
    /* FUNCTION POINTER */

    int Add(int a, int b) {
        return a + b;
    }

    int (*operation_pointer)(int, int) = Add; //operation_pointer is a pointer to a function.

    int result = operation_pointer(2, 3); // calls Add
     

    //function pointer

    #include <iostream>

    int Add(int a, int b) {
        return a + b;
    }

    int Multiply(int a, int b) {
        return a * b;
    }

    int Apply(int x, int y, int (*funct)(int, int)) {
        return funct(x, y);
    }

    int main() {
        int a = Apply(2, 3, Add);
        int b = Apply(2, 3, Multiply);
    }

     
     
     
    Use function pointers when you need to pass behavior as data, especially for callbacks or selecting operations at runtime.
     
    In moderm C++ prefer std::function or lambdas when flexibility is needed:
     
    #include <functional>

    std::function<int(int, int)> operation = Add;
     
     
      

    Namespace

    Use namespaces to organize code and prevent naming conflicts.
     
    /* BEST PRACTICE */
     
    // PREFER EXPLICIT NAMES
    std::cout;
    std::vector<int>;
     
    //Avoid in header files
     
    using namespace std; // bad in headers

    //namespace

    //witout namespace two functions with the same name
    //may conflit.

    //in this way both function may exits
    # include <iostream>

    namespace Avg {
        int Calculate(int a, int b) {
            return (a + b) / 2;
        }

    }

    namespace Basic {
        int Calculate(int a, int b) {
            return x + y;
        }
    }

    int main() {
        Avg::Calculate(2, 3);
        Basic::Calculate(8, 9);
       
        return 0;
    }


     

     

    Reserve Words 

    The following is a list of key reserved words in C++.

     Now we can see this in an applied example:

     void : Funciones que no retornan nada

    void en C++ significa "sin valor" o "ningún tipo de dato". ejecuta una acción, pero no devuelve ningún valor. 

    #include <iostream>

    void greet() {
    std::cout << "Hello World\n";
    }

    int main() {
    greet();
    return 0;
    }
     
     
     

     [pendiente]

     

    Debuging

    A debugger allows developers to inspect a program while it is running, making it possible to identify the exact source of an error without relying on dozens of std::cout statements. 

    • Instead of adding print statements use a debugger
    • Set a breakpoint in parts tha performs a critical calculation or task
      • Right before or between the calculation
      • Once paudes, stepping through code with "Step Into (F11)" to go line by line or "step over (F10)" to execute a function call without diving into its internal workings. 
    •  Examine variables
    • Carrefult obser values, execution path, look conditions and operations to identified the bug.
    • Fix and verified running the debugger again.
     
     
     
     
     Processo en VS Code
    1. Open your .cpp file
    2. Set break points (F9)
    3. Start debugin (F5)
    4. And gor throught it. 

    Atajos: 

    • F9 → agregar/quitar breakpoint
    • F5 → iniciar o continuar debug
    • F10 → Step Over
    • F11 → Step Into
    • Shift + F11 → Step Out 
     
     
     
     
     

    Entradas populares

    Lo mas consultado

    Entradas populares