/*! portfolio-allocation - v0.0.10 (2020-09-14), Roman Rubsamen */ var PortfolioAllocation=PortfolioAllocation||{};PortfolioAllocation=function(y){function k(t){var r={getCorrelationMatrix:function(t){for(var r=_(this.nbRows,this.nbColumns,t),n=0;nr?(i[e]=a,++e):(n[o]=a,++o);for(t=t.slice(0);0r?(i[e]=s,++e):(n[o]=s,++o)}for(;0e?(l=-this.nn+this.N,-e+this.N):(l=-1-e+this.N,n);for(var c=-1+this.N;f<=c;--c)h=h*m/l,--m,--l;if(this.N/(-i+this.N)>=u*Math.pow(h,a)){r=Math.pow(d(),a);break}r=Math.pow(d(),t)}this.selected_record+=e+1,this.a[this.idx_a++]=this.selected_record,this.N=-e+(-1+this.N),--this.nn,t=a,n=-e+n,o+=-13}1this.u[i])throw new Error("empty box detected: lower bound strictly greater than upper bound");this.sample=function(){for(var t=0;t(p=U,v=H,y=q,x=void 0,g=r(b=W),x=it.xmy(v,b),C=x.vectorNorm("two"),R=n(v),g+it.vectorDotProduct(x,y)+1/(2*p)*C*C+R+V);){if(-1!==A&&Af.data[C])throw new Error("infeasible problem detected");if(u.data[C]<=0)throw new Error("negative element detected in b");if(a.data[C]<=0)throw new Error("negative element detected in d");var E=(s.data[C]-l.data[C]*a.data[C])/u.data[C];d[C]=E,c[R++]=E;var M=(s.data[C]-f.data[C]*a.data[C])/u.data[C];w[C]=M,xg&&(g=F_i,y=E),F_ig&&(g=F_i,y=E)}if(g-C<=u)break;E=x,R=y;var M,A=(i.data[E]-m.data[E])*n.data[E],P=(m.data[R]-e.data[R])*n.data[R],z=P<=A?A:P,k=(e.data[E]-m.data[E])*n.data[E],_=(m.data[R]-i.data[R])*n.data[R],I=k<=_?k:_,V=C-g,F=t.data[E*t.nbColumns+E]/(n.data[E]*n.data[E])+t.data[R*t.nbColumns+R]/(n.data[R]*n.data[R])-2*t.data[E*t.nbColumns+R]/(n.data[E]*n.data[R]);if(0=r.getValue(u,1)-f?(a.setValue(u,1,r.getValue(u,1)),s-=r.getValue(u,1)-f):(a.setValue(u,1,f+s),s=0)}return[a.toArray(),it.vectorDotProduct(n,a)]}function S(t,r,n){var o=t.length;G(o,r,n);for(var i=0,e=0;e=o)return t;if("spectral"==n){if(0this.nbRows||r>this.nbColumns)throw new Error("index out of bounds when setting matrix value, ("+t+","+r+") in size ("+this.nbRows+","+this.nbColumns+")");return this.data[(t-1)*this.nbColumns+(r-1)]=n,this},setValue:function(t,r,n){return this.data[(t-1)*this.nbColumns+(r-1)]=n,this},getValueAt:function(t,r){if(t<1||r<1||t>this.nbRows||r>this.nbColumns)throw new Error("index out of bounds when getting matrix value, ("+t+","+r+") in size ("+this.nbRows+","+this.nbColumns+")");return this.data[(t-1)*this.nbColumns+(r-1)]},getValue:function(t,r){return this.data[(t-1)*this.nbColumns+(r-1)]},isSquare:function(){return this.nbRows===this.nbColumns},isSymmetric:function(t){if(null==t&&(t=0),!this.isSquare())return!1;for(var r=0;rt)return!1;return!0},isUnitDiagonal:function(t){if(null==t&&(t=0),!this.isSquare())return!1;for(var r=this.data[0],n=0;nt)},isCorrelationMatrix:function(t,r){if(null==t&&(t=0),null==r&&(r="boolean"),"exception"!=r&&"boolean"!=r)throw new Error("unexpected output type");try{if(!this.isSquare())throw"not square";if(!this.isSymmetric(t))throw"not symmetric";if(!this.isUnitDiagonal(t))throw"not unit diagonal";if(it.eig(this,{maxIter:-1,sortedEigenvalues:!0})[1].data[this.nbRows-1]<0)throw"not positive semi-definite";return!0}catch(t){if("exception"==r)throw new Error(t);return!1}},isCovarianceMatrix:function(t,r){if(null==t&&(t=0),null==r&&(r="boolean"),"exception"!=r&&"boolean"!=r)throw new Error("unexpected output type");try{if(!this.isSquare())throw"not square";if(!this.isSymmetric(t))throw"not symmetric";for(var n=this.data[0],o=0;ot&&(t=this.data[r]);return t},normalize:function(t){var r=_(this.nbRows,this.nbColumns,t),n=this.sum();if(0===n)throw new Error("sum of coefficients of matrix is null");for(var o=0;othis.nbRows)throw new Error("index out of bounds when getting matrix row, ("+t+") in size ("+this.nbRows+","+this.nbColumns+")");for(var n=_(this.nbColumns,1,r),o=0;othis.nbColumns)throw new Error("index out of bounds when getting matrix column, ("+t+") in size ("+this.nbRows+","+this.nbColumns+")");for(var n=_(this.nbRows,1,r),o=0;o=t[o])throw new Error("first parameter must be a sorted array");for(var i=1;i=t[i])throw new Error("second parameter must be a sorted array");var e=_(t.length,r.length,n);for(o=0;othis.nbRows)throw new Error("row index out of bounds: "+n);o=n-1,i=n,e=0,a=this.nbColumns}else if("column"==r){if(void 0===n)throw new Error("undefined row index");if(n<1||n>this.nbColumns)throw new Error("column index out of bounds: "+n);o=0,i=this.nbRows,e=n-1,a=n}else if(void 0!==r)throw new Error("unsupported matrix subset: "+r);if("one"==t){for(var s=0,u=o*this.nbColumns,l=o;li)return!1;return!0},it.xpy=function(t,r,n){if(!(t instanceof it))throw new Error("first input must be a matrix");if(!(r instanceof it))throw new Error("second input must be a matrix");if(t.nbColumns!==r.nbColumns||t.nbRows!==r.nbRows)throw new Error("input matrices sizes do not match: ("+t.nbRows+","+t.nbColumns+") - ("+r.nbRows+","+r.nbColumns+")");for(var o=_(t.nbRows,t.nbColumns,n),i=t.nbRows*t.nbColumns,e=0;eMath.abs(r)){o=(e=r/t)*(n=1/(a=(0<=t?1:-1)*Math.sqrt(1+e*e))),i=t*a}else{var e,a;n=(e=t/r)*(o=1/(a=(0<=r?1:-1)*Math.sqrt(1+e*e))),i=r*a}return[n,-o,i]}void 0===r&&(r={});var o=r.qLess||!1;if(!(t instanceof it))throw new Error("first input must be a matrix");if(t.nbRowsw){var v,b=u.data[d-1]-u.data[c-1];if(Math.abs(b)+p==Math.abs(b))v=a.data[(c-1)*a.nbColumns+(d-1)]/b;else{var y=.5*b/a.data[(c-1)*a.nbColumns+(d-1)];v=1/(Math.abs(y)+Math.sqrt(1+y*y)),y<0&&(v=-v)}var g=1/Math.sqrt(1+v*v),x=v*g,C=x/(1+g);b=v*a.data[(c-1)*a.nbColumns+(d-1)];for(f.data[c-1]-=b,f.data[d-1]+=b,u.data[c-1]-=b,u.data[d-1]+=b,a.data[(c-1)*a.nbColumns+(d-1)]=0,R=1;R<=c-1;++R){p=a.data[(R-1)*a.nbColumns+(c-1)],b=a.data[(R-1)*a.nbColumns+(d-1)];a.data[(R-1)*a.nbColumns+(c-1)]=p-x*(b+p*C),a.data[(R-1)*a.nbColumns+(d-1)]=b+x*(p-b*C)}for(R=c+1;R<=d-1;++R){p=a.data[(c-1)*a.nbColumns+(R-1)],b=a.data[(R-1)*a.nbColumns+(d-1)];a.data[(c-1)*a.nbColumns+(R-1)]=p-x*(b+p*C),a.data[(R-1)*a.nbColumns+(d-1)]=b+x*(p-b*C)}for(R=d+1;R<=e;++R){p=a.data[(c-1)*a.nbColumns+(R-1)],b=a.data[(d-1)*a.nbColumns+(R-1)];a.data[(c-1)*a.nbColumns+(R-1)]=p-x*(b+p*C),a.data[(d-1)*a.nbColumns+(R-1)]=b+x*(p-b*C)}for(var R=1;R<=e;++R){p=s.data[(R-1)*s.nbColumns+(c-1)],b=s.data[(R-1)*s.nbColumns+(d-1)];s.data[(R-1)*s.nbColumns+(c-1)]=p-x*(b+p*C),s.data[(R-1)*s.nbColumns+(d-1)]=b+x*(p-b*C)}}}for(c=1;c<=e;++c)l.data[c-1]+=f.data[c-1],u.data[c-1]=l.data[c-1],f.data[c-1]=0}var E=u,M=s;if(i){for(var A="function"==typeof Uint32Array?new Uint32Array(e):new Array(e),P=1;P<=e;++P)A[P-1]=P;A.sort(function(t,r){return u.data[r-1]-u.data[t-1]}),E=it.zeros(e,1),M=it.zeros(e,e);for(P=1;P<=e;++P){var z=A[P-1];E.data[P-1]=u.data[z-1];for(R=1;R<=e;++R)M.data[(R-1)*M.nbColumns+(P-1)]=s.data[(R-1)*s.nbColumns+(z-1)]}}return[M,E]},it.nullSpace=function(t,r){void 0===r&&(r={});var n=r.eps||void 0;if(!(t instanceof it))throw new Error("first input must be a matrix");var o=t.nbRows,i=t.nbColumns,e=null;if(i<=o){var a=(h=it.svdDecomposition(t,{maxIter:-1}))[0],s=h[1],u=h[2];for(void 0===n&&(n=o*(p(s.data[0])-s.data[0])),m=i;1<=m&&!(s.data[(m-1)*s.nbColumns+(m-1)]>n);--m);if((c=m)==i)e=it.zeros(i,1);else{e=new it.zeros(i,i-c);for(var l=c+1;l<=i;++l)for(var f=1;f<=i;++f)e.data[(f-1)*e.nbColumns+(l-(c+1)+1-1)]=u.data[(f-1)*u.nbColumns+(l-1)]}}else{var h,m,c;a=(h=it.svdDecomposition(t.transpose(),{maxIter:-1,svdForm:"full"}))[0],s=h[1],u=h[2];for(void 0===n&&(n=i*(p(s.data[0])-s.data[0])),m=o;1<=m&&!(s.data[(m-1)*s.nbColumns+(m-1)]>n);--m);if((c=m)==o)e=it.zeros(i,1);else{var d=new it.zeros(i,c);for(l=1;l<=c;++l)for(f=1;f<=i;++f)d.data[(f-1)*d.nbColumns+(l-1)]=a.data[(f-1)*a.nbColumns+(l-1)];var w=it.qrDecomposition(d)[0];for(e=new it.zeros(i,i-c),l=c+1;l<=i;++l)for(f=1;f<=i;++f)e.data[(f-1)*e.nbColumns+(l-(c+1)+1-1)]=w.data[(f-1)*w.nbColumns+(l-1)]}}return e},it.linsolveBackSubstitution=function(t,r){if(!(t instanceof it))throw new Error("first input must be a matrix");if(!(r instanceof it))throw new Error("second input must be a matrix");if(!t.isSquare())throw new Error("matrix is not square: ("+t.nbRows+","+t.nbColumns+")");if(t.nbRows!==r.nbRows)throw new Error("matrix and second member sizes do not match: ("+t.nbRows+","+t.nbColumns+") - ("+r.nbRows+","+r.nbColumns+")");if(1!==r.nbColumns)throw new Error("b is not a vector: ("+r.nbRows+","+r.nbColumns+")");for(var n=t.nbColumns,o=new it(r),i=n;1<=i;--i){var e=t.data[(i-1)*t.nbColumns+(i-1)];if(0==e)throw new Error("input matrix is not invertible: zero diagonal coefficient at index "+i);for(var a=i+1;a<=n;++a)o.data[i-1]-=t.data[(i-1)*t.nbColumns+(a-1)]*o.data[a-1];o.data[i-1]/=e}return o},it.linsolveForwardSubstitution=function(t,r){if(!(t instanceof it))throw new Error("first input must be a matrix");if(!(r instanceof it))throw new Error("second input must be a matrix");if(!t.isSquare())throw new Error("matrix is not square: ("+t.nbRows+","+t.nbColumns+")");if(t.nbRows!==r.nbRows)throw new Error("matrix and second member sizes do not match: ("+t.nbRows+","+t.nbColumns+") - ("+r.nbRows+","+r.nbColumns+")");if(1!==r.nbColumns)throw new Error("b is not a vector: ("+r.nbRows+","+r.nbColumns+")");for(var n=t.nbColumns,o=new it(r),i=1;i<=n;++i){var e=t.data[(i-1)*t.nbColumns+(i-1)];if(0==e)throw new Error("input matrix is not invertible: zero diagonal coefficient at index "+i);for(var a=1;a<=i-1;++a)o.data[i-1]-=t.data[(i-1)*t.nbColumns+(a-1)]*o.data[a-1];o.data[i-1]/=e}return o},it.randomOrthogonal=function(t){var r=it.normrnd(t,t),n=it.qrDecomposition(r),o=n[0],i=n[1],e=it.fill(1,t,function(t,r){return 0<=i.data[(r-1)*i.nbColumns+(r-1)]?1:-1});return it.elementwiseProduct(o,e)},it.randomCorrelation=function(t,n){if(void 0===n&&(n={}),void 0===n.eps&&(n.eps=1e-14),void 0===n.epsLambda&&(n.epsLambda=1e-8),void 0===n.lambda){n.lambda=new K(t).sample();for(var r=0;rn.epsLambda)throw new Error("input eigenvalues not summing to "+t);for(var i=n.eps,e=it.fill(1,t,function(t,r){return n.lambda[r-1]}),a=it.randomOrthogonal(t),s=it.axty(1,it.elementwiseProduct(a,e),a),u=1;ui){l=!1;break}1!=h&&(s.data[(f-1)*s.nbColumns+(f-1)]=1)}if(l)break;r=-1;var m=-1;for(f=1;f<=t;++f)s.data[(f-1)*s.nbColumns+(f-1)]<1&&-1===r&&(r=f),1>>1&1431655765))+(t>>>2&858993459))+(t>>>4)&252645135,t+=t>>>8,63&(t+=t>>>16)},nt.prototype={constructor:nt,resize:function(t){var r=this.words.length;if(!(r<t)){var n=t+this.WORD_LENGTH>>>this.WORD_LOG;if("function"==typeof Uint32Array){var o=new Uint32Array(n);o.set(this.words),this.words=o}else{this.words[n-1]=0;for(var i=r;i>>0).toString(2)).length>=this.WORD_LENGTH?o:new Array(this.WORD_LENGTH-o.length+1).join("0")+o}return t},set:function(t){return this.words.length<>>this.WORD_LOG]|=1<>>this.WORD_LOG]|=1<>>this.WORD_LOG]&=~(1<>>this.WORD_LOG]&1<>>this.WORD_LOG]^=1<=h&&(l=i[e],h=u[f=e]),u[e]<=d&&(m=i[e],d=u[c=e]);if(t.getValueAt(l,m)>r){var w=l===m?[l]:[l,m];i[f]=null,i[c]=null;for(e=0;er&&(p.push(i[e]),i[e]=null);if(n.push(p),l!==m){var v=[m];i[c]=null;for(e=0;er&&(v.push(i[e]),i[e]=null);n.push(v)}}}var b=[];for(e=0;eo;++i)e.push(this.cornerPortfolios[i]);e.push([n,o]),this.cornerPortfolios=e}}else{if("minVolatility"!=t)throw new Error("unknown constraint type");if(this.getLowestVolatility()o;++i)e.push(this.cornerPortfolios[i]);e.push([n,o]),this.cornerPortfolios=e}}},Z.prototype.computeMaximumSharpeRatioEfficientPortfolio=function(t){var r=function(t){var r=this.cornerPortfolios.length-1,n=0;if(r==n)return r;for(;r-n!=1;){var o=Math.floor((r+n)/2),i=this.cornerPortfolios[o][0],e=this.computePortfolioSharpeRatio(i,t),a=o+1,s=this.cornerPortfolios[a][0],u=this.computePortfolioSharpeRatio(s,t);if(u=this.highestRiskTolerance&&(this.highestRiskTolerancePortfolio=n,this.highestRiskTolerance=o)}}else{if("minVolatility"!=t)throw new Error("unknown constraint type");if(this.getLowestVolatility()=this.highestRiskTolerance&&(this.highestRiskTolerancePortfolio=n,this.highestRiskTolerance=o)}}},et.prototype.computeMaximumSharpeRatioEfficientPortfolio=function(o){var i,t=this.nbAssets,e=this.mu,r=this.sigma,n=this.lowerBounds,a=this.upperBounds,s=(this.epsEfficientPortfolioComputation,r),u=it.ones(t,1),l=n,f=a,h=this,m=function(t,r,n,o){void 0===o&&(o={});var i=o.maxIter;void 0===i&&(i=-1);var e=o.eps;void 0===e&&(e=1e-6);var a=(Math.sqrt(5)-1)/2,s=r,u=n,l=u-a*(u-s),f=s+a*(u-s),h=t(r),m=t(n),c=t(l),d=t(f);if(na.data[O-1]&&(R.data[O-1]=a.data[O-1]);else for(O=1;O<=x;++O)R.data[O-1]<0&&(R.data[O-1]=0);if(E=it.axpby(2,R,-1,C,E),f&&(w=it.xpy(d,it.elementwiseProduct(it.xmy(it.xy(o,E,z),t,z),I,z),w)),h){y=it.xpy(b,it.elementwiseProduct(it.xmy(it.xy(i,E,k),r,k),V,k),y);for(O=1;O<=v;++O)y.data[O-1]<0&&(y.data[O-1]=0)}var T=(M=it.xmy(R,C,M)).vectorNorm("infinity"),S=R.vectorNorm("infinity"),N=0,W=0;f&&(N=(p=it.xmy(w,d,p)).vectorNorm("infinity"),W=w.vectorNorm("infinity"));var q=0,B=0;if(h&&(q=(g=it.xmy(y,b,g)).vectorNorm("infinity"),B=y.vectorNorm("infinity")),T<=u*S&&N<=u*W&&q<=u*B)break;C=it.copy(R,C),f&&(d=it.copy(w,d)),h&&(b=it.copy(y,b))}return[R,it.vectorDotProduct(n,R)]}(s,u,it.fill(e+(r?0:1),i+1,function(t,r){return t<=e?r<=i?-n[r-1][t-1]:1:t==e+1?r<=i?1:0:void 0}),it.fill(e+(r?0:1),1,function(t,r){return t<=e?0:t==e+1?1:void 0}),a,it.fill(i+1,1,function(t,r){return t<=i?0:-1/0}),it.fill(i+1,1,function(t,r){return t<=i?1:1/0}),{maxIter:-1})[0],f=l.toArray(function(t,r,n){return t!=i+1}),h=l.data[i];return!0===o?[f,h]:f},y.minimumCorrelationWeights=function(t,r){var n=(t=new it(t).toCovarianceMatrix()).getVariances(),o=n.elemMap(function(t,r,n){return 1/Math.sqrt(n)}),i=t.getCorrelationMatrix(),e=i.nbRows;if(e<=2)return y.inverseVolatilityWeights(n,r);for(var a=i.toArray(function(t,r,n){return tr[0]?-1:1}):1==r&&n.sort(function(t,r){return t[0]=n[s]&&0o[s])throw new Error("internal error: asset present in the portfolio, but strictly above its upper bound")}if(a=Math.max(0,a),I=n[s]&&0=n[d]&&0=n[s]&&0h[s]){m=!1;break}if(a)for(s=0;sa[s]){m=!1;break}if(m){var c=t(h);cn[m-1]&&(x=n[m-1]),o.data[m-1]=x,i.data[m-1]=Math.log(x),s-=d*k.data[m-1],s+=i.data[m-1]*k.data[m-1];for(var M=1;M<=S;++M)e.data[M-1]+=z.data[(M-1)*z.nbColumns+(m-1)]*x,e.data[M-1]-=z.data[(M-1)*z.nbColumns+(m-1)]*c;if(a=I(o,e),"acf"===_.coordinatesSampler){var A=h-(.5*a-s);1==f?l.updateAverageGain(A):l.updateSchedulingPreference(m,A)}}var P=.5*a-s;if(-1==T&&Math.abs(P-u)<=F)break;u=P}return o}void 0===_&&(_={}),void 0===_.constraints&&(_.constraints={}),void 0===_.eps&&(_.eps=1e-10),void 0===_.epsSdp&&(_.epsSdp=1e-12),void 0===_.maxCycles&&(_.maxCycles=1e4),void 0===_.nbCycles&&(_.nbCycles=-1),void 0===_.outputPortfolioVolatility&&(_.outputPortfolioVolatility=!1),void 0===_.coordinatesSampler&&(_.coordinatesSampler="cyclic");var V,F=_.eps,o=_.epsSdp,O=_.maxCycles,T=_.nbCycles,t=_.outputPortfolioVolatility;if("cyclic"===_.coordinatesSampler)V=function(t){this.n=t,this.k=t,this.sampleCoordinate=function(){return this.k==this.n?-1:++this.k},this.generateCoordinates=function(){this.k=0}};else if("shuffledCyclic"===_.coordinatesSampler)V=function(t){this.n=t,this.k=t,this.r="function"==typeof Uint32Array?new Uint32Array(t):new Array(t);for(var r=0;rthis.p_max&&(n=this.p_max),this.prefsum=this.prefsum+n-this.pref[t-1],this.pref[t-1]=n,this.average_gain=(1-this.gain_learning_rate)*this.average_gain+this.gain_learning_rate*r},this.updateAverageGain=function(t){this.average_gain+=t/this.n}}}var S=(z=new it(z)).nbRows,n=(k=new it(k),null),i=null;if(_.constraints.minWeights&&(n=_.constraints.minWeights,!_.constraints.maxWeights)){i="function"==typeof Float64Array?new Float64Array(S):new Array(S);for(var e=0;e