# Architecture of a global pricing library with immutable payoffs

By global pricing library I mean a library

• handling equity, rate etc, hybrid products
• having several models (BS, LV, SV, LSV)
• having several numerical methods (analytic formula, MC, PDE FD/FE)

I never had to design a global pricing library, only had to write isolated MC or PDE FD pricing libraries, with BS, LV and SV mainly, in a purely front office setting, so I was quite free for the modelling and designing. In these cases I always used the following architecture (in the case of a toy MC) :

• a Product has a (reference to) a PayOff
• a PayOff has a Model and a ComputePayOffmethod that computes the payoff on a path generated by the model
• a Model has a RandomNumberGenerator and a GenerateMCPath method that generates an MC path given dates with the given random generator

PayOff is abstract, as well as Model and RandomNumberGenerator, even if I always had issues with avoiding exponential increase of subclasses due to transverse functionality, as I am not a design pattern (bridge ?) expert.

So that PayOff has a lot of "non-immutable" information. For instance if my RandomNumberGenerator is a Sobol, it may have a member that changes after generating random number, so that after a pricing, PayOff has a information that has changed. I never cared about that.

Now, I have the task of laying out a poc for a global pricing library, with the constraint that Product and PayOff must not change (they going to be (de)serialized). I could of course, with a lot of contorsions, continue to do as in the previous toy-example, but it would be wrong.

Still, after thinking, some things do not change : I indeed want to have three categories of "objects" :

• products (or payoffs to make it simple)
• models
• numerical methods

and these categories may intersect, for instance :

• the intersection of european payoffs, BS model and closed formulae (a special kind of numerical method) yields the BS formula
• the intersection of european payoffs and Heston model yields as numerical methods either closed formulas, PDE FD2D or MC

etc. In fact, the library needs to process a given payoff under a given model, using a given numerical method, keeping track of the fact that it cannot price everything in any model and with any numerical method ...

Is there a classic way to design this ? As I do not intend to necessarily reinvent the wheel, I looked at QuantLib and Strata so far, but they both have "non-immutable" "payoffs".

• I would say this is a problem that requires a lot of experience to get right from the start - the reality is that you'll make design decisions to begin with that seem like good ideas that later on end up hamstringing you - this is a problem you'll encounter in building any large system, it's not an easy problem. You'll then need to think about calculating Greeks on all the products, calculating pnl and attributing it to certain Greeks, how deep down the rabbit hole do you plan on going? Do you plan on making a full risk management system? – will Mar 7 '19 at 17:46
• The end of the road is indeed a full risk management system. But for a start it can be a generic MC pricer only. Still I guess there are bad habits to avoid from a start, and I am trying to avoid them. As I said, I am not really satisfied with QL nor with Strata. – Olorin Mar 7 '19 at 18:49
• So, I created a generic mc pricer which had mutlple models, prngs, correlation models, etc, all as you mentioned above. After I moved to an IB and saw how the rm system worked, as well. If you have the pricing system, then wrapping rm and pnl scalloping around it is not too hard, as it's all just going to be applying a series of bumps to the market data. The main bits of advice I'd give are 1. Make everything generic. 2. Be very strick about how you allow your objects to interact, if you let them mess with the internals of each other it quickly becomes very difficult to change your code. – will Mar 7 '19 at 20:17
• Why everything generic ? – Olorin Mar 8 '19 at 6:53
• Generic is potentially the wrong word, abstract is better. Not everything will have to be, but I just found it easier to outline everything in abstract classes and then have factory methods that instantiated the specific moving parts based on a load of config variables. There was a function that sat outside the whole thing and controlled the flow of information, but as sides from thst it was all abstractm – will Mar 8 '19 at 12:49