Link up orderbook websocket code, improve exchange test coverage and various other fixes

This commit is contained in:
Adrian Gallagher
2017-09-02 16:31:08 +10:00
parent 913c104d09
commit 87633c2142
34 changed files with 1215 additions and 354 deletions

View File

@@ -209,6 +209,11 @@ func TestBase64Decode(t *testing.T) {
expectedOutput, actualResult, err),
)
}
_, err = Base64Decode("-")
if err == nil {
t.Error("Test failed. Bad base64 string failed returned nil error")
}
}
func TestBase64Encode(t *testing.T) {
@@ -226,7 +231,7 @@ func TestBase64Encode(t *testing.T) {
func TestStringSliceDifference(t *testing.T) {
t.Parallel()
originalInputOne := []string{"hello"}
originalInputTwo := []string{"moto"}
originalInputTwo := []string{"hello", "moto"}
expectedOutput := []string{"hello moto"}
actualResult := StringSliceDifference(originalInputOne, originalInputTwo)
if reflect.DeepEqual(expectedOutput, actualResult) {
@@ -334,14 +339,17 @@ func TestReplaceString(t *testing.T) {
func TestRoundFloat(t *testing.T) {
t.Parallel()
originalInput := float64(1.4545445445)
precisionInput := 2
expectedOutput := float64(1.45)
actualResult := RoundFloat(originalInput, precisionInput)
if expectedOutput != actualResult {
t.Error(fmt.Sprintf(
"Test failed. Expected '%f'. Actual '%f'.", expectedOutput, actualResult),
)
// mapping of input vs expected result
testTable := map[float64]float64{
2.3232323: 2.32,
-2.3232323: -2.32,
}
for testInput, expectedOutput := range testTable {
actualOutput := RoundFloat(testInput, 2)
if actualOutput != expectedOutput {
t.Error(fmt.Sprintf("Test failed. RoundFloat Expected '%f'. Actual '%f'.",
expectedOutput, actualOutput))
}
}
}
@@ -650,6 +658,11 @@ func TestWriteFile(t *testing.T) {
if err != nil {
t.Errorf("Test failed. Common WriteFile error: %s", err)
}
err = WriteFile("", nil)
if err == nil {
t.Error("Test failed. Common WriteFile allowed bad path")
}
}
func TestRemoveFile(t *testing.T) {
@@ -672,9 +685,9 @@ func TestGetURIPath(t *testing.T) {
t.Parallel()
// mapping of input vs expected result
testTable := map[string]string{
"https://api.gdax.com/accounts": "/accounts",
"https://api.gdax.com/accounts?a=1&b=2": "/accounts?a=1&b=2",
"ht:tp:/invalidurl": "",
"https://api.gdax.com/accounts": "/accounts",
"https://api.gdax.com/accounts?a=1&b=2": "/accounts?a=1&b=2",
"http://www.google.com/accounts?!@#$%;^^": "",
}
for testInput, expectedOutput := range testTable {
actualOutput := GetURIPath(testInput)

View File

@@ -50,7 +50,6 @@ const (
maxCurrencyPairsPerRequest = 350
yahooYQLURL = "https://query.yahooapis.com/v1/public/yql?"
yahooDatabase = "store://datatables.org/alltableswithkeys"
yahooEnabled = false
fixerAPI = "http://api.fixer.io/latest"
// DefaultCurrencies has the default minimum of FIAT values
DefaultCurrencies = "USD,AUD,EUR,CNY"
@@ -69,6 +68,7 @@ var (
ErrCurrencyNotFound = errors.New("unable to find specified currency")
ErrQueryingYahoo = errors.New("unable to query Yahoo currency values")
ErrQueryingYahooZeroCount = errors.New("yahoo returned zero currency data")
yahooEnabled = false
)
// IsDefaultCurrency checks if the currency passed in matches the default
@@ -91,6 +91,7 @@ func IsDefaultCryptocurrency(currency string) bool {
func IsFiatCurrency(currency string) bool {
if BaseCurrencies == "" {
log.Println("IsFiatCurrency: BaseCurrencies string variable not populated")
return false
}
return common.StringContains(BaseCurrencies, common.StringToUpper(currency))
}
@@ -101,6 +102,7 @@ func IsCryptocurrency(currency string) bool {
log.Println(
"IsCryptocurrency: CryptoCurrencies string variable not populated",
)
return false
}
return common.StringContains(CryptoCurrencies, common.StringToUpper(currency))
}
@@ -313,6 +315,8 @@ func FetchYahooCurrencyData(currencyPairs []string) error {
return err
}
log.Printf("Currency recv: %s", resp)
yahooResp := YahooJSONResponse{}
err = common.JSONDecode([]byte(resp), &yahooResp)
if err != nil {
@@ -338,30 +342,5 @@ func QueryYahooCurrencyValues(currencies string) error {
"%d fiat currency pairs generated. Fetching Yahoo currency data (this may take a minute)..\n",
len(currencyPairs),
)
var err error
var pairs []string
index := 0
if len(currencyPairs) > maxCurrencyPairsPerRequest {
for index < len(currencyPairs) {
if len(currencyPairs)-index > maxCurrencyPairsPerRequest {
pairs = currencyPairs[index : index+maxCurrencyPairsPerRequest]
index += maxCurrencyPairsPerRequest
} else {
pairs = currencyPairs[index:]
index += (len(currencyPairs) - index)
}
err = FetchYahooCurrencyData(pairs)
if err != nil {
return err
}
}
} else {
pairs = currencyPairs[index:]
err = FetchYahooCurrencyData(pairs)
if err != nil {
return err
}
}
return nil
return FetchYahooCurrencyData(currencyPairs)
}

View File

@@ -58,6 +58,10 @@ func TestIsDefaultCryptocurrency(t *testing.T) {
func TestIsFiatCurrency(t *testing.T) {
t.Parallel()
if IsFiatCurrency("") {
t.Error("Test failed. TestIsFiatCurrency returned true on an empty string")
}
BaseCurrencies = "USD,AUD"
var str1, str2, str3 string = "BTC", "USD", "birds123"
@@ -81,6 +85,10 @@ func TestIsFiatCurrency(t *testing.T) {
func TestIsCryptocurrency(t *testing.T) {
t.Parallel()
if IsCryptocurrency("") {
t.Error("Test failed. TestIsCryptocurrency returned true on an empty string")
}
CryptoCurrencies = "BTC,LTC,DASH"
var str1, str2, str3 string = "USD", "BTC", "pterodactyl123"
@@ -256,25 +264,25 @@ func TestCheckAndAddCurrency(t *testing.T) {
}
func TestSeedCurrencyData(t *testing.T) {
currencyRequestDefault := ""
currencyRequestUSDAUD := "USD,AUD"
currencyRequestObtuse := "WigWham"
err := SeedCurrencyData(currencyRequestDefault)
if err != nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err, currencyRequestDefault,
)
}
err2 := SeedCurrencyData(currencyRequestUSDAUD)
if err2 != nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err2, currencyRequestUSDAUD,
)
}
if yahooEnabled {
currencyRequestDefault := ""
currencyRequestUSDAUD := "USD,AUD"
currencyRequestObtuse := "WigWham"
err := SeedCurrencyData(currencyRequestDefault)
if err != nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err, currencyRequestDefault,
)
}
err2 := SeedCurrencyData(currencyRequestUSDAUD)
if err2 != nil {
t.Errorf(
"Test Failed. SeedCurrencyData: Error %s with currency as %s.",
err2, currencyRequestUSDAUD,
)
}
err3 := SeedCurrencyData(currencyRequestObtuse)
if err3 == nil {
t.Errorf(
@@ -283,6 +291,12 @@ func TestSeedCurrencyData(t *testing.T) {
)
}
}
yahooEnabled = false
err := SeedCurrencyData("")
if err != nil {
t.Errorf("Test failed. SeedCurrencyData via Fixer. Error: %s", err)
}
}
func TestMakecurrencyPairs(t *testing.T) {
@@ -299,12 +313,10 @@ func TestMakecurrencyPairs(t *testing.T) {
}
func TestConvertCurrency(t *testing.T) {
fiatCurrencies := DefaultCurrencies
for _, currencyFrom := range common.SplitStrings(fiatCurrencies, ",") {
for _, currencyTo := range common.SplitStrings(fiatCurrencies, ",") {
if currencyFrom == currencyTo {
continue
} else {
if yahooEnabled {
fiatCurrencies := DefaultCurrencies
for _, currencyFrom := range common.SplitStrings(fiatCurrencies, ",") {
for _, currencyTo := range common.SplitStrings(fiatCurrencies, ",") {
floatyMcfloat, err := ConvertCurrency(1000, currencyFrom, currencyTo)
if err != nil {
t.Errorf(
@@ -323,6 +335,44 @@ func TestConvertCurrency(t *testing.T) {
}
}
}
yahooEnabled = false
_, err := ConvertCurrency(1000, "USD", "AUD")
if err != nil {
t.Errorf("Test failed. ConvertCurrency USD -> AUD. Error %s", err)
}
_, err = ConvertCurrency(1000, "AUD", "USD")
if err != nil {
t.Errorf("Test failed. ConvertCurrency AUD -> AUD. Error %s", err)
}
_, err = ConvertCurrency(1000, "CNY", "AUD")
if err != nil {
t.Errorf("Test failed. ConvertCurrency USD -> AUD. Error %s", err)
}
// Test non-existant currencies
_, err = ConvertCurrency(1000, "ASDF", "USD")
if err == nil {
t.Errorf("Test failed. ConvertCurrency non-existant currency -> USD. Error %s", err)
}
_, err = ConvertCurrency(1000, "USD", "ASDF")
if err == nil {
t.Errorf("Test failed. ConvertCurrency USD -> non-existant currency. Error %s", err)
}
_, err = ConvertCurrency(1000, "CNY", "UAHF")
if err == nil {
t.Errorf("Test failed. ConvertCurrency non-USD currency CNY -> non-existant currency. Error %s", err)
}
_, err = ConvertCurrency(1000, "UASF", "UAHF")
if err == nil {
t.Errorf("Test failed. ConvertCurrency non-existant currency -> non-existant currency. Error %s", err)
}
}
func TestFetchFixerCurrencyData(t *testing.T) {

View File

@@ -158,6 +158,20 @@ func TestNewCurrencyPairFromIndex(t *testing.T) {
actual, expected,
)
}
currency = "DOGEBTC"
pair = NewCurrencyPairFromIndex(currency, index)
pair.Delimiter = "-"
actual = pair.Pair()
expected = CurrencyItem("DOGE-BTC")
if actual != expected {
t.Errorf(
"Test failed. Pair(): %s was not equal to expected value: %s",
actual, expected,
)
}
}
func TestNewCurrencyPairFromString(t *testing.T) {

View File

@@ -29,7 +29,7 @@ func (a *Alphapoint) GetExchangeAccountInfo() (exchange.AccountInfo, error) {
}
// UpdateTicker updates and returns the ticker for a currency pair
func (a *Alphapoint) UpdateTicker(p pair.CurrencyPair) (ticker.Price, error) {
func (a *Alphapoint) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
var tickerPrice ticker.Price
tick, err := a.GetTicker(p.Pair().String())
if err != nil {
@@ -43,22 +43,22 @@ func (a *Alphapoint) UpdateTicker(p pair.CurrencyPair) (ticker.Price, error) {
tickerPrice.High = tick.High
tickerPrice.Volume = tick.Volume
tickerPrice.Last = tick.Last
ticker.ProcessTicker(a.GetName(), p, tickerPrice, ticker.Spot)
return ticker.GetTicker(a.Name, p, ticker.Spot)
ticker.ProcessTicker(a.GetName(), p, tickerPrice, assetType)
return ticker.GetTicker(a.Name, p, assetType)
}
// GetTickerPrice returns the ticker for a currency pair
func (a *Alphapoint) GetTickerPrice(p pair.CurrencyPair) (ticker.Price, error) {
tick, err := ticker.GetTicker(a.GetName(), p, ticker.Spot)
func (a *Alphapoint) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
tick, err := ticker.GetTicker(a.GetName(), p, assetType)
if err != nil {
return a.UpdateTicker(p)
return a.UpdateTicker(p, assetType)
}
return tick, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (a *Alphapoint) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (a *Alphapoint) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := a.GetOrderbook(p.Pair().String())
if err != nil {
return orderBook, err
@@ -66,23 +66,23 @@ func (a *Alphapoint) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBa
for x := range orderbookNew.Bids {
data := orderbookNew.Bids[x]
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: data.Quantity, Price: data.Price})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data.Quantity, Price: data.Price})
}
for x := range orderbookNew.Asks {
data := orderbookNew.Asks[x]
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: data.Quantity, Price: data.Price})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data.Quantity, Price: data.Price})
}
orderbook.ProcessOrderbook(a.GetName(), p, orderBook)
return orderbook.GetOrderbook(a.Name, p)
orderbook.ProcessOrderbook(a.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(a.Name, p, assetType)
}
// GetOrderbookEx returns the orderbook for a currency pair
func (a *Alphapoint) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(a.GetName(), p)
func (a *Alphapoint) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(a.GetName(), p, assetType)
if err == nil {
return a.UpdateOrderbook(p)
return a.UpdateOrderbook(p, assetType)
}
return ob, nil
}

View File

@@ -100,17 +100,17 @@ func (a *ANX) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Pric
}
// GetOrderbookEx returns the orderbook for a currency pair
func (a *ANX) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(a.GetName(), p)
func (a *ANX) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(a.GetName(), p, assetType)
if err == nil {
return a.UpdateOrderbook(p)
return a.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (a *ANX) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (a *ANX) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
return orderBook, nil
}

View File

@@ -67,32 +67,32 @@ func (b *Bitfinex) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker
}
// GetOrderbookEx returns the orderbook for a currency pair
func (b *Bitfinex) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p)
func (b *Bitfinex) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
if err == nil {
return b.UpdateOrderbook(p)
return b.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (b *Bitfinex) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (b *Bitfinex) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := b.GetOrderbook(p.Pair().String(), nil)
if err != nil {
return orderBook, err
}
for x := range orderbookNew.Asks {
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Price: orderbookNew.Asks[x].Price, Amount: orderbookNew.Asks[x].Amount})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Price: orderbookNew.Asks[x].Price, Amount: orderbookNew.Asks[x].Amount})
}
for x := range orderbookNew.Bids {
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Price: orderbookNew.Bids[x].Price, Amount: orderbookNew.Bids[x].Amount})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Price: orderbookNew.Bids[x].Price, Amount: orderbookNew.Bids[x].Amount})
}
orderbook.ProcessOrderbook(b.GetName(), p, orderBook)
return orderbook.GetOrderbook(b.Name, p)
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(b.Name, p, assetType)
}
// GetExchangeAccountInfo retrieves balances for all enabled currencies on the

View File

@@ -19,7 +19,8 @@ func TestRun(t *testing.T) {
func TestGetTickerPrice(t *testing.T) {
getTickerPrice := Bitfinex{}
_, err := getTickerPrice.GetTickerPrice(pair.NewCurrencyPair("BTC", "USD"), ticker.Spot)
_, err := getTickerPrice.GetTickerPrice(pair.NewCurrencyPair("BTC", "USD"),
ticker.Spot)
if err != nil {
t.Errorf("Test Failed - Bitfinex GetTickerPrice() error: %s", err)
}
@@ -27,7 +28,8 @@ func TestGetTickerPrice(t *testing.T) {
func TestGetOrderbookEx(t *testing.T) {
getOrderBookEx := Bitfinex{}
_, err := getOrderBookEx.GetOrderbookEx(pair.NewCurrencyPair("BTC", "USD"))
_, err := getOrderBookEx.GetOrderbookEx(pair.NewCurrencyPair("BTC", "USD"),
ticker.Spot)
if err != nil {
t.Errorf("Test Failed - Bitfinex GetOrderbookEx() error: %s", err)
}

View File

@@ -57,17 +57,17 @@ func (b *Bitstamp) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker
}
// GetOrderbookEx returns the orderbook for a currency pair
func (b *Bitstamp) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p)
func (b *Bitstamp) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
if err == nil {
return b.UpdateOrderbook(p)
return b.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (b *Bitstamp) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (b *Bitstamp) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := b.GetOrderbook(p.Pair().String())
if err != nil {
return orderBook, err
@@ -75,16 +75,16 @@ func (b *Bitstamp) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase
for x := range orderbookNew.Bids {
data := orderbookNew.Bids[x]
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: data.Amount, Price: data.Price})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data.Amount, Price: data.Price})
}
for x := range orderbookNew.Asks {
data := orderbookNew.Asks[x]
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: data.Amount, Price: data.Price})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data.Amount, Price: data.Price})
}
orderbook.ProcessOrderbook(b.GetName(), p, orderBook)
return orderbook.GetOrderbook(b.Name, p)
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(b.Name, p, assetType)
}
// GetExchangeAccountInfo retrieves balances for all enabled currencies for the

View File

@@ -100,17 +100,17 @@ func (b *Bittrex) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.
}
// GetOrderbookEx returns the orderbook for a currency pair
func (b *Bittrex) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p)
func (b *Bittrex) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
if err == nil {
return b.UpdateOrderbook(p)
return b.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (b *Bittrex) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (b *Bittrex) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := b.GetOrderbook(exchange.FormatExchangeCurrency(b.GetName(), p).String())
if err != nil {
return orderBook, err
@@ -118,7 +118,7 @@ func (b *Bittrex) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase,
for x := range orderbookNew.Buy {
orderBook.Bids = append(orderBook.Bids,
orderbook.OrderbookItem{
orderbook.Item{
Amount: orderbookNew.Buy[x].Quantity,
Price: orderbookNew.Buy[x].Rate,
},
@@ -127,13 +127,13 @@ func (b *Bittrex) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase,
for x := range orderbookNew.Sell {
orderBook.Asks = append(orderBook.Asks,
orderbook.OrderbookItem{
orderbook.Item{
Amount: orderbookNew.Sell[x].Quantity,
Price: orderbookNew.Sell[x].Rate,
},
)
}
orderbook.ProcessOrderbook(b.GetName(), p, orderBook)
return orderbook.GetOrderbook(b.Name, p)
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(b.Name, p, assetType)
}

View File

@@ -56,17 +56,17 @@ func (b *BTCC) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Pri
}
// GetOrderbookEx returns the orderbook for a currency pair
func (b *BTCC) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p)
func (b *BTCC) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
if err == nil {
return b.UpdateOrderbook(p)
return b.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (b *BTCC) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (b *BTCC) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := b.GetOrderBook(exchange.FormatExchangeCurrency(b.GetName(), p).String(), 100)
if err != nil {
return orderBook, err
@@ -74,16 +74,16 @@ func (b *BTCC) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, er
for x := range orderbookNew.Bids {
data := orderbookNew.Bids[x]
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Price: data[0], Amount: data[1]})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Price: data[0], Amount: data[1]})
}
for x := range orderbookNew.Asks {
data := orderbookNew.Asks[x]
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Price: data[0], Amount: data[1]})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Price: data[0], Amount: data[1]})
}
orderbook.ProcessOrderbook(b.GetName(), p, orderBook)
return orderbook.GetOrderbook(b.Name, p)
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(b.Name, p, assetType)
}
// GetExchangeAccountInfo : Retrieves balances for all enabled currencies for

View File

@@ -85,17 +85,17 @@ func (b *BTCE) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Pri
}
// GetOrderbookEx returns the orderbook for a currency pair
func (b *BTCE) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p)
func (b *BTCE) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
if err == nil {
return b.UpdateOrderbook(p)
return b.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (b *BTCE) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (b *BTCE) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := b.GetDepth(exchange.FormatExchangeCurrency(b.Name, p).String())
if err != nil {
return orderBook, err
@@ -103,16 +103,16 @@ func (b *BTCE) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, er
for x := range orderbookNew.Bids {
data := orderbookNew.Bids[x]
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Price: data[0], Amount: data[1]})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Price: data[0], Amount: data[1]})
}
for x := range orderbookNew.Asks {
data := orderbookNew.Asks[x]
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Price: data[0], Amount: data[1]})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Price: data[0], Amount: data[1]})
}
orderbook.ProcessOrderbook(b.GetName(), p, orderBook)
return orderbook.GetOrderbook(b.Name, p)
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(b.Name, p, assetType)
}
// GetExchangeAccountInfo retrieves balances for all enabled currencies for the

View File

@@ -75,17 +75,17 @@ func (b *BTCMarkets) GetTickerPrice(p pair.CurrencyPair, assetType string) (tick
}
// GetOrderbookEx returns orderbook base on the currency pair
func (b *BTCMarkets) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p)
func (b *BTCMarkets) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
if err == nil {
return b.UpdateOrderbook(p)
return b.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (b *BTCMarkets) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (b *BTCMarkets) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := b.GetOrderbook(p.GetFirstCurrency().String())
if err != nil {
return orderBook, err
@@ -93,16 +93,16 @@ func (b *BTCMarkets) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBa
for x := range orderbookNew.Bids {
data := orderbookNew.Bids[x]
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: data[1], Price: data[0]})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data[1], Price: data[0]})
}
for x := range orderbookNew.Asks {
data := orderbookNew.Asks[x]
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: data[1], Price: data[0]})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data[1], Price: data[0]})
}
orderbook.ProcessOrderbook(b.GetName(), p, orderBook)
return orderbook.GetOrderbook(b.Name, p)
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(b.Name, p, assetType)
}
// GetExchangeAccountInfo retrieves balances for all enabled currencies for the

View File

@@ -96,30 +96,30 @@ func (c *COINUT) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.P
}
// GetOrderbookEx returns orderbook base on the currency pair
func (c *COINUT) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(c.GetName(), p)
func (c *COINUT) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(c.GetName(), p, assetType)
if err == nil {
return c.UpdateOrderbook(p)
return c.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (c *COINUT) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (c *COINUT) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := c.GetInstrumentOrderbook(c.InstrumentMap[p.Pair().String()], 200)
if err != nil {
return orderBook, err
}
for x := range orderbookNew.Buy {
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: orderbookNew.Buy[x].Quantity, Price: orderbookNew.Buy[x].Price})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: orderbookNew.Buy[x].Quantity, Price: orderbookNew.Buy[x].Price})
}
for x := range orderbookNew.Sell {
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: orderbookNew.Sell[x].Quantity, Price: orderbookNew.Sell[x].Price})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: orderbookNew.Sell[x].Quantity, Price: orderbookNew.Sell[x].Price})
}
orderbook.ProcessOrderbook(c.GetName(), p, orderBook)
return orderbook.GetOrderbook(c.Name, p)
orderbook.ProcessOrderbook(c.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(c.Name, p, assetType)
}

View File

@@ -66,8 +66,8 @@ type IBotExchange interface {
IsEnabled() bool
GetTickerPrice(currency pair.CurrencyPair, assetType string) (ticker.Price, error)
UpdateTicker(currency pair.CurrencyPair, assetType string) (ticker.Price, error)
GetOrderbookEx(currency pair.CurrencyPair) (orderbook.OrderbookBase, error)
UpdateOrderbook(currency pair.CurrencyPair) (orderbook.OrderbookBase, error)
GetOrderbookEx(currency pair.CurrencyPair, assetType string) (orderbook.Base, error)
UpdateOrderbook(currency pair.CurrencyPair, assetType string) (orderbook.Base, error)
GetEnabledCurrencies() []pair.CurrencyPair
GetExchangeAccountInfo() (AccountInfo, error)
GetAuthenticatedAPISupport() bool

View File

@@ -3,10 +3,157 @@ package exchange
import (
"testing"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/pair"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
)
func TestSetAssetTypes(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig(config.ConfigTestFile)
if err != nil {
t.Fatalf("Test failed. TestSetAssetTypes failed to load config file. Error: %s", err)
}
b := Base{
Name: "TESTNAME",
}
err = b.SetAssetTypes()
if err == nil {
t.Fatal("Test failed. TestSetAssetTypes returned nil error for a non-existant exchange")
}
b.Name = "ANX"
err = b.SetAssetTypes()
if err != nil {
t.Fatalf("Test failed. TestSetAssetTypes. Error %s", err)
}
exch, err := cfg.GetExchangeConfig(b.Name)
if err != nil {
t.Fatalf("Test failed. TestSetAssetTypes load config failed. Error %s", err)
}
exch.AssetTypes = ""
err = cfg.UpdateExchangeConfig(exch)
if err != nil {
t.Fatalf("Test failed. TestSetAssetTypes update config failed. Error %s", err)
}
exch, err = cfg.GetExchangeConfig(b.Name)
if err != nil {
t.Fatalf("Test failed. TestSetAssetTypes load config failed. Error %s", err)
}
if exch.AssetTypes != "" {
t.Fatal("Test failed. TestSetAssetTypes assetTypes != ''")
}
err = b.SetAssetTypes()
if err != nil {
t.Fatalf("Test failed. TestSetAssetTypes. Error %s", err)
}
if !common.DataContains(b.AssetTypes, ticker.Spot) {
t.Fatal("Test failed. TestSetAssetTypes assetTypes is not set")
}
}
func TestGetExchangeAssetTypes(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig(config.ConfigTestFile)
if err != nil {
t.Fatalf("Failed to load config file. Error: %s", err)
}
result, err := GetExchangeAssetTypes("Bitfinex")
if err != nil {
t.Fatal("Test failed. Unable to obtain Bitfinex asset types")
}
if !common.DataContains(result, ticker.Spot) {
t.Fatal("Test failed. Bitfinex does not contain default asset type 'SPOT'")
}
_, err = GetExchangeAssetTypes("non-existant-exchange")
if err == nil {
t.Fatal("Test failed. Got asset types for non-existant exchange")
}
}
func TestSetCurrencyPairFormat(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig(config.ConfigTestFile)
if err != nil {
t.Fatalf("Test failed. TestSetCurrencyPairFormat failed to load config file. Error: %s", err)
}
b := Base{
Name: "TESTNAME",
}
err = b.SetCurrencyPairFormat()
if err == nil {
t.Fatal("Test failed. TestSetCurrencyPairFormat returned nil error for a non-existant exchange")
}
b.Name = "ANX"
err = b.SetCurrencyPairFormat()
if err != nil {
t.Fatalf("Test failed. TestSetCurrencyPairFormat. Error %s", err)
}
exch, err := cfg.GetExchangeConfig(b.Name)
if err != nil {
t.Fatalf("Test failed. TestSetCurrencyPairFormat load config failed. Error %s", err)
}
exch.ConfigCurrencyPairFormat = nil
exch.RequestCurrencyPairFormat = nil
err = cfg.UpdateExchangeConfig(exch)
if err != nil {
t.Fatalf("Test failed. TestSetCurrencyPairFormat update config failed. Error %s", err)
}
exch, err = cfg.GetExchangeConfig(b.Name)
if err != nil {
t.Fatalf("Test failed. TestSetCurrencyPairFormat load config failed. Error %s", err)
}
if exch.ConfigCurrencyPairFormat != nil && exch.RequestCurrencyPairFormat != nil {
t.Fatal("Test failed. TestSetCurrencyPairFormat exch values are not nil")
}
err = b.SetCurrencyPairFormat()
if err != nil {
t.Fatalf("Test failed. TestSetCurrencyPairFormat. Error %s", err)
}
if b.ConfigCurrencyPairFormat.Delimiter != "" &&
b.ConfigCurrencyPairFormat.Index != "BTC" &&
b.ConfigCurrencyPairFormat.Uppercase {
t.Fatal("Test failed. TestSetCurrencyPairFormat ConfigCurrencyPairFormat values are incorrect")
}
if b.RequestCurrencyPairFormat.Delimiter != "" &&
b.RequestCurrencyPairFormat.Index != "BTC" &&
b.RequestCurrencyPairFormat.Uppercase {
t.Fatal("Test failed. TestSetCurrencyPairFormat RequestCurrencyPairFormat values are incorrect")
}
}
func TestGetAuthenticatedAPISupport(t *testing.T) {
base := Base{
AuthenticatedAPISupport: false,
}
if base.GetAuthenticatedAPISupport() {
t.Fatal("Test failed. TestGetAuthenticatedAPISupport returned true when it should of been false.")
}
}
func TestGetName(t *testing.T) {
GetName := Base{
Name: "TESTNAME",
@@ -18,51 +165,132 @@ func TestGetName(t *testing.T) {
}
}
func TestSetCurrencyPairFormat(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig(config.ConfigTestFile)
if err != nil {
t.Fatalf("Failed to load config file. Error: %s", err)
}
exch, err := cfg.GetExchangeConfig("GDAX")
if err != nil {
t.Fatalf("Failed to load GDAX exchange config. Error: %s", err)
}
exch.RequestCurrencyPairFormat = nil
exch.ConfigCurrencyPairFormat = nil
err = cfg.UpdateExchangeConfig(exch)
if err != nil {
t.Fatalf("Failed to update GDAX config. Error: %s", err)
}
// to-do
}
func TestGetEnabledCurrencies(t *testing.T) {
enabledPairs := []string{"BTCUSD", "BTCAUD", "LTCUSD", "LTCAUD"}
GetEnabledCurrencies := Base{
Name: "TESTNAME",
EnabledPairs: enabledPairs,
b := Base{
Name: "TESTNAME",
}
enCurr := GetEnabledCurrencies.GetEnabledCurrencies()
if enCurr[0].Pair().String() != "BTCUSD" {
t.Error("Test Failed - Exchange GetEnabledCurrencies() incorrect string")
b.EnabledPairs = []string{"BTC-USD"}
format := config.CurrencyPairFormatConfig{
Delimiter: "-",
Index: "",
}
b.RequestCurrencyPairFormat = format
b.ConfigCurrencyPairFormat = format
c := b.GetEnabledCurrencies()
if c[0].Pair().String() != "BTC-USD" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
format.Delimiter = "~"
b.RequestCurrencyPairFormat = format
c = b.GetEnabledCurrencies()
if c[0].Pair().String() != "BTC-USD" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
format.Delimiter = ""
b.ConfigCurrencyPairFormat = format
c = b.GetEnabledCurrencies()
if c[0].Pair().String() != "BTC-USD" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
b.EnabledPairs = []string{"BTCDOGE"}
format.Index = "BTC"
b.ConfigCurrencyPairFormat = format
c = b.GetEnabledCurrencies()
if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "DOGE" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
b.EnabledPairs = []string{"BTC_USD"}
b.RequestCurrencyPairFormat.Delimiter = ""
b.ConfigCurrencyPairFormat.Delimiter = "_"
c = b.GetEnabledCurrencies()
if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "USD" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
b.EnabledPairs = []string{"BTCDOGE"}
b.RequestCurrencyPairFormat.Delimiter = ""
b.ConfigCurrencyPairFormat.Delimiter = ""
b.ConfigCurrencyPairFormat.Index = "BTC"
c = b.GetEnabledCurrencies()
if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "DOGE" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
b.EnabledPairs = []string{"BTCUSD"}
b.ConfigCurrencyPairFormat.Index = ""
c = b.GetEnabledCurrencies()
if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "USD" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
}
func TestGetAvailableCurrencies(t *testing.T) {
availablePairs := []string{"BTCUSD", "BTCAUD", "LTCUSD", "LTCAUD"}
GetEnabledCurrencies := Base{
Name: "TESTNAME",
AvailablePairs: availablePairs,
b := Base{
Name: "TESTNAME",
}
enCurr := GetEnabledCurrencies.GetAvailableCurrencies()
if enCurr[0].Pair().String() != "BTCUSD" {
b.AvailablePairs = []string{"BTC-USD"}
format := config.CurrencyPairFormatConfig{
Delimiter: "-",
Index: "",
}
b.RequestCurrencyPairFormat = format
b.ConfigCurrencyPairFormat = format
c := b.GetAvailableCurrencies()
if c[0].Pair().String() != "BTC-USD" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
format.Delimiter = "~"
b.RequestCurrencyPairFormat = format
c = b.GetAvailableCurrencies()
if c[0].Pair().String() != "BTC-USD" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
format.Delimiter = ""
b.ConfigCurrencyPairFormat = format
c = b.GetAvailableCurrencies()
if c[0].Pair().String() != "BTC-USD" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
b.AvailablePairs = []string{"BTCDOGE"}
format.Index = "BTC"
b.ConfigCurrencyPairFormat = format
c = b.GetAvailableCurrencies()
if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "DOGE" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
b.AvailablePairs = []string{"BTC_USD"}
b.RequestCurrencyPairFormat.Delimiter = ""
b.ConfigCurrencyPairFormat.Delimiter = "_"
c = b.GetAvailableCurrencies()
if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "USD" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
b.AvailablePairs = []string{"BTCDOGE"}
b.RequestCurrencyPairFormat.Delimiter = ""
b.ConfigCurrencyPairFormat.Delimiter = ""
b.ConfigCurrencyPairFormat.Index = "BTC"
c = b.GetAvailableCurrencies()
if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "DOGE" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
b.AvailablePairs = []string{"BTCUSD"}
b.ConfigCurrencyPairFormat.Index = ""
c = b.GetAvailableCurrencies()
if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "USD" {
t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string")
}
}
@@ -89,6 +317,14 @@ func TestGetExchangeFormatCurrencySeperator(t *testing.T) {
t.Errorf("Test failed - TestGetExchangeFormatCurrencySeperator expected %v != actual %v",
expected, actual)
}
expected = false
actual = GetExchangeFormatCurrencySeperator("blah")
if expected != actual {
t.Errorf("Test failed - TestGetExchangeFormatCurrencySeperator expected %v != actual %v",
expected, actual)
}
}
func TestGetAndFormatExchangeCurrencies(t *testing.T) {
@@ -112,6 +348,11 @@ func TestGetAndFormatExchangeCurrencies(t *testing.T) {
t.Errorf("Test failed - Exchange TestGetAndFormatExchangeCurrencies %s != %s",
actual, expected)
}
_, err = GetAndFormatExchangeCurrencies("non-existant", pairs)
if err == nil {
t.Errorf("Test failed - Exchange TestGetAndFormatExchangeCurrencies returned nil error on non-existant exchange")
}
}
func TestFormatExchangeCurrency(t *testing.T) {
@@ -193,33 +434,77 @@ func TestSetAPIKeys(t *testing.T) {
func TestUpdateEnabledCurrencies(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig(config.ConfigTestFile)
UAC := Base{Name: "ANX"}
enabledCurrencies := []string{"ltc", "btc", "usd", "aud"}
if err != nil {
t.Error(
"Test Failed - Exchange UpdateEnabledCurrencies() did not set correct values",
)
t.Fatal("Test failed. TestUpdateEnabledCurrencies failed to load config")
}
err2 := UAC.UpdateEnabledCurrencies(enabledCurrencies, false)
if err2 != nil {
t.Errorf("Test Failed - Exchange UpdateEnabledCurrencies() error: %s", err2)
UAC := Base{Name: "ANX"}
exchangeProducts := []string{"ltc", "btc", "usd", "aud"}
// Test updating exchange products for an exchange which doesn't exist
UAC.Name = "Blah"
err = UAC.UpdateEnabledCurrencies(exchangeProducts, false)
if err == nil {
t.Errorf("Test Failed - Exchange TestUpdateEnabledCurrencies succeeded on an exchange which doesn't exist")
}
// Test updating exchange products
UAC.Name = "ANX"
err = UAC.UpdateEnabledCurrencies(exchangeProducts, false)
if err != nil {
t.Errorf("Test Failed - Exchange TestUpdateEnabledCurrencies error: %s", err)
}
// Test updating the same new products, diff should be 0
UAC.Name = "ANX"
err = UAC.UpdateEnabledCurrencies(exchangeProducts, false)
if err != nil {
t.Errorf("Test Failed - Exchange TestUpdateEnabledCurrencies error: %s", err)
}
// Test force updating to only one product
exchangeProducts = []string{"btc"}
err = UAC.UpdateEnabledCurrencies(exchangeProducts, true)
if err != nil {
t.Errorf("Test Failed - Forced Exchange TestUpdateEnabledCurrencies error: %s", err)
}
}
func TestUpdateAvailableCurrencies(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig(config.ConfigTestFile)
if err != nil {
t.Fatal("Test failed. TestUpdateAvailableCurrencies failed to load config")
}
UAC := Base{Name: "ANX"}
exchangeProducts := []string{"ltc", "btc", "usd", "aud"}
if err != nil {
t.Error(
"Test Failed - Exchange UpdateAvailableCurrencies() did not set correct values",
)
// Test updating exchange products for an exchange which doesn't exist
UAC.Name = "Blah"
err = UAC.UpdateAvailableCurrencies(exchangeProducts, false)
if err == nil {
t.Errorf("Test Failed - Exchange UpdateAvailableCurrencies() succeeded on an exchange which doesn't exist")
}
err2 := UAC.UpdateAvailableCurrencies(exchangeProducts, false)
if err2 != nil {
t.Errorf("Test Failed - Exchange UpdateAvailableCurrencies() error: %s", err2)
// Test updating exchange products
UAC.Name = "ANX"
err = UAC.UpdateAvailableCurrencies(exchangeProducts, false)
if err != nil {
t.Errorf("Test Failed - Exchange UpdateAvailableCurrencies() error: %s", err)
}
// Test updating the same new products, diff should be 0
UAC.Name = "ANX"
err = UAC.UpdateAvailableCurrencies(exchangeProducts, false)
if err != nil {
t.Errorf("Test Failed - Exchange UpdateAvailableCurrencies() error: %s", err)
}
// Test force updating to only one product
exchangeProducts = []string{"btc"}
err = UAC.UpdateAvailableCurrencies(exchangeProducts, true)
if err != nil {
t.Errorf("Test Failed - Forced Exchange UpdateAvailableCurrencies() error: %s", err)
}
}

View File

@@ -97,17 +97,17 @@ func (g *GDAX) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Pri
}
// GetOrderbookEx returns orderbook base on the currency pair
func (g *GDAX) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(g.GetName(), p)
func (g *GDAX) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(g.GetName(), p, assetType)
if err == nil {
return g.UpdateOrderbook(p)
return g.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (g *GDAX) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (g *GDAX) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := g.GetOrderbook(exchange.FormatExchangeCurrency(g.Name, p).String(), 2)
if err != nil {
return orderBook, err
@@ -116,13 +116,13 @@ func (g *GDAX) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, er
obNew := orderbookNew.(GDAXOrderbookL1L2)
for x := range obNew.Bids {
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: obNew.Bids[x].Amount, Price: obNew.Bids[x].Price})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: obNew.Bids[x].Amount, Price: obNew.Bids[x].Price})
}
for x := range obNew.Asks {
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: obNew.Bids[x].Amount, Price: obNew.Bids[x].Price})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: obNew.Bids[x].Amount, Price: obNew.Bids[x].Price})
}
orderbook.ProcessOrderbook(g.GetName(), p, orderBook)
return orderbook.GetOrderbook(g.Name, p)
orderbook.ProcessOrderbook(g.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(g.Name, p, assetType)
}

View File

@@ -78,30 +78,30 @@ func (g *Gemini) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.P
}
// GetOrderbookEx returns orderbook base on the currency pair
func (g *Gemini) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(g.GetName(), p)
func (g *Gemini) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(g.GetName(), p, assetType)
if err == nil {
return g.UpdateOrderbook(p)
return g.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (g *Gemini) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (g *Gemini) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := g.GetOrderbook(p.Pair().String(), url.Values{})
if err != nil {
return orderBook, err
}
for x := range orderbookNew.Bids {
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: orderbookNew.Bids[x].Amount, Price: orderbookNew.Bids[x].Price})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: orderbookNew.Bids[x].Amount, Price: orderbookNew.Bids[x].Price})
}
for x := range orderbookNew.Asks {
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: orderbookNew.Asks[x].Amount, Price: orderbookNew.Asks[x].Price})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: orderbookNew.Asks[x].Amount, Price: orderbookNew.Asks[x].Price})
}
orderbook.ProcessOrderbook(g.GetName(), p, orderBook)
return orderbook.GetOrderbook(g.Name, p)
orderbook.ProcessOrderbook(g.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(g.Name, p, assetType)
}

View File

@@ -56,17 +56,17 @@ func (h *HUOBI) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Pr
}
// GetOrderbookEx returns orderbook base on the currency pair
func (h *HUOBI) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(h.GetName(), p)
func (h *HUOBI) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(h.GetName(), p, assetType)
if err == nil {
return h.UpdateOrderbook(p)
return h.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (h *HUOBI) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (h *HUOBI) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := h.GetOrderBook(p.GetFirstCurrency().Lower().String())
if err != nil {
return orderBook, err
@@ -74,16 +74,16 @@ func (h *HUOBI) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, e
for x := range orderbookNew.Bids {
data := orderbookNew.Bids[x]
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: data[1], Price: data[0]})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data[1], Price: data[0]})
}
for x := range orderbookNew.Asks {
data := orderbookNew.Asks[x]
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: data[1], Price: data[0]})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data[1], Price: data[0]})
}
orderbook.ProcessOrderbook(h.GetName(), p, orderBook)
return orderbook.GetOrderbook(h.Name, p)
orderbook.ProcessOrderbook(h.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(h.Name, p, assetType)
}
//GetExchangeAccountInfo retrieves balances for all enabled currencies for the

View File

@@ -53,17 +53,17 @@ func (i *ItBit) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Pr
}
// GetOrderbookEx returns orderbook base on the currency pair
func (i *ItBit) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(i.GetName(), p)
func (i *ItBit) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(i.GetName(), p, assetType)
if err == nil {
return i.UpdateOrderbook(p)
return i.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (i *ItBit) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (i *ItBit) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := i.GetOrderbook(exchange.FormatExchangeCurrency(i.Name,
p).String())
if err != nil {
@@ -80,7 +80,7 @@ func (i *ItBit) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, e
if err != nil {
log.Println(err)
}
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: amount, Price: price})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: amount, Price: price})
}
for x := range orderbookNew.Asks {
@@ -93,11 +93,11 @@ func (i *ItBit) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, e
if err != nil {
log.Println(err)
}
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: amount, Price: price})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: amount, Price: price})
}
orderbook.ProcessOrderbook(i.GetName(), p, orderBook)
return orderbook.GetOrderbook(i.Name, p)
orderbook.ProcessOrderbook(i.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(i.Name, p, assetType)
}
// GetExchangeAccountInfo retrieves balances for all enabled currencies for the

View File

@@ -78,32 +78,32 @@ func (k *Kraken) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.P
}
// GetOrderbookEx returns orderbook base on the currency pair
func (k *Kraken) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(k.GetName(), p)
func (k *Kraken) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(k.GetName(), p, assetType)
if err == nil {
return k.UpdateOrderbook(p)
return k.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (k *Kraken) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (k *Kraken) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := k.GetDepth(exchange.FormatExchangeCurrency(k.GetName(), p).String())
if err != nil {
return orderBook, err
}
for x := range orderbookNew.Bids {
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: orderbookNew.Bids[x].Amount, Price: orderbookNew.Bids[x].Price})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: orderbookNew.Bids[x].Amount, Price: orderbookNew.Bids[x].Price})
}
for x := range orderbookNew.Asks {
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: orderbookNew.Asks[x].Amount, Price: orderbookNew.Asks[x].Price})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: orderbookNew.Asks[x].Amount, Price: orderbookNew.Asks[x].Price})
}
orderbook.ProcessOrderbook(k.GetName(), p, orderBook)
return orderbook.GetOrderbook(k.Name, p)
orderbook.ProcessOrderbook(k.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(k.Name, p, assetType)
}
// GetExchangeAccountInfo retrieves balances for all enabled currencies for the

View File

@@ -56,32 +56,32 @@ func (l *LakeBTC) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.
}
// GetOrderbookEx returns orderbook base on the currency pair
func (l *LakeBTC) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(l.GetName(), p)
func (l *LakeBTC) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(l.GetName(), p, assetType)
if err == nil {
return l.UpdateOrderbook(p)
return l.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (l *LakeBTC) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (l *LakeBTC) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := l.GetOrderBook(p.Pair().String())
if err != nil {
return orderBook, err
}
for x := range orderbookNew.Bids {
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: orderbookNew.Bids[x].Amount, Price: orderbookNew.Bids[x].Price})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: orderbookNew.Bids[x].Amount, Price: orderbookNew.Bids[x].Price})
}
for x := range orderbookNew.Asks {
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: orderbookNew.Asks[x].Amount, Price: orderbookNew.Asks[x].Price})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: orderbookNew.Asks[x].Amount, Price: orderbookNew.Asks[x].Price})
}
orderbook.ProcessOrderbook(l.GetName(), p, orderBook)
return orderbook.GetOrderbook(l.Name, p)
orderbook.ProcessOrderbook(l.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(l.Name, p, assetType)
}
// GetExchangeAccountInfo retrieves balances for all enabled currencies for the

View File

@@ -75,17 +75,17 @@ func (l *Liqui) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Pr
}
// GetOrderbookEx returns orderbook base on the currency pair
func (l *Liqui) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(l.Name, p)
func (l *Liqui) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(l.Name, p, assetType)
if err == nil {
return l.UpdateOrderbook(p)
return l.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (l *Liqui) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (l *Liqui) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := l.GetDepth(exchange.FormatExchangeCurrency(l.Name, p).String())
if err != nil {
return orderBook, err
@@ -93,16 +93,16 @@ func (l *Liqui) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, e
for x := range orderbookNew.Bids {
data := orderbookNew.Bids[x]
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: data[1], Price: data[0]})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data[1], Price: data[0]})
}
for x := range orderbookNew.Asks {
data := orderbookNew.Asks[x]
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: data[1], Price: data[0]})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data[1], Price: data[0]})
}
orderbook.ProcessOrderbook(l.Name, p, orderBook)
return orderbook.GetOrderbook(l.Name, p)
orderbook.ProcessOrderbook(l.Name, p, orderBook, assetType)
return orderbook.GetOrderbook(l.Name, p, assetType)
}
// GetExchangeAccountInfo retrieves balances for all enabled currencies for the

View File

@@ -52,17 +52,17 @@ func (l *LocalBitcoins) GetTickerPrice(p pair.CurrencyPair, assetType string) (t
}
// GetOrderbookEx returns orderbook base on the currency pair
func (l *LocalBitcoins) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(l.GetName(), p)
func (l *LocalBitcoins) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(l.GetName(), p, assetType)
if err == nil {
return l.UpdateOrderbook(p)
return l.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (l *LocalBitcoins) UpdateOrderbook(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (l *LocalBitcoins) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := l.GetOrderbook(p.GetSecondCurrency().String())
if err != nil {
return orderBook, err
@@ -70,16 +70,16 @@ func (l *LocalBitcoins) UpdateOrderbook(p pair.CurrencyPair) (orderbook.Orderboo
for x := range orderbookNew.Bids {
data := orderbookNew.Bids[x]
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: data.Amount, Price: data.Price})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data.Amount, Price: data.Price})
}
for x := range orderbookNew.Asks {
data := orderbookNew.Asks[x]
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: data.Amount, Price: data.Price})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data.Amount, Price: data.Price})
}
orderbook.ProcessOrderbook(l.GetName(), p, orderBook)
return orderbook.GetOrderbook(l.Name, p)
orderbook.ProcessOrderbook(l.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(l.Name, p, assetType)
}
// GetExchangeAccountInfo retrieves balances for all enabled currencies for the

View File

@@ -74,17 +74,17 @@ func (o *OKCoin) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.P
}
// GetOrderbookEx returns orderbook base on the currency pair
func (o *OKCoin) GetOrderbookEx(currency pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(o.GetName(), currency)
func (o *OKCoin) GetOrderbookEx(currency pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(o.GetName(), currency, assetType)
if err == nil {
return o.UpdateOrderbook(currency)
return o.UpdateOrderbook(currency, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (o *OKCoin) UpdateOrderbook(currency pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (o *OKCoin) UpdateOrderbook(currency pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := o.GetOrderBook(exchange.FormatExchangeCurrency(o.Name, currency).String(), 200, false)
if err != nil {
return orderBook, err
@@ -92,16 +92,16 @@ func (o *OKCoin) UpdateOrderbook(currency pair.CurrencyPair) (orderbook.Orderboo
for x := range orderbookNew.Bids {
data := orderbookNew.Bids[x]
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: data[1], Price: data[0]})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data[1], Price: data[0]})
}
for x := range orderbookNew.Asks {
data := orderbookNew.Asks[x]
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: data[1], Price: data[0]})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data[1], Price: data[0]})
}
orderbook.ProcessOrderbook(o.GetName(), currency, orderBook)
return orderbook.GetOrderbook(o.Name, currency)
orderbook.ProcessOrderbook(o.GetName(), currency, orderBook, assetType)
return orderbook.GetOrderbook(o.Name, currency, assetType)
}
// GetExchangeAccountInfo retrieves balances for all enabled currencies for the

View File

@@ -7,33 +7,44 @@ import (
"github.com/thrasher-/gocryptotrader/currency/pair"
)
var (
// Const values for orderbook package
const (
ErrOrderbookForExchangeNotFound = "Ticker for exchange does not exist."
ErrPrimaryCurrencyNotFound = "Error primary currency for orderbook not found."
ErrSecondaryCurrencyNotFound = "Error secondary currency for orderbook not found."
Spot = "SPOT"
)
// Vars for the orderbook package
var (
Orderbooks []Orderbook
)
type OrderbookItem struct {
// Item stores the amount and price values
type Item struct {
Amount float64
Price float64
}
type OrderbookBase struct {
// Base holds the fields for the orderbook base
type Base struct {
Pair pair.CurrencyPair `json:"pair"`
CurrencyPair string `json:"CurrencyPair"`
Bids []OrderbookItem `json:"bids"`
Asks []OrderbookItem `json:"asks"`
Bids []Item `json:"bids"`
Asks []Item `json:"asks"`
LastUpdated time.Time `json:"last_updated"`
}
// Orderbook holds the orderbook information for a currency pair and type
type Orderbook struct {
Orderbook map[pair.CurrencyItem]map[pair.CurrencyItem]OrderbookBase
Orderbook map[pair.CurrencyItem]map[pair.CurrencyItem]map[string]Base
ExchangeName string
}
func (o *OrderbookBase) CalculateTotalBids() (float64, float64) {
// CalculateTotalBids returns the total amount of bids and the total orderbook
// bids value
func (o *Base) CalculateTotalBids() (float64, float64) {
amountCollated := float64(0)
total := float64(0)
for _, x := range o.Bids {
@@ -43,7 +54,9 @@ func (o *OrderbookBase) CalculateTotalBids() (float64, float64) {
return amountCollated, total
}
func (o *OrderbookBase) CalculateTotalAsks() (float64, float64) {
// CalculateTotalAsks returns the total amount of asks and the total orderbook
// asks value
func (o *Base) CalculateTotalAsks() (float64, float64) {
amountCollated := float64(0)
total := float64(0)
for _, x := range o.Asks {
@@ -53,29 +66,33 @@ func (o *OrderbookBase) CalculateTotalAsks() (float64, float64) {
return amountCollated, total
}
func (o *OrderbookBase) Update(Bids, Asks []OrderbookItem) {
// Update updates the bids and asks
func (o *Base) Update(Bids, Asks []Item) {
o.Bids = Bids
o.Asks = Asks
o.LastUpdated = time.Now()
}
func GetOrderbook(exchange string, p pair.CurrencyPair) (OrderbookBase, error) {
// GetOrderbook checks and returns the orderbook given an exchange name and
// currency pair if it exists
func GetOrderbook(exchange string, p pair.CurrencyPair, orderbookType string) (Base, error) {
orderbook, err := GetOrderbookByExchange(exchange)
if err != nil {
return OrderbookBase{}, err
return Base{}, err
}
if !FirstCurrencyExists(exchange, p.GetFirstCurrency()) {
return OrderbookBase{}, errors.New(ErrPrimaryCurrencyNotFound)
return Base{}, errors.New(ErrPrimaryCurrencyNotFound)
}
if !SecondCurrencyExists(exchange, p) {
return OrderbookBase{}, errors.New(ErrSecondaryCurrencyNotFound)
return Base{}, errors.New(ErrSecondaryCurrencyNotFound)
}
return orderbook.Orderbook[p.GetFirstCurrency()][p.GetSecondCurrency()], nil
return orderbook.Orderbook[p.GetFirstCurrency()][p.GetSecondCurrency()][orderbookType], nil
}
// GetOrderbookByExchange returns an exchange orderbook
func GetOrderbookByExchange(exchange string) (*Orderbook, error) {
for _, y := range Orderbooks {
if y.ExchangeName == exchange {
@@ -85,6 +102,8 @@ func GetOrderbookByExchange(exchange string) (*Orderbook, error) {
return nil, errors.New(ErrOrderbookForExchangeNotFound)
}
// FirstCurrencyExists checks to see if the first currency of the orderbook map
// exists
func FirstCurrencyExists(exchange string, currency pair.CurrencyItem) bool {
for _, y := range Orderbooks {
if y.ExchangeName == exchange {
@@ -96,6 +115,8 @@ func FirstCurrencyExists(exchange string, currency pair.CurrencyItem) bool {
return false
}
// SecondCurrencyExists checks to see if the second currency of the orderbook
// map exists
func SecondCurrencyExists(exchange string, p pair.CurrencyPair) bool {
for _, y := range Orderbooks {
if y.ExchangeName == exchange {
@@ -109,40 +130,51 @@ func SecondCurrencyExists(exchange string, p pair.CurrencyPair) bool {
return false
}
func CreateNewOrderbook(exchangeName string, p pair.CurrencyPair, orderbookNew OrderbookBase) Orderbook {
// CreateNewOrderbook creates a new orderbook
func CreateNewOrderbook(exchangeName string, p pair.CurrencyPair, orderbookNew Base, orderbookType string) Orderbook {
orderbook := Orderbook{}
orderbook.ExchangeName = exchangeName
orderbook.Orderbook = make(map[pair.CurrencyItem]map[pair.CurrencyItem]OrderbookBase)
sMap := make(map[pair.CurrencyItem]OrderbookBase)
sMap[p.GetSecondCurrency()] = orderbookNew
orderbook.Orderbook[p.GetFirstCurrency()] = sMap
orderbook.Orderbook = make(map[pair.CurrencyItem]map[pair.CurrencyItem]map[string]Base)
a := make(map[pair.CurrencyItem]map[string]Base)
b := make(map[string]Base)
b[orderbookType] = orderbookNew
a[p.SecondCurrency] = b
orderbook.Orderbook[p.FirstCurrency] = a
Orderbooks = append(Orderbooks, orderbook)
return orderbook
}
func ProcessOrderbook(exchangeName string, p pair.CurrencyPair, orderbookNew OrderbookBase) {
// ProcessOrderbook processes incoming orderbooks, creating or updating the
// Orderbook list
func ProcessOrderbook(exchangeName string, p pair.CurrencyPair, orderbookNew Base, orderbookType string) {
orderbookNew.CurrencyPair = p.Pair().String()
orderbookNew.LastUpdated = time.Now()
if len(Orderbooks) == 0 {
CreateNewOrderbook(exchangeName, p, orderbookNew)
CreateNewOrderbook(exchangeName, p, orderbookNew, orderbookType)
return
} else {
orderbook, err := GetOrderbookByExchange(exchangeName)
if err != nil {
CreateNewOrderbook(exchangeName, p, orderbookNew)
}
orderbook, err := GetOrderbookByExchange(exchangeName)
if err != nil {
CreateNewOrderbook(exchangeName, p, orderbookNew, orderbookType)
return
}
if FirstCurrencyExists(exchangeName, p.GetFirstCurrency()) {
if !SecondCurrencyExists(exchangeName, p) {
a := orderbook.Orderbook[p.FirstCurrency]
b := make(map[string]Base)
b[orderbookType] = orderbookNew
a[p.SecondCurrency] = b
orderbook.Orderbook[p.FirstCurrency] = a
return
}
if FirstCurrencyExists(exchangeName, p.GetFirstCurrency()) {
if !SecondCurrencyExists(exchangeName, p) {
second := orderbook.Orderbook[p.GetFirstCurrency()]
second[p.GetSecondCurrency()] = orderbookNew
orderbook.Orderbook[p.GetFirstCurrency()] = second
return
}
}
sMap := make(map[pair.CurrencyItem]OrderbookBase)
sMap[p.GetSecondCurrency()] = orderbookNew
orderbook.Orderbook[p.GetFirstCurrency()] = sMap
}
a := make(map[pair.CurrencyItem]map[string]Base)
b := make(map[string]Base)
b[orderbookType] = orderbookNew
a[p.SecondCurrency] = b
orderbook.Orderbook[p.FirstCurrency] = a
}

View File

@@ -0,0 +1,266 @@
package orderbook
import (
"testing"
"time"
"github.com/thrasher-/gocryptotrader/currency/pair"
)
func TestCalculateTotalBids(t *testing.T) {
t.Parallel()
currency := pair.NewCurrencyPair("BTC", "USD")
base := Base{
Pair: currency,
CurrencyPair: currency.Pair().String(),
Bids: []Item{Item{Price: 100, Amount: 10}},
LastUpdated: time.Now(),
}
a, b := base.CalculateTotalBids()
if a != 10 && b != 1000 {
t.Fatal("Test failed. TestCalculateTotalBids expected a = 10 and b = 1000")
}
}
func TestCalculateTotaAsks(t *testing.T) {
t.Parallel()
currency := pair.NewCurrencyPair("BTC", "USD")
base := Base{
Pair: currency,
CurrencyPair: currency.Pair().String(),
Asks: []Item{Item{Price: 100, Amount: 10}},
LastUpdated: time.Now(),
}
a, b := base.CalculateTotalAsks()
if a != 10 && b != 1000 {
t.Fatal("Test failed. TestCalculateTotalAsks expected a = 10 and b = 1000")
}
}
func TestUpdate(t *testing.T) {
t.Parallel()
currency := pair.NewCurrencyPair("BTC", "USD")
timeNow := time.Now()
base := Base{
Pair: currency,
CurrencyPair: currency.Pair().String(),
Asks: []Item{Item{Price: 100, Amount: 10}},
Bids: []Item{Item{Price: 200, Amount: 10}},
LastUpdated: timeNow,
}
asks := []Item{Item{Price: 200, Amount: 101}}
bids := []Item{Item{Price: 201, Amount: 100}}
time.Sleep(time.Millisecond * 50)
base.Update(bids, asks)
if !base.LastUpdated.After(timeNow) {
t.Fatal("test failed. TestUpdate expected LastUpdated to be greater then original time")
}
a, b := base.CalculateTotalAsks()
if a != 100 && b != 20200 {
t.Fatal("Test failed. TestUpdate expected a = 100 and b = 20100")
}
a, b = base.CalculateTotalBids()
if a != 100 && b != 20100 {
t.Fatal("Test failed. TestUpdate expected a = 100 and b = 20100")
}
}
func TestGetOrderbook(t *testing.T) {
currency := pair.NewCurrencyPair("BTC", "USD")
base := Base{
Pair: currency,
CurrencyPair: currency.Pair().String(),
Asks: []Item{Item{Price: 100, Amount: 10}},
Bids: []Item{Item{Price: 200, Amount: 10}},
}
CreateNewOrderbook("Exchange", currency, base, Spot)
result, err := GetOrderbook("Exchange", currency, Spot)
if err != nil {
t.Fatalf("Test failed. TestGetOrderbook failed to get orderbook. Error %s",
err)
}
if result.Pair.Pair() != currency.Pair() {
t.Fatal("Test failed. TestGetOrderbook failed. Mismatched pairs")
}
_, err = GetOrderbook("nonexistant", currency, Spot)
if err == nil {
t.Fatal("Test failed. TestGetOrderbook retrieved non-existant orderbook")
}
currency.FirstCurrency = "blah"
_, err = GetOrderbook("Exchange", currency, Spot)
if err == nil {
t.Fatal("Test failed. TestGetOrderbook retrieved non-existant orderbook using invalid first currency")
}
newCurrency := pair.NewCurrencyPair("BTC", "AUD")
_, err = GetOrderbook("Exchange", newCurrency, Spot)
if err == nil {
t.Fatal("Test failed. TestGetOrderbook retrieved non-existant orderbook using invalid second currency")
}
}
func TestGetOrderbookByExchange(t *testing.T) {
currency := pair.NewCurrencyPair("BTC", "USD")
base := Base{
Pair: currency,
CurrencyPair: currency.Pair().String(),
Asks: []Item{Item{Price: 100, Amount: 10}},
Bids: []Item{Item{Price: 200, Amount: 10}},
}
CreateNewOrderbook("Exchange", currency, base, Spot)
_, err := GetOrderbookByExchange("Exchange")
if err != nil {
t.Fatalf("Test failed. TestGetOrderbookByExchange failed to get orderbook. Error %s",
err)
}
_, err = GetOrderbookByExchange("nonexistant")
if err == nil {
t.Fatal("Test failed. TestGetOrderbookByExchange retrieved non-existant orderbook")
}
}
func TestFirstCurrencyExists(t *testing.T) {
currency := pair.NewCurrencyPair("BTC", "AUD")
base := Base{
Pair: currency,
CurrencyPair: currency.Pair().String(),
Asks: []Item{Item{Price: 100, Amount: 10}},
Bids: []Item{Item{Price: 200, Amount: 10}},
}
CreateNewOrderbook("Exchange", currency, base, Spot)
if !FirstCurrencyExists("Exchange", currency.FirstCurrency) {
t.Fatal("Test failed. TestFirstCurrencyExists expected first currency doesn't exist")
}
var item pair.CurrencyItem = "blah"
if FirstCurrencyExists("Exchange", item) {
t.Fatal("Test failed. TestFirstCurrencyExists unexpected first currency exists")
}
}
func TestSecondCurrencyExists(t *testing.T) {
currency := pair.NewCurrencyPair("BTC", "USD")
base := Base{
Pair: currency,
CurrencyPair: currency.Pair().String(),
Asks: []Item{Item{Price: 100, Amount: 10}},
Bids: []Item{Item{Price: 200, Amount: 10}},
}
CreateNewOrderbook("Exchange", currency, base, Spot)
if !SecondCurrencyExists("Exchange", currency) {
t.Fatal("Test failed. TestSecondCurrencyExists expected first currency doesn't exist")
}
currency.SecondCurrency = "blah"
if SecondCurrencyExists("Exchange", currency) {
t.Fatal("Test failed. TestSecondCurrencyExists unexpected first currency exists")
}
}
func TestCreateNewOrderbook(t *testing.T) {
currency := pair.NewCurrencyPair("BTC", "USD")
base := Base{
Pair: currency,
CurrencyPair: currency.Pair().String(),
Asks: []Item{Item{Price: 100, Amount: 10}},
Bids: []Item{Item{Price: 200, Amount: 10}},
}
CreateNewOrderbook("Exchange", currency, base, Spot)
result, err := GetOrderbook("Exchange", currency, Spot)
if err != nil {
t.Fatal("Test failed. TestCreateNewOrderbook failed to create new orderbook")
}
if result.Pair.Pair() != currency.Pair() {
t.Fatal("Test failed. TestCreateNewOrderbook result pair is incorrect")
}
a, b := result.CalculateTotalAsks()
if a != 10 && b != 1000 {
t.Fatal("Test failed. TestCreateNewOrderbook CalculateTotalAsks value is incorrect")
}
a, b = result.CalculateTotalBids()
if a != 10 && b != 2000 {
t.Fatal("Test failed. TestCreateNewOrderbook CalculateTotalBids value is incorrect")
}
}
func TestProcessOrderbook(t *testing.T) {
Orderbooks = []Orderbook{}
currency := pair.NewCurrencyPair("BTC", "USD")
base := Base{
Pair: currency,
CurrencyPair: currency.Pair().String(),
Asks: []Item{Item{Price: 100, Amount: 10}},
Bids: []Item{Item{Price: 200, Amount: 10}},
}
ProcessOrderbook("Exchange", currency, base, Spot)
result, err := GetOrderbook("Exchange", currency, Spot)
if err != nil {
t.Fatal("Test failed. TestProcessOrderbook failed to create new orderbook")
}
if result.Pair.Pair() != currency.Pair() {
t.Fatal("Test failed. TestProcessOrderbook result pair is incorrect")
}
currency = pair.NewCurrencyPair("BTC", "GBP")
base.Pair = currency
ProcessOrderbook("Exchange", currency, base, Spot)
result, err = GetOrderbook("Exchange", currency, Spot)
if err != nil {
t.Fatal("Test failed. TestProcessOrderbook failed to retrieve new orderbook")
}
if result.Pair.Pair() != currency.Pair() {
t.Fatal("Test failed. TestProcessOrderbook result pair is incorrect")
}
base.Asks = []Item{Item{Price: 200, Amount: 200}}
ProcessOrderbook("Exchange", currency, base, "monthly")
result, err = GetOrderbook("Exchange", currency, "monthly")
if err != nil {
t.Fatal("Test failed. TestProcessOrderbook failed to retrieve new orderbook")
}
a, b := result.CalculateTotalAsks()
if a != 200 && b != 40000 {
t.Fatal("Test failed. TestProcessOrderbook CalculateTotalsAsks incorrect values")
}
base.Bids = []Item{Item{Price: 420, Amount: 200}}
ProcessOrderbook("Blah", currency, base, "quarterly")
result, err = GetOrderbook("Blah", currency, "quarterly")
if err != nil {
t.Fatal("Test failed. TestProcessOrderbook failed to create new orderbook")
}
if a != 200 && b != 84000 {
t.Fatal("Test failed. TestProcessOrderbook CalculateTotalsBids incorrect values")
}
}

View File

@@ -61,17 +61,17 @@ func (p *Poloniex) GetTickerPrice(currencyPair pair.CurrencyPair, assetType stri
}
// GetOrderbookEx returns orderbook base on the currency pair
func (p *Poloniex) GetOrderbookEx(currencyPair pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(p.GetName(), currencyPair)
func (p *Poloniex) GetOrderbookEx(currencyPair pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(p.GetName(), currencyPair, assetType)
if err == nil {
return p.UpdateOrderbook(currencyPair)
return p.UpdateOrderbook(currencyPair, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (p *Poloniex) UpdateOrderbook(currencyPair pair.CurrencyPair) (orderbook.OrderbookBase, error) {
var orderBook orderbook.OrderbookBase
func (p *Poloniex) UpdateOrderbook(currencyPair pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := p.GetOrderbook(exchange.FormatExchangeCurrency(p.GetName(), currencyPair).String(), 1000)
if err != nil {
return orderBook, err
@@ -79,16 +79,16 @@ func (p *Poloniex) UpdateOrderbook(currencyPair pair.CurrencyPair) (orderbook.Or
for x := range orderbookNew.Bids {
data := orderbookNew.Bids[x]
orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Amount: data.Amount, Price: data.Price})
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data.Amount, Price: data.Price})
}
for x := range orderbookNew.Asks {
data := orderbookNew.Asks[x]
orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Amount: data.Amount, Price: data.Price})
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data.Amount, Price: data.Price})
}
orderbook.ProcessOrderbook(p.GetName(), currencyPair, orderBook)
return orderbook.GetOrderbook(p.Name, currencyPair)
orderbook.ProcessOrderbook(p.GetName(), currencyPair, orderBook, assetType)
return orderbook.GetOrderbook(p.Name, currencyPair, assetType)
}
// GetExchangeAccountInfo retrieves balances for all enabled currencies for the

View File

@@ -72,6 +72,23 @@ func TestGetTicker(t *testing.T) {
t.Error("Test Failed - ticker tickerPrice.CurrencyPair value is incorrect")
}
_, err = GetTicker("blah", newPair, Spot)
if err == nil {
t.Fatal("Test Failed. TestGetTicker returned nil error on invalid exchange")
}
newPair.FirstCurrency = "ETH"
_, err = GetTicker("bitfinex", newPair, Spot)
if err == nil {
t.Fatal("Test Failed. TestGetTicker returned ticker for invalid first currency")
}
btcltcPair := pair.NewCurrencyPair("BTC", "LTC")
_, err = GetTicker("bitfinex", btcltcPair, Spot)
if err == nil {
t.Fatal("Test Failed. TestGetTicker returned ticker for invalid second currency")
}
priceStruct.PriceATH = 9001
ProcessTicker("bitfinex", newPair, priceStruct, "futures_3m")
tickerPrice, err = GetTicker("bitfinex", newPair, "futures_3m")
@@ -220,6 +237,7 @@ func TestCreateNewTicker(t *testing.T) {
}
func TestProcessTicker(t *testing.T) { //non-appending function to tickers
Tickers = []Ticker{}
newPair := pair.NewCurrencyPair("BTC", "USD")
priceStruct := Price{
Pair: newPair,
@@ -234,4 +252,27 @@ func TestProcessTicker(t *testing.T) { //non-appending function to tickers
}
ProcessTicker("btcc", newPair, priceStruct, Spot)
result, err := GetTicker("btcc", newPair, Spot)
if err != nil {
t.Fatal("Test failed. TestProcessTicker failed to create and return a new ticker")
}
if result.Pair.Pair() != newPair.Pair() {
t.Fatal("Test failed. TestProcessTicker pair mismatch")
}
secondPair := pair.NewCurrencyPair("BTC", "AUD")
priceStruct.Pair = secondPair
ProcessTicker("btcc", secondPair, priceStruct, Spot)
result, err = GetTicker("btcc", secondPair, Spot)
if err != nil {
t.Fatal("Test failed. TestProcessTicker failed to create and return a new ticker")
}
result, err = GetTicker("btcc", newPair, Spot)
if err != nil {
t.Fatal("Test failed. TestProcessTicker failed to return an existing ticker")
}
}

View File

@@ -191,7 +191,7 @@ func main() {
go WebsocketHandler()
go TickerUpdaterRoutine()
//go OrderbookUpdaterRoutine()
go OrderbookUpdaterRoutine()
if bot.config.Webserver.Enabled {
err := bot.config.CheckWebserverConfigValues()

141
orderbook_routes.go Normal file
View File

@@ -0,0 +1,141 @@
package main
import (
"encoding/json"
"log"
"net/http"
"github.com/gorilla/mux"
"github.com/thrasher-/gocryptotrader/currency/pair"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
)
// GetSpecificOrderbook returns a specific orderbook given the currency,
// exchangeName and assetType
func GetSpecificOrderbook(currency, exchangeName, assetType string) (orderbook.Base, error) {
var specificOrderbook orderbook.Base
var err error
for i := 0; i < len(bot.exchanges); i++ {
if bot.exchanges[i] != nil {
if bot.exchanges[i].IsEnabled() && bot.exchanges[i].GetName() == exchangeName {
specificOrderbook, err = bot.exchanges[i].GetOrderbookEx(
pair.NewCurrencyPairFromString(currency),
assetType,
)
break
}
}
}
return specificOrderbook, err
}
func jsonOrderbookResponse(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
currency := vars["currency"]
exchange := vars["exchangeName"]
assetType := vars["assetType"]
if assetType == "" {
assetType = orderbook.Spot
}
response, err := GetSpecificOrderbook(currency, exchange, assetType)
if err != nil {
log.Printf("Failed to fetch orderbook for %s currency: %s\n", exchange,
currency)
return
}
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(response); err != nil {
panic(err)
}
}
// AllEnabledExchangeOrderbooks holds the enabled exchange orderbooks
type AllEnabledExchangeOrderbooks struct {
Data []EnabledExchangeOrderbooks `json:"data"`
}
// EnabledExchangeOrderbooks is a sub type for singular exchanges and respective
// orderbooks
type EnabledExchangeOrderbooks struct {
ExchangeName string `json:"exchangeName"`
ExchangeValues []orderbook.Base `json:"exchangeValues"`
}
// GetAllActiveOrderbooks returns all enabled exchanges orderbooks
func GetAllActiveOrderbooks() []EnabledExchangeOrderbooks {
var orderbookData []EnabledExchangeOrderbooks
for _, individualBot := range bot.exchanges {
if individualBot != nil && individualBot.IsEnabled() {
var individualExchange EnabledExchangeOrderbooks
exchangeName := individualBot.GetName()
individualExchange.ExchangeName = exchangeName
currencies := individualBot.GetEnabledCurrencies()
assetTypes, err := exchange.GetExchangeAssetTypes(exchangeName)
if err != nil {
log.Printf("failed to get %s exchange asset types. Error: %s",
exchangeName, err)
continue
}
for _, x := range currencies {
currency := x
var ob orderbook.Base
if len(assetTypes) > 1 {
for y := range assetTypes {
ob, err = individualBot.UpdateOrderbook(currency,
assetTypes[y])
}
} else {
ob, err = individualBot.UpdateOrderbook(currency,
assetTypes[0])
}
if err != nil {
log.Printf("failed to get %s %s orderbook. Error: %s",
currency.Pair().String(),
exchangeName,
err)
continue
}
individualExchange.ExchangeValues = append(
individualExchange.ExchangeValues, ob,
)
}
orderbookData = append(orderbookData, individualExchange)
}
}
return orderbookData
}
func getAllActiveOrderbooksResponse(w http.ResponseWriter, r *http.Request) {
var response AllEnabledExchangeOrderbooks
response.Data = GetAllActiveOrderbooks()
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(response); err != nil {
panic(err)
}
}
// OrderbookRoutes denotes the current exchange orderbook routes
var OrderbookRoutes = Routes{
Route{
"AllActiveExchangesAndOrderbooks",
"GET",
"/exchanges/orderbook/latest/all",
getAllActiveOrderbooksResponse,
},
Route{
"IndividualExchangeOrderbook",
"GET",
"/exchanges/{exchangeName}/orderbook/latest/{currency}",
jsonOrderbookResponse,
},
}

View File

@@ -18,6 +18,7 @@ func NewRouter(exchanges []exchange.IBotExchange) *mux.Router {
allRoutes = append(allRoutes, WalletRoutes...)
allRoutes = append(allRoutes, IndexRoute...)
allRoutes = append(allRoutes, WebsocketRoutes...)
allRoutes = append(allRoutes, OrderbookRoutes...)
for _, route := range allRoutes {
var handler http.Handler
handler = route.HandlerFunc

View File

@@ -5,6 +5,8 @@ import (
"log"
"time"
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-/gocryptotrader/currency/pair"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
@@ -31,6 +33,31 @@ func printSummary(result ticker.Price, p pair.CurrencyPair, assetType, exchangeN
result.Volume)
}
func printOrderbookSummary(result orderbook.Base, p pair.CurrencyPair, assetType, exchangeName string, err error) {
if err != nil {
log.Printf("failed to get %s %s orderbook. Error: %s",
p.Pair().String(),
exchangeName,
err)
return
}
bidsAmount, bidsValue := result.CalculateTotalBids()
asksAmount, asksValue := result.CalculateTotalAsks()
log.Printf("%s %s %s: Orderbook Bids len: %d amount: %f total value: %f Asks len: %d amount: %f total value: %f",
exchangeName,
exchange.FormatCurrency(p).String(),
assetType,
len(result.Bids),
bidsAmount,
bidsValue,
len(result.Asks),
asksAmount,
asksValue,
)
}
func relayWebsocketEvent(result interface{}, event, assetType, exchangeName string) {
evt := WebsocketEvent{
Data: result,
@@ -57,13 +84,15 @@ func TickerUpdaterRoutine() {
var err error
var assetTypes []string
assetTypes, err = exchange.GetExchangeAssetTypes(exchangeName)
if err != nil {
log.Printf("failed to get %s exchange asset types. Error: %s",
exchangeName, err)
}
for y := range enabledCurrencies {
currency := enabledCurrencies[y]
assetTypes, err = exchange.GetExchangeAssetTypes(exchangeName)
if err != nil {
log.Printf("failed to get %s exchange asset types. Error: %s",
exchangeName, err)
}
if len(assetTypes) > 1 {
for z := range assetTypes {
result, err = bot.exchanges[x].UpdateTicker(currency,
@@ -93,33 +122,42 @@ func OrderbookUpdaterRoutine() {
for {
for x := range bot.exchanges {
if bot.exchanges[x].IsEnabled() {
exchangeName := bot.exchanges[x].GetName()
if exchangeName == "ANX" {
if bot.exchanges[x].GetName() == "ANX" {
continue
}
exchangeName := bot.exchanges[x].GetName()
enabledCurrencies := bot.exchanges[x].GetEnabledCurrencies()
var result orderbook.Base
var err error
var assetTypes []string
assetTypes, err = exchange.GetExchangeAssetTypes(exchangeName)
if err != nil {
log.Printf("failed to get %s exchange asset types. Error: %s",
exchangeName, err)
}
for y := range enabledCurrencies {
currency := enabledCurrencies[y]
result, err := bot.exchanges[x].UpdateOrderbook(currency)
if err != nil {
log.Printf("failed to get %s orderbook", currency.Pair().String())
continue
}
log.Printf("%s %s %v",
exchangeName,
exchange.FormatCurrency(currency).String(),
result)
evt := WebsocketEvent{
Data: result,
Event: "orderbook_update",
Exchange: exchangeName,
if len(assetTypes) > 1 {
for z := range assetTypes {
result, err = bot.exchanges[x].UpdateOrderbook(currency,
assetTypes[z])
printOrderbookSummary(result, currency, assetTypes[z], exchangeName, err)
if err == nil {
relayWebsocketEvent(result, "orderbook_update", assetTypes[z], exchangeName)
}
}
} else {
result, err = bot.exchanges[x].UpdateOrderbook(currency,
assetTypes[0])
printOrderbookSummary(result, currency, assetTypes[0], exchangeName, err)
if err == nil {
relayWebsocketEvent(result, "orderbook_update", assetTypes[0], exchangeName)
}
}
BroadcastWebsocketMessage(evt)
}
}
}

View File

@@ -94,7 +94,6 @@ func SendWebsocketMessage(id int, data interface{}) error {
}
func BroadcastWebsocketMessage(evt WebsocketEvent) error {
log.Println(evt)
for _, x := range WebsocketClientHub {
x.Conn.WriteJSON(evt)
}