mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
Engine: BTC Markets V3 Updates (#385)
* Broken WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP * Errors Fixed * PR Changes * PR Changes * PR Changes * PR Changes * PR Changes * PR Changes * PR Changes * PR Changes * PR Changes * Offline Fees Fixed * MarketCandles fixed and constants added * t.log deleted * Broken WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP * Errors Fixed * PR Changes * PR Changes * PR Changes * MarketCandles fixed and constants added * t.log deleted * Added BSB and Order Status * WIP * Websocket and BatchPlaceCancelOrder and other minor nits fixed * Linter Issues Fixed * Function Name Change * Replacing b.GetMarkets with b.GetEnabledPairs * Pagination param changes and PlaceCancelBatch changes * Merge Conflicts WIP * Linter Issue Fixed * optional params fixed
This commit is contained in:
@@ -73,7 +73,7 @@ type EndpointResponse struct {
|
||||
// Bank contains all required data for a wrapper withdrawal request
|
||||
type Bank struct {
|
||||
BankAccountName string `json:"bankAccountName"`
|
||||
BankAccountNumber float64 `json:"bankAccountNumber"`
|
||||
BankAccountNumber string `json:"bankAccountNumber"`
|
||||
BankAddress string `json:"bankAddress"`
|
||||
BankCity string `json:"bankCity"`
|
||||
BankCountry string `json:"bankCountry"`
|
||||
|
||||
@@ -548,7 +548,7 @@ func (b *Bitfinex) WithdrawFIAT(withdrawalType, walletType string, withdrawReque
|
||||
req["walletselected"] = walletType
|
||||
req["amount"] = strconv.FormatFloat(withdrawRequest.Amount, 'f', -1, 64)
|
||||
req["account_name"] = withdrawRequest.BankAccountName
|
||||
req["account_number"] = strconv.FormatFloat(withdrawRequest.BankAccountNumber, 'f', -1, 64)
|
||||
req["account_number"] = withdrawRequest.BankAccountNumber
|
||||
req["bank_name"] = withdrawRequest.BankName
|
||||
req["bank_address"] = withdrawRequest.BankAddress
|
||||
req["bank_city"] = withdrawRequest.BankCity
|
||||
|
||||
@@ -917,7 +917,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
Description: "WITHDRAW IT ALL",
|
||||
},
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
BankAccountNumber: "12345",
|
||||
BankAddress: "123 Fake St",
|
||||
BankCity: "Tarry Town",
|
||||
BankCountry: "Hyrule",
|
||||
@@ -952,7 +952,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
Description: "WITHDRAW IT ALL",
|
||||
},
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
BankAccountNumber: "12345",
|
||||
BankAddress: "123 Fake St",
|
||||
BankCity: "Tarry Town",
|
||||
BankCountry: "Hyrule",
|
||||
|
||||
@@ -497,7 +497,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
Description: "WITHDRAW IT ALL",
|
||||
},
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
BankAccountNumber: "12345",
|
||||
BankCode: 123,
|
||||
BankAddress: "123 Fake St",
|
||||
BankCity: "Tarry Town",
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -419,9 +418,7 @@ func (b *Bithumb) WithdrawFiatFunds(withdrawRequest *exchange.FiatWithdrawReques
|
||||
return "", errors.New("only KRW is supported")
|
||||
}
|
||||
bankDetails := fmt.Sprintf("%v_%v", withdrawRequest.BankCode, withdrawRequest.BankName)
|
||||
bankAccountNumber := strconv.FormatFloat(withdrawRequest.BankAccountNumber, 'f', -1, 64)
|
||||
withdrawAmountInt := int64(withdrawRequest.Amount)
|
||||
resp, err := b.RequestKRWWithdraw(bankDetails, bankAccountNumber, withdrawAmountInt)
|
||||
resp, err := b.RequestKRWWithdraw(bankDetails, withdrawRequest.BankAccountNumber, int64(withdrawRequest.Amount))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -489,7 +489,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
Description: "WITHDRAW IT ALL",
|
||||
},
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
BankAccountNumber: "12345",
|
||||
BankAddress: "123 Fake St",
|
||||
BankCity: "Tarry Town",
|
||||
BankCountry: "AU",
|
||||
@@ -527,7 +527,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
Description: "WITHDRAW IT ALL",
|
||||
},
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
BankAccountNumber: "12345",
|
||||
BankAddress: "123 Fake St",
|
||||
BankCity: "Tarry Town",
|
||||
BankCountry: "AU",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,13 @@
|
||||
package btcmarkets
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"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/order"
|
||||
)
|
||||
|
||||
@@ -18,21 +18,23 @@ const (
|
||||
apiKey = ""
|
||||
apiSecret = ""
|
||||
canManipulateRealOrders = false
|
||||
BTCAUD = "BTC-AUD"
|
||||
LTCAUD = "LTC-AUD"
|
||||
ETHAUD = "ETH-AUD"
|
||||
fakePair = "Fake-USDT"
|
||||
bid = "bid"
|
||||
)
|
||||
|
||||
func TestSetDefaults(t *testing.T) {
|
||||
func TestMain(m *testing.M) {
|
||||
b.SetDefaults()
|
||||
}
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
cfg := config.GetConfig()
|
||||
err := cfg.LoadConfig("../../testdata/configtest.json", true)
|
||||
if err != nil {
|
||||
t.Fatal("BTC Markets load config error", err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
bConfig, err := cfg.GetExchangeConfig("BTC Markets")
|
||||
if err != nil {
|
||||
t.Error("BTC Markets Setup() init error")
|
||||
log.Fatal(err)
|
||||
}
|
||||
bConfig.API.Credentials.Key = apiKey
|
||||
bConfig.API.Credentials.Secret = apiSecret
|
||||
@@ -40,29 +42,27 @@ func TestSetup(t *testing.T) {
|
||||
|
||||
err = b.Setup(bConfig)
|
||||
if err != nil {
|
||||
t.Fatal("BTC Markets setup error", err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func areTestAPIKeysSet() bool {
|
||||
return b.AllowAuthenticatedRequest()
|
||||
}
|
||||
|
||||
func TestGetMarkets(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetMarkets()
|
||||
if err != nil {
|
||||
t.Error("GetMarkets() error", err)
|
||||
t.Error("GetTicker() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetTicker("BTC", "AUD")
|
||||
if err != nil {
|
||||
t.Error("GetTicker() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderbook(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetOrderbook("BTC", "AUD")
|
||||
_, err := b.GetTicker(BTCAUD)
|
||||
if err != nil {
|
||||
t.Error("GetOrderbook() error", err)
|
||||
}
|
||||
@@ -70,437 +70,412 @@ func TestGetOrderbook(t *testing.T) {
|
||||
|
||||
func TestGetTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetTrades("BTC", "AUD", nil)
|
||||
if err != nil {
|
||||
t.Error("GetTrades() error", err)
|
||||
}
|
||||
|
||||
val := url.Values{}
|
||||
val.Set("since", "0")
|
||||
_, err = b.GetTrades("BTC", "AUD", val)
|
||||
_, err := b.GetTrades(BTCAUD, 0, 0, 5)
|
||||
if err != nil {
|
||||
t.Error("GetTrades() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewOrder(t *testing.T) {
|
||||
func TestGetOrderbook(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.NewOrder("AUD", "BTC", 0, 0, "Bid",
|
||||
order.Limit.Lower(), "testTest")
|
||||
if err == nil {
|
||||
t.Error("NewOrder() Expected error")
|
||||
_, err := b.GetOrderbook(BTCAUD, 2)
|
||||
if err != nil {
|
||||
t.Error("GetTrades() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelExistingOrder(t *testing.T) {
|
||||
func TestGetMarketCandles(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.CancelExistingOrder([]int64{1337})
|
||||
if err == nil {
|
||||
t.Error("CancelExistingOrder() Expected error")
|
||||
_, err := b.GetMarketCandles(BTCAUD, "", "", "", 0, 0, 5)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrders(t *testing.T) {
|
||||
func TestGetTickers(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetOrders("AUD", "BTC", 10, 0, false)
|
||||
if err == nil {
|
||||
t.Error("GetOrders() Expected error")
|
||||
}
|
||||
_, err = b.GetOrders("AUD", "BTC", 10, 0, true)
|
||||
if err == nil {
|
||||
t.Error("GetOrders() Expected error")
|
||||
temp := []string{BTCAUD, LTCAUD, ETHAUD}
|
||||
_, err := b.GetTickers(temp)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderDetail(t *testing.T) {
|
||||
func TestGetMultipleOrderbooks(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetOrderDetail([]int64{1337})
|
||||
if err == nil {
|
||||
t.Error("GetOrderDetail() Expected error")
|
||||
temp := []string{BTCAUD, LTCAUD, ETHAUD}
|
||||
_, err := b.GetMultipleOrderbooks(temp)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetServerTime(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetServerTime()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccountBalance(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.GetAccountBalance()
|
||||
if err == nil {
|
||||
t.Error("GetAccountBalance() Expected error")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawCrypto(t *testing.T) {
|
||||
func TestGetTradingFees(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.WithdrawCrypto(0, "BTC", "LOLOLOL")
|
||||
if err == nil {
|
||||
t.Error("WithdrawCrypto() Expected error")
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.GetTradingFees()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawAUD(t *testing.T) {
|
||||
func TestGetTradeHistory(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.WithdrawAUD("BLA", "1337", "blawest", "1336", 10000000)
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.GetTradeHistory(ETHAUD, "", -1, -1, -1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = b.GetTradeHistory(BTCAUD, "", -1, -1, 1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = b.GetTradeHistory(fakePair, "", -1, -1, -1)
|
||||
if err == nil {
|
||||
t.Error("WithdrawAUD() Expected error")
|
||||
t.Error("expected an error due to invalid trading pair")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTradeByID(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.GetTradeByID("4712043732")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
||||
t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly")
|
||||
}
|
||||
_, err := b.NewOrder(BTCAUD, 100, 1, limit, bid, 0, 0, "", true, "", "")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = b.NewOrder(BTCAUD, 100, 1, "invalid", bid, 0, 0, "", true, "", "")
|
||||
if err == nil {
|
||||
t.Error("expected an error due to invalid ordertype")
|
||||
}
|
||||
_, err = b.NewOrder(BTCAUD, 100, 1, limit, "invalid", 0, 0, "", true, "", "")
|
||||
if err == nil {
|
||||
t.Error("expected an error due to invalid orderside")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.GetOrders("", -1, -1, 2, "")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = b.GetOrders(LTCAUD, -1, -1, -1, "open")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelOpenOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
||||
t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly")
|
||||
}
|
||||
temp := []string{BTCAUD, LTCAUD}
|
||||
_, err := b.CancelAllOpenOrdersByPairs(temp)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
temp = []string{BTCAUD, fakePair}
|
||||
_, err = b.CancelAllOpenOrdersByPairs(temp)
|
||||
if err == nil {
|
||||
t.Error("expected an error due to invalid marketID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.FetchOrder("4477045999")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = b.FetchOrder("696969")
|
||||
if err == nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
||||
t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly")
|
||||
}
|
||||
_, err := b.RemoveOrder("")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListWithdrawals(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.ListWithdrawals(-1, -1, -1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetWithdrawal(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.GetWithdrawal("4477381751")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListDeposits(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.ListDeposits(-1, -1, -1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDeposit(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.GetDeposit("4476769607")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListTransfers(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.ListTransfers(-1, -1, -1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTransfer(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.GetTransfer("4476769607")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = b.GetTransfer("6969696")
|
||||
if err == nil {
|
||||
t.Error("expected an error due to invalid transferID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchDepositAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.FetchDepositAddress("LTC", -1, -1, -1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = b.FetchDepositAddress(fakePair, -1, -1, -1)
|
||||
if err != nil {
|
||||
t.Error("expected an error due to invalid assetID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetWithdrawalFees(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetWithdrawalFees()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListAssets(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.ListAssets()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTransactions(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.GetTransactions("", -1, -1, -1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateNewReport(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.CreateNewReport("TransactionReport", "json")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetReport(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.GetReport("1kv38epne5v7lek9f18m60idg6")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestWithdaw(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
||||
t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly")
|
||||
}
|
||||
_, err := b.RequestWithdraw("BTC", 1, "sdjflajdslfjld", "", "", "", "")
|
||||
if err == nil {
|
||||
t.Error("expected an error due to invalid toAddress")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchPlaceCancelOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
||||
t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly")
|
||||
}
|
||||
var temp []PlaceBatch
|
||||
o := PlaceBatch{
|
||||
MarketID: BTCAUD,
|
||||
Amount: 11000,
|
||||
Price: 1,
|
||||
OrderType: order.Limit.String(),
|
||||
Side: bid,
|
||||
}
|
||||
_, err := b.BatchPlaceCancelOrders(nil, append(temp, o))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBatchTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
temp := []string{"4477045999", "4477381751", "4476769607"}
|
||||
_, err := b.GetBatchTrades(temp)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelBatchOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
||||
t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly")
|
||||
}
|
||||
temp := []string{"4477045999", "4477381751", "4477381751"}
|
||||
_, err := b.CancelBatchOrders(temp)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccountInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := b.GetAccountInfo()
|
||||
if err == nil {
|
||||
t.Error("GetAccountInfo() Expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFundingHistory(t *testing.T) {
|
||||
_, err := b.GetFundingHistory()
|
||||
if err == nil {
|
||||
t.Error("GetAccountInfo() Expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelOrder(t *testing.T) {
|
||||
_, err := b.CancelExistingOrder([]int64{1337})
|
||||
|
||||
if err == nil {
|
||||
t.Error("CancelgOrder() Expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderInfo(t *testing.T) {
|
||||
_, err := b.GetOrderInfo("1337")
|
||||
if err == nil {
|
||||
t.Error("GetOrderInfo() Expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func setFeeBuilder() *exchange.FeeBuilder {
|
||||
return &exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
}
|
||||
|
||||
// TestGetFeeByTypeOfflineTradeFee logic test
|
||||
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
var feeBuilder = setFeeBuilder()
|
||||
b.GetFeeByType(feeBuilder)
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
if feeBuilder.FeeType != exchange.OfflineTradeFee {
|
||||
t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType)
|
||||
}
|
||||
} else {
|
||||
if feeBuilder.FeeType != exchange.CryptocurrencyTradeFee {
|
||||
t.Errorf("Expected %v, received %v", exchange.CryptocurrencyTradeFee, feeBuilder.FeeType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFee(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
var feeBuilder = setFeeBuilder()
|
||||
|
||||
if apiKey != "" || apiSecret != "" {
|
||||
// CryptocurrencyTradeFee Fiat
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.Pair.Quote = currency.USD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0.00849999) || err != nil {
|
||||
t.Error(err)
|
||||
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.00849999), resp)
|
||||
}
|
||||
|
||||
// CryptocurrencyTradeFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0.0022) || err != nil {
|
||||
t.Error(err)
|
||||
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.0022), resp)
|
||||
}
|
||||
|
||||
// CryptocurrencyTradeFee High quantity
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.Amount = 1000
|
||||
feeBuilder.PurchasePrice = 1000
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(2200) || err != nil {
|
||||
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(22000), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// CryptocurrencyTradeFee IsMaker
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.IsMaker = true
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0.0022) || err != nil {
|
||||
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.0022), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// CryptocurrencyTradeFee Negative purchase price
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.PurchasePrice = -1000
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// CryptocurrencyWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0.001) || err != nil {
|
||||
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.001), resp)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// CyptocurrencyDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.CyptocurrencyDepositFee
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.FiatCurrency = currency.AUD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.FiatCurrency = currency.AUD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatWithdrawPermissions(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.AutoWithdrawFiatText
|
||||
|
||||
withdrawPermissions := b.FormatWithdrawPermissions()
|
||||
|
||||
if withdrawPermissions != expectedResult {
|
||||
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetActiveOrders(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
var getOrdersRequest = order.GetOrdersRequest{
|
||||
OrderType: order.AnyType,
|
||||
}
|
||||
|
||||
_, err := b.GetActiveOrders(&getOrdersRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Could not get open orders: %s", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderHistory(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
var getOrdersRequest = order.GetOrdersRequest{
|
||||
OrderType: order.AnyType,
|
||||
Currencies: []currency.Pair{currency.NewPair(currency.LTC,
|
||||
currency.BTC)},
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
|
||||
_, err := b.GetOrderHistory(&getOrdersRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Could not get order history: %s", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
var input order.GetOrdersRequest
|
||||
input.OrderSide = order.Buy
|
||||
_, err := b.GetOrderHistory(&input)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
|
||||
// ----------------------------------------------------------------------------------------------------------------------------
|
||||
func areTestAPIKeysSet() bool {
|
||||
return b.ValidateAPICredentials()
|
||||
}
|
||||
|
||||
func TestSubmitOrder(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var orderSubmission = &order.Submit{
|
||||
Pair: currency.Pair{
|
||||
Delimiter: "-",
|
||||
Base: currency.BTC,
|
||||
Quote: currency.LTC,
|
||||
},
|
||||
OrderSide: order.Buy,
|
||||
OrderType: order.Limit,
|
||||
Price: 1,
|
||||
Amount: 1,
|
||||
ClientID: "meowOrder",
|
||||
}
|
||||
response, err := b.SubmitOrder(orderSubmission)
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
t.Errorf("Order failed to be placed: %v", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
func TestUpdateOrderbook(t *testing.T) {
|
||||
t.Parallel()
|
||||
cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.AUD.String(), "-")
|
||||
_, err := b.UpdateOrderbook(cp, asset.Spot)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelExchangeOrder(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = &order.Cancel{
|
||||
OrderID: "1",
|
||||
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
AccountID: "1",
|
||||
CurrencyPair: currencyPair,
|
||||
}
|
||||
|
||||
err := b.CancelOrder(orderCancellation)
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Could not cancel orders: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = &order.Cancel{
|
||||
OrderID: "1",
|
||||
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
AccountID: "1",
|
||||
CurrencyPair: currencyPair,
|
||||
}
|
||||
|
||||
resp, err := b.CancelAllOrders(orderCancellation)
|
||||
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Could not cancel orders: %v", err)
|
||||
}
|
||||
|
||||
if len(resp.Status) > 0 {
|
||||
t.Errorf("%v orders failed to cancel", len(resp.Status))
|
||||
}
|
||||
}
|
||||
|
||||
func TestModifyOrder(t *testing.T) {
|
||||
_, err := b.ModifyOrder(&order.Modify{})
|
||||
if err == nil {
|
||||
t.Error("ModifyOrder() Expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdraw(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
withdrawCryptoRequest := exchange.CryptoWithdrawRequest{
|
||||
GenericWithdrawRequestInfo: exchange.GenericWithdrawRequestInfo{
|
||||
Amount: -1,
|
||||
Currency: currency.BTC,
|
||||
Description: "WITHDRAW IT ALL",
|
||||
},
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
}
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
_, err := b.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest)
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Withdraw failed to be placed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawFiat(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var withdrawFiatRequest = exchange.FiatWithdrawRequest{
|
||||
GenericWithdrawRequestInfo: exchange.GenericWithdrawRequestInfo{
|
||||
Amount: -1,
|
||||
Currency: currency.USD,
|
||||
Description: "WITHDRAW IT ALL",
|
||||
},
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
BankAddress: "123 Fake St",
|
||||
BankCity: "Tarry Town",
|
||||
BankCountry: "Hyrule",
|
||||
BankName: "Commonwealth Bank of Australia",
|
||||
WireCurrency: currency.AUD.String(),
|
||||
SwiftCode: "Taylor",
|
||||
RequiresIntermediaryBank: false,
|
||||
IsExpressWire: false,
|
||||
}
|
||||
|
||||
_, err := b.WithdrawFiatFunds(&withdrawFiatRequest)
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Withdraw failed to be placed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawInternationalBank(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var withdrawFiatRequest = exchange.FiatWithdrawRequest{}
|
||||
_, err := b.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest)
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("GetDepositAddress() error cannot be nil")
|
||||
func TestUpdateTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.AUD.String(), "-")
|
||||
_, err := b.UpdateTicker(cp, asset.Spot)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +1,74 @@
|
||||
package btcmarkets
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
)
|
||||
|
||||
// Response is the genralized response type
|
||||
type Response struct {
|
||||
Success bool `json:"success"`
|
||||
ErrorCode int `json:"errorCode"`
|
||||
ErrorMessage string `json:"errorMessage"`
|
||||
ID int `json:"id"`
|
||||
Responses []ResponseDetails `json:"responses"`
|
||||
ClientRequestID string `json:"clientRequestId"`
|
||||
Orders []Order `json:"orders"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
// ResponseDetails holds order status details
|
||||
type ResponseDetails struct {
|
||||
Success bool `json:"success"`
|
||||
ErrorCode int `json:"errorCode"`
|
||||
ErrorMessage string `json:"errorMessage"`
|
||||
ID int64 `json:"id"`
|
||||
}
|
||||
import "time"
|
||||
|
||||
// Market holds a tradable market instrument
|
||||
type Market struct {
|
||||
Instrument string `json:"instrument"`
|
||||
Currency string `json:"currency"`
|
||||
MarketID string `json:"marketId"`
|
||||
BaseAsset string `json:"baseAsset"`
|
||||
QuoteAsset string `json:"quoteAsset"`
|
||||
MinOrderAmount float64 `json:"minOrderAmount,string"`
|
||||
MaxOrderAmount float64 `json:"maxOrderAmount,string"`
|
||||
AmountDecimals int64 `json:"amountDecimals,string"`
|
||||
PriceDecimals int64 `json:"priceDecimals,string"`
|
||||
}
|
||||
|
||||
// Ticker holds ticker information
|
||||
type Ticker struct {
|
||||
BestAsk float64 `json:"bestAsk"`
|
||||
BestBid float64 `json:"bestBid"`
|
||||
Currency currency.Code `json:"currency"`
|
||||
High24h float64 `json:"high24h"`
|
||||
Instrument currency.Pair `json:"instrument"`
|
||||
LastPrice float64 `json:"lastPrice"`
|
||||
Low24h float64 `json:"low24h"`
|
||||
Price24h float64 `json:"price24h"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Volume24h float64 `json:"volume24h"`
|
||||
}
|
||||
|
||||
// Orderbook holds current orderbook information returned from the exchange
|
||||
type Orderbook struct {
|
||||
Currency string `json:"currency"`
|
||||
Instrument string `json:"instrument"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Asks [][]float64 `json:"asks"`
|
||||
Bids [][]float64 `json:"bids"`
|
||||
MarketID string `json:"marketId"`
|
||||
BestBID float64 `json:"bestBid,string"`
|
||||
BestAsk float64 `json:"bestAsk,string"`
|
||||
LastPrice float64 `json:"lastPrice,string"`
|
||||
Volume float64 `json:"volume24h,string"`
|
||||
Change24h float64 `json:"price24h,string"`
|
||||
Low24h float64 `json:"low24h,string"`
|
||||
High24h float64 `json:"high24h,string"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
// Trade holds trade information
|
||||
type Trade struct {
|
||||
TradeID int64 `json:"tid"`
|
||||
Amount float64 `json:"amount"`
|
||||
Price float64 `json:"price"`
|
||||
Date int64 `json:"date"`
|
||||
TradeID string `json:"id"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
// tempOrderbook stores orderbook data
|
||||
type tempOrderbook struct {
|
||||
MarketID string `json:"marketId"`
|
||||
SnapshotID int64 `json:"snapshotId"`
|
||||
Asks [][2]string `json:"asks"`
|
||||
Bids [][2]string `json:"bids"`
|
||||
}
|
||||
|
||||
// OBData stores orderbook data
|
||||
type OBData struct {
|
||||
Price float64
|
||||
Volume float64
|
||||
}
|
||||
|
||||
// Orderbook holds current orderbook information returned from the exchange
|
||||
type Orderbook struct {
|
||||
MarketID string
|
||||
SnapshotID int64
|
||||
Asks []OBData
|
||||
Bids []OBData
|
||||
}
|
||||
|
||||
// MarketCandle stores candle data for a given pair
|
||||
type MarketCandle struct {
|
||||
Time time.Time
|
||||
Open float64
|
||||
Close float64
|
||||
Low float64
|
||||
High float64
|
||||
Volume float64
|
||||
}
|
||||
|
||||
// TimeResp stores server time
|
||||
type TimeResp struct {
|
||||
Time time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
// TradingFee 30 day trade volume
|
||||
@@ -90,7 +98,7 @@ type Order struct {
|
||||
Instrument string `json:"instrument"`
|
||||
OrderSide string `json:"orderSide"`
|
||||
OrderType string `json:"ordertype"`
|
||||
CreationTime float64 `json:"creationTime"`
|
||||
CreationTime time.Time `json:"creationTime"`
|
||||
Status string `json:"status"`
|
||||
ErrorMessage string `json:"errorMessage"`
|
||||
Price float64 `json:"price"`
|
||||
@@ -102,19 +110,164 @@ type Order struct {
|
||||
|
||||
// TradeResponse holds trade information
|
||||
type TradeResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
CreationTime float64 `json:"creationTime"`
|
||||
Description string `json:"description"`
|
||||
Price float64 `json:"price"`
|
||||
Volume float64 `json:"volume"`
|
||||
Fee float64 `json:"fee"`
|
||||
ID int64 `json:"id"`
|
||||
CreationTime time.Time `json:"creationTime"`
|
||||
Description string `json:"description"`
|
||||
Price float64 `json:"price"`
|
||||
Volume float64 `json:"volume"`
|
||||
Fee float64 `json:"fee"`
|
||||
}
|
||||
|
||||
// AccountBalance holds account balance details
|
||||
type AccountBalance struct {
|
||||
Balance float64 `json:"balance"`
|
||||
PendingFunds float64 `json:"pendingFunds"`
|
||||
Currency string `json:"currency"`
|
||||
// AccountData stores account data
|
||||
type AccountData struct {
|
||||
AssetName string `json:"assetName"`
|
||||
Balance float64 `json:"balance,string"`
|
||||
Available float64 `json:"available,string"`
|
||||
Locked float64 `json:"locked,string"`
|
||||
}
|
||||
|
||||
// TradeHistoryData stores data of past trades
|
||||
type TradeHistoryData struct {
|
||||
ID string `json:"id"`
|
||||
MarketID string `json:"marketId"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Price float64 `json:"price,string"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Side string `json:"side"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
OrderID string `json:"orderId"`
|
||||
LiquidityType string `json:"liquidityType"`
|
||||
}
|
||||
|
||||
// OrderData stores data for new order created
|
||||
type OrderData struct {
|
||||
OrderID string `json:"orderId"`
|
||||
MarketID string `json:"marketId"`
|
||||
Side string `json:"side"`
|
||||
Type string `json:"type"`
|
||||
CreationTime time.Time `json:"creationTime"`
|
||||
Price float64 `json:"price,string"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
OpenAmount float64 `json:"openAmount,string"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
// CancelOrderResp stores data for cancelled orders
|
||||
type CancelOrderResp struct {
|
||||
OrderID string `json:"orderId"`
|
||||
ClientOrderID string `json:"clientOrderId"`
|
||||
}
|
||||
|
||||
// PaymentDetails stores payment address
|
||||
type PaymentDetails struct {
|
||||
Address string `json:"address"`
|
||||
}
|
||||
|
||||
// TransferData stores data from asset transfers
|
||||
type TransferData struct {
|
||||
ID string `json:"id"`
|
||||
AssetName string `json:"assetName"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
RequestType string `json:"type"`
|
||||
CreationTime time.Time `json:"creationTime"`
|
||||
Status string `json:"status"`
|
||||
Description string `json:"description"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
LastUpdate string `json:"lastUpdate"`
|
||||
PaymentDetails PaymentDetails `json:"paymentDetail"`
|
||||
}
|
||||
|
||||
// DepositAddress stores deposit address data
|
||||
type DepositAddress struct {
|
||||
Address string `json:"address"`
|
||||
AssetName string `json:"assetName"`
|
||||
}
|
||||
|
||||
// WithdrawalFeeData stores data for fees
|
||||
type WithdrawalFeeData struct {
|
||||
AssetName string `json:"assetName"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
}
|
||||
|
||||
// AssetData stores data for given asset
|
||||
type AssetData struct {
|
||||
AssetName string `json:"assetName"`
|
||||
MinDepositAmount float64 `json:"minDepositAmount,string"`
|
||||
MaxDepositAmount float64 `json:"maxDepositAmount,string"`
|
||||
DepositDecimals float64 `json:"depositDecimals,string"`
|
||||
MinWithdrawalAmount float64 `json:"minWithdrawalAmount,string"`
|
||||
MaxWithdrawalAmount float64 `json:"maxWithdrawalAmount,string"`
|
||||
WithdrawalDecimals float64 `json:"withdrawalDecimals,string"`
|
||||
WithdrawalFee float64 `json:"withdrawalFee,string"`
|
||||
DepositFee float64 `json:"depositFee,string"`
|
||||
}
|
||||
|
||||
// TransactionData stores data from past transactions
|
||||
type TransactionData struct {
|
||||
ID string `json:"id"`
|
||||
CreationTime time.Time `json:"creationTime"`
|
||||
Description string `json:"description"`
|
||||
AssetName string `json:"assetName"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Balance float64 `json:"balance,string"`
|
||||
FeeType string `json:"type"`
|
||||
RecordType string `json:"recordType"`
|
||||
ReferrenceID string `json:"referrenceId"`
|
||||
}
|
||||
|
||||
// CreateReportResp stores data for created report
|
||||
type CreateReportResp struct {
|
||||
ReportID string `json:"reportId"`
|
||||
}
|
||||
|
||||
// ReportData gets data for a created report
|
||||
type ReportData struct {
|
||||
ID string `json:"id"`
|
||||
ContentURL string `json:"contentUrl"`
|
||||
CreationTime time.Time `json:"creationTime"`
|
||||
ReportType string `json:"reportType"`
|
||||
Status string `json:"status"`
|
||||
Format string `json:"format"`
|
||||
}
|
||||
|
||||
// BatchPlaceData stores data for placed batch orders
|
||||
type BatchPlaceData struct {
|
||||
OrderID string `json:"orderId"`
|
||||
MarketID string `json:"marketId"`
|
||||
Side string `json:"side"`
|
||||
Type string `json:"type"`
|
||||
CreationTime time.Time `json:"creationTime"`
|
||||
Price float64 `json:"price,string"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
OpenAmount float64 `json:"openAmount,string"`
|
||||
Status string `json:"status"`
|
||||
ClientOrderID string `json:"clientOrderId"`
|
||||
}
|
||||
|
||||
// UnprocessedBatchResp stores data for unprocessed response
|
||||
type UnprocessedBatchResp struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
RequestID string `json:"requestId"`
|
||||
}
|
||||
|
||||
// BatchPlaceCancelResponse stores place and cancel batch data
|
||||
type BatchPlaceCancelResponse struct {
|
||||
PlacedOrders []BatchPlaceData `json:"placeOrders"`
|
||||
CancelledOrders []CancelOrderResp `json:"cancelOrders"`
|
||||
UnprocessedOrders []UnprocessedBatchResp `json:"unprocessedRequests"`
|
||||
}
|
||||
|
||||
// BatchTradeResponse stores the trades from batchtrades
|
||||
type BatchTradeResponse struct {
|
||||
Orders []BatchPlaceData `json:"orders"`
|
||||
UnprocessedRequests []UnprocessedBatchResp `json:"unprocessedRequests"`
|
||||
}
|
||||
|
||||
// BatchCancelResponse stores the cancellation details from batch cancels
|
||||
type BatchCancelResponse struct {
|
||||
CancelOrders []CancelOrderResp `json:"cancelOrders"`
|
||||
UnprocessedRequests []UnprocessedBatchResp `json:"unprocessedRequests"`
|
||||
}
|
||||
|
||||
// WithdrawRequestCrypto is a generalized withdraw request type
|
||||
@@ -134,18 +287,48 @@ type WithdrawRequestAUD struct {
|
||||
BSBNumber string `json:"bsbNumber"`
|
||||
}
|
||||
|
||||
// WithdrawalFees the large list of predefined withdrawal fees
|
||||
// Prone to change
|
||||
var WithdrawalFees = map[currency.Code]float64{
|
||||
currency.AUD: 0,
|
||||
currency.BTC: 0.001,
|
||||
currency.ETH: 0.001,
|
||||
currency.ETC: 0.001,
|
||||
currency.LTC: 0.0001,
|
||||
currency.XRP: 0.15,
|
||||
currency.BCH: 0.0001,
|
||||
currency.OMG: 0.15,
|
||||
currency.POWR: 5,
|
||||
// CancelBatch stores data for batch cancel request
|
||||
type CancelBatch struct {
|
||||
OrderID string `json:"orderId,omitempty"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
}
|
||||
|
||||
// PlaceBatch stores data for place batch request
|
||||
type PlaceBatch struct {
|
||||
MarketID string `json:"marketId"`
|
||||
Price float64 `json:"price"`
|
||||
Amount float64 `json:"amount"`
|
||||
OrderType string `json:"type"`
|
||||
Side string `json:"side"`
|
||||
TriggerPrice float64 `json:"triggerPrice,omitempty"`
|
||||
TriggerAmount float64 `json:"triggerAmount,omitempty"`
|
||||
TimeInForce string `json:"timeInForce,omitempty"`
|
||||
PostOnly bool `json:"postOnly,omitempty"`
|
||||
SelfTrade string `json:"selfTrade,omitempty"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
}
|
||||
|
||||
// PlaceOrderMethod stores data for place request
|
||||
type PlaceOrderMethod struct {
|
||||
PlaceOrder PlaceBatch `json:"placeOrder,omitempty"`
|
||||
}
|
||||
|
||||
// CancelOrderMethod stores data for Cancel request
|
||||
type CancelOrderMethod struct {
|
||||
CancelOrder CancelBatch `json:"cancelOrder,omitempty"`
|
||||
}
|
||||
|
||||
// TradingFeeData stores trading fee data
|
||||
type TradingFeeData struct {
|
||||
MakerFeeRate float64 `json:"makerFeeRate,string"`
|
||||
TakerFeeRate float64 `json:"takerFeeRate,string"`
|
||||
MarketID string `json:"marketId"`
|
||||
}
|
||||
|
||||
// TradingFeeResponse stores trading fee data
|
||||
type TradingFeeResponse struct {
|
||||
MonthlyVolume float64 `json:"volume30Day,string"`
|
||||
FeeByMarkets []TradingFeeData `json:"FeeByMarkets"`
|
||||
}
|
||||
|
||||
// WsSubscribe message sent via ws to subscribe
|
||||
@@ -155,6 +338,16 @@ type WsSubscribe struct {
|
||||
MessageType string `json:"messageType"`
|
||||
}
|
||||
|
||||
// WsAuthSubscribe message sent via login to subscribe
|
||||
type WsAuthSubscribe struct {
|
||||
MarketIDs []string `json:"marketIds,omitempty"`
|
||||
Channels []string `json:"channels"`
|
||||
Key string `json:"key"`
|
||||
Signature string `json:"signature"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
MessageType string `json:"messageType"`
|
||||
}
|
||||
|
||||
// WsMessageType message sent via ws to determine type
|
||||
type WsMessageType struct {
|
||||
MessageType string `json:"messageType"`
|
||||
@@ -193,7 +386,42 @@ type WsOrderbook struct {
|
||||
MessageType string `json:"messageType"`
|
||||
}
|
||||
|
||||
// WsError message received for orderbook errors
|
||||
// WsFundTransfer stores fund transfer data for websocket
|
||||
type WsFundTransfer struct {
|
||||
FundTransferID int64 `json:"fundtransferId"`
|
||||
TransferType string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Currency string `json:"currency"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
MessageType string `json:"messageType"`
|
||||
}
|
||||
|
||||
// WsTradeData stores trade data for websocket
|
||||
type WsTradeData struct {
|
||||
TradeID int64 `json:"tradeId"`
|
||||
Price float64 `json:"price,string"`
|
||||
Volume float64 `json:"volume,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
LiquidityType string `json:"liquidityType"`
|
||||
}
|
||||
|
||||
// WsOrderChange stores order data
|
||||
type WsOrderChange struct {
|
||||
OrderID int64 `json:"orderId"`
|
||||
MarketID string `json:"marketId"`
|
||||
Side string `json:"side"`
|
||||
OrderType string `json:"type"`
|
||||
OpenVolume float64 `json:"openVolume,string"`
|
||||
Status string `json:"status"`
|
||||
TriggerStatus string `json:"triggerStatus"`
|
||||
Trades []WsTradeData `json:"trades"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
MessageType string `json:"messageType"`
|
||||
}
|
||||
|
||||
// WsError stores websocket error data
|
||||
type WsError struct {
|
||||
MessageType string `json:"messageType"`
|
||||
Code int64 `json:"code"`
|
||||
|
||||
@@ -6,9 +6,13 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"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/orderbook"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/websocket/wshandler"
|
||||
@@ -32,10 +36,15 @@ func (b *BTCMarkets) WsConnect() error {
|
||||
if b.Verbose {
|
||||
log.Debugf(log.ExchangeSys, "%s Connected to Websocket.\n", b.Name)
|
||||
}
|
||||
|
||||
b.generateDefaultSubscriptions()
|
||||
go b.WsHandleData()
|
||||
|
||||
if b.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) {
|
||||
b.createChannels()
|
||||
if err != nil {
|
||||
b.Websocket.DataHandler <- err
|
||||
b.Websocket.SetCanUseAuthenticatedEndpoints(false)
|
||||
}
|
||||
}
|
||||
b.generateDefaultSubscriptions()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -64,11 +73,11 @@ func (b *BTCMarkets) WsHandleData() {
|
||||
continue
|
||||
}
|
||||
switch wsResponse.MessageType {
|
||||
case "heartbeat":
|
||||
case heartbeat:
|
||||
if b.Verbose {
|
||||
log.Debugf(log.ExchangeSys, "%v - Websocket heartbeat received %s", b.Name, resp.Raw)
|
||||
}
|
||||
case "orderbook":
|
||||
case wsOB:
|
||||
var ob WsOrderbook
|
||||
err := json.Unmarshal(resp.Raw, &ob)
|
||||
if err != nil {
|
||||
@@ -129,7 +138,7 @@ func (b *BTCMarkets) WsHandleData() {
|
||||
Asset: asset.Spot,
|
||||
Exchange: b.Name,
|
||||
}
|
||||
case "trade":
|
||||
case trade:
|
||||
var trade WsTrade
|
||||
err := json.Unmarshal(resp.Raw, &trade)
|
||||
if err != nil {
|
||||
@@ -145,7 +154,7 @@ func (b *BTCMarkets) WsHandleData() {
|
||||
Price: trade.Price,
|
||||
Amount: trade.Volume,
|
||||
}
|
||||
case "tick":
|
||||
case tick:
|
||||
var tick WsTick
|
||||
err := json.Unmarshal(resp.Raw, &tick)
|
||||
if err != nil {
|
||||
@@ -166,6 +175,22 @@ func (b *BTCMarkets) WsHandleData() {
|
||||
AssetType: asset.Spot,
|
||||
Pair: p,
|
||||
}
|
||||
case fundChange:
|
||||
var transferData WsFundTransfer
|
||||
err := json.Unmarshal(resp.Raw, &transferData)
|
||||
if err != nil {
|
||||
b.Websocket.DataHandler <- err
|
||||
continue
|
||||
}
|
||||
b.Websocket.DataHandler <- transferData
|
||||
case orderChange:
|
||||
var orderData WsOrderChange
|
||||
err := json.Unmarshal(resp.Raw, &orderData)
|
||||
if err != nil {
|
||||
b.Websocket.DataHandler <- err
|
||||
continue
|
||||
}
|
||||
b.Websocket.DataHandler <- orderData
|
||||
case "error":
|
||||
var wsErr WsError
|
||||
err := json.Unmarshal(resp.Raw, &wsErr)
|
||||
@@ -182,7 +207,7 @@ func (b *BTCMarkets) WsHandleData() {
|
||||
}
|
||||
|
||||
func (b *BTCMarkets) generateDefaultSubscriptions() {
|
||||
var channels = []string{"tick", "trade", "orderbook"}
|
||||
var channels = []string{tick, trade, wsOB}
|
||||
enabledCurrencies := b.GetEnabledPairs(asset.Spot)
|
||||
var subscriptions []wshandler.WebsocketChannelSubscription
|
||||
for i := range channels {
|
||||
@@ -198,10 +223,68 @@ func (b *BTCMarkets) generateDefaultSubscriptions() {
|
||||
|
||||
// Subscribe sends a websocket message to receive data from the channel
|
||||
func (b *BTCMarkets) Subscribe(channelToSubscribe wshandler.WebsocketChannelSubscription) error {
|
||||
req := WsSubscribe{
|
||||
MarketIDs: []string{channelToSubscribe.Currency.String()},
|
||||
Channels: []string{channelToSubscribe.Channel},
|
||||
MessageType: "subscribe",
|
||||
unauthChannels := []string{tick, trade, wsOB}
|
||||
authChannels := []string{fundChange, heartbeat, orderChange}
|
||||
switch {
|
||||
case common.StringDataCompare(unauthChannels, channelToSubscribe.Channel):
|
||||
req := WsSubscribe{
|
||||
MarketIDs: []string{b.FormatExchangeCurrency(channelToSubscribe.Currency, asset.Spot).String()},
|
||||
Channels: []string{channelToSubscribe.Channel},
|
||||
MessageType: subscribe,
|
||||
}
|
||||
err := b.WebsocketConn.SendMessage(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case common.StringDataCompare(authChannels, channelToSubscribe.Channel):
|
||||
message, ok := channelToSubscribe.Params["AuthSub"].(WsAuthSubscribe)
|
||||
if !ok {
|
||||
return errors.New("invalid params data")
|
||||
}
|
||||
tempAuthData := b.generateAuthSubscriptions()
|
||||
message.Channels = append(message.Channels, channelToSubscribe.Channel, heartbeat)
|
||||
message.Key = tempAuthData.Key
|
||||
message.Signature = tempAuthData.Signature
|
||||
message.Timestamp = tempAuthData.Timestamp
|
||||
err := b.WebsocketConn.SendMessage(message)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return b.WebsocketConn.SendMessage(req)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Login logs in allowing private ws events
|
||||
func (b *BTCMarkets) generateAuthSubscriptions() WsAuthSubscribe {
|
||||
var authSubInfo WsAuthSubscribe
|
||||
signTime := strconv.FormatInt(time.Now().UTC().UnixNano()/1000000, 10)
|
||||
strToSign := "/users/self/subscribe" + "\n" + signTime
|
||||
tempSign := crypto.GetHMAC(crypto.HashSHA512,
|
||||
[]byte(strToSign),
|
||||
[]byte(b.API.Credentials.Secret))
|
||||
sign := crypto.Base64Encode(tempSign)
|
||||
authSubInfo.Key = b.API.Credentials.Key
|
||||
authSubInfo.Signature = sign
|
||||
authSubInfo.Timestamp = signTime
|
||||
return authSubInfo
|
||||
}
|
||||
|
||||
// createChannels creates channels that need to be
|
||||
func (b *BTCMarkets) createChannels() {
|
||||
tempChannels := []string{orderChange, fundChange}
|
||||
var channels []wshandler.WebsocketChannelSubscription
|
||||
pairArray := b.GetEnabledPairs(asset.Spot)
|
||||
for y := range tempChannels {
|
||||
for x := range pairArray {
|
||||
var authSub WsAuthSubscribe
|
||||
var channel wshandler.WebsocketChannelSubscription
|
||||
channel.Params = make(map[string]interface{})
|
||||
channel.Channel = tempChannels[y]
|
||||
authSub.MarketIDs = append(authSub.MarketIDs, b.FormatExchangeCurrency(pairArray[x], asset.Spot).String())
|
||||
authSub.MessageType = subscribe
|
||||
channel.Params["AuthSub"] = authSub
|
||||
channels = append(channels, channel)
|
||||
}
|
||||
}
|
||||
b.Websocket.SubscribeToChannels(channels)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package btcmarkets
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -62,6 +61,7 @@ func (b *BTCMarkets) SetDefaults() {
|
||||
},
|
||||
UseGlobalFormat: true,
|
||||
RequestFormat: ¤cy.PairFormat{
|
||||
Delimiter: "-",
|
||||
Uppercase: true,
|
||||
},
|
||||
ConfigFormat: ¤cy.PairFormat{
|
||||
@@ -172,19 +172,31 @@ func (b *BTCMarkets) Start(wg *sync.WaitGroup) {
|
||||
// Run implements the BTC Markets wrapper
|
||||
func (b *BTCMarkets) Run() {
|
||||
if b.Verbose {
|
||||
log.Debugf(log.ExchangeSys,
|
||||
"%s Websocket: %s (url: %s).\n",
|
||||
b.Name,
|
||||
common.IsEnabled(b.Websocket.IsEnabled()),
|
||||
btcMarketsWSURL)
|
||||
b.PrintEnabledPairs()
|
||||
}
|
||||
|
||||
forceUpdate := false
|
||||
if !common.StringDataContains(b.GetEnabledPairs(asset.Spot).Strings(), "-") ||
|
||||
!common.StringDataContains(b.GetAvailablePairs(asset.Spot).Strings(), "-") {
|
||||
enabledPairs := []string{"BTC-AUD"}
|
||||
log.Warnln(log.ExchangeSys, "Available pairs for BTC Markets reset due to config upgrade, please enable the pairs you would like again.")
|
||||
forceUpdate = true
|
||||
|
||||
err := b.UpdatePairs(currency.NewPairsFromStrings(enabledPairs), asset.Spot, true, true)
|
||||
}
|
||||
if forceUpdate {
|
||||
enabledPairs := currency.Pairs{currency.Pair{
|
||||
Base: currency.BTC.Lower(),
|
||||
Quote: currency.AUD.Lower(),
|
||||
Delimiter: "-",
|
||||
},
|
||||
}
|
||||
err := b.UpdatePairs(enabledPairs, asset.Spot, true, true)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s failed to update currencies. Err: %s", b.Name, err)
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"%s Failed to update enabled currencies.\n",
|
||||
b.Name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,12 +206,18 @@ func (b *BTCMarkets) Run() {
|
||||
|
||||
err := b.UpdateTradablePairs(forceUpdate)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", b.Name, err)
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"%s failed to update tradable pairs. Err: %s",
|
||||
b.Name,
|
||||
err)
|
||||
}
|
||||
}
|
||||
|
||||
// FetchTradablePairs returns a list of the exchanges tradable pairs
|
||||
func (b *BTCMarkets) FetchTradablePairs(asset asset.Item) ([]string, error) {
|
||||
func (b *BTCMarkets) FetchTradablePairs(a asset.Item) ([]string, error) {
|
||||
if a != asset.Spot {
|
||||
return nil, fmt.Errorf("asset type of %s is not supported by %s", a, b.Name)
|
||||
}
|
||||
markets, err := b.GetMarkets()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -207,9 +225,8 @@ func (b *BTCMarkets) FetchTradablePairs(asset asset.Item) ([]string, error) {
|
||||
|
||||
var pairs []string
|
||||
for x := range markets {
|
||||
pairs = append(pairs, fmt.Sprintf("%v%v%v", markets[x].Instrument, b.GetPairFormat(asset, false).Delimiter, markets[x].Currency))
|
||||
pairs = append(pairs, markets[x].MarketID)
|
||||
}
|
||||
|
||||
return pairs, nil
|
||||
}
|
||||
|
||||
@@ -226,28 +243,26 @@ func (b *BTCMarkets) UpdateTradablePairs(forceUpdate bool) error {
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (b *BTCMarkets) UpdateTicker(p currency.Pair, assetType asset.Item) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
tick, err := b.GetTicker(p.Base.String(), p.Quote.String())
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
var resp ticker.Price
|
||||
allPairs := b.GetEnabledPairs(assetType)
|
||||
for x := range allPairs {
|
||||
tick, err := b.GetTicker(b.FormatExchangeCurrency(allPairs[x], assetType).String())
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp.Pair = allPairs[x]
|
||||
resp.Last = tick.LastPrice
|
||||
resp.High = tick.High24h
|
||||
resp.Low = tick.Low24h
|
||||
resp.Bid = tick.BestBID
|
||||
resp.Ask = tick.BestAsk
|
||||
resp.Volume = tick.Volume
|
||||
resp.LastUpdated = time.Now()
|
||||
err = ticker.ProcessTicker(b.Name, &resp, assetType)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
|
||||
tickerPrice = ticker.Price{
|
||||
Last: tick.LastPrice,
|
||||
High: tick.High24h,
|
||||
Low: tick.Low24h,
|
||||
Bid: tick.BestBid,
|
||||
Ask: tick.BestAsk,
|
||||
Volume: tick.Volume24h,
|
||||
Pair: p,
|
||||
LastUpdated: time.Unix(tick.Timestamp, 0),
|
||||
}
|
||||
|
||||
err = ticker.ProcessTicker(b.Name, &tickerPrice, assetType)
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
|
||||
return ticker.GetTicker(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
@@ -272,64 +287,50 @@ func (b *BTCMarkets) FetchOrderbook(p currency.Pair, assetType asset.Item) (orde
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (b *BTCMarkets) UpdateOrderbook(p currency.Pair, assetType asset.Item) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
orderbookNew, err := b.GetOrderbook(p.Base.String(),
|
||||
p.Quote.String())
|
||||
tempResp, err := b.GetOrderbook(b.FormatExchangeCurrency(p, assetType).String(), 2)
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
for x := range orderbookNew.Bids {
|
||||
for x := range tempResp.Bids {
|
||||
orderBook.Bids = append(orderBook.Bids, orderbook.Item{
|
||||
Amount: orderbookNew.Bids[x][1],
|
||||
Price: orderbookNew.Bids[x][0],
|
||||
})
|
||||
Amount: tempResp.Bids[x].Volume,
|
||||
Price: tempResp.Bids[x].Price})
|
||||
}
|
||||
|
||||
for x := range orderbookNew.Asks {
|
||||
for y := range tempResp.Asks {
|
||||
orderBook.Asks = append(orderBook.Asks, orderbook.Item{
|
||||
Amount: orderbookNew.Asks[x][1],
|
||||
Price: orderbookNew.Asks[x][0],
|
||||
})
|
||||
Amount: tempResp.Asks[y].Volume,
|
||||
Price: tempResp.Asks[y].Price})
|
||||
}
|
||||
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = b.Name
|
||||
orderBook.AssetType = assetType
|
||||
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetAccountInfo retrieves balances for all enabled currencies for the
|
||||
// BTCMarkets exchange
|
||||
// GetAccountInfo retrieves balances for all enabled currencies
|
||||
func (b *BTCMarkets) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
var response exchange.AccountInfo
|
||||
response.Exchange = b.Name
|
||||
|
||||
accountBalance, err := b.GetAccountBalance()
|
||||
var resp exchange.AccountInfo
|
||||
data, err := b.GetAccountBalance()
|
||||
if err != nil {
|
||||
return response, err
|
||||
return resp, err
|
||||
}
|
||||
|
||||
var currencies []exchange.AccountCurrencyInfo
|
||||
for i := 0; i < len(accountBalance); i++ {
|
||||
var exchangeCurrency exchange.AccountCurrencyInfo
|
||||
exchangeCurrency.CurrencyName = currency.NewCode(accountBalance[i].Currency)
|
||||
exchangeCurrency.TotalValue = accountBalance[i].Balance
|
||||
exchangeCurrency.Hold = accountBalance[i].PendingFunds
|
||||
|
||||
currencies = append(currencies, exchangeCurrency)
|
||||
var account exchange.Account
|
||||
for key := range data {
|
||||
c := currency.NewCode(data[key].AssetName)
|
||||
hold := data[key].Locked
|
||||
total := data[key].Balance
|
||||
account.Currencies = append(account.Currencies,
|
||||
exchange.AccountCurrencyInfo{CurrencyName: c,
|
||||
TotalValue: total,
|
||||
Hold: hold})
|
||||
}
|
||||
|
||||
response.Accounts = append(response.Accounts, exchange.Account{
|
||||
Currencies: currencies,
|
||||
})
|
||||
|
||||
return response, nil
|
||||
resp.Accounts = append(resp.Accounts, account)
|
||||
resp.Exchange = b.Name
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetFundingHistory returns funding history, deposits and
|
||||
@@ -345,35 +346,35 @@ func (b *BTCMarkets) GetExchangeHistory(p currency.Pair, assetType asset.Item) (
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
func (b *BTCMarkets) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) {
|
||||
var submitOrderResponse order.SubmitResponse
|
||||
var resp order.SubmitResponse
|
||||
if err := s.Validate(); err != nil {
|
||||
return submitOrderResponse, err
|
||||
return resp, err
|
||||
}
|
||||
|
||||
if strings.EqualFold(s.OrderSide.String(), order.Sell.String()) {
|
||||
if s.OrderSide == order.Sell {
|
||||
s.OrderSide = order.Ask
|
||||
}
|
||||
if strings.EqualFold(s.OrderSide.String(), order.Buy.String()) {
|
||||
if s.OrderSide == order.Buy {
|
||||
s.OrderSide = order.Bid
|
||||
}
|
||||
|
||||
response, err := b.NewOrder(s.Pair.Base.Upper().String(),
|
||||
s.Pair.Quote.Upper().String(),
|
||||
tempResp, err := b.NewOrder(b.FormatExchangeCurrency(s.Pair, asset.Spot).String(),
|
||||
s.Price,
|
||||
s.Amount,
|
||||
s.OrderSide.String(),
|
||||
s.OrderType.String(),
|
||||
s.TriggerPrice,
|
||||
s.TargetAmount,
|
||||
"",
|
||||
false,
|
||||
"",
|
||||
s.ClientID)
|
||||
|
||||
if response > 0 {
|
||||
submitOrderResponse.OrderID = strconv.FormatInt(response, 10)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
submitOrderResponse.IsOrderPlaced = true
|
||||
}
|
||||
|
||||
return submitOrderResponse, err
|
||||
resp.IsOrderPlaced = true
|
||||
resp.OrderID = tempResp.OrderID
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// ModifyOrder will allow of changing orderbook placement and limit to
|
||||
@@ -383,116 +384,130 @@ func (b *BTCMarkets) ModifyOrder(action *order.Modify) (string, error) {
|
||||
}
|
||||
|
||||
// CancelOrder cancels an order by its corresponding ID number
|
||||
func (b *BTCMarkets) CancelOrder(order *order.Cancel) error {
|
||||
orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = b.CancelExistingOrder([]int64{orderIDInt})
|
||||
func (b *BTCMarkets) CancelOrder(o *order.Cancel) error {
|
||||
_, err := b.RemoveOrder(o.OrderID)
|
||||
return err
|
||||
}
|
||||
|
||||
// CancelAllOrders cancels all orders associated with a currency pair
|
||||
func (b *BTCMarkets) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) {
|
||||
cancelAllOrdersResponse := order.CancelAllResponse{
|
||||
Status: make(map[string]string),
|
||||
}
|
||||
openOrders, err := b.GetOpenOrders()
|
||||
var resp order.CancelAllResponse
|
||||
tempMap := make(map[string]string)
|
||||
var orderIDs []string
|
||||
orders, err := b.GetOrders("", -1, -1, -1, "open")
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
return resp, err
|
||||
}
|
||||
|
||||
var orderList []int64
|
||||
for i := range openOrders {
|
||||
orderList = append(orderList, openOrders[i].ID)
|
||||
for x := range orders {
|
||||
orderIDs = append(orderIDs, orders[x].OrderID)
|
||||
}
|
||||
|
||||
if len(orderList) > 0 {
|
||||
orders, err := b.CancelExistingOrder(orderList)
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
}
|
||||
|
||||
for i := range orders {
|
||||
if !orders[i].Success {
|
||||
cancelAllOrdersResponse.Status[strconv.FormatInt(orders[i].ID, 10)] = orders[i].ErrorMessage
|
||||
}
|
||||
}
|
||||
tempResp, err := b.CancelBatchOrders(orderIDs)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
return cancelAllOrdersResponse, nil
|
||||
for y := range tempResp.CancelOrders {
|
||||
tempMap[tempResp.CancelOrders[y].OrderID] = "Success"
|
||||
}
|
||||
for z := range tempResp.UnprocessedRequests {
|
||||
tempMap[tempResp.UnprocessedRequests[z].RequestID] = "Cancellation Failed"
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetOrderInfo returns information on a current open order
|
||||
func (b *BTCMarkets) GetOrderInfo(orderID string) (order.Detail, error) {
|
||||
var OrderDetail order.Detail
|
||||
|
||||
o, err := strconv.ParseInt(orderID, 10, 64)
|
||||
var resp order.Detail
|
||||
o, err := b.FetchOrder(orderID)
|
||||
if err != nil {
|
||||
return OrderDetail, err
|
||||
return resp, err
|
||||
}
|
||||
|
||||
orders, err := b.GetOrderDetail([]int64{o})
|
||||
if err != nil {
|
||||
return OrderDetail, err
|
||||
resp.Exchange = b.Name
|
||||
resp.ID = orderID
|
||||
resp.CurrencyPair = currency.NewPairFromString(o.MarketID)
|
||||
resp.Price = o.Price
|
||||
resp.OrderDate = o.CreationTime
|
||||
resp.ExecutedAmount = o.Amount - o.OpenAmount
|
||||
resp.OrderSide = order.Bid
|
||||
if o.Side == ask {
|
||||
resp.OrderSide = order.Ask
|
||||
}
|
||||
|
||||
if len(orders) > 1 {
|
||||
return OrderDetail, errors.New("too many orders returned")
|
||||
switch o.Type {
|
||||
case limit:
|
||||
resp.OrderType = order.Limit
|
||||
case market:
|
||||
resp.OrderType = order.Market
|
||||
case stopLimit:
|
||||
resp.OrderType = order.Stop
|
||||
case stop:
|
||||
resp.OrderType = order.Stop
|
||||
case takeProfit:
|
||||
resp.OrderType = order.ImmediateOrCancel
|
||||
default:
|
||||
resp.OrderType = order.Unknown
|
||||
}
|
||||
|
||||
if len(orders) == 0 {
|
||||
return OrderDetail, errors.New("no orders found")
|
||||
resp.RemainingAmount = o.OpenAmount
|
||||
switch o.Status {
|
||||
case orderAccepted:
|
||||
resp.Status = order.Active
|
||||
case orderPlaced:
|
||||
resp.Status = order.Active
|
||||
case orderPartiallyMatched:
|
||||
resp.Status = order.PartiallyFilled
|
||||
case orderFullyMatched:
|
||||
resp.Status = order.Filled
|
||||
case orderCancelled:
|
||||
resp.Status = order.Cancelled
|
||||
case orderPartiallyCancelled:
|
||||
resp.Status = order.PartiallyCancelled
|
||||
case orderFailed:
|
||||
resp.Status = order.Rejected
|
||||
default:
|
||||
resp.Status = order.UnknownStatus
|
||||
}
|
||||
|
||||
for i := range orders {
|
||||
var side order.Side
|
||||
if strings.EqualFold(orders[i].OrderSide, order.Ask.String()) {
|
||||
side = order.Sell
|
||||
} else if strings.EqualFold(orders[i].OrderSide, order.Bid.String()) {
|
||||
side = order.Buy
|
||||
}
|
||||
orderDate := time.Unix(int64(orders[i].CreationTime), 0)
|
||||
orderType := order.Type(strings.ToUpper(orders[i].OrderType))
|
||||
|
||||
OrderDetail.Amount = orders[i].Volume
|
||||
OrderDetail.OrderDate = orderDate
|
||||
OrderDetail.Exchange = b.Name
|
||||
OrderDetail.ID = strconv.FormatInt(orders[i].ID, 10)
|
||||
OrderDetail.RemainingAmount = orders[i].OpenVolume
|
||||
OrderDetail.OrderSide = side
|
||||
OrderDetail.OrderType = orderType
|
||||
OrderDetail.Price = orders[i].Price
|
||||
OrderDetail.Status = order.Status(orders[i].Status)
|
||||
OrderDetail.CurrencyPair = currency.NewPairWithDelimiter(orders[i].Instrument,
|
||||
orders[i].Currency,
|
||||
b.GetPairFormat(asset.Spot, false).Delimiter)
|
||||
}
|
||||
|
||||
return OrderDetail, nil
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *BTCMarkets) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) {
|
||||
return "", common.ErrFunctionNotSupported
|
||||
temp, err := b.FetchDepositAddress(strings.ToUpper(cryptocurrency.String()), -1, -1, -1)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return temp.Address, nil
|
||||
}
|
||||
|
||||
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is submitted
|
||||
func (b *BTCMarkets) WithdrawCryptocurrencyFunds(withdrawRequest *exchange.CryptoWithdrawRequest) (string, error) {
|
||||
return b.WithdrawCrypto(withdrawRequest.Amount, withdrawRequest.Currency.String(), withdrawRequest.Address)
|
||||
a, err := b.RequestWithdraw(withdrawRequest.Currency.String(),
|
||||
withdrawRequest.Amount,
|
||||
withdrawRequest.Address,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return a.Status, nil
|
||||
}
|
||||
|
||||
// WithdrawFiatFunds returns a withdrawal ID when a
|
||||
// withdrawal is submitted
|
||||
func (b *BTCMarkets) WithdrawFiatFunds(withdrawRequest *exchange.FiatWithdrawRequest) (string, error) {
|
||||
if withdrawRequest.Currency != currency.AUD {
|
||||
return "", errors.New("only AUD is supported for withdrawals")
|
||||
return "", errors.New("only aud is supported for withdrawals")
|
||||
}
|
||||
return b.WithdrawAUD(withdrawRequest.BankAccountName,
|
||||
strconv.FormatFloat(withdrawRequest.BankAccountNumber, 'f', -1, 64),
|
||||
withdrawRequest.BankName,
|
||||
strconv.FormatFloat(withdrawRequest.BankCode, 'f', -1, 64),
|
||||
withdrawRequest.Amount)
|
||||
a, err := b.RequestWithdraw(withdrawRequest.GenericWithdrawRequestInfo.Currency.String(),
|
||||
withdrawRequest.GenericWithdrawRequestInfo.Amount,
|
||||
"",
|
||||
withdrawRequest.BankAccountName,
|
||||
withdrawRequest.BankAccountNumber,
|
||||
withdrawRequest.BSB,
|
||||
withdrawRequest.BankName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return a.Status, nil
|
||||
}
|
||||
|
||||
// WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a
|
||||
@@ -517,124 +532,116 @@ func (b *BTCMarkets) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, err
|
||||
|
||||
// GetActiveOrders retrieves any orders that are active/open
|
||||
func (b *BTCMarkets) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) {
|
||||
resp, err := b.GetOpenOrders()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var resp []order.Detail
|
||||
var tempResp order.Detail
|
||||
var tempData []OrderData
|
||||
if len(req.Currencies) == 0 {
|
||||
allPairs := b.GetEnabledPairs(asset.Spot)
|
||||
for a := range allPairs {
|
||||
req.Currencies = append(req.Currencies,
|
||||
allPairs[a])
|
||||
}
|
||||
}
|
||||
|
||||
var orders []order.Detail
|
||||
for i := range resp {
|
||||
var side order.Side
|
||||
if strings.EqualFold(resp[i].OrderSide, order.Ask.String()) {
|
||||
side = order.Sell
|
||||
} else if strings.EqualFold(resp[i].OrderSide, order.Bid.String()) {
|
||||
side = order.Buy
|
||||
var err error
|
||||
for x := range req.Currencies {
|
||||
tempData, err = b.GetOrders(b.FormatExchangeCurrency(req.Currencies[x], asset.Spot).String(), -1, -1, -1, "")
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
orderDate := time.Unix(int64(resp[i].CreationTime), 0)
|
||||
orderType := order.Type(strings.ToUpper(resp[i].OrderType))
|
||||
|
||||
openOrder := order.Detail{
|
||||
ID: strconv.FormatInt(resp[i].ID, 10),
|
||||
Amount: resp[i].Volume,
|
||||
Exchange: b.Name,
|
||||
RemainingAmount: resp[i].OpenVolume,
|
||||
OrderDate: orderDate,
|
||||
OrderSide: side,
|
||||
OrderType: orderType,
|
||||
Price: resp[i].Price,
|
||||
Status: order.Status(resp[i].Status),
|
||||
CurrencyPair: currency.NewPairWithDelimiter(resp[i].Instrument,
|
||||
resp[i].Currency,
|
||||
b.GetPairFormat(asset.Spot, false).Delimiter),
|
||||
for y := range tempData {
|
||||
tempResp.Exchange = b.Name
|
||||
tempResp.CurrencyPair = req.Currencies[x]
|
||||
tempResp.OrderSide = order.Bid
|
||||
if tempData[y].Side == ask {
|
||||
tempResp.OrderSide = order.Ask
|
||||
}
|
||||
tempResp.OrderDate = tempData[y].CreationTime
|
||||
switch tempData[y].Status {
|
||||
case orderAccepted:
|
||||
tempResp.Status = order.Active
|
||||
case orderPlaced:
|
||||
tempResp.Status = order.Active
|
||||
case orderPartiallyMatched:
|
||||
tempResp.Status = order.PartiallyFilled
|
||||
case orderFullyMatched:
|
||||
tempResp.Status = order.Filled
|
||||
case orderCancelled:
|
||||
tempResp.Status = order.Cancelled
|
||||
case orderPartiallyCancelled:
|
||||
tempResp.Status = order.PartiallyCancelled
|
||||
case orderFailed:
|
||||
tempResp.Status = order.Rejected
|
||||
}
|
||||
tempResp.Price = tempData[y].Price
|
||||
tempResp.Amount = tempData[y].Amount
|
||||
tempResp.ExecutedAmount = tempData[y].Amount - tempData[y].OpenAmount
|
||||
tempResp.RemainingAmount = tempData[y].OpenAmount
|
||||
resp = append(resp, tempResp)
|
||||
}
|
||||
|
||||
for j := range resp[i].Trades {
|
||||
tradeDate := time.Unix(int64(resp[i].Trades[j].CreationTime), 0)
|
||||
openOrder.Trades = append(openOrder.Trades, order.TradeHistory{
|
||||
Amount: resp[i].Trades[j].Volume,
|
||||
Exchange: b.Name,
|
||||
Price: resp[i].Trades[j].Price,
|
||||
TID: resp[i].Trades[j].ID,
|
||||
Timestamp: tradeDate,
|
||||
Fee: resp[i].Trades[j].Fee,
|
||||
Description: resp[i].Trades[j].Description,
|
||||
})
|
||||
}
|
||||
|
||||
orders = append(orders, openOrder)
|
||||
}
|
||||
|
||||
order.FilterOrdersByType(&orders, req.OrderType)
|
||||
order.FilterOrdersByTickRange(&orders, req.StartTicks, req.EndTicks)
|
||||
order.FilterOrdersBySide(&orders, req.OrderSide)
|
||||
return orders, nil
|
||||
order.FilterOrdersByType(&resp, req.OrderType)
|
||||
order.FilterOrdersByTickRange(&resp, req.StartTicks, req.EndTicks)
|
||||
order.FilterOrdersBySide(&resp, req.OrderSide)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetOrderHistory retrieves account order information
|
||||
// Can Limit response to specific order status
|
||||
func (b *BTCMarkets) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) {
|
||||
var resp []order.Detail
|
||||
var tempResp order.Detail
|
||||
var tempArray []string
|
||||
if len(req.Currencies) == 0 {
|
||||
return nil, errors.New("requires at least one currency pair to retrieve history")
|
||||
}
|
||||
|
||||
var respOrders []Order
|
||||
for i := range req.Currencies {
|
||||
resp, err := b.GetOrders(req.Currencies[i].Base.String(),
|
||||
req.Currencies[i].Quote.String(),
|
||||
200,
|
||||
0,
|
||||
true)
|
||||
orders, err := b.GetOrders("", -1, -1, -1, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return resp, err
|
||||
}
|
||||
for x := range orders {
|
||||
tempArray = append(tempArray, orders[x].OrderID)
|
||||
}
|
||||
respOrders = append(respOrders, resp...)
|
||||
}
|
||||
|
||||
var orders []order.Detail
|
||||
for i := range respOrders {
|
||||
var side order.Side
|
||||
if strings.EqualFold(respOrders[i].OrderSide, order.Ask.String()) {
|
||||
side = order.Sell
|
||||
} else if strings.EqualFold(respOrders[i].OrderSide, order.Bid.String()) {
|
||||
side = order.Buy
|
||||
for y := range req.Currencies {
|
||||
orders, err := b.GetOrders(b.FormatExchangeCurrency(req.Currencies[y], asset.Spot).String(), -1, -1, -1, "")
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
orderDate := time.Unix(int64(respOrders[i].CreationTime), 0)
|
||||
orderType := order.Type(strings.ToUpper(respOrders[i].OrderType))
|
||||
|
||||
openOrder := order.Detail{
|
||||
ID: strconv.FormatInt(respOrders[i].ID, 10),
|
||||
Amount: respOrders[i].Volume,
|
||||
Exchange: b.Name,
|
||||
RemainingAmount: respOrders[i].OpenVolume,
|
||||
OrderDate: orderDate,
|
||||
OrderSide: side,
|
||||
OrderType: orderType,
|
||||
Price: respOrders[i].Price,
|
||||
Status: order.Status(respOrders[i].Status),
|
||||
CurrencyPair: currency.NewPairWithDelimiter(respOrders[i].Instrument,
|
||||
respOrders[i].Currency,
|
||||
b.GetPairFormat(asset.Spot, false).Delimiter),
|
||||
for z := range orders {
|
||||
tempArray = append(tempArray, orders[z].OrderID)
|
||||
}
|
||||
|
||||
for j := range respOrders[i].Trades {
|
||||
tradeDate := time.Unix(int64(respOrders[i].Trades[j].CreationTime), 0)
|
||||
openOrder.Trades = append(openOrder.Trades, order.TradeHistory{
|
||||
Amount: respOrders[i].Trades[j].Volume,
|
||||
Exchange: b.Name,
|
||||
Price: respOrders[i].Trades[j].Price,
|
||||
TID: respOrders[i].Trades[j].ID,
|
||||
Timestamp: tradeDate,
|
||||
Fee: respOrders[i].Trades[j].Fee,
|
||||
Description: respOrders[i].Trades[j].Description,
|
||||
})
|
||||
}
|
||||
orders = append(orders, openOrder)
|
||||
}
|
||||
|
||||
order.FilterOrdersByType(&orders, req.OrderType)
|
||||
order.FilterOrdersByTickRange(&orders, req.StartTicks, req.EndTicks)
|
||||
order.FilterOrdersBySide(&orders, req.OrderSide)
|
||||
return orders, nil
|
||||
tempData, err := b.GetBatchTrades(tempArray)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
for c := range tempData.Orders {
|
||||
switch tempData.Orders[c].Status {
|
||||
case orderFailed:
|
||||
tempResp.Status = order.Rejected
|
||||
case orderPartiallyCancelled:
|
||||
tempResp.Status = order.PartiallyCancelled
|
||||
case orderCancelled:
|
||||
tempResp.Status = order.Cancelled
|
||||
case orderFullyMatched:
|
||||
tempResp.Status = order.Filled
|
||||
case orderPartiallyMatched:
|
||||
continue
|
||||
case orderPlaced:
|
||||
continue
|
||||
case orderAccepted:
|
||||
continue
|
||||
}
|
||||
tempResp.Exchange = b.Name
|
||||
tempResp.CurrencyPair = currency.NewPairFromString(tempData.Orders[c].MarketID)
|
||||
tempResp.OrderSide = order.Bid
|
||||
if tempData.Orders[c].Side == ask {
|
||||
tempResp.OrderSide = order.Ask
|
||||
}
|
||||
tempResp.OrderDate = tempData.Orders[c].CreationTime
|
||||
tempResp.Price = tempData.Orders[c].Price
|
||||
tempResp.ExecutedAmount = tempData.Orders[c].Amount
|
||||
resp = append(resp, tempResp)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// SubscribeToWebsocketChannels appends to ChannelsToSubscribe
|
||||
|
||||
@@ -193,12 +193,13 @@ type FiatWithdrawRequest struct {
|
||||
GenericWithdrawRequestInfo
|
||||
// FIAT related information
|
||||
BankAccountName string
|
||||
BankAccountNumber float64
|
||||
BankAccountNumber string
|
||||
BankName string
|
||||
BankAddress string
|
||||
BankCity string
|
||||
BankCountry string
|
||||
BankPostalCode string
|
||||
BSB string
|
||||
SwiftCode string
|
||||
IBAN string
|
||||
BankCode float64
|
||||
|
||||
@@ -37,12 +37,14 @@ var (
|
||||
|
||||
// Submit contains the order submission data
|
||||
type Submit struct {
|
||||
Pair currency.Pair
|
||||
OrderType Type
|
||||
OrderSide Side
|
||||
Price float64
|
||||
Amount float64
|
||||
ClientID string
|
||||
Pair currency.Pair
|
||||
OrderType Type
|
||||
OrderSide Side
|
||||
TriggerPrice float64
|
||||
TargetAmount float64
|
||||
Price float64
|
||||
Amount float64
|
||||
ClientID string
|
||||
}
|
||||
|
||||
// SubmitResponse is what is returned after submitting an order to an exchange
|
||||
@@ -161,17 +163,18 @@ type Status string
|
||||
|
||||
// All order status types
|
||||
const (
|
||||
AnyStatus Status = "ANY"
|
||||
New Status = "NEW"
|
||||
Active Status = "ACTIVE"
|
||||
PartiallyFilled Status = "PARTIALLY_FILLED"
|
||||
Filled Status = "FILLED"
|
||||
Cancelled Status = "CANCELED"
|
||||
PendingCancel Status = "PENDING_CANCEL"
|
||||
Rejected Status = "REJECTED"
|
||||
Expired Status = "EXPIRED"
|
||||
Hidden Status = "HIDDEN"
|
||||
UnknownStatus Status = "UNKNOWN"
|
||||
AnyStatus Status = "ANY"
|
||||
New Status = "NEW"
|
||||
Active Status = "ACTIVE"
|
||||
PartiallyCancelled Status = "PARTIALLY_CANCELLED"
|
||||
PartiallyFilled Status = "PARTIALLY_FILLED"
|
||||
Filled Status = "FILLED"
|
||||
Cancelled Status = "CANCELED"
|
||||
PendingCancel Status = "PENDING_CANCEL"
|
||||
Rejected Status = "REJECTED"
|
||||
Expired Status = "EXPIRED"
|
||||
Hidden Status = "HIDDEN"
|
||||
UnknownStatus Status = "UNKNOWN"
|
||||
)
|
||||
|
||||
// ByPrice used for sorting orders by price
|
||||
|
||||
Reference in New Issue
Block a user