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() {
{{result.volume+"股"}}
- {{"成本:"+result.costPrice+" "+result.profit+"%"+" ( "+result.profitAmount+" ¥ )"}}
+ {{"成本:"+result.costPrice+"*"+result.costVolume+" "+result.profit+"%"+" ( "+result.profitAmount+" ¥ )"}}
diff --git a/frontend/wailsjs/go/models.ts b/frontend/wailsjs/go/models.ts
index 8a1e2ff..8cf1279 100644
--- a/frontend/wailsjs/go/models.ts
+++ b/frontend/wailsjs/go/models.ts
@@ -144,8 +144,8 @@ export namespace data {
"成交金额": string;
"今日开盘价": string;
"昨日收盘价": string;
- "今日最低价": string;
"今日最高价": string;
+ "今日最低价": string;
"竞买价": string;
"竞卖价": string;
"买一报价": string;
@@ -168,6 +168,18 @@ export namespace data {
"卖四申报": string;
"卖五报价": string;
"卖五申报": string;
+ changePercent: number;
+ changePrice: number;
+ highRate: number;
+ lowRate: number;
+ costPrice: number;
+ costVolume: number;
+ profit: number;
+ profitAmount: number;
+ profitAmountToday: number;
+ sort: number;
+ alarmChangePercent: number;
+ alarmPrice: number;
static createFrom(source: any = {}) {
return new StockInfo(source);
@@ -189,8 +201,8 @@ export namespace data {
this["成交金额"] = source["成交金额"];
this["今日开盘价"] = source["今日开盘价"];
this["昨日收盘价"] = source["昨日收盘价"];
- this["今日最低价"] = source["今日最低价"];
this["今日最高价"] = source["今日最高价"];
+ this["今日最低价"] = source["今日最低价"];
this["竞买价"] = source["竞买价"];
this["竞卖价"] = source["竞卖价"];
this["买一报价"] = source["买一报价"];
@@ -213,6 +225,18 @@ export namespace data {
this["卖四申报"] = source["卖四申报"];
this["卖五报价"] = source["卖五报价"];
this["卖五申报"] = source["卖五申报"];
+ this.changePercent = source["changePercent"];
+ this.changePrice = source["changePrice"];
+ this.highRate = source["highRate"];
+ this.lowRate = source["lowRate"];
+ this.costPrice = source["costPrice"];
+ this.costVolume = source["costVolume"];
+ this.profit = source["profit"];
+ this.profitAmount = source["profitAmount"];
+ this.profitAmountToday = source["profitAmountToday"];
+ this.sort = source["sort"];
+ this.alarmChangePercent = source["alarmChangePercent"];
+ this.alarmPrice = source["alarmPrice"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {