88import java .util .List ;
99import java .util .Map ;
1010import java .util .function .BooleanSupplier ;
11+ import java .util .function .DoubleConsumer ;
1112import java .util .function .DoubleUnaryOperator ;
1213import java .util .function .Function ;
1314import java .util .stream .Collectors ;
1415
1516import net .finmath .climateschool .utilities .ModelFactory ;
1617import net .finmath .climateschool .utilities .RandomOperators ;
18+ import net .finmath .experiments .ui .parameter .BooleanParameter ;
1719import net .finmath .experiments .ui .parameter .DoubleParameter ;
1820import net .finmath .montecarlo .interestrate .TermStructureMonteCarloSimulationModel ;
1921import net .finmath .plots .DoubleToRandomVariableFunction ;
@@ -39,7 +41,9 @@ public class HestonModelGreeksAnalytic extends ExperimentUI {
3941 private final DecimalFormat numberDigit2 = new DecimalFormat ("#.00" );
4042 private final DecimalFormat numberPercent1 = new DecimalFormat ("#.0%" );
4143
42- Plot2D plot = null ;
44+ Plot2D plotDelta = null ;
45+ Plot2D plotGamma = null ;
46+ Plot2D plotVega = null ;
4347
4448 final static String RISK_FREE_RATE = "Risk Free Rate" ;
4549 final static String DIVIDEND_YIELD = "Dividend Yield" ;
@@ -61,13 +65,16 @@ public HestonModelGreeksAnalytic() {
6165 new DoubleParameter (V0 , 0.0423 , 0.0001 , 2.0 ),
6266 new DoubleParameter (RHO , -0.4 , -1.0 , 1.0 ),
6367 new DoubleParameter (OPTION_MATURIY , 0.2 , 0.01 , 5.0 ),
64- new DoubleParameter (OPTION_STRIKE , 50 , 90 , 250 )
68+ new DoubleParameter (OPTION_STRIKE , 50 , 90 , 250 ),
69+ new BooleanParameter ("Show Delta" , true ),
70+ new BooleanParameter ("Show Gamma" , false ),
71+ new BooleanParameter ("Show Vega" , false )
6572 ));
6673 }
6774
6875 public String getTitle () { return "Heston Model - Greeks (Analytic)" ; }
6976
70- public void runCalculation (BooleanSupplier isCancelled ) {
77+ public void runCalculation (BooleanSupplier isCancelled , DoubleConsumer progress ) {
7178 Map <String , Object > currentParameterSet = getExperimentParameters ().stream ().collect (Collectors .toMap (p -> p .getBindableValue ().getName (), p -> p .getBindableValue ().getValue ()));
7279
7380 System .out .println ("Calculation with Parameters: " + currentParameterSet );
@@ -82,6 +89,15 @@ public void runCalculation(BooleanSupplier isCancelled) {
8289 final double optionMaturity = (Double )currentParameterSet .get (OPTION_MATURIY );
8390 final double optionStrike = (Double )currentParameterSet .get (OPTION_STRIKE );
8491
92+ String titleSpec = "r=" +numberPercent1 .format (riskFreeRate ) + ", q=" +numberPercent1 .format (dividendYield ) +
93+ ", 𝜅=" + numberDigit2 .format (kappa ) +
94+ ", 𝜃=" + numberDigit2 .format (theta ) +
95+ ", 𝜎=" + numberDigit2 .format (sigma ) +
96+ ", v₀=" + numberDigit2 .format (v0 ) +
97+ ", 𝜌=" + numberDigit2 .format (rho ) +
98+ ", T=" + numberDigit2 .format (optionMaturity ) +
99+ ", K=" + numberDigit2 .format (optionStrike );
100+
85101 DoubleUnaryOperator deltaFun = (stock ) -> HestonModel .hestonOptionDelta (
86102 stock ,
87103 riskFreeRate ,
@@ -94,60 +110,133 @@ public void runCalculation(BooleanSupplier isCancelled) {
94110 optionMaturity ,
95111 optionStrike );
96112
97- DoubleUnaryOperator deltaFunBS = (stock ) -> {
98- return AnalyticFormulas .blackScholesOptionDelta (
113+ DoubleUnaryOperator gammaFun = (stock ) -> HestonModel .hestonOptionGamma (
99114 stock ,
100- riskFreeRate -dividendYield ,
101- Math .sqrt (v0 ),
115+ riskFreeRate ,
116+ dividendYield ,
117+ kappa ,
118+ theta ,
119+ sigma ,
120+ v0 ,
121+ rho ,
102122 optionMaturity ,
103- optionStrike ) * Math . exp (- dividendYield * optionMaturity ); } ;
123+ optionStrike );
104124
105- List <Plotable2D > plotables = List .of (
106- new PlotableFunction2D (0 , 300 , 200 , new Named <DoubleUnaryOperator >("Heston" , deltaFun ), new GraphStyle (null , new BasicStroke (), Color .blue )),
107- new PlotableFunction2D (0 , 300 , 200 , new Named <DoubleUnaryOperator >("Black Scholes" , deltaFunBS ), new GraphStyle (null , new BasicStroke (), Color .RED ))
108- );
125+ DoubleUnaryOperator vegaFun = (stock ) -> HestonModel .hestonOptionVega1 (
126+ stock ,
127+ riskFreeRate ,
128+ dividendYield ,
129+ kappa ,
130+ theta ,
131+ sigma ,
132+ v0 ,
133+ rho ,
134+ optionMaturity ,
135+ optionStrike );
109136
110- String titleSpec = "r=" +numberPercent1 .format (riskFreeRate ) + ", q=" +numberPercent1 .format (dividendYield ) +
111- ", 𝜅=" + numberDigit2 .format (kappa ) +
112- ", 𝜃=" + numberDigit2 .format (theta ) +
113- ", 𝜎=" + numberDigit2 .format (sigma ) +
114- ", v₀=" + numberDigit2 .format (v0 ) +
115- ", 𝜌=" + numberDigit2 .format (rho ) +
116- ", T=" + numberDigit2 .format (optionMaturity ) +
117- ", K=" + numberDigit2 .format (optionStrike );
137+ DoubleUnaryOperator deltaFunBS = (stock ) -> { return AnalyticFormulas .blackScholesOptionDelta (
138+ stock ,
139+ riskFreeRate -dividendYield ,
140+ Math .sqrt (v0 ),
141+ optionMaturity ,
142+ optionStrike ) * Math .exp (-dividendYield * optionMaturity );
143+ };
118144
119- String nameOfGreek = "Delta" ;
145+ DoubleUnaryOperator gammaFunBS = (stock ) -> { return AnalyticFormulas .blackScholesOptionGamma (
146+ stock ,
147+ riskFreeRate -dividendYield ,
148+ Math .sqrt (v0 ),
149+ optionMaturity ,
150+ optionStrike ) * Math .exp (-dividendYield * optionMaturity );
151+ };
152+
153+ DoubleUnaryOperator vegaFunBS = (stock ) -> { return AnalyticFormulas .blackScholesOptionVega (
154+ stock ,
155+ riskFreeRate -dividendYield ,
156+ Math .sqrt (v0 ),
157+ optionMaturity ,
158+ optionStrike ) * Math .exp (-dividendYield * optionMaturity );
159+ };
120160
121161 synchronized (this ) {
122162 if (!Thread .currentThread ().isInterrupted () && !isCancelled .getAsBoolean ()) {
123- if (plot == null ) {
124- try {
125- plot = new Plot2D (plotables );
126- plot .setTitle ("Heston vs Black Scholes Option " + nameOfGreek + "\n (" + titleSpec + ")" ).setXAxisLabel ("Spot" ).setYAxisLabel (nameOfGreek );
127- plot .setIsLegendVisible (true );
128- // plot.setYRange(-0.02, 0.10);
129- plot .show ();
163+ if ((Boolean )currentParameterSet .get ("Show Delta" ))
164+ plotDelta = plot (plotDelta , "Delta" , titleSpec , deltaFunBS , deltaFun );
165+ else {
166+ if (plotDelta != null ) {
167+ plotDelta .close ();
168+ plotDelta = null ;
130169 }
131- catch (Exception e ) {
132- e .printStackTrace ();
170+ }
171+ }
172+ if (!Thread .currentThread ().isInterrupted () && !isCancelled .getAsBoolean ()) {
173+ if ((Boolean )currentParameterSet .get ("Show Gamma" ))
174+ plotGamma = plot (plotGamma , "Gamma" , titleSpec , gammaFunBS , gammaFun );
175+ else {
176+ if (plotGamma != null ) {
177+ plotGamma .close ();
178+ plotGamma = null ;
133179 }
180+
134181 }
182+ }
183+ if (!Thread .currentThread ().isInterrupted () && !isCancelled .getAsBoolean ()) {
184+ if ((Boolean )currentParameterSet .get ("Show Vega" ))
185+ plotVega = plot (plotVega , "Vega" , titleSpec , vegaFunBS , vegaFun );
135186 else {
136- plot .setTitle ("Heston vs Black Scholes Option " + nameOfGreek + "\n (" + titleSpec + ")" ).setXAxisLabel ("Spot" ).setYAxisLabel (nameOfGreek );
137- plot .update (plotables );
187+ if (plotVega != null ) {
188+ plotVega .close ();
189+ plotVega = null ;
190+ }
138191 }
139192 }
140193 }
194+
195+ progress .accept (1.0 );
196+ }
197+
198+ private Plot2D plot (Plot2D plot , String nameOfGreek , String titleSpec , DoubleUnaryOperator greekBlackScholes , DoubleUnaryOperator greekHeston ) {
199+ List <Plotable2D > plotables = List .of (
200+ new PlotableFunction2D (0 , 300 , 200 , new Named <DoubleUnaryOperator >("Heston" , greekHeston ), new GraphStyle (null , new BasicStroke (), Color .blue )),
201+ new PlotableFunction2D (0 , 300 , 200 , new Named <DoubleUnaryOperator >("Black Scholes" , greekBlackScholes ), new GraphStyle (null , new BasicStroke (), Color .RED ))
202+ );
203+
204+ if (plot == null ) {
205+ try {
206+ plot = new Plot2D (plotables );
207+ plot .setTitle ("Heston vs Black Scholes Option " + nameOfGreek + "\n (" + titleSpec + ")" ).setXAxisLabel ("Spot" ).setYAxisLabel (nameOfGreek );
208+ plot .setIsLegendVisible (true );
209+ // plot.setYRange(-0.02, 0.10);
210+ plot .show ();
211+ }
212+ catch (Exception e ) {
213+ e .printStackTrace ();
214+ }
215+ }
216+ else {
217+ plot .setTitle ("Heston vs Black Scholes Option " + nameOfGreek + "\n (" + titleSpec + ")" ).setXAxisLabel ("Spot" ).setYAxisLabel (nameOfGreek );
218+ plot .update (plotables );
219+ }
220+
221+ return plot ;
141222 }
142223
143224 @ Override
144225 protected void onClose () {
145226 synchronized (this ) {
146227 super .onClose ();
147228 System .out .println ("Closing plot" );
148- if (plot != null ) {
149- plot .close ();
150- plot = null ;
229+ if (plotDelta != null ) {
230+ plotDelta .close ();
231+ plotDelta = null ;
232+ }
233+ if (plotGamma != null ) {
234+ plotGamma .close ();
235+ plotGamma = null ;
236+ }
237+ if (plotVega != null ) {
238+ plotVega .close ();
239+ plotVega = null ;
151240 }
152241 }
153242 }
0 commit comments