diff --git a/app.go b/app.go index 581f0ab..8c8c446 100644 --- a/app.go +++ b/app.go @@ -4,6 +4,7 @@ package main import ( "context" + "fmt" "github.com/coocood/freecache" "github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/v2/mathutil" @@ -47,16 +48,6 @@ func (a *App) startup(ctx context.Context) { // domReady is called after front-end resources have been loaded func (a *App) domReady(ctx context.Context) { // Add your action here - - //定时更新数据 - go func() { - ticker := time.NewTicker(time.Second) - defer ticker.Stop() - for range ticker.C { - runtime.WindowSetTitle(ctx, "go-stock "+time.Now().Format("2006-01-02 15:04")) - } - }() - //定时更新数据 go func() { ticker := time.NewTicker(time.Second * 2) @@ -105,28 +96,79 @@ func isTradingTime(date time.Time) bool { func MonitorStockPrices(a *App) { dest := &[]data.FollowedStock{} db.Dao.Model(&data.FollowedStock{}).Find(dest) - for _, item := range *dest { - follow := item - stockCode := follow.StockCode - go func() { - stockData, err := data.NewStockDataApi().GetStockCodeRealTimeData(stockCode) - if err != nil { - logger.SugaredLogger.Errorf("get stock code real time data error:%s", err.Error()) - return - } - price, err := convertor.ToFloat(stockData.Price) - if err != nil { - return - } - stockData.PrePrice = follow.Price - if follow.Price != price { - runtime.EventsEmit(a.ctx, "stock_price", stockData) - go db.Dao.Model(follow).Where("stock_code = ?", stockCode).Updates(map[string]interface{}{ - "price": stockData.Price, - }) - } - }() + total := float64(0) + for _, follow := range *dest { + stockData := getStockInfo(follow) + total += stockData.ProfitAmountToday + price, _ := convertor.ToFloat(stockData.Price) + if stockData.PrePrice != price { + go runtime.EventsEmit(a.ctx, "stock_price", stockData) + } } + title := "go-stock " + time.Now().Format(time.DateTime) + fmt.Sprintf(" %.2f¥", total) + runtime.WindowSetTitle(a.ctx, title) + systray.SetTooltip(title) + +} +func getStockInfo(follow data.FollowedStock) *data.StockInfo { + stockCode := follow.StockCode + stockData, err := data.NewStockDataApi().GetStockCodeRealTimeData(stockCode) + if err != nil { + logger.SugaredLogger.Errorf("get stock code real time data error:%s", err.Error()) + return nil + } + stockData.PrePrice = follow.Price //上次当前价格 + stockData.Sort = follow.Sort + stockData.CostPrice = follow.CostPrice //成本价 + stockData.CostVolume = follow.Volume //成本量 + stockData.AlarmChangePercent = follow.AlarmChangePercent + stockData.AlarmPrice = follow.AlarmPrice + + //当前价格 + price, _ := convertor.ToFloat(stockData.Price) + //当前价格为0 时 使用卖一价格作为当前价格 + if price == 0 { + price, _ = convertor.ToFloat(stockData.A1P) + } + //当前价格依然为0 时 使用买一报价作为当前价格 + if price == 0 { + price, _ = convertor.ToFloat(stockData.B1P) + } + + //昨日收盘价 + preClosePrice, _ := convertor.ToFloat(stockData.PreClose) + + //今日最高价 + highPrice, _ := convertor.ToFloat(stockData.High) + if highPrice == 0 { + highPrice, _ = convertor.ToFloat(stockData.Open) + } + + //今日最低价 + lowPrice, _ := convertor.ToFloat(stockData.Low) + if lowPrice == 0 { + lowPrice, _ = convertor.ToFloat(stockData.Open) + } + //开盘价 + //openPrice, _ := convertor.ToFloat(stockData.Open) + + stockData.ChangePrice = mathutil.RoundToFloat(price-preClosePrice, 2) + stockData.ChangePercent = mathutil.RoundToFloat(mathutil.Div(price-preClosePrice, preClosePrice)*100, 3) + stockData.HighRate = mathutil.RoundToFloat(mathutil.Div(highPrice-preClosePrice, preClosePrice)*100, 3) + stockData.LowRate = mathutil.RoundToFloat(mathutil.Div(lowPrice-preClosePrice, preClosePrice)*100, 3) + if follow.CostPrice > 0 && follow.Volume > 0 { + stockData.Profit = mathutil.RoundToFloat(mathutil.Div(price-follow.CostPrice, follow.CostPrice)*100, 3) + stockData.ProfitAmount = mathutil.RoundToFloat((price-follow.CostPrice)*float64(follow.Volume), 2) + stockData.ProfitAmountToday = mathutil.RoundToFloat((price-preClosePrice)*float64(follow.Volume), 2) + } + + //logger.SugaredLogger.Debugf("stockData:%+v", stockData) + if follow.Price != price { + go db.Dao.Model(follow).Where("stock_code = ?", stockCode).Updates(map[string]interface{}{ + "price": stockData.Price, + }) + } + return stockData } // beforeClose is called when the application is about to quit, @@ -161,8 +203,14 @@ func (a *App) shutdown(ctx context.Context) { } // Greet returns a greeting for the given name -func (a *App) Greet(name string) *data.StockInfo { - stockInfo, _ := data.NewStockDataApi().GetStockCodeRealTimeData(name) +func (a *App) Greet(stockCode string) *data.StockInfo { + //stockInfo, _ := data.NewStockDataApi().GetStockCodeRealTimeData(stockCode) + + follow := &data.FollowedStock{ + StockCode: stockCode, + } + db.Dao.Model(follow).Where("stock_code = ?", stockCode).First(follow) + stockInfo := getStockInfo(*follow) return stockInfo } diff --git a/backend/data/stock_data_api.go b/backend/data/stock_data_api.go index 7ddea77..4212cb5 100644 --- a/backend/data/stock_data_api.go +++ b/backend/data/stock_data_api.go @@ -43,8 +43,8 @@ type StockInfo struct { Amount string `json:"成交金额"` Open string `json:"今日开盘价"` PreClose string `json:"昨日收盘价"` - High string `json:"今日最低价"` - Low string `json:"今日最高价"` + High string `json:"今日最高价"` + Low string `json:"今日最低价"` Bid string `json:"竞买价"` Ask string `json:"竞卖价"` B1P string `json:"买一报价"` @@ -67,6 +67,21 @@ type StockInfo struct { A4V string `json:"卖四申报"` A5P string `json:"卖五报价"` A5V string `json:"卖五申报"` + + //以下是字段值需二次计算 + ChangePercent float64 `json:"changePercent"` //涨跌幅 + ChangePrice float64 `json:"changePrice"` //涨跌额 + HighRate float64 `json:"highRate"` //最高涨跌 + LowRate float64 `json:"lowRate"` //最低涨跌 + CostPrice float64 `json:"costPrice"` //成本价 + CostVolume int64 `json:"costVolume"` //持仓数量 + Profit float64 `json:"profit"` //总盈亏率 + ProfitAmount float64 `json:"profitAmount"` //总盈亏金额 + ProfitAmountToday float64 `json:"profitAmountToday"` //今日盈亏金额 + + Sort int64 `json:"sort"` //排序 + AlarmChangePercent float64 `json:"alarmChangePercent"` + AlarmPrice float64 `json:"alarmPrice"` } func (receiver StockInfo) TableName() string { diff --git a/frontend/src/components/stock.vue b/frontend/src/components/stock.vue index 0451a4c..d3d1a50 100644 --- a/frontend/src/components/stock.vue +++ b/frontend/src/components/stock.vue @@ -192,56 +192,36 @@ async function updateData(result) { result["当前价格"]=result["卖一报价"] } - let s=(result["当前价格"]-result["昨日收盘价"])*100/result["昨日收盘价"] - let roundedNum = s.toFixed(2); // 将数字转换为保留两位小数的字符串形式 - - // let s2=(result["上次当前价格"]-result["昨日收盘价"])*100/result["昨日收盘价"] - // let roundedNum2 = s2.toFixed(2); // 将数字转换为保留两位小数的字符串形式 - - result.rf=roundedNum - // result.rf2=roundedNum2 - result.s=roundedNum+"%" - - result.highRate=((result["今日最高价"]-result["今日开盘价"])*100/result["今日开盘价"]).toFixed(2)+"%" - result.lowRate=((result["今日最低价"]-result["今日开盘价"])*100/result["今日开盘价"]).toFixed(2)+"%" - - if (roundedNum>0) { + if (result.changePercent>0) { result.type="error" result.color="#E88080" - }else if (roundedNum<0) { + }else if (result.changePercent<0) { result.type="success" result.color="#63E2B7" }else { result.type="default" result.color="#FFFFFF" } - let res= followList.value.filter(item => item.StockCode===result['股票代码']) - if (res.length>0) { - result.Sort=res[0].Sort - result.costPrice=res[0].CostPrice - result.volume=res[0].Volume - result.profit=((result["当前价格"]-result.costPrice)*100/result.costPrice).toFixed(3) - result.profitAmountToday=(result.volume*(result["当前价格"]-result["昨日收盘价"])).toFixed(2) - result.profitAmount=(result.volume*(result["当前价格"]-result.costPrice)).toFixed(2) + if(result.profitAmount>0){ result.profitType="error" }else if(result.profitAmount<0){ result.profitType="success" } if(result["当前价格"]){ - if(res[0].AlarmChangePercent>0&&Math.abs(roundedNum)>=res[0].AlarmChangePercent){ + if(result.alarmChangePercent>0&&Math.abs(result.changePercent)>=result.alarmChangePercent){ SendMessage(result,1) } - if(res[0].AlarmPrice>0&&result["当前价格"]>=res[0].AlarmPrice){ + if(result.alarmPrice>0&&result["当前价格"]>=result.alarmPrice){ SendMessage(result,2) } - if(res[0].CostPrice>0&&result["当前价格"]>=res[0].CostPrice){ + if(result.costPrice>0&&result["当前价格"]>=result.costPrice){ SendMessage(result,3) } } - } + result.key=GetSortKey(result.Sort,result["股票代码"]) results.value[GetSortKey(result.Sort,result["股票代码"])]=result } @@ -251,57 +231,7 @@ async function monitor() { for (let code of stocks.value) { // console.log(code) Greet(code).then(result => { - if(result["当前价格"]<=0){ - result["当前价格"]=result["卖一报价"] - } - - let s=(result["当前价格"]-result["昨日收盘价"])*100/result["昨日收盘价"] - let roundedNum = s.toFixed(2); // 将数字转换为保留两位小数的字符串形式 - result.s=roundedNum+"%" - result.rf=roundedNum - result.highRate=((result["今日最高价"]-result["今日开盘价"])*100/result["今日开盘价"]).toFixed(2)+"%" - result.lowRate=((result["今日最低价"]-result["今日开盘价"])*100/result["今日开盘价"]).toFixed(2)+"%" - - if (roundedNum>0) { - result.type="error" - result.color="#E88080" - }else if (roundedNum<0) { - result.type="success" - result.color="#63E2B7" - }else { - result.type="default" - result.color="#FFFFFF" - } - let res= followList.value.filter(item => item.StockCode===code) - if (res.length>0) { - result.Sort=res[0].Sort - result.costPrice=res[0].CostPrice - result.volume=res[0].Volume - result.profit=((result["当前价格"]-result.costPrice)*100/result.costPrice).toFixed(3) - result.profitAmountToday=(result.volume*(result["当前价格"]-result["昨日收盘价"])).toFixed(2) - result.profitAmount=(result.volume*(result["当前价格"]-result.costPrice)).toFixed(2) - if(result.profitAmount>0){ - result.profitType="error" - }else if(result.profitAmount<0){ - result.profitType="success" - } - if(result["当前价格"]){ - if(res[0].AlarmChangePercent>0&&Math.abs(roundedNum)>=res[0].AlarmChangePercent){ - SendMessage(result,1) - } - - if(res[0].AlarmPrice>0&&result["当前价格"]>=res[0].AlarmPrice){ - SendMessage(result,2) - } - - if(res[0].CostPrice>0&&result["当前价格"]>=res[0].CostPrice){ - SendMessage(result,3) - } - } - } - result.key=GetSortKey(result.Sort,result["股票代码"]) - results.value[GetSortKey(result.Sort,result["股票代码"])]=result - + updateData(result) }) } } @@ -456,20 +386,22 @@ function getHeight() { - + - % + %   - {{result.profitAmountToday}} + + + - {{"最高 "+result["今日最高价"]+" "+result.highRate }} + {{"最高 "+result["今日最高价"]+" "+result.highRate }}% - {{"最低 "+result["今日最低价"]+" "+result.lowRate }} + {{"最低 "+result["今日最低价"]+" "+result.lowRate }}% {{"昨收 "+result["昨日收盘价"]}} @@ -484,7 +416,7 @@ function getHeight() {