Esempio n. 1
0
    public double[] ScaleSeries(double[] rawWeights_, double targetVol_, bool diagOnly_=false, bool useNMath_=true)
    {
      // catch empty weights coming in

      if (Math.Abs(rawWeights_.Select(x => Math.Abs(x)).Sum()) < 0.00000001)
        return rawWeights_;

      var matrixRawWeights = new double[1, rawWeights_.Length];
      for (int i = 0; i < rawWeights_.Length; ++i)
        matrixRawWeights[0, i] = rawWeights_[i];

      var scalingFactor = 0d;

      if (useNMath_)
      {
        // put weights and covariance into NMath constructs
        var weights = new NMathCore.DoubleMatrix(matrixRawWeights);
        var cov = new NMathCore.DoubleMatrix((diagOnly_) ? DiagonalData : Data);

        // multiply out to get variance
        var a = NMathCore.NMathFunctions.Product(weights, cov);
        var b = NMathCore.NMathFunctions.Product(a, weights.Transpose());

        // extract vol
        var vol = Math.Sqrt(b[0, 0]);
        if (vol == 0d) return rawWeights_; // must be empty weights coming in
        scalingFactor = vol/targetVol_;
      }
      else
      {
        var weights = Matrix<double>.Build.Dense(1, rawWeights_.Length, rawWeights_);
        var cov = Matrix<double>.Build.Dense(Data.GetLength(0), Data.GetLength(1),
          delegate(int i, int j) { return diagOnly_ ? DiagonalData[i, j] : Data[i, j]; });

        var wCov = weights * cov;
        var b = wCov * weights.Transpose();

        var vol = Math.Sqrt(b[0, 0]);
        if (vol == 0d) return rawWeights_;
        scalingFactor = vol/targetVol_;
      }

      double[] ret = new double[rawWeights_.Length];

      // scale the weights
      for (int j = 0; j < ret.Length; ++j)
        if (scalingFactor == 0)
          ret[j] = 0;
        else
          ret[j] = rawWeights_[j] / scalingFactor;

      return ret;
    }