본문 바로가기
Project/project2 - 주식시뮬레터(Matlab)

Matlab으로 4대 대장주 시뮬레이터 만들기

by 끊임없는정진 2023. 1. 19.

▶ 배경

 

이걸 만들 당시(2020년 상반기)에 주식붐이 엄청 일어났었다. 그래서 주식 시뮬레이터를 내가 직접 만들어보는 것은 어떨까 생각하여 만들게 되었고, 엄청나게 많은 시행착오를 거쳐 몇 번의 수정사항을 거쳐서 완성했다. 어떻게 만들었는지 그 과정과 결과물을 기록하기 위해서 해당 글을 작성한다. 단, 프로그래밍을 하나도 몰라서 Matlab으로 만들었다.

또한, 비전공자라 좀 많이 빼먹은 지식이 많다. 2020년 당시 학부생의 소꿉장난이라고 생각하고 애교로 봐주시면 감사할 것 같다.

 


 

▶ 배경지식 (혹은 시뮬레이터 설정)

 

기준금리에 따라 투자시장의 활성화, 주가의 등락이 결정된다고 가정한다. 

주식 가격의 등락 모델링은 Black-Sholes 식을 기준으로 구성했다. 

여기서, 내 능력의 한계로 몇가지 제약사항을 가정했다. 

[1] 거래 제약이 존재하지 않는다고 가정한다 : 세금, 수수료, 매수호가와 매도호가의 차이, 같은 거래비용이 없으며, 공매도에 대한 제약이 없다고 가정한다.

[2] 유럽형 콜옵션, 유럽형 풋옵션 : 미국형, 유럽형으로 나누어지는데 유럽식은 만기일에만 행사할 수 있음을 전제로 한다.

[3] 주식에 배당이 없음을 가정한다.

 


 

▶ Black-Scholes 식을 통한 주식 시뮬레이터 식모델링

 

일단 다음 확률 미분 방정식이 만족한다는 가정부터 시작했다.

 

위 식이 만족한다면 다음 식도 만족된다(여기서 Brown운동은 정규분포를 따른다고 가정한다.).

 

위 사실들을 바탕으로 식의 모델링을 하면 다음과 같이 식을 구성할 수 있다.

 

위 도출과정에 대해서 궁금하면 다음 문헌을 참고하면 도움이 된다.

     -> Black-Scholes 식의 다양한 유도 (최병선) - 295p  ,  금융공학 V (최병선) - 317p

 

모델링 한 식 중에서 m에 해당하는 µ값을 어떻게 설정할지가 또 문제가 된다. 해당 값은 추세모수, 즉 현재 상품의 추세를 적용해야 하는 계수이다. 나는 장기금리의 지표인 국채의 하락 또는 상승폭으로 추세모수를 정했다. 상승세라면 추세모수를 양수로, 하향세라면 음수로 준다.

σ값은 확산계수, 즉 확산이 증가되는 만큼 그 상품의 상향폭은 줄어들 것이다. 확산계수는 COSPI 대장주 4개(삼성전자, SK하이닉스, 삼성바이오로직스, Naver)의 10일의 주가로 산정한다. 해당 확산계수를 구하는 Sprice_interpolation.m 의 코드는 다음과 같다.

clear
clc

%=============================4개 대장주 확산계수===============================================
syms a x
y = -0.5*x^2 + randn*x -a;


%=============================삼성전자===============================================
disp('삼성전자')
S=load('Selectronics.txt');
INTPLT=zeros(1,9);
for i=2:10
    INTPLT(1,i-1)=S(1,i)/S(1,i-1)    ;
end

for i=2:10   
    soln=solve(y==0, x);
    ysoln=subs(soln, [a],[log(INTPLT(1,i-1))]);
    ysoln=simplify(ysoln);
    vpa(ysoln,3)
end    

%=============================SK하이닉스===============================================
disp('SK하이닉스')
J=load('SKhynics.txt');
INTPLTSK=zeros(1,9);
for i=2:10
    INTPLTSK(1,i-1)=J(1,i)/J(1,i-1);    
end

for i=2:10
    soln=solve(y==0, x);
    ysoln=subs(soln, [a],[log(INTPLTSK(1,i-1))]);
    ysoln=simplify(ysoln);
    vpa(ysoln,3)
end    

%=============================삼성바이오로직스===============================================
disp('삼성바이오로직스')
K=load('Sbiologics.txt');
INTPLTSB=zeros(1,9);
for i=2:10
    INTPLTSB(1,i-1)=K(1,i)/K(1,i-1);
end

for i=2:10
    soln=solve(y==0, x);
    ysoln=subs(soln, [a],[log(INTPLTSB(1,i-1))]);
    ysoln=simplify(ysoln);
    vpa(ysoln,3)
end    

%=============================Naver===============================================
disp('Naver')
L=load('Naver.txt')
INTPLTNV=zeros(1,9);
for i=2:10
    INTPLTNV(1,i-1)=L(1,i)/L(1,i-1);
end

for i=2:10
    soln=solve(y==0, x);
    ysoln=subs(soln, [a],[log(INTPLTNV(1,i-1))]);
    ysoln=simplify(ysoln);
    vpa(ysoln,3)
end    

 

 


 

▶ Black-Scholes 식을 통한 주식 시뮬레이터 프로토타입 (테스트용)

 

[1] 시나리오 구성 :

① 2008년 금융위기 (서브프라임 모기지 사태)

최저점을 찍은 10월 24일에 발표된 값부터 100일 전인 7월 16일에 발표된 100일 간의 국채의 이율 변동폭으로 한다. 
10월24일 발표한 우리나라 국고채 금리는 4.98%
7월16일에 발표한 우리나라 국고채 금리는 6.17%
4.98%-6.17%=1.19% 
µ=-0.0119

단, 2008년 당시의 COSPI 대장주의 주가 정보는 찾기가 힘드므로 최근 코로나사태의 폭락할 떄의 대장주 정보로 σ값을 대신 구한다. (3월 19일 기준 10일)
뒤에 소개할 Sprice_interpolation.m을 통해 구한 결과, 대장주 4개의 10일간 확산계수는
σ =0.0288

 

② 주식 호경기 (2020년 주식붐 일어났을 때)

한국은행이 저금리 정책을 시행하고 있는 가운데, 최근 100일 간(2020년 5월 기준)의 국고채 금리변화를 살펴보면,
0.826%-0.819%=0.007%
µ=0.0007

최근 100일간(2020년 5월 기준) 4개의 대장주의 COSPI지수를 통해Sprice_interpolation.m을 사용하여 확산계수를 구하였다.
σ=0.01225

 

③ 불경기

간단하게 호경기의 확산계수는 그대로 하고 추세만 감소추세로 하게끔 불경기의 추세계수의 반대부호로 계수를 산정했다.  즉,
µ=-0.0007
σ=0.01225
로 산정하게 된다.

 

④ 반등

반등은 금융위기같은 큰 주가의 하락에 있어서의 반작용이므로, 확산계수는 같게, 추세모수는 반대부호로 한다. 즉, 각 계수는
µ =0.0119
σ =0.0288
가 된다. 

 

[2] 시나리오 선정방법 :

일단, 시나리오 선정방법에 앞서서 어떤 과정에서 이렇게 선정하는 방법을 택했는지 부터 설명해야 할 것 같다. 

뜬금없지만, 어릴 때 부터 디아블로라는 게임을 엄청 좋아했다. 그런데 디아블로가 옛날 게임인 만큼 아이템을 떨어뜨릴 때의 매커니즘이 궁금했다. 

https://www.youtube.com/watch?v=fFxnZOwPnT0&t=46s

 

위 영상을 참조하면 알겠지만, 디아블로의 '카운테스'라는 보스가 아이템을 떨어뜨리는 매커니즘은 간략히 말하면,

1. 주사위 두개를 굴려서 눈의 합을 구한다. 2.그 합에 따라서 떨어뜨리는 템의 종류가 바뀐다.

와 같다.

 

위 방법에 따라서 나는 시나리오 선정을 0~1 중의 난수를 10개 생성한 뒤, 그 합에 따라서 시나리오를 설정하게끔 설계했다(0~1 금융위기, 1~5 불경기, 5~9 호경기, 9~10 반등).

 

[2] 프로그래밍 단계 : 대강 프로그래밍을 다음과 같이 하면, 주식을 그래프를 출력하는 주식 시뮬레이터를 만들 수 있다.

clear
clc

%========================각 변수의 정의==============================

%v    % 확산 계수(변동하는 범위의 크기)
%m    % 추세 계수(각 시나리오 별로 분석)
D=input('Days?(Recommendation=30~50)=');
t=1;
day=[1:D];

%========================경제상황 설정================================

dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
dicesum=sum(dice);
if dicesum<3
    stock(1,1)=2138; %코스피 시작가; 2020.06.25 개장기준(KOSPI)
    v=0.0288 ;       %금융위기 확산계수
    m=-0.0119 ;      %금융위기 추세(2008 국채 금리의 변화 바탕으로 금리 1.09% 하락)
elseif dicesum>=3 & dicesum<=5
    stock(1,1)=2138; %코스피 시작가; 2020.06.25 개장기준(KOSPI)
    v=0.00042;       %경기1 확산계수 2020.06.25 개장기준(KOSPI)4개 대장주
    m=-0.0007;       %경기1 추세 2020.06.25 개장기준(KOSPI)4개 대장주
elseif dicesum>5 & dicesum<=7
    stock(1,1)=2138; %코스피 시작가; 2020.06.25 개장기준(KOSPI)
    v=0.00042;       %경기2 확산계수 2020.06.25 개장기준(KOSPI)4개 대장주
    m=0.0007;        %경기2 추세 2020.06.25 개장기준(KOSPI)4개 대장주
else dicesum>7
    stock(1,1)=1337; %코스피 시작가; 2020.06.25 개장기준(KOSPI)에서 2008년 하락폭만큼 하락한 값 (약 37%)
    v=0.0288;        %반등 확산계수
    m=0.01119;       %반등 추세(2008 국채 금리의 변화폭 반대)
end


%========================KOSPI그래프 시뮬레이션========================

deltap1=zeros(1,D);
deltap2=zeros(1,D);
%delta-price를 입력하기 위하여 공간을 만들어주는 과정
for i=2:D
    stock(1,i)=stock(1,i-1)*exp((m-(v^2)/2)*t+v*randn);
    deltap1(1,i)=stock(1,i)-stock(1,i-1);
    if deltap1(1,i)<=0                %양봉(빨간 막대) 설정
       deltap2(1,i)=deltap1(1,i);     %음봉(파란 막대) 설정
    end
end


%========================그래프의 출력================================

plot (day, stock,'r-')    %주식차트 날짜선
hold on
bar (day, deltap1,'r')    %양봉(빨간 막대)
hold on
bar (day, deltap2,'b')    %음봉(파란 막대)
hold off
xlabel ('day','fontsize',12); 
ylabel ('Stock Price','fontsize',12); 
grid

 


 

▶ Black-Scholes 식을 통한 4대 대장주 주식 시뮬레이터

 

[1] 문제점 :

위 코드대로 만들면 문제점이 몇가지 발생한다. 우선, 100일 동안 똑같은 시나리오를 가정해서 개형이 극단적 방향으로 계속 진행된다. 두번째로 급락하면 반등을 못한다, 즉 망한 주식은 그대로 망하고 흥한 주식은 끝까지 흥한다. 세번째로 4개 대장주의 평균값으로 확산계수를 구해서 각 주식의 특색을 고려하지 못했다.

이러한 점들을 보강해서 '4대 대장주 주식 시뮬레이터'를 만들었다. 확산계수로 각 대장주들의 특색을 담는 것을 목표로 하고, 추세계수는 전과 똑같이 구했다.

위에 나온 Sprice interpolation.m 을 돌려보면 삼성전자, SK하이닉스, 삼성바이오, Naver의 확산계수를 한달동안의 데이터로 구한 결과 다음과 같이 나온다.

-삼성전자의 확산계수(σ)=0.0119
-SK하이닉스의 확산계수(σ)=0.0142
-삼성바이오의 확산계수(σ)=0.0143
-Naver의 확산계수(σ)=0.0212

 

[2] 이렇게 4대 대장주 특색을 담은 Matlab 코드를 만들면 다음과 같다.

clear
clc
%% 

%========================각 변수의 정의==============================

%v    % 확산 계수(변동하는 범위의 크기)
%m    % 추세 계수(각 시나리오 별로 분석)
D=input('Days?=');
C=input('어떤주식?(1.삼성전자 2.삼성바이오로직스 3.SK하이닉스 4.Naver; 숫자만 입력)=');
t=1;         
day=[1:D];   %나중에 출력할 그래프의 x축 설정
p=30;        %내가 설정할 시나리오 범위

%% 

%========================1번 대장주 주식(삼성전자)========================
deltapA1=zeros(1,D);
deltapB2=zeros(1,D);
%delta-price를 입력하기 위하여 공간을 만들어주는 과정

itn=0;  %반복회수: 0에서부터 시작함


if D<=p
    for i=2:D
        dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
        dicesum=sum(dice);
        stock1(1,1)=5780;
        if dicesum<3
            v=0.0374 ;       %금융위기 확산계수
            m=-0.0461;      %금융위기 추세
        elseif dicesum>=3 & dicesum<=5
            v=0.0119;       %경기1
            m=-0.0007;       %경기1
        elseif dicesum>5 & dicesum<=7
            v=0.0119;       %경기2
            m=0.0007;        %경기2
        elseif dicesum>=7
            v=0.0374;
            m=0.0461;
        end
        stock1(1,i)=stock1(1,i-1)*exp((m-(v^2)/2)*t+v*randn);
        deltapA1(1,i)=stock1(1,i)-stock1(1,i-1);
        if deltapA1(1,i)<=0                %양봉(빨간 막대) 설정
            deltapB2(1,i)=deltapA1(1,i);   %음봉(파란 막대) 설정
        end
    end
    
    
elseif D>p
    D1=D;                                  %날짜를 30일씩 끊어주는 작업
    while D1>p
        itn=itn+1;
        D1=D1-p;
    end
    stock1=zeros(p,itn+1);
    %stock을 입력하기 위해서 공간을 만들어주는 과정
    stock1(1,1)=5780;
    %시작가; 코로나사태 폭락 이전
    m=0;
    %m값을 정해놔야 이전상황 고려식이 막히지 않음
    r=0;
    %반복회수
    for i=1:itn
        if stock1(1,i)==0
            stock1(1,i)=stock1(p,i-1);
        end
        
        if i==1
            dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
            dicesum=sum(dice);
            %첫경우는 반등이 없다.
            if dicesum<2
                v=0.0374 ;       %금융위기 확산계수
                m=-0.0119 ;      %금융위기 추세
            elseif dicesum>=2 & dicesum<=6
                v=0.0119 ;       %경기1
                m=-0.0007;       %경기1
            elseif dicesum>6
                v=0.0119;       %경기2
                m=0.0119;        %경기2
            end
            
        elseif i~=1
            dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
            dicesum=sum(dice);
            if m==-0.0461 && r<3
                r=r+1;
                v=0.0374;      %금융위기 확산계수
                m=0.0163;      %금융위기 추세
            elseif m==0.0163 && r<3
                r=r+1;
                v=0.0374;      %금융위기 확산계수
                m=0.0163;      %금융위기 추세
            elseif m==0.0163 && r>=3
                r=0;
                v=0.0042;
                m=-0.001;
            elseif dicesum>=3 & dicesum<=6
                v=0.0119;       %경기1 확산계수
                m=-0.0007;       %경기1 추세
            elseif dicesum>6 & dicesum<=9.5
                v=0.0119;       %경기2 확산계수
                m=0.0007;        %경기2 추세
            elseif dicesum>9.5
                v=0.0374;
                m=0.0119;
            elseif dicesum<3
                v=0.0374 ;       %금융위기 확산계수
                m=-0.0461 ;      %금융위기 추세
            end
        end
        
        for j=2:p
            stock1(j,i)=stock1(j-1,i)*exp((m-(v^2)/2)*t+v*randn);
        end
    end
    if p*(itn+1)==D      %While D1>p로 설정하여 itn에 1을 더하여 줘야한다.
        dice=rand(1,10); %30일치가 남으면 30일치 주사위를 한번더 굴려준다.
        dicesum=sum(dice);
        if m==-0.0461 && r<3
            r=r+1;
            v=0.0374;      %금융위기 확산계수
            m=0.0163;      %금융위기 추세
        elseif m==0.0163 && r<3
            r=r+1;
            v=0.0374;      %금융위기 확산계수
            m=0.0163;      %금융위기 추세
        elseif m==0.0163 && r>=3
            r=0;
            v=0.0119;
            m=-0.001;
        elseif dicesum>=3 & dicesum<=5
            v=0.0119;       %경기1
            m=-0.0007;       %경기1
        elseif dicesum>5 & dicesum<=8
            v=0.0119;       %경기2
            m=0.0007;        %경기2
        elseif dicesum>8
            v=0.0374;
            m=0.0119;
        elseif dicesum<3
            v=0.0374 ;       %금융위기 확산계수
            m=-0.0461 ;      %금융위기 추세
        end
        for k=2:p
            stock1(1,itn+1)=stock1(p,itn);
            stock1(k,itn+1)=stock1(k-1,itn+1)*exp((m-(v^2)/2)*t+v*randn);
        end
    elseif p*(itn+1)~=D
        for k=2:D1
            stock1(1,itn+1)=stock1(p,itn);
            stock1(k,itn+1)=stock1(k-1,itn+1)*exp((m-(v^2)/2)*t+v*randn);
        end
    end
    stock1=nonzeros(stock1);    %Stock에서 0으로 되어있는 값을 없앤다.(zeros로 공간을 만들었기에 빈 공간은 0이 된다.)
    stock1=transpose(stock1);   %현재 Stock값은 편의상 위에서 아래로 입력했으므로 전치를 해준다.
    for i=2:D
        deltapA1(1,i)=stock1(1,i)-stock1(1,i-1);
        if deltapA1(1,i)<=0                %양봉(빨간 막대) 설정
            deltapB2(1,i)=deltapA1(1,i);     %음봉(파란 막대) 설정
        end
    end
end


%% 

%========================2번 대장주 주식(삼성바이오로직스)========================
deltapC1=zeros(1,D);
deltapD2=zeros(1,D);
%delta-price를 입력하기 위하여 공간을 만들어주는 과정

itn=0;  %반복회수: 0에서부터 시작함


if D<=p
    for i=2:D
        dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
        dicesum=sum(dice);
        stock2(1,1)=2138;
        if dicesum<3
            v=0.06808 ;       %금융위기 확산계수
            m=-0.0392 ;      %금융위기 추세
        elseif dicesum>=3 & dicesum<=5
            v=0.0143;       %경기1
            m=-0.0007;       %경기1
        elseif dicesum>5 & dicesum<=7
            v=0.0143;       %경기2
            m=0.0007;        %경기2
        elseif dicesum>=7
            v=0.06808;
            m=0.0656;
        end
        stock2(1,i)=stock2(1,i-1)*exp((m-(v^2)/2)*t+v*randn);
        deltapC1(1,i)=stock2(1,i)-stock2(1,i-1);
        if deltapC1(1,i)<=0                %양봉(빨간 막대) 설정
            deltapD2(1,i)=deltapC1(1,i);     %음봉(파란 막대) 설정
        end
    end
    
    
elseif D>p
    D1=D;
    while D1>p
        itn=itn+1;
        D1=D1-p;
    end
    stock2=zeros(p,itn+1);
    %stock을 입력하기 위해서 공간을 만들어주는 과정
    stock2(1,1)=2138;
    %시작가; 2020년 6월 25일 기준
    m=0;
    %m값을 정해놔야 이전상황 고려식이 막히지 않음
    for i=1:itn
        if stock2(1,i)==0
            stock2(1,i)=stock2(p,i-1);
        end
        
        if i==1
            dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
            dicesum=sum(dice);
            %첫경우는 반등이 없다.
            if dicesum<2
                v=0.06808 ;       %금융위기 확산계수
                m=-0.0392 ;      %금융위기 추세
            elseif dicesum>=2 & dicesum<=6
                v=0.0143;       %경기1
                m=-0.0007;       %경기1
            elseif dicesum>6
                v=0.0143;       %경기2
                m=0.0007;        %경기2
            end
            
        elseif i~=1
            dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
            dicesum=sum(dice);
            if m==-0.0392 && r<3
                r=r+1;
                v=0.06808;      %금융위기 확산계수
                m=0.0184;      %금융위기 추세
            elseif m==0.0184 && r<3
                r=r+1;
                v=0.06808;      %금융위기 확산계수
                m=0.0184;      %금융위기 추세
            elseif m==0.0184 && r>=3
                r=0;
                v=0.0143;
                m=-0.0007;
            elseif dicesum>=3 & dicesum<=6
                v=0.0143;       %경기1
                m=-0.0007;       %경기1
            elseif dicesum>6 & dicesum<=9.5
                v=0.0143;       %경기2
                m=0.0007;        %경기2
            elseif dicesum>9.5
                v=0.0374;
                m=0.0119;
            elseif dicesum<3
                v=0.06808 ;       %금융위기 확산계수
                m=-0.0392 ;      %금융위기 추세
            end
        end
        
        for j=2:p
            stock2(j,i)=stock2(j-1,i)*exp((m-(v^2)/2)*t+v*randn);
        end
    end
    if p*(itn+1)==D
        r=0;    %30일 남았으면 주사위로 남은 30일치를 정한다.
        dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
        dicesum=sum(dice);
        if m==-0.0392 && r<3
            r=r+1;
            v=0.06808;      %금융위기 확산계수
            m=0.0184;      %금융위기 추세
        elseif m==0.0184 && r<3
            r=r+1;
            v=0.06808;      %금융위기 확산계수
            m=0.0184;      %금융위기 추세
        elseif m==0.0184 && r>=3
            r=0;
            v=0.0143;
            m=-0.0007;
        elseif dicesum>=3 & dicesum<=6
            v=0.0143;       %경기1
            m=-0.0007;       %경기1
        elseif dicesum>6 & dicesum<=9.5
            v=0.0143;       %경기2
            m=0.0007;        %경기2
        elseif dicesum>9.5
            v=0.0143;
            m=0.0119;
        elseif dicesum<3
            v=0.06808 ;       %금융위기 확산계수
            m=-0.0392 ;      %금융위기 추세
        end
        for k=2:p
            stock2(1,itn+1)=stock2(p,itn);
            stock2(k,itn+1)=stock2(k-1,itn+1)*exp((m-(v^2)/2)*t+v*randn);
        end
    elseif p*(itn+1)~=D
        for k=2:D1
            stock2(1,itn+1)=stock2(p,itn);
            stock2(k,itn+1)=stock2(k-1,itn+1)*exp((m-(v^2)/2)*t+v*randn);
        end
    end
    stock2=nonzeros(stock2);    %Stock에서 0으로 되어있는 값을 없앤다.(zeros로 공간을 만들었기에 빈 공간은 0이 된다.)
    stock2=transpose(stock2);   %현재 Stock값은 편의상 위에서 아래로 입력했으므로 전치를 해준다.
    for i=2:D
        deltapC1(1,i)=stock2(1,i)-stock2(1,i-1);
        if deltapC1(1,i)<=0                %양봉(빨간 막대) 설정
            deltapD2(1,i)=deltapC1(1,i);     %음봉(파란 막대) 설정
        end
    end
end

%% 

%========================3번 대장주 주식(SK하이닉스)========================
deltapE1=zeros(1,D);
deltapF2=zeros(1,D);
%delta-price를 입력하기 위하여 공간을 만들어주는 과정

itn=0;  %반복회수: 0에서부터 시작함


if D<=p
    for i=2:D
        dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
        dicesum=sum(dice);
        stock3(1,1)=4840; %484000 간단화
        if dicesum<3
            v=0.0668 ;       %금융위기 확산계수
            m=-0.0653 ;      %금융위기 추세
        elseif dicesum>=3 & dicesum<=5
            v=0.0142;       %경기1
            m=-0.0007;       %경기1
        elseif dicesum>5 & dicesum<=7
            v=0.0142;       %경기2
            m=0.0007;        %경기2
        elseif dicesum>=7
            v=0.0668;
            m=0.0599;
        end
        stock3(1,i)=stock3(1,i-1)*exp((m-(v^2)/2)*t+v*randn);
        deltapE1(1,i)=stock3(1,i)-stock3(1,i-1);
        if deltapE1(1,i)<=0                %양봉(빨간 막대) 설정
            deltapF2(1,i)=deltapE1(1,i);     %음봉(파란 막대) 설정
        end
    end
    
    
elseif D>p
    D1=D;
    while D1>p
        itn=itn+1;
        D1=D1-p;
    end
    stock3=zeros(p,itn+1);
    %stock을 입력하기 위해서 공간을 만들어주는 과정
    stock3(1,1)=4840;
    %시작가; 코로나사태 이전; 484000 간단화
    m=0;
    %m값을 정해놔야 이전상황 고려식이 막히지 않음
    r=0;
    %반복횟수
    for i=1:itn
        if stock3(1,i)==0
            stock3(1,i)=stock3(p,i-1);
        end
        
        if i==1
            dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
            dicesum=sum(dice);
            %첫경우는 반등이 없다.
            if dicesum<2
                v=0.0668 ;       %금융위기 확산계수
                m=-0.0653 ;      %금융위기 추세
            elseif dicesum>=2 & dicesum<=6
                v=0.0142;       %경기1
                m=-0.0007;       %경기1
            elseif dicesum>6
                v=0.0142;       %경기2
                m=0.0007;        %경기2
            end
            
        elseif i~=1
            
            dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
            dicesum=sum(dice);
            if m==-0.0653 && r<3
                r=r+1;
                v=0.0668;      %금융위기 확산계수
                m=0.0230;      %금융위기 추세
            elseif m==0.0230 && r<3
                r=r+1;
                v=0.0668;      %금융위기 확산계수
                m=0.0230;      %금융위기 추세
            elseif m==0.0230 && r>=3
                r=0;
                v=0.0142;
                m=-0.001;
            elseif dicesum>=3 & dicesum<=6
                v=0.0142;       %경기1
                m=-0.0007;       %경기1
            elseif dicesum>6 & dicesum<=9.5
                v=0.0142;       %경기2
                m=0.0007;        %경기2
            elseif dicesum>9.5
                v=0.0668;
                m=0.0199;
            elseif dicesum<3
                v=0.0668 ;       %금융위기 확산계수
                m=-0.0653 ;      %금융위기 추세
            end
        end
        
        for j=2:p
            stock3(j,i)=stock3(j-1,i)*exp((m-(v^2)/2)*t+v*randn);
        end
    end
    if p*(itn+1)==D
        dice=rand(1,10); %30일치가 남으면 30일치 주사위를 한번더 굴려준다.
        dicesum=sum(dice);
        if m==-0.0653 && r<3
            r=r+1;
            v=0.0374;      %금융위기 확산계수
            m=0.0230;      %금융위기 추세
        elseif m==0.0230 && r<3
            r=r+1;
            v=0.0374;      %금융위기 확산계수
            m=0.0230;      %금융위기 추세
        elseif m==0.0230 && r>=3
            r=0;
            v=0.0142;
            m=-0.001;
        elseif dicesum>=3 & dicesum<=6
            v=0.0142;       %경기1
            m=-0.0007;       %경기1
        elseif dicesum>6 & dicesum<=9.5
            v=0.0142;       %경기2
            m=0.0007;        %경기2
        elseif dicesum>9.5
            v=0.0374;
            m=0.0199;
        elseif dicesum<3
            v=0.0374 ;       %금융위기 확산계수
            m=-0.0653 ;      %금융위기 추세
        end
        for k=2:p
            stock3(1,itn+1)=stock3(p,itn);
            stock3(k,itn+1)=stock3(k-1,itn+1)*exp((m-(v^2)/2)*t+v*randn);
        end
    elseif p*(itn+1)~=D
        for k=2:D1
            stock3(1,itn+1)=stock3(p,itn);
            stock3(k,itn+1)=stock3(k-1,itn+1)*exp((m-(v^2)/2)*t+v*randn);
        end
    end
    stock3=nonzeros(stock3);    %Stock에서 0으로 되어있는 값을 없앤다.(zeros로 공간을 만들었기에 빈 공간은 0이 된다.)
    stock3=transpose(stock3);   %현재 Stock값은 편의상 위에서 아래로 입력했으므로 전치를 해준다.
    for i=2:D
        deltapE1(1,i)=stock3(1,i)-stock3(1,i-1);
        if deltapE1(1,i)<=0                %양봉(빨간 막대) 설정
            deltapF2(1,i)=deltapE1(1,i);     %음봉(파란 막대) 설정
        end
    end
end

%% 

%========================4번 대장주 주식(Naver)============================
deltapG1=zeros(1,D);
deltapH2=zeros(1,D);
%delta-price를 입력하기 위하여 공간을 만들어주는 과정

itn=0;  %반복회수: 0에서부터 시작함


if D<=p
    for i=2:D
        dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
        dicesum=sum(dice);
        stock4(1,1)=1905;
        if dicesum<3
            v=0.0513 ;       %금융위기 확산계수
            m=-0.0374 ;      %금융위기 추세
        elseif dicesum>=3 & dicesum<=5
            v=0.0212;       %경기1
            m=-0.0007;       %경기1
        elseif dicesum>5 & dicesum<=7
            v=0.0212;       %경기2
            m=0.0007;        %경기2
        elseif dicesum>=7
            v=0.0513;
            m=0.0518;
        end
        stock4(1,i)=stock4(1,i-1)*exp((m-(v^2)/2)*t+v*randn);
        deltapG1(1,i)=stock4(1,i)-stock4(1,i-1);
        if deltapG1(1,i)<=0                %양봉(빨간 막대) 설정
            deltapH2(1,i)=deltapG1(1,i);    %음봉(파란 막대) 설정
        end
    end
    
    
elseif D>p
    D1=D;
    while D1>p
        itn=itn+1;
        D1=D1-p;
    end
    stock4=zeros(p,itn+1);
    %stock을 입력하기 위해서 공간을 만들어주는 과정
    stock4(1,1)=1905;
    %시작가; 코로나 사태이전; 190500을 간단화
    m=0;
    %m값을 정해놔야 이전상황 고려식이 막히지 않음
    for i=1:itn
        if stock4(1,i)==0
            stock4(1,i)=stock4(p,i-1);
        end
        
        if i==1
            dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
            dicesum=sum(dice);
            %첫경우는 반등이 없다.
            if dicesum<2
                v=0.0513 ;       %금융위기 확산계수
                m=-0.0374 ;      %금융위기 추세
            elseif dicesum>=2 & dicesum<=6
                v=0.0212;       %경기1
                m=-0.0007;       %경기1
            elseif dicesum>6
                v=0.0212;       %경기2
                m=0.0007;        %경기2
            end
            
        elseif i~=1
            dice=rand(1,10); %경제상황을 정하기 위한 주사위 굴리기
            dicesum=sum(dice);
            if m==-0.0392 && r<3
                r=r+1;
                v=0.0513;      %금융위기 확산계수
                m=0.0250;      %금융위기 추세
            elseif m==0.0250 && r<3
                r=r+1;
                v=0.0513;      %금융위기 확산계수
                m=0.0250;      %금융위기 추세
            elseif m==0.0250 && r>=3
                r=0;
                v=0.0212;
                m=-0.0007;
            elseif dicesum>=3 & dicesum<=6
                v=0.0212;       %경기1
                m=-0.0007;       %경기1
            elseif dicesum>6 & dicesum<=9.5
                v=0.0212;       %경기2
                m=0.0007;        %경기2
            elseif dicesum>9.5
                v=0.0513;
                m=0.0119;
            elseif dicesum<3
                v=0.0513 ;       %금융위기 확산계수
                m=-0.0392 ;      %금융위기 추세
            end
        end
        
        for j=2:p
            stock4(j,i)=stock4(j-1,i)*exp((m-(v^2)/2)*t+v*randn);
        end
    end
    if p*(itn+1)==D
        dice=rand(1,10); %30일치가 남으면 30일치 주사위를 한번더 굴려준다.
        dicesum=sum(dice);
        if m==-0.0392 && r<3
            r=r+1;
            v=0.0513;      %금융위기 확산계수
            m=0.0250;      %금융위기 추세
        elseif m==0.0250 && r<3
            r=r+1;
            v=0.0513;      %금융위기 확산계수
            m=0.0250;      %금융위기 추세
        elseif m==0.0250 && r>=3
            r=0;
            v=0.0212;
            m=-0.0007;
        elseif dicesum>=3 & dicesum<=6
            v=0.0212;       %경기1
            m=-0.0007;       %경기1
        elseif dicesum>6 & dicesum<=9.5
            v=0.0212;       %경기2
            m=0.0007;        %경기2
        elseif dicesum>9.5
            v=0.0513;
            m=0.0119;
        elseif dicesum<3
            v=0.0513 ;       %금융위기 확산계수
            m=-0.0392 ;      %금융위기 추세
        end
        for k=2:p
            stock4(1,itn+1)=stock4(p,itn);
            stock4(k,itn+1)=stock4(k-1,itn+1)*exp((m-(v^2)/2)*t+v*randn);
        end
    elseif p*(itn+1)~=D
        for k=2:D1
            stock4(1,itn+1)=stock4(p,itn);
            stock4(k,itn+1)=stock4(k-1,itn+1)*exp((m-(v^2)/2)*t+v*randn);
        end
    end
    stock4=nonzeros(stock4);    %Stock에서 0으로 되어있는 값을 없앤다.(zeros로 공간을 만들었기에 빈 공간은 0이 된다.)
    stock4=transpose(stock4);   %현재 Stock값은 편의상 위에서 아래로 입력했으므로 전치를 해준다.
    for i=2:D
        deltapG1(1,i)=stock4(1,i)-stock4(1,i-1);
        if deltapG1(1,i)<=0                %양봉(빨간 막대) 설정
            deltapH2(1,i)=deltapG1(1,i);     %음봉(파란 막대) 설정
        end
    end
end




%% 


%========================그래프의 출력================================


if C==1
    plot (day, stock1,'r-')    %주식차트 날짜선
    hold on
    bar (day, deltapA1,'r')    %양봉(빨간 막대)
    hold on
    bar (day, deltapB2,'b')    %음봉(파란 막대)
    hold off
    xlabel ('day','fontsize',12);
    ylabel ('Stock Price','fontsize',12);
    grid
    
    
elseif C==2
    plot (day, stock2,'r-')    %주식차트 날짜선
    hold on
    bar (day, deltapC1,'r')    %양봉(빨간 막대)
    hold on
    bar (day, deltapD2,'b')    %음봉(파란 막대)
    hold off
    xlabel ('day','fontsize',12);
    ylabel ('Stock Price','fontsize',12);
    grid
    
    
elseif C==3
    plot (day, stock3,'r-')    %주식차트 날짜선
    hold on
    bar (day, deltapE1,'r')    %양봉(빨간 막대)
    hold on
    bar (day, deltapF2,'b')    %음봉(파란 막대)
    hold off
    xlabel ('day','fontsize',12);
    ylabel ('Stock Price','fontsize',12);
    grid
    
    
elseif C==4
    plot (day, stock4,'r-')    %주식차트 날짜선
    hold on
    bar (day, deltapG1,'r')    %양봉(빨간 막대)
    hold on
    bar (day, deltapH2,'b')    %음봉(파란 막대)
    hold off
    xlabel ('day','fontsize',12);
    ylabel ('Stock Price','fontsize',12);
    grid
    
else
    disp('오류: 유효한 주식 번호를 입력하십시오.')
    
end

 


 

▶ Black-Scholes 식을 통한 4대 대장주 주식 시뮬레이터 작동 확인

 

 

 

참고문헌 :

한국은행: http://www.bok.or.kr/
최진기의 경제상식 오늘부터 1일 - 최진기
서브프라임 모기지론 사태: https://brunch.co.kr/@businessinsight/22
Black-Scholes식의 다양한 유도 - 서울대학교 경제연구소(최병선).2012.12.31
금융공학V(Introduction to Financial Engineering with R) – 최병선
시뮬레이션을 이용한 Black-Scholes 옵션모형의 헤지위험 분석 – 정도섭, 손진현. 2005.10
코스피 ‘폭락 뒤 반등의 추억'https://news.joins.com/article/5940258
디아블로2 카운테스 룬 드랍 구조, 룬 파밍에 대해서https://www.youtube.com/watch?v=fFxnZOwPnT0&t=46s

댓글