## Black Scholes calculator online

price of Call option and Option’s delta and gamma

introduce inputs in yellow cells:
dividend yield (all cash dividends divided by spot)

excel :

Advanced Black-Scholes online calculator takes real market interest rate curve and can calculate American options

## formula Black Scholes

Black Scholes formula is $Call=df(F_0N(d_+)-KN(d_-))$

where $F_0$ is forward of the stock S at time 0 for maturity T $F_0=S_0e^{-qT}/df_T$

where:
q – dividend yield
df – discount factor for time T $d_+=\frac{ln(F_0/K)}{\sigma\sqrt{T}}+0.5\sigma\sqrt{T}$ $d_-=\frac{ln(F_0/K)}{\sigma\sqrt{T}}-0.5\sigma\sqrt{T}$

Posted in OTC derivatives valuation Tagged with: , ,

## how to value Credit Default Swap default leg and default probabilities

how to value CDS (credit default swap) default leg with following time structure:

0—-t1—–t2—-t3—–t4—–….—T

Suppose that default (at time $\tau$) can only occur at discrete times t1,t2,t3,..
and Qi=survival probability until time $t_i$

then $\tau - time of default {=t_1,=t_2,=t_3 ...}$ $= 1 - ( 1-Q_2 + Q_3)= Q_2-Q_3$

default leg of Credit Default Swap pays: $discounted payoff = (1-R) ( df_1 E{\bf1}(\tau=t_1) + df_2 E{\bf1}(\tau=t_2)+ ...)$ $=(1-R) ( df_1 P(\tau=t_1)+df_2 P(\tau=t_2)+ ...)$ $=(1-R) ( df_1(1-Q_1)+df_2(Q_1-Q_2)+df_3(Q_2-Q_3) ... )$

where $df_1$ is discount factor for $t_1$ and R – recovery rate (normally assumed ot be 40%)

to use continuous time one normally use intensity: $Q(t)=exp( -\int_{0}^{T}\lambda(s)ds)$
in practice $\lambda$ is assumed to be piecewise-constant chaning value on market CDS maturities

useful approximations:
Credit Default Swap spread $\approx p(1-R) \approx \lambda (1-R)$
where $\lambda$ is intensity and approx. equal to probability of default in first year.

Posted in math, OTC derivatives valuation Tagged with:

## Part 5

c++ finance course

### Objective

based on this you’ll be able to price Autocallable, Himalaya, Spread and similar basket options

Here let’s see how to price an option on 2 stocks with payoff $( w_1S_1+w_2S_2-K)^+$
where $w_i$ are basket weights

let’s consider zero interest rate environment and n non-dividend paying stocks with dynamics: (for interest rates and dividends just add $(r-q)dt$ terms to this dynamics $dS_1=S_1 \sigma_1 dW_1(t)$ $dS_2=S_2 \sigma_2 dW_2(t)$ $dW_i dW_j=\rho_{i,j} dt$

where $\rho_{i,j}$ is a stock correlation matrix

given the correlation matrix we’ll construct it’s Cholesky decomposition.
Cholesky decomposition can be done with boost but it’s easier to do it with QuantLib implementation.
to store correlation and cholesky matrices we’ll use QuantLib::Matrix class.
we’ll store vector of independent gaussians in the QuantLib::Array class.
we don’t store in std::vector class because to be able to multiply matrix by vector they need to come from the same library.

to obtain correlated gaussians we’ll generate vector of independent gaussians $\vec{\epsilon}= (\epsilon_1, \epsilon_2)$ first.
then vector of correlated gaussians is $M_{cholesky} \vec{\epsilon}$

here’s the code for wights =1

#include <boost/random/variate_generator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>
#include <iostream>
#include <ql/quantlib.hpp>

double pp(double x) //positive part   x+
{
if(x>0) return x;
return 0;
}

void main()
{

boost::mt19937 mt;
boost::normal_distribution<> distribution;
boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>* normal(new boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>(mt,distribution));

int numberSimulations=10000;

std::vector<double> S0(2);
S0=100.0;// S1(0) - spot price of first stock
S0=100.0;//S2(0) - spot price of second stock

std::vector<double> sigma(2);
sigma=0.2; //volatility of S1
sigma=0.2;//volatility of S2

double T=1.0;//maturity in years
double K=100.0;//strike of option
double sum=0;//for monte-carlo averaging
double payoff=0;
double NT=100;//number of time intervals
double dt=T/NT;

QuantLib::Matrix rho(2,2);//correlation matrix

rho=1;rho=0.5;
rho=0.5;rho=1;

QuantLib::Matrix cholesky=QuantLib::CholeskyDecomposition(rho);

for(int iSim=0;iSim<numberSimulations;iSim++) //outer loop for simulations
{

std::vector<double> Sprev(S0); //create a vector equal to S0 with its values
std::vector<double> Snext(2);//create vector with 2 elemens

for(double t=0;t<T;t+=dt) //inner loop for constructing one stock price from time 0 to T
{
QuantLib::Array epsilon(2);//create a vector with 2 elements .we'll put here independent gaussians
epsilon=(*normal)();
epsilon=(*normal)();

QuantLib::Array x(2);
x=cholesky*epsilon; //correlated gaussians

for(int iStock=0;iStock<2;iStock++) //loop over all stocks
{
Snext[iStock]=Sprev[iStock]*std::exp(-0.5*sigma[iStock]*sigma[iStock]*dt+sigma[iStock]*std::sqrt(dt)*x[iStock]);
Sprev[iStock]=Snext[iStock];
}
}

payoff=pp(Snext+Snext-K);

sum+=payoff;
}

int dummy;std::cin>>dummy;
}


#### Exercises

– modify the program to calculate asian basket payoff
– modify the program to N stocks
– modify program to include interest rates and dividend yield

Posted in quant finance coding course

# Part 4

c++ finance course

# Monte-Carlo c++ – Path-dependent payoffs

### Objective

– price asian option with c++
– price lookback option

here we’ll show how to extend previous programs to price path dependent payoffs

#### Asian Option

lets consider following asian payoff: $payoff=(\frac{1}{T}\int_0^T S_t dt - K)^+$

1) instead of calculating the integral we’ll calculate average price of Stock S
2) to compute the average we’ll subdivide interval of time [0..T] in N parts each dt apart

0–dt–2td–3dt–…. T

we’ll have to simulate every path time step by time step
to go from previous time step to next one by black scholes dynamics (interest rates=0 for simplicity) $S_0=100$ $S_{dt}=S_0 exp( -0.5 \sigma^2 dt + \sigma \sqrt{dt} x )$ $S_{next}=S_{prev} exp( -0.5 \sigma^2 dt + \sigma \sqrt{dt} x )$

here comes the code for asian option:

#include <boost/random/variate_generator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>
#include <iostream>

double pp(double x) //positive part   x+
{
if(x>0) return x;
return 0;
}

void main()
{

boost::mt19937 mt;
boost::normal_distribution<> distribution;
boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>* normal(new boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>(mt,distribution));

int numberSimulations=1000;

double S0=100.0;
double sigma=0.2;
double T=1.0;
double K=100.0;
double sum=0;
double payoff=0;
double NT=100;
double dt=T/NT;

for(int iSim=0;iSim<numberSimulations;iSim++) //outer loop for simulations
{
double Sprev=S0;
double Snext=0;
double averageSum=0;

for(double t=0;t<=T;t+=dt) //inner loop for constructing one stock price path from time 0 to T
{
double x=(*normal)();
Snext=Sprev*std::exp(-0.5*sigma*sigma*dt+sigma*std::sqrt(dt)*x);
averageSum+=Snext;
Sprev=Snext;
//std::cout<<"\n"<<Snext; output to console of stock dynamics
}

payoff=pp(averageSum/NT-K);
sum+=payoff;
}

std::cout<<"\nCall="<<sum/numberSimulations<<std::endl;

int dummy;std::cin>>dummy;
}



in this example code we use a common construct for path-dependent payoffs :2 monte carlo loops
one for generating one path (inner loop) and another, outer loop for Monte carlo averaging of payoff

#### LookBack Option

in lookback option payoff strike is minimum of the stock price path over the period
so let’s change previous program to calculate lookback option $payoff=(S_T-\min_{0

#include <boost/random/variate_generator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>
#include <iostream>

double pp(double x) //positive part   x+
{
if(x>0) return x;
return 0;
}

void main()
{

boost::mt19937 mt;
boost::normal_distribution<> distribution;
boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>* normal(new boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>(mt,distribution));

int numberSimulations=1000;

double S0=100.0;
double sigma=0.2;
double T=1.0;
double K=100.0;
double sum=0;
double payoff=0;
double NT=100;
double dt=T/NT;

for(int iSim=0;iSim<numberSimulations;iSim++) //outer loop for simulations
{
double Sprev=S0;
double Snext=0;
double currentMin=S0; //set current minimum stock level to initial price

for(double t=0;t<=T;t+=dt) //inner loop for constructing one stock price from time 0 to T
{
double x=(*normal)();
Snext=Sprev*std::exp(-0.5*sigma*sigma*dt+sigma*std::sqrt(dt)*x);
if(Snext<currentMin) currentMin=Snext;
Sprev=Snext;
//std::cout<<"\n"<<Snext<<" MIN="<<currentMin;// output to console of stock dynamics
}

payoff=pp(Snext-currentMin);
sum+=payoff;
}

std::cout<<"\nLookBack Call="<<sum/numberSimulations<<std::endl;

int dummy;std::cin>>dummy;
}


#### Exercises

– introduce non-zero interest rates
– calculate lookback option where strike is maximum stock price over the period

Posted in quant finance coding course

# Part 3

c++ finance course

# Monte-Carlo c++

### Objective

– generate random numbers
– Calculate Call option with Monte – Carlo
– intro to std::vector

here we’ll see how to use containers in C++

in many books on c++ you’ll see that people use c++ arrays ( for example double x) for storing variables.It has quite many drawbacks for beginners , so here we’ll use std::vector to store real numbers.
std::vector is an object – it means you add dot “.” after the object name and you will see it has not only one value but many different “sub-variables” and “sub-functions”

### Gaussian random number generation

To implement Monte-Carlo engine in C++ we’ll need standard gaussian numbers.
C++ has a built-in random number generators , but they are no good for financial engineering (function random()).

One of the most used pseudo – random generators with good characteristics is Mersenne Twister algorithm
It’s implemented in Boost. After we have uniform random numbers we can generate Gaussian number with a function.It’s also implemented in Boost.
here’s the code to generate 100 standard gaussians:

#include <boost/random/variate_generator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>
#include <iostream>

void main()
{

boost::mt19937 mt; //create object of mersenne twister generator
boost::normal_distribution<> distribution; // create distribution object
boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>* normal(new boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>(mt,distribution)); //create variate generator which will generate gaussians

for (int i=0;i<100;i++)
std::cout<< (*normal)()<<std::endl; //  gaussian is retrieved with function   (*normal)()     asterisk * is because normal variable is a pointer

int dummy;std::cin>>dummy;
}



here we use a pointer to variable.
pointer is basically address of variable in memory.
to access variables by pointers one uses asterisk *

### Storage of data in std::vector

to store these numbers we can use class std::vector

here we’ll illustrate its common use:

#include <boost/random/variate_generator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>
#include <iostream>
#include <vector>

void main()
{

boost::mt19937 mt;
boost::normal_distribution<> distribution;
boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>* normal    (new boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>(mt,distribution));

std::vector<double> v;

for (int i=0;i<100;i++)
v.push_back( (*normal)() ) ;

for (int i=0;i<100;i++)
std::cout<<v[i]<<std::endl;

int dummy;std::cin>>dummy;
}



now lets make a function to calculate the mean of elements of vector

#include <boost/random/variate_generator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>
#include <iostream>
#include <vector>

double mean(std::vector<double>& v) //here we use &  to indicate that we pass value of variable to function by address and not by creating new variable and copying data into it
{
int N=v.size();
double sum=0;
for(int i=0;i<N;i++)
sum+=v[i];
return sum/N;

}

void main()
{

boost::mt19937 mt;
boost::normal_distribution<> distribution;
boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>* normal(new boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>(mt,distribution));

std::vector<double> v;

for (int i=0;i<100;i++)
v.push_back( (*normal)() ) ;

for (int i=0;i<100;i++)
std::cout<<v[i]<<std::endl;

std::cout<<"\nmean="<<mean(v);

int dummy;std::cin>>dummy;
}


here we’ve shown how to to pass vectors as function parameters
most useful vector expressions are:

std::vector<double> v;//create empty vector
std::vector<double> v(10);//create vector of 10 elements  first element is v
v=4;//set value of first vector element;
v.resize(100);//resize vector to have 100 elements;
v.size();//returns number of elements


if you want to make simple operations on vectors there are chances that these operations are already implemented in STL or in boost.
for example our previous program to compute mean of array could be rewritten using STL algorithms as following:

sum =std::accumulate(v.begin(),v.end(),0.0); //need to #include <numeric>


so before writing a function to do simple things on vector google first somthing among the lines “std::vector sum of elements”

#### Exercise

– change previous program to calculate variance of random numbers

as we have random numbers now we are ready to implement call option price

### Call option with monte carlo c++

suppose Black-Scholes dynamics with 0 interest rates, so $S_T=S_0 exp(-0.5 \sigma^2 T + \sigma \sqrt{T} x )$
where x is standard gaussian

Monte-Carlo Call price is just average of payoffs $(S_T(x)-K)^+$

#include <boost/random/variate_generator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>
#include <iostream>

double pp(double x) //positive part   x+
{
if(x>0) return x;
return 0;
}

void main()
{

boost::mt19937 mt;
boost::normal_distribution<> distribution;
boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>* normal(new boost::variate_generator<boost::mt19937&,boost::normal_distribution<>>(mt,distribution));

int numberSimulations=100000;

double S0=100.0;
double sigma=0.2;
double T=1.0;
double K=100.0;
double sum=0;
double payoff=0;

for(int iSim=0;iSim<numberSimulations;iSim++)
{
double x=(*normal)();
payoff=pp(S0*std::exp(-0.5*sigma*sigma*T+sigma*std::sqrt(T)*x)-K);
sum+=payoff;
}

std::cout<<"\nCall="<<sum/numberSimulations<<std::endl;

int dummy;std::cin>>dummy;
}



#### Exercises

– change program to include non-zero constant interest rate
– change program to calculate Put option price
– verify call put parity

Posted in quant finance coding course

## black scholes via numerical integration

finance c++ course

## objective

– calculate Call option in Black Scholes model using c++

C++ and QuantLib have many types of variables in quant finance most useful types are:

double – to store real number
int – to store integer number
QuantLib::Date – to store dates
QuantLib::Array – to store array of double
QuantLib::Matrix – to store 2d matrix of doubles

lets start by doing some numerical integration

delete all the contents of source.cpp file and copy paste following code

## Example – numerical integration

this code will calculate integral $\int_{0}^{1}e^xdx$

#include <iostream>
#include <cmath> //for using math functions

//everything after // is a comment

double f(double x) //declaration of function f(x)=exp(x)
{
return std::exp(x);
}

void main()
{

double dt=0.0001; //integration step
double sum=0; //current value of integral
for(double t=0;t<1.0;t+=dt) //for loop    t+=dt means t=t+dt
{
sum+=f(t)*dt; // its equivalent to write sum=sum+f(t)*dt;
}
std::cout<<"integral "<< sum; //output

int dummy;std::cin>>dummy;//screen delay
}


important notes:
use 1.0 instead of just 1
in c++ 1.0 and 1 are different numbers 1.0 is real number and 1 is integer number
it means that 1/2=0 while 1.0/2 is 0.5

when doing comparisons of doubles don’t use if(x==0)
use if( std::abs(x)for loop
see “variables scope” here http://www.cplusplus.com/doc/tutorial/variables/

here we used simplest form of numerical integration
for a faster/ more precise integratoin you can use other methods
many of them are described in free book “numerical recipes in c”
this book is for C but the code structure would be the same

## example – call option in Black Scholes model using integration

now lets change previous program to calculate Call option in Black Scholes model with zero interest rates

risk-neutral dynamics: $dS=S*\sigma dWt$
so $S_T=S_0 exp(-0.5 \sigma^2+\sigma \sqrt T x )$
where x is a standard gaussian
so the call option price will be $Call=\int_{-\infty}^{+\infty} (S_0 e^{-0.5 \sigma^2+\sigma \sqrt T x} - K)^+ \phi(x) dx$
where $\phi(x)=\frac{1}{\sqrt{2\pi}}exp(-0.5 x^2)$ standard gaussian density
S0=100
volatility=20%
maturity=T=1 year

#include <iostream>
#include <cmath>
#include <boost/math/constants/constants.hpp>

double density(double x) //normal density
{
const double pi = boost::math::constants::pi<double>();
return 1.0/sqrt(2.0*pi)*std::exp(-0.5*x*x);
}

double pp(double x) //positive part   x+
{
if(x>0) return x;
return 0;
}

double f(double K,double S0,double T,double sigma,double x) //function to integrate
{
return pp(S0*std::exp(-0.5*sigma*sigma*T+sigma*std::sqrt(T)*x)-K)*density(x);
}

void main()
{
double S0=100.0;
double sigma=0.2;
double T=1.0;
double K=80.0;
double dx=0.0001;
double sum=0;

for(double x=-10.0;x<10.0;x+=dx)
{
sum+=f(K,S0,T,sigma,x)*dx;
}
std::cout<<"call= "<< sum;

int dummy;std::cin>>dummy;
}


Notes:

we have to pass arguments again to the integrated function because their original scope is inside main() , so variables K, S0 etc are not visible inside function f(x)
we use boost here to extract Pi constant , so it will be easier to port this program to linux for example (standard c++ has no math constants)

### exercises

– debug first program by setting break points and watch variables sum and t change value
– change first program to integrate via trapezoidal rule , check the results against known answer $e^1-1$
– change second program to include non zero interest rates
– change second program to calculate put price
– verify call put parity

### some tricks

if you’ve got an error always start by correcting first compile error (double click on compile error line)
some c++ error messages are quite cryptic and are results of previous errors

for example remove “;” after return statement
press F7 to compile
now double-click on first error:

Posted in quant finance coding course

## C++ finance course for beginners – part 1 – hello world

REQUIREMENTS:
– microsoft visual studio express 2012 (it’s free,older versions are similar. there are slight differences between microsoft and linux c++)
– some programming experience in another language

### Course objectives:

-price various derivatives using c++ code
-use basic quantlib and boost functions useful in financial engineering

### C++ ,Boost and Quantlib install

#### 2) install boost

– unpack it into drive C:
[so its unpacked into c:\boost_1_53_0 ]

– go to the dir c:\boost_1_53_0 and run bootstrap.bat
– run b2.exe
it will take few hours to build!

– go to dir c:\boost_1_53_0\stage
move whole dir “lib” to c:\boost_1_53_0\ so all built libraries are inside c:\boost_1_53_0\lib

#### 3) install quantlib

http://sourceforge.net/projects/quantlib/files/

unpack it to C:\

– open visual studio express for desktop

File->Open project -> QuantLib_vc10.sln

Choose “update” in the next dialog . it will convert files to visual studio 2012 format

in the solution explorer window select QuantLib

change “include directories” variable to include path to boost
change “library directories” variable to include path to boost\lib

now delete all projects except QuantLib from the solution (click on every project in solution explorer and press “del”)

press F7 to build quantlib [or menu->build->build solution]

## Hello world program

choose Visual C++ -> Win32 Console Application

press OK->NEXT (do NOT press FINISH yet)

check “Empty Project”
uncheck “Security…” box

click Finish

right Click on ConsoleApplication1 anc change include and library directory to include QuantLib and boost directories:

in the window copy paste following code:

#include <ql/quantlib.hpp>
#include <iostream>

using namespace QuantLib;

void main()
{

Date date1(30,January,2013);
Date date2;
date2=date1+1*Years;

std::cout<<date2;

int dummy;std::cin>>dummy;
}


press F7 to compile

double click on error :

and change the following line :

#  error "unknown Microsoft compiler"


by

#  define QL_LIB_TOOLSET "vc100"


so it looks like that:

press F7 to build project and F5 to run

quick explanation of the code:

#include <ql/quantlib.hpp>
#include <iostream>


these lines just insert files named quantlib.hpp and iostream into your source file
quantlib.hpp is needed to have quantlib functions and definitions (Date object)
and iostream is used to write to output console

using namespace QuantLib;


without this line you’d had to write “QuantLib::” before every quantlib object

void main()
{

Date date1(30,January,2013);
Date date2;
date2=date1+1*Years;

std::cout<<date2;

int dummy;std::cin>>dummy;
}


these lines define main function
in c++ when console program starts it automatically start executing the function main()

	Date date1(30,January,2013);
Date date2;


here we define two QuantLib objects(variables) date1 and date2 and assign a value for the first variable

date2=date1+1*Years;
std::cout<<date2;


here we assign value for date2 to be 1 year from date1

and std::cout part prints the result to console

int dummy;std::cin>>dummy;


this is needed to pause the screen

### debugging C++ program

to debug program left click where the red dot appears and press F5

the program will start debug and you can hover cursor over the variable to see it's value

as you can see date1 will show some long number instead of date .It's because internally quantlib uses Excel format for dates .
press F10 to execute instructions one by one of F5 again to continue program until next break point

Posted in quant finance coding course

## FX forward valuation excel

Here we’ll show how to value FX forwards (Foreign eXchange) on EURUSD exchange rate in excel with quantlib excel addin

in this example we’ll need following market data:

• EURUSD spot
• EURUSD forward points (can get from bloomberg or reuters)
• EUR discount curve (for example EUR 6m curve)
• In this spreadsheet we first construct syntetic USD yield curve based on EURUSD forward points, so after we could use usual formulas for FX forward valuation

FX forward valuation excel:

Posted in OTC derivatives valuation

## Amortizing interest rate swap valuation excel example

Amortizing interest rate swap valuation excel with 2 curves example:

for online amortizing interest rate swap valuation with credit valuation adjustment see Online Amortizing Interest rate swap valuation with CVA and OIS discounting
for quantlib python version see Amortizing Interest rate swap valuation with python quantlib

In this example we value amortizing swap with 2 flat curves : discount curve and forwarding curve.
You can get curves in this format on Bloomberg or Reuters terminals.
to get real value of swap paste curves for your valuation date and adjust arguments in formulas.
set appropriate daycount conventions (usually actual/360 or 30/360) and calendars (usually TARGET in European contracts) from termsheet.

2) open file at QuantLibXL\xll\QuantLibXL-vc90-mt-s-1_2_0.xll
3) open spreadsheet ctrl-alt-f9 to recalculate all

for quantlib c++ valuation see https://www.pricederivatives.com/en/how-to-value-swap-with-2-curves-with-quantlib-quantlib-swap-example/

Posted in OTC derivatives valuation, quantlib Tagged with: , ,

## Simple Derivatives CVA Calculation Example (credit valuation adjustment) excel

Here we show simplest method called current net exposure

for more elaborated Monte-Carlo method using python see CVA with monte carlo calculation

for online interest rate swaps and OTC derivatives valuation with CVA see Derivatives accounting calculators

## derivatives CVA calculation example:

lets say we have derivatives portfolio with the same counterparty which consist of 2 amortizing swaps
one approximate method for would be to calculate Net exposure at valuation time

lets say swap1 worth today 2M$swap2 worth -1M$

if there’s a netting agreement then total today’s exposure is (1-R)*(2M-1M) = (1-R)*1M $R is recovery normally supposed to be at 40% then CVA would be price to hedge this exposure with CDS (fixed leg of CDS) lets say counterparty Credit Defualt Swap spread is flat 300 pb (3%) then the cost of this hedge would be approximately CVA=3% * (maturity in years) * (1-R) *1M$

if we want to improve the quality of this approximation we could take average exposure of swaps until maturity (at maturity exposure to swap is 0) which equals exposure today /2

so final formula would be

CVA=0.5*3% * (maturity in years) * (1-R) *1M \$

in case that two swaps have different maturity then we would have to weight the exposure by maturity factor of each instrument

if total exposure is negative with this method CVA=0 and we would have to take own CDS spread to calculate DVA (debit valuation adjustment)

example cva calculation in Excel (you can edit cells)

FAS 157 require derivatives CVA to be calculated for fair value of derivatives, as well as basel 3 for banks

# Derivatives CVA calculation example excel

to calculate value of annuity properly we can use quantlib addin from http://quantlib.org/quantlibxl/

2) open file at QuantLibXL\xll\QuantLibXL-vc90-mt-s-1_2_0.xll
3) open spreadsheet ctrl-alt-f9 to recalculate all

Here we calculate simplified derivatives CVA/DVA for a portfolio of 3 OTC derivatives with the same counterparty
if net current exposure is negative then we’ll have only DVA and we’ll use institution’s own CDS spread, else we’ll have only CVA and we’ll need to apply counterparty CDS spreads (both found on bloomberg or reuters terminals).

In this example we use sample flat curve for discounting. For proper use we’ll need to paste real curve for desired valuation date (also found on bloomberg or reuters)
the standard recovery of 40% is used.

to calculate annuity we’ll calculate swap value with 0 floating leg using quantlib addin functions for swap. 