Esempio n. 1
0
        private static double[] MapDensityPointsToDiscretePrices(double[] densityPoints, double[] pricesArray)
        {
            Common.DoubleList newList = new Common.DoubleList();

            for (int i = 0; i < densityPoints.Length; i++)
            {
                for (int j = 0; j < pricesArray.Length; j++)
                {
                    if (pricesArray[j] <= densityPoints[i] && pricesArray[j + 1] >= densityPoints[i])
                    {
                        if (densityPoints[i] - pricesArray[j] > pricesArray[j + 1] - densityPoints[i])
                        {
                            newList.Add(pricesArray[j + 1]);
                        }
                        else
                        {
                            newList.Add(pricesArray[j]);
                        }
                        break;
                    }
                }
            }

            newList.Sort();
            return(newList.ToArray());
        }
Esempio n. 2
0
        public static double[] GetThresholdsForClusters(int cMAType, double[] derivatives)
        {
            Common.DoubleList minThresholdRequiredList      = new Common.DoubleList();
            Common.DoubleList finalMinThresholdRequiredList = new Common.DoubleList();

            double?minThresholdRequired      = 0;
            double?localMinThresholdRequired = 0;

            while (minThresholdRequired != null)
            {
                minThresholdRequired = null;
                if (derivatives.Length >= 2)
                {
                    for (int j = 0; j < derivatives.Length - 1; j++)
                    {
                        double localThreshold = derivatives[j] > derivatives[j + 1] ? derivatives[j] : derivatives[j + 1];
                        if (localThreshold > localMinThresholdRequired)
                        {
                            if (minThresholdRequired == null)
                            {
                                minThresholdRequired = localThreshold;
                            }
                            else if (minThresholdRequired > localThreshold)
                            {
                                minThresholdRequired = localThreshold;
                            }
                        }
                    }
                    if (minThresholdRequired != null)
                    {
                        localMinThresholdRequired = minThresholdRequired;
                        minThresholdRequiredList.Add(minThresholdRequired.GetValueOrDefault());
                    }
                }
            }

            foreach (var val in minThresholdRequiredList)
            {
                double?maxAllowedThreshold = null;
                switch (cMAType)
                {
                case (int)CMAType.Regular:
                    maxAllowedThreshold = MAX_REDQ_THRESHOLD;
                    break;

                case (int)CMAType.ShortSale:
                    maxAllowedThreshold = MAX_SHORTSALE_THRESHOLD;
                    break;

                case (int)CMAType.Rehab:
                    maxAllowedThreshold = MAX_REHAB_THRESHOLD;
                    break;
                }
                if (val <= maxAllowedThreshold)
                {
                    finalMinThresholdRequiredList.Add(val);
                }
            }
            return(finalMinThresholdRequiredList.ToArray());
        }
Esempio n. 3
0
        public DoubleList SubList(Func <double, bool> filter)
        {
            DoubleList retList = new Common.DoubleList();

            foreach (var val in this)
            {
                if (filter(val))
                {
                    retList.Add(val);
                }
            }
            return(retList);
        }
Esempio n. 4
0
        private static DAL.AutomatedSuggestedPropertyPrices getSuggestedPropertyPrices(int cMAType, string subjectBBL, List <DAL.CMAResult> results)
        {
            DAL.AutomatedSuggestedPropertyPrices price = new DAL.AutomatedSuggestedPropertyPrices();
            price.SubjectBBL = subjectBBL;

            var subject = DAL.CMA.GetSubject(subjectBBL);

            if (subject == null)
            {
                price.message = "Error locating Subject Information";
                return(price);
            }

            double?GLA = subject.GLA.GetValueOrDefault();

            if (GLA == null || GLA == 0)
            {
                price.message = "GLA is null or zero for Subject";
                return(price);
            }

            if (results.Count == 0)
            {
                price.message = "No Comparables found";
                return(price);
            }

            Common.DoubleList pricessqft = new Common.DoubleList();
            foreach (var comp in results)
            {
                pricessqft.Add(Math.Round(comp.DeedAmount.GetValueOrDefault() / comp.GLA.GetValueOrDefault(), 0));
            }
            pricessqft.Sort();

            double medianPrice = Common.Statistics.Percentile(pricessqft, 50);

            double[] pricesArray = pricessqft.ToArray();
            //Round Prices
            for (int j = 0; j < pricesArray.Length; j++)
            {
                pricesArray[j] = Math.Round(pricesArray[j], 0);
            }

            //What is the minimum threshold required to get a cluster from our comparables
            // double[] derivatives = GetSimplePriceDerivates(pricesArray);
            // double[] minThresholds = GetThresholdsForClusters(cMAType, derivatives);

            //KDE Approach
            double[] kDEDensityPoints    = ApplyGaussianKDE(pricesArray);
            double[] modifiedDerivatives = GetModifiedPriceDerivatesUsingKDEDensityPoints(pricesArray, kDEDensityPoints);
            double[] minKDEThresholds    = GetThresholdsForClusters(cMAType, modifiedDerivatives);

            if (minKDEThresholds.Length < 1)
            {
                price.message = "No price clusters can be established based on threshold percentages defined.";
                return(price);
            }

            //Using minThresholds find clusters in comparables with KDE points
            //List<KDECluster> clusters = FindClustersWithKDE(cMAType, kDEDensityPoints, minThresholds, pricesArray);
            List <KDECluster> clusters = FindClustersWithKDE(cMAType, kDEDensityPoints, minKDEThresholds, pricesArray);

            //Using minThresholds find clusters in comparables Old Approach
            //Clusters clusterInfo = FindClusters(cMAType, derivatives, minThresholds);

            //Select the appropriate cluster based on CMAType price derivatives approach
            //ClusterSelection clusterSelection = SelectCluster(cMAType, clusterInfo);

            // ClusterSelection clusterSelectionKDE = SelectCluster(cMAType, clusters, medianPrice);
            ClusterSelection clusterSelectionKDE = SelectCluster(cMAType, clusters, medianPrice);

            //mix and max values from the cluster
            double?minClusterValue = null, maxClusterValue = null;


            if (clusterSelectionKDE.kDEcluster != null)
            {
                minClusterValue = clusterSelectionKDE.kDEcluster.minValue;
                maxClusterValue = clusterSelectionKDE.kDEcluster.maxValue;
            }

            /*
             * else if (clusterSelection.clusterValue != -1) //old Approach
             * {
             *  minClusterValue = Math.Round(pricesArray[clusterInfo.clusters[clusterSelection.clusterValue]],0);
             *  maxClusterValue = Math.Round(pricesArray[clusterInfo.clusters[clusterSelection.clusterValue] + 1],0);
             *  int i = clusterInfo.clusters[clusterSelection.clusterValue] + 1;
             *  while (i < derivatives.Length)
             *  {
             *      if (derivatives[i] <= clusterInfo.minThresholdRequired.GetValueOrDefault())
             *          maxClusterValue = Math.Round(pricesArray[i + 1],0);
             *      else
             *          break;
             *      i++;
             *  }
             *  price.message = clusterSelection.message;
             * }
             */

            //use min max values to compute subject price
            if (minClusterValue != null && maxClusterValue != null)
            {
                price.SubjectBBL = subjectBBL;

                price.minClusterValue = minClusterValue;
                price.maxClusterValue = maxClusterValue;

                price.LowPrice    = Math.Round(pricessqft.Min(x => x >= minClusterValue && x <= maxClusterValue) * GLA.GetValueOrDefault(), 0);
                price.AVGPrice    = Math.Round(pricessqft.Average(x => x >= minClusterValue && x <= maxClusterValue) * GLA.GetValueOrDefault(), 0);
                price.MedianPrice = Math.Round(Common.Statistics.Percentile(pricessqft.SubList(x => x >= minClusterValue && x <= maxClusterValue), 50) * GLA.GetValueOrDefault(), 0);
                price.HighPrice   = Math.Round(pricessqft.Max(x => x >= minClusterValue && x <= maxClusterValue) * GLA.GetValueOrDefault(), 0);
            }
            else
            {
                price.SubjectBBL = subjectBBL;
                price.message    = clusterSelectionKDE.message;
            }

            return(price);
        }
Esempio n. 5
0
        private static double[] ApplyGaussianKDE(double[] pricesArray)
        {
            double minValue, maxValue;
            int    distance;
            int    kernelSize;

            Common.DoubleList localDensityPoints = new Common.DoubleList();

            if (pricesArray.Length <= 1)
            {
                return(localDensityPoints.ToArray());
            }

            minValue = pricesArray[0];
            maxValue = pricesArray[pricesArray.Length - 1];
            distance = Convert.ToInt32(Math.Round(maxValue - minValue) + 1);

            kernelSize = distance / (pricesArray.Length - 1);
            if (kernelSize % 2 == 0)
            {
                kernelSize += 1;
            }

            double[] SampleArray = new double[distance];

            for (int i = 0; i < distance; i++)
            {
                SampleArray[i] = 0;
            }

            for (int j = 0; j < pricesArray.Length; j++)
            {
                int samplePoint = Convert.ToInt32(pricesArray[j] - minValue);
                SampleArray[samplePoint] += 1000;
            }

            double[] densityArray = Common.Statistics.ApplyGaussianKDEV2(SampleArray, kernelSize, GAUSSIAN_SIGMA);

            double?localMaxima = 0;
            int?   direction   = null;

            for (int i = 0; i < distance; i++)
            {
                if (localMaxima == null)
                {
                    localMaxima = densityArray[i];
                }
                else if (densityArray[i] >= localMaxima)
                {
                    direction   = 1;
                    localMaxima = densityArray[i];
                }
                else
                {
                    if (direction == 1)
                    {
                        localDensityPoints.Add(i + minValue);
                    }
                    direction   = 0;
                    localMaxima = densityArray[i];
                }
            }

            return(localDensityPoints.ToArray());
        }