Column sorting

master
Michael Dvorkin 11 years ago
parent 4d4ed17228
commit e0b8453680
  1. 94
      lib/layout.go
  2. 91
      lib/sorter.go
  3. 7
      lib/yahoo_market.go
  4. 6
      lib/yahoo_quotes.go

@ -8,6 +8,7 @@ import (
`regexp`
`strings`
`text/template`
`sort`
`time`
)
@ -24,23 +25,23 @@ type Layout struct {
//-----------------------------------------------------------------------------
func (self *Layout) Initialize() *Layout {
self.columns = make([]Column, TotalColumns)
self.columns[0] = Column{ -7, `Ticker`}
self.columns[1] = Column{ 10, `Last`}
self.columns[2] = Column{ 10, `Change`}
self.columns[3] = Column{ 10, `%Change`}
self.columns[4] = Column{ 10, `Open`}
self.columns[5] = Column{ 10, `Low`}
self.columns[6] = Column{ 10, `High`}
self.columns[7] = Column{ 10, `52w Low`}
self.columns[8] = Column{ 10, `52w High`}
self.columns[9] = Column{ 11, `Volume`}
self.columns[10] = Column{ 11, `AvgVolume`}
self.columns[11] = Column{ 10, `P/E`}
self.columns[12] = Column{ 10, `Dividend`}
self.columns[13] = Column{ 10, `Yield`}
self.columns[14] = Column{ 11, `MktCap`}
self.columns = []Column{
{ -7, `Ticker`},
{ 10, `Last`},
{ 10, `Change`},
{ 10, `%Change`},
{ 10, `Open`},
{ 10, `Low`},
{ 10, `High`},
{ 10, `52w Low`},
{ 10, `52w High`},
{ 11, `Volume`},
{ 11, `AvgVolume`},
{ 10, `P/E`},
{ 10, `Dividend`},
{ 10, `Yield`},
{ 11, `MktCap`},
}
return self
}
@ -68,7 +69,7 @@ func (self *Layout) Market(m *Market) string {
markup += "\n"
markup += `{{.Advances.name}}: {{.Advances.nyse}} ({{.Advances.nysep}}) on NYSE and {{.Advances.nasdaq}} ({{.Advances.nasdaqp}}) on Nasdaq. `
markup += `{{.Declines.name}}: {{.Declines.nyse}} ({{.Declines.nysep}}) on NYSE and {{.Declines.nasdaq}} ({{.Declines.nasdaqp}}) on Nasdaq`
if !m.Open {
if m.IsClosed {
markup += `<right>U.S. markets closed</right>`
}
markup += "\n"
@ -105,7 +106,7 @@ func (self *Layout) Quotes(quotes *Quotes) string {
{{.Header}}
{{range.Stocks}}{{.Color}}{{.Ticker}}{{.LastTrade}}{{.Change}}{{.ChangePercent}}{{.Open}}{{.Low}}{{.High}}{{.Low52}}{{.High52}}{{.Volume}}{{.AvgVolume}}{{.PeRatio}}{{.Dividend}}{{.Yield}}{{.MarketCap}}
{{range.Stocks}}{{.Color}}{{.Ticker}}{{.LastTrade}}{{.Change}}{{.ChangePct}}{{.Open}}{{.Low}}{{.High}}{{.Low52}}{{.High52}}{{.Volume}}{{.AvgVolume}}{{.PeRatio}}{{.Dividend}}{{.Yield}}{{.MarketCap}}
{{end}}`
//markup += fmt.Sprintf("[%v]", quotes.profile.Grouped)
template, err := template.New(`quotes`).Parse(markup)
@ -140,12 +141,15 @@ func (self *Layout) Header(profile *Profile) string {
//-----------------------------------------------------------------------------
func (self *Layout) prettify(quotes *Quotes) []Stock {
var sorts []sort.Interface
pretty := make([]Stock, len(quotes.stocks))
for i, q := range group(quotes) {
//for i, q := range group(quotes) {
for i, q := range quotes.stocks {
pretty[i].Ticker = pad(q.Ticker, self.columns[0].width)
pretty[i].LastTrade = pad(with_currency(q.LastTrade), self.columns[1].width)
pretty[i].Change = pad(with_currency(q.Change), self.columns[2].width)
pretty[i].ChangePercent = pad(last_of_pair(q.ChangePercent), self.columns[3].width)
pretty[i].ChangePct = pad(last_of_pair(q.ChangePct), self.columns[3].width)
pretty[i].Open = pad(with_currency(q.Open), self.columns[4].width)
pretty[i].Low = pad(with_currency(q.Low), self.columns[5].width)
pretty[i].High = pad(with_currency(q.High), self.columns[6].width)
@ -158,6 +162,50 @@ func (self *Layout) prettify(quotes *Quotes) []Stock {
pretty[i].Yield = pad(with_percent(q.Yield), self.columns[13].width)
pretty[i].MarketCap = pad(with_currency(q.MarketCapX), self.columns[14].width)
}
if quotes.profile.Ascending {
sorts = []sort.Interface{
ByTickerAsc { pretty },
ByLastTradeAsc { pretty },
ByChangeAsc { pretty },
ByChangePctAsc { pretty },
ByOpenAsc { pretty },
ByLowAsc { pretty },
ByHighAsc { pretty },
ByLow52Asc { pretty },
ByHigh52Asc { pretty },
ByVolumeAsc { pretty },
ByAvgVolumeAsc { pretty },
ByPeRatioAsc { pretty },
//ByPeRatioXAsc { pretty },
ByDividendAsc { pretty },
ByYieldAsc { pretty },
ByMarketCapAsc { pretty },
//ByMarketCapXAsc { pretty },
}
} else {
sorts = []sort.Interface{
ByTickerDesc { pretty },
ByLastTradeDesc { pretty },
ByChangeDesc { pretty },
ByChangePctDesc { pretty },
ByOpenDesc { pretty },
ByLowDesc { pretty },
ByHighDesc { pretty },
ByLow52Desc { pretty },
ByHigh52Desc { pretty },
ByVolumeDesc { pretty },
ByAvgVolumeDesc { pretty },
ByPeRatioDesc { pretty },
//ByPeRatioXDesc { pretty },
ByDividendDesc { pretty },
ByYieldDesc { pretty },
ByMarketCapDesc { pretty },
//ByMarketCapXDesc { pretty },
}
}
sort.Sort(sorts[quotes.profile.SortColumn])
return pretty
}
@ -188,9 +236,9 @@ func group(quotes *Quotes) []Stock {
func arrow_for(column int, profile *Profile) string {
if column == profile.SortColumn {
if profile.Ascending {
return string('\U00002193')
} else {
return string('\U00002191')
} else {
return string('\U00002193')
}
}
return ``

@ -0,0 +1,91 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
package mop
import (
`strings`
`strconv`
)
type Sortable []Stock
func (list Sortable) Len() int { return len(list) }
func (list Sortable) Swap(i, j int) { list[i], list[j] = list[j], list[i] }
type ByTickerAsc struct { Sortable }
type ByLastTradeAsc struct { Sortable }
type ByChangeAsc struct { Sortable }
type ByChangePctAsc struct { Sortable }
type ByOpenAsc struct { Sortable }
type ByLowAsc struct { Sortable }
type ByHighAsc struct { Sortable }
type ByLow52Asc struct { Sortable }
type ByHigh52Asc struct { Sortable }
type ByVolumeAsc struct { Sortable }
type ByAvgVolumeAsc struct { Sortable }
type ByPeRatioAsc struct { Sortable }
type ByPeRatioXAsc struct { Sortable }
type ByDividendAsc struct { Sortable }
type ByYieldAsc struct { Sortable }
type ByMarketCapAsc struct { Sortable }
type ByMarketCapXAsc struct { Sortable }
type ByTickerDesc struct { Sortable }
type ByLastTradeDesc struct { Sortable }
type ByChangeDesc struct { Sortable }
type ByChangePctDesc struct { Sortable }
type ByOpenDesc struct { Sortable }
type ByLowDesc struct { Sortable }
type ByHighDesc struct { Sortable }
type ByLow52Desc struct { Sortable }
type ByHigh52Desc struct { Sortable }
type ByVolumeDesc struct { Sortable }
type ByAvgVolumeDesc struct { Sortable }
type ByPeRatioDesc struct { Sortable }
type ByPeRatioXDesc struct { Sortable }
type ByDividendDesc struct { Sortable }
type ByYieldDesc struct { Sortable }
type ByMarketCapDesc struct { Sortable }
type ByMarketCapXDesc struct { Sortable }
func (list ByTickerAsc) Less(i, j int) bool { return list.Sortable[i].Ticker < list.Sortable[j].Ticker }
func (list ByLastTradeAsc) Less(i, j int) bool { return list.Sortable[i].LastTrade < list.Sortable[j].LastTrade }
func (list ByChangeAsc) Less(i, j int) bool { return z(list.Sortable[i].Change) < z(list.Sortable[j].Change) }
func (list ByChangePctAsc) Less(i, j int) bool { return z(list.Sortable[i].ChangePct) < z(list.Sortable[j].ChangePct) }
func (list ByOpenAsc) Less(i, j int) bool { return list.Sortable[i].Open < list.Sortable[j].Open }
func (list ByLowAsc) Less(i, j int) bool { return list.Sortable[i].Low < list.Sortable[j].Low }
func (list ByHighAsc) Less(i, j int) bool { return list.Sortable[i].High < list.Sortable[j].High }
func (list ByLow52Asc) Less(i, j int) bool { return list.Sortable[i].Low52 < list.Sortable[j].Low52 }
func (list ByHigh52Asc) Less(i, j int) bool { return list.Sortable[i].High52 < list.Sortable[j].High52 }
func (list ByVolumeAsc) Less(i, j int) bool { return list.Sortable[i].Volume < list.Sortable[j].Volume }
func (list ByAvgVolumeAsc) Less(i, j int) bool { return list.Sortable[i].AvgVolume < list.Sortable[j].AvgVolume }
func (list ByPeRatioAsc) Less(i, j int) bool { return list.Sortable[i].PeRatio < list.Sortable[j].PeRatio }
func (list ByPeRatioXAsc) Less(i, j int) bool { return list.Sortable[i].PeRatioX < list.Sortable[j].PeRatioX }
func (list ByDividendAsc) Less(i, j int) bool { return list.Sortable[i].Dividend < list.Sortable[j].Dividend }
func (list ByYieldAsc) Less(i, j int) bool { return list.Sortable[i].Yield < list.Sortable[j].Yield }
func (list ByMarketCapAsc) Less(i, j int) bool { return list.Sortable[i].MarketCap < list.Sortable[j].MarketCap }
func (list ByMarketCapXAsc) Less(i, j int) bool { return list.Sortable[i].MarketCapX < list.Sortable[j].MarketCapX }
func (list ByTickerDesc) Less(i, j int) bool { return list.Sortable[j].Ticker < list.Sortable[i].Ticker }
func (list ByLastTradeDesc) Less(i, j int) bool { return list.Sortable[j].LastTrade < list.Sortable[i].LastTrade }
func (list ByChangeDesc) Less(i, j int) bool { return z(list.Sortable[j].Change) < z(list.Sortable[i].Change) }
func (list ByChangePctDesc) Less(i, j int) bool { return z(list.Sortable[j].ChangePct) < z(list.Sortable[i].ChangePct) }
func (list ByOpenDesc) Less(i, j int) bool { return list.Sortable[j].Open < list.Sortable[i].Open }
func (list ByLowDesc) Less(i, j int) bool { return list.Sortable[j].Low < list.Sortable[i].Low }
func (list ByHighDesc) Less(i, j int) bool { return list.Sortable[j].High < list.Sortable[i].High }
func (list ByLow52Desc) Less(i, j int) bool { return list.Sortable[j].Low52 < list.Sortable[i].Low52 }
func (list ByHigh52Desc) Less(i, j int) bool { return list.Sortable[j].High52 < list.Sortable[i].High52 }
func (list ByVolumeDesc) Less(i, j int) bool { return list.Sortable[j].Volume < list.Sortable[i].Volume }
func (list ByAvgVolumeDesc) Less(i, j int) bool { return list.Sortable[j].AvgVolume < list.Sortable[i].AvgVolume }
func (list ByPeRatioDesc) Less(i, j int) bool { return list.Sortable[j].PeRatio < list.Sortable[i].PeRatio }
func (list ByPeRatioXDesc) Less(i, j int) bool { return list.Sortable[j].PeRatioX < list.Sortable[i].PeRatioX }
func (list ByDividendDesc) Less(i, j int) bool { return list.Sortable[j].Dividend < list.Sortable[i].Dividend }
func (list ByYieldDesc) Less(i, j int) bool { return list.Sortable[j].Yield < list.Sortable[i].Yield }
func (list ByMarketCapDesc) Less(i, j int) bool { return list.Sortable[j].MarketCap < list.Sortable[i].MarketCap }
func (list ByMarketCapXDesc) Less(i, j int) bool { return list.Sortable[j].MarketCapX < list.Sortable[i].MarketCapX }
func z(str string) float32 {
float := strings.Replace(strings.Trim(str, ` %`), `$`, ``, 1)
value,_ := strconv.ParseFloat(float, 32)
return float32(value)
}

@ -11,7 +11,7 @@ import (
)
type Market struct {
Open bool
IsClosed bool
Dow map[string]string
Nasdaq map[string]string
Sp500 map[string]string
@ -24,7 +24,7 @@ type Market struct {
//-----------------------------------------------------------------------------
func (self *Market) Initialize() *Market {
self.Open = true
self.IsClosed = false
self.Dow = make(map[string]string)
self.Nasdaq = make(map[string]string)
self.Sp500 = make(map[string]string)
@ -65,7 +65,8 @@ func (self *Market) Format() string {
func (self *Market) check_if_market_open(body []byte) []byte {
start := bytes.Index(body, []byte(`id="yfs_market_time"`))
finish := start + bytes.Index(body[start:], []byte(`</span>`))
self.Open = !bytes.Contains(body[start:finish], []byte(`closed`))
snippet := body[start:finish]
self.IsClosed = bytes.Contains(snippet, []byte(`closed`)) || bytes.Contains(snippet, []byte(`open in`))
return body[finish:]
}

@ -40,7 +40,7 @@ type Stock struct {
Ticker string
LastTrade string
Change string
ChangePercent string
ChangePct string
Open string
Low string
High string
@ -72,7 +72,7 @@ func (self *Quotes) Initialize(market *Market, profile *Profile) *Quotes {
//-----------------------------------------------------------------------------
func (self *Quotes) Fetch() *Quotes {
if self.market.Open || self.stocks == nil {
if !self.market.IsClosed || self.stocks == nil {
// Format the URL and send the request.
url := fmt.Sprintf(yahoo_quotes_url, self.profile.ListOfTickers())
response, err := http.Get(url)
@ -124,7 +124,7 @@ func (self *Quotes) parse(body []byte) *Quotes {
self.stocks[i].Ticker = string(columns[0])
self.stocks[i].LastTrade = string(columns[1])
self.stocks[i].Change = string(columns[2])
self.stocks[i].ChangePercent = string(columns[3])
self.stocks[i].ChangePct = string(columns[3])
self.stocks[i].Open = string(columns[4])
self.stocks[i].Low = string(columns[5])
self.stocks[i].High = string(columns[6])

Loading…
Cancel
Save