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 blofin struct { Exchange } func NewBlofinCore() blofin { p := blofin{} setDefaults(&p) return p } func (this *blofin) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "blofin", "name": "BloFin", "countries": []interface{}{"US"}, "version": "v1", "rateLimit": 100, "pro": true, "has": map[string]interface{} { "CORS": nil, "spot": false, "margin": false, "swap": true, "future": false, "option": false, "addMargin": false, "borrowMargin": false, "cancelAllOrders": false, "cancelOrder": true, "cancelOrders": true, "closeAllPositions": false, "closePosition": true, "createDepositAddress": false, "createMarketBuyOrderWithCost": false, "createMarketSellOrderWithCost": false, "createOrder": true, "createOrders": true, "createOrderWithTakeProfitAndStopLoss": true, "createPostOnlyOrder": false, "createReduceOnlyOrder": false, "createStopLimitOrder": false, "createStopLossOrder": true, "createStopMarketOrder": false, "createStopOrder": false, "createTakeProfitOrder": true, "editOrder": false, "fetchAccounts": false, "fetchBalance": true, "fetchBidsAsks": nil, "fetchBorrowInterest": false, "fetchBorrowRateHistories": false, "fetchBorrowRateHistory": false, "fetchCanceledOrders": false, "fetchClosedOrder": false, "fetchClosedOrders": false, "fetchCrossBorrowRate": false, "fetchCrossBorrowRates": false, "fetchCurrencies": false, "fetchDeposit": false, "fetchDepositAddress": false, "fetchDepositAddresses": false, "fetchDepositAddressesByNetwork": false, "fetchDeposits": true, "fetchDepositsWithdrawals": false, "fetchDepositWithdrawFee": "emulated", "fetchDepositWithdrawFees": false, "fetchFundingHistory": true, "fetchFundingRate": true, "fetchFundingRateHistory": true, "fetchFundingRates": false, "fetchGreeks": false, "fetchIndexOHLCV": false, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": false, "fetchL3OrderBook": false, "fetchLedger": true, "fetchLedgerEntry": nil, "fetchLeverage": true, "fetchLeverages": true, "fetchLeverageTiers": false, "fetchMarginMode": true, "fetchMarginModes": false, "fetchMarketLeverageTiers": false, "fetchMarkets": true, "fetchMarkOHLCV": false, "fetchMySettlementHistory": false, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenInterest": false, "fetchOpenInterestHistory": false, "fetchOpenOrder": nil, "fetchOpenOrders": true, "fetchOrder": nil, "fetchOrderBook": true, "fetchOrderBooks": false, "fetchOrders": false, "fetchOrderTrades": true, "fetchPosition": true, "fetchPositions": true, "fetchPositionsForSymbol": false, "fetchPositionsRisk": false, "fetchPremiumIndexOHLCV": false, "fetchSettlementHistory": false, "fetchStatus": false, "fetchTicker": true, "fetchTickers": true, "fetchTime": false, "fetchTrades": true, "fetchTradingFee": false, "fetchTradingFees": false, "fetchTradingLimits": false, "fetchTransactionFee": false, "fetchTransactionFees": false, "fetchTransactions": false, "fetchTransfer": false, "fetchTransfers": false, "fetchUnderlyingAssets": false, "fetchVolatilityHistory": false, "fetchWithdrawal": false, "fetchWithdrawals": true, "fetchWithdrawalWhitelist": false, "reduceMargin": false, "repayCrossMargin": false, "setLeverage": true, "setMargin": false, "setMarginMode": false, "setPositionMode": false, "signIn": false, "transfer": true, "withdraw": false, }, "timeframes": map[string]interface{} { "1m": "1m", "3m": "3m", "5m": "5m", "15m": "15m", "30m": "30m", "1h": "1H", "2h": "2H", "4h": "4H", "6h": "6H", "8h": "8H", "12h": "12H", "1d": "1D", "3d": "3D", "1w": "1W", "1M": "1M", }, "hostname": "www.blofin.com", "urls": map[string]interface{} { "logo": "https://github.com/user-attachments/assets/518cdf80-f05d-4821-a3e3-d48ceb41d73b", "api": map[string]interface{} { "rest": "https://openapi.blofin.com", }, "test": map[string]interface{} { "rest": "https://demo-trading-openapi.blofin.com", }, "referral": map[string]interface{} { "url": "https://blofin.com/register?referral_code=f79EsS", "discount": 0.05, }, "www": "https://www.blofin.com", "doc": "https://blofin.com/docs", }, "api": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "market/instruments": 1, "market/tickers": 1, "market/books": 1, "market/trades": 1, "market/candles": 1, "market/mark-price": 1, "market/funding-rate": 1, "market/funding-rate-history": 1, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "asset/balances": 1, "trade/orders-pending": 1, "trade/fills-history": 1, "asset/deposit-history": 1, "asset/withdrawal-history": 1, "asset/bills": 1, "account/balance": 1, "account/positions": 1, "account/leverage-info": 1, "account/margin-mode": 1, "account/batch-leverage-info": 1, "trade/orders-tpsl-pending": 1, "trade/orders-history": 1, "trade/orders-tpsl-history": 1, "user/query-apikey": 1, "affiliate/basic": 1, "copytrading/instruments": 1, "copytrading/account/balance": 1, "copytrading/account/positions-by-order": 1, "copytrading/account/positions-details-by-order": 1, "copytrading/account/positions-by-contract": 1, "copytrading/account/position-mode": 1, "copytrading/account/leverage-info": 1, "copytrading/trade/orders-pending": 1, "copytrading/trade/pending-tpsl-by-contract": 1, "copytrading/trade/position-history-by-order": 1, "copytrading/trade/orders-history": 1, "copytrading/trade/pending-tpsl-by-order": 1, }, "post": map[string]interface{} { "trade/order": 1, "trade/cancel-order": 1, "account/set-leverage": 1, "trade/batch-orders": 1, "trade/order-tpsl": 1, "trade/cancel-batch-orders": 1, "trade/cancel-tpsl": 1, "trade/close-position": 1, "asset/transfer": 1, "copytrading/account/set-position-mode": 1, "copytrading/account/set-leverage": 1, "copytrading/trade/place-order": 1, "copytrading/trade/cancel-order": 1, "copytrading/trade/place-tpsl-by-contract": 1, "copytrading/trade/cancel-tpsl-by-contract": 1, "copytrading/trade/place-tpsl-by-order": 1, "copytrading/trade/cancel-tpsl-by-order": 1, "copytrading/trade/close-position-by-order": 1, "copytrading/trade/close-position-by-contract": 1, }, }, }, "fees": map[string]interface{} { "swap": map[string]interface{} { "taker": this.ParseNumber("0.00060"), "maker": this.ParseNumber("0.00020"), }, }, "requiredCredentials": map[string]interface{} { "apiKey": true, "secret": true, "password": true, }, "features": map[string]interface{} { "default": map[string]interface{} { "sandbox": false, "createOrder": map[string]interface{} { "timeInForce": map[string]interface{} { "IOC": true, "FOK": true, "PO": true, "GTD": false, }, "leverage": false, "marketBuyRequiresPrice": false, "marketBuyByCost": false, "selfTradePrevention": false, "trailing": false, "iceberg": false, }, "createOrders": map[string]interface{} { "max": 10, }, "fetchMyTrades": map[string]interface{} { "marginMode": false, "limit": 100, "daysBack": 100000, "untilDays": 100000, "symbolRequired": false, }, "fetchOrder": nil, "fetchOpenOrders": map[string]interface{} { "marginMode": false, "limit": 100, "trigger": true, "trailing": false, "symbolRequired": false, }, "fetchOrders": nil, "fetchClosedOrders": map[string]interface{} { "marginMode": false, "limit": 1000, "daysBack": 100000, "daysBackCanceled": 1, "untilDays": 100000, "trigger": true, "trailing": false, "symbolRequired": false, }, "fetchOHLCV": map[string]interface{} { "limit": 1440, }, }, "spot": map[string]interface{} { "extends": "default", "createOrder": map[string]interface{} { "marginMode": false, "triggerPrice": false, "triggerPriceType": nil, "triggerDirection": false, "stopLossPrice": false, "takeProfitPrice": false, "attachedStopLossTakeProfit": nil, "hedged": false, }, }, "forDerivatives": map[string]interface{} { "extends": "default", "createOrder": map[string]interface{} { "marginMode": true, "triggerPrice": false, "triggerPriceType": nil, "triggerDirection": false, "stopLossPrice": true, "takeProfitPrice": true, "attachedStopLossTakeProfit": map[string]interface{} { "triggerPriceType": nil, "price": true, }, "hedged": true, }, }, "swap": map[string]interface{} { "linear": map[string]interface{} { "extends": "forDerivatives", }, "inverse": nil, }, "future": map[string]interface{} { "linear": nil, "inverse": nil, }, }, "exceptions": map[string]interface{} { "exact": map[string]interface{} { "400": BadRequest, "401": AuthenticationError, "500": ExchangeError, "404": BadRequest, "405": BadRequest, "406": BadRequest, "429": RateLimitExceeded, "152001": BadRequest, "152002": BadRequest, "152003": BadRequest, "152004": BadRequest, "152005": BadRequest, "152006": InvalidOrder, "152007": InvalidOrder, "152008": InvalidOrder, "152009": InvalidOrder, "150003": InvalidOrder, "150004": InvalidOrder, "542": InvalidOrder, "102002": InvalidOrder, "102005": InvalidOrder, "102014": InvalidOrder, "102015": InvalidOrder, "102022": InvalidOrder, "102037": InvalidOrder, "102038": InvalidOrder, "102039": InvalidOrder, "102040": InvalidOrder, "102047": InvalidOrder, "102048": InvalidOrder, "102049": InvalidOrder, "102050": InvalidOrder, "102051": InvalidOrder, "102052": InvalidOrder, "102053": InvalidOrder, "102054": InvalidOrder, "102055": InvalidOrder, "102064": BadRequest, "102065": BadRequest, "102068": BadRequest, "103013": ExchangeError, "Order failed. Insufficient USDT margin in account": InsufficientFunds, }, "broad": map[string]interface{} { "Internal Server Error": ExchangeNotAvailable, "server error": ExchangeNotAvailable, }, }, "httpExceptions": map[string]interface{} { "429": ExchangeNotAvailable, }, "precisionMode": TICK_SIZE, "options": map[string]interface{} { "brokerId": "ec6dd3a7dd982d0b", "accountsByType": map[string]interface{} { "swap": "futures", "funding": "funding", "future": "futures", "copy_trading": "copy_trading", "earn": "earn", "spot": "spot", }, "accountsById": map[string]interface{} { "funding": "funding", "futures": "swap", "copy_trading": "copy_trading", "earn": "earn", "spot": "spot", }, "defaultNetwork": "ERC20", "defaultNetworks": map[string]interface{} { "ETH": "ERC20", "BTC": "BTC", "USDT": "TRC20", }, "networks": map[string]interface{} { "BTC": "Bitcoin", "BEP20": "BSC", "ERC20": "ERC20", "TRC20": "TRC20", }, "fetchOpenInterestHistory": map[string]interface{} { "timeframes": map[string]interface{} { "5m": "5m", "1h": "1H", "8h": "8H", "1d": "1D", "5M": "5m", "1H": "1H", "8H": "8H", "1D": "1D", }, }, "fetchOHLCV": map[string]interface{} { "timezone": "UTC", }, "fetchPositions": map[string]interface{} { "method": "privateGetAccountPositions", }, "createOrder": "privatePostTradeOrder", "createMarketBuyOrderRequiresPrice": false, "fetchMarkets": []interface{}{"swap"}, "defaultType": "swap", "fetchLedger": map[string]interface{} { "method": "privateGetAssetBills", }, "fetchOpenOrders": map[string]interface{} { "method": "privateGetTradeOrdersPending", }, "cancelOrders": map[string]interface{} { "method": "privatePostTradeCancelBatchOrders", }, "fetchCanceledOrders": map[string]interface{} { "method": "privateGetTradeOrdersHistory", }, "fetchClosedOrders": map[string]interface{} { "method": "privateGetTradeOrdersHistory", }, "withdraw": map[string]interface{} { "password": nil, "pwd": nil, }, "exchangeType": map[string]interface{} { "spot": "SPOT", "swap": "SWAP", "SPOT": "SPOT", "SWAP": "SWAP", }, }, }) } /** * @method * @name blofin#fetchMarkets * @description retrieves data on all markets for blofin * @see https://blofin.com/docs#get-instruments * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *blofin) 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.PublicGetMarketInstruments(params)) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseMarkets(data) return nil }() return ch } func (this *blofin) ParseMarket(market interface{}) interface{} { var id interface{} = this.SafeString(market, "instId") var typeVar interface{} = this.SafeStringLower(market, "instType") var spot interface{} = (IsEqual(typeVar, "spot")) var future interface{} = (IsEqual(typeVar, "future")) var swap interface{} = (IsEqual(typeVar, "swap")) var option interface{} = (IsEqual(typeVar, "option")) var contract interface{} = IsTrue(swap) || IsTrue(future) var baseId interface{} = this.SafeString(market, "baseCurrency") var quoteId interface{} = this.SafeString(market, "quoteCurrency") var settleId interface{} = this.SafeString(market, "quoteCurrency") var settle interface{} = this.SafeCurrencyCode(settleId) var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) var symbol interface{} = Add(Add(base, "/"), quote) if IsTrue(swap) { symbol = Add(Add(symbol, ":"), settle) } var expiry interface{} = nil var strikePrice interface{} = nil var optionType interface{} = nil var tickSize interface{} = this.SafeString(market, "tickSize") var fees interface{} = this.SafeDict2(this.Fees, typeVar, "trading", map[string]interface{} {}) var taker interface{} = this.SafeNumber(fees, "taker") var maker interface{} = this.SafeNumber(fees, "maker") var maxLeverage interface{} = this.SafeString(market, "maxLeverage", "100") maxLeverage = Precise.StringMax(maxLeverage, "1") var isActive interface{} = (IsEqual(this.SafeString(market, "state"), "live")) return this.SafeMarketStructure(map[string]interface{} { "id": id, "symbol": symbol, "base": base, "quote": quote, "baseId": baseId, "quoteId": quoteId, "settle": settle, "settleId": settleId, "type": typeVar, "spot": spot, "option": option, "margin": IsTrue(spot) && IsTrue((Precise.StringGt(maxLeverage, "1"))), "swap": swap, "future": future, "active": isActive, "taker": taker, "maker": maker, "contract": contract, "linear": Ternary(IsTrue(contract), (IsEqual(quoteId, settleId)), nil), "inverse": Ternary(IsTrue(contract), (IsEqual(baseId, settleId)), nil), "contractSize": Ternary(IsTrue(contract), this.SafeNumber(market, "contractValue"), nil), "expiry": expiry, "expiryDatetime": expiry, "strike": strikePrice, "optionType": optionType, "created": this.SafeInteger(market, "listTime"), "precision": map[string]interface{} { "amount": this.SafeNumber(market, "lotSize"), "price": this.ParseNumber(tickSize), }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": this.ParseNumber("1"), "max": this.ParseNumber(maxLeverage), }, "amount": map[string]interface{} { "min": this.SafeNumber(market, "minSize"), "max": nil, }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": nil, "max": nil, }, }, "info": market, }) } /** * @method * @name blofin#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://blofin.com/docs#get-order-book * @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 *blofin) 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 retRes5828 := (<-this.LoadMarkets()) PanicOnError(retRes5828) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } limit = Ternary(IsTrue((IsEqual(limit, nil))), 50, limit) if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", limit) // max 100 } response:= (<-this.PublicGetMarketBooks(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "", // "data": [ // { // "asks": [ // ["0.07228","4.211619","0","2"], // price, amount, liquidated orders, total open orders // ["0.0723","299.880364","0","2"], // ["0.07231","3.72832","0","1"], // ], // "bids": [ // ["0.07221","18.5","0","1"], // ["0.0722","18.5","0","1"], // ["0.07219","0.505407","0","1"], // ], // "ts": "1621438475342" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var first interface{} = this.SafeDict(data, 0, map[string]interface{} {}) var timestamp interface{} = this.SafeInteger(first, "ts") ch <- this.ParseOrderBook(first, symbol, timestamp) return nil }() return ch } func (this *blofin) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // response similar for REST & WS // // { // instId: "ADA-USDT", // ts: "1707736811486", // last: "0.5315", // lastSize: "4", // askPrice: "0.5318", // askSize: "248", // bidPrice: "0.5315", // bidSize: "63", // open24h: "0.5555", // high24h: "0.5563", // low24h: "0.5315", // volCurrency24h: "198560100", // vol24h: "1985601", // } // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeInteger(ticker, "ts") var marketId interface{} = this.SafeString(ticker, "instId") market = this.SafeMarket(marketId, market, "-") var symbol interface{} = GetValue(market, "symbol") var last interface{} = this.SafeString(ticker, "last") var open interface{} = this.SafeString(ticker, "open24h") var spot interface{} = this.SafeBool(market, "spot", false) var quoteVolume interface{} = Ternary(IsTrue(spot), this.SafeString(ticker, "volCurrency24h"), nil) var baseVolume interface{} = this.SafeString(ticker, "vol24h") var high interface{} = this.SafeString(ticker, "high24h") var low interface{} = this.SafeString(ticker, "low24h") return this.SafeTicker(map[string]interface{} { "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "high": high, "low": low, "bid": this.SafeString(ticker, "bidPrice"), "bidVolume": this.SafeString(ticker, "bidSize"), "ask": this.SafeString(ticker, "askPrice"), "askVolume": this.SafeString(ticker, "askSize"), "vwap": nil, "open": open, "close": last, "last": last, "previousClose": nil, "change": nil, "percentage": nil, "average": nil, "baseVolume": baseVolume, "quoteVolume": quoteVolume, "indexPrice": this.SafeString(ticker, "indexPrice"), "markPrice": this.SafeString(ticker, "markPrice"), "info": ticker, }, market) } /** * @method * @name blofin#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://blofin.com/docs#get-tickers * @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 *blofin) 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 retRes6868 := (<-this.LoadMarkets()) PanicOnError(retRes6868) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } response:= (<-this.PublicGetMarketTickers(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) var first interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseTicker(first, market) return nil }() return ch } /** * @method * @name blofin#fetchMarkPrice * @description fetches mark price for the market * @see https://docs.blofin.com/index.html#get-mark-price * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.subType] "linear" or "inverse" * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ func (this *blofin) FetchMarkPrice(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 retRes7088 := (<-this.LoadMarkets()) PanicOnError(retRes7088) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } response:= (<-this.PublicGetMarketMarkPrice(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) var first interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseTicker(first, market) return nil }() return ch } /** * @method * @name blofin#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://blofin.com/docs#get-tickers * @param {string[]} [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 *blofin) 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 retRes7298 := (<-this.LoadMarkets()) PanicOnError(retRes7298) symbols = this.MarketSymbols(symbols) response:= (<-this.PublicGetMarketTickers(params)) PanicOnError(response) var tickers interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTickers(tickers, symbols) return nil }() return ch } func (this *blofin) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // fetch trades (response similar for REST & WS) // // { // "tradeId": "3263934920", // "instId": "LTC-USDT", // "price": "67.87", // "size": "1", // "side": "buy", // "ts": "1707232020854" // } // // my trades // { // "instId": "LTC-USDT", // "tradeId": "1440847", // "orderId": "2075705202", // "fillPrice": "67.850000000000000000", // "fillSize": "1.000000000000000000", // "fillPnl": "0.000000000000000000", // "side": "buy", // "positionSide": "net", // "fee": "0.040710000000000000", // "ts": "1707224678878", // "brokerId": "" // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString(trade, "tradeId") var marketId interface{} = this.SafeString(trade, "instId") market = this.SafeMarket(marketId, market, "-") var symbol interface{} = GetValue(market, "symbol") var timestamp interface{} = this.SafeInteger(trade, "ts") var price interface{} = this.SafeString2(trade, "price", "fillPrice") var amount interface{} = this.SafeString2(trade, "size", "fillSize") var side interface{} = this.SafeString(trade, "side") var orderId interface{} = this.SafeString(trade, "orderId") var feeCost interface{} = this.SafeString(trade, "fee") var fee interface{} = nil if IsTrue(!IsEqual(feeCost, nil)) { fee = map[string]interface{} { "cost": feeCost, "currency": GetValue(market, "settle"), } } return this.SafeTrade(map[string]interface{} { "info": trade, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "symbol": symbol, "id": id, "order": orderId, "type": nil, "takerOrMaker": nil, "side": side, "price": price, "amount": amount, "cost": nil, "fee": fee, }, market) } /** * @method * @name blofin#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://blofin.com/docs#get-trades * @param {string} symbol unified symbol of the market to fetch trades for * @param {int} [since] timestamp in ms of the earliest trade to fetch * @param {int} [limit] the maximum amount of trades to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.paginate] *only applies to publicGetMarketHistoryTrades* default false, when true will automatically paginate by calling this endpoint multiple times * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ func (this *blofin) 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 retRes8118 := (<-this.LoadMarkets()) PanicOnError(retRes8118) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes81519 := (<-this.FetchPaginatedCallCursor("fetchTrades", symbol, since, limit, params, "tradeId", "after", nil, 100)) PanicOnError(retRes81519) ch <- retRes81519 return nil } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } var response interface{} = nil if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100 } var method interface{} = nil methodparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "method", "publicGetMarketTrades"); method = GetValue(methodparamsVariable,0); params = GetValue(methodparamsVariable,1) if IsTrue(IsEqual(method, "publicGetMarketTrades")) { response = (<-this.PublicGetMarketTrades(this.Extend(request, params))) PanicOnError(response) } var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTrades(data, market, since, limit) return nil }() return ch } func (this *blofin) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { // // [ // "1678928760000", // timestamp // "24341.4", // open // "24344", // high // "24313.2", // low // "24323", // close // "628", // contract volume // "2.5819", // base volume // "62800", // quote volume // "0" // candlestick state // ] // market := GetArg(optionalArgs, 0, nil) _ = market return []interface{}{this.SafeInteger(ohlcv, 0), this.SafeNumber(ohlcv, 1), this.SafeNumber(ohlcv, 2), this.SafeNumber(ohlcv, 3), this.SafeNumber(ohlcv, 4), this.SafeNumber(ohlcv, 6)} } /** * @method * @name blofin#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://blofin.com/docs#get-candlesticks * @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 * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *blofin) 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 retRes8738 := (<-this.LoadMarkets()) PanicOnError(retRes8738) var market interface{} = this.Market(symbol) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes87819 := (<-this.FetchPaginatedCallDeterministic("fetchOHLCV", symbol, since, limit, timeframe, params, 100)) PanicOnError(retRes87819) ch <- retRes87819 return nil } if IsTrue(IsEqual(limit, nil)) { limit = 100 // default 100, max 100 } var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), "bar": this.SafeString(this.Timeframes, timeframe, timeframe), "limit": limit, } var until interface{} = this.SafeInteger(params, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "after", until) params = this.Omit(params, "until") } var response interface{} = nil response = (<-this.PublicGetMarketCandles(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOHLCVs(data, market, timeframe, since, limit) return nil }() return ch } /** * @method * @name blofin#fetchFundingRateHistory * @description fetches historical funding rate prices * @see https://blofin.com/docs#get-funding-rate-history * @param {string} symbol unified symbol of the market to fetch the funding rate history for * @param {int} [since] timestamp in ms of the earliest funding rate to fetch * @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} */ func (this *blofin) FetchFundingRateHistory(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, " fetchFundingRateHistory() requires a symbol argument"))) } retRes9158 := (<-this.LoadMarkets()) PanicOnError(retRes9158) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchFundingRateHistory", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes91919 := (<-this.FetchPaginatedCallDeterministic("fetchFundingRateHistory", symbol, since, limit, "8h", params)) PanicOnError(retRes91919) ch <- retRes91919 return nil } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "before", mathMax(Subtract(since, 1), 0)) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PublicGetMarketFundingRateHistory(this.Extend(request, params))) PanicOnError(response) var rates interface{} = []interface{}{} var data interface{} = this.SafeList(response, "data", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var rate interface{} = GetValue(data, i) var timestamp interface{} = this.SafeInteger(rate, "fundingTime") AppendToArray(&rates,map[string]interface{} { "info": rate, "symbol": GetValue(market, "symbol"), "fundingRate": this.SafeNumber(rate, "fundingRate"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), }) } var sorted interface{} = this.SortBy(rates, "timestamp") ch <- this.FilterBySymbolSinceLimit(sorted, GetValue(market, "symbol"), since, limit) return nil }() return ch } func (this *blofin) ParseFundingRate(contract interface{}, optionalArgs ...interface{}) interface{} { // // { // "fundingRate": "0.00027815", // "fundingTime": "1634256000000", // "instId": "BTC-USD-SWAP", // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(contract, "instId") var symbol interface{} = this.SafeSymbol(marketId, market) var fundingTime interface{} = this.SafeInteger(contract, "fundingTime") // > The current interest is 0. return map[string]interface{} { "info": contract, "symbol": symbol, "markPrice": nil, "indexPrice": nil, "interestRate": this.ParseNumber("0"), "estimatedSettlePrice": nil, "timestamp": nil, "datetime": nil, "fundingRate": this.SafeNumber(contract, "fundingRate"), "fundingTimestamp": fundingTime, "fundingDatetime": this.Iso8601(fundingTime), "nextFundingRate": nil, "nextFundingTimestamp": nil, "nextFundingDatetime": nil, "previousFundingRate": nil, "previousFundingTimestamp": nil, "previousFundingDatetime": nil, "interval": nil, } } /** * @method * @name blofin#fetchFundingRate * @description fetch the current funding rate * @see https://blofin.com/docs#get-funding-rate * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure} */ func (this *blofin) FetchFundingRate(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 retRes9938 := (<-this.LoadMarkets()) PanicOnError(retRes9938) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "swap")) { panic(ExchangeError(Add(this.Id, " fetchFundingRate() is only valid for swap markets"))) } var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } response:= (<-this.PublicGetMarketFundingRate(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "fundingRate": "0.00027815", // "fundingTime": "1634256000000", // "instId": "BTC-USD-SWAP", // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var entry interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseFundingRate(entry, market) return nil }() return ch } func (this *blofin) ParseBalanceByType(response interface{}) interface{} { var data interface{} = this.SafeList(response, "data") if IsTrue(IsTrue((!IsEqual(data, nil))) && IsTrue(IsArray(data))) { return this.ParseFundingBalance(response) } else { return this.ParseBalance(response) } } func (this *blofin) ParseBalance(response interface{}) interface{} { // // "data" similar for REST & WS // // { // "code": "0", // "msg": "success", // "data": { // "ts": "1697021343571", // "totalEquity": "10011254.077985990315787910", // "isolatedEquity": "861.763132108800000000", // "details": [ // { // "currency": "USDT", // "equity": "10014042.988958415234430699548", // "balance": "10013119.885958415234430699", // "ts": "1697021343571", // "isolatedEquity": "862.003200000000000000048", // "available": "9996399.4708691159703362725", // "availableEquity": "9996399.4708691159703362725", // "frozen": "15805.149672632597427761", // "orderFrozen": "14920.994472632597427761", // "equityUsd": "10011254.077985990315787910", // "isolatedUnrealizedPnl": "-22.151999999999999999952", // "bonus": "0" // present only in REST // "unrealizedPnl": "0" // present only in WS // } // ] // } // } // var result interface{} = map[string]interface{} { "info": response, } var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) var timestamp interface{} = this.SafeInteger(data, "ts") var details interface{} = this.SafeList(data, "details", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(details)); i++ { var balance interface{} = GetValue(details, i) var currencyId interface{} = this.SafeString(balance, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) var account interface{} = this.Account() // it may be incorrect to use total, free and used for swap accounts var eq interface{} = this.SafeString(balance, "equity") var availEq interface{} = this.SafeString(balance, "available") if IsTrue(IsTrue((IsEqual(eq, nil))) || IsTrue((IsEqual(availEq, nil)))) { AddElementToObject(account, "free", this.SafeString(balance, "availableEquity")) AddElementToObject(account, "used", this.SafeString(balance, "frozen")) } else { AddElementToObject(account, "total", eq) AddElementToObject(account, "free", availEq) } AddElementToObject(result, code, account) } AddElementToObject(result, "timestamp", timestamp) AddElementToObject(result, "datetime", this.Iso8601(timestamp)) return this.SafeBalance(result) } func (this *blofin) ParseFundingBalance(response interface{}) interface{} { // // { // "code": "0", // "msg": "success", // "data": [ // { // "currency": "USDT", // "balance": "10012514.919418081548717298", // "available": "9872132.414278782284622898", // "frozen": "138556.471805965930761067", // "bonus": "0" // } // ] // } // var result interface{} = map[string]interface{} { "info": response, } var data interface{} = this.SafeList(response, "data", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var balance interface{} = GetValue(data, i) var currencyId interface{} = this.SafeString(balance, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) var account interface{} = this.Account() // it may be incorrect to use total, free and used for swap accounts AddElementToObject(account, "total", this.SafeString(balance, "balance")) AddElementToObject(account, "free", this.SafeString(balance, "available")) AddElementToObject(account, "used", this.SafeString(balance, "frozen")) AddElementToObject(result, code, account) } return this.SafeBalance(result) } func (this *blofin) ParseTradingFee(fee interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market return map[string]interface{} { "info": fee, "symbol": this.SafeSymbol(nil, market), "maker": this.ParseNumber(Precise.StringNeg(this.SafeString2(fee, "maker", "makerU"))), "taker": this.ParseNumber(Precise.StringNeg(this.SafeString2(fee, "taker", "takerU"))), "percentage": nil, "tierBased": nil, } } /** * @method * @name blofin#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://blofin.com/docs#get-balance * @see https://blofin.com/docs#get-futures-account-balance * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.accountType] the type of account to fetch the balance for, either 'funding' or 'futures' or 'copy_trading' or 'earn' * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure} */ func (this *blofin) 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 retRes11418 := (<-this.LoadMarkets()) PanicOnError(retRes11418) var accountType interface{} = nil accountTypeparamsVariable := this.HandleOptionAndParams2(params, "fetchBalance", "accountType", "type"); accountType = GetValue(accountTypeparamsVariable,0); params = GetValue(accountTypeparamsVariable,1) var request interface{} = map[string]interface{} {} var response interface{} = nil if IsTrue(IsTrue(!IsEqual(accountType, nil)) && IsTrue(!IsEqual(accountType, "swap"))) { var options interface{} = this.SafeDict(this.Options, "accountsByType", map[string]interface{} {}) var parsedAccountType interface{} = this.SafeString(options, accountType, accountType) AddElementToObject(request, "accountType", parsedAccountType) response = (<-this.PrivateGetAssetBalances(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateGetAccountBalance(this.Extend(request, params))) PanicOnError(response) } ch <- this.ParseBalanceByType(response) return nil }() return ch } func (this *blofin) CreateOrderRequest(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) interface{} { price := GetArg(optionalArgs, 0, nil) _ = price params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), "side": side, "orderType": typeVar, "size": this.AmountToPrecision(symbol, amount), "brokerId": this.SafeString(this.Options, "brokerId", "ec6dd3a7dd982d0b"), } var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("createOrder", params, "cross"); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) AddElementToObject(request, "marginMode", marginMode) var timeInForce interface{} = this.SafeString(params, "timeInForce", "GTC") var isMarketOrder interface{} = IsEqual(typeVar, "market") params = this.Omit(params, []interface{}{"timeInForce"}) var ioc interface{} = IsTrue((IsEqual(timeInForce, "IOC"))) || IsTrue((IsEqual(typeVar, "ioc"))) var marketIOC interface{} = (IsTrue(isMarketOrder) && IsTrue(ioc)) if IsTrue(IsTrue(isMarketOrder) || IsTrue(marketIOC)) { AddElementToObject(request, "orderType", "market") } else { AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) } var postOnly interface{} = false postOnlyparamsVariable := this.HandlePostOnly(isMarketOrder, IsEqual(typeVar, "post_only"), params); postOnly = GetValue(postOnlyparamsVariable,0); params = GetValue(postOnlyparamsVariable,1) if IsTrue(postOnly) { AddElementToObject(request, "type", "post_only") } var stopLoss interface{} = this.SafeDict(params, "stopLoss") var takeProfit interface{} = this.SafeDict(params, "takeProfit") params = this.Omit(params, []interface{}{"stopLoss", "takeProfit"}) var isStopLoss interface{} = !IsEqual(stopLoss, nil) var isTakeProfit interface{} = !IsEqual(takeProfit, nil) if IsTrue(IsTrue(isStopLoss) || IsTrue(isTakeProfit)) { if IsTrue(isStopLoss) { var slTriggerPrice interface{} = this.SafeString2(stopLoss, "triggerPrice", "stopPrice") AddElementToObject(request, "slTriggerPrice", this.PriceToPrecision(symbol, slTriggerPrice)) var slOrderPrice interface{} = this.SafeString(stopLoss, "price", "-1") AddElementToObject(request, "slOrderPrice", this.PriceToPrecision(symbol, slOrderPrice)) } if IsTrue(isTakeProfit) { var tpTriggerPrice interface{} = this.SafeString2(takeProfit, "triggerPrice", "stopPrice") AddElementToObject(request, "tpTriggerPrice", this.PriceToPrecision(symbol, tpTriggerPrice)) var tpPrice interface{} = this.SafeString(takeProfit, "price", "-1") AddElementToObject(request, "tpOrderPrice", this.PriceToPrecision(symbol, tpPrice)) } } return this.Extend(request, params) } func (this *blofin) ParseOrderStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "canceled": "canceled", "order_failed": "canceled", "live": "open", "partially_filled": "open", "filled": "closed", "effective": "closed", } return this.SafeString(statuses, status, status) } func (this *blofin) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // response similar for REST & WS // // { // "orderId": "2075628533", // "clientOrderId": "", // "instId": "LTC-USDT", // "marginMode": "cross", // "positionSide": "net", // "side": "buy", // "orderType": "market", // "price": "0.000000000000000000", // "size": "1.000000000000000000", // "reduceOnly": "true", // "leverage": "3", // "state": "filled", // "filledSize": "1.000000000000000000", // "pnl": "-0.050000000000000000", // "averagePrice": "68.110000000000000000", // "fee": "0.040866000000000000", // "createTime": "1706891359010", // "updateTime": "1706891359098", // "orderCategory": "normal", // "tpTriggerPrice": null, // "tpOrderPrice": null, // "slTriggerPrice": null, // "slOrderPrice": null, // "cancelSource": "not_canceled", // "cancelSourceReason": null, // "brokerId": "ec6dd3a7dd982d0b" // "filled_amount": "1.000000000000000000", // filledAmount in "ws" watchOrders // "cancelSource": "", // only in WS // "instType": "SWAP", // only in WS // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString2(order, "tpslId", "orderId") var timestamp interface{} = this.SafeInteger(order, "createTime") var lastUpdateTimestamp interface{} = this.SafeInteger(order, "updateTime") var lastTradeTimestamp interface{} = this.SafeInteger(order, "fillTime") var side interface{} = this.SafeString(order, "side") var typeVar interface{} = this.SafeString(order, "orderType") var postOnly interface{} = nil var timeInForce interface{} = nil if IsTrue(IsEqual(typeVar, "post_only")) { postOnly = true typeVar = "limit" } else if IsTrue(IsEqual(typeVar, "fok")) { timeInForce = "FOK" typeVar = "limit" } else if IsTrue(IsEqual(typeVar, "ioc")) { timeInForce = "IOC" typeVar = "limit" } var marketId interface{} = this.SafeString(order, "instId") market = this.SafeMarket(marketId, market) var symbol interface{} = this.SafeSymbol(marketId, market, "-") var filled interface{} = this.SafeString(order, "filledSize") var price interface{} = this.SafeString2(order, "px", "price") var average interface{} = this.SafeString(order, "averagePrice") var status interface{} = this.ParseOrderStatus(this.SafeString(order, "state")) var feeCostString interface{} = this.SafeString(order, "fee") var amount interface{} = this.SafeString(order, "size") var leverage interface{} = this.SafeString(order, "leverage", "1") var contractSize interface{} = this.SafeString(market, "contractSize") var baseAmount interface{} = Precise.StringMul(contractSize, filled) var cost interface{} = nil if IsTrue(!IsEqual(average, nil)) { cost = Precise.StringMul(average, baseAmount) cost = Precise.StringDiv(cost, leverage) } // spot market buy: "sz" can refer either to base currency units or to quote currency units var fee interface{} = nil if IsTrue(!IsEqual(feeCostString, nil)) { var feeCostSigned interface{} = Precise.StringAbs(feeCostString) var feeCurrencyId interface{} = this.SafeString(order, "feeCcy", "USDT") var feeCurrencyCode interface{} = this.SafeCurrencyCode(feeCurrencyId) fee = map[string]interface{} { "cost": this.ParseNumber(feeCostSigned), "currency": feeCurrencyCode, } } var clientOrderId interface{} = this.SafeString(order, "clientOrderId") if IsTrue(IsTrue((!IsEqual(clientOrderId, nil))) && IsTrue((IsLessThan(GetLength(clientOrderId), 1)))) { clientOrderId = nil // fix empty clientOrderId string } var stopLossTriggerPrice interface{} = this.SafeNumber(order, "slTriggerPrice") var stopLossPrice interface{} = this.SafeNumber(order, "slOrderPrice") var takeProfitTriggerPrice interface{} = this.SafeNumber(order, "tpTriggerPrice") var takeProfitPrice interface{} = this.SafeNumber(order, "tpOrderPrice") var reduceOnlyRaw interface{} = this.SafeString(order, "reduceOnly") var reduceOnly interface{} = (IsEqual(reduceOnlyRaw, "true")) return this.SafeOrder(map[string]interface{} { "info": order, "id": id, "clientOrderId": clientOrderId, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastTradeTimestamp": lastTradeTimestamp, "lastUpdateTimestamp": lastUpdateTimestamp, "symbol": symbol, "type": typeVar, "timeInForce": timeInForce, "postOnly": postOnly, "side": side, "price": price, "stopLossTriggerPrice": stopLossTriggerPrice, "takeProfitTriggerPrice": takeProfitTriggerPrice, "stopLossPrice": stopLossPrice, "takeProfitPrice": takeProfitPrice, "average": average, "cost": cost, "amount": amount, "filled": filled, "remaining": nil, "status": status, "fee": fee, "trades": nil, "reduceOnly": reduceOnly, }, market) } /** * @method * @name blofin#createOrder * @description create a trade order * @see https://blofin.com/docs#place-order * @see https://blofin.com/docs#place-tpsl-order * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' or 'post_only' or 'ioc' or 'fok' * @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 {bool} [params.reduceOnly] a mark to reduce the position size for margin, swap and future orders * @param {bool} [params.postOnly] true to place a post only order * @param {string} [params.marginMode] 'cross' or 'isolated', default is 'cross' * @param {float} [params.stopLossPrice] stop loss trigger price (will use privatePostTradeOrderTpsl) * @param {float} [params.takeProfitPrice] take profit trigger price (will use privatePostTradeOrderTpsl) * @param {string} [params.positionSide] *stopLossPrice/takeProfitPrice orders only* 'long' or 'short' or 'net' default is 'net' * @param {string} [params.clientOrderId] a unique id for the order * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered * @param {float} [params.takeProfit.triggerPrice] take profit trigger price * @param {float} [params.takeProfit.price] take profit order price (if not provided the order will be a market order) * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price * @param {float} [params.stopLoss.price] stop loss order price (if not provided the order will be a market order) * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *blofin) 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 retRes13698 := (<-this.LoadMarkets()) PanicOnError(retRes13698) var market interface{} = this.Market(symbol) var tpsl interface{} = this.SafeBool(params, "tpsl", false) params = this.Omit(params, "tpsl") var method interface{} = nil methodparamsVariable := this.HandleOptionAndParams(params, "createOrder", "method", "privatePostTradeOrder"); method = GetValue(methodparamsVariable,0); params = GetValue(methodparamsVariable,1) var isStopLossPriceDefined interface{} = !IsEqual(this.SafeString(params, "stopLossPrice"), nil) var isTakeProfitPriceDefined interface{} = !IsEqual(this.SafeString(params, "takeProfitPrice"), nil) var isType2Order interface{} = (IsTrue(isStopLossPriceDefined) || IsTrue(isTakeProfitPriceDefined)) var response interface{} = nil if IsTrue(IsTrue(IsTrue(tpsl) || IsTrue((IsEqual(method, "privatePostTradeOrderTpsl")))) || IsTrue(isType2Order)) { var tpslRequest interface{} = this.CreateTpslOrderRequest(symbol, typeVar, side, amount, price, params) response = (<-this.PrivatePostTradeOrderTpsl(tpslRequest)) PanicOnError(response) } else { var request interface{} = this.CreateOrderRequest(symbol, typeVar, side, amount, price, params) response = (<-this.PrivatePostTradeOrder(request)) PanicOnError(response) } var data interface{} = this.SafeList(response, "data", []interface{}{}) var first interface{} = this.SafeDict(data, 0) var order interface{} = this.ParseOrder(first, market) AddElementToObject(order, "type", typeVar) AddElementToObject(order, "side", side) ch <- order return nil }() return ch } func (this *blofin) CreateTpslOrderRequest(symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) interface{} { amount := GetArg(optionalArgs, 0, nil) _ = amount price := GetArg(optionalArgs, 1, nil) _ = price params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params var market interface{} = this.Market(symbol) var positionSide interface{} = this.SafeString(params, "positionSide", "net") var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), "side": side, "positionSide": positionSide, "brokerId": this.SafeString(this.Options, "brokerId", "ec6dd3a7dd982d0b"), } if IsTrue(!IsEqual(amount, nil)) { AddElementToObject(request, "size", this.AmountToPrecision(symbol, amount)) } var marginMode interface{} = this.SafeString(params, "marginMode", "cross") // cross or isolated if IsTrue(IsTrue(!IsEqual(marginMode, "cross")) && IsTrue(!IsEqual(marginMode, "isolated"))) { panic(BadRequest(Add(this.Id, " createTpslOrder() requires a marginMode parameter that must be either cross or isolated"))) } var stopLossPrice interface{} = this.SafeString(params, "stopLossPrice") var takeProfitPrice interface{} = this.SafeString(params, "takeProfitPrice") if IsTrue(!IsEqual(stopLossPrice, nil)) { AddElementToObject(request, "slTriggerPrice", this.PriceToPrecision(symbol, stopLossPrice)) if IsTrue(IsEqual(typeVar, "market")) { AddElementToObject(request, "slOrderPrice", "-1") } else { AddElementToObject(request, "slOrderPrice", this.PriceToPrecision(symbol, price)) } } else if IsTrue(!IsEqual(takeProfitPrice, nil)) { AddElementToObject(request, "tpTriggerPrice", this.PriceToPrecision(symbol, takeProfitPrice)) if IsTrue(IsEqual(typeVar, "market")) { AddElementToObject(request, "tpOrderPrice", "-1") } else { AddElementToObject(request, "tpOrderPrice", this.PriceToPrecision(symbol, price)) } } AddElementToObject(request, "marginMode", marginMode) params = this.Omit(params, []interface{}{"stopLossPrice", "takeProfitPrice"}) return this.Extend(request, params) } /** * @method * @name blofin#cancelOrder * @description cancels an open order * @see https://blofin.com/docs#cancel-order * @see https://blofin.com/docs#cancel-tpsl-order * @param {string} id order id * @param {string} symbol unified symbol of the market the order was made in * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.trigger] True if cancelling a trigger/conditional order/tp sl orders * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *blofin) CancelOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrder() requires a symbol argument"))) } retRes14488 := (<-this.LoadMarkets()) PanicOnError(retRes14488) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } var isTrigger interface{} = this.SafeBoolN(params, []interface{}{"stop", "trigger", "tpsl"}, false) var clientOrderId interface{} = this.SafeString(params, "clientOrderId") if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "clientOrderId", clientOrderId) } else { if !IsTrue(isTrigger) { AddElementToObject(request, "orderId", ToString(id)) } else { AddElementToObject(request, "tpslId", ToString(id)) } } var query interface{} = this.Omit(params, []interface{}{"orderId", "clientOrderId", "stop", "trigger", "tpsl"}) if IsTrue(isTrigger) { tpslResponse:= (<-this.CancelOrders([]interface{}{id}, symbol, params)) PanicOnError(tpslResponse) var first interface{} = this.SafeDict(tpslResponse, 0) ch <- first return nil } response:= (<-this.PrivatePostTradeCancelOrder(this.Extend(request, query))) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) var order interface{} = this.SafeDict(data, 0) ch <- this.ParseOrder(order, market) return nil }() return ch } /** * @method * @name blofin#createOrders * @description create a list of trade orders * @see https://blofin.com/docs#place-multiple-orders * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params * @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 *blofin) CreateOrders(orders 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 retRes14868 := (<-this.LoadMarkets()) PanicOnError(retRes14868) var ordersRequests interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { var rawOrder interface{} = GetValue(orders, i) var marketId interface{} = this.SafeString(rawOrder, "symbol") var typeVar interface{} = this.SafeString(rawOrder, "type") var side interface{} = this.SafeString(rawOrder, "side") var amount interface{} = this.SafeValue(rawOrder, "amount") var price interface{} = this.SafeValue(rawOrder, "price") var orderParams interface{} = this.SafeDict(rawOrder, "params", map[string]interface{} {}) var extendedParams interface{} = this.Extend(orderParams, params) // the request does not accept extra params since it's a list, so we're extending each order with the common params var orderRequest interface{} = this.CreateOrderRequest(marketId, typeVar, side, amount, price, extendedParams) AppendToArray(&ordersRequests,orderRequest) } response:= (<-this.PrivatePostTradeBatchOrders(ordersRequests)) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(data) return nil }() return ch } /** * @method * @name blofin#fetchOpenOrders * @description Fetch orders that are still open * @see https://blofin.com/docs#get-active-orders * @see https://blofin.com/docs#get-active-tpsl-orders * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch open orders for * @param {int} [limit] the maximum number of open orders structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {bool} [params.trigger] True if fetching trigger or conditional orders * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *blofin) 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 retRes15208 := (<-this.LoadMarkets()) PanicOnError(retRes15208) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOpenOrders", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes152419 := (<-this.FetchPaginatedCallDynamic("fetchOpenOrders", symbol, since, limit, params)) PanicOnError(retRes152419) ch <- retRes152419 return nil } var request interface{} = map[string]interface{} {} var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "instId", GetValue(market, "id")) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 100 } var isTrigger interface{} = this.SafeBoolN(params, []interface{}{"stop", "trigger", "tpsl", "TPSL"}, false) var method interface{} = nil methodparamsVariable := this.HandleOptionAndParams(params, "fetchOpenOrders", "method", "privateGetTradeOrdersPending"); method = GetValue(methodparamsVariable,0); params = GetValue(methodparamsVariable,1) var query interface{} = this.Omit(params, []interface{}{"method", "stop", "trigger", "tpsl", "TPSL"}) var response interface{} = nil if IsTrue(IsTrue(isTrigger) || IsTrue((IsEqual(method, "privateGetTradeOrdersTpslPending")))) { response = (<-this.PrivateGetTradeOrdersTpslPending(this.Extend(request, query))) PanicOnError(response) } else { response = (<-this.PrivateGetTradeOrdersPending(this.Extend(request, query))) PanicOnError(response) } var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(data, market, since, limit) return nil }() return ch } /** * @method * @name blofin#fetchMyTrades * @description fetch all trades made by the user * @see https://blofin.com/docs#get-trade-history * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] Timestamp in ms of the latest time to retrieve trades for * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *blofin) 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 retRes15648 := (<-this.LoadMarkets()) PanicOnError(retRes15648) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchMyTrades", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes156819 := (<-this.FetchPaginatedCallDynamic("fetchMyTrades", symbol, since, limit, params)) PanicOnError(retRes156819) ch <- retRes156819 return nil } var request interface{} = map[string]interface{} {} var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "instId", GetValue(market, "id")) } requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 100 } response:= (<-this.PrivateGetTradeFillsHistory(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTrades(data, market, since, limit) return nil }() return ch } /** * @method * @name blofin#fetchDeposits * @description fetch all deposits made to an account * @see https://blofin.com/docs#get-deposite-history * @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 * @param {int} [params.until] the latest time in ms to fetch entries for * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *blofin) 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 retRes16008 := (<-this.LoadMarkets()) PanicOnError(retRes16008) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchDeposits", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes160419 := (<-this.FetchPaginatedCallDynamic("fetchDeposits", code, since, limit, params)) PanicOnError(retRes160419) ch <- retRes160419 return nil } var request interface{} = map[string]interface{} {} var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "currency", GetValue(currency, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "before", mathMax(Subtract(since, 1), 0)) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 100 } requestparamsVariable := this.HandleUntilOption("after", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.PrivateGetAssetDepositHistory(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTransactions(data, currency, since, limit, params) return nil }() return ch } /** * @method * @name blofin#fetchWithdrawals * @description fetch all withdrawals made from an account * @see https://blofin.com/docs#get-withdraw-history * @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 * @param {int} [params.until] the latest time in ms to fetch entries for * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *blofin) 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 retRes16398 := (<-this.LoadMarkets()) PanicOnError(retRes16398) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchWithdrawals", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes164319 := (<-this.FetchPaginatedCallDynamic("fetchWithdrawals", code, since, limit, params)) PanicOnError(retRes164319) ch <- retRes164319 return nil } var request interface{} = map[string]interface{} {} var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "currency", GetValue(currency, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "before", mathMax(Subtract(since, 1), 0)) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 100 } requestparamsVariable := this.HandleUntilOption("after", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.PrivateGetAssetWithdrawalHistory(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTransactions(data, currency, since, limit, params) return nil }() return ch } /** * @method * @name blofin#fetchLedger * @description fetch the history of changes, actions done by the user or operations that altered the balance of the user * @see https://blofin.com/docs#get-funds-transfer-history * @param {string} [code] unified currency code, default is undefined * @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined * @param {int} [limit] max number of ledger entries to return, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.marginMode] 'cross' or 'isolated' * @param {int} [params.until] the latest time in ms to fetch entries for * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger} */ func (this *blofin) FetchLedger(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes16798 := (<-this.LoadMarkets()) PanicOnError(retRes16798) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchLedger", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes168319 := (<-this.FetchPaginatedCallDynamic("fetchLedger", code, since, limit, params)) PanicOnError(retRes168319) ch <- retRes168319 return nil } var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "currency", GetValue(currency, "id")) } requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) var response interface{} = nil response = (<-this.PrivateGetAssetBills(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseLedger(data, currency, since, limit) return nil }() return ch } func (this *blofin) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // // fetchDeposits // // { // "currency": "USDT", // "chain": "TRC20", // "address": "TGfJLtnsh3B9EqekFEBZ1nR14QanBUf5Bi", // "txId": "892f4e0c32268b29b2e541ef30d32a30bbf10f902adcc4b1428319ed7c3758fd", // "type": "0", // "amount": "86.975843", // "state": "1", // "ts": "1703163304153", // "tag": null, // "confirm": "16", // "depositId": "36c8e2a7ea184a219de72215a696acaf" // } // fetchWithdrawals // { // "currency": "USDT", // "chain": "TRC20", // "address": "TYgB3sVXHPEDQUu288EG1uMFh9Pk2swLgW", // "txId": "1fd5ac52df414d7ea66194cadd9a5b4d2422c2b9720037f66d98207f9858fd96", // "type": "0", // "amount": "9", // "fee": "1", // "feeCurrency": "USDT", // "state": "3", // "clientId": null, // "ts": "1707217439351", // "tag": null, // "memo": null, // "withdrawId": "e0768698cfdf4aee8e54654c3775914b" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var typeVar interface{} = nil var id interface{} = nil var withdrawalId interface{} = this.SafeString(transaction, "withdrawId") var depositId interface{} = this.SafeString(transaction, "depositId") var addressTo interface{} = this.SafeString(transaction, "address") var address interface{} = addressTo var tagTo interface{} = this.SafeString(transaction, "tag") if IsTrue(!IsEqual(withdrawalId, nil)) { typeVar = "withdrawal" id = withdrawalId } else { id = depositId typeVar = "deposit" } var currencyId interface{} = this.SafeString(transaction, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) var amount interface{} = this.SafeNumber(transaction, "amount") var status interface{} = this.ParseTransactionStatus(this.SafeString(transaction, "state")) var txid interface{} = this.SafeString(transaction, "txId") var timestamp interface{} = this.SafeInteger(transaction, "ts") var feeCurrencyId interface{} = this.SafeString(transaction, "feeCurrency") var feeCode interface{} = this.SafeCurrencyCode(feeCurrencyId) var feeCost interface{} = this.SafeNumber(transaction, "fee") return map[string]interface{} { "info": transaction, "id": id, "currency": code, "amount": amount, "network": nil, "addressFrom": nil, "addressTo": addressTo, "address": address, "tagFrom": nil, "tagTo": tagTo, "tag": tagTo, "status": status, "type": typeVar, "updated": nil, "txid": txid, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "internal": nil, "comment": nil, "fee": map[string]interface{} { "currency": feeCode, "cost": feeCost, }, } } func (this *blofin) ParseTransactionStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "0": "pending", "1": "ok", "2": "failed", "3": "pending", } return this.SafeString(statuses, status, status) } func (this *blofin) ParseLedgerEntryType(typeVar interface{}) interface{} { var types interface{} = map[string]interface{} { "1": "transfer", "2": "trade", "3": "trade", "4": "rebate", "5": "trade", "6": "transfer", "7": "trade", "8": "fee", "9": "trade", "10": "trade", "11": "trade", } return this.SafeString(types, typeVar, typeVar) } func (this *blofin) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} { currency := GetArg(optionalArgs, 0, nil) _ = currency var currencyId interface{} = this.SafeString(item, "currency") var code interface{} = this.SafeCurrencyCode(currencyId, currency) currency = this.SafeCurrency(currencyId, currency) var timestamp interface{} = this.SafeInteger(item, "ts") return this.SafeLedgerEntry(map[string]interface{} { "info": item, "id": this.SafeString(item, "transferId"), "direction": nil, "account": nil, "referenceId": this.SafeString(item, "clientId"), "referenceAccount": nil, "type": this.ParseLedgerEntryType(this.SafeString(item, "type")), "currency": code, "amount": this.SafeNumber(item, "amount"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "before": nil, "after": nil, "status": "ok", "fee": nil, }, currency) } func (this *blofin) ParseIds(ids interface{}) interface{} { /** * @ignore * @method * @name blofin#parseIds * @param {string[]|string} ids order ids * @returns {string[]} list of order ids */ if IsTrue(IsString(ids)) { return Split(ids, ",") } else { return ids } } /** * @method * @name blofin#cancelOrders * @description cancel multiple orders * @see https://blofin.com/docs#cancel-multiple-orders * @param {string[]} ids order ids * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.trigger] whether the order is a stop/trigger order * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *blofin) CancelOrders(ids interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // TODO : the original endpoint signature differs, according to that you can skip individual symbol and assign ids in batch. At this moment, `params` is not being used too. symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrders() requires a symbol argument"))) } retRes18708 := (<-this.LoadMarkets()) PanicOnError(retRes18708) var market interface{} = this.Market(symbol) var request interface{} = []interface{}{} var options interface{} = this.SafeDict(this.Options, "cancelOrders", map[string]interface{} {}) var defaultMethod interface{} = this.SafeString(options, "method", "privatePostTradeCancelBatchOrders") var method interface{} = this.SafeString(params, "method", defaultMethod) var clientOrderIds interface{} = this.ParseIds(this.SafeValue(params, "clientOrderId")) var tpslIds interface{} = this.ParseIds(this.SafeValue(params, "tpslId")) var trigger interface{} = this.SafeBoolN(params, []interface{}{"stop", "trigger", "tpsl"}) if IsTrue(trigger) { method = "privatePostTradeCancelTpsl" } if IsTrue(IsEqual(clientOrderIds, nil)) { ids = this.ParseIds(ids) if IsTrue(!IsEqual(tpslIds, nil)) { for i := 0; IsLessThan(i, GetArrayLength(tpslIds)); i++ { AppendToArray(&request,map[string]interface{} { "tpslId": GetValue(tpslIds, i), "instId": GetValue(market, "id"), }) } } for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ { if IsTrue(trigger) { AppendToArray(&request,map[string]interface{} { "tpslId": GetValue(ids, i), "instId": GetValue(market, "id"), }) } else { AppendToArray(&request,map[string]interface{} { "orderId": GetValue(ids, i), "instId": GetValue(market, "id"), }) } } } else { for i := 0; IsLessThan(i, GetArrayLength(clientOrderIds)); i++ { AppendToArray(&request,map[string]interface{} { "instId": GetValue(market, "id"), "clientOrderId": GetValue(clientOrderIds, i), }) } } var response interface{} = nil if IsTrue(IsEqual(method, "privatePostTradeCancelTpsl")) { response = (<-this.PrivatePostTradeCancelTpsl(request)) PanicOnError(response) // * dont extend with params, otherwise ARRAY will be turned into OBJECT } else { response = (<-this.PrivatePostTradeCancelBatchOrders(request)) PanicOnError(response) // * dont extend with params, otherwise ARRAY will be turned into OBJECT } var ordersData interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(ordersData, market, nil, nil, params) return nil }() return ch } /** * @method * @name blofin#transfer * @description transfer currency internally between wallets on the same account * @see https://blofin.com/docs#funds-transfer * @param {string} code unified currency code * @param {float} amount amount to transfer * @param {string} fromAccount account to transfer from (funding, swap, copy_trading, earn) * @param {string} toAccount account to transfer to (funding, swap, copy_trading, earn) * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure} */ func (this *blofin) Transfer(code interface{}, amount interface{}, fromAccount interface{}, toAccount 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 retRes19368 := (<-this.LoadMarkets()) PanicOnError(retRes19368) var currency interface{} = this.Currency(code) var accountsByType interface{} = this.SafeDict(this.Options, "accountsByType", map[string]interface{} {}) var fromId interface{} = this.SafeString(accountsByType, fromAccount, fromAccount) var toId interface{} = this.SafeString(accountsByType, toAccount, toAccount) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), "amount": this.CurrencyToPrecision(code, amount), "fromAccount": fromId, "toAccount": toId, } response:= (<-this.PrivatePostAssetTransfer(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseTransfer(data, currency) return nil }() return ch } func (this *blofin) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} { currency := GetArg(optionalArgs, 0, nil) _ = currency var id interface{} = this.SafeString(transfer, "transferId") return map[string]interface{} { "info": transfer, "id": id, "timestamp": nil, "datetime": nil, "currency": nil, "amount": nil, "fromAccount": nil, "toAccount": nil, "status": nil, } } /** * @method * @name blofin#fetchPosition * @description fetch data on a single open contract trade position * @see https://blofin.com/docs#get-positions * @param {string} symbol unified market symbol of the market the position is held in, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.instType] MARGIN, SWAP, FUTURES, OPTION * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *blofin) FetchPosition(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 retRes19788 := (<-this.LoadMarkets()) PanicOnError(retRes19788) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } response:= (<-this.PrivateGetAccountPositions(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) var position interface{} = this.SafeDict(data, 0) if IsTrue(IsEqual(position, nil)) { return nil } ch <- this.ParsePosition(position, market) return nil }() return ch } /** * @method * @name blofin#fetchPositions * @description fetch data on a single open contract trade position * @see https://blofin.com/docs#get-positions * @param {string[]} [symbols] list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.instType] MARGIN, SWAP, FUTURES, OPTION * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *blofin) FetchPositions(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 retRes20038 := (<-this.LoadMarkets()) PanicOnError(retRes20038) symbols = this.MarketSymbols(symbols) response:= (<-this.PrivateGetAccountPositions(params)) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) var result interface{} = this.ParsePositions(data) ch <- this.FilterByArrayPositions(result, "symbol", symbols, false) return nil }() return ch } func (this *blofin) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} { // // response similar for REST & WS // // { // instType: 'SWAP', // instId: 'LTC-USDT', // marginMode: 'cross', // positionId: '644159', // positionSide: 'net', // positions: '1', // availablePositions: '1', // averagePrice: '68.16', // unrealizedPnl: '0.80631223', // unrealizedPnlRatio: '0.03548909463028169', // leverage: '3', // liquidationPrice: '10.116655172370356435', // markPrice: '68.96', // initialMargin: '22.988770743333333333', // margin: '', // this field might not exist in rest response // marginRatio: '152.523509620342499273', // maintenanceMargin: '0.34483156115', // adl: '4', // createTime: '1707235776528', // updateTime: '1707235776528' // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(position, "instId") market = this.SafeMarket(marketId, market) var symbol interface{} = GetValue(market, "symbol") var pos interface{} = this.SafeString(position, "positions") var contractsAbs interface{} = Precise.StringAbs(pos) var side interface{} = this.SafeString(position, "positionSide") var hedged interface{} = !IsEqual(side, "net") var contracts interface{} = this.ParseNumber(contractsAbs) if IsTrue(!IsEqual(pos, nil)) { if IsTrue(IsEqual(side, "net")) { if IsTrue(Precise.StringGt(pos, "0")) { side = "long" } else if IsTrue(Precise.StringLt(pos, "0")) { side = "short" } else { side = nil } } } var contractSize interface{} = this.SafeNumber(market, "contractSize") var contractSizeString interface{} = this.NumberToString(contractSize) var markPriceString interface{} = this.SafeString(position, "markPrice") var notionalString interface{} = this.SafeString(position, "notionalUsd") if IsTrue(GetValue(market, "inverse")) { notionalString = Precise.StringDiv(Precise.StringMul(contractsAbs, contractSizeString), markPriceString) } var notional interface{} = this.ParseNumber(notionalString) var marginMode interface{} = this.SafeString(position, "marginMode") var initialMarginString interface{} = nil var entryPriceString interface{} = this.SafeString(position, "averagePrice") var unrealizedPnlString interface{} = this.SafeString(position, "unrealizedPnl") var leverageString interface{} = this.SafeString(position, "leverage") var initialMarginPercentage interface{} = nil var collateralString interface{} = nil if IsTrue(IsEqual(marginMode, "cross")) { initialMarginString = this.SafeString(position, "initialMargin") collateralString = Precise.StringAdd(initialMarginString, unrealizedPnlString) } else if IsTrue(IsEqual(marginMode, "isolated")) { initialMarginPercentage = Precise.StringDiv("1", leverageString) collateralString = this.SafeString(position, "margin") } var maintenanceMarginString interface{} = this.SafeString(position, "maintenanceMargin") var maintenanceMargin interface{} = this.ParseNumber(maintenanceMarginString) var maintenanceMarginPercentageString interface{} = Precise.StringDiv(maintenanceMarginString, notionalString) if IsTrue(IsEqual(initialMarginPercentage, nil)) { initialMarginPercentage = this.ParseNumber(Precise.StringDiv(initialMarginString, notionalString, 4)) } else if IsTrue(IsEqual(initialMarginString, nil)) { initialMarginString = Precise.StringMul(initialMarginPercentage, notionalString) } var rounder interface{} = "0.00005" // round to closest 0.01% var maintenanceMarginPercentage interface{} = this.ParseNumber(Precise.StringDiv(Precise.StringAdd(maintenanceMarginPercentageString, rounder), "1", 4)) var liquidationPrice interface{} = this.SafeNumber(position, "liquidationPrice") var percentageString interface{} = this.SafeString(position, "unrealizedPnlRatio") var percentage interface{} = this.ParseNumber(Precise.StringMul(percentageString, "100")) var timestamp interface{} = this.SafeInteger(position, "updateTime") var marginRatio interface{} = this.ParseNumber(Precise.StringDiv(maintenanceMarginString, collateralString, 4)) return this.SafePosition(map[string]interface{} { "info": position, "id": nil, "symbol": symbol, "notional": notional, "marginMode": marginMode, "liquidationPrice": liquidationPrice, "entryPrice": this.ParseNumber(entryPriceString), "unrealizedPnl": this.ParseNumber(unrealizedPnlString), "percentage": percentage, "contracts": contracts, "contractSize": contractSize, "markPrice": this.ParseNumber(markPriceString), "lastPrice": nil, "side": side, "hedged": hedged, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastUpdateTimestamp": nil, "maintenanceMargin": maintenanceMargin, "maintenanceMarginPercentage": maintenanceMarginPercentage, "collateral": this.ParseNumber(collateralString), "initialMargin": this.ParseNumber(initialMarginString), "initialMarginPercentage": this.ParseNumber(initialMarginPercentage), "leverage": this.ParseNumber(leverageString), "marginRatio": marginRatio, "stopLossPrice": nil, "takeProfitPrice": nil, }) } /** * @method * @name blofin#fetchLeverages * @description fetch the set leverage for all contract markets * @see https://docs.blofin.com/index.html#get-multiple-leverage * @param {string[]} symbols a list of unified market symbols, required on blofin * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.marginMode] 'cross' or 'isolated' * @returns {object} a list of [leverage structures]{@link https://docs.ccxt.com/#/?id=leverage-structure} */ func (this *blofin) FetchLeverages(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 retRes21368 := (<-this.LoadMarkets()) PanicOnError(retRes21368) if IsTrue(IsEqual(symbols, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchLeverages() requires a symbols argument"))) } var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchLeverages", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) if IsTrue(IsEqual(marginMode, nil)) { marginMode = this.SafeString(params, "marginMode", "cross") // cross as default marginMode } if IsTrue(IsTrue((!IsEqual(marginMode, "cross"))) && IsTrue((!IsEqual(marginMode, "isolated")))) { panic(BadRequest(Add(this.Id, " fetchLeverages() requires a marginMode parameter that must be either cross or isolated"))) } symbols = this.MarketSymbols(symbols) var instIds interface{} = "" for i := 0; IsLessThan(i, GetArrayLength(symbols)); i++ { var entry interface{} = GetValue(symbols, i) var entryMarket interface{} = this.Market(entry) if IsTrue(IsGreaterThan(i, 0)) { instIds = Add(Add(instIds, ","), GetValue(entryMarket, "id")) } else { instIds = Add(instIds, GetValue(entryMarket, "id")) } } var request interface{} = map[string]interface{} { "instId": instIds, "marginMode": marginMode, } response:= (<-this.PrivateGetAccountBatchLeverageInfo(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "success", // "data": [ // { // "leverage": "3", // "marginMode": "cross", // "instId": "BTC-USDT" // }, // ] // } // var leverages interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseLeverages(leverages, symbols, "instId") return nil }() return ch } /** * @method * @name blofin#fetchLeverage * @description fetch the set leverage for a market * @see https://docs.blofin.com/index.html#get-leverage * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.marginMode] 'cross' or 'isolated' * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure} */ func (this *blofin) FetchLeverage(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 retRes21928 := (<-this.LoadMarkets()) PanicOnError(retRes21928) var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchLeverage", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) if IsTrue(IsEqual(marginMode, nil)) { marginMode = this.SafeString(params, "marginMode", "cross") // cross as default marginMode } if IsTrue(IsTrue((!IsEqual(marginMode, "cross"))) && IsTrue((!IsEqual(marginMode, "isolated")))) { panic(BadRequest(Add(this.Id, " fetchLeverage() requires a marginMode parameter that must be either cross or isolated"))) } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), "marginMode": marginMode, } response:= (<-this.PrivateGetAccountLeverageInfo(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "success", // "data": { // "leverage": "3", // "marginMode": "cross", // "instId": "BTC-USDT" // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseLeverage(data, market) return nil }() return ch } func (this *blofin) ParseLeverage(leverage interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(leverage, "instId") var leverageValue interface{} = this.SafeInteger(leverage, "leverage") return map[string]interface{} { "info": leverage, "symbol": this.SafeSymbol(marketId, market), "marginMode": this.SafeStringLower(leverage, "marginMode"), "longLeverage": leverageValue, "shortLeverage": leverageValue, } } /** * @method * @name blofin#setLeverage * @description set the level of leverage for a market * @see https://blofin.com/docs#set-leverage * @param {int} leverage the rate of leverage * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.marginMode] 'cross' or 'isolated' * @returns {object} response from the exchange */ func (this *blofin) SetLeverage(leverage interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " setLeverage() requires a symbol argument"))) } // WARNING: THIS WILL INCREASE LIQUIDATION PRICE FOR OPEN ISOLATED LONG POSITIONS // AND DECREASE LIQUIDATION PRICE FOR OPEN ISOLATED SHORT POSITIONS if IsTrue(IsTrue((IsLessThan(leverage, 1))) || IsTrue((IsGreaterThan(leverage, 125)))) { panic(BadRequest(Add(this.Id, " setLeverage() leverage should be between 1 and 125"))) } retRes22548 := (<-this.LoadMarkets()) PanicOnError(retRes22548) var market interface{} = this.Market(symbol) var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("setLeverage", params, "cross"); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) if IsTrue(IsTrue((!IsEqual(marginMode, "cross"))) && IsTrue((!IsEqual(marginMode, "isolated")))) { panic(BadRequest(Add(this.Id, " setLeverage() requires a marginMode parameter that must be either cross or isolated"))) } var request interface{} = map[string]interface{} { "leverage": leverage, "marginMode": marginMode, "instId": GetValue(market, "id"), } response:= (<-this.PrivatePostAccountSetLeverage(this.Extend(request, params))) PanicOnError(response) ch <- response return nil }() return ch } /** * @method * @name blofin#closePosition * @description closes open positions for a market * @see https://blofin.com/docs#close-positions * @param {string} symbol Unified CCXT market symbol * @param {string} [side] 'buy' or 'sell', leave as undefined in net mode * @param {object} [params] extra parameters specific to the blofin api endpoint * @param {string} [params.clientOrderId] a unique identifier for the order * @param {string} [params.marginMode] 'cross' or 'isolated', default is 'cross; * @param {string} [params.code] *required in the case of closing cross MARGIN position for Single-currency margin* margin currency * * EXCHANGE SPECIFIC PARAMETERS * @param {boolean} [params.autoCxl] whether any pending orders for closing out needs to be automatically canceled when close position via a market order. false or true, the default is false * @param {string} [params.tag] order tag a combination of case-sensitive alphanumerics, all numbers, or all letters of up to 16 characters * @returns {object[]} [A list of position structures]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *blofin) ClosePosition(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) side := GetArg(optionalArgs, 0, nil) _ = side params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes22888 := (<-this.LoadMarkets()) PanicOnError(retRes22888) var market interface{} = this.Market(symbol) var clientOrderId interface{} = this.SafeString(params, "clientOrderId") var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("closePosition", params, "cross"); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), "marginMode": marginMode, } if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "clientOrderId", clientOrderId) } response:= (<-this.PrivatePostTradeClosePosition(this.Extend(request, params))) PanicOnError(response) ch <- this.SafeDict(response, "data") return nil }() return ch } /** * @method * @name blofin#fetchClosedOrders * @description fetches information on multiple closed orders made by the user * @see https://blofin.com/docs#get-order-history * @see https://blofin.com/docs#get-tpsl-order-history * @param {string} symbol unified market symbol of the market orders were made in * @param {int} [since] the earliest time in ms to fetch orders for * @param {int} [limit] the maximum number of orde structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {bool} [params.trigger] True if fetching trigger or conditional orders * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *blofin) FetchClosedOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes23198 := (<-this.LoadMarkets()) PanicOnError(retRes23198) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchClosedOrders", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes232319 := (<-this.FetchPaginatedCallDynamic("fetchClosedOrders", symbol, since, limit, params)) PanicOnError(retRes232319) ch <- retRes232319 return nil } var request interface{} = map[string]interface{} {} var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "instId", GetValue(market, "id")) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 100 } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "begin", since) } var isTrigger interface{} = this.SafeBoolN(params, []interface{}{"stop", "trigger", "tpsl", "TPSL"}, false) var method interface{} = nil methodparamsVariable := this.HandleOptionAndParams(params, "fetchOpenOrders", "method", "privateGetTradeOrdersHistory"); method = GetValue(methodparamsVariable,0); params = GetValue(methodparamsVariable,1) var query interface{} = this.Omit(params, []interface{}{"method", "stop", "trigger", "tpsl", "TPSL"}) var response interface{} = nil if IsTrue(IsTrue((isTrigger)) || IsTrue((IsEqual(method, "privateGetTradeOrdersTpslHistory")))) { response = (<-this.PrivateGetTradeOrdersTpslHistory(this.Extend(request, query))) PanicOnError(response) } else { response = (<-this.PrivateGetTradeOrdersHistory(this.Extend(request, query))) PanicOnError(response) } var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(data, market, since, limit) return nil }() return ch } /** * @method * @name blofin#fetchMarginMode * @description fetches the margin mode of a trading pair * @see https://docs.blofin.com/index.html#get-margin-mode * @param {string} symbol unified symbol of the market to fetch the margin mode for * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [margin mode structure]{@link https://docs.ccxt.com/#/?id=margin-mode-structure} */ func (this *blofin) FetchMarginMode(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 retRes23628 := (<-this.LoadMarkets()) PanicOnError(retRes23628) var market interface{} = this.Market(symbol) response:= (<-this.PrivateGetAccountMarginMode(params)) PanicOnError(response) // // { // "code": "0", // "msg": "success", // "data": { // "marginMode": "cross" // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseMarginMode(data, market) return nil }() return ch } func (this *blofin) ParseMarginMode(marginMode interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market return map[string]interface{} { "info": marginMode, "symbol": GetValue(market, "symbol"), "marginMode": this.SafeString(marginMode, "marginMode"), } } func (this *blofin) 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 } // // {"code":"152002","msg":"Parameter bar error."} // var code interface{} = this.SafeString(response, "code") var message interface{} = this.SafeString(response, "msg") var feedback interface{} = Add(Add(this.Id, " "), body) if IsTrue(IsTrue(!IsEqual(code, nil)) && IsTrue(!IsEqual(code, "0"))) { this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), message, feedback) this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), code, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, feedback) panic(ExchangeError(feedback)) } // // { // orderId: null, // clientOrderId: '', // msg: 'Order failed. Insufficient USDT margin in account', // code: '103003' // } // var data interface{} = this.SafeList(response, "data") var first interface{} = this.SafeDict(data, 0) var insideMsg interface{} = this.SafeString(first, "msg") var insideCode interface{} = this.SafeString(first, "code") if IsTrue(IsTrue(!IsEqual(insideCode, nil)) && IsTrue(!IsEqual(insideCode, "0"))) { this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), insideCode, feedback) this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), insideMsg, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), insideMsg, feedback) } return nil } func (this *blofin) 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 request interface{} = Add(Add(Add("/api/", this.Version), "/"), this.ImplodeParams(path, params)) var query interface{} = this.Omit(params, this.ExtractParams(path)) var url interface{} = Add(this.ImplodeHostname(GetValue(GetValue(this.Urls, "api"), "rest")), request) // const type = this.getPathAuthenticationType (path); if IsTrue(IsEqual(api, "public")) { if !IsTrue(this.IsEmpty(query)) { url = Add(url, Add("?", this.Urlencode(query))) } } else if IsTrue(IsEqual(api, "private")) { this.CheckRequiredCredentials() var timestamp interface{} = ToString(this.Milliseconds()) headers = map[string]interface{} { "ACCESS-KEY": this.ApiKey, "ACCESS-PASSPHRASE": this.Password, "ACCESS-TIMESTAMP": timestamp, "ACCESS-NONCE": timestamp, } var sign_body interface{} = "" if IsTrue(IsEqual(method, "GET")) { if !IsTrue(this.IsEmpty(query)) { var urlencodedQuery interface{} = Add("?", this.Urlencode(query)) url = Add(url, urlencodedQuery) request = Add(request, urlencodedQuery) } } else { if !IsTrue(this.IsEmpty(query)) { body = this.Json(query) sign_body = body } AddElementToObject(headers, "Content-Type", "application/json") } var auth interface{} = Add(Add(Add(Add(request, method), timestamp), timestamp), sign_body) var signature interface{} = this.StringToBase64(this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha256)) AddElementToObject(headers, "ACCESS-SIGN", signature) } return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } func (this *blofin) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }