Files
gocryptotrader/exchanges/orderbook/orderbook.go
2017-04-19 00:16:53 +10:00

148 lines
3.9 KiB
Go

package orderbook
import (
"errors"
"time"
"github.com/thrasher-/gocryptotrader/currency/pair"
)
var (
ErrOrderbookForExchangeNotFound = "Ticker for exchange does not exist."
ErrPrimaryCurrencyNotFound = "Error primary currency for orderbook not found."
ErrSecondaryCurrencyNotFound = "Error secondary currency for orderbook not found."
Orderbooks []Orderbook
)
type OrderbookItem struct {
Amount float64
Price float64
}
type OrderbookBase struct {
Pair pair.CurrencyPair `json:"pair"`
CurrencyPair string `json:"CurrencyPair"`
Bids []OrderbookItem `json:"bids"`
Asks []OrderbookItem `json:"asks"`
LastUpdated time.Time `json:"last_updated"`
}
type Orderbook struct {
Orderbook map[pair.CurrencyItem]map[pair.CurrencyItem]OrderbookBase
ExchangeName string
}
func (o *OrderbookBase) CalculateTotalBids() (float64, float64) {
amountCollated := float64(0)
total := float64(0)
for _, x := range o.Bids {
amountCollated += x.Amount
total += x.Amount * x.Price
}
return amountCollated, total
}
func (o *OrderbookBase) CalculateTotalAsks() (float64, float64) {
amountCollated := float64(0)
total := float64(0)
for _, x := range o.Asks {
amountCollated += x.Amount
total += x.Amount * x.Price
}
return amountCollated, total
}
func (o *OrderbookBase) Update(Bids, Asks []OrderbookItem) {
o.Bids = Bids
o.Asks = Asks
o.LastUpdated = time.Now()
}
func GetOrderbook(exchange string, p pair.CurrencyPair) (OrderbookBase, error) {
orderbook, err := GetOrderbookByExchange(exchange)
if err != nil {
return OrderbookBase{}, err
}
if !FirstCurrencyExists(exchange, p.GetFirstCurrency()) {
return OrderbookBase{}, errors.New(ErrPrimaryCurrencyNotFound)
}
if !SecondCurrencyExists(exchange, p) {
return OrderbookBase{}, errors.New(ErrSecondaryCurrencyNotFound)
}
return orderbook.Orderbook[p.GetFirstCurrency()][p.GetSecondCurrency()], nil
}
func GetOrderbookByExchange(exchange string) (*Orderbook, error) {
for _, y := range Orderbooks {
if y.ExchangeName == exchange {
return &y, nil
}
}
return nil, errors.New(ErrOrderbookForExchangeNotFound)
}
func FirstCurrencyExists(exchange string, currency pair.CurrencyItem) bool {
for _, y := range Orderbooks {
if y.ExchangeName == exchange {
if _, ok := y.Orderbook[currency]; ok {
return true
}
}
}
return false
}
func SecondCurrencyExists(exchange string, p pair.CurrencyPair) bool {
for _, y := range Orderbooks {
if y.ExchangeName == exchange {
if _, ok := y.Orderbook[p.GetFirstCurrency()]; ok {
if _, ok := y.Orderbook[p.GetFirstCurrency()][p.GetSecondCurrency()]; ok {
return true
}
}
}
}
return false
}
func CreateNewOrderbook(exchangeName string, p pair.CurrencyPair, orderbookNew OrderbookBase) 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
Orderbooks = append(Orderbooks, orderbook)
return orderbook
}
func ProcessOrderbook(exchangeName string, p pair.CurrencyPair, orderbookNew OrderbookBase) {
orderbookNew.CurrencyPair = p.Pair().String()
if len(Orderbooks) == 0 {
CreateNewOrderbook(exchangeName, p, orderbookNew)
return
} else {
orderbook, err := GetOrderbookByExchange(exchangeName)
if err != nil {
CreateNewOrderbook(exchangeName, p, orderbookNew)
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
}
}