Remove WEX exchange support

This commit is contained in:
Adrian Gallagher
2019-02-08 13:52:53 +11:00
parent 5e5ca8a887
commit 26d67f5228
15 changed files with 3 additions and 1825 deletions

View File

@@ -45,7 +45,6 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader
| OKCoin International | Yes | Yes | No |
| OKEX | Yes | Yes | No |
| Poloniex | Yes | Yes | NA |
| WEX | Yes | NA | NA |
| Yobit | Yes | NA | NA |
| ZB.COM | Yes | Yes | NA |

View File

@@ -11,7 +11,7 @@ import (
const (
// Default number of enabled exchanges. Modify this whenever an exchange is
// added or removed
defaultEnabledExchanges = 29
defaultEnabledExchanges = 28
)
func TestGetCurrencyConfig(t *testing.T) {

View File

@@ -1189,48 +1189,6 @@
}
]
},
{
"name": "WEX",
"enabled": true,
"verbose": false,
"websocket": false,
"useSandbox": false,
"restPollingDelay": 10,
"httpTimeout": 15000000000,
"httpUserAgent": "",
"authenticatedApiSupport": false,
"apiKey": "Key",
"apiSecret": "Secret",
"apiUrl": "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API",
"apiUrlSecondary": "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API",
"proxyAddress": "",
"websocketUrl": "NON_DEFAULT_HTTP_LINK_TO_WEBSOCKET_EXCHANGE_API",
"availablePairs": "USD_RUR,BCH_DSH,BCHET_BCH,BCH_EUR,NMCET_NMC,EUR_RUR,DSH_EUR,BCH_BTC,USDET_USD,RURET_RUR,XMR_EUR,NMC_USD,DSH_BTC,DSH_ZEC,ZEC_BTC,LTCET_LTC,ETHET_ETH,XMR_USD,BTC_USD,NVC_BTC,ETH_ZEC,BCH_USD,BCH_ETH,ZEC_LTC,PPCET_PPC,LTC_BTC,LTC_USD,PPC_USD,DSH_LTC,DSH_ETH,ETH_LTC,BTCET_BTC,NVCET_NVC,PPC_BTC,ETH_BTC,ETH_RUR,DSHET_DSH,BTC_RUR,DSH_USD,NVC_USD,EUR_USD,ETH_EUR,ZEC_RUR,NMC_BTC,BCH_RUR,BCH_LTC,USDT_USD,XMR_ETH,XMR_RUR,LTC_EUR,ZEC_USD,ETH_USD,DSH_RUR,BTC_EUR,LTC_RUR,BCH_ZEC,EURET_EUR,BTC_USDT,XMR_BTC",
"enabledPairs": "BTC_USD,LTC_USD,LTC_BTC,ETH_USD",
"baseCurrencies": "USD,RUR,EUR",
"assetTypes": "SPOT",
"supportsAutoPairUpdates": true,
"configCurrencyPairFormat": {
"uppercase": true,
"delimiter": "_"
},
"requestCurrencyPairFormat": {
"uppercase": false,
"delimiter": "_",
"separator": "-"
},
"bankAccounts": [
{
"bankName": "",
"bankAddress": "",
"accountName": "",
"accountNumber": "",
"swiftCode": "",
"iban": "",
"supportedCurrencies": ""
}
]
},
{
"name": "Yobit",
"enabled": true,

View File

@@ -31,7 +31,6 @@ import (
"github.com/thrasher-/gocryptotrader/exchanges/okcoin"
"github.com/thrasher-/gocryptotrader/exchanges/okex"
"github.com/thrasher-/gocryptotrader/exchanges/poloniex"
"github.com/thrasher-/gocryptotrader/exchanges/wex"
"github.com/thrasher-/gocryptotrader/exchanges/yobit"
"github.com/thrasher-/gocryptotrader/exchanges/zb"
log "github.com/thrasher-/gocryptotrader/logger"
@@ -187,8 +186,6 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error {
exch = new(okex.OKEX)
case "poloniex":
exch = new(poloniex.Poloniex)
case "wex":
exch = new(wex.WEX)
case "yobit":
exch = new(yobit.Yobit)
case "zb":

View File

@@ -554,7 +554,7 @@ func TestGetExchangeFormatCurrencySeperator(t *testing.T) {
}
expected := true
actual := GetExchangeFormatCurrencySeperator("WEX")
actual := GetExchangeFormatCurrencySeperator("Yobit")
if expected != actual {
t.Errorf("Test failed - TestGetExchangeFormatCurrencySeperator expected %v != actual %v",

View File

@@ -1,133 +0,0 @@
# GoCryptoTrader package Wex
<img src="https://github.com/thrasher-/gocryptotrader/blob/master/web/src/assets/page-logo.png?raw=true" width="350px" height="350px" hspace="70">
[![Build Status](https://travis-ci.org/thrasher-/gocryptotrader.svg?branch=master)](https://travis-ci.org/thrasher-/gocryptotrader)
[![Software License](https://img.shields.io/badge/License-MIT-orange.svg?style=flat-square)](https://github.com/thrasher-/gocryptotrader/blob/master/LICENSE)
[![GoDoc](https://godoc.org/github.com/thrasher-/gocryptotrader?status.svg)](https://godoc.org/github.com/thrasher-/gocryptotrader/exchanges/wex)
[![Coverage Status](http://codecov.io/github/thrasher-/gocryptotrader/coverage.svg?branch=master)](http://codecov.io/github/thrasher-/gocryptotrader?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/thrasher-/gocryptotrader)](https://goreportcard.com/report/github.com/thrasher-/gocryptotrader)
This wex package is part of the GoCryptoTrader codebase.
## This is still in active development
You can track ideas, planned features and what's in progresss on this Trello board: [https://trello.com/b/ZAhMhpOy/gocryptotrader](https://trello.com/b/ZAhMhpOy/gocryptotrader).
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://gocryptotrader.herokuapp.com/)
## Wex Exchange
### Current Features
+ REST Support
### How to enable
+ [Enable via configuration](https://github.com/thrasher-/gocryptotrader/tree/master/config#enable-exchange-via-config-example)
+ Individual package example below:
```go
// Exchanges will be abstracted out in further updates and examples will be
// supplied then
```
### How to do REST public/private calls
+ If enabled via "configuration".json file the exchange will be added to the
IBotExchange array in the ```go var bot Bot``` and you will only be able to use
the wrapper interface functions for accessing exchange data. View routines.go
for an example of integration usage with GoCryptoTrader. Rudimentary example
below:
main.go
```go
var w exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Wex" {
y = bot.exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := w.GetTickerPrice()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := w.GetOrderbookEx()
if err != nil {
// Handle error
}
// Private calls - wrapper functions - make sure your APIKEY and APISECRET are
// set and AuthenticatedAPISupport is set to true
// Fetches current account information
accountInfo, err := w.GetAccountInfo()
if err != nil {
// Handle error
}
```
+ If enabled via individually importing package, rudimentary example below:
```go
// Public calls
// Fetches current ticker information
ticker, err := w.GetTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := w.GetDepth()
if err != nil {
// Handle error
}
// Private calls - make sure your APIKEY and APISECRET are set and
// AuthenticatedAPISupport is set to true
// Fetches current account information
accountInfo, err := w.GetAccountInfo()
if err != nil {
// Handle error
}
// Submits an order and the exchange and returns its tradeID
tradeID, err := w.Trade("BTCUSD", "MARKET", 1, 2)
if err != nil {
// Handle error
}
```
### Please click GoDocs chevron above to view current GoDoc information for this package
## Contribution
Please feel free to submit any pull requests or suggest any desired features to be added.
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).
+ 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">
If this framework helped you in any way, or you would like to support the developers working on it, please donate Bitcoin to:
***1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB***

View File

@@ -1,457 +0,0 @@
package wex
import (
"errors"
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/symbol"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/request"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
log "github.com/thrasher-/gocryptotrader/logger"
)
const (
wexAPIPublicURL = "https://wex1.in/api"
wexAPIPrivateURL = "https://wex1.in/tapi"
wexAPIPublicVersion = "3"
wexAPIPrivateVersion = "1"
wexInfo = "info"
wexTicker = "ticker"
wexDepth = "depth"
wexTrades = "trades"
wexAccountInfo = "getInfo"
wexTrade = "Trade"
wexActiveOrders = "ActiveOrders"
wexOrderInfo = "OrderInfo"
wexCancelOrder = "CancelOrder"
wexTradeHistory = "TradeHistory"
wexTransactionHistory = "TransHistory"
wexWithdrawCoin = "WithdrawCoin"
wexCoinDepositAddress = "CoinDepositAddress"
wexCreateCoupon = "CreateCoupon"
wexRedeemCoupon = "RedeemCoupon"
wexAuthRate = 0
wexUnauthRate = 0
)
// WEX is the overarching type across the wex package
type WEX struct {
exchange.Base
Ticker map[string]Ticker
}
// SetDefaults sets current default value for WEX
func (w *WEX) SetDefaults() {
w.Name = "WEX"
w.Enabled = false
w.Fee = 0.2
w.Verbose = false
w.RESTPollingDelay = 10
w.Ticker = make(map[string]Ticker)
w.APIWithdrawPermissions = exchange.AutoWithdrawCryptoWithAPIPermission |
exchange.NoFiatWithdrawals
w.RequestCurrencyPairFormat.Delimiter = "_"
w.RequestCurrencyPairFormat.Uppercase = false
w.RequestCurrencyPairFormat.Separator = "-"
w.ConfigCurrencyPairFormat.Delimiter = "_"
w.ConfigCurrencyPairFormat.Uppercase = true
w.AssetTypes = []string{ticker.Spot}
w.SupportsAutoPairUpdating = true
w.SupportsRESTTickerBatching = true
w.Requester = request.New(w.Name,
request.NewRateLimit(time.Second, wexAuthRate),
request.NewRateLimit(time.Second, wexUnauthRate),
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout))
w.APIUrlDefault = wexAPIPublicURL
w.APIUrl = w.APIUrlDefault
w.APIUrlSecondaryDefault = wexAPIPrivateURL
w.APIUrlSecondary = w.APIUrlSecondaryDefault
w.WebsocketInit()
}
// Setup sets exchange configuration parameters for WEX
func (w *WEX) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
w.SetEnabled(false)
} else {
w.Enabled = true
w.AuthenticatedAPISupport = exch.AuthenticatedAPISupport
w.SetAPIKeys(exch.APIKey, exch.APISecret, "", false)
w.SetHTTPClientTimeout(exch.HTTPTimeout)
w.SetHTTPClientUserAgent(exch.HTTPUserAgent)
w.RESTPollingDelay = exch.RESTPollingDelay
w.Verbose = exch.Verbose
w.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
w.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
w.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
err := w.SetCurrencyPairFormat()
if err != nil {
log.Fatal(err)
}
err = w.SetAssetTypes()
if err != nil {
log.Fatal(err)
}
err = w.SetAutoPairDefaults()
if err != nil {
log.Fatal(err)
}
err = w.SetAPIURL(exch)
if err != nil {
log.Fatal(err)
}
err = w.SetClientProxyAddress(exch.ProxyAddress)
if err != nil {
log.Fatal(err)
}
}
}
// GetTradablePairs returns a list of available pairs from the exchange
func (w *WEX) GetTradablePairs() ([]string, error) {
result, err := w.GetInfo()
if err != nil {
return nil, err
}
var currencies []string
for x := range result.Pairs {
currencies = append(currencies, common.StringToUpper(x))
}
return currencies, nil
}
// GetInfo returns the WEX info
func (w *WEX) GetInfo() (Info, error) {
resp := Info{}
req := fmt.Sprintf("%s/%s/%s/", w.APIUrl, wexAPIPublicVersion, wexInfo)
return resp, w.SendHTTPRequest(req, &resp)
}
// GetTicker returns a ticker for a specific currency
func (w *WEX) GetTicker(symbol string) (map[string]Ticker, error) {
type Response struct {
Data map[string]Ticker
}
response := Response{}
req := fmt.Sprintf("%s/%s/%s/%s", w.APIUrl, wexAPIPublicVersion, wexTicker, symbol)
return response.Data, w.SendHTTPRequest(req, &response.Data)
}
// GetDepth returns the depth for a specific currency
func (w *WEX) GetDepth(symbol string) (Orderbook, error) {
type Response struct {
Data map[string]Orderbook
}
response := Response{}
req := fmt.Sprintf("%s/%s/%s/%s", w.APIUrl, wexAPIPublicVersion, wexDepth, symbol)
return response.Data[symbol], w.SendHTTPRequest(req, &response.Data)
}
// GetTrades returns the trades for a specific currency
func (w *WEX) GetTrades(symbol string) ([]Trades, error) {
type Response struct {
Data map[string][]Trades
}
response := Response{}
req := fmt.Sprintf("%s/%s/%s/%s", w.APIUrl, wexAPIPublicVersion, wexTrades, symbol)
return response.Data[symbol], w.SendHTTPRequest(req, &response.Data)
}
// GetAccountInformation returns a users account info
func (w *WEX) GetAccountInformation() (AccountInfo, error) {
var result AccountInfo
err := w.SendAuthenticatedHTTPRequest(wexAccountInfo, url.Values{}, &result)
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
}
return result, nil
}
// GetOpenOrders returns the active orders for a specific currency
func (w *WEX) GetOpenOrders(pair string) (map[string]ActiveOrders, error) {
req := url.Values{}
req.Add("pair", pair)
var result map[string]ActiveOrders
return result, w.SendAuthenticatedHTTPRequest(wexActiveOrders, req, &result)
}
// GetOrderInformation returns the order info for a specific order ID
func (w *WEX) GetOrderInformation(OrderID int64) (map[string]OrderInfo, error) {
req := url.Values{}
req.Add("order_id", strconv.FormatInt(OrderID, 10))
var result map[string]OrderInfo
return result, w.SendAuthenticatedHTTPRequest(wexOrderInfo, req, &result)
}
// CancelExistingOrder cancels an order for a specific order ID
func (w *WEX) CancelExistingOrder(OrderID int64) (bool, error) {
req := url.Values{}
req.Add("order_id", strconv.FormatInt(OrderID, 10))
var result CancelOrder
err := w.SendAuthenticatedHTTPRequest(wexCancelOrder, req, &result)
if err != nil {
return false, err
}
if result.Error != "" {
return false, errors.New(result.Error)
}
return true, nil
}
// Trade places an order and returns the order ID if successful or an error
func (w *WEX) Trade(pair, orderType string, amount, price float64) (int64, error) {
req := url.Values{}
req.Add("pair", pair)
req.Add("type", orderType)
req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64))
req.Add("rate", strconv.FormatFloat(price, 'f', -1, 64))
var result Trade
err := w.SendAuthenticatedHTTPRequest(wexTrade, req, &result)
if err != nil {
return 0, err
}
if result.Error != "" {
return 0, errors.New(result.Error)
}
return int64(result.OrderID), nil
}
// GetTransactionHistory returns the transaction history
func (w *WEX) GetTransactionHistory(TIDFrom, Count, TIDEnd int64, order, since, end string) (map[string]TransHistory, error) {
req := url.Values{}
req.Add("from", strconv.FormatInt(TIDFrom, 10))
req.Add("count", strconv.FormatInt(Count, 10))
req.Add("from_id", strconv.FormatInt(TIDFrom, 10))
req.Add("end_id", strconv.FormatInt(TIDEnd, 10))
req.Add("order", order)
req.Add("since", since)
req.Add("end", end)
var result map[string]TransHistory
return result,
w.SendAuthenticatedHTTPRequest(wexTransactionHistory, req, &result)
}
// GetTradeHistory returns the trade history
func (w *WEX) GetTradeHistory(TIDFrom, Count, TIDEnd, since, end int64, order, pair string) (map[string]TradeHistory, error) {
req := url.Values{}
req.Add("from", strconv.FormatInt(TIDFrom, 10))
req.Add("count", strconv.FormatInt(Count, 10))
req.Add("from_id", strconv.FormatInt(TIDFrom, 10))
req.Add("end_id", strconv.FormatInt(TIDEnd, 10))
req.Add("order", order)
req.Add("since", strconv.FormatInt(since, 10))
req.Add("end", strconv.FormatInt(end, 10))
req.Add("pair", pair)
result := TradeHistoryResponse{}
return result.Data, w.SendAuthenticatedHTTPRequest(wexTradeHistory, req, &result)
}
// WithdrawCoins withdraws coins for a specific coin
func (w *WEX) WithdrawCoins(coin string, amount float64, address string) (WithdrawCoins, error) {
req := url.Values{}
req.Add("coinName", coin)
req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64))
req.Add("address", address)
var result WithdrawCoins
err := w.SendAuthenticatedHTTPRequest(wexWithdrawCoin, req, &result)
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
}
return result, nil
}
// CoinDepositAddress returns the deposit address for a specific currency
func (w *WEX) CoinDepositAddress(coin string) (string, error) {
req := url.Values{}
req.Add("coinName", coin)
var result CoinDepositAddress
err := w.SendAuthenticatedHTTPRequest(wexCoinDepositAddress, req, &result)
if err != nil {
return result.Address, err
}
if result.Error != "" {
return result.Address, errors.New(result.Error)
}
return result.Address, nil
}
// CreateCoupon creates an exchange coupon for a sepcific currency
func (w *WEX) CreateCoupon(currency string, amount float64) (CreateCoupon, error) {
req := url.Values{}
req.Add("currency", currency)
req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64))
var result CreateCoupon
err := w.SendAuthenticatedHTTPRequest(wexCreateCoupon, req, &result)
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
}
return result, nil
}
// RedeemCoupon redeems an exchange coupon
func (w *WEX) RedeemCoupon(coupon string) (RedeemCoupon, error) {
req := url.Values{}
req.Add("coupon", coupon)
var result RedeemCoupon
err := w.SendAuthenticatedHTTPRequest(wexRedeemCoupon, req, &result)
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
}
return result, nil
}
// SendHTTPRequest sends an unauthenticated HTTP request
func (w *WEX) SendHTTPRequest(path string, result interface{}) error {
return w.SendPayload(http.MethodGet, path, nil, nil, result, false, w.Verbose)
}
// SendAuthenticatedHTTPRequest sends an authenticated HTTP request to WEX
func (w *WEX) SendAuthenticatedHTTPRequest(method string, values url.Values, result interface{}) (err error) {
if !w.AuthenticatedAPISupport {
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet,
w.Name)
}
if w.Nonce.Get() == 0 {
w.Nonce.Set(time.Now().Unix())
} else {
w.Nonce.Inc()
}
values.Set("nonce", w.Nonce.String())
values.Set("method", method)
encoded := values.Encode()
hmac := common.GetHMAC(common.HashSHA512, []byte(encoded), []byte(w.APISecret))
if w.Verbose {
log.Debugf("Sending POST request to %s calling method %s with params %s\n",
w.APIUrlSecondary,
method,
encoded)
}
headers := make(map[string]string)
headers["Key"] = w.APIKey
headers["Sign"] = common.HexEncodeToString(hmac)
headers["Content-Type"] = "application/x-www-form-urlencoded"
return w.SendPayload(http.MethodPost,
w.APIUrlSecondary,
headers,
strings.NewReader(encoded),
result,
true,
w.Verbose)
}
// GetFee returns an estimate of fee based on type of transaction
func (w *WEX) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
var fee float64
switch feeBuilder.FeeType {
case exchange.CryptocurrencyTradeFee:
info, err := w.GetInfo()
if err != nil {
return 0, err
}
currency := feeBuilder.FirstCurrency + feeBuilder.Delimiter + feeBuilder.SecondCurrency
fee = calculateTradingFee(info, currency, feeBuilder.PurchasePrice, feeBuilder.Amount)
case exchange.CryptocurrencyWithdrawalFee:
fee = getWithdrawalFee(feeBuilder.FirstCurrency)
case exchange.InternationalBankDepositFee:
fee = getInternationalBankDepositFee(feeBuilder.CurrencyItem, feeBuilder.Amount, feeBuilder.BankTransactionType)
}
if fee < 0 {
fee = 0
}
return fee, nil
}
func calculateTradingFee(info Info, currency string, purchasePrice, amount float64) (fee float64) {
fee = info.Pairs[common.StringToLower(currency)].Fee
return (fee / 100) * amount * purchasePrice
}
func getWithdrawalFee(currency string) float64 {
return WithdrawalFees[currency]
}
func getInternationalBankDepositFee(currency string, amount float64, bankTransactionType exchange.InternationalBankTransactionType) float64 {
var fee float64
switch bankTransactionType {
case exchange.WireTransfer:
fallthrough
case exchange.WesternUnion:
switch currency {
case symbol.USD:
fee = 0.065 * amount
}
case exchange.MoneyGram:
switch currency {
case symbol.USD:
fee = 0.065 * amount
}
case exchange.Contact:
switch currency {
case symbol.USD:
fee = 0.065 * amount
}
}
return fee
}

View File

@@ -1,514 +0,0 @@
package wex
import (
"math"
"testing"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/pair"
"github.com/thrasher-/gocryptotrader/currency/symbol"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
)
var w WEX
// Please supply your own keys for better unit testing
const (
apiKey = ""
apiSecret = ""
canManipulateRealOrders = false
isWexEncounteringIssues = true
)
func TestSetDefaults(t *testing.T) {
w.SetDefaults()
}
func TestSetup(t *testing.T) {
wexConfig := config.GetConfig()
wexConfig.LoadConfig("../../testdata/configtest.json")
conf, err := wexConfig.GetExchangeConfig("WEX")
if err != nil {
t.Error("Test Failed - WEX init error")
}
conf.APIKey = apiKey
conf.APISecret = apiSecret
conf.AuthenticatedAPISupport = true
w.Setup(conf)
}
func TestGetTradablePairs(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.GetTradablePairs()
if err != nil {
t.Errorf("Test failed. GetTradablePairs err: %s", err)
}
}
func TestGetInfo(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.GetInfo()
if err != nil {
t.Error("Test Failed - GetInfo() error")
}
}
func TestGetTicker(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.GetTicker("btc_usd")
if err != nil {
t.Error("Test Failed - GetTicker() error", err)
}
}
func TestGetDepth(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.GetDepth("btc_usd")
if err != nil {
t.Error("Test Failed - GetDepth() error", err)
}
}
func TestGetTrades(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.GetTrades("btc_usd")
if err != nil {
t.Error("Test Failed - GetTrades() error", err)
}
}
func TestGetAccountInfo(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.GetAccountInfo()
if err == nil {
t.Error("Test Failed - GetAccountInfo() error", err)
}
}
func GetOpenOrders(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.GetOpenOrders("")
if err == nil {
t.Error("Test Failed - GetOpenOrders() error", err)
}
}
func TestGetOrderInfo(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.GetOrderInfo(6196974)
if err == nil {
t.Error("Test Failed - GetOrderInfo() error", err)
}
}
func TestCancelExistingOrder(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.CancelExistingOrder(1337)
if err == nil {
t.Error("Test Failed - CancelExistingOrder() error", err)
}
}
func TestTrade(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.Trade("", "buy", 0, 0)
if err == nil {
t.Error("Test Failed - Trade() error", err)
}
}
func TestGetTransactionHistory(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.GetTransactionHistory(0, 0, 0, "", "", "")
if err == nil {
t.Error("Test Failed - GetTransactionHistory() error", err)
}
}
func TestWithdrawCoins(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.WithdrawCoins("", 0, "")
if err == nil {
t.Error("Test Failed - WithdrawCoins() error", err)
}
}
func TestCoinDepositAddress(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.CoinDepositAddress("btc")
if err == nil {
t.Error("Test Failed - WithdrawCoins() error", err)
}
}
func TestCreateCoupon(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.CreateCoupon("bla", 0)
if err == nil {
t.Error("Test Failed - CreateCoupon() error", err)
}
}
func TestRedeemCoupon(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.RedeemCoupon("bla")
if err == nil {
t.Error("Test Failed - RedeemCoupon() error", err)
}
}
func setFeeBuilder() exchange.FeeBuilder {
return exchange.FeeBuilder{
Amount: 1,
Delimiter: "_",
FeeType: exchange.CryptocurrencyTradeFee,
FirstCurrency: symbol.LTC,
SecondCurrency: symbol.BTC,
IsMaker: false,
PurchasePrice: 1,
CurrencyItem: symbol.USD,
BankTransactionType: exchange.WireTransfer,
}
}
func TestGetFee(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
w.SetDefaults()
TestSetup(t)
var feeBuilder = setFeeBuilder()
// CryptocurrencyTradeFee Basic
if resp, err := w.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)
}
// CryptocurrencyTradeFee High quantity
feeBuilder = setFeeBuilder()
feeBuilder.Amount = 1000
feeBuilder.PurchasePrice = 1000
if resp, err := w.GetFee(feeBuilder); resp != float64(2000) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(2000), resp)
t.Error(err)
}
// CryptocurrencyTradeFee IsMaker
feeBuilder = setFeeBuilder()
feeBuilder.IsMaker = true
if resp, err := w.GetFee(feeBuilder); resp != float64(0.002) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.002), resp)
t.Error(err)
}
// CryptocurrencyTradeFee Negative purchase price
feeBuilder = setFeeBuilder()
feeBuilder.PurchasePrice = -1000
if resp, err := w.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Error(err)
}
// CryptocurrencyWithdrawalFee Basic
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
if resp, err := w.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)
}
// CryptocurrencyWithdrawalFee Invalid currency
feeBuilder = setFeeBuilder()
feeBuilder.FirstCurrency = "hello"
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
if resp, err := w.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Error(err)
}
// CyptocurrencyDepositFee Basic
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.CyptocurrencyDepositFee
if resp, err := w.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Error(err)
}
// InternationalBankDepositFee Basic
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.InternationalBankDepositFee
if resp, err := w.GetFee(feeBuilder); resp != float64(0.065) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.065), resp)
t.Error(err)
}
// InternationalBankWithdrawalFee Basic
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
feeBuilder.CurrencyItem = symbol.USD
if resp, err := w.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Error(err)
}
}
func TestFormatWithdrawPermissions(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
w.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.NoFiatWithdrawalsText
withdrawPermissions := w.FormatWithdrawPermissions()
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
w.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
}
_, err := w.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) {
w.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
StartTicks: time.Unix(0, 0),
EndTicks: time.Unix(math.MaxInt64, 0),
}
_, err := w.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")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
if w.APIKey != "" && w.APIKey != "Key" &&
w.APISecret != "" && w.APISecret != "Secret" {
return true
}
return false
}
func TestSubmitOrder(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
w.SetDefaults()
TestSetup(t)
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
var pair = pair.CurrencyPair{
Delimiter: "_",
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.USD,
}
response, err := w.SubmitOrder(pair, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi")
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 TestCancelExchangeOrder(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
w.SetDefaults()
TestSetup(t)
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
OrderID: "1",
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
AccountID: "1",
CurrencyPair: currencyPair,
}
err := w.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) {
if isWexEncounteringIssues {
t.Skip()
}
w.SetDefaults()
TestSetup(t)
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
OrderID: "1",
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
AccountID: "1",
CurrencyPair: currencyPair,
}
resp, err := w.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.OrderStatus) > 0 {
t.Errorf("%v orders failed to cancel", len(resp.OrderStatus))
}
}
func TestModifyOrder(t *testing.T) {
_, err := w.ModifyOrder(exchange.ModifyOrder{})
if err == nil {
t.Error("Test failed - ModifyOrder() error")
}
}
func TestWithdraw(t *testing.T) {
w.SetDefaults()
TestSetup(t)
var withdrawCryptoRequest = exchange.WithdrawRequest{
Amount: 100,
Currency: symbol.LTC,
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
Description: "WITHDRAW IT ALL",
}
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := w.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) {
w.SetDefaults()
TestSetup(t)
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
var withdrawFiatRequest = exchange.WithdrawRequest{}
_, err := w.WithdrawFiatFunds(withdrawFiatRequest)
if err != common.ErrFunctionNotSupported {
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestWithdrawInternationalBank(t *testing.T) {
w.SetDefaults()
TestSetup(t)
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
var withdrawFiatRequest = exchange.WithdrawRequest{}
_, err := w.WithdrawFiatFundsToInternationalBank(withdrawFiatRequest)
if err != common.ErrFunctionNotSupported {
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
}
}

View File

@@ -1,178 +0,0 @@
package wex
import "github.com/thrasher-/gocryptotrader/currency/symbol"
// Response is a generic struct used for exchange API request result
type Response struct {
Return interface{} `json:"return"`
Success int `json:"success"`
Error string `json:"error"`
}
// Info holds server time and pair information
type Info struct {
ServerTime int64 `json:"server_time"`
Pairs map[string]Pair `json:"pairs"`
}
// Ticker stores the ticker information
type Ticker struct {
High float64
Low float64
Avg float64
Vol float64
VolumeCurrent float64 `json:"vol_cur"`
Last float64
Buy float64
Sell float64
Updated int64
}
// Orderbook stores the asks and bids orderbook information
type Orderbook struct {
Asks [][]float64 `json:"asks"`
Bids [][]float64 `json:"bids"`
}
// Trades stores trade information
type Trades struct {
Type string `json:"type"`
Price float64 `json:"bid"`
Amount float64 `json:"amount"`
TID int64 `json:"tid"`
Timestamp int64 `json:"timestamp"`
}
// ActiveOrders stores active order information
type ActiveOrders struct {
Pair string `json:"pair"`
Type string `json:"sell"`
Amount float64 `json:"amount"`
Rate float64 `json:"rate"`
TimestampCreated float64 `json:"time_created"`
Status int `json:"status"`
}
// Pair holds pair information
type Pair struct {
DecimalPlaces int `json:"decimal_places"`
MinPrice float64 `json:"min_price"`
MaxPrice float64 `json:"max_price"`
MinAmount float64 `json:"min_amount"`
Hidden int `json:"hidden"`
Fee float64 `json:"fee"`
}
// AccountInfo stores the account information for a user
type AccountInfo struct {
Funds map[string]float64 `json:"funds"`
OpenOrders int `json:"open_orders"`
Rights struct {
Info int `json:"info"`
Trade int `json:"trade"`
Withdraw int `json:"withdraw"`
} `json:"rights"`
ServerTime float64 `json:"server_time"`
TransactionCount int `json:"transaction_count"`
Error string `json:"error"`
}
// OrderInfo stores order information
type OrderInfo struct {
Pair string `json:"pair"`
Type string `json:"sell"`
StartAmount float64 `json:"start_amount"`
Amount float64 `json:"amount"`
Rate float64 `json:"rate"`
TimestampCreated float64 `json:"time_created"`
Status int `json:"status"`
}
// CancelOrder is used for the CancelOrder API request response
type CancelOrder struct {
OrderID float64 `json:"order_id"`
Funds map[string]float64 `json:"funds"`
Error string `json:"error"`
}
// Trade stores the trade information
type Trade struct {
Received float64 `json:"received"`
Remains float64 `json:"remains"`
OrderID float64 `json:"order_id"`
Funds map[string]float64 `json:"funds"`
Error string `json:"error"`
}
// TransHistory stores transaction history
type TransHistory struct {
Type int `json:"type"`
Amount float64 `json:"amount"`
Currency string `json:"currency"`
Description string `json:"desc"`
Status int `json:"status"`
Timestamp float64 `json:"timestamp"`
}
//TradeHistoryResponse returns all your trade history
type TradeHistoryResponse struct {
Success int64 `json:"success"`
Data map[string]TradeHistory `json:"return,omitempty"`
}
// TradeHistory stores trade history
type TradeHistory struct {
Pair string `json:"pair"`
Type string `json:"type"`
Amount float64 `json:"amount"`
Rate float64 `json:"rate"`
OrderID float64 `json:"order_id"`
MyOrder int `json:"is_your_order"`
Timestamp float64 `json:"timestamp"`
}
// CoinDepositAddress stores a curency deposit address
type CoinDepositAddress struct {
Address string `json:"address"`
Error string `json:"error"`
}
// WithdrawCoins stores information for a withdrawcoins request
type WithdrawCoins struct {
TID int64 `json:"tId"`
AmountSent float64 `json:"amountSent"`
Funds map[string]float64 `json:"funds"`
Error string `json:"error"`
}
// CreateCoupon stores information coupon information
type CreateCoupon struct {
Coupon string `json:"coupon"`
TransID int64 `json:"transID"`
Funds map[string]float64 `json:"funds"`
Error string `json:"error"`
}
// RedeemCoupon stores redeem coupon information
type RedeemCoupon struct {
CouponAmount float64 `json:"couponAmount,string"`
CouponCurrency string `json:"couponCurrency"`
TransID int64 `json:"transID"`
Error string `json:"error"`
}
// WithdrawalFees the large list of predefined withdrawal fees
// Prone to change, using highest value
var WithdrawalFees = map[string]float64{
symbol.BTC: 0.0004,
symbol.LTC: 0.001,
symbol.NMC: 0.1,
symbol.NVC: 0.1,
symbol.PPC: 0.1,
symbol.DSH: 0.001,
symbol.ETH: 0.003,
symbol.BCH: 0.001,
symbol.ZEC: 0.001,
symbol.USDT: 10,
symbol.XMR: 0.01,
}

View File

@@ -1,351 +0,0 @@
package wex
import (
"errors"
"fmt"
"math"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
log "github.com/thrasher-/gocryptotrader/logger"
)
// Start starts the WEX go routine
func (w *WEX) Start(wg *sync.WaitGroup) {
wg.Add(1)
go func() {
w.Run()
wg.Done()
}()
}
// Run implements the WEX wrapper
func (w *WEX) Run() {
if w.Verbose {
log.Debugf("%s Websocket: %s.", w.GetName(), common.IsEnabled(w.Websocket.IsEnabled()))
log.Debugf("%s polling delay: %ds.\n", w.GetName(), w.RESTPollingDelay)
log.Debugf("%s %d currencies enabled: %s.\n", w.GetName(), len(w.EnabledPairs), w.EnabledPairs)
}
exchangeProducts, err := w.GetTradablePairs()
if err != nil {
log.Errorf("%s Failed to get available symbols.\n", w.GetName())
} else {
forceUpgrade := false
if !common.StringDataContains(w.EnabledPairs, "_") || !common.StringDataContains(w.AvailablePairs, "_") {
forceUpgrade = true
}
if forceUpgrade {
enabledPairs := []string{"BTC_USD", "LTC_USD", "LTC_BTC", "ETH_USD"}
log.Warn("Enabled pairs for WEX reset due to config upgrade, please enable the ones you would like again.")
err = w.UpdateCurrencies(enabledPairs, true, true)
if err != nil {
log.Errorf("%s Failed to get config.\n", w.GetName())
}
}
err = w.UpdateCurrencies(exchangeProducts, false, forceUpgrade)
if err != nil {
log.Errorf("%s Failed to get config.\n", w.GetName())
}
}
}
// UpdateTicker updates and returns the ticker for a currency pair
func (w *WEX) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
var tickerPrice ticker.Price
pairsCollated, err := exchange.GetAndFormatExchangeCurrencies(w.Name, w.GetEnabledCurrencies())
if err != nil {
return tickerPrice, err
}
result, err := w.GetTicker(pairsCollated.String())
if err != nil {
return tickerPrice, err
}
for _, x := range w.GetEnabledCurrencies() {
currency := exchange.FormatExchangeCurrency(w.Name, x).Lower().String()
var tp ticker.Price
tp.Pair = x
tp.Last = result[currency].Last
tp.Ask = result[currency].Sell
tp.Bid = result[currency].Buy
tp.Last = result[currency].Last
tp.Low = result[currency].Low
tp.Volume = result[currency].VolumeCurrent
ticker.ProcessTicker(w.Name, x, tp, assetType)
}
return ticker.GetTicker(w.Name, p, assetType)
}
// GetTickerPrice returns the ticker for a currency pair
func (w *WEX) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
tick, err := ticker.GetTicker(w.GetName(), p, assetType)
if err != nil {
return w.UpdateTicker(p, assetType)
}
return tick, nil
}
// GetOrderbookEx returns the orderbook for a currency pair
func (w *WEX) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
ob, err := orderbook.GetOrderbook(w.GetName(), p, assetType)
if err != nil {
return w.UpdateOrderbook(p, assetType)
}
return ob, nil
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (w *WEX) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
var orderBook orderbook.Base
orderbookNew, err := w.GetDepth(exchange.FormatExchangeCurrency(w.Name, p).String())
if err != nil {
return orderBook, err
}
for x := range orderbookNew.Bids {
data := orderbookNew.Bids[x]
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Price: data[0], Amount: data[1]})
}
for x := range orderbookNew.Asks {
data := orderbookNew.Asks[x]
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Price: data[0], Amount: data[1]})
}
orderbook.ProcessOrderbook(w.GetName(), p, orderBook, assetType)
return orderbook.GetOrderbook(w.Name, p, assetType)
}
// GetAccountInfo retrieves balances for all enabled currencies for the
// WEX exchange
func (w *WEX) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.Exchange = w.GetName()
accountBalance, err := w.GetAccountInformation()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for x, y := range accountBalance.Funds {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = common.StringToUpper(x)
exchangeCurrency.TotalValue = y
exchangeCurrency.Hold = 0
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
// GetFundingHistory returns funding history, deposits and
// withdrawals
func (w *WEX) GetFundingHistory() ([]exchange.FundHistory, error) {
var fundHistory []exchange.FundHistory
return fundHistory, common.ErrFunctionNotSupported
}
// GetExchangeHistory returns historic trade data since exchange opening.
func (w *WEX) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
var resp []exchange.TradeHistory
return resp, common.ErrNotYetImplemented
}
// SubmitOrder submits a new order
func (w *WEX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
var submitOrderResponse exchange.SubmitOrderResponse
if orderType != exchange.LimitOrderType {
return submitOrderResponse, errors.New("only limit orders are allowed")
}
response, err := w.Trade(p.Pair().String(), side.ToString(), amount, price)
if response > 0 {
submitOrderResponse.OrderID = fmt.Sprintf("%v", response)
}
if err == nil {
submitOrderResponse.IsOrderPlaced = true
}
return submitOrderResponse, err
}
// ModifyOrder will allow of changing orderbook placement and limit to
// market conversion
func (w *WEX) ModifyOrder(action exchange.ModifyOrder) (string, error) {
return "", common.ErrNotYetImplemented
}
// CancelOrder cancels an order by its corresponding ID number
func (w *WEX) CancelOrder(order exchange.OrderCancellation) error {
orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64)
if err != nil {
return err
}
_, err = w.CancelExistingOrder(orderIDInt)
return err
}
// CancelAllOrders cancels all orders associated with a currency pair
func (w *WEX) CancelAllOrders(_ exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
var allActiveOrders map[string]ActiveOrders
for _, pair := range w.EnabledPairs {
activeOrders, err := w.GetOpenOrders(pair)
if err != nil {
return cancelAllOrdersResponse, err
}
for k, v := range activeOrders {
allActiveOrders[k] = v
}
}
for k := range allActiveOrders {
orderIDInt, err := strconv.ParseInt(k, 10, 64)
if err != nil {
return cancelAllOrdersResponse, err
}
_, err = w.CancelExistingOrder(orderIDInt)
if err != nil {
cancelAllOrdersResponse.OrderStatus[k] = err.Error()
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order
func (w *WEX) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
var orderDetail exchange.OrderDetail
return orderDetail, common.ErrNotYetImplemented
}
// GetDepositAddress returns a deposit address for a specified currency
func (w *WEX) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrNotYetImplemented
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is
// submitted
func (w *WEX) WithdrawCryptocurrencyFunds(withdrawRequest exchange.WithdrawRequest) (string, error) {
resp, err := w.WithdrawCoins(withdrawRequest.Currency.String(), withdrawRequest.Amount, withdrawRequest.Address)
return fmt.Sprintf("%v", resp.TID), err
}
// WithdrawFiatFunds returns a withdrawal ID when a
// withdrawal is submitted
func (w *WEX) WithdrawFiatFunds(withdrawRequest exchange.WithdrawRequest) (string, error) {
return "", common.ErrFunctionNotSupported
}
// WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a
// withdrawal is submitted
func (w *WEX) WithdrawFiatFundsToInternationalBank(withdrawRequest exchange.WithdrawRequest) (string, error) {
return "", common.ErrFunctionNotSupported
}
// GetWebsocket returns a pointer to the exchange websocket
func (w *WEX) GetWebsocket() (*exchange.Websocket, error) {
return nil, common.ErrNotYetImplemented
}
// GetFeeByType returns an estimate of fee based on type of transaction
func (w *WEX) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
return w.GetFee(feeBuilder)
}
// GetWithdrawCapabilities returns the types of withdrawal methods permitted by the exchange
func (w *WEX) GetWithdrawCapabilities() uint32 {
return w.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (w *WEX) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var orders []exchange.OrderDetail
for _, currency := range getOrdersRequest.Currencies {
resp, err := w.GetOpenOrders(exchange.FormatExchangeCurrency(w.Name, currency).String())
if err != nil {
return nil, err
}
for ID, order := range resp {
symbol := pair.NewCurrencyPairDelimiter(order.Pair, w.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(int64(order.TimestampCreated), 0)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
ID: ID,
Amount: order.Amount,
Price: order.Rate,
OrderSide: side,
OrderDate: orderDate,
CurrencyPair: symbol,
Exchange: w.Name,
})
}
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (w *WEX) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var allOrders []TradeHistory
for _, currency := range getOrdersRequest.Currencies {
resp, err := w.GetTradeHistory(0, 10000, math.MaxInt64, getOrdersRequest.StartTicks.Unix(), getOrdersRequest.EndTicks.Unix(), "DESC", exchange.FormatExchangeCurrency(w.Name, currency).String())
if err != nil {
return nil, err
}
for _, order := range resp {
allOrders = append(allOrders, order)
}
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
symbol := pair.NewCurrencyPairDelimiter(order.Pair, w.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(int64(order.Timestamp), 0)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.OrderID),
Amount: order.Amount,
Price: order.Rate,
OrderSide: side,
OrderDate: orderDate,
CurrencyPair: symbol,
Exchange: w.Name,
})
}
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -17,7 +17,7 @@ import (
log "github.com/thrasher-/gocryptotrader/logger"
)
// Start starts the WEX go routine
// Start starts the Yobit go routine
func (y *Yobit) Start(wg *sync.WaitGroup) {
wg.Add(1)
go func() {

View File

@@ -470,48 +470,6 @@
}
]
},
{
"name": "WEX",
"enabled": true,
"verbose": false,
"websocket": false,
"useSandbox": false,
"restPollingDelay": 10,
"httpTimeout": 15000000000,
"httpUserAgent": "",
"authenticatedApiSupport": false,
"apiKey": "Key",
"apiSecret": "Secret",
"apiUrl": "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API",
"apiUrlSecondary": "NON_DEFAULT_HTTP_LINK_TO_EXCHANGE_API",
"proxyAddress": "",
"websocketUrl": "NON_DEFAULT_HTTP_LINK_TO_WEBSOCKET_EXCHANGE_API",
"availablePairs": "BTC_EUR,EUR_USD,DSH_RUR,DSH_EUR,BCH_BTC,BCH_RUR,PPC_USD,XMR_USD,DSH_BTC,PPCET_PPC,XMR_RUR,LTC_EUR,ZEC_USD,ZEC_LTC,BTC_USDT,EUR_RUR,DSH_USD,USDET_USD,EURET_EUR,BCHET_BCH,ETH_USD,ETH_EUR,ZEC_BTC,NVC_USD,DSH_ETH,DSH_ZEC,ETH_BTC,ETH_LTC,NMC_USD,BCH_USD,XMR_BTC,ZEC_RUR,XMR_EUR,BCH_EUR,NMCET_NMC,USDT_USD,LTC_USD,NMC_BTC,ETH_ZEC,RURET_RUR,DSHET_DSH,XMR_ETH,NVC_BTC,USD_RUR,PPC_BTC,BCH_LTC,BCH_DSH,LTCET_LTC,LTC_BTC,ETHET_ETH,NVCET_NVC,BTC_RUR,BCH_ZEC,BTCET_BTC,BTC_USD,LTC_RUR,DSH_LTC,ETH_RUR,BCH_ETH",
"enabledPairs": "BTC_USD,LTC_USD,LTC_BTC,ETH_USD",
"baseCurrencies": "USD,RUR,EUR",
"assetTypes": "SPOT",
"supportsAutoPairUpdates": true,
"configCurrencyPairFormat": {
"uppercase": true,
"delimiter": "_"
},
"requestCurrencyPairFormat": {
"uppercase": false,
"delimiter": "_",
"separator": "-"
},
"bankAccounts": [
{
"bankName": "",
"bankAddress": "",
"accountName": "",
"accountNumber": "",
"swiftCode": "",
"iban": "",
"supportedCurrencies": ""
}
]
},
{
"name": "BTC Markets",
"enabled": true,

View File

@@ -72,7 +72,6 @@ const (
okcoin = "..%s..%sexchanges%sokcoin%s"
okex = "..%s..%sexchanges%sokex%s"
poloniex = "..%s..%sexchanges%spoloniex%s"
wex = "..%s..%sexchanges%swex%s"
yobit = "..%s..%sexchanges%syobit%s"
zb = "..%s..%sexchanges%szb%s"
@@ -246,7 +245,6 @@ func addPaths() {
codebasePaths["exchanges okcoin"] = fmt.Sprintf(okcoin, path, path, path, path)
codebasePaths["exchanges okex"] = fmt.Sprintf(okex, path, path, path, path)
codebasePaths["exchanges poloniex"] = fmt.Sprintf(poloniex, path, path, path, path)
codebasePaths["exchanges wex"] = fmt.Sprintf(wex, path, path, path, path)
codebasePaths["exchanges yobit"] = fmt.Sprintf(yobit, path, path, path, path)
codebasePaths["exchanges zb"] = fmt.Sprintf(zb, path, path, path, path)

View File

@@ -1,98 +0,0 @@
{{define "exchanges wex" -}}
{{template "header" .}}
## Wex Exchange
### Current Features
+ REST Support
### How to enable
+ [Enable via configuration](https://github.com/thrasher-/gocryptotrader/tree/master/config#enable-exchange-via-config-example)
+ Individual package example below:
```go
// Exchanges will be abstracted out in further updates and examples will be
// supplied then
```
### How to do REST public/private calls
+ If enabled via "configuration".json file the exchange will be added to the
IBotExchange array in the ```go var bot Bot``` and you will only be able to use
the wrapper interface functions for accessing exchange data. View routines.go
for an example of integration usage with GoCryptoTrader. Rudimentary example
below:
main.go
```go
var w exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Wex" {
y = bot.exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := w.GetTickerPrice()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := w.GetOrderbookEx()
if err != nil {
// Handle error
}
// Private calls - wrapper functions - make sure your APIKEY and APISECRET are
// set and AuthenticatedAPISupport is set to true
// Fetches current account information
accountInfo, err := w.GetAccountInfo()
if err != nil {
// Handle error
}
```
+ If enabled via individually importing package, rudimentary example below:
```go
// Public calls
// Fetches current ticker information
ticker, err := w.GetTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := w.GetDepth()
if err != nil {
// Handle error
}
// Private calls - make sure your APIKEY and APISECRET are set and
// AuthenticatedAPISupport is set to true
// Fetches current account information
accountInfo, err := w.GetAccountInfo()
if err != nil {
// Handle error
}
// Submits an order and the exchange and returns its tradeID
tradeID, err := w.Trade("BTCUSD", "MARKET", 1, 2)
if err != nil {
// Handle error
}
```
### Please click GoDocs chevron above to view current GoDoc information for this package
{{template "contributions"}}
{{template "donations"}}
{{end}}

View File

@@ -46,7 +46,6 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader
| OKCoin International | Yes | Yes | No |
| OKEX | Yes | Yes | No |
| Poloniex | Yes | Yes | NA |
| WEX | Yes | NA | NA |
| Yobit | Yes | NA | NA |
| ZB.COM | Yes | Yes | NA |