master
Michael Dvorkin 10 years ago
parent 7932776cf5
commit bc666ec165
  1. 2
      LICENSE
  2. 2
      README.md
  3. 4
      cmd/mop.go
  4. 4
      cnn_market.go
  5. 5
      column_editor.go
  6. 48
      layout.go
  7. 26
      line_editor.go
  8. 4
      markup.go
  9. 4
      profile.go
  10. 6
      screen.go
  11. 243
      sorter.go
  12. 2
      yahoo_quotes.go

@ -1,4 +1,4 @@
Copyright (c) 2013 Michael Dvorkin. All Rights Reserved.
Copyright (c) 2013-2015 Michael Dvorkin. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

@ -44,7 +44,7 @@ comments, suggestions, and contributions are welcome.
### License ###
Copyright (c) 2013 Michael Dvorkin. All Rights Reserved.
Copyright (c) 2013-2015 Michael Dvorkin. All Rights Reserved.
"mike" + "@dvorkin" + ".net" || "twitter.com/mid"
Permission is hereby granted, free of charge, to any person obtaining

@ -1,4 +1,4 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Copyright (c) 2013-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.
@ -10,7 +10,7 @@ import (
`time`
)
const help = `Mop v0.2.0 -- Copyright (c) 2013-15 Michael Dvorkin. All Rights Reserved.
const help = `Mop v0.2.0 -- Copyright (c) 2013-2015 by Michael Dvorkin. All Rights Reserved.
NO WARRANTIES OF ANY KIND WHATSOEVER. SEE THE LICENSE FILE FOR DETAILS.
<u>Command</u> <u>Description </u>

@ -1,4 +1,4 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Copyright (c) 2013-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.
@ -37,7 +37,7 @@ type Market struct {
// Returns new initialized Market struct.
func NewMarket() *Market {
market := &Market{};
market := &Market{}
market.IsClosed = false
market.Dow = make(map[string]string)
market.Nasdaq = make(map[string]string)

@ -1,4 +1,4 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Copyright (c) 2013-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.
@ -72,7 +72,7 @@ func (editor *ColumnEditor) selectLeftColumn() *ColumnEditor {
//-----------------------------------------------------------------------------
func (editor *ColumnEditor) selectRightColumn() *ColumnEditor {
editor.profile.selectedColumn++
if editor.profile.selectedColumn > editor.layout.TotalColumns() - 1 {
if editor.profile.selectedColumn > editor.layout.TotalColumns()-1 {
editor.profile.selectedColumn = 0
}
return editor
@ -98,4 +98,3 @@ func (editor *ColumnEditor) redrawHeader() {
editor.screen.DrawLine(0, 4, editor.layout.Header(editor.profile))
termbox.Flush()
}

@ -1,4 +1,4 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Copyright (c) 2013-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.
@ -20,7 +20,7 @@ type Column struct {
width int // Column width.
name string // The name of the field in the Stock struct.
title string // Column title to display in the header.
formatter func(string)string // Optional function to format the contents of the column.
formatter func(string) string // Optional function to format the contents of the column.
}
// Layout is used to format and display all the collected data, i.e. market
@ -37,21 +37,21 @@ type Layout struct {
func NewLayout() *Layout {
layout := &Layout{}
layout.columns = []Column{
{ -7, `Ticker`, `Ticker`, nil },
{ 10, `LastTrade`, `Last`, currency },
{ 10, `Change`, `Change`, currency },
{ 10, `ChangePct`, `Change%`, last },
{ 10, `Open`, `Open`, currency },
{ 10, `Low`, `Low`, currency },
{ 10, `High`, `High`, currency },
{ 10, `Low52`, `52w Low`, currency },
{ 10, `High52`, `52w High`, currency },
{ 11, `Volume`, `Volume`, nil },
{ 11, `AvgVolume`, `AvgVolume`, nil },
{ 9, `PeRatio`, `P/E`, blank },
{ 9, `Dividend`, `Dividend`, zero },
{ 9, `Yield`, `Yield`, percent },
{ 11, `MarketCap`, `MktCap`, currency },
{-7, `Ticker`, `Ticker`, nil},
{10, `LastTrade`, `Last`, currency},
{10, `Change`, `Change`, currency},
{10, `ChangePct`, `Change%`, last},
{10, `Open`, `Open`, currency},
{10, `Low`, `Low`, currency},
{10, `High`, `High`, currency},
{10, `Low52`, `52w Low`, currency},
{10, `High52`, `52w High`, currency},
{11, `Volume`, `Volume`, nil},
{11, `AvgVolume`, `AvgVolume`, nil},
{9, `PeRatio`, `P/E`, blank},
{9, `Dividend`, `Dividend`, zero},
{9, `Yield`, `Yield`, percent},
{11, `MarketCap`, `MktCap`, currency},
}
layout.regex = regexp.MustCompile(`(\.\d+)[BMK]?$`)
layout.marketTemplate = buildMarketTemplate()
@ -107,12 +107,12 @@ func (layout *Layout) Quotes(quotes *Quotes) string {
func (layout *Layout) Header(profile *Profile) string {
str, selectedColumn := ``, profile.selectedColumn
for i,col := range layout.columns {
for i, col := range layout.columns {
arrow := arrowFor(i, profile)
if i != selectedColumn {
str += fmt.Sprintf(`%*s`, col.width, arrow + col.title)
str += fmt.Sprintf(`%*s`, col.width, arrow+col.title)
} else {
str += fmt.Sprintf(`<r>%*s</r>`, col.width, arrow + col.title)
str += fmt.Sprintf(`<r>%*s</r>`, col.width, arrow+col.title)
}
}
@ -139,7 +139,7 @@ func (layout *Layout) prettify(quotes *Quotes) []Stock {
// - If the column has the formatter method then call it.
// - Set the column value padding it to the given width.
//
for _,column := range layout.columns {
for _, column := range layout.columns {
// ex. value = stock.Change
value := reflect.ValueOf(&stock).Elem().FieldByName(column.name).String()
if column.formatter != nil {
@ -173,7 +173,7 @@ func (layout *Layout) pad(str string, width int) string {
if len(match) > 0 {
switch len(match[1]) {
case 2:
str = strings.Replace(str, match[1], match[1] + `0`, 1)
str = strings.Replace(str, match[1], match[1]+`0`, 1)
case 4, 5:
str = strings.Replace(str, match[1], match[1][0:3], 1)
}
@ -218,13 +218,13 @@ func group(stocks []Stock) []Stock {
grouped := make([]Stock, len(stocks))
current := 0
for _,stock := range stocks {
for _, stock := range stocks {
if stock.Advancing {
grouped[current] = stock
current++
}
}
for _,stock := range stocks {
for _, stock := range stocks {
if !stock.Advancing {
grouped[current] = stock
current++

@ -1,4 +1,4 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Copyright (c) 2013-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.
@ -42,7 +42,7 @@ func (editor *LineEditor) Prompt(command rune) *LineEditor {
editor.prompt = prompt
editor.command = command
editor.screen.DrawLine(0, 3, `<white>` + editor.prompt + `</>`)
editor.screen.DrawLine(0, 3, `<white>`+editor.prompt+`</>`)
termbox.SetCursor(len(editor.prompt), 3)
termbox.Flush()
}
@ -97,12 +97,12 @@ func (editor *LineEditor) deletePreviousCharacter() *LineEditor {
if editor.cursor > 0 {
if editor.cursor < len(editor.input) {
// Remove character in the middle of the input string.
editor.input = editor.input[0 : editor.cursor-1] + editor.input[editor.cursor : len(editor.input)]
editor.input = editor.input[0:editor.cursor-1] + editor.input[editor.cursor:len(editor.input)]
} else {
// Remove last input character.
editor.input = editor.input[ : len(editor.input)-1]
editor.input = editor.input[:len(editor.input)-1]
}
editor.screen.DrawLine(len(editor.prompt), 3, editor.input + ` `) // Erase last character.
editor.screen.DrawLine(len(editor.prompt), 3, editor.input+` `) // Erase last character.
editor.moveLeft()
}
@ -113,7 +113,7 @@ func (editor *LineEditor) deletePreviousCharacter() *LineEditor {
func (editor *LineEditor) insertCharacter(ch rune) *LineEditor {
if editor.cursor < len(editor.input) {
// Insert the character in the middle of the input string.
editor.input = editor.input[0 : editor.cursor] + string(ch) + editor.input[editor.cursor : len(editor.input)]
editor.input = editor.input[0:editor.cursor] + string(ch) + editor.input[editor.cursor:len(editor.input)]
} else {
// Append the character to the end of the input string.
editor.input += string(ch)
@ -128,7 +128,7 @@ func (editor *LineEditor) insertCharacter(ch rune) *LineEditor {
func (editor *LineEditor) moveLeft() *LineEditor {
if editor.cursor > 0 {
editor.cursor--
termbox.SetCursor(len(editor.prompt) + editor.cursor, 3)
termbox.SetCursor(len(editor.prompt)+editor.cursor, 3)
}
return editor
@ -138,7 +138,7 @@ func (editor *LineEditor) moveLeft() *LineEditor {
func (editor *LineEditor) moveRight() *LineEditor {
if editor.cursor < len(editor.input) {
editor.cursor++
termbox.SetCursor(len(editor.prompt) + editor.cursor, 3)
termbox.SetCursor(len(editor.prompt)+editor.cursor, 3)
}
return editor
@ -147,7 +147,7 @@ func (editor *LineEditor) moveRight() *LineEditor {
//-----------------------------------------------------------------------------
func (editor *LineEditor) jumpToBeginning() *LineEditor {
editor.cursor = 0
termbox.SetCursor(len(editor.prompt) + editor.cursor, 3)
termbox.SetCursor(len(editor.prompt)+editor.cursor, 3)
return editor
}
@ -155,7 +155,7 @@ func (editor *LineEditor) jumpToBeginning() *LineEditor {
//-----------------------------------------------------------------------------
func (editor *LineEditor) jumpToEnd() *LineEditor {
editor.cursor = len(editor.input)
termbox.SetCursor(len(editor.prompt) + editor.cursor, 3)
termbox.SetCursor(len(editor.prompt)+editor.cursor, 3)
return editor
}
@ -166,7 +166,7 @@ func (editor *LineEditor) execute() *LineEditor {
case '+':
tickers := editor.tokenize()
if len(tickers) > 0 {
if added,_ := editor.quotes.AddTickers(tickers); added > 0 {
if added, _ := editor.quotes.AddTickers(tickers); added > 0 {
editor.screen.Draw(editor.quotes)
}
}
@ -174,13 +174,13 @@ func (editor *LineEditor) execute() *LineEditor {
tickers := editor.tokenize()
if len(tickers) > 0 {
before := len(editor.quotes.profile.Tickers)
if removed,_ := editor.quotes.RemoveTickers(tickers); removed > 0 {
if removed, _ := editor.quotes.RemoveTickers(tickers); removed > 0 {
editor.screen.Draw(editor.quotes)
// Clear the lines at the bottom of the list, if any.
after := before - removed
for i := before; i > after; i-- {
editor.screen.ClearLine(0, i + 4)
editor.screen.ClearLine(0, i+4)
}
}
}

@ -1,4 +1,4 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Copyright (c) 2013-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.
@ -138,7 +138,7 @@ func (markup *Markup) supportedTags() *regexp.Regexp {
arr := []string{}
for tag := range markup.tags {
arr = append(arr, `</?` + tag + `>`)
arr = append(arr, `</?`+tag+`>`)
}
return regexp.MustCompile(strings.Join(arr, `|`))

@ -1,4 +1,4 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Copyright (c) 2013-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.
@ -36,7 +36,7 @@ func NewProfile() *Profile {
profile.MarketRefresh = 12 // Market data gets fetched every 12s (5 times per minute).
profile.QuotesRefresh = 5 // Stock quotes get updated every 5s (12 times per minute).
profile.Grouped = false // Stock quotes are *not* grouped by advancing/declining.
profile.Tickers = []string{ `AAPL`, `C`, `GOOG`, `IBM`, `KO`, `ORCL`, `V` }
profile.Tickers = []string{`AAPL`, `C`, `GOOG`, `IBM`, `KO`, `ORCL`, `V`}
profile.SortColumn = 0 // Stock quotes are sorted by ticker name.
profile.Ascending = true // A to Z.
profile.Save()

@ -1,4 +1,4 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Copyright (c) 2013-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.
@ -87,7 +87,7 @@ func (screen *Screen) ClearLine(x int, y int) *Screen {
// market data, stock quotes, current time, and an arbitrary string.
func (screen *Screen) Draw(objects ...interface{}) *Screen {
if screen.pausedAt != nil {
defer screen.DrawLine(0, 0, `<right><r>` + screen.pausedAt.Format(`3:04:05pm PST`) + `</r></right>`)
defer screen.DrawLine(0, 0, `<right><r>`+screen.pausedAt.Format(`3:04:05pm PST`)+`</r></right>`)
}
for _, ptr := range objects {
switch ptr.(type) {
@ -99,7 +99,7 @@ func (screen *Screen) Draw(objects ...interface{}) *Screen {
screen.draw(screen.layout.Quotes(object.Fetch()))
case time.Time:
timestamp := ptr.(time.Time).Format(`3:04:05pm PST`)
screen.DrawLine(0, 0, `<right>` + timestamp + `</right>`)
screen.DrawLine(0, 0, `<right>`+timestamp+`</right>`)
default:
screen.draw(ptr.(string))
}

@ -1,4 +1,4 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Copyright (c) 2013-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.
@ -18,72 +18,129 @@ type Sorter struct {
}
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 byDividendAsc struct { sortable }
type byYieldAsc struct { sortable }
type byMarketCapAsc 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 byDividendDesc struct { sortable }
type byYieldDesc struct { sortable }
type byMarketCapDesc 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 c(list.sortable[i].Change) < c(list.sortable[j].Change) }
func (list byChangePctAsc) Less(i, j int) bool { return c(list.sortable[i].ChangePct) < c(list.sortable[j].ChangePct) }
func (list byOpenAsc) Less(i, j int) bool { return list.sortable[i].Open < list.sortable[j].Open }
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 byDividendAsc struct{ sortable }
type byYieldAsc struct{ sortable }
type byMarketCapAsc 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 byDividendDesc struct{ sortable }
type byYieldDesc struct{ sortable }
type byMarketCapDesc 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 c(list.sortable[i].Change) < c(list.sortable[j].Change)
}
func (list byChangePctAsc) Less(i, j int) bool {
return c(list.sortable[i].ChangePct) < c(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 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 m(list.sortable[i].MarketCap) < m(list.sortable[j].MarketCap) }
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 c(list.sortable[j].ChangePct) < c(list.sortable[i].ChangePct) }
func (list byChangePctDesc) Less(i, j int) bool { return c(list.sortable[j].ChangePct) < c(list.sortable[i].ChangePct) }
func (list byOpenDesc) Less(i, j int) bool { return list.sortable[j].Open < list.sortable[i].Open }
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 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 m(list.sortable[i].MarketCap) < m(list.sortable[j].MarketCap)
}
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 c(list.sortable[j].ChangePct) < c(list.sortable[i].ChangePct)
}
func (list byChangePctDesc) Less(i, j int) bool {
return c(list.sortable[j].ChangePct) < c(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 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 m(list.sortable[j].MarketCap) < m(list.sortable[i].MarketCap) }
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 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 m(list.sortable[j].MarketCap) < m(list.sortable[i].MarketCap)
}
// Returns new Sorter struct.
func NewSorter(profile *Profile) *Sorter {
@ -99,39 +156,39 @@ func (sorter *Sorter) SortByCurrentColumn(stocks []Stock) *Sorter {
if sorter.profile.Ascending {
interfaces = []sort.Interface{
byTickerAsc { stocks },
byLastTradeAsc { stocks },
byChangeAsc { stocks },
byChangePctAsc { stocks },
byOpenAsc { stocks },
byLowAsc { stocks },
byHighAsc { stocks },
byLow52Asc { stocks },
byHigh52Asc { stocks },
byVolumeAsc { stocks },
byAvgVolumeAsc { stocks },
byPeRatioAsc { stocks },
byDividendAsc { stocks },
byYieldAsc { stocks },
byMarketCapAsc { stocks },
byTickerAsc{stocks},
byLastTradeAsc{stocks},
byChangeAsc{stocks},
byChangePctAsc{stocks},
byOpenAsc{stocks},
byLowAsc{stocks},
byHighAsc{stocks},
byLow52Asc{stocks},
byHigh52Asc{stocks},
byVolumeAsc{stocks},
byAvgVolumeAsc{stocks},
byPeRatioAsc{stocks},
byDividendAsc{stocks},
byYieldAsc{stocks},
byMarketCapAsc{stocks},
}
} else {
interfaces = []sort.Interface{
byTickerDesc { stocks },
byLastTradeDesc { stocks },
byChangeDesc { stocks },
byChangePctDesc { stocks },
byOpenDesc { stocks },
byLowDesc { stocks },
byHighDesc { stocks },
byLow52Desc { stocks },
byHigh52Desc { stocks },
byVolumeDesc { stocks },
byAvgVolumeDesc { stocks },
byPeRatioDesc { stocks },
byDividendDesc { stocks },
byYieldDesc { stocks },
byMarketCapDesc { stocks },
byTickerDesc{stocks},
byLastTradeDesc{stocks},
byChangeDesc{stocks},
byChangePctDesc{stocks},
byOpenDesc{stocks},
byLowDesc{stocks},
byHighDesc{stocks},
byLow52Desc{stocks},
byHigh52Desc{stocks},
byVolumeDesc{stocks},
byAvgVolumeDesc{stocks},
byPeRatioDesc{stocks},
byDividendDesc{stocks},
byYieldDesc{stocks},
byMarketCapDesc{stocks},
}
}
@ -153,7 +210,7 @@ func c(str string) float32 {
func m(str string) float32 {
multiplier := 1.0
switch str[len(str)-1:len(str)] { // Check the last character.
switch str[len(str)-1 : len(str)] { // Check the last character.
case `B`:
multiplier = 1000000000.0
case `M`:

@ -1,4 +1,4 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Copyright (c) 2013-2015 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

Loading…
Cancel
Save