You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

148 lines
4.7 KiB

package vmts
import (
"fmt"
"sig-pub/pkg/types"
"github.com/bytedance/sonic"
"github.com/govalues/decimal"
)
var (
rawValueLimit = 5 // 避免单行数据过大
)
type Metric struct {
Metric map[string]string `json:"metric"` // {"__name__":"open","instance":"DOGE-USDT-SWAP"}
Values []float64 `json:"values"`
Timestamps []int64 `json:"timestamps"`
}
func NewMetric(name string, tags ...string) *Metric {
if len(tags)%2 != 0 {
panic(fmt.Sprintf("%s error length tags: %v", name, tags))
}
metric := map[string]string{"__name__": name}
for i := 0; i < len(tags); i += 2 {
metric[tags[i]] = tags[i+1]
}
return &Metric{
Metric: metric,
}
}
func (m *Metric) AddTag(name, value string) {
m.Metric[name] = value
}
func (m *Metric) AddTsValue(ts int64, value float64) {
m.Timestamps = append(m.Timestamps, ts)
m.Values = append(m.Values, value)
}
func (m *Metric) ToRowJson() ([]byte, error) {
return sonic.Marshal(m)
}
func Kline2Metrics0(inst types.TradeInstance, klines []*types.Kline) (metrics []*Metric) {
instMetrics := make(map[string][6]*Metric)
// id := inst.InstId
// inst.InstId = "doge_udst"
// defer func() {
// inst.InstId = id
// }()
for _, kline := range klines {
ms, ok := instMetrics[inst.InstId]
if !ok || (rawValueLimit > 0 && len(ms[0].Values) >= rawValueLimit) {
ms = [6]*Metric{
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "open"),
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "high"),
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "low"),
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "close"),
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "vol"),
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "volQuote"),
}
instMetrics[inst.InstId] = ms
for i := range len(ms) {
metrics = append(metrics, ms[i])
}
}
// TODO open sz price
open, _ := kline.Open.Float64()
high, _ := kline.High.Float64()
low, _ := kline.Low.Float64()
close, _ := kline.Close.Float64()
vol, _ := kline.Vol.Float64()
volQuote, _ := kline.VolQuote.Float64()
ms[0].AddTsValue(kline.Ts, open)
ms[1].AddTsValue(kline.Ts, high)
ms[2].AddTsValue(kline.Ts, low)
ms[3].AddTsValue(kline.Ts, close)
ms[4].AddTsValue(kline.Ts, vol)
ms[5].AddTsValue(kline.Ts, volQuote)
}
return
}
func Kline2Metrics(inst types.TradeInstance, klines []*types.Kline) (metrics []*Metric, err error) {
instMetrics := make(map[string][6]*Metric)
var priceSz, quantitySz decimal.Decimal
if priceSz, err = decimal.Ten.PowInt(int(inst.PriceSz)); err != nil {
return
}
if quantitySz, err = decimal.Ten.PowInt(int(inst.QuantitySz)); err != nil {
return
}
for _, kline := range klines {
ms, ok := instMetrics[inst.InstId]
if !ok || (rawValueLimit > 0 && len(ms[0].Values) >= rawValueLimit) {
ms = [6]*Metric{
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "open"),
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "high"),
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "low"),
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "close"),
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "vol"),
NewMetric(inst.InstId, "interval", string(kline.Interval), "exchange", inst.Exchange.String(), "kind", "volQuote"),
}
instMetrics[inst.InstId] = ms
for i := range len(ms) {
metrics = append(metrics, ms[i])
}
}
// 存储精度处理
var open, high, low, close, vol, volQuote decimal.Decimal
if open, err = kline.Open.Mul(priceSz); err != nil {
return
}
if high, err = kline.High.Mul(priceSz); err != nil {
return
}
if low, err = kline.Low.Mul(priceSz); err != nil {
return
}
if close, err = kline.Close.Mul(priceSz); err != nil {
return
}
if vol, err = kline.Vol.Mul(quantitySz); err != nil {
return
}
if volQuote, err = kline.VolQuote.Mul(quantitySz); err != nil {
return
}
var klineValues = []decimal.Decimal{open, high, low, close, vol, volQuote}
for i, value := range klineValues {
value_f64, ok := value.Float64()
if !ok {
err = fmt.Errorf("kline value scale to float64 error: %s", value.String())
return
}
ms[i].AddTsValue(kline.Ts, value_f64)
}
}
return
}