// 深圳证券交易所上市公司 func (m China) shenzhenCompanies() ([]Company, error) { urls := [...]string{ "http://www.szse.cn/szseWeb/ShowReport.szse?SHOWTYPE=EXCEL&CATALOGID=1110&tab1PAGENUM=1&ENCODE=1&TABKEY=tab1", } var list []Company for _, url := range urls { // 尝试从网络获取实时上市公司列表 html, err := net.DownloadStringRetry(url, retryTimes, retryIntervalSeconds) if err != nil { return nil, err } // 深圳证券交易所的查询结果是GBK编码的,需要转成UTF8 html, err, _, _ = gogb2312.ConvertGB2312String(html) if err != nil { return nil, err } // 解析Html companies, err := m.parseShenzhenHTML(html) if err != nil { return nil, err } list = append(list, companies...) } return list, nil }
// Crawl 获取公司每天的报价 func (yahoo YahooFinance) Crawl(_market market.Market, company market.Company, date time.Time) (*market.CompanyDailyQuote, error) { // 起止时间 start := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location()) end := start.AddDate(0, 0, 1) pattern := "https://finance-yql.media.yahoo.com/v7/finance/chart/%s?period2=%d&period1=%d&interval=1m&indicators=quote&includeTimestamps=true&includePrePost=true&events=div%%7Csplit%%7Cearn&corsDomain=finance.yahoo.com" url := fmt.Sprintf(pattern, _market.YahooQueryCode(company), end.Unix(), start.Unix()) // 查询Yahoo财经接口,返回股票分时数据 str, err := net.DownloadStringRetry(url, yahoo.RetryCount(), yahoo.RetryInterval()) if err != nil { return nil, err } // 解析Json quote := &YahooQuote{} err = json.Unmarshal([]byte(str), "e) if err != nil { return nil, err } // 校验 err = yahoo.valid(quote) if err != nil { return nil, err } // 解析 return yahoo.parse(_market, company, date, quote) }
// 更新上市公司列表 func (m HongKong) Companies() ([]Company, error) { urls := [...]string{ "https://www.hkex.com.hk/chi/market/sec_tradinfo/stockcode/eisdeqty_c.htm", "https://www.hkex.com.hk/chi/market/sec_tradinfo/stockcode/eisdgems_c.htm", } companies := make([]Company, 0) for _, url := range urls { // 尝试从网络获取实时上市公司列表 html, err := net.DownloadStringRetry(url, retryTimes, retryIntervalSeconds) if err != nil { return nil, err } // 解析json hk, err := m.parseHtml(html) if err != nil { return nil, err } companies = append(companies, hk...) } // 按Code排序 sort.Sort(CompanyList(companies)) return companies, nil }
// Companies 上市公司 func (m America) Companies() ([]Company, error) { urls := [...]string{ "http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=NASDAQ&render=download", "http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=NYSE&render=download", "http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=AMEX&render=download", } var list []Company for _, url := range urls { // 尝试从网络获取实时上市公司列表 csv, err := net.DownloadStringRetry(url, retryTimes, retryIntervalSeconds) if err != nil { return nil, err } // 解析CSV companies, err := m.parseCSV(csv) if err != nil { return nil, err } list = append(list, companies...) } // 按Code排序 sort.Sort(CompanyList(list)) return list, nil }
// 从雅虎财经获取上市公司分时数据 func downloadCompanyDaily(market Market, code, queryCode string, date time.Time) (string, error) { // 如果不存在就抓取 start := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location()) end := start.Add(time.Hour * 24) pattern := "https://finance-yql.media.yahoo.com/v7/finance/chart/%s?period2=%d&period1=%d&interval=1m&indicators=quote&includeTimestamps=true&includePrePost=true&events=div%7Csplit%7Cearn&corsDomain=finance.yahoo.com" url := fmt.Sprintf(pattern, queryCode, end.Unix(), start.Unix()) // 查询Yahoo财经接口,返回股票分时数据 return net.DownloadStringRetry(url, retryTimes, retryIntervalSeconds) }
// 查询分时数据 func QueryMinuteHistories(market, code string, start, end time.Time) ([]MinuteHistory, error) { log.Print("ServerAddress:", config.Get().ServerAddress) // url := path.Join(config.Get().ServerAddress, market, code, start, end, "1m") url := fmt.Sprintf("%s/%s/%s/%s/%s/1m", config.Get().ServerAddress, strings.ToLower(market), strings.ToLower(code), start.Format("20060102"), end.Format("20060102")) // url := "http://52.69.228.175:602/america/aapl/20151101/20151111/1m" // url := "http://localhost:602/america/aapl/20151101/20151111/1m" // log.Print("url:", url) content, err := net.DownloadStringRetry(url, 3, 10) if err != nil { return nil, err } r := result.HttpResult{} err = json.Unmarshal([]byte(content), &r) if err != nil { return nil, err } if !r.Success { return nil, fmt.Errorf("从服务器查询分时数据出错:%s", r.Message) } objs, ok := r.Data.([]interface{}) if !ok { return nil, fmt.Errorf("转换Data出错:%v", r.Data) } upperMarket := strings.Title(market) upperCode := strings.ToUpper(code) var currentTradingDate time.Time histories := make([]MinuteHistory, 0) for _, obj := range objs { //log.Print(reflect.TypeOf(obj).String()) values, ok := obj.([]interface{}) if !ok { return nil, fmt.Errorf("转换Data item出错:%v", obj) } _time, err := time.Parse("0601021504", strconv.FormatInt(int64(values[0].(float64)), 10)) if err != nil { return nil, err } date := utime.BeginOfDay(_time) if !date.Equal(currentTradingDate) { currentTradingDate = date } histories = append(histories, MinuteHistory{ Market: upperMarket, Code: upperCode, Time: _time, Open: float32(values[1].(float64)) / 1000, Close: float32(values[2].(float64)) / 1000, High: float32(values[3].(float64)) / 1000, Low: float32(values[4].(float64)) / 1000, Volume: int64(values[5].(float64))}) } return histories, nil }