Ejemplo 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());
        }
Ejemplo n.º 2
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);
        }