84 lines
2.4 KiB
Go
84 lines
2.4 KiB
Go
package mock
|
|
|
|
import (
|
|
"log"
|
|
|
|
"git.apinb.com/bsm-sdk/core/utils"
|
|
"git.apinb.com/quant/gostock/internal/impl"
|
|
"git.apinb.com/quant/gostock/internal/models"
|
|
)
|
|
|
|
func Run(key string, ymd int) {
|
|
log.Println("Run Mock Order.")
|
|
var stocks []*models.StratModel
|
|
impl.DBService.Where("strat_key=? and ymd=? and ai_score>=?", key, ymd, 5).Find(&stocks)
|
|
if len(stocks) == 0 {
|
|
log.Println("No data to process.")
|
|
return
|
|
}
|
|
for _, s := range stocks {
|
|
log.Printf("Processing %s %s", s.Code, s.StratKey)
|
|
|
|
// 1.判断是否有持仓
|
|
var cnt int64
|
|
impl.DBService.Model(&models.MockPosition{}).Where("code=? and status=0", s.Code).Count(&cnt)
|
|
if cnt > 0 {
|
|
log.Printf("Position exists for %s, skip.", s.Code)
|
|
continue
|
|
}
|
|
// 2.获取当日收盘最新价
|
|
var latestPrice float64
|
|
impl.DBService.Model(&models.StockDaily{}).Where("ts_code=? and trade_date=?", s.Code, ymd).Select("close").Scan(&latestPrice)
|
|
if latestPrice == 0 {
|
|
log.Printf("No data for %s, skip.", s.Code)
|
|
continue
|
|
}
|
|
|
|
// 3.开仓
|
|
newOpenPrice := utils.FloatRound(latestPrice*1.005, 2) // 默认开仓价为收盘价+0.5%的滑点
|
|
log.Printf("Latest price for %s is %f,open %f", s.Code, latestPrice, newOpenPrice)
|
|
impl.DBService.Model(&models.MockPosition{}).Create(&models.MockPosition{
|
|
Code: s.Code,
|
|
OpenPrice: newOpenPrice,
|
|
Pnl: 0,
|
|
PnlRate: 0,
|
|
Status: 0,
|
|
})
|
|
}
|
|
|
|
CheckClose()
|
|
}
|
|
|
|
func CheckClose() {
|
|
log.Println("Check Close Mock Order.")
|
|
var positions []*models.MockPosition
|
|
impl.DBService.Where("status=0").Find(&positions)
|
|
for _, p := range positions {
|
|
var item models.StockDaily
|
|
err := impl.DBService.Model(&models.StockDaily{}).Where("ts_code=?", p.Code).Order("id desc").Limit(1).First(&item).Error
|
|
if err != nil {
|
|
log.Printf("No data for %s, skip.", p.Code)
|
|
continue
|
|
}
|
|
|
|
// 1.通过最高价计算平仓价格
|
|
newClosePrice := utils.FloatRound(item.High*0.99, 2)
|
|
log.Printf("Latest price for %s is %f,close %f", p.Code, item.High, newClosePrice)
|
|
|
|
// 2.计算盈亏
|
|
pnl := utils.FloatRound(newClosePrice-p.OpenPrice, 2)
|
|
pnlRate := utils.FloatRound(pnl/p.OpenPrice*100, 2)
|
|
log.Printf("Pnl for %s is %f,rate %f", p.Code, pnl, pnlRate)
|
|
// 3.判断盈亏超过20%,才确定平仓
|
|
if pnlRate >= 20 {
|
|
impl.DBService.Model(&models.MockPosition{}).Where("id=?", p.ID).Updates(map[string]any{
|
|
"close_price": newClosePrice,
|
|
"pnl": pnl,
|
|
"pnl_rate": pnlRate,
|
|
"status": 1,
|
|
})
|
|
|
|
}
|
|
}
|
|
}
|