github.com/bitfinexcom/bitfinex-api-go@v0.0.0-20210608095005-9e0b26f200fb/pkg/models/margin/margin.go (about)

     1  package margin
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/bitfinexcom/bitfinex-api-go/pkg/convert"
     7  )
     8  
     9  type InfoBase struct {
    10  	UserProfitLoss float64
    11  	UserSwaps      float64
    12  	MarginBalance  float64
    13  	MarginNet      float64
    14  	MarginRequired float64
    15  }
    16  
    17  type InfoUpdate struct {
    18  	Symbol          string
    19  	TradableBalance float64
    20  	GrossBalance    float64
    21  	Buy             float64
    22  	Sell            float64
    23  }
    24  
    25  // FromRaw returns either a InfoBase or InfoUpdate, since
    26  // the Margin Info is split up into a base and per symbol parts.
    27  func FromRaw(raw []interface{}) (o interface{}, err error) {
    28  	if len(raw) < 2 {
    29  		return o, fmt.Errorf("data slice too short for margin info base: %#v", raw)
    30  	}
    31  
    32  	typ, ok := raw[0].(string)
    33  	if !ok {
    34  		return o, fmt.Errorf("expected margin info type in first position for margin info but got %#v", raw)
    35  	}
    36  
    37  	if len(raw) > 1 && typ == "base" { // This should be ["base", [...]]
    38  		data, ok := raw[1].([]interface{})
    39  		if !ok {
    40  			return o, fmt.Errorf("expected margin info array in second position for margin info but got %#v", raw)
    41  		}
    42  
    43  		return baseFromRaw(data)
    44  	}
    45  
    46  	if len(raw) > 2 && typ == "sym" { // This should be ["sym", SYMBOL, [...]]
    47  		symbol, ok := raw[1].(string)
    48  		if !ok {
    49  			return o, fmt.Errorf("expected margin info symbol in second position for margin info update but got %#v", raw)
    50  		}
    51  
    52  		data, ok := raw[2].([]interface{})
    53  		if !ok {
    54  			return o, fmt.Errorf("expected margin info array in third position for margin info update but got %#v", raw)
    55  		}
    56  
    57  		return updateFromRaw(symbol, data)
    58  	}
    59  
    60  	return nil, fmt.Errorf("invalid margin info type in %#v", raw)
    61  }
    62  
    63  func updateFromRaw(symbol string, raw []interface{}) (o *InfoUpdate, err error) {
    64  	if len(raw) < 4 {
    65  		return o, fmt.Errorf("data slice too short for margin info update: %#v", raw)
    66  	}
    67  
    68  	o = &InfoUpdate{
    69  		Symbol:          symbol,
    70  		TradableBalance: convert.F64ValOrZero(raw[0]),
    71  		GrossBalance:    convert.F64ValOrZero(raw[1]),
    72  		Buy:             convert.F64ValOrZero(raw[2]),
    73  		Sell:            convert.F64ValOrZero(raw[3]),
    74  	}
    75  
    76  	return
    77  }
    78  
    79  func baseFromRaw(raw []interface{}) (ib *InfoBase, err error) {
    80  	if len(raw) < 5 {
    81  		return ib, fmt.Errorf("data slice too short for margin info base: %#v", raw)
    82  	}
    83  
    84  	ib = &InfoBase{
    85  		UserProfitLoss: convert.F64ValOrZero(raw[0]),
    86  		UserSwaps:      convert.F64ValOrZero(raw[1]),
    87  		MarginBalance:  convert.F64ValOrZero(raw[2]),
    88  		MarginNet:      convert.F64ValOrZero(raw[3]),
    89  		MarginRequired: convert.F64ValOrZero(raw[4]),
    90  	}
    91  
    92  	return
    93  }