github.com/diadata-org/diadata@v1.4.593/internal/pkg/filtersBlockService/FilterVWAP.go (about)

     1  package filters
     2  
     3  import (
     4  	"math"
     5  	"strconv"
     6  	"time"
     7  
     8  	"github.com/diadata-org/diadata/pkg/dia"
     9  	log "github.com/sirupsen/logrus"
    10  )
    11  
    12  // FilterVWAP ...
    13  type FilterVWAP struct {
    14  	asset              dia.Asset
    15  	exchange           string
    16  	currentTime        time.Time
    17  	prices             []float64
    18  	volumes            []float64
    19  	lastTrade          dia.Trade
    20  	param              int
    21  	value              float64
    22  	filterName         string
    23  	nativeDenomination bool
    24  	modified           bool
    25  }
    26  
    27  // NewFilterVWAP ...
    28  func NewFilterVWAP(asset dia.Asset, exchange string, currentTime time.Time, param int, nativeDenomination bool) *FilterVWAP {
    29  	s := &FilterVWAP{
    30  		asset:              asset,
    31  		exchange:           exchange,
    32  		prices:             []float64{},
    33  		volumes:            []float64{},
    34  		currentTime:        currentTime,
    35  		param:              param,
    36  		filterName:         "VWAP" + strconv.Itoa(param),
    37  		nativeDenomination: nativeDenomination,
    38  	}
    39  	return s
    40  }
    41  
    42  // Compute ...
    43  func (s *FilterVWAP) Compute(trade dia.Trade) {
    44  	s.compute(trade)
    45  }
    46  
    47  func (filter *FilterVWAP) compute(trade dia.Trade) {
    48  	filter.modified = true
    49  	if filter.lastTrade != (dia.Trade{}) {
    50  		if trade.Time.Before(filter.currentTime) {
    51  			log.Errorln("FilterVWAP: Ignoring Trade out of order ", filter.currentTime, trade.Time)
    52  			return
    53  		}
    54  	}
    55  	filter.fill(trade)
    56  	filter.lastTrade = trade
    57  }
    58  
    59  // fill just adds a trade to the prices and volumes slices.
    60  func (filter *FilterVWAP) fill(trade dia.Trade) {
    61  	// filter.currentTime is the timestamp of the last filled trade.
    62  	filter.processDataPoint(trade)
    63  	filter.currentTime = trade.Time
    64  }
    65  
    66  func (filter *FilterVWAP) processDataPoint(trade dia.Trade) {
    67  	if !filter.nativeDenomination {
    68  		filter.prices = append([]float64{trade.EstimatedUSDPrice}, filter.prices...)
    69  	} else {
    70  		filter.prices = append([]float64{trade.Price}, filter.prices...)
    71  	}
    72  	filter.volumes = append([]float64{trade.Volume}, filter.volumes...)
    73  }
    74  
    75  // FinalCompute ...
    76  func (s *FilterVWAP) FinalCompute(t time.Time) float64 {
    77  	return s.finalCompute(t)
    78  }
    79  
    80  func (s *FilterVWAP) finalCompute(t time.Time) float64 {
    81  	log.Infof("computed value %v at time %v ", s.value, t)
    82  	if s.lastTrade == (dia.Trade{}) {
    83  		return 0.0
    84  	}
    85  
    86  	var totalVolume float64 = 0
    87  	var priceVolume []float64
    88  	var totalPriceVolume float64 = 0
    89  
    90  	for index, price := range s.prices {
    91  		priceVolume = append(priceVolume, price*math.Abs(s.volumes[index]))
    92  	}
    93  
    94  	for _, v := range s.volumes {
    95  		totalVolume += math.Abs(v)
    96  	}
    97  
    98  	for _, v := range priceVolume {
    99  		totalPriceVolume += v
   100  	}
   101  
   102  	if totalVolume > 0 {
   103  		s.value = totalPriceVolume / totalVolume
   104  	}
   105  
   106  	return s.value
   107  }
   108  
   109  // FilterPointForBlock ...
   110  func (s *FilterVWAP) FilterPointForBlock() *dia.FilterPoint {
   111  	return s.filterPointForBlock()
   112  }
   113  func (s *FilterVWAP) filterPointForBlock() *dia.FilterPoint {
   114  	if s.exchange != "" {
   115  		return &dia.FilterPoint{
   116  			Value: s.value,
   117  			Name:  "VWAP" + strconv.Itoa(s.param),
   118  			Time:  s.currentTime,
   119  			Asset: s.asset,
   120  		}
   121  	} else {
   122  		return &dia.FilterPoint{
   123  			Value: s.value,
   124  			Name:  "VWAP" + strconv.Itoa(s.param),
   125  			Time:  s.currentTime,
   126  			Asset: s.asset,
   127  		}
   128  	}
   129  }