github.com/diadata-org/diadata@v1.4.593/pkg/dia/Trade.go (about)

     1  package dia
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/zekroTJA/timedmap"
    11  )
    12  
    13  // GetBaseToken returns the base token of a trading pair
    14  // TO DO (20/11/2020): This method is no longer needed once we switch to new Token/Trade structs
    15  func (t *Trade) GetBaseToken() string {
    16  
    17  	if t.BaseToken.Symbol != "" {
    18  		return t.BaseToken.Symbol
    19  	}
    20  
    21  	pair := strings.ToUpper(t.Pair)
    22  	if len(pair) > 3 {
    23  		switch t.Source {
    24  		case KrakenExchange:
    25  			if pair[len(pair)-3:] == "XBT" {
    26  				return "BTC"
    27  			}
    28  		case BitfinexExchange:
    29  			if pair[len(pair)-3:] == "USD" {
    30  				return "USDT"
    31  			}
    32  		case HitBTCExchange:
    33  			if pair[len(pair)-3:] == "USD" {
    34  				return "USDT"
    35  			}
    36  		}
    37  	}
    38  
    39  	second := strings.TrimPrefix(pair, strings.ToUpper(t.Symbol)+"_")
    40  	if second != pair {
    41  		return second
    42  	}
    43  	second = strings.TrimPrefix(pair, strings.ToUpper(t.Symbol)+"-")
    44  	if second != pair {
    45  		return second
    46  	}
    47  	second = strings.TrimPrefix(pair, strings.ToUpper(t.Symbol)+"/")
    48  	if second != pair {
    49  		return second
    50  	}
    51  
    52  	return strings.TrimPrefix(pair, strings.ToUpper(t.Symbol))
    53  }
    54  
    55  // SwapTrade swaps base and quote token of a trade and inverts the price accordingly
    56  func SwapTrade(t Trade) (Trade, error) {
    57  	if t.Price == 0 {
    58  		return t, errors.New("zero price. cannot swap trade")
    59  	}
    60  	t.BaseToken, t.QuoteToken = t.QuoteToken, t.BaseToken
    61  	t.Symbol = t.QuoteToken.Symbol
    62  	t.Pair = t.QuoteToken.Symbol + "-" + t.BaseToken.Symbol
    63  	t.Volume = -t.Price * t.Volume
    64  	t.Price = 1 / t.Price
    65  
    66  	return t, nil
    67  }
    68  
    69  // IdentifyDuplicateFull returns true in case a trade is fully identical to one stored in the timed map @falseDuplicateTrades.
    70  func (t *Trade) IdentifyDuplicateFull(falseDuplicateTrades *timedmap.TimedMap, memory time.Duration) (discardTrade bool) {
    71  	if _, ok := falseDuplicateTrades.GetValue(t.TradeIdentifierFull()).(int); !ok {
    72  		falseDuplicateTrades.Set(t.TradeIdentifierFull(), 1, memory)
    73  	} else {
    74  		discardTrade = true
    75  	}
    76  	return
    77  }
    78  
    79  // IdentifyDuplicateTagset identifies trades with identical timestamps and tagsets and add a Nanosecond to
    80  // the timestamp in order for the trade not to be overwritten in Influx.
    81  func (t *Trade) IdentifyDuplicateTagset(duplicateTrades *timedmap.TimedMap, memory time.Duration) {
    82  	if val, ok := duplicateTrades.GetValue(t.TradeIdentifierTagset()).(int); !ok {
    83  		duplicateTrades.Set(t.TradeIdentifierTagset(), 1, memory)
    84  	} else {
    85  		// Set trade identifier as key with value incremented.
    86  		duplicateTrades.Set(t.TradeIdentifierTagset(), val+1, memory)
    87  		// Add old value as Nanosecond to trade time.
    88  		t.Time = t.Time.Add(time.Duration(val) * time.Nanosecond)
    89  	}
    90  }
    91  
    92  // TradeIdentifierFull returns an identifier with respect to all fields of a trade.
    93  func (t *Trade) TradeIdentifierFull() string {
    94  	timeString := strconv.Itoa(int(t.Time.UnixNano()))
    95  	priceString := fmt.Sprintf("%f", t.Price)
    96  	volumeString := fmt.Sprintf("%f", t.Volume)
    97  	return timeString +
    98  		priceString +
    99  		volumeString +
   100  		t.ForeignTradeID +
   101  		t.Source +
   102  		t.QuoteToken.Address +
   103  		t.QuoteToken.Blockchain +
   104  		t.BaseToken.Address +
   105  		t.BaseToken.Blockchain
   106  }
   107  
   108  // TradeIdentifierTagset returns an identifier with respect to the tagset of a trade in Influx.
   109  // In other words, a trade with this same tagset is overwritten in Influx trades table.
   110  func (t *Trade) TradeIdentifierTagset() string {
   111  	timeString := strconv.Itoa(int(t.Time.UnixNano()))
   112  	return timeString +
   113  		t.Symbol +
   114  		t.Pair +
   115  		t.Source +
   116  		t.QuoteToken.Address +
   117  		t.QuoteToken.Blockchain +
   118  		t.BaseToken.Address +
   119  		t.BaseToken.Blockchain
   120  }