// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
package main
import (
"fmt"
"bytes"
"regexp"
"strings"
"text/template"
)
type Market struct {
Dow map[string]string
Nasdaq map[string]string
Sp500 map[string]string
Advances map[string]string
Declines map[string]string
Unchanged map[string]string
Highs map[string]string
Lows map[string]string
}
//-----------------------------------------------------------------------------
func main() {
html := `
...
Advances & Declines
|
NYSE |
NASDAQ |
Advances |
2,992
(72%)
|
1,445
(57%)
|
Declines |
1,040
(25%)
|
950
(38%)
|
Unchanged |
113
(3%)
|
128
(5%)
|
Up Vol* |
2,582
(74%)
|
950
(60%)
|
Down Vol* |
863
(25%)
|
625
(39%)
|
Unch. Vol* |
46
(1%)
|
20
(1%)
|
New Hi's |
350 |
314 |
New Lo's |
117 |
19 |
...
NYSE |
LAST |
CHANGE |
`
html = `
...
Advances & Declines
|
NYSE |
NASDAQ |
Advances |
1,962
(48%)
|
1,322
(53%)
|
Declines |
2,029
(49%)
|
1,068
(43%)
|
Unchanged |
126
(3%)
|
115
(5%)
|
Up Vol* |
1,822
(55%)
|
918
(58%)
|
Down Vol* |
1,417
(43%)
|
636
(40%)
|
Unch. Vol* |
76
(2%)
|
24
(2%)
|
New Hi's |
355 |
337 |
New Lo's |
110 |
14 |
Most Actives
...
`
start := strings.Index(html, ``
const some = `<.+?`
const space = `\s*`
const color = `#([08c]{6});">\s*`
const price = `([\d\.,]+)`
const percent = `\(([\d\.,%]+)\)`
regex := []string{
"(Dow)", any, price, some, color, price, some, percent, any,
"(Nasdaq)", any, price, some, color, price, some, percent, any,
"(S&P 500)", any, price, some, color, price, some, percent, any,
"(Advances)", any, price, space, percent, any, price, space, percent, any,
"(Declines)", any, price, space, percent, any, price, space, percent, any,
"(Unchanged)", any, price, space, percent, any, price, space, percent, any,
"(New Hi's)", any, price, any, price, any,
"(New Lo's)", any, price, any, price, any,
}
re := regexp.MustCompile(strings.Join(regex, ""))
matches := re.FindAllStringSubmatch(html, -1)
if len(matches) > 0 {
fmt.Printf("%d matches\n", len(matches[0]))
for i, str := range matches[0][1:] {
fmt.Printf("%d) [%s]\n", i, str)
}
} else {
println("No matches")
}
return
m := Market{
Dow: make(map[string]string),
Nasdaq: make(map[string]string),
Sp500: make(map[string]string),
Advances: make(map[string]string),
Declines: make(map[string]string),
Unchanged: make(map[string]string),
Highs: make(map[string]string),
Lows: make(map[string]string),
}
m.Dow[`name`] = matches[0][1]
m.Dow[`latest`] = matches[0][2]
m.Dow[`change`] = matches[0][4]
if matches[0][3] == "Up" {
m.Dow[`change`] = "+" + matches[0][4]
m.Dow[`percent`] = "+" + matches[0][5]
} else {
m.Dow[`change`] = "-" + matches[0][4]
m.Dow[`percent`] = "-" + matches[0][5]
}
m.Nasdaq[`name`] = matches[0][6]
m.Nasdaq[`latest`] = matches[0][7]
if matches[0][8] == "Up" {
m.Nasdaq[`change`] = "+" + matches[0][9]
m.Nasdaq[`percent`] = "+" + matches[0][10]
} else {
m.Nasdaq[`change`] = "-" + matches[0][9]
m.Nasdaq[`percent`] = "-" + matches[0][10]
}
m.Sp500[`name`] = matches[0][11]
m.Sp500[`latest`] = matches[0][12]
if matches[0][13] == "Up" {
m.Sp500[`change`] = "+" + matches[0][14]
m.Sp500[`percent`] = "+" + matches[0][15]
} else {
m.Sp500[`change`] = "-" + matches[0][14]
m.Sp500[`percent`] = "-" + matches[0][15]
}
m.Advances[`name`] = matches[0][16]
m.Advances[`nyse`] = matches[0][17]
m.Advances[`nysep`] = matches[0][18]
m.Advances[`nasdaq`] = matches[0][19]
m.Advances[`nasdaqp`] = matches[0][20]
m.Declines[`name`] = matches[0][21]
m.Declines[`nyse`] = matches[0][22]
m.Declines[`nysep`] = matches[0][23]
m.Declines[`nasdaq`] = matches[0][24]
m.Declines[`nasdaqp`] = matches[0][25]
m.Unchanged[`name`] = matches[0][26]
m.Unchanged[`nyse`] = matches[0][27]
m.Unchanged[`nysep`] = matches[0][28]
m.Unchanged[`nasdaq`] = matches[0][29]
m.Unchanged[`nasdaqp`] = matches[0][30]
m.Highs[`name`] = matches[0][31]
m.Highs[`nyse`] = matches[0][32]
m.Highs[`nasdaq`] = matches[0][33]
m.Lows[`name`] = matches[0][34]
m.Lows[`nyse`] = matches[0][35]
m.Lows[`nasdaq`] = matches[0][36]
fmt.Printf("%q\n", m)
println(Format(m))
}
//-----------------------------------------------------------------------------
func Format(m Market) string {
markup := `{{.Dow.name}}: {{.Dow.change}} ({{.Dow.percent}}) at {{.Dow.latest}}, `
markup += `{{.Sp500.name}}: {{.Sp500.change}} ({{.Sp500.percent}}) at {{.Sp500.latest}}, `
markup += `{{.Nasdaq.name}}: {{.Nasdaq.change}} ({{.Nasdaq.percent}}) at {{.Nasdaq.latest}}`
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`
markup += "\n"
markup += `New highs: {{.Highs.nyse}} on NYSE and {{.Highs.nasdaq}} on Nasdaq. `
markup += `New lows: {{.Lows.nyse}} on NYSE and {{.Lows.nasdaq}} on Nasdaq.`
template, err := template.New("screen").Parse(markup)
if err != nil {
panic(err)
}
buffer := new(bytes.Buffer)
err = template.Execute(buffer, m)
if err != nil {
panic(err)
}
return buffer.String()
}