code.vegaprotocol.io/vega@v0.79.0/datanode/entities/candle.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package entities
    17  
    18  import (
    19  	"encoding/json"
    20  	"fmt"
    21  	"time"
    22  
    23  	v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2"
    24  	"code.vegaprotocol.io/vega/protos/vega"
    25  
    26  	"github.com/shopspring/decimal"
    27  )
    28  
    29  type Candle struct {
    30  	PeriodStart        time.Time
    31  	LastUpdateInPeriod time.Time
    32  	Open               decimal.Decimal
    33  	Close              decimal.Decimal
    34  	High               decimal.Decimal
    35  	Low                decimal.Decimal
    36  	Volume             uint64
    37  	Notional           uint64
    38  }
    39  
    40  func (c *Candle) ToV1CandleProto(interval vega.Interval) (*vega.Candle, error) {
    41  	return &vega.Candle{
    42  		Timestamp: c.PeriodStart.UnixNano(),
    43  		Datetime:  c.LastUpdateInPeriod.Format(time.RFC3339Nano),
    44  		High:      c.High.String(),
    45  		Low:       c.Low.String(),
    46  		Open:      c.Open.String(),
    47  		Close:     c.Close.String(),
    48  		Volume:    c.Volume,
    49  		Notional:  c.Notional,
    50  		Interval:  interval,
    51  	}, nil
    52  }
    53  
    54  func (c *Candle) ToV2CandleProto() *v2.Candle {
    55  	var openPx, highPx, lowPx, closePx string
    56  
    57  	if c.Open.GreaterThan(decimal.Zero) {
    58  		openPx = c.Open.String()
    59  	}
    60  
    61  	if c.High.GreaterThan(decimal.Zero) {
    62  		highPx = c.High.String()
    63  	}
    64  
    65  	if c.Low.GreaterThan(decimal.Zero) {
    66  		lowPx = c.Low.String()
    67  	}
    68  
    69  	if c.Close.GreaterThan(decimal.Zero) {
    70  		closePx = c.Close.String()
    71  	}
    72  
    73  	return &v2.Candle{
    74  		Start:      c.PeriodStart.UnixNano(),
    75  		LastUpdate: c.LastUpdateInPeriod.UnixNano(),
    76  		High:       highPx,
    77  		Low:        lowPx,
    78  		Open:       openPx,
    79  		Close:      closePx,
    80  		Volume:     c.Volume,
    81  		Notional:   c.Notional,
    82  	}
    83  }
    84  
    85  func (c Candle) Cursor() *Cursor {
    86  	cc := CandleCursor{
    87  		PeriodStart: c.PeriodStart,
    88  	}
    89  	return NewCursor(cc.String())
    90  }
    91  
    92  func (c Candle) ToProtoEdge(_ ...any) (*v2.CandleEdge, error) {
    93  	return &v2.CandleEdge{
    94  		Node:   c.ToV2CandleProto(),
    95  		Cursor: c.Cursor().Encode(),
    96  	}, nil
    97  }
    98  
    99  type CandleCursor struct {
   100  	PeriodStart time.Time `json:"periodStart"`
   101  }
   102  
   103  func (c CandleCursor) String() string {
   104  	bs, err := json.Marshal(c)
   105  	if err != nil {
   106  		panic(fmt.Errorf("could not marshal candle cursor: %w", err))
   107  	}
   108  	return string(bs)
   109  }
   110  
   111  func (c *CandleCursor) Parse(cursorString string) error {
   112  	if cursorString == "" {
   113  		return nil
   114  	}
   115  	return json.Unmarshal([]byte(cursorString), c)
   116  }