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 }