Serving the Quantitative Finance Community

 
 
User avatar
rmax
Posts: 374
Joined: December 8th, 2005, 9:31 am

Re: C++11 and C++14 Articles

August 10th, 2018, 3:26 pm

I am not sure I necessarily agree with the last section on the programming paradigm etc. I am also not convinced that people write code alone - I have not worked in an environment like that for probably 20+ years, so small places yes, but larger institutions I think not. I also think that it is true that prorgramming projects can "rush straight in", but this has been known about for years (The mythical man month etc).  However it is interesting to note WHY people act in that way even though there is literature out there showing conclusively it is not the way to act.
My 2 cents for a Friday afternoon.
 
User avatar
Cuchulainn
Topic Author
Posts: 20253
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

August 10th, 2018, 8:52 pm

Some initial thoughts to mull over for the weekend (from Fred Brooks);
Chemical engineers learned long ago that a process that works in the laboratory cannot be implemented in a factory in one step. An intermediate step called the pilot plant is necessary....In most [software] projects, the first system is barely usable. It may be too slow, too big, awkward to use, or all three. There is no alternative but to start again, smarting but smarter, and build a redesigned version in which these problems are solved.... Delivering the throwaway to customers buys time, but it does so only at the cost of agony for the user, distraction for the builders while they do the redesign, and a bad reputation for the product that the best redesign will find hard to live down. Hence, plan to throw one away; you will, anyhow.
The other chapters discuss why this is so and Brooks points out one of his mistakes in the first edition--"David Parnas Was Right, and I Was Wrong About Information Hiding." 

My guess (I am fairly sure) that a large % of developers' Sapir-Whorp vocabulary does not contain the metaphors 'top-down', 'decomposition' and 'information hiding'. (this is part of your WHY remark.). There's a zillion ways to run a software project; not all are equal.

//
In part II we elaborate a bit more on loosely coupled systems and hiding nasty stuff behind black boxes (like legacy systems).

This paper is the second in a series of two on the design of software systems in computational finance. Both papers are concerned with applications using a combinationof C++, C#, and C++/CLI in the Microsoft .NET Framework. We create
a multilanguage application to value an equity-linked product. The actual pricing
of this product will be performed by the QuantLib Monte Carlo framework. We
use C++/CLI code as a wrapper class for native C++ code. Then, we use C# as a
front end to the C++/CLI wrapper, after having constructed transaction-related
parameters and market data. For flexible input data construction, a specific
factory mechanism will be implemented using Assembly, Reflection API, and
dynamic data types. Finally, we interface C# client code to Excel. The source code
for the application in this paper can be requested by contacting the authors. Since
this paper discusses how we implemented the application, we feel that compiling
and running the corresponding code will be an aid in understanding the design
rationale.

Keywords
native C++, C#, C++/CLI, interoperable and reusable code, multilanguage applications,
factory design, equity-linked products, Excel-DNA

//
'Software Engineering' is more of an art than science.
 
User avatar
Cuchulainn
Topic Author
Posts: 20253
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

August 29th, 2018, 1:22 pm

I have just been informed by my publisher John Wiley today (my 66th birthday!) that my second edition will be published 31 August 2018.
Attachments
C++ second edition.png
Last edited by Cuchulainn on August 30th, 2018, 10:40 am, edited 2 times in total.
 
User avatar
ppauper
Posts: 11729
Joined: November 15th, 2001, 1:29 pm

Re: C++11 and C++14 Articles

August 29th, 2018, 3:03 pm

congratulations
 
User avatar
Cuchulainn
Topic Author
Posts: 20253
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

August 29th, 2018, 3:57 pm

Thank you. ppauper!
 
User avatar
Cuchulainn
Topic Author
Posts: 20253
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

September 3rd, 2018, 11:42 am

Sample chapter and overview of book
Attachments
Chapter1Watermark.pdf
(651.67 KiB) Downloaded 201 times
 
User avatar
ExSan
Posts: 493
Joined: April 12th, 2003, 10:40 am

Re: C++11 and C++14 Articles

September 11th, 2018, 1:48 pm

I have just been informed by my publisher John Wiley today (my 66th birthday!) that my second edition will be published 31 August 2018.
congratulations as well
°°° About ExSan bit.ly/3U5bIdq °°°
 
User avatar
Cuchulainn
Topic Author
Posts: 20253
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

September 11th, 2018, 2:46 pm

Muchos gracias, amigo Exsan
 
User avatar
Cuchulainn
Topic Author
Posts: 20253
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

September 21st, 2018, 11:09 am

Here is sample code for a 1-factor Monte Carlo pricer based on the Actor model (Carl Hewitt)

https://en.wikipedia.org/wiki/Actor_model

The code is built with Micrsoft's C++ Asynchonous Agents Library as well as C# TPL Workflow Library.

Actor has many advantages for concurrent applications. You can run the code and see how it goes.

The bottom-up OOP object network approach is not so useful here. In general, the best approach is system/task decomposition and coarse-grained parallel. Then each actor can be made fine-grained multi-threaded.
Attachments
AgentsLibrary.zip
(7.6 KiB) Downloaded 178 times
Last edited by Cuchulainn on September 21st, 2018, 11:19 am, edited 2 times in total.
 
User avatar
Cuchulainn
Topic Author
Posts: 20253
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

September 21st, 2018, 11:13 am

C# Actor MC
// TestAgentsMC.cs
//
// Monte Carlo option pricing using agents in a producer-consumer 
// metaphor.
//
// Compare this solution with
//
//  Multicast delegates
//  Event Pattern
//  OOP Observer pattern.
//
// Actors might be a good solution for batch jobs.
//
// Code ported from C++ to C#
//
// (C) Datasim Education BV 2016-2018
//

using System;
using System.Threading;

using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics;
using MathNet.Numerics.LinearAlgebra.Double;
using System.Globalization;
using MathNet.Numerics.Random;
using MathNet.Numerics.Distributions;

using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;

using System.Diagnostics; // For StopWatch

public static class Utility
{
    public static void ThreadSafePrint(string s)
    { // Function to avoid garbled output on the console


        object _locker = new object();
        Monitor.Enter(_locker);
        try
        {
            Console.WriteLine("{0}", s);
        }
        finally { Monitor.Enter(_locker); }

    }

}

// Encapsulate all data in one place
public class OptionData
{ // Option data + behaviour

    public double K;
    public double T;
    public double r;
    public double sig;

    public int type;

    // Extra data 
    public double D;       // dividend

    public OptionData()
    {
        K = 65.0; T = 0.25;
        r = 0.08; sig = 0.3; D = 0.0;
        type = -1;
    }

    public OptionData(OptionData opt)
    {
        K = opt.K; T = opt.T;
        r = opt.r; sig = opt.sig; D = opt.D;
        type = opt.type;
    }

    public OptionData(double strike, double expiration, double interestRate,
                       double volatility, double dividend, int PC)
    {
        K = strike; T = expiration; r = interestRate; sig = volatility; D = dividend; type = PC;
    }
  

    public double myPayOffFunction(double S)
    { // Payoff function

        if (type == 1)
        { // Call

            return Math.Max(S - K, 0.0);
        }
        else
        { // Put

            return Math.Max(K - S, 0.0);
        }
    }
}


public class MyMersenneTwister 
{ // Math.Net 19937

    private MersenneTwister mt;
    public MyMersenneTwister() { mt = new MersenneTwister(); }

    public double GenerateRn()
    {
        return Normal.Sample(mt, 0.0, 1.0);
    }
}

class Sde
{ // Defines drift + diffusion + data

    private OptionData data;    // The data for the option

    public Sde(OptionData opt) { data = opt; }

 	public double drift(double t, double S)
	{ // Drift term

		return (data.r - data.D)*S; // r - D
	}


	public double diffusion(double t, double S)
	{ // Diffusion term

		return data.sig * S;
	}

    public double expiration()
	{
		return data.T;
	}
}


// Demonstrates a basic agent that produces values.
class PathEvolver // Producer/Source
{
    // The target buffer to write to.
    private ITargetBlock<double> _target;

	private int NT;
	private int NSIM;

	private Sde sde;
	private double S0;

    private MyMersenneTwister mt;

public PathEvolver(ITargetBlock<double> target, int NSteps, int NSimulations, Sde stochasticDE,
                                    double S_0)
    {
        _target = (target);  NT=(NSteps); NSIM=(NSimulations);
        sde=(stochasticDE); S0=(S_0);

        mt = new MyMersenneTwister();
    }



    public void run()
    {
        Utility.ThreadSafePrint("Starting producer");

        double k = sde.expiration() / NT;
        double sqrk = Math.Sqrt(k);
        double v;

        for (int n = 0; n < NSIM; ++n)
        {
       //    if ((n/10000)*n == n)
             //   Console.Write("{0}, ", n);
        

            double VOld = S0; double VNew = 0;
            double x = 0.0;

            for (long index = 0; index < NT; ++index)
            {
                v = mt.GenerateRn();
                // The FDM (in this case explicit Euler), equation (9.2) from the text
                VNew = VOld + (k * sde.drift(x, VOld)) + (sqrk * sde.diffusion(x, VOld) * v);

                VOld = VNew;
                x += k;
            }
    //        Console.WriteLine("{0}, ", VNew);
            _target.Post(VNew);

        }


        _target.Complete();


        Utility.ThreadSafePrint("Exit producer");
    }

}

// Demonstrates a basic agent that consumes values.
public class OptionPricer
{

	// The source buffer to read from.
    public ISourceBlock<double> _source;

	// ...

	private OptionData myOption;
	private double price;

    public OptionPricer(ISourceBlock<double> source, OptionData opt)
    {

        _source = (source);  myOption=(opt);price=0.0;
    }


	public double Price()
	{ // Option price

		return price;
	}

	public async Task<double> run()
	{
			
		double payoffT;
		double avgPayoffT = 0.0;
		double squaredPayoff = 0.0;
		double sumPriceT = 0.0;
		int NSIM = 0;
		double VNew;
        Console.WriteLine(" Receiving... ");
        while (await _source.OutputAvailableAsync())
        {
         //   if ((NSIM / 10000) * NSIM == NSIM)
            //      Console.Write("{0}, ", NSIM);

            // Assemble quantities (postprocessing)
            VNew = _source.Receive();
			payoffT = myOption.myPayOffFunction(VNew);
			sumPriceT += payoffT;
			avgPayoffT += payoffT / NSIM;
			avgPayoffT *= avgPayoffT;

			squaredPayoff += (payoffT*payoffT);
			NSIM++;
		}
        Console.WriteLine(" Receiving");
        // Finally, discounting the average price
        price = Math.Exp(-myOption.r * myOption.T) * sumPriceT / NSIM;

        return price;

        Utility.ThreadSafePrint("Exit consumer");
 
    }
};



class TestTPL
{
    
    static void Main(string[] args)
    {

        // Create and start the stopwatch
        Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();

        // Create and start the producer and consumer agents.
        OptionData myOption = new OptionData();
     
        int NT = 500;
        int NSIM = 100000;

      
        // Create SDE
        var sde1 = new Sde(myOption);
        double S0 = 60.0;

        OptionData myOption2 = new OptionData(myOption);
        myOption2.type = 1;
        var sde2 = new Sde(myOption2);

        OptionData myOption3 = new OptionData(myOption);
        myOption3.K = 70.0;
        var sde3 = new Sde(myOption3);

        // A message buffer that is shared by the agents.
        var buffer = new BufferBlock<double>(); // unbounded or bounded buffer store
        var buffer2 = new BufferBlock<double>();
        var buffer3 = new BufferBlock<double>();

        PathEvolver producer = new PathEvolver(buffer, NT, NSIM, sde1, S0);
        PathEvolver producer2 = new PathEvolver(buffer2, NT, NSIM, sde2, S0);
        PathEvolver producer3 = new PathEvolver(buffer3, NT, NSIM, sde2, S0);
        // Define pricers
        OptionPricer consumer = new OptionPricer(buffer, myOption);
        OptionPricer consumer2 = new OptionPricer(buffer2, myOption2);
        OptionPricer consumer3 = new OptionPricer(buffer3, myOption3);

        var cs = consumer.run();
        var cs2 = consumer2.run();
        var cs3 = consumer3.run();

        producer.run();
        producer2.run();
        producer3.run();

        cs.Wait();
        cs2.Wait();
        cs3.Wait();

        stopWatch.Stop();
        // Get the elapsed time as a TimeSpan value.
        TimeSpan ts = stopWatch.Elapsed;

        // Format and display the TimeSpan value.
        string elapsedTime = String.Format("Elapsed time {0:00}:{1:00}:{2:00}.{3:00}",
                                            ts.Hours, ts.Minutes, ts.Seconds,
                                             ts.Milliseconds / 10);
        Console.WriteLine(elapsedTime, "RunTime");


        Console.WriteLine(consumer.Price());
        Console.WriteLine(consumer2.Price());
        Console.WriteLine(consumer3.Price());
    }
}
 
User avatar
Cuchulainn
Topic Author
Posts: 20253
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: C++11 and C++14 Articles

November 6th, 2018, 4:43 pm

 
User avatar
MikeJuniperhill
Posts: 4
Joined: February 7th, 2004, 11:57 am

Re: C++11 and C++14 Articles

November 8th, 2018, 4:29 pm

Source code and the other required files can be downloaded from Datasim blog. Moreover, detailed instructions for assembling the application can be found in my blog.

Regards, Mike