Manim 을 본격적으로 이용해 보기 위해 그래프 그리는 작업을 준비했습니다.
금융공학에서 가장 유명한 그래프는 Black Schoels formula를 이용해서 구한 call option의 가격 그래프일 것입니다.
2022.08.17 - [금융공학] - 옵션 #2. 옵션 프리미엄 구하기(Closed form)
에서 공식을 확인할 수 있고, 옵션 가격식에 대한 python code는 2022.08.19 - [금융공학] - 옵션 #4. 옵션 프리미엄 구하기 실습: 명시적 FDM등에서 발견할 수 있습니다.
Call option 가격 그래프
다음은
- 행사가 100
- 만기 1년
- 이자율 2%
- 연속배당률 0%
- 변동성 : 10%, 20%, 30%, 40%, 50%
인 상황에서 기초자산의 현재가가 50~150을 움직일 때, Manim으로 그려본 그래프입니다.
Python Code
위 그래프를 구현한 코드는 다음과 같습니다.
from scipy.stats import norm
N = norm.cdf
def CallOptionBS(S, K, T, r, q, sigma):
if T == 0:
return np.max(S - K, 0)
else:
d1 = (np.log(S / K) + (r - q + sigma ** 2 / 2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
return S * np.exp(-q * T) * N(d1) - K * np.exp(-r * T) * N(d2)
class CoordSysExample(Scene):
def construct(self):
# the location of the ticks depends on the x_range and y_range.
grid = Axes(
x_range=[50, 150, 10], # step size determines num_decimal_places.
y_range=[0, 50, 10],
x_length=9,
y_length=5.5,
x_axis_config={"include_numbers": True, "font_size": 24},
#
# axis_config={
# "numbers_to_include": np.arange(50,150+10, 10),
# "font_size": 24,
# },
tips=False,
)
#Labels for the x-axis and y-axis.
y_label = grid.get_y_axis_label(Text("Call Value", font_size=30), edge=LEFT, direction=LEFT, buff=0.4)
x_label = grid.get_x_axis_label(Text("Stock", font_size=30), direction=DOWN, edge=DOWN)
grid_labels = VGroup(x_label, y_label)
# Draw Graph
vol_list = [0.1, 0.2, 0.3, 0.4, 0.5]
graphs = VGroup()
for i, vol in enumerate(vol_list):
if i == 0:
graph = grid.plot(lambda x: CallOptionBS(x, 100, 1, 0.02, 0, vol), color=BLUE_A)
label = grid.get_graph_label(graph=graph,
label=MathTex(r"\sigma={}\%".format(vol * 100), font_size=30),
x_val=100,
direction=RIGHT * 2,
color=BLUE_A
)
graphs += label
elif i == len(vol_list) - 1:
graph = grid.plot(lambda x: CallOptionBS(x, 100, 1, 0.02, 0, vol), color=YELLOW_A)
label = grid.get_graph_label(graph=graph,
label=MathTex(r"\sigma={}\%".format(vol * 100), font_size=30),
x_val=100,
direction=LEFT * 2,
color=YELLOW_A
)
graphs += label
else:
graph = grid.plot(lambda x: CallOptionBS(x, 100, 1, 0.02, 0, vol), color=WHITE)
title = Title(
r"Black Scholes Formula for Call Option",
include_underline=False,
font_size=40,
)
self.add(title, graphs, grid, grid_labels)
def CallOptionBS(S, K, T, r, q, sigma):
이 부분은 2022.08.19 - [금융공학] - 옵션 #4. 옵션 프리미엄 구하기 실습: 명시적 FDM 등등에서 많이 다루었던 코드이기 때문에 생략하도록 하겠습니다.
간략히 코드를 살펴보죠.
grid = Axes(
x_range=[50, 150, 10], # 50, 150 까지 step =10 으로 간격설정
y_range=[0, 50, 10], # 0~50 까지 step= 10으로 간격설정
x_length=9, #x 축의 길이는 9
y_length=5.5,
x_axis_config={"include_numbers": True, "font_size": 24}, #x축 환경을 세팅함. 숫자라벨을 포함하고, 폰트크기는 24
# x,y 양축을 동시에 환경설정하는 것은 아래와 같은 방법으로..
# axis_config={
# "numbers_to_include": np.arange(50,150+10, 10),
# "font_size": 24,
# },
tips=False, # 좌표축끝의 화살표 모양은 제거한다.
)
○ Axes 라는 클래스가 나옵니다. 여기의 설명을 그대로 가져왔습니다.
class Axes(x_range=None, y_range=None, x_length=12, y_length=6, axis_config=None, x_axis_config=None, y_axis_config=None, tips=True, **kwargs) $x,y$ 축을 생성하는 클래스입니다. PARAMETERS ○ x_range : The (x_min, x_max, x_step) values of the x-axis. ○ y_range : The (y_min, y_max, y_step) values of the y-axis. ○ x_length : The length of the x-axis. ○ y_length : The length of the y-axis. ○ axis_config : x축과 y축 동시에 환경설정하는 Numline Class형태 ○ x_axis_config : NumberLine that influence the x-axis. (x축 환경설정) ○ y_axis_config : NumberLine that influence the y-axis. (y축 환경설정) ○ tips (bool) : Whether or not to include the tips on both axes. (좌표축 끝의 화살촉 여부) |
○ x-axis-config, y-axis-config, axis-config는 모두 축에 대한 환경 설정을 하는 기능으로, NumberLine이라는 class의 변수들을 그대로 씁니다. 여기를 참고해 보세요.
class NumberLine(x_range=None, length=None, unit_size=1, include_ticks=True, tick_size=0.1, numbers_with_elongated_ticks=None, longer_tick_multiple=2, exclude_origin_tick=False, rotation=0, stroke_width=2.0, include_tip=False, tip_width=0.35, tip_height=0.35, include_numbers=False, font_size=36, label_direction=array([ 0., -1., 0.]), label_constructor=m.mobject.text.tex_mobject.MathTex'>, scaling=m.mobject.graphing.scale.LinearBase object>, line_to_number_buff=0.25, decimal_number_config=None, numbers_to_exclude=None, numbers_to_include=None, **kwargs)[source] 주로 쓰는 파라미터는 아래와 같습니다. ○ rotation (float) – The angle (in radians) at which the line is rotated. 축의 회전에 관계됨 ○ include_numbers (bool) – Whether to add numbers to the tick marks. The number of decimal places is determined by the step size, this default can be overridden by decimal_number_config, 축에 label을 표기할지의 문제 ○ scaling (_ScaleBase) – The way the x_range is value is scaled, i.e. LogBase for a logarithmic numberline. Defaults to LinearBase. ○ font_size (float) – The size of the label mobjects. Defaults to 36. ○ numbers_to_exclude (Iterable[float] | None) – An explicit iterable of numbers to not be added to the number line. ○ numbers_to_include (Iterable[float] | None) – An explicit iterable of numbers to add to the number line |
○ tip 은 축의 끝부분 화살촉 표시로, False이면 화살촉이 안 보입니다.
#Labels for the x-axis and y-axis.
y_label = grid.get_y_axis_label(Text("Call Value", font_size=30), edge=LEFT, direction=LEFT, buff=0.4)
x_label = grid.get_x_axis_label(Text("Stock", font_size=30), direction=DOWN, edge=DOWN)
grid_labels = VGroup(x_label, y_label)
○ get_x_axis_label , get_y_axis_label : $x$축 $y$축 label 지정을 하는 옵션입니다.
get_x_axis_label(label, edge=array([1., 1., 0.]), direction=array([1., 1., 0.]), buff=0.1, **kwargs) ○ label (float | str | Mobject) – The label. Defaults to MathTex for str and float inputs, Label 이름을 뜻함 ○ edge (Sequence[float]) – The edge of the x-axis to which the label will be added, by default UR. Label이 축에 어떻게 위치하는지를 정하는 방향 ○ direction (Sequence[float]) – Allows for further positioning of the label from an edge, by default UR. Edge에서 더 미세조정하는 Label의 위치 ○ buff (float) – The distance of the label from the line. 선에서 얼만큼 여유를 두고 label이 쓰여지는지 |
# Draw Graph
vol_list = [0.1, 0.2, 0.3, 0.4, 0.5] # Volatility는 총 5개 값
graphs = VGroup() # 5의 graph를 담을 Vectorized Group설정
for i, vol in enumerate(vol_list): # index와 volatility를 같이 for문 돌리기 위해 enumerate씀
if i == 0: #첫번째 vol에 대해서
graph = grid.plot(lambda x: CallOptionBS(x, 100, 1, 0.02, 0, vol), color=BLUE_A)
#call option graph를 그림
# grid 축에 그린 graph에 label을 설정함
label = grid.get_graph_label(graph=graph,
label=MathTex(r"\sigma={}\%".format(vol * 100), font_size=30),
x_val=100,
direction=RIGHT * 2,
color=BLUE_A
)
graphs += label # label object를 graph 그룹에 담음
elif i == len(vol_list) - 1: # 마지막 vol에 대해서
# yellow color 그래프 그림
graph = grid.plot(lambda x: CallOptionBS(x, 100, 1, 0.02, 0, vol), color=YELLOW_A)
# label을 붙임
label = grid.get_graph_label(graph=graph,
label=MathTex(r"\sigma={}\%".format(vol * 100), font_size=30),
x_val=100,
direction=LEFT * 2,
color=YELLOW_A
)
graphs += label
else: # 중간 vol들은 그냥 white로 그림
graph = grid.plot(lambda x: CallOptionBS(x, 100, 1, 0.02, 0, vol), color=WHITE)
○ get_graph_label 은 그래프에 레이블(label)을 설정하는 메서드입니다. 여기를 참고해 보세요.
get_graph_label(graph, label='f(x)', x_val=None, direction=array([1., 0., 0.]), buff=0.25, color=None, dot=False, dot_config=None) 파라미터 ○ graph (ParametricFunction) – The curve. (label 을 붙일 커브) ○ label (float | str | Mobject) – The label for the function’s curve. (레이블 명) ○ x_val (float | None) – The x_value along the curve that positions the label. (레이블을 붙일 $x$좌표 위치) ○ direction (Sequence[float]) – The cartesian position, relative to the curve that the label will be at –> LEFT, RIGHT. (레이블이 쓰여지는 방향) ○ buff (float) – The distance between the curve and the label.(레이블과 커브와의 여유거리 조정) ○ color (Color | None) – The color of the label. Defaults to the color of the curve. (레이블의 색) ○ dot (bool) – Whether to add a dot at the point on the graph. (레이블이 쓰여질 $x$좌표에 점 표시를 하는지 여부) dot_config (dict | None) – Additional parameters to be passed to Dot. |
title = Title(
r"Black Scholes Formula for Call Option",
include_underline=False,
font_size=40,
)
○ Title 은 제목입니다.
class Title(*text_parts, include_underline=True, match_underline_width_to_text=False, underline_buff=0.25, **kwargs) ○ 제목과 폰트사이즈, 밑줄 포함여부 등을 정할 수 있습니다. |
'파이썬 > MANIM' 카테고리의 다른 글
Manim. 삼각형의 scale, rotate (0) | 2022.09.26 |
---|---|
Manim. 도형 회전 rotate의 비밀 (0) | 2022.09.22 |
Manim. 삼각형 그리기 (0) | 2022.09.21 |
Manim. 정사각형 그리기 (0) | 2022.09.16 |
Manim. 원 그리기 (0) | 2022.09.14 |
댓글