add mock order.
This commit is contained in:
@@ -30,6 +30,7 @@ func main() {
|
|||||||
app.Use(middleware.Cors())
|
app.Use(middleware.Cors())
|
||||||
app.Use(gin.Recovery())
|
app.Use(gin.Recovery())
|
||||||
app.GET("/", restful.Ping)
|
app.GET("/", restful.Ping)
|
||||||
|
app.GET("/start/strategy", restful.Starter)
|
||||||
|
|
||||||
// 启动HTTP服务器
|
// 启动HTTP服务器
|
||||||
err := app.Run(fmt.Sprintf(":%s", config.Spec.Port))
|
err := app.Run(fmt.Sprintf(":%s", config.Spec.Port))
|
||||||
|
|||||||
@@ -22,9 +22,10 @@ func main() {
|
|||||||
config.New(ServiceKey)
|
config.New(ServiceKey)
|
||||||
impl.NewImpl()
|
impl.NewImpl()
|
||||||
|
|
||||||
|
ymd := models.GetYmd()
|
||||||
for _, code := range strategy.GetStocks() {
|
for _, code := range strategy.GetStocks() {
|
||||||
strategy.InitCacheByCode(code)
|
strategy.InitCacheByCode(code)
|
||||||
model := models.NewStratModel("selector", code)
|
model := models.NewStratModel("selector", code, ymd)
|
||||||
stratRule := rule.NewRule(model)
|
stratRule := rule.NewRule(model)
|
||||||
{
|
{
|
||||||
stratRule.RunUpDate(strategy.Cache[code].Basic.ListDate)
|
stratRule.RunUpDate(strategy.Cache[code].Basic.ListDate)
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Service: gostock
|
Service: gostock
|
||||||
Port: 14299
|
Port: 13499
|
||||||
|
|
||||||
Databases:
|
Databases:
|
||||||
Driver: postgres
|
Driver: postgres
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Service: gostock
|
Service: gostock
|
||||||
Port: 14299
|
Port: 13499
|
||||||
|
|
||||||
Databases:
|
Databases:
|
||||||
Driver: postgres
|
Driver: postgres
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Service: gostock
|
Service: gostock
|
||||||
Port: 14299
|
Port: 13499
|
||||||
|
|
||||||
Databases:
|
Databases:
|
||||||
Driver: postgres
|
Driver: postgres
|
||||||
|
|||||||
81
internal/logic/mock/order.go
Normal file
81
internal/logic/mock/order.go
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(p.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,
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
internal/logic/restful/starter.go
Normal file
43
internal/logic/restful/starter.go
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"git.apinb.com/quant/gostock/internal/logic/mock"
|
||||||
|
"git.apinb.com/quant/gostock/internal/logic/strategy"
|
||||||
|
"git.apinb.com/quant/gostock/internal/logic/strategy/rule"
|
||||||
|
"git.apinb.com/quant/gostock/internal/models"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Starter(ctx *gin.Context) {
|
||||||
|
log.Println("Strategy START.")
|
||||||
|
ymd := models.GetYmd()
|
||||||
|
for _, code := range strategy.GetStocks() {
|
||||||
|
strategy.InitCacheByCode(code)
|
||||||
|
model := models.NewStratModel("selector", code, ymd)
|
||||||
|
stratRule := rule.NewRule(model)
|
||||||
|
{
|
||||||
|
stratRule.RunUpDate(strategy.Cache[code].Basic.ListDate)
|
||||||
|
stratRule.RunST(strategy.Cache[code].Basic.Name)
|
||||||
|
stratRule.RunIndustry(strategy.Cache[code].Basic.Industry)
|
||||||
|
stratRule.RunPrice(code)
|
||||||
|
stratRule.RunAmount(code)
|
||||||
|
stratRule.RunRoe(code)
|
||||||
|
stratRule.RunRsi(code)
|
||||||
|
|
||||||
|
// 过滤无需AI分析
|
||||||
|
if model.StScore > 0 && model.IndustryScore > 0 && model.GtPrice > 0 && model.GtAmount > 0 && model.GtRoe > 0 && model.ScoreRsi > 0 {
|
||||||
|
model.AiScore = 0 // 待分析
|
||||||
|
} else {
|
||||||
|
model.AiScore = -2
|
||||||
|
model.AddDesc("无需AI分析")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
model.Save()
|
||||||
|
}
|
||||||
|
|
||||||
|
strategy.BootAiStart("selector", ymd)
|
||||||
|
log.Println("Strategy END.")
|
||||||
|
mock.Run("selector", ymd)
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
|
import "gorm.io/gorm"
|
||||||
|
|
||||||
type MockPosition struct {
|
type MockPosition struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
Code string
|
Code string
|
||||||
@@ -7,5 +9,5 @@ type MockPosition struct {
|
|||||||
ClosePrice float64
|
ClosePrice float64
|
||||||
Pnl float64
|
Pnl float64
|
||||||
PnlRate float64
|
PnlRate float64
|
||||||
Status int
|
Status int `default:"0"`
|
||||||
}
|
}
|
||||||
@@ -52,10 +52,10 @@ func (StratModel) TableName() string {
|
|||||||
return "strat_model"
|
return "strat_model"
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStratModel(key, code string) *StratModel {
|
func NewStratModel(key, code string, ymd int) *StratModel {
|
||||||
obj := StratModel{
|
obj := StratModel{
|
||||||
StratKey: key,
|
StratKey: key,
|
||||||
Ymd: GetYmd(),
|
Ymd: ymd,
|
||||||
Code: code,
|
Code: code,
|
||||||
}
|
}
|
||||||
return &obj
|
return &obj
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
GOARCH=amd64 GOOS=linux go build -o ../builds/gostock ./cmd/cli/main.go
|
GOARCH=amd64 GOOS=linux go build -o ../builds/gostock ./cmd/main/main.go
|
||||||
|
|
||||||
nohup ./gostock > /data/app/logs/gostock.log 2>&1 &
|
nohup ./gostock > /data/app/logs/gostock.log 2>&1 &
|
||||||
Reference in New Issue
Block a user