2614 lines
108 KiB
Go
2614 lines
108 KiB
Go
package ccxt
|
|
|
|
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
|
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
|
|
|
type bitvavo struct {
|
|
Exchange
|
|
|
|
}
|
|
|
|
func NewBitvavoCore() bitvavo {
|
|
p := bitvavo{}
|
|
setDefaults(&p)
|
|
return p
|
|
}
|
|
|
|
func (this *bitvavo) Describe() interface{} {
|
|
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
|
|
"id": "bitvavo",
|
|
"name": "Bitvavo",
|
|
"countries": []interface{}{"NL"},
|
|
"rateLimit": 60,
|
|
"version": "v2",
|
|
"certified": false,
|
|
"pro": true,
|
|
"has": map[string]interface{} {
|
|
"CORS": nil,
|
|
"spot": true,
|
|
"margin": false,
|
|
"swap": false,
|
|
"future": false,
|
|
"option": false,
|
|
"addMargin": false,
|
|
"cancelAllOrders": true,
|
|
"cancelOrder": true,
|
|
"closeAllPositions": false,
|
|
"closePosition": false,
|
|
"createOrder": true,
|
|
"createReduceOnlyOrder": false,
|
|
"createStopLimitOrder": true,
|
|
"createStopMarketOrder": true,
|
|
"createStopOrder": true,
|
|
"editOrder": true,
|
|
"fetchBalance": true,
|
|
"fetchBorrowRateHistories": false,
|
|
"fetchBorrowRateHistory": false,
|
|
"fetchCrossBorrowRate": false,
|
|
"fetchCrossBorrowRates": false,
|
|
"fetchCurrencies": true,
|
|
"fetchDepositAddress": true,
|
|
"fetchDepositAddresses": false,
|
|
"fetchDepositAddressesByNetwork": false,
|
|
"fetchDeposits": true,
|
|
"fetchDepositWithdrawFee": "emulated",
|
|
"fetchDepositWithdrawFees": true,
|
|
"fetchFundingHistory": false,
|
|
"fetchFundingRate": false,
|
|
"fetchFundingRateHistory": false,
|
|
"fetchFundingRates": false,
|
|
"fetchIndexOHLCV": false,
|
|
"fetchIsolatedBorrowRate": false,
|
|
"fetchIsolatedBorrowRates": false,
|
|
"fetchLeverage": false,
|
|
"fetchLeverageTiers": false,
|
|
"fetchMarginMode": false,
|
|
"fetchMarkets": true,
|
|
"fetchMarkOHLCV": false,
|
|
"fetchMyTrades": true,
|
|
"fetchOHLCV": true,
|
|
"fetchOpenInterestHistory": false,
|
|
"fetchOpenOrders": true,
|
|
"fetchOrder": true,
|
|
"fetchOrderBook": true,
|
|
"fetchOrders": true,
|
|
"fetchPosition": false,
|
|
"fetchPositionHistory": false,
|
|
"fetchPositionMode": false,
|
|
"fetchPositions": false,
|
|
"fetchPositionsForSymbol": false,
|
|
"fetchPositionsHistory": false,
|
|
"fetchPositionsRisk": false,
|
|
"fetchPremiumIndexOHLCV": false,
|
|
"fetchTicker": true,
|
|
"fetchTickers": true,
|
|
"fetchTime": true,
|
|
"fetchTrades": true,
|
|
"fetchTradingFee": false,
|
|
"fetchTradingFees": true,
|
|
"fetchTransfer": false,
|
|
"fetchTransfers": false,
|
|
"fetchWithdrawals": true,
|
|
"reduceMargin": false,
|
|
"setLeverage": false,
|
|
"setMarginMode": false,
|
|
"setPositionMode": false,
|
|
"transfer": false,
|
|
"withdraw": true,
|
|
},
|
|
"timeframes": map[string]interface{} {
|
|
"1m": "1m",
|
|
"5m": "5m",
|
|
"15m": "15m",
|
|
"30m": "30m",
|
|
"1h": "1h",
|
|
"2h": "2h",
|
|
"4h": "4h",
|
|
"6h": "6h",
|
|
"8h": "8h",
|
|
"12h": "12h",
|
|
"1d": "1d",
|
|
},
|
|
"urls": map[string]interface{} {
|
|
"logo": "https://github.com/user-attachments/assets/d213155c-8c71-4701-9bd5-45351febc2a8",
|
|
"api": map[string]interface{} {
|
|
"public": "https://api.bitvavo.com",
|
|
"private": "https://api.bitvavo.com",
|
|
},
|
|
"www": "https://bitvavo.com/",
|
|
"doc": "https://docs.bitvavo.com/",
|
|
"fees": "https://bitvavo.com/en/fees",
|
|
"referral": "https://bitvavo.com/?a=24F34952F7",
|
|
},
|
|
"api": map[string]interface{} {
|
|
"public": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"time": 1,
|
|
"markets": 1,
|
|
"assets": 1,
|
|
"{market}/book": 1,
|
|
"{market}/trades": 5,
|
|
"{market}/candles": 1,
|
|
"ticker/price": 1,
|
|
"ticker/book": 1,
|
|
"ticker/24h": map[string]interface{} {
|
|
"cost": 1,
|
|
"noMarket": 25,
|
|
},
|
|
},
|
|
},
|
|
"private": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"account": 1,
|
|
"order": 1,
|
|
"orders": 5,
|
|
"ordersOpen": map[string]interface{} {
|
|
"cost": 1,
|
|
"noMarket": 25,
|
|
},
|
|
"trades": 5,
|
|
"balance": 5,
|
|
"deposit": 1,
|
|
"depositHistory": 5,
|
|
"withdrawalHistory": 5,
|
|
},
|
|
"post": map[string]interface{} {
|
|
"order": 1,
|
|
"withdrawal": 1,
|
|
},
|
|
"put": map[string]interface{} {
|
|
"order": 1,
|
|
},
|
|
"delete": map[string]interface{} {
|
|
"order": 1,
|
|
"orders": 1,
|
|
},
|
|
},
|
|
},
|
|
"fees": map[string]interface{} {
|
|
"trading": map[string]interface{} {
|
|
"tierBased": true,
|
|
"percentage": true,
|
|
"taker": this.ParseNumber("0.0025"),
|
|
"maker": this.ParseNumber("0.002"),
|
|
"tiers": map[string]interface{} {
|
|
"taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.0025")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.0020")}, []interface{}{this.ParseNumber("250000"), this.ParseNumber("0.0016")}, []interface{}{this.ParseNumber("500000"), this.ParseNumber("0.0012")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.0010")}, []interface{}{this.ParseNumber("2500000"), this.ParseNumber("0.0008")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.0006")}, []interface{}{this.ParseNumber("10000000"), this.ParseNumber("0.0005")}, []interface{}{this.ParseNumber("25000000"), this.ParseNumber("0.0004")}},
|
|
"maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.0015")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.0010")}, []interface{}{this.ParseNumber("250000"), this.ParseNumber("0.0008")}, []interface{}{this.ParseNumber("500000"), this.ParseNumber("0.0006")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.0005")}, []interface{}{this.ParseNumber("2500000"), this.ParseNumber("0.0004")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.0004")}, []interface{}{this.ParseNumber("10000000"), this.ParseNumber("0.0003")}, []interface{}{this.ParseNumber("25000000"), this.ParseNumber("0.0003")}},
|
|
},
|
|
},
|
|
},
|
|
"requiredCredentials": map[string]interface{} {
|
|
"apiKey": true,
|
|
"secret": true,
|
|
},
|
|
"features": map[string]interface{} {
|
|
"spot": map[string]interface{} {
|
|
"sandbox": false,
|
|
"createOrder": map[string]interface{} {
|
|
"marginMode": false,
|
|
"triggerPrice": true,
|
|
"triggerPriceType": nil,
|
|
"triggerDirection": nil,
|
|
"stopLossPrice": true,
|
|
"takeProfitPrice": true,
|
|
"attachedStopLossTakeProfit": nil,
|
|
"timeInForce": map[string]interface{} {
|
|
"IOC": true,
|
|
"FOK": true,
|
|
"PO": true,
|
|
"GTD": false,
|
|
},
|
|
"hedged": false,
|
|
"trailing": false,
|
|
"leverage": false,
|
|
"marketBuyRequiresPrice": false,
|
|
"marketBuyByCost": true,
|
|
"selfTradePrevention": true,
|
|
"iceberg": false,
|
|
},
|
|
"createOrders": nil,
|
|
"fetchMyTrades": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 1000,
|
|
"daysBack": 100000,
|
|
"untilDays": 100000,
|
|
"symbolRequired": true,
|
|
},
|
|
"fetchOrder": map[string]interface{} {
|
|
"marginMode": false,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": true,
|
|
},
|
|
"fetchOpenOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": nil,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": true,
|
|
},
|
|
"fetchOrders": map[string]interface{} {
|
|
"marginMode": true,
|
|
"limit": 1000,
|
|
"daysBack": 100000,
|
|
"untilDays": 100000,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": true,
|
|
},
|
|
"fetchClosedOrders": nil,
|
|
"fetchOHLCV": map[string]interface{} {
|
|
"limit": 1440,
|
|
},
|
|
},
|
|
"swap": map[string]interface{} {
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
},
|
|
"future": map[string]interface{} {
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
},
|
|
},
|
|
"exceptions": map[string]interface{} {
|
|
"exact": map[string]interface{} {
|
|
"101": ExchangeError,
|
|
"102": BadRequest,
|
|
"103": RateLimitExceeded,
|
|
"104": RateLimitExceeded,
|
|
"105": PermissionDenied,
|
|
"107": ExchangeNotAvailable,
|
|
"108": ExchangeNotAvailable,
|
|
"109": ExchangeNotAvailable,
|
|
"110": BadRequest,
|
|
"200": BadRequest,
|
|
"201": BadRequest,
|
|
"202": BadRequest,
|
|
"203": BadSymbol,
|
|
"204": BadRequest,
|
|
"205": BadRequest,
|
|
"206": BadRequest,
|
|
"210": InvalidOrder,
|
|
"211": InvalidOrder,
|
|
"212": InvalidOrder,
|
|
"213": InvalidOrder,
|
|
"214": InvalidOrder,
|
|
"215": InvalidOrder,
|
|
"216": InsufficientFunds,
|
|
"217": InvalidOrder,
|
|
"230": ExchangeError,
|
|
"231": ExchangeError,
|
|
"232": BadRequest,
|
|
"233": InvalidOrder,
|
|
"234": InvalidOrder,
|
|
"235": ExchangeError,
|
|
"236": BadRequest,
|
|
"240": OrderNotFound,
|
|
"300": AuthenticationError,
|
|
"301": AuthenticationError,
|
|
"302": AuthenticationError,
|
|
"303": AuthenticationError,
|
|
"304": AuthenticationError,
|
|
"305": AuthenticationError,
|
|
"306": AuthenticationError,
|
|
"307": PermissionDenied,
|
|
"308": AuthenticationError,
|
|
"309": AuthenticationError,
|
|
"310": PermissionDenied,
|
|
"311": PermissionDenied,
|
|
"312": PermissionDenied,
|
|
"315": BadRequest,
|
|
"317": AccountSuspended,
|
|
"400": ExchangeError,
|
|
"401": ExchangeError,
|
|
"402": PermissionDenied,
|
|
"403": PermissionDenied,
|
|
"404": OnMaintenance,
|
|
"405": ExchangeError,
|
|
"406": BadRequest,
|
|
"407": ExchangeError,
|
|
"408": InsufficientFunds,
|
|
"409": InvalidAddress,
|
|
"410": ExchangeError,
|
|
"411": BadRequest,
|
|
"412": InvalidAddress,
|
|
"413": InvalidAddress,
|
|
"414": ExchangeError,
|
|
},
|
|
"broad": map[string]interface{} {
|
|
"start parameter is invalid": BadRequest,
|
|
"symbol parameter is invalid": BadSymbol,
|
|
"amount parameter is invalid": InvalidOrder,
|
|
"orderId parameter is invalid": InvalidOrder,
|
|
},
|
|
},
|
|
"options": map[string]interface{} {
|
|
"currencyToPrecisionRoundingMode": TRUNCATE,
|
|
"BITVAVO-ACCESS-WINDOW": 10000,
|
|
"networks": map[string]interface{} {
|
|
"ERC20": "ETH",
|
|
"TRC20": "TRX",
|
|
},
|
|
},
|
|
"precisionMode": SIGNIFICANT_DIGITS,
|
|
"commonCurrencies": map[string]interface{} {
|
|
"MIOTA": "IOTA",
|
|
},
|
|
})
|
|
}
|
|
func (this *bitvavo) AmountToPrecision(symbol interface{}, amount interface{}) interface{} {
|
|
// https://docs.bitfinex.com/docs/introduction#amount-precision
|
|
// The amount field allows up to 8 decimals.
|
|
// Anything exceeding this will be rounded to the 8th decimal.
|
|
return this.DecimalToPrecision(amount, TRUNCATE, GetValue(GetValue(GetValue(this.Markets, symbol), "precision"), "amount"), DECIMAL_PLACES)
|
|
}
|
|
func (this *bitvavo) PriceToPrecision(symbol interface{}, price interface{}) interface{} {
|
|
price = this.DecimalToPrecision(price, ROUND, GetValue(GetValue(GetValue(this.Markets, symbol), "precision"), "price"), this.PrecisionMode)
|
|
// https://docs.bitfinex.com/docs/introduction#price-precision
|
|
// The precision level of all trading prices is based on significant figures.
|
|
// All pairs on Bitfinex use up to 5 significant digits and up to 8 decimals (e.g. 1.2345, 123.45, 1234.5, 0.00012345).
|
|
// Prices submit with a precision larger than 5 will be cut by the API.
|
|
return this.DecimalToPrecision(price, TRUNCATE, 8, DECIMAL_PLACES)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchTime
|
|
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
*/
|
|
func (this *bitvavo) FetchTime(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
response:= (<-this.PublicGetTime(params))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// { "time": 1590379519148 }
|
|
//
|
|
ch <- this.SafeInteger(response, "time")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchMarkets
|
|
* @see https://docs.bitvavo.com/#tag/General/paths/~1markets/get
|
|
* @description retrieves data on all markets for bitvavo
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} an array of objects representing market data
|
|
*/
|
|
func (this *bitvavo) FetchMarkets(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
response:= (<-this.PublicGetMarkets(params))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "market":"ADA-BTC",
|
|
// "status":"trading", // "trading" "halted" "auction"
|
|
// "base":"ADA",
|
|
// "quote":"BTC",
|
|
// "pricePrecision":5,
|
|
// "minOrderInBaseAsset":"100",
|
|
// "minOrderInQuoteAsset":"0.001",
|
|
// "orderTypes": [ "market", "limit" ]
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseMarkets(response)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) ParseMarkets(markets interface{}) interface{} {
|
|
var currencies interface{} = this.Currencies
|
|
var currenciesById interface{} = this.IndexBy(currencies, "id")
|
|
var result interface{} = []interface{}{}
|
|
var fees interface{} = this.Fees
|
|
for i := 0; IsLessThan(i, GetArrayLength(markets)); i++ {
|
|
var market interface{} = GetValue(markets, i)
|
|
var id interface{} = this.SafeString(market, "market")
|
|
var baseId interface{} = this.SafeString(market, "base")
|
|
var quoteId interface{} = this.SafeString(market, "quote")
|
|
var base interface{} = this.SafeCurrencyCode(baseId)
|
|
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
|
var status interface{} = this.SafeString(market, "status")
|
|
var baseCurrency interface{} = this.SafeValue(currenciesById, baseId)
|
|
var basePrecision interface{} = this.SafeInteger(baseCurrency, "precision")
|
|
AppendToArray(&result,this.SafeMarketStructure(map[string]interface{} {
|
|
"id": id,
|
|
"symbol": Add(Add(base, "/"), quote),
|
|
"base": base,
|
|
"quote": quote,
|
|
"settle": nil,
|
|
"baseId": baseId,
|
|
"quoteId": quoteId,
|
|
"settleId": nil,
|
|
"type": "spot",
|
|
"spot": true,
|
|
"margin": false,
|
|
"swap": false,
|
|
"future": false,
|
|
"option": false,
|
|
"active": (IsEqual(status, "trading")),
|
|
"contract": false,
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
"contractSize": nil,
|
|
"expiry": nil,
|
|
"expiryDatetime": nil,
|
|
"strike": nil,
|
|
"optionType": nil,
|
|
"taker": GetValue(GetValue(fees, "trading"), "taker"),
|
|
"maker": GetValue(GetValue(fees, "trading"), "maker"),
|
|
"precision": map[string]interface{} {
|
|
"amount": this.SafeInteger(baseCurrency, "decimals", basePrecision),
|
|
"price": this.SafeInteger(market, "pricePrecision"),
|
|
},
|
|
"limits": map[string]interface{} {
|
|
"leverage": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"amount": map[string]interface{} {
|
|
"min": this.SafeNumber(market, "minOrderInBaseAsset"),
|
|
"max": nil,
|
|
},
|
|
"price": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"cost": map[string]interface{} {
|
|
"min": this.SafeNumber(market, "minOrderInQuoteAsset"),
|
|
"max": nil,
|
|
},
|
|
},
|
|
"created": nil,
|
|
"info": market,
|
|
}))
|
|
}
|
|
return result
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchCurrencies
|
|
* @see https://docs.bitvavo.com/#tag/General/paths/~1assets/get
|
|
* @description fetches all available currencies on an exchange
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} an associative dictionary of currencies
|
|
*/
|
|
func (this *bitvavo) FetchCurrencies(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
response:= (<-this.PublicGetAssets(params))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol": "USDT",
|
|
// "displayTicker": "USDT",
|
|
// "name": "Tether",
|
|
// "slug": "tether",
|
|
// "popularity": -1,
|
|
// "decimals": 6,
|
|
// "depositFee": "0",
|
|
// "depositConfirmations": 64,
|
|
// "depositStatus": "OK",
|
|
// "withdrawalFee": "3.2",
|
|
// "withdrawalMinAmount": "3.2",
|
|
// "withdrawalStatus": "OK",
|
|
// "networks": [
|
|
// "ETH"
|
|
// ],
|
|
// "light": {
|
|
// "color": "#009393",
|
|
// "icon": { "hash": "4ad7c699", "svg": "https://...", "webp16": "https://...", "webp32": "https://...", "webp64": "https://...", "webp128": "https://...", "webp256": "https://...", "png16": "https://...", "png32": "https://...", "png64": "https://...", "png128": "https://...", "png256": "https://..."
|
|
// }
|
|
// },
|
|
// "dark": {
|
|
// "color": "#009393",
|
|
// "icon": { "hash": "4ad7c699", "svg": "https://...", "webp16": "https://...", "webp32": "https://...", "webp64": "https://...", "webp128": "https://...", "webp256": "https://...", "png16": "https://...", "png32": "https://...", "png64": "https://...", "png128": "https://...", "png256": "https://..."
|
|
// }
|
|
// },
|
|
// "visibility": "PUBLIC",
|
|
// "message": ""
|
|
// },
|
|
// ]
|
|
//
|
|
ch <- this.ParseCurrenciesCustom(response)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) ParseCurrenciesCustom(currencies interface{}) interface{} {
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol": "USDT",
|
|
// "displayTicker": "USDT",
|
|
// "name": "Tether",
|
|
// "slug": "tether",
|
|
// "popularity": -1,
|
|
// "decimals": 6,
|
|
// "depositFee": "0",
|
|
// "depositConfirmations": 64,
|
|
// "depositStatus": "OK",
|
|
// "withdrawalFee": "3.2",
|
|
// "withdrawalMinAmount": "3.2",
|
|
// "withdrawalStatus": "OK",
|
|
// "networks": [
|
|
// "ETH"
|
|
// ],
|
|
// "light": {
|
|
// "color": "#009393",
|
|
// "icon": { "hash": "4ad7c699", "svg": "https://...", "webp16": "https://...", "webp32": "https://...", "webp64": "https://...", "webp128": "https://...", "webp256": "https://...", "png16": "https://...", "png32": "https://...", "png64": "https://...", "png128": "https://...", "png256": "https://..."
|
|
// }
|
|
// },
|
|
// "dark": {
|
|
// "color": "#009393",
|
|
// "icon": { "hash": "4ad7c699", "svg": "https://...", "webp16": "https://...", "webp32": "https://...", "webp64": "https://...", "webp128": "https://...", "webp256": "https://...", "png16": "https://...", "png32": "https://...", "png64": "https://...", "png128": "https://...", "png256": "https://..."
|
|
// }
|
|
// },
|
|
// "visibility": "PUBLIC",
|
|
// "message": ""
|
|
// },
|
|
// ]
|
|
//
|
|
var result interface{} = map[string]interface{} {}
|
|
for i := 0; IsLessThan(i, GetArrayLength(currencies)); i++ {
|
|
var currency interface{} = GetValue(currencies, i)
|
|
var id interface{} = this.SafeString(currency, "symbol")
|
|
var code interface{} = this.SafeCurrencyCode(id)
|
|
var networks interface{} = map[string]interface{} {}
|
|
var networksArray interface{} = this.SafeValue(currency, "networks", []interface{}{})
|
|
var networksLength interface{} = GetArrayLength(networksArray)
|
|
var isOneNetwork interface{} = (IsEqual(networksLength, 1))
|
|
var deposit interface{} = (IsEqual(this.SafeValue(currency, "depositStatus"), "OK"))
|
|
var withdrawal interface{} = (IsEqual(this.SafeValue(currency, "withdrawalStatus"), "OK"))
|
|
var active interface{} = IsTrue(deposit) && IsTrue(withdrawal)
|
|
var withdrawFee interface{} = this.SafeNumber(currency, "withdrawalFee")
|
|
var precision interface{} = this.SafeInteger(currency, "decimals", 8)
|
|
var minWithdraw interface{} = this.SafeNumber(currency, "withdrawalMinAmount")
|
|
// absolutely all of them have 1 network atm - ETH. So, we can reliably assign that inside networks
|
|
if IsTrue(isOneNetwork) {
|
|
var networkId interface{} = GetValue(networksArray, 0)
|
|
var networkCode interface{} = this.NetworkIdToCode(networkId)
|
|
AddElementToObject(networks, networkCode, map[string]interface{} {
|
|
"info": currency,
|
|
"id": networkId,
|
|
"network": networkCode,
|
|
"active": active,
|
|
"deposit": deposit,
|
|
"withdraw": withdrawal,
|
|
"fee": withdrawFee,
|
|
"precision": precision,
|
|
"limits": map[string]interface{} {
|
|
"withdraw": map[string]interface{} {
|
|
"min": minWithdraw,
|
|
"max": nil,
|
|
},
|
|
},
|
|
})
|
|
}
|
|
AddElementToObject(result, code, map[string]interface{} {
|
|
"info": currency,
|
|
"id": id,
|
|
"code": code,
|
|
"name": this.SafeString(currency, "name"),
|
|
"active": active,
|
|
"deposit": deposit,
|
|
"withdraw": withdrawal,
|
|
"networks": networks,
|
|
"fee": withdrawFee,
|
|
"precision": precision,
|
|
"limits": map[string]interface{} {
|
|
"amount": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"deposit": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"withdraw": map[string]interface{} {
|
|
"min": minWithdraw,
|
|
"max": nil,
|
|
},
|
|
},
|
|
})
|
|
}
|
|
// set currencies here to avoid calling publicGetAssets twice
|
|
this.Currencies = this.DeepExtend(this.Currencies, result)
|
|
return result
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchTicker
|
|
* @see https://docs.bitvavo.com/#tag/Market-Data/paths/~1ticker~124h/get
|
|
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
*/
|
|
func (this *bitvavo) FetchTicker(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes6418 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes6418)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"market": GetValue(market, "id"),
|
|
}
|
|
|
|
response:= (<-this.PublicGetTicker24h(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "market":"ETH-BTC",
|
|
// "open":"0.022578",
|
|
// "high":"0.023019",
|
|
// "low":"0.022572",
|
|
// "last":"0.023019",
|
|
// "volume":"25.16366324",
|
|
// "volumeQuote":"0.57333305",
|
|
// "bid":"0.023039",
|
|
// "bidSize":"0.53500578",
|
|
// "ask":"0.023041",
|
|
// "askSize":"0.47859202",
|
|
// "timestamp":1590381666900
|
|
// }
|
|
//
|
|
ch <- this.ParseTicker(response, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchTicker
|
|
//
|
|
// {
|
|
// "market":"ETH-BTC",
|
|
// "open":"0.022578",
|
|
// "high":"0.023019",
|
|
// "low":"0.022573",
|
|
// "last":"0.023019",
|
|
// "volume":"25.16366324",
|
|
// "volumeQuote":"0.57333305",
|
|
// "bid":"0.023039",
|
|
// "bidSize":"0.53500578",
|
|
// "ask":"0.023041",
|
|
// "askSize":"0.47859202",
|
|
// "timestamp":1590381666900
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var marketId interface{} = this.SafeString(ticker, "market")
|
|
var symbol interface{} = this.SafeSymbol(marketId, market, "-")
|
|
var timestamp interface{} = this.SafeInteger(ticker, "timestamp")
|
|
var last interface{} = this.SafeString(ticker, "last")
|
|
var baseVolume interface{} = this.SafeString(ticker, "volume")
|
|
var quoteVolume interface{} = this.SafeString(ticker, "volumeQuote")
|
|
var open interface{} = this.SafeString(ticker, "open")
|
|
return this.SafeTicker(map[string]interface{} {
|
|
"symbol": symbol,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"high": this.SafeString(ticker, "high"),
|
|
"low": this.SafeString(ticker, "low"),
|
|
"bid": this.SafeString(ticker, "bid"),
|
|
"bidVolume": this.SafeString(ticker, "bidSize"),
|
|
"ask": this.SafeString(ticker, "ask"),
|
|
"askVolume": this.SafeString(ticker, "askSize"),
|
|
"vwap": nil,
|
|
"open": open,
|
|
"close": last,
|
|
"last": last,
|
|
"previousClose": nil,
|
|
"change": nil,
|
|
"percentage": nil,
|
|
"average": nil,
|
|
"baseVolume": baseVolume,
|
|
"quoteVolume": quoteVolume,
|
|
"info": ticker,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchTickers
|
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
*/
|
|
func (this *bitvavo) FetchTickers(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbols := GetArg(optionalArgs, 0, nil)
|
|
_ = symbols
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes7258 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes7258)
|
|
|
|
response:= (<-this.PublicGetTicker24h(params))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "market":"ADA-BTC",
|
|
// "open":"0.0000059595",
|
|
// "high":"0.0000059765",
|
|
// "low":"0.0000059595",
|
|
// "last":"0.0000059765",
|
|
// "volume":"2923.172",
|
|
// "volumeQuote":"0.01743483",
|
|
// "bid":"0.0000059515",
|
|
// "bidSize":"1117.630919",
|
|
// "ask":"0.0000059585",
|
|
// "askSize":"809.999739",
|
|
// "timestamp":1590382266324
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseTickers(response, symbols)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchTrades
|
|
* @see https://docs.bitvavo.com/#tag/Market-Data/paths/~1{market}~1trades/get
|
|
* @description get the list of most recent trades for a particular symbol
|
|
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
* @param {int} [limit] the maximum amount of trades to fetch
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
*/
|
|
func (this *bitvavo) FetchTrades(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
since := GetArg(optionalArgs, 0, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 1, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes7628 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes7628)
|
|
var market interface{} = this.Market(symbol)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes76719 := (<-this.FetchPaginatedCallDynamic("fetchTrades", symbol, since, limit, params))
|
|
PanicOnError(retRes76719)
|
|
ch <- retRes76719
|
|
return nil
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"market": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", mathMin(limit, 1000))
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "start", since)
|
|
}
|
|
requestparamsVariable := this.HandleUntilOption("end", request, params);
|
|
request = GetValue(requestparamsVariable,0);
|
|
params = GetValue(requestparamsVariable,1)
|
|
|
|
response:= (<-this.PublicGetMarketTrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "id":"94154c98-6e8b-4e33-92a8-74e33fc05650",
|
|
// "timestamp":1590382761859,
|
|
// "amount":"0.06026079",
|
|
// "price":"8095.3",
|
|
// "side":"buy"
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseTrades(response, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchTrades (public)
|
|
//
|
|
// {
|
|
// "id":"94154c98-6e8b-4e33-92a8-74e33fc05650",
|
|
// "timestamp":1590382761859,
|
|
// "amount":"0.06026079",
|
|
// "price":"8095.3",
|
|
// "side":"buy"
|
|
// }
|
|
//
|
|
// createOrder, fetchOpenOrders, fetchOrders, editOrder (private)
|
|
//
|
|
// {
|
|
// "id":"b0c86aa5-6ed3-4a2d-ba3a-be9a964220f4",
|
|
// "timestamp":1590505649245,
|
|
// "amount":"0.249825",
|
|
// "price":"183.49",
|
|
// "taker":true,
|
|
// "fee":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "settled":true
|
|
// }
|
|
//
|
|
// fetchMyTrades (private)
|
|
//
|
|
// {
|
|
// "id":"b0c86aa5-6ed3-4a2d-ba3a-be9a964220f4",
|
|
// "orderId":"af76d6ce-9f7c-4006-b715-bb5d430652d0",
|
|
// "timestamp":1590505649245,
|
|
// "market":"ETH-EUR",
|
|
// "side":"sell",
|
|
// "amount":"0.249825",
|
|
// "price":"183.49",
|
|
// "taker":true,
|
|
// "fee":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "settled":true
|
|
// }
|
|
//
|
|
// watchMyTrades (private)
|
|
//
|
|
// {
|
|
// "event": "fill",
|
|
// "timestamp": 1590964470132,
|
|
// "market": "ETH-EUR",
|
|
// "orderId": "85d082e1-eda4-4209-9580-248281a29a9a",
|
|
// "fillId": "861d2da5-aa93-475c-8d9a-dce431bd4211",
|
|
// "side": "sell",
|
|
// "amount": "0.1",
|
|
// "price": "211.46",
|
|
// "taker": true,
|
|
// "fee": "0.056",
|
|
// "feeCurrency": "EUR"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var priceString interface{} = this.SafeString(trade, "price")
|
|
var amountString interface{} = this.SafeString(trade, "amount")
|
|
var timestamp interface{} = this.SafeInteger(trade, "timestamp")
|
|
var side interface{} = this.SafeString(trade, "side")
|
|
var id interface{} = this.SafeString2(trade, "id", "fillId")
|
|
var marketId interface{} = this.SafeString(trade, "market")
|
|
var symbol interface{} = this.SafeSymbol(marketId, market, "-")
|
|
var taker interface{} = this.SafeValue(trade, "taker")
|
|
var takerOrMaker interface{} = nil
|
|
if IsTrue(!IsEqual(taker, nil)) {
|
|
takerOrMaker = Ternary(IsTrue(taker), "taker", "maker")
|
|
}
|
|
var feeCostString interface{} = this.SafeString(trade, "fee")
|
|
var fee interface{} = nil
|
|
if IsTrue(!IsEqual(feeCostString, nil)) {
|
|
var feeCurrencyId interface{} = this.SafeString(trade, "feeCurrency")
|
|
var feeCurrencyCode interface{} = this.SafeCurrencyCode(feeCurrencyId)
|
|
fee = map[string]interface{} {
|
|
"cost": feeCostString,
|
|
"currency": feeCurrencyCode,
|
|
}
|
|
}
|
|
var orderId interface{} = this.SafeString(trade, "orderId")
|
|
return this.SafeTrade(map[string]interface{} {
|
|
"info": trade,
|
|
"id": id,
|
|
"symbol": symbol,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"order": orderId,
|
|
"type": nil,
|
|
"side": side,
|
|
"takerOrMaker": takerOrMaker,
|
|
"price": priceString,
|
|
"amount": amountString,
|
|
"cost": nil,
|
|
"fee": fee,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchTradingFees
|
|
* @see https://docs.bitvavo.com/#tag/Account/paths/~1account/get
|
|
* @description fetch the trading fees for multiple markets
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
|
|
*/
|
|
func (this *bitvavo) FetchTradingFees(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes9058 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes9058)
|
|
|
|
response:= (<-this.PrivateGetAccount(params))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "fees": {
|
|
// "taker": "0.0025",
|
|
// "maker": "0.0015",
|
|
// "volume": "10000.00"
|
|
// }
|
|
// }
|
|
//
|
|
ch <- this.ParseTradingFees(response)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) ParseTradingFees(fees interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "fees": {
|
|
// "taker": "0.0025",
|
|
// "maker": "0.0015",
|
|
// "volume": "10000.00"
|
|
// }
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var feesValue interface{} = this.SafeValue(fees, "fees")
|
|
var maker interface{} = this.SafeNumber(feesValue, "maker")
|
|
var taker interface{} = this.SafeNumber(feesValue, "taker")
|
|
var result interface{} = map[string]interface{} {}
|
|
for i := 0; IsLessThan(i, GetArrayLength(this.Symbols)); i++ {
|
|
var symbol interface{} = GetValue(this.Symbols, i)
|
|
AddElementToObject(result, symbol, map[string]interface{} {
|
|
"info": fees,
|
|
"symbol": symbol,
|
|
"maker": maker,
|
|
"taker": taker,
|
|
"percentage": true,
|
|
"tierBased": true,
|
|
})
|
|
}
|
|
return result
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchOrderBook
|
|
* @see https://docs.bitvavo.com/#tag/Market-Data/paths/~1{market}~1book/get
|
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
* @param {int} [limit] the maximum amount of order book entries to return
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
*/
|
|
func (this *bitvavo) FetchOrderBook(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
limit := GetArg(optionalArgs, 0, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes9588 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes9588)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"market": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "depth", limit)
|
|
}
|
|
|
|
response:= (<-this.PublicGetMarketBook(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "market":"BTC-EUR",
|
|
// "nonce":35883831,
|
|
// "bids":[
|
|
// ["8097.4","0.6229099"],
|
|
// ["8097.2","0.64151283"],
|
|
// ["8097.1","0.24966294"],
|
|
// ],
|
|
// "asks":[
|
|
// ["8097.5","1.36916911"],
|
|
// ["8098.8","0.33462248"],
|
|
// ["8099.3","1.12908646"],
|
|
// ]
|
|
// }
|
|
//
|
|
var orderbook interface{} = this.ParseOrderBook(response, GetValue(market, "symbol"))
|
|
AddElementToObject(orderbook, "nonce", this.SafeInteger(response, "nonce"))
|
|
|
|
ch <- orderbook
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// [
|
|
// 1590383700000,
|
|
// "8088.5",
|
|
// "8088.5",
|
|
// "8088.5",
|
|
// "8088.5",
|
|
// "0.04788623"
|
|
// ]
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
return []interface{}{this.SafeInteger(ohlcv, 0), this.SafeNumber(ohlcv, 1), this.SafeNumber(ohlcv, 2), this.SafeNumber(ohlcv, 3), this.SafeNumber(ohlcv, 4), this.SafeNumber(ohlcv, 5)}
|
|
}
|
|
func (this *bitvavo) FetchOHLCVRequest(symbol interface{}, optionalArgs ...interface{}) interface{} {
|
|
timeframe := GetArg(optionalArgs, 0, "1m")
|
|
_ = timeframe
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"market": GetValue(market, "id"),
|
|
"interval": this.SafeString(this.Timeframes, timeframe, timeframe),
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
// https://github.com/ccxt/ccxt/issues/9227
|
|
var duration interface{} = this.ParseTimeframe(timeframe)
|
|
AddElementToObject(request, "start", since)
|
|
if IsTrue(IsEqual(limit, nil)) {
|
|
limit = 1440
|
|
} else {
|
|
limit = mathMin(limit, 1440)
|
|
}
|
|
AddElementToObject(request, "end", this.Sum(since, Multiply(Multiply(limit, duration), 1000)))
|
|
}
|
|
requestparamsVariable := this.HandleUntilOption("end", request, params);
|
|
request = GetValue(requestparamsVariable,0);
|
|
params = GetValue(requestparamsVariable,1)
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit) // default 1440, max 1440
|
|
}
|
|
return this.Extend(request, params)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchOHLCV
|
|
* @see https://docs.bitvavo.com/#tag/Market-Data/paths/~1{market}~1candles/get
|
|
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
* @param {string} timeframe the length of time each candle represents
|
|
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
* @param {int} [limit] the maximum amount of candles to fetch
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
*/
|
|
func (this *bitvavo) FetchOHLCV(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
timeframe := GetArg(optionalArgs, 0, "1m")
|
|
_ = timeframe
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes10518 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes10518)
|
|
var market interface{} = this.Market(symbol)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes105619 := (<-this.FetchPaginatedCallDeterministic("fetchOHLCV", symbol, since, limit, timeframe, params, 1440))
|
|
PanicOnError(retRes105619)
|
|
ch <- retRes105619
|
|
return nil
|
|
}
|
|
var request interface{} = this.FetchOHLCVRequest(symbol, timeframe, since, limit, params)
|
|
|
|
response:= (<-this.PublicGetMarketCandles(request))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// [1590383700000,"8088.5","8088.5","8088.5","8088.5","0.04788623"],
|
|
// [1590383580000,"8091.3","8091.5","8091.3","8091.5","0.04931221"],
|
|
// [1590383520000,"8090.3","8092.7","8090.3","8092.5","0.04001286"],
|
|
// ]
|
|
//
|
|
ch <- this.ParseOHLCVs(response, market, timeframe, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) ParseBalance(response interface{}) interface{} {
|
|
var result interface{} = map[string]interface{} {
|
|
"info": response,
|
|
"timestamp": nil,
|
|
"datetime": nil,
|
|
}
|
|
for i := 0; IsLessThan(i, GetArrayLength(response)); i++ {
|
|
var balance interface{} = GetValue(response, i)
|
|
var currencyId interface{} = this.SafeString(balance, "symbol")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
|
var account interface{} = this.Account()
|
|
AddElementToObject(account, "free", this.SafeString(balance, "available"))
|
|
AddElementToObject(account, "used", this.SafeString(balance, "inOrder"))
|
|
AddElementToObject(result, code, account)
|
|
}
|
|
return this.SafeBalance(result)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchBalance
|
|
* @see https://docs.bitvavo.com/#tag/Account/paths/~1balance/get
|
|
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
*/
|
|
func (this *bitvavo) FetchBalance(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes10978 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes10978)
|
|
|
|
response:= (<-this.PrivateGetBalance(params))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol": "BTC",
|
|
// "available": "1.57593193",
|
|
// "inOrder": "0.74832374"
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseBalance(response)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchDepositAddress
|
|
* @description fetch the deposit address for a currency associated with this account
|
|
* @param {string} code unified currency code
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
*/
|
|
func (this *bitvavo) FetchDepositAddress(code interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes11208 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes11208)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(currency, "id"),
|
|
}
|
|
|
|
response:= (<-this.PrivateGetDeposit(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "address": "0x449889e3234514c45d57f7c5a571feba0c7ad567",
|
|
// "paymentId": "10002653"
|
|
// }
|
|
//
|
|
var address interface{} = this.SafeString(response, "address")
|
|
var tag interface{} = this.SafeString(response, "paymentId")
|
|
this.CheckAddress(address)
|
|
|
|
ch <- map[string]interface{} {
|
|
"info": response,
|
|
"currency": code,
|
|
"network": nil,
|
|
"address": address,
|
|
"tag": tag,
|
|
}
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) CreateOrderRequest(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) interface{} {
|
|
price := GetArg(optionalArgs, 0, nil)
|
|
_ = price
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"market": GetValue(market, "id"),
|
|
"side": side,
|
|
"orderType": typeVar,
|
|
}
|
|
var isMarketOrder interface{} = IsTrue(IsTrue((IsEqual(typeVar, "market"))) || IsTrue((IsEqual(typeVar, "stopLoss")))) || IsTrue((IsEqual(typeVar, "takeProfit")))
|
|
var isLimitOrder interface{} = IsTrue(IsTrue((IsEqual(typeVar, "limit"))) || IsTrue((IsEqual(typeVar, "stopLossLimit")))) || IsTrue((IsEqual(typeVar, "takeProfitLimit")))
|
|
var timeInForce interface{} = this.SafeString(params, "timeInForce")
|
|
var triggerPrice interface{} = this.SafeStringN(params, []interface{}{"triggerPrice", "stopPrice", "triggerAmount"})
|
|
var postOnly interface{} = this.IsPostOnly(isMarketOrder, false, params)
|
|
var stopLossPrice interface{} = this.SafeValue(params, "stopLossPrice") // trigger when price crosses from above to below this value
|
|
var takeProfitPrice interface{} = this.SafeValue(params, "takeProfitPrice") // trigger when price crosses from below to above this value
|
|
params = this.Omit(params, []interface{}{"timeInForce", "triggerPrice", "stopPrice", "stopLossPrice", "takeProfitPrice"})
|
|
if IsTrue(isMarketOrder) {
|
|
var cost interface{} = nil
|
|
if IsTrue(!IsEqual(price, nil)) {
|
|
var priceString interface{} = this.NumberToString(price)
|
|
var amountString interface{} = this.NumberToString(amount)
|
|
var quoteAmount interface{} = Precise.StringMul(amountString, priceString)
|
|
cost = this.ParseNumber(quoteAmount)
|
|
} else {
|
|
cost = this.SafeNumber(params, "cost")
|
|
}
|
|
if IsTrue(!IsEqual(cost, nil)) {
|
|
var precision interface{} = GetValue(this.Currency(GetValue(market, "quote")), "precision")
|
|
AddElementToObject(request, "amountQuote", this.DecimalToPrecision(cost, TRUNCATE, precision, this.PrecisionMode))
|
|
} else {
|
|
AddElementToObject(request, "amount", this.AmountToPrecision(symbol, amount))
|
|
}
|
|
params = this.Omit(params, []interface{}{"cost"})
|
|
} else if IsTrue(isLimitOrder) {
|
|
AddElementToObject(request, "price", this.PriceToPrecision(symbol, price))
|
|
AddElementToObject(request, "amount", this.AmountToPrecision(symbol, amount))
|
|
}
|
|
var isTakeProfit interface{} = IsTrue(IsTrue((!IsEqual(takeProfitPrice, nil))) || IsTrue((IsEqual(typeVar, "takeProfit")))) || IsTrue((IsEqual(typeVar, "takeProfitLimit")))
|
|
var isStopLoss interface{} = IsTrue(IsTrue(IsTrue((!IsEqual(stopLossPrice, nil))) || IsTrue(IsTrue((!IsEqual(triggerPrice, nil))) && IsTrue((!IsTrue(isTakeProfit))))) || IsTrue((IsEqual(typeVar, "stopLoss")))) || IsTrue((IsEqual(typeVar, "stopLossLimit")))
|
|
if IsTrue(isStopLoss) {
|
|
if IsTrue(!IsEqual(stopLossPrice, nil)) {
|
|
triggerPrice = stopLossPrice
|
|
}
|
|
AddElementToObject(request, "orderType", Ternary(IsTrue(isMarketOrder), "stopLoss", "stopLossLimit"))
|
|
} else if IsTrue(isTakeProfit) {
|
|
if IsTrue(!IsEqual(takeProfitPrice, nil)) {
|
|
triggerPrice = takeProfitPrice
|
|
}
|
|
AddElementToObject(request, "orderType", Ternary(IsTrue(isMarketOrder), "takeProfit", "takeProfitLimit"))
|
|
}
|
|
if IsTrue(!IsEqual(triggerPrice, nil)) {
|
|
AddElementToObject(request, "triggerAmount", this.PriceToPrecision(symbol, triggerPrice))
|
|
AddElementToObject(request, "triggerType", "price")
|
|
AddElementToObject(request, "triggerReference", "lastTrade") // 'bestBid', 'bestAsk', 'midPrice'
|
|
}
|
|
if IsTrue(IsTrue((!IsEqual(timeInForce, nil))) && IsTrue((!IsEqual(timeInForce, "PO")))) {
|
|
AddElementToObject(request, "timeInForce", timeInForce)
|
|
}
|
|
if IsTrue(postOnly) {
|
|
AddElementToObject(request, "postOnly", true)
|
|
}
|
|
return this.Extend(request, params)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#createOrder
|
|
* @description create a trade order
|
|
* @see https://docs.bitvavo.com/#tag/Trading-endpoints/paths/~1order/post
|
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
* @param {string} type 'market' or 'limit'
|
|
* @param {string} side 'buy' or 'sell'
|
|
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
* @param {float} price the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
* @param {object} [params] extra parameters specific to the bitvavo api endpoint
|
|
* @param {string} [params.timeInForce] "GTC", "IOC", or "PO"
|
|
* @param {float} [params.stopPrice] Alias for triggerPrice
|
|
* @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
|
|
* @param {bool} [params.postOnly] If true, the order will only be posted to the order book and not executed immediately
|
|
* @param {float} [params.stopLossPrice] The price at which a stop loss order is triggered at
|
|
* @param {float} [params.takeProfitPrice] The price at which a take profit order is triggered at
|
|
* @param {string} [params.triggerType] "price"
|
|
* @param {string} [params.triggerReference] "lastTrade", "bestBid", "bestAsk", "midPrice" Only for stop orders: Use this to determine which parameter will trigger the order
|
|
* @param {string} [params.selfTradePrevention] "decrementAndCancel", "cancelOldest", "cancelNewest", "cancelBoth"
|
|
* @param {bool} [params.disableMarketProtection] don't cancel if the next fill price is 10% worse than the best fill price
|
|
* @param {bool} [params.responseRequired] Set this to 'false' when only an acknowledgement of success or failure is required, this is faster.
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitvavo) CreateOrder(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
price := GetArg(optionalArgs, 0, nil)
|
|
_ = price
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes12328 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes12328)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = this.CreateOrderRequest(symbol, typeVar, side, amount, price, params)
|
|
|
|
response:= (<-this.PrivatePostOrder(request))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "orderId":"dec6a640-5b4c-45bc-8d22-3b41c6716630",
|
|
// "market":"DOGE-EUR",
|
|
// "created":1654789135146,
|
|
// "updated":1654789135153,
|
|
// "status":"new",
|
|
// "side":"buy",
|
|
// "orderType":"stopLossLimit",
|
|
// "amount":"200",
|
|
// "amountRemaining":"200",
|
|
// "price":"0.07471",
|
|
// "triggerPrice":"0.0747",
|
|
// "triggerAmount":"0.0747",
|
|
// "triggerType":"price",
|
|
// "triggerReference":"lastTrade",
|
|
// "onHold":"14.98",
|
|
// "onHoldCurrency":"EUR",
|
|
// "filledAmount":"0",
|
|
// "filledAmountQuote":"0",
|
|
// "feePaid":"0",
|
|
// "feeCurrency":"EUR",
|
|
// "fills":[ // filled with market orders only
|
|
// {
|
|
// "id":"b0c86aa5-6ed3-4a2d-ba3a-be9a964220f4",
|
|
// "timestamp":1590505649245,
|
|
// "amount":"0.249825",
|
|
// "price":"183.49",
|
|
// "taker":true,
|
|
// "fee":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "settled":true
|
|
// }
|
|
// ],
|
|
// "selfTradePrevention":"decrementAndCancel",
|
|
// "visible":true,
|
|
// "timeInForce":"GTC",
|
|
// "postOnly":false
|
|
// }
|
|
//
|
|
ch <- this.ParseOrder(response, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) EditOrderRequest(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) interface{} {
|
|
amount := GetArg(optionalArgs, 0, nil)
|
|
_ = amount
|
|
price := GetArg(optionalArgs, 1, nil)
|
|
_ = price
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
var request interface{} = map[string]interface{} {}
|
|
var market interface{} = this.Market(symbol)
|
|
var amountRemaining interface{} = this.SafeNumber(params, "amountRemaining")
|
|
var triggerPrice interface{} = this.SafeStringN(params, []interface{}{"triggerPrice", "stopPrice", "triggerAmount"})
|
|
params = this.Omit(params, []interface{}{"amountRemaining", "triggerPrice", "stopPrice", "triggerAmount"})
|
|
if IsTrue(!IsEqual(price, nil)) {
|
|
AddElementToObject(request, "price", this.PriceToPrecision(symbol, price))
|
|
}
|
|
if IsTrue(!IsEqual(amount, nil)) {
|
|
AddElementToObject(request, "amount", this.AmountToPrecision(symbol, amount))
|
|
}
|
|
if IsTrue(!IsEqual(amountRemaining, nil)) {
|
|
AddElementToObject(request, "amountRemaining", this.AmountToPrecision(symbol, amountRemaining))
|
|
}
|
|
if IsTrue(!IsEqual(triggerPrice, nil)) {
|
|
AddElementToObject(request, "triggerAmount", this.PriceToPrecision(symbol, triggerPrice))
|
|
}
|
|
request = this.Extend(request, params)
|
|
if IsTrue(this.IsEmpty(request)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " editOrder() requires an amount argument, or a price argument, or non-empty params")))
|
|
}
|
|
var clientOrderId interface{} = this.SafeString(params, "clientOrderId")
|
|
if IsTrue(IsEqual(clientOrderId, nil)) {
|
|
AddElementToObject(request, "orderId", id)
|
|
}
|
|
AddElementToObject(request, "market", GetValue(market, "id"))
|
|
return request
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#editOrder
|
|
* @description edit a trade order
|
|
* @see https://docs.bitvavo.com/#tag/Orders/paths/~1order/put
|
|
* @param {string} id cancel order id
|
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
* @param {string} type 'market' or 'limit'
|
|
* @param {string} side 'buy' or 'sell'
|
|
* @param {float} [amount] how much of currency you want to trade in units of base currency
|
|
* @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
* @param {object} [params] extra parameters specific to the bitvavo api endpoint
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitvavo) EditOrder(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
amount := GetArg(optionalArgs, 0, nil)
|
|
_ = amount
|
|
price := GetArg(optionalArgs, 1, nil)
|
|
_ = price
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes13248 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes13248)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = this.EditOrderRequest(id, symbol, typeVar, side, amount, price, params)
|
|
|
|
response:= (<-this.PrivatePutOrder(request))
|
|
PanicOnError(response)
|
|
|
|
ch <- this.ParseOrder(response, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) CancelOrderRequest(id interface{}, optionalArgs ...interface{}) interface{} {
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " cancelOrder() requires a symbol argument")))
|
|
}
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"market": GetValue(market, "id"),
|
|
}
|
|
var clientOrderId interface{} = this.SafeString(params, "clientOrderId")
|
|
if IsTrue(IsEqual(clientOrderId, nil)) {
|
|
AddElementToObject(request, "orderId", id)
|
|
}
|
|
return this.Extend(request, params)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#cancelOrder
|
|
* @see https://docs.bitvavo.com/#tag/Orders/paths/~1order/delete
|
|
* @description cancels an open order
|
|
* @see https://docs.bitvavo.com/#tag/Trading-endpoints/paths/~1order/delete
|
|
* @param {string} id order id
|
|
* @param {string} symbol unified symbol of the market the order was made in
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitvavo) CancelOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes13588 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes13588)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = this.CancelOrderRequest(id, symbol, params)
|
|
|
|
response:= (<-this.PrivateDeleteOrder(request))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "orderId": "2e7ce7fc-44e2-4d80-a4a7-d079c4750b61"
|
|
// }
|
|
//
|
|
ch <- this.ParseOrder(response, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#cancelAllOrders
|
|
* @see https://docs.bitvavo.com/#tag/Orders/paths/~1orders/delete
|
|
* @description cancel all open orders
|
|
* @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitvavo) CancelAllOrders(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes13808 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes13808)
|
|
var request interface{} = map[string]interface{} {}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "market", GetValue(market, "id"))
|
|
}
|
|
|
|
response:= (<-this.PrivateDeleteOrders(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "orderId": "1be6d0df-d5dc-4b53-a250-3376f3b393e6"
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseOrders(response, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchOrder
|
|
* @description fetches information on an order made by the user
|
|
* @see https://docs.bitvavo.com/#tag/Trading-endpoints/paths/~1order/get
|
|
* @param {string} id the order id
|
|
* @param {string} symbol unified symbol of the market the order was made in
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitvavo) FetchOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOrder() requires a symbol argument")))
|
|
}
|
|
|
|
retRes14128 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes14128)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"market": GetValue(market, "id"),
|
|
}
|
|
var clientOrderId interface{} = this.SafeString(params, "clientOrderId")
|
|
if IsTrue(IsEqual(clientOrderId, nil)) {
|
|
AddElementToObject(request, "orderId", id)
|
|
}
|
|
|
|
response:= (<-this.PrivateGetOrder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "orderId":"af76d6ce-9f7c-4006-b715-bb5d430652d0",
|
|
// "market":"ETH-EUR",
|
|
// "created":1590505649241,
|
|
// "updated":1590505649241,
|
|
// "status":"filled",
|
|
// "side":"sell",
|
|
// "orderType":"market",
|
|
// "amount":"0.249825",
|
|
// "amountRemaining":"0",
|
|
// "onHold":"0",
|
|
// "onHoldCurrency":"ETH",
|
|
// "filledAmount":"0.249825",
|
|
// "filledAmountQuote":"45.84038925",
|
|
// "feePaid":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "fills":[
|
|
// {
|
|
// "id":"b0c86aa5-6ed3-4a2d-ba3a-be9a964220f4",
|
|
// "timestamp":1590505649245,
|
|
// "amount":"0.249825",
|
|
// "price":"183.49",
|
|
// "taker":true,
|
|
// "fee":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "settled":true
|
|
// }
|
|
// ],
|
|
// "selfTradePrevention":"decrementAndCancel",
|
|
// "visible":false,
|
|
// "disableMarketProtection":false
|
|
// }
|
|
//
|
|
ch <- this.ParseOrder(response, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) FetchOrdersRequest(optionalArgs ...interface{}) interface{} {
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"market": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "start", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit) // default 500, max 1000
|
|
}
|
|
requestparamsVariable := this.HandleUntilOption("end", request, params);
|
|
request = GetValue(requestparamsVariable,0);
|
|
params = GetValue(requestparamsVariable,1)
|
|
return this.Extend(request, params)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchOrders
|
|
* @see https://docs.bitvavo.com/#tag/Trading-endpoints/paths/~1orders/get
|
|
* @description fetches information on multiple orders made by the user
|
|
* @param {string} symbol unified market symbol of the market orders were made in
|
|
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitvavo) FetchOrders(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOrders() requires a symbol argument")))
|
|
}
|
|
|
|
retRes14968 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes14968)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOrders", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes150019 := (<-this.FetchPaginatedCallDynamic("fetchOrders", symbol, since, limit, params))
|
|
PanicOnError(retRes150019)
|
|
ch <- retRes150019
|
|
return nil
|
|
}
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = this.FetchOrdersRequest(symbol, since, limit, params)
|
|
|
|
response:= (<-this.PrivateGetOrders(request))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "orderId":"af76d6ce-9f7c-4006-b715-bb5d430652d0",
|
|
// "market":"ETH-EUR",
|
|
// "created":1590505649241,
|
|
// "updated":1590505649241,
|
|
// "status":"filled",
|
|
// "side":"sell",
|
|
// "orderType":"market",
|
|
// "amount":"0.249825",
|
|
// "amountRemaining":"0",
|
|
// "onHold":"0",
|
|
// "onHoldCurrency":"ETH",
|
|
// "filledAmount":"0.249825",
|
|
// "filledAmountQuote":"45.84038925",
|
|
// "feePaid":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "fills":[
|
|
// {
|
|
// "id":"b0c86aa5-6ed3-4a2d-ba3a-be9a964220f4",
|
|
// "timestamp":1590505649245,
|
|
// "amount":"0.249825",
|
|
// "price":"183.49",
|
|
// "taker":true,
|
|
// "fee":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "settled":true
|
|
// }
|
|
// ],
|
|
// "selfTradePrevention":"decrementAndCancel",
|
|
// "visible":false,
|
|
// "disableMarketProtection":false
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseOrders(response, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchOpenOrders
|
|
* @see https://docs.bitvavo.com/#tag/Trading-endpoints/paths/~1ordersOpen/get
|
|
* @description fetch all unfilled currently open orders
|
|
* @param {string} symbol unified market symbol
|
|
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitvavo) FetchOpenOrders(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes15568 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes15568)
|
|
var request interface{} = map[string]interface{} {}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "market", GetValue(market, "id"))
|
|
}
|
|
|
|
response:= (<-this.PrivateGetOrdersOpen(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "orderId":"af76d6ce-9f7c-4006-b715-bb5d430652d0",
|
|
// "market":"ETH-EUR",
|
|
// "created":1590505649241,
|
|
// "updated":1590505649241,
|
|
// "status":"filled",
|
|
// "side":"sell",
|
|
// "orderType":"market",
|
|
// "amount":"0.249825",
|
|
// "amountRemaining":"0",
|
|
// "onHold":"0",
|
|
// "onHoldCurrency":"ETH",
|
|
// "filledAmount":"0.249825",
|
|
// "filledAmountQuote":"45.84038925",
|
|
// "feePaid":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "fills":[
|
|
// {
|
|
// "id":"b0c86aa5-6ed3-4a2d-ba3a-be9a964220f4",
|
|
// "timestamp":1590505649245,
|
|
// "amount":"0.249825",
|
|
// "price":"183.49",
|
|
// "taker":true,
|
|
// "fee":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "settled":true
|
|
// }
|
|
// ],
|
|
// "selfTradePrevention":"decrementAndCancel",
|
|
// "visible":false,
|
|
// "disableMarketProtection":false
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseOrders(response, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) ParseOrderStatus(status interface{}) interface{} {
|
|
var statuses interface{} = map[string]interface{} {
|
|
"new": "open",
|
|
"canceled": "canceled",
|
|
"canceledAuction": "canceled",
|
|
"canceledSelfTradePrevention": "canceled",
|
|
"canceledIOC": "canceled",
|
|
"canceledFOK": "canceled",
|
|
"canceledMarketProtection": "canceled",
|
|
"canceledPostOnly": "canceled",
|
|
"filled": "closed",
|
|
"partiallyFilled": "open",
|
|
"expired": "canceled",
|
|
"rejected": "canceled",
|
|
"awaitingTrigger": "open",
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *bitvavo) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// cancelOrder, cancelAllOrders
|
|
//
|
|
// {
|
|
// "orderId": "2e7ce7fc-44e2-4d80-a4a7-d079c4750b61"
|
|
// }
|
|
//
|
|
// createOrder, fetchOrder, fetchOpenOrders, fetchOrders, editOrder
|
|
//
|
|
// {
|
|
// "orderId":"af76d6ce-9f7c-4006-b715-bb5d430652d0",
|
|
// "market":"ETH-EUR",
|
|
// "created":1590505649241,
|
|
// "updated":1590505649241,
|
|
// "status":"filled",
|
|
// "side":"sell",
|
|
// "orderType":"market",
|
|
// "amount":"0.249825",
|
|
// "amountRemaining":"0",
|
|
// "price": "183.49", // limit orders only
|
|
// "onHold":"0",
|
|
// "onHoldCurrency":"ETH",
|
|
// "filledAmount":"0.249825",
|
|
// "filledAmountQuote":"45.84038925",
|
|
// "feePaid":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "fills":[
|
|
// {
|
|
// "id":"b0c86aa5-6ed3-4a2d-ba3a-be9a964220f4",
|
|
// "timestamp":1590505649245,
|
|
// "amount":"0.249825",
|
|
// "price":"183.49",
|
|
// "taker":true,
|
|
// "fee":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "settled":true
|
|
// }
|
|
// ],
|
|
// "selfTradePrevention":"decrementAndCancel",
|
|
// "visible":false,
|
|
// "disableMarketProtection":false
|
|
// "timeInForce": "GTC",
|
|
// "postOnly": true,
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var id interface{} = this.SafeString(order, "orderId")
|
|
var timestamp interface{} = this.SafeInteger(order, "created")
|
|
var marketId interface{} = this.SafeString(order, "market")
|
|
market = this.SafeMarket(marketId, market, "-")
|
|
var symbol interface{} = GetValue(market, "symbol")
|
|
var status interface{} = this.ParseOrderStatus(this.SafeString(order, "status"))
|
|
var side interface{} = this.SafeString(order, "side")
|
|
var typeVar interface{} = this.SafeString(order, "orderType")
|
|
var price interface{} = this.SafeString(order, "price")
|
|
var amount interface{} = this.SafeString(order, "amount")
|
|
var remaining interface{} = this.SafeString(order, "amountRemaining")
|
|
var filled interface{} = this.SafeString(order, "filledAmount")
|
|
var cost interface{} = this.SafeString(order, "filledAmountQuote")
|
|
if IsTrue(IsEqual(cost, nil)) {
|
|
var amountQuote interface{} = this.SafeString(order, "amountQuote")
|
|
var amountQuoteRemaining interface{} = this.SafeString(order, "amountQuoteRemaining")
|
|
cost = Precise.StringSub(amountQuote, amountQuoteRemaining)
|
|
}
|
|
var fee interface{} = nil
|
|
var feeCost interface{} = this.SafeNumber(order, "feePaid")
|
|
if IsTrue(!IsEqual(feeCost, nil)) {
|
|
var feeCurrencyId interface{} = this.SafeString(order, "feeCurrency")
|
|
var feeCurrencyCode interface{} = this.SafeCurrencyCode(feeCurrencyId)
|
|
fee = map[string]interface{} {
|
|
"cost": feeCost,
|
|
"currency": feeCurrencyCode,
|
|
}
|
|
}
|
|
var rawTrades interface{} = this.SafeValue(order, "fills", []interface{}{})
|
|
var timeInForce interface{} = this.SafeString(order, "timeInForce")
|
|
var postOnly interface{} = this.SafeValue(order, "postOnly")
|
|
// https://github.com/ccxt/ccxt/issues/8489
|
|
return this.SafeOrder(map[string]interface{} {
|
|
"info": order,
|
|
"id": id,
|
|
"clientOrderId": nil,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"lastTradeTimestamp": nil,
|
|
"symbol": symbol,
|
|
"type": typeVar,
|
|
"timeInForce": timeInForce,
|
|
"postOnly": postOnly,
|
|
"side": side,
|
|
"price": price,
|
|
"triggerPrice": this.SafeNumber(order, "triggerPrice"),
|
|
"amount": amount,
|
|
"cost": cost,
|
|
"average": nil,
|
|
"filled": filled,
|
|
"remaining": remaining,
|
|
"status": status,
|
|
"fee": fee,
|
|
"trades": rawTrades,
|
|
}, market)
|
|
}
|
|
func (this *bitvavo) FetchMyTradesRequest(optionalArgs ...interface{}) interface{} {
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"market": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "start", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit) // default 500, max 1000
|
|
}
|
|
requestparamsVariable := this.HandleUntilOption("end", request, params);
|
|
request = GetValue(requestparamsVariable,0);
|
|
params = GetValue(requestparamsVariable,1)
|
|
return this.Extend(request, params)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchMyTrades
|
|
* @see https://docs.bitvavo.com/#tag/Trading-endpoints/paths/~1trades/get
|
|
* @description fetch all trades made by the user
|
|
* @param {string} symbol unified market symbol
|
|
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
*/
|
|
func (this *bitvavo) FetchMyTrades(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchMyTrades() requires a symbol argument")))
|
|
}
|
|
|
|
retRes17648 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes17648)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchMyTrades", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes176819 := (<-this.FetchPaginatedCallDynamic("fetchMyTrades", symbol, since, limit, params))
|
|
PanicOnError(retRes176819)
|
|
ch <- retRes176819
|
|
return nil
|
|
}
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = this.FetchMyTradesRequest(symbol, since, limit, params)
|
|
|
|
response:= (<-this.PrivateGetTrades(request))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "id":"b0c86aa5-6ed3-4a2d-ba3a-be9a964220f4",
|
|
// "orderId":"af76d6ce-9f7c-4006-b715-bb5d430652d0",
|
|
// "timestamp":1590505649245,
|
|
// "market":"ETH-EUR",
|
|
// "side":"sell",
|
|
// "amount":"0.249825",
|
|
// "price":"183.49",
|
|
// "taker":true,
|
|
// "fee":"0.12038925",
|
|
// "feeCurrency":"EUR",
|
|
// "settled":true
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseTrades(response, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) WithdrawRequest(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) interface{} {
|
|
tag := GetArg(optionalArgs, 0, nil)
|
|
_ = tag
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(currency, "id"),
|
|
"amount": this.CurrencyToPrecision(code, amount),
|
|
"address": address,
|
|
}
|
|
if IsTrue(!IsEqual(tag, nil)) {
|
|
AddElementToObject(request, "paymentId", tag)
|
|
}
|
|
return this.Extend(request, params)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#withdraw
|
|
* @description make a withdrawal
|
|
* @param {string} code unified currency code
|
|
* @param {float} amount the amount to withdraw
|
|
* @param {string} address the address to withdraw to
|
|
* @param {string} tag
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *bitvavo) Withdraw(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
tag := GetArg(optionalArgs, 0, nil)
|
|
_ = tag
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
tagparamsVariable := this.HandleWithdrawTagAndParams(tag, params);
|
|
tag = GetValue(tagparamsVariable,0);
|
|
params = GetValue(tagparamsVariable,1)
|
|
this.CheckAddress(address)
|
|
|
|
retRes18228 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes18228)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = this.WithdrawRequest(code, amount, address, tag, params)
|
|
|
|
response:= (<-this.PrivatePostWithdrawal(request))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "success": true,
|
|
// "symbol": "BTC",
|
|
// "amount": "1.5"
|
|
// }
|
|
//
|
|
ch <- this.ParseTransaction(response, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) FetchWithdrawalsRequest(optionalArgs ...interface{}) interface{} {
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
var request interface{} = map[string]interface{} {}
|
|
var currency interface{} = nil
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
AddElementToObject(request, "symbol", GetValue(currency, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "start", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit) // default 500, max 1000
|
|
}
|
|
return this.Extend(request, params)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchWithdrawals
|
|
* @see https://docs.bitvavo.com/#tag/Account/paths/~1withdrawalHistory/get
|
|
* @description fetch all withdrawals made from an account
|
|
* @param {string} code unified currency code
|
|
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the bitvavo api endpoint
|
|
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *bitvavo) FetchWithdrawals(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes18698 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes18698)
|
|
var request interface{} = this.FetchWithdrawalsRequest(code, since, limit, params)
|
|
var currency interface{} = nil
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
}
|
|
|
|
response:= (<-this.PrivateGetWithdrawalHistory(request))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "timestamp":1590531212000,
|
|
// "symbol":"ETH",
|
|
// "amount":"0.091",
|
|
// "fee":"0.009",
|
|
// "status":"awaiting_bitvavo_inspection",
|
|
// "address":"0xe42b309f1eE9F0cbf7f54CcF3bc2159eBfA6735b",
|
|
// "paymentId": "10002653",
|
|
// "txId": "927b3ea50c5bb52c6854152d305dfa1e27fc01d10464cf10825d96d69d235eb3",
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseTransactions(response, currency, since, limit, map[string]interface{} {
|
|
"type": "withdrawal",
|
|
})
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) FetchDepositsRequest(optionalArgs ...interface{}) interface{} {
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
var request interface{} = map[string]interface{} {}
|
|
var currency interface{} = nil
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
AddElementToObject(request, "symbol", GetValue(currency, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "start", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit) // default 500, max 1000
|
|
}
|
|
return this.Extend(request, params)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchDeposits
|
|
* @see https://docs.bitvavo.com/#tag/Account/paths/~1depositHistory/get
|
|
* @description fetch all deposits made to an account
|
|
* @param {string} code unified currency code
|
|
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the bitvavo api endpoint
|
|
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *bitvavo) FetchDeposits(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes19268 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes19268)
|
|
var request interface{} = this.FetchDepositsRequest(code, since, limit, params)
|
|
var currency interface{} = nil
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
}
|
|
|
|
response:= (<-this.PrivateGetDepositHistory(request))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "timestamp":1590492401000,
|
|
// "symbol":"ETH",
|
|
// "amount":"0.249825",
|
|
// "fee":"0",
|
|
// "status":"completed",
|
|
// "txId":"0x5167b473fd37811f9ef22364c3d54726a859ef9d98934b3a1e11d7baa8d2c2e2"
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseTransactions(response, currency, since, limit, map[string]interface{} {
|
|
"type": "deposit",
|
|
})
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) ParseTransactionStatus(status interface{}) interface{} {
|
|
var statuses interface{} = map[string]interface{} {
|
|
"awaiting_processing": "pending",
|
|
"awaiting_email_confirmation": "pending",
|
|
"awaiting_bitvavo_inspection": "pending",
|
|
"approved": "pending",
|
|
"sending": "pending",
|
|
"in_mempool": "pending",
|
|
"processed": "pending",
|
|
"completed": "ok",
|
|
"canceled": "canceled",
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *bitvavo) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// withdraw
|
|
//
|
|
// {
|
|
// "success": true,
|
|
// "symbol": "BTC",
|
|
// "amount": "1.5"
|
|
// }
|
|
//
|
|
// fetchWithdrawals
|
|
//
|
|
// {
|
|
// "timestamp": 1542967486256,
|
|
// "symbol": "BTC",
|
|
// "amount": "0.99994",
|
|
// "address": "BitcoinAddress",
|
|
// "paymentId": "10002653",
|
|
// "txId": "927b3ea50c5bb52c6854152d305dfa1e27fc01d10464cf10825d96d69d235eb3",
|
|
// "fee": "0.00006",
|
|
// "status": "awaiting_processing"
|
|
// }
|
|
//
|
|
// fetchDeposits
|
|
//
|
|
// {
|
|
// "timestamp":1590492401000,
|
|
// "symbol":"ETH",
|
|
// "amount":"0.249825",
|
|
// "fee":"0",
|
|
// "status":"completed",
|
|
// "txId":"0x5167b473fd37811f9ef22364c3d54726a859ef9d98934b3a1e11d7baa8d2c2e2"
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var id interface{} = nil
|
|
var timestamp interface{} = this.SafeInteger(transaction, "timestamp")
|
|
var currencyId interface{} = this.SafeString(transaction, "symbol")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
|
|
var status interface{} = this.ParseTransactionStatus(this.SafeString(transaction, "status"))
|
|
var amount interface{} = this.SafeNumber(transaction, "amount")
|
|
var address interface{} = this.SafeString(transaction, "address")
|
|
var txid interface{} = this.SafeString(transaction, "txId")
|
|
var fee interface{} = nil
|
|
var feeCost interface{} = this.SafeNumber(transaction, "fee")
|
|
if IsTrue(!IsEqual(feeCost, nil)) {
|
|
fee = map[string]interface{} {
|
|
"cost": feeCost,
|
|
"currency": code,
|
|
}
|
|
}
|
|
var typeVar interface{} = nil
|
|
if IsTrue(IsTrue((InOp(transaction, "success"))) || IsTrue((InOp(transaction, "address")))) {
|
|
typeVar = "withdrawal"
|
|
} else {
|
|
typeVar = "deposit"
|
|
}
|
|
var tag interface{} = this.SafeString(transaction, "paymentId")
|
|
return map[string]interface{} {
|
|
"info": transaction,
|
|
"id": id,
|
|
"txid": txid,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"addressFrom": nil,
|
|
"address": address,
|
|
"addressTo": address,
|
|
"tagFrom": nil,
|
|
"tag": tag,
|
|
"tagTo": tag,
|
|
"type": typeVar,
|
|
"amount": amount,
|
|
"currency": code,
|
|
"status": status,
|
|
"updated": nil,
|
|
"fee": fee,
|
|
"network": nil,
|
|
"comment": nil,
|
|
"internal": nil,
|
|
}
|
|
}
|
|
func (this *bitvavo) ParseDepositWithdrawFee(fee interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "symbol": "1INCH",
|
|
// "name": "1inch",
|
|
// "decimals": 8,
|
|
// "depositFee": "0",
|
|
// "depositConfirmations": 64,
|
|
// "depositStatus": "OK",
|
|
// "withdrawalFee": "6.1",
|
|
// "withdrawalMinAmount": "6.1",
|
|
// "withdrawalStatus": "OK",
|
|
// "networks": [
|
|
// "ETH"
|
|
// ],
|
|
// "message": ""
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var result interface{} = map[string]interface{} {
|
|
"info": fee,
|
|
"withdraw": map[string]interface{} {
|
|
"fee": this.SafeNumber(fee, "withdrawalFee"),
|
|
"percentage": false,
|
|
},
|
|
"deposit": map[string]interface{} {
|
|
"fee": this.SafeNumber(fee, "depositFee"),
|
|
"percentage": false,
|
|
},
|
|
"networks": map[string]interface{} {},
|
|
}
|
|
var networks interface{} = this.SafeValue(fee, "networks")
|
|
var networkId interface{} = this.SafeValue(networks, 0) // Bitvavo currently only supports one network per currency
|
|
var currencyCode interface{} = this.SafeString(currency, "code")
|
|
if IsTrue(IsEqual(networkId, "Mainnet")) {
|
|
networkId = currencyCode
|
|
}
|
|
var networkCode interface{} = this.NetworkIdToCode(networkId, currencyCode)
|
|
AddElementToObject(GetValue(result, "networks"), networkCode, map[string]interface{} {
|
|
"deposit": GetValue(result, "deposit"),
|
|
"withdraw": GetValue(result, "withdraw"),
|
|
})
|
|
return result
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitvavo#fetchDepositWithdrawFees
|
|
* @description fetch deposit and withdraw fees
|
|
* @see https://docs.bitvavo.com/#tag/General/paths/~1assets/get
|
|
* @param {string[]|undefined} codes list of unified currency codes
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
*/
|
|
func (this *bitvavo) FetchDepositWithdrawFees(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
codes := GetArg(optionalArgs, 0, nil)
|
|
_ = codes
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes20988 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes20988)
|
|
|
|
response:= (<-this.PublicGetAssets(params))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol": "1INCH",
|
|
// "name": "1inch",
|
|
// "decimals": 8,
|
|
// "depositFee": "0",
|
|
// "depositConfirmations": 64,
|
|
// "depositStatus": "OK",
|
|
// "withdrawalFee": "6.1",
|
|
// "withdrawalMinAmount": "6.1",
|
|
// "withdrawalStatus": "OK",
|
|
// "networks": [
|
|
// "ETH"
|
|
// ],
|
|
// "message": ""
|
|
// },
|
|
// ]
|
|
//
|
|
ch <- this.ParseDepositWithdrawFees(response, codes, "symbol")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitvavo) Sign(path interface{}, optionalArgs ...interface{}) interface{} {
|
|
api := GetArg(optionalArgs, 0, "public")
|
|
_ = api
|
|
method := GetArg(optionalArgs, 1, "GET")
|
|
_ = method
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
headers := GetArg(optionalArgs, 3, nil)
|
|
_ = headers
|
|
body := GetArg(optionalArgs, 4, nil)
|
|
_ = body
|
|
var query interface{} = this.Omit(params, this.ExtractParams(path))
|
|
var url interface{} = Add(Add(Add("/", this.Version), "/"), this.ImplodeParams(path, params))
|
|
var getOrDelete interface{} = IsTrue((IsEqual(method, "GET"))) || IsTrue((IsEqual(method, "DELETE")))
|
|
if IsTrue(getOrDelete) {
|
|
if IsTrue(GetArrayLength(ObjectKeys(query))) {
|
|
url = Add(url, Add("?", this.Urlencode(query)))
|
|
}
|
|
}
|
|
if IsTrue(IsEqual(api, "private")) {
|
|
this.CheckRequiredCredentials()
|
|
var payload interface{} = ""
|
|
if !IsTrue(getOrDelete) {
|
|
if IsTrue(GetArrayLength(ObjectKeys(query))) {
|
|
body = this.Json(query)
|
|
payload = body
|
|
}
|
|
}
|
|
var timestamp interface{} = ToString(this.Milliseconds())
|
|
var auth interface{} = Add(Add(Add(timestamp, method), url), payload)
|
|
var signature interface{} = this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha256)
|
|
var accessWindow interface{} = this.SafeString(this.Options, "BITVAVO-ACCESS-WINDOW", "10000")
|
|
headers = map[string]interface{} {
|
|
"BITVAVO-ACCESS-KEY": this.ApiKey,
|
|
"BITVAVO-ACCESS-SIGNATURE": signature,
|
|
"BITVAVO-ACCESS-TIMESTAMP": timestamp,
|
|
"BITVAVO-ACCESS-WINDOW": accessWindow,
|
|
}
|
|
if !IsTrue(getOrDelete) {
|
|
AddElementToObject(headers, "Content-Type", "application/json")
|
|
}
|
|
}
|
|
url = Add(GetValue(GetValue(this.Urls, "api"), api), url)
|
|
return map[string]interface{} {
|
|
"url": url,
|
|
"method": method,
|
|
"body": body,
|
|
"headers": headers,
|
|
}
|
|
}
|
|
func (this *bitvavo) HandleErrors(httpCode interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} {
|
|
if IsTrue(IsEqual(response, nil)) {
|
|
return nil // fallback to default error handler
|
|
}
|
|
//
|
|
// {"errorCode":308,"error":"The signature length is invalid (HMAC-SHA256 should return a 64 length hexadecimal string)."}
|
|
// {"errorCode":203,"error":"symbol parameter is required."}
|
|
// {"errorCode":205,"error":"symbol parameter is invalid."}
|
|
//
|
|
var errorCode interface{} = this.SafeString(response, "errorCode")
|
|
var error interface{} = this.SafeString(response, "error")
|
|
if IsTrue(!IsEqual(errorCode, nil)) {
|
|
var feedback interface{} = Add(Add(this.Id, " "), body)
|
|
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), error, feedback)
|
|
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorCode, feedback)
|
|
panic(ExchangeError(feedback))
|
|
}
|
|
return nil
|
|
}
|
|
func (this *bitvavo) CalculateRateLimiterCost(api interface{}, method interface{}, path interface{}, params interface{}, optionalArgs ...interface{}) interface{} {
|
|
config := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = config
|
|
if IsTrue(IsTrue((InOp(config, "noMarket"))) && !IsTrue((InOp(params, "market")))) {
|
|
return GetValue(config, "noMarket")
|
|
}
|
|
return this.SafeValue(config, "cost", 1)
|
|
}
|
|
|
|
|
|
func (this *bitvavo) Init(userConfig map[string]interface{}) {
|
|
this.Exchange = Exchange{}
|
|
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
|
|
this.Exchange.DerivedExchange = this
|
|
}
|