Skip to content

Pricing framework for complex financial derivatives.

License

Notifications You must be signed in to change notification settings

johannesgerer/Fipster

Repository files navigation

Fipster Build Status

High performance pricing framework for complex financial derivatives using finite difference methods.

Features:

  • Versatile configuration via XML (see the docs)
  • Calculate expectation values for risk neutral valuation, utility indifference pricing and other expectation based pricing methods
  • Derive optimal/pessimal strategies for payoffs that depend on decisions (like exercise decisions in Bermuda/American options or optimal hedging decisions)
  • Provides a novel implementation of the Cryer algorithm for general linear complementary problems (used for American type exercise with more than one exercise region)
  • Explicit, Implicit and Crank-Nicholson time-stepping (with Rannacher steps for smooth Greeks)
  • Arbitrary dimensional state space, i.e. any number of underlyings and driving factors such as stochastic volatility. Curse of dimensionality (somewhat) weakened through automatic Strang splitting.
  • Any combination of von-Neumann and Dirichlet boundary conditions (boundary conditions are solved using a novel implementation of a sparse Sherman-Morrison approach)
  • Arbitrary nesting and compounding of derivatives, i.e. calculated prices can be transparantly used as payoffs
  • Automatic coarse-grained parallelization through the use of an extended version of Intel's TBB Flow Graph (see below)
  • Automatic optimal PDE discretization: the optimal finite difference stencil is derived using non-negative least squares

The software was used to derive numerical results for my dissertation.

Dependencies

  • Boost >= 1.54
    • Boost Headers (Ubuntu: libboost-dev)
    • Boost Filesystems (Ubuntu: libboost-filesystem-dev)
    • Boost Program Options (Ubuntu: libboost-program-options-dev)
    • Boost System (Ubuntu: libboost-system-dev)
  • Threading Building Blocks (Intel TBB) >= 4.4_20160526
  • Eigen Template Library >= 3.2 (Ubuntu: libeigen3-dev)
  • gcc >= 6.2.0 | >= 4.8.5 | clang >= 3.5.0
    • compiling with MS Visual C++ should also work

(see also the travis configuration)

Usage

Compiling / Running

make runo

which uses the config.xml in the same directory.

Alternatively, you can build it with make opt and the run it with src/main --config <path>

Developement Build

make run or make debug

Configuration

Fipster uses its own XML-based configuration format to describe what to calculate. Please refer to the docs and example configurations.

Here is an excerpt of config/positions.xml:

<boundaryConditions id="BCs1" tolerance="1e-14">
  <stateVariable nr="1">
    <lower  type="Dirichlet" inhomSource="futureValue"/>
    <upper  type="Dirichlet" inhomSource="futureValue"/>
  </stateVariable>
</boundaryConditions>

<finiteDifferenceWeights id="BSIsoWAm">
  <stencilType>OneDiagonal</stencilType>
  <PDE type="BSIso">
    <discountingRate>0.05</discountingRate>
    <volatility>.5</volatility>
    <correlation>0.0</correlation>
    <drift>0.05</drift>
  </PDE>
  <partialDerivativeOrder>2</partialDerivativeOrder>
  <higherOrderWeight>0.9</higherOrderWeight>
</finiteDifferenceWeights>

<expectation id="AmExpectation">
  <boundaryConditions>BCs1</boundaryConditions>
  <finiteDifferenceWeights>BSIsoWAm</finiteDifferenceWeights>
  <strangSymmetrization>true</strangSymmetrization>
  <timeStepping>
    <offset>0</offset>
    <stepSize>0.01e6</stepSize>
  </timeStepping>
  <theta>0.5</theta>
  <rannacherSteps steps="2">
    <strangSymmetrization>false</strangSymmetrization>
    <stepSize>0.005e6</stepSize>
    <theta>1</theta>
  </rannacherSteps>
</expectation>

<option id="AmOption">
  <discountingRate>0.0</discountingRate>
	<expectation>AmExpectation</expectation>
	<times>
		<stop>1e8</stop>
		<offset>1e8</offset>
		<stepSize>0.01e6</stepSize>
	</times>
	<exercise>
		<implicit>false</implicit>
		<value>payoff1</value>
	</exercise>
</option>

<solution active="1" id="Decisions0" hedgingPos="true">
  <fields>
		<option id="AmOption" exercise="always"/>
		<option id="Option" exercise="always" skip="2">
			<deltaHedging>
				<option id="AmOption" exercise="always"/>
			</deltaHedging>
		</option>
  </fields>
  <times>
    <start>.75e8</start>
    <offset>.75e8</offset>
    <stop>1e8</stop>
    <stepSize>.12e7</stepSize>
  </times>
  <fixedPlotTime>1e8</fixedPlotTime>
  <grid>grid1</grid>
  <singleValues>
    <at><x>40</x></at>
    <at><x>45</x></at>
    <at><x>120</x></at>
  </singleValues>
</solution>

The corresponding program output on a quadcore CPU, where .x.... is used to indicate which CPU core calculated a certain step:

> src/main --config config/positions.xml 
careful: discounting_rate only applies to the expectation, thus it is not suitable to calcuate higher moments of discounted quantites by solving this pde with undiscounted final values
x.....: Parser  | create_graph_and_run (parallel)
x.....: Hedging grid (hedging_grid_f):

[("cache hit", 9616979), ("cache miss", 545119), ("continue_nodes", 7), ("edges", 1384335), ("function_nodes", 518), ("joined_function_node", 358862), ("runtime_join_nodes", 420172)]
Cache size of 'boundary_conditions':1
Cache size of 'fdweights':2
Cache size of 'payoff1':2502
Cache size of 'Option':56700
Cache size of 'AmOption':5002
Cache size of 'Expectation1':169200
Cache size of 'AmExpectation':10002
Cache size of 'splitter':2
Cache size of 'timestepping_operator':4
x.....: GRAPH  | Start and wait for all
.x....: EXPL FL (0) | START
.x....: EXPL FL| DONE
x.....: EXPL FL (0) | START
x.....: EXPL FL| DONE
..x...: WEIGHTS| for 2 neighbors and 2 of PDE terms
..x...: WEIGHTS| (unconstrained weights) are NOT overdetermined
..x...: WEIGHTS| nSites: 298
..x...: WEIGHTS| Accessing Least Squares TLS
..x...: WEIGHTS| DONE, maxNorm:0.000e+00 in 6.280e-05s
..x...: &gsi: 0x7fabc0002950
..x...: WEIGHTS| DONE systems information in 7.717e-06s
..x...: BCs    | START
..x...: BCs    | DONE, assembled and inverted: 8.352e-06s
..x...: SPLITIN| START
..x...: SPLITIN| TESTING Split
..x...: SPLITIN| DONE TESTING Split
..x...: SPLITIN| DONE
..x...: WEIGHTS| for 2 neighbors and 2 of PDE terms
..x...: WEIGHTS| (unconstrained weights) are NOT overdetermined
..x...: WEIGHTS| nSites: 298
..x...: WEIGHTS| DONE, maxNorm:0.000e+00 in 5.090e-05s
..x...: &gsi: 0x7fabc0004b20
..x...: WEIGHTS| DONE systems information in 4.658e-06s
..x...: SPLITIN| START
..x...: SPLITIN| TESTING Split
..x...: SPLITIN| DONE TESTING Split
..x...: SPLITIN| DONE
..x...: EXPECT | Accessing Time Stepping TLS
.x....: EXPECT | Accessing Time Stepping TLS
...x..: EXPECT | Accessing Time Stepping TLS
x.....: EXPECT | Accessing Time Stepping TLS
.x....: OUTPUT (Decisions0 at time 100000000 on grid grid1) | START
...x..: OUTPUT (Decisions2 at time 100000000 on grid grid1) | START
[...]
x.....: OUTPUT (Decisions0 at time 76200000 on grid grid1) | START
..x...: OUTPUT (Decisions1 at time 76200000 on grid grid1) | START
.x....: OUTPUT (Decisions2 at time 76200000 on grid grid1) | START
..x...: OUTPUT (Decisions1 at time 75000000 on grid grid1) | START
x.....: OUTPUT (Decisions0 at time 75000000 on grid grid1) | START
...x..: OUTPUT (Decisions2 at time 75000000 on grid grid1) | START

Flow graph architecture

flow_graph_bodies

About

Pricing framework for complex financial derivatives.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages