Files
gocryptotrader/engine/exchange_manager.go
Jaydeep Rajpurohit 247da918a8 exchanges: Add ByBit support (#887)
* few fixes and add ratelimiter

* adds test

* revert configtest.json changes

* configtest updated

* WIP: adds public endpoint support

* WIP: adds public endpoint support

* adds public endpoint support

* WIP: adds auth. endpoint support

* adds test for auth. endpoint

* fixes

* adds auth. endpoint support

* WIP: ws support

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* Testing

* Complete WS spot testing

* adds support for ws events

* minor change

* WIP: adds REST support for CoinMarginedFutures

* Fixes

* WIP: adds REST support for CoinMarginedFutures

* Fixes

* improvement in SPOT REST

* Typo fix

* WIP: add REST support for CMF Account API

* minor fixes

* WIP: add support for CMF conditional orders and few minor fixes

* complete support for CMF conditional orders

* adds support for public CMF endpoint

* adds support for CMF position API

* Complete REST CMF support

* WIP

* Testing REST CMF support

* Testing REST CMF support

* Testing REST CMF support completed

* WIP: add support for UMF

* completed non-auth UMF

* WIP: add support for REST Auth. UMF

* WIP: add support for REST Auth. UMF and some improvements

* WIP

* WIP

* WIP

* completed REST UMF

* renaming

* adds REST support for futures

* add testcases for UMF and some optimizations

* add testcases for futures

* Testing UMF, futures and its changes

* Fixes

* Fixes after testing

* WIP

* WIP

* WIP

* completed ws USDT futures support

* WIP: ws support for futures

* fixes in WS futures

* fixes in WS support

* roll back changes made for WS CMF, USDT and Futures

* fixes

* WIP

* WIP

* fixes

* Steps for new PR

* WIP

* WIP

* WIP

* WIP

* complete PR setup

* fixes for successfully running tests

* update in symbol for futures pair in test file

* WIP

* Fixes in test file and other minor fix

* fix testdata/configtest.json

* reset CONTRIBUTORS file

* review changes

* remove unwanted file

* remove redundant code

* improvisation

* adds comment for exported functions

* remove unwanted TODO and commented code

* fix

* improvisation

* fix

* defined errors

* improvisation

* improvisation

* improvisation

* updates test

* adds comment for exported types

* review changes

* review changes

* fix

* fixes

* Changes for making BYBIT compatible with existing code base

* Test file changes

* Changes for making BYBIT compatible with existing code base

* Changes for making BYBIT compatible with existing code base

* fix lint issues

* fix

* review changes

* review changes

* review changes

* review changes

* review changes

* review changes

* review changes

* review changes

* review changes

* review changes

* WIP

* add test cases for new API's

* minor improvements

* add missing API and their tests

* minor fixes

* add bybitTime

* add bybitTimeSec, bybitTimeMilliSec, bybitTimeNanoSec and necessary support

* fix GetTradeHistory function

* error handling

* test fixes

* add GetServerTime API

* adds GetHistoricCandlesExtended and review changes

* test fixes

* minor fix

* integrating CMF Bybit recent change log

* minor fixes

* adds extractCurrencyPair

* minor fixes

* minor fix

* review changes

* adds variable declaration of error

* review commit

* adds embeddable type in API response for all API and integrate it

* fixes

* adds authentication WS connection

* review changes

* review changes

* compatible changes

* adds asset to GetWithdrawalsHistory

* adds asset_type in rpc.proto

* adds asset argument in gctcli withdrawal request command

* improve error handling in exchange API error

* web socket fix

* review changes

* improvements

* improvements

* minor fix

* review changes

* fixing wrapper issues

* fixes

* fixes

* review changes

* add test cases

* fix for GetActiveOrders

* lint fixes

* fixes in websocket

* adds wrapper testcases

* adds wrapper testcases

* adds wrapper testcases

* fixes

* fix issue with GetHistoricCandlesExtended

* fix merge issues

* improving error reporting

* adds wrapper testcases and a minor fix

* gctrpc changes

* adds test cases
fixes in websocket

* review changes for ws

* review changes in WS

* fix gctrpc

* merge fixes

* review changes

* WIP

* updates pair in configs

* adds new asset USDCMarginedFutures

* adds URL const for USDCMarginedFutures

* adds API support

* minor fixes

* adds kline API

* minor fix

* adds API

* adds API

* adds API

* WIP

* WIP

* WIP

* adds support for USDC auth requests to SendAuthHTTPRequest

* adds SendUSDCAuthHTTPRequest

* run test and fix them

* rollback support added for Auth. USDC request inside SendAuthHTTPRequest

* adds API and test cases

* adds API and test cases

* adds APIs and test cases

* adds APIs

* adds rate limit for USDC

* adds USDCMarginedFutures to wrapper

* adds USDC testcases in wrapper and fix few issues

* minor test fixes

* minor test fixes

* fix lint issues

* WIP

* Merge changes

* minor fixes

* remove "else" and optimize

* review changes

* review changes

* review changes

* fix lint issue

* merge fix

* fix test

* fix templates and run them

* changes after merge

* review changes and improvements

* code improvement

* fixes with respect to changes in API response in documentation

* fixed review change in test

* adds check in CancelExistingOrder

* update exchange template

* review changes

* adds GetDepositAddress API

* WIP: adds GetOrderHistory

* complete GetOrderHistory

* fixes

* adds test case

* fixes and add WithdrawFund API

* WIP

* WIP

* updating all SendAuthHTTPRequest call

* adds WithdrawCryptocurrencyFunds

* update test cases

* fix lint issues

* fixes after merge

* adds GetAvailableTransferChains and few fixes

* minor fix in GetDepositAddress

* minor fix with WS ping/pong handling

* add ping handler for WS Auth.

* fix typo mistake

* update doc
2022-08-08 11:29:43 +10:00

212 lines
6.3 KiB
Go

package engine
import (
"errors"
"fmt"
"strings"
"sync"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/binance"
"github.com/thrasher-corp/gocryptotrader/exchanges/bitfinex"
"github.com/thrasher-corp/gocryptotrader/exchanges/bitflyer"
"github.com/thrasher-corp/gocryptotrader/exchanges/bithumb"
"github.com/thrasher-corp/gocryptotrader/exchanges/bitmex"
"github.com/thrasher-corp/gocryptotrader/exchanges/bitstamp"
"github.com/thrasher-corp/gocryptotrader/exchanges/bittrex"
"github.com/thrasher-corp/gocryptotrader/exchanges/btcmarkets"
"github.com/thrasher-corp/gocryptotrader/exchanges/btse"
"github.com/thrasher-corp/gocryptotrader/exchanges/bybit"
"github.com/thrasher-corp/gocryptotrader/exchanges/coinbasepro"
"github.com/thrasher-corp/gocryptotrader/exchanges/coinut"
"github.com/thrasher-corp/gocryptotrader/exchanges/exmo"
"github.com/thrasher-corp/gocryptotrader/exchanges/ftx"
"github.com/thrasher-corp/gocryptotrader/exchanges/gateio"
"github.com/thrasher-corp/gocryptotrader/exchanges/gemini"
"github.com/thrasher-corp/gocryptotrader/exchanges/hitbtc"
"github.com/thrasher-corp/gocryptotrader/exchanges/huobi"
"github.com/thrasher-corp/gocryptotrader/exchanges/itbit"
"github.com/thrasher-corp/gocryptotrader/exchanges/kraken"
"github.com/thrasher-corp/gocryptotrader/exchanges/lbank"
"github.com/thrasher-corp/gocryptotrader/exchanges/localbitcoins"
"github.com/thrasher-corp/gocryptotrader/exchanges/okcoin"
"github.com/thrasher-corp/gocryptotrader/exchanges/okex"
"github.com/thrasher-corp/gocryptotrader/exchanges/poloniex"
"github.com/thrasher-corp/gocryptotrader/exchanges/yobit"
"github.com/thrasher-corp/gocryptotrader/exchanges/zb"
"github.com/thrasher-corp/gocryptotrader/log"
)
// vars related to exchange functions
var (
ErrNoExchangesLoaded = errors.New("no exchanges have been loaded")
ErrExchangeNotFound = errors.New("exchange not found")
ErrExchangeAlreadyLoaded = errors.New("exchange already loaded")
ErrExchangeFailedToLoad = errors.New("exchange failed to load")
ErrExchangeNameIsEmpty = errors.New("exchange name is empty")
)
// CustomExchangeBuilder interface allows external applications to create
// custom/unsupported exchanges that satisfy the IBotExchange interface.
type CustomExchangeBuilder interface {
NewExchangeByName(name string) (exchange.IBotExchange, error)
}
// ExchangeManager manages what exchanges are loaded
type ExchangeManager struct {
m sync.Mutex
exchanges map[string]exchange.IBotExchange
Builder CustomExchangeBuilder
}
// SetupExchangeManager creates a new exchange manager
func SetupExchangeManager() *ExchangeManager {
return &ExchangeManager{
exchanges: make(map[string]exchange.IBotExchange),
}
}
// Add adds or replaces an exchange
func (m *ExchangeManager) Add(exch exchange.IBotExchange) {
if exch == nil {
return
}
m.m.Lock()
m.exchanges[strings.ToLower(exch.GetName())] = exch
m.m.Unlock()
}
// GetExchanges returns all stored exchanges
func (m *ExchangeManager) GetExchanges() ([]exchange.IBotExchange, error) {
if m == nil {
return nil, fmt.Errorf("exchange manager: %w", ErrNilSubsystem)
}
m.m.Lock()
defer m.m.Unlock()
exchs := make([]exchange.IBotExchange, 0, len(m.exchanges))
for _, x := range m.exchanges {
exchs = append(exchs, x)
}
return exchs, nil
}
// RemoveExchange removes an exchange from the manager
func (m *ExchangeManager) RemoveExchange(exchName string) error {
if m.Len() == 0 {
return ErrNoExchangesLoaded
}
exch, err := m.GetExchangeByName(exchName)
if err != nil {
return err
}
m.m.Lock()
defer m.m.Unlock()
err = exch.GetBase().Requester.Shutdown()
if err != nil {
return err
}
delete(m.exchanges, strings.ToLower(exchName))
log.Infof(log.ExchangeSys, "%s exchange unloaded successfully.\n", exchName)
return nil
}
// GetExchangeByName returns an exchange by its name if it exists
func (m *ExchangeManager) GetExchangeByName(exchangeName string) (exchange.IBotExchange, error) {
if m == nil {
return nil, fmt.Errorf("exchange manager: %w", ErrNilSubsystem)
}
if exchangeName == "" {
return nil, fmt.Errorf("exchange manager: %w", ErrExchangeNameIsEmpty)
}
m.m.Lock()
defer m.m.Unlock()
exch, ok := m.exchanges[strings.ToLower(exchangeName)]
if !ok {
return nil, fmt.Errorf("%s %w", exchangeName, ErrExchangeNotFound)
}
return exch, nil
}
// Len says how many exchanges are loaded
func (m *ExchangeManager) Len() int {
m.m.Lock()
defer m.m.Unlock()
return len(m.exchanges)
}
// NewExchangeByName helps create a new exchange to be loaded
func (m *ExchangeManager) NewExchangeByName(name string) (exchange.IBotExchange, error) {
if m == nil {
return nil, fmt.Errorf("exchange manager %w", ErrNilSubsystem)
}
nameLower := strings.ToLower(name)
if exch, _ := m.GetExchangeByName(nameLower); exch != nil {
return nil, fmt.Errorf("%s %w", name, ErrExchangeAlreadyLoaded)
}
var exch exchange.IBotExchange
switch nameLower {
case "binance":
exch = new(binance.Binance)
case "bitfinex":
exch = new(bitfinex.Bitfinex)
case "bitflyer":
exch = new(bitflyer.Bitflyer)
case "bithumb":
exch = new(bithumb.Bithumb)
case "bitmex":
exch = new(bitmex.Bitmex)
case "bitstamp":
exch = new(bitstamp.Bitstamp)
case "bittrex":
exch = new(bittrex.Bittrex)
case "btc markets":
exch = new(btcmarkets.BTCMarkets)
case "btse":
exch = new(btse.BTSE)
case "bybit":
exch = new(bybit.Bybit)
case "coinut":
exch = new(coinut.COINUT)
case "exmo":
exch = new(exmo.EXMO)
case "coinbasepro":
exch = new(coinbasepro.CoinbasePro)
case "ftx":
exch = new(ftx.FTX)
case "gateio":
exch = new(gateio.Gateio)
case "gemini":
exch = new(gemini.Gemini)
case "hitbtc":
exch = new(hitbtc.HitBTC)
case "huobi":
exch = new(huobi.HUOBI)
case "itbit":
exch = new(itbit.ItBit)
case "kraken":
exch = new(kraken.Kraken)
case "lbank":
exch = new(lbank.Lbank)
case "localbitcoins":
exch = new(localbitcoins.LocalBitcoins)
case "okcoin international":
exch = new(okcoin.OKCoin)
case "okex":
exch = new(okex.OKEX)
case "poloniex":
exch = new(poloniex.Poloniex)
case "yobit":
exch = new(yobit.Yobit)
case "zb":
exch = new(zb.ZB)
default:
if m.Builder != nil {
return m.Builder.NewExchangeByName(nameLower)
}
return nil, fmt.Errorf("%s, %w", nameLower, ErrExchangeNotFound)
}
return exch, nil
}