You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1214 lines
43 KiB

2 months ago
package processor
import (
"encoding/json"
"fmt"
"github.com/360EntSecGroup-Skylar/excelize"
"github.com/gin-gonic/gin"
"github.com/shopspring/decimal"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"log"
"net/http"
"strconv"
"strings"
"time"
"wss-pool/cmd/common"
"wss-pool/config"
"wss-pool/internal"
"wss-pool/internal/data"
"wss-pool/internal/data/business"
"wss-pool/internal/data/mysqlbusiness"
red "wss-pool/internal/redis"
"wss-pool/logging/applogger"
"wss-pool/pkg/model"
"wss-pool/pkg/model/stock"
)
var topIc = "https://"
var TotalSize int = 10
var FreeSymbolKey = "USER:MARKET:"
var MarketType = map[int]string{
1: "spots",
2: "contract",
3: "US",
4: "Indonesia",
5: "Malaysia",
6: "Thailand",
7: "India",
9: "Singapore",
12: "HongKong",
14: "UK",
15: "France",
16: "Germany",
17: "Brazil",
18: "Japan",
19: "Forex",
}
type StockSymbol struct {
Code string `json:"code"`
Name string `json:"name"`
MarketType int `json:"market_type"`
TradeNumericCode string `json:"trade_numeric_code"`
}
// ExchangeSymbolList Obtain stock list data
func ExchangeSymbolList(c *gin.Context) {
/* 股票代码查询业务逻辑
1列表查询传入交易所代码
2搜索
1带有交易所代码--模糊查询当前交易所的股票
2不带有交易所代码--模糊查询所有股票
3查询股票列表不排序,搜索排序(通过code排序)
*/
symbol := internal.ReplaceStr(c.Query("symbol")) // 国家(美股,马股)
pageSize := internal.IntegerInit(internal.ReplaceStr(c.Query("pageSize"))) // 每页显示多少条数据
pageNumber := internal.IntegerInit(internal.ReplaceStr(c.Query("pageNumber"))) // 第几页
sort := internal.IntegerInit(internal.ReplaceStr(c.Query("sort"))) // Code排序
search := internal.ReplaceStr(c.Query("search")) // 搜索数据(模糊
code := internal.ReplaceStr(c.Query("code")) // 多个代码
primaryExchange := internal.ReplaceStr(c.Query("primaryExchange")) // 交易所
if pageSize <= 0 || pageNumber <= 0 {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "分页参数不能为零", internal.QueryError))
return
}
var condition = symbol
var filter bson.M
if len(search) > 0 {
//香港股票代码特殊处理
if symbol == "HongKong" {
numberWithoutLeadingZeros := strings.TrimLeft(search, "0")
if numberWithoutLeadingZeros == "" {
numberWithoutLeadingZeros = "0"
}
search = numberWithoutLeadingZeros
}
if len(primaryExchange) > 0 {
filter = bson.M{"Country": condition, "Exchange": primaryExchange, "$or": []bson.M{{"Code": bson.M{"$regex": search}}, {"Name": bson.M{"$regex": search}}, {"NumericCode": bson.M{"$regex": search}}}, "YesterdayClose": bson.M{"$ne": ""}}
} else {
filter = bson.M{"Country": condition, "$or": []bson.M{{"Code": bson.M{"$regex": search}}, {"Name": bson.M{"$regex": search}}, {"NumericCode": bson.M{"$regex": search}}}, "YesterdayClose": bson.M{"$ne": ""}, "Exchange": bson.M{"$exists": true}}
}
} else {
if len(primaryExchange) > 0 {
filter = bson.M{"Country": condition, "Exchange": primaryExchange, "YesterdayClose": bson.M{"$ne": ""}}
} else {
filter = bson.M{"Country": condition, "YesterdayClose": bson.M{"$ne": ""}, "Exchange": bson.M{"$exists": true}}
}
}
codeSearch := "Code"
if symbol == "Malaysia" {
codeSearch = "NumericCode"
}
str_s := strings.Split(code, "-")
if len(code) > 0 {
if len(primaryExchange) > 0 {
filter = bson.M{"Country": condition, "Exchange": primaryExchange, "YesterdayClose": bson.M{"$ne": ""}, codeSearch: bson.M{"$in": str_s}}
} else {
filter = bson.M{"Country": condition, "YesterdayClose": bson.M{"$ne": ""}, codeSearch: bson.M{"$in": str_s}, "Exchange": bson.M{"$exists": true}}
}
}
total, err := data.MgoFindTotal(data.StockList, filter)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("查询数据表: %v", data.StockList)
//applogger.Debug("查询数据总数: %v", total)
pageData := make([]stock.StockPolygon, 0)
if sort == 0 {
sort = -1
}
sortField := "Vol"
if symbol == "US" {
sortField = "DP"
}
//applogger.Debug("查询条件: %v", filter)
var md stock.MgoPageSize
md.PageSize = pageSize
md.PageNumber = pageNumber
md.Total = total
if err = data.MgoPagingFindStruct(data.StockList, filter, int64(pageSize), int64(pageNumber), sortField, sort, &pageData); err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QuerySuccess))
}
//applogger.Debug("查询数据: %", len(pageData))
if len(pageData) <= 0 {
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QuerySuccess))
return
}
var dataStockPolygon = make([]stock.StockPolygon, 0)
for k, v := range pageData {
key := business.StockClosingPrice[fmt.Sprintf("%sNew", v.Locale)]
pageData[k].ClosePrice, err = red.Hget(key, v.Code)
if err != nil {
continue
}
if common.IsExistStock(v.Locale, v.Code) {
dataStockPolygon = append(dataStockPolygon, pageData[k])
}
}
md.Data = dataStockPolygon
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QuerySuccess))
}
// ExchangeFreeSymbolList exchange free symbol list
func ExchangeFreeSymbolList(c *gin.Context) {
id := internal.ReplaceStr(c.Query("id")) // 用户ID
market_type := internal.IntegerInit(internal.ReplaceStr(c.Query("market_type"))) // 市场
pageSize := internal.IntegerInit(internal.ReplaceStr(c.Query("pageSize"))) // 每页显示多少条数据
pageNumber := internal.IntegerInit(internal.ReplaceStr(c.Query("pageNumber"))) // 第几页
if pageSize <= 0 || pageNumber <= 0 {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "分页参数不能为零", internal.QueryError))
return
}
if len(id) <= 0 || market_type <= 0 {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "参数不能为空", internal.QueryError))
return
}
var md stock.MgoPageSize
var dataStockPolygon = make([]stock.StockPolygon, 0)
md.PageSize = pageSize
md.PageNumber = pageNumber
userIdKey := fmt.Sprintf("%v%v", FreeSymbolKey, id)
result, err := red.Get_Cache_Byte(userIdKey)
if err != nil {
md.Data = dataStockPolygon
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QueryError))
return
}
var freeList []StockSymbol
if err = json.Unmarshal(result, &freeList); err != nil {
md.Data = dataStockPolygon
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QueryError))
return
}
// 组合需要查询自选缓存股票code
var symbolList []string
var condition = MarketType[market_type]
for _, value := range freeList {
if market_type == value.MarketType {
symbolList = append(symbolList, value.Code)
}
}
//applogger.Debug("查询自选股票列表: %v", symbolList)
codeSearch := "Code"
if condition == "Malaysia" {
codeSearch = "NumericCode"
}
filter := bson.M{"Country": condition, "YesterdayClose": bson.M{"$ne": ""}, codeSearch: bson.M{"$in": symbolList}, "Exchange": bson.M{"$exists": true}}
total, err := data.MgoFindTotal(data.StockList, filter)
if err != nil {
md.Total = int64(len(symbolList))
md.Data = dataStockPolygon
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QueryError))
return
}
//applogger.Debug("查询数据表: %v", data.StockList)
//applogger.Debug("查询数据总数: %v", total)
//applogger.Debug("查询条件: %v", filter)
md.Total = total
var pageData = make([]stock.StockPolygon, 0)
sortField := "Vol"
if condition == "US" {
sortField = "DP"
}
if err = data.MgoPagingFindStruct(data.StockList, filter, int64(pageSize), int64(pageNumber), sortField, -1, &pageData); err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QuerySuccess))
return
}
if len(pageData) <= 0 {
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QuerySuccess))
return
}
for k, v := range pageData {
key := business.StockClosingPrice[fmt.Sprintf("%sNew", v.Locale)]
pageData[k].ClosePrice, err = red.Hget(key, v.Code)
if err != nil {
continue
}
if common.IsExistStock(v.Locale, v.Code) {
dataStockPolygon = append(dataStockPolygon, pageData[k])
}
}
md.Data = dataStockPolygon
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, md, internal.QuerySuccess))
}
func UpdateKeepDecimal(c *gin.Context) {
param := model.Data{}
err := c.BindJSON(&param)
if err != nil {
applogger.Error("BindJSON", err.Error())
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "param error", internal.QueryError))
return
} else if param.StockCode == "" {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "stock_code null", internal.QueryError))
return
} else if param.KeepDecimal == 0 {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "keep_decimal error", internal.QueryError))
return
} else if param.Currency == "" {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "currency error", internal.QueryError))
return
}
filterS := bson.D{{"Code", bson.M{
"$eq": param.StockCode,
}}, {"Currency", bson.M{
"$eq": param.Currency,
}}}
updateData := bson.M{
"$set": bson.M{
"Code": param.StockCode,
"KeepDecimal": param.KeepDecimal,
}}
if err := data.MgoUpdateOne(data.StockList, filterS, updateData); err != nil {
applogger.Error("MgoBulkWrite update err:%v", err)
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err.Error(), internal.QueryError))
return
}
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "ok", internal.QuerySuccess))
}
func SymbolToExcel(c *gin.Context) {
country := internal.ReplaceStr(c.Query("country"))
filter := bson.M{}
if country != "" {
filter = bson.M{"Country": country}
} else {
country = "total"
}
res := make([]stock.StockPolygon, 0)
data.MgoFindRes(data.StockList, filter, &res)
// 创建Excel文件
file := excelize.NewFile()
sheetName := "Sheet1"
// 写入表头
file.SetCellValue(sheetName, "A1", "Code")
file.SetCellValue(sheetName, "B1", "Name")
file.SetCellValue(sheetName, "C1", "Country")
file.SetCellValue(sheetName, "D1", "PrimaryExchange")
file.SetCellValue(sheetName, "E1", "Symbol")
file.SetCellValue(sheetName, "F1", "NumericCode")
file.SetCellValue(sheetName, "G1", "Intro")
file.SetCellValue(sheetName, "H1", "JapanIntro")
file.SetCellValue(sheetName, "I1", "JapanName")
// 写入数据
row := 2 // 从第二行开始写入数据
for _, val := range res {
if val.PrimaryExchange == "" {
applogger.Error(val.Locale, val.Code, " not Exchange")
continue
}
file.SetCellValue(sheetName, "A"+strconv.Itoa(row), val.Code)
file.SetCellValue(sheetName, "B"+strconv.Itoa(row), val.Name)
file.SetCellValue(sheetName, "C"+strconv.Itoa(row), val.Locale)
file.SetCellValue(sheetName, "D"+strconv.Itoa(row), val.PrimaryExchange)
file.SetCellValue(sheetName, "E"+strconv.Itoa(row), val.Symbol)
file.SetCellValue(sheetName, "F"+strconv.Itoa(row), val.NumericCode)
file.SetCellValue(sheetName, "G"+strconv.Itoa(row), val.Intro)
file.SetCellValue(sheetName, "H"+strconv.Itoa(row), val.JapanIntro)
file.SetCellValue(sheetName, "I"+strconv.Itoa(row), val.JapanName)
row++
}
// 保存文件
err := file.SaveAs(fmt.Sprintf("/home/ubuntu/wss-server/%s.xlsx", country))
if err != nil {
log.Fatal(err)
}
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", internal.QuerySuccess))
}
func ExcelToSymbolByJapanJson(c *gin.Context) {
data.Mgo_init(config.Config.Mongodb)
f, err := excelize.OpenFile("/home/ubuntu/wss-server/Japan.xlsx")
if err != nil {
applogger.Error("ExcelToSymbol err:%v", err)
return
}
var dataList []mongo.WriteModel
// 获取 Sheet1 上所有单元格
rows := f.GetRows("Sheet1")
for k, row := range rows {
if k == 0 {
continue
}
applogger.Debug("Code:%v", row[0])
applogger.Debug("Name:%v", row[1])
applogger.Debug("Country:%v", row[2])
applogger.Debug("PrimaryExchange:%v", row[3])
applogger.Debug("Symbol:%v", row[4])
applogger.Debug("NumericCode:%v", row[5])
applogger.Debug("Intro:%v", row[6])
applogger.Debug("JapanIntro:%v", row[7])
applogger.Debug("JapanName:%v", row[8])
filter := bson.D{{"Code", bson.M{
"$eq": row[0],
}}, {"Country", bson.M{
"$eq": row[2],
}}}
update := bson.D{{"$set", bson.D{
{"Code", row[0]},
{"Name", row[1]},
{"Country", row[2]},
{"PrimaryExchange", row[3]},
{"Symbol", row[4]},
{"NumericCode", row[5]},
{"Intro", row[6]},
{"JapanIntro", row[7]},
{"JapanName", row[8]},
}}}
models := mongo.NewUpdateOneModel().SetFilter(filter).SetUpdate(update).SetUpsert(true)
dataList = append(dataList, models)
}
if len(dataList) > 0 {
if err = data.MgoBulkWrite(data.StockList, dataList); err != nil {
applogger.Error("MgoInsertMany err:%v", err)
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "operation failure", internal.QueryError))
return
}
}
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok"))
}
func ExcelToSymbolByJapan(c *gin.Context) {
data.Mgo_init(config.Config.Mongodb)
f, err := excelize.OpenFile("/home/ubuntu/wss-server/Japan_edited.xlsx")
if err != nil {
applogger.Error("ExcelToSymbol err:%v", err)
return
}
var dataList []mongo.WriteModel
// 获取 Sheet1 上所有单元格
rows := f.GetRows("Sheet1")
for k, row := range rows {
if k == 0 {
continue
}
applogger.Debug("Name:%v", row[0])
applogger.Debug("Symbol:%v", row[1])
applogger.Debug("JapanName:%v", row[2])
filter := bson.D{{"Symbol", bson.M{"$eq": row[1]}}}
update := bson.D{{"$set", bson.D{{"JapanName", row[2]}}}}
models := mongo.NewUpdateOneModel().SetFilter(filter).SetUpdate(update).SetUpsert(true)
dataList = append(dataList, models)
}
if len(dataList) > 0 {
if err = data.MgoBulkWrite(data.StockList, dataList); err != nil {
applogger.Error("MgoInsertMany err:%v", err)
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "operation failure", internal.QueryError))
return
}
}
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok"))
}
func ExcelToForexCode(c *gin.Context) {
data.Mgo_init(config.Config.Mongodb)
f, err := excelize.OpenFile("/home/ubuntu/wss-server/forex_code.xlsx")
if err != nil {
applogger.Error("ExcelToSymbol err:%v", err)
return
}
var dataList []mongo.WriteModel
applogger.Debug("这里执行了。。。。。")
// 获取 Sheet1 上所有单元格
rows := f.GetRows("Sheet1")
for k, row := range rows {
if k == 0 {
continue
}
applogger.Debug("code:%v", row[0])
applogger.Debug("name:%v", row[1])
applogger.Debug("category:%v", row[2])
applogger.Debug("symbol:%v", row[3])
filter := bson.D{{"code", bson.M{"$eq": row[0]}}}
update := bson.D{{"$set", bson.D{
{"code", row[0]},
{"name", row[1]},
{"category", row[2]},
{"symbol", row[3]},
}}}
models := mongo.NewUpdateOneModel().SetFilter(filter).SetUpdate(update).SetUpsert(true)
dataList = append(dataList, models)
}
applogger.Debug("这里执行了。。。。。111111")
if len(dataList) > 0 {
if err = data.MgoBulkWrite(data.ForexListBak, dataList); err != nil {
applogger.Error("MgoInsertMany err:%v", err)
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "operation failure", internal.QueryError))
return
}
}
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", "ok"))
}
func TickerToExcel(c *gin.Context) {
filter := bson.M{}
res := make([]stock.ForexData, 0)
data.MgoFindRes(data.StockList, filter, &res)
// 创建Excel文件
file := excelize.NewFile()
sheetName := "Sheet1"
// 写入表头
file.SetCellValue(sheetName, "A1", "code")
file.SetCellValue(sheetName, "B1", "Name")
file.SetCellValue(sheetName, "C1", "Country")
file.SetCellValue(sheetName, "D1", "PrimaryExchange")
file.SetCellValue(sheetName, "E1", "Symbol")
file.SetCellValue(sheetName, "F1", "NumericCode")
// 写入数据
row := 2 // 从第二行开始写入数据
for _, val := range res {
file.SetCellValue(sheetName, "A"+strconv.Itoa(row), val.Ticker)
file.SetCellValue(sheetName, "B"+strconv.Itoa(row), "")
file.SetCellValue(sheetName, "C"+strconv.Itoa(row), "")
file.SetCellValue(sheetName, "D"+strconv.Itoa(row), "")
file.SetCellValue(sheetName, "E"+strconv.Itoa(row), "")
file.SetCellValue(sheetName, "F"+strconv.Itoa(row), "")
row++
}
// 保存文件
//err := file.SaveAs(fmt.Sprintf("/home/ubuntu/wss-server/%s.xlsx", "forex"))
err := file.SaveAs(fmt.Sprintf("./cmd/%s.xlsx", "forex"))
if err != nil {
log.Fatal(err)
}
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", internal.QuerySuccess))
}
func OptionToExcel(c *gin.Context) {
symbol := internal.ReplaceStr(c.Query("option"))
filter := bson.M{"Country": symbol}
res := make([]model.OptionPolygon, 0)
data.MgoFindRes(data.OptionList, filter, &res)
// 创建Excel文件
file := excelize.NewFile()
sheetName := "Sheet1"
// 写入表头
file.SetCellValue(sheetName, "A1", "Code")
file.SetCellValue(sheetName, "B1", "Name")
file.SetCellValue(sheetName, "C1", "Country")
file.SetCellValue(sheetName, "D1", "Tape")
// 写入数据
row := 2 // 从第二行开始写入数据
for _, val := range res {
file.SetCellValue(sheetName, "A"+strconv.Itoa(row), val.Stock)
file.SetCellValue(sheetName, "B"+strconv.Itoa(row), val.Stock)
file.SetCellValue(sheetName, "C"+strconv.Itoa(row), val.Country)
file.SetCellValue(sheetName, "D"+strconv.Itoa(row), val.PrimaryExchange)
row++
}
// 保存文件
err := file.SaveAs(fmt.Sprintf("%s.xlsx", symbol))
if err != nil {
log.Fatal(err)
}
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, "", internal.QuerySuccess))
}
// IntraDisCal IntraDisCal data
func IntraDisCal(c *gin.Context) {
symbol := strings.ToUpper(internal.ReplaceStr(c.Query("symbol"))) // 股票代码
intMin := internal.IntegerInit(internal.ReplaceStr(c.Query("interval"))) // 查询间隔
from := internal.IntegerInit(internal.ReplaceStr(c.Query("from"))) // 开始时间
applogger.Debug("Incoming parameters:%v", symbol, intMin)
if from <= 0 {
c.JSON(http.StatusOK, internal.GinResult(http.StatusUnauthorized, "parameter error", internal.QueryError))
return
}
//filter := bson.M{"Code": symbol, "YesterdayClose": bson.M{"$ne": ""}, "BeforeClose": bson.M{"$ne": ""}}
intTime := intMin * 60 * 1000
match := bson.D{
{"$match", bson.D{
{"s", symbol},
{"t", bson.D{{"$gte", from}}}},
}}
group := bson.D{{
"$group", bson.D{
{"_id", bson.D{{"$subtract", bson.A{"$t", bson.D{{"$mod", bson.A{"$t", intTime}}}}}}},
{"fisrtTime", bson.D{{"$first", "$t"}}},
{"lastTime", bson.D{{"$last", "$t"}}},
{"datetime", bson.D{{"$first", bson.D{{"$dateToString",
bson.D{{"format", "%Y-%m-%d %H:%M:%S"},
{"date", bson.D{{"$add", bson.A{time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC), "$t", 28800000}}}}}}}}}},
{"timestamp", bson.D{{"$first", "$t"}}},
{"open", bson.D{{"$max", bson.D{{"$toDouble", "$p"}}}}},
{"high", bson.D{{"$max", bson.D{{"$toDouble", "$h"}}}}},
{"low", bson.D{{"$min", bson.D{{"$toDouble", "$l"}}}}},
{"close", bson.D{{"$min", bson.D{{"$toDouble", "$cl"}}}}},
{"volume", bson.D{{"$sum", "$v"}}},
}}}
sort := bson.D{{"$sort", bson.D{{"timestamp", 1}}}}
operations := mongo.Pipeline{match, group, sort}
applogger.Debug("mongodb filter info: %v", operations)
mapList, err := data.MgoAggregate(data.StockUs, operations)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusUnauthorized, "MgoAggregate err", internal.QueryError))
return
}
applogger.Debug("data info: %v", mapList)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, mapList, internal.QuerySuccess))
}
// FindShareBySymbol 自选列表查询服务
func FindShareBySymbol(c *gin.Context) {
auth := internal.ReplaceStr(c.Query("auth"))
systemBoursesId := internal.IntegerInit(internal.ReplaceStr(c.Query("systemBoursesId")))
bourseType := internal.IntegerInit(internal.ReplaceStr(c.Query("bourseType")))
if len(auth) == 0 {
c.JSON(http.StatusOK, internal.GinResult(http.StatusUnauthorized, internal.QueryToken, internal.QueryError))
return
}
check, userId, err := mysqlbusiness.GetBoUsers(auth)
if err != nil {
applogger.Error("GetBoUsers err: %v", err)
c.JSON(http.StatusOK, internal.GinResult(http.StatusUnauthorized, internal.QueryToken, internal.QueryError))
return
}
if !check {
c.JSON(http.StatusOK, internal.GinResult(http.StatusUnauthorized, internal.QueryToken, internal.QueryError))
return
}
usList, err := mysqlbusiness.GetBoUserOptionalStocksNew(bourseType, systemBoursesId, userId)
if err != nil {
applogger.Error("GetBoUserOptionalStocks err : %v", err)
c.JSON(http.StatusOK, internal.GinResult(http.StatusUnauthorized, "", internal.QueryError))
return
}
var keys []bson.M
for _, value := range usList {
code := value.Stockcode
keys = append(keys, bson.M{"Code": code})
}
filter := bson.M{"$or": keys}
pagedData, err := data.MgoFind(data.StockList, filter)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusInternalServerError, err, internal.QueryError))
return
}
pagedDataMap := make(map[string]stock.StockShare)
for _, vue := range pagedData.([]primitive.M) {
var stockM stock.StockShare
code := vue["Code"]
beforeClose := vue["BeforeClose"]
yesterdayClose := vue["YesterdayClose"]
fullName := vue["Name"]
stockM.BeforeClose = beforeClose.(string)
stockM.YesterdayClose = yesterdayClose.(string)
stockM.Name = fullName.(string)
pagedDataMap[code.(string)] = stockM
}
applogger.Debug("")
var dataList []model.Data
for _, value := range usList {
var md model.Data
dataBool := false
vue, ok := pagedDataMap[value.Stockcode]
if ok {
md.BeforeClose = decimal.RequireFromString(vue.BeforeClose)
md.YesterdayClose = decimal.RequireFromString(vue.YesterdayClose)
md.FullName = vue.Name
md.Id = value.Id
md.BourseType = value.Boursetype
md.SystemBoursesId = value.Systemboursesid
md.UserId = value.Userid
md.StockCode = value.Stockcode
dataList = append(dataList, md)
dataBool = true
}
if !dataBool {
md.Id = value.Id
md.BourseType = value.Boursetype
md.SystemBoursesId = value.Systemboursesid
md.UserId = value.Userid
md.StockCode = value.Stockcode
md.FullName = ""
dataList = append(dataList, md)
}
dataBool = false
}
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, dataList, internal.QuerySuccess))
}
// Fundamentals 获取个人股票信息
func Fundamentals(c *gin.Context) {
// https://eodhistoricaldata.com/api/fundamentals/AAPL.US?api_token=demo
symbol := internal.ReplaceStr(c.Query("symbol"))
region := internal.ReplaceStr(c.Query("region"))
filter := internal.ReplaceStr(c.Query("filter"))
var param string
param = fmt.Sprintf("api_token=%v", config.Config.ShareGather.FinancialKey)
if len(filter) > 0 {
param = param + "&" + fmt.Sprintf("filter=%v", filter)
}
if len(symbol) == 0 {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, "参数错误", internal.QueryError))
return
}
qe := fmt.Sprintf("%v.%v", symbol, region)
url := fmt.Sprintf("%v%v/api/fundamentals/%v?%v", topIc, config.Config.ShareGather.FinancialHost, qe, param)
applogger.Debug("url info:%v", url)
bodyStr := make(map[string]interface{})
data, err := red.Get_Cache_Data(symbol)
applogger.Debug("数据信息:%v", data)
if err != nil {
applogger.Error("Get_Cache_Data err: %v", err)
}
if len(data) == 0 {
bodyStr, err = internal.HttpGetDoNew(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("bodyStr info:%v", bodyStr)
jsonStr, err := json.Marshal(bodyStr)
if err != nil {
applogger.Debug("http data json Marshal err: %v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
if err = red.Set_Cache_Data(symbol, jsonStr, 1440); err != nil {
applogger.Error("write Set_Cache_Data info err: %v", err)
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
} else {
if err := json.Unmarshal([]byte(data), &bodyStr); err != nil {
applogger.Error("select redis data json Unmarshal err: %v", err)
}
}
//applogger.Debug("data info:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// FundamentalsNew Obtain individual stock information data (add close)
func FundamentalsNew(c *gin.Context) {
// https://eodhistoricaldata.com/api/fundamentals/AAPL.US?api_token=demo
symbol := internal.ReplaceStr(c.Query("symbol"))
region := internal.ReplaceStr(c.Query("region"))
filter := internal.ReplaceStr(c.Query("filter"))
filterM := bson.M{"Code": symbol}
pagedData, err := data.MgoFind(data.StockList, filterM)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
var yesterdayClose, beforeClose string
for _, vue := range pagedData.([]primitive.M) {
yesterdayClose = vue["YesterdayClose"].(string)
beforeClose = vue["BeforeClose"].(string)
}
applogger.Debug("data info: %v", yesterdayClose, beforeClose)
var param string
param = fmt.Sprintf("api_token=%v", config.Config.ShareGather.FinancialKey)
if len(filter) > 0 {
param = param + "&" + fmt.Sprintf("filter=%v", filter)
}
qe := fmt.Sprintf("%v.%v", symbol, region)
url := fmt.Sprintf("%v%v/api/fundamentals/%v?%v", topIc, config.Config.ShareGather.FinancialHost, qe, param)
applogger.Debug("info url:%v", url)
bodyStr := make(map[string]interface{})
data, err := red.Get_Cache_Data(symbol)
if err != nil {
applogger.Error("Get_Cache_Data err: %v", err)
}
if len(data) == 0 {
bodyStr, err = internal.HttpGetDoNew(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("bodyStr info:%v", bodyStr)
jsonStr, err := json.Marshal(bodyStr)
if err != nil {
//applogger.Debug("http data json Marshal err: %v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
if err := red.Set_Cache_Data(symbol, jsonStr, 1440); err != nil {
applogger.Error("write Set_Cache_Data info err: %v", err)
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
} else {
if err := json.Unmarshal([]byte(data), &bodyStr); err != nil {
applogger.Error("select redis data json Unmarshal err: %v", err)
}
}
bodyStr["YesterdayClose"] = yesterdayClose
bodyStr["BeforeClose"] = beforeClose
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// Intraday Daily historical data
func Intraday(c *gin.Context) {
// https://eodhistoricaldata.com/api/intraday/AAPL.US?api_token=647dd6744b94f4.20894198&fmt=json&from=1564752900&to=1564753200&interval=1m
symbol := internal.ReplaceStr(c.Query("symbol"))
region := internal.ReplaceStr(c.Query("region"))
from := internal.ReplaceStr(c.Query("from"))
interval := internal.ReplaceStr(c.Query("interval"))
to := internal.ReplaceStr(c.Query("to"))
var param string
param = fmt.Sprintf("api_token=%v", config.Config.ShareGather.FinancialKey)
if len(from) > 0 {
param = param + "&" + fmt.Sprintf("from=%v", from)
}
if len(to) > 0 {
param = param + "&" + fmt.Sprintf("to=%v", to)
}
if len(interval) > 0 {
param = param + "&" + fmt.Sprintf("interval=%v", interval)
}
qe := fmt.Sprintf("%v.%v", symbol, region)
url := fmt.Sprintf("%v%v/api/intraday/%v?fmt=json&%v", topIc, config.Config.ShareGather.FinancialHost, qe, param)
applogger.Debug("url data info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// Eod End of Day Historical Data
func Eod(c *gin.Context) {
// https://eodhistoricaldata.com/api/eod/MCD.US?api_token=647dd6744b94f4.20894198&period=d&order=d&from=2017-01-05&to=2017-02-10&fmt=json
symbol := internal.ReplaceStr(c.Query("symbol"))
region := internal.ReplaceStr(c.Query("region"))
period := internal.ReplaceStr(c.Query("period"))
order := internal.ReplaceStr(c.Query("order"))
from := internal.ReplaceStr(c.Query("from"))
to := internal.ReplaceStr(c.Query("to"))
// 条件组装
var param string
param = fmt.Sprintf("api_token=%v", config.Config.ShareGather.FinancialKey)
if len(order) > 0 {
param = param + "&" + fmt.Sprintf("from=%v", from)
}
if len(period) > 0 {
param = param + "&" + fmt.Sprintf("period=%v", period)
}
if len(from) > 0 {
param = param + "&" + fmt.Sprintf("from=%v", from)
}
if len(to) > 0 {
param = param + "&" + fmt.Sprintf("to=%v", to)
}
qe := fmt.Sprintf("%v.%v", symbol, region)
url := fmt.Sprintf("%v%v/api/eod/%v?fmt=json&%v", topIc, config.Config.ShareGather.FinancialHost, qe, param)
applogger.Debug("url data info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
/****https://polygon.io/docs/stocks/get_v2_aggs_grouped_locale_us_market_stocks__date*****/
// Aggregates 股票聚合条形图
func Aggregates(c *gin.Context) {
stocksTicker := internal.ReplaceStr(c.Query("stocksTicker")) // AAPL
resolution := internal.ReplaceStr(c.Query("multiplier")) //multiplier
from := internal.ReplaceStr(c.Query("from")) // from
to := internal.ReplaceStr(c.Query("to"))
//fmt.Println(resolution, to)
if strings.Contains("5,15,30,60,1", resolution) && !common.IsOpeningUS() {
to = fmt.Sprintf("%d", common.GetToTime()/1000)
}
//fmt.Println(to)
//else if timespan == "minute" && multiplier == 15 && common.IsOpeningUS() {
// to = fmt.Sprintf("%d", common.GenerateSingaporeMinTimestamp(15).UnixMilli())
//} else if timespan == "minute" && multiplier == 5 && common.IsOpeningUS() {
// to = fmt.Sprintf("%d", common.GenerateSingaporeMinTimestamp(5).UnixMilli())
//}
url := fmt.Sprintf("%v%vstock/candle?symbol=%s&resolution=%s&from=%s&to=%s&token=%s",
topIc, config.Config.FinnhubUs.FinnhubHost, stocksTicker, resolution, from, to, config.Config.FinnhubUs.FinnhubKey)
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// Grouped 获取整个股票/股票市场的每日开盘价、最高价、最低价和收盘价 (OHLC)
func Grouped(c *gin.Context) {
// /v2/aggs/grouped/locale/us/market/stocks/{date}
// https://api.polygon.io/v2/aggs/grouped/locale/us/market/stocks/2023-01-09?adjusted=true&apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
date := internal.ReplaceStr(c.Query("date")) // date
param := fmt.Sprintf("apiKey=%v", config.Config.ShareGather.PolygonKey)
url := fmt.Sprintf("%v%v/v2/aggs/grouped/locale/us/market/stocks/%v?adjusted=true&%v",
topIc, config.Config.ShareGather.PolygonHost, date, param)
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// OpenClose 股票每日开盘/收盘
func OpenClose(c *gin.Context) {
// /v1/open-close/{stocksTicker}/{date}
// https://api.polygon.io/v1/open-close/AAPL/2023-01-09?adjusted=true&apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
stocksTicker := internal.ReplaceStr(c.Query("stocksTicker")) // AAPL
date := internal.ReplaceStr(c.Query("date")) // date
param := fmt.Sprintf("apiKey=%v", config.Config.ShareGather.PolygonKey)
url := fmt.Sprintf("%v%v/v1/open-close/%v/%v?adjusted=true&%v",
topIc, config.Config.ShareGather.PolygonHost, stocksTicker, date, param)
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// PreviousClose 上一收盘价
func PreviousClose(c *gin.Context) {
// /v2/aggs/ticker/{stocksTicker}/prev
// https://api.polygon.io/v2/aggs/ticker/AAPL/prev?adjusted=true&apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
stocksTicker := internal.ReplaceStr(c.Query("stocksTicker")) // AAPL
param := fmt.Sprintf("apiKey=%v", config.Config.ShareGather.PolygonKey)
var tickerList []string
if len(stocksTicker) > 0 {
tickerList = strings.Split(stocksTicker, ",")
}
var codeCloseList []stock.Results
for _, ticker := range tickerList {
url := fmt.Sprintf("%v%v/v2/aggs/ticker/%v/prev?adjusted=true&%v",
topIc, config.Config.ShareGather.PolygonHost, ticker, param)
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//var code string
//var closePrice float64
//for key, value := range bodyStr {
// switch key {
// case "results":
// boDay := value.([]interface{})
// for _, vue := range boDay {
// switch vue.(type) {
// case map[string]interface{}:
// da := vue.(map[string]interface{})
// for e, v := range da {
// switch e {
// case "T":
// code = v.(string)
// case "c":
// closePrice = v.(float64)
// default:
// }
// }
// default:
// }
// }
// }
//}
item := stock.AggsTicke{}
json.Unmarshal([]byte(bodyStr), &item)
if len(item.Results) > 0 {
codeCloseList = append(codeCloseList, item.Results[0])
}
}
applogger.Debug("data info:%v", codeCloseList)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, codeCloseList, internal.QuerySuccess))
}
// Trades 获取给定时间范围内股票代码的交易
func Trades(c *gin.Context) {
ticker := internal.ReplaceStr(c.Query("ticker")) // AAPL
date := internal.ReplaceStr(c.Query("date"))
param := fmt.Sprintf("apiKey=%v", config.Config.ShareGather.PolygonKey)
url := fmt.Sprintf("%v%v/trades/%s?timestamp=%s&order=desc&%v",
topIc, config.Config.ShareGather.PolygonHost, ticker, date, param)
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// LastTrade 获取给定股票的最新交易
func LastTrade(c *gin.Context) {
// /v2/last/trade/{stocksTicker}
// https://api.polygon.io/v2/last/trade/AAPL?apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
stocksTicker := internal.ReplaceStr(c.Query("stocksTicker")) // AAPL
param := fmt.Sprintf("apiKey=%v", config.Config.ShareGather.PolygonKey)
url := fmt.Sprintf("%v%v/v2/last/trade/%v?%v",
topIc, config.Config.ShareGather.PolygonHost, stocksTicker, param)
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// Quotes TODO: 获取给定时间范围内股票代码的交易
func Quotes(c *gin.Context) {
// https://api.polygon.io/v3/quotes/AAPL?apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
}
// LastQuote 股票的最新NBBO(报价)刻度
func LastQuote(c *gin.Context) {
// /v2/last/nbbo/{stocksTicker}
// https://api.polygon.io/v2/last/nbbo/AAPL?apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
stocksTicker := internal.ReplaceStr(c.Query("stocksTicker")) // AAPL
param := fmt.Sprintf("apiKey=%v", config.Config.ShareGather.PolygonKey)
url := fmt.Sprintf("%v%v/v2/last/nbbo/%v?%v",
topIc, config.Config.ShareGather.PolygonHost, stocksTicker, param)
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// SnapshotAllTickers 所有交易股票代码的最新市场数据
func SnapshotAllTickers(c *gin.Context) {
// /v2/snapshot/locale/us/markets/stocks/tickers
// https://api.polygon.io/v2/snapshot/locale/us/markets/stocks/tickers?include_otc=true&apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
param := fmt.Sprintf("apiKey=%v", config.Config.ShareGather.PolygonKey)
url := fmt.Sprintf("%v%v/v2/snapshot/locale/us/markets/stocks/tickers?include_otc=true&%v",
topIc, config.Config.ShareGather.PolygonHost, param)
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// SnapshotGainersLosers 获取股票/股票市场当前前20名涨幅或跌幅的最新市场数据
func SnapshotGainersLosers(c *gin.Context) {
// /v2/snapshot/locale/us/markets/stocks/{direction}
// https://api.polygon.io/v2/snapshot/locale/us/markets/stocks/gainers?include_otc=true&apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
// https://api.polygon.io/v2/snapshot/locale/us/markets/stocks/losers?include_otc=true&apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
direction := internal.ReplaceStr(c.Query("direction")) // AAPL
param := fmt.Sprintf("apiKey=%v", config.Config.ShareGather.PolygonKey)
url := fmt.Sprintf("%v%v/v2/snapshot/locale/us/markets/stocks/%v?include_otc=true&%v",
topIc, config.Config.ShareGather.PolygonHost, direction, param)
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// SnapshotOneTicker 获取单个交易股票行情的最新市场数据
func SnapshotOneTicker(c *gin.Context) {
// /v2/snapshot/locale/us/markets/stocks/tickers/{stocksTicker}
// https://api.polygon.io/v2/snapshot/locale/us/markets/stocks/tickers/AAPL?apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
stocksTicker := internal.ReplaceStr(c.Query("stocksTicker")) // AAPL
param := fmt.Sprintf("apiKey=%v", config.Config.ShareGather.PolygonKey)
url := fmt.Sprintf("%v%v/v2/snapshot/locale/us/markets/stocks/tickers/%v?%v",
topIc, config.Config.ShareGather.PolygonHost, stocksTicker, param)
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// ReferenceTicker TODO: 所有股票代码
func ReferenceTicker(c *gin.Context) {
// /v3/reference/tickers
// https://api.polygon.io/v3/reference/tickers?active=true&apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
param := fmt.Sprintf("apiKey=%v", config.Config.ShareGather.PolygonKey)
url := fmt.Sprintf("%v%v/v3/reference/tickers?active=true&%v", topIc, config.Config.ShareGather.PolygonHost, param)
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// ReferenceTickerDetails 股票代码详细信息
func ReferenceTickerDetails(c *gin.Context) {
// /v3/reference/tickers/{ticker}
// https://api.polygon.io/v3/reference/tickers/AAPL?apiKey=CDGMfPJmyiEX5dbjagLSEipf5Y4XbXVb
ticker := internal.ReplaceStr(c.Query("ticker")) // AAPL
//param := fmt.Sprintf("apiKey=%v", config.Config.ShareGather.PolygonKey)
//
//url := fmt.Sprintf("%v%v/v3/reference/tickers/%v?%v",
// topIc, config.Config.ShareGather.PolygonHost, ticker, param)
//
//applogger.Debug("Url info:%v", url)
//
//bodyStr, err := internal.HttpGet(url)
//if err != nil {
// c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
// return
//}
var bodyStr string
//if strings.Contains(bodyStr, "Ticker not found") {
filter := bson.M{"Country": "US", "Code": ticker}
projection := bson.M{}
sort := bson.M{}
result, _ := data.MgoFindProjection(data.StockList, filter, projection, sort, 0)
if len(result) > 0 {
bodyStr = fmt.Sprintf(`{"results": {"ticker": "%s","name": "%s","market": "stocks","locale": "us","primary_exchange": "%s","description": "%s"},"status": "OK"}`, business.TypeCheck(result[0]["Code"]), business.TypeCheck(result[0]["Name"]), business.TypeCheck(result[0]["Exchange"]), business.TypeCheck(result[0]["Intro"]))
}
// }
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}
// 股票资讯
func ReferenceTickerNews(c *gin.Context) {
ticker := internal.ReplaceStr(c.Query("ticker")) // AAPL
url := fmt.Sprintf("%v%vcompany-news?symbol=%s&from=%s&to=%s&token=%s",
topIc, config.Config.FinnhubUs.FinnhubHost, ticker, common.NewsUsTime(-7), common.NewsUsTime(0), config.Config.FinnhubUs.FinnhubKey)
if ticker == "" {
url = fmt.Sprintf("%v%vnews?category=general&token=%s",
topIc, config.Config.FinnhubUs.FinnhubHost, config.Config.FinnhubUs.FinnhubKey)
}
applogger.Debug("Url info:%v", url)
bodyStr, err := internal.HttpGet(url)
if err != nil {
c.JSON(http.StatusOK, internal.GinResult(http.StatusBadRequest, err, internal.QueryError))
return
}
//applogger.Debug("第三方数据接收:%v", bodyStr)
c.JSON(http.StatusOK, internal.GinResult(http.StatusOK, bodyStr, internal.QuerySuccess))
}