|
|
|
@ -57,8 +57,14 @@ type stockinfo struct { |
|
|
|
|
Scode string |
|
|
|
|
Sname string |
|
|
|
|
Ft string |
|
|
|
|
Upt string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type recordinfo struct { |
|
|
|
|
Date string |
|
|
|
|
Time string |
|
|
|
|
Totalstocks string |
|
|
|
|
} |
|
|
|
|
// Quotes stores relevant pointers as well as the array of stock quotes for
|
|
|
|
|
// the tickers we are tracking.
|
|
|
|
|
type Quotes struct { |
|
|
|
@ -74,6 +80,7 @@ type Quotes struct { |
|
|
|
|
totalstocks []stockinfo |
|
|
|
|
needrefresh bool |
|
|
|
|
addedstocks []string |
|
|
|
|
Allflag bool |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Sets the initial values and returns new Quotes struct.
|
|
|
|
@ -94,6 +101,7 @@ func NewQuotes(market *Market, profile *Profile, res map[string]*stock.Stock, wa |
|
|
|
|
totalstocks: []stockinfo{}, |
|
|
|
|
upstocks: map[string]string{}, |
|
|
|
|
needrefresh: true, |
|
|
|
|
Allflag: false, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -389,6 +397,31 @@ func padString(str string, length int) string { |
|
|
|
|
return str |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (quotes *Quotes) Sendtotalstocks() { |
|
|
|
|
stockdata, err := json.Marshal(quotes.totalstocks)//json.MarshalIndent(quotes.totalstocks, "", " ")
|
|
|
|
|
if err != nil { |
|
|
|
|
fmt.Println(err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
topic := "stock/response/standby" |
|
|
|
|
|
|
|
|
|
dataresp := map[string]interface{}{ |
|
|
|
|
"totalstocks": string(stockdata), |
|
|
|
|
"date": quotes.watchlist.Baseon, |
|
|
|
|
"time": time.Now().Format("15:04:05"), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
jsonData, err := json.MarshalIndent(dataresp, "", " ") |
|
|
|
|
if err != nil { |
|
|
|
|
fmt.Println(err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
message := string(jsonData) |
|
|
|
|
token := quotes.client.Publish(topic, 0, false, message) |
|
|
|
|
token.Wait() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (quotes *Quotes) Sendstockgraphreq(index interface{}, istime bool) { |
|
|
|
|
var selcode string |
|
|
|
|
if intvalue, ok := index.(int); ok { |
|
|
|
@ -469,7 +502,7 @@ func (quotes *Quotes) parsereview(res map[string]*stock.Stock) (*Quotes, error) |
|
|
|
|
q := res[scode].Market |
|
|
|
|
b := res[scode].Base |
|
|
|
|
|
|
|
|
|
quotes.totalstocks = append(quotes.totalstocks, stockinfo{scode, b.Name, q.Time}) |
|
|
|
|
quotes.totalstocks = append(quotes.totalstocks, stockinfo{scode, b.Name, q.Time, q.Time}) |
|
|
|
|
quotes.upstocks[scode] = q.Time |
|
|
|
|
|
|
|
|
|
open, close, high, low, ndays := getnextdaysHL(scode, wamap[scode].AnalyseFrom) |
|
|
|
@ -521,107 +554,74 @@ func (quotes *Quotes) parsereview(res map[string]*stock.Stock) (*Quotes, error) |
|
|
|
|
return quotes, nil
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// this will parse the json objects
|
|
|
|
|
func (quotes *Quotes) parse2(body []byte, res map[string]*stock.Stock) (*Quotes, error) { |
|
|
|
|
// response -> quoteResponse -> result|error (array) -> map[string]interface{}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Stocks has non-int things
|
|
|
|
|
// d := map[string]map[string][]Stock{}
|
|
|
|
|
// some of these are numbers vs strings
|
|
|
|
|
// d := map[string]map[string][]map[string]string{}
|
|
|
|
|
//d := map[string]map[string][]map[string]interface{}{}
|
|
|
|
|
//err := json.Unmarshal(body, &d)
|
|
|
|
|
//if err != nil {
|
|
|
|
|
// return nil, err
|
|
|
|
|
//}
|
|
|
|
|
//results := d["quoteResponse"]["result"]
|
|
|
|
|
/* |
|
|
|
|
quotes.stocks = make([]Stock, len(results)) |
|
|
|
|
for i, raw := range results { |
|
|
|
|
result := map[string]string{} |
|
|
|
|
for k, v := range raw { |
|
|
|
|
switch v.(type) { |
|
|
|
|
case string: |
|
|
|
|
result[k] = v.(string) |
|
|
|
|
case float64: |
|
|
|
|
result[k] = float2Str(v.(float64)) |
|
|
|
|
default: |
|
|
|
|
result[k] = fmt.Sprintf("%v", v) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
quotes.stocks[i].Ticker = result["symbol"] |
|
|
|
|
quotes.stocks[i].LastTrade = result["regularMarketPrice"] |
|
|
|
|
quotes.stocks[i].Change = result["regularMarketChange"] |
|
|
|
|
quotes.stocks[i].ChangePct = result["regularMarketChangePercent"] |
|
|
|
|
quotes.stocks[i].Open = result["regularMarketOpen"] |
|
|
|
|
quotes.stocks[i].Low = result["regularMarketDayLow"] |
|
|
|
|
quotes.stocks[i].High = result["regularMarketDayHigh"] |
|
|
|
|
quotes.stocks[i].Low52 = result["fiftyTwoWeekLow"] |
|
|
|
|
quotes.stocks[i].High52 = result["fiftyTwoWeekHigh"] |
|
|
|
|
quotes.stocks[i].Volume = result["regularMarketVolume"] |
|
|
|
|
quotes.stocks[i].AvgVolume = result["averageDailyVolume10Day"] |
|
|
|
|
quotes.stocks[i].PeRatio = result["trailingPE"] |
|
|
|
|
// TODO calculate rt
|
|
|
|
|
quotes.stocks[i].PeRatioX = result["trailingPE"] |
|
|
|
|
quotes.stocks[i].Dividend = result["trailingAnnualDividendRate"] |
|
|
|
|
quotes.stocks[i].Yield = result["trailingAnnualDividendYield"] |
|
|
|
|
quotes.stocks[i].MarketCap = result["marketCap"] |
|
|
|
|
// TODO calculate rt?
|
|
|
|
|
quotes.stocks[i].MarketCapX = result["marketCap"] |
|
|
|
|
quotes.stocks[i].Currency = result["currency"] |
|
|
|
|
quotes.stocks[i].PreOpen = result["preMarketChangePercent"] |
|
|
|
|
quotes.stocks[i].AfterHours = result["postMarketChangePercent"] |
|
|
|
|
|
|
|
|
|
fmt.Println(i) |
|
|
|
|
fmt.Println("-------------------") |
|
|
|
|
for k, v := range result { |
|
|
|
|
fmt.Println(k, v) |
|
|
|
|
} |
|
|
|
|
fmt.Println("-------------------") |
|
|
|
|
|
|
|
|
|
adv, err := strconv.ParseFloat(quotes.stocks[i].Change, 64) |
|
|
|
|
quotes.stocks[i].Direction = 0 |
|
|
|
|
if err == nil { |
|
|
|
|
if adv < 0.0 { |
|
|
|
|
quotes.stocks[i].Direction = -1 |
|
|
|
|
} else if adv > 0.0 { |
|
|
|
|
quotes.stocks[i].Direction = 1 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
func (quotes *Quotes) Reload(){ |
|
|
|
|
filedata, err := ioutil.ReadFile("stocklist.json") |
|
|
|
|
if err != nil { |
|
|
|
|
fmt.Println(err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Use the "http.Get" function to fetch the URL and get the response
|
|
|
|
|
response, err := http.Get("http://119.29.166.226/q/dayjson/2023-04-20ml.json")//("http://119.29.166.226/q/dayjson/ml.json")
|
|
|
|
|
var stocks []stockinfo |
|
|
|
|
err = json.Unmarshal(filedata, &stocks) |
|
|
|
|
if err != nil { |
|
|
|
|
// Handle error
|
|
|
|
|
fmt.Println(err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
defer response.Body.Close() |
|
|
|
|
|
|
|
|
|
//respbody, err := ioutil.ReadAll(response.Body)
|
|
|
|
|
//if err != nil {
|
|
|
|
|
// handle error
|
|
|
|
|
//}
|
|
|
|
|
quotes.totalstocks = quotes.totalstocks[:0] |
|
|
|
|
for _, item := range quotes.profile.Tickers {//profile stock to trace
|
|
|
|
|
if _, ok := quotes.res[item]; ok { |
|
|
|
|
quotes.totalstocks = append(quotes.totalstocks, stockinfo{item, quotes.res[item].Base.Name, "09:00:00", "09:00:00"}) |
|
|
|
|
quotes.upstocks["sh600000"] = "09:00:00" |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
quotes.totalstocks = append(quotes.totalstocks, stocks...) |
|
|
|
|
for _, item := range stocks { |
|
|
|
|
quotes.upstocks[item.Scode] = item.Upt |
|
|
|
|
} |
|
|
|
|
quotes.stocks = nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Use the "json" package to decode the response body into a JSON object
|
|
|
|
|
func (quotes *Quotes) Reloadbyjson(payload []byte){ |
|
|
|
|
/*filedata, err := ioutil.ReadFile("stocklist0616.json") |
|
|
|
|
if err != nil { |
|
|
|
|
fmt.Println(err) |
|
|
|
|
return |
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
var watchlist Watchlist |
|
|
|
|
var scodes []string |
|
|
|
|
err = json.NewDecoder(response.Body).Decode(&watchlist) |
|
|
|
|
var records recordinfo |
|
|
|
|
err := json.Unmarshal(payload, &records) |
|
|
|
|
if err != nil { |
|
|
|
|
// Handle error
|
|
|
|
|
fmt.Println(err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//var data Data
|
|
|
|
|
//err = json.Unmarshal(respbody, &data)
|
|
|
|
|
var stocks []stockinfo |
|
|
|
|
err = json.Unmarshal([]byte(records.Totalstocks), &stocks) |
|
|
|
|
if err != nil { |
|
|
|
|
// Handle error
|
|
|
|
|
fmt.Println(err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
quotes.totalstocks = quotes.totalstocks[:0] |
|
|
|
|
for _, item := range quotes.profile.Tickers {//profile stock to trace
|
|
|
|
|
if _, ok := quotes.res[item]; ok { |
|
|
|
|
quotes.totalstocks = append(quotes.totalstocks, stockinfo{item, quotes.res[item].Base.Name, "09:00:00", "09:00:00"}) |
|
|
|
|
quotes.upstocks["sh600000"] = "09:00:00" |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
quotes.totalstocks = append(quotes.totalstocks, stocks...) |
|
|
|
|
for _, item := range stocks { |
|
|
|
|
quotes.upstocks[item.Scode] = item.Upt |
|
|
|
|
} |
|
|
|
|
quotes.stocks = nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (quotes* Quotes) ResetforNewday(watchlist *Watchlist) { |
|
|
|
|
quotes.totalstocks = quotes.totalstocks[:0] |
|
|
|
|
quotes.watchlist = watchlist |
|
|
|
|
quotes.upstocks = map[string]string{} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// this will parse the json objects
|
|
|
|
|
func (quotes *Quotes) parse2(body []byte, res map[string]*stock.Stock) (*Quotes, error) { |
|
|
|
|
var scodes []string |
|
|
|
|
wamap := make(map[string]WatchlistItem, len(quotes.watchlist.Watchlist)) |
|
|
|
|
for _, item := range quotes.watchlist.Watchlist { |
|
|
|
@ -633,8 +633,10 @@ func (quotes *Quotes) parse2(body []byte, res map[string]*stock.Stock) (*Quotes, |
|
|
|
|
if _, ok := res[item.Scode]; ok { |
|
|
|
|
//fmt.Println(item.Scode)
|
|
|
|
|
q := res[item.Scode].Market |
|
|
|
|
isin, _ := contains(quotes.totalstocks, item.Scode) |
|
|
|
|
//fmt.Println(q.Name, q.PreClose , q.LastPrice ,q.LastPrice , enterPrice)
|
|
|
|
|
if q.PreClose < q.LastPrice && q.LastPrice >= enterPrice && q.PreClose < enterPrice{ |
|
|
|
|
if ((q.PreClose < q.LastPrice && q.LastPrice >= enterPrice && q.PreClose < enterPrice )|| |
|
|
|
|
isin == true && quotes.Allflag == true){ |
|
|
|
|
//fmt.Println(enterPrice)
|
|
|
|
|
scodes = append(scodes, item.Scode) |
|
|
|
|
//fmt.Println(scodes)
|
|
|
|
@ -671,7 +673,7 @@ func (quotes *Quotes) parse2(body []byte, res map[string]*stock.Stock) (*Quotes, |
|
|
|
|
|
|
|
|
|
isin, index := contains(quotes.totalstocks, scode) |
|
|
|
|
if isin == false { |
|
|
|
|
quotes.totalstocks = append(quotes.totalstocks, stockinfo{scode, q.Name, q.Time}) |
|
|
|
|
quotes.totalstocks = append(quotes.totalstocks, stockinfo{scode, q.Name, q.Time, q.Time}) |
|
|
|
|
quotes.upstocks[scode] = q.Time |
|
|
|
|
}else { |
|
|
|
|
|
|
|
|
@ -680,6 +682,7 @@ func (quotes *Quotes) parse2(body []byte, res map[string]*stock.Stock) (*Quotes, |
|
|
|
|
diff := gettimediff(quotes.totalstocks[index].Ft, q.Time) |
|
|
|
|
if diff > time.Hour { |
|
|
|
|
quotes.upstocks[scode] = q.Time |
|
|
|
|
quotes.totalstocks[index].Upt = q.Time |
|
|
|
|
} |
|
|
|
|
quotes.totalstocks[index].Ft = q.Time |
|
|
|
|
} |
|
|
|
@ -728,6 +731,7 @@ func (quotes *Quotes) parse2(body []byte, res map[string]*stock.Stock) (*Quotes, |
|
|
|
|
|
|
|
|
|
quotes.stocks[i].AvgVolume = quotes.upstocks[scode] |
|
|
|
|
quotes.stocks[i].Dividend = b.Symbol |
|
|
|
|
quotes.stocks[i].PeRatio = quotes.watchlist.Baseon[5:] |
|
|
|
|
if _, ok := wamap[scode]; ok { |
|
|
|
|
strprice, _ := strconv.ParseFloat(wamap[scode].Enterprice, 64) |
|
|
|
|
stdchange := q.LastPrice - strprice |
|
|
|
|