// 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 := ` ...
Symbol Last Change
Dow 15,300.34 Up 75.65 (0.50%)
Nasdaq 3,504.26 Up 19.43 (0.56%)
S&P 500 1,652.32 Up 11.86 (0.72%)
10-Yr Bond 2.63% Down 0.02
NYSE Volume 3,490,723,250.00
Nasdaq Volume... 1,594,900,625.00
Indices: US - World | Most Actives

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
... ` html = ` ...
NYSE LAST CHANGE
Symbol Last Change
Dow 15,464.30 Up 3.38 (0.02%)
Nasdaq 3,600.08 0.00 (0.00%)
S&P 500 1,680.19 Up 5.17 (0.31%)
10-Yr Bond 2.60% Up 0.03
NYSE Volume 3,315,714,000.00
Nasdaq Volume... 1,578,376,875.00
Indices: US - World | Most Actives

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
*in millions

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() }