144 lines
3.7 KiB
Go
144 lines
3.7 KiB
Go
package quotation
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"strings"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type RawResponse struct {
|
|
BizSts struct {
|
|
Cd string `json:"cd"`
|
|
} `json:"BizSts"`
|
|
Msg struct {
|
|
DtTm string `json:"dtTm"`
|
|
} `json:"Msg"`
|
|
Trad []struct {
|
|
Scty struct {
|
|
SctyQtn struct {
|
|
OpngPric float64 `json:"opngPric"`
|
|
MinPric float64 `json:"minPric"`
|
|
MaxPric float64 `json:"maxPric"`
|
|
AvrgPric float64 `json:"avrgPric"`
|
|
CurPrc float64 `json:"curPrc"`
|
|
PrcFlcn float64 `json:"prcFlcn"`
|
|
} `json:"SctyQtn"`
|
|
Mkt struct {
|
|
Nm string `json:"nm"`
|
|
} `json:"mkt"`
|
|
Symb string `json:"symb"`
|
|
Desc string `json:"desc"`
|
|
IndxCmpnInd bool `json:"indxCmpnInd"`
|
|
} `json:"scty"`
|
|
TTLQty int `json:"ttlQty"`
|
|
} `json:"Trad"`
|
|
}
|
|
|
|
type Response struct {
|
|
Symbol string `json:"symbol"`
|
|
Name string `json:"name"`
|
|
Market string `json:"market"`
|
|
OpeningPrice float64 `json:"openingPrice"`
|
|
MinPrice float64 `json:"minPrice"`
|
|
MaxPrice float64 `json:"maxPrice"`
|
|
AveragePrice float64 `json:"averagePrice"`
|
|
CurrentPrice float64 `json:"currentPrice"`
|
|
PriceVariation float64 `json:"priceVariation"`
|
|
IndexComponentIndicator bool `json:"indexComponentIndicator"`
|
|
}
|
|
|
|
type RawErrorResponse struct {
|
|
BizSts struct {
|
|
Cd string `json:"cd"`
|
|
Desc string `json:"desc"`
|
|
} `json:"BizSts"`
|
|
Msg struct {
|
|
DtTm string `json:"dtTm"`
|
|
} `json:"Msg"`
|
|
}
|
|
|
|
type Error struct {
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
func HandlerListCompanies(w http.ResponseWriter, r *http.Request) {
|
|
ticker := strings.Split(r.URL.Path, "/")[4]
|
|
log.Info("Getting quotation info for ticker: " + ticker)
|
|
if ticker == "" {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
w.Write([]byte("Ticker is required"))
|
|
return
|
|
}
|
|
|
|
client := http.Client{}
|
|
res, err := client.Get(fmt.Sprintf("https://cotacao.b3.com.br/mds/api/v1/instrumentQuotation/%s", ticker))
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
w.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
|
|
defer res.Body.Close()
|
|
w.Header().Set("Content-Type", "application/json")
|
|
// add 1min cache header
|
|
w.Header().Set("Cache-Control", "max-age=60, public")
|
|
|
|
out, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
w.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
|
|
var raw RawResponse
|
|
err = json.Unmarshal(out, &raw)
|
|
if err != nil || raw.BizSts.Cd != "OK" {
|
|
var errorResponse RawErrorResponse
|
|
err = json.Unmarshal(out, &errorResponse)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
w.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
|
|
// 404
|
|
w.WriteHeader(http.StatusNotFound)
|
|
formatedError := Error{Message: errorResponse.BizSts.Desc}
|
|
err := json.NewEncoder(w).Encode(formatedError)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
w.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
var response []Response
|
|
for _, trad := range raw.Trad {
|
|
response = append(response, Response{
|
|
Symbol: trad.Scty.Symb,
|
|
Name: trad.Scty.Desc,
|
|
Market: trad.Scty.Mkt.Nm,
|
|
OpeningPrice: trad.Scty.SctyQtn.OpngPric,
|
|
MinPrice: trad.Scty.SctyQtn.MinPric,
|
|
MaxPrice: trad.Scty.SctyQtn.MaxPric,
|
|
AveragePrice: trad.Scty.SctyQtn.AvrgPric,
|
|
CurrentPrice: trad.Scty.SctyQtn.CurPrc,
|
|
PriceVariation: trad.Scty.SctyQtn.PrcFlcn,
|
|
IndexComponentIndicator: trad.Scty.IndxCmpnInd,
|
|
})
|
|
}
|
|
|
|
err = json.NewEncoder(w).Encode(response[0])
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
w.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
return
|
|
}
|