mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
* Improved error message when no config is set on startup * Change inccorect error wording * bump Bitfinex websocket orderbook return length to max * temporary fix of incorrect orderbook updates, limit to bid and ask len of 100, will be extended later if needed * Fixed issue in binance websocket that appended 0 volume bid/ask items * Fix panic when unmarshalling an empty pair from config * Add get pair asset method for exchange base Fix Bitmex orderbook stream Unbuffer Bitmex orderbook stream * force syncer to update ticker instead of fetch, which allows a stream * Fix websocket last price for coinbasepro * fix websocket ticker for coinut * Fix websocket orderbook stream Huobi * increase orderbook depth REST for Huobi * Fix websocket support and ensure data integrity * Fix time parsing issue after error checks * check error, only process enabled currency pairs, signal websocket data processing * expanded websocket functionality for okgroup * Add logic to not process zero length slice for orderbooks * fix websocket ticker only updating enabled and individual book updates * ZB fixes to order submission/retrieval/cancellation w/ general fixes * Quiet unnecessary warning * updated config entry values for REST and websocket (initial hack until I come up with a better solution for asset types) * Ch GetName function to field access modifyer & rm useless code * Add in error I missed * Nits addressed * some more fixes * Turned kraken default websocket to true and some small changes * fixes linter issues * Ensured okgroup books and sent update through to datahandler. Zb update as well. * Add test case to get asset type from pair * Add test for pairs unmarshal * Add testing and addressed nits * FIX linter issue * Addressed Gees nits * Thanks glorious spotter * more nitorinos * Addres even more nits * Add stringerino 4000 * Fix for panic cause by sort slice out of range, also nits addressed * fix linter issues * Changed from function to field access * Changed from function to field access * fix for orderbook update panic, removes quick fix - caused by sync item fetching through same protocol * Add new test and update random generator * pass in invalid string to future ob fetching, due to futures contract expire and a http 400 error is returned
194 lines
4.1 KiB
Go
194 lines
4.1 KiB
Go
package currency
|
|
|
|
import (
|
|
"math/rand"
|
|
"strings"
|
|
|
|
"github.com/thrasher-corp/gocryptotrader/common"
|
|
log "github.com/thrasher-corp/gocryptotrader/logger"
|
|
)
|
|
|
|
// NewPairsFromStrings takes in currency pair strings and returns a currency
|
|
// pair list
|
|
func NewPairsFromStrings(pairs []string) Pairs {
|
|
var ps Pairs
|
|
for _, p := range pairs {
|
|
if p == "" {
|
|
continue
|
|
}
|
|
|
|
ps = append(ps, NewPairFromString(p))
|
|
}
|
|
return ps
|
|
}
|
|
|
|
// Strings returns a slice of strings referring to each currency pair
|
|
func (p Pairs) Strings() []string {
|
|
var list []string
|
|
for i := range p {
|
|
list = append(list, p[i].String())
|
|
}
|
|
return list
|
|
}
|
|
|
|
// Join returns a comma separated list of currency pairs
|
|
func (p Pairs) Join() string {
|
|
return strings.Join(p.Strings(), ",")
|
|
}
|
|
|
|
// Format formats the pair list to the exchange format configuration
|
|
func (p Pairs) Format(delimiter, index string, uppercase bool) Pairs {
|
|
var pairs Pairs
|
|
for i := range p {
|
|
var formattedPair = Pair{
|
|
Delimiter: delimiter,
|
|
Base: p[i].Base,
|
|
Quote: p[i].Quote,
|
|
}
|
|
if index != "" {
|
|
newP, err := NewPairFromIndex(p[i].String(), index)
|
|
if err != nil {
|
|
log.Errorf(log.Global,
|
|
"failed to create NewPairFromIndex. Err: %s\n", err)
|
|
continue
|
|
}
|
|
formattedPair.Base = newP.Base
|
|
formattedPair.Quote = newP.Quote
|
|
}
|
|
|
|
if uppercase {
|
|
pairs = append(pairs, formattedPair.Upper())
|
|
} else {
|
|
pairs = append(pairs, formattedPair.Lower())
|
|
}
|
|
}
|
|
return pairs
|
|
}
|
|
|
|
// UnmarshalJSON comforms type to the umarshaler interface
|
|
func (p *Pairs) UnmarshalJSON(d []byte) error {
|
|
var pairs string
|
|
err := common.JSONDecode(d, &pairs)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// If no pairs enabled in config just continue
|
|
if pairs == "" {
|
|
return nil
|
|
}
|
|
|
|
var allThePairs Pairs
|
|
for _, data := range strings.Split(pairs, ",") {
|
|
allThePairs = append(allThePairs, NewPairFromString(data))
|
|
}
|
|
|
|
*p = allThePairs
|
|
return nil
|
|
}
|
|
|
|
// MarshalJSON conforms type to the marshaler interface
|
|
func (p Pairs) MarshalJSON() ([]byte, error) {
|
|
return common.JSONEncode(p.Join())
|
|
}
|
|
|
|
// Upper returns an upper formatted pair list
|
|
func (p Pairs) Upper() Pairs {
|
|
var upper Pairs
|
|
for i := range p {
|
|
upper = append(upper, p[i].Upper())
|
|
}
|
|
return upper
|
|
}
|
|
|
|
// Slice exposes the underlying type
|
|
func (p Pairs) Slice() []Pair {
|
|
return p
|
|
}
|
|
|
|
// Contains checks to see if a specified pair exists inside a currency pair
|
|
// array
|
|
func (p Pairs) Contains(check Pair, exact bool) bool {
|
|
for _, pair := range p.Slice() {
|
|
if exact {
|
|
if pair.Equal(check) {
|
|
return true
|
|
}
|
|
} else {
|
|
if pair.EqualIncludeReciprocal(check) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// RemovePairsByFilter checks to see if a pair contains a specific currency
|
|
// and removes it from the list of pairs
|
|
func (p Pairs) RemovePairsByFilter(filter Code) Pairs {
|
|
var pairs Pairs
|
|
for _, pair := range p.Slice() {
|
|
if pair.ContainsCurrency(filter) {
|
|
continue
|
|
}
|
|
pairs = append(pairs, pair)
|
|
}
|
|
return pairs
|
|
}
|
|
|
|
// Remove removes the specified pair from the list of pairs if it exists
|
|
func (p Pairs) Remove(pair Pair) Pairs {
|
|
var pairs Pairs
|
|
for x := range p {
|
|
if p[x].Equal(pair) {
|
|
continue
|
|
}
|
|
pairs = append(pairs, p[x])
|
|
}
|
|
return pairs
|
|
}
|
|
|
|
// Add adds a specified pair to the list of pairs if it doesn't exist
|
|
func (p Pairs) Add(pair Pair) Pairs {
|
|
if p.Contains(pair, true) {
|
|
return p
|
|
}
|
|
p = append(p, pair)
|
|
return p
|
|
}
|
|
|
|
// FindDifferences returns pairs which are new or have been removed
|
|
func (p Pairs) FindDifferences(pairs Pairs) (newPairs, removedPairs Pairs) {
|
|
for x := range pairs {
|
|
if pairs[x].String() == "" {
|
|
continue
|
|
}
|
|
if !p.Contains(pairs[x], true) {
|
|
newPairs = append(newPairs, pairs[x])
|
|
}
|
|
}
|
|
for _, oldPair := range p {
|
|
if oldPair.String() == "" {
|
|
continue
|
|
}
|
|
if !pairs.Contains(oldPair, true) {
|
|
removedPairs = append(removedPairs, oldPair)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// GetRandomPair returns a random pair from a list of pairs
|
|
func (p Pairs) GetRandomPair() Pair {
|
|
pairsLen := len(p)
|
|
|
|
if pairsLen == 0 {
|
|
return Pair{Base: NewCode(""), Quote: NewCode("")}
|
|
}
|
|
|
|
return p[rand.Intn(pairsLen)]
|
|
}
|
|
|
|
// Pairs defines a list of pairs
|
|
type Pairs []Pair
|