2024-12-15 17:40:14 +08:00
|
|
|
|
package core
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
logrus "github.com/sirupsen/logrus"
|
|
|
|
|
"os"
|
|
|
|
|
"strconv"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// TODO 目前没有实现tickerInfo,用一分钟维度的candle代替, 后续如果订阅ws的话,ticker就不用了,也还是直接用candle1m就够了
|
|
|
|
|
type Coaster struct {
|
|
|
|
|
InstID string `json:"instID"`
|
|
|
|
|
Period string `json:"period"`
|
|
|
|
|
Count int `json:"count"`
|
|
|
|
|
Scale float64 `json:"scale"`
|
|
|
|
|
LastUpdateTime int64 `json:"lastUpdateTime"`
|
|
|
|
|
UpdateNickName string `json:"updateNickName"`
|
|
|
|
|
CandleList CandleList `json:"candleList"`
|
|
|
|
|
Ma7List MaXList `json:"ma7List"`
|
|
|
|
|
Ma30List MaXList `json:"ma30List"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CoasterInfo struct {
|
|
|
|
|
InstID string
|
|
|
|
|
Period string
|
|
|
|
|
InsertedNew bool
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (co Coaster) RPushSample(cr *Core, sp Sample, ctype string) (*Sample, error) {
|
|
|
|
|
cd := Candle{}
|
|
|
|
|
spjs, _ := json.Marshal(sp)
|
|
|
|
|
logrus.Debug("RPushSample spjs: ", string(spjs))
|
|
|
|
|
if ctype == "candle" {
|
|
|
|
|
json.Unmarshal(spjs, &cd)
|
|
|
|
|
cd.Data[0] = cd.Data[0]
|
|
|
|
|
cd.Data[1], _ = strconv.ParseFloat(cd.Data[1].(string), 64)
|
|
|
|
|
cd.Data[2], _ = strconv.ParseFloat(cd.Data[2].(string), 64)
|
|
|
|
|
cd.Data[3], _ = strconv.ParseFloat(cd.Data[3].(string), 64)
|
|
|
|
|
cd.Data[4], _ = strconv.ParseFloat(cd.Data[4].(string), 64)
|
|
|
|
|
cd.Data[5], _ = strconv.ParseFloat(cd.Data[5].(string), 64)
|
|
|
|
|
cd.Data[6], _ = strconv.ParseFloat(cd.Data[6].(string), 64)
|
|
|
|
|
sm, err := co.CandleList.RPush(&cd)
|
|
|
|
|
if err == nil {
|
|
|
|
|
now := time.Now().UnixMilli()
|
|
|
|
|
co.LastUpdateTime = now
|
|
|
|
|
co.CandleList.LastUpdateTime = now
|
2024-12-15 20:42:18 +08:00
|
|
|
|
co.UpdateNickName = GetRandomString(12)
|
|
|
|
|
co.CandleList.UpdateNickName = GetRandomString(12)
|
2024-12-15 17:40:14 +08:00
|
|
|
|
}
|
|
|
|
|
return &sm, err
|
|
|
|
|
}
|
|
|
|
|
mx := MaX{}
|
|
|
|
|
if ctype == "ma7" {
|
|
|
|
|
json.Unmarshal(spjs, &mx)
|
|
|
|
|
sm, err := co.Ma7List.RPush(&mx)
|
|
|
|
|
if err == nil {
|
|
|
|
|
now := time.Now().UnixMilli()
|
|
|
|
|
co.LastUpdateTime = now
|
2024-12-15 20:42:18 +08:00
|
|
|
|
co.Ma7List.UpdateNickName = GetRandomString(12)
|
2024-12-15 17:40:14 +08:00
|
|
|
|
co.Ma7List.LastUpdateTime = now
|
|
|
|
|
}
|
|
|
|
|
return &sm, err
|
|
|
|
|
}
|
|
|
|
|
if ctype == "ma30" {
|
|
|
|
|
json.Unmarshal(spjs, &mx)
|
|
|
|
|
sm, err := co.Ma30List.RPush(&mx)
|
|
|
|
|
// bj, _ := json.Marshal(co)
|
|
|
|
|
if err == nil {
|
|
|
|
|
now := time.Now().UnixMilli()
|
|
|
|
|
co.LastUpdateTime = now
|
2024-12-15 20:42:18 +08:00
|
|
|
|
co.Ma30List.UpdateNickName = GetRandomString(12)
|
2024-12-15 17:40:14 +08:00
|
|
|
|
co.Ma30List.LastUpdateTime = now
|
|
|
|
|
}
|
|
|
|
|
return &sm, err
|
|
|
|
|
}
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (co *Coaster) SetToKey(cr *Core) (string, error) {
|
|
|
|
|
co.CandleList.RecursiveBubbleS(len(co.CandleList.List), "asc")
|
|
|
|
|
co.Ma7List.RecursiveBubbleS(len(co.Ma7List.List), "asc")
|
|
|
|
|
co.Ma30List.RecursiveBubbleS(len(co.Ma30List.List), "asc")
|
|
|
|
|
js, _ := json.Marshal(*co)
|
|
|
|
|
coasterName := co.InstID + "|" + co.Period + "|coaster"
|
|
|
|
|
res, err := cr.RedisLocalCli.Set(coasterName, string(js), 0).Result()
|
|
|
|
|
return res, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (coi *CoasterInfo) Process(cr *Core) {
|
|
|
|
|
curCo, _ := cr.GetCoasterFromPlate(coi.InstID, coi.Period)
|
|
|
|
|
go func(co Coaster) {
|
|
|
|
|
//这里执行:创建一个tray对象,用现有的co的数据计算和填充其listMap
|
|
|
|
|
// TODO 发到一个channel里来执行下面的任务,
|
|
|
|
|
allow := os.Getenv("SARDINE_MAKESERIES") == "true"
|
|
|
|
|
if !allow {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
srs, err := co.UpdateTray(cr)
|
|
|
|
|
if err != nil || srs == nil {
|
|
|
|
|
logrus.Warn("tray err: ", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
_, err = srs.SetToKey(cr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logrus.Warn("srs SetToKey err: ", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
//实例化完一个tray之后,拿着这个tray去执行Analytics方法
|
|
|
|
|
//
|
2024-12-15 20:42:18 +08:00
|
|
|
|
// srsinfo := SeriesInfo{
|
|
|
|
|
// InstID: curCo.InstID,
|
|
|
|
|
// Period: curCo.Period,
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// cr.SeriesChan <- &srsinfo
|
2024-12-15 17:40:14 +08:00
|
|
|
|
}(curCo)
|
|
|
|
|
|
|
|
|
|
go func(co Coaster) {
|
|
|
|
|
// 每3次会有一次触发缓存落盘
|
|
|
|
|
// run := utils.Shaizi(3)
|
|
|
|
|
// if run {
|
|
|
|
|
_, err := co.SetToKey(cr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logrus.Warn("coaster process err: ", err)
|
|
|
|
|
fmt.Println("coaster SetToKey err: ", err)
|
|
|
|
|
}
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
}(curCo)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO 类似于InsertIntoPlate函数,照猫画虎就行了
|
|
|
|
|
func (co *Coaster) UpdateTray(cr *Core) (*Series, error) {
|
|
|
|
|
cr.Mu1.Lock()
|
|
|
|
|
defer cr.Mu1.Unlock()
|
|
|
|
|
//尝试从内存读取tray对象
|
|
|
|
|
tr, trayFounded := cr.TrayMap[co.InstID]
|
|
|
|
|
if !trayFounded {
|
|
|
|
|
tr1, err := co.LoadTray(cr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
cr.TrayMap[co.InstID] = tr1
|
|
|
|
|
tr = tr1
|
|
|
|
|
}
|
|
|
|
|
srs, seriesFounded := tr.SeriesMap["period"+co.Period]
|
|
|
|
|
err := errors.New("")
|
|
|
|
|
if !seriesFounded {
|
|
|
|
|
srs1, err := tr.NewSeries(cr, co.Period)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
tr.SeriesMap["period"+co.Period] = srs1
|
|
|
|
|
} else {
|
|
|
|
|
err = srs.Refresh(cr)
|
|
|
|
|
}
|
|
|
|
|
// if err == nil {
|
|
|
|
|
// bj, _ := json.Marshal(srs)
|
|
|
|
|
// logrus.Debug("series:,string"(bj))
|
|
|
|
|
// }
|
|
|
|
|
return srs, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
|
func (co *Coaster) LoadTray(cr *Core) (*Tray, error) {
|
|
|
|
|
tray := Tray{}
|
|
|
|
|
tray.Init(co.InstID)
|
|
|
|
|
prs := cr.Cfg.Config.Get("candleDimentions").MustArray()
|
|
|
|
|
for _, v := range prs {
|
|
|
|
|
tray.NewSeries(cr, v.(string))
|
|
|
|
|
}
|
|
|
|
|
return &tray, nil
|
|
|
|
|
}
|