このページの翻訳は最新ではありません。ここをクリックして,英語の最新版を参照してください。
この例では,混合整数線形計画法(MILP)ソルバーintlinprog
を使用して,混合整数二次計画法(MIQP)のポートフォリオ最適化問題の解法を示します。考え方としては,MIQP問題を局所的に近似する一連のMILP問題を反復的に求めるというものです。問題ベースのアプローチについては,混合整数二次計画法ポートフォリオ最適化問題:問題ベースを参照してください。
马科维茨が示したように,多くのポートフォリオ最適化問題は二次計画問題として表されます(“投资组合选择,”j .金融卷7,问题1,第91 - 77页,1952年3月)。N
件の項目から成る一連の資産があり,ポートフォリオを選ぶとします。ここで
は資産
における投資割合です。各資産の平均収益のベクトル
および収益の共分散行列
がわかっている場合,与えられた危険回避のレベル
に対し,リスク調整後の期待収益を最大化します。
quadprog
ソルバーを使用してこの二次計画問題を解きます。しかし,そのままの二次計画問題に加えて,ポートフォリオに次のようなさまざまな制限をかけることが必要な場合があります。
ポートフォリオに含まれる資産が米
個を超えないものとする。ここでM < = N
。
ポートフォリオが少なくとも米
個の資産を含むとする。ここで0 < m <= m
。
“半連続的な”制約があるものとする。これは, であるか, および のいくつかの固定割合について であることを意味します。
quadprog
にこれらの制約を含めることはできません。難しいのは,制約の離散的な性質です。さらに,混合整数線形計画法ソルバーintlinprog
は離散的な制約は処理できますが,二次の目的関数は扱いません。
この例では,制約を満たすと共に,しだいに二次の目的関数を近似するようになる一連のMILP問題を作成します。この手法はこの例については機能しますが,他の問題や制約のタイプには当てはまらない場合があります。
まず制約をモデル化します。
は資産配分の割合を表すベクトルであり,各 について です。ポートフォリオに含まれる資産の個数をモデル化するため, の場合は 、 の場合は になるように指標変数 を設定します。この制限を満たす変数を得るため,ベクトル をバイナリ変数に設定し,線形制約を課します。
これらの不等式によって, と はまったく同時にゼロになります。また, の場合は常に, になります。
また,ポートフォリオ内の資産数への制約を実現させるため,線形制約を課します。
最初に定式化したように,目的関数を最大化しようと試みます。ところが、Optimization Toolbox™ のソルバーではすべて最小化されます。そこで、目的関数の負の値を最小化するように問題を定式化します。
この目的関数は非線形です。intlinprog
MILPソルバーには線形目的関数が必要です。この問題を線形目的関数と非線形な制約をもつ問題に再度定式化する標準の手法があります。二次の項を表すためにスラック変数
を導入します。
MILP近似を反復的に解く際,新規の線形制約を組み込み,各制約によって,現在の点の近くにある非線形な制約を局所的に近似します。具体的には, が定数ベクトル, が変数ベクトルである について,制約の1次テイラー近似は次のようになります。
を で置き換えると,次のようになります。
各中間解 について,上式の線形部分として と に新しい線形制約を導入します。
これは という形式になります。ここで, 、 項の乗数は 、 です。
問題に新規の線形制約を追加するこの方法は,切除平面法と呼ばれます。詳細については,J。e·凯利。求解凸规划的切割平面法j . Soc.Indust.Appl.Math.Vol。4号,第712 - 703页,1960年12月を参照してください。
intlinprog
ソルバー向けに問題を表すためには以下を行う必要があります。
変数が表す内容の決定
これらの変数の下限と上限の明示
線形の等式および不等式行列の指定
最初の 個の変数は ベクトルを表し,次の 個の変数は2値の ベクトルを表し,最後の変数はスラック変数 を表します。問題には 個の変数が含まれています。
問題のデータを読み込みます。このデータには,ベクトルr
225年に含まれる個の期待される収益と,225行225列の行列问
に含まれる収益の共分散があります。データは”ポートフォリオ最適化問題に対する二次計画法の使用“の例と同じです。
负载port5r = mean_return;Q = Correlation .* (stdDev_return * stdDev_return');
資産の数をN
に設定します。
N =长度(r);
変数のインデックスを設定します
xvars = 1: N;vvars = N + 1:2 * N;zvar = 2 * N + 1;
問題において2 n + 1
個のすべての変数の下限はゼロです。最初の2 n
個の変数の上限は1で最後の変数には上限はありません。
磅= 0 (2 * N + 1, - 1);乌兰巴托的= (2 * N + 1, - 1);乌兰巴托(zvar) =正;
解における資産の数を100 ~ 150に設定します。この制約を次の形式で問題に組み込みます。
形式 の2つの線形制約を記述すると,次のようになります。
M = 150;m = 100;一个= 0(1、2 * N + 1);%分配矩阵(vvars) = 1;% A*x表示v(i)的和一个=[;——];b = 0 (2, 1);分配b向量b (1) = M;b (2) = - m;
半連続的な制約を含めます。それぞれの資産タイプについて,非ゼロの最小の資産の割合を0.001
に,また,最大の割合を0.05
にします。
fmin = 0.001;fmax = 0.05;
線形不等式として,不等式 および を含めます。
Atemp =眼(N);Amax = horzcat (Atemp -Atemp * fmax, 0 (N - 1));一个= [;Amax];b = [b; 0 (N, 1)];阿明= horzcat (-Atemp Atemp * fmin, 0 (N - 1));一个= (;Amin);b = [b; 0 (N, 1)];
ポートフォリオは100%運用であるという制約を含めます。これは, を意味します。
Aeq = 0(1、2 * N + 1);%分配Aeq矩阵Aeq (xvars) = 1;说真的= 1;
危険回避係数
をOne hundred.
に設定します。
λ= 100;
目的関数 をベクトルとして定義します。変数 の乗数にはゼロを含めます。
f = (- r; 0 (N, 1)λ);
問題を反復的に解くために,現在の制約をもつ問題を解くことから始めます。現在の制約については,いかなる線形化も実施していません。vvars
ベクトルは整数制約をもちます。
选择= optimoptions (@intlinprog,“显示”,“关闭”);%抑制迭代显示[xLinInt, fval exitFlagInt、输出]= intlinprog (f vvars A、b Aeq,说真的,磅,乌兰巴托,选项);
反復の停止条件を決めます。スラック変数 が真の二次値の0.01%以内になったときに反復を止めます。制約が累積されても問題が厳密に実行可能であることを確保するために,許容誤差を既定より小さく設定します。
thediff = 1的军医;iter = 1;%迭代计数器资产= xLinInt (xvars);% x变量truequadratic =资产' * Q *资产;zslack = xLinInt (zvar);松弛变量值选择= optimoptions(选项,“LPOptimalityTolerance”1平台以及“RelativeGapTolerance”1 e-8...“ConstraintTolerance”1 e-9“IntegerTolerance”1 e-6);
プロットするために二次の真値とスラック変数の計算履歴を保存します。
历史= [truequadratic, zslack];
二次の値およびスラック変数の値を計算します。それらが異なる場合は,別の線形制約を追加して再度解を求めます。
ツールボックスの構文にある,それぞれの新規の線形制約 は次の線形近似から得られます。
の新しい行, の新しい要素,および の1係数で表される 項があるのがわかります。
新規の解が求まったら,元の解と新規解の中間にある線形制約を使用します。線形制約を含んでいるこのヒューリスティックな方法のほうが,単純に新規解を用いるよりも高速になる場合があります。この中間のヒューリスティックな方法の代わりに解を使う場合は,下記の中途“の行にコメントし,その次の行のコメントを解除します。
而ab ((zslack - truequatic)/ truequatic) > thediff%相对误差newArow = horzcat(2 *资产* Q, 0 (1, N), 1);%线性约束rhs =资产' * Q *资产;%在线性化约束的右边一个= [;newArow];b = (b; rhs);%用新的约束条件解决问题[xLinInt, fval exitFlagInt、输出]= intlinprog (f vvars A、b Aeq,说真的,磅,乌兰巴托,选项);资产=(资产+ xLinInt (xvars)) / 2;从以前到现在的中途% assets = xLinInt(xars);%使用前一行或这一行xLinInt(xxars)'*Q* xLinInt(xxars);zslack = xLinInt (zvar);历史=(历史;truequadratic, zslack);Iter = Iter + 1;结束
スラック変数と目的関数の二次の部分の計算履歴をプロットしてどのように収束するかを確認します。
情节(历史)传说(“二次”,“松弛”)包含(的迭代次数)标题(“二次逼近和线性逼近(松弛)”)
MILPの解はどのような品質でしょうか。输出
構造体に,その情報が含まれます。解における,内部で計算された目的関数の限界値間のギャップの絶対値を検証します。
disp (output.absolutegap)
0
ギャップの絶対値はゼロであり,MILPの解は正確であることを示しています。
最適な資産配分をプロットします。中間位置での更新を使用すると,资产
は制約を満たさない可能性があるため,资产
ではなく,xLinInt (xvars)
を使用します。
栏(xLinInt (xvars))网格在包含(“资产指数”) ylabel (投资的比例)标题(“最优资产配置”)
非ゼロの資産配分のすべてが半連続的な範囲 と の間にあることが簡単に確認できます。
非ゼロの資産がいくつあるでしょうか。制約は,非ゼロの資産の数が100 ~ 150です。
sum (xLinInt (vvars))
ans = 100
この資産配分により期待される収益,そしてリスク調整された収益値はどれほどでしょうか。
流('预期收益为%g,风险调整后的收益为%g.\n',...r * xLinInt (xvars)、-fval)
预期收益为0.000595107,风险调整后的收益为-0.0360382。
特に金融工具箱™でのポートフォリオ最適化用に設計された機能を使用すると,より詳細な分析が可能です。ポートフォリオクラスを使用して半連続および濃度の制約を直接処理する方法を示す例については,具有半连续和基数约束的投资组合优化(金融工具箱)を参照してください。