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이라 하자)를 매도하여 총 매도액이
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 (
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
with constraints
1)
2)
3)
4)
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 |
끝

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
