108 lines
3.2 KiB
Go
108 lines
3.2 KiB
Go
package rpc_fea
|
||
|
||
import (
|
||
"github.com/banbox/banbot/biz"
|
||
"github.com/banbox/banbot/btime"
|
||
"github.com/banbox/banbot/core"
|
||
"github.com/banbox/banbot/orm"
|
||
"github.com/banbox/banexg"
|
||
"github.com/banbox/banexg/errs"
|
||
"github.com/banbox/banexg/log"
|
||
utils2 "github.com/banbox/banexg/utils"
|
||
"github.com/banbox/banta"
|
||
"go.uber.org/zap"
|
||
"gonum.org/v1/gonum/mat"
|
||
)
|
||
|
||
type AiFea2State struct {
|
||
cg *banta.CGraph
|
||
feasBig *mat.Dense
|
||
avgCostBigs []float64 //大周期的成本价
|
||
}
|
||
|
||
func pubAiFea2(exsList []*orm.ExSymbol, req *biz.SubReq, rsp biz.FeaFeeder_SubFeaturesServer) error {
|
||
var sample = int(req.Sample)
|
||
if sample <= 0 {
|
||
sample = 10
|
||
}
|
||
startDt := btime.ToDateStr(req.Start, core.DefaultDateFmt)
|
||
endDt := btime.ToDateStr(req.End, core.DefaultDateFmt)
|
||
log.Info("start ai fea2", zap.Int("pair", len(exsList)), zap.String("start", startDt),
|
||
zap.String("end", endDt), zap.Int("sample", sample))
|
||
var seqNum = 150 // 特征序列长度
|
||
var penNum = 80 // 笔矩阵长度
|
||
var depth = 100 // 笔矩阵深度:100个深度
|
||
tfSml, tfBig := "5m", "1h"
|
||
tfMSecs := int64(utils2.TFToSecs(tfSml) * 1000)
|
||
tfMSecsBig := int64(utils2.TFToSecs(tfBig) * 1000)
|
||
|
||
task := &GenFeaTask{
|
||
TfSml: tfSml,
|
||
TfBig: tfBig,
|
||
WarmSml: 2000,
|
||
WarmBig: 300,
|
||
TfMSecs: tfMSecs,
|
||
TfMSecsBig: tfMSecsBig,
|
||
NextObsNum: 30,
|
||
}
|
||
|
||
states := make(map[string]*AiFea2State)
|
||
for _, exs := range exsList {
|
||
states[exs.Symbol] = &AiFea2State{
|
||
cg: &banta.CGraph{ParseLevel: banta.ParseLevelPen, MaxPen: penNum * 3 / 2},
|
||
}
|
||
}
|
||
|
||
batch := NewBatchMap(len(exsList))
|
||
|
||
task.OnBar = func(e *banta.BarEnv, b *banexg.Kline, futs []*banexg.Kline) *errs.Error {
|
||
state := states[e.Symbol]
|
||
state.cg.AddBar(e)
|
||
state.cg.Parse()
|
||
feas := onAiFeatures2(e, 30)
|
||
if e.BarNum%sample > 0 || len(state.cg.Pens) < penNum || len(futs) == 0 || state.feasBig == nil {
|
||
// 预热时futs为nil
|
||
return nil
|
||
}
|
||
// 收集特征,发送到监听端
|
||
minChgVal := banta.ATR(e.High, e.Low, e.Close, 30).Get(0) * 5
|
||
futProbs := genFutProbsV1(futs, minChgVal, 0.4)
|
||
mats, _ := GenPenMats2(state.cg, penNum, depth, false)
|
||
avgCosts := avgCostN(e, 10, 20, 40, 80, 160, 320)
|
||
info := make([]float64, 0, 25)
|
||
info = append(info, avgCosts...)
|
||
info = append(info, state.avgCostBigs...)
|
||
return batch.Add(rsp, e, b.Time, map[string]*biz.NumArr{
|
||
"one": matToNumArr(mats[0]),
|
||
"two": matToNumArr(mats[1]),
|
||
"feas": matToNumArr(feas),
|
||
"feas2": matToNumArr(state.feasBig),
|
||
"bar": {
|
||
Data: []float64{float64(b.Time / 1000), b.Open, b.High, b.Low, b.Close, b.Volume},
|
||
Shape: []int32{6},
|
||
},
|
||
"y": {
|
||
Data: []float64{futProbs[0], futProbs[1], futProbs[2]},
|
||
Shape: []int32{3},
|
||
},
|
||
"info": {
|
||
Data: info, Shape: []int32{int32(len(info))},
|
||
},
|
||
})
|
||
}
|
||
task.OnInfoBar = func(e *banta.BarEnv, b *banexg.Kline) *errs.Error {
|
||
state := states[e.Symbol]
|
||
state.feasBig = onAiFeatures2(e, seqNum)
|
||
state.avgCostBigs = avgCostN(e, 10, 20, 40, 80, 160, 320)
|
||
return nil
|
||
}
|
||
task.OnEnvEnd = func(bar *banexg.PairTFKline, adj *orm.AdjInfo) {
|
||
if bar == nil {
|
||
return
|
||
}
|
||
state := states[bar.Symbol]
|
||
state.cg = &banta.CGraph{ParseLevel: banta.ParseLevelPen, MaxPen: penNum * 3 / 2}
|
||
}
|
||
return pubFeaBase(exsList, req, task)
|
||
}
|