feat(app): 优化股票监控和交易时间判断

- 添加了判断是否为交易日和交易时间的函数
- 修改了股票价格更新逻辑,只在交易时间内进行监控
- 优化了股票价格显示,增加了上次当前价格字段
- 更新了前端组件,支持显示股票价格变化动画
This commit is contained in:
spark 2025-01-08 15:28:08 +08:00
parent 1554d3309d
commit d3c6c1d570
5 changed files with 89 additions and 40 deletions

43
app.go
View File

@ -53,7 +53,7 @@ func (a *App) domReady(ctx context.Context) {
ticker := time.NewTicker(time.Second) ticker := time.NewTicker(time.Second)
defer ticker.Stop() defer ticker.Stop()
for range ticker.C { for range ticker.C {
runtime.WindowSetTitle(ctx, "go-stock "+time.Now().Format("2006-01-02 15:04:05")) runtime.WindowSetTitle(ctx, "go-stock "+time.Now().Format("2006-01-02 15:04"))
} }
}() }()
@ -62,10 +62,46 @@ func (a *App) domReady(ctx context.Context) {
ticker := time.NewTicker(time.Second * 2) ticker := time.NewTicker(time.Second * 2)
defer ticker.Stop() defer ticker.Stop()
for range ticker.C { for range ticker.C {
MonitorStockPrices(a) if isTradingTime(time.Now()) {
MonitorStockPrices(a)
}
} }
}() }()
} }
// isTradingDay 判断是否是交易日
func isTradingDay(date time.Time) bool {
weekday := date.Weekday()
// 判断是否是周末
if weekday == time.Saturday || weekday == time.Sunday {
return false
}
// 这里可以添加具体的节假日判断逻辑
// 例如:判断是否是春节、国庆节等
return true
}
// isTradingTime 判断是否是交易时间
func isTradingTime(date time.Time) bool {
if !isTradingDay(date) {
return false
}
hour, minute, _ := date.Clock()
// 判断是否在9:15到11:30之间
if (hour == 9 && minute >= 15) || (hour == 10) || (hour == 11 && minute <= 30) {
return true
}
// 判断是否在13:00到15:00之间
if (hour == 13) || (hour == 14) || (hour == 15 && minute <= 0) {
return true
}
return false
}
func MonitorStockPrices(a *App) { func MonitorStockPrices(a *App) {
dest := &[]data.FollowedStock{} dest := &[]data.FollowedStock{}
db.Dao.Model(&data.FollowedStock{}).Find(dest) db.Dao.Model(&data.FollowedStock{}).Find(dest)
@ -78,18 +114,17 @@ func MonitorStockPrices(a *App) {
logger.SugaredLogger.Errorf("get stock code real time data error:%s", err.Error()) logger.SugaredLogger.Errorf("get stock code real time data error:%s", err.Error())
return return
} }
price, err := convertor.ToFloat(stockData.Price) price, err := convertor.ToFloat(stockData.Price)
if err != nil { if err != nil {
return return
} }
stockData.PrePrice = follow.Price
if follow.Price != price { if follow.Price != price {
runtime.EventsEmit(a.ctx, "stock_price", stockData) runtime.EventsEmit(a.ctx, "stock_price", stockData)
go db.Dao.Model(follow).Where("stock_code = ?", stockCode).Updates(map[string]interface{}{ go db.Dao.Model(follow).Where("stock_code = ?", stockCode).Updates(map[string]interface{}{
"price": stockData.Price, "price": stockData.Price,
}) })
} }
}() }()
} }
} }

View File

@ -33,39 +33,40 @@ type StockDataApi struct {
} }
type StockInfo struct { type StockInfo struct {
gorm.Model gorm.Model
Date string `json:"日期" gorm:"index"` Date string `json:"日期" gorm:"index"`
Time string `json:"时间" gorm:"index"` Time string `json:"时间" gorm:"index"`
Code string `json:"股票代码" gorm:"index"` Code string `json:"股票代码" gorm:"index"`
Name string `json:"股票名称" gorm:"index"` Name string `json:"股票名称" gorm:"index"`
Price string `json:"当前价格"` PrePrice float64 `json:"上次当前价格"`
Volume string `json:"成交的股票数"` Price string `json:"当前价格"`
Amount string `json:"成交金额"` Volume string `json:"成交的股票数"`
Open string `json:"今日开盘价"` Amount string `json:"成交金额"`
PreClose string `json:"昨日收盘价"` Open string `json:"今日开盘价"`
High string `json:"今日最低价"` PreClose string `json:"昨日收盘价"`
Low string `json:"今日最高价"` High string `json:"今日最低价"`
Bid string `json:"竞买价"` Low string `json:"今日最高价"`
Ask string `json:"竞卖价"` Bid string `json:"竞买价"`
B1P string `json:"买一报价"` Ask string `json:"竞卖价"`
B1V string `json:"买一申报"` B1P string `json:"买一报价"`
B2P string `json:"买二报价"` B1V string `json:"买一申报"`
B2V string `json:"买二申报"` B2P string `json:"买二报价"`
B3P string `json:"买三报价"` B2V string `json:"买二申报"`
B3V string `json:"买三申报"` B3P string `json:"买三报价"`
B4P string `json:"买四报价"` B3V string `json:"买三申报"`
B4V string `json:"买四申报"` B4P string `json:"买四报价"`
B5P string `json:"买五报价"` B4V string `json:"买四申报"`
B5V string `json:"买五申报"` B5P string `json:"买五报价"`
A1P string `json:"卖一报价"` B5V string `json:"买五申报"`
A1V string `json:"卖一申报"` A1P string `json:"卖一报价"`
A2P string `json:"卖二报价"` A1V string `json:"卖一申报"`
A2V string `json:"卖二申报"` A2P string `json:"卖二报价"`
A3P string `json:"卖三报价"` A2V string `json:"卖二申报"`
A3V string `json:"卖三申报"` A3P string `json:"卖三报价"`
A4P string `json:"卖四报价"` A3V string `json:"卖三申报"`
A4V string `json:"卖四申报"` A4P string `json:"卖四报价"`
A5P string `json:"卖五报价"` A4V string `json:"卖四申报"`
A5V string `json:"卖五申报"` A5P string `json:"卖五报价"`
A5V string `json:"卖五申报"`
} }
func (receiver StockInfo) TableName() string { func (receiver StockInfo) TableName() string {

View File

@ -194,6 +194,12 @@ async function updateData(result) {
let s=(result["当前价格"]-result["昨日收盘价"])*100/result["昨日收盘价"] let s=(result["当前价格"]-result["昨日收盘价"])*100/result["昨日收盘价"]
let roundedNum = s.toFixed(2); // 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.s=roundedNum+"%"
result.highRate=((result["今日最高价"]-result["今日开盘价"])*100/result["今日开盘价"]).toFixed(2)+"%" result.highRate=((result["今日最高价"]-result["今日开盘价"])*100/result["今日开盘价"]).toFixed(2)+"%"
@ -252,7 +258,7 @@ async function monitor() {
let s=(result["当前价格"]-result["昨日收盘价"])*100/result["昨日收盘价"] let s=(result["当前价格"]-result["昨日收盘价"])*100/result["昨日收盘价"]
let roundedNum = s.toFixed(2); // let roundedNum = s.toFixed(2); //
result.s=roundedNum+"%" result.s=roundedNum+"%"
result.rf=roundedNum
result.highRate=((result["今日最高价"]-result["今日开盘价"])*100/result["今日开盘价"]).toFixed(2)+"%" result.highRate=((result["今日最高价"]-result["今日开盘价"])*100/result["今日开盘价"]).toFixed(2)+"%"
result.lowRate=((result["今日最低价"]-result["今日开盘价"])*100/result["今日开盘价"]).toFixed(2)+"%" result.lowRate=((result["今日最低价"]-result["今日开盘价"])*100/result["今日开盘价"]).toFixed(2)+"%"
@ -449,7 +455,12 @@ function getHeight() {
<n-card :data-code="result['股票代码']" :bordered="false" :title="result['股票名称']" :closable="true" @close="removeMonitor(result['股票代码'],result['股票名称'],result.key)"> <n-card :data-code="result['股票代码']" :bordered="false" :title="result['股票名称']" :closable="true" @close="removeMonitor(result['股票代码'],result['股票名称'],result.key)">
<n-grid :cols="1" :y-gap="6"> <n-grid :cols="1" :y-gap="6">
<n-gi> <n-gi>
<n-text :type="result.type" >{{result["当前价格"]}}</n-text><n-text style="padding-left: 10px;" :type="result.type">{{ result.s}}</n-text>&nbsp; <n-text :type="result.type" >
<n-number-animation :precision="2" :from="result['上次当前价格']" :to="Number(result['当前价格'])" />
</n-text>
<n-text style="padding-left: 10px;" :type="result.type">
<n-number-animation :precision="2" :from="0" :to="result.rf" />%
</n-text>&nbsp;
<n-text size="small" v-if="result.profitAmountToday>0" :type="result.type">{{result.profitAmountToday}}</n-text> <n-text size="small" v-if="result.profitAmountToday>0" :type="result.type">{{result.profitAmountToday}}</n-text>
</n-gi> </n-gi>
</n-grid> </n-grid>

View File

@ -138,6 +138,7 @@ export namespace data {
"时间": string; "时间": string;
"股票代码": string; "股票代码": string;
"股票名称": string; "股票名称": string;
"上次当前价格": number;
"当前价格": string; "当前价格": string;
"成交的股票数": string; "成交的股票数": string;
"成交金额": string; "成交金额": string;
@ -182,6 +183,7 @@ export namespace data {
this["时间"] = source["时间"]; this["时间"] = source["时间"];
this["股票代码"] = source["股票代码"]; this["股票代码"] = source["股票代码"];
this["股票名称"] = source["股票名称"]; this["股票名称"] = source["股票名称"];
this["上次当前价格"] = source["上次当前价格"];
this["当前价格"] = source["当前价格"]; this["当前价格"] = source["当前价格"];
this["成交的股票数"] = source["成交的股票数"]; this["成交的股票数"] = source["成交的股票数"];
this["成交金额"] = source["成交金额"]; this["成交金额"] = source["成交金额"];

View File

@ -44,7 +44,7 @@ func main() {
if stocksBin != nil && len(stocksBin) > 0 { if stocksBin != nil && len(stocksBin) > 0 {
go initStockData() go initStockData()
} }
//updateBasicInfo() updateBasicInfo()
// Create an instance of the app structure // Create an instance of the app structure
app := NewApp() app := NewApp()