본문 바로가기

Julia

Julia 활용 #1 - 비선형(non-linear) optimization(최적화) model으로 주식 포트폴리오내 어떤 조합을 매도할지 판단하자

Project 목표: 주어진 주식 포트폴리오에서 어떤 조합으로 매도해야 조어진 조건들을 최대한 충족시키는지를 코딩하자.  - 조건들 1. 매도액은 $300에 가까울 것, 2. 매도 후 주식 포트폴리오의 price-to-earnings ratio가 45 이하일 것. 

- 사용 언어: julia

- 사용 editor (Atom / uber-juno)

- 사용 package: JuMP, Ipopt, Juniper 

- 사용 개념: optimization (min/max) with constraints, bounded domain 

- 작성일: 2021년 5월 2일 

 

 

목차

1. 결과물

2. Motivation

3. Optimization problem with constraints 으로 전환

4. 코딩 + 설명 (영어)

5. 결과 해석

 

 

1. 결과물

# show values q1, q2, and objective value
@show value(q1)
value(q1) = 4.0

@show value(q2)
value(q2) = 3.0

@show objective_value(model)
objective_value(model) = 297.0000029699887

 

2. Motivation

아래와 같이 포트폴리오가 구성되어 있다고 가정하자.

종목 price quantity price-to-earnings (per)
Apple $48 8 43
Microsoft $35 4 55

 

조건

1) 포트폴리오 관리 차원에서, Apple 주식 몇 주(q1이라 하자) 와 Micrsoft 주식 몇 주(q2이라 하자)를 매도하여 총 매도액이 $300에 최대한 가깝게 하도록 하고 싶다. 즉, $48*q1 + $35*q2 = 총 매도액이 최대한 $300에 가까운 (q1, q2)을 찾고 싶다.

2) 또한, q1과 q2을 매도한 후 남은 포트폴리오의 price-to-earnings 비율이 45미만이 되길 바란다. 

3) q1은 0개부터 8개까지 매도 가능하며, q1은 0 혹은 양의 정수(integer)가 되어야 한다.

4) q2은 0개부터 4개까지 매도 가능하며, q2은 0 혹은 양의 정수(integer)가 되어야 한다.

 

 

3. Optimization problem with constraints 으로 전환

choose q1, q2 such that maximize ($48*q1 + $35*q2) 
with constraints

1) 48*q1+35*q2 <= 300

2) (48*(8-q1)/(48*(8-q1)+35*(4-q2))+35*(4-q2)/(48*(8-q1)+35*(4-q2)))<=45)

3) 0<=q1<=8, AND q1 is an integer 

4) 0<=q2<=4, AND q2 is an integer 

 

보기 좋게 Latex 수식으로 출력하면:

choose q1 and q2 such that 

$ max(48*q_1+35*q_2) $ with respect to q1 and q2 

with constraints

1) $ 48*q_1+35*q_2 \leqslant 300 $

2) $ \frac{48*(8-q_1)}{48*(8-q_1)+35*(4-q_2)} + \frac{35*(4-q_2)}{48*(8-q_1)+35*(4-q_2)} \leqslant 45 $

3) $ q_1 \in [0,8] \ and \ q_1 \in \mathbb{Z} $

4) $ q_2 \in [0,4] \ and \ q_2 \in \mathbb{Z} $

 

LaTex 입력을 위한 참고: LaTex online editor: Online LaTeX Equation Editor - create, integrate and download (codecogs.com)  http://latex.codecogs.com/eqneditor/editor.php

 

Online LaTeX Equation Editor - create, integrate and download

 

latex.codecogs.com

 

4. 코딩 + 설명 (영어)

# date written: May 02, 2021
# topic: non-linear optimization problem with domain values bounded to integer values
# motivation: given [stock1name, price1, quantity1, per1], [stock2name, price2, quantity2, per2]
# note: quantity1 and quantity2 are integers. price1, price2, per1, and per2 are rational numbers.
# note2: for simplicity, let quantity1 = q1, price1 = p1 and so on.

# objective function: choose q1 and q2 such that maximmize (p1*q1 + p2*q2)
# constraint1: (p1*q1 + p2*q2) <= $300
# constraint2: ((p1*q1)/(p1*q1+p2*q2))*per1 + ((p2*q2)/(p1*q1+p2*q2))*per2 <= 45
# constraint3: (0<=q1<=original q1) AND q1 is an integer
# constraint4: (0<=q2<=original q2) AND q2 is an integer

# coding-related
# a brief introduction to Julia packages JuMP, Ipopt, and Juniper
# JuMP: a modeling language for mathematical optimization embedded in Julia. JuMP supports solvers for a variet of problem classes, including linear, mixed-integer, second-order conic, and nonlinear programming.
# Ipopt: "Interior Point OPTimizer" is a software library for large scale nonlinear optimization of continous systems
# Juniper: an open-source nonlinear branch-and-bound solver in Julia

using Pkg
Pkg.add("JuMP")
Pkg.add("Ipopt")
Pkg.add("Juniper")

# use JuMP, Ipopt, Juniper
using JuMP, Ipopt, Juniper

# set optimizer as Juniper's optimizer, so that bounded domains could be used for nonlinear optimization problem
optimizer = Juniper.Optimizer

# set non-linear solver from Ipopt package, so that nonlinear optimization could be used
nl_solver = optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0)

# set model 'm' as model: 1) optimizer from Juniper, 2) attribute nl_solver from Ipopt
model = Model(optimizer_with_attributes(optimizer, "nl_solver" => nl_solver))

# remove the relationship between model and q1; between model and q2
# purpose of removal: to avoid possible attachment of q1 and q2 to model, from previous codes
unregister(model, :q1)
unregister(model, :q2)

# create the variable q1 in the model, with conditions q1 in [0:8] while q1 in the integer set
# create the variable q2 in the model, with conditions q1 in [0:4] while q1 in the integer set
@variable(model,0<=q1<=8, start=0, Int)
@variable(model, 0<=q2<=4, start=0, Int)

# set non-linear constraints with p1=48, p2=35, and the sum of product pq <= 300
# set non-linear constraints with p1=48, p2=35, original q1 = 8, original q2 = 4, and the weighted per <= 45
@NLconstraint(model, 48*q1+35*q2 <= 300)
@NLconstraint(model, (48*(8-q1)/(48*(8-q1)+35*(4-q2))+35*(4-q2)/(48*(8-q1)+35*(4-q2)))<=45)

# set the objective function, and decided min or max
@NLobjective(model, Max, 48*q1+35*q2)

# run the optimization
optimize!(model)

# show values q1, q2, and objective value
@show value(q1)
@show value(q2)
@show objective_value(model)​

 

결과물은 q1=4 (Apple 주식 매도량), q2 = 3(Microsoft 주식 매도량)을 추천한다. 이 조합은 총 매도 금액이 약 $297으로 계산된다. 

# show values q1, q2, and objective value
@show value(q1)
value(q1) = 4.0

@show value(q2)
value(q2) = 3.0

@show objective_value(model)
objective_value(model) = 297.0000029699887

 

참고를 위해 아래에 기존 포트폴리오를 적는다.

종목 price quantity price-to-earnings (per)
Apple $48 8 43
Microsoft $35 4 55

 

 

프로그래밍 언어 중 하나인 julia 로고

Project 목표: 주어진 주식 포트폴리오에서 어떤 조합으로 매도해야 조어진 조건들을 최대한 충족시키는지를 코딩하자.  - 조건들 1. 매도액은 $300에 가까울 것, 2. 매도 후 주식 포트폴리오의 price-to-earnings ratio가 45 이하일 것.

- 사용 언어: julia

- 사용 package: JuMP, Ipopt, Juniper 

- 사용 개념: optimization (min/max) with constraints, bounded domain 

- 작성일: 2021년 5월 2일 

 

목차

1. 결과물

2. Motivation

3. Optimization problem with constraints 으로 전환

4. 코딩 + 설명 (영어)

5. 결과 해석

 

https://compute2080.tistory.com 

 

Compute2080: 금융공학, 프로그래밍, 정량화(quantify)

 

compute2080.tistory.com

 

coding capture 화면