1405 lines
60 KiB
Go
1405 lines
60 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 bithumb struct {
|
||
|
Exchange
|
||
|
|
||
|
}
|
||
|
|
||
|
func NewBithumbCore() bithumb {
|
||
|
p := bithumb{}
|
||
|
setDefaults(&p)
|
||
|
return p
|
||
|
}
|
||
|
|
||
|
func (this *bithumb) Describe() interface{} {
|
||
|
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
|
||
|
"id": "bithumb",
|
||
|
"name": "Bithumb",
|
||
|
"countries": []interface{}{"KR"},
|
||
|
"rateLimit": 500,
|
||
|
"pro": true,
|
||
|
"has": map[string]interface{} {
|
||
|
"CORS": true,
|
||
|
"spot": true,
|
||
|
"margin": false,
|
||
|
"swap": false,
|
||
|
"future": false,
|
||
|
"option": false,
|
||
|
"addMargin": false,
|
||
|
"cancelOrder": true,
|
||
|
"closeAllPositions": false,
|
||
|
"closePosition": false,
|
||
|
"createMarketOrder": true,
|
||
|
"createOrder": true,
|
||
|
"createReduceOnlyOrder": false,
|
||
|
"fetchBalance": true,
|
||
|
"fetchBorrowRateHistories": false,
|
||
|
"fetchBorrowRateHistory": false,
|
||
|
"fetchCrossBorrowRate": false,
|
||
|
"fetchCrossBorrowRates": false,
|
||
|
"fetchFundingHistory": false,
|
||
|
"fetchFundingRate": false,
|
||
|
"fetchFundingRateHistory": false,
|
||
|
"fetchFundingRates": false,
|
||
|
"fetchIndexOHLCV": false,
|
||
|
"fetchIsolatedBorrowRate": false,
|
||
|
"fetchIsolatedBorrowRates": false,
|
||
|
"fetchLeverage": false,
|
||
|
"fetchMarkets": true,
|
||
|
"fetchMarkOHLCV": false,
|
||
|
"fetchOHLCV": true,
|
||
|
"fetchOpenInterestHistory": false,
|
||
|
"fetchOpenOrders": true,
|
||
|
"fetchOrder": true,
|
||
|
"fetchOrderBook": true,
|
||
|
"fetchPosition": false,
|
||
|
"fetchPositionHistory": false,
|
||
|
"fetchPositionMode": false,
|
||
|
"fetchPositions": false,
|
||
|
"fetchPositionsForSymbol": false,
|
||
|
"fetchPositionsHistory": false,
|
||
|
"fetchPositionsRisk": false,
|
||
|
"fetchPremiumIndexOHLCV": false,
|
||
|
"fetchTicker": true,
|
||
|
"fetchTickers": true,
|
||
|
"fetchTrades": true,
|
||
|
"fetchTransfer": false,
|
||
|
"fetchTransfers": false,
|
||
|
"reduceMargin": false,
|
||
|
"setLeverage": false,
|
||
|
"setMarginMode": false,
|
||
|
"setPositionMode": false,
|
||
|
"transfer": false,
|
||
|
"withdraw": true,
|
||
|
},
|
||
|
"hostname": "bithumb.com",
|
||
|
"urls": map[string]interface{} {
|
||
|
"logo": "https://github.com/user-attachments/assets/c9e0eefb-4777-46b9-8f09-9d7f7c4af82d",
|
||
|
"api": map[string]interface{} {
|
||
|
"public": "https://api.{hostname}/public",
|
||
|
"private": "https://api.{hostname}",
|
||
|
},
|
||
|
"www": "https://www.bithumb.com",
|
||
|
"doc": "https://apidocs.bithumb.com",
|
||
|
"fees": "https://en.bithumb.com/customer_support/info_fee",
|
||
|
},
|
||
|
"api": map[string]interface{} {
|
||
|
"public": map[string]interface{} {
|
||
|
"get": []interface{}{"ticker/ALL_{quoteId}", "ticker/{baseId}_{quoteId}", "orderbook/ALL_{quoteId}", "orderbook/{baseId}_{quoteId}", "transaction_history/{baseId}_{quoteId}", "network-info", "assetsstatus/multichain/ALL", "assetsstatus/multichain/{currency}", "withdraw/minimum/ALL", "withdraw/minimum/{currency}", "assetsstatus/ALL", "assetsstatus/{baseId}", "candlestick/{baseId}_{quoteId}/{interval}"},
|
||
|
},
|
||
|
"private": map[string]interface{} {
|
||
|
"post": []interface{}{"info/account", "info/balance", "info/wallet_address", "info/ticker", "info/orders", "info/user_transactions", "info/order_detail", "trade/place", "trade/cancel", "trade/btc_withdrawal", "trade/krw_deposit", "trade/krw_withdrawal", "trade/market_buy", "trade/market_sell", "trade/stop_limit"},
|
||
|
},
|
||
|
},
|
||
|
"fees": map[string]interface{} {
|
||
|
"trading": map[string]interface{} {
|
||
|
"maker": this.ParseNumber("0.0025"),
|
||
|
"taker": this.ParseNumber("0.0025"),
|
||
|
},
|
||
|
},
|
||
|
"precisionMode": SIGNIFICANT_DIGITS,
|
||
|
"features": map[string]interface{} {
|
||
|
"spot": map[string]interface{} {
|
||
|
"sandbox": false,
|
||
|
"createOrder": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"triggerPrice": false,
|
||
|
"triggerPriceType": nil,
|
||
|
"triggerDirection": false,
|
||
|
"stopLossPrice": false,
|
||
|
"takeProfitPrice": false,
|
||
|
"attachedStopLossTakeProfit": nil,
|
||
|
"timeInForce": map[string]interface{} {
|
||
|
"IOC": false,
|
||
|
"FOK": false,
|
||
|
"PO": false,
|
||
|
"GTD": false,
|
||
|
},
|
||
|
"hedged": false,
|
||
|
"trailing": false,
|
||
|
"leverage": false,
|
||
|
"marketBuyRequiresPrice": false,
|
||
|
"marketBuyByCost": false,
|
||
|
"selfTradePrevention": false,
|
||
|
"iceberg": false,
|
||
|
},
|
||
|
"createOrders": nil,
|
||
|
"fetchMyTrades": nil,
|
||
|
"fetchOrder": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"trigger": false,
|
||
|
"trailing": false,
|
||
|
"symbolRequired": true,
|
||
|
},
|
||
|
"fetchOpenOrders": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"limit": 1000,
|
||
|
"trigger": false,
|
||
|
"trailing": false,
|
||
|
"symbolRequired": true,
|
||
|
},
|
||
|
"fetchOrders": nil,
|
||
|
"fetchClosedOrders": nil,
|
||
|
"fetchOHLCV": map[string]interface{} {
|
||
|
"limit": 1000,
|
||
|
},
|
||
|
},
|
||
|
"swap": map[string]interface{} {
|
||
|
"linear": nil,
|
||
|
"inverse": nil,
|
||
|
},
|
||
|
"future": map[string]interface{} {
|
||
|
"linear": nil,
|
||
|
"inverse": nil,
|
||
|
},
|
||
|
},
|
||
|
"exceptions": map[string]interface{} {
|
||
|
"Bad Request(SSL)": BadRequest,
|
||
|
"Bad Request(Bad Method)": BadRequest,
|
||
|
"Bad Request.(Auth Data)": AuthenticationError,
|
||
|
"Not Member": AuthenticationError,
|
||
|
"Invalid Apikey": AuthenticationError,
|
||
|
"Method Not Allowed.(Access IP)": PermissionDenied,
|
||
|
"Method Not Allowed.(BTC Adress)": InvalidAddress,
|
||
|
"Method Not Allowed.(Access)": PermissionDenied,
|
||
|
"Database Fail": ExchangeNotAvailable,
|
||
|
"Invalid Parameter": BadRequest,
|
||
|
"5600": ExchangeError,
|
||
|
"Unknown Error": ExchangeError,
|
||
|
"After May 23th, recent_transactions is no longer, hence users will not be able to connect to recent_transactions": ExchangeError,
|
||
|
},
|
||
|
"timeframes": map[string]interface{} {
|
||
|
"1m": "1m",
|
||
|
"3m": "3m",
|
||
|
"5m": "5m",
|
||
|
"10m": "10m",
|
||
|
"30m": "30m",
|
||
|
"1h": "1h",
|
||
|
"6h": "6h",
|
||
|
"12h": "12h",
|
||
|
"1d": "24h",
|
||
|
},
|
||
|
"options": map[string]interface{} {
|
||
|
"quoteCurrencies": map[string]interface{} {
|
||
|
"BTC": map[string]interface{} {
|
||
|
"limits": map[string]interface{} {
|
||
|
"cost": map[string]interface{} {
|
||
|
"min": 0.0002,
|
||
|
"max": 100,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"KRW": map[string]interface{} {
|
||
|
"limits": map[string]interface{} {
|
||
|
"cost": map[string]interface{} {
|
||
|
"min": 500,
|
||
|
"max": 5000000000,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"commonCurrencies": map[string]interface{} {
|
||
|
"ALT": "ArchLoot",
|
||
|
"FTC": "FTC2",
|
||
|
"SOC": "Soda Coin",
|
||
|
},
|
||
|
})
|
||
|
}
|
||
|
func (this *bithumb) SafeMarket(optionalArgs ...interface{}) interface{} {
|
||
|
// bithumb has a different type of conflict in markets, because
|
||
|
// their ids are the base currency (BTC for instance), so we can have
|
||
|
// multiple "BTC" ids representing the different markets (BTC/ETH, "BTC/DOGE", etc)
|
||
|
// since they're the same we just need to return one
|
||
|
marketId := GetArg(optionalArgs, 0, nil)
|
||
|
_ = marketId
|
||
|
market := GetArg(optionalArgs, 1, nil)
|
||
|
_ = market
|
||
|
delimiter := GetArg(optionalArgs, 2, nil)
|
||
|
_ = delimiter
|
||
|
marketType := GetArg(optionalArgs, 3, nil)
|
||
|
_ = marketType
|
||
|
return this.Exchange.SafeMarket(marketId, market, delimiter, "spot")
|
||
|
}
|
||
|
func (this *bithumb) AmountToPrecision(symbol interface{}, amount interface{}) interface{} {
|
||
|
return this.DecimalToPrecision(amount, TRUNCATE, GetValue(GetValue(GetValue(this.Markets, symbol), "precision"), "amount"), DECIMAL_PLACES)
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#fetchMarkets
|
||
|
* @description retrieves data on all markets for bithumb
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%ED%98%84%EC%9E%AC%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C-all
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object[]} an array of objects representing market data
|
||
|
*/
|
||
|
func (this *bithumb) 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
|
||
|
var result interface{} = []interface{}{}
|
||
|
var quoteCurrencies interface{} = this.SafeDict(this.Options, "quoteCurrencies", map[string]interface{} {})
|
||
|
var quotes interface{} = ObjectKeys(quoteCurrencies)
|
||
|
var promises interface{} = []interface{}{}
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(quotes)); i++ {
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"quoteId": GetValue(quotes, i),
|
||
|
}
|
||
|
AppendToArray(&promises,this.PublicGetTickerALLQuoteId(this.Extend(request, params)))
|
||
|
}
|
||
|
|
||
|
results:= (<-promiseAll(promises))
|
||
|
PanicOnError(results)
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(quotes)); i++ {
|
||
|
var quote interface{} = GetValue(quotes, i)
|
||
|
var quoteId interface{} = quote
|
||
|
var response interface{} = GetValue(results, i)
|
||
|
var data interface{} = this.SafeDict(response, "data")
|
||
|
var extension interface{} = this.SafeDict(quoteCurrencies, quote, map[string]interface{} {})
|
||
|
var currencyIds interface{} = ObjectKeys(data)
|
||
|
for j := 0; IsLessThan(j, GetArrayLength(currencyIds)); j++ {
|
||
|
var currencyId interface{} = GetValue(currencyIds, j)
|
||
|
if IsTrue(IsEqual(currencyId, "date")) {
|
||
|
continue
|
||
|
}
|
||
|
var market interface{} = GetValue(data, currencyId)
|
||
|
var base interface{} = this.SafeCurrencyCode(currencyId)
|
||
|
var active interface{} = true
|
||
|
if IsTrue(IsArray(market)) {
|
||
|
var numElements interface{} = GetArrayLength(market)
|
||
|
if IsTrue(IsEqual(numElements, 0)) {
|
||
|
active = false
|
||
|
}
|
||
|
}
|
||
|
var entry interface{} = this.DeepExtend(map[string]interface{} {
|
||
|
"id": currencyId,
|
||
|
"symbol": Add(Add(base, "/"), quote),
|
||
|
"base": base,
|
||
|
"quote": quote,
|
||
|
"settle": nil,
|
||
|
"baseId": currencyId,
|
||
|
"quoteId": quoteId,
|
||
|
"settleId": nil,
|
||
|
"type": "spot",
|
||
|
"spot": true,
|
||
|
"margin": false,
|
||
|
"swap": false,
|
||
|
"future": false,
|
||
|
"option": false,
|
||
|
"active": active,
|
||
|
"contract": false,
|
||
|
"linear": nil,
|
||
|
"inverse": nil,
|
||
|
"contractSize": nil,
|
||
|
"expiry": nil,
|
||
|
"expiryDateTime": nil,
|
||
|
"strike": nil,
|
||
|
"optionType": nil,
|
||
|
"precision": map[string]interface{} {
|
||
|
"amount": ParseInt("4"),
|
||
|
"price": ParseInt("4"),
|
||
|
},
|
||
|
"limits": map[string]interface{} {
|
||
|
"leverage": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": nil,
|
||
|
},
|
||
|
"amount": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": nil,
|
||
|
},
|
||
|
"price": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": nil,
|
||
|
},
|
||
|
"cost": map[string]interface{} {},
|
||
|
},
|
||
|
"created": nil,
|
||
|
"info": market,
|
||
|
}, extension)
|
||
|
AppendToArray(&result,entry)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ch <- result
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bithumb) ParseBalance(response interface{}) interface{} {
|
||
|
var result interface{} = map[string]interface{} {
|
||
|
"info": response,
|
||
|
}
|
||
|
var balances interface{} = this.SafeDict(response, "data")
|
||
|
var codes interface{} = ObjectKeys(this.Currencies)
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(codes)); i++ {
|
||
|
var code interface{} = GetValue(codes, i)
|
||
|
var account interface{} = this.Account()
|
||
|
var currency interface{} = this.Currency(code)
|
||
|
var lowerCurrencyId interface{} = this.SafeStringLower(currency, "id")
|
||
|
AddElementToObject(account, "total", this.SafeString(balances, Add("total_", lowerCurrencyId)))
|
||
|
AddElementToObject(account, "used", this.SafeString(balances, Add("in_use_", lowerCurrencyId)))
|
||
|
AddElementToObject(account, "free", this.SafeString(balances, Add("available_", lowerCurrencyId)))
|
||
|
AddElementToObject(result, code, account)
|
||
|
}
|
||
|
return this.SafeBalance(result)
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#fetchBalance
|
||
|
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%EB%B3%B4%EC%9C%A0%EC%9E%90%EC%82%B0-%EC%A1%B0%ED%9A%8C
|
||
|
* @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 *bithumb) 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
|
||
|
|
||
|
retRes4108 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes4108)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"currency": "ALL",
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivatePostInfoBalance(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
ch <- this.ParseBalance(response)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#fetchOrderBook
|
||
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%ED%98%B8%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C
|
||
|
* @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 *bithumb) 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
|
||
|
|
||
|
retRes4298 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes4298)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"baseId": GetValue(market, "baseId"),
|
||
|
"quoteId": GetValue(market, "quoteId"),
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "count", limit) // default 30, max 30
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetOrderbookBaseIdQuoteId(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "status":"0000",
|
||
|
// "data":{
|
||
|
// "timestamp":"1587621553942",
|
||
|
// "payment_currency":"KRW",
|
||
|
// "order_currency":"BTC",
|
||
|
// "bids":[
|
||
|
// {"price":"8652000","quantity":"0.0043"},
|
||
|
// {"price":"8651000","quantity":"0.0049"},
|
||
|
// {"price":"8650000","quantity":"8.4791"},
|
||
|
// ],
|
||
|
// "asks":[
|
||
|
// {"price":"8654000","quantity":"0.119"},
|
||
|
// {"price":"8655000","quantity":"0.254"},
|
||
|
// {"price":"8658000","quantity":"0.119"},
|
||
|
// ]
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
||
|
var timestamp interface{} = this.SafeInteger(data, "timestamp")
|
||
|
|
||
|
ch <- this.ParseOrderBook(data, symbol, timestamp, "bids", "asks", "price", "quantity")
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bithumb) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// fetchTicker, fetchTickers
|
||
|
//
|
||
|
// {
|
||
|
// "opening_price":"227100",
|
||
|
// "closing_price":"228400",
|
||
|
// "min_price":"222300",
|
||
|
// "max_price":"230000",
|
||
|
// "units_traded":"82618.56075337",
|
||
|
// "acc_trade_value":"18767376138.6031",
|
||
|
// "prev_closing_price":"227100",
|
||
|
// "units_traded_24H":"151871.13484676",
|
||
|
// "acc_trade_value_24H":"34247610416.8974",
|
||
|
// "fluctate_24H":"8700",
|
||
|
// "fluctate_rate_24H":"3.96",
|
||
|
// "date":"1587710327264", // fetchTickers inject this
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var timestamp interface{} = this.SafeInteger(ticker, "date")
|
||
|
var symbol interface{} = this.SafeSymbol(nil, market)
|
||
|
var open interface{} = this.SafeString(ticker, "opening_price")
|
||
|
var close interface{} = this.SafeString(ticker, "closing_price")
|
||
|
var baseVolume interface{} = this.SafeString(ticker, "units_traded_24H")
|
||
|
var quoteVolume interface{} = this.SafeString(ticker, "acc_trade_value_24H")
|
||
|
return this.SafeTicker(map[string]interface{} {
|
||
|
"symbol": symbol,
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"high": this.SafeString(ticker, "max_price"),
|
||
|
"low": this.SafeString(ticker, "min_price"),
|
||
|
"bid": this.SafeString(ticker, "buy_price"),
|
||
|
"bidVolume": nil,
|
||
|
"ask": this.SafeString(ticker, "sell_price"),
|
||
|
"askVolume": nil,
|
||
|
"vwap": nil,
|
||
|
"open": open,
|
||
|
"close": close,
|
||
|
"last": close,
|
||
|
"previousClose": nil,
|
||
|
"change": nil,
|
||
|
"percentage": nil,
|
||
|
"average": nil,
|
||
|
"baseVolume": baseVolume,
|
||
|
"quoteVolume": quoteVolume,
|
||
|
"info": ticker,
|
||
|
}, market)
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#fetchTickers
|
||
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%ED%98%84%EC%9E%AC%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C-all
|
||
|
* @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 *bithumb) 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
|
||
|
|
||
|
retRes5238 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes5238)
|
||
|
var result interface{} = map[string]interface{} {}
|
||
|
var quoteCurrencies interface{} = this.SafeDict(this.Options, "quoteCurrencies", map[string]interface{} {})
|
||
|
var quotes interface{} = ObjectKeys(quoteCurrencies)
|
||
|
var promises interface{} = []interface{}{}
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(quotes)); i++ {
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"quoteId": GetValue(quotes, i),
|
||
|
}
|
||
|
AppendToArray(&promises,this.PublicGetTickerALLQuoteId(this.Extend(request, params)))
|
||
|
}
|
||
|
|
||
|
responses:= (<-promiseAll(promises))
|
||
|
PanicOnError(responses)
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(quotes)); i++ {
|
||
|
var quote interface{} = GetValue(quotes, i)
|
||
|
var response interface{} = GetValue(responses, i)
|
||
|
//
|
||
|
// {
|
||
|
// "status":"0000",
|
||
|
// "data":{
|
||
|
// "BTC":{
|
||
|
// "opening_price":"9045000",
|
||
|
// "closing_price":"9132000",
|
||
|
// "min_price":"8938000",
|
||
|
// "max_price":"9168000",
|
||
|
// "units_traded":"4619.79967497",
|
||
|
// "acc_trade_value":"42021363832.5187",
|
||
|
// "prev_closing_price":"9041000",
|
||
|
// "units_traded_24H":"8793.5045804",
|
||
|
// "acc_trade_value_24H":"78933458515.4962",
|
||
|
// "fluctate_24H":"530000",
|
||
|
// "fluctate_rate_24H":"6.16"
|
||
|
// },
|
||
|
// "date":"1587710878669"
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
||
|
var timestamp interface{} = this.SafeInteger(data, "date")
|
||
|
var tickers interface{} = this.Omit(data, "date")
|
||
|
var currencyIds interface{} = ObjectKeys(tickers)
|
||
|
for j := 0; IsLessThan(j, GetArrayLength(currencyIds)); j++ {
|
||
|
var currencyId interface{} = GetValue(currencyIds, j)
|
||
|
var ticker interface{} = GetValue(data, currencyId)
|
||
|
var base interface{} = this.SafeCurrencyCode(currencyId)
|
||
|
var symbol interface{} = Add(Add(base, "/"), quote)
|
||
|
var market interface{} = this.SafeMarket(symbol)
|
||
|
AddElementToObject(ticker, "date", timestamp)
|
||
|
AddElementToObject(result, symbol, this.ParseTicker(ticker, market))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ch <- this.FilterByArrayTickers(result, "symbol", symbols)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#fetchTicker
|
||
|
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%ED%98%84%EC%9E%AC%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C
|
||
|
* @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 *bithumb) 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
|
||
|
|
||
|
retRes5868 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes5868)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"baseId": GetValue(market, "baseId"),
|
||
|
"quoteId": GetValue(market, "quoteId"),
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetTickerBaseIdQuoteId(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "status":"0000",
|
||
|
// "data":{
|
||
|
// "opening_price":"227100",
|
||
|
// "closing_price":"228400",
|
||
|
// "min_price":"222300",
|
||
|
// "max_price":"230000",
|
||
|
// "units_traded":"82618.56075337",
|
||
|
// "acc_trade_value":"18767376138.6031",
|
||
|
// "prev_closing_price":"227100",
|
||
|
// "units_traded_24H":"151871.13484676",
|
||
|
// "acc_trade_value_24H":"34247610416.8974",
|
||
|
// "fluctate_24H":"8700",
|
||
|
// "fluctate_rate_24H":"3.96",
|
||
|
// "date":"1587710327264"
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
||
|
|
||
|
ch <- this.ParseTicker(data, market)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bithumb) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// [
|
||
|
// 1576823400000, // 기준 시간
|
||
|
// "8284000", // 시가
|
||
|
// "8286000", // 종가
|
||
|
// "8289000", // 고가
|
||
|
// "8276000", // 저가
|
||
|
// "15.41503692" // 거래량
|
||
|
// ]
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
return []interface{}{this.SafeInteger(ohlcv, 0), this.SafeNumber(ohlcv, 1), this.SafeNumber(ohlcv, 3), this.SafeNumber(ohlcv, 4), this.SafeNumber(ohlcv, 2), this.SafeNumber(ohlcv, 5)}
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#fetchOHLCV
|
||
|
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/candlestick-rest-api
|
||
|
* @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
|
||
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
||
|
*/
|
||
|
func (this *bithumb) 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
|
||
|
|
||
|
retRes6508 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes6508)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"baseId": GetValue(market, "baseId"),
|
||
|
"quoteId": GetValue(market, "quoteId"),
|
||
|
"interval": this.SafeString(this.Timeframes, timeframe, timeframe),
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetCandlestickBaseIdQuoteIdInterval(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "status": "0000",
|
||
|
// "data": {
|
||
|
// [
|
||
|
// 1576823400000, // 기준 시간
|
||
|
// "8284000", // 시가
|
||
|
// "8286000", // 종가
|
||
|
// "8289000", // 고가
|
||
|
// "8276000", // 저가
|
||
|
// "15.41503692" // 거래량
|
||
|
// ],
|
||
|
// [
|
||
|
// 1576824000000, // 기준 시간
|
||
|
// "8284000", // 시가
|
||
|
// "8281000", // 종가
|
||
|
// "8289000", // 고가
|
||
|
// "8275000", // 저가
|
||
|
// "6.19584467" // 거래량
|
||
|
// ],
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
||
|
|
||
|
ch <- this.ParseOHLCVs(data, market, timeframe, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bithumb) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// fetchTrades (public)
|
||
|
//
|
||
|
// {
|
||
|
// "transaction_date":"2020-04-23 22:21:46",
|
||
|
// "type":"ask",
|
||
|
// "units_traded":"0.0125",
|
||
|
// "price":"8667000",
|
||
|
// "total":"108337"
|
||
|
// }
|
||
|
//
|
||
|
// fetchOrder (private)
|
||
|
//
|
||
|
// {
|
||
|
// "transaction_date": "1572497603902030",
|
||
|
// "price": "8601000",
|
||
|
// "units": "0.005",
|
||
|
// "fee_currency": "KRW",
|
||
|
// "fee": "107.51",
|
||
|
// "total": "43005"
|
||
|
// }
|
||
|
//
|
||
|
// a workaround for their bug in date format, hours are not 0-padded
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var timestamp interface{} = nil
|
||
|
var transactionDatetime interface{} = this.SafeString(trade, "transaction_date")
|
||
|
if IsTrue(!IsEqual(transactionDatetime, nil)) {
|
||
|
var parts interface{} = Split(transactionDatetime, " ")
|
||
|
var numParts interface{} = GetArrayLength(parts)
|
||
|
if IsTrue(IsGreaterThan(numParts, 1)) {
|
||
|
var transactionDate interface{} = GetValue(parts, 0)
|
||
|
var transactionTime interface{} = GetValue(parts, 1)
|
||
|
if IsTrue(IsLessThan(GetLength(transactionTime), 8)) {
|
||
|
transactionTime = Add("0", transactionTime)
|
||
|
}
|
||
|
timestamp = this.Parse8601(Add(Add(transactionDate, " "), transactionTime))
|
||
|
} else {
|
||
|
timestamp = this.SafeIntegerProduct(trade, "transaction_date", 0.001)
|
||
|
}
|
||
|
}
|
||
|
if IsTrue(!IsEqual(timestamp, nil)) {
|
||
|
timestamp = Subtract(timestamp, Multiply(9, 3600000)) // they report UTC + 9 hours, server in Korean timezone
|
||
|
}
|
||
|
var typeVar interface{} = nil
|
||
|
var side interface{} = this.SafeString(trade, "type")
|
||
|
side = Ternary(IsTrue((IsEqual(side, "ask"))), "sell", "buy")
|
||
|
var id interface{} = this.SafeString(trade, "cont_no")
|
||
|
market = this.SafeMarket(nil, market)
|
||
|
var priceString interface{} = this.SafeString(trade, "price")
|
||
|
var amountString interface{} = this.FixCommaNumber(this.SafeString2(trade, "units_traded", "units"))
|
||
|
var costString interface{} = this.SafeString(trade, "total")
|
||
|
var fee interface{} = nil
|
||
|
var feeCostString interface{} = this.SafeString(trade, "fee")
|
||
|
if IsTrue(!IsEqual(feeCostString, nil)) {
|
||
|
var feeCurrencyId interface{} = this.SafeString(trade, "fee_currency")
|
||
|
var feeCurrencyCode interface{} = this.CommonCurrencyCode(feeCurrencyId)
|
||
|
fee = map[string]interface{} {
|
||
|
"cost": feeCostString,
|
||
|
"currency": feeCurrencyCode,
|
||
|
}
|
||
|
}
|
||
|
return this.SafeTrade(map[string]interface{} {
|
||
|
"id": id,
|
||
|
"info": trade,
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"symbol": GetValue(market, "symbol"),
|
||
|
"order": nil,
|
||
|
"type": typeVar,
|
||
|
"side": side,
|
||
|
"takerOrMaker": nil,
|
||
|
"price": priceString,
|
||
|
"amount": amountString,
|
||
|
"cost": costString,
|
||
|
"fee": fee,
|
||
|
}, market)
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#fetchTrades
|
||
|
* @description get the list of most recent trades for a particular symbol
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%EC%B5%9C%EA%B7%BC-%EC%B2%B4%EA%B2%B0-%EB%82%B4%EC%97%AD
|
||
|
* @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 *bithumb) 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
|
||
|
|
||
|
retRes7758 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes7758)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"baseId": GetValue(market, "baseId"),
|
||
|
"quoteId": GetValue(market, "quoteId"),
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "count", limit) // default 20, max 100
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetTransactionHistoryBaseIdQuoteId(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "status":"0000",
|
||
|
// "data":[
|
||
|
// {
|
||
|
// "transaction_date":"2020-04-23 22:21:46",
|
||
|
// "type":"ask",
|
||
|
// "units_traded":"0.0125",
|
||
|
// "price":"8667000",
|
||
|
// "total":"108337"
|
||
|
// },
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
||
|
|
||
|
ch <- this.ParseTrades(data, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#createOrder
|
||
|
* @description create a trade order
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%EC%A7%80%EC%A0%95%EA%B0%80-%EC%A3%BC%EB%AC%B8%ED%95%98%EA%B8%B0
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%EC%8B%9C%EC%9E%A5%EA%B0%80-%EB%A7%A4%EC%88%98%ED%95%98%EA%B8%B0
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%EC%8B%9C%EC%9E%A5%EA%B0%80-%EB%A7%A4%EB%8F%84%ED%95%98%EA%B8%B0
|
||
|
* @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 *bithumb) 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
|
||
|
|
||
|
retRes8198 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes8198)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"order_currency": GetValue(market, "id"),
|
||
|
"payment_currency": GetValue(market, "quote"),
|
||
|
"units": amount,
|
||
|
}
|
||
|
var method interface{} = "privatePostTradePlace"
|
||
|
if IsTrue(IsEqual(typeVar, "limit")) {
|
||
|
AddElementToObject(request, "price", price)
|
||
|
AddElementToObject(request, "type", Ternary(IsTrue((IsEqual(side, "buy"))), "bid", "ask"))
|
||
|
} else {
|
||
|
method = Add("privatePostTradeMarket", this.Capitalize(side))
|
||
|
}
|
||
|
|
||
|
response:= (<-this.callDynamically(method, this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
var id interface{} = this.SafeString(response, "order_id")
|
||
|
if IsTrue(IsEqual(id, nil)) {
|
||
|
panic(InvalidOrder(Add(this.Id, " createOrder() did not return an order id")))
|
||
|
}
|
||
|
|
||
|
ch <- this.SafeOrder(map[string]interface{} {
|
||
|
"info": response,
|
||
|
"symbol": symbol,
|
||
|
"type": typeVar,
|
||
|
"side": side,
|
||
|
"id": id,
|
||
|
}, market)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#fetchOrder
|
||
|
* @description fetches information on an order made by the user
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%EA%B1%B0%EB%9E%98-%EC%A3%BC%EB%AC%B8%EB%82%B4%EC%97%AD-%EC%83%81%EC%84%B8-%EC%A1%B0%ED%9A%8C
|
||
|
* @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 *bithumb) 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")))
|
||
|
}
|
||
|
|
||
|
retRes8618 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes8618)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"order_id": id,
|
||
|
"count": 1,
|
||
|
"order_currency": GetValue(market, "base"),
|
||
|
"payment_currency": GetValue(market, "quote"),
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivatePostInfoOrderDetail(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "status": "0000",
|
||
|
// "data": {
|
||
|
// "order_date": "1603161798539254",
|
||
|
// "type": "ask",
|
||
|
// "order_status": "Cancel",
|
||
|
// "order_currency": "BTC",
|
||
|
// "payment_currency": "KRW",
|
||
|
// "watch_price": "0",
|
||
|
// "order_price": "13344000",
|
||
|
// "order_qty": "0.0125",
|
||
|
// "cancel_date": "1603161803809993",
|
||
|
// "cancel_type": "사용자취소",
|
||
|
// "contract": [
|
||
|
// {
|
||
|
// "transaction_date": "1603161799976383",
|
||
|
// "price": "13344000",
|
||
|
// "units": "0.0015",
|
||
|
// "fee_currency": "KRW",
|
||
|
// "fee": "0",
|
||
|
// "total": "20016"
|
||
|
// }
|
||
|
// ],
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeDict(response, "data")
|
||
|
|
||
|
ch <- this.ParseOrder(this.Extend(data, map[string]interface{} {
|
||
|
"order_id": id,
|
||
|
}), market)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bithumb) ParseOrderStatus(status interface{}) interface{} {
|
||
|
var statuses interface{} = map[string]interface{} {
|
||
|
"Pending": "open",
|
||
|
"Completed": "closed",
|
||
|
"Cancel": "canceled",
|
||
|
}
|
||
|
return this.SafeString(statuses, status, status)
|
||
|
}
|
||
|
func (this *bithumb) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
//
|
||
|
// fetchOrder
|
||
|
//
|
||
|
// {
|
||
|
// "transaction_date": "1572497603668315",
|
||
|
// "type": "bid",
|
||
|
// "order_status": "Completed", // Completed, Cancel ...
|
||
|
// "order_currency": "BTC",
|
||
|
// "payment_currency": "KRW",
|
||
|
// "watch_price": "0", // present in Cancel order
|
||
|
// "order_price": "8601000",
|
||
|
// "order_qty": "0.007",
|
||
|
// "cancel_date": "", // filled in Cancel order
|
||
|
// "cancel_type": "", // filled in Cancel order, i.e. 사용자취소
|
||
|
// "contract": [
|
||
|
// {
|
||
|
// "transaction_date": "1572497603902030",
|
||
|
// "price": "8601000",
|
||
|
// "units": "0.005",
|
||
|
// "fee_currency": "KRW",
|
||
|
// "fee": "107.51",
|
||
|
// "total": "43005"
|
||
|
// },
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
// fetchOpenOrders
|
||
|
//
|
||
|
// {
|
||
|
// "order_currency": "BTC",
|
||
|
// "payment_currency": "KRW",
|
||
|
// "order_id": "C0101000007408440032",
|
||
|
// "order_date": "1571728739360570",
|
||
|
// "type": "bid",
|
||
|
// "units": "5.0",
|
||
|
// "units_remaining": "5.0",
|
||
|
// "price": "501000",
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var timestamp interface{} = this.SafeIntegerProduct(order, "order_date", 0.001)
|
||
|
var sideProperty interface{} = this.SafeString2(order, "type", "side")
|
||
|
var side interface{} = Ternary(IsTrue((IsEqual(sideProperty, "bid"))), "buy", "sell")
|
||
|
var status interface{} = this.ParseOrderStatus(this.SafeString(order, "order_status"))
|
||
|
var price interface{} = this.SafeString2(order, "order_price", "price")
|
||
|
var typeVar interface{} = "limit"
|
||
|
if IsTrue(Precise.StringEquals(price, "0")) {
|
||
|
typeVar = "market"
|
||
|
}
|
||
|
var amount interface{} = this.FixCommaNumber(this.SafeString2(order, "order_qty", "units"))
|
||
|
var remaining interface{} = this.FixCommaNumber(this.SafeString(order, "units_remaining"))
|
||
|
if IsTrue(IsEqual(remaining, nil)) {
|
||
|
if IsTrue(IsEqual(status, "closed")) {
|
||
|
remaining = "0"
|
||
|
} else if IsTrue(!IsEqual(status, "canceled")) {
|
||
|
remaining = amount
|
||
|
}
|
||
|
}
|
||
|
var symbol interface{} = nil
|
||
|
var baseId interface{} = this.SafeString(order, "order_currency")
|
||
|
var quoteId interface{} = this.SafeString(order, "payment_currency")
|
||
|
var base interface{} = this.SafeCurrencyCode(baseId)
|
||
|
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
||
|
if IsTrue(IsTrue((!IsEqual(base, nil))) && IsTrue((!IsEqual(quote, nil)))) {
|
||
|
symbol = Add(Add(base, "/"), quote)
|
||
|
}
|
||
|
if IsTrue(IsEqual(symbol, nil)) {
|
||
|
market = this.SafeMarket(nil, market)
|
||
|
symbol = GetValue(market, "symbol")
|
||
|
}
|
||
|
var id interface{} = this.SafeString(order, "order_id")
|
||
|
var rawTrades interface{} = this.SafeList(order, "contract", []interface{}{})
|
||
|
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": nil,
|
||
|
"postOnly": nil,
|
||
|
"side": side,
|
||
|
"price": price,
|
||
|
"triggerPrice": nil,
|
||
|
"amount": amount,
|
||
|
"cost": nil,
|
||
|
"average": nil,
|
||
|
"filled": nil,
|
||
|
"remaining": remaining,
|
||
|
"status": status,
|
||
|
"fee": nil,
|
||
|
"trades": rawTrades,
|
||
|
}, market)
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#fetchOpenOrders
|
||
|
* @description fetch all unfilled currently open orders
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%EA%B1%B0%EB%9E%98-%EC%A3%BC%EB%AC%B8%EB%82%B4%EC%97%AD-%EC%A1%B0%ED%9A%8C
|
||
|
* @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 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 *bithumb) 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
|
||
|
if IsTrue(IsEqual(symbol, nil)) {
|
||
|
panic(ArgumentsRequired(Add(this.Id, " fetchOpenOrders() requires a symbol argument")))
|
||
|
}
|
||
|
|
||
|
retRes10238 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes10238)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
if IsTrue(IsEqual(limit, nil)) {
|
||
|
limit = 100
|
||
|
}
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"count": limit,
|
||
|
"order_currency": GetValue(market, "base"),
|
||
|
"payment_currency": GetValue(market, "quote"),
|
||
|
}
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "after", since)
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivatePostInfoOrders(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "status": "0000",
|
||
|
// "data": [
|
||
|
// {
|
||
|
// "order_currency": "BTC",
|
||
|
// "payment_currency": "KRW",
|
||
|
// "order_id": "C0101000007408440032",
|
||
|
// "order_date": "1571728739360570",
|
||
|
// "type": "bid",
|
||
|
// "units": "5.0",
|
||
|
// "units_remaining": "5.0",
|
||
|
// "price": "501000",
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
||
|
|
||
|
ch <- this.ParseOrders(data, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#cancelOrder
|
||
|
* @description cancels an open order
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%EC%A3%BC%EB%AC%B8-%EC%B7%A8%EC%86%8C%ED%95%98%EA%B8%B0
|
||
|
* @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 *bithumb) 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
|
||
|
if IsTrue(IsEqual(symbol, nil)) {
|
||
|
panic(ArgumentsRequired(Add(this.Id, " cancelOrder() requires a symbol argument")))
|
||
|
}
|
||
|
var side_in_params interface{} = (InOp(params, "side"))
|
||
|
if !IsTrue(side_in_params) {
|
||
|
panic(ArgumentsRequired(Add(this.Id, " cancelOrder() requires a `side` parameter (sell or buy)")))
|
||
|
}
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var side interface{} = Ternary(IsTrue((IsEqual(GetValue(params, "side"), "buy"))), "bid", "ask")
|
||
|
params = this.Omit(params, []interface{}{"side", "currency"})
|
||
|
// https://github.com/ccxt/ccxt/issues/6771
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"order_id": id,
|
||
|
"type": side,
|
||
|
"order_currency": GetValue(market, "base"),
|
||
|
"payment_currency": GetValue(market, "quote"),
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivatePostTradeCancel(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// {
|
||
|
// 'status': 'string',
|
||
|
// }
|
||
|
//
|
||
|
ch <- this.SafeOrder(map[string]interface{} {
|
||
|
"info": response,
|
||
|
})
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bithumb) CancelUnifiedOrder(order 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
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"side": GetValue(order, "side"),
|
||
|
}
|
||
|
|
||
|
retRes110115 := (<-this.CancelOrder(GetValue(order, "id"), GetValue(order, "symbol"), this.Extend(request, params)))
|
||
|
PanicOnError(retRes110115)
|
||
|
ch <- retRes110115
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bithumb#withdraw
|
||
|
* @description make a withdrawal
|
||
|
* @see https://apidocs.bithumb.com/v1.2.0/reference/%EC%BD%94%EC%9D%B8-%EC%B6%9C%EA%B8%88%ED%95%98%EA%B8%B0-%EA%B0%9C%EC%9D%B8
|
||
|
* @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 *bithumb) 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)
|
||
|
|
||
|
retRes11198 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes11198)
|
||
|
var currency interface{} = this.Currency(code)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"units": amount,
|
||
|
"address": address,
|
||
|
"currency": GetValue(currency, "id"),
|
||
|
}
|
||
|
if IsTrue(IsTrue(IsTrue(IsTrue(IsTrue(IsEqual(code, "XRP")) || IsTrue(IsEqual(code, "XMR"))) || IsTrue(IsEqual(code, "EOS"))) || IsTrue(IsEqual(code, "STEEM"))) || IsTrue(IsEqual(code, "TON"))) {
|
||
|
var destination interface{} = this.SafeString(params, "destination")
|
||
|
if IsTrue(IsTrue((IsEqual(tag, nil))) && IsTrue((IsEqual(destination, nil)))) {
|
||
|
panic(ArgumentsRequired(Add(Add(Add(this.Id, " "), code), " withdraw() requires a tag argument or an extra destination param")))
|
||
|
} else if IsTrue(!IsEqual(tag, nil)) {
|
||
|
AddElementToObject(request, "destination", tag)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivatePostTradeBtcWithdrawal(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// { "status" : "0000"}
|
||
|
//
|
||
|
ch <- this.ParseTransaction(response, currency)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bithumb) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// withdraw
|
||
|
//
|
||
|
// { "status" : "0000"}
|
||
|
//
|
||
|
currency := GetArg(optionalArgs, 0, nil)
|
||
|
_ = currency
|
||
|
currency = this.SafeCurrency(nil, currency)
|
||
|
return map[string]interface{} {
|
||
|
"id": nil,
|
||
|
"txid": nil,
|
||
|
"timestamp": nil,
|
||
|
"datetime": nil,
|
||
|
"network": nil,
|
||
|
"addressFrom": nil,
|
||
|
"address": nil,
|
||
|
"addressTo": nil,
|
||
|
"amount": nil,
|
||
|
"type": nil,
|
||
|
"currency": GetValue(currency, "code"),
|
||
|
"status": nil,
|
||
|
"updated": nil,
|
||
|
"tagFrom": nil,
|
||
|
"tag": nil,
|
||
|
"tagTo": nil,
|
||
|
"comment": nil,
|
||
|
"internal": nil,
|
||
|
"fee": nil,
|
||
|
"info": transaction,
|
||
|
}
|
||
|
}
|
||
|
func (this *bithumb) FixCommaNumber(numberStr interface{}) interface{} {
|
||
|
// some endpoints need this https://github.com/ccxt/ccxt/issues/11031
|
||
|
if IsTrue(IsEqual(numberStr, nil)) {
|
||
|
return nil
|
||
|
}
|
||
|
var finalNumberStr interface{} = numberStr
|
||
|
for IsGreaterThan(GetIndexOf(finalNumberStr, ","), OpNeg(1)) {
|
||
|
finalNumberStr = Replace(finalNumberStr, ",", "")
|
||
|
}
|
||
|
return finalNumberStr
|
||
|
}
|
||
|
func (this *bithumb) Nonce() interface{} {
|
||
|
return this.Milliseconds()
|
||
|
}
|
||
|
func (this *bithumb) 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 endpoint interface{} = Add("/", this.ImplodeParams(path, params))
|
||
|
var url interface{} = Add(this.ImplodeHostname(GetValue(GetValue(this.Urls, "api"), api)), endpoint)
|
||
|
var query interface{} = this.Omit(params, this.ExtractParams(path))
|
||
|
if IsTrue(IsEqual(api, "public")) {
|
||
|
if IsTrue(GetArrayLength(ObjectKeys(query))) {
|
||
|
url = Add(url, Add("?", this.Urlencode(query)))
|
||
|
}
|
||
|
} else {
|
||
|
this.CheckRequiredCredentials()
|
||
|
body = this.Urlencode(this.Extend(map[string]interface{} {
|
||
|
"endpoint": endpoint,
|
||
|
}, query))
|
||
|
var nonce interface{} = ToString(this.Nonce())
|
||
|
var auth interface{} = Add(Add(Add(Add(endpoint, "//" + "0"), body), "//" + "0"), nonce) // eslint-disable-line quotes
|
||
|
var signature interface{} = this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha512)
|
||
|
var signature64 interface{} = this.StringToBase64(signature)
|
||
|
headers = map[string]interface{} {
|
||
|
"Accept": "application/json",
|
||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||
|
"Api-Key": this.ApiKey,
|
||
|
"Api-Sign": signature64,
|
||
|
"Api-Nonce": nonce,
|
||
|
}
|
||
|
}
|
||
|
return map[string]interface{} {
|
||
|
"url": url,
|
||
|
"method": method,
|
||
|
"body": body,
|
||
|
"headers": headers,
|
||
|
}
|
||
|
}
|
||
|
func (this *bithumb) 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
|
||
|
}
|
||
|
if IsTrue(InOp(response, "status")) {
|
||
|
//
|
||
|
// {"status":"5100","message":"After May 23th, recent_transactions is no longer, hence users will not be able to connect to recent_transactions"}
|
||
|
//
|
||
|
var status interface{} = this.SafeString(response, "status")
|
||
|
var message interface{} = this.SafeString(response, "message")
|
||
|
if IsTrue(!IsEqual(status, nil)) {
|
||
|
if IsTrue(IsEqual(status, "0000")) {
|
||
|
return nil // no error
|
||
|
} else if IsTrue(IsEqual(message, "거래 진행중인 내역이 존재하지 않습니다.")) {
|
||
|
// https://github.com/ccxt/ccxt/issues/9017
|
||
|
return nil // no error
|
||
|
}
|
||
|
var feedback interface{} = Add(Add(this.Id, " "), message)
|
||
|
this.ThrowExactlyMatchedException(this.Exceptions, status, feedback)
|
||
|
this.ThrowExactlyMatchedException(this.Exceptions, message, feedback)
|
||
|
panic(ExchangeError(feedback))
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
|
||
|
func (this *bithumb) Init(userConfig map[string]interface{}) {
|
||
|
this.Exchange = Exchange{}
|
||
|
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
|
||
|
this.Exchange.DerivedExchange = this
|
||
|
}
|