Расчет формулы Black-Scholes

Опубликовано в QLua

Для коллекции: расчет формулы Блэка-Шоулза на нескольких языках.

Умолчания:

  • S = Stock price
  • X = Strike price
  • T = Years to maturity
  • R = Risk-free rate
  • = Volatility

 

Lua

function cnd(x)

-- taylor series coefficients
   local a1, a2, a3, a4, a5 = 0.31938153, -0.356563782, 1.781477937,-1.821255978, 1.330274429
   local l = math.abs(x)
   local k = 1.0 / (1.0 + 0.2316419 * l)
   local w = 1.0 - 1.0 / math.sqrt(2 * math.pi) * math.exp(-l * l / 2) * (a1 * k + a2 * k * k + a3 * math.pow(k, 3) + a4 * math.pow(k, 4) + a5 * math.pow(k, 5))
   if x < 0 then w = 1.0 - w end
   return w
end

-- The Black-Scholes option valuation function
-- is_call: true for call, false for put
-- s: current price
-- x: strike price
-- t: time
-- r: interest rate
-- v: volatility
function black_scholes(is_call, s, x, t, r, v)
   local d1 = (math.log(s / x) + (r + v * v / 2.0) * t) / (v * math.sqrt(t))
   local d2 = d1 - v * math.sqrt(t)
   if is_call then
      return s * cnd(d1) - x * math.exp(-r * t) * cnd(d2)
   else
      return x * math.exp(-r * t) * cnd(-d2) - s * cnd(-d1)
   end
end

C++

С++

#ifndef Pi 
#define Pi 3.141592653589793238462643 
#endif 

double BlackScholes(char CallPutFlag, double S, double X, double T, double r,double v)
{
   double d1, d2;
   d1=(log(S/X)+(r+v*v/2)*T)/(v*sqrt(T));
   d2=d1-v*sqrt(T);

   if(CallPutFlag == 'c')
      return S *CND(d1)-X * exp(-r*T)*CND(d2);
   else if(CallPutFlag == 'p')
      return X * exp(-r * T) * CND(-d2) - S * CND(-d1);
}

double CND( double X )
{
   double L, K, w ;
   double const a1 = 0.31938153, a2 = -0.356563782, a3 = 1.781477937;
   double const a4 = -1.821255978, a5 = 1.330274429;
   L = fabs(X);
   K = 1.0 / (1.0 + 0.2316419 * L);
   w = 1.0 - 1.0 / sqrt(2 * Pi) * exp(-L *L / 2) * (a1 * K + a2 * K *K + a3 * pow(K,3) + a4 * pow(K,4) + a5 * pow(K,5));
   if (X < 0)
      w= 1.0 - w;
   return w;
}

 

JAVASCRIPT

function BlackScholes(PutCallFlag, S, X, T, r, v) {

var d1, d2;
d1 = (Math.log(S / X) + (r + v * v / 2.0) * T) / (v * Math.sqrt(T));
d2 = d1 - v * Math.sqrt(T);


if (PutCallFlag== "c")
return S * CND(d1)-X * Math.exp(-r * T) * CND(d2);
else
return X * Math.exp(-r * T) * CND(-d2) - S * CND(-d1);

}

/* The cummulative Normal distribution function: */

function CND(x){

var a1, a2, a3, a4 ,a5, k ;

a1 = 0.31938153, a2 =-0.356563782, a3 = 1.781477937, a4= -1.821255978 , a5= 1.330274429;

if(x<0.0)
return 1-CND(-x);
else
k = 1.0 / (1.0 + 0.2316419 * x);
return 1.0 - Math.exp(-x * x / 2.0)/ Math.sqrt(2*Math.PI) * k
* (a1 + k * (-0.356563782 + k * (1.781477937 + k * (-1.821255978 + k * 1.330274429)))) ;

}

 

PHP

function CND ($x) {

$Pi = 3.141592653589793238;
$a1 = 0.319381530;
$a2 = -0.356563782;
$a3 = 1.781477937;
$a4 = -1.821255978;
$a5 = 1.330274429;
$L = abs($x);
$k = 1 / ( 1 + 0.2316419 * $L);
$p = 1 - 1 / pow(2 * $Pi, 0.5) * exp( -pow($L, 2) / 2 ) * ($a1 * $k + $a2 * pow($k, 2) + $a3 * pow($k, 3) + $a4 * pow($k, 4) + $a5 * pow($k, 5) );
if ($x >= 0) { 
  return $p;
} else {
  return 1-$p;
}
}
function BlackScholes ($call_put_flag, $S, $X, $T, $r, $v) 
{
$d1 = ( log($S / $X) + ($r + pow($v, 2) / 2) * $T ) / ( $v * pow($T, 0.5) );
$d2 = $d1 - $v * pow($T, 0.5);
if ($call_put_flag == 'c') {
  return $S * CND($d1) - $X * exp( -$r * $T ) * CND($d2);
} else { 
  return $X * exp( -$r * $T ) * CND(-$d2) - $S * CND(-$d1);
}}

 

AUTOIT

;BlackScholes stock option function

Func _BlackScholes()
  Local $CallPutFlag, $S, $w, $T, $r, $v,$d1 = (Log($S / $w) + ($r + $v ^ 2 / 2) * $T) / ($v * Sqrt($T)), $d2 = $d1 - $v * Sqrt($T)
  If $CallPutFlag = "c" Then
     Local $callval = ($S * _CND($d1) - $w * Exp(-$r * $T) * _CND($d2))
  ElseIf $CallPutFlag = "p" Then
     Local $putval = ($w * Exp(-$r * $T) * _CND(-$d2) - $S * _CND(-$d1))
  EndIf
EndFunc ;==>_BlackScholes

;The cumulative normal distribution function
Func _CND($w)
   Const $a1 = 0.31938153, $a2 = -0.356563782, $a3 = 1.781477937, $a4 = -1.821255978, $a5 = 1.330274429, $Pi = 3.14159265
   $w1 = $w
   $L = Abs($w)
   $K = 1 / (1 + 0.2316419 * $L)
   $w = 1 - 1 / Sqrt(2 * $Pi) * Exp(-$L * $L / 2) * ($a1 * $K + $a2 * $K ^ 2 + $a3 * $K ^ 3 + $a4 * $K ^ 4 + $a5 * $K ^ 5)

   If $w1 < 0 Then
      $w = 1 - $w
   EndIf
   Return $w

EndFunc

VISUAL BASIC

Public Function BlackScholes(CallPutFlag As String, S As Double, X As Double, T As Double, r As Double, v As Double) As Double

Dim d1 As Double, d2 As Double

d1 = (Log(S / X) + (r + v ^ 2 / 2) * T) / (v * Sqr(T))
d2 = d1 - v * Sqr(T)
If CallPutFlag = "c" Then
   BlackScholes = S * CND(d1) - X * Exp(-r * T) * CND(d2)
ElseIf CallPutFlag = "p" Then
   BlackScholes = X * Exp(-r * T) * CND(-d2) - S * CND(-d1)
End If
End Function

'// The cumulative normal distribution function
Public Function CND(X As Double) As Double

Dim L As Double, K As Double
Const a1 = 0.31938153: Const a2 = -0.356563782: Const a3 = 1.781477937:
Const a4 = -1.821255978: Const a5 = 1.330274429

L = Abs(X)
K = 1 / (1 + 0.2316419 * L)
CND = 1 - 1 / Sqr(2 * Application.Pi()) * Exp(-L ^ 2 / 2) * (a1 * K + a2 * K ^ 2 + a3 * K ^ 3 + a4 * K ^ 4 + a5 * K ^ 5)

If X < 0 Then
CND = 1 - CND
End If
End Function

MATLAB

function BlackScholes(CP,S,X,T,r,v)

d1=(log(S/X)+(r+v^2/2)*T)/(v*sqrt(T));
d2=d1-v*sqrt(T);
if CP=='c' 
   S*normcdf(d1)-X*exp(-r*T)*normcdf(d2) 
else 
   X*exp(-r*T)*normcdf(-d2)-S*normcdf(-d1)
end

 


C#

using System;


namespace BlackScholes
{
/// <summary>
/// Summary description for BlackSholes.
/// </summary>
public class BlackSholes
{
public BlackSholes()
{
//
// TODO: Add constructor logic here
//
}
/* The Black and Scholes (1973) Stock option formula
* C# Implementation
* uses the C# Math.PI field rather than a constant as in the C++ implementaion
* the value of Pi is 3.14159265358979323846
*/
public double BlackScholes(string CallPutFlag, double S, double X, 
double T, double r, double v)
{
double d1 = 0.0;
double d2 = 0.0;
double dBlackScholes = 0.0;

d1 = (Math.Log(S / X) + (r + v * v / 2.0) * T) / (v * Math.Sqrt(T));
d2 = d1 - v * Math.Sqrt(T);
if (CallPutFlag == "c")

   dBlackScholes = S * CND(d1) - X * Math.Exp(-r * T) * CND(d2);
}
else if (CallPutFlag == "p") 
{
   dBlackScholes = X * Math.Exp(-r * T) * CND(-d2) - S * CND(-d1); 
}
return dBlackScholes;
}
public double CND(double X)
{
double L = 0.0;
double K = 0.0;
double dCND = 0.0;
const double a1 = 0.31938153; 
const double a2 = -0.356563782; 
const double a3 = 1.781477937;
const double a4 = -1.821255978;
const double a5 = 1.330274429;
L = Math.Abs(X);
K = 1.0 / (1.0 + 0.2316419 * L);
dCND = 1.0 - 1.0 / Math.Sqrt(2 * Convert.ToDouble(Math.PI.ToString())) * Math.Exp(-L * L / 2.0) * (a1 * K + a2 * K * K + a3 * Math.Pow(K, 3.0) + a4 * Math.Pow(K, 4.0) + a5 * Math.Pow(K, 5.0));

if (X < 0) 
{
  return 1.0 - dCND;
}
else
{
  return dCND;
}
}
}
}

DELPHI/PASCAL

function BlackScholes(CallPutFlag : string; S, X, T, r, v : Double) : Double;

var
d1, d2 : Double;
begin
Result := 0;
d1 := (LN(S / X) + (r + Power(v, 2) / 2) * T) / (v * SqRt(T));
d2 := d1 - v * SqRt(T);
if CallPutFlag = 'c' then
   Result := S * CND(d1) - X * Exp(-r * T) * CND(d2)
else
   if CallPutFlag = 'p' then
      Result := X * Exp(-r * T) * CND(-d2) - S * CND(-d1);
end;

 

function CND(X : Double) : Double;
var
  L, K : Double;
const
  a1 = 0.31938153; a2 = -0.356563782; a3 = 1.781477937;
  a4 = -1.821255978; a5 = 1.330274429;
begin
  L := Abs(X);
  K := 1 / (1 + 0.2316419 * L);
  Result := 1 - 1 / SqRt(2 * Pi) * Exp(-Power(L, 2) / 2) * (a1 * K + a2 * Power(K, 2) + a3 * Power(K, 3) + a4 * Power(K, 4) + a5 * Power(K, 5));
  if X < 0 then
    Result := (1 - Result)
end;

Архив QLua