67 lines
1.6 KiB
Go
67 lines
1.6 KiB
Go
package logic
|
|
|
|
import (
|
|
"math"
|
|
"sort"
|
|
)
|
|
|
|
func CalculateCardValue(baseSales, exactSales []float64, factors map[string]float64) float64 {
|
|
bpRaw := calculateBasePrice(baseSales)
|
|
emp := 0.0
|
|
if len(exactSales) > 0 {
|
|
emp = calculateBasePrice(exactSales)
|
|
}
|
|
bpFinal := calculateFinalBasePrice(bpRaw, emp, len(exactSales))
|
|
value := (bpFinal * factors["GF"] * factors["RF"] * factors["EF"] * factors["ST"] * factors["DF"] * factors["AF"] * factors["MF"]) + factors["TAF"]
|
|
return math.Round(value*100) / 100
|
|
}
|
|
|
|
func calculateBasePrice(sales []float64) float64 {
|
|
cleanSales := removeOutliers(sales)
|
|
median := calculateMedian(cleanSales)
|
|
stdDev := calculateStdDev(cleanSales, median)
|
|
vaf := 1 + (stdDev/median)*0.1
|
|
return median * vaf
|
|
}
|
|
|
|
func calculateFinalBasePrice(bp, emp float64, exactCount int) float64 {
|
|
weight := 0.0
|
|
switch {
|
|
case exactCount >= 10:
|
|
weight = 0.8
|
|
case exactCount >= 5:
|
|
weight = 0.6
|
|
case exactCount >= 2:
|
|
weight = 0.4
|
|
}
|
|
return (bp * (1 - weight)) + (emp * weight)
|
|
}
|
|
|
|
func removeOutliers(sales []float64) []float64 {
|
|
median := calculateMedian(sales)
|
|
var filtered []float64
|
|
for _, s := range sales {
|
|
if s >= median*0.7 && s <= median*1.3 {
|
|
filtered = append(filtered, s)
|
|
}
|
|
}
|
|
return filtered
|
|
}
|
|
|
|
func calculateMedian(sales []float64) float64 {
|
|
sort.Float64s(sales)
|
|
n := len(sales)
|
|
if n%2 == 0 {
|
|
return (sales[n/2-1] + sales[n/2]) / 2
|
|
}
|
|
return sales[n/2]
|
|
}
|
|
|
|
func calculateStdDev(sales []float64, mean float64) float64 {
|
|
var sum float64
|
|
for _, s := range sales {
|
|
sum += math.Pow(s-mean, 2)
|
|
}
|
|
return math.Sqrt(sum / float64(len(sales)))
|
|
}
|