Start websocket implementation

This commit is contained in:
Adrian Gallagher
2017-04-04 11:05:31 +10:00
parent 89848eb6e9
commit a1040c8d94
25 changed files with 738 additions and 125 deletions

View File

@@ -1,8 +1,6 @@
package alphapoint
import (
"log"
"github.com/thrasher-/gocryptotrader/currency/pair"
"github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
@@ -30,21 +28,32 @@ func (a *Alphapoint) GetExchangeAccountInfo() (exchange.AccountInfo, error) {
return response, nil
}
// GetTickerPrice returns the current ticker price by currency pair
func (a *Alphapoint) GetTickerPrice(p pair.CurrencyPair) ticker.TickerPrice {
func (a *Alphapoint) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, err := a.GetTicker(p.Pair().String())
if err != nil {
log.Println(err)
return ticker.TickerPrice{}
return tickerPrice, err
}
tickerPrice.Pair = p
tickerPrice.Ask = tick.Ask
tickerPrice.Bid = tick.Bid
return tickerPrice
tickerPrice.Low = tick.Low
tickerPrice.High = tick.High
tickerPrice.Volume = tick.Volume
tickerPrice.Last = tick.Last
ticker.ProcessTicker(a.GetName(), p, tickerPrice)
return tickerPrice, nil
}
func (a *Alphapoint) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tick, err := ticker.GetTicker(a.GetName(), p)
if err != nil {
return a.UpdateTicker(p)
}
return tick, nil
}
// GetOrderbookEx returns an orderbookbase by currency pair
func (a *Alphapoint) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(a.GetName(), p)
if err == nil {

View File

@@ -27,7 +27,7 @@ func (a *ANX) Run() {
for x := range pairs {
currency := pairs[x]
go func() {
ticker, err := a.GetTickerPrice(currency)
ticker, err := a.UpdateTicker(currency)
if err != nil {
log.Println(err)
return
@@ -40,12 +40,7 @@ func (a *ANX) Run() {
}
}
func (a *ANX) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(a.GetName(), p)
if err == nil {
return tickerNew, nil
}
func (a *ANX) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, err := a.GetTicker(p.Pair().String())
if err != nil {
@@ -111,6 +106,14 @@ func (a *ANX) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
return tickerPrice, nil
}
func (a *ANX) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(a.GetName(), p)
if err != nil {
return a.UpdateTicker(p)
}
return tickerNew, nil
}
func (e *ANX) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
return orderbook.OrderbookBase{}, nil
}

View File

@@ -44,7 +44,7 @@ func (b *Bitfinex) Run() {
for x := range pairs {
currency := pairs[x]
go func() {
ticker, err := b.GetTickerPrice(currency)
ticker, err := b.UpdateTicker(currency)
if err != nil {
return
}
@@ -56,18 +56,13 @@ func (b *Bitfinex) Run() {
}
}
// GetTickerPrice returns ticker information
func (b *Bitfinex) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tick, err := ticker.GetTicker(b.GetName(), p)
if err == nil {
return tick, nil
}
func (b *Bitfinex) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tickerNew, err := b.GetTicker(p.Pair().String(), nil)
if err != nil {
return tickerPrice, err
}
tickerPrice.Pair = p
tickerPrice.Ask = tickerNew.Ask
tickerPrice.Bid = tickerNew.Bid
@@ -79,7 +74,14 @@ func (b *Bitfinex) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, erro
return tickerPrice, nil
}
// GetOrderbookEx returns orderbook information based on currency pair
func (b *Bitfinex) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tick, err := ticker.GetTicker(b.GetName(), p)
if err != nil {
return b.UpdateTicker(p)
}
return tick, nil
}
func (b *Bitfinex) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p)
if err == nil {

View File

@@ -34,7 +34,7 @@ func (b *Bitstamp) Run() {
for x := range pairs {
currency := pairs[x]
go func() {
ticker, err := b.GetTickerPrice(currency)
ticker, err := b.UpdateTicker(currency)
if err != nil {
log.Println(err)
return
@@ -47,13 +47,7 @@ func (b *Bitstamp) Run() {
}
}
// GetTickerPrice returns ticker price information
func (b *Bitstamp) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(b.GetName(), p)
if err == nil {
return tickerNew, nil
}
func (b *Bitstamp) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, err := b.GetTicker(p.Pair().String(), false)
if err != nil {
@@ -71,7 +65,14 @@ func (b *Bitstamp) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, erro
return tickerPrice, nil
}
// GetOrderbookEx returns base orderbook information
func (b *Bitstamp) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tick, err := ticker.GetTicker(b.GetName(), p)
if err != nil {
return b.UpdateTicker(p)
}
return tick, nil
}
func (b *Bitstamp) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p)
if err == nil {

View File

@@ -32,7 +32,7 @@ func (b *BTCC) Run() {
for x := range pairs {
currency := pairs[x]
go func() {
ticker, err := b.GetTickerPrice(currency)
ticker, err := b.UpdateTicker(currency)
if err != nil {
log.Println(err)
return
@@ -45,18 +45,12 @@ func (b *BTCC) Run() {
}
}
func (b *BTCC) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(b.GetName(), p)
if err == nil {
return tickerNew, nil
}
func (b *BTCC) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, err := b.GetTicker(exchange.FormatExchangeCurrency(b.GetName(), p).String())
if err != nil {
return tickerPrice, err
}
tickerPrice.Pair = p
tickerPrice.Ask = tick.Sell
tickerPrice.Bid = tick.Buy
@@ -68,6 +62,14 @@ func (b *BTCC) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
return tickerPrice, nil
}
func (b *BTCC) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(b.GetName(), p)
if err != nil {
return b.UpdateTicker(p)
}
return tickerNew, nil
}
func (b *BTCC) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p)
if err == nil {

View File

@@ -50,9 +50,14 @@ func (b *BTCE) Run() {
}
}
func (b *BTCE) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
func (b *BTCE) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, ok := b.Ticker[exchange.FormatExchangeCurrency(b.Name, p).String()]
result, err := b.GetTicker(p.Pair().String())
if err != nil {
return tickerPrice, err
}
tick, ok := result[p.Pair().Lower().String()]
if !ok {
return tickerPrice, errors.New("unable to get currency")
}
@@ -67,6 +72,14 @@ func (b *BTCE) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
return tickerPrice, nil
}
func (b *BTCE) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tick, err := ticker.GetTicker(b.GetName(), p)
if err != nil {
return b.UpdateTicker(p)
}
return tick, nil
}
func (b *BTCE) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(b.GetName(), p)
if err == nil {

View File

@@ -57,7 +57,7 @@ func (b *BTCMarkets) Run() {
for x := range pairs {
curr := pairs[x]
go func() {
ticker, err := b.GetTickerPrice(curr)
ticker, err := b.UpdateTicker(curr)
if err != nil {
return
}
@@ -73,13 +73,7 @@ func (b *BTCMarkets) Run() {
}
}
// GetTickerPrice returns ticker information
func (b *BTCMarkets) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(b.GetName(), p)
if err == nil {
return tickerNew, nil
}
func (b *BTCMarkets) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, err := b.GetTicker(p.GetFirstCurrency().String())
if err != nil {
@@ -92,6 +86,13 @@ func (b *BTCMarkets) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, er
ticker.ProcessTicker(b.GetName(), p, tickerPrice)
return tickerPrice, nil
}
func (b *BTCMarkets) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(b.GetName(), p)
if err != nil {
return b.UpdateTicker(p)
}
return tickerNew, nil
}
// GetOrderbookEx returns orderbook base on the currency pair
func (b *BTCMarkets) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {

View File

@@ -50,7 +50,7 @@ func (c *COINUT) Run() {
for x := range pairs {
currency := pairs[x]
go func() {
ticker, err := c.GetTickerPrice(currency)
ticker, err := c.UpdateTicker(currency)
if err != nil {
log.Println(err)
return
@@ -84,12 +84,7 @@ func (c *COINUT) GetExchangeAccountInfo() (exchange.AccountInfo, error) {
return response, nil
}
func (c *COINUT) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(c.GetName(), p)
if err == nil {
return tickerNew, nil
}
func (c *COINUT) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, err := c.GetInstrumentTicker(c.InstrumentMap[p.Pair().String()])
if err != nil {
@@ -103,6 +98,15 @@ func (c *COINUT) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error)
tickerPrice.Low = tick.LowestSell
ticker.ProcessTicker(c.GetName(), p, tickerPrice)
return tickerPrice, nil
}
func (c *COINUT) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(c.GetName(), p)
if err != nil {
return c.UpdateTicker(p)
}
return tickerNew, nil
}
func (c *COINUT) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {

View File

@@ -64,6 +64,7 @@ type IBotExchange interface {
GetName() string
IsEnabled() bool
GetTickerPrice(currency pair.CurrencyPair) (ticker.TickerPrice, error)
UpdateTicker(currency pair.CurrencyPair) (ticker.TickerPrice, error)
GetOrderbookEx(currency pair.CurrencyPair) (orderbook.OrderbookBase, error)
GetEnabledCurrencies() []pair.CurrencyPair
GetExchangeAccountInfo() (AccountInfo, error)

View File

@@ -48,7 +48,7 @@ func (g *GDAX) Run() {
for x := range pairs {
currency := pairs[x]
go func() {
ticker, err := g.GetTickerPrice(currency)
ticker, err := g.UpdateTicker(currency)
if err != nil {
log.Println(err)
@@ -81,12 +81,7 @@ func (g *GDAX) GetExchangeAccountInfo() (exchange.AccountInfo, error) {
return response, nil
}
func (g *GDAX) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(g.GetName(), p)
if err == nil {
return tickerNew, nil
}
func (g *GDAX) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, err := g.GetTicker(exchange.FormatExchangeCurrency(g.Name, p).String())
if err != nil {
@@ -108,6 +103,14 @@ func (g *GDAX) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
return tickerPrice, nil
}
func (g *GDAX) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(g.GetName(), p)
if err != nil {
return g.UpdateTicker(p)
}
return tickerNew, nil
}
func (g *GDAX) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(g.GetName(), p)
if err == nil {

View File

@@ -37,7 +37,7 @@ func (g *Gemini) Run() {
for x := range pairs {
currency := pairs[x]
go func() {
ticker, err := g.GetTickerPrice(currency)
ticker, err := g.UpdateTicker(currency)
if err != nil {
log.Println(err)
return
@@ -63,18 +63,12 @@ func (e *Gemini) GetExchangeAccountInfo() (exchange.AccountInfo, error) {
exchangeCurrency.CurrencyName = accountBalance[i].Currency
exchangeCurrency.TotalValue = accountBalance[i].Amount
exchangeCurrency.Hold = accountBalance[i].Available
response.Currencies = append(response.Currencies, exchangeCurrency)
}
return response, nil
}
func (g *Gemini) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(g.GetName(), p)
if err == nil {
return tickerNew, nil
}
func (g *Gemini) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, err := g.GetTicker(p.Pair().String())
if err != nil {
@@ -89,6 +83,14 @@ func (g *Gemini) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error)
return tickerPrice, nil
}
func (g *Gemini) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(g.GetName(), p)
if err != nil {
return g.UpdateTicker(p)
}
return tickerNew, nil
}
func (g *Gemini) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(g.GetName(), p)
if err == nil {

View File

@@ -33,7 +33,7 @@ func (h *HUOBI) Run() {
for x := range pairs {
curr := pairs[x]
go func() {
ticker, err := h.GetTickerPrice(curr)
ticker, err := h.UpdateTicker(curr)
if err != nil {
log.Println(err)
return
@@ -50,12 +50,7 @@ func (h *HUOBI) Run() {
}
}
func (h *HUOBI) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(h.GetName(), p)
if err == nil {
return tickerNew, nil
}
func (h *HUOBI) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, err := h.GetTicker(p.GetFirstCurrency().Lower().String())
if err != nil {
@@ -72,6 +67,14 @@ func (h *HUOBI) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error)
return tickerPrice, nil
}
func (h *HUOBI) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(h.GetName(), p)
if err != nil {
return h.UpdateTicker(p)
}
return tickerNew, nil
}
func (h *HUOBI) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(h.GetName(), p)
if err == nil {

View File

@@ -26,7 +26,7 @@ func (i *ItBit) Run() {
for x := range pairs {
currency := pairs[x]
go func() {
ticker, err := i.GetTickerPrice(currency)
ticker, err := i.UpdateTicker(currency)
if err != nil {
log.Println(err)
return
@@ -39,12 +39,7 @@ func (i *ItBit) Run() {
}
}
func (i *ItBit) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(i.GetName(), p)
if err == nil {
return tickerNew, nil
}
func (i *ItBit) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, err := i.GetTicker(p.Pair().String())
if err != nil {
@@ -62,6 +57,14 @@ func (i *ItBit) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error)
return tickerPrice, nil
}
func (i *ItBit) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(i.GetName(), p)
if err != nil {
return i.UpdateTicker(p)
}
return tickerNew, nil
}
func (i *ItBit) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(i.GetName(), p)
if err == nil {

View File

@@ -57,6 +57,10 @@ func (k *Kraken) Run() {
}
}
func (k *Kraken) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
return ticker.TickerPrice{}, nil
}
//This will return the TickerPrice struct when tickers are completed here..
func (k *Kraken) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice

View File

@@ -26,7 +26,7 @@ func (l *LakeBTC) Run() {
pairs := l.GetEnabledCurrencies()
for x := range pairs {
currency := pairs[x]
ticker, err := l.GetTickerPrice(currency)
ticker, err := l.UpdateTicker(currency)
if err != nil {
log.Println(err)
continue
@@ -38,12 +38,7 @@ func (l *LakeBTC) Run() {
}
}
func (l *LakeBTC) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(l.GetName(), p)
if err == nil {
return tickerNew, nil
}
func (l *LakeBTC) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tick, err := l.GetTicker()
if err != nil {
return ticker.TickerPrice{}, err
@@ -66,6 +61,14 @@ func (l *LakeBTC) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error
return tickerPrice, nil
}
func (l *LakeBTC) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(l.GetName(), p)
if err != nil {
return l.UpdateTicker(p)
}
return tickerNew, nil
}
func (l *LakeBTC) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(l.GetName(), p)
if err == nil {

View File

@@ -61,6 +61,10 @@ func (l *Liqui) Run() {
}
}
func (l *Liqui) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
return ticker.TickerPrice{}, nil
}
func (l *Liqui) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, ok := l.Ticker[exchange.FormatExchangeCurrency(l.Name, p).String()]

View File

@@ -39,6 +39,10 @@ func (l *LocalBitcoins) Run() {
}
}
func (l *LocalBitcoins) UpdateTicker(p pair.CurrencyPair) (ticker.TickerPrice, error) {
return ticker.TickerPrice{}, nil
}
func (l *LocalBitcoins) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(l.GetName(), p)
if err == nil {

View File

@@ -46,7 +46,7 @@ func (o *OKCoin) Run() {
}()
}
go func() {
ticker, err := o.GetTickerPrice(curr)
ticker, err := o.UpdateTicker(curr)
if err != nil {
log.Println(err)
return
@@ -56,7 +56,7 @@ func (o *OKCoin) Run() {
}()
} else {
go func() {
ticker, err := o.GetTickerPrice(curr)
ticker, err := o.UpdateTicker(curr)
if err != nil {
log.Println(err)
return
@@ -74,12 +74,7 @@ func (o *OKCoin) Run() {
}
}
func (o *OKCoin) GetTickerPrice(currency pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(o.GetName(), currency)
if err == nil {
return tickerNew, nil
}
func (o *OKCoin) UpdateTicker(currency pair.CurrencyPair) (ticker.TickerPrice, error) {
var tickerPrice ticker.TickerPrice
tick, err := o.GetTicker(exchange.FormatExchangeCurrency(o.Name, currency).String())
if err != nil {
@@ -96,6 +91,14 @@ func (o *OKCoin) GetTickerPrice(currency pair.CurrencyPair) (ticker.TickerPrice,
return tickerPrice, nil
}
func (o *OKCoin) GetTickerPrice(currency pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(o.GetName(), currency)
if err != nil {
return o.UpdateTicker(currency)
}
return tickerNew, nil
}
func (o *OKCoin) GetOrderbookEx(currency pair.CurrencyPair) (orderbook.OrderbookBase, error) {
ob, err := orderbook.GetOrderbook(o.GetName(), currency)
if err == nil {

View File

@@ -32,7 +32,7 @@ func (p *Poloniex) Run() {
for x := range pairs {
currency := pairs[x]
go func() {
ticker, err := p.GetTickerPrice(currency)
ticker, err := p.UpdateTicker(currency)
if err != nil {
log.Println(err)
return
@@ -45,13 +45,8 @@ func (p *Poloniex) Run() {
}
}
func (p *Poloniex) GetTickerPrice(currencyPair pair.CurrencyPair) (ticker.TickerPrice, error) {
func (p *Poloniex) UpdateTicker(currencyPair pair.CurrencyPair) (ticker.TickerPrice, error) {
currency := currencyPair.Pair().String()
tickerNew, err := ticker.GetTicker(p.GetName(), currencyPair)
if err == nil {
return tickerNew, nil
}
var tickerPrice ticker.TickerPrice
tick, err := p.GetTicker()
if err != nil {
@@ -69,6 +64,14 @@ func (p *Poloniex) GetTickerPrice(currencyPair pair.CurrencyPair) (ticker.Ticker
return tickerPrice, nil
}
func (p *Poloniex) GetTickerPrice(currencyPair pair.CurrencyPair) (ticker.TickerPrice, error) {
tickerNew, err := ticker.GetTicker(p.GetName(), currencyPair)
if err != nil {
return p.UpdateTicker(currencyPair)
}
return tickerNew, nil
}
func (p *Poloniex) GetOrderbookEx(currencyPair pair.CurrencyPair) (orderbook.OrderbookBase, error) {
currency := currencyPair.Pair().String()
ob, err := orderbook.GetOrderbook(p.GetName(), currencyPair)

View File

@@ -187,6 +187,11 @@ func main() {
SeedExchangeAccountInfo(GetAllEnabledExchangeAccountInfo().Data)
go portfolio.StartPortfolioWatcher()
log.Println("Starting websocket handler")
go WebsocketHandler()
go TickerUpdaterRoutine()
if bot.config.Webserver.Enabled {
err := bot.config.CheckWebserverConfigValues()
if err != nil {

View File

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

37
routines.go Normal file
View File

@@ -0,0 +1,37 @@
package main
import (
"log"
"time"
"github.com/thrasher-/gocryptotrader/currency/pair"
)
func TickerUpdaterRoutine() {
log.Println("Starting ticker updater routine")
for {
for x := range bot.exchanges {
if bot.exchanges[x].IsEnabled() {
exchangeName := bot.exchanges[x].GetName()
enabledCurrencies := bot.exchanges[x].GetEnabledCurrencies()
for _, y := range enabledCurrencies {
currency := pair.NewCurrencyPair(y[0:3], y[3:])
result, err := bot.exchanges[x].UpdateTicker(currency)
if err != nil {
log.Printf("failed to get %s currency", currency.Pair().String())
continue
}
evt := WebsocketEvent{
Data: result,
Event: "ticker_update",
Exchange: exchangeName,
}
BroadcastWebsocketMessage(evt)
}
}
}
time.Sleep(time.Second * 10)
}
}

View File

@@ -10,31 +10,35 @@ import (
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
)
func jsonTickerResponse(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
currency := vars["currency"]
exchangeName := vars["exchangeName"]
var response ticker.TickerPrice
func GetSpecificTicker(currency, exchangeName string) (ticker.TickerPrice, error) {
var specificTicker ticker.TickerPrice
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 {
response, err = bot.exchanges[i].GetTickerPrice(
specificTicker, err = bot.exchanges[i].GetTickerPrice(
pair.NewCurrencyPairFromString(currency),
)
if err != nil {
log.Println(err)
continue
}
break
}
}
}
return specificTicker, err
}
func jsonTickerResponse(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
currency := vars["currency"]
exchange := vars["exchangeName"]
response, err := GetSpecificTicker(currency, exchange)
if err != nil {
log.Printf("Failed to fetch ticker for %s currency: %s\n", exchange,
currency)
return
}
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
encoder := json.NewEncoder(w)
if err = encoder.Encode(response); err != nil {
if err := json.NewEncoder(w).Encode(response); err != nil {
panic(err)
}
}
@@ -51,8 +55,8 @@ type EnabledExchangeCurrencies struct {
ExchangeValues []ticker.TickerPrice `json:"exchangeValues"`
}
func getAllActiveTickersResponse(w http.ResponseWriter, r *http.Request) {
var response AllEnabledExchangeCurrencies
func GetAllActiveTickers() []EnabledExchangeCurrencies {
var tickerData []EnabledExchangeCurrencies
for _, individualBot := range bot.exchanges {
if individualBot != nil && individualBot.IsEnabled() {
@@ -74,9 +78,16 @@ func getAllActiveTickersResponse(w http.ResponseWriter, r *http.Request) {
individualExchange.ExchangeValues, tickerPrice,
)
}
response.Data = append(response.Data, individualExchange)
tickerData = append(tickerData, individualExchange)
}
}
return tickerData
}
func getAllActiveTickersResponse(w http.ResponseWriter, r *http.Request) {
var response AllEnabledExchangeCurrencies
response.Data = GetAllActiveTickers()
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(response); err != nil {

View File

@@ -0,0 +1,221 @@
package main
import (
"log"
"net/http"
"time"
"github.com/gorilla/websocket"
"github.com/thrasher-/gocryptotrader/common"
)
var (
WSConn *websocket.Conn
)
type WebsocketEvent struct {
Event string `json:"event"`
Data interface{} `json:"data"`
Exchange string `json:"exchange,omitempty"`
}
type WebsocketAuth struct {
Username string `json:"username"`
Password string `json:"password"`
}
type WebsocketEventResponse struct {
Event string `json:"event"`
Data interface{} `json:"data"`
Error string `json:"error"`
}
type WebsocketTickerRequest struct {
Exchange string `json:"exchangeName"`
Currency string `json:"currency"`
}
func SendWebsocketAuth(username, password string) error {
pwHash := common.HexEncodeToString(common.GetSHA256([]byte(password)))
req := WebsocketEvent{
Event: "auth",
Data: WebsocketAuth{
Username: username,
Password: pwHash,
},
}
return SendWebsocketMsg(req)
}
func SendWebsocketMsg(data interface{}) error {
return WSConn.WriteJSON(data)
}
func GetWebsocketTicker(currency string) error {
wsevt := WebsocketEvent{
Event: "ticker",
Data: currency,
}
return SendWebsocketMsg(wsevt)
}
func main() {
var Dialer websocket.Dialer
var err error
WSConn, _, err = Dialer.Dial("ws://localhost:9050/ws", http.Header{})
if err != nil {
log.Println("Unable to connect to websocket server")
return
}
log.Println("Connected to websocket!")
log.Println("Authenticating..")
SendWebsocketAuth("username", "password")
var wsResp WebsocketEventResponse
err = WSConn.ReadJSON(&wsResp)
if err != nil {
log.Println(err)
return
}
if wsResp.Error != "" {
log.Fatal(wsResp.Error)
}
log.Println("Authenticated successfully")
log.Println("Getting config..")
req := WebsocketEvent{
Event: "GetConfig",
}
err = WSConn.WriteJSON(req)
if err != nil {
log.Println(err)
return
}
err = WSConn.ReadJSON(&wsResp)
if err != nil {
log.Println(err)
return
}
if wsResp.Error != "" {
log.Fatal(wsResp.Error)
}
log.Printf("Fetched config.")
req = WebsocketEvent{
Event: "SaveConfig",
Data: wsResp.Data,
}
log.Println("Saving config..")
err = WSConn.WriteJSON(req)
if err != nil {
log.Fatal(err)
}
err = WSConn.ReadJSON(&wsResp)
if err != nil {
log.Println(err)
return
}
if wsResp.Error != "" {
log.Fatal(wsResp.Error)
}
log.Println("Saved config!")
log.Println("Getting account info..")
req = WebsocketEvent{
Event: "GetAccountInfo",
}
err = WSConn.WriteJSON(req)
if err != nil {
log.Println(err)
return
}
err = WSConn.ReadJSON(&wsResp)
if err != nil {
log.Println(err)
return
}
if wsResp.Error != "" {
log.Fatal(wsResp.Error)
}
log.Println("Getting tickers..")
req = WebsocketEvent{
Event: "GetTickers",
}
err = WSConn.WriteJSON(req)
if err != nil {
log.Println(err)
return
}
err = WSConn.ReadJSON(&wsResp)
if err != nil {
log.Println(err)
return
}
if wsResp.Error != "" {
log.Fatal(wsResp.Error)
}
log.Println("Getting specific ticker..")
var tickReq WebsocketTickerRequest
tickReq.Currency = "LTCUSD"
tickReq.Exchange = "Bitfinex"
req = WebsocketEvent{
Event: "GetTicker",
Data: tickReq,
}
err = WSConn.WriteJSON(req)
if err != nil {
log.Println(err)
return
}
err = WSConn.ReadJSON(&wsResp)
if err != nil {
log.Println(err)
return
}
if wsResp.Error != "" {
log.Fatal(wsResp.Error)
}
log.Println(wsResp)
for {
msgType, resp, err := WSConn.ReadMessage()
if err != nil {
log.Fatal(err)
}
log.Println(msgType)
log.Println(string(resp))
}
time.Sleep(time.Second * 10)
WSConn.Close()
}

270
websocket.go Normal file
View File

@@ -0,0 +1,270 @@
package main
import (
"errors"
"log"
"net/http"
"time"
"github.com/gorilla/websocket"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
WebsocketResponseSuccess = "OK"
)
var WebsocketRoutes = Routes{
Route{
"ws",
"GET",
"/ws",
WebsocketClientHandler,
},
}
type WebsocketClient struct {
ID int
Conn *websocket.Conn
LastRecv time.Time
Authenticated bool
}
type WebsocketEvent struct {
Exchange string `json:"exchange,omitempty"`
Event string
Data interface{}
}
type WebsocketEventResponse struct {
Event string `json:"event"`
Data interface{} `json:"data"`
Error string `json:"error"`
}
type WebsocketTickerRequest struct {
Exchange string `json:"exchangeName"`
Currency string `json:"currency"`
}
var WebsocketClientHub []WebsocketClient
func WebsocketClientHandler(w http.ResponseWriter, r *http.Request) {
upgrader := websocket.Upgrader{
WriteBufferSize: 1024,
ReadBufferSize: 1024,
}
newClient := WebsocketClient{
ID: len(WebsocketClientHub),
}
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
newClient.Conn = conn
WebsocketClientHub = append(WebsocketClientHub, newClient)
log.Println("New websocket client connected.")
}
func DisconnectWebsocketClient(id int, err error) {
for i := range WebsocketClientHub {
if WebsocketClientHub[i].ID == id {
WebsocketClientHub[i].Conn.Close()
WebsocketClientHub = append(WebsocketClientHub[:i], WebsocketClientHub[i+1:]...)
log.Printf("Disconnected Websocket client, error: %s", err)
return
}
}
}
func SendWebsocketMessage(id int, data interface{}) error {
for _, x := range WebsocketClientHub {
if x.ID == id {
return x.Conn.WriteJSON(data)
}
}
return nil
}
func BroadcastWebsocketMessage(evt WebsocketEvent) error {
log.Println(evt)
for _, x := range WebsocketClientHub {
x.Conn.WriteJSON(evt)
}
return nil
}
type WebsocketAuth struct {
Username string `json:"username"`
Password string `json:"password"`
}
func WebsocketHandler() {
for {
for x := range WebsocketClientHub {
msgType, msg, err := WebsocketClientHub[x].Conn.ReadMessage()
if err != nil {
DisconnectWebsocketClient(x, err)
continue
}
if msgType != websocket.TextMessage {
DisconnectWebsocketClient(x, err)
continue
}
var evt WebsocketEvent
err = common.JSONDecode(msg, &evt)
if err != nil {
log.Println(err)
continue
}
if evt.Event == "" {
DisconnectWebsocketClient(x, errors.New("Websocket client sent data we did not understand"))
continue
}
dataJSON, err := common.JSONEncode(evt.Data)
if err != nil {
log.Println(err)
continue
}
if !WebsocketClientHub[x].Authenticated && evt.Event != "auth" {
wsResp := WebsocketEventResponse{
Event: "auth",
Error: "you must authenticate first",
}
SendWebsocketMessage(x, wsResp)
DisconnectWebsocketClient(x, errors.New("Websocket client did not auth"))
continue
} else if !WebsocketClientHub[x].Authenticated && evt.Event == "auth" {
var auth WebsocketAuth
err = common.JSONDecode(dataJSON, &auth)
if err != nil {
log.Println(err)
continue
}
hashPW := common.HexEncodeToString(common.GetSHA256([]byte("password")))
if auth.Username == "username" && auth.Password == hashPW {
WebsocketClientHub[x].Authenticated = true
wsResp := WebsocketEventResponse{
Event: "auth",
Data: WebsocketResponseSuccess,
}
SendWebsocketMessage(x, wsResp)
log.Println("Websocket client authenticated successfully")
continue
} else {
wsResp := WebsocketEventResponse{
Event: "auth",
Error: "invalid username/password",
}
SendWebsocketMessage(x, wsResp)
DisconnectWebsocketClient(x, errors.New("Websocket client sent wrong username/password"))
continue
}
}
switch evt.Event {
case "GetConfig":
wsResp := WebsocketEventResponse{
Event: "GetConfig",
Data: bot.config,
}
SendWebsocketMessage(x, wsResp)
continue
case "SaveConfig":
wsResp := WebsocketEventResponse{
Event: "SaveConfig",
}
var cfg config.Config
err := common.JSONDecode(dataJSON, &cfg)
if err != nil {
wsResp.Error = err.Error()
SendWebsocketMessage(x, wsResp)
log.Println(err)
continue
}
//Save change the settings
for x := range bot.config.Exchanges {
for i := 0; i < len(cfg.Exchanges); i++ {
if cfg.Exchanges[i].Name == bot.config.Exchanges[x].Name {
bot.config.Exchanges[x].Enabled = cfg.Exchanges[i].Enabled
bot.config.Exchanges[x].APIKey = cfg.Exchanges[i].APIKey
bot.config.Exchanges[x].APISecret = cfg.Exchanges[i].APISecret
bot.config.Exchanges[x].EnabledPairs = cfg.Exchanges[i].EnabledPairs
}
}
}
//Reload the configuration
err = bot.config.SaveConfig(bot.configFile)
if err != nil {
wsResp.Error = err.Error()
SendWebsocketMessage(x, wsResp)
continue
}
err = bot.config.LoadConfig(bot.configFile)
if err != nil {
wsResp.Error = err.Error()
SendWebsocketMessage(x, wsResp)
continue
}
setupBotExchanges()
wsResp.Data = WebsocketResponseSuccess
SendWebsocketMessage(x, wsResp)
continue
case "GetAccountInfo":
accountInfo := GetAllEnabledExchangeAccountInfo()
wsResp := WebsocketEventResponse{
Event: "GetAccountInfo",
Data: accountInfo,
}
SendWebsocketMessage(x, wsResp)
continue
case "GetTicker":
wsResp := WebsocketEventResponse{
Event: "GetTicker",
}
var tickerReq WebsocketTickerRequest
err := common.JSONDecode(dataJSON, &tickerReq)
if err != nil {
wsResp.Error = err.Error()
SendWebsocketMessage(x, wsResp)
log.Println(err)
continue
}
data, err := GetSpecificTicker(tickerReq.Currency,
tickerReq.Exchange)
if err != nil {
wsResp.Error = err.Error()
SendWebsocketMessage(x, wsResp)
log.Println(err)
continue
}
wsResp.Data = data
SendWebsocketMessage(x, wsResp)
continue
case "GetTickers":
wsResp := WebsocketEventResponse{
Event: "GetTickers",
}
tickers := GetAllActiveTickers()
wsResp.Data = tickers
SendWebsocketMessage(x, wsResp)
continue
}
}
time.Sleep(time.Millisecond)
}
}