mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-02 23:16:51 +00:00
Merge branch 'master' into engine
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
# GoCryptoTrader package Hitbtc
|
||||
|
||||
<img src="https://github.com/thrasher-/gocryptotrader/blob/master/web/src/assets/page-logo.png?raw=true" width="350px" height="350px" hspace="70">
|
||||
<img src="https://github.com/thrasher-corp/gocryptotrader/blob/master/web/src/assets/page-logo.png?raw=true" width="350px" height="350px" hspace="70">
|
||||
|
||||
|
||||
[](https://travis-ci.org/thrasher-/gocryptotrader)
|
||||
[](https://github.com/thrasher-/gocryptotrader/blob/master/LICENSE)
|
||||
[](https://godoc.org/github.com/thrasher-/gocryptotrader/exchanges/hitbtc)
|
||||
[](http://codecov.io/github/thrasher-/gocryptotrader?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/thrasher-/gocryptotrader)
|
||||
[](https://travis-ci.org/thrasher-corp/gocryptotrader)
|
||||
[](https://github.com/thrasher-corp/gocryptotrader/blob/master/LICENSE)
|
||||
[](https://godoc.org/github.com/thrasher-corp/gocryptotrader/exchanges/hitbtc)
|
||||
[](http://codecov.io/github/thrasher-corp/gocryptotrader?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/thrasher-corp/gocryptotrader)
|
||||
|
||||
|
||||
This hitbtc package is part of the GoCryptoTrader codebase.
|
||||
@@ -27,7 +27,7 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader
|
||||
|
||||
### How to enable
|
||||
|
||||
+ [Enable via configuration](https://github.com/thrasher-/gocryptotrader/tree/master/config#enable-exchange-via-config-example)
|
||||
+ [Enable via configuration](https://github.com/thrasher-corp/gocryptotrader/tree/master/config#enable-exchange-via-config-example)
|
||||
|
||||
+ Individual package example below:
|
||||
|
||||
@@ -128,12 +128,12 @@ When submitting a PR, please abide by our coding guidelines:
|
||||
|
||||
+ Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)).
|
||||
+ Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines.
|
||||
+ Code must adhere to our [coding style](https://github.com/thrasher-/gocryptotrader/blob/master/doc/coding_style.md).
|
||||
+ Code must adhere to our [coding style](https://github.com/thrasher-corp/gocryptotrader/blob/master/doc/coding_style.md).
|
||||
+ Pull requests need to be based on and opened against the `master` branch.
|
||||
|
||||
## Donations
|
||||
|
||||
<img src="https://github.com/thrasher-/gocryptotrader/blob/master/web/src/assets/donate.png?raw=true" hspace="70">
|
||||
<img src="https://github.com/thrasher-corp/gocryptotrader/blob/master/web/src/assets/donate.png?raw=true" hspace="70">
|
||||
|
||||
If this framework helped you in any way, or you would like to support the developers working on it, please donate Bitcoin to:
|
||||
|
||||
|
||||
@@ -7,12 +7,11 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common/crypto"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/common/crypto"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/wshandler"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -48,8 +47,7 @@ const (
|
||||
// HitBTC is the overarching type across the hitbtc package
|
||||
type HitBTC struct {
|
||||
exchange.Base
|
||||
WebsocketConn *websocket.Conn
|
||||
wsRequestMtx sync.Mutex
|
||||
WebsocketConn *wshandler.WebsocketConnection
|
||||
}
|
||||
|
||||
// Public Market Data
|
||||
|
||||
@@ -6,14 +6,16 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/sharedtestvalues"
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/wshandler"
|
||||
)
|
||||
|
||||
var h HitBTC
|
||||
var wsSetupRan bool
|
||||
|
||||
// Please supply your own APIKEYS here for due diligence testing
|
||||
const (
|
||||
@@ -102,7 +104,7 @@ func TestGetFee(t *testing.T) {
|
||||
var feeBuilder = setFeeBuilder()
|
||||
if areTestAPIKeysSet() {
|
||||
// CryptocurrencyTradeFee Basic
|
||||
if resp, err := h.GetFee(feeBuilder); resp != float64(0.001) || err != nil {
|
||||
if resp, err := h.GetFee(feeBuilder); resp != float64(0.002) || err != nil {
|
||||
t.Error(err)
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.002), resp)
|
||||
}
|
||||
@@ -111,7 +113,7 @@ func TestGetFee(t *testing.T) {
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.Amount = 1000
|
||||
feeBuilder.PurchasePrice = 1000
|
||||
if resp, err := h.GetFee(feeBuilder); resp != float64(1000) || err != nil {
|
||||
if resp, err := h.GetFee(feeBuilder); resp != float64(2000) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(2000), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -119,7 +121,7 @@ func TestGetFee(t *testing.T) {
|
||||
// CryptocurrencyTradeFee IsMaker
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.IsMaker = true
|
||||
if resp, err := h.GetFee(feeBuilder); resp != float64(-0.0001) || err != nil {
|
||||
if resp, err := h.GetFee(feeBuilder); resp != float64(0.001) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.001), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -127,7 +129,7 @@ func TestGetFee(t *testing.T) {
|
||||
// CryptocurrencyTradeFee Negative purchase price
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.PurchasePrice = -1000
|
||||
if resp, err := h.GetFee(feeBuilder); resp != float64(-1) || err != nil {
|
||||
if resp, err := h.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -135,7 +137,7 @@ func TestGetFee(t *testing.T) {
|
||||
// CryptocurrencyWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
||||
if resp, err := h.GetFee(feeBuilder); resp != float64(0.009580) || err != nil {
|
||||
if resp, err := h.GetFee(feeBuilder); resp != float64(0.042800) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.042800), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -389,16 +391,25 @@ func TestGetDepositAddress(t *testing.T) {
|
||||
}
|
||||
}
|
||||
func setupWsAuth(t *testing.T) {
|
||||
if wsSetupRan {
|
||||
return
|
||||
}
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
if !h.Websocket.IsEnabled() && !h.API.AuthenticatedWebsocketSupport || !areTestAPIKeysSet() {
|
||||
t.Skip(exchange.WebsocketNotEnabled)
|
||||
t.Skip(wshandler.WebsocketNotEnabled)
|
||||
}
|
||||
var err error
|
||||
var dialer websocket.Dialer
|
||||
h.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride()
|
||||
h.Websocket.TrafficAlert = sharedtestvalues.GetWebsocketStructChannelOverride()
|
||||
h.WebsocketConn, _, err = dialer.Dial(hitbtcWebsocketAddress, http.Header{})
|
||||
h.WebsocketConn = &wshandler.WebsocketConnection{
|
||||
ExchangeName: h.Name,
|
||||
URL: hitbtcWebsocketAddress,
|
||||
Verbose: h.Verbose,
|
||||
ResponseMaxLimit: exchange.DefaultWebsocketResponseMaxLimit,
|
||||
ResponseCheckTimeout: exchange.DefaultWebsocketResponseCheckTimeout,
|
||||
}
|
||||
var dialer websocket.Dialer
|
||||
err := h.WebsocketConn.Dial(&dialer, http.Header{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -411,84 +422,86 @@ func setupWsAuth(t *testing.T) {
|
||||
case <-timer.C:
|
||||
}
|
||||
timer.Stop()
|
||||
wsSetupRan = true
|
||||
}
|
||||
|
||||
// TestWsCancelOrder dials websocket, sends cancel request.
|
||||
func TestWsCancelOrder(t *testing.T) {
|
||||
setupWsAuth(t)
|
||||
err := h.wsCancelOrder("ImNotARealOrderID")
|
||||
if !canManipulateRealOrders {
|
||||
t.Skip("canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
_, err := h.wsCancelOrder("ImNotARealOrderID")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
|
||||
select {
|
||||
case <-h.Websocket.DataHandler:
|
||||
case <-timer.C:
|
||||
t.Error("Expecting response")
|
||||
}
|
||||
timer.Stop()
|
||||
}
|
||||
|
||||
// TestWsPlaceOrder dials websocket, sends order submission.
|
||||
func TestWsPlaceOrder(t *testing.T) {
|
||||
setupWsAuth(t)
|
||||
err := h.wsPlaceOrder(currency.NewPair(currency.LTC, currency.BTC), exchange.BuyOrderSide.ToString(), 1, 1)
|
||||
if !canManipulateRealOrders {
|
||||
t.Skip("canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
_, err := h.wsPlaceOrder(currency.NewPair(currency.LTC, currency.BTC), exchange.BuyOrderSide.ToString(), 1, 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
|
||||
select {
|
||||
case <-h.Websocket.DataHandler:
|
||||
case <-timer.C:
|
||||
t.Error("Expecting response")
|
||||
}
|
||||
timer.Stop()
|
||||
}
|
||||
|
||||
// TestWsReplaceOrder dials websocket, sends replace order request.
|
||||
func TestWsReplaceOrder(t *testing.T) {
|
||||
setupWsAuth(t)
|
||||
err := h.wsReplaceOrder("ImNotARealOrderID", 1, 1)
|
||||
if !canManipulateRealOrders {
|
||||
t.Skip("canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
_, err := h.wsReplaceOrder("ImNotARealOrderID", 1, 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
|
||||
select {
|
||||
case <-h.Websocket.DataHandler:
|
||||
case <-timer.C:
|
||||
t.Error("Expecting response")
|
||||
}
|
||||
timer.Stop()
|
||||
}
|
||||
|
||||
// TestWsGetActiveOrders dials websocket, sends get active orders request.
|
||||
func TestWsGetActiveOrders(t *testing.T) {
|
||||
setupWsAuth(t)
|
||||
err := h.wsGetActiveOrders()
|
||||
_, err := h.wsGetActiveOrders()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
|
||||
select {
|
||||
case <-h.Websocket.DataHandler:
|
||||
case <-timer.C:
|
||||
t.Error("Expecting response")
|
||||
}
|
||||
timer.Stop()
|
||||
}
|
||||
|
||||
// TestWsGetTradingBalance dials websocket, sends get trading balance request.
|
||||
func TestWsGetTradingBalance(t *testing.T) {
|
||||
setupWsAuth(t)
|
||||
err := h.wsGetTradingBalance()
|
||||
_, err := h.wsGetTradingBalance()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestWsGetTradingBalance dials websocket, sends get trading balance request.
|
||||
func TestWsGetTrades(t *testing.T) {
|
||||
setupWsAuth(t)
|
||||
_, err := h.wsGetTrades(currency.NewPair(currency.ETH, currency.BTC), 1000, "ASC", "id")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestWsGetTradingBalance dials websocket, sends get trading balance request.
|
||||
func TestWsGetSymbols(t *testing.T) {
|
||||
setupWsAuth(t)
|
||||
_, err := h.wsGetSymbols(currency.NewPair(currency.ETH, currency.BTC))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestWsGetTradingBalance dials websocket, sends get trading balance request.
|
||||
func TestSsGetCurrencies(t *testing.T) {
|
||||
setupWsAuth(t)
|
||||
_, err := h.wsGetCurrencies(currency.BTC)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
|
||||
select {
|
||||
case <-h.Websocket.DataHandler:
|
||||
case <-timer.C:
|
||||
t.Error("Expecting response")
|
||||
}
|
||||
timer.Stop()
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package hitbtc
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
)
|
||||
|
||||
// Ticker holds ticker information
|
||||
@@ -299,13 +299,16 @@ type LendingHistory struct {
|
||||
}
|
||||
|
||||
type capture struct {
|
||||
Method string `json:"method,omitempty"`
|
||||
Result interface{} `json:"result"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"error"`
|
||||
ID int64 `json:"id,omitempty"`
|
||||
Method string `json:"method,omitempty"`
|
||||
Result interface{} `json:"result"`
|
||||
Error ResponseError `json:"error,omitempty"`
|
||||
ID int64 `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseError contains error codes from JSON responses
|
||||
type ResponseError struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// WsRequest defines a request obj for the JSON-RPC and gets a websocket
|
||||
@@ -393,12 +396,13 @@ type WsLoginData struct {
|
||||
// WsActiveOrdersResponse Active order response for auth subscription to reports
|
||||
type WsActiveOrdersResponse struct {
|
||||
Params []WsActiveOrdersResponseData `json:"params"`
|
||||
Error ResponseError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// WsActiveOrdersResponseData Active order data for WsActiveOrdersResponse
|
||||
type WsActiveOrdersResponseData struct {
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
@@ -416,12 +420,13 @@ type WsActiveOrdersResponseData struct {
|
||||
// WsReportResponse report response for auth subscription to reports
|
||||
type WsReportResponse struct {
|
||||
Params WsReportResponseData `json:"params"`
|
||||
Error ResponseError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// WsReportResponseData Report data for WsReportResponse
|
||||
type WsReportResponseData struct {
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
@@ -449,7 +454,7 @@ type WsSubmitOrderRequest struct {
|
||||
|
||||
// WsSubmitOrderRequestData WS request data
|
||||
type WsSubmitOrderRequestData struct {
|
||||
ClientOrderID string `json:"clientOrderId"`
|
||||
ClientOrderID int64 `json:"clientOrderId,string,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Price float64 `json:"price,string"`
|
||||
@@ -460,6 +465,7 @@ type WsSubmitOrderRequestData struct {
|
||||
type WsSubmitOrderSuccessResponse struct {
|
||||
Result WsSubmitOrderSuccessResponseData `json:"result"`
|
||||
ID int64 `json:"id"`
|
||||
Error ResponseError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// WsSubmitOrderSuccessResponseData WS response data
|
||||
@@ -482,7 +488,7 @@ type WsSubmitOrderSuccessResponseData struct {
|
||||
|
||||
// WsSubmitOrderErrorResponse WS error response
|
||||
type WsSubmitOrderErrorResponse struct {
|
||||
Error WsSubmitOrderErrorResponseData `json:"error"`
|
||||
Error WsSubmitOrderErrorResponseData `json:"error,omitempty"`
|
||||
ID int64 `json:"id"`
|
||||
}
|
||||
|
||||
@@ -497,12 +503,13 @@ type WsSubmitOrderErrorResponseData struct {
|
||||
type WsCancelOrderResponse struct {
|
||||
Result WsCancelOrderResponseData `json:"result"`
|
||||
ID int64 `json:"id"`
|
||||
Error ResponseError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// WsCancelOrderResponseData WS response data
|
||||
type WsCancelOrderResponseData struct {
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
@@ -521,12 +528,13 @@ type WsCancelOrderResponseData struct {
|
||||
type WsReplaceOrderResponse struct {
|
||||
Result WsReplaceOrderResponseData `json:"result"`
|
||||
ID int64 `json:"id"`
|
||||
Error ResponseError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// WsReplaceOrderResponseData WS response data
|
||||
type WsReplaceOrderResponseData struct {
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
@@ -546,12 +554,13 @@ type WsReplaceOrderResponseData struct {
|
||||
type WsGetActiveOrdersResponse struct {
|
||||
Result []WsGetActiveOrdersResponseData `json:"result"`
|
||||
ID int64 `json:"id"`
|
||||
Error ResponseError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// WsGetActiveOrdersResponseData WS response data
|
||||
type WsGetActiveOrdersResponseData struct {
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
@@ -571,6 +580,7 @@ type WsGetActiveOrdersResponseData struct {
|
||||
type WsGetTradingBalanceResponse struct {
|
||||
Result []WsGetTradingBalanceResponseData `json:"result"`
|
||||
ID int64 `json:"id"`
|
||||
Error ResponseError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// WsGetTradingBalanceResponseData WS response data
|
||||
@@ -606,3 +616,106 @@ type WsReplaceOrderRequestData struct {
|
||||
Quantity float64 `json:"quantity,string,omitempty"`
|
||||
Price float64 `json:"price,string,omitempty"`
|
||||
}
|
||||
|
||||
// WsGetCurrenciesRequest gets currencies
|
||||
type WsGetCurrenciesRequest struct {
|
||||
Method string `json:"method"`
|
||||
Params WsGetCurrenciesRequestParameters `json:"params"`
|
||||
ID int64 `json:"id"`
|
||||
}
|
||||
|
||||
// WsGetCurrenciesRequestParameters parameters
|
||||
type WsGetCurrenciesRequestParameters struct {
|
||||
Currency currency.Code `json:"currency"`
|
||||
}
|
||||
|
||||
// WsGetCurrenciesResponse currency response
|
||||
type WsGetCurrenciesResponse struct {
|
||||
Result WsGetCurrenciesResponseData `json:"result"`
|
||||
ID int64 `json:"id"`
|
||||
Error ResponseError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// WsGetCurrenciesResponseData currency response data
|
||||
type WsGetCurrenciesResponseData struct {
|
||||
ID currency.Code `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
Crypto bool `json:"crypto"`
|
||||
PayinEnabled bool `json:"payinEnabled"`
|
||||
PayinPaymentID bool `json:"payinPaymentId"`
|
||||
PayinConfirmations int64 `json:"payinConfirmations"`
|
||||
PayoutEnabled bool `json:"payoutEnabled"`
|
||||
PayoutIsPaymentID bool `json:"payoutIsPaymentId"`
|
||||
TransferEnabled bool `json:"transferEnabled"`
|
||||
Delisted bool `json:"delisted"`
|
||||
PayoutFee string `json:"payoutFee"`
|
||||
}
|
||||
|
||||
// WsGetSymbolsRequest request data
|
||||
type WsGetSymbolsRequest struct {
|
||||
Method string `json:"method"`
|
||||
Params WsGetSymbolsRequestParameters `json:"params"`
|
||||
ID int64 `json:"id"`
|
||||
}
|
||||
|
||||
// WsGetSymbolsRequestParameters request parameters
|
||||
type WsGetSymbolsRequestParameters struct {
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
}
|
||||
|
||||
// WsGetSymbolsResponse symbol response
|
||||
type WsGetSymbolsResponse struct {
|
||||
Result WsGetSymbolsResponseData `json:"result"`
|
||||
ID int64 `json:"id"`
|
||||
Error ResponseError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// WsGetSymbolsResponseData symbol response data
|
||||
type WsGetSymbolsResponseData struct {
|
||||
ID currency.Pair `json:"id"`
|
||||
BaseCurrency currency.Code `json:"baseCurrency"`
|
||||
QuoteCurrency currency.Code `json:"quoteCurrency"`
|
||||
QuantityIncrement float64 `json:"quantityIncrement,string"`
|
||||
TickSize float64 `json:"tickSize,string"`
|
||||
TakeLiquidityRate float64 `json:"takeLiquidityRate,string"`
|
||||
ProvideLiquidityRate float64 `json:"provideLiquidityRate,string"`
|
||||
FeeCurrency currency.Code `json:"feeCurrency"`
|
||||
}
|
||||
|
||||
// WsGetTradesRequest trade request
|
||||
type WsGetTradesRequest struct {
|
||||
Method string `json:"method"`
|
||||
Params WsGetTradesRequestParameters `json:"params"`
|
||||
ID int64 `json:"id"`
|
||||
}
|
||||
|
||||
// WsGetTradesRequestParameters trade request params
|
||||
type WsGetTradesRequestParameters struct {
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Limit int64 `json:"limit"`
|
||||
Sort string `json:"sort"`
|
||||
By string `json:"by"`
|
||||
}
|
||||
|
||||
// WsGetTradesResponse response
|
||||
type WsGetTradesResponse struct {
|
||||
Jsonrpc string `json:"jsonrpc"`
|
||||
Result WsGetTradesResponseData `json:"result"`
|
||||
ID int64 `json:"id"`
|
||||
Error ResponseError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// WsGetTradesResponseData trade response data
|
||||
type WsGetTradesResponseData struct {
|
||||
Data []WsGetTradesResponseTrades `json:"data"`
|
||||
Symbol string `json:"symbol"`
|
||||
}
|
||||
|
||||
// WsGetTradesResponseTrades trade response
|
||||
type WsGetTradesResponseTrades struct {
|
||||
ID int64 `json:"id"`
|
||||
Price float64 `json:"price,string"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Side string `json:"side"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
@@ -4,24 +4,25 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/common/crypto"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/nonce"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/common/crypto"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/nonce"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/wshandler"
|
||||
log "github.com/thrasher-corp/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
const (
|
||||
hitbtcWebsocketAddress = "wss://api.hitbtc.com/api/2/ws"
|
||||
rpcVersion = "2.0"
|
||||
rateLimit = 20
|
||||
)
|
||||
|
||||
var requestID nonce.Nonce
|
||||
@@ -29,26 +30,13 @@ var requestID nonce.Nonce
|
||||
// WsConnect starts a new connection with the websocket API
|
||||
func (h *HitBTC) WsConnect() error {
|
||||
if !h.Websocket.IsEnabled() || !h.IsEnabled() {
|
||||
return errors.New(exchange.WebsocketNotEnabled)
|
||||
return errors.New(wshandler.WebsocketNotEnabled)
|
||||
}
|
||||
|
||||
var dialer websocket.Dialer
|
||||
|
||||
if h.Websocket.GetProxyAddress() != "" {
|
||||
proxy, err := url.Parse(h.Websocket.GetProxyAddress())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dialer.Proxy = http.ProxyURL(proxy)
|
||||
}
|
||||
|
||||
var err error
|
||||
h.WebsocketConn, _, err = dialer.Dial(hitbtcWebsocketAddress, http.Header{})
|
||||
err := h.WebsocketConn.Dial(&dialer, http.Header{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go h.WsHandleData()
|
||||
err = h.wsLogin()
|
||||
if err != nil {
|
||||
@@ -60,17 +48,6 @@ func (h *HitBTC) WsConnect() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// WsReadData reads from the websocket connection
|
||||
func (h *HitBTC) WsReadData() (exchange.WebsocketResponse, error) {
|
||||
_, resp, err := h.WebsocketConn.ReadMessage()
|
||||
if err != nil {
|
||||
return exchange.WebsocketResponse{}, err
|
||||
}
|
||||
|
||||
h.Websocket.TrafficAlert <- struct{}{}
|
||||
return exchange.WebsocketResponse{Raw: resp}, nil
|
||||
}
|
||||
|
||||
// WsHandleData handles websocket data
|
||||
func (h *HitBTC) WsHandleData() {
|
||||
h.Websocket.Wg.Add(1)
|
||||
@@ -85,11 +62,12 @@ func (h *HitBTC) WsHandleData() {
|
||||
return
|
||||
|
||||
default:
|
||||
resp, err := h.WsReadData()
|
||||
resp, err := h.WebsocketConn.ReadMessage()
|
||||
if err != nil {
|
||||
h.Websocket.DataHandler <- err
|
||||
return
|
||||
}
|
||||
h.Websocket.TrafficAlert <- struct{}{}
|
||||
|
||||
var init capture
|
||||
err = common.JSONDecode(resp.Raw, &init)
|
||||
@@ -97,11 +75,14 @@ func (h *HitBTC) WsHandleData() {
|
||||
h.Websocket.DataHandler <- err
|
||||
continue
|
||||
}
|
||||
|
||||
if init.Error.Code == 1002 {
|
||||
h.Websocket.SetCanUseAuthenticatedEndpoints(false)
|
||||
}
|
||||
if init.ID > 0 {
|
||||
h.WebsocketConn.AddResponseWithID(init.ID, resp.Raw)
|
||||
continue
|
||||
}
|
||||
if init.Error.Message != "" || init.Error.Code != 0 {
|
||||
if init.Error.Code == 1002 {
|
||||
h.Websocket.SetCanUseAuthenticatedEndpoints(false)
|
||||
}
|
||||
h.Websocket.DataHandler <- fmt.Errorf("hitbtc.go error - Code: %d, Message: %s",
|
||||
init.Error.Code,
|
||||
init.Error.Message)
|
||||
@@ -119,7 +100,7 @@ func (h *HitBTC) WsHandleData() {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HitBTC) handleSubscriptionUpdates(resp exchange.WebsocketResponse, init capture) {
|
||||
func (h *HitBTC) handleSubscriptionUpdates(resp wshandler.WebsocketResponse, init capture) {
|
||||
switch init.Method {
|
||||
case "ticker":
|
||||
var ticker WsTicker
|
||||
@@ -133,7 +114,7 @@ func (h *HitBTC) handleSubscriptionUpdates(resp exchange.WebsocketResponse, init
|
||||
h.Websocket.DataHandler <- err
|
||||
return
|
||||
}
|
||||
h.Websocket.DataHandler <- exchange.TickerData{
|
||||
h.Websocket.DataHandler <- wshandler.TickerData{
|
||||
Exchange: h.GetName(),
|
||||
AssetType: asset.Spot,
|
||||
Pair: currency.NewPairFromString(ticker.Params.Symbol),
|
||||
@@ -189,7 +170,7 @@ func (h *HitBTC) handleSubscriptionUpdates(resp exchange.WebsocketResponse, init
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HitBTC) handleCommandResponses(resp exchange.WebsocketResponse, init capture) {
|
||||
func (h *HitBTC) handleCommandResponses(resp wshandler.WebsocketResponse, init capture) {
|
||||
switch resultType := init.Result.(type) {
|
||||
case map[string]interface{}:
|
||||
switch resultType["reportType"].(string) {
|
||||
@@ -269,7 +250,7 @@ func (h *HitBTC) WsProcessOrderbookSnapshot(ob WsOrderbook) error {
|
||||
return err
|
||||
}
|
||||
|
||||
h.Websocket.DataHandler <- exchange.WebsocketOrderbookUpdate{
|
||||
h.Websocket.DataHandler <- wshandler.WebsocketOrderbookUpdate{
|
||||
Exchange: h.GetName(),
|
||||
Asset: asset.Spot,
|
||||
Pair: p,
|
||||
@@ -300,7 +281,7 @@ func (h *HitBTC) WsProcessOrderbookUpdate(ob WsOrderbook) error {
|
||||
return err
|
||||
}
|
||||
|
||||
h.Websocket.DataHandler <- exchange.WebsocketOrderbookUpdate{
|
||||
h.Websocket.DataHandler <- wshandler.WebsocketOrderbookUpdate{
|
||||
Exchange: h.GetName(),
|
||||
Asset: asset.Spot,
|
||||
Pair: p,
|
||||
@@ -311,9 +292,9 @@ func (h *HitBTC) WsProcessOrderbookUpdate(ob WsOrderbook) error {
|
||||
// GenerateDefaultSubscriptions Adds default subscriptions to websocket to be handled by ManageSubscriptions()
|
||||
func (h *HitBTC) GenerateDefaultSubscriptions() {
|
||||
var channels = []string{"subscribeTicker", "subscribeOrderbook", "subscribeTrades", "subscribeCandles"}
|
||||
var subscriptions []exchange.WebsocketChannelSubscription
|
||||
var subscriptions []wshandler.WebsocketChannelSubscription
|
||||
if h.Websocket.CanUseAuthenticatedEndpoints() {
|
||||
subscriptions = append(subscriptions, exchange.WebsocketChannelSubscription{
|
||||
subscriptions = append(subscriptions, wshandler.WebsocketChannelSubscription{
|
||||
Channel: "subscribeReports",
|
||||
})
|
||||
}
|
||||
@@ -321,7 +302,7 @@ func (h *HitBTC) GenerateDefaultSubscriptions() {
|
||||
for i := range channels {
|
||||
for j := range enabledCurrencies {
|
||||
enabledCurrencies[j].Delimiter = ""
|
||||
subscriptions = append(subscriptions, exchange.WebsocketChannelSubscription{
|
||||
subscriptions = append(subscriptions, wshandler.WebsocketChannelSubscription{
|
||||
Channel: channels[i],
|
||||
Currency: enabledCurrencies[j],
|
||||
})
|
||||
@@ -331,7 +312,7 @@ func (h *HitBTC) GenerateDefaultSubscriptions() {
|
||||
}
|
||||
|
||||
// Subscribe sends a websocket message to receive data from the channel
|
||||
func (h *HitBTC) Subscribe(channelToSubscribe exchange.WebsocketChannelSubscription) error {
|
||||
func (h *HitBTC) Subscribe(channelToSubscribe wshandler.WebsocketChannelSubscription) error {
|
||||
subscribe := WsNotification{
|
||||
Method: channelToSubscribe.Channel,
|
||||
}
|
||||
@@ -353,11 +334,11 @@ func (h *HitBTC) Subscribe(channelToSubscribe exchange.WebsocketChannelSubscript
|
||||
}
|
||||
}
|
||||
|
||||
return h.wsSend(subscribe)
|
||||
return h.WebsocketConn.SendMessage(subscribe)
|
||||
}
|
||||
|
||||
// Unsubscribe sends a websocket message to stop receiving data from the channel
|
||||
func (h *HitBTC) Unsubscribe(channelToSubscribe exchange.WebsocketChannelSubscription) error {
|
||||
func (h *HitBTC) Unsubscribe(channelToSubscribe wshandler.WebsocketChannelSubscription) error {
|
||||
unsubscribeChannel := strings.Replace(channelToSubscribe.Channel, "subscribe", "unsubscribe", 1)
|
||||
subscribe := WsNotification{
|
||||
JSONRPCVersion: rpcVersion,
|
||||
@@ -379,21 +360,7 @@ func (h *HitBTC) Unsubscribe(channelToSubscribe exchange.WebsocketChannelSubscri
|
||||
}
|
||||
}
|
||||
|
||||
return h.wsSend(subscribe)
|
||||
}
|
||||
|
||||
// WsSend sends data to the websocket server
|
||||
func (h *HitBTC) wsSend(data interface{}) error {
|
||||
h.wsRequestMtx.Lock()
|
||||
defer h.wsRequestMtx.Unlock()
|
||||
json, err := common.JSONEncode(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if h.Verbose {
|
||||
log.Debugf(log.ExchangeSys, "%v sending message to websocket %v", h.Name, string(json))
|
||||
}
|
||||
return h.WebsocketConn.WriteMessage(websocket.TextMessage, json)
|
||||
return h.WebsocketConn.SendMessage(subscribe)
|
||||
}
|
||||
|
||||
// Unsubscribe sends a websocket message to stop receiving data from the channel
|
||||
@@ -414,7 +381,7 @@ func (h *HitBTC) wsLogin() error {
|
||||
},
|
||||
}
|
||||
|
||||
err := h.wsSend(request)
|
||||
err := h.WebsocketConn.SendMessage(request)
|
||||
if err != nil {
|
||||
h.Websocket.SetCanUseAuthenticatedEndpoints(false)
|
||||
return err
|
||||
@@ -423,43 +390,68 @@ func (h *HitBTC) wsLogin() error {
|
||||
}
|
||||
|
||||
// wsPlaceOrder sends a websocket message to submit an order
|
||||
func (h *HitBTC) wsPlaceOrder(pair currency.Pair, side string, price, quantity float64) error {
|
||||
func (h *HitBTC) wsPlaceOrder(pair currency.Pair, side string, price, quantity float64) (*WsSubmitOrderSuccessResponse, error) {
|
||||
if !h.Websocket.CanUseAuthenticatedEndpoints() {
|
||||
return fmt.Errorf("%v not authenticated, cannot place order", h.Name)
|
||||
return nil, fmt.Errorf("%v not authenticated, cannot place order", h.Name)
|
||||
}
|
||||
id := h.WebsocketConn.GenerateMessageID(false)
|
||||
request := WsSubmitOrderRequest{
|
||||
Method: "newOrder",
|
||||
Params: WsSubmitOrderRequestData{
|
||||
ClientOrderID: fmt.Sprintf("%v", time.Now().Unix()),
|
||||
ClientOrderID: id,
|
||||
Symbol: pair,
|
||||
Side: strings.ToLower(side),
|
||||
Price: price,
|
||||
Quantity: quantity,
|
||||
},
|
||||
ID: int64(requestID.GetInc()),
|
||||
ID: id,
|
||||
}
|
||||
return h.wsSend(request)
|
||||
resp, err := h.WebsocketConn.SendMessageReturnResponse(id, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
var response WsSubmitOrderSuccessResponse
|
||||
err = common.JSONDecode(resp, &response)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
if response.Error.Code > 0 || response.Error.Message != "" {
|
||||
return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message)
|
||||
}
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
// wsCancelOrder sends a websocket message to cancel an order
|
||||
func (h *HitBTC) wsCancelOrder(clientOrderID string) error {
|
||||
func (h *HitBTC) wsCancelOrder(clientOrderID string) (*WsCancelOrderResponse, error) {
|
||||
if !h.Websocket.CanUseAuthenticatedEndpoints() {
|
||||
return fmt.Errorf("%v not authenticated, cannot place order", h.Name)
|
||||
return nil, fmt.Errorf("%v not authenticated, cannot place order", h.Name)
|
||||
}
|
||||
request := WsCancelOrderRequest{
|
||||
Method: "cancelOrder",
|
||||
Params: WsCancelOrderRequestData{
|
||||
ClientOrderID: clientOrderID,
|
||||
},
|
||||
ID: int64(requestID.GetInc()),
|
||||
ID: h.WebsocketConn.GenerateMessageID(false),
|
||||
}
|
||||
return h.wsSend(request)
|
||||
resp, err := h.WebsocketConn.SendMessageReturnResponse(request.ID, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
var response WsCancelOrderResponse
|
||||
err = common.JSONDecode(resp, &response)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
if response.Error.Code > 0 || response.Error.Message != "" {
|
||||
return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message)
|
||||
}
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
// wsReplaceOrder sends a websocket message to replace an order
|
||||
func (h *HitBTC) wsReplaceOrder(clientOrderID string, quantity, price float64) error {
|
||||
func (h *HitBTC) wsReplaceOrder(clientOrderID string, quantity, price float64) (*WsReplaceOrderResponse, error) {
|
||||
if !h.Websocket.CanUseAuthenticatedEndpoints() {
|
||||
return fmt.Errorf("%v not authenticated, cannot place order", h.Name)
|
||||
return nil, fmt.Errorf("%v not authenticated, cannot place order", h.Name)
|
||||
}
|
||||
request := WsReplaceOrderRequest{
|
||||
Method: "cancelReplaceOrder",
|
||||
@@ -469,33 +461,144 @@ func (h *HitBTC) wsReplaceOrder(clientOrderID string, quantity, price float64) e
|
||||
Quantity: quantity,
|
||||
Price: price,
|
||||
},
|
||||
ID: int64(requestID.GetInc()),
|
||||
ID: h.WebsocketConn.GenerateMessageID(false),
|
||||
}
|
||||
return h.wsSend(request)
|
||||
resp, err := h.WebsocketConn.SendMessageReturnResponse(request.ID, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
var response WsReplaceOrderResponse
|
||||
err = common.JSONDecode(resp, &response)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
if response.Error.Code > 0 || response.Error.Message != "" {
|
||||
return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message)
|
||||
}
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
// wsGetActiveOrders sends a websocket message to get all active orders
|
||||
func (h *HitBTC) wsGetActiveOrders() error {
|
||||
func (h *HitBTC) wsGetActiveOrders() (*WsActiveOrdersResponse, error) {
|
||||
if !h.Websocket.CanUseAuthenticatedEndpoints() {
|
||||
return fmt.Errorf("%v not authenticated, cannot place order", h.Name)
|
||||
return nil, fmt.Errorf("%v not authenticated, cannot place order", h.Name)
|
||||
}
|
||||
request := WsReplaceOrderRequest{
|
||||
Method: "getOrders",
|
||||
Params: WsReplaceOrderRequestData{},
|
||||
ID: int64(requestID.GetInc()),
|
||||
ID: h.WebsocketConn.GenerateMessageID(false),
|
||||
}
|
||||
return h.wsSend(request)
|
||||
resp, err := h.WebsocketConn.SendMessageReturnResponse(request.ID, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
var response WsActiveOrdersResponse
|
||||
err = common.JSONDecode(resp, &response)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
if response.Error.Code > 0 || response.Error.Message != "" {
|
||||
return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message)
|
||||
}
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
// wsGetTradingBalance sends a websocket message to get trading balance
|
||||
func (h *HitBTC) wsGetTradingBalance() error {
|
||||
func (h *HitBTC) wsGetTradingBalance() (*WsGetTradingBalanceResponse, error) {
|
||||
if !h.Websocket.CanUseAuthenticatedEndpoints() {
|
||||
return fmt.Errorf("%v not authenticated, cannot place order", h.Name)
|
||||
return nil, fmt.Errorf("%v not authenticated, cannot place order", h.Name)
|
||||
}
|
||||
request := WsReplaceOrderRequest{
|
||||
Method: "getTradingBalance",
|
||||
Params: WsReplaceOrderRequestData{},
|
||||
ID: int64(requestID.GetInc()),
|
||||
ID: h.WebsocketConn.GenerateMessageID(false),
|
||||
}
|
||||
return h.wsSend(request)
|
||||
resp, err := h.WebsocketConn.SendMessageReturnResponse(request.ID, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
var response WsGetTradingBalanceResponse
|
||||
err = common.JSONDecode(resp, &response)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
if response.Error.Code > 0 || response.Error.Message != "" {
|
||||
return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message)
|
||||
}
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
// wsGetCurrencies sends a websocket message to get trading balance
|
||||
func (h *HitBTC) wsGetCurrencies(currencyItem currency.Code) (*WsGetCurrenciesResponse, error) {
|
||||
request := WsGetCurrenciesRequest{
|
||||
Method: "getCurrency",
|
||||
Params: WsGetCurrenciesRequestParameters{
|
||||
Currency: currencyItem,
|
||||
},
|
||||
ID: h.WebsocketConn.GenerateMessageID(false),
|
||||
}
|
||||
resp, err := h.WebsocketConn.SendMessageReturnResponse(request.ID, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
var response WsGetCurrenciesResponse
|
||||
err = common.JSONDecode(resp, &response)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
if response.Error.Code > 0 || response.Error.Message != "" {
|
||||
return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message)
|
||||
}
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
// wsGetSymbols sends a websocket message to get trading balance
|
||||
func (h *HitBTC) wsGetSymbols(currencyItem currency.Pair) (*WsGetSymbolsResponse, error) {
|
||||
request := WsGetSymbolsRequest{
|
||||
Method: "getSymbol",
|
||||
Params: WsGetSymbolsRequestParameters{
|
||||
Symbol: currencyItem,
|
||||
},
|
||||
ID: h.WebsocketConn.GenerateMessageID(false),
|
||||
}
|
||||
resp, err := h.WebsocketConn.SendMessageReturnResponse(request.ID, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
var response WsGetSymbolsResponse
|
||||
err = common.JSONDecode(resp, &response)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
if response.Error.Code > 0 || response.Error.Message != "" {
|
||||
return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message)
|
||||
}
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
// wsGetSymbols sends a websocket message to get trading balance
|
||||
func (h *HitBTC) wsGetTrades(currencyItem currency.Pair, limit int64, sort, by string) (*WsGetTradesResponse, error) {
|
||||
request := WsGetTradesRequest{
|
||||
Method: "getTrades",
|
||||
Params: WsGetTradesRequestParameters{
|
||||
Symbol: currencyItem,
|
||||
Limit: limit,
|
||||
Sort: sort,
|
||||
By: by,
|
||||
},
|
||||
ID: h.WebsocketConn.GenerateMessageID(false),
|
||||
}
|
||||
resp, err := h.WebsocketConn.SendMessageReturnResponse(request.ID, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
var response WsGetTradesResponse
|
||||
err = common.JSONDecode(resp, &response)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %v", h.Name, err)
|
||||
}
|
||||
if response.Error.Code > 0 || response.Error.Message != "" {
|
||||
return &response, fmt.Errorf("%v Error:%v Message:%v", h.Name, response.Error.Code, response.Error.Message)
|
||||
}
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
@@ -8,15 +8,16 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/wshandler"
|
||||
log "github.com/thrasher-corp/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
// GetDefaultConfig returns a default exchange config
|
||||
@@ -88,9 +89,17 @@ func (h *HitBTC) SetDefaults() {
|
||||
h.API.Endpoints.URLDefault = apiURL
|
||||
h.API.Endpoints.URL = h.API.Endpoints.URLDefault
|
||||
h.API.Endpoints.WebsocketURL = hitbtcWebsocketAddress
|
||||
h.WebsocketInit()
|
||||
h.Websocket.Functionality = exchange.WebsocketTickerSupported |
|
||||
exchange.WebsocketOrderbookSupported
|
||||
h.Websocket = wshandler.New()
|
||||
h.Websocket.Functionality = wshandler.WebsocketTickerSupported |
|
||||
wshandler.WebsocketOrderbookSupported |
|
||||
wshandler.WebsocketSubscribeSupported |
|
||||
wshandler.WebsocketUnsubscribeSupported |
|
||||
wshandler.WebsocketAuthenticatedEndpointsSupported |
|
||||
wshandler.WebsocketSubmitOrderSupported |
|
||||
wshandler.WebsocketCancelOrderSupported |
|
||||
wshandler.WebsocketMessageCorrelationSupported
|
||||
h.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit
|
||||
h.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout
|
||||
}
|
||||
|
||||
// Setup sets user exchange configuration settings
|
||||
@@ -105,14 +114,29 @@ func (h *HitBTC) Setup(exch *config.ExchangeConfig) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return h.WebsocketSetup(h.WsConnect,
|
||||
err = h.Websocket.Setup(h.WsConnect,
|
||||
h.Subscribe,
|
||||
h.Unsubscribe,
|
||||
exch.Name,
|
||||
exch.Features.Enabled.Websocket,
|
||||
exch.Verbose,
|
||||
hitbtcWebsocketAddress,
|
||||
exch.API.Endpoints.WebsocketURL)
|
||||
exch.API.Endpoints.WebsocketURL,
|
||||
exch.API.AuthenticatedWebsocketSupport)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h.WebsocketConn = &wshandler.WebsocketConnection{
|
||||
ExchangeName: h.Name,
|
||||
URL: h.Websocket.GetWebsocketURL(),
|
||||
ProxyURL: h.Websocket.GetProxyAddress(),
|
||||
Verbose: h.Verbose,
|
||||
RateLimit: rateLimit,
|
||||
ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout,
|
||||
ResponseMaxLimit: exch.WebsocketResponseMaxLimit,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start starts the HitBTC go routine
|
||||
@@ -395,7 +419,7 @@ func (h *HitBTC) WithdrawFiatFundsToInternationalBank(withdrawRequest *exchange.
|
||||
}
|
||||
|
||||
// GetWebsocket returns a pointer to the exchange websocket
|
||||
func (h *HitBTC) GetWebsocket() (*exchange.Websocket, error) {
|
||||
func (h *HitBTC) GetWebsocket() (*wshandler.Websocket, error) {
|
||||
return h.Websocket, nil
|
||||
}
|
||||
|
||||
@@ -484,20 +508,20 @@ func (h *HitBTC) GetOrderHistory(getOrdersRequest *exchange.GetOrdersRequest) ([
|
||||
|
||||
// SubscribeToWebsocketChannels appends to ChannelsToSubscribe
|
||||
// which lets websocket.manageSubscriptions handle subscribing
|
||||
func (h *HitBTC) SubscribeToWebsocketChannels(channels []exchange.WebsocketChannelSubscription) error {
|
||||
func (h *HitBTC) SubscribeToWebsocketChannels(channels []wshandler.WebsocketChannelSubscription) error {
|
||||
h.Websocket.SubscribeToChannels(channels)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnsubscribeToWebsocketChannels removes from ChannelsToSubscribe
|
||||
// which lets websocket.manageSubscriptions handle unsubscribing
|
||||
func (h *HitBTC) UnsubscribeToWebsocketChannels(channels []exchange.WebsocketChannelSubscription) error {
|
||||
h.Websocket.UnsubscribeToChannels(channels)
|
||||
func (h *HitBTC) UnsubscribeToWebsocketChannels(channels []wshandler.WebsocketChannelSubscription) error {
|
||||
h.Websocket.RemoveSubscribedChannels(channels)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSubscriptions returns a copied list of subscriptions
|
||||
func (h *HitBTC) GetSubscriptions() ([]exchange.WebsocketChannelSubscription, error) {
|
||||
func (h *HitBTC) GetSubscriptions() ([]wshandler.WebsocketChannelSubscription, error) {
|
||||
return h.Websocket.GetSubscriptions(), nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user