sábado, 17 de abril de 2021

Calculadora de opciones en JavaScript

Veamos cómo programar una calculadora en Java Script para obtener el precio teórico de la prima de una opción financiera europea.

Esta entrada forma parte de una serie de post publicados.

  1. Calculadora sencilla en JavaScript
  2. Calculadora de opciones en JavaScript

Continuaremos desde donde lo dejamos y realizaremos los siguientes pasos.

Paso 1

Vamos a nuestro Visual Studio Code (VSC) y duplicamos el archivo index.html. Para ello, situamos el cursor sobre el nombre de archivo, en el panel de la izquierda y pulsamos Control+C para copiar. Luego, pulsamos Control+V para pegar la copia. Esto genera un nuevo archivo denominado index copy.html.

Renombramos el archivo index copy.html con el nombre sumados.html. Para renombrar lo que hacemos es pulsar con el botón derecho del ratón sobre el nombre de archivo y en el menú contextual que se obtiene elegimos rename.

Volvemos a duplicar el archivo index.html y renombramos la copia como valorOpcion.html.


Paso 2

Editamos el archivo index.html de forma que ahora quedará así.

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="./style.css">
  <title>Calculadoras</title>
</head>
<body>
  <h1>Calculadoras en JavaScript</h1>
  <ul>
    <li><a href="./sumados.html">Sumar dos números</a></li>
    <li><a href="./valorOpcion.html">Valoración de opciones por Black-Scholes</a></li>
  <ul>
</body>
</html>


Paso 3

Editamos el archivo style.css que ahora quedará así.

 body {  
   background-color: LightCyan;  
  }  
 #resultH2{  
   color: blue;  
 }  
 .main{  
  width: 600px;  
  display: flex;  
  justify-content: space-between;  
  margin: 10px 0px 10px 0px;  
 }  
 input {   
  text-align: right;   
 }  

Paso 4

Editamos el archivo valorOpcion.html que quedará así.
 <!DOCTYPE html>  
 <html lang="es">  
 <head>  
   <meta charset="UTF-8">  
   <link rel="stylesheet" href="./style.css">  
   <script src="./blackscholes.js"></script>  
   <title>Black-Scholes</title>  
 </head>  
 <body>  
   <h1>Black-Scholes</h1>  
   <p>Valor de una opción CALL europea por el método de Black-Scholes.</p>  
   <h2>Variables de entrada</h2>  
   <ul>  
     <li class="main">Precio Spot del activo subyacente: S <input type="number" value="100" id="S"></li>  
     <li class="main">Precio de ejercicio (Strike): E <input type="number" value="110" id="E"></li>  
     <li class="main">Volatilidad (en tanto por uno): &sigma; <input type="number" value="0.2" id="sigma"> </li>  
     <li class="main">Rentabilidad libre de riesgo:<br></li>  
     <li class="main"><p style="margin: 0px;">Tanto efectivo anual en tanto por uno: <i>i</i></p> <input type="number" value="0.07" id="tanto"></li>  
     <li class="main">Duración hasta vencimiento en años: T <input type="number" value="2" id="T"> </li>  
   </ul>  
   <p>Pulse el botón para obtener el precio teórico de un CALL europeo.</p>  
   <input type="button" value="CALL por Black-Scholes" onclick="CALLeuropea()">  
   <h2 id="resultH2">Resultado</h2>  
   <p id="total"></p>  
 </body>  
 </html>  

Paso 5

Creamos el archivo blackscholes.js. La función de la distribución  Normal acumulada programada en JavaScript se puede ver en una respuesta de Stackoverflow.

En JS no es tan sencillo obtener la distribución Normal acumulada como en otros lenguajes más orientados a los cálculos científicos o a manejar datos, por ejemplo:
  • Python 
    • from statistics import NormalDist
    • NormalDist(mu=100, sigma=10).cdf(100)
  • R
    • print(pnorm(q = 110, mean = 100, sd = 10))
  • Excel
    • =NORM.DIST(110,100,10,TRUE)
En todos los ejemplos obtenemos el mismo valor de la normal acumulada: 0.8413447460685429.
 function Normal(z) {  
   var j, k, kMax, m, values, total, subtotal, item, z2, z4, a, b;  
   if (z < -6) { return 0; }  
   if (z > 6) { return 1; }  
   m   = 1;  
   b   = z;  
   z2   = z * z;  
   z4   = z2 * z2;  
   values = [];  
   for (k=0; k<100; k+=2) {  
     a = 2*k + 1;  
     item = b / (a*m);  
     item *= (1 - (a*z2)/((a+1)*(a+2)));  
     values.push(item);  
     m *= (4*(k+1)*(k+2));  
     b *= z4;  
   }  
   total = 0;  
   for (k=49; k>=0; k--) {  
     total += values[k];  
   }  
   return 0.5 + 0.3989422804014327 * total;  
 }  
 function CALLeuropea(){  
   let S=parseFloat(document.getElementById("S").value);  
   let E=parseFloat(document.getElementById("E").value);  
   let sigma=parseFloat(document.getElementById("sigma").value);  
   let tanto=parseFloat(document.getElementById("tanto").value);  
   let T=parseFloat(document.getElementById("T").value);  
   let myTotal=document.getElementById("total");  
   //Primero convertimos el tanto efectivo anual en un tanto instantáneo  
   let r= Math.log(1+tanto); //log es el neperiano  
   console.log("r=",r)  
   //Calculamos d1, d2, y la prima  
   let d1 = (Math.log(S/E)+(r+sigma**2/2)*T)/(sigma*Math.sqrt(T));  
   let d2 = (Math.log(S/E)+(r-sigma**2/2)*T)/(sigma*Math.sqrt(T));  
   let primaCALL=S*Normal(d1)-E*Math.E**(-r*T)*Normal(d2);  
   myTotal.innerText="La prima estimada del CALL es: "+ primaCALL;  
 }  
El código para obtener el valor de la opción CALL europera por el método de Black-Scholes está basado en el post siguiente.


Paso 6

Podemos ver el resultado en nuestro Localhost.



Paso 7

Subimos los cambios a GitHub.

Paso 8

Paso 9

Podemos ver el código en el repositorio de GitHub:










tamaño de fuente: 24px;

No hay comentarios:

Publicar un comentario