2013-10-09 2 views
0

У меня есть следующий код разработки эффективной границы для портфеля активов:Связанные ограничения игнорируются Matlab

lb=Bounds(:,1); 
ub=Bounds(:,2); 

P = Portfolio('AssetList', AssetList,'LowerBound', lb, 'UpperBound', ub, 'Budget', 1); 
P = P.estimateAssetMoments(AssetReturns) 
[Passetmean, Passetcovar] = P.getAssetMoments 

pwgt = P.estimateFrontier(20); 
[prsk, pret] = P.estimatePortMoments(pwgt); 

Он отлично работает, кроме того, что она не учитывает ограничения в некоторой степени (результаты ниже). Как установить ограничения жесткими ограничениями, т. Е. Предотвратить его игнорирование верхней границы нуля? Например, когда я устанавливаю верхнюю и нижнюю границы нуля (т. Е. Я не хочу, чтобы какой-либо конкретный актив включался в портфель), я все равно получаю значения в рассчитанных весах портфеля для этого актива, хотя и очень маленькие, исходящие из часть оптимизированного портфеля. Нижние оценки (фунт), верхние оценки (UB), и один из весов портфеля (pwgt) изложены ниже:

lb     ub      pwgt(:,1) 
0     0     1.06685493772574e-16 
0     0     4.17200995972422e-16 
0     0     0 
0     0     2.76688394418301e-16 
0     0     3.39138439553466e-16 
0.192222222222222 0.252222222222222 0.192222222222222 
0.0811111111111111 0.141111111111111 0.105624956477606 
0.0912121212121212 0.151212121212121 0.0912121212121212 
0.0912121212121212 0.151212121212121 0.0912121212121212 
0.0306060606060606 0.0906060606060606 0.0306060606060606 
0.0306060606060606 0.0906060606060606 0.0306060606060606 
0.121515151515152 0.181515151515152 0.181515151515152 
0.0508080808080808 0.110808080808081 0.110808080808081 
0.00367003367003366 0.0636700336700337 0.0388531580005063 
0.00367003367003366 0.0636700336700337 0.0636700336700338 
0.00367003367003366 0.0636700336700337 0.0636700336700337 
0     0     0 
0     0     0 
0     0     1.29236898960272e-16 

я мог бы использовать что-то вроде: pwgt=floor(pwgt*1000)/1000;, но не более элегантное решение чем это?

ответ

0

Дело в том, что ваша оценка не была проигнорирована.

Вы вычисляете числа с плавающей запятой, и, следовательно, 0 и 4.17200995972422e-16 оба достаточно близки к 0, чтобы ваша программа позволяла им.

Моя рекомендация действительно было бы округлить свои результаты (или просто отображать меньше десятичных знаков с format short), однако я хотел бы сделать округление так:

pwgt=round(pwgt*100000)/100000; 

Обратите внимание, что другие результаты также могут быть «выше» верхняя граница, однако это не станет видимым из-за незначительности.

0

У меня были такие проблемы, как код ламината/инженерных свойств, который распространял ошибки во всем. Я исправил это, взяв все значения, которые у меня были, и систематически преобразовывал их из double в sym, и вдруг мои значения 1e-16 стали реальными нулями, что я мог также eval(val) и все еще видеть как нули! Это может помочь, но вам, возможно, придется зайти в файлы .m, которые вы используете, и преобразовать числа в sym с помощью val = sym(val).

Я не помню наверняка, но я думаю, что функции Matlab МОГУТ изменить sym на двойной, как только они получат данные для собственной внутренней обработки.

Смежные вопросы