mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-04 07:26:47 +00:00
cmd/exchange_template, exchanges: Update templates and propogate to exchanges (#1777)
* Added TimeInForce type and updated related files * Linter issue fix and minor coinbasepro type update * Bitrex consts update * added unit test and minor changes in bittrex * Unit tests update * Fix minor linter issues * Update TestStringToTimeInForce unit test * Exchange test template change * A different approach * fix conflict with gateio timeInForce * minor exchange template update * Minor fix to test_files template * Update order tests * Complete updating the order unit tests * Updating exchange wrapper and test template files * update kucoin and deribit wrapper to match the time in force change * minor comment update * fix time-in-force related test errors * linter issue fix * ADD_NEW_EXCHANGE documentation update * time in force constants, functions and unit tests update * shift tif policies to TimeInForce * Update time-in-force, related functions, and unit tests * fix linter issue and time-in-force processing * added a good till crossing tif value * order type fix and fix related tim-in-force entries * update time-in-force unmarshaling and unit test * consistency guideline added * fix time-in-force error in gateio * linter issue fix * update based on review comments * add unit test and fix missing issues * minor fix and added benchmark unit test * change GTT to GTC for limit * fix linter issue * added time-in-force value to place order param * fix minor issues based on review comment and move tif code to separate files * update on exchanges linked to time-in-force * resolve missing review comments * minor linter issues fix * added time-in-force handler and update timeInForce parametered endpoint * minor fixes based on review * nits fix * update based on review * linter fix * rm getTimeInForce func and minor change to time-in-force * minor change * update based on review comments * wrappers and time-in-force calling approach * minor change * update gateio string to timeInForce conversion and unit test * update exchange template * update wrapper template file * policy comments, and template files update * rename all exchange types name to Exchange * update on template files and template generation * templates and generation code and other updates * linter issue fix * added subscriptions and websocket templates * update ADD_NEW_EXCHANGE.md with recent binance functions and implementations * rename template files and update unit tests * minor template and unit test fix * rename templates and fix on unit tests * update on template files and documentation * removed unnecessary tag fix and update templates * fix Add_NEW_EXCHANGE.md doc file * formatting, comments, and error checks update on template files * rename exchange receivers to e and ex for consistency * rename unit test exchange receiver and minor updates * linter issues fix * fix deribit issue and minor style update * fix test issues caused by receiver change * raname local variables exchange declaration variables * update templates comments * update templates and related comments * renamed ex to e * update template comments * toggle WS to false to improve coverage * template comments update * added test coverage to Ws enabled and minor changes --------- Co-authored-by: Samuel Reid <43227667+cranktakular@users.noreply.github.com>
This commit is contained in:
@@ -53,16 +53,16 @@ const (
|
||||
|
||||
var errSymbolIsEmpty = errors.New("symbol cannot be empty")
|
||||
|
||||
// Bithumb is the overarching type across the Bithumb package
|
||||
type Bithumb struct {
|
||||
// Exchange implements exchange.IBotExchange and contains additional specific api methods for interacting with Bithumb
|
||||
type Exchange struct {
|
||||
exchange.Base
|
||||
location *time.Location
|
||||
obm orderbookManager
|
||||
}
|
||||
|
||||
// GetTradablePairs returns a list of tradable currencies
|
||||
func (b *Bithumb) GetTradablePairs(ctx context.Context) ([]string, error) {
|
||||
result, err := b.GetAllTickers(ctx)
|
||||
func (e *Exchange) GetTradablePairs(ctx context.Context) ([]string, error) {
|
||||
result, err := e.GetAllTickers(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -77,9 +77,9 @@ func (b *Bithumb) GetTradablePairs(ctx context.Context) ([]string, error) {
|
||||
// GetTicker returns ticker information
|
||||
//
|
||||
// symbol e.g. "btc"
|
||||
func (b *Bithumb) GetTicker(ctx context.Context, symbol string) (Ticker, error) {
|
||||
func (e *Exchange) GetTicker(ctx context.Context, symbol string) (Ticker, error) {
|
||||
var response TickerResponse
|
||||
err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicTicker+strings.ToUpper(symbol), &response)
|
||||
err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicTicker+strings.ToUpper(symbol), &response)
|
||||
if err != nil {
|
||||
return response.Data, err
|
||||
}
|
||||
@@ -92,9 +92,9 @@ func (b *Bithumb) GetTicker(ctx context.Context, symbol string) (Ticker, error)
|
||||
}
|
||||
|
||||
// GetAllTickers returns all ticker information
|
||||
func (b *Bithumb) GetAllTickers(ctx context.Context) (map[string]Ticker, error) {
|
||||
func (e *Exchange) GetAllTickers(ctx context.Context) (map[string]Ticker, error) {
|
||||
var response TickersResponse
|
||||
err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicTicker+"all", &response)
|
||||
err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicTicker+"all", &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -121,9 +121,9 @@ func (b *Bithumb) GetAllTickers(ctx context.Context) (map[string]Ticker, error)
|
||||
// GetOrderBook returns current orderbook
|
||||
//
|
||||
// symbol e.g. "btc"
|
||||
func (b *Bithumb) GetOrderBook(ctx context.Context, symbol string) (*Orderbook, error) {
|
||||
func (e *Exchange) GetOrderBook(ctx context.Context, symbol string) (*Orderbook, error) {
|
||||
response := Orderbook{}
|
||||
err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderBook+strings.ToUpper(symbol), &response)
|
||||
err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderBook+strings.ToUpper(symbol), &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -136,12 +136,12 @@ func (b *Bithumb) GetOrderBook(ctx context.Context, symbol string) (*Orderbook,
|
||||
}
|
||||
|
||||
// GetAssetStatus returns the withdrawal and deposit status for the symbol
|
||||
func (b *Bithumb) GetAssetStatus(ctx context.Context, symbol string) (*Status, error) {
|
||||
func (e *Exchange) GetAssetStatus(ctx context.Context, symbol string) (*Status, error) {
|
||||
if symbol == "" {
|
||||
return nil, errSymbolIsEmpty
|
||||
}
|
||||
var response Status
|
||||
err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicAssetStatus+strings.ToUpper(symbol), &response)
|
||||
err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicAssetStatus+strings.ToUpper(symbol), &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -154,9 +154,9 @@ func (b *Bithumb) GetAssetStatus(ctx context.Context, symbol string) (*Status, e
|
||||
}
|
||||
|
||||
// GetAssetStatusAll returns the withdrawal and deposit status for all symbols
|
||||
func (b *Bithumb) GetAssetStatusAll(ctx context.Context) (*StatusAll, error) {
|
||||
func (e *Exchange) GetAssetStatusAll(ctx context.Context) (*StatusAll, error) {
|
||||
var response StatusAll
|
||||
err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicAssetStatus+"ALL", &response)
|
||||
err := e.SendHTTPRequest(ctx, exchange.RestSpot, publicAssetStatus+"ALL", &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -171,12 +171,12 @@ func (b *Bithumb) GetAssetStatusAll(ctx context.Context) (*StatusAll, error) {
|
||||
// GetTransactionHistory returns recent transactions
|
||||
//
|
||||
// symbol e.g. "btc"
|
||||
func (b *Bithumb) GetTransactionHistory(ctx context.Context, symbol string) (TransactionHistory, error) {
|
||||
func (e *Exchange) GetTransactionHistory(ctx context.Context, symbol string) (TransactionHistory, error) {
|
||||
response := TransactionHistory{}
|
||||
path := publicTransactionHistory +
|
||||
strings.ToUpper(symbol)
|
||||
|
||||
err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response)
|
||||
err := e.SendHTTPRequest(ctx, exchange.RestSpot, path, &response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
@@ -190,7 +190,7 @@ func (b *Bithumb) GetTransactionHistory(ctx context.Context, symbol string) (Tra
|
||||
|
||||
// GetAccountInformation returns account information based on the desired
|
||||
// order/payment currencies
|
||||
func (b *Bithumb) GetAccountInformation(ctx context.Context, orderCurrency, paymentCurrency string) (Account, error) {
|
||||
func (e *Exchange) GetAccountInformation(ctx context.Context, orderCurrency, paymentCurrency string) (Account, error) {
|
||||
var response Account
|
||||
if orderCurrency == "" {
|
||||
return response, errSymbolIsEmpty
|
||||
@@ -203,11 +203,11 @@ func (b *Bithumb) GetAccountInformation(ctx context.Context, orderCurrency, paym
|
||||
}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateAccInfo, val, &response)
|
||||
e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateAccInfo, val, &response)
|
||||
}
|
||||
|
||||
// GetAccountBalance returns customer wallet information
|
||||
func (b *Bithumb) GetAccountBalance(ctx context.Context, c string) (FullBalance, error) {
|
||||
func (e *Exchange) GetAccountBalance(ctx context.Context, c string) (FullBalance, error) {
|
||||
var response Balance
|
||||
fullBalance := FullBalance{
|
||||
make(map[string]float64),
|
||||
@@ -222,7 +222,7 @@ func (b *Bithumb) GetAccountBalance(ctx context.Context, c string) (FullBalance,
|
||||
vals.Set("currency", c)
|
||||
}
|
||||
|
||||
err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateAccBalance, vals, &response)
|
||||
err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateAccBalance, vals, &response)
|
||||
if err != nil {
|
||||
return fullBalance, err
|
||||
}
|
||||
@@ -260,12 +260,12 @@ func (b *Bithumb) GetAccountBalance(ctx context.Context, c string) (FullBalance,
|
||||
// GetWalletAddress returns customer wallet address
|
||||
//
|
||||
// currency e.g. btc, ltc or "", will default to btc without currency specified
|
||||
func (b *Bithumb) GetWalletAddress(ctx context.Context, curr currency.Code) (WalletAddressRes, error) {
|
||||
func (e *Exchange) GetWalletAddress(ctx context.Context, curr currency.Code) (WalletAddressRes, error) {
|
||||
response := WalletAddressRes{}
|
||||
params := url.Values{}
|
||||
params.Set("currency", curr.Upper().String())
|
||||
|
||||
err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateWalletAdd, params, &response)
|
||||
err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateWalletAdd, params, &response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
@@ -303,11 +303,11 @@ func (b *Bithumb) GetWalletAddress(ctx context.Context, curr currency.Code) (Wal
|
||||
}
|
||||
|
||||
// GetLastTransaction returns customer last transaction
|
||||
func (b *Bithumb) GetLastTransaction(ctx context.Context) (LastTransactionTicker, error) {
|
||||
func (e *Exchange) GetLastTransaction(ctx context.Context) (LastTransactionTicker, error) {
|
||||
response := LastTransactionTicker{}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateTicker, nil, &response)
|
||||
e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateTicker, nil, &response)
|
||||
}
|
||||
|
||||
// GetOrders returns order list
|
||||
@@ -317,7 +317,7 @@ func (b *Bithumb) GetLastTransaction(ctx context.Context) (LastTransactionTicker
|
||||
// count: Value : 1 ~1000 (default : 100)
|
||||
// after: YYYY-MM-DD hh:mm:ss's UNIX Timestamp
|
||||
// (2014-11-28 16:40:01 = 1417160401000)
|
||||
func (b *Bithumb) GetOrders(ctx context.Context, orderID, transactionType string, count int64, after time.Time, orderCurrency, paymentCurrency currency.Code) (Orders, error) {
|
||||
func (e *Exchange) GetOrders(ctx context.Context, orderID, transactionType string, count int64, after time.Time, orderCurrency, paymentCurrency currency.Code) (Orders, error) {
|
||||
response := Orders{}
|
||||
params := url.Values{}
|
||||
|
||||
@@ -347,11 +347,11 @@ func (b *Bithumb) GetOrders(ctx context.Context, orderID, transactionType string
|
||||
}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateOrders, params, &response)
|
||||
e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateOrders, params, &response)
|
||||
}
|
||||
|
||||
// GetUserTransactions returns customer transactions
|
||||
func (b *Bithumb) GetUserTransactions(ctx context.Context, offset, count, searchType int64, orderCurrency, paymentCurrency currency.Code) (UserTransactions, error) {
|
||||
func (e *Exchange) GetUserTransactions(ctx context.Context, offset, count, searchType int64, orderCurrency, paymentCurrency currency.Code) (UserTransactions, error) {
|
||||
params := url.Values{}
|
||||
if offset > 0 {
|
||||
params.Set("offset", strconv.FormatInt(offset, 10))
|
||||
@@ -370,7 +370,7 @@ func (b *Bithumb) GetUserTransactions(ctx context.Context, offset, count, search
|
||||
}
|
||||
var response UserTransactions
|
||||
|
||||
return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateUserTrans, params, &response)
|
||||
return response, e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateUserTrans, params, &response)
|
||||
}
|
||||
|
||||
// PlaceTrade executes a trade order
|
||||
@@ -380,7 +380,7 @@ func (b *Bithumb) GetUserTransactions(ctx context.Context, offset, count, search
|
||||
// transactionType: Transaction type(bid : purchase, ask : sales)
|
||||
// units: Order quantity
|
||||
// price: Transaction amount per currency
|
||||
func (b *Bithumb) PlaceTrade(ctx context.Context, orderCurrency, transactionType string, units float64, price int64) (OrderPlace, error) {
|
||||
func (e *Exchange) PlaceTrade(ctx context.Context, orderCurrency, transactionType string, units float64, price int64) (OrderPlace, error) {
|
||||
response := OrderPlace{}
|
||||
|
||||
params := url.Values{}
|
||||
@@ -391,7 +391,7 @@ func (b *Bithumb) PlaceTrade(ctx context.Context, orderCurrency, transactionType
|
||||
params.Set("price", strconv.FormatInt(price, 10))
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privatePlaceTrade, params, &response)
|
||||
e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privatePlaceTrade, params, &response)
|
||||
}
|
||||
|
||||
// GetOrderDetails returns specific order details
|
||||
@@ -400,7 +400,7 @@ func (b *Bithumb) PlaceTrade(ctx context.Context, orderCurrency, transactionType
|
||||
// transactionType: Transaction type(bid : purchase, ask : sales)
|
||||
// currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS
|
||||
// (default value: BTC)
|
||||
func (b *Bithumb) GetOrderDetails(ctx context.Context, orderID, transactionType, currency string) (OrderDetails, error) {
|
||||
func (e *Exchange) GetOrderDetails(ctx context.Context, orderID, transactionType, currency string) (OrderDetails, error) {
|
||||
response := OrderDetails{}
|
||||
|
||||
params := url.Values{}
|
||||
@@ -409,7 +409,7 @@ func (b *Bithumb) GetOrderDetails(ctx context.Context, orderID, transactionType,
|
||||
params.Set("currency", strings.ToUpper(currency))
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateOrderDetail, params, &response)
|
||||
e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateOrderDetail, params, &response)
|
||||
}
|
||||
|
||||
// CancelTrade cancels a customer purchase/sales transaction
|
||||
@@ -417,7 +417,7 @@ func (b *Bithumb) GetOrderDetails(ctx context.Context, orderID, transactionType,
|
||||
// orderID: Order number registered for purchase/sales
|
||||
// currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS
|
||||
// (default value: BTC)
|
||||
func (b *Bithumb) CancelTrade(ctx context.Context, transactionType, orderID, currency string) (ActionStatus, error) {
|
||||
func (e *Exchange) CancelTrade(ctx context.Context, transactionType, orderID, currency string) (ActionStatus, error) {
|
||||
response := ActionStatus{}
|
||||
|
||||
params := url.Values{}
|
||||
@@ -426,7 +426,7 @@ func (b *Bithumb) CancelTrade(ctx context.Context, transactionType, orderID, cur
|
||||
params.Set("currency", strings.ToUpper(currency))
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateCancelTrade, nil, &response)
|
||||
e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateCancelTrade, nil, &response)
|
||||
}
|
||||
|
||||
// WithdrawCrypto withdraws a customer currency to an address
|
||||
@@ -437,7 +437,7 @@ func (b *Bithumb) CancelTrade(ctx context.Context, transactionType, orderID, cur
|
||||
// currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM
|
||||
// (default value: BTC)
|
||||
// units: Quantity to withdraw currency
|
||||
func (b *Bithumb) WithdrawCrypto(ctx context.Context, address, destination, currency string, units float64) (ActionStatus, error) {
|
||||
func (e *Exchange) WithdrawCrypto(ctx context.Context, address, destination, currency string, units float64) (ActionStatus, error) {
|
||||
response := ActionStatus{}
|
||||
|
||||
params := url.Values{}
|
||||
@@ -449,16 +449,16 @@ func (b *Bithumb) WithdrawCrypto(ctx context.Context, address, destination, curr
|
||||
params.Set("units", strconv.FormatFloat(units, 'f', -1, 64))
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateBTCWithdraw, params, &response)
|
||||
e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateBTCWithdraw, params, &response)
|
||||
}
|
||||
|
||||
// RequestKRWDepositDetails returns Bithumb banking details for deposit
|
||||
// information
|
||||
func (b *Bithumb) RequestKRWDepositDetails(ctx context.Context) (KRWDeposit, error) {
|
||||
func (e *Exchange) RequestKRWDepositDetails(ctx context.Context) (KRWDeposit, error) {
|
||||
response := KRWDeposit{}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateKRWDeposit, nil, &response)
|
||||
e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateKRWDeposit, nil, &response)
|
||||
}
|
||||
|
||||
// RequestKRWWithdraw allows a customer KRW withdrawal request
|
||||
@@ -466,7 +466,7 @@ func (b *Bithumb) RequestKRWDepositDetails(ctx context.Context) (KRWDeposit, err
|
||||
// bank: Bankcode with bank name e.g. (bankcode)_(bankname)
|
||||
// account: Withdrawing bank account number
|
||||
// price: Withdrawing amount
|
||||
func (b *Bithumb) RequestKRWWithdraw(ctx context.Context, bank, account string, price int64) (ActionStatus, error) {
|
||||
func (e *Exchange) RequestKRWWithdraw(ctx context.Context, bank, account string, price int64) (ActionStatus, error) {
|
||||
response := ActionStatus{}
|
||||
|
||||
params := url.Values{}
|
||||
@@ -475,7 +475,7 @@ func (b *Bithumb) RequestKRWWithdraw(ctx context.Context, bank, account string,
|
||||
params.Set("price", strconv.FormatInt(price, 10))
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateKRWWithdraw, params, &response)
|
||||
e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateKRWWithdraw, params, &response)
|
||||
}
|
||||
|
||||
// MarketBuyOrder initiates a buy order through available order books
|
||||
@@ -483,7 +483,7 @@ func (b *Bithumb) RequestKRWWithdraw(ctx context.Context, bank, account string,
|
||||
// currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS
|
||||
// (default value: BTC)
|
||||
// units: Order quantity
|
||||
func (b *Bithumb) MarketBuyOrder(ctx context.Context, pair currency.Pair, units float64) (MarketBuy, error) {
|
||||
func (e *Exchange) MarketBuyOrder(ctx context.Context, pair currency.Pair, units float64) (MarketBuy, error) {
|
||||
response := MarketBuy{}
|
||||
|
||||
params := url.Values{}
|
||||
@@ -492,7 +492,7 @@ func (b *Bithumb) MarketBuyOrder(ctx context.Context, pair currency.Pair, units
|
||||
params.Set("units", strconv.FormatFloat(units, 'f', -1, 64))
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateMarketBuy, params, &response)
|
||||
e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateMarketBuy, params, &response)
|
||||
}
|
||||
|
||||
// MarketSellOrder initiates a sell order through available order books
|
||||
@@ -500,7 +500,7 @@ func (b *Bithumb) MarketBuyOrder(ctx context.Context, pair currency.Pair, units
|
||||
// currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS
|
||||
// (default value: BTC)
|
||||
// units: Order quantity
|
||||
func (b *Bithumb) MarketSellOrder(ctx context.Context, pair currency.Pair, units float64) (MarketSell, error) {
|
||||
func (e *Exchange) MarketSellOrder(ctx context.Context, pair currency.Pair, units float64) (MarketSell, error) {
|
||||
response := MarketSell{}
|
||||
|
||||
params := url.Values{}
|
||||
@@ -509,12 +509,12 @@ func (b *Bithumb) MarketSellOrder(ctx context.Context, pair currency.Pair, units
|
||||
params.Set("units", strconv.FormatFloat(units, 'f', -1, 64))
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateMarketSell, params, &response)
|
||||
e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateMarketSell, params, &response)
|
||||
}
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (b *Bithumb) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error {
|
||||
endpoint, err := b.API.Endpoints.GetURL(ep)
|
||||
func (e *Exchange) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result any) error {
|
||||
endpoint, err := e.API.Endpoints.GetURL(ep)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -522,22 +522,22 @@ func (b *Bithumb) SendHTTPRequest(ctx context.Context, ep exchange.URL, path str
|
||||
Method: http.MethodGet,
|
||||
Path: endpoint + path,
|
||||
Result: result,
|
||||
Verbose: b.Verbose,
|
||||
HTTPDebugging: b.HTTPDebugging,
|
||||
HTTPRecording: b.HTTPRecording,
|
||||
Verbose: e.Verbose,
|
||||
HTTPDebugging: e.HTTPDebugging,
|
||||
HTTPRecording: e.HTTPRecording,
|
||||
}
|
||||
return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) {
|
||||
return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) {
|
||||
return item, nil
|
||||
}, request.UnauthenticatedRequest)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated HTTP request to bithumb
|
||||
func (b *Bithumb) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, path string, params url.Values, result any) error {
|
||||
creds, err := b.GetCredentials(ctx)
|
||||
func (e *Exchange) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, path string, params url.Values, result any) error {
|
||||
creds, err := e.GetCredentials(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
endpoint, err := b.API.Endpoints.GetURL(ep)
|
||||
endpoint, err := e.API.Endpoints.GetURL(ep)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -546,7 +546,7 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.
|
||||
}
|
||||
|
||||
var intermediary json.RawMessage
|
||||
err = b.SendPayload(ctx, request.Auth, func() (*request.Item, error) {
|
||||
err = e.SendPayload(ctx, request.Auth, func() (*request.Item, error) {
|
||||
// This is time window sensitive
|
||||
n := strconv.FormatInt(time.Now().UnixMilli(), 10)
|
||||
|
||||
@@ -573,9 +573,9 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.
|
||||
Body: bytes.NewBufferString(payload),
|
||||
Result: &intermediary,
|
||||
NonceEnabled: true,
|
||||
Verbose: b.Verbose,
|
||||
HTTPDebugging: b.HTTPDebugging,
|
||||
HTTPRecording: b.HTTPRecording,
|
||||
Verbose: e.Verbose,
|
||||
HTTPDebugging: e.HTTPDebugging,
|
||||
HTTPRecording: e.HTTPRecording,
|
||||
}, nil
|
||||
}, request.AuthenticatedRequest)
|
||||
if err != nil {
|
||||
@@ -599,7 +599,7 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
func (b *Bithumb) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) {
|
||||
func (e *Exchange) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) {
|
||||
var fee float64
|
||||
|
||||
switch feeBuilder.FeeType {
|
||||
@@ -676,15 +676,15 @@ var errCode = map[string]string{
|
||||
}
|
||||
|
||||
// GetCandleStick returns candle stick data for requested pair
|
||||
func (b *Bithumb) GetCandleStick(ctx context.Context, symbol, interval string) (resp *OHLCVResponse, err error) {
|
||||
func (e *Exchange) GetCandleStick(ctx context.Context, symbol, interval string) (resp *OHLCVResponse, err error) {
|
||||
path := publicCandleStick + symbol + "/" + interval
|
||||
err = b.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp)
|
||||
err = e.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp)
|
||||
return
|
||||
}
|
||||
|
||||
// FetchExchangeLimits fetches spot order execution limits
|
||||
func (b *Bithumb) FetchExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) {
|
||||
ticks, err := b.GetAllTickers(ctx)
|
||||
func (e *Exchange) FetchExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) {
|
||||
ticks, err := e.GetAllTickers(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -29,18 +29,18 @@ const (
|
||||
|
||||
var testPair = currency.NewPairWithDelimiter("BTC", "KRW", "_")
|
||||
|
||||
var b = &Bithumb{}
|
||||
var e *Exchange
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
b = new(Bithumb)
|
||||
if err := testexch.Setup(b); err != nil {
|
||||
e = new(Exchange)
|
||||
if err := testexch.Setup(e); err != nil {
|
||||
log.Fatalf("Bithumb Setup error: %s", err)
|
||||
}
|
||||
|
||||
if apiKey != "" && apiSecret != "" {
|
||||
b.API.AuthenticatedSupport = true
|
||||
b.API.AuthenticatedWebsocketSupport = true
|
||||
b.SetCredentials(apiKey, apiSecret, "", "", "", "")
|
||||
e.API.AuthenticatedSupport = true
|
||||
e.API.AuthenticatedWebsocketSupport = true
|
||||
e.SetCredentials(apiKey, apiSecret, "", "", "", "")
|
||||
}
|
||||
|
||||
os.Exit(m.Run())
|
||||
@@ -48,13 +48,13 @@ func TestMain(m *testing.M) {
|
||||
|
||||
func TestGetTradablePairs(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetTradablePairs(t.Context())
|
||||
_, err := e.GetTradablePairs(t.Context())
|
||||
require.NoError(t, err, "GetTradablePairs must not error")
|
||||
}
|
||||
|
||||
func TestGetTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
tick, err := b.GetTicker(t.Context(), testPair.Base.String())
|
||||
tick, err := e.GetTicker(t.Context(), testPair.Base.String())
|
||||
require.NoError(t, err, "GetTicker must not error")
|
||||
assert.Positive(t, tick.OpeningPrice, "OpeningPrice should be positive")
|
||||
assert.Positive(t, tick.ClosingPrice, "ClosingPrice should be positive")
|
||||
@@ -73,14 +73,14 @@ func TestGetTicker(t *testing.T) {
|
||||
// not all currencies have dates and fluctuation rates
|
||||
func TestGetAllTickers(t *testing.T) {
|
||||
t.Parallel()
|
||||
tick, err := b.GetAllTickers(t.Context())
|
||||
tick, err := e.GetAllTickers(t.Context())
|
||||
require.NoError(t, err, "GetAllTickers must not error")
|
||||
assert.NotEmpty(t, tick, "tick should not be empty")
|
||||
}
|
||||
|
||||
func TestGetOrderBook(t *testing.T) {
|
||||
t.Parallel()
|
||||
ob, err := b.GetOrderBook(t.Context(), testPair.Base.String())
|
||||
ob, err := e.GetOrderBook(t.Context(), testPair.Base.String())
|
||||
require.NoError(t, err, "GetOrderBook must not error")
|
||||
assert.NotEmpty(t, ob.Status, "Status should not be empty")
|
||||
assert.NotEmpty(t, ob.Data.Timestamp, "Timestamp should not be empty")
|
||||
@@ -90,8 +90,8 @@ func TestGetOrderBook(t *testing.T) {
|
||||
|
||||
func TestGetTransactionHistory(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
_, err := b.GetTransactionHistory(t.Context(), testPair.Base.String())
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
_, err := e.GetTransactionHistory(t.Context(), testPair.Base.String())
|
||||
require.NoError(t, err, "GetTransactionHistory must not error")
|
||||
}
|
||||
|
||||
@@ -99,28 +99,28 @@ func TestGetAccountInformation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Offline test
|
||||
_, err := b.GetAccountInformation(t.Context(), "", "")
|
||||
_, err := e.GetAccountInformation(t.Context(), "", "")
|
||||
assert.Error(t, err, "expected error when no order currency is specified")
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
_, err = b.GetAccountInformation(t.Context(), testPair.Base.String(), testPair.Quote.String())
|
||||
_, err = e.GetAccountInformation(t.Context(), testPair.Base.String(), testPair.Quote.String())
|
||||
assert.NoError(t, err, "GetAccountInformation should not error")
|
||||
}
|
||||
|
||||
func TestGetAccountBalance(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
_, err := b.GetAccountBalance(t.Context(), testPair.Base.String())
|
||||
_, err := e.GetAccountBalance(t.Context(), testPair.Base.String())
|
||||
require.NoError(t, err, "GetAccountBalance must not error")
|
||||
}
|
||||
|
||||
func TestGetWalletAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
a, err := b.GetWalletAddress(t.Context(), testPair.Base)
|
||||
a, err := e.GetWalletAddress(t.Context(), testPair.Base)
|
||||
require.NoError(t, err, "GetWalletAddress must not error")
|
||||
assert.NotEmpty(t, a.Data.Currency, "Currency should not be empty")
|
||||
assert.NotEmpty(t, a.Data.Tag, "Tag should not be empty")
|
||||
@@ -129,96 +129,96 @@ func TestGetWalletAddress(t *testing.T) {
|
||||
|
||||
func TestGetLastTransaction(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
_, err := b.GetLastTransaction(t.Context())
|
||||
_, err := e.GetLastTransaction(t.Context())
|
||||
require.NoError(t, err, "GetLastTransaction must not error")
|
||||
}
|
||||
|
||||
func TestGetOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
_, err := b.GetOrders(t.Context(), "1337", order.Bid.Lower(), 100, time.Time{}, testPair.Base, testPair.Quote)
|
||||
_, err := e.GetOrders(t.Context(), "1337", order.Bid.Lower(), 100, time.Time{}, testPair.Base, testPair.Quote)
|
||||
require.NoError(t, err, "GetOrders must not error")
|
||||
}
|
||||
|
||||
func TestGetUserTransactions(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
_, err := b.GetUserTransactions(t.Context(), 0, 0, 0, currency.EMPTYCODE, currency.EMPTYCODE)
|
||||
_, err := e.GetUserTransactions(t.Context(), 0, 0, 0, currency.EMPTYCODE, currency.EMPTYCODE)
|
||||
require.NoError(t, err, "GetUserTransactions must not error")
|
||||
}
|
||||
|
||||
func TestPlaceTrade(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
_, err := b.PlaceTrade(t.Context(), testPair.Base.String(), order.Bid.Lower(), 0, 0)
|
||||
_, err := e.PlaceTrade(t.Context(), testPair.Base.String(), order.Bid.Lower(), 0, 0)
|
||||
require.NoError(t, err, "PlaceTrade must not error")
|
||||
}
|
||||
|
||||
func TestGetOrderDetails(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
_, err := b.GetOrderDetails(t.Context(), "1337", order.Bid.Lower(), testPair.Base.String())
|
||||
_, err := e.GetOrderDetails(t.Context(), "1337", order.Bid.Lower(), testPair.Base.String())
|
||||
require.NoError(t, err, "GetOrderDetails must not error")
|
||||
}
|
||||
|
||||
func TestCancelTrade(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
_, err := b.CancelTrade(t.Context(), "", "", "")
|
||||
_, err := e.CancelTrade(t.Context(), "", "", "")
|
||||
require.NoError(t, err, "CancelTrade must not error")
|
||||
}
|
||||
|
||||
func TestWithdrawCrypto(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
_, err := b.WithdrawCrypto(t.Context(), "LQxiDhKU7idKiWQhx4ALKYkBx8xKEQVxJR", "", "ltc", 0)
|
||||
_, err := e.WithdrawCrypto(t.Context(), "LQxiDhKU7idKiWQhx4ALKYkBx8xKEQVxJR", "", "ltc", 0)
|
||||
require.NoError(t, err, "WithdrawCrypto must not error")
|
||||
}
|
||||
|
||||
func TestRequestKRWDepositDetails(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
_, err := b.RequestKRWDepositDetails(t.Context())
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
_, err := e.RequestKRWDepositDetails(t.Context())
|
||||
require.NoError(t, err, "RequestKRWDepositDetails must not error")
|
||||
}
|
||||
|
||||
func TestRequestKRWWithdraw(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
_, err := b.RequestKRWWithdraw(t.Context(), "102_bank", "1337", 1000)
|
||||
_, err := e.RequestKRWWithdraw(t.Context(), "102_bank", "1337", 1000)
|
||||
require.NoError(t, err, "RequestKRWWithdraw must not error")
|
||||
}
|
||||
|
||||
func TestMarketBuyOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
_, err := b.MarketBuyOrder(t.Context(), testPair, 0)
|
||||
_, err := e.MarketBuyOrder(t.Context(), testPair, 0)
|
||||
require.NoError(t, err, "MarketBuyOrder must not error")
|
||||
}
|
||||
|
||||
func TestMarketSellOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
_, err := b.MarketSellOrder(t.Context(), testPair, 0)
|
||||
_, err := e.MarketSellOrder(t.Context(), testPair, 0)
|
||||
require.NoError(t, err, "MarketSellOrder must not error")
|
||||
}
|
||||
|
||||
func TestUpdateTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testexch.UpdatePairsOnce(t, b)
|
||||
tick, err := b.UpdateTicker(t.Context(), testPair, asset.Spot)
|
||||
testexch.UpdatePairsOnce(t, e)
|
||||
tick, err := e.UpdateTicker(t.Context(), testPair, asset.Spot)
|
||||
require.NoError(t, err, "UpdateTicker must not error")
|
||||
assert.Positive(t, tick.High, "High should be positive")
|
||||
assert.Positive(t, tick.Low, "Low should be positive")
|
||||
@@ -233,8 +233,8 @@ func TestUpdateTicker(t *testing.T) {
|
||||
func TestUpdateTickers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testexch.UpdatePairsOnce(t, b)
|
||||
err := b.UpdateTickers(t.Context(), asset.Spot)
|
||||
testexch.UpdatePairsOnce(t, e)
|
||||
err := e.UpdateTickers(t.Context(), asset.Spot)
|
||||
require.NoError(t, err, "UpdateTickers must not error")
|
||||
}
|
||||
|
||||
@@ -251,10 +251,10 @@ func setFeeBuilder() *exchange.FeeBuilder {
|
||||
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
t.Parallel()
|
||||
feeBuilder := setFeeBuilder()
|
||||
_, err := b.GetFeeByType(t.Context(), feeBuilder)
|
||||
_, err := e.GetFeeByType(t.Context(), feeBuilder)
|
||||
require.NoError(t, err, "GetFeeByType must not error")
|
||||
|
||||
if !sharedtestvalues.AreAPICredentialsSet(b) {
|
||||
if !sharedtestvalues.AreAPICredentialsSet(e) {
|
||||
assert.Equal(t, exchange.OfflineTradeFee, feeBuilder.FeeType, "FeeType should be correct")
|
||||
} else {
|
||||
assert.Equal(t, exchange.CryptocurrencyTradeFee, feeBuilder.FeeType, "FeeType should be correct")
|
||||
@@ -265,65 +265,65 @@ func TestGetFee(t *testing.T) {
|
||||
t.Parallel()
|
||||
feeBuilder := setFeeBuilder()
|
||||
// CryptocurrencyTradeFee Basic
|
||||
_, err := b.GetFee(feeBuilder)
|
||||
_, err := e.GetFee(feeBuilder)
|
||||
require.NoError(t, err, "GetFee must not error")
|
||||
|
||||
// CryptocurrencyTradeFee High quantity
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.Amount = 1000
|
||||
feeBuilder.PurchasePrice = 1000
|
||||
_, err = b.GetFee(feeBuilder)
|
||||
_, err = e.GetFee(feeBuilder)
|
||||
require.NoError(t, err, "GetFee must not error")
|
||||
|
||||
// CryptocurrencyTradeFee IsMaker
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.IsMaker = true
|
||||
_, err = b.GetFee(feeBuilder)
|
||||
_, err = e.GetFee(feeBuilder)
|
||||
require.NoError(t, err, "GetFee must not error")
|
||||
|
||||
// CryptocurrencyTradeFee Negative purchase price
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.PurchasePrice = -1000
|
||||
_, err = b.GetFee(feeBuilder)
|
||||
_, err = e.GetFee(feeBuilder)
|
||||
require.NoError(t, err, "GetFee must not error")
|
||||
|
||||
// CryptocurrencyWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
||||
_, err = b.GetFee(feeBuilder)
|
||||
_, err = e.GetFee(feeBuilder)
|
||||
require.NoError(t, err, "GetFee must not error")
|
||||
|
||||
// CryptocurrencyDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.CryptocurrencyDepositFee
|
||||
_, err = b.GetFee(feeBuilder)
|
||||
_, err = e.GetFee(feeBuilder)
|
||||
require.NoError(t, err, "GetFee must not error")
|
||||
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
_, err = b.GetFee(feeBuilder)
|
||||
_, err = e.GetFee(feeBuilder)
|
||||
require.NoError(t, err, "GetFee must not error")
|
||||
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
_, err = b.GetFee(feeBuilder)
|
||||
_, err = e.GetFee(feeBuilder)
|
||||
require.NoError(t, err, "GetFee must not error")
|
||||
}
|
||||
|
||||
func TestFormatWithdrawPermissions(t *testing.T) {
|
||||
t.Parallel()
|
||||
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.AutoWithdrawFiatText
|
||||
withdrawPermissions := b.FormatWithdrawPermissions()
|
||||
withdrawPermissions := e.FormatWithdrawPermissions()
|
||||
assert.Equal(t, expectedResult, withdrawPermissions, "withdrawPermissions should be correct")
|
||||
}
|
||||
|
||||
func TestGetActiveOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
getOrdersRequest := order.MultiOrderRequest{
|
||||
Type: order.AnyType,
|
||||
@@ -331,13 +331,13 @@ func TestGetActiveOrders(t *testing.T) {
|
||||
AssetType: asset.Spot,
|
||||
}
|
||||
|
||||
_, err := b.GetActiveOrders(t.Context(), &getOrdersRequest)
|
||||
_, err := e.GetActiveOrders(t.Context(), &getOrdersRequest)
|
||||
require.NoError(t, err, "GetActiveOrders must not error")
|
||||
}
|
||||
|
||||
func TestGetOrderHistory(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
getOrdersRequest := order.MultiOrderRequest{
|
||||
Type: order.AnyType,
|
||||
@@ -346,7 +346,7 @@ func TestGetOrderHistory(t *testing.T) {
|
||||
Pairs: currency.Pairs{testPair},
|
||||
}
|
||||
|
||||
_, err := b.GetOrderHistory(t.Context(), &getOrdersRequest)
|
||||
_, err := e.GetOrderHistory(t.Context(), &getOrdersRequest)
|
||||
require.NoError(t, err, "GetOrderHistory must not error")
|
||||
}
|
||||
|
||||
@@ -355,10 +355,10 @@ func TestGetOrderHistory(t *testing.T) {
|
||||
|
||||
func TestSubmitOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
orderSubmission := &order.Submit{
|
||||
Exchange: b.Name,
|
||||
Exchange: e.Name,
|
||||
Pair: testPair,
|
||||
Side: order.Buy,
|
||||
Type: order.Limit,
|
||||
@@ -367,13 +367,13 @@ func TestSubmitOrder(t *testing.T) {
|
||||
ClientID: "meowOrder",
|
||||
AssetType: asset.Spot,
|
||||
}
|
||||
_, err := b.SubmitOrder(t.Context(), orderSubmission)
|
||||
_, err := e.SubmitOrder(t.Context(), orderSubmission)
|
||||
require.NoError(t, err, "SubmitOrder must not error")
|
||||
}
|
||||
|
||||
func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
orderCancellation := &order.Cancel{
|
||||
OrderID: "1",
|
||||
@@ -382,13 +382,13 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
AssetType: asset.Spot,
|
||||
}
|
||||
|
||||
err := b.CancelOrder(t.Context(), orderCancellation)
|
||||
err := e.CancelOrder(t.Context(), orderCancellation)
|
||||
require.NoError(t, err, "CancelOrder must not error")
|
||||
}
|
||||
|
||||
func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
orderCancellation := &order.Cancel{
|
||||
OrderID: "1",
|
||||
@@ -397,7 +397,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
AssetType: asset.Spot,
|
||||
}
|
||||
|
||||
resp, err := b.CancelAllOrders(t.Context(), orderCancellation)
|
||||
resp, err := e.CancelAllOrders(t.Context(), orderCancellation)
|
||||
require.NoError(t, err, "CancelAllOrders must not error")
|
||||
|
||||
assert.Emptyf(t, resp.Status, "%v orders failed to cancel", len(resp.Status))
|
||||
@@ -405,17 +405,17 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
|
||||
func TestGetAccountInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
_, err := b.UpdateAccountInfo(t.Context(), asset.Spot)
|
||||
_, err := e.UpdateAccountInfo(t.Context(), asset.Spot)
|
||||
require.NoError(t, err, "UpdateAccountInfo must not error")
|
||||
}
|
||||
|
||||
func TestModifyOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
_, err := b.ModifyOrder(t.Context(), &order.Modify{
|
||||
_, err := e.ModifyOrder(t.Context(), &order.Modify{
|
||||
OrderID: "1337",
|
||||
Price: 100,
|
||||
Amount: 1000,
|
||||
@@ -428,21 +428,21 @@ func TestModifyOrder(t *testing.T) {
|
||||
|
||||
func TestWithdraw(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
t.Skip("TestWithdraw not allowed for live tests")
|
||||
}
|
||||
|
||||
func TestWithdrawFiat(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
withdrawFiatRequest := withdraw.Request{
|
||||
Type: withdraw.Fiat,
|
||||
Exchange: b.Name,
|
||||
Exchange: e.Name,
|
||||
Fiat: withdraw.FiatRequest{
|
||||
Bank: banking.Account{
|
||||
SupportedExchanges: b.Name,
|
||||
SupportedExchanges: e.Name,
|
||||
Enabled: true,
|
||||
AccountName: "Satoshi Nakamoto",
|
||||
AccountNumber: "12345",
|
||||
@@ -464,30 +464,30 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
|
||||
_, err := b.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest)
|
||||
_, err := e.WithdrawFiatFunds(t.Context(), &withdrawFiatRequest)
|
||||
require.NoError(t, err, "WithdrawFiatFunds must not error")
|
||||
}
|
||||
|
||||
func TestWithdrawInternationalBank(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
withdrawFiatRequest := withdraw.Request{}
|
||||
_, err := b.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest)
|
||||
_, err := e.WithdrawFiatFundsToInternationalBank(t.Context(), &withdrawFiatRequest)
|
||||
assert.ErrorIs(t, err, common.ErrFunctionNotSupported)
|
||||
}
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
_, err := b.GetDepositAddress(t.Context(), testPair.Base, "", "")
|
||||
_, err := e.GetDepositAddress(t.Context(), testPair.Base, "", "")
|
||||
require.NoError(t, err, "GetDepositAddress must not error")
|
||||
}
|
||||
|
||||
func TestGetCandleStick(t *testing.T) {
|
||||
t.Parallel()
|
||||
c, err := b.GetCandleStick(t.Context(), testPair.String(), "1m")
|
||||
c, err := e.GetCandleStick(t.Context(), testPair.String(), "1m")
|
||||
require.NoError(t, err, "GetCandleStick must not error")
|
||||
assert.NotEmpty(t, c.Status, "Status should not be empty")
|
||||
assert.NotEmpty(t, c.Data, "Data should not be empty")
|
||||
@@ -496,7 +496,7 @@ func TestGetCandleStick(t *testing.T) {
|
||||
func TestGetHistoricCandles(t *testing.T) {
|
||||
t.Parallel()
|
||||
startTime := time.Now().AddDate(0, -1, 0)
|
||||
c, err := b.GetHistoricCandles(t.Context(), testPair, asset.Spot, kline.OneDay, startTime, time.Now())
|
||||
c, err := e.GetHistoricCandles(t.Context(), testPair, asset.Spot, kline.OneDay, startTime, time.Now())
|
||||
require.NoError(t, err, "GetHistoricCandles must not error")
|
||||
assert.NotEmpty(t, c.Exchange, "Exchange should not be empty")
|
||||
assert.NotEmpty(t, c.Candles, "Candles should not be empty")
|
||||
@@ -505,14 +505,14 @@ func TestGetHistoricCandles(t *testing.T) {
|
||||
func TestGetHistoricCandlesExtended(t *testing.T) {
|
||||
t.Parallel()
|
||||
startTime := time.Now().Add(-time.Hour * 24)
|
||||
_, err := b.GetHistoricCandlesExtended(t.Context(), testPair, asset.Spot, kline.OneDay, startTime, time.Now())
|
||||
_, err := e.GetHistoricCandlesExtended(t.Context(), testPair, asset.Spot, kline.OneDay, startTime, time.Now())
|
||||
assert.ErrorIs(t, err, common.ErrFunctionNotSupported)
|
||||
}
|
||||
|
||||
func TestGetRecentTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tr, err := b.GetRecentTrades(t.Context(), testPair, asset.Spot)
|
||||
tr, err := e.GetRecentTrades(t.Context(), testPair, asset.Spot)
|
||||
require.NoError(t, err, "GetRecentTrades must not error")
|
||||
assert.NotEmpty(t, tr, "Trades should not be empty")
|
||||
for _, req := range tr {
|
||||
@@ -526,16 +526,16 @@ func TestGetRecentTrades(t *testing.T) {
|
||||
|
||||
func TestGetHistoricTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetHistoricTrades(t.Context(), testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now())
|
||||
_, err := e.GetHistoricTrades(t.Context(), testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now())
|
||||
assert.ErrorIs(t, err, common.ErrFunctionNotSupported)
|
||||
}
|
||||
|
||||
func TestUpdateOrderExecutionLimits(t *testing.T) {
|
||||
t.Parallel()
|
||||
err := b.UpdateOrderExecutionLimits(t.Context(), asset.Empty)
|
||||
err := e.UpdateOrderExecutionLimits(t.Context(), asset.Empty)
|
||||
require.NoError(t, err, "UpdateOrderExecutionLimits must not error")
|
||||
|
||||
limit, err := b.GetOrderExecutionLimits(asset.Spot, testPair)
|
||||
limit, err := e.GetOrderExecutionLimits(asset.Spot, testPair)
|
||||
require.NoError(t, err, "GetOrderExecutionLimits must not error")
|
||||
|
||||
err = limit.Conforms(46241000, 0.00001, order.Limit)
|
||||
@@ -595,10 +595,10 @@ func TestGetAmountMinimum(t *testing.T) {
|
||||
|
||||
func TestGetAssetStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetAssetStatus(t.Context(), "")
|
||||
_, err := e.GetAssetStatus(t.Context(), "")
|
||||
assert.ErrorIs(t, err, errSymbolIsEmpty)
|
||||
|
||||
s, err := b.GetAssetStatus(t.Context(), "sol")
|
||||
s, err := e.GetAssetStatus(t.Context(), "sol")
|
||||
require.NoError(t, err, "GetAssetStatus must not error")
|
||||
assert.NotEmpty(t, s.Status, "Status should not be empty")
|
||||
assert.NotEmpty(t, s.Data.DepositStatus, "DepositStatus should not be empty")
|
||||
@@ -607,7 +607,7 @@ func TestGetAssetStatus(t *testing.T) {
|
||||
|
||||
func TestGetAssetStatusAll(t *testing.T) {
|
||||
t.Parallel()
|
||||
s, err := b.GetAssetStatusAll(t.Context())
|
||||
s, err := e.GetAssetStatusAll(t.Context())
|
||||
require.NoError(t, err, "GetAssetStatusAll must not error")
|
||||
require.NoError(t, err, "GetAssetStatus must not error")
|
||||
assert.NotEmpty(t, s.Status, "Status should not be empty")
|
||||
@@ -615,42 +615,42 @@ func TestGetAssetStatusAll(t *testing.T) {
|
||||
|
||||
func TestUpdateCurrencyStates(t *testing.T) {
|
||||
t.Parallel()
|
||||
err := b.UpdateCurrencyStates(t.Context(), asset.Spot)
|
||||
err := e.UpdateCurrencyStates(t.Context(), asset.Spot)
|
||||
require.NoError(t, err, "UpdateCurrencyStates must not error")
|
||||
}
|
||||
|
||||
func TestGetWithdrawalsHistory(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
_, err := b.GetWithdrawalsHistory(t.Context(), testPair.Base, asset.Spot)
|
||||
_, err := e.GetWithdrawalsHistory(t.Context(), testPair.Base, asset.Spot)
|
||||
require.NoError(t, err, "GetWithdrawalsHistory must not error")
|
||||
}
|
||||
|
||||
func TestGetOrderInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
_, err := b.GetOrderInfo(t.Context(), "1234", testPair, asset.Spot)
|
||||
_, err := e.GetOrderInfo(t.Context(), "1234", testPair, asset.Spot)
|
||||
require.NoError(t, err, "GetOrderInfo must not error")
|
||||
}
|
||||
|
||||
func TestGetWithdrawalHistory(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
_, err := b.GetWithdrawalsHistory(t.Context(), testPair.Base, asset.Spot)
|
||||
_, err := e.GetWithdrawalsHistory(t.Context(), testPair.Base, asset.Spot)
|
||||
require.NoError(t, err, "GetWithdrawalsHistory must not error")
|
||||
}
|
||||
|
||||
func TestGetCurrencyTradeURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
testexch.UpdatePairsOnce(t, b)
|
||||
for _, a := range b.GetAssetTypes(false) {
|
||||
pairs, err := b.CurrencyPairs.GetPairs(a, false)
|
||||
testexch.UpdatePairsOnce(t, e)
|
||||
for _, a := range e.GetAssetTypes(false) {
|
||||
pairs, err := e.CurrencyPairs.GetPairs(a, false)
|
||||
require.NoErrorf(t, err, "cannot get pairs for %s", a)
|
||||
require.NotEmptyf(t, pairs, "no pairs for %s", a)
|
||||
resp, err := b.GetCurrencyTradeURL(t.Context(), a, pairs[0])
|
||||
resp, err := e.GetCurrencyTradeURL(t.Context(), a, pairs[0])
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, resp)
|
||||
}
|
||||
|
||||
@@ -35,50 +35,50 @@ var defaultSubscriptions = subscription.List{
|
||||
}
|
||||
|
||||
// WsConnect initiates a websocket connection
|
||||
func (b *Bithumb) WsConnect() error {
|
||||
func (e *Exchange) WsConnect() error {
|
||||
ctx := context.TODO()
|
||||
if !b.Websocket.IsEnabled() || !b.IsEnabled() {
|
||||
if !e.Websocket.IsEnabled() || !e.IsEnabled() {
|
||||
return websocket.ErrWebsocketNotEnabled
|
||||
}
|
||||
|
||||
var dialer gws.Dialer
|
||||
dialer.HandshakeTimeout = b.Config.HTTPTimeout
|
||||
dialer.HandshakeTimeout = e.Config.HTTPTimeout
|
||||
dialer.Proxy = http.ProxyFromEnvironment
|
||||
|
||||
err := b.Websocket.Conn.Dial(ctx, &dialer, http.Header{})
|
||||
err := e.Websocket.Conn.Dial(ctx, &dialer, http.Header{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v - Unable to connect to Websocket. Error: %w", b.Name, err)
|
||||
return fmt.Errorf("%v - Unable to connect to Websocket. Error: %w", e.Name, err)
|
||||
}
|
||||
|
||||
b.Websocket.Wg.Add(1)
|
||||
go b.wsReadData()
|
||||
e.Websocket.Wg.Add(1)
|
||||
go e.wsReadData()
|
||||
|
||||
b.setupOrderbookManager(ctx)
|
||||
e.setupOrderbookManager(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
// wsReadData receives and passes on websocket messages for processing
|
||||
func (b *Bithumb) wsReadData() {
|
||||
defer b.Websocket.Wg.Done()
|
||||
func (e *Exchange) wsReadData() {
|
||||
defer e.Websocket.Wg.Done()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-b.Websocket.ShutdownC:
|
||||
case <-e.Websocket.ShutdownC:
|
||||
return
|
||||
default:
|
||||
resp := b.Websocket.Conn.ReadMessage()
|
||||
resp := e.Websocket.Conn.ReadMessage()
|
||||
if resp.Raw == nil {
|
||||
return
|
||||
}
|
||||
err := b.wsHandleData(resp.Raw)
|
||||
err := e.wsHandleData(resp.Raw)
|
||||
if err != nil {
|
||||
b.Websocket.DataHandler <- err
|
||||
e.Websocket.DataHandler <- err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bithumb) wsHandleData(respRaw []byte) error {
|
||||
func (e *Exchange) wsHandleData(respRaw []byte) error {
|
||||
var resp WsResponse
|
||||
err := json.Unmarshal(respRaw, &resp)
|
||||
if err != nil {
|
||||
@@ -102,12 +102,12 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error {
|
||||
return err
|
||||
}
|
||||
var lu time.Time
|
||||
lu, err = time.ParseInLocation(tickerTimeLayout, tick.Date+tick.Time, b.location)
|
||||
lu, err = time.ParseInLocation(tickerTimeLayout, tick.Date+tick.Time, e.location)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.Websocket.DataHandler <- &ticker.Price{
|
||||
ExchangeName: b.Name,
|
||||
e.Websocket.DataHandler <- &ticker.Price{
|
||||
ExchangeName: e.Name,
|
||||
AssetType: asset.Spot,
|
||||
Last: tick.PreviousClosePrice,
|
||||
Pair: tick.Symbol,
|
||||
@@ -120,7 +120,7 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error {
|
||||
LastUpdated: lu,
|
||||
}
|
||||
case "transaction":
|
||||
if !b.IsSaveTradeDataEnabled() {
|
||||
if !e.IsSaveTradeDataEnabled() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -133,13 +133,13 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error {
|
||||
toBuffer := make([]trade.Data, len(trades.List))
|
||||
var lu time.Time
|
||||
for x := range trades.List {
|
||||
lu, err = time.ParseInLocation(tradeTimeLayout, trades.List[x].ContractTime, b.location)
|
||||
lu, err = time.ParseInLocation(tradeTimeLayout, trades.List[x].ContractTime, e.location)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
toBuffer[x] = trade.Data{
|
||||
Exchange: b.Name,
|
||||
Exchange: e.Name,
|
||||
AssetType: asset.Spot,
|
||||
CurrencyPair: trades.List[x].Symbol,
|
||||
Timestamp: lu,
|
||||
@@ -148,7 +148,7 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error {
|
||||
}
|
||||
}
|
||||
|
||||
err = b.AddTradesToBuffer(toBuffer...)
|
||||
err = e.AddTradesToBuffer(toBuffer...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -158,9 +158,9 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
init, err := b.UpdateLocalBuffer(&orderbooks)
|
||||
init, err := e.UpdateLocalBuffer(&orderbooks)
|
||||
if err != nil && !init {
|
||||
return fmt.Errorf("%v - UpdateLocalCache error: %s", b.Name, err)
|
||||
return fmt.Errorf("%v - UpdateLocalCache error: %s", e.Name, err)
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
@@ -171,23 +171,23 @@ func (b *Bithumb) wsHandleData(respRaw []byte) error {
|
||||
}
|
||||
|
||||
// generateSubscriptions generates the default subscription set
|
||||
func (b *Bithumb) generateSubscriptions() (subscription.List, error) {
|
||||
return b.Features.Subscriptions.ExpandTemplates(b)
|
||||
func (e *Exchange) generateSubscriptions() (subscription.List, error) {
|
||||
return e.Features.Subscriptions.ExpandTemplates(e)
|
||||
}
|
||||
|
||||
// GetSubscriptionTemplate returns a subscription channel template
|
||||
func (b *Bithumb) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) {
|
||||
func (e *Exchange) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) {
|
||||
return template.New("master.tmpl").Funcs(sprig.FuncMap()).Funcs(template.FuncMap{"subToReq": subToReq}).Parse(subTplText)
|
||||
}
|
||||
|
||||
// Subscribe subscribes to a set of channels
|
||||
func (b *Bithumb) Subscribe(subs subscription.List) error {
|
||||
func (e *Exchange) Subscribe(subs subscription.List) error {
|
||||
ctx := context.TODO()
|
||||
var errs error
|
||||
for _, s := range subs {
|
||||
err := b.Websocket.Conn.SendJSONMessage(ctx, request.Unset, json.RawMessage(s.QualifiedChannel))
|
||||
err := e.Websocket.Conn.SendJSONMessage(ctx, request.Unset, json.RawMessage(s.QualifiedChannel))
|
||||
if err == nil {
|
||||
err = b.Websocket.AddSuccessfulSubscriptions(b.Websocket.Conn, s)
|
||||
err = e.Websocket.AddSuccessfulSubscriptions(e.Websocket.Conn, s)
|
||||
}
|
||||
if err != nil {
|
||||
errs = common.AppendError(errs, err)
|
||||
|
||||
@@ -28,7 +28,7 @@ func TestWsHandleData(t *testing.T) {
|
||||
|
||||
pairs := currency.Pairs{currency.NewBTCUSDT()}
|
||||
|
||||
dummy := Bithumb{
|
||||
dummy := Exchange{
|
||||
location: time.Local,
|
||||
Base: exchange.Base{
|
||||
Name: "dummy",
|
||||
@@ -52,7 +52,7 @@ func TestWsHandleData(t *testing.T) {
|
||||
}
|
||||
|
||||
dummy.setupOrderbookManager(t.Context())
|
||||
dummy.API.Endpoints = b.NewEndpoints()
|
||||
dummy.API.Endpoints = e.NewEndpoints()
|
||||
|
||||
welcomeMsg := []byte(`{"status":"0000","resmsg":"Connected Successfully"}`)
|
||||
err := dummy.wsHandleData(welcomeMsg)
|
||||
@@ -94,12 +94,12 @@ func TestSubToReq(t *testing.T) {
|
||||
|
||||
func TestGenerateSubscriptions(t *testing.T) {
|
||||
t.Parallel()
|
||||
b := new(Bithumb)
|
||||
require.NoError(t, testexch.Setup(b), "Test instance Setup must not error")
|
||||
e := new(Exchange)
|
||||
require.NoError(t, testexch.Setup(e), "Test instance Setup must not error")
|
||||
p := currency.Pairs{currency.NewPairWithDelimiter("BTC", "KRW", "_"), currency.NewPairWithDelimiter("ETH", "KRW", "_")}
|
||||
require.NoError(t, b.CurrencyPairs.StorePairs(asset.Spot, p, false))
|
||||
require.NoError(t, b.CurrencyPairs.StorePairs(asset.Spot, p, true))
|
||||
subs, err := b.generateSubscriptions()
|
||||
require.NoError(t, e.CurrencyPairs.StorePairs(asset.Spot, p, false))
|
||||
require.NoError(t, e.CurrencyPairs.StorePairs(asset.Spot, p, true))
|
||||
subs, err := e.generateSubscriptions()
|
||||
require.NoError(t, err)
|
||||
exp := subscription.List{
|
||||
{Asset: asset.Spot, Channel: subscription.AllTradesChannel, Pairs: p, QualifiedChannel: `{"type":"transaction","symbols":["BTC_KRW","ETH_KRW"]}`},
|
||||
|
||||
@@ -35,26 +35,26 @@ import (
|
||||
var errNotEnoughPairs = errors.New("at least one currency is required to fetch order history")
|
||||
|
||||
// SetDefaults sets the basic defaults for Bithumb
|
||||
func (b *Bithumb) SetDefaults() {
|
||||
b.Name = "Bithumb"
|
||||
b.Enabled = true
|
||||
b.Verbose = true
|
||||
b.API.CredentialsValidator.RequiresKey = true
|
||||
b.API.CredentialsValidator.RequiresSecret = true
|
||||
func (e *Exchange) SetDefaults() {
|
||||
e.Name = "Bithumb"
|
||||
e.Enabled = true
|
||||
e.Verbose = true
|
||||
e.API.CredentialsValidator.RequiresKey = true
|
||||
e.API.CredentialsValidator.RequiresSecret = true
|
||||
|
||||
requestFmt := ¤cy.PairFormat{Uppercase: true, Delimiter: currency.UnderscoreDelimiter}
|
||||
configFmt := ¤cy.PairFormat{Uppercase: true, Delimiter: currency.DashDelimiter}
|
||||
err := b.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot)
|
||||
err := e.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot)
|
||||
if err != nil {
|
||||
log.Errorln(log.ExchangeSys, err)
|
||||
}
|
||||
|
||||
b.location, err = time.LoadLocation("Asia/Seoul")
|
||||
e.location, err = time.LoadLocation("Asia/Seoul")
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "Bithumb unable to load time location: %s", err)
|
||||
}
|
||||
|
||||
b.Features = exchange.Features{
|
||||
e.Features = exchange.Features{
|
||||
Supports: exchange.FeaturesSupported{
|
||||
REST: true,
|
||||
RESTCapabilities: protocol.Features{
|
||||
@@ -116,14 +116,14 @@ func (b *Bithumb) SetDefaults() {
|
||||
},
|
||||
Subscriptions: defaultSubscriptions.Clone(),
|
||||
}
|
||||
b.Requester, err = request.New(b.Name,
|
||||
e.Requester, err = request.New(e.Name,
|
||||
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
|
||||
request.WithLimiter(GetRateLimit()))
|
||||
if err != nil {
|
||||
log.Errorln(log.ExchangeSys, err)
|
||||
}
|
||||
b.API.Endpoints = b.NewEndpoints()
|
||||
err = b.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{
|
||||
e.API.Endpoints = e.NewEndpoints()
|
||||
err = e.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{
|
||||
exchange.RestSpot: apiURL,
|
||||
exchange.WebsocketSpot: wsEndpoint,
|
||||
})
|
||||
@@ -131,44 +131,44 @@ func (b *Bithumb) SetDefaults() {
|
||||
log.Errorln(log.ExchangeSys, err)
|
||||
}
|
||||
|
||||
b.Websocket = websocket.NewManager()
|
||||
b.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit
|
||||
b.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout
|
||||
e.Websocket = websocket.NewManager()
|
||||
e.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit
|
||||
e.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout
|
||||
}
|
||||
|
||||
// Setup takes in the supplied exchange configuration details and sets params
|
||||
func (b *Bithumb) Setup(exch *config.Exchange) error {
|
||||
func (e *Exchange) Setup(exch *config.Exchange) error {
|
||||
err := exch.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exch.Enabled {
|
||||
b.SetEnabled(false)
|
||||
e.SetEnabled(false)
|
||||
return nil
|
||||
}
|
||||
err = b.SetupDefaults(exch)
|
||||
err = e.SetupDefaults(exch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ePoint, err := b.API.Endpoints.GetURL(exchange.WebsocketSpot)
|
||||
ePoint, err := e.API.Endpoints.GetURL(exchange.WebsocketSpot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.Websocket.Setup(&websocket.ManagerSetup{
|
||||
err = e.Websocket.Setup(&websocket.ManagerSetup{
|
||||
ExchangeConfig: exch,
|
||||
DefaultURL: wsEndpoint,
|
||||
RunningURL: ePoint,
|
||||
Connector: b.WsConnect,
|
||||
Subscriber: b.Subscribe,
|
||||
GenerateSubscriptions: b.generateSubscriptions,
|
||||
Features: &b.Features.Supports.WebsocketCapabilities,
|
||||
Connector: e.WsConnect,
|
||||
Subscriber: e.Subscribe,
|
||||
GenerateSubscriptions: e.generateSubscriptions,
|
||||
Features: &e.Features.Supports.WebsocketCapabilities,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return b.Websocket.SetupNewConnection(&websocket.ConnectionSetup{
|
||||
return e.Websocket.SetupNewConnection(&websocket.ConnectionSetup{
|
||||
ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout,
|
||||
ResponseMaxLimit: exch.WebsocketResponseMaxLimit,
|
||||
RateLimit: request.NewWeightedRateLimitByDuration(time.Second),
|
||||
@@ -176,8 +176,8 @@ func (b *Bithumb) Setup(exch *config.Exchange) error {
|
||||
}
|
||||
|
||||
// FetchTradablePairs returns a list of the exchanges tradable pairs
|
||||
func (b *Bithumb) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) {
|
||||
currencies, err := b.GetTradablePairs(ctx)
|
||||
func (e *Exchange) FetchTradablePairs(ctx context.Context, _ asset.Item) (currency.Pairs, error) {
|
||||
currencies, err := e.GetTradablePairs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -196,25 +196,25 @@ func (b *Bithumb) FetchTradablePairs(ctx context.Context, _ asset.Item) (currenc
|
||||
|
||||
// UpdateTradablePairs updates the exchanges available pairs and stores
|
||||
// them in the exchanges config
|
||||
func (b *Bithumb) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error {
|
||||
pairs, err := b.FetchTradablePairs(ctx, asset.Spot)
|
||||
func (e *Exchange) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error {
|
||||
pairs, err := e.FetchTradablePairs(ctx, asset.Spot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.UpdatePairs(pairs, asset.Spot, false, forceUpdate)
|
||||
err = e.UpdatePairs(pairs, asset.Spot, false, forceUpdate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return b.EnsureOnePairEnabled()
|
||||
return e.EnsureOnePairEnabled()
|
||||
}
|
||||
|
||||
// UpdateTickers updates the ticker for all currency pairs of a given asset type
|
||||
func (b *Bithumb) UpdateTickers(ctx context.Context, a asset.Item) error {
|
||||
tickers, err := b.GetAllTickers(ctx)
|
||||
func (e *Exchange) UpdateTickers(ctx context.Context, a asset.Item) error {
|
||||
tickers, err := e.GetAllTickers(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pairs, err := b.GetEnabledPairs(a)
|
||||
pairs, err := e.GetEnabledPairs(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -226,7 +226,7 @@ func (b *Bithumb) UpdateTickers(ctx context.Context, a asset.Item) error {
|
||||
return fmt.Errorf("enabled pair %s [%s] not found in returned ticker map %v",
|
||||
pairs[i], pairs, tickers)
|
||||
}
|
||||
p, err := b.FormatExchangeCurrency(pairs[i], a)
|
||||
p, err := e.FormatExchangeCurrency(pairs[i], a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -237,7 +237,7 @@ func (b *Bithumb) UpdateTickers(ctx context.Context, a asset.Item) error {
|
||||
Open: t.OpeningPrice,
|
||||
Close: t.ClosingPrice,
|
||||
Pair: p,
|
||||
ExchangeName: b.Name,
|
||||
ExchangeName: e.Name,
|
||||
AssetType: a,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -248,30 +248,30 @@ func (b *Bithumb) UpdateTickers(ctx context.Context, a asset.Item) error {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (b *Bithumb) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) {
|
||||
if err := b.UpdateTickers(ctx, a); err != nil {
|
||||
func (e *Exchange) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) {
|
||||
if err := e.UpdateTickers(ctx, a); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ticker.GetTicker(b.Name, p, a)
|
||||
return ticker.GetTicker(e.Name, p, a)
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (b *Bithumb) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) {
|
||||
func (e *Exchange) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Book, error) {
|
||||
if p.IsEmpty() {
|
||||
return nil, currency.ErrCurrencyPairEmpty
|
||||
}
|
||||
if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil {
|
||||
if err := e.CurrencyPairs.IsAssetEnabled(assetType); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
book := &orderbook.Book{
|
||||
Exchange: b.Name,
|
||||
Exchange: e.Name,
|
||||
Pair: p,
|
||||
Asset: assetType,
|
||||
ValidateOrderbook: b.ValidateOrderbook,
|
||||
ValidateOrderbook: e.ValidateOrderbook,
|
||||
}
|
||||
curr := p.Base.String()
|
||||
|
||||
orderbookNew, err := b.GetOrderBook(ctx, curr)
|
||||
orderbookNew, err := e.GetOrderBook(ctx, curr)
|
||||
if err != nil {
|
||||
return book, err
|
||||
}
|
||||
@@ -296,14 +296,14 @@ func (b *Bithumb) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTyp
|
||||
if err != nil {
|
||||
return book, err
|
||||
}
|
||||
return orderbook.Get(b.Name, p, assetType)
|
||||
return orderbook.Get(e.Name, p, assetType)
|
||||
}
|
||||
|
||||
// UpdateAccountInfo retrieves balances for all enabled currencies for the
|
||||
// Bithumb exchange
|
||||
func (b *Bithumb) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) {
|
||||
func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) {
|
||||
var info account.Holdings
|
||||
bal, err := b.GetAccountBalance(ctx, "ALL")
|
||||
bal, err := e.GetAccountBalance(ctx, "ALL")
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
@@ -334,8 +334,8 @@ func (b *Bithumb) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (
|
||||
AssetType: assetType,
|
||||
})
|
||||
|
||||
info.Exchange = b.Name
|
||||
creds, err := b.GetCredentials(ctx)
|
||||
info.Exchange = e.Name
|
||||
creds, err := e.GetCredentials(ctx)
|
||||
if err != nil {
|
||||
return account.Holdings{}, err
|
||||
}
|
||||
@@ -349,13 +349,13 @@ func (b *Bithumb) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (
|
||||
|
||||
// GetAccountFundingHistory returns funding history, deposits and
|
||||
// withdrawals
|
||||
func (b *Bithumb) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) {
|
||||
func (e *Exchange) GetAccountFundingHistory(_ context.Context) ([]exchange.FundingHistory, error) {
|
||||
return nil, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
// GetWithdrawalsHistory returns previous withdrawals data
|
||||
func (b *Bithumb) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) {
|
||||
transactions, err := b.GetUserTransactions(ctx, 0, 0, 3, c, currency.EMPTYCODE)
|
||||
func (e *Exchange) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ asset.Item) ([]exchange.WithdrawalHistory, error) {
|
||||
transactions, err := e.GetUserTransactions(ctx, 0, 0, 3, c, currency.EMPTYCODE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -372,13 +372,13 @@ func (b *Bithumb) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _
|
||||
}
|
||||
|
||||
// GetRecentTrades returns the most recent trades for a currency and asset
|
||||
func (b *Bithumb) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) {
|
||||
func (e *Exchange) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) {
|
||||
var err error
|
||||
p, err = b.FormatExchangeCurrency(p, assetType)
|
||||
p, err = e.FormatExchangeCurrency(p, assetType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tradeData, err := b.GetTransactionHistory(ctx, p.String())
|
||||
tradeData, err := e.GetTransactionHistory(ctx, p.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -390,7 +390,7 @@ func (b *Bithumb) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp
|
||||
return nil, err
|
||||
}
|
||||
resp[i] = trade.Data{
|
||||
Exchange: b.Name,
|
||||
Exchange: e.Name,
|
||||
CurrencyPair: p,
|
||||
AssetType: assetType,
|
||||
Side: side,
|
||||
@@ -400,7 +400,7 @@ func (b *Bithumb) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp
|
||||
}
|
||||
}
|
||||
|
||||
err = b.AddTradesToBuffer(resp...)
|
||||
err = e.AddTradesToBuffer(resp...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -410,18 +410,18 @@ func (b *Bithumb) GetRecentTrades(ctx context.Context, p currency.Pair, assetTyp
|
||||
}
|
||||
|
||||
// GetHistoricTrades returns historic trade data within the timeframe provided
|
||||
func (b *Bithumb) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) {
|
||||
func (e *Exchange) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) {
|
||||
return nil, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
// TODO: Fill this out to support limit orders
|
||||
func (b *Bithumb) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) {
|
||||
if err := s.Validate(b.GetTradingRequirements()); err != nil {
|
||||
func (e *Exchange) SubmitOrder(ctx context.Context, s *order.Submit) (*order.SubmitResponse, error) {
|
||||
if err := s.Validate(e.GetTradingRequirements()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fPair, err := b.FormatExchangeCurrency(s.Pair, s.AssetType)
|
||||
fPair, err := e.FormatExchangeCurrency(s.Pair, s.AssetType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -429,14 +429,14 @@ func (b *Bithumb) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm
|
||||
var orderID string
|
||||
if s.Side.IsLong() {
|
||||
var result MarketBuy
|
||||
result, err = b.MarketBuyOrder(ctx, fPair, s.Amount)
|
||||
result, err = e.MarketBuyOrder(ctx, fPair, s.Amount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderID = result.OrderID
|
||||
} else if s.Side.IsShort() {
|
||||
var result MarketSell
|
||||
result, err = b.MarketSellOrder(ctx, fPair, s.Amount)
|
||||
result, err = e.MarketSellOrder(ctx, fPair, s.Amount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -447,27 +447,27 @@ func (b *Bithumb) SubmitOrder(ctx context.Context, s *order.Submit) (*order.Subm
|
||||
|
||||
// ModifyOrder will allow of changing orderbook placement and limit to
|
||||
// market conversion
|
||||
func (b *Bithumb) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) {
|
||||
func (e *Exchange) ModifyOrder(_ context.Context, _ *order.Modify) (*order.ModifyResponse, error) {
|
||||
return nil, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
// CancelOrder cancels an order by its corresponding ID number
|
||||
func (b *Bithumb) CancelOrder(ctx context.Context, o *order.Cancel) error {
|
||||
func (e *Exchange) CancelOrder(ctx context.Context, o *order.Cancel) error {
|
||||
if err := o.Validate(o.StandardCancel()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := b.CancelTrade(ctx, o.Side.String(), o.OrderID, o.Pair.Base.String())
|
||||
_, err := e.CancelTrade(ctx, o.Side.String(), o.OrderID, o.Pair.Base.String())
|
||||
return err
|
||||
}
|
||||
|
||||
// CancelBatchOrders cancels an orders by their corresponding ID numbers
|
||||
func (b *Bithumb) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) {
|
||||
func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) {
|
||||
return nil, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
// CancelAllOrders cancels all orders associated with a currency pair
|
||||
func (b *Bithumb) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) {
|
||||
func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) {
|
||||
if err := orderCancellation.Validate(); err != nil {
|
||||
return order.CancelAllResponse{}, err
|
||||
}
|
||||
@@ -477,13 +477,13 @@ func (b *Bithumb) CancelAllOrders(ctx context.Context, orderCancellation *order.
|
||||
}
|
||||
|
||||
var allOrders []OrderData
|
||||
currs, err := b.GetEnabledPairs(asset.Spot)
|
||||
currs, err := e.GetEnabledPairs(asset.Spot)
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
}
|
||||
|
||||
for i := range currs {
|
||||
orders, err := b.GetOrders(ctx, "", orderCancellation.Side.String(), 100, time.Time{}, currs[i].Base, currency.EMPTYCODE)
|
||||
orders, err := e.GetOrders(ctx, "", orderCancellation.Side.String(), 100, time.Time{}, currs[i].Base, currency.EMPTYCODE)
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
}
|
||||
@@ -491,7 +491,7 @@ func (b *Bithumb) CancelAllOrders(ctx context.Context, orderCancellation *order.
|
||||
}
|
||||
|
||||
for i := range allOrders {
|
||||
_, err := b.CancelTrade(ctx,
|
||||
_, err := e.CancelTrade(ctx,
|
||||
orderCancellation.Side.String(),
|
||||
allOrders[i].OrderID,
|
||||
orderCancellation.Pair.Base.String())
|
||||
@@ -504,11 +504,11 @@ func (b *Bithumb) CancelAllOrders(ctx context.Context, orderCancellation *order.
|
||||
}
|
||||
|
||||
// GetOrderInfo returns order information based on order ID
|
||||
func (b *Bithumb) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, _ asset.Item) (*order.Detail, error) {
|
||||
func (e *Exchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, _ asset.Item) (*order.Detail, error) {
|
||||
if pair.IsEmpty() {
|
||||
return nil, currency.ErrCurrencyPairEmpty
|
||||
}
|
||||
orders, err := b.GetOrders(ctx, orderID, "", 0, time.Time{}, pair.Base, currency.EMPTYCODE)
|
||||
orders, err := e.GetOrders(ctx, orderID, "", 0, time.Time{}, pair.Base, currency.EMPTYCODE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -518,7 +518,7 @@ func (b *Bithumb) GetOrderInfo(ctx context.Context, orderID string, pair currenc
|
||||
}
|
||||
orderDetail := order.Detail{
|
||||
Amount: orders.Data[i].Units,
|
||||
Exchange: b.Name,
|
||||
Exchange: e.Name,
|
||||
ExecutedAmount: orders.Data[i].Units - orders.Data[i].UnitsRemaining,
|
||||
OrderID: orders.Data[i].OrderID,
|
||||
Date: orders.Data[i].OrderDate.Time(),
|
||||
@@ -540,8 +540,8 @@ func (b *Bithumb) GetOrderInfo(ctx context.Context, orderID string, pair currenc
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *Bithumb) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) {
|
||||
addr, err := b.GetWalletAddress(ctx, cryptocurrency)
|
||||
func (e *Exchange) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, _ string) (*deposit.Address, error) {
|
||||
addr, err := e.GetWalletAddress(ctx, cryptocurrency)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -554,11 +554,11 @@ func (b *Bithumb) GetDepositAddress(ctx context.Context, cryptocurrency currency
|
||||
|
||||
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is
|
||||
// submitted
|
||||
func (b *Bithumb) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) {
|
||||
func (e *Exchange) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) {
|
||||
if err := withdrawRequest.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v, err := b.WithdrawCrypto(ctx,
|
||||
v, err := e.WithdrawCrypto(ctx,
|
||||
withdrawRequest.Crypto.Address,
|
||||
withdrawRequest.Crypto.AddressTag,
|
||||
withdrawRequest.Currency.String(),
|
||||
@@ -574,7 +574,7 @@ func (b *Bithumb) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReque
|
||||
|
||||
// WithdrawFiatFunds returns a withdrawal ID when a
|
||||
// withdrawal is submitted
|
||||
func (b *Bithumb) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) {
|
||||
func (e *Exchange) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) {
|
||||
if err := withdrawRequest.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -586,7 +586,7 @@ func (b *Bithumb) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdr
|
||||
}
|
||||
bankDetails := strconv.FormatFloat(withdrawRequest.Fiat.Bank.BankCode, 'f', -1, 64) +
|
||||
"_" + withdrawRequest.Fiat.Bank.BankName
|
||||
resp, err := b.RequestKRWWithdraw(ctx,
|
||||
resp, err := e.RequestKRWWithdraw(ctx,
|
||||
bankDetails,
|
||||
withdrawRequest.Fiat.Bank.AccountNumber,
|
||||
int64(withdrawRequest.Amount))
|
||||
@@ -603,24 +603,24 @@ func (b *Bithumb) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdr
|
||||
}
|
||||
|
||||
// WithdrawFiatFundsToInternationalBank is not supported as Bithumb only withdraws KRW to South Korean banks
|
||||
func (b *Bithumb) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) {
|
||||
func (e *Exchange) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) {
|
||||
return nil, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
// GetFeeByType returns an estimate of fee based on type of transaction
|
||||
func (b *Bithumb) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) {
|
||||
func (e *Exchange) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) {
|
||||
if feeBuilder == nil {
|
||||
return 0, fmt.Errorf("%T %w", feeBuilder, common.ErrNilPointer)
|
||||
}
|
||||
if !b.AreCredentialsValid(ctx) && // Todo check connection status
|
||||
if !e.AreCredentialsValid(ctx) && // Todo check connection status
|
||||
feeBuilder.FeeType == exchange.CryptocurrencyTradeFee {
|
||||
feeBuilder.FeeType = exchange.OfflineTradeFee
|
||||
}
|
||||
return b.GetFee(feeBuilder)
|
||||
return e.GetFee(feeBuilder)
|
||||
}
|
||||
|
||||
// GetActiveOrders retrieves any orders that are active/open
|
||||
func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) {
|
||||
func (e *Exchange) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) {
|
||||
err := req.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -630,7 +630,7 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ
|
||||
return nil, errNotEnoughPairs
|
||||
}
|
||||
|
||||
format, err := b.GetPairFormat(req.AssetType, false)
|
||||
format, err := e.GetPairFormat(req.AssetType, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -638,7 +638,7 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ
|
||||
var orders []order.Detail
|
||||
for x := range req.Pairs {
|
||||
var resp Orders
|
||||
resp, err = b.GetOrders(ctx, "", "", 1000, time.Time{}, req.Pairs[x].Base, currency.EMPTYCODE)
|
||||
resp, err = e.GetOrders(ctx, "", "", 1000, time.Time{}, req.Pairs[x].Base, currency.EMPTYCODE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -650,7 +650,7 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ
|
||||
|
||||
orderDetail := order.Detail{
|
||||
Amount: resp.Data[i].Units,
|
||||
Exchange: b.Name,
|
||||
Exchange: e.Name,
|
||||
ExecutedAmount: resp.Data[i].Units - resp.Data[i].UnitsRemaining,
|
||||
OrderID: resp.Data[i].OrderID,
|
||||
Date: resp.Data[i].OrderDate.Time(),
|
||||
@@ -672,12 +672,12 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequ
|
||||
orders = append(orders, orderDetail)
|
||||
}
|
||||
}
|
||||
return req.Filter(b.Name, orders), nil
|
||||
return req.Filter(e.Name, orders), nil
|
||||
}
|
||||
|
||||
// GetOrderHistory retrieves account order information
|
||||
// Can Limit response to specific order status
|
||||
func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) {
|
||||
func (e *Exchange) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) {
|
||||
err := req.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -687,7 +687,7 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ
|
||||
return nil, errNotEnoughPairs
|
||||
}
|
||||
|
||||
format, err := b.GetPairFormat(req.AssetType, false)
|
||||
format, err := e.GetPairFormat(req.AssetType, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -695,7 +695,7 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ
|
||||
var orders []order.Detail
|
||||
for x := range req.Pairs {
|
||||
var resp Orders
|
||||
resp, err = b.GetOrders(ctx, "", "", 1000, time.Time{}, req.Pairs[x].Base, currency.EMPTYCODE)
|
||||
resp, err = e.GetOrders(ctx, "", "", 1000, time.Time{}, req.Pairs[x].Base, currency.EMPTYCODE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -709,7 +709,7 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ
|
||||
Amount: resp.Data[i].Units,
|
||||
ExecutedAmount: resp.Data[i].Units - resp.Data[i].UnitsRemaining,
|
||||
RemainingAmount: resp.Data[i].UnitsRemaining,
|
||||
Exchange: b.Name,
|
||||
Exchange: e.Name,
|
||||
OrderID: resp.Data[i].OrderID,
|
||||
Date: resp.Data[i].OrderDate.Time(),
|
||||
Price: resp.Data[i].Price,
|
||||
@@ -729,29 +729,29 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequ
|
||||
orders = append(orders, orderDetail)
|
||||
}
|
||||
}
|
||||
return req.Filter(b.Name, orders), nil
|
||||
return req.Filter(e.Name, orders), nil
|
||||
}
|
||||
|
||||
// ValidateAPICredentials validates current credentials used for wrapper
|
||||
// functionality
|
||||
func (b *Bithumb) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error {
|
||||
_, err := b.UpdateAccountInfo(ctx, assetType)
|
||||
return b.CheckTransientError(err)
|
||||
func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error {
|
||||
_, err := e.UpdateAccountInfo(ctx, assetType)
|
||||
return e.CheckTransientError(err)
|
||||
}
|
||||
|
||||
// FormatExchangeKlineInterval returns Interval to exchange formatted string
|
||||
func (b *Bithumb) FormatExchangeKlineInterval(in kline.Interval) string {
|
||||
func (e *Exchange) FormatExchangeKlineInterval(in kline.Interval) string {
|
||||
return in.Short()
|
||||
}
|
||||
|
||||
// GetHistoricCandles returns candles between a time period for a set time interval
|
||||
func (b *Bithumb) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) {
|
||||
req, err := b.GetKlineRequest(pair, a, interval, start, end, true)
|
||||
func (e *Exchange) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, interval kline.Interval, start, end time.Time) (*kline.Item, error) {
|
||||
req, err := e.GetKlineRequest(pair, a, interval, start, end, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
candles, err := b.GetCandleStick(ctx, req.RequestFormatted.String(), b.FormatExchangeKlineInterval(req.ExchangeInterval))
|
||||
candles, err := e.GetCandleStick(ctx, req.RequestFormatted.String(), e.FormatExchangeKlineInterval(req.ExchangeInterval))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -777,22 +777,22 @@ func (b *Bithumb) GetHistoricCandles(ctx context.Context, pair currency.Pair, a
|
||||
}
|
||||
|
||||
// GetHistoricCandlesExtended returns candles between a time period for a set time interval
|
||||
func (b *Bithumb) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) {
|
||||
func (e *Exchange) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) {
|
||||
return nil, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
// UpdateOrderExecutionLimits sets exchange executions for a required asset type
|
||||
func (b *Bithumb) UpdateOrderExecutionLimits(ctx context.Context, _ asset.Item) error {
|
||||
limits, err := b.FetchExchangeLimits(ctx)
|
||||
func (e *Exchange) UpdateOrderExecutionLimits(ctx context.Context, _ asset.Item) error {
|
||||
limits, err := e.FetchExchangeLimits(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot update exchange execution limits: %w", err)
|
||||
}
|
||||
return b.LoadLimits(limits)
|
||||
return e.LoadLimits(limits)
|
||||
}
|
||||
|
||||
// UpdateCurrencyStates updates currency states for exchange
|
||||
func (b *Bithumb) UpdateCurrencyStates(ctx context.Context, a asset.Item) error {
|
||||
status, err := b.GetAssetStatusAll(ctx)
|
||||
func (e *Exchange) UpdateCurrencyStates(ctx context.Context, a asset.Item) error {
|
||||
status, err := e.GetAssetStatusAll(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -804,27 +804,27 @@ func (b *Bithumb) UpdateCurrencyStates(ctx context.Context, a asset.Item) error
|
||||
Deposit: convert.BoolPtr(options.DepositStatus == 1),
|
||||
}
|
||||
}
|
||||
return b.States.UpdateAll(a, payload)
|
||||
return e.States.UpdateAll(a, payload)
|
||||
}
|
||||
|
||||
// GetServerTime returns the current exchange server time.
|
||||
func (b *Bithumb) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) {
|
||||
func (e *Exchange) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) {
|
||||
return time.Time{}, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
// GetFuturesContractDetails returns all contracts from the exchange by asset type
|
||||
func (b *Bithumb) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) {
|
||||
func (e *Exchange) GetFuturesContractDetails(context.Context, asset.Item) ([]futures.Contract, error) {
|
||||
return nil, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
// GetLatestFundingRates returns the latest funding rates data
|
||||
func (b *Bithumb) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) {
|
||||
func (e *Exchange) GetLatestFundingRates(context.Context, *fundingrate.LatestRateRequest) ([]fundingrate.LatestRateResponse, error) {
|
||||
return nil, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
// GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair
|
||||
func (b *Bithumb) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) {
|
||||
_, err := b.CurrencyPairs.IsPairEnabled(cp, a)
|
||||
func (e *Exchange) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) {
|
||||
_, err := e.CurrencyPairs.IsPairEnabled(cp, a)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const (
|
||||
maxWSOrderbookWorkers = 10
|
||||
)
|
||||
|
||||
func (b *Bithumb) processBooks(updates *WsOrderbooks) error {
|
||||
func (e *Exchange) processBooks(updates *WsOrderbooks) error {
|
||||
bids := make([]orderbook.Level, 0, len(updates.List))
|
||||
asks := make([]orderbook.Level, 0, len(updates.List))
|
||||
for x := range updates.List {
|
||||
@@ -35,7 +35,7 @@ func (b *Bithumb) processBooks(updates *WsOrderbooks) error {
|
||||
}
|
||||
asks = append(asks, i)
|
||||
}
|
||||
return b.Websocket.Orderbook.Update(&orderbook.Update{
|
||||
return e.Websocket.Orderbook.Update(&orderbook.Update{
|
||||
Pair: updates.List[0].Symbol,
|
||||
Asset: asset.Spot,
|
||||
Bids: bids,
|
||||
@@ -45,30 +45,30 @@ func (b *Bithumb) processBooks(updates *WsOrderbooks) error {
|
||||
}
|
||||
|
||||
// UpdateLocalBuffer updates and returns the most recent iteration of the orderbook
|
||||
func (b *Bithumb) UpdateLocalBuffer(wsdp *WsOrderbooks) (bool, error) {
|
||||
func (e *Exchange) UpdateLocalBuffer(wsdp *WsOrderbooks) (bool, error) {
|
||||
if len(wsdp.List) < 1 {
|
||||
return false, errors.New("insufficient data to process")
|
||||
}
|
||||
err := b.obm.stageWsUpdate(wsdp, wsdp.List[0].Symbol, asset.Spot)
|
||||
err := e.obm.stageWsUpdate(wsdp, wsdp.List[0].Symbol, asset.Spot)
|
||||
if err != nil {
|
||||
init, err2 := b.obm.checkIsInitialSync(wsdp.List[0].Symbol)
|
||||
init, err2 := e.obm.checkIsInitialSync(wsdp.List[0].Symbol)
|
||||
if err2 != nil {
|
||||
return false, err2
|
||||
}
|
||||
return init, err
|
||||
}
|
||||
|
||||
err = b.applyBufferUpdate(wsdp.List[0].Symbol)
|
||||
err = e.applyBufferUpdate(wsdp.List[0].Symbol)
|
||||
if err != nil {
|
||||
b.invalidateAndCleanupOrderbook(wsdp.List[0].Symbol)
|
||||
e.invalidateAndCleanupOrderbook(wsdp.List[0].Symbol)
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
// applyBufferUpdate applies the buffer to the orderbook or initiates a new
|
||||
// orderbook sync by the REST protocol which is off handed to go routine.
|
||||
func (b *Bithumb) applyBufferUpdate(pair currency.Pair) error {
|
||||
fetching, needsFetching, err := b.obm.handleFetchingBook(pair)
|
||||
func (e *Exchange) applyBufferUpdate(pair currency.Pair) error {
|
||||
fetching, needsFetching, err := e.obm.handleFetchingBook(pair)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -77,22 +77,22 @@ func (b *Bithumb) applyBufferUpdate(pair currency.Pair) error {
|
||||
}
|
||||
|
||||
if needsFetching {
|
||||
if b.Verbose {
|
||||
log.Debugf(log.WebsocketMgr, "%s Orderbook: Fetching via REST\n", b.Name)
|
||||
if e.Verbose {
|
||||
log.Debugf(log.WebsocketMgr, "%s Orderbook: Fetching via REST\n", e.Name)
|
||||
}
|
||||
return b.obm.fetchBookViaREST(pair)
|
||||
return e.obm.fetchBookViaREST(pair)
|
||||
}
|
||||
|
||||
recent, err := b.Websocket.Orderbook.GetOrderbook(pair, asset.Spot)
|
||||
recent, err := e.Websocket.Orderbook.GetOrderbook(pair, asset.Spot)
|
||||
if err != nil {
|
||||
log.Errorf(log.WebsocketMgr, "%s error fetching recent orderbook when applying updates: %s\n", b.Name, err)
|
||||
log.Errorf(log.WebsocketMgr, "%s error fetching recent orderbook when applying updates: %s\n", e.Name, err)
|
||||
}
|
||||
|
||||
if recent != nil {
|
||||
err = b.obm.checkAndProcessOrderbookUpdate(b.processBooks, pair, recent)
|
||||
err = e.obm.checkAndProcessOrderbookUpdate(e.processBooks, pair, recent)
|
||||
if err != nil {
|
||||
log.Errorf(log.WebsocketMgr, "%s error processing update - initiating new orderbook sync via REST: %s\n", b.Name, err)
|
||||
err = b.obm.setNeedsFetchingBook(pair)
|
||||
log.Errorf(log.WebsocketMgr, "%s error processing update - initiating new orderbook sync via REST: %s\n", e.Name, err)
|
||||
err = e.obm.setNeedsFetchingBook(pair)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -104,24 +104,24 @@ func (b *Bithumb) applyBufferUpdate(pair currency.Pair) error {
|
||||
|
||||
// SynchroniseWebsocketOrderbook synchronises full orderbook for currency pair
|
||||
// asset
|
||||
func (b *Bithumb) SynchroniseWebsocketOrderbook(ctx context.Context) {
|
||||
b.Websocket.Wg.Add(1)
|
||||
func (e *Exchange) SynchroniseWebsocketOrderbook(ctx context.Context) {
|
||||
e.Websocket.Wg.Add(1)
|
||||
go func() {
|
||||
defer b.Websocket.Wg.Done()
|
||||
defer e.Websocket.Wg.Done()
|
||||
for {
|
||||
select {
|
||||
case <-b.Websocket.ShutdownC:
|
||||
case <-e.Websocket.ShutdownC:
|
||||
for {
|
||||
select {
|
||||
case <-b.obm.jobs:
|
||||
case <-e.obm.jobs:
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
case j := <-b.obm.jobs:
|
||||
err := b.processJob(ctx, j.Pair)
|
||||
case j := <-e.obm.jobs:
|
||||
err := e.processJob(ctx, j.Pair)
|
||||
if err != nil {
|
||||
log.Errorf(log.WebsocketMgr, "%s processing websocket orderbook error %v", b.Name, err)
|
||||
log.Errorf(log.WebsocketMgr, "%s processing websocket orderbook error %v", e.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,45 +129,45 @@ func (b *Bithumb) SynchroniseWebsocketOrderbook(ctx context.Context) {
|
||||
}
|
||||
|
||||
// processJob fetches and processes orderbook updates
|
||||
func (b *Bithumb) processJob(ctx context.Context, p currency.Pair) error {
|
||||
err := b.SeedLocalCache(ctx, p)
|
||||
func (e *Exchange) processJob(ctx context.Context, p currency.Pair) error {
|
||||
err := e.SeedLocalCache(ctx, p)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s %s seeding local cache for orderbook error: %v",
|
||||
p, asset.Spot, err)
|
||||
}
|
||||
|
||||
err = b.obm.stopFetchingBook(p)
|
||||
err = e.obm.stopFetchingBook(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Immediately apply the buffer updates so we don't wait for a
|
||||
// new update to initiate this.
|
||||
err = b.applyBufferUpdate(p)
|
||||
err = e.applyBufferUpdate(p)
|
||||
if err != nil {
|
||||
b.invalidateAndCleanupOrderbook(p)
|
||||
e.invalidateAndCleanupOrderbook(p)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// invalidateAndCleanupOrderbook invalidates orderbook and cleans local cache
|
||||
func (b *Bithumb) invalidateAndCleanupOrderbook(p currency.Pair) {
|
||||
if err := b.Websocket.Orderbook.InvalidateOrderbook(p, asset.Spot); err != nil {
|
||||
log.Errorf(log.WebsocketMgr, "%s invalidate orderbook websocket error: %v", b.Name, err)
|
||||
func (e *Exchange) invalidateAndCleanupOrderbook(p currency.Pair) {
|
||||
if err := e.Websocket.Orderbook.InvalidateOrderbook(p, asset.Spot); err != nil {
|
||||
log.Errorf(log.WebsocketMgr, "%s invalidate orderbook websocket error: %v", e.Name, err)
|
||||
}
|
||||
if err := b.obm.cleanup(p); err != nil {
|
||||
log.Errorf(log.WebsocketMgr, "%s cleanup websocket error: %v", b.Name, err)
|
||||
if err := e.obm.cleanup(p); err != nil {
|
||||
log.Errorf(log.WebsocketMgr, "%s cleanup websocket error: %v", e.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bithumb) setupOrderbookManager(ctx context.Context) {
|
||||
if b.obm.state == nil {
|
||||
b.obm.state = make(map[currency.Code]map[currency.Code]map[asset.Item]*update)
|
||||
b.obm.jobs = make(chan job, maxWSOrderbookJobs)
|
||||
func (e *Exchange) setupOrderbookManager(ctx context.Context) {
|
||||
if e.obm.state == nil {
|
||||
e.obm.state = make(map[currency.Code]map[currency.Code]map[asset.Item]*update)
|
||||
e.obm.jobs = make(chan job, maxWSOrderbookJobs)
|
||||
} else {
|
||||
// Change state on reconnect for initial sync.
|
||||
for _, m1 := range b.obm.state {
|
||||
for _, m1 := range e.obm.state {
|
||||
for _, m2 := range m1 {
|
||||
for _, update := range m2 {
|
||||
update.initialSync = true
|
||||
@@ -180,7 +180,7 @@ func (b *Bithumb) setupOrderbookManager(ctx context.Context) {
|
||||
|
||||
for range maxWSOrderbookWorkers {
|
||||
// 10 workers for synchronising book
|
||||
b.SynchroniseWebsocketOrderbook(ctx)
|
||||
e.SynchroniseWebsocketOrderbook(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,22 +398,22 @@ bufferEmpty:
|
||||
}
|
||||
|
||||
// SeedLocalCache seeds depth data
|
||||
func (b *Bithumb) SeedLocalCache(ctx context.Context, p currency.Pair) error {
|
||||
ob, err := b.GetOrderBook(ctx, p.String())
|
||||
func (e *Exchange) SeedLocalCache(ctx context.Context, p currency.Pair) error {
|
||||
ob, err := e.GetOrderBook(ctx, p.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return b.SeedLocalCacheWithBook(p, ob)
|
||||
return e.SeedLocalCacheWithBook(p, ob)
|
||||
}
|
||||
|
||||
// SeedLocalCacheWithBook seeds the local orderbook cache
|
||||
func (b *Bithumb) SeedLocalCacheWithBook(p currency.Pair, o *Orderbook) error {
|
||||
func (e *Exchange) SeedLocalCacheWithBook(p currency.Pair, o *Orderbook) error {
|
||||
ob := &orderbook.Book{
|
||||
Pair: p,
|
||||
Asset: asset.Spot,
|
||||
Exchange: b.Name,
|
||||
Exchange: e.Name,
|
||||
LastUpdated: o.Data.Timestamp.Time(),
|
||||
ValidateOrderbook: b.ValidateOrderbook,
|
||||
ValidateOrderbook: e.ValidateOrderbook,
|
||||
Bids: make(orderbook.Levels, len(o.Data.Bids)),
|
||||
Asks: make(orderbook.Levels, len(o.Data.Asks)),
|
||||
}
|
||||
@@ -425,7 +425,7 @@ func (b *Bithumb) SeedLocalCacheWithBook(p currency.Pair, o *Orderbook) error {
|
||||
ob.Asks[i].Price = o.Data.Asks[i].Price
|
||||
ob.Asks[i].Amount = o.Data.Asks[i].Quantity
|
||||
}
|
||||
return b.Websocket.Orderbook.LoadSnapshot(ob)
|
||||
return e.Websocket.Orderbook.LoadSnapshot(ob)
|
||||
}
|
||||
|
||||
// setNeedsFetchingBook completes the book fetching initiation.
|
||||
|
||||
Reference in New Issue
Block a user