커뮤니티
내재변동성
2017-12-23 16:46:15
351
글번호 115237
안녕하세요.
항상 수고가 많으십니다.
질문드립니다 -----------------------------------------
내재변동성에 대한 검색을 해보았더니,
글번호 : 3894
작성자 : 수식지왕
수식지왕님이 올리신 글이 보이더군요.
그래서 그대로 아래 지표식을 복사하여 적용시켜 보았더니 많은 에러가 나옵니다.
아래 지표식들을 어떻게 적용해야 하는지 가르쳐 주시면 감사하겠습니다.
그림 1
그림1
저희 카페 회원의 요청으로 만들어 보았습니다.
인터넷에서 검색만 해보면 블랙숄즈 옵션 이론에 대해 VBA소스가 많이 돌아 다닙니다.
다만, 문제는 버전이 조금씩 달라서 어떤 것이 정답인지 헷갈린다는 겁니다.
VBA 소스를 예스 언어로 컨버전해서 테스트 해보고 약간씩 수정을 해서 예트 월물 조회화면에서 보여주는 값에 근접하는 수식을 채택했습니다.
입력값이 상이해서 그런지 일치하는 값을 구하기 어렵고 비슷하다는 정도입니다.
테스트 기간이 길지 않아 일부 오류가 발견될 수도 있습니다.
_NormSDist.yfu (표준정규분포사용자함수)
input:z(numeric);
var : a1(0.31938153),
a2(-0.356563782),
a3(1.781477937),
a4(-1.821255978),
a5(1.330274429),
R(0.2316419),
Exp(2.71828182846),
k(0),
N(0);
k = 1 / (1 + (R * Abs(z)));
N = 1 / (Sqrt(2 * Pie())) * Exp^(-(z^2) / 2);
_NormSDist = 1 - N * (a1 * k + a2 * (k ^ 2) + a3 * (k ^ 3) + a4 * (k ^ 4) + a5 * (k ^ 5));
If z < 0 Then
_NormSDist = 1 - _NormSDist;
_BlackSholes.yfu (BS 모델이론가 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (r + (Sig^2) / 2) * T) / (Sig*sqrt(T));
var2 = var1 - Sig*sqrt(T);
if cpflag == 1 then
{
_BlackSholes = S * _NormSDist(var1) - X * (Exp^((-r)*T)) * _NormSDist(var2);
}
else if cpflag == 2 then
{
_BlackSholes = X * (Exp^((-r)*T)) * _NormSDist(var2) - S * _NormSDist(var1);
}
_ImVol.yfu (내재변동성 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Price(numeric);
var:vLow(0), vHigh(0), vi(0),cLow(0), cHigh(0), Epsilon(0.001), j(0), n(5000);
vLow = 0.01;
vHigh = 2;
cLow = _BlackSholes(cpFlag, S, X, T, r, q, vLow);
cHigh = _BlackSholes(cpFlag, S, X, T, r, q, vHigh);
vi = vLow + (Price - cLow) * (vHigh - vLow) / (cHigh - cLow);
for j = 0 to n
{
If _BlackSholes(cpFlag, S, X, T, r, q, vi) < Price Then
vLow = vi;
Else
vHigh = vi;
cLow = _BlackSholes(cpFlag, S, X, T, r, q, vLow);
cHigh = _BlackSholes(cpFlag, S, X, T, r, q, vHigh);
vi = vLow + (Price - cLow) * (vHigh - vLow) / (cHigh - cLow);
if Abs(Price - _BlackSholes(cpFlag, S, X, T, r, q, vi)) <= Epsilon then
{
var1 = vi;
j = n;
}
}
_ImVol = vi;
_Delta.yfu (델타 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
if cpflag == 1 then
{
_Delta = Exp^((q-r)*T) * _NormSDist(var1);
}
else if cpflag == 2 then
{
_Delta = Exp^((q-r)*T) * (_NormSDist(var1)-1);
}
_Gamma.yfu (감마 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
var3 = (1 / Sqrt(2 * pie())) * (1 / Exp^((var1^2) / 2));
_Gamma = Exp^((q-r)*T) * var3 / (S*Sig*Sqrt(T));
_Vega.yfu (베가 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*Sqrt(T));
var3 = (1 / Sqrt(2*pie())) * (1 / Exp^((var1^2) / 2));
_Vega = S * Exp^((q-r)*T) * var3 * Sqrt(T) /100;
_Theta.yfu (쎄타 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
var2 = var1 - Sig*sqrt(T);
var3 = (1 / Sqrt(2 * pie())) * (1 / Exp^((var1^2) / 2));
if cpflag == 1 then
{
_Theta = (-1) * (S * Exp^((q-r)*T) * var3 * Sig) / (2*Sqrt(T))
- (q-r) * S * Exp^((q-r)*T) * _NormSDist(var1)
- r * X * Exp^((-r)*T) * _NormSDist(var2);
}
else if cpflag == 2 then
{
_Theta = (-1) * (S * Exp^((q-r)*T) * var3 * Sig) / (2*Sqrt(T))
+ (q-r) * S * Exp^((q-r)*T) * _NormSDist(-var1)
+ r * X * Exp^((-r)*T) * _NormSDist(-var2);
}
_Theta = _Theta / 365;
_Rho.yfu (로 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
var2 = var1 - Sig*sqrt(T);
if cpflag == 1 then
{
_Rho = X * T * Exp^((q-r)*T) * _NormSDist(var2);
}
else if cpflag == 2 then
{
_Rho = -X * T * Exp^((q-r)*T) * _NormSDist(-var2);
}
옵션민감도.yin (지표식)
/*cpFlag : Call,Put 구분, 1,2로 표현
S : 기초자산가격의 가격, 예)주가지수(KOSPI200)
X : 행사가격
T : 잔존만기(연율)
r : 무위험 이자율, 예) CD금리
q : 배당률
Sig : 변동성 */
input: cpflag(1), //콜풋 입력
InS(0), //현재 지수를 입력 안하면 data 참조를 통해 실시간 가격을 이용. 테스트시 이용
x(145.0), //행사가 입력
ex(20050908), //만기일
r(0.0351), //CD 금리, 요기서 볼 수 있음 ==> http://stock.koscom.co.kr/
q(0), //배당률
InSig(0), //내재변동성을 입력 안하면 자체 계산된 변동성을 사용. 단, 오차 감안해야 함
InPrice(0); //역시 테스트를 목적으로 함
var:S(0),T(0),sig(0),price(0),ImVol(0),bs(0),delta(0),gamma(0),vega(0),theta(0),rho(0);
S = iff(inS!=0,inS,data1("c")); //kospi200종합을 같이 띄워 놓아야 합니다.
T = (DateToJulian(ex) - DateToJulian(date) + 1)/365;
price = iff(inPrice!=0,inPrice,c);
imvol = _ImVol(cpFlag, S, X, T, r, q, price);
sig = iff(insig!=0,insig,ImVol);
bs = _BlackSholes(cpFlag, S, X, T, r, q, sig);
delta = _Delta(cpFlag, S, X, T, r, q, sig);
gamma = _gamma(cpFlag, S, X, T, r, q, sig);
theta = _theta(cpFlag, S, X, T, r, q, sig);
vega = _vega(cpFlag, S, X, T, r, q, sig);
rho = _rho(cpFlag, S, X, T, r, q, sig);
plot1(imvol*100,"내재변동성");
plot2(bs,"이론가");
plot3(delta,"델타");
plot4(gamma,"감마");
plot5(theta,"쎄타");
plot6(vega,"베가");
plot7(rho,"로");
답변 1
예스스탁 예스스탁 답변
2017-12-26 15:45:55
안녕하세요
예스스탁입니다.
수식이 이전버전 내용이라 아래와 같이 변경하셔야 합니다.
총 8개의 사용자함수를 만드신 후에 올리신 지표식 적용해 보셔야 합니다.
문법만 현재 버전에 맞게 수정해 드립니다.
1. 사용자함수(_NormSDist)
input:z(numeric);
var : a1(0.31938153),
a2(-0.356563782),
a3(1.781477937),
a4(-1.821255978),
a5(1.330274429),
R(0.2316419),
Exp(2.71828182846),
k(0),
N(0);
k = 1 / (1 + (R * Abs(z)));
N = 1 / (Sqrt(2 * Pie())) * Exp^(-(z^2) / 2);
_NormSDist = 1 - N * (a1 * k + a2 * (k ^ 2) + a3 * (k ^ 3) + a4 * (k ^ 4) + a5 * (k ^ 5));
If z < 0 Then
_NormSDist = 1 - _NormSDist[1];
2 사용자함수(_BlackSholes)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (r + (Sig^2) / 2) * T) / (Sig*sqrt(T));
var2 = var1 - Sig*sqrt(T);
if cpflag == 1 then
{
_BlackSholes = S * _NormSDist(var1) - X * (Exp^((-r)*T)) * _NormSDist(var2);
}
else if cpflag == 2 then
{
_BlackSholes = X * (Exp^((-r)*T)) * _NormSDist(var2) - S * _NormSDist(var1);
}
3 사용자함수(_ImVol)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Price(numeric);
var:vLow(0), vHigh(0), vi(0),cLow(0), cHigh(0), Epsilon(0.001), j(0), n(5000);
vLow = 0.01;
vHigh = 2;
cLow = _BlackSholes(cpFlag, S, X, T, r, q, vLow);
cHigh = _BlackSholes(cpFlag, S, X, T, r, q, vHigh);
vi = vLow + (Price - cLow) * (vHigh - vLow) / (cHigh - cLow);
for j = 0 to n
{
If _BlackSholes(cpFlag, S, X, T, r, q, vi) < Price Then
vLow = vi;
Else
vHigh = vi;
cLow = _BlackSholes(cpFlag, S, X, T, r, q, vLow);
cHigh = _BlackSholes(cpFlag, S, X, T, r, q, vHigh);
vi = vLow + (Price - cLow) * (vHigh - vLow) / (cHigh - cLow);
if Abs(Price - _BlackSholes(cpFlag, S, X, T, r, q, vi)) <= Epsilon then
{
var1 = vi;
j = n;
}
}
_ImVol = vi;
4 사용자함수(_Delta)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
if cpflag == 1 then
{
_Delta = Exp^((q-r)*T) * _NormSDist(var1);
}
else if cpflag == 2 then
{
_Delta = Exp^((q-r)*T) * (_NormSDist(var1)-1);
}
5 사용자함수(_Gamma)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
var3 = (1 / Sqrt(2 * pie())) * (1 / Exp^((var1^2) / 2));
_Gamma = Exp^((q-r)*T) * var3 / (S*Sig*Sqrt(T));
6 사용자함수(_Vega)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*Sqrt(T));
var3 = (1 / Sqrt(2*pie())) * (1 / Exp^((var1^2) / 2));
_Vega = S * Exp^((q-r)*T) * var3 * Sqrt(T) /100;
7 사용자함수(_Theta)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
var2 = var1 - Sig*sqrt(T);
var3 = (1 / Sqrt(2 * pie())) * (1 / Exp^((var1^2) / 2));
if cpflag == 1 then
{
_Theta = (-1) * (S * Exp^((q-r)*T) * var3 * Sig) / (2*Sqrt(T))
- (q-r) * S * Exp^((q-r)*T) * _NormSDist(var1)
- r * X * Exp^((-r)*T) * _NormSDist(var2);
}
else if cpflag == 2 then
{
_Theta = (-1) * (S * Exp^((q-r)*T) * var3 * Sig) / (2*Sqrt(T))
+ (q-r) * S * Exp^((q-r)*T) * _NormSDist(-var1)
+ r * X * Exp^((-r)*T) * _NormSDist(-var2);
}
_Theta = _Theta / 365;
8 사용자함수(_Rho)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
var2 = var1 - Sig*sqrt(T);
if cpflag == 1 then
{
_Rho = X * T * Exp^((q-r)*T) * _NormSDist(var2);
}
else if cpflag == 2 then
{
_Rho = -X * T * Exp^((q-r)*T) * _NormSDist(-var2);
}
즐거운 하루되세요
> 샐리짱 님이 쓴 글입니다.
> 제목 : 내재변동성
>
안녕하세요.
항상 수고가 많으십니다.
질문드립니다 -----------------------------------------
내재변동성에 대한 검색을 해보았더니,
글번호 : 3894
작성자 : 수식지왕
수식지왕님이 올리신 글이 보이더군요.
그래서 그대로 아래 지표식을 복사하여 적용시켜 보았더니 많은 에러가 나옵니다.
아래 지표식들을 어떻게 적용해야 하는지 가르쳐 주시면 감사하겠습니다.
그림 1
그림1
저희 카페 회원의 요청으로 만들어 보았습니다.
인터넷에서 검색만 해보면 블랙숄즈 옵션 이론에 대해 VBA소스가 많이 돌아 다닙니다.
다만, 문제는 버전이 조금씩 달라서 어떤 것이 정답인지 헷갈린다는 겁니다.
VBA 소스를 예스 언어로 컨버전해서 테스트 해보고 약간씩 수정을 해서 예트 월물 조회화면에서 보여주는 값에 근접하는 수식을 채택했습니다.
입력값이 상이해서 그런지 일치하는 값을 구하기 어렵고 비슷하다는 정도입니다.
테스트 기간이 길지 않아 일부 오류가 발견될 수도 있습니다.
_NormSDist.yfu (표준정규분포사용자함수)
input:z(numeric);
var : a1(0.31938153),
a2(-0.356563782),
a3(1.781477937),
a4(-1.821255978),
a5(1.330274429),
R(0.2316419),
Exp(2.71828182846),
k(0),
N(0);
k = 1 / (1 + (R * Abs(z)));
N = 1 / (Sqrt(2 * Pie())) * Exp^(-(z^2) / 2);
_NormSDist = 1 - N * (a1 * k + a2 * (k ^ 2) + a3 * (k ^ 3) + a4 * (k ^ 4) + a5 * (k ^ 5));
If z < 0 Then
_NormSDist = 1 - _NormSDist;
_BlackSholes.yfu (BS 모델이론가 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (r + (Sig^2) / 2) * T) / (Sig*sqrt(T));
var2 = var1 - Sig*sqrt(T);
if cpflag == 1 then
{
_BlackSholes = S * _NormSDist(var1) - X * (Exp^((-r)*T)) * _NormSDist(var2);
}
else if cpflag == 2 then
{
_BlackSholes = X * (Exp^((-r)*T)) * _NormSDist(var2) - S * _NormSDist(var1);
}
_ImVol.yfu (내재변동성 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Price(numeric);
var:vLow(0), vHigh(0), vi(0),cLow(0), cHigh(0), Epsilon(0.001), j(0), n(5000);
vLow = 0.01;
vHigh = 2;
cLow = _BlackSholes(cpFlag, S, X, T, r, q, vLow);
cHigh = _BlackSholes(cpFlag, S, X, T, r, q, vHigh);
vi = vLow + (Price - cLow) * (vHigh - vLow) / (cHigh - cLow);
for j = 0 to n
{
If _BlackSholes(cpFlag, S, X, T, r, q, vi) < Price Then
vLow = vi;
Else
vHigh = vi;
cLow = _BlackSholes(cpFlag, S, X, T, r, q, vLow);
cHigh = _BlackSholes(cpFlag, S, X, T, r, q, vHigh);
vi = vLow + (Price - cLow) * (vHigh - vLow) / (cHigh - cLow);
if Abs(Price - _BlackSholes(cpFlag, S, X, T, r, q, vi)) <= Epsilon then
{
var1 = vi;
j = n;
}
}
_ImVol = vi;
_Delta.yfu (델타 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
if cpflag == 1 then
{
_Delta = Exp^((q-r)*T) * _NormSDist(var1);
}
else if cpflag == 2 then
{
_Delta = Exp^((q-r)*T) * (_NormSDist(var1)-1);
}
_Gamma.yfu (감마 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
var3 = (1 / Sqrt(2 * pie())) * (1 / Exp^((var1^2) / 2));
_Gamma = Exp^((q-r)*T) * var3 / (S*Sig*Sqrt(T));
_Vega.yfu (베가 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*Sqrt(T));
var3 = (1 / Sqrt(2*pie())) * (1 / Exp^((var1^2) / 2));
_Vega = S * Exp^((q-r)*T) * var3 * Sqrt(T) /100;
_Theta.yfu (쎄타 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
var2 = var1 - Sig*sqrt(T);
var3 = (1 / Sqrt(2 * pie())) * (1 / Exp^((var1^2) / 2));
if cpflag == 1 then
{
_Theta = (-1) * (S * Exp^((q-r)*T) * var3 * Sig) / (2*Sqrt(T))
- (q-r) * S * Exp^((q-r)*T) * _NormSDist(var1)
- r * X * Exp^((-r)*T) * _NormSDist(var2);
}
else if cpflag == 2 then
{
_Theta = (-1) * (S * Exp^((q-r)*T) * var3 * Sig) / (2*Sqrt(T))
+ (q-r) * S * Exp^((q-r)*T) * _NormSDist(-var1)
+ r * X * Exp^((-r)*T) * _NormSDist(-var2);
}
_Theta = _Theta / 365;
_Rho.yfu (로 사용자함수)
input:cpflag(numeric),S(numeric),X(numeric),T(numeric),r(numeric),q(numeric),Sig(numeric);
var:Exp(2.71828182846);
var1 = (log(S/X) + (q + (Sig^2) / 2)*T) / (Sig*sqrt(T));
var2 = var1 - Sig*sqrt(T);
if cpflag == 1 then
{
_Rho = X * T * Exp^((q-r)*T) * _NormSDist(var2);
}
else if cpflag == 2 then
{
_Rho = -X * T * Exp^((q-r)*T) * _NormSDist(-var2);
}
옵션민감도.yin (지표식)
/*cpFlag : Call,Put 구분, 1,2로 표현
S : 기초자산가격의 가격, 예)주가지수(KOSPI200)
X : 행사가격
T : 잔존만기(연율)
r : 무위험 이자율, 예) CD금리
q : 배당률
Sig : 변동성 */
input: cpflag(1), //콜풋 입력
InS(0), //현재 지수를 입력 안하면 data 참조를 통해 실시간 가격을 이용. 테스트시 이용
x(145.0), //행사가 입력
ex(20050908), //만기일
r(0.0351), //CD 금리, 요기서 볼 수 있음 ==> http://stock.koscom.co.kr/
q(0), //배당률
InSig(0), //내재변동성을 입력 안하면 자체 계산된 변동성을 사용. 단, 오차 감안해야 함
InPrice(0); //역시 테스트를 목적으로 함
var:S(0),T(0),sig(0),price(0),ImVol(0),bs(0),delta(0),gamma(0),vega(0),theta(0),rho(0);
S = iff(inS!=0,inS,data1("c")); //kospi200종합을 같이 띄워 놓아야 합니다.
T = (DateToJulian(ex) - DateToJulian(date) + 1)/365;
price = iff(inPrice!=0,inPrice,c);
imvol = _ImVol(cpFlag, S, X, T, r, q, price);
sig = iff(insig!=0,insig,ImVol);
bs = _BlackSholes(cpFlag, S, X, T, r, q, sig);
delta = _Delta(cpFlag, S, X, T, r, q, sig);
gamma = _gamma(cpFlag, S, X, T, r, q, sig);
theta = _theta(cpFlag, S, X, T, r, q, sig);
vega = _vega(cpFlag, S, X, T, r, q, sig);
rho = _rho(cpFlag, S, X, T, r, q, sig);
plot1(imvol*100,"내재변동성");
plot2(bs,"이론가");
plot3(delta,"델타");
plot4(gamma,"감마");
plot5(theta,"쎄타");
plot6(vega,"베가");
plot7(rho,"로");