Merge branch 'master' into engine

This commit is contained in:
Adrian Gallagher
2019-06-17 14:36:06 +10:00
4 changed files with 118 additions and 62 deletions

View File

@@ -9,11 +9,13 @@ import (
"github.com/thrasher-/gocryptotrader/exchanges/asset"
)
// Const values for orderbook package
// const values for orderbook package
const (
ErrOrderbookForExchangeNotFound = "ticker for exchange does not exist"
ErrPrimaryCurrencyNotFound = "primary currency for orderbook not found"
ErrSecondaryCurrencyNotFound = "secondary currency for orderbook not found"
errExchangeOrderbookNotFound = "orderbook for exchange does not exist"
errPairNotSet = "orderbook currency pair not set"
errAssetTypeNotSet = "orderbook asset type not set"
errBaseCurrencyNotFound = "orderbook base currency not found"
errQuoteCurrencyNotFound = "orderbook quote currency not found"
)
// Vars for the orderbook package
@@ -81,11 +83,11 @@ func Get(exchange string, p currency.Pair, orderbookType asset.Item) (Base, erro
}
if !BaseCurrencyExists(exchange, p.Base) {
return Base{}, errors.New(ErrPrimaryCurrencyNotFound)
return Base{}, errors.New(errBaseCurrencyNotFound)
}
if !QuoteCurrencyExists(exchange, p) {
return Base{}, errors.New(ErrSecondaryCurrencyNotFound)
return Base{}, errors.New(errQuoteCurrencyNotFound)
}
return orderbook.Orderbook[p.Base.Item][p.Quote.Item][orderbookType], nil
@@ -100,7 +102,7 @@ func GetByExchange(exchange string) (*Orderbook, error) {
return &Orderbooks[x], nil
}
}
return nil, errors.New(ErrOrderbookForExchangeNotFound)
return nil, errors.New(errExchangeOrderbookNotFound)
}
// BaseCurrencyExists checks to see if the base currency of the orderbook map
@@ -155,11 +157,11 @@ func CreateNewOrderbook(exchangeName string, orderbookNew *Base, orderbookType a
// list
func (o *Base) Process() error {
if o.Pair.IsEmpty() {
return errors.New("orderbook currency pair not populated")
return errors.New(errPairNotSet)
}
if o.AssetType == "" {
return errors.New("orderbook asset type not set")
return errors.New(errAssetTypeNotSet)
}
if o.LastUpdated.IsZero() {

View File

@@ -87,7 +87,7 @@ func TestGetOrderbook(t *testing.T) {
t.Fatalf("Test failed. TestGetOrderbook failed to get orderbook. Error %s",
err)
}
if result.Pair.String() != c.String() {
if !result.Pair.Equal(c) {
t.Fatal("Test failed. TestGetOrderbook failed. Mismatched pairs")
}
@@ -186,7 +186,7 @@ func TestCreateNewOrderbook(t *testing.T) {
t.Fatal("Test failed. TestCreateNewOrderbook failed to create new orderbook")
}
if result.Pair.String() != c.String() {
if !result.Pair.Equal(c) {
t.Fatal("Test failed. TestCreateNewOrderbook result pair is incorrect")
}
@@ -205,41 +205,66 @@ func TestProcessOrderbook(t *testing.T) {
Orderbooks = []Orderbook{}
c := currency.NewPairFromStrings("BTC", "USD")
base := Base{
Pair: c,
Asks: []Item{{Price: 100, Amount: 10}},
Bids: []Item{{Price: 200, Amount: 10}},
ExchangeName: "Exchange",
AssetType: asset.Spot,
}
// test for empty pair
base.Pair = currency.Pair{}
err := base.Process()
if err != nil {
t.Error("Test Failed - Process() error", err)
if err == nil {
t.Error("empty pair should throw an err")
}
// test for empty asset type
base.Pair = c
err = base.Process()
if err == nil {
t.Error("empty asset type should throw an err")
}
// now process a valid orderbook
base.AssetType = asset.Spot
err = base.Process()
if err != nil {
t.Error("unexpcted result: ", err)
}
result, err := Get("Exchange", c, asset.Spot)
if err != nil {
t.Fatal("Test failed. TestProcessOrderbook failed to create new orderbook")
}
if result.Pair.String() != c.String() {
if !result.Pair.Equal(c) {
t.Fatal("Test failed. TestProcessOrderbook result pair is incorrect")
}
// now test for processing a pair with a different quote currency
c = currency.NewPairFromStrings("BTC", "GBP")
base.Pair = c
err = base.Process()
if err != nil {
t.Error("Test Failed - Process() error", err)
}
result, err = Get("Exchange", c, asset.Spot)
if err != nil {
t.Fatal("Test failed. TestProcessOrderbook failed to retrieve new orderbook")
}
if !result.Pair.Equal(c) {
t.Fatal("Test failed. TestProcessOrderbook result pair is incorrect")
}
if result.Pair.String() != c.String() {
// now test for processing a pair which has a different base currency
c = currency.NewPairFromStrings("LTC", "GBP")
base.Pair = c
err = base.Process()
if err != nil {
t.Error("Test Failed - Process() error", err)
}
result, err = Get("Exchange", c, asset.Spot)
if err != nil {
t.Fatal("Test failed. TestProcessOrderbook failed to retrieve new orderbook")
}
if !result.Pair.Equal(c) {
t.Fatal("Test failed. TestProcessOrderbook result pair is incorrect")
}

View File

@@ -11,11 +11,13 @@ import (
"github.com/thrasher-/gocryptotrader/exchanges/asset"
)
// Const values for the ticker package
// const values for the ticker package
const (
ErrTickerForExchangeNotFound = "ticker for exchange does not exist"
ErrPrimaryCurrencyNotFound = "error primary currency for ticker not found"
ErrSecondaryCurrencyNotFound = "error secondary currency for ticker not found"
errExchangeTickerNotFound = "ticker for exchange does not exist"
errPairNotSet = "ticker currency pair not set"
errAssetTypeNotSet = "ticker asset type not set"
errBaseCurrencyNotFound = "ticker base currency not found"
errQuoteCurrencyNotFound = "ticker quote currency not found"
)
// Vars for the ticker package
@@ -74,12 +76,12 @@ func GetTicker(exchange string, p currency.Pair, tickerType asset.Item) (Price,
return Price{}, err
}
if !FirstCurrencyExists(exchange, p.Base) {
return Price{}, errors.New(ErrPrimaryCurrencyNotFound)
if !BaseCurrencyExists(exchange, p.Base) {
return Price{}, errors.New(errBaseCurrencyNotFound)
}
if !SecondCurrencyExists(exchange, p) {
return Price{}, errors.New(ErrSecondaryCurrencyNotFound)
if !QuoteCurrencyExists(exchange, p) {
return Price{}, errors.New(errQuoteCurrencyNotFound)
}
return ticker.Price[p.Base.Upper().String()][p.Quote.Upper().String()][tickerType.String()], nil
@@ -94,12 +96,12 @@ func GetTickerByExchange(exchange string) (*Ticker, error) {
return &Tickers[x], nil
}
}
return nil, errors.New(ErrTickerForExchangeNotFound)
return nil, errors.New(errExchangeTickerNotFound)
}
// FirstCurrencyExists checks to see if the first currency of the Price map
// BaseCurrencyExists checks to see if the base currency of the ticker map
// exists
func FirstCurrencyExists(exchange string, currency currency.Code) bool {
func BaseCurrencyExists(exchange string, currency currency.Code) bool {
m.Lock()
defer m.Unlock()
for _, y := range Tickers {
@@ -112,9 +114,9 @@ func FirstCurrencyExists(exchange string, currency currency.Code) bool {
return false
}
// SecondCurrencyExists checks to see if the second currency of the Price map
// QuoteCurrencyExists checks to see if the quote currency of the ticker map
// exists
func SecondCurrencyExists(exchange string, p currency.Pair) bool {
func QuoteCurrencyExists(exchange string, p currency.Pair) bool {
m.Lock()
defer m.Unlock()
for _, y := range Tickers {
@@ -147,23 +149,29 @@ func CreateNewTicker(exchangeName string, tickerNew *Price, tickerType asset.Ite
// ProcessTicker processes incoming tickers, creating or updating the Tickers
// list
func ProcessTicker(exchangeName string, tickerNew *Price, tickerType asset.Item) error {
if tickerNew.Pair.String() == "" {
return errors.New("")
func ProcessTicker(exchangeName string, tickerNew *Price, assetType asset.Item) error {
if tickerNew.Pair.IsEmpty() {
return errors.New(errPairNotSet)
}
tickerNew.LastUpdated = time.Now()
if assetType == "" {
return errors.New(errAssetTypeNotSet)
}
if tickerNew.LastUpdated.IsZero() {
tickerNew.LastUpdated = time.Now()
}
ticker, err := GetTickerByExchange(exchangeName)
if err != nil {
CreateNewTicker(exchangeName, tickerNew, tickerType)
CreateNewTicker(exchangeName, tickerNew, assetType)
return nil
}
if FirstCurrencyExists(exchangeName, tickerNew.Pair.Base) {
if BaseCurrencyExists(exchangeName, tickerNew.Pair.Base) {
m.Lock()
a := make(map[string]Price)
a[tickerType.String()] = *tickerNew
a[assetType.String()] = *tickerNew
ticker.Price[tickerNew.Pair.Base.Upper().String()][tickerNew.Pair.Quote.Upper().String()] = a
m.Unlock()
return nil
@@ -172,7 +180,7 @@ func ProcessTicker(exchangeName string, tickerNew *Price, tickerType asset.Item)
m.Lock()
a := make(map[string]map[string]Price)
b := make(map[string]Price)
b[tickerType.String()] = *tickerNew
b[assetType.String()] = *tickerNew
a[tickerNew.Pair.Quote.Upper().String()] = b
ticker.Price[tickerNew.Pair.Base.Upper().String()] = a
m.Unlock()

View File

@@ -76,7 +76,7 @@ func TestGetTicker(t *testing.T) {
if err != nil {
t.Errorf("Test Failed - Ticker GetTicker init error: %s", err)
}
if tickerPrice.Pair.String() != "BTCUSD" {
if !tickerPrice.Pair.Equal(newPair) {
t.Error("Test Failed - ticker tickerPrice.CurrencyPair value is incorrect")
}
@@ -139,7 +139,7 @@ func TestGetTickerByExchange(t *testing.T) {
}
}
func TestFirstCurrencyExists(t *testing.T) {
func TestBaseCurrencyExists(t *testing.T) {
newPair := currency.NewPairFromStrings("BTC", "USD")
priceStruct := Price{
Pair: newPair,
@@ -155,15 +155,15 @@ func TestFirstCurrencyExists(t *testing.T) {
alphaTicker := CreateNewTicker("alphapoint", &priceStruct, asset.Spot)
Tickers = append(Tickers, alphaTicker)
if !FirstCurrencyExists("alphapoint", currency.BTC) {
t.Error("Test Failed - FirstCurrencyExists1 value return is incorrect")
if !BaseCurrencyExists("alphapoint", currency.BTC) {
t.Error("Test Failed - BaseCurrencyExists1 value return is incorrect")
}
if FirstCurrencyExists("alphapoint", currency.NewCode("CATS")) {
t.Error("Test Failed - FirstCurrencyExists2 value return is incorrect")
if BaseCurrencyExists("alphapoint", currency.NewCode("CATS")) {
t.Error("Test Failed - BaseCurrencyExists2 value return is incorrect")
}
}
func TestSecondCurrencyExists(t *testing.T) {
func TestQuoteCurrencyExists(t *testing.T) {
t.Parallel()
newPair := currency.NewPairFromStrings("BTC", "USD")
@@ -181,13 +181,13 @@ func TestSecondCurrencyExists(t *testing.T) {
bitstampTicker := CreateNewTicker("bitstamp", &priceStruct, asset.Spot)
Tickers = append(Tickers, bitstampTicker)
if !SecondCurrencyExists("bitstamp", newPair) {
t.Error("Test Failed - SecondCurrencyExists1 value return is incorrect")
if !QuoteCurrencyExists("bitstamp", newPair) {
t.Error("Test Failed - QuoteCurrencyExists1 value return is incorrect")
}
newPair.Quote = currency.NewCode("DOGS")
if SecondCurrencyExists("bitstamp", newPair) {
t.Error("Test Failed - SecondCurrencyExists2 value return is incorrect")
if QuoteCurrencyExists("bitstamp", newPair) {
t.Error("Test Failed - QuoteCurrencyExists2 value return is incorrect")
}
}
@@ -217,7 +217,7 @@ func TestCreateNewTicker(t *testing.T) {
t.Error("Test Failed - ticker CreateNewTicker.ExchangeName value is not ANX")
}
if newTicker.Price[currency.BTC.Upper().String()][currency.USD.Upper().String()][asset.Spot.String()].Pair.String() != "BTCUSD" {
if !newTicker.Price[currency.BTC.Upper().String()][currency.USD.Upper().String()][asset.Spot.String()].Pair.Equal(newPair) {
t.Error("Test Failed - ticker newTicker.Price[BTC][USD].Pair.Pair().String() value is not expected 'BTCUSD'")
}
if reflect.TypeOf(newTicker.Price["BTC"]["USD"][asset.Spot.String()].Ask).String() != float64Type {
@@ -251,7 +251,6 @@ func TestProcessTicker(t *testing.T) { // non-appending function to tickers
exchName := "bitstamp"
newPair := currency.NewPairFromStrings("BTC", "USD")
priceStruct := Price{
Pair: newPair,
Last: 1200,
High: 1298,
Low: 1148,
@@ -261,37 +260,59 @@ func TestProcessTicker(t *testing.T) { // non-appending function to tickers
PriceATH: 1337,
}
err := ProcessTicker(exchName, &Price{}, asset.Spot)
// test for empty pair
err := ProcessTicker(exchName, &priceStruct, asset.Spot)
if err == nil {
t.Fatal("empty pair should throw an err")
}
// test for empty asset type
priceStruct.Pair = newPair
err = ProcessTicker(exchName, &priceStruct, "")
if err == nil {
t.Fatal("Test failed. ProcessTicker error cannot be nil")
}
// now process a valid ticker
err = ProcessTicker(exchName, &priceStruct, asset.Spot)
if err != nil {
t.Fatal("Test failed. ProcessTicker error", err)
}
result, err := GetTicker(exchName, newPair, asset.Spot)
if err != nil {
t.Fatal("Test failed. TestProcessTicker failed to create and return a new ticker")
}
if result.Pair.String() != newPair.String() {
if !result.Pair.Equal(newPair) {
t.Fatal("Test failed. TestProcessTicker pair mismatch")
}
secondPair := currency.NewPairFromStrings("BTC", "AUD")
priceStruct.Pair = secondPair
// now test for processing a pair with a different quote currency
newPair = currency.NewPairFromStrings("BTC", "AUD")
priceStruct.Pair = newPair
err = ProcessTicker(exchName, &priceStruct, asset.Spot)
if err != nil {
t.Fatal("Test failed. ProcessTicker error", err)
}
result, err = GetTicker(exchName, secondPair, asset.Spot)
result, err = GetTicker(exchName, newPair, asset.Spot)
if err != nil {
t.Fatal("Test failed. TestProcessTicker failed to create and return a new ticker")
}
result, err = GetTicker(exchName, newPair, asset.Spot)
if err != nil {
t.Fatal("Test failed. TestProcessTicker failed to return an existing ticker")
}
// now test for processing a pair which has a different base currency
newPair = currency.NewPairFromStrings("LTC", "AUD")
priceStruct.Pair = newPair
err = ProcessTicker(exchName, &priceStruct, asset.Spot)
if err != nil {
t.Fatal("Test failed. ProcessTicker error", err)
}
result, err = GetTicker(exchName, newPair, asset.Spot)
if err != nil {
t.Fatal("Test failed. TestProcessTicker failed to create and return a new ticker")
}
result, err = GetTicker(exchName, newPair, asset.Spot)
if err != nil {
t.Fatal("Test failed. TestProcessTicker failed to return an existing ticker")