diff --git a/filter.go b/filter.go index f79decc..68ae446 100644 --- a/filter.go +++ b/filter.go @@ -4,7 +4,10 @@ package mop -import "strings" +import ( + "strings" + "strconv" +) // Filter gets called to sort stock quotes by one of the columns. The // setup is rather lengthy; there should probably be more concise way @@ -20,32 +23,47 @@ func NewFilter(profile *Profile) *Filter { } } +// Changes money and % notation to a plain float for math, comparisons. +func stringToNumber (numberString string) float64 { + // If the string "$3.6B" is passed in, the returned float will be 3.6E+09. + // If 0.03% is passed in, the returned float will be 0.03 (NOT 0.0003!). + newString := strings.TrimSpace(numberString) // Take off whitespace. + newString = strings.Replace(newString,"$","",1) // Remove the $ symbol. + newString = strings.Replace(newString,"%","",1) // Remove the $ symbol. + newString = strings.Replace(newString,"K","E+3",1) // Thousand (kilo) + newString = strings.Replace(newString,"M","E+6",1) // Million + newString = strings.Replace(newString,"B","E+9",1) // Billion + newString = strings.Replace(newString,"T","E+12",1) // Trillion + finalValue, _ := strconv.ParseFloat(newString, 64) + return finalValue +} + // Apply builds a list of sort interface based on current sort // order, then calls sort.Sort to do the actual job. func (filter *Filter) Apply(stocks []Stock) []Stock { var filteredStocks []Stock for _, stock := range stocks { - var values = map[string]interface{}{ - "ticker": strings.TrimSpace(stock.Ticker), - "last": m(stock.LastTrade), - "change": c(stock.Change), - "changePercent": c(stock.ChangePct), - "open": m(stock.Open), - "low": m(stock.Low), - "high": m(stock.High), - "low52": m(stock.Low52), - "high52": m(stock.High52), - "volume": m(stock.Volume), - "avgVolume": m(stock.AvgVolume), - "pe": m(stock.PeRatio), - "peX": m(stock.PeRatioX), - "dividend": m(stock.Dividend), - "yield": m(stock.Yield), - "mktCap": m(stock.MarketCap), - "mktCapX": m(stock.MarketCapX), - "advancing": stock.Advancing, - } + var values = make(map[string]interface{}) + // Make conversions from the strings to floats where necessary. + values["ticker"] = strings.TrimSpace(stock.Ticker) // Remains string + values["last"] = stringToNumber(stock.LastTrade) + values["change"] = stringToNumber(stock.Change) + values["changePercent"] = stringToNumber(stock.ChangePct) + values["open"] = stringToNumber(stock.Open) + values["low"] = stringToNumber(stock.Low) + values["high"] = stringToNumber(stock.High) + values["low52"] = stringToNumber(stock.Low52) + values["high52"] = stringToNumber(stock.High52) + values["dividend"] = stringToNumber(stock.Dividend) + values["yield"] = stringToNumber(stock.Yield) + values["mktCap"] = stringToNumber(stock.MarketCap) + values["mktCapX"] = stringToNumber(stock.MarketCapX) + values["volume"] = stringToNumber(stock.Volume) + values["avgVolume"] = stringToNumber(stock.AvgVolume) + values["pe"] = stringToNumber(stock.PeRatio) + values["peX"] = stringToNumber(stock.PeRatioX) + values["advancing"] = stock.Advancing // Remains bool. result, err := filter.profile.filterExpression.Evaluate(values)