1572 lines
65 KiB
Go
1572 lines
65 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 luno struct {
|
|
Exchange
|
|
|
|
}
|
|
|
|
func NewLunoCore() luno {
|
|
p := luno{}
|
|
setDefaults(&p)
|
|
return p
|
|
}
|
|
|
|
func (this *luno) Describe() interface{} {
|
|
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
|
|
"id": "luno",
|
|
"name": "luno",
|
|
"countries": []interface{}{"GB", "SG", "ZA"},
|
|
"rateLimit": 200,
|
|
"version": "1",
|
|
"pro": true,
|
|
"has": map[string]interface{} {
|
|
"CORS": nil,
|
|
"spot": true,
|
|
"margin": false,
|
|
"swap": false,
|
|
"future": false,
|
|
"option": false,
|
|
"addMargin": false,
|
|
"cancelOrder": true,
|
|
"closeAllPositions": false,
|
|
"closePosition": false,
|
|
"createOrder": true,
|
|
"createReduceOnlyOrder": false,
|
|
"fetchAccounts": true,
|
|
"fetchBalance": true,
|
|
"fetchBorrowRateHistory": false,
|
|
"fetchClosedOrders": true,
|
|
"fetchCrossBorrowRate": false,
|
|
"fetchCrossBorrowRates": false,
|
|
"fetchFundingHistory": false,
|
|
"fetchFundingRate": false,
|
|
"fetchFundingRateHistory": false,
|
|
"fetchFundingRates": false,
|
|
"fetchIndexOHLCV": false,
|
|
"fetchIsolatedBorrowRate": false,
|
|
"fetchIsolatedBorrowRates": false,
|
|
"fetchLedger": true,
|
|
"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,
|
|
"fetchTrades": true,
|
|
"fetchTradingFee": true,
|
|
"fetchTradingFees": false,
|
|
"reduceMargin": false,
|
|
"setLeverage": false,
|
|
"setMarginMode": false,
|
|
"setPositionMode": false,
|
|
},
|
|
"urls": map[string]interface{} {
|
|
"referral": "https://www.luno.com/invite/44893A",
|
|
"logo": "https://user-images.githubusercontent.com/1294454/27766607-8c1a69d8-5ede-11e7-930c-540b5eb9be24.jpg",
|
|
"api": map[string]interface{} {
|
|
"public": "https://api.luno.com/api",
|
|
"private": "https://api.luno.com/api",
|
|
"exchange": "https://api.luno.com/api/exchange",
|
|
"exchangePrivate": "https://api.luno.com/api/exchange",
|
|
},
|
|
"www": "https://www.luno.com",
|
|
"doc": []interface{}{"https://www.luno.com/en/api", "https://npmjs.org/package/bitx", "https://github.com/bausmeier/node-bitx"},
|
|
},
|
|
"api": map[string]interface{} {
|
|
"exchange": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"markets": 1,
|
|
},
|
|
},
|
|
"exchangePrivate": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"candles": 1,
|
|
},
|
|
},
|
|
"public": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"orderbook": 1,
|
|
"orderbook_top": 1,
|
|
"ticker": 1,
|
|
"tickers": 1,
|
|
"trades": 1,
|
|
},
|
|
},
|
|
"private": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"accounts/{id}/pending": 1,
|
|
"accounts/{id}/transactions": 1,
|
|
"balance": 1,
|
|
"beneficiaries": 1,
|
|
"fee_info": 1,
|
|
"funding_address": 1,
|
|
"listorders": 1,
|
|
"listtrades": 1,
|
|
"send_fee": 1,
|
|
"orders/{id}": 1,
|
|
"withdrawals": 1,
|
|
"withdrawals/{id}": 1,
|
|
"transfers": 1,
|
|
},
|
|
"post": map[string]interface{} {
|
|
"accounts": 1,
|
|
"address/validate": 1,
|
|
"postorder": 1,
|
|
"marketorder": 1,
|
|
"stoporder": 1,
|
|
"funding_address": 1,
|
|
"withdrawals": 1,
|
|
"send": 1,
|
|
"oauth2/grant": 1,
|
|
"beneficiaries": 1,
|
|
},
|
|
"put": map[string]interface{} {
|
|
"accounts/{id}/name": 1,
|
|
},
|
|
"delete": map[string]interface{} {
|
|
"withdrawals/{id}": 1,
|
|
"beneficiaries/{id}": 1,
|
|
},
|
|
},
|
|
},
|
|
"timeframes": map[string]interface{} {
|
|
"1m": 60,
|
|
"5m": 300,
|
|
"15m": 900,
|
|
"30m": 1800,
|
|
"1h": 3600,
|
|
"3h": 10800,
|
|
"4h": 14400,
|
|
"1d": 86400,
|
|
"3d": 259200,
|
|
"1w": 604800,
|
|
},
|
|
"fees": map[string]interface{} {
|
|
"trading": map[string]interface{} {
|
|
"tierBased": true,
|
|
"percentage": true,
|
|
"taker": this.ParseNumber("0.001"),
|
|
"maker": this.ParseNumber("0"),
|
|
},
|
|
},
|
|
"precisionMode": TICK_SIZE,
|
|
"features": map[string]interface{} {
|
|
"spot": map[string]interface{} {
|
|
"sandbox": false,
|
|
"createOrder": map[string]interface{} {
|
|
"marginMode": false,
|
|
"triggerPrice": true,
|
|
"triggerPriceType": nil,
|
|
"triggerDirection": true,
|
|
"stopLossPrice": false,
|
|
"takeProfitPrice": false,
|
|
"attachedStopLossTakeProfit": nil,
|
|
"timeInForce": map[string]interface{} {
|
|
"IOC": true,
|
|
"FOK": true,
|
|
"PO": true,
|
|
"GTD": false,
|
|
},
|
|
"hedged": false,
|
|
"trailing": false,
|
|
"leverage": false,
|
|
"marketBuyByCost": true,
|
|
"marketBuyRequiresPrice": false,
|
|
"selfTradePrevention": false,
|
|
"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": false,
|
|
},
|
|
"fetchOpenOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 1000,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 1000,
|
|
"daysBack": 100000,
|
|
"untilDays": nil,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchClosedOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 1000,
|
|
"daysBack": 100000,
|
|
"daysBackCanceled": 1,
|
|
"untilDays": nil,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOHLCV": map[string]interface{} {
|
|
"limit": nil,
|
|
},
|
|
},
|
|
"swap": map[string]interface{} {
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
},
|
|
"future": map[string]interface{} {
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
},
|
|
},
|
|
})
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchMarkets
|
|
* @description retrieves data on all markets for luno
|
|
* @see https://www.luno.com/en/developers/api#tag/Market/operation/Markets
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} an array of objects representing market data
|
|
*/
|
|
func (this *luno) 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.ExchangeGetMarkets(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "markets":[
|
|
// {
|
|
// "market_id":"BCHXBT",
|
|
// "trading_status":"ACTIVE",
|
|
// "base_currency":"BCH",
|
|
// "counter_currency":"XBT",
|
|
// "min_volume":"0.01",
|
|
// "max_volume":"100.00",
|
|
// "volume_scale":2,
|
|
// "min_price":"0.0001",
|
|
// "max_price":"1.00",
|
|
// "price_scale":6,
|
|
// "fee_scale":8,
|
|
// },
|
|
// ]
|
|
// }
|
|
//
|
|
var result interface{} = []interface{}{}
|
|
var markets interface{} = this.SafeValue(response, "markets", []interface{}{})
|
|
for i := 0; IsLessThan(i, GetArrayLength(markets)); i++ {
|
|
var market interface{} = GetValue(markets, i)
|
|
var id interface{} = this.SafeString(market, "market_id")
|
|
var baseId interface{} = this.SafeString(market, "base_currency")
|
|
var quoteId interface{} = this.SafeString(market, "counter_currency")
|
|
var base interface{} = this.SafeCurrencyCode(baseId)
|
|
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
|
var status interface{} = this.SafeString(market, "trading_status")
|
|
AppendToArray(&result,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, "ACTIVE")),
|
|
"contract": false,
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
"contractSize": nil,
|
|
"expiry": nil,
|
|
"expiryDatetime": nil,
|
|
"strike": nil,
|
|
"optionType": nil,
|
|
"precision": map[string]interface{} {
|
|
"amount": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "volume_scale"))),
|
|
"price": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "price_scale"))),
|
|
},
|
|
"limits": map[string]interface{} {
|
|
"leverage": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"amount": map[string]interface{} {
|
|
"min": this.SafeNumber(market, "min_volume"),
|
|
"max": this.SafeNumber(market, "max_volume"),
|
|
},
|
|
"price": map[string]interface{} {
|
|
"min": this.SafeNumber(market, "min_price"),
|
|
"max": this.SafeNumber(market, "max_price"),
|
|
},
|
|
"cost": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
},
|
|
"created": nil,
|
|
"info": market,
|
|
})
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchAccounts
|
|
* @description fetch all the accounts associated with a profile
|
|
* @see https://www.luno.com/en/developers/api#tag/Accounts/operation/getBalances
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type
|
|
*/
|
|
func (this *luno) FetchAccounts(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.PrivateGetBalance(params))
|
|
PanicOnError(response)
|
|
var wallets interface{} = this.SafeValue(response, "balance", []interface{}{})
|
|
var result interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(wallets)); i++ {
|
|
var account interface{} = GetValue(wallets, i)
|
|
var accountId interface{} = this.SafeString(account, "account_id")
|
|
var currencyId interface{} = this.SafeString(account, "asset")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
|
AppendToArray(&result,map[string]interface{} {
|
|
"id": accountId,
|
|
"type": nil,
|
|
"currency": code,
|
|
"info": account,
|
|
})
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *luno) ParseBalance(response interface{}) interface{} {
|
|
var wallets interface{} = this.SafeValue(response, "balance", []interface{}{})
|
|
var result interface{} = map[string]interface{} {
|
|
"info": response,
|
|
"timestamp": nil,
|
|
"datetime": nil,
|
|
}
|
|
for i := 0; IsLessThan(i, GetArrayLength(wallets)); i++ {
|
|
var wallet interface{} = GetValue(wallets, i)
|
|
var currencyId interface{} = this.SafeString(wallet, "asset")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
|
var reserved interface{} = this.SafeString(wallet, "reserved")
|
|
var unconfirmed interface{} = this.SafeString(wallet, "unconfirmed")
|
|
var balance interface{} = this.SafeString(wallet, "balance")
|
|
var reservedUnconfirmed interface{} = Precise.StringAdd(reserved, unconfirmed)
|
|
var balanceUnconfirmed interface{} = Precise.StringAdd(balance, unconfirmed)
|
|
if IsTrue(InOp(result, code)) {
|
|
AddElementToObject(GetValue(result, code), "used", Precise.StringAdd(GetValue(GetValue(result, code), "used"), reservedUnconfirmed))
|
|
AddElementToObject(GetValue(result, code), "total", Precise.StringAdd(GetValue(GetValue(result, code), "total"), balanceUnconfirmed))
|
|
} else {
|
|
var account interface{} = this.Account()
|
|
AddElementToObject(account, "used", reservedUnconfirmed)
|
|
AddElementToObject(account, "total", balanceUnconfirmed)
|
|
AddElementToObject(result, code, account)
|
|
}
|
|
}
|
|
return this.SafeBalance(result)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchBalance
|
|
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
* @see https://www.luno.com/en/developers/api#tag/Accounts/operation/getBalances
|
|
* @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 *luno) 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
|
|
|
|
retRes4228 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes4228)
|
|
|
|
response:= (<-this.PrivateGetBalance(params))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "balance": [
|
|
// {'account_id': '119...1336','asset': 'XBT','balance': '0.00','reserved': '0.00',"unconfirmed": "0.00"},
|
|
// {'account_id': '66...289','asset': 'XBT','balance': '0.00','reserved': '0.00',"unconfirmed": "0.00"},
|
|
// {'account_id': '718...5300','asset': 'ETH','balance': '0.00','reserved': '0.00',"unconfirmed": "0.00"},
|
|
// {'account_id': '818...7072','asset': 'ZAR','balance': '0.001417','reserved': '0.00',"unconfirmed": "0.00"}]}
|
|
// ]
|
|
// }
|
|
//
|
|
ch <- this.ParseBalance(response)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchOrderBook
|
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
* @see https://www.luno.com/en/developers/api#tag/Market/operation/GetOrderBookFull
|
|
* @see https://www.luno.com/en/developers/api#tag/Market/operation/GetOrderBook
|
|
* @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 *luno) 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
|
|
|
|
retRes4498 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes4498)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
var response interface{} = nil
|
|
if IsTrue(IsTrue(!IsEqual(limit, nil)) && IsTrue(IsLessThanOrEqual(limit, 100))) {
|
|
|
|
response = (<-this.PublicGetOrderbookTop(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
|
|
response = (<-this.PublicGetOrderbook(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
var timestamp interface{} = this.SafeInteger(response, "timestamp")
|
|
|
|
ch <- this.ParseOrderBook(response, GetValue(market, "symbol"), timestamp, "bids", "asks", "price", "volume")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *luno) ParseOrderStatus(status interface{}) interface{} {
|
|
var statuses interface{} = map[string]interface{} {
|
|
"PENDING": "open",
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *luno) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "base": "string",
|
|
// "completed_timestamp": "string",
|
|
// "counter": "string",
|
|
// "creation_timestamp": "string",
|
|
// "expiration_timestamp": "string",
|
|
// "fee_base": "string",
|
|
// "fee_counter": "string",
|
|
// "limit_price": "string",
|
|
// "limit_volume": "string",
|
|
// "order_id": "string",
|
|
// "pair": "string",
|
|
// "state": "PENDING",
|
|
// "type": "BID"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var timestamp interface{} = this.SafeInteger(order, "creation_timestamp")
|
|
var status interface{} = this.ParseOrderStatus(this.SafeString(order, "state"))
|
|
status = Ternary(IsTrue((IsEqual(status, "open"))), status, status)
|
|
var side interface{} = nil
|
|
var orderType interface{} = this.SafeString(order, "type")
|
|
if IsTrue(IsTrue((IsEqual(orderType, "ASK"))) || IsTrue((IsEqual(orderType, "SELL")))) {
|
|
side = "sell"
|
|
} else if IsTrue(IsTrue((IsEqual(orderType, "BID"))) || IsTrue((IsEqual(orderType, "BUY")))) {
|
|
side = "buy"
|
|
}
|
|
var marketId interface{} = this.SafeString(order, "pair")
|
|
market = this.SafeMarket(marketId, market)
|
|
var price interface{} = this.SafeString(order, "limit_price")
|
|
var amount interface{} = this.SafeString(order, "limit_volume")
|
|
var quoteFee interface{} = this.SafeNumber(order, "fee_counter")
|
|
var baseFee interface{} = this.SafeNumber(order, "fee_base")
|
|
var filled interface{} = this.SafeString(order, "base")
|
|
var cost interface{} = this.SafeString(order, "counter")
|
|
var fee interface{} = nil
|
|
if IsTrue(!IsEqual(quoteFee, nil)) {
|
|
fee = map[string]interface{} {
|
|
"cost": quoteFee,
|
|
"currency": GetValue(market, "quote"),
|
|
}
|
|
} else if IsTrue(!IsEqual(baseFee, nil)) {
|
|
fee = map[string]interface{} {
|
|
"cost": baseFee,
|
|
"currency": GetValue(market, "base"),
|
|
}
|
|
}
|
|
var id interface{} = this.SafeString(order, "order_id")
|
|
return this.SafeOrder(map[string]interface{} {
|
|
"id": id,
|
|
"clientOrderId": nil,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"timestamp": timestamp,
|
|
"lastTradeTimestamp": nil,
|
|
"status": status,
|
|
"symbol": GetValue(market, "symbol"),
|
|
"type": nil,
|
|
"timeInForce": nil,
|
|
"postOnly": nil,
|
|
"side": side,
|
|
"price": price,
|
|
"triggerPrice": nil,
|
|
"amount": amount,
|
|
"filled": filled,
|
|
"cost": cost,
|
|
"remaining": nil,
|
|
"trades": nil,
|
|
"fee": fee,
|
|
"info": order,
|
|
"average": nil,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchOrder
|
|
* @description fetches information on an order made by the user
|
|
* @see https://www.luno.com/en/developers/api#tag/Orders/operation/GetOrder
|
|
* @param {string} id order id
|
|
* @param {string} symbol not used by luno fetchOrder
|
|
* @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 *luno) 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
|
|
|
|
retRes5578 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes5578)
|
|
var request interface{} = map[string]interface{} {
|
|
"id": id,
|
|
}
|
|
|
|
response:= (<-this.PrivateGetOrdersId(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
ch <- this.ParseOrder(response)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *luno) FetchOrdersByState(state interface{}, 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
|
|
|
|
retRes5668 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes5668)
|
|
var request interface{} = map[string]interface{} {}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(state, nil)) {
|
|
AddElementToObject(request, "state", state)
|
|
}
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "pair", GetValue(market, "id"))
|
|
}
|
|
|
|
response:= (<-this.PrivateGetListorders(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
var orders interface{} = this.SafeList(response, "orders", []interface{}{})
|
|
|
|
ch <- this.ParseOrders(orders, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchOrders
|
|
* @description fetches information on multiple orders made by the user
|
|
* @see https://www.luno.com/en/developers/api#tag/Orders/operation/ListOrders
|
|
* @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
|
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *luno) 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
|
|
|
|
retRes59315 := (<-this.FetchOrdersByState(nil, symbol, since, limit, params))
|
|
PanicOnError(retRes59315)
|
|
ch <- retRes59315
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchOpenOrders
|
|
* @description fetch all unfilled currently open orders
|
|
* @see https://www.luno.com/en/developers/api#tag/Orders/operation/ListOrders
|
|
* @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 *luno) 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
|
|
|
|
retRes60815 := (<-this.FetchOrdersByState("PENDING", symbol, since, limit, params))
|
|
PanicOnError(retRes60815)
|
|
ch <- retRes60815
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchClosedOrders
|
|
* @description fetches information on multiple closed orders made by the user
|
|
* @see https://www.luno.com/en/developers/api#tag/Orders/operation/ListOrders
|
|
* @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
|
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *luno) FetchClosedOrders(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
|
|
|
|
retRes62315 := (<-this.FetchOrdersByState("COMPLETE", symbol, since, limit, params))
|
|
PanicOnError(retRes62315)
|
|
ch <- retRes62315
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *luno) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
|
// {
|
|
// "pair":"XBTAUD",
|
|
// "timestamp":1642201439301,
|
|
// "bid":"59972.30000000",
|
|
// "ask":"59997.99000000",
|
|
// "last_trade":"59997.99000000",
|
|
// "rolling_24_hour_volume":"1.89510000",
|
|
// "status":"ACTIVE"
|
|
// }
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var timestamp interface{} = this.SafeInteger(ticker, "timestamp")
|
|
var marketId interface{} = this.SafeString(ticker, "pair")
|
|
var symbol interface{} = this.SafeSymbol(marketId, market)
|
|
var last interface{} = this.SafeString(ticker, "last_trade")
|
|
return this.SafeTicker(map[string]interface{} {
|
|
"symbol": symbol,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"high": nil,
|
|
"low": nil,
|
|
"bid": this.SafeString(ticker, "bid"),
|
|
"bidVolume": nil,
|
|
"ask": this.SafeString(ticker, "ask"),
|
|
"askVolume": nil,
|
|
"vwap": nil,
|
|
"open": nil,
|
|
"close": last,
|
|
"last": last,
|
|
"previousClose": nil,
|
|
"change": nil,
|
|
"percentage": nil,
|
|
"average": nil,
|
|
"baseVolume": this.SafeString(ticker, "rolling_24_hour_volume"),
|
|
"quoteVolume": nil,
|
|
"info": ticker,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchTickers
|
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
* @see https://www.luno.com/en/developers/api#tag/Market/operation/GetTickers
|
|
* @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 *luno) 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
|
|
|
|
retRes6748 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes6748)
|
|
symbols = this.MarketSymbols(symbols)
|
|
|
|
response:= (<-this.PublicGetTickers(params))
|
|
PanicOnError(response)
|
|
var tickers interface{} = this.IndexBy(GetValue(response, "tickers"), "pair")
|
|
var ids interface{} = ObjectKeys(tickers)
|
|
var result interface{} = map[string]interface{} {}
|
|
for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ {
|
|
var id interface{} = GetValue(ids, i)
|
|
var market interface{} = this.SafeMarket(id)
|
|
var symbol interface{} = GetValue(market, "symbol")
|
|
var ticker interface{} = GetValue(tickers, id)
|
|
AddElementToObject(result, symbol, this.ParseTicker(ticker, market))
|
|
}
|
|
|
|
ch <- this.FilterByArrayTickers(result, "symbol", symbols)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchTicker
|
|
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
* @see https://www.luno.com/en/developers/api#tag/Market/operation/GetTicker
|
|
* @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 *luno) 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
|
|
|
|
retRes7008 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes7008)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
|
|
response:= (<-this.PublicGetTicker(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
// {
|
|
// "pair":"XBTAUD",
|
|
// "timestamp":1642201439301,
|
|
// "bid":"59972.30000000",
|
|
// "ask":"59997.99000000",
|
|
// "last_trade":"59997.99000000",
|
|
// "rolling_24_hour_volume":"1.89510000",
|
|
// "status":"ACTIVE"
|
|
// }
|
|
ch <- this.ParseTicker(response, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *luno) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchTrades (public)
|
|
//
|
|
// {
|
|
// "sequence":276989,
|
|
// "timestamp":1648651276949,
|
|
// "price":"35773.20000000",
|
|
// "volume":"0.00300000",
|
|
// "is_buy":false
|
|
// }
|
|
//
|
|
// fetchMyTrades (private)
|
|
//
|
|
// {
|
|
// "pair":"LTCXBT",
|
|
// "sequence":3256813,
|
|
// "order_id":"BXEX6XHHDT5EGW2",
|
|
// "type":"ASK",
|
|
// "timestamp":1648652135235,
|
|
// "price":"0.002786",
|
|
// "volume":"0.10",
|
|
// "base":"0.10",
|
|
// "counter":"0.0002786",
|
|
// "fee_base":"0.0001",
|
|
// "fee_counter":"0.00",
|
|
// "is_buy":false,
|
|
// "client_order_id":""
|
|
// }
|
|
//
|
|
// For public trade data (is_buy === True) indicates 'buy' side but for private trade data
|
|
// is_buy indicates maker or taker. The value of "type" (ASK/BID) indicate sell/buy side.
|
|
// Private trade data includes ID field which public trade data does not.
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var orderId interface{} = this.SafeString(trade, "order_id")
|
|
var id interface{} = this.SafeString(trade, "sequence")
|
|
var takerOrMaker interface{} = nil
|
|
var side interface{} = nil
|
|
if IsTrue(!IsEqual(orderId, nil)) {
|
|
var typeVar interface{} = this.SafeString(trade, "type")
|
|
if IsTrue(IsTrue((IsEqual(typeVar, "ASK"))) || IsTrue((IsEqual(typeVar, "SELL")))) {
|
|
side = "sell"
|
|
} else if IsTrue(IsTrue((IsEqual(typeVar, "BID"))) || IsTrue((IsEqual(typeVar, "BUY")))) {
|
|
side = "buy"
|
|
}
|
|
if IsTrue(IsTrue(IsEqual(side, "sell")) && IsTrue(GetValue(trade, "is_buy"))) {
|
|
takerOrMaker = "maker"
|
|
} else if IsTrue(IsTrue(IsEqual(side, "buy")) && !IsTrue(GetValue(trade, "is_buy"))) {
|
|
takerOrMaker = "maker"
|
|
} else {
|
|
takerOrMaker = "taker"
|
|
}
|
|
} else {
|
|
side = Ternary(IsTrue(GetValue(trade, "is_buy")), "buy", "sell")
|
|
}
|
|
var feeBaseString interface{} = this.SafeString(trade, "fee_base")
|
|
var feeCounterString interface{} = this.SafeString(trade, "fee_counter")
|
|
var feeCurrency interface{} = nil
|
|
var feeCost interface{} = nil
|
|
if IsTrue(!IsEqual(feeBaseString, nil)) {
|
|
if !IsTrue(Precise.StringEquals(feeBaseString, "0.0")) {
|
|
feeCurrency = GetValue(market, "base")
|
|
feeCost = feeBaseString
|
|
}
|
|
} else if IsTrue(!IsEqual(feeCounterString, nil)) {
|
|
if !IsTrue(Precise.StringEquals(feeCounterString, "0.0")) {
|
|
feeCurrency = GetValue(market, "quote")
|
|
feeCost = feeCounterString
|
|
}
|
|
}
|
|
var timestamp interface{} = this.SafeInteger(trade, "timestamp")
|
|
return this.SafeTrade(map[string]interface{} {
|
|
"info": trade,
|
|
"id": id,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"symbol": GetValue(market, "symbol"),
|
|
"order": orderId,
|
|
"type": nil,
|
|
"side": side,
|
|
"takerOrMaker": takerOrMaker,
|
|
"price": this.SafeString(trade, "price"),
|
|
"amount": this.SafeString2(trade, "volume", "base"),
|
|
"cost": this.SafeString(trade, "counter"),
|
|
"fee": map[string]interface{} {
|
|
"cost": feeCost,
|
|
"currency": feeCurrency,
|
|
},
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchTrades
|
|
* @description get the list of most recent trades for a particular symbol
|
|
* @see https://www.luno.com/en/developers/api#tag/Market/operation/ListTrades
|
|
* @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
|
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
*/
|
|
func (this *luno) 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
|
|
|
|
retRes8218 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes8218)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "since", since)
|
|
}
|
|
|
|
response:= (<-this.PublicGetTrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "trades":[
|
|
// {
|
|
// "sequence":276989,
|
|
// "timestamp":1648651276949,
|
|
// "price":"35773.20000000",
|
|
// "volume":"0.00300000",
|
|
// "is_buy":false
|
|
// },...
|
|
// ]
|
|
// }
|
|
//
|
|
var trades interface{} = this.SafeList(response, "trades", []interface{}{})
|
|
|
|
ch <- this.ParseTrades(trades, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchOHLCV
|
|
* @see https://www.luno.com/en/developers/api#tag/Market/operation/GetCandles
|
|
* @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 luno api endpoint
|
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
*/
|
|
func (this *luno) 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
|
|
|
|
retRes8608 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes8608)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"duration": this.SafeValue(this.Timeframes, timeframe, timeframe),
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "since", this.ParseToInt(since))
|
|
} else {
|
|
var duration interface{} = Multiply(Multiply(1000, 1000), this.ParseTimeframe(timeframe))
|
|
AddElementToObject(request, "since", Subtract(this.Milliseconds(), duration))
|
|
}
|
|
|
|
response:= (<-this.ExchangePrivateGetCandles(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "candles": [
|
|
// {
|
|
// "timestamp": 1664055240000,
|
|
// "open": "19612.65",
|
|
// "close": "19612.65",
|
|
// "high": "19612.65",
|
|
// "low": "19612.65",
|
|
// "volume": "0.00"
|
|
// },...
|
|
// ],
|
|
// "duration": 60,
|
|
// "pair": "XBTEUR"
|
|
// }
|
|
//
|
|
var ohlcvs interface{} = this.SafeList(response, "candles", []interface{}{})
|
|
|
|
ch <- this.ParseOHLCVs(ohlcvs, market, timeframe, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *luno) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
|
|
// {
|
|
// "timestamp": 1664055240000,
|
|
// "open": "19612.65",
|
|
// "close": "19612.65",
|
|
// "high": "19612.65",
|
|
// "low": "19612.65",
|
|
// "volume": "0.00"
|
|
// }
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
return []interface{}{this.SafeInteger(ohlcv, "timestamp"), this.SafeNumber(ohlcv, "open"), this.SafeNumber(ohlcv, "high"), this.SafeNumber(ohlcv, "low"), this.SafeNumber(ohlcv, "close"), this.SafeNumber(ohlcv, "volume")}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchMyTrades
|
|
* @description fetch all trades made by the user
|
|
* @see https://www.luno.com/en/developers/api#tag/Orders/operation/ListUserTrades
|
|
* @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
|
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
*/
|
|
func (this *luno) 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")))
|
|
}
|
|
|
|
retRes9278 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes9278)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "since", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.PrivateGetListtrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "trades":[
|
|
// {
|
|
// "pair":"LTCXBT",
|
|
// "sequence":3256813,
|
|
// "order_id":"BXEX6XHHDT5EGW2",
|
|
// "type":"ASK",
|
|
// "timestamp":1648652135235,
|
|
// "price":"0.002786",
|
|
// "volume":"0.10",
|
|
// "base":"0.10",
|
|
// "counter":"0.0002786",
|
|
// "fee_base":"0.0001",
|
|
// "fee_counter":"0.00",
|
|
// "is_buy":false,
|
|
// "client_order_id":""
|
|
// },...
|
|
// ]
|
|
// }
|
|
//
|
|
var trades interface{} = this.SafeList(response, "trades", []interface{}{})
|
|
|
|
ch <- this.ParseTrades(trades, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchTradingFee
|
|
* @description fetch the trading fees for a market
|
|
* @see https://www.luno.com/en/developers/api#tag/Orders/operation/getFeeInfo
|
|
* @param {string} symbol unified market symbol
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
*/
|
|
func (this *luno) FetchTradingFee(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
|
|
|
|
retRes9748 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes9748)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
|
|
response:= (<-this.PrivateGetFeeInfo(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "maker_fee": "0.00250000",
|
|
// "taker_fee": "0.00500000",
|
|
// "thirty_day_volume": "0"
|
|
// }
|
|
//
|
|
ch <- map[string]interface{} {
|
|
"info": response,
|
|
"symbol": symbol,
|
|
"maker": this.SafeNumber(response, "maker_fee"),
|
|
"taker": this.SafeNumber(response, "taker_fee"),
|
|
"percentage": nil,
|
|
"tierBased": nil,
|
|
}
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#createOrder
|
|
* @description create a trade order
|
|
* @see https://www.luno.com/en/developers/api#tag/Orders/operation/PostMarketOrder
|
|
* @see https://www.luno.com/en/developers/api#tag/Orders/operation/PostLimitOrder
|
|
* @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 exchange API endpoint
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *luno) 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
|
|
|
|
retRes10128 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes10128)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
var response interface{} = nil
|
|
if IsTrue(IsEqual(typeVar, "market")) {
|
|
AddElementToObject(request, "type", ToUpper(side))
|
|
// todo add createMarketBuyOrderRequires price logic as it is implemented in the other exchanges
|
|
if IsTrue(IsEqual(side, "buy")) {
|
|
AddElementToObject(request, "counter_volume", this.AmountToPrecision(GetValue(market, "symbol"), amount))
|
|
} else {
|
|
AddElementToObject(request, "base_volume", this.AmountToPrecision(GetValue(market, "symbol"), amount))
|
|
}
|
|
|
|
response = (<-this.PrivatePostMarketorder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
AddElementToObject(request, "volume", this.AmountToPrecision(GetValue(market, "symbol"), amount))
|
|
AddElementToObject(request, "price", this.PriceToPrecision(GetValue(market, "symbol"), price))
|
|
AddElementToObject(request, "type", Ternary(IsTrue((IsEqual(side, "buy"))), "BID", "ASK"))
|
|
|
|
response = (<-this.PrivatePostPostorder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
|
|
ch <- this.SafeOrder(map[string]interface{} {
|
|
"info": response,
|
|
"id": GetValue(response, "order_id"),
|
|
}, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#cancelOrder
|
|
* @description cancels an open order
|
|
* @see https://www.luno.com/en/developers/api#tag/Orders/operation/StopOrder
|
|
* @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 *luno) 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
|
|
|
|
retRes10508 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes10508)
|
|
var request interface{} = map[string]interface{} {
|
|
"order_id": id,
|
|
}
|
|
|
|
response:= (<-this.PrivatePostStoporder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "success": true
|
|
// }
|
|
//
|
|
ch <- this.SafeOrder(map[string]interface{} {
|
|
"info": response,
|
|
})
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *luno) FetchLedgerByEntries(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
// by default without entry number or limit number, return most recent entry
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
entry := GetArg(optionalArgs, 1, nil)
|
|
_ = entry
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(entry, nil)) {
|
|
entry = OpNeg(1)
|
|
}
|
|
if IsTrue(IsEqual(limit, nil)) {
|
|
limit = 1
|
|
}
|
|
var since interface{} = nil
|
|
var request interface{} = map[string]interface{} {
|
|
"min_row": entry,
|
|
"max_row": this.Sum(entry, limit),
|
|
}
|
|
|
|
retRes107815 := (<-this.FetchLedger(code, since, limit, this.Extend(request, params)))
|
|
PanicOnError(retRes107815)
|
|
ch <- retRes107815
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name luno#fetchLedger
|
|
* @description fetch the history of changes, actions done by the user or operations that altered the balance of the user
|
|
* @see https://www.luno.com/en/developers/api#tag/Accounts/operation/ListTransactions
|
|
* @param {string} [code] unified currency code, default is undefined
|
|
* @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
|
|
* @param {int} [limit] max number of ledger entries to return, default is undefined
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger}
|
|
*/
|
|
func (this *luno) FetchLedger(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
|
|
|
|
retRes10938 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes10938)
|
|
|
|
retRes10948 := (<-this.LoadAccounts())
|
|
PanicOnError(retRes10948)
|
|
var currency interface{} = nil
|
|
var id interface{} = this.SafeString(params, "id") // account id
|
|
var min_row interface{} = this.SafeValue(params, "min_row")
|
|
var max_row interface{} = this.SafeValue(params, "max_row")
|
|
if IsTrue(IsEqual(id, nil)) {
|
|
if IsTrue(IsEqual(code, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchLedger() requires a currency code argument if no account id specified in params")))
|
|
}
|
|
currency = this.Currency(code)
|
|
var accountsByCurrencyCode interface{} = this.IndexBy(this.Accounts, "currency")
|
|
var account interface{} = this.SafeValue(accountsByCurrencyCode, code)
|
|
if IsTrue(IsEqual(account, nil)) {
|
|
panic(ExchangeError(Add(Add(this.Id, " fetchLedger() could not find account id for "), code)))
|
|
}
|
|
id = GetValue(account, "id")
|
|
}
|
|
if IsTrue(IsTrue(IsEqual(min_row, nil)) && IsTrue(IsEqual(max_row, nil))) {
|
|
max_row = 0 // Default to most recent transactions
|
|
min_row = OpNeg(1000) // Maximum number of records supported
|
|
} else if IsTrue(IsTrue(IsEqual(min_row, nil)) || IsTrue(IsEqual(max_row, nil))) {
|
|
panic(ExchangeError(Add(this.Id, " fetchLedger() require both params \\'max_row\\' and \\'min_row\\' or neither to be defined")))
|
|
}
|
|
if IsTrue(IsTrue(!IsEqual(limit, nil)) && IsTrue(IsGreaterThan(Subtract(max_row, min_row), limit))) {
|
|
if IsTrue(IsLessThanOrEqual(max_row, 0)) {
|
|
min_row = Subtract(max_row, limit)
|
|
} else if IsTrue(IsGreaterThan(min_row, 0)) {
|
|
max_row = Add(min_row, limit)
|
|
}
|
|
}
|
|
if IsTrue(IsGreaterThan(Subtract(max_row, min_row), 1000)) {
|
|
panic(ExchangeError(Add(this.Id, " fetchLedger() requires the params \\'max_row\\' - \\'min_row\\' <= 1000")))
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"id": id,
|
|
"min_row": min_row,
|
|
"max_row": max_row,
|
|
}
|
|
|
|
response:= (<-this.PrivateGetAccountsIdTransactions(this.Extend(params, request)))
|
|
PanicOnError(response)
|
|
var entries interface{} = this.SafeValue(response, "transactions", []interface{}{})
|
|
|
|
ch <- this.ParseLedger(entries, currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *luno) ParseLedgerComment(comment interface{}) interface{} {
|
|
var words interface{} = Split(comment, " ")
|
|
var types interface{} = map[string]interface{} {
|
|
"Withdrawal": "fee",
|
|
"Trading": "fee",
|
|
"Payment": "transaction",
|
|
"Sent": "transaction",
|
|
"Deposit": "transaction",
|
|
"Received": "transaction",
|
|
"Released": "released",
|
|
"Reserved": "reserved",
|
|
"Sold": "trade",
|
|
"Bought": "trade",
|
|
"Failure": "failed",
|
|
}
|
|
var referenceId interface{} = nil
|
|
var firstWord interface{} = this.SafeString(words, 0)
|
|
var thirdWord interface{} = this.SafeString(words, 2)
|
|
var fourthWord interface{} = this.SafeString(words, 3)
|
|
var typeVar interface{} = this.SafeString(types, firstWord, nil)
|
|
if IsTrue(IsTrue((IsEqual(typeVar, nil))) && IsTrue((IsEqual(thirdWord, "fee")))) {
|
|
typeVar = "fee"
|
|
}
|
|
if IsTrue(IsTrue((IsEqual(typeVar, "reserved"))) && IsTrue((IsEqual(fourthWord, "order")))) {
|
|
referenceId = this.SafeString(words, 4)
|
|
}
|
|
return map[string]interface{} {
|
|
"type": typeVar,
|
|
"referenceId": referenceId,
|
|
}
|
|
}
|
|
func (this *luno) ParseLedgerEntry(entry interface{}, optionalArgs ...interface{}) interface{} {
|
|
// const details = this.safeValue (entry, 'details', {});
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var id interface{} = this.SafeString(entry, "row_index")
|
|
var account_id interface{} = this.SafeString(entry, "account_id")
|
|
var timestamp interface{} = this.SafeInteger(entry, "timestamp")
|
|
var currencyId interface{} = this.SafeString(entry, "currency")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
|
|
currency = this.SafeCurrency(currencyId, currency)
|
|
var available_delta interface{} = this.SafeString(entry, "available_delta")
|
|
var balance_delta interface{} = this.SafeString(entry, "balance_delta")
|
|
var after interface{} = this.SafeString(entry, "balance")
|
|
var comment interface{} = this.SafeString(entry, "description")
|
|
var before interface{} = after
|
|
var amount interface{} = "0.0"
|
|
var result interface{} = this.ParseLedgerComment(comment)
|
|
var typeVar interface{} = GetValue(result, "type")
|
|
var referenceId interface{} = GetValue(result, "referenceId")
|
|
var direction interface{} = nil
|
|
var status interface{} = nil
|
|
if !IsTrue(Precise.StringEquals(balance_delta, "0.0")) {
|
|
before = Precise.StringSub(after, balance_delta)
|
|
status = "ok"
|
|
amount = Precise.StringAbs(balance_delta)
|
|
} else if IsTrue(Precise.StringLt(available_delta, "0.0")) {
|
|
status = "pending"
|
|
amount = Precise.StringAbs(available_delta)
|
|
} else if IsTrue(Precise.StringGt(available_delta, "0.0")) {
|
|
status = "canceled"
|
|
amount = Precise.StringAbs(available_delta)
|
|
}
|
|
if IsTrue(IsTrue(Precise.StringGt(balance_delta, "0")) || IsTrue(Precise.StringGt(available_delta, "0"))) {
|
|
direction = "in"
|
|
} else if IsTrue(IsTrue(Precise.StringLt(balance_delta, "0")) || IsTrue(Precise.StringLt(available_delta, "0"))) {
|
|
direction = "out"
|
|
}
|
|
return this.SafeLedgerEntry(map[string]interface{} {
|
|
"info": entry,
|
|
"id": id,
|
|
"direction": direction,
|
|
"account": account_id,
|
|
"referenceId": referenceId,
|
|
"referenceAccount": nil,
|
|
"type": typeVar,
|
|
"currency": code,
|
|
"amount": this.ParseToNumeric(amount),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"before": this.ParseToNumeric(before),
|
|
"after": this.ParseToNumeric(after),
|
|
"status": status,
|
|
"fee": nil,
|
|
}, currency)
|
|
}
|
|
func (this *luno) 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 url interface{} = Add(Add(Add(Add(GetValue(GetValue(this.Urls, "api"), api), "/"), this.Version), "/"), this.ImplodeParams(path, params))
|
|
var query interface{} = this.Omit(params, this.ExtractParams(path))
|
|
if IsTrue(GetArrayLength(ObjectKeys(query))) {
|
|
url = Add(url, Add("?", this.Urlencode(query)))
|
|
}
|
|
if IsTrue(IsTrue((IsEqual(api, "private"))) || IsTrue((IsEqual(api, "exchangePrivate")))) {
|
|
this.CheckRequiredCredentials()
|
|
var auth interface{} = this.StringToBase64(Add(Add(this.ApiKey, ":"), this.Secret))
|
|
headers = map[string]interface{} {
|
|
"Authorization": Add("Basic ", auth),
|
|
}
|
|
}
|
|
return map[string]interface{} {
|
|
"url": url,
|
|
"method": method,
|
|
"body": body,
|
|
"headers": headers,
|
|
}
|
|
}
|
|
func (this *luno) 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
|
|
}
|
|
var error interface{} = this.SafeValue(response, "error")
|
|
if IsTrue(!IsEqual(error, nil)) {
|
|
panic(ExchangeError(Add(Add(this.Id, " "), this.Json(response))))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
|
|
func (this *luno) Init(userConfig map[string]interface{}) {
|
|
this.Exchange = Exchange{}
|
|
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
|
|
this.Exchange.DerivedExchange = this
|
|
}
|