diff --git a/LICENSE b/LICENSE
index 6e65a05..9437929 100644
--- a/LICENSE
+++ b/LICENSE
@@ -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
diff --git a/README.md b/README.md
index 156800f..965ca44 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/cmd/mop.go b/cmd/mop.go
index 53442df..52a96dc 100644
--- a/cmd/mop.go
+++ b/cmd/mop.go
@@ -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.
Command Description
diff --git a/cnn_market.go b/cnn_market.go
index 126e800..d8fb47b 100644
--- a/cnn_market.go
+++ b/cnn_market.go
@@ -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,61 +18,61 @@ const marketURL = `http://money.cnn.com/data/markets/`
// Market stores current market information displayed in the top three lines of
// the screen. The market data is fetched and parsed from the HTML page above.
type Market struct {
- IsClosed bool // True when U.S. markets are closed.
- Dow map[string]string // Hash of Dow Jones indicators.
- Nasdaq map[string]string // Hash of NASDAQ indicators.
- Sp500 map[string]string // Hash of S&P 500 indicators.
- Tokyo map[string]string
- HongKong map[string]string
- London map[string]string
- Frankfurt map[string]string
- Yield map[string]string
- Oil map[string]string
- Yen map[string]string
- Euro map[string]string
- Gold map[string]string
- regex *regexp.Regexp // Regex to parse market data from HTML.
- errors string // Error(s), if any.
+ IsClosed bool // True when U.S. markets are closed.
+ Dow map[string]string // Hash of Dow Jones indicators.
+ Nasdaq map[string]string // Hash of NASDAQ indicators.
+ Sp500 map[string]string // Hash of S&P 500 indicators.
+ Tokyo map[string]string
+ HongKong map[string]string
+ London map[string]string
+ Frankfurt map[string]string
+ Yield map[string]string
+ Oil map[string]string
+ Yen map[string]string
+ Euro map[string]string
+ Gold map[string]string
+ regex *regexp.Regexp // Regex to parse market data from HTML.
+ errors string // Error(s), if any.
}
// Returns new initialized Market struct.
func NewMarket() *Market {
- market := &Market{};
- market.IsClosed = false
- market.Dow = make(map[string]string)
- market.Nasdaq = make(map[string]string)
- market.Sp500 = make(map[string]string)
-
- market.Tokyo = make(map[string]string)
- market.HongKong = make(map[string]string)
- market.London = make(map[string]string)
+ market := &Market{}
+ market.IsClosed = false
+ market.Dow = make(map[string]string)
+ market.Nasdaq = make(map[string]string)
+ market.Sp500 = make(map[string]string)
+
+ market.Tokyo = make(map[string]string)
+ market.HongKong = make(map[string]string)
+ market.London = make(map[string]string)
market.Frankfurt = make(map[string]string)
- market.Yield = make(map[string]string)
- market.Oil = make(map[string]string)
- market.Yen = make(map[string]string)
- market.Euro = make(map[string]string)
- market.Gold = make(map[string]string)
+ market.Yield = make(map[string]string)
+ market.Oil = make(map[string]string)
+ market.Yen = make(map[string]string)
+ market.Euro = make(map[string]string)
+ market.Gold = make(map[string]string)
- market.errors = ``
+ market.errors = ``
const any = `\s*(?:.+?)`
const price = `>([\d\.,]+)`
const percent = `>([\+\-]?[\d\.,]+%?)<`
rules := []string{
- `>Dow<`, any, percent, any, price, any, percent, any,
- `>Nasdaq<`, any, percent, any, price, any, percent, any,
- `">S&P<`, any, percent, any, price, any, percent, any,
+ `>Dow<`, any, percent, any, price, any, percent, any,
+ `>Nasdaq<`, any, percent, any, price, any, percent, any,
+ `">S&P<`, any, percent, any, price, any, percent, any,
`>Nikkei 225<`, any, percent, any, price, any, percent, any,
- `>Hang Seng<`, any, percent, any, price, any, percent, any,
- `>FTSE 100<`, any, percent, any, price, any, percent, any,
- `>DAX<`, any, percent, any, price, any, percent, any,
- `>10-year yield<`, any, price, any, percent, any,
- `>Oil<`, any, price, any, percent, any,
- `>Yen<`, any, price, any, percent, any,
- `>Euro<`, any, price, any, percent, any,
- `>Gold<`, any, price, any, percent, any,
+ `>Hang Seng<`, any, percent, any, price, any, percent, any,
+ `>FTSE 100<`, any, percent, any, price, any, percent, any,
+ `>DAX<`, any, percent, any, price, any, percent, any,
+ `>10-year yield<`, any, price, any, percent, any,
+ `>Oil<`, any, price, any, percent, any,
+ `>Yen<`, any, price, any, percent, any,
+ `>Euro<`, any, price, any, percent, any,
+ `>Gold<`, any, price, any, percent, any,
}
market.regex = regexp.MustCompile(strings.Join(rules, ``))
@@ -131,9 +131,9 @@ func (market *Market) trim(body []byte) []byte {
func (market *Market) extract(snippet []byte) *Market {
matches := market.regex.FindStringSubmatch(string(snippet))
- if len(matches) < 31 {
- panic(`Unable to parse ` + marketURL)
- }
+ if len(matches) < 31 {
+ panic(`Unable to parse ` + marketURL)
+ }
market.Dow[`change`] = matches[1]
market.Dow[`latest`] = matches[2]
diff --git a/column_editor.go b/column_editor.go
index 699bcde..b008d5f 100644
--- a/column_editor.go
+++ b/column_editor.go
@@ -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,19 +10,19 @@ import `github.com/michaeldv/termbox-go`
// current column name in the header, then waits for arrow keys (choose
// another column), Enter (reverse sort order), or Esc (exit).
type ColumnEditor struct {
- screen *Screen // Pointer to Screen so we could use screen.Draw().
- quotes *Quotes // Pointer to Quotes to redraw them when the sort order changes.
- layout *Layout // Pointer to Layout to redraw stock quotes header.
- profile *Profile // Pointer to Profile where we save newly selected sort order.
+ screen *Screen // Pointer to Screen so we could use screen.Draw().
+ quotes *Quotes // Pointer to Quotes to redraw them when the sort order changes.
+ layout *Layout // Pointer to Layout to redraw stock quotes header.
+ profile *Profile // Pointer to Profile where we save newly selected sort order.
}
// Returns new initialized ColumnEditor struct. As part of initialization it
// highlights current column name (as stored in Profile).
func NewColumnEditor(screen *Screen, quotes *Quotes) *ColumnEditor {
editor := &ColumnEditor{
- screen: screen,
- quotes: quotes,
- layout: screen.layout,
+ screen: screen,
+ quotes: quotes,
+ layout: screen.layout,
profile: quotes.profile,
}
@@ -43,7 +43,7 @@ func (editor *ColumnEditor) Handle(event termbox.Event) bool {
case termbox.KeyEnter:
editor.execute()
- case termbox.KeyArrowLeft:
+ case termbox.KeyArrowLeft:
editor.selectLeftColumn()
case termbox.KeyArrowRight:
@@ -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()
}
-
diff --git a/layout.go b/layout.go
index d6ff386..156b73a 100644
--- a/layout.go
+++ b/layout.go
@@ -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.
@@ -17,41 +17,41 @@ import (
// Column describes formatting rules for individual column within the list
// of stock quotes.
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.
+ 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.
}
// Layout is used to format and display all the collected data, i.e. market
// updates and the list of stock quotes.
type Layout struct {
- columns []Column // List of stock quotes columns.
- sorter *Sorter // Pointer to sorting receiver.
- regex *regexp.Regexp // Pointer to regular expression to align decimal points.
- marketTemplate *template.Template // Pointer to template to format market data.
- quotesTemplate *template.Template // Pointer to template to format the list of stock quotes.
+ columns []Column // List of stock quotes columns.
+ sorter *Sorter // Pointer to sorting receiver.
+ regex *regexp.Regexp // Pointer to regular expression to align decimal points.
+ marketTemplate *template.Template // Pointer to template to format market data.
+ quotesTemplate *template.Template // Pointer to template to format the list of stock quotes.
}
// Creates the layout and assigns the default values that stay unchanged.
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()
@@ -63,8 +63,8 @@ func NewLayout() *Layout {
// Market merges given market data structure with the market template and
// returns formatted string that includes highlighting markup.
func (layout *Layout) Market(market *Market) string {
- if ok, err := market.Ok(); !ok { // If there was an error fetching market data...
- return err // then simply return the error string.
+ if ok, err := market.Ok(); !ok { // If there was an error fetching market data...
+ return err // then simply return the error string.
}
highlight(market.Dow, market.Sp500, market.Nasdaq,
@@ -80,14 +80,14 @@ func (layout *Layout) Market(market *Market) string {
// and the list of given stock quotes. It returns formatted string with
// all the necessary markup.
func (layout *Layout) Quotes(quotes *Quotes) string {
- if ok, err := quotes.Ok(); !ok { // If there was an error fetching stock quotes...
- return err // then simply return the error string.
+ if ok, err := quotes.Ok(); !ok { // If there was an error fetching stock quotes...
+ return err // then simply return the error string.
}
vars := struct {
- Now string // Current timestamp.
- Header string // Formatted header line.
- Stocks []Stock // List of formatted stock quotes.
+ Now string // Current timestamp.
+ Header string // Formatted header line.
+ Stocks []Stock // List of formatted stock quotes.
}{
time.Now().Format(`3:04:05pm PST`),
layout.Header(quotes.profile),
@@ -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(`%*s`, col.width, arrow + col.title)
+ str += fmt.Sprintf(`%*s`, 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++
diff --git a/line_editor.go b/line_editor.go
index 03cab55..a5b6201 100644
--- a/line_editor.go
+++ b/line_editor.go
@@ -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.
@@ -15,13 +15,13 @@ import (
// data and keep track of cursor movements (left, right, beginning of the
// line, end of the line, and backspace).
type LineEditor struct {
- command rune // Keyboard command such as '+' or '-'.
- cursor int // Current cursor position within the input line.
- prompt string // Prompt string for the command.
- input string // User typed input string.
- screen *Screen // Pointer to Screen.
- quotes *Quotes // Pointer to Quotes.
- regex *regexp.Regexp // Regex to split comma-delimited input string.
+ command rune // Keyboard command such as '+' or '-'.
+ cursor int // Current cursor position within the input line.
+ prompt string // Prompt string for the command.
+ input string // User typed input string.
+ screen *Screen // Pointer to Screen.
+ quotes *Quotes // Pointer to Quotes.
+ regex *regexp.Regexp // Regex to split comma-delimited input string.
}
// Returns new initialized LineEditor struct.
@@ -29,7 +29,7 @@ func NewLineEditor(screen *Screen, quotes *Quotes) *LineEditor {
return &LineEditor{
screen: screen,
quotes: quotes,
- regex: regexp.MustCompile(`[,\s]+`),
+ regex: regexp.MustCompile(`[,\s]+`),
}
}
@@ -42,7 +42,7 @@ func (editor *LineEditor) Prompt(command rune) *LineEditor {
editor.prompt = prompt
editor.command = command
- editor.screen.DrawLine(0, 3, `` + editor.prompt + `>`)
+ editor.screen.DrawLine(0, 3, ``+editor.prompt+`>`)
termbox.SetCursor(len(editor.prompt), 3)
termbox.Flush()
}
@@ -65,7 +65,7 @@ func (editor *LineEditor) Handle(ev termbox.Event) bool {
case termbox.KeyEnter:
return editor.execute().done()
- case termbox.KeyBackspace, termbox.KeyBackspace2:
+ case termbox.KeyBackspace, termbox.KeyBackspace2:
editor.deletePreviousCharacter()
case termbox.KeyCtrlB, termbox.KeyArrowLeft:
@@ -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)
}
}
}
diff --git a/markup.go b/markup.go
index fae6b1e..bffca94 100644
--- a/markup.go
+++ b/markup.go
@@ -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.
@@ -24,36 +24,36 @@ import (
// The ... tag is used to right align the enclosed string
// (ex. when displaying current time in the upper right corner).
type Markup struct {
- Foreground termbox.Attribute // Foreground color.
- Background termbox.Attribute // Background color (so far always termbox.ColorDefault).
- RightAligned bool // True when the string is right aligned.
- tags map[string]termbox.Attribute // Tags to Termbox translation hash.
- regex *regexp.Regexp // Regex to identify the supported tag names.
+ Foreground termbox.Attribute // Foreground color.
+ Background termbox.Attribute // Background color (so far always termbox.ColorDefault).
+ RightAligned bool // True when the string is right aligned.
+ tags map[string]termbox.Attribute // Tags to Termbox translation hash.
+ regex *regexp.Regexp // Regex to identify the supported tag names.
}
// Creates markup to define tag to Termbox translation rules and store default
// colors and column alignments.
func NewMarkup() *Markup {
markup := &Markup{}
- markup.Foreground = termbox.ColorDefault
- markup.Background = termbox.ColorDefault
- markup.RightAligned = false
+ markup.Foreground = termbox.ColorDefault
+ markup.Background = termbox.ColorDefault
+ markup.RightAligned = false
markup.tags = make(map[string]termbox.Attribute)
- markup.tags[`/`] = termbox.ColorDefault
- markup.tags[`black`] = termbox.ColorBlack
- markup.tags[`red`] = termbox.ColorRed
- markup.tags[`green`] = termbox.ColorGreen
- markup.tags[`yellow`] = termbox.ColorYellow
- markup.tags[`blue`] = termbox.ColorBlue
+ markup.tags[`/`] = termbox.ColorDefault
+ markup.tags[`black`] = termbox.ColorBlack
+ markup.tags[`red`] = termbox.ColorRed
+ markup.tags[`green`] = termbox.ColorGreen
+ markup.tags[`yellow`] = termbox.ColorYellow
+ markup.tags[`blue`] = termbox.ColorBlue
markup.tags[`magenta`] = termbox.ColorMagenta
- markup.tags[`cyan`] = termbox.ColorCyan
- markup.tags[`white`] = termbox.ColorWhite
- markup.tags[`right`] = termbox.ColorDefault // Termbox can combine attributes and a single color using bitwise OR.
- markup.tags[`b`] = termbox.AttrBold // Attribute = 1 << (iota + 4)
- markup.tags[`u`] = termbox.AttrUnderline
- markup.tags[`r`] = termbox.AttrReverse
- markup.regex = markup.supportedTags() // Once we have the hash we could build the regex.
+ markup.tags[`cyan`] = termbox.ColorCyan
+ markup.tags[`white`] = termbox.ColorWhite
+ markup.tags[`right`] = termbox.ColorDefault // Termbox can combine attributes and a single color using bitwise OR.
+ markup.tags[`b`] = termbox.AttrBold // Attribute = 1 << (iota + 4)
+ markup.tags[`u`] = termbox.AttrUnderline
+ markup.tags[`r`] = termbox.AttrReverse
+ markup.regex = markup.supportedTags() // Once we have the hash we could build the regex.
return markup
}
@@ -111,17 +111,17 @@ func (markup *Markup) process(tag string, open bool) bool {
if attribute, ok := markup.tags[tag]; ok {
switch tag {
case `right`:
- markup.RightAligned = open // On for , off for .
+ markup.RightAligned = open // On for , off for .
default:
if open {
if attribute >= termbox.AttrBold {
- markup.Foreground |= attribute // Set the Termbox attribute.
+ markup.Foreground |= attribute // Set the Termbox attribute.
} else {
- markup.Foreground = attribute // Set the Termbox color.
+ markup.Foreground = attribute // Set the Termbox color.
}
} else {
if attribute >= termbox.AttrBold {
- markup.Foreground &= ^attribute // Clear the Termbox attribute.
+ markup.Foreground &= ^attribute // Clear the Termbox attribute.
} else {
markup.Foreground = termbox.ColorDefault
}
@@ -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, `|`))
diff --git a/profile.go b/profile.go
index e86b3cd..ce70d38 100644
--- a/profile.go
+++ b/profile.go
@@ -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,13 +18,13 @@ const moprc = `/.moprc`
// stock tickers). The settings are serialized using JSON and saved in
// the ~/.moprc file.
type Profile struct {
- Tickers []string // List of stock tickers to display.
- MarketRefresh int // Time interval to refresh market data.
- QuotesRefresh int // Time interval to refresh stock quotes.
- SortColumn int // Column number by which we sort stock quotes.
- Ascending bool // True when sort order is ascending.
- Grouped bool // True when stocks are grouped by advancing/declining.
- selectedColumn int // Stores selected column number when the column editor is active.
+ Tickers []string // List of stock tickers to display.
+ MarketRefresh int // Time interval to refresh market data.
+ QuotesRefresh int // Time interval to refresh stock quotes.
+ SortColumn int // Column number by which we sort stock quotes.
+ Ascending bool // True when sort order is ascending.
+ Grouped bool // True when stocks are grouped by advancing/declining.
+ selectedColumn int // Stores selected column number when the column editor is active.
}
// Creates the profile and attempts to load the settings from ~/.moprc file.
@@ -32,13 +32,13 @@ type Profile struct {
func NewProfile() *Profile {
profile := &Profile{}
data, err := ioutil.ReadFile(profile.defaultFileName())
- if err != nil { // Set default values:
- 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.SortColumn = 0 // Stock quotes are sorted by ticker name.
- profile.Ascending = true // A to Z.
+ if err != nil { // Set default values:
+ 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.SortColumn = 0 // Stock quotes are sorted by ticker name.
+ profile.Ascending = true // A to Z.
profile.Save()
} else {
json.Unmarshal(data, profile)
@@ -110,9 +110,9 @@ func (profile *Profile) RemoveTickers(tickers []string) (removed int, err error)
// for the current column, or to pick another sort column.
func (profile *Profile) Reorder() error {
if profile.selectedColumn == profile.SortColumn {
- profile.Ascending = !profile.Ascending // Reverse sort order.
+ profile.Ascending = !profile.Ascending // Reverse sort order.
} else {
- profile.SortColumn = profile.selectedColumn // Pick new sort column.
+ profile.SortColumn = profile.selectedColumn // Pick new sort column.
}
return profile.Save()
}
diff --git a/screen.go b/screen.go
index 8774410..b1c4e87 100644
--- a/screen.go
+++ b/screen.go
@@ -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.
@@ -13,12 +13,12 @@ import (
// Screen is thin wrapper aroung Termbox library to provide basic display
// capabilities as requied by Mop.
type Screen struct {
- width int // Current number of columns.
- height int // Current number of rows.
- cleared bool // True after the screens gets cleared.
- layout *Layout // Pointer to layout (gets created by screen).
- markup *Markup // Pointer to markup processor (gets created by screen).
- pausedAt *time.Time // Timestamp of the pause request or nil if none.
+ width int // Current number of columns.
+ height int // Current number of rows.
+ cleared bool // True after the screens gets cleared.
+ layout *Layout // Pointer to layout (gets created by screen).
+ markup *Markup // Pointer to markup processor (gets created by screen).
+ pausedAt *time.Time // Timestamp of the pause request or nil if none.
}
// Initializes Termbox, creates screen along with layout and markup, and
@@ -54,14 +54,14 @@ func (screen *Screen) Resize() *Screen {
// Pause is a toggle function that either creates a timestamp of the pause
// request or resets it to nil.
func (screen *Screen) Pause(pause bool) *Screen {
- if pause {
- screen.pausedAt = new(time.Time)
- *screen.pausedAt = time.Now()
- } else {
- screen.pausedAt = nil
- }
-
- return screen
+ if pause {
+ screen.pausedAt = new(time.Time)
+ *screen.pausedAt = time.Now()
+ } else {
+ screen.pausedAt = nil
+ }
+
+ return screen
}
// Clear makes the entire screen blank using default background color.
@@ -86,9 +86,9 @@ func (screen *Screen) ClearLine(x int, y int) *Screen {
// Draw accepts variable number of arguments and knows how to display the
// 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, `` + screen.pausedAt.Format(`3:04:05pm PST`) + ``)
- }
+ if screen.pausedAt != nil {
+ defer screen.DrawLine(0, 0, ``+screen.pausedAt.Format(`3:04:05pm PST`)+``)
+ }
for _, ptr := range objects {
switch ptr.(type) {
case *Market:
@@ -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, `` + timestamp + ``)
+ screen.DrawLine(0, 0, ``+timestamp+``)
default:
screen.draw(ptr.(string))
}
diff --git a/sorter.go b/sorter.go
index f02e178..576d98f 100644
--- a/sorter.go
+++ b/sorter.go
@@ -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.
@@ -14,76 +14,133 @@ import (
// setup is rather lengthy; there should probably be more concise way
// that uses reflection and avoids hardcoding the column names.
type Sorter struct {
- profile *Profile // Pointer to where we store sort column and order.
+ profile *Profile // Pointer to where we store sort column and order.
}
type sortable []Stock
-func (list sortable) Len() int { return len(list) }
+
+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 }
-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 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) }
+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 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)
+}
// 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`:
@@ -162,7 +219,7 @@ func m(str string) float32 {
multiplier = 1000.0
}
- trimmed := strings.Trim(str, ` $BMK`) // Get rid of non-numeric characters.
+ trimmed := strings.Trim(str, ` $BMK`) // Get rid of non-numeric characters.
value, _ := strconv.ParseFloat(trimmed, 32)
return float32(value * multiplier)
diff --git a/yahoo_quotes.go b/yahoo_quotes.go
index a20fcb0..3e1dc62 100644
--- a/yahoo_quotes.go
+++ b/yahoo_quotes.go
@@ -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.
@@ -24,41 +24,41 @@ const quotesURL = `http://download.finance.yahoo.com/d/quotes.csv?s=%s&f=sl1c1p2
// Stock stores quote information for the particular stock ticker. The data
// for all the fields except 'Advancing' is fetched using Yahoo market API.
type Stock struct {
- Ticker string // Stock ticker.
- LastTrade string // l1: last trade.
- Change string // c6: change real time.
- ChangePct string // k2: percent change real time.
- Open string // o: market open price.
- Low string // g: day's low.
- High string // h: day's high.
- Low52 string // j: 52-weeks low.
- High52 string // k: 52-weeks high.
- Volume string // v: volume.
- AvgVolume string // a2: average volume.
- PeRatio string // r2: P/E ration real time.
- PeRatioX string // r: P/E ration (fallback when real time is N/A).
- Dividend string // d: dividend.
- Yield string // y: dividend yield.
- MarketCap string // j3: market cap real time.
- MarketCapX string // j1: market cap (fallback when real time is N/A).
- Advancing bool // True when change is >= $0.
+ Ticker string // Stock ticker.
+ LastTrade string // l1: last trade.
+ Change string // c6: change real time.
+ ChangePct string // k2: percent change real time.
+ Open string // o: market open price.
+ Low string // g: day's low.
+ High string // h: day's high.
+ Low52 string // j: 52-weeks low.
+ High52 string // k: 52-weeks high.
+ Volume string // v: volume.
+ AvgVolume string // a2: average volume.
+ PeRatio string // r2: P/E ration real time.
+ PeRatioX string // r: P/E ration (fallback when real time is N/A).
+ Dividend string // d: dividend.
+ Yield string // y: dividend yield.
+ MarketCap string // j3: market cap real time.
+ MarketCapX string // j1: market cap (fallback when real time is N/A).
+ Advancing bool // True when change is >= $0.
}
// Quotes stores relevant pointers as well as the array of stock quotes for
// the tickers we are tracking.
type Quotes struct {
- market *Market // Pointer to Market.
- profile *Profile // Pointer to Profile.
- stocks []Stock // Array of stock quote data.
- errors string // Error string if any.
+ market *Market // Pointer to Market.
+ profile *Profile // Pointer to Profile.
+ stocks []Stock // Array of stock quote data.
+ errors string // Error string if any.
}
// Sets the initial values and returns new Quotes struct.
func NewQuotes(market *Market, profile *Profile) *Quotes {
return &Quotes{
- market: market,
+ market: market,
profile: profile,
- errors: ``,
+ errors: ``,
}
}
@@ -102,7 +102,7 @@ func (quotes *Quotes) Ok() (bool, string) {
// when user adds new stock tickers.
func (quotes *Quotes) AddTickers(tickers []string) (added int, err error) {
if added, err = quotes.profile.AddTickers(tickers); err == nil && added > 0 {
- quotes.stocks = nil // Force fetch.
+ quotes.stocks = nil // Force fetch.
}
return
}
@@ -112,7 +112,7 @@ func (quotes *Quotes) AddTickers(tickers []string) (added int, err error) {
// when user removes existing stock tickers.
func (quotes *Quotes) RemoveTickers(tickers []string) (removed int, err error) {
if removed, err = quotes.profile.RemoveTickers(tickers); err == nil && removed > 0 {
- quotes.stocks = nil // Force fetch.
+ quotes.stocks = nil // Force fetch.
}
return
}