3287 lines
149 KiB
Go
3287 lines
149 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 exmo struct {
|
|
Exchange
|
|
|
|
}
|
|
|
|
func NewExmoCore() exmo {
|
|
p := exmo{}
|
|
setDefaults(&p)
|
|
return p
|
|
}
|
|
|
|
func (this *exmo) Describe() interface{} {
|
|
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
|
|
"id": "exmo",
|
|
"name": "EXMO",
|
|
"countries": []interface{}{"LT"},
|
|
"rateLimit": 100,
|
|
"version": "v1.1",
|
|
"has": map[string]interface{} {
|
|
"CORS": nil,
|
|
"spot": true,
|
|
"margin": true,
|
|
"swap": false,
|
|
"future": false,
|
|
"option": false,
|
|
"addMargin": true,
|
|
"cancelOrder": true,
|
|
"cancelOrders": false,
|
|
"createDepositAddress": false,
|
|
"createMarketBuyOrder": true,
|
|
"createMarketBuyOrderWithCost": true,
|
|
"createMarketOrderWithCost": true,
|
|
"createOrder": true,
|
|
"createStopLimitOrder": true,
|
|
"createStopMarketOrder": true,
|
|
"createStopOrder": true,
|
|
"editOrder": true,
|
|
"fetchAccounts": false,
|
|
"fetchBalance": true,
|
|
"fetchCanceledOrders": true,
|
|
"fetchCurrencies": true,
|
|
"fetchDeposit": true,
|
|
"fetchDepositAddress": true,
|
|
"fetchDepositAddresses": false,
|
|
"fetchDepositAddressesByNetwork": false,
|
|
"fetchDeposits": true,
|
|
"fetchDepositsWithdrawals": true,
|
|
"fetchDepositWithdrawFee": "emulated",
|
|
"fetchDepositWithdrawFees": true,
|
|
"fetchFundingHistory": false,
|
|
"fetchFundingRate": false,
|
|
"fetchFundingRateHistory": false,
|
|
"fetchFundingRates": false,
|
|
"fetchIndexOHLCV": false,
|
|
"fetchMarginMode": false,
|
|
"fetchMarkets": true,
|
|
"fetchMarkOHLCV": false,
|
|
"fetchMyTrades": true,
|
|
"fetchOHLCV": true,
|
|
"fetchOpenInterestHistory": false,
|
|
"fetchOpenOrders": true,
|
|
"fetchOrder": "emulated",
|
|
"fetchOrderBook": true,
|
|
"fetchOrderBooks": true,
|
|
"fetchOrderTrades": true,
|
|
"fetchPosition": false,
|
|
"fetchPositionHistory": false,
|
|
"fetchPositionMode": false,
|
|
"fetchPositions": false,
|
|
"fetchPositionsHistory": false,
|
|
"fetchPositionsRisk": false,
|
|
"fetchPremiumIndexOHLCV": false,
|
|
"fetchTicker": true,
|
|
"fetchTickers": true,
|
|
"fetchTrades": true,
|
|
"fetchTradingFee": false,
|
|
"fetchTradingFees": true,
|
|
"fetchTransactionFees": true,
|
|
"fetchTransactions": "emulated",
|
|
"fetchTransfer": false,
|
|
"fetchTransfers": false,
|
|
"fetchWithdrawal": true,
|
|
"fetchWithdrawals": true,
|
|
"reduceMargin": true,
|
|
"setMargin": false,
|
|
"transfer": false,
|
|
"withdraw": true,
|
|
},
|
|
"timeframes": map[string]interface{} {
|
|
"1m": "1",
|
|
"5m": "5",
|
|
"15m": "15",
|
|
"30m": "30",
|
|
"45m": "45",
|
|
"1h": "60",
|
|
"2h": "120",
|
|
"3h": "180",
|
|
"4h": "240",
|
|
"1d": "D",
|
|
"1w": "W",
|
|
"1M": "M",
|
|
},
|
|
"urls": map[string]interface{} {
|
|
"logo": "https://user-images.githubusercontent.com/1294454/27766491-1b0ea956-5eda-11e7-9225-40d67b481b8d.jpg",
|
|
"api": map[string]interface{} {
|
|
"public": "https://api.exmo.com",
|
|
"private": "https://api.exmo.com",
|
|
"web": "https://exmo.me",
|
|
},
|
|
"www": "https://exmo.me",
|
|
"referral": "https://exmo.me/?ref=131685",
|
|
"doc": []interface{}{"https://exmo.me/en/api_doc?ref=131685"},
|
|
"fees": "https://exmo.com/en/docs/fees",
|
|
},
|
|
"api": map[string]interface{} {
|
|
"web": map[string]interface{} {
|
|
"get": []interface{}{"ctrl/feesAndLimits", "en/docs/fees"},
|
|
},
|
|
"public": map[string]interface{} {
|
|
"get": []interface{}{"currency", "currency/list/extended", "order_book", "pair_settings", "ticker", "trades", "candles_history", "required_amount", "payments/providers/crypto/list"},
|
|
},
|
|
"private": map[string]interface{} {
|
|
"post": []interface{}{"user_info", "order_create", "order_cancel", "stop_market_order_create", "stop_market_order_cancel", "user_open_orders", "user_trades", "user_cancelled_orders", "order_trades", "deposit_address", "withdraw_crypt", "withdraw_get_txid", "excode_create", "excode_load", "code_check", "wallet_history", "wallet_operations", "margin/user/order/create", "margin/user/order/update", "margin/user/order/cancel", "margin/user/position/close", "margin/user/position/margin_add", "margin/user/position/margin_remove", "margin/currency/list", "margin/pair/list", "margin/settings", "margin/funding/list", "margin/user/info", "margin/user/order/list", "margin/user/order/history", "margin/user/order/trades", "margin/user/order/max_quantity", "margin/user/position/list", "margin/user/position/margin_remove_info", "margin/user/position/margin_add_info", "margin/user/wallet/list", "margin/user/wallet/history", "margin/user/trade/list", "margin/trades", "margin/liquidation/feed"},
|
|
},
|
|
},
|
|
"fees": map[string]interface{} {
|
|
"trading": map[string]interface{} {
|
|
"feeSide": "get",
|
|
"tierBased": true,
|
|
"percentage": true,
|
|
"maker": this.ParseNumber("0.004"),
|
|
"taker": this.ParseNumber("0.004"),
|
|
},
|
|
"transaction": map[string]interface{} {
|
|
"tierBased": false,
|
|
"percentage": false,
|
|
},
|
|
},
|
|
"options": map[string]interface{} {
|
|
"networks": map[string]interface{} {
|
|
"ETH": "ERC20",
|
|
"TRX": "TRC20",
|
|
},
|
|
"fetchTradingFees": map[string]interface{} {
|
|
"method": "fetchPrivateTradingFees",
|
|
},
|
|
"margin": map[string]interface{} {
|
|
"fillResponseFromRequest": true,
|
|
},
|
|
},
|
|
"features": map[string]interface{} {
|
|
"spot": map[string]interface{} {
|
|
"sandbox": false,
|
|
"createOrder": map[string]interface{} {
|
|
"marginMode": true,
|
|
"triggerPrice": true,
|
|
"triggerPriceType": nil,
|
|
"triggerDirection": false,
|
|
"stopLossPrice": false,
|
|
"takeProfitPrice": false,
|
|
"attachedStopLossTakeProfit": nil,
|
|
"timeInForce": map[string]interface{} {
|
|
"IOC": true,
|
|
"FOK": true,
|
|
"PO": true,
|
|
"GTD": true,
|
|
},
|
|
"hedged": false,
|
|
"selfTradePrevention": false,
|
|
"trailing": false,
|
|
"leverage": true,
|
|
"marketBuyByCost": true,
|
|
"marketBuyRequiresPrice": false,
|
|
"iceberg": false,
|
|
},
|
|
"createOrders": nil,
|
|
"fetchMyTrades": map[string]interface{} {
|
|
"marginMode": true,
|
|
"limit": 100,
|
|
"daysBack": nil,
|
|
"untilDays": nil,
|
|
"symbolRequired": true,
|
|
},
|
|
"fetchOrder": map[string]interface{} {
|
|
"marginMode": false,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOpenOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": nil,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"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,
|
|
},
|
|
},
|
|
"commonCurrencies": map[string]interface{} {
|
|
"GMT": "GMT Token",
|
|
},
|
|
"precisionMode": TICK_SIZE,
|
|
"exceptions": map[string]interface{} {
|
|
"exact": map[string]interface{} {
|
|
"140333": InvalidOrder,
|
|
"140434": BadRequest,
|
|
"40005": AuthenticationError,
|
|
"40009": InvalidNonce,
|
|
"40015": ExchangeError,
|
|
"40016": OnMaintenance,
|
|
"40017": AuthenticationError,
|
|
"40032": PermissionDenied,
|
|
"40033": PermissionDenied,
|
|
"40034": RateLimitExceeded,
|
|
"50052": InsufficientFunds,
|
|
"50054": InsufficientFunds,
|
|
"50304": OrderNotFound,
|
|
"50173": OrderNotFound,
|
|
"50277": InvalidOrder,
|
|
"50319": InvalidOrder,
|
|
"50321": InvalidOrder,
|
|
"50381": InvalidOrder,
|
|
},
|
|
"broad": map[string]interface{} {
|
|
"range period is too long": BadRequest,
|
|
"invalid syntax": BadRequest,
|
|
"API rate limit exceeded": RateLimitExceeded,
|
|
},
|
|
},
|
|
})
|
|
}
|
|
func (this *exmo) ModifyMarginHelper(symbol interface{}, amount interface{}, typeVar 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
|
|
|
|
retRes3088 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes3088)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"position_id": GetValue(market, "id"),
|
|
"quantity": amount,
|
|
}
|
|
var response interface{} = nil
|
|
if IsTrue(IsEqual(typeVar, "add")) {
|
|
|
|
response = (<-this.PrivatePostMarginUserPositionMarginAdd(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(IsEqual(typeVar, "reduce")) {
|
|
|
|
response = (<-this.PrivatePostMarginUserPositionMarginRemove(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
//
|
|
// {}
|
|
//
|
|
var margin interface{} = this.ParseMarginModification(response, market)
|
|
var options interface{} = this.SafeValue(this.Options, "margin", map[string]interface{} {})
|
|
var fillResponseFromRequest interface{} = this.SafeBool(options, "fillResponseFromRequest", true)
|
|
if IsTrue(fillResponseFromRequest) {
|
|
AddElementToObject(margin, "type", typeVar)
|
|
AddElementToObject(margin, "amount", amount)
|
|
}
|
|
|
|
ch <- margin
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) ParseMarginModification(data interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {}
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
return map[string]interface{} {
|
|
"info": data,
|
|
"symbol": this.SafeSymbol(nil, market),
|
|
"type": nil,
|
|
"marginMode": "isolated",
|
|
"amount": nil,
|
|
"total": nil,
|
|
"code": this.SafeValue(market, "quote"),
|
|
"status": "ok",
|
|
"timestamp": nil,
|
|
"datetime": nil,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#reduceMargin
|
|
* @description remove margin from a position
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#eebf9f25-0289-4946-9482-89872c738449
|
|
* @param {string} symbol unified market symbol
|
|
* @param {float} amount the amount of margin to remove
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=reduce-margin-structure}
|
|
*/
|
|
func (this *exmo) ReduceMargin(symbol interface{}, amount 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
|
|
|
|
retRes36215 := (<-this.ModifyMarginHelper(symbol, amount, "reduce", params))
|
|
PanicOnError(retRes36215)
|
|
ch <- retRes36215
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#addMargin
|
|
* @description add margin
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#143ef808-79ca-4e49-9e79-a60ea4d8c0e3
|
|
* @param {string} symbol unified market symbol
|
|
* @param {float} amount amount of margin to add
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=add-margin-structure}
|
|
*/
|
|
func (this *exmo) AddMargin(symbol interface{}, amount 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
|
|
|
|
retRes37615 := (<-this.ModifyMarginHelper(symbol, amount, "add", params))
|
|
PanicOnError(retRes37615)
|
|
ch <- retRes37615
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchTradingFees
|
|
* @description fetch the trading fees for multiple markets
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#90927062-256c-4b03-900f-2b99131f9a54
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#7de7e75c-5833-45a8-b937-c2276d235aaa
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
|
|
*/
|
|
func (this *exmo) FetchTradingFees(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
var options interface{} = this.SafeValue(this.Options, "fetchTradingFees", map[string]interface{} {})
|
|
var defaultMethod interface{} = this.SafeString(options, "method", "fetchPrivateTradingFees")
|
|
var method interface{} = this.SafeString(params, "method", defaultMethod)
|
|
params = this.Omit(params, "method")
|
|
if IsTrue(IsEqual(method, "fetchPrivateTradingFees")) {
|
|
|
|
retRes39419 := (<-this.FetchPrivateTradingFees(params))
|
|
PanicOnError(retRes39419)
|
|
ch <- retRes39419
|
|
return nil
|
|
} else {
|
|
|
|
retRes39619 := (<-this.FetchPublicTradingFees(params))
|
|
PanicOnError(retRes39619)
|
|
ch <- retRes39619
|
|
return nil
|
|
}
|
|
return nil
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) FetchPrivateTradingFees(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
|
|
|
|
retRes4018 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes4018)
|
|
|
|
response:= (<-this.PrivatePostMarginPairList(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "pairs": [{
|
|
// "name": "EXM_USD",
|
|
// "buy_price": "0.02728391",
|
|
// "sell_price": "0.0276",
|
|
// "last_trade_price": "0.0276",
|
|
// "ticker_updated": "1646956050056696046",
|
|
// "is_fair_price": true,
|
|
// "max_price_precision": "8",
|
|
// "min_order_quantity": "1",
|
|
// "max_order_quantity": "50000",
|
|
// "min_order_price": "0.00000001",
|
|
// "max_order_price": "1000",
|
|
// "max_position_quantity": "50000",
|
|
// "trade_taker_fee": "0.05",
|
|
// "trade_maker_fee": "0",
|
|
// "liquidation_fee": "0.5",
|
|
// "max_leverage": "3",
|
|
// "default_leverage": "3",
|
|
// "liquidation_level": "5",
|
|
// "margin_call_level": "7.5",
|
|
// "position": "1",
|
|
// "updated": "1638976144797807397"
|
|
// }
|
|
// ...
|
|
// ]
|
|
// }
|
|
//
|
|
var pairs interface{} = this.SafeValue(response, "pairs", []interface{}{})
|
|
var result interface{} = map[string]interface{} {}
|
|
for i := 0; IsLessThan(i, GetArrayLength(pairs)); i++ {
|
|
var pair interface{} = GetValue(pairs, i)
|
|
var marketId interface{} = this.SafeString(pair, "name")
|
|
var symbol interface{} = this.SafeSymbol(marketId, nil, "_")
|
|
var makerString interface{} = this.SafeString(pair, "trade_maker_fee")
|
|
var takerString interface{} = this.SafeString(pair, "trade_taker_fee")
|
|
var maker interface{} = this.ParseNumber(Precise.StringDiv(makerString, "100"))
|
|
var taker interface{} = this.ParseNumber(Precise.StringDiv(takerString, "100"))
|
|
AddElementToObject(result, symbol, map[string]interface{} {
|
|
"info": pair,
|
|
"symbol": symbol,
|
|
"maker": maker,
|
|
"taker": taker,
|
|
"percentage": true,
|
|
"tierBased": true,
|
|
})
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) FetchPublicTradingFees(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
|
|
|
|
retRes4558 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes4558)
|
|
|
|
response:= (<-this.PublicGetPairSettings(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "BTC_USD": {
|
|
// "min_quantity": "0.00002",
|
|
// "max_quantity": "1000",
|
|
// "min_price": "1",
|
|
// "max_price": "150000",
|
|
// "max_amount": "500000",
|
|
// "min_amount": "1",
|
|
// "price_precision": "2",
|
|
// "commission_taker_percent": "0.3",
|
|
// "commission_maker_percent": "0.3"
|
|
// },
|
|
// }
|
|
//
|
|
var result interface{} = map[string]interface{} {}
|
|
for i := 0; IsLessThan(i, GetArrayLength(this.Symbols)); i++ {
|
|
var symbol interface{} = GetValue(this.Symbols, i)
|
|
var market interface{} = this.Market(symbol)
|
|
var fee interface{} = this.SafeValue(response, GetValue(market, "id"), map[string]interface{} {})
|
|
var makerString interface{} = this.SafeString(fee, "commission_maker_percent")
|
|
var takerString interface{} = this.SafeString(fee, "commission_taker_percent")
|
|
var maker interface{} = this.ParseNumber(Precise.StringDiv(makerString, "100"))
|
|
var taker interface{} = this.ParseNumber(Precise.StringDiv(takerString, "100"))
|
|
AddElementToObject(result, symbol, map[string]interface{} {
|
|
"info": fee,
|
|
"symbol": symbol,
|
|
"maker": maker,
|
|
"taker": taker,
|
|
"percentage": true,
|
|
"tierBased": true,
|
|
})
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) ParseFixedFloatValue(input interface{}) interface{} {
|
|
if IsTrue(IsTrue((IsEqual(input, nil))) || IsTrue((IsEqual(input, "-")))) {
|
|
return nil
|
|
}
|
|
if IsTrue(IsEqual(input, "")) {
|
|
return 0
|
|
}
|
|
var isPercentage interface{} = (IsGreaterThanOrEqual(GetIndexOf(input, "%"), 0))
|
|
var parts interface{} = Split(input, " ")
|
|
var value interface{} = Replace(GetValue(parts, 0), "%", "")
|
|
var result interface{} = ParseFloat(value)
|
|
if IsTrue(IsTrue((IsGreaterThan(result, 0))) && IsTrue(isPercentage)) {
|
|
panic(ExchangeError(Add(Add(this.Id, " parseFixedFloatValue() detected an unsupported non-zero percentage-based fee "), input)))
|
|
}
|
|
return result
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchTransactionFees
|
|
* @deprecated
|
|
* @description please use fetchDepositWithdrawFees instead
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#4190035d-24b1-453d-833b-37e0a52f88e2
|
|
* @param {string[]|undefined} codes list of unified currency codes
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a list of [transaction fees structures]{@link https://docs.ccxt.com/#/?id=fees-structure}
|
|
*/
|
|
func (this *exmo) FetchTransactionFees(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
codes := GetArg(optionalArgs, 0, nil)
|
|
_ = codes
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes5218 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes5218)
|
|
|
|
cryptoList:= (<-this.PublicGetPaymentsProvidersCryptoList(params))
|
|
PanicOnError(cryptoList)
|
|
//
|
|
// {
|
|
// "BTC":[
|
|
// { "type":"deposit", "name":"BTC", "currency_name":"BTC", "min":"0.001", "max":"0", "enabled":true,"comment":"Minimum deposit amount is 0.001 BTC. We do not support BSC and BEP20 network, please consider this when sending funds", "commission_desc":"0%", "currency_confirmations":1 },
|
|
// { "type":"withdraw", "name":"BTC", "currency_name":"BTC", "min":"0.001", "max":"350", "enabled":true,"comment":"Do not withdraw directly to the Crowdfunding or ICO address as your account will not be credited with tokens from such sales.", "commission_desc":"0.0005 BTC", "currency_confirmations":6 }
|
|
// ],
|
|
// "ETH":[
|
|
// { "type":"withdraw", "name":"ETH", "currency_name":"ETH", "min":"0.01", "max":"500", "enabled":true,"comment":"Do not withdraw directly to the Crowdfunding or ICO address as your account will not be credited with tokens from such sales.", "commission_desc":"0.004 ETH", "currency_confirmations":4 },
|
|
// { "type":"deposit", "name":"ETH", "currency_name":"ETH", "min":"0.01", "max":"0", "enabled":true,"comment":"Minimum deposit amount is 0.01 ETH. We do not support BSC and BEP20 network, please consider this when sending funds", "commission_desc":"0%", "currency_confirmations":1 }
|
|
// ],
|
|
// "USDT":[
|
|
// { "type":"deposit", "name":"USDT (OMNI)", "currency_name":"USDT", "min":"10", "max":"0", "enabled":false,"comment":"Minimum deposit amount is 10 USDT", "commission_desc":"0%", "currency_confirmations":2 },
|
|
// { "type":"withdraw", "name":"USDT (OMNI)", "currency_name":"USDT", "min":"10", "max":"100000", "enabled":false,"comment":"Do not withdraw directly to the Crowdfunding or ICO address as your account will not be credited with tokens from such sales.", "commission_desc":"5 USDT", "currency_confirmations":6 },
|
|
// { "type":"deposit", "name":"USDT (ERC20)", "currency_name":"USDT", "min":"10", "max":"0", "enabled":true,"comment":"Minimum deposit amount is 10 USDT", "commission_desc":"0%", "currency_confirmations":2 },
|
|
// {
|
|
// "type":"withdraw",
|
|
// "name":"USDT (ERC20)",
|
|
// "currency_name":"USDT",
|
|
// "min":"55",
|
|
// "max":"200000",
|
|
// "enabled":true,
|
|
// "comment":"Caution! Do not withdraw directly to a crowdfund or ICO address, as your account will not be credited with tokens from such sales. Recommendation: Due to the high load of ERC20 network, using TRC20 address for withdrawal is recommended.",
|
|
// "commission_desc":"10 USDT",
|
|
// "currency_confirmations":6
|
|
// },
|
|
// { "type":"deposit", "name":"USDT (TRC20)", "currency_name":"USDT", "min":"10", "max":"100000", "enabled":true,"comment":"Minimum deposit amount is 10 USDT. Only TRON main network supported", "commission_desc":"0%", "currency_confirmations":2 },
|
|
// { "type":"withdraw", "name":"USDT (TRC20)", "currency_name":"USDT", "min":"10", "max":"150000", "enabled":true,"comment":"Caution! Do not withdraw directly to a crowdfund or ICO address, as your account will not be credited with tokens from such sales. Only TRON main network supported.", "commission_desc":"1 USDT", "currency_confirmations":6 }
|
|
// ],
|
|
// "XLM":[
|
|
// { "type":"deposit", "name":"XLM", "currency_name":"XLM", "min":"1", "max":"1000000", "enabled":true,"comment":"Attention! A deposit without memo(invoice) will not be credited. Minimum deposit amount is 1 XLM. We do not support BSC and BEP20 network, please consider this when sending funds", "commission_desc":"0%", "currency_confirmations":1 },
|
|
// { "type":"withdraw", "name":"XLM", "currency_name":"XLM", "min":"21", "max":"1000000", "enabled":true,"comment":"Caution! Do not withdraw directly to a crowdfund or ICO address, as your account will not be credited with tokens from such sales.", "commission_desc":"0.01 XLM", "currency_confirmations":1 }
|
|
// ],
|
|
// }
|
|
//
|
|
var result interface{} = map[string]interface{} {}
|
|
var cryptoListKeys interface{} = ObjectKeys(cryptoList)
|
|
for i := 0; IsLessThan(i, GetArrayLength(cryptoListKeys)); i++ {
|
|
var code interface{} = GetValue(cryptoListKeys, i)
|
|
if IsTrue(IsTrue(!IsEqual(codes, nil)) && !IsTrue(this.InArray(code, codes))) {
|
|
continue
|
|
}
|
|
AddElementToObject(result, code, map[string]interface{} {
|
|
"deposit": nil,
|
|
"withdraw": nil,
|
|
})
|
|
var currency interface{} = this.Currency(code)
|
|
var currencyId interface{} = this.SafeString(currency, "id")
|
|
var providers interface{} = this.SafeValue(cryptoList, currencyId, []interface{}{})
|
|
for j := 0; IsLessThan(j, GetArrayLength(providers)); j++ {
|
|
var provider interface{} = GetValue(providers, j)
|
|
var typeInner interface{} = this.SafeString(provider, "type")
|
|
var commissionDesc interface{} = this.SafeString(provider, "commission_desc")
|
|
var fee interface{} = this.ParseFixedFloatValue(commissionDesc)
|
|
AddElementToObject(GetValue(result, code), typeInner, fee)
|
|
}
|
|
AddElementToObject(GetValue(result, code), "info", providers)
|
|
}
|
|
// cache them for later use
|
|
AddElementToObject(this.Options, "transactionFees", result)
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchDepositWithdrawFees
|
|
* @description fetch deposit and withdraw fees
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#4190035d-24b1-453d-833b-37e0a52f88e2
|
|
* @param {string[]|undefined} codes list of unified currency codes
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a list of [transaction fees structures]{@link https://docs.ccxt.com/#/?id=fees-structure}
|
|
*/
|
|
func (this *exmo) FetchDepositWithdrawFees(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
codes := GetArg(optionalArgs, 0, nil)
|
|
_ = codes
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes5958 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes5958)
|
|
|
|
response:= (<-this.PublicGetPaymentsProvidersCryptoList(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "USDT": [
|
|
// {
|
|
// "type": "deposit", // or "withdraw"
|
|
// "name": "USDT (ERC20)",
|
|
// "currency_name": "USDT",
|
|
// "min": "10",
|
|
// "max": "0",
|
|
// "enabled": true,
|
|
// "comment": "Minimum deposit amount is 10 USDT",
|
|
// "commission_desc": "0%",
|
|
// "currency_confirmations": 2
|
|
// },
|
|
// ...
|
|
// ],
|
|
// ...
|
|
// }
|
|
//
|
|
var result interface{} = this.ParseDepositWithdrawFees(response, codes)
|
|
// cache them for later use
|
|
AddElementToObject(this.Options, "transactionFees", result)
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) ParseDepositWithdrawFee(fee interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// [
|
|
// {
|
|
// "type": "deposit", // or "withdraw"
|
|
// "name": "BTC",
|
|
// "currency_name": "BTC",
|
|
// "min": "0.001",
|
|
// "max": "0",
|
|
// "enabled": true,
|
|
// "comment": "Minimum deposit amount is 0.001 BTC. We do not support BSC and BEP20 network, please consider this when sending funds",
|
|
// "commission_desc": "0%",
|
|
// "currency_confirmations": 1
|
|
// },
|
|
// ...
|
|
// ]
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var result interface{} = this.DepositWithdrawFee(fee)
|
|
for i := 0; IsLessThan(i, GetArrayLength(fee)); i++ {
|
|
var provider interface{} = GetValue(fee, i)
|
|
var typeVar interface{} = this.SafeString(provider, "type")
|
|
var networkId interface{} = this.SafeString(provider, "name")
|
|
var networkCode interface{} = this.NetworkIdToCode(networkId, this.SafeString(currency, "code"))
|
|
var commissionDesc interface{} = this.SafeString(provider, "commission_desc")
|
|
var splitCommissionDesc interface{} = []interface{}{}
|
|
var percentage interface{} = nil
|
|
if IsTrue(!IsEqual(commissionDesc, nil)) {
|
|
splitCommissionDesc = Split(commissionDesc, "%")
|
|
var splitCommissionDescLength interface{} = GetArrayLength(splitCommissionDesc)
|
|
percentage = IsGreaterThanOrEqual(splitCommissionDescLength, 2)
|
|
}
|
|
var network interface{} = this.SafeValue(GetValue(result, "networks"), networkCode)
|
|
if IsTrue(IsEqual(network, nil)) {
|
|
AddElementToObject(GetValue(result, "networks"), networkCode, map[string]interface{} {
|
|
"withdraw": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
"deposit": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
})
|
|
}
|
|
AddElementToObject(GetValue(GetValue(result, "networks"), networkCode), typeVar, map[string]interface{} {
|
|
"fee": this.ParseFixedFloatValue(this.SafeString(splitCommissionDesc, 0)),
|
|
"percentage": percentage,
|
|
})
|
|
}
|
|
return this.AssignDefaultDepositWithdrawFees(result)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchCurrencies
|
|
* @description fetches all available currencies on an exchange
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#7cdf0ca8-9ff6-4cf3-aa33-bcec83155c49
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#4190035d-24b1-453d-833b-37e0a52f88e2
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} an associative dictionary of currencies
|
|
*/
|
|
func (this *exmo) FetchCurrencies(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
//
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
currencyList:= (<-this.PublicGetCurrencyListExtended(params))
|
|
PanicOnError(currencyList)
|
|
//
|
|
// [
|
|
// {"name":"VLX","description":"Velas"},
|
|
// {"name":"RUB","description":"Russian Ruble"},
|
|
// {"name":"BTC","description":"Bitcoin"},
|
|
// {"name":"USD","description":"US Dollar"}
|
|
// ]
|
|
//
|
|
|
|
cryptoList:= (<-this.PublicGetPaymentsProvidersCryptoList(params))
|
|
PanicOnError(cryptoList)
|
|
//
|
|
// {
|
|
// "BTC":[
|
|
// { "type":"deposit", "name":"BTC", "currency_name":"BTC", "min":"0.001", "max":"0", "enabled":true,"comment":"Minimum deposit amount is 0.001 BTC. We do not support BSC and BEP20 network, please consider this when sending funds", "commission_desc":"0%", "currency_confirmations":1 },
|
|
// { "type":"withdraw", "name":"BTC", "currency_name":"BTC", "min":"0.001", "max":"350", "enabled":true,"comment":"Do not withdraw directly to the Crowdfunding or ICO address as your account will not be credited with tokens from such sales.", "commission_desc":"0.0005 BTC", "currency_confirmations":6 }
|
|
// ],
|
|
// "ETH":[
|
|
// { "type":"withdraw", "name":"ETH", "currency_name":"ETH", "min":"0.01", "max":"500", "enabled":true,"comment":"Do not withdraw directly to the Crowdfunding or ICO address as your account will not be credited with tokens from such sales.", "commission_desc":"0.004 ETH", "currency_confirmations":4 },
|
|
// { "type":"deposit", "name":"ETH", "currency_name":"ETH", "min":"0.01", "max":"0", "enabled":true,"comment":"Minimum deposit amount is 0.01 ETH. We do not support BSC and BEP20 network, please consider this when sending funds", "commission_desc":"0%", "currency_confirmations":1 }
|
|
// ],
|
|
// "USDT":[
|
|
// { "type":"deposit", "name":"USDT (OMNI)", "currency_name":"USDT", "min":"10", "max":"0", "enabled":false,"comment":"Minimum deposit amount is 10 USDT", "commission_desc":"0%", "currency_confirmations":2 },
|
|
// { "type":"withdraw", "name":"USDT (OMNI)", "currency_name":"USDT", "min":"10", "max":"100000", "enabled":false,"comment":"Do not withdraw directly to the Crowdfunding or ICO address as your account will not be credited with tokens from such sales.", "commission_desc":"5 USDT", "currency_confirmations":6 },
|
|
// { "type":"deposit", "name":"USDT (ERC20)", "currency_name":"USDT", "min":"10", "max":"0", "enabled":true,"comment":"Minimum deposit amount is 10 USDT", "commission_desc":"0%", "currency_confirmations":2 },
|
|
// { "type":"withdraw", "name":"USDT (ERC20)", "currency_name":"USDT", "min":"55", "max":"200000", "enabled":true, "comment":"Caution! Do not withdraw directly to a crowdfund or ICO address, as your account will not be credited with tokens from such sales. Recommendation: Due to the high load of ERC20 network, using TRC20 address for withdrawal is recommended.", "commission_desc":"10 USDT", "currency_confirmations":6 },
|
|
// { "type":"deposit", "name":"USDT (TRC20)", "currency_name":"USDT", "min":"10", "max":"100000", "enabled":true,"comment":"Minimum deposit amount is 10 USDT. Only TRON main network supported", "commission_desc":"0%", "currency_confirmations":2 },
|
|
// { "type":"withdraw", "name":"USDT (TRC20)", "currency_name":"USDT", "min":"10", "max":"150000", "enabled":true,"comment":"Caution! Do not withdraw directly to a crowdfund or ICO address, as your account will not be credited with tokens from such sales. Only TRON main network supported.", "commission_desc":"1 USDT", "currency_confirmations":6 }
|
|
// ],
|
|
// "XLM":[
|
|
// { "type":"deposit", "name":"XLM", "currency_name":"XLM", "min":"1", "max":"1000000", "enabled":true,"comment":"Attention! A deposit without memo(invoice) will not be credited. Minimum deposit amount is 1 XLM. We do not support BSC and BEP20 network, please consider this when sending funds", "commission_desc":"0%", "currency_confirmations":1 },
|
|
// { "type":"withdraw", "name":"XLM", "currency_name":"XLM", "min":"21", "max":"1000000", "enabled":true,"comment":"Caution! Do not withdraw directly to a crowdfund or ICO address, as your account will not be credited with tokens from such sales.", "commission_desc":"0.01 XLM", "currency_confirmations":1 }
|
|
// ],
|
|
// }
|
|
//
|
|
var result interface{} = map[string]interface{} {}
|
|
for i := 0; IsLessThan(i, GetArrayLength(currencyList)); i++ {
|
|
var currency interface{} = GetValue(currencyList, i)
|
|
var currencyId interface{} = this.SafeString(currency, "name")
|
|
var name interface{} = this.SafeString(currency, "description")
|
|
var providers interface{} = this.SafeValue(cryptoList, currencyId)
|
|
var active interface{} = false
|
|
var typeVar interface{} = "crypto"
|
|
var limits interface{} = map[string]interface{} {
|
|
"deposit": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"withdraw": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
}
|
|
var fee interface{} = nil
|
|
var depositEnabled interface{} = nil
|
|
var withdrawEnabled interface{} = nil
|
|
if IsTrue(IsEqual(providers, nil)) {
|
|
active = true
|
|
typeVar = "fiat"
|
|
} else {
|
|
for j := 0; IsLessThan(j, GetArrayLength(providers)); j++ {
|
|
var provider interface{} = GetValue(providers, j)
|
|
var typeInner interface{} = this.SafeString(provider, "type")
|
|
var minValue interface{} = this.SafeString(provider, "min")
|
|
var maxValue interface{} = this.SafeString(provider, "max")
|
|
if IsTrue(Precise.StringEq(maxValue, "0.0")) {
|
|
maxValue = nil
|
|
}
|
|
var activeProvider interface{} = this.SafeValue(provider, "enabled")
|
|
if IsTrue(IsEqual(typeInner, "deposit")) {
|
|
if IsTrue(IsTrue(activeProvider) && !IsTrue(depositEnabled)) {
|
|
depositEnabled = true
|
|
} else if !IsTrue(activeProvider) {
|
|
depositEnabled = false
|
|
}
|
|
} else if IsTrue(IsEqual(typeInner, "withdraw")) {
|
|
if IsTrue(IsTrue(activeProvider) && !IsTrue(withdrawEnabled)) {
|
|
withdrawEnabled = true
|
|
} else if !IsTrue(activeProvider) {
|
|
withdrawEnabled = false
|
|
}
|
|
}
|
|
if IsTrue(activeProvider) {
|
|
active = true
|
|
var limitMin interface{} = this.NumberToString(GetValue(GetValue(limits, typeInner), "min"))
|
|
if IsTrue(IsTrue((IsEqual(GetValue(GetValue(limits, typeInner), "min"), nil))) || IsTrue((Precise.StringLt(minValue, limitMin)))) {
|
|
AddElementToObject(GetValue(limits, typeInner), "min", minValue)
|
|
AddElementToObject(GetValue(limits, typeInner), "max", maxValue)
|
|
if IsTrue(IsEqual(typeInner, "withdraw")) {
|
|
var commissionDesc interface{} = this.SafeString(provider, "commission_desc")
|
|
fee = this.ParseFixedFloatValue(commissionDesc)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
|
AddElementToObject(result, code, map[string]interface{} {
|
|
"id": currencyId,
|
|
"code": code,
|
|
"name": name,
|
|
"type": typeVar,
|
|
"active": active,
|
|
"deposit": depositEnabled,
|
|
"withdraw": withdrawEnabled,
|
|
"fee": fee,
|
|
"precision": this.ParseNumber("1e-8"),
|
|
"limits": limits,
|
|
"info": providers,
|
|
"networks": map[string]interface{} {},
|
|
})
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchMarkets
|
|
* @description retrieves data on all markets for exmo
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#7de7e75c-5833-45a8-b937-c2276d235aaa
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} an array of objects representing market data
|
|
*/
|
|
func (this *exmo) 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.PublicGetPairSettings(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "BTC_USD":{
|
|
// "min_quantity":"0.0001",
|
|
// "max_quantity":"1000",
|
|
// "min_price":"1",
|
|
// "max_price":"30000",
|
|
// "max_amount":"500000",
|
|
// "min_amount":"1",
|
|
// "price_precision":8,
|
|
// "commission_taker_percent":"0.4",
|
|
// "commission_maker_percent":"0.4"
|
|
// },
|
|
// }
|
|
//
|
|
var marginPairsDict interface{} = map[string]interface{} {}
|
|
if IsTrue(this.CheckRequiredCredentials(false)) {
|
|
|
|
marginPairs:= (<-this.PrivatePostMarginPairList(params))
|
|
PanicOnError(marginPairs)
|
|
//
|
|
// {
|
|
// "pairs": [
|
|
// {
|
|
// "buy_price": "55978.85",
|
|
// "default_leverage": "3",
|
|
// "is_fair_price": true,
|
|
// "last_trade_price": "55999.23",
|
|
// "liquidation_fee": "2",
|
|
// "liquidation_level": "10",
|
|
// "margin_call_level": "15",
|
|
// "max_leverage": "3",
|
|
// "max_order_price": "150000",
|
|
// "max_order_quantity": "1",
|
|
// "max_position_quantity": "1",
|
|
// "max_price_precision": 2,
|
|
// "min_order_price": "1",
|
|
// "min_order_quantity": "0.00002",
|
|
// "name": "BTC_USD",
|
|
// "position": 1,
|
|
// "sell_price": "55985.51",
|
|
// "ticker_updated": "1619019818936107989",
|
|
// "trade_maker_fee": "0",
|
|
// "trade_taker_fee": "0.05",
|
|
// "updated": "1619008608955599013"
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
var pairs interface{} = this.SafeValue(marginPairs, "pairs")
|
|
marginPairsDict = this.IndexBy(pairs, "name")
|
|
}
|
|
var keys interface{} = ObjectKeys(response)
|
|
var result interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ {
|
|
var id interface{} = GetValue(keys, i)
|
|
var market interface{} = GetValue(response, id)
|
|
var marginMarket interface{} = this.SafeValue(marginPairsDict, id)
|
|
var symbol interface{} = Replace(id, "_", "/")
|
|
baseIdquoteIdVariable := Split(symbol, "/");
|
|
baseId := GetValue(baseIdquoteIdVariable,0);
|
|
quoteId := GetValue(baseIdquoteIdVariable,1)
|
|
var base interface{} = this.SafeCurrencyCode(baseId)
|
|
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
|
var takerString interface{} = this.SafeString(market, "commission_taker_percent")
|
|
var makerString interface{} = this.SafeString(market, "commission_maker_percent")
|
|
var maxQuantity interface{} = this.SafeString(market, "max_quantity")
|
|
var marginMaxQuantity interface{} = this.SafeString(marginMarket, "max_order_quantity")
|
|
AppendToArray(&result,map[string]interface{} {
|
|
"id": id,
|
|
"symbol": symbol,
|
|
"base": base,
|
|
"quote": quote,
|
|
"settle": nil,
|
|
"baseId": baseId,
|
|
"quoteId": quoteId,
|
|
"settleId": nil,
|
|
"type": "spot",
|
|
"spot": true,
|
|
"margin": !IsEqual(marginMarket, nil),
|
|
"swap": false,
|
|
"future": false,
|
|
"option": false,
|
|
"active": nil,
|
|
"contract": false,
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
"taker": this.ParseNumber(Precise.StringDiv(takerString, "100")),
|
|
"maker": this.ParseNumber(Precise.StringDiv(makerString, "100")),
|
|
"contractSize": nil,
|
|
"expiry": nil,
|
|
"expiryDatetime": nil,
|
|
"strike": nil,
|
|
"optionType": nil,
|
|
"precision": map[string]interface{} {
|
|
"amount": this.ParseNumber("1e-8"),
|
|
"price": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "price_precision"))),
|
|
},
|
|
"limits": map[string]interface{} {
|
|
"leverage": map[string]interface{} {
|
|
"min": nil,
|
|
"max": this.SafeNumber(market, "leverage"),
|
|
},
|
|
"amount": map[string]interface{} {
|
|
"min": this.SafeNumber(market, "min_quantity"),
|
|
"max": this.ParseNumber(Precise.StringMax(maxQuantity, marginMaxQuantity)),
|
|
},
|
|
"price": map[string]interface{} {
|
|
"min": this.SafeNumber(market, "min_price"),
|
|
"max": this.SafeNumber(market, "max_price"),
|
|
},
|
|
"cost": map[string]interface{} {
|
|
"min": this.SafeNumber(market, "min_amount"),
|
|
"max": this.SafeNumber(market, "max_amount"),
|
|
},
|
|
},
|
|
"created": nil,
|
|
"info": market,
|
|
})
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchOHLCV
|
|
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#65eeb949-74e5-4631-9184-c38387fe53e8
|
|
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
* @param {string} timeframe the length of time each candle represents
|
|
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
* @param {int} [limit] the maximum amount of candles to fetch
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] timestamp in ms of the latest candle to fetch
|
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
*/
|
|
func (this *exmo) 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
|
|
|
|
retRes9428 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes9428)
|
|
var market interface{} = this.Market(symbol)
|
|
var until interface{} = this.SafeIntegerProduct(params, "until", 0.001)
|
|
var untilIsDefined interface{} = (!IsEqual(until, nil))
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
"resolution": this.SafeString(this.Timeframes, timeframe, timeframe),
|
|
}
|
|
var maxLimit interface{} = 3000
|
|
var duration interface{} = this.ParseTimeframe(timeframe)
|
|
var now interface{} = this.ParseToInt(Divide(this.Milliseconds(), 1000))
|
|
if IsTrue(IsEqual(since, nil)) {
|
|
var to interface{} = Ternary(IsTrue(untilIsDefined), mathMin(until, now), now)
|
|
if IsTrue(IsEqual(limit, nil)) {
|
|
limit = 1000 // cap default at generous amount
|
|
} else {
|
|
limit = mathMin(limit, maxLimit)
|
|
}
|
|
AddElementToObject(request, "from", Subtract(Subtract(to, (Multiply(limit, duration))), 1))
|
|
AddElementToObject(request, "to", to)
|
|
} else {
|
|
AddElementToObject(request, "from", Subtract(this.ParseToInt(Divide(since, 1000)), 1))
|
|
if IsTrue(untilIsDefined) {
|
|
AddElementToObject(request, "to", mathMin(until, now))
|
|
} else {
|
|
if IsTrue(IsEqual(limit, nil)) {
|
|
limit = maxLimit
|
|
} else {
|
|
limit = mathMin(limit, maxLimit)
|
|
}
|
|
var to interface{} = this.Sum(since, Multiply(limit, duration))
|
|
AddElementToObject(request, "to", mathMin(to, now))
|
|
}
|
|
}
|
|
params = this.Omit(params, "until")
|
|
|
|
response:= (<-this.PublicGetCandlesHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "candles":[
|
|
// {"t":1584057600000,"o":0.02235144,"c":0.02400233,"h":0.025171,"l":0.02221,"v":5988.34031761},
|
|
// {"t":1584144000000,"o":0.0240373,"c":0.02367413,"h":0.024399,"l":0.0235,"v":2027.82522329},
|
|
// {"t":1584230400000,"o":0.02363458,"c":0.02319242,"h":0.0237948,"l":0.02223196,"v":1707.96944997},
|
|
// ]
|
|
// }
|
|
//
|
|
var candles interface{} = this.SafeList(response, "candles", []interface{}{})
|
|
|
|
ch <- this.ParseOHLCVs(candles, market, timeframe, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "t":1584057600000,
|
|
// "o":0.02235144,
|
|
// "c":0.02400233,
|
|
// "h":0.025171,
|
|
// "l":0.02221,
|
|
// "v":5988.34031761
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
return []interface{}{this.SafeInteger(ohlcv, "t"), this.SafeNumber(ohlcv, "o"), this.SafeNumber(ohlcv, "h"), this.SafeNumber(ohlcv, "l"), this.SafeNumber(ohlcv, "c"), this.SafeNumber(ohlcv, "v")}
|
|
}
|
|
func (this *exmo) ParseBalance(response interface{}) interface{} {
|
|
var result interface{} = map[string]interface{} {
|
|
"info": response,
|
|
}
|
|
var wallets interface{} = this.SafeValue(response, "wallets")
|
|
if IsTrue(!IsEqual(wallets, nil)) {
|
|
var currencyIds interface{} = ObjectKeys(wallets)
|
|
for i := 0; IsLessThan(i, GetArrayLength(currencyIds)); i++ {
|
|
var currencyId interface{} = GetValue(currencyIds, i)
|
|
var item interface{} = GetValue(wallets, currencyId)
|
|
var currency interface{} = this.SafeCurrencyCode(currencyId)
|
|
var account interface{} = this.Account()
|
|
AddElementToObject(account, "used", this.SafeString(item, "used"))
|
|
AddElementToObject(account, "free", this.SafeString(item, "free"))
|
|
AddElementToObject(account, "total", this.SafeString(item, "balance"))
|
|
AddElementToObject(result, currency, account)
|
|
}
|
|
} else {
|
|
var free interface{} = this.SafeValue(response, "balances", map[string]interface{} {})
|
|
var used interface{} = this.SafeValue(response, "reserved", map[string]interface{} {})
|
|
var currencyIds interface{} = ObjectKeys(free)
|
|
for i := 0; IsLessThan(i, GetArrayLength(currencyIds)); i++ {
|
|
var currencyId interface{} = GetValue(currencyIds, i)
|
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
|
var account interface{} = this.Account()
|
|
if IsTrue(InOp(free, currencyId)) {
|
|
AddElementToObject(account, "free", this.SafeString(free, currencyId))
|
|
}
|
|
if IsTrue(InOp(used, currencyId)) {
|
|
AddElementToObject(account, "used", this.SafeString(used, currencyId))
|
|
}
|
|
AddElementToObject(result, code, account)
|
|
}
|
|
}
|
|
return this.SafeBalance(result)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchBalance
|
|
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#59c5160f-27a1-4d9a-8cfb-7979c7ffaac6
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#c8388df7-1f9f-4d41-81c4-5a387d171dc6
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.marginMode] *isolated* fetches the isolated margin balance
|
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
*/
|
|
func (this *exmo) 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
|
|
|
|
retRes10588 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes10588)
|
|
var marginMode interface{} = nil
|
|
marginModeparamsVariable := this.HandleMarginModeAndParams("fetchBalance", params);
|
|
marginMode = GetValue(marginModeparamsVariable,0);
|
|
params = GetValue(marginModeparamsVariable,1)
|
|
if IsTrue(IsEqual(marginMode, "cross")) {
|
|
panic(BadRequest(Add(this.Id, " does not support cross margin")))
|
|
}
|
|
var response interface{} = nil
|
|
if IsTrue(IsEqual(marginMode, "isolated")) {
|
|
|
|
response = (<-this.PrivatePostMarginUserWalletList(params))
|
|
PanicOnError(response)
|
|
} else {
|
|
|
|
response = (<-this.PrivatePostUserInfo(params))
|
|
PanicOnError(response)
|
|
}
|
|
|
|
ch <- this.ParseBalance(response)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchOrderBook
|
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#c60c51a8-e683-4f45-a000-820723d37871
|
|
* @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 *exmo) 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
|
|
|
|
retRes11078 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes11078)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.PublicGetOrderBook(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
var result interface{} = this.SafeDict(response, GetValue(market, "id"))
|
|
|
|
ch <- this.ParseOrderBook(result, GetValue(market, "symbol"), nil, "bid", "ask")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchOrderBooks
|
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data for multiple markets
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#c60c51a8-e683-4f45-a000-820723d37871
|
|
* @param {string[]|undefined} symbols list of unified market symbols, all symbols fetched if undefined, default is undefined
|
|
* @param {int} [limit] max number of entries per orderbook to return, default is undefined
|
|
* @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 symbol
|
|
*/
|
|
func (this *exmo) FetchOrderBooks(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbols := GetArg(optionalArgs, 0, nil)
|
|
_ = symbols
|
|
limit := GetArg(optionalArgs, 1, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes11318 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes11318)
|
|
var ids interface{} = nil
|
|
if IsTrue(IsEqual(symbols, nil)) {
|
|
ids = Join(this.Ids, ",")
|
|
// max URL length is 2083 symbols, including http schema, hostname, tld, etc...
|
|
if IsTrue(IsGreaterThan(GetArrayLength(ids), 2048)) {
|
|
var numIds interface{} = GetArrayLength(this.Ids)
|
|
panic(ExchangeError(Add(Add(Add(this.Id, " fetchOrderBooks() has "), ToString(numIds)), " symbols exceeding max URL length, you are required to specify a list of symbols in the first argument to fetchOrderBooks")))
|
|
}
|
|
} else {
|
|
ids = this.MarketIds(symbols)
|
|
ids = Join(ids, ",")
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": ids,
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.PublicGetOrderBook(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
var result interface{} = map[string]interface{} {}
|
|
var marketIds interface{} = ObjectKeys(response)
|
|
for i := 0; IsLessThan(i, GetArrayLength(marketIds)); i++ {
|
|
var marketId interface{} = GetValue(marketIds, i)
|
|
var symbol interface{} = this.SafeSymbol(marketId)
|
|
AddElementToObject(result, symbol, this.ParseOrderBook(GetValue(response, marketId), symbol, nil, "bid", "ask"))
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "buy_price":"0.00002996",
|
|
// "sell_price":"0.00003002",
|
|
// "last_trade":"0.00002992",
|
|
// "high":"0.00003028",
|
|
// "low":"0.00002935",
|
|
// "avg":"0.00002963",
|
|
// "vol":"1196546.3163222",
|
|
// "vol_curr":"35.80066578",
|
|
// "updated":1642291733
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var timestamp interface{} = this.SafeTimestamp(ticker, "updated")
|
|
market = this.SafeMarket(nil, market)
|
|
var last interface{} = this.SafeString(ticker, "last_trade")
|
|
return this.SafeTicker(map[string]interface{} {
|
|
"symbol": GetValue(market, "symbol"),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"high": this.SafeString(ticker, "high"),
|
|
"low": this.SafeString(ticker, "low"),
|
|
"bid": this.SafeString(ticker, "buy_price"),
|
|
"bidVolume": nil,
|
|
"ask": this.SafeString(ticker, "sell_price"),
|
|
"askVolume": nil,
|
|
"vwap": nil,
|
|
"open": nil,
|
|
"close": last,
|
|
"last": last,
|
|
"previousClose": nil,
|
|
"change": nil,
|
|
"percentage": nil,
|
|
"average": this.SafeString(ticker, "avg"),
|
|
"baseVolume": this.SafeString(ticker, "vol"),
|
|
"quoteVolume": this.SafeString(ticker, "vol_curr"),
|
|
"info": ticker,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchTickers
|
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#4c8e6459-3503-4361-b012-c34bb9f7e385
|
|
* @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 *exmo) 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
|
|
|
|
retRes12128 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes12128)
|
|
symbols = this.MarketSymbols(symbols)
|
|
|
|
response:= (<-this.PublicGetTicker(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ADA_BTC":{
|
|
// "buy_price":"0.00002996",
|
|
// "sell_price":"0.00003002",
|
|
// "last_trade":"0.00002992",
|
|
// "high":"0.00003028",
|
|
// "low":"0.00002935",
|
|
// "avg":"0.00002963",
|
|
// "vol":"1196546.3163222",
|
|
// "vol_curr":"35.80066578",
|
|
// "updated":1642291733
|
|
// }
|
|
// }
|
|
//
|
|
var result interface{} = map[string]interface{} {}
|
|
var marketIds interface{} = ObjectKeys(response)
|
|
for i := 0; IsLessThan(i, GetArrayLength(marketIds)); i++ {
|
|
var marketId interface{} = GetValue(marketIds, i)
|
|
var market interface{} = this.SafeMarket(marketId, nil, "_")
|
|
var symbol interface{} = GetValue(market, "symbol")
|
|
var ticker interface{} = this.SafeValue(response, marketId)
|
|
AddElementToObject(result, symbol, this.ParseTicker(ticker, market))
|
|
}
|
|
|
|
ch <- this.FilterByArrayTickers(result, "symbol", symbols)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchTicker
|
|
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#4c8e6459-3503-4361-b012-c34bb9f7e385
|
|
* @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 *exmo) 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
|
|
|
|
retRes12528 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes12528)
|
|
|
|
response:= (<-this.PublicGetTicker(params))
|
|
PanicOnError(response)
|
|
var market interface{} = this.Market(symbol)
|
|
|
|
ch <- this.ParseTicker(GetValue(response, GetValue(market, "id")), market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchTrades (public)
|
|
//
|
|
// {
|
|
// "trade_id":165087520,
|
|
// "date":1587470005,
|
|
// "type":"buy",
|
|
// "quantity":"1.004",
|
|
// "price":"0.02491461",
|
|
// "amount":"0.02501426"
|
|
// },
|
|
//
|
|
// fetchMyTrades, fetchOrderTrades
|
|
//
|
|
// {
|
|
// "trade_id": 3,
|
|
// "date": 1435488248,
|
|
// "type": "buy",
|
|
// "pair": "BTC_USD",
|
|
// "order_id": 12345,
|
|
// "quantity": 1,
|
|
// "price": 100,
|
|
// "amount": 100,
|
|
// "exec_type": "taker",
|
|
// "commission_amount": "0.02",
|
|
// "commission_currency": "BTC",
|
|
// "commission_percent": "0.2"
|
|
// }
|
|
//
|
|
// fetchMyTrades (margin)
|
|
//
|
|
// {
|
|
// "trade_id": "692861757015952517",
|
|
// "trade_dt": "1693951853197811824",
|
|
// "trade_type": "buy",
|
|
// "pair": "ADA_USDT",
|
|
// "quantity": "1.96607879",
|
|
// "price": "0.2568",
|
|
// "amount": "0.50488903"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var timestamp interface{} = this.SafeTimestamp(trade, "date")
|
|
var id interface{} = this.SafeString(trade, "trade_id")
|
|
var orderId interface{} = this.SafeString(trade, "order_id")
|
|
var priceString interface{} = this.SafeString(trade, "price")
|
|
var amountString interface{} = this.SafeString(trade, "quantity")
|
|
var costString interface{} = this.SafeString(trade, "amount")
|
|
var side interface{} = this.SafeString2(trade, "type", "trade_type")
|
|
var typeVar interface{} = nil
|
|
var marketId interface{} = this.SafeString(trade, "pair")
|
|
market = this.SafeMarket(marketId, market, "_")
|
|
var symbol interface{} = GetValue(market, "symbol")
|
|
var isMaker interface{} = this.SafeValue(trade, "is_maker")
|
|
var takerOrMakerDefault interface{} = nil
|
|
if IsTrue(!IsEqual(isMaker, nil)) {
|
|
takerOrMakerDefault = Ternary(IsTrue(isMaker), "maker", "taker")
|
|
}
|
|
var takerOrMaker interface{} = this.SafeString(trade, "exec_type", takerOrMakerDefault)
|
|
var fee interface{} = nil
|
|
var feeCostString interface{} = this.SafeString(trade, "commission_amount")
|
|
if IsTrue(!IsEqual(feeCostString, nil)) {
|
|
var feeCurrencyId interface{} = this.SafeString(trade, "commission_currency")
|
|
var feeCurrencyCode interface{} = this.SafeCurrencyCode(feeCurrencyId)
|
|
var feeRateString interface{} = this.SafeString(trade, "commission_percent")
|
|
if IsTrue(!IsEqual(feeRateString, nil)) {
|
|
feeRateString = Precise.StringDiv(feeRateString, "1000", 18)
|
|
}
|
|
fee = map[string]interface{} {
|
|
"cost": feeCostString,
|
|
"currency": feeCurrencyCode,
|
|
"rate": feeRateString,
|
|
}
|
|
}
|
|
return this.SafeTrade(map[string]interface{} {
|
|
"id": id,
|
|
"info": trade,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"symbol": symbol,
|
|
"order": orderId,
|
|
"type": typeVar,
|
|
"side": side,
|
|
"takerOrMaker": takerOrMaker,
|
|
"price": priceString,
|
|
"amount": amountString,
|
|
"cost": costString,
|
|
"fee": fee,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchTrades
|
|
* @description get the list of most recent trades for a particular symbol
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#5a5a9c0d-cf17-47f6-9d62-6d4404ebd5ac
|
|
* @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 *exmo) 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
|
|
|
|
retRes13618 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes13618)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
|
|
response:= (<-this.PublicGetTrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ETH_BTC":[
|
|
// {
|
|
// "trade_id":165087520,
|
|
// "date":1587470005,
|
|
// "type":"buy",
|
|
// "quantity":"1.004",
|
|
// "price":"0.02491461",
|
|
// "amount":"0.02501426"
|
|
// },
|
|
// {
|
|
// "trade_id":165087369,
|
|
// "date":1587469938,
|
|
// "type":"buy",
|
|
// "quantity":"0.94",
|
|
// "price":"0.02492348",
|
|
// "amount":"0.02342807"
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeList(response, GetValue(market, "id"), []interface{}{})
|
|
|
|
ch <- this.ParseTrades(data, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchMyTrades
|
|
* @description fetch all trades made by the user
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#b8d8d9af-4f46-46a1-939b-ad261d79f452 // spot
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#f4b1aaf8-399f-403b-ab5e-4926d967a106 // margin
|
|
* @param {string} symbol a symbol is required but it can be a single string, or a non-empty array
|
|
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
* @param {int} [limit] *required for margin orders* the maximum number of trades structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
*
|
|
* EXCHANGE SPECIFIC PARAMETERS
|
|
* @param {int} [params.offset] last deal offset, default = 0
|
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
*/
|
|
func (this *exmo) 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")))
|
|
}
|
|
var marginMode interface{} = nil
|
|
marginModeparamsVariable := this.HandleMarginModeAndParams("fetchMyTrades", params);
|
|
marginMode = GetValue(marginModeparamsVariable,0);
|
|
params = GetValue(marginModeparamsVariable,1)
|
|
if IsTrue(IsEqual(marginMode, "cross")) {
|
|
panic(BadRequest(Add(this.Id, " only isolated margin is supported")))
|
|
}
|
|
|
|
retRes14178 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes14178)
|
|
var market interface{} = this.Market(symbol)
|
|
var pair interface{} = GetValue(market, "id")
|
|
var isSpot interface{} = !IsEqual(marginMode, "isolated")
|
|
if IsTrue(IsEqual(limit, nil)) {
|
|
limit = 100
|
|
}
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(isSpot) {
|
|
AddElementToObject(request, "pair", pair)
|
|
} else {
|
|
AddElementToObject(request, "pair_name", pair)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
var offset interface{} = this.SafeInteger(params, "offset", 0)
|
|
AddElementToObject(request, "offset", offset)
|
|
var response interface{} = nil
|
|
if IsTrue(isSpot) {
|
|
|
|
response = (<-this.PrivatePostUserTrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
|
|
responseFromExchange:= (<-this.PrivatePostMarginTrades(this.Extend(request, params)))
|
|
PanicOnError(responseFromExchange)
|
|
//
|
|
// {
|
|
// "trades": {
|
|
// "ADA_USDT": [
|
|
// {
|
|
// "trade_id": "692861757015952517",
|
|
// "trade_dt": "1693951853197811824",
|
|
// "trade_type": "buy",
|
|
// "pair": "ADA_USDT",
|
|
// "quantity": "1.96607879",
|
|
// "price": "0.2568",
|
|
// "amount": "0.50488903"
|
|
// },
|
|
// ]
|
|
// ...
|
|
// }
|
|
// }
|
|
//
|
|
response = this.SafeValue(responseFromExchange, "trades")
|
|
}
|
|
var result interface{} = []interface{}{}
|
|
var marketIdsInner interface{} = ObjectKeys(response)
|
|
for i := 0; IsLessThan(i, GetArrayLength(marketIdsInner)); i++ {
|
|
var marketId interface{} = GetValue(marketIdsInner, i)
|
|
var resultMarket interface{} = this.SafeMarket(marketId, nil, "_")
|
|
var items interface{} = GetValue(response, marketId)
|
|
var trades interface{} = this.ParseTrades(items, resultMarket, since, limit)
|
|
result = this.ArrayConcat(result, trades)
|
|
}
|
|
|
|
ch <- this.FilterBySinceLimit(result, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#createMarketOrderWithCost
|
|
* @description create a market order by providing the symbol, side and cost
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#80daa469-ec59-4d0a-b229-6a311d8dd1cd
|
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
* @param {string} side 'buy' or 'sell'
|
|
* @param {float} cost how much you want to trade in units of the quote currency
|
|
* @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 *exmo) CreateMarketOrderWithCost(symbol interface{}, side interface{}, cost 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
|
|
|
|
retRes15078 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes15078)
|
|
params = this.Extend(params, map[string]interface{} {
|
|
"cost": cost,
|
|
})
|
|
|
|
retRes150915 := (<-this.CreateOrder(symbol, "market", side, cost, nil, params))
|
|
PanicOnError(retRes150915)
|
|
ch <- retRes150915
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#createMarketBuyOrderWithCost
|
|
* @description create a market buy order by providing the symbol and cost
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#80daa469-ec59-4d0a-b229-6a311d8dd1cd
|
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
* @param {float} cost how much you want to trade in units of the quote currency
|
|
* @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 *exmo) CreateMarketBuyOrderWithCost(symbol interface{}, cost 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
|
|
|
|
retRes15238 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes15238)
|
|
params = this.Extend(params, map[string]interface{} {
|
|
"cost": cost,
|
|
})
|
|
|
|
retRes152515 := (<-this.CreateOrder(symbol, "market", "buy", cost, nil, params))
|
|
PanicOnError(retRes152515)
|
|
ch <- retRes152515
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#createMarketSellOrderWithCost
|
|
* @description create a market sell order by providing the symbol and cost
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#80daa469-ec59-4d0a-b229-6a311d8dd1cd
|
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
* @param {float} cost how much you want to trade in units of the quote currency
|
|
* @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 *exmo) CreateMarketSellOrderWithCost(symbol interface{}, cost 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
|
|
|
|
retRes15398 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes15398)
|
|
params = this.Extend(params, map[string]interface{} {
|
|
"cost": cost,
|
|
})
|
|
|
|
retRes154115 := (<-this.CreateOrder(symbol, "market", "sell", cost, nil, params))
|
|
PanicOnError(retRes154115)
|
|
ch <- retRes154115
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#createOrder
|
|
* @description create a trade order
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#80daa469-ec59-4d0a-b229-6a311d8dd1cd
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#de6f4321-eeac-468c-87f7-c4ad7062e265 // stop market
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#3561b86c-9ff1-436e-8e68-ac926b7eb523 // margin
|
|
* @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
|
|
* @param {float} [params.triggerPrice] the price at which a trigger order is triggered at
|
|
* @param {string} [params.timeInForce] *spot only* 'fok', 'ioc' or 'post_only'
|
|
* @param {boolean} [params.postOnly] *spot only* true for post only orders
|
|
* @param {float} [params.cost] *spot only* *market orders only* the cost of the order in the quote currency for market orders
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *exmo) 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
|
|
|
|
retRes15648 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes15648)
|
|
var market interface{} = this.Market(symbol)
|
|
var isMarket interface{} = IsTrue((IsEqual(typeVar, "market"))) && IsTrue((IsEqual(price, nil)))
|
|
var marginMode interface{} = nil
|
|
marginModeparamsVariable := this.HandleMarginModeAndParams("createOrder", params);
|
|
marginMode = GetValue(marginModeparamsVariable,0);
|
|
params = GetValue(marginModeparamsVariable,1)
|
|
if IsTrue(IsEqual(marginMode, "cross")) {
|
|
panic(BadRequest(Add(this.Id, " only supports isolated margin")))
|
|
}
|
|
var isSpot interface{} = (!IsEqual(marginMode, "isolated"))
|
|
var triggerPrice interface{} = this.SafeStringN(params, []interface{}{"triggerPrice", "stopPrice", "stop_price"})
|
|
var cost interface{} = this.SafeString(params, "cost")
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(IsEqual(cost, nil)) {
|
|
AddElementToObject(request, "quantity", this.AmountToPrecision(GetValue(market, "symbol"), amount))
|
|
} else {
|
|
AddElementToObject(request, "quantity", this.CostToPrecision(GetValue(market, "symbol"), cost))
|
|
}
|
|
var clientOrderId interface{} = this.SafeValue2(params, "client_id", "clientOrderId")
|
|
if IsTrue(!IsEqual(clientOrderId, nil)) {
|
|
clientOrderId = this.SafeInteger2(params, "client_id", "clientOrderId")
|
|
if IsTrue(IsEqual(clientOrderId, nil)) {
|
|
panic(BadRequest(Add(this.Id, " createOrder() client order id must be an integer / numeric literal")))
|
|
} else {
|
|
AddElementToObject(request, "client_id", clientOrderId)
|
|
}
|
|
}
|
|
var leverage interface{} = this.SafeNumber(params, "leverage")
|
|
if IsTrue(!IsTrue(isSpot) && IsTrue((IsEqual(leverage, nil)))) {
|
|
panic(ArgumentsRequired(Add(this.Id, " createOrder requires an extra param params[\"leverage\"] for margin orders")))
|
|
}
|
|
params = this.Omit(params, []interface{}{"stopPrice", "stop_price", "triggerPrice", "timeInForce", "client_id", "clientOrderId", "cost"})
|
|
if IsTrue(!IsEqual(price, nil)) {
|
|
AddElementToObject(request, "price", this.PriceToPrecision(GetValue(market, "symbol"), price))
|
|
}
|
|
var response interface{} = nil
|
|
if IsTrue(isSpot) {
|
|
if IsTrue(!IsEqual(triggerPrice, nil)) {
|
|
if IsTrue(IsEqual(typeVar, "limit")) {
|
|
panic(BadRequest(Add(this.Id, " createOrder () cannot create stop limit orders for spot, only stop market")))
|
|
} else {
|
|
AddElementToObject(request, "type", side)
|
|
AddElementToObject(request, "trigger_price", this.PriceToPrecision(symbol, triggerPrice))
|
|
}
|
|
|
|
response = (<-this.PrivatePostStopMarketOrderCreate(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
var execType interface{} = this.SafeString(params, "exec_type")
|
|
var isPostOnly interface{} = nil
|
|
isPostOnlyparamsVariable := this.HandlePostOnly(IsEqual(typeVar, "market"), IsEqual(execType, "post_only"), params);
|
|
isPostOnly = GetValue(isPostOnlyparamsVariable,0);
|
|
params = GetValue(isPostOnlyparamsVariable,1)
|
|
var timeInForce interface{} = this.SafeString(params, "timeInForce")
|
|
AddElementToObject(request, "price", Ternary(IsTrue(isMarket), 0, this.PriceToPrecision(GetValue(market, "symbol"), price)))
|
|
if IsTrue(IsEqual(typeVar, "limit")) {
|
|
AddElementToObject(request, "type", side)
|
|
} else if IsTrue(IsEqual(typeVar, "market")) {
|
|
var marketSuffix interface{} = Ternary(IsTrue((!IsEqual(cost, nil))), "_total", "")
|
|
AddElementToObject(request, "type", Add(Add("market_", side), marketSuffix))
|
|
}
|
|
if IsTrue(isPostOnly) {
|
|
AddElementToObject(request, "exec_type", "post_only")
|
|
} else if IsTrue(!IsEqual(timeInForce, nil)) {
|
|
AddElementToObject(request, "exec_type", timeInForce)
|
|
}
|
|
|
|
response = (<-this.PrivatePostOrderCreate(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
} else {
|
|
if IsTrue(!IsEqual(triggerPrice, nil)) {
|
|
AddElementToObject(request, "stop_price", this.PriceToPrecision(symbol, triggerPrice))
|
|
if IsTrue(IsEqual(typeVar, "limit")) {
|
|
AddElementToObject(request, "type", Add("stop_limit_", side))
|
|
} else if IsTrue(IsEqual(typeVar, "market")) {
|
|
AddElementToObject(request, "type", Add("stop_", side))
|
|
} else {
|
|
AddElementToObject(request, "type", typeVar)
|
|
}
|
|
} else {
|
|
if IsTrue(IsTrue(IsEqual(typeVar, "limit")) || IsTrue(IsEqual(typeVar, "market"))) {
|
|
AddElementToObject(request, "type", Add(Add(typeVar, "_"), side))
|
|
} else {
|
|
AddElementToObject(request, "type", typeVar)
|
|
}
|
|
}
|
|
|
|
response = (<-this.PrivatePostMarginUserOrderCreate(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
|
|
ch <- this.ParseOrder(response, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#cancelOrder
|
|
* @description cancels an open order
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#1f710d4b-75bc-4b65-ad68-006f863a3f26
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#a4d0aae8-28f7-41ac-94fd-c4030130453d // stop market
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#705dfec5-2b35-4667-862b-faf54eca6209 // margin
|
|
* @param {string} id order id
|
|
* @param {string} symbol not used by exmo cancelOrder ()
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {boolean} [params.trigger] true to cancel a trigger order
|
|
* @param {string} [params.marginMode] set to 'cross' or 'isolated' to cancel a margin order
|
|
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *exmo) 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
|
|
|
|
retRes16758 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes16758)
|
|
var request interface{} = map[string]interface{} {}
|
|
var trigger interface{} = this.SafeValue2(params, "trigger", "stop")
|
|
params = this.Omit(params, []interface{}{"trigger", "stop"})
|
|
var marginMode interface{} = nil
|
|
marginModeparamsVariable := this.HandleMarginModeAndParams("cancelOrder", params);
|
|
marginMode = GetValue(marginModeparamsVariable,0);
|
|
params = GetValue(marginModeparamsVariable,1)
|
|
if IsTrue(IsEqual(marginMode, "cross")) {
|
|
panic(BadRequest(Add(this.Id, " only supports isolated margin")))
|
|
}
|
|
var response interface{} = nil
|
|
if IsTrue((IsEqual(marginMode, "isolated"))) {
|
|
AddElementToObject(request, "order_id", id)
|
|
|
|
response = (<-this.PrivatePostMarginUserOrderCancel(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
if IsTrue(trigger) {
|
|
AddElementToObject(request, "parent_order_id", id)
|
|
|
|
response = (<-this.PrivatePostStopMarketOrderCancel(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
AddElementToObject(request, "order_id", id)
|
|
|
|
response = (<-this.PrivatePostOrderCancel(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
}
|
|
|
|
ch <- this.ParseOrder(response)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchOrder
|
|
* @description *spot only* fetches information on an order made by the user
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#cf27781e-28e5-4b39-a52d-3110f5d22459 // spot
|
|
* @param {string} id order id
|
|
* @param {string} symbol not used by exmo 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 *exmo) 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
|
|
|
|
retRes17238 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes17238)
|
|
var request interface{} = map[string]interface{} {
|
|
"order_id": ToString(id),
|
|
}
|
|
|
|
response:= (<-this.PrivatePostOrderTrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "type": "buy",
|
|
// "in_currency": "BTC",
|
|
// "in_amount": "1",
|
|
// "out_currency": "USD",
|
|
// "out_amount": "100",
|
|
// "trades": [
|
|
// {
|
|
// "trade_id": 3,
|
|
// "date": 1435488248,
|
|
// "type": "buy",
|
|
// "pair": "BTC_USD",
|
|
// "order_id": 12345,
|
|
// "quantity": 1,
|
|
// "price": 100,
|
|
// "amount": 100
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
var order interface{} = this.ParseOrder(response)
|
|
AddElementToObject(order, "id", ToString(id))
|
|
|
|
ch <- order
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchOrderTrades
|
|
* @description fetch all the trades made from a single order
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#cf27781e-28e5-4b39-a52d-3110f5d22459 // spot
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#00810661-9119-46c5-aec5-55abe9cb42c7 // margin
|
|
* @param {string} id order id
|
|
* @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 to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.marginMode] set to "isolated" to fetch trades for a margin order
|
|
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
*/
|
|
func (this *exmo) FetchOrderTrades(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
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
var marginMode interface{} = nil
|
|
marginModeparamsVariable := this.HandleMarginModeAndParams("fetchOrderTrades", params);
|
|
marginMode = GetValue(marginModeparamsVariable,0);
|
|
params = GetValue(marginModeparamsVariable,1)
|
|
if IsTrue(IsEqual(marginMode, "cross")) {
|
|
panic(BadRequest(Add(this.Id, " only supports isolated margin")))
|
|
}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"order_id": ToString(id),
|
|
}
|
|
var response interface{} = nil
|
|
if IsTrue(IsEqual(marginMode, "isolated")) {
|
|
|
|
response = (<-this.PrivatePostMarginUserOrderTrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
|
|
response = (<-this.PrivatePostOrderTrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
var trades interface{} = this.SafeList(response, "trades")
|
|
|
|
ch <- this.ParseTrades(trades, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchOpenOrders
|
|
* @description fetch all unfilled currently open orders
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#0e135370-daa4-4689-8acd-b6876dee9ba1 // spot open orders
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#a7cfd4f0-476e-4675-b33f-22a46902f245 // margin
|
|
* @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
|
|
* @param {string} [params.marginMode] set to "isolated" for margin orders
|
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *exmo) 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
|
|
|
|
retRes18468 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes18468)
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
symbol = GetValue(market, "symbol")
|
|
}
|
|
var marginMode interface{} = nil
|
|
marginModeparamsVariable := this.HandleMarginModeAndParams("fetchOpenOrders", params);
|
|
marginMode = GetValue(marginModeparamsVariable,0);
|
|
params = GetValue(marginModeparamsVariable,1)
|
|
var isMargin interface{} = (IsTrue((IsEqual(marginMode, "cross"))) || IsTrue((IsEqual(marginMode, "isolated"))))
|
|
var response interface{} = nil
|
|
var orders interface{} = []interface{}{}
|
|
if IsTrue(isMargin) {
|
|
|
|
response = (<-this.PrivatePostMarginUserOrderList(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "orders": [
|
|
// {
|
|
// "client_id": "0",
|
|
// "comment": "",
|
|
// "created": "1619068707985325495",
|
|
// "distance": "0",
|
|
// "expire": 0,
|
|
// "funding_currency": "BTC",
|
|
// "funding_quantity": "0.01",
|
|
// "funding_rate": "0.02",
|
|
// "leverage": "2",
|
|
// "order_id": "123",
|
|
// "pair": "BTC_USD",
|
|
// "previous_type": "limit_sell",
|
|
// "price": "58000",
|
|
// "quantity": "0.01",
|
|
// "src": 0,
|
|
// "stop_price": "0",
|
|
// "trigger_price": "58000",
|
|
// "type": "limit_sell",
|
|
// "updated": 1619068707989411800
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
params = this.Extend(params, map[string]interface{} {
|
|
"status": "open",
|
|
})
|
|
var responseOrders interface{} = this.SafeValue(response, "orders")
|
|
orders = this.ParseOrders(responseOrders, market, since, limit, params)
|
|
} else {
|
|
|
|
response = (<-this.PrivatePostUserOpenOrders(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "USDT_USD": [
|
|
// {
|
|
// "parent_order_id": "507061384740151010",
|
|
// "client_id": "100500",
|
|
// "created": "1589547391",
|
|
// "type": "stop_market_buy",
|
|
// "pair": "USDT_USD",
|
|
// "quantity": "1",
|
|
// "trigger_price": "5",
|
|
// "amount": "5"
|
|
// }
|
|
// ],
|
|
// ...
|
|
// }
|
|
//
|
|
var marketIds interface{} = ObjectKeys(response)
|
|
for i := 0; IsLessThan(i, GetArrayLength(marketIds)); i++ {
|
|
var marketId interface{} = GetValue(marketIds, i)
|
|
var marketInner interface{} = this.SafeMarket(marketId)
|
|
params = this.Extend(params, map[string]interface{} {
|
|
"status": "open",
|
|
})
|
|
var parsedOrders interface{} = this.ParseOrders(GetValue(response, marketId), marketInner, since, limit, params)
|
|
orders = this.ArrayConcat(orders, parsedOrders)
|
|
}
|
|
}
|
|
|
|
ch <- orders
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) ParseStatus(status interface{}) interface{} {
|
|
if IsTrue(IsEqual(status, nil)) {
|
|
return nil
|
|
}
|
|
var statuses interface{} = map[string]interface{} {
|
|
"cancel_started": "canceled",
|
|
}
|
|
if IsTrue(IsGreaterThanOrEqual(GetIndexOf(status, "cancel"), 0)) {
|
|
status = "canceled"
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *exmo) ParseSide(orderType interface{}) interface{} {
|
|
var side interface{} = map[string]interface{} {
|
|
"limit_buy": "buy",
|
|
"limit_sell": "sell",
|
|
"market_buy": "buy",
|
|
"market_sell": "sell",
|
|
"stop_buy": "buy",
|
|
"stop_sell": "sell",
|
|
"stop_limit_buy": "buy",
|
|
"stop_limit_sell": "sell",
|
|
"trailing_stop_buy": "buy",
|
|
"trailing_stop_sell": "sell",
|
|
"stop_market_sell": "sell",
|
|
"stop_market_buy": "buy",
|
|
"buy": "buy",
|
|
"sell": "sell",
|
|
}
|
|
return this.SafeString(side, orderType, orderType)
|
|
}
|
|
func (this *exmo) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchOrders, fetchOpenOrders, fetchClosedOrders, fetchCanceledOrders
|
|
//
|
|
// {
|
|
// "order_id": "14",
|
|
// "created": "1435517311",
|
|
// "type": "buy",
|
|
// "pair": "BTC_USD",
|
|
// "price": "100",
|
|
// "quantity": "1",
|
|
// "amount": "100"
|
|
// }
|
|
//
|
|
// fetchOrder
|
|
//
|
|
// {
|
|
// "type": "buy",
|
|
// "in_currency": "BTC",
|
|
// "in_amount": "1",
|
|
// "out_currency": "USD",
|
|
// "out_amount": "100",
|
|
// "trades": [
|
|
// {
|
|
// "trade_id": 3,
|
|
// "date": 1435488248,
|
|
// "type": "buy",
|
|
// "pair": "BTC_USD",
|
|
// "order_id": 12345,
|
|
// "quantity": 1,
|
|
// "price": 100,
|
|
// "amount": 100
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
// Margin fetchOpenOrders
|
|
//
|
|
// {
|
|
// "client_id": "0",
|
|
// "comment": "",
|
|
// "created": "1619068707985325495",
|
|
// "distance": "0",
|
|
// "expire": 0,
|
|
// "funding_currency": "BTC",
|
|
// "funding_quantity": "0.01",
|
|
// "funding_rate": "0.02",
|
|
// "leverage": "2",
|
|
// "order_id": "123",
|
|
// "pair": "BTC_USD",
|
|
// "previous_type": "limit_sell",
|
|
// "price": "58000",
|
|
// "quantity": "0.01",
|
|
// "src": 0,
|
|
// "stop_price": "0",
|
|
// "trigger_price": "58000",
|
|
// "type": "limit_sell",
|
|
// "updated": 1619068707989411800
|
|
// }
|
|
//
|
|
// Margin fetchClosedOrders
|
|
//
|
|
// {
|
|
// "distance": "0",
|
|
// "event_id": "692842802860022508",
|
|
// "event_time": "1619069531190173720",
|
|
// "event_type": "OrderCancelStarted",
|
|
// "order_id": "123",
|
|
// "order_status": "cancel_started",
|
|
// "order_type": "limit_sell",
|
|
// "pair": "BTC_USD",
|
|
// "price": "54115",
|
|
// "quantity": "0.001",
|
|
// "stop_price": "0",
|
|
// "trade_id": "0",
|
|
// "trade_price": "0",
|
|
// "trade_quantity": "0",
|
|
// "trade_type": ""
|
|
// },
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var id interface{} = this.SafeString2(order, "order_id", "parent_order_id")
|
|
var eventTime interface{} = this.SafeIntegerProduct2(order, "event_time", "created", 0.000001)
|
|
var timestamp interface{} = this.SafeTimestamp(order, "created", eventTime)
|
|
var orderType interface{} = this.SafeString2(order, "type", "order_type")
|
|
var side interface{} = this.ParseSide(orderType)
|
|
var marketId interface{} = nil
|
|
if IsTrue(InOp(order, "pair")) {
|
|
marketId = GetValue(order, "pair")
|
|
} else if IsTrue(IsTrue((InOp(order, "in_currency"))) && IsTrue((InOp(order, "out_currency")))) {
|
|
if IsTrue(IsEqual(side, "buy")) {
|
|
marketId = Add(Add(GetValue(order, "in_currency"), "_"), GetValue(order, "out_currency"))
|
|
} else {
|
|
marketId = Add(Add(GetValue(order, "out_currency"), "_"), GetValue(order, "in_currency"))
|
|
}
|
|
}
|
|
market = this.SafeMarket(marketId, market)
|
|
var symbol interface{} = GetValue(market, "symbol")
|
|
var amount interface{} = this.SafeString(order, "quantity")
|
|
if IsTrue(IsEqual(amount, nil)) {
|
|
var amountField interface{} = Ternary(IsTrue((IsEqual(side, "buy"))), "in_amount", "out_amount")
|
|
amount = this.SafeString(order, amountField)
|
|
}
|
|
var price interface{} = this.SafeString(order, "price")
|
|
var cost interface{} = this.SafeString(order, "amount")
|
|
var transactions interface{} = this.SafeValue(order, "trades", []interface{}{})
|
|
var clientOrderId interface{} = this.SafeInteger(order, "client_id")
|
|
var triggerPrice interface{} = this.SafeString(order, "stop_price")
|
|
if IsTrue(IsEqual(triggerPrice, "0")) {
|
|
triggerPrice = nil
|
|
}
|
|
var typeVar interface{} = nil
|
|
if IsTrue(IsTrue((!IsEqual(orderType, "buy"))) && IsTrue((!IsEqual(orderType, "sell")))) {
|
|
typeVar = orderType
|
|
}
|
|
return this.SafeOrder(map[string]interface{} {
|
|
"id": id,
|
|
"clientOrderId": clientOrderId,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"timestamp": timestamp,
|
|
"lastTradeTimestamp": this.SafeIntegerProduct(order, "updated", 0.000001),
|
|
"status": this.ParseStatus(this.SafeString(order, "order_status")),
|
|
"symbol": symbol,
|
|
"type": typeVar,
|
|
"timeInForce": nil,
|
|
"postOnly": nil,
|
|
"side": side,
|
|
"price": price,
|
|
"triggerPrice": triggerPrice,
|
|
"cost": cost,
|
|
"amount": amount,
|
|
"filled": nil,
|
|
"remaining": nil,
|
|
"average": nil,
|
|
"trades": transactions,
|
|
"fee": nil,
|
|
"info": order,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchCanceledOrders
|
|
* @description fetches information on multiple canceled orders made by the user
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#1d2524dd-ae6d-403a-a067-77b50d13fbe5 // margin
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#a51be1d0-af5f-44e4-99d7-f7b04c6067d0 // spot canceled orders
|
|
* @param {string} symbol unified market symbol of the market orders were made in
|
|
* @param {int} [since] timestamp in ms of the earliest order, default is undefined
|
|
* @param {int} [limit] max number of orders to return, default is undefined
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.marginMode] set to "isolated" for margin orders
|
|
* @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *exmo) FetchCanceledOrders(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
|
|
|
|
retRes21108 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes21108)
|
|
var marginMode interface{} = nil
|
|
marginModeparamsVariable := this.HandleMarginModeAndParams("fetchOrders", params);
|
|
marginMode = GetValue(marginModeparamsVariable,0);
|
|
params = GetValue(marginModeparamsVariable,1)
|
|
if IsTrue(IsEqual(marginMode, "cross")) {
|
|
panic(BadRequest(Add(this.Id, " only supports isolated margin")))
|
|
}
|
|
if IsTrue(IsEqual(limit, nil)) {
|
|
limit = 100
|
|
}
|
|
var isSpot interface{} = (!IsEqual(marginMode, "isolated"))
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
var marketInner interface{} = this.Market(symbol)
|
|
symbol = GetValue(marketInner, "symbol")
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"limit": limit,
|
|
}
|
|
AddElementToObject(request, "offset", Ternary(IsTrue((!IsEqual(since, nil))), limit, 0))
|
|
AddElementToObject(request, "limit", limit)
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
}
|
|
var response interface{} = nil
|
|
if IsTrue(isSpot) {
|
|
|
|
response = (<-this.PrivatePostUserCancelledOrders(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// [
|
|
// {
|
|
// "order_id": "27056153840",
|
|
// "client_id": "0",
|
|
// "created": "1653428646",
|
|
// "type": "buy",
|
|
// "pair": "BTC_USDT",
|
|
// "quantity": "0.1",
|
|
// "price": "10",
|
|
// "amount": "1"
|
|
// }
|
|
// ]
|
|
//
|
|
params = this.Extend(params, map[string]interface{} {
|
|
"status": "canceled",
|
|
})
|
|
|
|
ch <- this.ParseOrders(response, market, since, limit, params)
|
|
return nil
|
|
} else {
|
|
|
|
responseSwap:= (<-this.PrivatePostMarginUserOrderHistory(this.Extend(request, params)))
|
|
PanicOnError(responseSwap)
|
|
//
|
|
// {
|
|
// "items": [
|
|
// {
|
|
// "event_id": "692862104574106858",
|
|
// "event_time": "1694116400173489405",
|
|
// "event_type": "OrderCancelStarted",
|
|
// "order_id": "692862104561289319",
|
|
// "order_type": "stop_limit_sell",
|
|
// "order_status": "cancel_started",
|
|
// "trade_id": "0",
|
|
// "trade_type":"",
|
|
// "trade_quantity": "0",
|
|
// "trade_price": "0",
|
|
// "pair": "ADA_USDT",
|
|
// "quantity": "12",
|
|
// "price": "0.23",
|
|
// "stop_price": "0.22",
|
|
// "distance": "0"
|
|
// }
|
|
// ...
|
|
// ]
|
|
// }
|
|
//
|
|
var items interface{} = this.SafeValue(responseSwap, "items")
|
|
var orders interface{} = this.ParseOrders(items, market, since, limit, params)
|
|
var result interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ {
|
|
var order interface{} = GetValue(orders, i)
|
|
if IsTrue(IsEqual(GetValue(order, "status"), "canceled")) {
|
|
AppendToArray(&result,order)
|
|
}
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
}
|
|
return nil
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#editOrder
|
|
* @description *margin only* edit a trade order
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#f27ee040-c75f-4b59-b608-d05bd45b7899 // margin
|
|
* @param {string} id order id
|
|
* @param {string} symbol unified CCXT market symbol
|
|
* @param {string} type not used by exmo editOrder
|
|
* @param {string} side not used by exmo editOrder
|
|
* @param {float} [amount] how much of the currency you want to trade in units of the 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
|
|
* @param {float} [params.triggerPrice] stop price for stop-market and stop-limit orders
|
|
* @param {string} params.marginMode must be set to isolated
|
|
*
|
|
* EXCHANGE SPECIFIC PARAMETERS
|
|
* @param {int} [params.distance] distance for trailing stop orders
|
|
* @param {int} [params.expire] expiration timestamp in UTC timezone for the order. order will not be expired if expire is 0
|
|
* @param {string} [params.comment] optional comment for order. up to 50 latin symbols, whitespaces, underscores
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *exmo) EditOrder(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
amount := GetArg(optionalArgs, 0, nil)
|
|
_ = amount
|
|
price := GetArg(optionalArgs, 1, nil)
|
|
_ = price
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes22158 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes22158)
|
|
var market interface{} = this.Market(symbol)
|
|
var marginMode interface{} = nil
|
|
marginModeparamsVariable := this.HandleMarginModeAndParams("editOrder", params);
|
|
marginMode = GetValue(marginModeparamsVariable,0);
|
|
params = GetValue(marginModeparamsVariable,1)
|
|
if IsTrue(!IsEqual(marginMode, "isolated")) {
|
|
panic(BadRequest(Add(this.Id, " editOrder() can only be used for isolated margin orders")))
|
|
}
|
|
var triggerPrice interface{} = this.SafeNumberN(params, []interface{}{"triggerPrice", "stopPrice", "stop_price"})
|
|
params = this.Omit(params, []interface{}{"triggerPrice", "stopPrice"})
|
|
var request interface{} = map[string]interface{} {
|
|
"order_id": id,
|
|
}
|
|
if IsTrue(!IsEqual(amount, nil)) {
|
|
AddElementToObject(request, "quantity", amount)
|
|
}
|
|
if IsTrue(!IsEqual(price, nil)) {
|
|
AddElementToObject(request, "price", this.PriceToPrecision(GetValue(market, "symbol"), price))
|
|
}
|
|
if IsTrue(!IsEqual(triggerPrice, nil)) {
|
|
AddElementToObject(request, "stop_price", this.PriceToPrecision(GetValue(market, "symbol"), triggerPrice))
|
|
}
|
|
|
|
response:= (<-this.PrivatePostMarginUserOrderUpdate(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
ch <- this.ParseOrder(response)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchDepositAddress
|
|
* @description fetch the deposit address for a currency associated with this account
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#c8f9ced9-7ab6-4383-a6a4-bc54469ba60e
|
|
* @param {string} code unified currency code
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
*/
|
|
func (this *exmo) FetchDepositAddress(code interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes22508 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes22508)
|
|
|
|
response:= (<-this.PrivatePostDepositAddress(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "TRX":"TBnwrf4ZdoYXE3C8L2KMs7YPSL3fg6q6V9",
|
|
// "USDTTRC20":"TBnwrf4ZdoYXE3C8L2KMs7YPSL3fg6q6V9"
|
|
// }
|
|
//
|
|
var depositAddress interface{} = this.SafeString(response, code)
|
|
var address interface{} = nil
|
|
var tag interface{} = nil
|
|
if IsTrue(depositAddress) {
|
|
var addressAndTag interface{} = Split(depositAddress, ",")
|
|
address = GetValue(addressAndTag, 0)
|
|
var numParts interface{} = GetArrayLength(addressAndTag)
|
|
if IsTrue(IsGreaterThan(numParts, 1)) {
|
|
tag = GetValue(addressAndTag, 1)
|
|
}
|
|
}
|
|
this.CheckAddress(address)
|
|
|
|
ch <- map[string]interface{} {
|
|
"info": response,
|
|
"currency": code,
|
|
"network": nil,
|
|
"address": address,
|
|
"tag": tag,
|
|
}
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) GetMarketFromTrades(trades interface{}) interface{} {
|
|
var tradesBySymbol interface{} = this.IndexBy(trades, "pair")
|
|
var symbols interface{} = ObjectKeys(tradesBySymbol)
|
|
var numSymbols interface{} = GetArrayLength(symbols)
|
|
if IsTrue(IsEqual(numSymbols, 1)) {
|
|
return GetValue(this.Markets, GetValue(symbols, 0))
|
|
}
|
|
return nil
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#withdraw
|
|
* @description make a withdrawal
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#3ab9c34d-ad58-4f87-9c57-2e2ea88a8325
|
|
* @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 *exmo) 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)
|
|
|
|
retRes23038 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes23038)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"amount": amount,
|
|
"currency": GetValue(currency, "id"),
|
|
"address": address,
|
|
}
|
|
if IsTrue(!IsEqual(tag, nil)) {
|
|
AddElementToObject(request, "invoice", tag)
|
|
}
|
|
var networks interface{} = this.SafeValue(this.Options, "networks", map[string]interface{} {})
|
|
var network interface{} = this.SafeStringUpper(params, "network") // this line allows the user to specify either ERC20 or ETH
|
|
network = this.SafeString(networks, network, network) // handle ERC20>ETH alias
|
|
if IsTrue(!IsEqual(network, nil)) {
|
|
AddElementToObject(request, "transport", network)
|
|
params = this.Omit(params, "network")
|
|
}
|
|
|
|
response:= (<-this.PrivatePostWithdrawCrypt(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
ch <- this.ParseTransaction(response, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) ParseTransactionStatus(status interface{}) interface{} {
|
|
var statuses interface{} = map[string]interface{} {
|
|
"transferred": "ok",
|
|
"paid": "ok",
|
|
"pending": "pending",
|
|
"processing": "pending",
|
|
"verifying": "pending",
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *exmo) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchDepositsWithdrawals
|
|
//
|
|
// {
|
|
// "dt": 1461841192,
|
|
// "type": "deposit",
|
|
// "curr": "RUB",
|
|
// "status": "processing",
|
|
// "provider": "Qiwi (LA) [12345]",
|
|
// "amount": "1",
|
|
// "account": "",
|
|
// "txid": "ec46f784ad976fd7f7539089d1a129fe46...",
|
|
// }
|
|
//
|
|
// fetchWithdrawals
|
|
//
|
|
// {
|
|
// "operation_id": 47412538520634344,
|
|
// "created": 1573760013,
|
|
// "updated": 1573760013,
|
|
// "type": "withdraw",
|
|
// "currency": "DOGE",
|
|
// "status": "Paid",
|
|
// "amount": "300",
|
|
// "provider": "DOGE",
|
|
// "commission": "0",
|
|
// "account": "DOGE: DBVy8pF1f8yxaCVEHqHeR7kkcHecLQ8nRS",
|
|
// "order_id": 69670170,
|
|
// "provider_type": "crypto",
|
|
// "crypto_address": "DBVy8pF1f8yxaCVEHqHeR7kkcHecLQ8nRS",
|
|
// "card_number": "",
|
|
// "wallet_address": "",
|
|
// "email": "",
|
|
// "phone": "",
|
|
// "extra": {
|
|
// "txid": "f2b66259ae1580f371d38dd27e31a23fff8c04122b65ee3ab5a3f612d579c792",
|
|
// "confirmations": null,
|
|
// "excode": "",
|
|
// "invoice": ""
|
|
// },
|
|
// "error": ""
|
|
// }
|
|
//
|
|
// withdraw
|
|
//
|
|
// {
|
|
// "result": true,
|
|
// "error": "",
|
|
// "task_id": 11775077
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var timestamp interface{} = this.SafeTimestamp2(transaction, "dt", "created")
|
|
var amountString interface{} = this.SafeString(transaction, "amount")
|
|
if IsTrue(!IsEqual(amountString, nil)) {
|
|
amountString = Precise.StringAbs(amountString)
|
|
}
|
|
var txid interface{} = this.SafeString(transaction, "txid")
|
|
if IsTrue(IsEqual(txid, nil)) {
|
|
var extra interface{} = this.SafeValue(transaction, "extra", map[string]interface{} {})
|
|
var extraTxid interface{} = this.SafeString(extra, "txid")
|
|
if IsTrue(!IsEqual(extraTxid, "")) {
|
|
txid = extraTxid
|
|
}
|
|
}
|
|
var typeVar interface{} = this.SafeString(transaction, "type")
|
|
var currencyId interface{} = this.SafeString2(transaction, "curr", "currency")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
|
|
var address interface{} = nil
|
|
var comment interface{} = nil
|
|
var account interface{} = this.SafeString(transaction, "account")
|
|
if IsTrue(IsEqual(typeVar, "deposit")) {
|
|
comment = account
|
|
} else if IsTrue(IsEqual(typeVar, "withdrawal")) {
|
|
address = account
|
|
if IsTrue(!IsEqual(address, nil)) {
|
|
var parts interface{} = Split(address, ":")
|
|
var numParts interface{} = GetArrayLength(parts)
|
|
if IsTrue(IsEqual(numParts, 2)) {
|
|
address = this.SafeString(parts, 1)
|
|
address = Replace(address, " ", "")
|
|
}
|
|
}
|
|
}
|
|
var fee interface{} = map[string]interface{} {
|
|
"currency": nil,
|
|
"cost": nil,
|
|
"rate": nil,
|
|
}
|
|
// fixed funding fees only (for now)
|
|
if !IsTrue(GetValue(GetValue(this.Fees, "transaction"), "percentage")) {
|
|
var key interface{} = Ternary(IsTrue((IsEqual(typeVar, "withdrawal"))), "withdraw", "deposit")
|
|
var feeCost interface{} = this.SafeString(transaction, "commission")
|
|
if IsTrue(IsEqual(feeCost, nil)) {
|
|
var transactionFees interface{} = this.SafeValue(this.Options, "transactionFees", map[string]interface{} {})
|
|
var codeFees interface{} = this.SafeValue(transactionFees, code, map[string]interface{} {})
|
|
feeCost = this.SafeString(codeFees, key)
|
|
}
|
|
// users don't pay for cashbacks, no fees for that
|
|
var provider interface{} = this.SafeString(transaction, "provider")
|
|
if IsTrue(IsEqual(provider, "cashback")) {
|
|
feeCost = "0"
|
|
}
|
|
if IsTrue(!IsEqual(feeCost, nil)) {
|
|
// withdrawal amount includes the fee
|
|
if IsTrue(IsEqual(typeVar, "withdrawal")) {
|
|
amountString = Precise.StringSub(amountString, feeCost)
|
|
}
|
|
AddElementToObject(fee, "cost", this.ParseNumber(feeCost))
|
|
AddElementToObject(fee, "currency", code)
|
|
}
|
|
}
|
|
return map[string]interface{} {
|
|
"info": transaction,
|
|
"id": this.SafeString2(transaction, "order_id", "task_id"),
|
|
"txid": txid,
|
|
"type": typeVar,
|
|
"currency": code,
|
|
"network": this.SafeString(transaction, "provider"),
|
|
"amount": this.ParseNumber(amountString),
|
|
"status": this.ParseTransactionStatus(this.SafeStringLower(transaction, "status")),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"address": address,
|
|
"addressFrom": nil,
|
|
"addressTo": address,
|
|
"tag": nil,
|
|
"tagFrom": nil,
|
|
"tagTo": nil,
|
|
"updated": this.SafeTimestamp(transaction, "updated"),
|
|
"comment": comment,
|
|
"internal": nil,
|
|
"fee": fee,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchDepositsWithdrawals
|
|
* @description fetch history of deposits and withdrawals
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#31e69a33-4849-4e6a-b4b4-6d574238f6a7
|
|
* @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined
|
|
* @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
|
|
* @param {int} [limit] max number of deposit/withdrawals to return, default is undefined
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *exmo) FetchDepositsWithdrawals(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
|
|
|
|
retRes24838 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes24838)
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "date", this.ParseToInt(Divide(since, 1000)))
|
|
}
|
|
var currency interface{} = nil
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
}
|
|
|
|
response:= (<-this.PrivatePostWalletHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "result": true,
|
|
// "error": "",
|
|
// "begin": "1493942400",
|
|
// "end": "1494028800",
|
|
// "history": [
|
|
// {
|
|
// "dt": 1461841192,
|
|
// "type": "deposit",
|
|
// "curr": "RUB",
|
|
// "status": "processing",
|
|
// "provider": "Qiwi (LA) [12345]",
|
|
// "amount": "1",
|
|
// "account": "",
|
|
// "txid": "ec46f784ad976fd7f7539089d1a129fe46...",
|
|
// },
|
|
// {
|
|
// "dt": 1463414785,
|
|
// "type": "withdrawal",
|
|
// "curr": "USD",
|
|
// "status": "paid",
|
|
// "provider": "EXCODE",
|
|
// "amount": "-1",
|
|
// "account": "EX-CODE_19371_USDda...",
|
|
// "txid": "",
|
|
// },
|
|
// ],
|
|
// }
|
|
//
|
|
ch <- this.ParseTransactions(GetValue(response, "history"), currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchWithdrawals
|
|
* @description fetch all withdrawals made from an account
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
|
|
* @param {string} code unified currency code
|
|
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *exmo) FetchWithdrawals(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes25388 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes25388)
|
|
var currency interface{} = nil
|
|
var request interface{} = map[string]interface{} {
|
|
"type": "withdraw",
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit) // default: 100, maximum: 100
|
|
}
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
AddElementToObject(request, "currency", GetValue(currency, "id"))
|
|
}
|
|
|
|
response:= (<-this.PrivatePostWalletOperations(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "items": [
|
|
// {
|
|
// "operation_id": 47412538520634344,
|
|
// "created": 1573760013,
|
|
// "updated": 1573760013,
|
|
// "type": "withdraw",
|
|
// "currency": "DOGE",
|
|
// "status": "Paid",
|
|
// "amount": "300",
|
|
// "provider": "DOGE",
|
|
// "commission": "0",
|
|
// "account": "DOGE: DBVy8pF1f8yxaCVEHqHeR7kkcHecLQ8nRS",
|
|
// "order_id": 69670170,
|
|
// "extra": {
|
|
// "txid": "f2b66259ae1580f371d38dd27e31a23fff8c04122b65ee3ab5a3f612d579c792",
|
|
// "excode": "",
|
|
// "invoice": ""
|
|
// },
|
|
// "error": ""
|
|
// },
|
|
// ],
|
|
// "count": 23
|
|
// }
|
|
//
|
|
var items interface{} = this.SafeList(response, "items", []interface{}{})
|
|
|
|
ch <- this.ParseTransactions(items, currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchWithdrawal
|
|
* @description fetch data on a currency withdrawal via the withdrawal id
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
|
|
* @param {string} id withdrawal id
|
|
* @param {string} code unified currency code of the currency withdrawn, default is undefined
|
|
* @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 *exmo) FetchWithdrawal(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes25928 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes25928)
|
|
var currency interface{} = nil
|
|
var request interface{} = map[string]interface{} {
|
|
"order_id": id,
|
|
"type": "withdraw",
|
|
}
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
AddElementToObject(request, "currency", GetValue(currency, "id"))
|
|
}
|
|
|
|
response:= (<-this.PrivatePostWalletOperations(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "items": [
|
|
// {
|
|
// "operation_id": 47412538520634344,
|
|
// "created": 1573760013,
|
|
// "updated": 1573760013,
|
|
// "type": "deposit",
|
|
// "currency": "DOGE",
|
|
// "status": "Paid",
|
|
// "amount": "300",
|
|
// "provider": "DOGE",
|
|
// "commission": "0",
|
|
// "account": "DOGE: DBVy8pF1f8yxaCVEHqHeR7kkcHecLQ8nRS",
|
|
// "order_id": 69670170,
|
|
// "extra": {
|
|
// "txid": "f2b66259ae1580f371d38dd27e31a23fff8c04122b65ee3ab5a3f612d579c792",
|
|
// "excode": "",
|
|
// "invoice": ""
|
|
// },
|
|
// "error": ""
|
|
// },
|
|
// ],
|
|
// "count": 23
|
|
// }
|
|
//
|
|
var items interface{} = this.SafeValue(response, "items", []interface{}{})
|
|
var first interface{} = this.SafeDict(items, 0, map[string]interface{} {})
|
|
|
|
ch <- this.ParseTransaction(first, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchDeposit
|
|
* @description fetch information on a deposit
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
|
|
* @param {string} id deposit id
|
|
* @param {string} code unified currency code, default is undefined
|
|
* @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 *exmo) FetchDeposit(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes26458 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes26458)
|
|
var currency interface{} = nil
|
|
var request interface{} = map[string]interface{} {
|
|
"order_id": id,
|
|
"type": "deposit",
|
|
}
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
AddElementToObject(request, "currency", GetValue(currency, "id"))
|
|
}
|
|
|
|
response:= (<-this.PrivatePostWalletOperations(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "items": [
|
|
// {
|
|
// "operation_id": 47412538520634344,
|
|
// "created": 1573760013,
|
|
// "updated": 1573760013,
|
|
// "type": "deposit",
|
|
// "currency": "DOGE",
|
|
// "status": "Paid",
|
|
// "amount": "300",
|
|
// "provider": "DOGE",
|
|
// "commission": "0",
|
|
// "account": "DOGE: DBVy8pF1f8yxaCVEHqHeR7kkcHecLQ8nRS",
|
|
// "order_id": 69670170,
|
|
// "extra": {
|
|
// "txid": "f2b66259ae1580f371d38dd27e31a23fff8c04122b65ee3ab5a3f612d579c792",
|
|
// "excode": "",
|
|
// "invoice": ""
|
|
// },
|
|
// "error": ""
|
|
// },
|
|
// ],
|
|
// "count": 23
|
|
// }
|
|
//
|
|
var items interface{} = this.SafeValue(response, "items", []interface{}{})
|
|
var first interface{} = this.SafeDict(items, 0, map[string]interface{} {})
|
|
|
|
ch <- this.ParseTransaction(first, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name exmo#fetchDeposits
|
|
* @description fetch all deposits made to an account
|
|
* @see https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
|
|
* @param {string} code unified currency code
|
|
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *exmo) FetchDeposits(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes26998 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes26998)
|
|
var currency interface{} = nil
|
|
var request interface{} = map[string]interface{} {
|
|
"type": "deposit",
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit) // default: 100, maximum: 100
|
|
}
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
AddElementToObject(request, "currency", GetValue(currency, "id"))
|
|
}
|
|
|
|
response:= (<-this.PrivatePostWalletOperations(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "items": [
|
|
// {
|
|
// "operation_id": 47412538520634344,
|
|
// "created": 1573760013,
|
|
// "updated": 1573760013,
|
|
// "type": "deposit",
|
|
// "currency": "DOGE",
|
|
// "status": "Paid",
|
|
// "amount": "300",
|
|
// "provider": "DOGE",
|
|
// "commission": "0",
|
|
// "account": "DOGE: DBVy8pF1f8yxaCVEHqHeR7kkcHecLQ8nRS",
|
|
// "order_id": 69670170,
|
|
// "extra": {
|
|
// "txid": "f2b66259ae1580f371d38dd27e31a23fff8c04122b65ee3ab5a3f612d579c792",
|
|
// "excode": "",
|
|
// "invoice": ""
|
|
// },
|
|
// "error": ""
|
|
// },
|
|
// ],
|
|
// "count": 23
|
|
// }
|
|
//
|
|
var items interface{} = this.SafeList(response, "items", []interface{}{})
|
|
|
|
ch <- this.ParseTransactions(items, currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *exmo) 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(GetValue(GetValue(this.Urls, "api"), api), "/")
|
|
if IsTrue(!IsEqual(api, "web")) {
|
|
url = Add(url, Add(this.Version, "/"))
|
|
}
|
|
url = Add(url, path)
|
|
if IsTrue(IsTrue((IsEqual(api, "public"))) || IsTrue((IsEqual(api, "web")))) {
|
|
if IsTrue(GetArrayLength(ObjectKeys(params))) {
|
|
url = Add(url, Add("?", this.Urlencode(params)))
|
|
}
|
|
} else if IsTrue(IsEqual(api, "private")) {
|
|
this.CheckRequiredCredentials()
|
|
var nonce interface{} = this.Nonce()
|
|
body = this.Urlencode(this.Extend(map[string]interface{} {
|
|
"nonce": nonce,
|
|
}, params))
|
|
headers = map[string]interface{} {
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
"Key": this.ApiKey,
|
|
"Sign": this.Hmac(this.Encode(body), this.Encode(this.Secret), sha512),
|
|
}
|
|
}
|
|
return map[string]interface{} {
|
|
"url": url,
|
|
"method": method,
|
|
"body": body,
|
|
"headers": headers,
|
|
}
|
|
}
|
|
func (this *exmo) Nonce() interface{} {
|
|
return this.Milliseconds()
|
|
}
|
|
func (this *exmo) 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(IsTrue((InOp(response, "error"))) && !IsTrue((InOp(response, "result")))) {
|
|
// error: {
|
|
// "code": "140434",
|
|
// "msg": "Your margin balance is not sufficient to place the order for '5 TON'. Please top up your margin wallet by "2.5 USDT"."
|
|
// }
|
|
//
|
|
var errorCode interface{} = this.SafeValue(response, "error", map[string]interface{} {})
|
|
var messageError interface{} = this.SafeString(errorCode, "msg")
|
|
var code interface{} = this.SafeString(errorCode, "code")
|
|
var feedback interface{} = Add(Add(this.Id, " "), body)
|
|
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), code, feedback)
|
|
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), messageError, feedback)
|
|
panic(ExchangeError(feedback))
|
|
}
|
|
if IsTrue(IsTrue((InOp(response, "result"))) || IsTrue((InOp(response, "errmsg")))) {
|
|
//
|
|
// {"result":false,"error":"Error 50052: Insufficient funds"}
|
|
// {"s":"error","errmsg":"strconv.ParseInt: parsing \"\": invalid syntax"}
|
|
//
|
|
var success interface{} = this.SafeBool(response, "result", false)
|
|
if IsTrue(IsString(success)) {
|
|
if IsTrue(IsTrue((IsEqual(success, "true"))) || IsTrue((IsEqual(success, "1")))) {
|
|
success = true
|
|
} else {
|
|
success = false
|
|
}
|
|
}
|
|
if !IsTrue(success) {
|
|
var code interface{} = nil
|
|
var message interface{} = this.SafeString2(response, "error", "errmsg")
|
|
var errorParts interface{} = Split(message, ":")
|
|
var numParts interface{} = GetArrayLength(errorParts)
|
|
if IsTrue(IsGreaterThan(numParts, 1)) {
|
|
var errorSubParts interface{} = Split(GetValue(errorParts, 0), " ")
|
|
var numSubParts interface{} = GetArrayLength(errorSubParts)
|
|
code = Ternary(IsTrue((IsGreaterThan(numSubParts, 1))), GetValue(errorSubParts, 1), GetValue(errorSubParts, 0))
|
|
}
|
|
var feedback interface{} = Add(Add(this.Id, " "), body)
|
|
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), code, feedback)
|
|
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, feedback)
|
|
panic(ExchangeError(feedback))
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
|
|
func (this *exmo) Init(userConfig map[string]interface{}) {
|
|
this.Exchange = Exchange{}
|
|
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
|
|
this.Exchange.DerivedExchange = this
|
|
}
|