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 htx struct { Exchange } func NewHtxCore() htx { p := htx{} setDefaults(&p) return p } func (this *htx) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "htx", "name": "HTX", "countries": []interface{}{"CN"}, "rateLimit": 100, "userAgent": GetValue(this.UserAgents, "chrome100"), "certified": true, "version": "v1", "hostname": "api.huobi.pro", "pro": true, "has": map[string]interface{} { "CORS": nil, "spot": true, "margin": true, "swap": true, "future": true, "option": nil, "addMargin": nil, "borrowCrossMargin": true, "borrowIsolatedMargin": true, "cancelAllOrders": true, "cancelAllOrdersAfter": true, "cancelOrder": true, "cancelOrders": true, "closeAllPositions": false, "closePosition": true, "createDepositAddress": nil, "createMarketBuyOrderWithCost": true, "createMarketOrderWithCost": false, "createMarketSellOrderWithCost": false, "createOrder": true, "createOrders": true, "createReduceOnlyOrder": false, "createStopLimitOrder": true, "createStopLossOrder": true, "createStopMarketOrder": true, "createStopOrder": true, "createTakeProfitOrder": true, "createTrailingPercentOrder": true, "createTriggerOrder": true, "fetchAccounts": true, "fetchBalance": true, "fetchBidsAsks": nil, "fetchBorrowInterest": true, "fetchBorrowRateHistories": nil, "fetchBorrowRateHistory": nil, "fetchCanceledOrders": nil, "fetchClosedOrder": nil, "fetchClosedOrders": true, "fetchCrossBorrowRate": false, "fetchCrossBorrowRates": false, "fetchCurrencies": true, "fetchDeposit": nil, "fetchDepositAddress": true, "fetchDepositAddresses": nil, "fetchDepositAddressesByNetwork": true, "fetchDeposits": true, "fetchDepositWithdrawFee": "emulated", "fetchDepositWithdrawFees": true, "fetchFundingHistory": true, "fetchFundingRate": true, "fetchFundingRateHistory": true, "fetchFundingRates": true, "fetchIndexOHLCV": true, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": true, "fetchL3OrderBook": nil, "fetchLastPrices": true, "fetchLedger": true, "fetchLedgerEntry": nil, "fetchLeverage": false, "fetchLeverageTiers": true, "fetchLiquidations": true, "fetchMarginAdjustmentHistory": false, "fetchMarketLeverageTiers": "emulated", "fetchMarkets": true, "fetchMarkOHLCV": true, "fetchMyLiquidations": false, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenInterest": true, "fetchOpenInterestHistory": true, "fetchOpenInterests": true, "fetchOpenOrder": nil, "fetchOpenOrders": true, "fetchOrder": true, "fetchOrderBook": true, "fetchOrderBooks": nil, "fetchOrders": true, "fetchOrderTrades": true, "fetchPosition": true, "fetchPositionHistory": "emulated", "fetchPositions": true, "fetchPositionsHistory": false, "fetchPositionsRisk": false, "fetchPremiumIndexOHLCV": true, "fetchSettlementHistory": true, "fetchStatus": true, "fetchTicker": true, "fetchTickers": true, "fetchTime": true, "fetchTrades": true, "fetchTradingFee": true, "fetchTradingFees": false, "fetchTradingLimits": true, "fetchTransactionFee": nil, "fetchTransactionFees": nil, "fetchTransactions": nil, "fetchTransfers": nil, "fetchWithdrawAddresses": true, "fetchWithdrawal": nil, "fetchWithdrawals": true, "fetchWithdrawalWhitelist": nil, "reduceMargin": nil, "repayCrossMargin": true, "repayIsolatedMargin": true, "setLeverage": true, "setMarginMode": false, "setPositionMode": true, "signIn": nil, "transfer": true, "withdraw": true, }, "timeframes": map[string]interface{} { "1m": "1min", "5m": "5min", "15m": "15min", "30m": "30min", "1h": "60min", "4h": "4hour", "1d": "1day", "1w": "1week", "1M": "1mon", "1y": "1year", }, "urls": map[string]interface{} { "logo": "https://user-images.githubusercontent.com/1294454/76137448-22748a80-604e-11ea-8069-6e389271911d.jpg", "hostnames": map[string]interface{} { "contract": "api.hbdm.com", "spot": "api.huobi.pro", "status": map[string]interface{} { "spot": "status.huobigroup.com", "future": map[string]interface{} { "inverse": "status-dm.huobigroup.com", "linear": "status-linear-swap.huobigroup.com", }, "swap": map[string]interface{} { "inverse": "status-swap.huobigroup.com", "linear": "status-linear-swap.huobigroup.com", }, }, }, "api": map[string]interface{} { "status": "https://{hostname}", "contract": "https://{hostname}", "spot": "https://{hostname}", "public": "https://{hostname}", "private": "https://{hostname}", "v2Public": "https://{hostname}", "v2Private": "https://{hostname}", }, "www": "https://www.huobi.com", "referral": map[string]interface{} { "url": "https://www.htx.com.vc/invite/en-us/1h?invite_code=6rmm2223", "discount": 0.15, }, "doc": []interface{}{"https://huobiapi.github.io/docs/spot/v1/en/", "https://huobiapi.github.io/docs/dm/v1/en/", "https://huobiapi.github.io/docs/coin_margined_swap/v1/en/", "https://huobiapi.github.io/docs/usdt_swap/v1/en/", "https://www.huobi.com/en-us/opend/newApiPages/"}, "fees": "https://www.huobi.com/about/fee/", }, "api": map[string]interface{} { "v2Public": map[string]interface{} { "get": map[string]interface{} { "reference/currencies": 1, "market-status": 1, }, }, "v2Private": map[string]interface{} { "get": map[string]interface{} { "account/ledger": 1, "account/withdraw/quota": 1, "account/withdraw/address": 1, "account/deposit/address": 1, "account/repayment": 5, "reference/transact-fee-rate": 1, "account/asset-valuation": 0.2, "point/account": 5, "sub-user/user-list": 1, "sub-user/user-state": 1, "sub-user/account-list": 1, "sub-user/deposit-address": 1, "sub-user/query-deposit": 1, "user/api-key": 1, "user/uid": 1, "algo-orders/opening": 1, "algo-orders/history": 1, "algo-orders/specific": 1, "c2c/offers": 1, "c2c/offer": 1, "c2c/transactions": 1, "c2c/repayment": 1, "c2c/account": 1, "etp/reference": 1, "etp/transactions": 5, "etp/transaction": 5, "etp/rebalance": 1, "etp/limit": 1, }, "post": map[string]interface{} { "account/transfer": 1, "account/repayment": 5, "point/transfer": 5, "sub-user/management": 1, "sub-user/creation": 1, "sub-user/tradable-market": 1, "sub-user/transferability": 1, "sub-user/api-key-generation": 1, "sub-user/api-key-modification": 1, "sub-user/api-key-deletion": 1, "sub-user/deduct-mode": 1, "algo-orders": 1, "algo-orders/cancel-all-after": 1, "algo-orders/cancellation": 1, "c2c/offer": 1, "c2c/cancellation": 1, "c2c/cancel-all": 1, "c2c/repayment": 1, "c2c/transfer": 1, "etp/creation": 5, "etp/redemption": 5, "etp/{transactId}/cancel": 10, "etp/batch-cancel": 50, }, }, "public": map[string]interface{} { "get": map[string]interface{} { "common/symbols": 1, "common/currencys": 1, "common/timestamp": 1, "common/exchange": 1, "settings/currencys": 1, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "account/accounts": 0.2, "account/accounts/{id}/balance": 0.2, "account/accounts/{sub-uid}": 1, "account/history": 4, "cross-margin/loan-info": 1, "margin/loan-info": 1, "fee/fee-rate/get": 1, "order/openOrders": 0.4, "order/orders": 0.4, "order/orders/{id}": 0.4, "order/orders/{id}/matchresults": 0.4, "order/orders/getClientOrder": 0.4, "order/history": 1, "order/matchresults": 1, "query/deposit-withdraw": 1, "margin/loan-orders": 0.2, "margin/accounts/balance": 0.2, "cross-margin/loan-orders": 1, "cross-margin/accounts/balance": 1, "points/actions": 1, "points/orders": 1, "subuser/aggregate-balance": 10, "stable-coin/exchange_rate": 1, "stable-coin/quote": 1, }, "post": map[string]interface{} { "account/transfer": 1, "futures/transfer": 1, "order/batch-orders": 0.4, "order/orders/place": 0.2, "order/orders/submitCancelClientOrder": 0.2, "order/orders/batchCancelOpenOrders": 0.4, "order/orders/{id}/submitcancel": 0.2, "order/orders/batchcancel": 0.4, "dw/withdraw/api/create": 1, "dw/withdraw-virtual/{id}/cancel": 1, "dw/transfer-in/margin": 10, "dw/transfer-out/margin": 10, "margin/orders": 10, "margin/orders/{id}/repay": 10, "cross-margin/transfer-in": 1, "cross-margin/transfer-out": 1, "cross-margin/orders": 1, "cross-margin/orders/{id}/repay": 1, "stable-coin/exchange": 1, "subuser/transfer": 10, }, }, "status": map[string]interface{} { "public": map[string]interface{} { "spot": map[string]interface{} { "get": map[string]interface{} { "api/v2/summary.json": 1, }, }, "future": map[string]interface{} { "inverse": map[string]interface{} { "get": map[string]interface{} { "api/v2/summary.json": 1, }, }, "linear": map[string]interface{} { "get": map[string]interface{} { "api/v2/summary.json": 1, }, }, }, "swap": map[string]interface{} { "inverse": map[string]interface{} { "get": map[string]interface{} { "api/v2/summary.json": 1, }, }, "linear": map[string]interface{} { "get": map[string]interface{} { "api/v2/summary.json": 1, }, }, }, }, }, "spot": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "v2/market-status": 1, "v1/common/symbols": 1, "v1/common/currencys": 1, "v2/settings/common/currencies": 1, "v2/reference/currencies": 1, "v1/common/timestamp": 1, "v1/common/exchange": 1, "v1/settings/common/chains": 1, "v1/settings/common/currencys": 1, "v1/settings/common/symbols": 1, "v2/settings/common/symbols": 1, "v1/settings/common/market-symbols": 1, "market/history/candles": 1, "market/history/kline": 1, "market/detail/merged": 1, "market/tickers": 1, "market/detail": 1, "market/depth": 1, "market/trade": 1, "market/history/trade": 1, "market/etp": 1, "v2/etp/reference": 1, "v2/etp/rebalance": 1, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "v1/account/accounts": 0.2, "v1/account/accounts/{account-id}/balance": 0.2, "v2/account/valuation": 1, "v2/account/asset-valuation": 0.2, "v1/account/history": 4, "v2/account/ledger": 1, "v2/point/account": 5, "v2/account/deposit/address": 1, "v2/account/withdraw/quota": 1, "v2/account/withdraw/address": 1, "v2/reference/currencies": 1, "v1/query/deposit-withdraw": 1, "v1/query/withdraw/client-order-id": 1, "v2/user/api-key": 1, "v2/user/uid": 1, "v2/sub-user/user-list": 1, "v2/sub-user/user-state": 1, "v2/sub-user/account-list": 1, "v2/sub-user/deposit-address": 1, "v2/sub-user/query-deposit": 1, "v1/subuser/aggregate-balance": 10, "v1/account/accounts/{sub-uid}": 1, "v1/order/openOrders": 0.4, "v1/order/orders/{order-id}": 0.4, "v1/order/orders/getClientOrder": 0.4, "v1/order/orders/{order-id}/matchresult": 0.4, "v1/order/orders/{order-id}/matchresults": 0.4, "v1/order/orders": 0.4, "v1/order/history": 1, "v1/order/matchresults": 1, "v2/reference/transact-fee-rate": 1, "v2/algo-orders/opening": 1, "v2/algo-orders/history": 1, "v2/algo-orders/specific": 1, "v1/margin/loan-info": 1, "v1/margin/loan-orders": 0.2, "v1/margin/accounts/balance": 0.2, "v1/cross-margin/loan-info": 1, "v1/cross-margin/loan-orders": 1, "v1/cross-margin/accounts/balance": 1, "v2/account/repayment": 5, "v1/stable-coin/quote": 1, "v1/stable_coin/exchange_rate": 1, "v2/etp/transactions": 5, "v2/etp/transaction": 5, "v2/etp/limit": 1, }, "post": map[string]interface{} { "v1/account/transfer": 1, "v1/futures/transfer": 1, "v2/point/transfer": 5, "v2/account/transfer": 1, "v1/dw/withdraw/api/create": 1, "v1/dw/withdraw-virtual/{withdraw-id}/cancel": 1, "v2/sub-user/deduct-mode": 1, "v2/sub-user/creation": 1, "v2/sub-user/management": 1, "v2/sub-user/tradable-market": 1, "v2/sub-user/transferability": 1, "v2/sub-user/api-key-generation": 1, "v2/sub-user/api-key-modification": 1, "v2/sub-user/api-key-deletion": 1, "v1/subuser/transfer": 10, "v1/trust/user/active/credit": 10, "v1/order/orders/place": 0.2, "v1/order/batch-orders": 0.4, "v1/order/auto/place": 0.2, "v1/order/orders/{order-id}/submitcancel": 0.2, "v1/order/orders/submitCancelClientOrder": 0.2, "v1/order/orders/batchCancelOpenOrders": 0.4, "v1/order/orders/batchcancel": 0.4, "v2/algo-orders/cancel-all-after": 1, "v2/algo-orders": 1, "v2/algo-orders/cancellation": 1, "v2/account/repayment": 5, "v1/dw/transfer-in/margin": 10, "v1/dw/transfer-out/margin": 10, "v1/margin/orders": 10, "v1/margin/orders/{order-id}/repay": 10, "v1/cross-margin/transfer-in": 1, "v1/cross-margin/transfer-out": 1, "v1/cross-margin/orders": 1, "v1/cross-margin/orders/{order-id}/repay": 1, "v1/stable-coin/exchange": 1, "v2/etp/creation": 5, "v2/etp/redemption": 5, "v2/etp/{transactId}/cancel": 10, "v2/etp/batch-cancel": 50, }, }, }, "contract": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "api/v1/timestamp": 1, "heartbeat/": 1, "api/v1/contract_contract_info": 1, "api/v1/contract_index": 1, "api/v1/contract_query_elements": 1, "api/v1/contract_price_limit": 1, "api/v1/contract_open_interest": 1, "api/v1/contract_delivery_price": 1, "market/depth": 1, "market/bbo": 1, "market/history/kline": 1, "index/market/history/mark_price_kline": 1, "market/detail/merged": 1, "market/detail/batch_merged": 1, "v2/market/detail/batch_merged": 1, "market/trade": 1, "market/history/trade": 1, "api/v1/contract_risk_info": 1, "api/v1/contract_insurance_fund": 1, "api/v1/contract_adjustfactor": 1, "api/v1/contract_his_open_interest": 1, "api/v1/contract_ladder_margin": 1, "api/v1/contract_api_state": 1, "api/v1/contract_elite_account_ratio": 1, "api/v1/contract_elite_position_ratio": 1, "api/v1/contract_liquidation_orders": 1, "api/v1/contract_settlement_records": 1, "index/market/history/index": 1, "index/market/history/basis": 1, "api/v1/contract_estimated_settlement_price": 1, "api/v3/contract_liquidation_orders": 1, "swap-api/v1/swap_contract_info": 1, "swap-api/v1/swap_index": 1, "swap-api/v1/swap_query_elements": 1, "swap-api/v1/swap_price_limit": 1, "swap-api/v1/swap_open_interest": 1, "swap-ex/market/depth": 1, "swap-ex/market/bbo": 1, "swap-ex/market/history/kline": 1, "index/market/history/swap_mark_price_kline": 1, "swap-ex/market/detail/merged": 1, "v2/swap-ex/market/detail/batch_merged": 1, "index/market/history/swap_premium_index_kline": 1, "swap-ex/market/detail/batch_merged": 1, "swap-ex/market/trade": 1, "swap-ex/market/history/trade": 1, "swap-api/v1/swap_risk_info": 1, "swap-api/v1/swap_insurance_fund": 1, "swap-api/v1/swap_adjustfactor": 1, "swap-api/v1/swap_his_open_interest": 1, "swap-api/v1/swap_ladder_margin": 1, "swap-api/v1/swap_api_state": 1, "swap-api/v1/swap_elite_account_ratio": 1, "swap-api/v1/swap_elite_position_ratio": 1, "swap-api/v1/swap_estimated_settlement_price": 1, "swap-api/v1/swap_liquidation_orders": 1, "swap-api/v1/swap_settlement_records": 1, "swap-api/v1/swap_funding_rate": 1, "swap-api/v1/swap_batch_funding_rate": 1, "swap-api/v1/swap_historical_funding_rate": 1, "swap-api/v3/swap_liquidation_orders": 1, "index/market/history/swap_estimated_rate_kline": 1, "index/market/history/swap_basis": 1, "linear-swap-api/v1/swap_contract_info": 1, "linear-swap-api/v1/swap_index": 1, "linear-swap-api/v1/swap_query_elements": 1, "linear-swap-api/v1/swap_price_limit": 1, "linear-swap-api/v1/swap_open_interest": 1, "linear-swap-ex/market/depth": 1, "linear-swap-ex/market/bbo": 1, "linear-swap-ex/market/history/kline": 1, "index/market/history/linear_swap_mark_price_kline": 1, "linear-swap-ex/market/detail/merged": 1, "linear-swap-ex/market/detail/batch_merged": 1, "v2/linear-swap-ex/market/detail/batch_merged": 1, "linear-swap-ex/market/trade": 1, "linear-swap-ex/market/history/trade": 1, "linear-swap-api/v1/swap_risk_info": 1, "swap-api/v1/linear-swap-api/v1/swap_insurance_fund": 1, "linear-swap-api/v1/swap_adjustfactor": 1, "linear-swap-api/v1/swap_cross_adjustfactor": 1, "linear-swap-api/v1/swap_his_open_interest": 1, "linear-swap-api/v1/swap_ladder_margin": 1, "linear-swap-api/v1/swap_cross_ladder_margin": 1, "linear-swap-api/v1/swap_api_state": 1, "linear-swap-api/v1/swap_cross_transfer_state": 1, "linear-swap-api/v1/swap_cross_trade_state": 1, "linear-swap-api/v1/swap_elite_account_ratio": 1, "linear-swap-api/v1/swap_elite_position_ratio": 1, "linear-swap-api/v1/swap_liquidation_orders": 1, "linear-swap-api/v1/swap_settlement_records": 1, "linear-swap-api/v1/swap_funding_rate": 1, "linear-swap-api/v1/swap_batch_funding_rate": 1, "linear-swap-api/v1/swap_historical_funding_rate": 1, "linear-swap-api/v3/swap_liquidation_orders": 1, "index/market/history/linear_swap_premium_index_kline": 1, "index/market/history/linear_swap_estimated_rate_kline": 1, "index/market/history/linear_swap_basis": 1, "linear-swap-api/v1/swap_estimated_settlement_price": 1, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "api/v1/contract_sub_auth_list": 1, "api/v1/contract_api_trading_status": 1, "swap-api/v1/swap_sub_auth_list": 1, "swap-api/v1/swap_api_trading_status": 1, "linear-swap-api/v1/swap_sub_auth_list": 1, "linear-swap-api/v1/swap_api_trading_status": 1, "linear-swap-api/v1/swap_cross_position_side": 1, "linear-swap-api/v1/swap_position_side": 1, "linear-swap-api/v3/unified_account_info": 1, "linear-swap-api/v3/fix_position_margin_change_record": 1, "linear-swap-api/v3/swap_unified_account_type": 1, "linear-swap-api/v3/linear_swap_overview_account_info": 1, }, "post": map[string]interface{} { "api/v1/contract_balance_valuation": 1, "api/v1/contract_account_info": 1, "api/v1/contract_position_info": 1, "api/v1/contract_sub_auth": 1, "api/v1/contract_sub_account_list": 1, "api/v1/contract_sub_account_info_list": 1, "api/v1/contract_sub_account_info": 1, "api/v1/contract_sub_position_info": 1, "api/v1/contract_financial_record": 1, "api/v1/contract_financial_record_exact": 1, "api/v1/contract_user_settlement_records": 1, "api/v1/contract_order_limit": 1, "api/v1/contract_fee": 1, "api/v1/contract_transfer_limit": 1, "api/v1/contract_position_limit": 1, "api/v1/contract_account_position_info": 1, "api/v1/contract_master_sub_transfer": 1, "api/v1/contract_master_sub_transfer_record": 1, "api/v1/contract_available_level_rate": 1, "api/v3/contract_financial_record": 1, "api/v3/contract_financial_record_exact": 1, "api/v1/contract-cancel-after": 1, "api/v1/contract_order": 1, "api/v1/contract_batchorder": 1, "api/v1/contract_cancel": 1, "api/v1/contract_cancelall": 1, "api/v1/contract_switch_lever_rate": 1, "api/v1/lightning_close_position": 1, "api/v1/contract_order_info": 1, "api/v1/contract_order_detail": 1, "api/v1/contract_openorders": 1, "api/v1/contract_hisorders": 1, "api/v1/contract_hisorders_exact": 1, "api/v1/contract_matchresults": 1, "api/v1/contract_matchresults_exact": 1, "api/v3/contract_hisorders": 1, "api/v3/contract_hisorders_exact": 1, "api/v3/contract_matchresults": 1, "api/v3/contract_matchresults_exact": 1, "api/v1/contract_trigger_order": 1, "api/v1/contract_trigger_cancel": 1, "api/v1/contract_trigger_cancelall": 1, "api/v1/contract_trigger_openorders": 1, "api/v1/contract_trigger_hisorders": 1, "api/v1/contract_tpsl_order": 1, "api/v1/contract_tpsl_cancel": 1, "api/v1/contract_tpsl_cancelall": 1, "api/v1/contract_tpsl_openorders": 1, "api/v1/contract_tpsl_hisorders": 1, "api/v1/contract_relation_tpsl_order": 1, "api/v1/contract_track_order": 1, "api/v1/contract_track_cancel": 1, "api/v1/contract_track_cancelall": 1, "api/v1/contract_track_openorders": 1, "api/v1/contract_track_hisorders": 1, "swap-api/v1/swap_balance_valuation": 1, "swap-api/v1/swap_account_info": 1, "swap-api/v1/swap_position_info": 1, "swap-api/v1/swap_account_position_info": 1, "swap-api/v1/swap_sub_auth": 1, "swap-api/v1/swap_sub_account_list": 1, "swap-api/v1/swap_sub_account_info_list": 1, "swap-api/v1/swap_sub_account_info": 1, "swap-api/v1/swap_sub_position_info": 1, "swap-api/v1/swap_financial_record": 1, "swap-api/v1/swap_financial_record_exact": 1, "swap-api/v1/swap_user_settlement_records": 1, "swap-api/v1/swap_available_level_rate": 1, "swap-api/v1/swap_order_limit": 1, "swap-api/v1/swap_fee": 1, "swap-api/v1/swap_transfer_limit": 1, "swap-api/v1/swap_position_limit": 1, "swap-api/v1/swap_master_sub_transfer": 1, "swap-api/v1/swap_master_sub_transfer_record": 1, "swap-api/v3/swap_financial_record": 1, "swap-api/v3/swap_financial_record_exact": 1, "swap-api/v1/swap-cancel-after": 1, "swap-api/v1/swap_order": 1, "swap-api/v1/swap_batchorder": 1, "swap-api/v1/swap_cancel": 1, "swap-api/v1/swap_cancelall": 1, "swap-api/v1/swap_lightning_close_position": 1, "swap-api/v1/swap_switch_lever_rate": 1, "swap-api/v1/swap_order_info": 1, "swap-api/v1/swap_order_detail": 1, "swap-api/v1/swap_openorders": 1, "swap-api/v1/swap_hisorders": 1, "swap-api/v1/swap_hisorders_exact": 1, "swap-api/v1/swap_matchresults": 1, "swap-api/v1/swap_matchresults_exact": 1, "swap-api/v3/swap_matchresults": 1, "swap-api/v3/swap_matchresults_exact": 1, "swap-api/v3/swap_hisorders": 1, "swap-api/v3/swap_hisorders_exact": 1, "swap-api/v1/swap_trigger_order": 1, "swap-api/v1/swap_trigger_cancel": 1, "swap-api/v1/swap_trigger_cancelall": 1, "swap-api/v1/swap_trigger_openorders": 1, "swap-api/v1/swap_trigger_hisorders": 1, "swap-api/v1/swap_tpsl_order": 1, "swap-api/v1/swap_tpsl_cancel": 1, "swap-api/v1/swap_tpsl_cancelall": 1, "swap-api/v1/swap_tpsl_openorders": 1, "swap-api/v1/swap_tpsl_hisorders": 1, "swap-api/v1/swap_relation_tpsl_order": 1, "swap-api/v1/swap_track_order": 1, "swap-api/v1/swap_track_cancel": 1, "swap-api/v1/swap_track_cancelall": 1, "swap-api/v1/swap_track_openorders": 1, "swap-api/v1/swap_track_hisorders": 1, "linear-swap-api/v1/swap_lever_position_limit": 1, "linear-swap-api/v1/swap_cross_lever_position_limit": 1, "linear-swap-api/v1/swap_balance_valuation": 1, "linear-swap-api/v1/swap_account_info": 1, "linear-swap-api/v1/swap_cross_account_info": 1, "linear-swap-api/v1/swap_position_info": 1, "linear-swap-api/v1/swap_cross_position_info": 1, "linear-swap-api/v1/swap_account_position_info": 1, "linear-swap-api/v1/swap_cross_account_position_info": 1, "linear-swap-api/v1/swap_sub_auth": 1, "linear-swap-api/v1/swap_sub_account_list": 1, "linear-swap-api/v1/swap_cross_sub_account_list": 1, "linear-swap-api/v1/swap_sub_account_info_list": 1, "linear-swap-api/v1/swap_cross_sub_account_info_list": 1, "linear-swap-api/v1/swap_sub_account_info": 1, "linear-swap-api/v1/swap_cross_sub_account_info": 1, "linear-swap-api/v1/swap_sub_position_info": 1, "linear-swap-api/v1/swap_cross_sub_position_info": 1, "linear-swap-api/v1/swap_financial_record": 1, "linear-swap-api/v1/swap_financial_record_exact": 1, "linear-swap-api/v1/swap_user_settlement_records": 1, "linear-swap-api/v1/swap_cross_user_settlement_records": 1, "linear-swap-api/v1/swap_available_level_rate": 1, "linear-swap-api/v1/swap_cross_available_level_rate": 1, "linear-swap-api/v1/swap_order_limit": 1, "linear-swap-api/v1/swap_fee": 1, "linear-swap-api/v1/swap_transfer_limit": 1, "linear-swap-api/v1/swap_cross_transfer_limit": 1, "linear-swap-api/v1/swap_position_limit": 1, "linear-swap-api/v1/swap_cross_position_limit": 1, "linear-swap-api/v1/swap_master_sub_transfer": 1, "linear-swap-api/v1/swap_master_sub_transfer_record": 1, "linear-swap-api/v1/swap_transfer_inner": 1, "linear-swap-api/v3/swap_financial_record": 1, "linear-swap-api/v3/swap_financial_record_exact": 1, "linear-swap-api/v1/swap_order": 1, "linear-swap-api/v1/swap_cross_order": 1, "linear-swap-api/v1/swap_batchorder": 1, "linear-swap-api/v1/swap_cross_batchorder": 1, "linear-swap-api/v1/swap_cancel": 1, "linear-swap-api/v1/swap_cross_cancel": 1, "linear-swap-api/v1/swap_cancelall": 1, "linear-swap-api/v1/swap_cross_cancelall": 1, "linear-swap-api/v1/swap_switch_lever_rate": 1, "linear-swap-api/v1/swap_cross_switch_lever_rate": 1, "linear-swap-api/v1/swap_lightning_close_position": 1, "linear-swap-api/v1/swap_cross_lightning_close_position": 1, "linear-swap-api/v1/swap_order_info": 1, "linear-swap-api/v1/swap_cross_order_info": 1, "linear-swap-api/v1/swap_order_detail": 1, "linear-swap-api/v1/swap_cross_order_detail": 1, "linear-swap-api/v1/swap_openorders": 1, "linear-swap-api/v1/swap_cross_openorders": 1, "linear-swap-api/v1/swap_hisorders": 1, "linear-swap-api/v1/swap_cross_hisorders": 1, "linear-swap-api/v1/swap_hisorders_exact": 1, "linear-swap-api/v1/swap_cross_hisorders_exact": 1, "linear-swap-api/v1/swap_matchresults": 1, "linear-swap-api/v1/swap_cross_matchresults": 1, "linear-swap-api/v1/swap_matchresults_exact": 1, "linear-swap-api/v1/swap_cross_matchresults_exact": 1, "linear-swap-api/v1/linear-cancel-after": 1, "linear-swap-api/v1/swap_switch_position_mode": 1, "linear-swap-api/v1/swap_cross_switch_position_mode": 1, "linear-swap-api/v3/swap_matchresults": 1, "linear-swap-api/v3/swap_cross_matchresults": 1, "linear-swap-api/v3/swap_matchresults_exact": 1, "linear-swap-api/v3/swap_cross_matchresults_exact": 1, "linear-swap-api/v3/swap_hisorders": 1, "linear-swap-api/v3/swap_cross_hisorders": 1, "linear-swap-api/v3/swap_hisorders_exact": 1, "linear-swap-api/v3/swap_cross_hisorders_exact": 1, "linear-swap-api/v3/fix_position_margin_change": 1, "linear-swap-api/v3/swap_switch_account_type": 1, "linear-swap-api/v3/linear_swap_fee_switch": 1, "linear-swap-api/v1/swap_trigger_order": 1, "linear-swap-api/v1/swap_cross_trigger_order": 1, "linear-swap-api/v1/swap_trigger_cancel": 1, "linear-swap-api/v1/swap_cross_trigger_cancel": 1, "linear-swap-api/v1/swap_trigger_cancelall": 1, "linear-swap-api/v1/swap_cross_trigger_cancelall": 1, "linear-swap-api/v1/swap_trigger_openorders": 1, "linear-swap-api/v1/swap_cross_trigger_openorders": 1, "linear-swap-api/v1/swap_trigger_hisorders": 1, "linear-swap-api/v1/swap_cross_trigger_hisorders": 1, "linear-swap-api/v1/swap_tpsl_order": 1, "linear-swap-api/v1/swap_cross_tpsl_order": 1, "linear-swap-api/v1/swap_tpsl_cancel": 1, "linear-swap-api/v1/swap_cross_tpsl_cancel": 1, "linear-swap-api/v1/swap_tpsl_cancelall": 1, "linear-swap-api/v1/swap_cross_tpsl_cancelall": 1, "linear-swap-api/v1/swap_tpsl_openorders": 1, "linear-swap-api/v1/swap_cross_tpsl_openorders": 1, "linear-swap-api/v1/swap_tpsl_hisorders": 1, "linear-swap-api/v1/swap_cross_tpsl_hisorders": 1, "linear-swap-api/v1/swap_relation_tpsl_order": 1, "linear-swap-api/v1/swap_cross_relation_tpsl_order": 1, "linear-swap-api/v1/swap_track_order": 1, "linear-swap-api/v1/swap_cross_track_order": 1, "linear-swap-api/v1/swap_track_cancel": 1, "linear-swap-api/v1/swap_cross_track_cancel": 1, "linear-swap-api/v1/swap_track_cancelall": 1, "linear-swap-api/v1/swap_cross_track_cancelall": 1, "linear-swap-api/v1/swap_track_openorders": 1, "linear-swap-api/v1/swap_cross_track_openorders": 1, "linear-swap-api/v1/swap_track_hisorders": 1, "linear-swap-api/v1/swap_cross_track_hisorders": 1, }, }, }, }, "fees": map[string]interface{} { "trading": map[string]interface{} { "feeSide": "get", "tierBased": false, "percentage": true, "maker": this.ParseNumber("0.002"), "taker": this.ParseNumber("0.002"), }, }, "exceptions": map[string]interface{} { "broad": map[string]interface{} { "contract is restricted of closing positions on API. Please contact customer service": OnMaintenance, "maintain": OnMaintenance, "API key has no permission": PermissionDenied, }, "exact": map[string]interface{} { "403": AuthenticationError, "1010": AccountNotEnabled, "1003": AuthenticationError, "1013": BadSymbol, "1017": OrderNotFound, "1034": InvalidOrder, "1036": InvalidOrder, "1039": InvalidOrder, "1041": InvalidOrder, "1047": InsufficientFunds, "1048": InsufficientFunds, "1051": InvalidOrder, "1066": BadSymbol, "1067": InvalidOrder, "1094": InvalidOrder, "1220": AccountNotEnabled, "1303": BadRequest, "1461": InvalidOrder, "4007": BadRequest, "bad-request": BadRequest, "validation-format-error": BadRequest, "validation-constraints-required": BadRequest, "base-date-limit-error": BadRequest, "api-not-support-temp-addr": PermissionDenied, "timeout": RequestTimeout, "gateway-internal-error": ExchangeNotAvailable, "account-frozen-balance-insufficient-error": InsufficientFunds, "invalid-amount": InvalidOrder, "order-limitorder-amount-min-error": InvalidOrder, "order-limitorder-amount-max-error": InvalidOrder, "order-marketorder-amount-min-error": InvalidOrder, "order-limitorder-price-min-error": InvalidOrder, "order-limitorder-price-max-error": InvalidOrder, "order-stop-order-hit-trigger": InvalidOrder, "order-value-min-error": InvalidOrder, "order-invalid-price": InvalidOrder, "order-holding-limit-failed": InvalidOrder, "order-orderprice-precision-error": InvalidOrder, "order-etp-nav-price-max-error": InvalidOrder, "order-orderstate-error": OrderNotFound, "order-queryorder-invalid": OrderNotFound, "order-update-error": ExchangeNotAvailable, "api-signature-check-failed": AuthenticationError, "api-signature-not-valid": AuthenticationError, "base-record-invalid": OrderNotFound, "base-symbol-trade-disabled": BadSymbol, "base-symbol-error": BadSymbol, "system-maintenance": OnMaintenance, "base-request-exceed-frequency-limit": RateLimitExceeded, "invalid symbol": BadSymbol, "symbol trade not open now": BadSymbol, "require-symbol": BadSymbol, "invalid-address": BadRequest, "base-currency-chain-error": BadRequest, "dw-insufficient-balance": InsufficientFunds, "base-withdraw-fee-error": BadRequest, "dw-withdraw-min-limit": BadRequest, "request limit": RateLimitExceeded, }, }, "precisionMode": TICK_SIZE, "options": map[string]interface{} { "fetchMarkets": map[string]interface{} { "types": map[string]interface{} { "spot": true, "linear": true, "inverse": true, }, }, "timeDifference": 0, "adjustForTimeDifference": false, "fetchOHLCV": map[string]interface{} { "useHistoricalEndpointForSpot": true, }, "withdraw": map[string]interface{} { "includeFee": false, }, "defaultType": "spot", "defaultSubType": "linear", "defaultNetwork": "ERC20", "defaultNetworks": map[string]interface{} { "ETH": "ERC20", "BTC": "BTC", "USDT": "TRC20", }, "networks": map[string]interface{} { "TRC20": "TRX", "BTC": "BTC", "ERC20": "ETH", "SOL": "SOLANA", "HRC20": "HECO", "BEP20": "BSC", "XMR": "XMR", "LTC": "LTC", "XRP": "XRP", "XLM": "XLM", "CRONOS": "CRO", "CRO": "CRO", "GLMR": "GLMR", "POLYGON": "MATIC", "MATIC": "MATIC", "BTT": "BTT", "CUBE": "CUBE", "IOST": "IOST", "NEO": "NEO", "KLAY": "KLAY", "EOS": "EOS", "THETA": "THETA", "NAS": "NAS", "NULS": "NULS", "QTUM": "QTUM", "FTM": "FTM", "CELO": "CELO", "DOGE": "DOGE", "DOGECHAIN": "DOGECHAIN", "NEAR": "NEAR", "STEP": "STEP", "BITCI": "BITCI", "CARDANO": "ADA", "ADA": "ADA", "ETC": "ETC", "LUK": "LUK", "MINEPLEX": "MINEPLEX", "DASH": "DASH", "ZEC": "ZEC", "IOTA": "IOTA", "NEON3": "NEON3", "XEM": "XEM", "HC": "HC", "LSK": "LSK", "DCR": "DCR", "BTG": "BTG", "STEEM": "STEEM", "BTS": "BTS", "ICX": "ICX", "WAVES": "WAVES", "CMT": "CMT", "BTM": "BTM", "VET": "VET", "XZC": "XZC", "ACT": "ACT", "SMT": "SMT", "BCD": "BCD", "WAX": "WAX1", "WICC": "WICC", "ELF": "ELF", "ZIL": "ZIL", "ELA": "ELA", "BCX": "BCX", "SBTC": "SBTC", "BIFI": "BIFI", "CTXC": "CTXC", "WAN": "WAN", "POLYX": "POLYX", "PAI": "PAI", "WTC": "WTC", "DGB": "DGB", "XVG": "XVG", "AAC": "AAC", "AE": "AE", "SEELE": "SEELE", "BCV": "BCV", "GRS": "GRS", "ARDR": "ARDR", "NANO": "NANO", "ZEN": "ZEN", "RBTC": "RBTC", "BSV": "BSV", "GAS": "GAS", "XTZ": "XTZ", "LAMB": "LAMB", "CVNT1": "CVNT1", "DOCK": "DOCK", "SC": "SC", "KMD": "KMD", "ETN": "ETN", "TOP": "TOP", "IRIS": "IRIS", "UGAS": "UGAS", "TT": "TT", "NEWTON": "NEWTON", "VSYS": "VSYS", "FSN": "FSN", "BHD": "BHD", "ONE": "ONE", "EM": "EM", "CKB": "CKB", "EOSS": "EOSS", "HIVE": "HIVE", "RVN": "RVN", "DOT": "DOT", "KSM": "KSM", "BAND": "BAND", "OEP4": "OEP4", "NBS": "NBS", "FIS": "FIS", "AR": "AR", "HBAR": "HBAR", "FIL": "FIL", "MASS": "MASS", "KAVA": "KAVA", "XYM": "XYM", "ENJ": "ENJ", "CRUST": "CRUST", "ICP": "ICP", "CSPR": "CSPR", "FLOW": "FLOW", "IOTX": "IOTX", "LAT": "LAT", "APT": "APT", "XCH": "XCH", "MINA": "MINA", "XEC": "ECASH", "XPRT": "XPRT", "CCA": "ACA", "AOTI": "COTI", "AKT": "AKT", "ARS": "ARS", "ASTR": "ASTR", "AZERO": "AZERO", "BLD": "BLD", "BRISE": "BRISE", "CORE": "CORE", "DESO": "DESO", "DFI": "DFI", "EGLD": "EGLD", "ERG": "ERG", "ETHF": "ETHFAIR", "ETHW": "ETHW", "EVMOS": "EVMOS", "FIO": "FIO", "FLR": "FLR", "FINSCHIA": "FINSCHIA", "KMA": "KMA", "KYVE": "KYVE", "MEV": "MEV", "MOVR": "MOVR", "NODL": "NODL", "OAS": "OAS", "OSMO": "OSMO", "PAYCOIN": "PAYCOIN", "POKT": "POKT", "PYG": "PYG", "REI": "REI", "SCRT": "SCRT", "SDN": "SDN", "SEI": "SEI", "SGB": "SGB", "SUI": "SUI", "SXP": "SOLAR", "SYS": "SYS", "TENET": "TENET", "TON": "TON", "UNQ": "UNQ", "UYU": "UYU", "WEMIX": "WEMIX", "XDC": "XDC", "XPLA": "XPLA", }, "fetchOrdersByStatesMethod": "spot_private_get_v1_order_orders", "createMarketBuyOrderRequiresPrice": true, "language": "en-US", "broker": map[string]interface{} { "id": "AA03022abc", }, "accountsByType": map[string]interface{} { "spot": "pro", "funding": "pro", "future": "futures", }, "accountsById": map[string]interface{} { "spot": "spot", "margin": "margin", "otc": "otc", "point": "point", "super-margin": "super-margin", "investment": "investment", "borrow": "borrow", "grid-trading": "grid-trading", "deposit-earning": "deposit-earning", "otc-options": "otc-options", }, "typesByAccount": map[string]interface{} { "pro": "spot", "futures": "future", }, "spot": map[string]interface{} { "stopOrderTypes": map[string]interface{} { "stop-limit": true, "buy-stop-limit": true, "sell-stop-limit": true, "stop-limit-fok": true, "buy-stop-limit-fok": true, "sell-stop-limit-fok": true, }, "limitOrderTypes": map[string]interface{} { "limit": true, "buy-limit": true, "sell-limit": true, "ioc": true, "buy-ioc": true, "sell-ioc": true, "limit-maker": true, "buy-limit-maker": true, "sell-limit-maker": true, "stop-limit": true, "buy-stop-limit": true, "sell-stop-limit": true, "limit-fok": true, "buy-limit-fok": true, "sell-limit-fok": true, "stop-limit-fok": true, "buy-stop-limit-fok": true, "sell-stop-limit-fok": true, }, }, }, "commonCurrencies": map[string]interface{} { "NGL": "GFNGL", "GET": "THEMIS", "GTC": "GAMECOM", "HIT": "HITCHAIN", "PNT": "PENTA", "SBTC": "SUPERBITCOIN", "SOUL": "SOULSAVER", "BIFI": "BITCOINFILE", "FUD": "FTX Users Debt", }, "features": map[string]interface{} { "spot": map[string]interface{} { "sandbox": true, "createOrder": map[string]interface{} { "marginMode": true, "triggerPrice": true, "triggerDirection": true, "triggerPriceType": nil, "stopLossPrice": false, "takeProfitPrice": false, "attachedStopLossTakeProfit": nil, "timeInForce": map[string]interface{} { "IOC": true, "FOK": true, "PO": true, "GTD": false, }, "hedged": false, "trailing": false, "iceberg": false, "selfTradePrevention": true, "leverage": true, "marketBuyByCost": true, "marketBuyRequiresPrice": true, }, "createOrders": map[string]interface{} { "max": 10, }, "fetchMyTrades": map[string]interface{} { "marginMode": false, "limit": 500, "daysBack": 120, "untilDays": 2, "symbolRequired": false, }, "fetchOrder": map[string]interface{} { "marginMode": false, "trigger": false, "trailing": false, "symbolRequired": false, }, "fetchOpenOrders": map[string]interface{} { "marginMode": false, "trigger": true, "trailing": false, "limit": 500, "symbolRequired": false, }, "fetchOrders": map[string]interface{} { "marginMode": false, "trigger": true, "trailing": false, "limit": 500, "untilDays": 2, "daysBack": 180, "symbolRequired": false, }, "fetchClosedOrders": map[string]interface{} { "marginMode": false, "trigger": true, "trailing": false, "untilDays": 2, "limit": 500, "daysBack": 180, "daysBackCanceled": Divide(1, 12), "symbolRequired": false, }, "fetchOHLCV": map[string]interface{} { "limit": 1000, }, }, "forDerivatives": map[string]interface{} { "extends": "spot", "createOrder": map[string]interface{} { "stopLossPrice": true, "takeProfitPrice": true, "trailing": true, "hedged": true, }, "createOrders": map[string]interface{} { "max": 25, }, "fetchOrder": map[string]interface{} { "marginMode": true, }, "fetchOpenOrders": map[string]interface{} { "marginMode": true, "trigger": false, "trailing": false, "limit": 50, }, "fetchOrders": map[string]interface{} { "marginMode": true, "trigger": false, "trailing": false, "limit": 50, "daysBack": 90, }, "fetchClosedOrders": map[string]interface{} { "marginMode": true, "trigger": false, "trailing": false, "untilDays": 2, "limit": 50, "daysBack": 90, "daysBackCanceled": Divide(1, 12), }, "fetchOHLCV": map[string]interface{} { "limit": 2000, }, }, "swap": map[string]interface{} { "linear": map[string]interface{} { "extends": "forDerivatives", }, "inverse": map[string]interface{} { "extends": "forDerivatives", }, }, "future": map[string]interface{} { "linear": map[string]interface{} { "extends": "forDerivatives", }, "inverse": map[string]interface{} { "extends": "forDerivatives", }, }, }, }) } /** * @method * @name htx#fetchStatus * @description the latest known information on the availability of the exchange API * @see https://huobiapi.github.io/docs/spot/v1/en/#get-system-status * @see https://huobiapi.github.io/docs/dm/v1/en/#get-system-status * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-system-status * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#get-system-status * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#query-whether-the-system-is-available // contractPublicGetHeartbeat * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure} */ func (this *htx) FetchStatus(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 retRes13848 := (<-this.LoadMarkets()) PanicOnError(retRes13848) var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchStatus", nil, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var enabledForContracts interface{} = this.HandleOption("fetchStatus", "enableForContracts", false) // temp fix for: https://status-linear-swap.huobigroup.com/api/v2/summary.json var response interface{} = nil if IsTrue(IsTrue(!IsEqual(marketType, "spot")) && IsTrue(enabledForContracts)) { var subType interface{} = this.SafeString(params, "subType", GetValue(this.Options, "defaultSubType")) if IsTrue(IsEqual(marketType, "swap")) { if IsTrue(IsEqual(subType, "linear")) { response = (<-this.StatusPublicSwapLinearGetApiV2SummaryJson()) PanicOnError(response) } else if IsTrue(IsEqual(subType, "inverse")) { response = (<-this.StatusPublicSwapInverseGetApiV2SummaryJson()) PanicOnError(response) } } else if IsTrue(IsEqual(marketType, "future")) { if IsTrue(IsEqual(subType, "linear")) { response = (<-this.StatusPublicFutureLinearGetApiV2SummaryJson()) PanicOnError(response) } else if IsTrue(IsEqual(subType, "inverse")) { response = (<-this.StatusPublicFutureInverseGetApiV2SummaryJson()) PanicOnError(response) } } else if IsTrue(IsEqual(marketType, "contract")) { response = (<-this.ContractPublicGetHeartbeat()) PanicOnError(response) } } else if IsTrue(IsEqual(marketType, "spot")) { response = (<-this.StatusPublicSpotGetApiV2SummaryJson()) PanicOnError(response) } // // statusPublicSpotGetApiV2SummaryJson, statusPublicSwapInverseGetApiV2SummaryJson, statusPublicFutureLinearGetApiV2SummaryJson, statusPublicFutureInverseGetApiV2SummaryJson // // { // "page": { // "id":"mn7l2lw8pz4p", // "name":"Huobi Futures-USDT-margined Swaps", // "url":"https://status-linear-swap.huobigroup.com", // "time_zone":"Asia/Singapore", // "updated_at":"2022-04-29T12:47:21.319+08:00"}, // "components": [ // { // "id":"lrv093qk3yp5", // "name":"market data", // "status":"operational", // "created_at":"2020-10-29T14:08:59.427+08:00", // "updated_at":"2020-10-29T14:08:59.427+08:00", // "position":1,"description":null, // "showcase":false, // "start_date":null, // "group_id":null, // "page_id":"mn7l2lw8pz4p", // "group":true, // "only_show_if_degraded":false, // "components": [ // "82k5jxg7ltxd" // list of related components // ] // }, // ], // "incidents": [ // empty array if there are no issues // { // "id": "rclfxz2g21ly", // incident id // "name": "Market data is delayed", // incident name // "status": "investigating", // incident status // "created_at": "2020-02-11T03:15:01.913Z", // incident create time // "updated_at": "2020-02-11T03:15:02.003Z", // incident update time // "monitoring_at": null, // "resolved_at": null, // "impact": "minor", // incident impact // "shortlink": "http://stspg.io/pkvbwp8jppf9", // "started_at": "2020-02-11T03:15:01.906Z", // "page_id": "p0qjfl24znv5", // "incident_updates": [ // { // "id": "dwfsk5ttyvtb", // "status": "investigating", // "body": "Market data is delayed", // "incident_id": "rclfxz2g21ly", // "created_at": "2020-02-11T03:15:02.000Z", // "updated_at": "2020-02-11T03:15:02.000Z", // "display_at": "2020-02-11T03:15:02.000Z", // "affected_components": [ // { // "code": "nctwm9tghxh6", // "name": "Market data", // "old_status": "operational", // "new_status": "degraded_performance" // } // ], // "deliver_notifications": true, // "custom_tweet": null, // "tweet_id": null // } // ], // "components": [ // { // "id": "nctwm9tghxh6", // "name": "Market data", // "status": "degraded_performance", // "created_at": "2020-01-13T09:34:48.284Z", // "updated_at": "2020-02-11T03:15:01.951Z", // "position": 8, // "description": null, // "showcase": false, // "group_id": null, // "page_id": "p0qjfl24znv5", // "group": false, // "only_show_if_degraded": false // } // ] // }, ... // ], // "scheduled_maintenances":[ // empty array if there are no scheduled maintenances // { // "id": "k7g299zl765l", // incident id // "name": "Schedule maintenance", // incident name // "status": "scheduled", // incident status // "created_at": "2020-02-11T03:16:31.481Z", // incident create time // "updated_at": "2020-02-11T03:16:31.530Z", // incident update time // "monitoring_at": null, // "resolved_at": null, // "impact": "maintenance", // incident impact // "shortlink": "http://stspg.io/md4t4ym7nytd", // "started_at": "2020-02-11T03:16:31.474Z", // "page_id": "p0qjfl24znv5", // "incident_updates": [ // { // "id": "8whgr3rlbld8", // "status": "scheduled", // "body": "We will be undergoing scheduled maintenance during this time.", // "incident_id": "k7g299zl765l", // "created_at": "2020-02-11T03:16:31.527Z", // "updated_at": "2020-02-11T03:16:31.527Z", // "display_at": "2020-02-11T03:16:31.527Z", // "affected_components": [ // { // "code": "h028tnzw1n5l", // "name": "Deposit And Withdraw - Deposit", // "old_status": "operational", // "new_status": "operational" // } // ], // "deliver_notifications": true, // "custom_tweet": null, // "tweet_id": null // } // ], // "components": [ // { // "id": "h028tnzw1n5l", // "name": "Deposit", // "status": "operational", // "created_at": "2019-12-05T02:07:12.372Z", // "updated_at": "2020-02-10T12:34:52.970Z", // "position": 1, // "description": null, // "showcase": false, // "group_id": "gtd0nyr3pf0k", // "page_id": "p0qjfl24znv5", // "group": false, // "only_show_if_degraded": false // } // ], // "scheduled_for": "2020-02-15T00:00:00.000Z", // scheduled maintenance start time // "scheduled_until": "2020-02-15T01:00:00.000Z" // scheduled maintenance end time // } // ], // "status": { // "indicator":"none", // none, minor, major, critical, maintenance // "description":"all systems operational" // All Systems Operational, Minor Service Outage, Partial System Outage, Partially Degraded Service, Service Under Maintenance // } // } // // // contractPublicGetHeartbeat // // { // "status": "ok", // 'ok', 'error' // "data": { // "heartbeat": 1, // future 1: available, 0: maintenance with service suspended // "estimated_recovery_time": null, // estimated recovery time in milliseconds // "swap_heartbeat": 1, // "swap_estimated_recovery_time": null, // "option_heartbeat": 1, // "option_estimated_recovery_time": null, // "linear_swap_heartbeat": 1, // "linear_swap_estimated_recovery_time": null // }, // "ts": 1557714418033 // } // var status interface{} = nil var updated interface{} = nil var url interface{} = nil if IsTrue(IsEqual(marketType, "contract")) { var statusRaw interface{} = this.SafeString(response, "status") if IsTrue(IsEqual(statusRaw, nil)) { status = nil } else { status = Ternary(IsTrue((IsEqual(statusRaw, "ok"))), "ok", "maintenance") // 'ok', 'error' } updated = this.SafeString(response, "ts") } else { var statusData interface{} = this.SafeValue(response, "status", map[string]interface{} {}) var statusRaw interface{} = this.SafeString(statusData, "indicator") status = Ternary(IsTrue((IsEqual(statusRaw, "none"))), "ok", "maintenance") // none, minor, major, critical, maintenance var pageData interface{} = this.SafeValue(response, "page", map[string]interface{} {}) var datetime interface{} = this.SafeString(pageData, "updated_at") updated = this.Parse8601(datetime) url = this.SafeString(pageData, "url") } ch <- map[string]interface{} { "status": status, "updated": updated, "eta": nil, "url": url, "info": response, } return nil }() return ch } /** * @method * @name htx#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @see https://huobiapi.github.io/docs/spot/v1/en/#get-current-timestamp * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-current-system-timestamp * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ func (this *htx) FetchTime(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var options interface{} = this.SafeValue(this.Options, "fetchTime", map[string]interface{} {}) var defaultType interface{} = this.SafeString(this.Options, "defaultType", "spot") var typeVar interface{} = this.SafeString(options, "type", defaultType) typeVar = this.SafeString(params, "type", typeVar) var response interface{} = nil if IsTrue(IsTrue((IsEqual(typeVar, "future"))) || IsTrue((IsEqual(typeVar, "swap")))) { response = (<-this.ContractPublicGetApiV1Timestamp(params)) PanicOnError(response) } else { response = (<-this.SpotPublicGetV1CommonTimestamp(params)) PanicOnError(response) } // // spot // // {"status":"ok","data":1637504261099} // // future, swap // // {"status":"ok","ts":1637504164707} // ch <- this.SafeInteger2(response, "data", "ts") return nil }() return ch } func (this *htx) ParseTradingFee(fee interface{}, optionalArgs ...interface{}) interface{} { // // { // "symbol":"btcusdt", // "actualMakerRate":"0.002", // "actualTakerRate":"0.002", // "takerFeeRate":"0.002", // "makerFeeRate":"0.002" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(fee, "symbol") return map[string]interface{} { "info": fee, "symbol": this.SafeSymbol(marketId, market), "maker": this.SafeNumber(fee, "actualMakerRate"), "taker": this.SafeNumber(fee, "actualTakerRate"), "percentage": nil, "tierBased": nil, } } /** * @method * @name htx#fetchTradingFee * @description fetch the trading fees for a market * @see https://huobiapi.github.io/docs/spot/v1/en/#get-current-fee-rate-applied-to-the-user * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure} */ func (this *htx) FetchTradingFee(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes16628 := (<-this.LoadMarkets()) PanicOnError(retRes16628) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbols": GetValue(market, "id"), } response:= (<-this.SpotPrivateGetV2ReferenceTransactFeeRate(this.Extend(request, params))) PanicOnError(response) // // { // "code":200, // "data":[ // { // "symbol":"btcusdt", // "actualMakerRate":"0.002", // "actualTakerRate":"0.002", // "takerFeeRate":"0.002", // "makerFeeRate":"0.002" // } // ], // "success":true // } // var data interface{} = this.SafeValue(response, "data", []interface{}{}) var first interface{} = this.SafeValue(data, 0, map[string]interface{} {}) ch <- this.ParseTradingFee(first, market) return nil }() return ch } func (this *htx) FetchTradingLimits(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // this method should not be called directly, use loadTradingLimits () instead // by default it will try load withdrawal fees of all currencies (with separate requests) // however if you define symbols = [ 'ETH/BTC', 'LTC/BTC' ] in args it will only load those symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes16928 := (<-this.LoadMarkets()) PanicOnError(retRes16928) if IsTrue(IsEqual(symbols, nil)) { symbols = this.Symbols } var result interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(symbols)); i++ { var symbol interface{} = GetValue(symbols, i) AddElementToObject(result, symbol, (<-this.FetchTradingLimitsById(this.MarketId(symbol), params))) } ch <- result return nil }() return ch } /** * @ignore * @method * @name htx#fetchTradingLimitsById * @see https://huobiapi.github.io/docs/spot/v1/en/#get-current-fee-rate-applied-to-the-user * @param {string} id market id * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} the limits object of a market structure */ func (this *htx) FetchTradingLimitsById(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var request interface{} = map[string]interface{} { "symbol": id, } response:= (<-this.SpotPublicGetV1CommonExchange(this.Extend(request, params))) PanicOnError(response) // // { status: "ok", // "data": { symbol: "aidocbtc", // "buy-limit-must-less-than": 1.1, // "sell-limit-must-greater-than": 0.9, // "limit-order-must-greater-than": 1, // "limit-order-must-less-than": 5000000, // "market-buy-order-must-greater-than": 0.0001, // "market-buy-order-must-less-than": 100, // "market-sell-order-must-greater-than": 1, // "market-sell-order-must-less-than": 500000, // "circuit-break-when-greater-than": 10000, // "circuit-break-when-less-than": 10, // "market-sell-order-rate-must-less-than": 0.1, // "market-buy-order-rate-must-less-than": 0.1 } } // ch <- this.ParseTradingLimits(this.SafeValue(response, "data", map[string]interface{} {})) return nil }() return ch } func (this *htx) ParseTradingLimits(limits interface{}, optionalArgs ...interface{}) interface{} { // // { "symbol": "aidocbtc", // "buy-limit-must-less-than": 1.1, // "sell-limit-must-greater-than": 0.9, // "limit-order-must-greater-than": 1, // "limit-order-must-less-than": 5000000, // "market-buy-order-must-greater-than": 0.0001, // "market-buy-order-must-less-than": 100, // "market-sell-order-must-greater-than": 1, // "market-sell-order-must-less-than": 500000, // "circuit-break-when-greater-than": 10000, // "circuit-break-when-less-than": 10, // "market-sell-order-rate-must-less-than": 0.1, // "market-buy-order-rate-must-less-than": 0.1 } // symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params return map[string]interface{} { "info": limits, "limits": map[string]interface{} { "amount": map[string]interface{} { "min": this.SafeNumber(limits, "limit-order-must-greater-than"), "max": this.SafeNumber(limits, "limit-order-must-less-than"), }, }, } } func (this *htx) CostToPrecision(symbol interface{}, cost interface{}) interface{} { return this.DecimalToPrecision(cost, TRUNCATE, GetValue(GetValue(GetValue(this.Markets, symbol), "precision"), "cost"), this.PrecisionMode) } /** * @method * @name htx#fetchMarkets * @description retrieves data on all markets for huobi * @see https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-trading-symbol-v1-deprecated * @see https://huobiapi.github.io/docs/dm/v1/en/#get-contract-info * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-swap-info * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-swap-info * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *htx) 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 if IsTrue(GetValue(this.Options, "adjustForTimeDifference")) { retRes178112 := (<-this.LoadTimeDifference()) PanicOnError(retRes178112) } var types interface{} = nil typesparamsVariable := this.HandleOptionAndParams(params, "fetchMarkets", "types", map[string]interface{} {}); types = GetValue(typesparamsVariable,0); params = GetValue(typesparamsVariable,1) var allMarkets interface{} = []interface{}{} var promises interface{} = []interface{}{} var keys interface{} = ObjectKeys(types) for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ { var key interface{} = GetValue(keys, i) if IsTrue(this.SafeBool(types, key)) { if IsTrue(IsEqual(key, "spot")) { AppendToArray(&promises,this.FetchMarketsByTypeAndSubType("spot", nil, params)) } else if IsTrue(IsEqual(key, "linear")) { AppendToArray(&promises,this.FetchMarketsByTypeAndSubType(nil, "linear", params)) } else if IsTrue(IsEqual(key, "inverse")) { AppendToArray(&promises,this.FetchMarketsByTypeAndSubType("swap", "inverse", params)) AppendToArray(&promises,this.FetchMarketsByTypeAndSubType("future", "inverse", params)) } } } promises = (<-promiseAll(promises)) PanicOnError(promises) for i := 0; IsLessThan(i, GetArrayLength(promises)); i++ { allMarkets = this.ArrayConcat(allMarkets, GetValue(promises, i)) } ch <- allMarkets return nil }() return ch } /** * @ignore * @method * @name htx#fetchMarketsByTypeAndSubType * @description retrieves data on all markets of a certain type and/or subtype * @see https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-trading-symbol-v1-deprecated * @see https://huobiapi.github.io/docs/dm/v1/en/#get-contract-info * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-swap-info * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-swap-info * @param {string} [type] 'spot', 'swap' or 'future' * @param {string} [subType] 'linear' or 'inverse' * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *htx) FetchMarketsByTypeAndSubType(typeVar interface{}, subType interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var isSpot interface{} = (IsEqual(typeVar, "spot")) var request interface{} = map[string]interface{} {} var response interface{} = nil if !IsTrue(isSpot) { if IsTrue(IsEqual(subType, "linear")) { AddElementToObject(request, "business_type", "all") // override default to fetch all linear markets response = (<-this.ContractPublicGetLinearSwapApiV1SwapContractInfo(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(subType, "inverse")) { if IsTrue(IsEqual(typeVar, "future")) { response = (<-this.ContractPublicGetApiV1ContractContractInfo(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(typeVar, "swap")) { response = (<-this.ContractPublicGetSwapApiV1SwapContractInfo(this.Extend(request, params))) PanicOnError(response) } } } else { response = (<-this.SpotPublicGetV1CommonSymbols(this.Extend(request, params))) PanicOnError(response) } // // spot // // { // "status":"ok", // "data":[ // { // "base-currency":"xrp3s", // "quote-currency":"usdt", // "price-precision":4, // "amount-precision":4, // "symbol-partition":"innovation", // "symbol":"xrp3susdt", // "state":"online", // "value-precision":8, // "min-order-amt":0.01, // "max-order-amt":1616.4353, // "min-order-value":5, // "limit-order-min-order-amt":0.01, // "limit-order-max-order-amt":1616.4353, // "limit-order-max-buy-amt":1616.4353, // "limit-order-max-sell-amt":1616.4353, // "sell-market-min-order-amt":0.01, // "sell-market-max-order-amt":1616.4353, // "buy-market-max-order-value":2500, // "max-order-value":2500, // "underlying":"xrpusdt", // "mgmt-fee-rate":0.035000000000000000, // "charge-time":"23:55:00", // "rebal-time":"00:00:00", // "rebal-threshold":-5, // "init-nav":10.000000000000000000, // "api-trading":"enabled", // "tags":"etp,nav,holdinglimit" // }, // ] // } // // inverse (swap & future) // // { // "status":"ok", // "data":[ // { // "symbol":"BTC", // "contract_code":"BTC211126", /// BTC-USD in swap // "contract_type":"this_week", // only in future // "contract_size":100, // "price_tick":0.1, // "delivery_date":"20211126", // only in future // "delivery_time":"1637913600000", // empty in swap // "create_date":"20211112", // "contract_status":1, // "settlement_time":"1637481600000" // only in future // "settlement_date":"16xxxxxxxxxxx" // only in swap // }, // ... // ], // "ts":1637474595140 // } // // linear (swap & future) // // { // "status":"ok", // "data":[ // { // "symbol":"BTC", // "contract_code":"BTC-USDT-211231", // or "BTC-USDT" in swap // "contract_size":0.001, // "price_tick":0.1, // "delivery_date":"20211231", // empty in swap // "delivery_time":"1640937600000", // empty in swap // "create_date":"20211228", // "contract_status":1, // "settlement_date":"1640764800000", // "support_margin_mode":"cross", // "all" or "cross" // "business_type":"futures", // "swap" or "futures" // "pair":"BTC-USDT", // "contract_type":"this_week", // "swap", "this_week", "next_week", "quarter" // "trade_partition":"USDT", // } // ], // "ts":1640736207263 // } // var markets interface{} = this.SafeList(response, "data", []interface{}{}) var numMarkets interface{} = GetArrayLength(markets) if IsTrue(IsLessThan(numMarkets, 1)) { panic(OperationFailed(Add(Add(this.Id, " fetchMarkets() returned an empty response: "), this.Json(response)))) } var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(markets)); i++ { var market interface{} = GetValue(markets, i) var baseId interface{} = nil var quoteId interface{} = nil var settleId interface{} = nil var id interface{} = nil var lowercaseId interface{} = nil var contract interface{} = (InOp(market, "contract_code")) var spot interface{} = !IsTrue(contract) var swap interface{} = false var future interface{} = false var linear interface{} = nil var inverse interface{} = nil // check if parsed market is contract if IsTrue(contract) { id = this.SafeString(market, "contract_code") lowercaseId = ToLower(id) var delivery_date interface{} = this.SafeString(market, "delivery_date") var business_type interface{} = this.SafeString(market, "business_type") future = !IsEqual(delivery_date, nil) swap = !IsTrue(future) linear = !IsEqual(business_type, nil) inverse = !IsTrue(linear) if IsTrue(swap) { typeVar = "swap" var parts interface{} = Split(id, "-") baseId = this.SafeStringLower(market, "symbol") quoteId = this.SafeStringLower(parts, 1) settleId = Ternary(IsTrue(inverse), baseId, quoteId) } else if IsTrue(future) { typeVar = "future" baseId = this.SafeStringLower(market, "symbol") if IsTrue(inverse) { quoteId = "USD" settleId = baseId } else { var pair interface{} = this.SafeString(market, "pair") var parts interface{} = Split(pair, "-") quoteId = this.SafeStringLower(parts, 1) settleId = quoteId } } } else { typeVar = "spot" baseId = this.SafeString(market, "base-currency") quoteId = this.SafeString(market, "quote-currency") id = Add(baseId, quoteId) lowercaseId = ToLower(id) } var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) var settle interface{} = this.SafeCurrencyCode(settleId) var symbol interface{} = Add(Add(base, "/"), quote) var expiry interface{} = nil if IsTrue(contract) { if IsTrue(inverse) { symbol = Add(symbol, Add(":", base)) } else if IsTrue(linear) { symbol = Add(symbol, Add(":", quote)) } if IsTrue(future) { expiry = this.SafeInteger(market, "delivery_time") symbol = Add(symbol, Add("-", this.Yymmdd(expiry))) } } var contractSize interface{} = this.SafeNumber(market, "contract_size") var minCost interface{} = this.SafeNumber(market, "min-order-value") var maxAmount interface{} = this.SafeNumber(market, "max-order-amt") var minAmount interface{} = this.SafeNumber(market, "min-order-amt") if IsTrue(contract) { if IsTrue(linear) { minAmount = contractSize } else if IsTrue(inverse) { minCost = contractSize } } var pricePrecision interface{} = nil var amountPrecision interface{} = nil var costPrecision interface{} = nil var maker interface{} = nil var taker interface{} = nil var active interface{} = nil if IsTrue(spot) { pricePrecision = this.ParseNumber(this.ParsePrecision(this.SafeString(market, "price-precision"))) amountPrecision = this.ParseNumber(this.ParsePrecision(this.SafeString(market, "amount-precision"))) costPrecision = this.ParseNumber(this.ParsePrecision(this.SafeString(market, "value-precision"))) maker = this.ParseNumber("0.002") taker = this.ParseNumber("0.002") var state interface{} = this.SafeString(market, "state") active = (IsEqual(state, "online")) } else { pricePrecision = this.SafeNumber(market, "price_tick") amountPrecision = this.ParseNumber("1") // other markets have step size of 1 contract maker = this.ParseNumber("0.0002") taker = this.ParseNumber("0.0005") var contractStatus interface{} = this.SafeInteger(market, "contract_status") active = (IsEqual(contractStatus, 1)) } var leverageRatio interface{} = this.SafeString(market, "leverage-ratio", "1") var superLeverageRatio interface{} = this.SafeString(market, "super-margin-leverage-ratio", "1") var hasLeverage interface{} = IsTrue(Precise.StringGt(leverageRatio, "1")) || IsTrue(Precise.StringGt(superLeverageRatio, "1")) // 0 Delisting // 1 Listing // 2 Pending Listing // 3 Suspension // 4 Suspending of Listing // 5 In Settlement // 6 Delivering // 7 Settlement Completed // 8 Delivered // 9 Suspending of Trade var created interface{} = nil var createdDate interface{} = this.SafeString(market, "create_date") // i.e 20230101 if IsTrue(!IsEqual(createdDate, nil)) { var createdArray interface{} = this.StringToCharsArray(createdDate) createdDate = Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(GetValue(createdArray, 0), GetValue(createdArray, 1)), GetValue(createdArray, 2)), GetValue(createdArray, 3)), "-"), GetValue(createdArray, 4)), GetValue(createdArray, 5)), "-"), GetValue(createdArray, 6)), GetValue(createdArray, 7)), " 00:00:00") created = this.Parse8601(createdDate) } AppendToArray(&result,map[string]interface{} { "id": id, "lowercaseId": lowercaseId, "symbol": symbol, "base": base, "quote": quote, "settle": settle, "baseId": baseId, "quoteId": quoteId, "settleId": settleId, "type": typeVar, "spot": spot, "margin": (IsTrue(spot) && IsTrue(hasLeverage)), "swap": swap, "future": future, "option": false, "active": active, "contract": contract, "linear": linear, "inverse": inverse, "taker": taker, "maker": maker, "contractSize": contractSize, "expiry": expiry, "expiryDatetime": this.Iso8601(expiry), "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": amountPrecision, "price": pricePrecision, "cost": costPrecision, }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": this.ParseNumber("1"), "max": this.ParseNumber(leverageRatio), "superMax": this.ParseNumber(superLeverageRatio), }, "amount": map[string]interface{} { "min": minAmount, "max": maxAmount, }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": minCost, "max": nil, }, }, "created": created, "info": market, }) } ch <- result return nil }() return ch } func (this *htx) TryGetSymbolFromFutureMarkets(symbolOrMarketId interface{}) interface{} { if IsTrue(InOp(this.Markets, symbolOrMarketId)) { return symbolOrMarketId } // only on "future" market type (inverse & linear), market-id differs between "fetchMarkets" and "fetchTicker" // so we have to create a mapping // - market-id from fetchMarkts: `BTC-USDT-240419` (linear future) or `BTC240412` (inverse future) // - market-id from fetchTciker[s]: `BTC-USDT-CW` (linear future) or `BTC_CW` (inverse future) if !IsTrue((InOp(this.Options, "futureMarketIdsForSymbols"))) { AddElementToObject(this.Options, "futureMarketIdsForSymbols", map[string]interface{} {}) } var futureMarketIdsForSymbols interface{} = this.SafeDict(this.Options, "futureMarketIdsForSymbols", map[string]interface{} {}) if IsTrue(InOp(futureMarketIdsForSymbols, symbolOrMarketId)) { return GetValue(futureMarketIdsForSymbols, symbolOrMarketId) } var futureMarkets interface{} = this.FilterBy(this.Markets, "future", true) var futuresCharsMaps interface{} = map[string]interface{} { "this_week": "CW", "next_week": "NW", "quarter": "CQ", "next_quarter": "NQ", } for i := 0; IsLessThan(i, GetArrayLength(futureMarkets)); i++ { var market interface{} = GetValue(futureMarkets, i) var info interface{} = this.SafeValue(market, "info", map[string]interface{} {}) var contractType interface{} = this.SafeString(info, "contract_type") var contractSuffix interface{} = GetValue(futuresCharsMaps, contractType) // see comment on formats a bit above var constructedId interface{} = Ternary(IsTrue(GetValue(market, "linear")), Add(Add(Add(Add(GetValue(market, "base"), "-"), GetValue(market, "quote")), "-"), contractSuffix), Add(Add(GetValue(market, "base"), "_"), contractSuffix)) if IsTrue(IsEqual(constructedId, symbolOrMarketId)) { var symbol interface{} = GetValue(market, "symbol") AddElementToObject(GetValue(this.Options, "futureMarketIdsForSymbols"), symbolOrMarketId, symbol) return symbol } } // if not found, just save it to avoid unnecessary future iterations AddElementToObject(GetValue(this.Options, "futureMarketIdsForSymbols"), symbolOrMarketId, symbolOrMarketId) return symbolOrMarketId } func (this *htx) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // fetchTicker // // { // "amount": 26228.672978342216, // "open": 9078.95, // "close": 9146.86, // "high": 9155.41, // "id": 209988544334, // "count": 265846, // "low": 8988.0, // "version": 209988544334, // "ask": [ 9146.87, 0.156134 ], // "vol": 2.3822168242201668E8, // "bid": [ 9146.86, 0.080758 ], // } // // fetchTickers // // { // "symbol": "bhdht", // "open": 2.3938, // "high": 2.4151, // "low": 2.3323, // "close": 2.3909, // "amount": 628.992, // "vol": 1493.71841095, // "count": 2088, // "bid": 2.3643, // "bidSize": 0.7136, // "ask": 2.4061, // "askSize": 0.4156 // } // // watchTikcer - bbo // { // "seqId": 161499562790, // "ask": 16829.51, // "askSize": 0.707776, // "bid": 16829.5, // "bidSize": 1.685945, // "quoteTime": 1671941599612, // "symbol": "btcusdt" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString2(ticker, "symbol", "contract_code") var symbol interface{} = this.SafeSymbol(marketId, market) symbol = this.TryGetSymbolFromFutureMarkets(symbol) var timestamp interface{} = this.SafeInteger2(ticker, "ts", "quoteTime") var bid interface{} = nil var bidVolume interface{} = nil var ask interface{} = nil var askVolume interface{} = nil if IsTrue(InOp(ticker, "bid")) { if IsTrue(IsArray(GetValue(ticker, "bid"))) { bid = this.SafeString(GetValue(ticker, "bid"), 0) bidVolume = this.SafeString(GetValue(ticker, "bid"), 1) } else { bid = this.SafeString(ticker, "bid") bidVolume = this.SafeString(ticker, "bidSize") } } if IsTrue(InOp(ticker, "ask")) { if IsTrue(IsArray(GetValue(ticker, "ask"))) { ask = this.SafeString(GetValue(ticker, "ask"), 0) askVolume = this.SafeString(GetValue(ticker, "ask"), 1) } else { ask = this.SafeString(ticker, "ask") askVolume = this.SafeString(ticker, "askSize") } } var open interface{} = this.SafeString(ticker, "open") var close interface{} = this.SafeString(ticker, "close") var baseVolume interface{} = this.SafeString(ticker, "amount") var quoteVolume interface{} = this.SafeString(ticker, "vol") return this.SafeTicker(map[string]interface{} { "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "high": this.SafeString(ticker, "high"), "low": this.SafeString(ticker, "low"), "bid": bid, "bidVolume": bidVolume, "ask": ask, "askVolume": askVolume, "vwap": nil, "open": open, "close": close, "last": close, "previousClose": nil, "change": nil, "percentage": nil, "average": nil, "baseVolume": baseVolume, "quoteVolume": quoteVolume, "info": ticker, }, market) } /** * @method * @name htx#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://huobiapi.github.io/docs/spot/v1/en/#get-latest-aggregated-ticker * @see https://huobiapi.github.io/docs/dm/v1/en/#get-market-data-overview * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-market-data-overview * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-market-data-overview * @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 *htx) 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 retRes22618 := (<-this.LoadMarkets()) PanicOnError(retRes22618) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} {} var response interface{} = nil if IsTrue(GetValue(market, "linear")) { AddElementToObject(request, "contract_code", GetValue(market, "id")) response = (<-this.ContractPublicGetLinearSwapExMarketDetailMerged(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { if IsTrue(GetValue(market, "future")) { AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.ContractPublicGetMarketDetailMerged(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "swap")) { AddElementToObject(request, "contract_code", GetValue(market, "id")) response = (<-this.ContractPublicGetSwapExMarketDetailMerged(this.Extend(request, params))) PanicOnError(response) } } else { AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.SpotPublicGetMarketDetailMerged(this.Extend(request, params))) PanicOnError(response) } // // spot // // { // "status": "ok", // "ch": "market.btcusdt.detail.merged", // "ts": 1583494336669, // "tick": { // "amount": 26228.672978342216, // "open": 9078.95, // "close": 9146.86, // "high": 9155.41, // "id": 209988544334, // "count": 265846, // "low": 8988.0, // "version": 209988544334, // "ask": [ 9146.87, 0.156134 ], // "vol": 2.3822168242201668E8, // "bid": [ 9146.86, 0.080758 ], // } // } // // future, swap // // { // "ch":"market.BTC211126.detail.merged", // "status":"ok", // "tick":{ // "amount":"669.3385682049668320322569544150680718474", // "ask":[59117.44,48], // "bid":[59082,48], // "close":"59087.97", // "count":5947, // "high":"59892.62", // "id":1637502670, // "low":"57402.87", // "open":"57638", // "ts":1637502670059, // "vol":"394598" // }, // "ts":1637502670059 // } // var tick interface{} = this.SafeValue(response, "tick", map[string]interface{} {}) var ticker interface{} = this.ParseTicker(tick, market) var timestamp interface{} = this.SafeInteger(response, "ts") AddElementToObject(ticker, "timestamp", timestamp) AddElementToObject(ticker, "datetime", this.Iso8601(timestamp)) ch <- ticker return nil }() return ch } /** * @method * @name htx#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://huobiapi.github.io/docs/spot/v1/en/#get-latest-tickers-for-all-pairs * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-a-batch-of-market-data-overview * @see https://huobiapi.github.io/docs/dm/v1/en/#get-a-batch-of-market-data-overview * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-a-batch-of-market-data-overview-v2 * @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 *htx) 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 retRes23448 := (<-this.LoadMarkets()) PanicOnError(retRes23448) symbols = this.MarketSymbols(symbols) var first interface{} = this.SafeString(symbols, 0) var market interface{} = nil if IsTrue(!IsEqual(first, nil)) { market = this.Market(first) } var isSubTypeRequested interface{} = IsTrue((InOp(params, "subType"))) || IsTrue((InOp(params, "business_type"))) var typeVar interface{} = nil var subType interface{} = nil typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchTickers", market, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) subTypeparamsVariable := this.HandleSubTypeAndParams("fetchTickers", market, params); subType = GetValue(subTypeparamsVariable,0); params = GetValue(subTypeparamsVariable,1) var request interface{} = map[string]interface{} {} var isSpot interface{} = (IsEqual(typeVar, "spot")) var future interface{} = (IsEqual(typeVar, "future")) var swap interface{} = (IsEqual(typeVar, "swap")) var linear interface{} = (IsEqual(subType, "linear")) var inverse interface{} = (IsEqual(subType, "inverse")) var response interface{} = nil if IsTrue(!IsTrue(isSpot) || IsTrue(isSubTypeRequested)) { if IsTrue(linear) { // independently of type, supports calling all linear symbols i.e. fetchTickers(undefined, {subType:'linear'}) if IsTrue(future) { AddElementToObject(request, "business_type", "futures") } else if IsTrue(swap) { AddElementToObject(request, "business_type", "swap") } else { AddElementToObject(request, "business_type", "all") } response = (<-this.ContractPublicGetLinearSwapExMarketDetailBatchMerged(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(inverse) { if IsTrue(future) { response = (<-this.ContractPublicGetMarketDetailBatchMerged(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(swap) { response = (<-this.ContractPublicGetSwapExMarketDetailBatchMerged(this.Extend(request, params))) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " fetchTickers() you have to set params[\"type\"] to either \"swap\" or \"future\" for inverse contracts"))) } } else { panic(NotSupported(Add(this.Id, " fetchTickers() you have to set params[\"subType\"] to either \"linear\" or \"inverse\" for contracts"))) } } else { response = (<-this.SpotPublicGetMarketTickers(this.Extend(request, params))) PanicOnError(response) } // // spot // // { // "data":[ // { // "symbol":"hbcbtc", // "open":5.313E-5, // "high":5.34E-5, // "low":5.112E-5, // "close":5.175E-5, // "amount":1183.87, // "vol":0.0618599229, // "count":205, // "bid":5.126E-5, // "bidSize":5.25, // "ask":5.214E-5, // "askSize":150.0 // }, // ], // "status":"ok", // "ts":1639547261293 // } // // linear swap, linear future, inverse swap, inverse future // // { // "status":"ok", // "ticks":[ // { // "id":1637504679, // "ts":1637504679372, // "ask":[0.10644,100], // "bid":[0.10624,26], // "symbol":"TRX_CW", // "open":"0.10233", // "close":"0.10644", // "low":"0.1017", // "high":"0.10725", // "amount":"2340267.415144052378486261756692535687481566", // "count":882, // "vol":"24706", // "trade_turnover":"840726.5048", // only in linear futures // "business_type":"futures", // only in linear futures // "contract_code":"BTC-USDT-CW", // only in linear futures, instead of 'symbol' // } // ], // "ts":1637504679376 // } // var rawTickers interface{} = this.SafeList2(response, "data", "ticks", []interface{}{}) var tickers interface{} = this.ParseTickers(rawTickers, symbols, params) ch <- this.FilterByArrayTickers(tickers, "symbol", symbols) return nil }() return ch } /** * @method * @name htx#fetchLastPrices * @description fetches the last price for multiple markets * @see https://www.htx.com/en-us/opend/newApiPages/?id=8cb81024-77b5-11ed-9966-0242ac110003 linear swap & linear future * @see https://www.htx.com/en-us/opend/newApiPages/?id=28c2e8fc-77ae-11ed-9966-0242ac110003 inverse future * @see https://www.htx.com/en-us/opend/newApiPages/?id=5d517ef5-77b6-11ed-9966-0242ac110003 inverse swap * @param {string[]} [symbols] unified symbols of the markets to fetch the last prices * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of lastprices structures */ func (this *htx) FetchLastPrices(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 retRes24558 := (<-this.LoadMarkets()) PanicOnError(retRes24558) symbols = this.MarketSymbols(symbols) var market interface{} = this.GetMarketFromSymbols(symbols) var typeVar interface{} = nil var subType interface{} = nil subTypeparamsVariable := this.HandleSubTypeAndParams("fetchLastPrices", market, params); subType = GetValue(subTypeparamsVariable,0); params = GetValue(subTypeparamsVariable,1) typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchLastPrices", market, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) var response interface{} = nil if IsTrue(IsTrue((IsTrue((IsEqual(typeVar, "swap"))) || IsTrue((IsEqual(typeVar, "future"))))) && IsTrue((IsEqual(subType, "linear")))) { response = (<-this.ContractPublicGetLinearSwapExMarketTrade(params)) PanicOnError(response) } else if IsTrue(IsTrue((IsEqual(typeVar, "swap"))) && IsTrue((IsEqual(subType, "inverse")))) { response = (<-this.ContractPublicGetSwapExMarketTrade(params)) PanicOnError(response) } else if IsTrue(IsTrue((IsEqual(typeVar, "future"))) && IsTrue((IsEqual(subType, "inverse")))) { response = (<-this.ContractPublicGetMarketTrade(params)) PanicOnError(response) } else { panic(NotSupported(Add(Add(Add(this.Id, " fetchLastPrices() does not support "), typeVar), " markets yet"))) } var tick interface{} = this.SafeValue(response, "tick", map[string]interface{} {}) var data interface{} = this.SafeList(tick, "data", []interface{}{}) ch <- this.ParseLastPrices(data, symbols) return nil }() return ch } func (this *htx) ParseLastPrice(entry interface{}, optionalArgs ...interface{}) interface{} { // example responses are documented in fetchLastPrices market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString2(entry, "symbol", "contract_code") market = this.SafeMarket(marketId, market) var price interface{} = this.SafeNumber(entry, "price") var direction interface{} = this.SafeString(entry, "direction") // "buy" or "sell" // group timestamp should not be assigned to the individual trades' times return map[string]interface{} { "symbol": GetValue(market, "symbol"), "timestamp": nil, "datetime": nil, "price": price, "side": direction, "info": entry, } } /** * @method * @name htx#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://huobiapi.github.io/docs/spot/v1/en/#get-market-depth * @see https://huobiapi.github.io/docs/dm/v1/en/#get-market-depth * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-market-depth * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-market-depth * @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 *htx) 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 retRes25778 := (<-this.LoadMarkets()) PanicOnError(retRes25778) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "type": "step0", } var response interface{} = nil if IsTrue(GetValue(market, "linear")) { AddElementToObject(request, "contract_code", GetValue(market, "id")) response = (<-this.ContractPublicGetLinearSwapExMarketDepth(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { if IsTrue(GetValue(market, "future")) { AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.ContractPublicGetMarketDepth(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "swap")) { AddElementToObject(request, "contract_code", GetValue(market, "id")) response = (<-this.ContractPublicGetSwapExMarketDepth(this.Extend(request, params))) PanicOnError(response) } } else { if IsTrue(!IsEqual(limit, nil)) { // Valid depths are 5, 10, 20 or empty https://huobiapi.github.io/docs/spot/v1/en/#get-market-depth if IsTrue(IsTrue(IsTrue(IsTrue((!IsEqual(limit, 5))) && IsTrue((!IsEqual(limit, 10)))) && IsTrue((!IsEqual(limit, 20)))) && IsTrue((!IsEqual(limit, 150)))) { panic(BadRequest(Add(this.Id, " fetchOrderBook() limit argument must be undefined, 5, 10, 20, or 150, default is 150"))) } // only set the depth if it is not 150 // 150 is the implicit default on the exchange side for step0 and no orderbook aggregation // it is not accepted by the exchange if you set it explicitly if IsTrue(!IsEqual(limit, 150)) { AddElementToObject(request, "depth", limit) } } AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.SpotPublicGetMarketDepth(this.Extend(request, params))) PanicOnError(response) } // // spot, future, swap // // { // "status": "ok", // "ch": "market.btcusdt.depth.step0", // "ts": 1583474832790, // "tick": { // "bids": [ // [ 9100.290000000000000000, 0.200000000000000000 ], // [ 9099.820000000000000000, 0.200000000000000000 ], // [ 9099.610000000000000000, 0.205000000000000000 ], // ], // "asks": [ // [ 9100.640000000000000000, 0.005904000000000000 ], // [ 9101.010000000000000000, 0.287311000000000000 ], // [ 9101.030000000000000000, 0.012121000000000000 ], // ], // "ch":"market.BTC-USD.depth.step0", // "ts":1583474832008, // "id":1637554816, // "mrid":121654491624, // "version":104999698781 // } // } // if IsTrue(InOp(response, "tick")) { if !IsTrue(GetValue(response, "tick")) { panic(BadSymbol(Add(Add(this.Id, " fetchOrderBook() returned empty response: "), this.Json(response)))) } var tick interface{} = this.SafeValue(response, "tick") var timestamp interface{} = this.SafeInteger(tick, "ts", this.SafeInteger(response, "ts")) var result interface{} = this.ParseOrderBook(tick, symbol, timestamp) AddElementToObject(result, "nonce", this.SafeInteger(tick, "version")) ch <- result return nil } panic(ExchangeError(Add(Add(this.Id, " fetchOrderBook() returned unrecognized response: "), this.Json(response)))) }() return ch } func (this *htx) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // spot fetchTrades (public) // // { // "amount": 0.010411000000000000, // "trade-id": 102090736910, // "ts": 1583497692182, // "id": 10500517034273194594947, // "price": 9096.050000000000000000, // "direction": "sell" // } // // spot fetchMyTrades (private) // // { // "symbol": "swftcbtc", // "fee-currency": "swftc", // "filled-fees": "0", // "source": "spot-api", // "id": 83789509854000, // "type": "buy-limit", // "order-id": 83711103204909, // 'filled-points': "0.005826843283532154", // "fee-deduct-currency": "ht", // 'filled-amount': "45941.53", // "price": "0.0000001401", // "created-at": 1597933260729, // "match-id": 100087455560, // "role": "maker", // "trade-id": 100050305348 // } // // linear swap isolated margin fetchOrder details // // { // "trade_id": 131560927, // "trade_price": 13059.800000000000000000, // "trade_volume": 1.000000000000000000, // "trade_turnover": 13.059800000000000000, // "trade_fee": -0.005223920000000000, // "created_at": 1603703614715, // "role": "taker", // "fee_asset": "USDT", // "profit": 0, // "real_profit": 0, // "id": "131560927-770334322963152896-1" // } // // inverse swap cross margin fetchMyTrades // // { // "contract_type":"swap", // "pair":"O3-USDT", // "business_type":"swap", // "query_id":652123190, // "match_id":28306009409, // "order_id":941137865226903553, // "symbol":"O3", // "contract_code":"O3-USDT", // "direction":"sell", // "offset":"open", // "trade_volume":100.000000000000000000, // "trade_price":0.398500000000000000, // "trade_turnover":39.850000000000000000, // "trade_fee":-0.007970000000000000, // "offset_profitloss":0E-18, // "create_date":1644426352999, // "role":"Maker", // "order_source":"api", // "order_id_str":"941137865226903553", // "id":"28306009409-941137865226903553-1", // "fee_asset":"USDT", // "margin_mode":"cross", // "margin_account":"USDT", // "real_profit":0E-18, // "trade_partition":"USDT" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString2(trade, "contract_code", "symbol") market = this.SafeMarket(marketId, market) var symbol interface{} = GetValue(market, "symbol") var timestamp interface{} = this.SafeInteger2(trade, "ts", "created-at") timestamp = this.SafeInteger2(trade, "created_at", "create_date", timestamp) var order interface{} = this.SafeString2(trade, "order-id", "order_id") var side interface{} = this.SafeString(trade, "direction") var typeVar interface{} = this.SafeString(trade, "type") if IsTrue(!IsEqual(typeVar, nil)) { var typeParts interface{} = Split(typeVar, "-") side = GetValue(typeParts, 0) typeVar = GetValue(typeParts, 1) } var takerOrMaker interface{} = this.SafeStringLower(trade, "role") var priceString interface{} = this.SafeString2(trade, "price", "trade_price") var amountString interface{} = this.SafeString2(trade, "filled-amount", "amount") amountString = this.SafeString(trade, "trade_volume", amountString) var costString interface{} = this.SafeString(trade, "trade_turnover") var fee interface{} = nil var feeCost interface{} = this.SafeString(trade, "filled-fees") if IsTrue(IsEqual(feeCost, nil)) { feeCost = Precise.StringNeg(this.SafeString(trade, "trade_fee")) } var feeCurrencyId interface{} = this.SafeString2(trade, "fee-currency", "fee_asset") var feeCurrency interface{} = this.SafeCurrencyCode(feeCurrencyId) var filledPoints interface{} = this.SafeString(trade, "filled-points") if IsTrue(!IsEqual(filledPoints, nil)) { if IsTrue(IsTrue((IsEqual(feeCost, nil))) || IsTrue(Precise.StringEquals(feeCost, "0"))) { var feeDeductCurrency interface{} = this.SafeString(trade, "fee-deduct-currency") if IsTrue(!IsEqual(feeDeductCurrency, nil)) { feeCost = filledPoints feeCurrency = this.SafeCurrencyCode(feeDeductCurrency) } } } if IsTrue(!IsEqual(feeCost, nil)) { fee = map[string]interface{} { "cost": feeCost, "currency": feeCurrency, } } var id interface{} = this.SafeStringN(trade, []interface{}{"trade_id", "trade-id", "id"}) return this.SafeTrade(map[string]interface{} { "id": id, "info": trade, "order": order, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "symbol": symbol, "type": typeVar, "side": side, "takerOrMaker": takerOrMaker, "price": priceString, "amount": amountString, "cost": costString, "fee": fee, }, market) } /** * @method * @name htx#fetchOrderTrades * @description fetch all the trades made from a single order * @see https://huobiapi.github.io/docs/spot/v1/en/#get-the-match-result-of-an-order * @param {string} id order id * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *htx) FetchOrderTrades(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchOrderTrades", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) if IsTrue(!IsEqual(marketType, "spot")) { panic(NotSupported(Add(this.Id, " fetchOrderTrades() is only supported for spot markets"))) } retRes281715 := (<-this.FetchSpotOrderTrades(id, symbol, since, limit, params)) PanicOnError(retRes281715) ch <- retRes281715 return nil }() return ch } /** * @ignore * @method * @name htx#fetchOrderTrades * @description fetch all the trades made from a single order * @see https://huobiapi.github.io/docs/spot/v1/en/#get-the-match-result-of-an-order * @param {string} id order id * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *htx) FetchSpotOrderTrades(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes28348 := (<-this.LoadMarkets()) PanicOnError(retRes28348) var request interface{} = map[string]interface{} { "order-id": id, } response:= (<-this.SpotPrivateGetV1OrderOrdersOrderIdMatchresults(this.Extend(request, params))) PanicOnError(response) ch <- this.ParseTrades(GetValue(response, "data"), nil, since, limit) return nil }() return ch } /** * @method * @name htx#fetchMyTrades * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-match-results-via-multiple-fields-new * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-match-results-via-multiple-fields-new * @see https://huobiapi.github.io/docs/spot/v1/en/#search-match-results * @description fetch all trades made by the user * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch 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 *htx) 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 retRes28588 := (<-this.LoadMarkets()) PanicOnError(retRes28588) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchMyTrades", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes286219 := (<-this.FetchPaginatedCallDynamic("fetchMyTrades", symbol, since, limit, params)) PanicOnError(retRes286219) ch <- retRes286219 return nil } var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchMyTrades", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var request interface{} = map[string]interface{} {} var response interface{} = nil if IsTrue(IsEqual(marketType, "spot")) { if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "symbol", GetValue(market, "id")) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", limit) // default 100, max 500 } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start-time", since) // a date within 120 days from today } requestparamsVariable := this.HandleUntilOption("end-time", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response = (<-this.SpotPrivateGetV1OrderMatchresults(this.Extend(request, params))) PanicOnError(response) } else { if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchMyTrades() requires a symbol argument"))) } AddElementToObject(request, "contract", GetValue(market, "id")) AddElementToObject(request, "trade_type", 0) // 0 all, 1 open long, 2 open short, 3 close short, 4 close long, 5 liquidate long positions, 6 liquidate short positions if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start_time", since) // a date within 120 days from today } requestparamsVariable := this.HandleUntilOption("end_time", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "page_size", limit) // default 100, max 500 } if IsTrue(GetValue(market, "linear")) { var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchMyTrades", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) if IsTrue(IsEqual(marginMode, "isolated")) { response = (<-this.ContractPrivatePostLinearSwapApiV3SwapMatchresultsExact(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(marginMode, "cross")) { response = (<-this.ContractPrivatePostLinearSwapApiV3SwapCrossMatchresultsExact(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "inverse")) { if IsTrue(IsEqual(marketType, "future")) { AddElementToObject(request, "symbol", GetValue(market, "settleId")) response = (<-this.ContractPrivatePostApiV3ContractMatchresultsExact(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(marketType, "swap")) { response = (<-this.ContractPrivatePostSwapApiV3SwapMatchresultsExact(this.Extend(request, params))) PanicOnError(response) } else { panic(NotSupported(Add(Add(Add(this.Id, " fetchMyTrades() does not support "), marketType), " markets"))) } } } // // spot // // { // "status": "ok", // "data": [ // { // "symbol": "polyusdt", // "fee-currency": "poly", // "source": "spot-web", // "price": "0.338", // "created-at": 1629443051839, // "role": "taker", // "order-id": 345487249132375, // "match-id": 5014, // "trade-id": 1085, // "filled-amount": "147.928994082840236", // "filled-fees": "0", // "filled-points": "0.1", // "fee-deduct-currency": "hbpoint", // "fee-deduct-state": "done", // "id": 313288753120940, // "type": "buy-market" // } // ] // } // // contracts // // { // "status": "ok", // "data": { // "trades": [ // { // "query_id": 2424420723, // "match_id": 113891764710, // "order_id": 773135295142658048, // "symbol": "ADA", // "contract_type": "quarter", // swap // "business_type": "futures", // swap // "contract_code": "ADA201225", // "direction": "buy", // "offset": "open", // "trade_volume": 1, // "trade_price": 0.092, // "trade_turnover": 10, // "trade_fee": -0.021739130434782608, // "offset_profitloss": 0, // "create_date": 1604371703183, // "role": "Maker", // "order_source": "web", // "order_id_str": "773135295142658048", // "fee_asset": "ADA", // "margin_mode": "isolated", // cross // "margin_account": "BTC-USDT", // "real_profit": 0, // "id": "113891764710-773135295142658048-1", // "trade_partition":"USDT", // } // ], // "remain_size": 15, // "next_id": 2424413094 // }, // "ts": 1604372202243 // } // var trades interface{} = this.SafeValue(response, "data") if !IsTrue(IsArray(trades)) { trades = this.SafeValue(trades, "trades") } ch <- this.ParseTrades(trades, market, since, limit) return nil }() return ch } /** * @method * @name htx#fetchTrades * @see https://huobiapi.github.io/docs/spot/v1/en/#get-the-most-recent-trades * @see https://huobiapi.github.io/docs/dm/v1/en/#query-a-batch-of-trade-records-of-a-contract * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-a-batch-of-trade-records-of-a-contract * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-a-batch-of-trade-records-of-a-contract * @description get the list of most recent trades for a particular symbol * @param {string} symbol unified symbol of the market to fetch trades for * @param {int} [since] timestamp in ms of the earliest trade to fetch * @param {int} [limit] the maximum amount of trades to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ func (this *htx) 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, 1000) _ = limit params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params retRes30268 := (<-this.LoadMarkets()) PanicOnError(retRes30268) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", mathMin(limit, 2000)) // max 2000 } var response interface{} = nil if IsTrue(GetValue(market, "future")) { if IsTrue(GetValue(market, "inverse")) { AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.ContractPublicGetMarketHistoryTrade(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "linear")) { AddElementToObject(request, "contract_code", GetValue(market, "id")) response = (<-this.ContractPublicGetLinearSwapExMarketHistoryTrade(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "swap")) { AddElementToObject(request, "contract_code", GetValue(market, "id")) if IsTrue(GetValue(market, "inverse")) { response = (<-this.ContractPublicGetSwapExMarketHistoryTrade(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "linear")) { response = (<-this.ContractPublicGetLinearSwapExMarketHistoryTrade(this.Extend(request, params))) PanicOnError(response) } } else { AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.SpotPublicGetMarketHistoryTrade(this.Extend(request, params))) PanicOnError(response) } // // { // "status": "ok", // "ch": "market.btcusdt.trade.detail", // "ts": 1583497692365, // "data": [ // { // "id": 105005170342, // "ts": 1583497692182, // "data": [ // { // "amount": 0.010411000000000000, // "trade-id": 102090736910, // "ts": 1583497692182, // "id": 10500517034273194594947, // "price": 9096.050000000000000000, // "direction": "sell" // } // ] // }, // // ... // ] // } // var data interface{} = this.SafeValue(response, "data", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var trades interface{} = this.SafeValue(GetValue(data, i), "data", []interface{}{}) for j := 0; IsLessThan(j, GetArrayLength(trades)); j++ { var trade interface{} = this.ParseTrade(GetValue(trades, j), market) AppendToArray(&result,trade) } } result = this.SortBy(result, "timestamp") ch <- this.FilterBySymbolSinceLimit(result, GetValue(market, "symbol"), since, limit) return nil }() return ch } func (this *htx) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { // // { // "amount":1.2082, // "open":0.025096, // "close":0.025095, // "high":0.025096, // "id":1591515300, // "count":6, // "low":0.025095, // "vol":0.0303205097 // } // market := GetArg(optionalArgs, 0, nil) _ = market return []interface{}{this.SafeTimestamp(ohlcv, "id"), this.SafeNumber(ohlcv, "open"), this.SafeNumber(ohlcv, "high"), this.SafeNumber(ohlcv, "low"), this.SafeNumber(ohlcv, "close"), this.SafeNumber(ohlcv, "amount")} } /** * @method * @name htx#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://huobiapi.github.io/docs/spot/v1/en/#get-klines-candles * @see https://huobiapi.github.io/docs/dm/v1/en/#get-kline-data * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-kline-data * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-kline-data * @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 {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @param {string} [params.useHistoricalEndpointForSpot] true/false - whether use the historical candles endpoint for spot markets or default klines endpoint * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *htx) 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 retRes31338 := (<-this.LoadMarkets()) PanicOnError(retRes31338) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes313719 := (<-this.FetchPaginatedCallDeterministic("fetchOHLCV", symbol, since, limit, timeframe, params, 1000)) PanicOnError(retRes313719) ch <- retRes313719 return nil } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "period": this.SafeString(this.Timeframes, timeframe, timeframe), } var priceType interface{} = this.SafeStringN(params, []interface{}{"priceType", "price"}) params = this.Omit(params, []interface{}{"priceType", "price"}) var until interface{} = nil untilparamsVariable := this.HandleParamInteger(params, "until"); until = GetValue(untilparamsVariable,0); params = GetValue(untilparamsVariable,1) var untilSeconds interface{} = Ternary(IsTrue((!IsEqual(until, nil))), this.ParseToInt(Divide(until, 1000)), nil) if IsTrue(GetValue(market, "contract")) { if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", mathMin(limit, 2000)) // when using limit: from & to are ignored } else { limit = 2000 // only used for from/to calculation } if IsTrue(IsEqual(priceType, nil)) { var duration interface{} = this.ParseTimeframe(timeframe) var calcualtedEnd interface{} = nil if IsTrue(IsEqual(since, nil)) { var now interface{} = this.Seconds() AddElementToObject(request, "from", Subtract(now, Multiply(duration, (Subtract(limit, 1))))) calcualtedEnd = now } else { var start interface{} = this.ParseToInt(Divide(since, 1000)) AddElementToObject(request, "from", start) calcualtedEnd = this.Sum(start, Multiply(duration, (Subtract(limit, 1)))) } AddElementToObject(request, "to", Ternary(IsTrue((!IsEqual(untilSeconds, nil))), untilSeconds, calcualtedEnd)) } } var response interface{} = nil if IsTrue(GetValue(market, "future")) { if IsTrue(GetValue(market, "inverse")) { AddElementToObject(request, "symbol", GetValue(market, "id")) if IsTrue(IsEqual(priceType, "mark")) { response = (<-this.ContractPublicGetIndexMarketHistoryMarkPriceKline(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(priceType, "index")) { response = (<-this.ContractPublicGetIndexMarketHistoryIndex(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(priceType, "premiumIndex")) { panic(BadRequest(Add(Add(Add(Add(Add(this.Id, " "), GetValue(market, "type")), " has no api endpoint for "), priceType), " kline data"))) } else { response = (<-this.ContractPublicGetMarketHistoryKline(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "linear")) { AddElementToObject(request, "contract_code", GetValue(market, "id")) if IsTrue(IsEqual(priceType, "mark")) { response = (<-this.ContractPublicGetIndexMarketHistoryLinearSwapMarkPriceKline(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(priceType, "index")) { panic(BadRequest(Add(Add(Add(Add(Add(this.Id, " "), GetValue(market, "type")), " has no api endpoint for "), priceType), " kline data"))) } else if IsTrue(IsEqual(priceType, "premiumIndex")) { response = (<-this.ContractPublicGetIndexMarketHistoryLinearSwapPremiumIndexKline(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPublicGetLinearSwapExMarketHistoryKline(this.Extend(request, params))) PanicOnError(response) } } } else if IsTrue(GetValue(market, "swap")) { AddElementToObject(request, "contract_code", GetValue(market, "id")) if IsTrue(GetValue(market, "inverse")) { if IsTrue(IsEqual(priceType, "mark")) { response = (<-this.ContractPublicGetIndexMarketHistorySwapMarkPriceKline(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(priceType, "index")) { panic(BadRequest(Add(Add(Add(Add(Add(this.Id, " "), GetValue(market, "type")), " has no api endpoint for "), priceType), " kline data"))) } else if IsTrue(IsEqual(priceType, "premiumIndex")) { response = (<-this.ContractPublicGetIndexMarketHistorySwapPremiumIndexKline(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPublicGetSwapExMarketHistoryKline(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "linear")) { if IsTrue(IsEqual(priceType, "mark")) { response = (<-this.ContractPublicGetIndexMarketHistoryLinearSwapMarkPriceKline(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(priceType, "index")) { panic(BadRequest(Add(Add(Add(Add(Add(this.Id, " "), GetValue(market, "type")), " has no api endpoint for "), priceType), " kline data"))) } else if IsTrue(IsEqual(priceType, "premiumIndex")) { response = (<-this.ContractPublicGetIndexMarketHistoryLinearSwapPremiumIndexKline(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPublicGetLinearSwapExMarketHistoryKline(this.Extend(request, params))) PanicOnError(response) } } } else { AddElementToObject(request, "symbol", GetValue(market, "id")) var useHistorical interface{} = nil useHistoricalparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "useHistoricalEndpointForSpot", true); useHistorical = GetValue(useHistoricalparamsVariable,0); params = GetValue(useHistoricalparamsVariable,1) if !IsTrue(useHistorical) { if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", mathMin(limit, 2000)) // max 2000 } response = (<-this.SpotPublicGetMarketHistoryKline(this.Extend(request, params))) PanicOnError(response) } else { // "from & to" only available for the this endpoint if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "from", this.ParseToInt(Divide(since, 1000))) } if IsTrue(!IsEqual(untilSeconds, nil)) { AddElementToObject(request, "to", untilSeconds) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", mathMin(1000, limit)) // max 1000, otherwise default returns 150 } response = (<-this.SpotPublicGetMarketHistoryCandles(this.Extend(request, params))) PanicOnError(response) } } // // { // "status":"ok", // "ch":"market.ethbtc.kline.1min", // "ts":1591515374371, // "data":[ // {"amount":0.0,"open":0.025095,"close":0.025095,"high":0.025095,"id":1591515360,"count":0,"low":0.025095,"vol":0.0}, // {"amount":1.2082,"open":0.025096,"close":0.025095,"high":0.025096,"id":1591515300,"count":6,"low":0.025095,"vol":0.0303205097}, // {"amount":0.0648,"open":0.025096,"close":0.025096,"high":0.025096,"id":1591515240,"count":2,"low":0.025096,"vol":0.0016262208}, // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOHLCVs(data, market, timeframe, since, limit) return nil }() return ch } /** * @method * @name htx#fetchAccounts * @description fetch all the accounts associated with a profile * @see https://huobiapi.github.io/docs/spot/v1/en/#get-all-accounts-of-the-current-user * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type */ func (this *htx) FetchAccounts(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes32718 := (<-this.LoadMarkets()) PanicOnError(retRes32718) response:= (<-this.SpotPrivateGetV1AccountAccounts(params)) PanicOnError(response) // // { // "status":"ok", // "data":[ // {"id":5202591,"type":"point","subtype":"","state":"working"}, // {"id":1528640,"type":"spot","subtype":"","state":"working"}, // ] // } // var data interface{} = this.SafeValue(response, "data") ch <- this.ParseAccounts(data) return nil }() return ch } func (this *htx) ParseAccount(account interface{}) interface{} { // // { // "id": 5202591, // "type": "point", // spot, margin, otc, point, super-margin, investment, borrow, grid-trading, deposit-earning, otc-options // "subtype": "", // The corresponding trading symbol (currency pair) the isolated margin is based on, e.g. btcusdt // "state": "working" // working, lock // } // var typeId interface{} = this.SafeString(account, "type") var accountsById interface{} = this.SafeValue(this.Options, "accountsById", map[string]interface{} {}) var typeVar interface{} = this.SafeValue(accountsById, typeId, typeId) return map[string]interface{} { "info": account, "id": this.SafeString(account, "id"), "type": typeVar, "code": nil, } } /** * @method * @name htx#fetchAccountIdByType * @description fetch all the accounts by a type and marginModeassociated with a profile * @see https://huobiapi.github.io/docs/spot/v1/en/#get-all-accounts-of-the-current-user * @param {string} type 'spot', 'swap' or 'future * @param {string} [marginMode] 'cross' or 'isolated' * @param {string} [symbol] unified ccxt market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type */ func (this *htx) FetchAccountIdByType(typeVar interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) marginMode := GetArg(optionalArgs, 0, nil) _ = marginMode symbol := GetArg(optionalArgs, 1, nil) _ = symbol params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params accounts:= (<-this.LoadAccounts()) PanicOnError(accounts) var accountId interface{} = this.SafeValue2(params, "accountId", "account-id") if IsTrue(!IsEqual(accountId, nil)) { ch <- accountId return nil } if IsTrue(IsEqual(typeVar, "spot")) { if IsTrue(IsEqual(marginMode, "cross")) { typeVar = "super-margin" } else if IsTrue(IsEqual(marginMode, "isolated")) { typeVar = "margin" } } var marketId interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { marketId = this.MarketId(symbol) } for i := 0; IsLessThan(i, GetArrayLength(accounts)); i++ { var account interface{} = GetValue(accounts, i) var info interface{} = this.SafeValue(account, "info") var subtype interface{} = this.SafeString(info, "subtype", nil) var typeFromAccount interface{} = this.SafeString(account, "type") if IsTrue(IsEqual(typeVar, "margin")) { if IsTrue(IsEqual(subtype, marketId)) { ch <- this.SafeString(account, "id") return nil } } else if IsTrue(IsEqual(typeVar, typeFromAccount)) { ch <- this.SafeString(account, "id") return nil } } var defaultAccount interface{} = this.SafeValue(accounts, 0, map[string]interface{} {}) ch <- this.SafeString(defaultAccount, "id") return nil }() return ch } /** * @method * @name htx#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://huobiapi.github.io/docs/spot/v1/en/#apiv2-currency-amp-chains * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ func (this *htx) FetchCurrencies(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params response:= (<-this.SpotPublicGetV2ReferenceCurrencies(params)) PanicOnError(response) // // { // "code": 200, // "data": [ // { // "currency": "sxp", // "assetType": "1", // "chains": [ // { // "chain": "sxp", // "displayName": "ERC20", // "baseChain": "ETH", // "baseChainProtocol": "ERC20", // "isDynamic": true, // "numOfConfirmations": "12", // "numOfFastConfirmations": "12", // "depositStatus": "allowed", // "minDepositAmt": "0.23", // "withdrawStatus": "allowed", // "minWithdrawAmt": "0.23", // "withdrawPrecision": "8", // "maxWithdrawAmt": "227000.000000000000000000", // "withdrawQuotaPerDay": "227000.000000000000000000", // "withdrawQuotaPerYear": null, // "withdrawQuotaTotal": null, // "withdrawFeeType": "fixed", // "transactFeeWithdraw": "11.1653", // "addrWithTag": false, // "addrDepositTag": false // } // ], // "instStatus": "normal" // } // ] // } // } // var data interface{} = this.SafeValue(response, "data", []interface{}{}) var result interface{} = map[string]interface{} {} AddElementToObject(this.Options, "networkChainIdsByNames", map[string]interface{} {}) AddElementToObject(this.Options, "networkNamesByChainIds", map[string]interface{} {}) for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var entry interface{} = GetValue(data, i) var currencyId interface{} = this.SafeString(entry, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) AddElementToObject(GetValue(this.Options, "networkChainIdsByNames"), code, map[string]interface{} {}) var chains interface{} = this.SafeValue(entry, "chains", []interface{}{}) var networks interface{} = map[string]interface{} {} var instStatus interface{} = this.SafeString(entry, "instStatus") var currencyActive interface{} = IsEqual(instStatus, "normal") var minPrecision interface{} = nil var minDeposit interface{} = nil var minWithdraw interface{} = nil var maxWithdraw interface{} = nil var deposit interface{} = false var withdraw interface{} = false for j := 0; IsLessThan(j, GetArrayLength(chains)); j++ { var chainEntry interface{} = GetValue(chains, j) var uniqueChainId interface{} = this.SafeString(chainEntry, "chain") // i.e. usdterc20, trc20usdt ... var title interface{} = this.SafeString2(chainEntry, "baseChain", "displayName") // baseChain and baseChainProtocol are together existent or inexistent in entries, but baseChain is preferred. when they are both inexistent, then we use generic displayName AddElementToObject(GetValue(GetValue(this.Options, "networkChainIdsByNames"), code), title, uniqueChainId) AddElementToObject(GetValue(this.Options, "networkNamesByChainIds"), uniqueChainId, title) var networkCode interface{} = this.NetworkIdToCode(uniqueChainId) minDeposit = this.SafeNumber(chainEntry, "minDepositAmt") minWithdraw = this.SafeNumber(chainEntry, "minWithdrawAmt") maxWithdraw = this.SafeNumber(chainEntry, "maxWithdrawAmt") var withdrawStatus interface{} = this.SafeString(chainEntry, "withdrawStatus") var depositStatus interface{} = this.SafeString(chainEntry, "depositStatus") var withdrawEnabled interface{} = (IsEqual(withdrawStatus, "allowed")) var depositEnabled interface{} = (IsEqual(depositStatus, "allowed")) withdraw = Ternary(IsTrue((withdrawEnabled)), withdrawEnabled, withdraw) deposit = Ternary(IsTrue((depositEnabled)), depositEnabled, deposit) var active interface{} = IsTrue(withdrawEnabled) && IsTrue(depositEnabled) var precision interface{} = this.ParsePrecision(this.SafeString(chainEntry, "withdrawPrecision")) if IsTrue(!IsEqual(precision, nil)) { minPrecision = Ternary(IsTrue((IsEqual(minPrecision, nil))), precision, Precise.StringMin(precision, minPrecision)) } var fee interface{} = this.SafeNumber(chainEntry, "transactFeeWithdraw") AddElementToObject(networks, networkCode, map[string]interface{} { "info": chainEntry, "id": uniqueChainId, "network": networkCode, "limits": map[string]interface{} { "deposit": map[string]interface{} { "min": minDeposit, "max": nil, }, "withdraw": map[string]interface{} { "min": minWithdraw, "max": maxWithdraw, }, }, "active": active, "deposit": depositEnabled, "withdraw": withdrawEnabled, "fee": fee, "precision": this.ParseNumber(precision), }) } AddElementToObject(result, code, map[string]interface{} { "info": entry, "code": code, "id": currencyId, "active": currencyActive, "deposit": deposit, "withdraw": withdraw, "fee": nil, "name": nil, "limits": map[string]interface{} { "amount": map[string]interface{} { "min": nil, "max": nil, }, "withdraw": map[string]interface{} { "min": minWithdraw, "max": maxWithdraw, }, "deposit": map[string]interface{} { "min": nil, "max": nil, }, }, "precision": this.ParseNumber(minPrecision), "networks": networks, }) } ch <- result return nil }() return ch } func (this *htx) NetworkIdToCode(optionalArgs ...interface{}) interface{} { // here network-id is provided as a pair of currency & chain (i.e. trc20usdt) networkId := GetArg(optionalArgs, 0, nil) _ = networkId currencyCode := GetArg(optionalArgs, 1, nil) _ = currencyCode var keys interface{} = ObjectKeys(GetValue(this.Options, "networkNamesByChainIds")) var keysLength interface{} = GetArrayLength(keys) if IsTrue(IsEqual(keysLength, 0)) { panic(ExchangeError(Add(this.Id, " networkIdToCode() - markets need to be loaded at first"))) } var networkTitle interface{} = this.SafeValue(GetValue(this.Options, "networkNamesByChainIds"), networkId, networkId) return this.Exchange.NetworkIdToCode(networkTitle) } func (this *htx) NetworkCodeToId(networkCode interface{}, optionalArgs ...interface{}) interface{} { currencyCode := GetArg(optionalArgs, 0, nil) _ = currencyCode if IsTrue(IsEqual(currencyCode, nil)) { panic(ArgumentsRequired(Add(this.Id, " networkCodeToId() requires a currencyCode argument"))) } var keys interface{} = ObjectKeys(GetValue(this.Options, "networkChainIdsByNames")) var keysLength interface{} = GetArrayLength(keys) if IsTrue(IsEqual(keysLength, 0)) { panic(ExchangeError(Add(this.Id, " networkCodeToId() - markets need to be loaded at first"))) } var uniqueNetworkIds interface{} = this.SafeValue(GetValue(this.Options, "networkChainIdsByNames"), currencyCode, map[string]interface{} {}) if IsTrue(InOp(uniqueNetworkIds, networkCode)) { return GetValue(uniqueNetworkIds, networkCode) } else { var networkTitle interface{} = this.Exchange.NetworkCodeToId(networkCode) return this.SafeValue(uniqueNetworkIds, networkTitle, networkTitle) } } /** * @method * @name htx#fetchBalance * @see https://huobiapi.github.io/docs/spot/v1/en/#get-account-balance-of-a-specific-account * @see https://www.htx.com/en-us/opend/newApiPages/?id=7ec4b429-7773-11ed-9966-0242ac110003 * @see https://www.htx.com/en-us/opend/newApiPages/?id=10000074-77b7-11ed-9966-0242ac110003 * @see https://huobiapi.github.io/docs/dm/v1/en/#query-asset-valuation * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-user-s-account-information * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-query-user-s-account-information * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-query-user-39-s-account-information * @description query for balance and get the amount of funds available for trading or funds locked in orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {bool} [params.unified] provide this parameter if you have a recent account with unified cross+isolated margin account * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure} */ func (this *htx) 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 retRes35358 := (<-this.LoadMarkets()) PanicOnError(retRes35358) var typeVar interface{} = nil typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchBalance", nil, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) var options interface{} = this.SafeValue(this.Options, "fetchBalance", map[string]interface{} {}) var isUnifiedAccount interface{} = this.SafeValue2(params, "isUnifiedAccount", "unified", false) params = this.Omit(params, []interface{}{"isUnifiedAccount", "unified"}) var request interface{} = map[string]interface{} {} var spot interface{} = (IsEqual(typeVar, "spot")) var future interface{} = (IsEqual(typeVar, "future")) var defaultSubType interface{} = this.SafeString2(this.Options, "defaultSubType", "subType", "linear") var subType interface{} = this.SafeString2(options, "defaultSubType", "subType", defaultSubType) subType = this.SafeString2(params, "defaultSubType", "subType", subType) var inverse interface{} = (IsEqual(subType, "inverse")) var linear interface{} = (IsEqual(subType, "linear")) var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchBalance", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) params = this.Omit(params, []interface{}{"defaultSubType", "subType"}) var isolated interface{} = (IsEqual(marginMode, "isolated")) var cross interface{} = (IsEqual(marginMode, "cross")) var margin interface{} = IsTrue((IsEqual(typeVar, "margin"))) || IsTrue((IsTrue(spot) && IsTrue((IsTrue(cross) || IsTrue(isolated))))) var response interface{} = nil if IsTrue(IsTrue(spot) || IsTrue(margin)) { if IsTrue(margin) { if IsTrue(isolated) { response = (<-this.SpotPrivateGetV1MarginAccountsBalance(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.SpotPrivateGetV1CrossMarginAccountsBalance(this.Extend(request, params))) PanicOnError(response) } } else { retRes356416 := (<-this.LoadAccounts()) PanicOnError(retRes356416) accountId:= (<-this.FetchAccountIdByType(typeVar, nil, nil, params)) PanicOnError(accountId) AddElementToObject(request, "account-id", accountId) response = (<-this.SpotPrivateGetV1AccountAccountsAccountIdBalance(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(isUnifiedAccount) { response = (<-this.ContractPrivateGetLinearSwapApiV3UnifiedAccountInfo(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(linear) { if IsTrue(isolated) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapAccountInfo(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossAccountInfo(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(inverse) { if IsTrue(future) { response = (<-this.ContractPrivatePostApiV1ContractAccountInfo(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostSwapApiV1SwapAccountInfo(this.Extend(request, params))) PanicOnError(response) } } // // spot // // { // "status": "ok", // "data": { // "id": 1528640, // "type": "spot", // "state": "working", // "list": [ // { "currency": "lun", "type": "trade", "balance": "0", "seq-num": "0" }, // { "currency": "lun", "type": "frozen", "balance": "0", "seq-num": "0" }, // { "currency": "ht", "type": "frozen", "balance": "0", "seq-num": "145" }, // ] // }, // "ts":1637644827566 // } // // cross margin // // { // "status": "ok", // "data": { // "id": 51015302, // "type": "cross-margin", // "state": "working", // "risk-rate": "2", // "acct-balance-sum": "100", // "debt-balance-sum": "0", // "list": [ // { "currency": "usdt", "type": "trade", "balance": "100" }, // { "currency": "usdt", "type": "frozen", "balance": "0" }, // { "currency": "usdt", "type": "loan-available", "balance": "200" }, // { "currency": "usdt", "type": "transfer-out-available", "balance": "-1" }, // { "currency": "ht", "type": "loan-available", "balance": "36.60724091" }, // { "currency": "ht", "type": "transfer-out-available", "balance": "-1" }, // { "currency": "btc", "type": "trade", "balance": "1168.533000000000000000" }, // { "currency": "btc", "type": "frozen", "balance": "0.000000000000000000" }, // { "currency": "btc", "type": "loan", "balance": "-2.433000000000000000" }, // { "currency": "btc", "type": "interest", "balance": "-0.000533000000000000" }, // { "currency": "btc", "type": "transfer-out-available", "balance": "1163.872174670000000000" }, // { "currency": "btc", "type": "loan-available", "balance": "8161.876538350676000000" } // ] // }, // "code": 200 // } // // isolated margin // // { // "data": [ // { // "id": 18264, // "type": "margin", // "state": "working", // "symbol": "btcusdt", // "fl-price": "0", // "fl-type": "safe", // "risk-rate": "475.952571086994250554", // "list": [ // { "currency": "btc","type": "trade","balance": "1168.533000000000000000" }, // { "currency": "btc","type": "frozen","balance": "0.000000000000000000" }, // { "currency": "btc","type": "loan","balance": "-2.433000000000000000" }, // { "currency": "btc","type": "interest","balance": "-0.000533000000000000" }, // { "currency": "btc","type": "transfer-out-available", "balance": "1163.872174670000000000" }, // { "currency": "btc","type": "loan-available", "balance": "8161.876538350676000000" } // ] // } // ] // } // // future, swap isolated // // { // "status": "ok", // "data": [ // { // "symbol": "BTC", // "margin_balance": 0, // "margin_position": 0E-18, // "margin_frozen": 0, // "margin_available": 0E-18, // "profit_real": 0, // "profit_unreal": 0, // "risk_rate": null, // "withdraw_available": 0, // "liquidation_price": null, // "lever_rate": 5, // "adjust_factor": 0.025000000000000000, // "margin_static": 0, // "is_debit": 0, // future only // "contract_code": "BTC-USD", // swap only // "margin_asset": "USDT", // linear only // "margin_mode": "isolated", // linear only // "margin_account": "BTC-USDT" // linear only // "transfer_profit_ratio": null // inverse only // }, // ], // "ts": 1637644827566 // } // // linear cross futures and linear cross swap // // { // "status": "ok", // "data": [ // { // "futures_contract_detail": [ // { // "symbol": "ETH", // "contract_code": "ETH-USDT-220325", // "margin_position": 0, // "margin_frozen": 0, // "margin_available": 200.000000000000000000, // "profit_unreal": 0E-18, // "liquidation_price": null, // "lever_rate": 5, // "adjust_factor": 0.060000000000000000, // "contract_type": "quarter", // "pair": "ETH-USDT", // "business_type": "futures" // }, // ], // "margin_mode": "cross", // "margin_account": "USDT", // "margin_asset": "USDT", // "margin_balance": 49.874186030200000000, // "money_in": 50, // "money_out": 0, // "margin_static": 49.872786030200000000, // "margin_position": 6.180000000000000000, // "margin_frozen": 6.000000000000000000, // "profit_unreal": 0.001400000000000000, // "withdraw_available": 37.6927860302, // "risk_rate": 271.984050521072796934, // "new_risk_rate": 0.001858676950514399, // "contract_detail": [ // { // "symbol": "MANA", // "contract_code": "MANA-USDT", // "margin_position": 0, // "margin_frozen": 0, // "margin_available": 200.000000000000000000, // "profit_unreal": 0E-18, // "liquidation_price": null, // "lever_rate": 5, // "adjust_factor": 0.100000000000000000, // "contract_type": "swap", // "pair": "MANA-USDT", // "business_type": "swap" // }, // ] // } // ], // "ts": 1640915104870 // } // // TODO add balance parsing for linear swap // var result interface{} = map[string]interface{} { "info": response, } var data interface{} = this.SafeValue(response, "data") if IsTrue(IsTrue(spot) || IsTrue(margin)) { if IsTrue(isolated) { for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var entry interface{} = GetValue(data, i) var symbol interface{} = this.SafeSymbol(this.SafeString(entry, "symbol")) var balances interface{} = this.SafeValue(entry, "list") var subResult interface{} = map[string]interface{} {} for j := 0; IsLessThan(j, GetArrayLength(balances)); j++ { var balance interface{} = GetValue(balances, j) var currencyId interface{} = this.SafeString(balance, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) AddElementToObject(subResult, code, this.ParseMarginBalanceHelper(balance, code, subResult)) } AddElementToObject(result, symbol, this.SafeBalance(subResult)) } } else { var balances interface{} = this.SafeValue(data, "list", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(balances)); i++ { var balance interface{} = GetValue(balances, i) var currencyId interface{} = this.SafeString(balance, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) AddElementToObject(result, code, this.ParseMarginBalanceHelper(balance, code, result)) } result = this.SafeBalance(result) } } else if IsTrue(isUnifiedAccount) { for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var entry interface{} = GetValue(data, i) var marginAsset interface{} = this.SafeString(entry, "margin_asset") var currencyCode interface{} = this.SafeCurrencyCode(marginAsset) if IsTrue(isolated) { var isolated_swap interface{} = this.SafeValue(entry, "isolated_swap", map[string]interface{} {}) for j := 0; IsLessThan(j, GetArrayLength(isolated_swap)); j++ { var balance interface{} = GetValue(isolated_swap, j) var marketId interface{} = this.SafeString(balance, "contract_code") var subBalance interface{} = map[string]interface{} { "code": currencyCode, "free": this.SafeNumber(balance, "margin_available"), } var symbol interface{} = this.SafeSymbol(marketId) AddElementToObject(result, symbol, subBalance) result = this.SafeBalance(result) } } else { var account interface{} = this.Account() AddElementToObject(account, "free", this.SafeString(entry, "margin_static")) AddElementToObject(account, "used", this.SafeString(entry, "margin_frozen")) AddElementToObject(result, currencyCode, account) result = this.SafeBalance(result) } } } else if IsTrue(linear) { var first interface{} = this.SafeValue(data, 0, map[string]interface{} {}) if IsTrue(isolated) { for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var balance interface{} = GetValue(data, i) var marketId interface{} = this.SafeString2(balance, "contract_code", "margin_account") var market interface{} = this.SafeMarket(marketId) var currencyId interface{} = this.SafeString(balance, "margin_asset") var currency interface{} = this.SafeCurrency(currencyId) var code interface{} = this.SafeString(market, "settle", GetValue(currency, "code")) // the exchange outputs positions for delisted markets // https://www.huobi.com/support/en-us/detail/74882968522337 // we skip it if the market was delisted if IsTrue(!IsEqual(code, nil)) { var account interface{} = this.Account() AddElementToObject(account, "free", this.SafeString(balance, "margin_balance")) AddElementToObject(account, "used", this.SafeString(balance, "margin_frozen")) var accountsByCode interface{} = map[string]interface{} {} AddElementToObject(accountsByCode, code, account) var symbol interface{} = GetValue(market, "symbol") AddElementToObject(result, symbol, this.SafeBalance(accountsByCode)) } } } else { var account interface{} = this.Account() AddElementToObject(account, "free", this.SafeString(first, "withdraw_available")) AddElementToObject(account, "total", this.SafeString(first, "margin_balance")) var currencyId interface{} = this.SafeString2(first, "margin_asset", "symbol") var code interface{} = this.SafeCurrencyCode(currencyId) AddElementToObject(result, code, account) result = this.SafeBalance(result) } } else if IsTrue(inverse) { for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var balance interface{} = GetValue(data, i) var currencyId interface{} = this.SafeString(balance, "symbol") var code interface{} = this.SafeCurrencyCode(currencyId) var account interface{} = this.Account() AddElementToObject(account, "free", this.SafeString(balance, "margin_available")) AddElementToObject(account, "used", this.SafeString(balance, "margin_frozen")) AddElementToObject(result, code, account) } result = this.SafeBalance(result) } ch <- result return nil }() return ch } /** * @method * @name htx#fetchOrder * @description fetches information on an order made by the user * @see https://huobiapi.github.io/docs/spot/v1/en/#get-the-order-detail-of-an-order-based-on-client-order-id * @see https://huobiapi.github.io/docs/spot/v1/en/#get-the-order-detail-of-an-order * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-information-of-an-order * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-information-of-order * @see https://huobiapi.github.io/docs/dm/v1/en/#get-information-of-an-order * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-information-of-an-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 * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *htx) FetchOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes38598 := (<-this.LoadMarkets()) PanicOnError(retRes38598) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchOrder", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var request interface{} = map[string]interface{} {} var response interface{} = nil if IsTrue(IsEqual(marketType, "spot")) { var clientOrderId interface{} = this.SafeString(params, "clientOrderId") if IsTrue(!IsEqual(clientOrderId, nil)) { // will be filled below in extend () // they expect clientOrderId instead of client-order-id // request['clientOrderId'] = clientOrderId; response = (<-this.SpotPrivateGetV1OrderOrdersGetClientOrder(this.Extend(request, params))) PanicOnError(response) } else { AddElementToObject(request, "order-id", id) response = (<-this.SpotPrivateGetV1OrderOrdersOrderId(this.Extend(request, params))) PanicOnError(response) } } else { if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOrder() requires a symbol argument"))) } var clientOrderId interface{} = this.SafeString2(params, "client_order_id", "clientOrderId") if IsTrue(IsEqual(clientOrderId, nil)) { AddElementToObject(request, "order_id", id) } else { AddElementToObject(request, "client_order_id", clientOrderId) params = this.Omit(params, []interface{}{"client_order_id", "clientOrderId"}) } AddElementToObject(request, "contract_code", GetValue(market, "id")) if IsTrue(GetValue(market, "linear")) { var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchOrder", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) if IsTrue(IsEqual(marginMode, "isolated")) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapOrderInfo(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(marginMode, "cross")) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossOrderInfo(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "inverse")) { if IsTrue(IsEqual(marketType, "future")) { AddElementToObject(request, "symbol", GetValue(market, "settleId")) response = (<-this.ContractPrivatePostApiV1ContractOrderInfo(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(marketType, "swap")) { response = (<-this.ContractPrivatePostSwapApiV1SwapOrderInfo(this.Extend(request, params))) PanicOnError(response) } else { panic(NotSupported(Add(Add(Add(this.Id, " fetchOrder() does not support "), marketType), " markets"))) } } } // // spot // // { // "status":"ok", // "data":{ // "id":438398393065481, // "symbol":"ethusdt", // "account-id":1528640, // "client-order-id":"AA03022abc2163433e-006b-480e-9ad1-d4781478c5e7", // "amount":"0.100000000000000000", // "price":"3000.000000000000000000", // "created-at":1640549994642, // "type":"buy-limit", // "field-amount":"0.0", // "field-cash-amount":"0.0", // "field-fees":"0.0", // "finished-at":0, // "source":"spot-api", // "state":"submitted", // "canceled-at":0 // } // } // // linear swap cross margin // // { // "status":"ok", // "data":[ // { // "business_type":"swap", // "contract_type":"swap", // "pair":"BTC-USDT", // "symbol":"BTC", // "contract_code":"BTC-USDT", // "volume":1, // "price":3000, // "order_price_type":"limit", // "order_type":1, // "direction":"buy", // "offset":"open", // "lever_rate":1, // "order_id":924912513206878210, // "client_order_id":null, // "created_at":1640557927189, // "trade_volume":0, // "trade_turnover":0, // "fee":0, // "trade_avg_price":null, // "margin_frozen":3.000000000000000000, // "profit":0, // "status":3, // "order_source":"api", // "order_id_str":"924912513206878210", // "fee_asset":"USDT", // "liquidation_type":"0", // "canceled_at":0, // "margin_asset":"USDT", // "margin_account":"USDT", // "margin_mode":"cross", // "is_tpsl":0, // "real_profit":0 // } // ], // "ts":1640557982556 // } // // linear swap isolated margin detail // // { // "status": "ok", // "data": { // "symbol": "BTC", // "contract_code": "BTC-USDT", // "instrument_price": 0, // "final_interest": 0, // "adjust_value": 0, // "lever_rate": 10, // "direction": "sell", // "offset": "open", // "volume": 1.000000000000000000, // "price": 13059.800000000000000000, // "created_at": 1603703614712, // "canceled_at": 0, // "order_source": "api", // "order_price_type": "opponent", // "margin_frozen": 0, // "profit": 0, // "trades": [ // { // "trade_id": 131560927, // "trade_price": 13059.800000000000000000, // "trade_volume": 1.000000000000000000, // "trade_turnover": 13.059800000000000000, // "trade_fee": -0.005223920000000000, // "created_at": 1603703614715, // "role": "taker", // "fee_asset": "USDT", // "profit": 0, // "real_profit": 0, // "id": "131560927-770334322963152896-1" // } // ], // "total_page": 1, // "current_page": 1, // "total_size": 1, // "liquidation_type": "0", // "fee_asset": "USDT", // "fee": -0.005223920000000000, // "order_id": 770334322963152896, // "order_id_str": "770334322963152896", // "client_order_id": 57012021045, // "order_type": "1", // "status": 6, // "trade_avg_price": 13059.800000000000000000, // "trade_turnover": 13.059800000000000000, // "trade_volume": 1.000000000000000000, // "margin_asset": "USDT", // "margin_mode": "isolated", // "margin_account": "BTC-USDT", // "real_profit": 0, // "is_tpsl": 0 // }, // "ts": 1603703678477 // } var order interface{} = this.SafeValue(response, "data") if IsTrue(IsArray(order)) { order = this.SafeValue(order, 0) } ch <- this.ParseOrder(order) return nil }() return ch } func (this *htx) ParseMarginBalanceHelper(balance interface{}, code interface{}, result interface{}) interface{} { var account interface{} = nil if IsTrue(InOp(result, code)) { account = GetValue(result, code) } else { account = this.Account() } if IsTrue(IsEqual(GetValue(balance, "type"), "trade")) { AddElementToObject(account, "free", this.SafeString(balance, "balance")) } if IsTrue(IsEqual(GetValue(balance, "type"), "frozen")) { AddElementToObject(account, "used", this.SafeString(balance, "balance")) } return account } func (this *htx) FetchSpotOrdersByStates(states interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params var method interface{} = this.SafeString(this.Options, "fetchOrdersByStatesMethod", "spot_private_get_v1_order_orders") // spot_private_get_v1_order_history if IsTrue(IsEqual(method, "spot_private_get_v1_order_orders")) { if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOrders() requires a symbol argument"))) } } retRes40788 := (<-this.LoadMarkets()) PanicOnError(retRes40788) var market interface{} = nil var request interface{} = map[string]interface{} { "states": states, } if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "symbol", GetValue(market, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start-time", since) // a window of 48 hours within 180 days AddElementToObject(request, "end-time", this.Sum(since, Multiply(Multiply(Multiply(48, 60), 60), 1000))) } requestparamsVariable := this.HandleUntilOption("end-time", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", limit) } var response interface{} = nil if IsTrue(IsEqual(method, "spot_private_get_v1_order_orders")) { response = (<-this.SpotPrivateGetV1OrderOrders(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.SpotPrivateGetV1OrderHistory(this.Extend(request, params))) PanicOnError(response) } // // spot_private_get_v1_order_orders GET /v1/order/orders // // { // "status": "ok", // "data": [ // { // "id": 13997833014, // "symbol": "ethbtc", // "account-id": 3398321, // "client-order-id": "23456", // "amount": "0.045000000000000000", // "price": "0.034014000000000000", // "created-at": 1545836976871, // "type": "sell-limit", // "field-amount": "0.045000000000000000", // "field-cash-amount": "0.001530630000000000", // "field-fees": "0.000003061260000000", // "finished-at": 1545837948214, // "source": "spot-api", // "state": "filled", // "canceled-at": 0 // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(data, market, since, limit) return nil }() return ch } func (this *htx) FetchSpotOrders(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 retRes414615 := (<-this.FetchSpotOrdersByStates("pre-submitted,submitted,partial-filled,filled,partial-canceled,canceled", symbol, since, limit, params)) PanicOnError(retRes414615) ch <- retRes414615 return nil }() return ch } func (this *htx) FetchClosedSpotOrders(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 retRes415015 := (<-this.FetchSpotOrdersByStates("filled,partial-canceled,canceled", symbol, since, limit, params)) PanicOnError(retRes415015) ch <- retRes415015 return nil }() return ch } func (this *htx) FetchContractOrders(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, " fetchContractOrders() requires a symbol argument"))) } retRes41578 := (<-this.LoadMarkets()) PanicOnError(retRes41578) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "trade_type": 0, "status": "0", } var response interface{} = nil var trigger interface{} = this.SafeBool2(params, "stop", "trigger") var stopLossTakeProfit interface{} = this.SafeValue(params, "stopLossTakeProfit") var trailing interface{} = this.SafeBool(params, "trailing", false) params = this.Omit(params, []interface{}{"stop", "stopLossTakeProfit", "trailing", "trigger"}) if IsTrue(IsTrue(IsTrue(trigger) || IsTrue(stopLossTakeProfit)) || IsTrue(trailing)) { if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "page_size", limit) } AddElementToObject(request, "contract_code", GetValue(market, "id")) AddElementToObject(request, "create_date", 90) } else { if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start_time", since) // max 90 days back } AddElementToObject(request, "contract", GetValue(market, "id")) AddElementToObject(request, "type", 1) // 1:All Orders,2:Order in Finished Status } requestparamsVariable := this.HandleUntilOption("end_time", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) if IsTrue(GetValue(market, "linear")) { var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchContractOrders", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) if IsTrue(IsEqual(marginMode, "isolated")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTriggerHisorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTpslHisorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTrackHisorders(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV3SwapHisorders(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(IsEqual(marginMode, "cross")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTriggerHisorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTpslHisorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTrackHisorders(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV3SwapCrossHisorders(this.Extend(request, params))) PanicOnError(response) } } } else if IsTrue(GetValue(market, "inverse")) { if IsTrue(GetValue(market, "swap")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostSwapApiV1SwapTriggerHisorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostSwapApiV1SwapTpslHisorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostSwapApiV1SwapTrackHisorders(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostSwapApiV3SwapHisorders(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "future")) { AddElementToObject(request, "symbol", GetValue(market, "settleId")) if IsTrue(trigger) { response = (<-this.ContractPrivatePostApiV1ContractTriggerHisorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostApiV1ContractTpslHisorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostApiV1ContractTrackHisorders(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostApiV3ContractHisorders(this.Extend(request, params))) PanicOnError(response) } } } // // future and swap // // { // "code": 200, // "msg": "ok", // "data": [ // { // "direction": "buy", // "offset": "open", // "volume": 1.000000000000000000, // "price": 25000.000000000000000000, // "profit": 0E-18, // "pair": "BTC-USDT", // "query_id": 47403349100, // "order_id": 1103683465337593856, // "contract_code": "BTC-USDT-230505", // "symbol": "BTC", // "lever_rate": 5, // "create_date": 1683180243577, // "order_source": "web", // "canceled_source": "web", // "order_price_type": 1, // "order_type": 1, // "margin_frozen": 0E-18, // "trade_volume": 0E-18, // "trade_turnover": 0E-18, // "fee": 0E-18, // "trade_avg_price": 0, // "status": 7, // "order_id_str": "1103683465337593856", // "fee_asset": "USDT", // "fee_amount": 0, // "fee_quote_amount": 0, // "liquidation_type": "0", // "margin_asset": "USDT", // "margin_mode": "cross", // "margin_account": "USDT", // "update_time": 1683180352034, // "is_tpsl": 0, // "real_profit": 0, // "trade_partition": "USDT", // "reduce_only": 0, // "contract_type": "this_week", // "business_type": "futures" // } // ], // "ts": 1683239909141 // } // // trigger // // { // "status": "ok", // "data": { // "orders": [ // { // "contract_type": "swap", // "business_type": "swap", // "pair": "BTC-USDT", // "symbol": "BTC", // "contract_code": "BTC-USDT", // "trigger_type": "le", // "volume": 1.000000000000000000, // "order_type": 1, // "direction": "buy", // "offset": "open", // "lever_rate": 1, // "order_id": 1103670703588327424, // "order_id_str": "1103670703588327424", // "relation_order_id": "-1", // "order_price_type": "limit", // "status": 6, // "order_source": "web", // "trigger_price": 25000.000000000000000000, // "triggered_price": null, // "order_price": 24000.000000000000000000, // "created_at": 1683177200945, // "triggered_at": null, // "order_insert_at": 0, // "canceled_at": 1683179075234, // "fail_code": null, // "fail_reason": null, // "margin_mode": "cross", // "margin_account": "USDT", // "update_time": 1683179075958, // "trade_partition": "USDT", // "reduce_only": 0 // }, // ], // "total_page": 1, // "current_page": 1, // "total_size": 2 // }, // "ts": 1683239702792 // } // // stop-loss and take-profit // // { // "status": "ok", // "data": { // "orders": [ // { // "contract_type": "swap", // "business_type": "swap", // "pair": "BTC-USDT", // "symbol": "BTC", // "contract_code": "BTC-USDT", // "margin_mode": "cross", // "margin_account": "USDT", // "volume": 1.000000000000000000, // "order_type": 1, // "tpsl_order_type": "sl", // "direction": "sell", // "order_id": 1103680386844839936, // "order_id_str": "1103680386844839936", // "order_source": "web", // "trigger_type": "le", // "trigger_price": 25000.000000000000000000, // "created_at": 1683179509613, // "order_price_type": "market", // "status": 11, // "source_order_id": null, // "relation_tpsl_order_id": "-1", // "canceled_at": 0, // "fail_code": null, // "fail_reason": null, // "triggered_price": null, // "relation_order_id": "-1", // "update_time": 1683179968231, // "order_price": 0E-18, // "trade_partition": "USDT" // }, // ], // "total_page": 1, // "current_page": 1, // "total_size": 2 // }, // "ts": 1683229230233 // } // var orders interface{} = this.SafeValue(response, "data") if !IsTrue(IsArray(orders)) { orders = this.SafeValue(orders, "orders", []interface{}{}) } ch <- this.ParseOrders(orders, market, since, limit) return nil }() return ch } func (this *htx) FetchClosedContractOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params var request interface{} = map[string]interface{} { "status": "5,6,7", } retRes439115 := (<-this.FetchContractOrders(symbol, since, limit, this.Extend(request, params))) PanicOnError(retRes439115) ch <- retRes439115 return nil }() return ch } /** * @method * @name htx#fetchOrders * @see https://huobiapi.github.io/docs/spot/v1/en/#search-past-orders * @see https://huobiapi.github.io/docs/spot/v1/en/#search-historical-orders-within-48-hours * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-orders-new * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-orders-new * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-history-orders-new * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-history-orders-via-multiple-fields-new * @description fetches information on multiple orders made by the user * @param {string} symbol unified market symbol of the market orders were made in * @param {int} [since] the earliest time in ms to fetch orders for * @param {int} [limit] the maximum number of order structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {bool} [params.trigger] *contract only* if the orders are trigger trigger orders or not * @param {bool} [params.stopLossTakeProfit] *contract only* if the orders are stop-loss or take-profit orders * @param {int} [params.until] the latest time in ms to fetch entries for * @param {boolean} [params.trailing] *contract only* set to true if you want to fetch trailing stop orders * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *htx) FetchOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes44158 := (<-this.LoadMarkets()) PanicOnError(retRes44158) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchOrders", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var contract interface{} = IsTrue((IsEqual(marketType, "swap"))) || IsTrue((IsEqual(marketType, "future"))) if IsTrue(IsTrue(contract) && IsTrue((IsEqual(symbol, nil)))) { panic(ArgumentsRequired(Add(Add(Add(this.Id, " fetchOrders() requires a symbol argument for "), marketType), " orders"))) } if IsTrue(contract) { retRes442719 := (<-this.FetchContractOrders(symbol, since, limit, params)) PanicOnError(retRes442719) ch <- retRes442719 return nil } else { retRes442919 := (<-this.FetchSpotOrders(symbol, since, limit, params)) PanicOnError(retRes442919) ch <- retRes442919 return nil } return nil }() return ch } /** * @method * @name htx#fetchClosedOrders * @see https://huobiapi.github.io/docs/spot/v1/en/#search-past-orders * @see https://huobiapi.github.io/docs/spot/v1/en/#search-historical-orders-within-48-hours * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-history-orders-new * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-history-orders-new * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-history-orders-new * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-history-orders-via-multiple-fields-new * @description fetches information on multiple closed orders made by the user * @param {string} symbol unified market symbol of the market orders were made in * @param {int} [since] the earliest time in ms to fetch orders for * @param {int} [limit] the maximum number of order structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {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 {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *htx) 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 retRes44528 := (<-this.LoadMarkets()) PanicOnError(retRes44528) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchClosedOrders", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes445619 := (<-this.FetchPaginatedCallDynamic("fetchClosedOrders", symbol, since, limit, params, 100)) PanicOnError(retRes445619) ch <- retRes445619 return nil } var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchClosedOrders", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) if IsTrue(IsEqual(marketType, "spot")) { retRes446519 := (<-this.FetchClosedSpotOrders(symbol, since, limit, params)) PanicOnError(retRes446519) ch <- retRes446519 return nil } else { retRes446719 := (<-this.FetchClosedContractOrders(symbol, since, limit, params)) PanicOnError(retRes446719) ch <- retRes446719 return nil } return nil }() return ch } /** * @method * @name htx#fetchOpenOrders * @see https://huobiapi.github.io/docs/spot/v1/en/#get-all-open-orders * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-current-unfilled-order-acquisition * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-current-unfilled-order-acquisition * @description fetch all unfilled currently open orders * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch open orders for * @param {int} [limit] the maximum number of open order structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {bool} [params.trigger] *contract only* if the orders are trigger trigger orders or not * @param {bool} [params.stopLossTakeProfit] *contract only* if the orders are stop-loss or take-profit orders * @param {boolean} [params.trailing] *contract only* set to true if you want to fetch trailing stop orders * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *htx) 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 retRes44888 := (<-this.LoadMarkets()) PanicOnError(retRes44888) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var request interface{} = map[string]interface{} {} var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchOpenOrders", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var response interface{} = nil if IsTrue(IsEqual(marketType, "spot")) { if IsTrue(!IsEqual(symbol, nil)) { AddElementToObject(request, "symbol", GetValue(market, "id")) } // todo replace with fetchAccountIdByType var accountId interface{} = this.SafeString(params, "account-id") if IsTrue(IsEqual(accountId, nil)) { // pick the first account retRes450516 := (<-this.LoadAccounts()) PanicOnError(retRes450516) for i := 0; IsLessThan(i, GetArrayLength(this.Accounts)); i++ { var account interface{} = GetValue(this.Accounts, i) if IsTrue(IsEqual(this.SafeString(account, "type"), "spot")) { accountId = this.SafeString(account, "id") if IsTrue(!IsEqual(accountId, nil)) { break } } } } AddElementToObject(request, "account-id", accountId) if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", limit) } params = this.Omit(params, "account-id") response = (<-this.SpotPrivateGetV1OrderOpenOrders(this.Extend(request, params))) PanicOnError(response) } else { if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOpenOrders() requires a symbol argument"))) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "page_size", limit) } AddElementToObject(request, "contract_code", GetValue(market, "id")) var trigger interface{} = this.SafeBool2(params, "stop", "trigger") var stopLossTakeProfit interface{} = this.SafeValue(params, "stopLossTakeProfit") var trailing interface{} = this.SafeBool(params, "trailing", false) params = this.Omit(params, []interface{}{"stop", "stopLossTakeProfit", "trailing", "trigger"}) if IsTrue(GetValue(market, "linear")) { var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchOpenOrders", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) if IsTrue(IsEqual(marginMode, "isolated")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTriggerOpenorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTpslOpenorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTrackOpenorders(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapOpenorders(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(IsEqual(marginMode, "cross")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTriggerOpenorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTpslOpenorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTrackOpenorders(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossOpenorders(this.Extend(request, params))) PanicOnError(response) } } } else if IsTrue(GetValue(market, "inverse")) { if IsTrue(GetValue(market, "swap")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostSwapApiV1SwapTriggerOpenorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostSwapApiV1SwapTpslOpenorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostSwapApiV1SwapTrackOpenorders(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostSwapApiV1SwapOpenorders(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "future")) { AddElementToObject(request, "symbol", GetValue(market, "settleId")) if IsTrue(trigger) { response = (<-this.ContractPrivatePostApiV1ContractTriggerOpenorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostApiV1ContractTpslOpenorders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostApiV1ContractTrackOpenorders(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostApiV1ContractOpenorders(this.Extend(request, params))) PanicOnError(response) } } } } // // spot // // { // "status":"ok", // "data":[ // { // "symbol":"ethusdt", // "source":"api", // "amount":"0.010000000000000000", // "account-id":1528640, // "created-at":1561597491963, // "price":"400.000000000000000000", // "filled-amount":"0.0", // "filled-cash-amount":"0.0", // "filled-fees":"0.0", // "id":38477101630, // "state":"submitted", // "type":"sell-limit" // } // ] // } // // futures // // { // "status": "ok", // "data": { // "orders": [ // { // "symbol": "ADA", // "contract_code": "ADA201225", // "contract_type": "quarter", // "volume": 1, // "price": 0.0925, // "order_price_type": "post_only", // "order_type": 1, // "direction": "buy", // "offset": "close", // "lever_rate": 20, // "order_id": 773131315209248768, // "client_order_id": null, // "created_at": 1604370469629, // "trade_volume": 0, // "trade_turnover": 0, // "fee": 0, // "trade_avg_price": null, // "margin_frozen": 0, // "profit": 0, // "status": 3, // "order_source": "web", // "order_id_str": "773131315209248768", // "fee_asset": "ADA", // "liquidation_type": null, // "canceled_at": null, // "is_tpsl": 0, // "update_time": 1606975980467, // "real_profit": 0 // } // ], // "total_page": 1, // "current_page": 1, // "total_size": 1 // }, // "ts": 1604370488518 // } // // trigger // // { // "status": "ok", // "data": { // "orders": [ // { // "contract_type": "swap", // "business_type": "swap", // "pair": "BTC-USDT", // "symbol": "BTC", // "contract_code": "BTC-USDT", // "trigger_type": "le", // "volume": 1.000000000000000000, // "order_type": 1, // "direction": "buy", // "offset": "open", // "lever_rate": 1, // "order_id": 1103670703588327424, // "order_id_str": "1103670703588327424", // "order_source": "web", // "trigger_price": 25000.000000000000000000, // "order_price": 24000.000000000000000000, // "created_at": 1683177200945, // "order_price_type": "limit", // "status": 2, // "margin_mode": "cross", // "margin_account": "USDT", // "trade_partition": "USDT", // "reduce_only": 0 // } // ], // "total_page": 1, // "current_page": 1, // "total_size": 1 // }, // "ts": 1683177805320 // } // // stop-loss and take-profit // // { // "status": "ok", // "data": { // "orders": [ // { // "contract_type": "swap", // "business_type": "swap", // "pair": "BTC-USDT", // "symbol": "BTC", // "contract_code": "BTC-USDT", // "margin_mode": "cross", // "margin_account": "USDT", // "volume": 1.000000000000000000, // "order_type": 1, // "direction": "sell", // "order_id": 1103680386844839936, // "order_id_str": "1103680386844839936", // "order_source": "web", // "trigger_type": "le", // "trigger_price": 25000.000000000000000000, // "order_price": 0E-18, // "created_at": 1683179509613, // "order_price_type": "market", // "status": 2, // "tpsl_order_type": "sl", // "source_order_id": null, // "relation_tpsl_order_id": "-1", // "trade_partition": "USDT" // } // ], // "total_page": 1, // "current_page": 1, // "total_size": 1 // }, // "ts": 1683179527011 // } // // trailing // // { // "status": "ok", // "data": { // "orders": [ // { // "contract_type": "swap", // "business_type": "swap", // "pair": "BTC-USDT", // "symbol": "BTC", // "contract_code": "BTC-USDT", // "volume": 1.000000000000000000, // "order_type": 1, // "direction": "sell", // "offset": "close", // "lever_rate": 1, // "order_id": 1192021437253877761, // "order_id_str": "1192021437253877761", // "order_source": "api", // "created_at": 1704241657328, // "order_price_type": "formula_price", // "status": 2, // "callback_rate": 0.050000000000000000, // "active_price": 50000.000000000000000000, // "is_active": 0, // "margin_mode": "cross", // "margin_account": "USDT", // "trade_partition": "USDT", // "reduce_only": 1 // }, // ], // "total_page": 1, // "current_page": 1, // "total_size": 2 // }, // "ts": 1704242440106 // } // var orders interface{} = this.SafeValue(response, "data") if !IsTrue(IsArray(orders)) { orders = this.SafeValue(orders, "orders", []interface{}{}) } ch <- this.ParseOrders(orders, market, since, limit) return nil }() return ch } func (this *htx) ParseOrderStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "partial-filled": "open", "partial-canceled": "canceled", "filled": "closed", "canceled": "canceled", "submitted": "open", "created": "open", "1": "open", "2": "open", "3": "open", "4": "open", "5": "canceled", "6": "closed", "7": "canceled", "11": "canceling", } return this.SafeString(statuses, status, status) } func (this *htx) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // spot // // { // "id": 13997833014, // "symbol": "ethbtc", // "account-id": 3398321, // "amount": "0.045000000000000000", // "price": "0.034014000000000000", // "created-at": 1545836976871, // "type": "sell-limit", // "field-amount": "0.045000000000000000", // they have fixed it for filled-amount // "field-cash-amount": "0.001530630000000000", // they have fixed it for filled-cash-amount // "field-fees": "0.000003061260000000", // they have fixed it for filled-fees // "finished-at": 1545837948214, // "source": "spot-api", // "state": "filled", // "canceled-at": 0 // } // // { // "id": 20395337822, // "symbol": "ethbtc", // "account-id": 5685075, // "amount": "0.001000000000000000", // "price": "0.0", // "created-at": 1545831584023, // "type": "buy-market", // "field-amount": "0.029100000000000000", // they have fixed it for filled-amount // "field-cash-amount": "0.000999788700000000", // they have fixed it for filled-cash-amount // "field-fees": "0.000058200000000000", // they have fixed it for filled-fees // "finished-at": 1545831584181, // "source": "spot-api", // "state": "filled", // "canceled-at": 0 // } // // linear swap cross margin createOrder // // { // "order_id":924660854912552960, // "order_id_str":"924660854912552960" // } // // contracts fetchOrder // // { // "business_type":"swap", // "contract_type":"swap", // "pair":"BTC-USDT", // "symbol":"BTC", // "contract_code":"BTC-USDT", // "volume":1, // "price":3000, // "order_price_type":"limit", // "order_type":1, // "direction":"buy", // "offset":"open", // "lever_rate":1, // "order_id":924912513206878210, // "client_order_id":null, // "created_at":1640557927189, // "trade_volume":0, // "trade_turnover":0, // "fee":0, // "trade_avg_price":null, // "margin_frozen":3.000000000000000000, // "profit":0, // "status":3, // "order_source":"api", // "order_id_str":"924912513206878210", // "fee_asset":"USDT", // "liquidation_type":"0", // "canceled_at":0, // "margin_asset":"USDT", // "margin_account":"USDT", // "margin_mode":"cross", // "is_tpsl":0, // "real_profit":0 // } // // contracts fetchOrder detailed // // { // "symbol": "BTC", // "contract_code": "BTC-USDT", // "instrument_price": 0, // "final_interest": 0, // "adjust_value": 0, // "lever_rate": 10, // "direction": "sell", // "offset": "open", // "volume": 1.000000000000000000, // "price": 13059.800000000000000000, // "created_at": 1603703614712, // "canceled_at": 0, // "order_source": "api", // "order_price_type": "opponent", // "margin_frozen": 0, // "profit": 0, // "trades": [ // { // "trade_id": 131560927, // "trade_price": 13059.800000000000000000, // "trade_volume": 1.000000000000000000, // "trade_turnover": 13.059800000000000000, // "trade_fee": -0.005223920000000000, // "created_at": 1603703614715, // "role": "taker", // "fee_asset": "USDT", // "profit": 0, // "real_profit": 0, // "id": "131560927-770334322963152896-1" // } // ], // "total_page": 1, // "current_page": 1, // "total_size": 1, // "liquidation_type": "0", // "fee_asset": "USDT", // "fee": -0.005223920000000000, // "order_id": 770334322963152896, // "order_id_str": "770334322963152896", // "client_order_id": 57012021045, // "order_type": "1", // "status": 6, // "trade_avg_price": 13059.800000000000000000, // "trade_turnover": 13.059800000000000000, // "trade_volume": 1.000000000000000000, // "margin_asset": "USDT", // "margin_mode": "isolated", // "margin_account": "BTC-USDT", // "real_profit": 0, // "is_tpsl": 0 // } // // future and swap: fetchOrders // // { // "order_id": 773131315209248768, // "contract_code": "ADA201225", // "symbol": "ADA", // "lever_rate": 20, // "direction": "buy", // "offset": "close", // "volume": 1, // "price": 0.0925, // "create_date": 1604370469629, // "update_time": 1603704221118, // "order_source": "web", // "order_price_type": 6, // "order_type": 1, // "margin_frozen": 0, // "profit": 0, // "contract_type": "quarter", // "trade_volume": 0, // "trade_turnover": 0, // "fee": 0, // "trade_avg_price": 0, // "status": 3, // "order_id_str": "773131315209248768", // "fee_asset": "ADA", // "liquidation_type": "0", // "is_tpsl": 0, // "real_profit": 0 // "margin_asset": "USDT", // "margin_mode": "cross", // "margin_account": "USDT", // "trade_partition": "USDT", // only in isolated & cross of linear // "reduce_only": "1", // only in isolated & cross of linear // "contract_type": "quarter", // only in cross-margin (inverse & linear) // "pair": "BTC-USDT", // only in cross-margin (inverse & linear) // "business_type": "futures" // only in cross-margin (inverse & linear) // } // // trigger: fetchOpenOrders // // { // "contract_type": "swap", // "business_type": "swap", // "pair": "BTC-USDT", // "symbol": "BTC", // "contract_code": "BTC-USDT", // "trigger_type": "le", // "volume": 1.000000000000000000, // "order_type": 1, // "direction": "buy", // "offset": "open", // "lever_rate": 1, // "order_id": 1103670703588327424, // "order_id_str": "1103670703588327424", // "order_source": "web", // "trigger_price": 25000.000000000000000000, // "order_price": 24000.000000000000000000, // "created_at": 1683177200945, // "order_price_type": "limit", // "status": 2, // "margin_mode": "cross", // "margin_account": "USDT", // "trade_partition": "USDT", // "reduce_only": 0 // } // // stop-loss and take-profit: fetchOpenOrders // // { // "contract_type": "swap", // "business_type": "swap", // "pair": "BTC-USDT", // "symbol": "BTC", // "contract_code": "BTC-USDT", // "margin_mode": "cross", // "margin_account": "USDT", // "volume": 1.000000000000000000, // "order_type": 1, // "direction": "sell", // "order_id": 1103680386844839936, // "order_id_str": "1103680386844839936", // "order_source": "web", // "trigger_type": "le", // "trigger_price": 25000.000000000000000000, // "order_price": 0E-18, // "created_at": 1683179509613, // "order_price_type": "market", // "status": 2, // "tpsl_order_type": "sl", // "source_order_id": null, // "relation_tpsl_order_id": "-1", // "trade_partition": "USDT" // } // // trailing: fetchOpenOrders // // { // "contract_type": "swap", // "business_type": "swap", // "pair": "BTC-USDT", // "symbol": "BTC", // "contract_code": "BTC-USDT", // "volume": 1.000000000000000000, // "order_type": 1, // "direction": "sell", // "offset": "close", // "lever_rate": 1, // "order_id": 1192021437253877761, // "order_id_str": "1192021437253877761", // "order_source": "api", // "created_at": 1704241657328, // "order_price_type": "formula_price", // "status": 2, // "callback_rate": 0.050000000000000000, // "active_price": 50000.000000000000000000, // "is_active": 0, // "margin_mode": "cross", // "margin_account": "USDT", // "trade_partition": "USDT", // "reduce_only": 1 // } // // trigger: fetchOrders // // { // "contract_type": "swap", // "business_type": "swap", // "pair": "BTC-USDT", // "symbol": "BTC", // "contract_code": "BTC-USDT", // "trigger_type": "le", // "volume": 1.000000000000000000, // "order_type": 1, // "direction": "buy", // "offset": "open", // "lever_rate": 1, // "order_id": 1103670703588327424, // "order_id_str": "1103670703588327424", // "relation_order_id": "-1", // "order_price_type": "limit", // "status": 6, // "order_source": "web", // "trigger_price": 25000.000000000000000000, // "triggered_price": null, // "order_price": 24000.000000000000000000, // "created_at": 1683177200945, // "triggered_at": null, // "order_insert_at": 0, // "canceled_at": 1683179075234, // "fail_code": null, // "fail_reason": null, // "margin_mode": "cross", // "margin_account": "USDT", // "update_time": 1683179075958, // "trade_partition": "USDT", // "reduce_only": 0 // } // // stop-loss and take-profit: fetchOrders // // { // "contract_type": "swap", // "business_type": "swap", // "pair": "BTC-USDT", // "symbol": "BTC", // "contract_code": "BTC-USDT", // "margin_mode": "cross", // "margin_account": "USDT", // "volume": 1.000000000000000000, // "order_type": 1, // "tpsl_order_type": "sl", // "direction": "sell", // "order_id": 1103680386844839936, // "order_id_str": "1103680386844839936", // "order_source": "web", // "trigger_type": "le", // "trigger_price": 25000.000000000000000000, // "created_at": 1683179509613, // "order_price_type": "market", // "status": 11, // "source_order_id": null, // "relation_tpsl_order_id": "-1", // "canceled_at": 0, // "fail_code": null, // "fail_reason": null, // "triggered_price": null, // "relation_order_id": "-1", // "update_time": 1683179968231, // "order_price": 0E-18, // "trade_partition": "USDT" // } // // spot: createOrders // // [ // { // "order-id": 936847569789079, // "client-order-id": "AA03022abc3a55e82c-0087-4fc2-beac-112fdebb1ee9" // }, // { // "client-order-id": "AA03022abcdb3baefb-3cfa-4891-8009-082b3d46ca82", // "err-code": "account-frozen-balance-insufficient-error", // "err-msg": "trade account balance is not enough, left: `89`" // } // ] // // swap and future: createOrders // // [ // { // "index": 2, // "err_code": 1047, // "err_msg": "Insufficient margin available." // }, // { // "order_id": 1172923090632953857, // "index": 1, // "order_id_str": "1172923090632953857" // } // ] // market := GetArg(optionalArgs, 0, nil) _ = market var rejectedCreateOrders interface{} = this.SafeString2(order, "err_code", "err-code") var status interface{} = this.ParseOrderStatus(this.SafeString2(order, "state", "status")) if IsTrue(!IsEqual(rejectedCreateOrders, nil)) { status = "rejected" } var id interface{} = this.SafeStringN(order, []interface{}{"id", "order_id_str", "order-id"}) var side interface{} = this.SafeString(order, "direction") var typeVar interface{} = this.SafeString(order, "order_price_type") if IsTrue(InOp(order, "type")) { var orderType interface{} = Split(GetValue(order, "type"), "-") side = GetValue(orderType, 0) typeVar = GetValue(orderType, 1) } var marketId interface{} = this.SafeString2(order, "contract_code", "symbol") market = this.SafeMarket(marketId, market) var timestamp interface{} = this.SafeIntegerN(order, []interface{}{"created_at", "created-at", "create_date"}) var clientOrderId interface{} = this.SafeString2(order, "client_order_id", Add("client-or", "der-id")) // transpiler regex trick for php issue var cost interface{} = nil var amount interface{} = nil if IsTrue(IsTrue((!IsEqual(typeVar, nil))) && IsTrue((IsGreaterThanOrEqual(GetIndexOf(typeVar, "market"), 0)))) { cost = this.SafeString(order, "field-cash-amount") } else { amount = this.SafeString2(order, "volume", "amount") cost = this.SafeStringN(order, []interface{}{"filled-cash-amount", "field-cash-amount", "trade_turnover"}) // same typo here } var filled interface{} = this.SafeStringN(order, []interface{}{"filled-amount", "field-amount", "trade_volume"}) // typo in their API, filled amount var price interface{} = this.SafeString2(order, "price", "order_price") var feeCost interface{} = this.SafeString2(order, "filled-fees", "field-fees") // typo in their API, filled feeSide feeCost = this.SafeString(order, "fee", feeCost) var fee interface{} = nil if IsTrue(!IsEqual(feeCost, nil)) { var feeCurrency interface{} = nil var feeCurrencyId interface{} = this.SafeString(order, "fee_asset") if IsTrue(!IsEqual(feeCurrencyId, nil)) { feeCurrency = this.SafeCurrencyCode(feeCurrencyId) } else { feeCurrency = Ternary(IsTrue((IsEqual(side, "sell"))), GetValue(market, "quote"), GetValue(market, "base")) } fee = map[string]interface{} { "cost": feeCost, "currency": feeCurrency, } } var average interface{} = this.SafeString(order, "trade_avg_price") var trades interface{} = this.SafeValue(order, "trades") var reduceOnlyInteger interface{} = this.SafeInteger(order, "reduce_only") var reduceOnly interface{} = nil if IsTrue(!IsEqual(reduceOnlyInteger, nil)) { reduceOnly = Ternary(IsTrue((IsEqual(reduceOnlyInteger, 0))), false, true) } return this.SafeOrder(map[string]interface{} { "info": order, "id": id, "clientOrderId": clientOrderId, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastTradeTimestamp": nil, "symbol": GetValue(market, "symbol"), "type": typeVar, "timeInForce": nil, "postOnly": nil, "side": side, "price": price, "triggerPrice": this.SafeString2(order, "stop-price", "trigger_price"), "average": average, "cost": cost, "amount": amount, "filled": filled, "remaining": nil, "status": status, "reduceOnly": reduceOnly, "fee": fee, "trades": trades, }, market) } /** * @method * @name htx#createMarketBuyOrderWithCost * @description create a market buy order by providing the symbol and cost * @see https://www.htx.com/en-us/opend/newApiPages/?id=7ec4ee16-7773-11ed-9966-0242ac110003 * @param {string} symbol unified symbol of the market to create an order in * @param {float} cost how much you want to trade in units of the quote currency * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *htx) CreateMarketBuyOrderWithCost(symbol interface{}, cost interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes52438 := (<-this.LoadMarkets()) PanicOnError(retRes52438) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "spot")) { panic(NotSupported(Add(this.Id, " createMarketBuyOrderWithCost() supports spot orders only"))) } AddElementToObject(params, "createMarketBuyOrderRequiresPrice", false) retRes524915 := (<-this.CreateOrder(symbol, "market", "buy", cost, nil, params)) PanicOnError(retRes524915) ch <- retRes524915 return nil }() return ch } /** * @method * @name htx#createTrailingPercentOrder * @description create a trailing order by providing the symbol, type, side, amount, price and trailingPercent * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much you want to trade in units of the base currency, or number of contracts * @param {float} [price] the price for the order to be filled at, in units of the quote currency, ignored in market orders * @param {float} trailingPercent the percent to trail away from the current market price * @param {float} trailingTriggerPrice the price to activate a trailing order, default uses the price argument * @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 *htx) CreateTrailingPercentOrder(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 trailingPercent := GetArg(optionalArgs, 1, nil) _ = trailingPercent trailingTriggerPrice := GetArg(optionalArgs, 2, nil) _ = trailingTriggerPrice params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params if IsTrue(IsEqual(trailingPercent, nil)) { panic(ArgumentsRequired(Add(this.Id, " createTrailingPercentOrder() requires a trailingPercent argument"))) } if IsTrue(IsEqual(trailingTriggerPrice, nil)) { panic(ArgumentsRequired(Add(this.Id, " createTrailingPercentOrder() requires a trailingTriggerPrice argument"))) } AddElementToObject(params, "trailingPercent", trailingPercent) AddElementToObject(params, "trailingTriggerPrice", trailingTriggerPrice) retRes527515 := (<-this.CreateOrder(symbol, typeVar, side, amount, price, params)) PanicOnError(retRes527515) ch <- retRes527515 return nil }() return ch } /** * @method * @ignore * @name htx#createSpotOrderRequest * @description helper function to build request * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much you want to trade in units of the base currency * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.timeInForce] supports 'IOC' and 'FOK' * @param {float} [params.cost] the quote quantity that can be used as an alternative for the amount for market buy orders * @returns {object} request to be sent to the exchange */ func (this *htx) CreateSpotOrderRequest(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 retRes52948 := (<-this.LoadMarkets()) PanicOnError(retRes52948) retRes52958 := (<-this.LoadAccounts()) PanicOnError(retRes52958) var market interface{} = this.Market(symbol) var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("createOrder", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) accountId:= (<-this.FetchAccountIdByType(GetValue(market, "type"), marginMode, symbol)) PanicOnError(accountId) var request interface{} = map[string]interface{} { "account-id": accountId, "symbol": GetValue(market, "id"), } var orderType interface{} = Replace(typeVar, "buy-", "") orderType = Replace(orderType, "sell-", "") var options interface{} = this.SafeValue(this.Options, GetValue(market, "type"), map[string]interface{} {}) var triggerPrice interface{} = this.SafeStringN(params, []interface{}{"triggerPrice", "stopPrice", "stop-price"}) if IsTrue(IsEqual(triggerPrice, nil)) { var stopOrderTypes interface{} = this.SafeValue(options, "stopOrderTypes", map[string]interface{} {}) if IsTrue(InOp(stopOrderTypes, orderType)) { panic(ArgumentsRequired(Add(this.Id, " createOrder() requires a triggerPrice for a trigger order"))) } } else { var defaultOperator interface{} = Ternary(IsTrue((IsEqual(side, "sell"))), "lte", "gte") var stopOperator interface{} = this.SafeString(params, "operator", defaultOperator) AddElementToObject(request, "stop-price", this.PriceToPrecision(symbol, triggerPrice)) AddElementToObject(request, "operator", stopOperator) if IsTrue(IsTrue((IsEqual(orderType, "limit"))) || IsTrue((IsEqual(orderType, "limit-fok")))) { orderType = Add("stop-", orderType) } else if IsTrue(IsTrue((!IsEqual(orderType, "stop-limit"))) && IsTrue((!IsEqual(orderType, "stop-limit-fok")))) { panic(NotSupported(Add(Add(Add(this.Id, " createOrder() does not support "), typeVar), " orders"))) } } var postOnly interface{} = nil postOnlyparamsVariable := this.HandlePostOnly(IsEqual(orderType, "market"), IsEqual(orderType, "limit-maker"), params); postOnly = GetValue(postOnlyparamsVariable,0); params = GetValue(postOnlyparamsVariable,1) if IsTrue(postOnly) { orderType = "limit-maker" } var timeInForce interface{} = this.SafeString(params, "timeInForce", "GTC") if IsTrue(IsEqual(timeInForce, "FOK")) { orderType = Add(orderType, "-fok") } else if IsTrue(IsEqual(timeInForce, "IOC")) { orderType = "ioc" } AddElementToObject(request, "type", Add(Add(side, "-"), orderType)) var clientOrderId interface{} = this.SafeString2(params, "clientOrderId", "client-order-id") // must be 64 chars max and unique within 24 hours if IsTrue(IsEqual(clientOrderId, nil)) { var broker interface{} = this.SafeValue(this.Options, "broker", map[string]interface{} {}) var brokerId interface{} = this.SafeString(broker, "id") AddElementToObject(request, "client-order-id", Add(brokerId, this.Uuid())) } else { AddElementToObject(request, "client-order-id", clientOrderId) } if IsTrue(IsEqual(marginMode, "cross")) { AddElementToObject(request, "source", "super-margin-api") } else if IsTrue(IsEqual(marginMode, "isolated")) { AddElementToObject(request, "source", "margin-api") } else if IsTrue(IsEqual(marginMode, "c2c")) { AddElementToObject(request, "source", "c2c-margin-api") } if IsTrue(IsTrue((IsEqual(orderType, "market"))) && IsTrue((IsEqual(side, "buy")))) { var quoteAmount interface{} = nil var createMarketBuyOrderRequiresPrice interface{} = true createMarketBuyOrderRequiresPriceparamsVariable := this.HandleOptionAndParams(params, "createOrder", "createMarketBuyOrderRequiresPrice", true); createMarketBuyOrderRequiresPrice = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,0); params = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,1) var cost interface{} = this.SafeNumber(params, "cost") params = this.Omit(params, "cost") if IsTrue(!IsEqual(cost, nil)) { quoteAmount = this.AmountToPrecision(symbol, cost) } else if IsTrue(createMarketBuyOrderRequiresPrice) { if IsTrue(IsEqual(price, nil)) { panic(InvalidOrder(Add(this.Id, " createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument"))) } else { // despite that cost = amount * price is in quote currency and should have quote precision // the exchange API requires the cost supplied in 'amount' to be of base precision // more about it here: // https://github.com/ccxt/ccxt/pull/4395 // https://github.com/ccxt/ccxt/issues/7611 // we use amountToPrecision here because the exchange requires cost in base precision var amountString interface{} = this.NumberToString(amount) var priceString interface{} = this.NumberToString(price) quoteAmount = this.AmountToPrecision(symbol, Precise.StringMul(amountString, priceString)) } } else { quoteAmount = this.AmountToPrecision(symbol, amount) } AddElementToObject(request, "amount", quoteAmount) } else { AddElementToObject(request, "amount", this.AmountToPrecision(symbol, amount)) } var limitOrderTypes interface{} = this.SafeValue(options, "limitOrderTypes", map[string]interface{} {}) if IsTrue(InOp(limitOrderTypes, orderType)) { AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) } params = this.Omit(params, []interface{}{"triggerPrice", "stopPrice", "stop-price", "clientOrderId", "client-order-id", "operator", "timeInForce"}) ch <- this.Extend(request, params) return nil }() return ch } func (this *htx) CreateContractOrderRequest(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) interface{} { /** * @method * @ignore * @name htx#createContractOrderRequest * @description helper function to build request * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much you want to trade in units of the base currency * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.timeInForce] supports 'IOC' and 'FOK' * @param {float} [params.trailingPercent] *contract only* the percent to trail away from the current market price * @param {float} [params.trailingTriggerPrice] *contract only* the price to trigger a trailing order, default uses the price argument * @returns {object} request to be sent to the exchange */ 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{} { "contract_code": GetValue(market, "id"), "volume": this.AmountToPrecision(symbol, amount), "direction": side, } var postOnly interface{} = nil postOnlyparamsVariable := this.HandlePostOnly(IsEqual(typeVar, "market"), IsEqual(typeVar, "post_only"), params); postOnly = GetValue(postOnlyparamsVariable,0); params = GetValue(postOnlyparamsVariable,1) if IsTrue(postOnly) { typeVar = "post_only" } var timeInForce interface{} = this.SafeString(params, "timeInForce", "GTC") if IsTrue(IsEqual(timeInForce, "FOK")) { typeVar = "fok" } else if IsTrue(IsEqual(timeInForce, "IOC")) { typeVar = "ioc" } var triggerPrice interface{} = this.SafeNumberN(params, []interface{}{"triggerPrice", "stopPrice", "trigger_price"}) var stopLossTriggerPrice interface{} = this.SafeNumber2(params, "stopLossPrice", "sl_trigger_price") var takeProfitTriggerPrice interface{} = this.SafeNumber2(params, "takeProfitPrice", "tp_trigger_price") var trailingPercent interface{} = this.SafeString2(params, "trailingPercent", "callback_rate") var trailingTriggerPrice interface{} = this.SafeNumber(params, "trailingTriggerPrice", price) var isTrailingPercentOrder interface{} = !IsEqual(trailingPercent, nil) var isTrigger interface{} = !IsEqual(triggerPrice, nil) var isStopLossTriggerOrder interface{} = !IsEqual(stopLossTriggerPrice, nil) var isTakeProfitTriggerOrder interface{} = !IsEqual(takeProfitTriggerPrice, nil) if IsTrue(isTrigger) { var triggerType interface{} = this.SafeString2(params, "triggerType", "trigger_type", "le") AddElementToObject(request, "trigger_type", triggerType) AddElementToObject(request, "trigger_price", this.PriceToPrecision(symbol, triggerPrice)) if IsTrue(!IsEqual(price, nil)) { AddElementToObject(request, "order_price", this.PriceToPrecision(symbol, price)) } } else if IsTrue(IsTrue(isStopLossTriggerOrder) || IsTrue(isTakeProfitTriggerOrder)) { if IsTrue(isStopLossTriggerOrder) { AddElementToObject(request, "sl_order_price_type", typeVar) AddElementToObject(request, "sl_trigger_price", this.PriceToPrecision(symbol, stopLossTriggerPrice)) if IsTrue(!IsEqual(price, nil)) { AddElementToObject(request, "sl_order_price", this.PriceToPrecision(symbol, price)) } } else { AddElementToObject(request, "tp_order_price_type", typeVar) AddElementToObject(request, "tp_trigger_price", this.PriceToPrecision(symbol, takeProfitTriggerPrice)) if IsTrue(!IsEqual(price, nil)) { AddElementToObject(request, "tp_order_price", this.PriceToPrecision(symbol, price)) } } } else if IsTrue(isTrailingPercentOrder) { var trailingPercentString interface{} = Precise.StringDiv(trailingPercent, "100") AddElementToObject(request, "callback_rate", this.ParseToNumeric(trailingPercentString)) AddElementToObject(request, "active_price", trailingTriggerPrice) AddElementToObject(request, "order_price_type", this.SafeString(params, "order_price_type", "formula_price")) } else { var clientOrderId interface{} = this.SafeInteger2(params, "client_order_id", "clientOrderId") if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "client_order_id", clientOrderId) params = this.Omit(params, []interface{}{"clientOrderId"}) } if IsTrue(IsTrue(IsTrue(IsTrue(IsEqual(typeVar, "limit")) || IsTrue(IsEqual(typeVar, "ioc"))) || IsTrue(IsEqual(typeVar, "fok"))) || IsTrue(IsEqual(typeVar, "post_only"))) { AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) } } var reduceOnly interface{} = this.SafeBool2(params, "reduceOnly", "reduce_only", false) if IsTrue(!IsTrue(isStopLossTriggerOrder) && !IsTrue(isTakeProfitTriggerOrder)) { if IsTrue(reduceOnly) { AddElementToObject(request, "reduce_only", 1) } AddElementToObject(request, "lever_rate", this.SafeIntegerN(params, []interface{}{"leverRate", "lever_rate", "leverage"}, 1)) if !IsTrue(isTrailingPercentOrder) { AddElementToObject(request, "order_price_type", typeVar) } } var hedged interface{} = this.SafeBool(params, "hedged", false) if IsTrue(hedged) { if IsTrue(reduceOnly) { AddElementToObject(request, "offset", "close") } else { AddElementToObject(request, "offset", "open") } } var broker interface{} = this.SafeValue(this.Options, "broker", map[string]interface{} {}) var brokerId interface{} = this.SafeString(broker, "id") AddElementToObject(request, "channel_code", brokerId) params = this.Omit(params, []interface{}{"reduceOnly", "triggerPrice", "stopPrice", "stopLossPrice", "takeProfitPrice", "triggerType", "leverRate", "timeInForce", "leverage", "trailingPercent", "trailingTriggerPrice", "hedged"}) return this.Extend(request, params) } /** * @method * @name htx#createOrder * @description create a trade order * @see https://huobiapi.github.io/docs/spot/v1/en/#place-a-new-order // spot, margin * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-an-order // coin-m swap * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-trigger-order // coin-m swap trigger * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-an-order // usdt-m swap cross * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-trigger-order // usdt-m swap cross trigger * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-an-order // usdt-m swap isolated * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-trigger-order // usdt-m swap isolated trigger * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-set-a-take-profit-and-stop-loss-order-for-an-existing-position * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-set-a-take-profit-and-stop-loss-order-for-an-existing-position * @see https://huobiapi.github.io/docs/dm/v1/en/#place-an-order // coin-m futures * @see https://huobiapi.github.io/docs/dm/v1/en/#place-trigger-order // coin-m futures contract trigger * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much you want to trade in units of the base currency * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {float} [params.triggerPrice] the price a trigger order is triggered at * @param {string} [params.triggerType] *contract trigger orders only* ge: greater than or equal to, le: less than or equal to * @param {float} [params.stopLossPrice] *contract only* the price a stop-loss order is triggered at * @param {float} [params.takeProfitPrice] *contract only* the price a take-profit order is triggered at * @param {string} [params.operator] *spot and margin only* gte or lte, trigger price condition * @param {string} [params.offset] *contract only* 'both' (linear only), 'open', or 'close', required in hedge mode and for inverse markets * @param {bool} [params.postOnly] *contract only* true or false * @param {int} [params.leverRate] *contract only* required for all contract orders except tpsl, leverage greater than 20x requires prior approval of high-leverage agreement * @param {string} [params.timeInForce] supports 'IOC' and 'FOK' * @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount * @param {float} [params.trailingPercent] *contract only* the percent to trail away from the current market price * @param {float} [params.trailingTriggerPrice] *contract only* the price to trigger a trailing order, default uses the price argument * @param {bool} [params.hedged] *contract only* true for hedged mode, false for one way mode, default is false * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *htx) 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 retRes55378 := (<-this.LoadMarkets()) PanicOnError(retRes55378) var market interface{} = this.Market(symbol) var triggerPrice interface{} = this.SafeNumberN(params, []interface{}{"triggerPrice", "stopPrice", "trigger_price"}) var stopLossTriggerPrice interface{} = this.SafeNumber2(params, "stopLossPrice", "sl_trigger_price") var takeProfitTriggerPrice interface{} = this.SafeNumber2(params, "takeProfitPrice", "tp_trigger_price") var trailingPercent interface{} = this.SafeNumber(params, "trailingPercent") var isTrailingPercentOrder interface{} = !IsEqual(trailingPercent, nil) var isTrigger interface{} = !IsEqual(triggerPrice, nil) var isStopLossTriggerOrder interface{} = !IsEqual(stopLossTriggerPrice, nil) var isTakeProfitTriggerOrder interface{} = !IsEqual(takeProfitTriggerPrice, nil) var response interface{} = nil if IsTrue(GetValue(market, "spot")) { if IsTrue(isTrailingPercentOrder) { panic(NotSupported(Add(this.Id, " createOrder() does not support trailing orders for spot markets"))) } spotRequest:= (<-this.CreateSpotOrderRequest(symbol, typeVar, side, amount, price, params)) PanicOnError(spotRequest) response = (<-this.SpotPrivatePostV1OrderOrdersPlace(spotRequest)) PanicOnError(response) } else { var contractRequest interface{} = this.CreateContractOrderRequest(symbol, typeVar, side, amount, price, params) if IsTrue(GetValue(market, "linear")) { var marginMode interface{} = nil marginModecontractRequestVariable := this.HandleMarginModeAndParams("createOrder", contractRequest); marginMode = GetValue(marginModecontractRequestVariable,0); contractRequest = GetValue(marginModecontractRequestVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) if IsTrue(IsEqual(marginMode, "isolated")) { if IsTrue(isTrigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTriggerOrder(contractRequest)) PanicOnError(response) } else if IsTrue(IsTrue(isStopLossTriggerOrder) || IsTrue(isTakeProfitTriggerOrder)) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTpslOrder(contractRequest)) PanicOnError(response) } else if IsTrue(isTrailingPercentOrder) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTrackOrder(contractRequest)) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapOrder(contractRequest)) PanicOnError(response) } } else if IsTrue(IsEqual(marginMode, "cross")) { if IsTrue(isTrigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTriggerOrder(contractRequest)) PanicOnError(response) } else if IsTrue(IsTrue(isStopLossTriggerOrder) || IsTrue(isTakeProfitTriggerOrder)) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTpslOrder(contractRequest)) PanicOnError(response) } else if IsTrue(isTrailingPercentOrder) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTrackOrder(contractRequest)) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossOrder(contractRequest)) PanicOnError(response) } } } else if IsTrue(GetValue(market, "inverse")) { var offset interface{} = this.SafeString(params, "offset") if IsTrue(IsEqual(offset, nil)) { panic(ArgumentsRequired(Add(this.Id, " createOrder () requires an extra parameter params[\"offset\"] to be set to \"open\" or \"close\" when placing orders in inverse markets"))) } if IsTrue(GetValue(market, "swap")) { if IsTrue(isTrigger) { response = (<-this.ContractPrivatePostSwapApiV1SwapTriggerOrder(contractRequest)) PanicOnError(response) } else if IsTrue(IsTrue(isStopLossTriggerOrder) || IsTrue(isTakeProfitTriggerOrder)) { response = (<-this.ContractPrivatePostSwapApiV1SwapTpslOrder(contractRequest)) PanicOnError(response) } else if IsTrue(isTrailingPercentOrder) { response = (<-this.ContractPrivatePostSwapApiV1SwapTrackOrder(contractRequest)) PanicOnError(response) } else { response = (<-this.ContractPrivatePostSwapApiV1SwapOrder(contractRequest)) PanicOnError(response) } } else if IsTrue(GetValue(market, "future")) { if IsTrue(isTrigger) { response = (<-this.ContractPrivatePostApiV1ContractTriggerOrder(contractRequest)) PanicOnError(response) } else if IsTrue(IsTrue(isStopLossTriggerOrder) || IsTrue(isTakeProfitTriggerOrder)) { response = (<-this.ContractPrivatePostApiV1ContractTpslOrder(contractRequest)) PanicOnError(response) } else if IsTrue(isTrailingPercentOrder) { response = (<-this.ContractPrivatePostApiV1ContractTrackOrder(contractRequest)) PanicOnError(response) } else { response = (<-this.ContractPrivatePostApiV1ContractOrder(contractRequest)) PanicOnError(response) } } } } // // spot // // {"status":"ok","data":"438398393065481"} // // swap and future // // { // "status": "ok", // "data": { // "order_id": 924660854912552960, // "order_id_str": "924660854912552960" // }, // "ts": 1640497927185 // } // // stop-loss and take-profit // // { // "status": "ok", // "data": { // "tp_order": { // "order_id": 1101494204040163328, // "order_id_str": "1101494204040163328" // }, // "sl_order": null // }, // "ts": :1682658283024 // } // var data interface{} = nil var result interface{} = nil if IsTrue(GetValue(market, "spot")) { ch <- this.SafeOrder(map[string]interface{} { "info": response, "id": this.SafeString(response, "data"), "timestamp": nil, "datetime": nil, "lastTradeTimestamp": nil, "status": nil, "symbol": nil, "type": typeVar, "side": side, "price": price, "amount": amount, "filled": nil, "remaining": nil, "cost": nil, "trades": nil, "fee": nil, "clientOrderId": nil, "average": nil, }, market) return nil } else if IsTrue(isStopLossTriggerOrder) { data = this.SafeValue(response, "data", map[string]interface{} {}) result = this.SafeValue(data, "sl_order", map[string]interface{} {}) } else if IsTrue(isTakeProfitTriggerOrder) { data = this.SafeValue(response, "data", map[string]interface{} {}) result = this.SafeValue(data, "tp_order", map[string]interface{} {}) } else { result = this.SafeValue(response, "data", map[string]interface{} {}) } ch <- this.ParseOrder(result, market) return nil }() return ch } /** * @method * @name htx#createOrders * @description create a list of trade orders * @see https://huobiapi.github.io/docs/spot/v1/en/#place-a-batch-of-orders * @see https://huobiapi.github.io/docs/dm/v1/en/#place-a-batch-of-orders * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-a-batch-of-orders * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-a-batch-of-orders * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-a-batch-of-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 *htx) 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 retRes56888 := (<-this.LoadMarkets()) PanicOnError(retRes56888) var ordersRequests interface{} = []interface{}{} var symbol interface{} = nil var market interface{} = nil var marginMode interface{} = nil for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { var rawOrder interface{} = GetValue(orders, i) var marketId interface{} = this.SafeString(rawOrder, "symbol") if IsTrue(IsEqual(symbol, nil)) { symbol = marketId } else { if IsTrue(!IsEqual(symbol, marketId)) { panic(BadRequest(Add(this.Id, " createOrders() requires all orders to have the same 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.SafeValue(rawOrder, "params", map[string]interface{} {}) var marginResult interface{} = this.HandleMarginModeAndParams("createOrders", orderParams) var currentMarginMode interface{} = GetValue(marginResult, 0) if IsTrue(!IsEqual(currentMarginMode, nil)) { if IsTrue(IsEqual(marginMode, nil)) { marginMode = currentMarginMode } else { if IsTrue(!IsEqual(marginMode, currentMarginMode)) { panic(BadRequest(Add(this.Id, " createOrders() requires all orders to have the same margin mode (isolated or cross)"))) } } } market = this.Market(symbol) var orderRequest interface{} = nil if IsTrue(GetValue(market, "spot")) { orderRequest = (<-this.CreateSpotOrderRequest(marketId, typeVar, side, amount, price, orderParams)) PanicOnError(orderRequest) } else { orderRequest = this.CreateContractOrderRequest(marketId, typeVar, side, amount, price, orderParams) } orderRequest = this.Omit(orderRequest, "marginMode") AppendToArray(&ordersRequests,orderRequest) } var request interface{} = map[string]interface{} {} var response interface{} = nil if IsTrue(GetValue(market, "spot")) { response = (<-this.PrivatePostOrderBatchOrders(ordersRequests)) PanicOnError(response) } else { AddElementToObject(request, "orders_data", ordersRequests) if IsTrue(GetValue(market, "linear")) { marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) if IsTrue(IsEqual(marginMode, "isolated")) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapBatchorder(request)) PanicOnError(response) } else if IsTrue(IsEqual(marginMode, "cross")) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossBatchorder(request)) PanicOnError(response) } } else if IsTrue(GetValue(market, "inverse")) { if IsTrue(GetValue(market, "swap")) { response = (<-this.ContractPrivatePostSwapApiV1SwapBatchorder(request)) PanicOnError(response) } else if IsTrue(GetValue(market, "future")) { response = (<-this.ContractPrivatePostApiV1ContractBatchorder(request)) PanicOnError(response) } } } // // spot // // { // "status": "ok", // "data": [ // { // "order-id": 936847569789079, // "client-order-id": "AA03022abc3a55e82c-0087-4fc2-beac-112fdebb1ee9" // }, // { // "client-order-id": "AA03022abcdb3baefb-3cfa-4891-8009-082b3d46ca82", // "err-code": "account-frozen-balance-insufficient-error", // "err-msg": "trade account balance is not enough, left: `89`" // } // ] // } // // swap and future // // { // "status": "ok", // "data": { // "errors": [ // { // "index": 2, // "err_code": 1047, // "err_msg": "Insufficient margin available." // } // ], // "success": [ // { // "order_id": 1172923090632953857, // "index": 1, // "order_id_str": "1172923090632953857" // } // ] // }, // "ts": 1699688256671 // } // var result interface{} = nil if IsTrue(GetValue(market, "spot")) { result = this.SafeValue(response, "data", []interface{}{}) } else { var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var success interface{} = this.SafeValue(data, "success", []interface{}{}) var errors interface{} = this.SafeValue(data, "errors", []interface{}{}) result = this.ArrayConcat(success, errors) } ch <- this.ParseOrders(result, market) return nil }() return ch } /** * @method * @name htx#cancelOrder * @description cancels an open 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] *contract only* if the order is a trigger trigger order or not * @param {boolean} [params.stopLossTakeProfit] *contract only* if the order is a stop-loss or take-profit order * @param {boolean} [params.trailing] *contract only* set to true if you want to cancel a trailing order * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *htx) 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 retRes58168 := (<-this.LoadMarkets()) PanicOnError(retRes58168) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("cancelOrder", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var request interface{} = map[string]interface{} {} var response interface{} = nil if IsTrue(IsEqual(marketType, "spot")) { var clientOrderId interface{} = this.SafeString2(params, "client-order-id", "clientOrderId") if IsTrue(IsEqual(clientOrderId, nil)) { AddElementToObject(request, "order-id", id) response = (<-this.SpotPrivatePostV1OrderOrdersOrderIdSubmitcancel(this.Extend(request, params))) PanicOnError(response) } else { AddElementToObject(request, "client-order-id", clientOrderId) params = this.Omit(params, []interface{}{"client-order-id", "clientOrderId"}) response = (<-this.SpotPrivatePostV1OrderOrdersSubmitCancelClientOrder(this.Extend(request, params))) PanicOnError(response) } } else { if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrder() requires a symbol argument"))) } var clientOrderId interface{} = this.SafeString2(params, "client_order_id", "clientOrderId") if IsTrue(IsEqual(clientOrderId, nil)) { AddElementToObject(request, "order_id", id) } else { AddElementToObject(request, "client_order_id", clientOrderId) params = this.Omit(params, []interface{}{"client_order_id", "clientOrderId"}) } if IsTrue(GetValue(market, "future")) { AddElementToObject(request, "symbol", GetValue(market, "settleId")) } else { AddElementToObject(request, "contract_code", GetValue(market, "id")) } var trigger interface{} = this.SafeBool2(params, "stop", "trigger") var stopLossTakeProfit interface{} = this.SafeValue(params, "stopLossTakeProfit") var trailing interface{} = this.SafeBool(params, "trailing", false) params = this.Omit(params, []interface{}{"stop", "stopLossTakeProfit", "trailing", "trigger"}) if IsTrue(GetValue(market, "linear")) { var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("cancelOrder", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) if IsTrue(IsEqual(marginMode, "isolated")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTriggerCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTpslCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTrackCancel(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCancel(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(IsEqual(marginMode, "cross")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTriggerCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTpslCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTrackCancel(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossCancel(this.Extend(request, params))) PanicOnError(response) } } } else if IsTrue(GetValue(market, "inverse")) { if IsTrue(GetValue(market, "swap")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostSwapApiV1SwapTriggerCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostSwapApiV1SwapTpslCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostSwapApiV1SwapTrackCancel(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostSwapApiV1SwapCancel(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "future")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostApiV1ContractTriggerCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostApiV1ContractTpslCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostApiV1ContractTrackCancel(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostApiV1ContractCancel(this.Extend(request, params))) PanicOnError(response) } } } else { panic(NotSupported(Add(Add(Add(this.Id, " cancelOrder() does not support "), marketType), " markets"))) } } // // spot // // { // "status": "ok", // "data": "10138899000", // } // // future and swap // // { // "status": "ok", // "data": { // "errors": [], // "successes": "924660854912552960" // }, // "ts": 1640504486089 // } // ch <- this.Extend(this.ParseOrder(response, market), map[string]interface{} { "id": id, "status": "canceled", }) return nil }() return ch } /** * @method * @name htx#cancelOrders * @description cancel multiple orders * @param {string[]} ids order ids * @param {string} symbol unified market symbol, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {bool} [params.trigger] *contract only* if the orders are trigger trigger orders or not * @param {bool} [params.stopLossTakeProfit] *contract only* if the orders are stop-loss or take-profit orders * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *htx) CancelOrders(ids 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 retRes59548 := (<-this.LoadMarkets()) PanicOnError(retRes59548) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("cancelOrders", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var request interface{} = map[string]interface{} {} var response interface{} = nil if IsTrue(IsEqual(marketType, "spot")) { var clientOrderIds interface{} = this.SafeValue2(params, "client-order-id", "clientOrderId") clientOrderIds = this.SafeValue2(params, "client-order-ids", "clientOrderIds", clientOrderIds) if IsTrue(IsEqual(clientOrderIds, nil)) { if IsTrue(IsString(clientOrderIds)) { AddElementToObject(request, "order-ids", []interface{}{ids}) } else { AddElementToObject(request, "order-ids", ids) } } else { if IsTrue(IsString(clientOrderIds)) { AddElementToObject(request, "client-order-ids", []interface{}{clientOrderIds}) } else { AddElementToObject(request, "client-order-ids", clientOrderIds) } params = this.Omit(params, []interface{}{"client-order-id", "client-order-ids", "clientOrderId", "clientOrderIds"}) } response = (<-this.SpotPrivatePostV1OrderOrdersBatchcancel(this.Extend(request, params))) PanicOnError(response) } else { if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrders() requires a symbol argument"))) } var clientOrderIds interface{} = this.SafeString2(params, "client_order_id", "clientOrderId") clientOrderIds = this.SafeString2(params, "client_order_ids", "clientOrderIds", clientOrderIds) if IsTrue(IsEqual(clientOrderIds, nil)) { AddElementToObject(request, "order_id", Join(ids, ",")) } else { AddElementToObject(request, "client_order_id", clientOrderIds) params = this.Omit(params, []interface{}{"client_order_id", "client_order_ids", "clientOrderId", "clientOrderIds"}) } if IsTrue(GetValue(market, "future")) { AddElementToObject(request, "symbol", GetValue(market, "settleId")) } else { AddElementToObject(request, "contract_code", GetValue(market, "id")) } var trigger interface{} = this.SafeBool2(params, "stop", "trigger") var stopLossTakeProfit interface{} = this.SafeValue(params, "stopLossTakeProfit") params = this.Omit(params, []interface{}{"stop", "stopLossTakeProfit", "trigger"}) if IsTrue(GetValue(market, "linear")) { var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("cancelOrders", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) if IsTrue(IsEqual(marginMode, "isolated")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTriggerCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTpslCancel(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCancel(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(IsEqual(marginMode, "cross")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTriggerCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTpslCancel(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossCancel(this.Extend(request, params))) PanicOnError(response) } } } else if IsTrue(GetValue(market, "inverse")) { if IsTrue(GetValue(market, "swap")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostSwapApiV1SwapTriggerCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostSwapApiV1SwapTpslCancel(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostSwapApiV1SwapCancel(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "future")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostApiV1ContractTriggerCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostApiV1ContractTpslCancel(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostApiV1ContractCancel(this.Extend(request, params))) PanicOnError(response) } } } else { panic(NotSupported(Add(Add(Add(this.Id, " cancelOrders() does not support "), marketType), " markets"))) } } // // spot // // { // "status": "ok", // "data": { // "success": [ // "5983466" // ], // "failed": [ // { // "err-msg": "Incorrect order state", // "order-state": 7, // "order-id": "", // "err-code": "order-orderstate-error", // "client-order-id": "first" // }, // { // "err-msg": "Incorrect order state", // "order-state": 7, // "order-id": "", // "err-code": "order-orderstate-error", // "client-order-id": "second" // }, // { // "err-msg": "The record is not found.", // "order-id": "", // "err-code": "base-not-found", // "client-order-id": "third" // } // ] // } // } // // future and swap // // { // "status": "ok", // "data": { // "errors": [ // { // "order_id": "769206471845261312", // "err_code": 1061, // "err_msg": "This order doesnt exist." // } // ], // "successes": "773120304138219520" // }, // "ts": 1604367997451 // } // var data interface{} = this.SafeDict(response, "data") ch <- this.ParseCancelOrders(data) return nil }() return ch } func (this *htx) ParseCancelOrders(orders interface{}) interface{} { // // { // "success": [ // "5983466" // ], // "failed": [ // { // "err-msg": "Incorrect order state", // "order-state": 7, // "order-id": "", // "err-code": "order-orderstate-error", // "client-order-id": "first" // }, // ... // ] // } // // { // "errors": [ // { // "order_id": "769206471845261312", // "err_code": 1061, // "err_msg": "This order doesnt exist." // } // ], // "successes": "1258075374411399168,1258075393254871040" // } // var successes interface{} = this.SafeString(orders, "successes") var success interface{} = nil if IsTrue(!IsEqual(successes, nil)) { success = Split(successes, ",") } else { success = this.SafeList(orders, "success", []interface{}{}) } var failed interface{} = this.SafeList2(orders, "errors", "failed", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(success)); i++ { var order interface{} = GetValue(success, i) AppendToArray(&result,this.SafeOrder(map[string]interface{} { "info": order, "id": order, "status": "canceled", })) } for i := 0; IsLessThan(i, GetArrayLength(failed)); i++ { var order interface{} = GetValue(failed, i) AppendToArray(&result,this.SafeOrder(map[string]interface{} { "info": order, "id": this.SafeString2(order, "order-id", "order_id"), "status": "failed", "clientOrderId": this.SafeString(order, "client-order-id"), })) } return result } /** * @method * @name htx#cancelAllOrders * @description cancel all open orders * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.trigger] *contract only* if the orders are trigger trigger orders or not * @param {boolean} [params.stopLossTakeProfit] *contract only* if the orders are stop-loss or take-profit orders * @param {boolean} [params.trailing] *contract only* set to true if you want to cancel all trailing orders * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *htx) CancelAllOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes61788 := (<-this.LoadMarkets()) PanicOnError(retRes61788) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("cancelAllOrders", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var request interface{} = map[string]interface{} {} var response interface{} = nil if IsTrue(IsEqual(marketType, "spot")) { if IsTrue(!IsEqual(symbol, nil)) { AddElementToObject(request, "symbol", GetValue(market, "id")) } response = (<-this.SpotPrivatePostV1OrderOrdersBatchCancelOpenOrders(this.Extend(request, params))) PanicOnError(response) // // { // "code": 200, // "data": { // "success-count": 2, // "failed-count": 0, // "next-id": 5454600 // } // } // var data interface{} = this.SafeDict(response, "data") ch <- []interface{}{this.SafeOrder(map[string]interface{} { "info": data, })} return nil } else { if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelAllOrders() requires a symbol argument"))) } if IsTrue(GetValue(market, "future")) { AddElementToObject(request, "symbol", GetValue(market, "settleId")) } AddElementToObject(request, "contract_code", GetValue(market, "id")) var trigger interface{} = this.SafeBool2(params, "stop", "trigger") var stopLossTakeProfit interface{} = this.SafeValue(params, "stopLossTakeProfit") var trailing interface{} = this.SafeBool(params, "trailing", false) params = this.Omit(params, []interface{}{"stop", "stopLossTakeProfit", "trailing", "trigger"}) if IsTrue(GetValue(market, "linear")) { var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("cancelAllOrders", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) if IsTrue(IsEqual(marginMode, "isolated")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTriggerCancelall(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTpslCancelall(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapTrackCancelall(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCancelall(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(IsEqual(marginMode, "cross")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTriggerCancelall(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTpslCancelall(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossTrackCancelall(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossCancelall(this.Extend(request, params))) PanicOnError(response) } } } else if IsTrue(GetValue(market, "inverse")) { if IsTrue(GetValue(market, "swap")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostSwapApiV1SwapTriggerCancelall(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostSwapApiV1SwapTpslCancelall(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostSwapApiV1SwapTrackCancelall(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostSwapApiV1SwapCancelall(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "future")) { if IsTrue(trigger) { response = (<-this.ContractPrivatePostApiV1ContractTriggerCancelall(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(stopLossTakeProfit) { response = (<-this.ContractPrivatePostApiV1ContractTpslCancelall(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(trailing) { response = (<-this.ContractPrivatePostApiV1ContractTrackCancelall(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostApiV1ContractCancelall(this.Extend(request, params))) PanicOnError(response) } } } else { panic(NotSupported(Add(Add(Add(this.Id, " cancelAllOrders() does not support "), marketType), " markets"))) } // // { // "status": "ok", // "data": { // "errors": [], // "successes": "1104754904426696704" // }, // "ts": "1683435723755" // } // var data interface{} = this.SafeDict(response, "data") ch <- this.ParseCancelOrders(data) return nil } return nil }() return ch } /** * @method * @name htx#cancelAllOrdersAfter * @description dead man's switch, cancel all orders after the given timeout * @see https://huobiapi.github.io/docs/spot/v1/en/#dead-man-s-switch * @param {number} timeout time in milliseconds, 0 represents cancel the timer * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} the api result */ func (this *htx) CancelAllOrdersAfter(timeout 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 retRes63088 := (<-this.LoadMarkets()) PanicOnError(retRes63088) var request interface{} = map[string]interface{} { "timeout": Ternary(IsTrue((IsGreaterThan(timeout, 0))), this.ParseToInt(Divide(timeout, 1000)), 0), } response:= (<-this.V2PrivatePostAlgoOrdersCancelAllAfter(this.Extend(request, params))) PanicOnError(response) // // { // "code": 200, // "message": "success", // "data": { // "currentTime": 1630491627230, // "triggerTime": 1630491637230 // } // } // ch <- response return nil }() return ch } func (this *htx) ParseDepositAddress(depositAddress interface{}, optionalArgs ...interface{}) interface{} { // // { // "currency": "usdt", // "address": "0xf7292eb9ba7bc50358e27f0e025a4d225a64127b", // "addressTag": "", // "chain": "usdterc20", // trc20usdt, hrc20usdt, usdt, algousdt // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var address interface{} = this.SafeString(depositAddress, "address") var tag interface{} = this.SafeString(depositAddress, "addressTag") var currencyId interface{} = this.SafeString(depositAddress, "currency") currency = this.SafeCurrency(currencyId, currency) var code interface{} = this.SafeCurrencyCode(currencyId, currency) var note interface{} = this.SafeString(depositAddress, "note") var networkId interface{} = this.SafeString(depositAddress, "chain") this.CheckAddress(address) return map[string]interface{} { "currency": code, "address": address, "tag": tag, "network": this.NetworkIdToCode(networkId), "note": note, "info": depositAddress, } } /** * @method * @see https://www.htx.com/en-us/opend/newApiPages/?id=7ec50029-7773-11ed-9966-0242ac110003 * @name htx#fetchDepositAddressesByNetwork * @description fetch a dictionary of addresses for a currency, indexed by network * @param {string} code unified currency code of the currency for the deposit address * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [address structures]{@link https://docs.ccxt.com/#/?id=address-structure} indexed by the network */ func (this *htx) FetchDepositAddressesByNetwork(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes63638 := (<-this.LoadMarkets()) PanicOnError(retRes63638) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), } response:= (<-this.SpotPrivateGetV2AccountDepositAddress(this.Extend(request, params))) PanicOnError(response) // // { // "code": 200, // "data": [ // { // "currency": "eth", // "address": "0xf7292eb9ba7bc50358e27f0e025a4d225a64127b", // "addressTag": "", // "chain": "eth" // } // ] // } // var data interface{} = this.SafeValue(response, "data", []interface{}{}) var parsed interface{} = this.ParseDepositAddresses(data, []interface{}{GetValue(currency, "code")}, false) ch <- this.IndexBy(parsed, "network") return nil }() return ch } /** * @method * @name htx#fetchDepositAddress * @description fetch the deposit address for a currency associated with this account * @see https://www.htx.com/en-us/opend/newApiPages/?id=7ec50029-7773-11ed-9966-0242ac110003 * @param {string} code unified currency code * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure} */ func (this *htx) FetchDepositAddress(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes63978 := (<-this.LoadMarkets()) PanicOnError(retRes63978) var currency interface{} = this.Currency(code) networkCodeparamsOmitedVariable := this.HandleNetworkCodeAndParams(params); networkCode := GetValue(networkCodeparamsOmitedVariable,0); paramsOmited := GetValue(networkCodeparamsOmitedVariable,1) indexedAddresses:= (<-this.FetchDepositAddressesByNetwork(code, paramsOmited)) PanicOnError(indexedAddresses) var selectedNetworkCode interface{} = this.SelectNetworkCodeFromUnifiedNetworks(GetValue(currency, "code"), networkCode, indexedAddresses) ch <- GetValue(indexedAddresses, selectedNetworkCode) return nil }() return ch } func (this *htx) FetchWithdrawAddresses(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) note := GetArg(optionalArgs, 0, nil) _ = note networkCode := GetArg(optionalArgs, 1, nil) _ = networkCode params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params retRes64068 := (<-this.LoadMarkets()) PanicOnError(retRes64068) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), } response:= (<-this.SpotPrivateGetV2AccountWithdrawAddress(this.Extend(request, params))) PanicOnError(response) // // { // "code": 200, // "data": [ // { // "currency": "eth", // "chain": "eth" // "note": "Binance - TRC20", // "addressTag": "", // "address": "0xf7292eb9ba7bc50358e27f0e025a4d225a64127b", // } // ] // } // var data interface{} = this.SafeValue(response, "data", []interface{}{}) var allAddresses interface{} = this.ParseDepositAddresses(data, []interface{}{GetValue(currency, "code")}, false) // cjg: to do remove this weird object or array ambiguity var addresses interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(allAddresses)); i++ { var address interface{} = GetValue(allAddresses, i) var noteMatch interface{} = IsTrue((IsEqual(note, nil))) || IsTrue((IsEqual(GetValue(address, "note"), note))) var networkMatch interface{} = IsTrue((IsEqual(networkCode, nil))) || IsTrue((IsEqual(GetValue(address, "network"), networkCode))) if IsTrue(IsTrue(noteMatch) && IsTrue(networkMatch)) { AppendToArray(&addresses,address) } } ch <- addresses return nil }() return ch } /** * @method * @name htx#fetchDeposits * @see https://www.htx.com/en-us/opend/newApiPages/?id=7ec4f050-7773-11ed-9966-0242ac110003 * @description fetch all deposits made to an account * @param {string} code unified currency code * @param {int} [since] the earliest time in ms to fetch deposits for * @param {int} [limit] the maximum number of deposits structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *htx) 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 if IsTrue(IsTrue(IsEqual(limit, nil)) || IsTrue(IsGreaterThan(limit, 100))) { limit = 100 } retRes64558 := (<-this.LoadMarkets()) PanicOnError(retRes64558) var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) } var request interface{} = map[string]interface{} { "type": "deposit", "direct": "next", "from": 0, } if IsTrue(!IsEqual(currency, nil)) { AddElementToObject(request, "currency", GetValue(currency, "id")) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", limit) // max 100 } response:= (<-this.SpotPrivateGetV1QueryDepositWithdraw(this.Extend(request, params))) PanicOnError(response) // // { // "status": "ok", // "data": [ // { // "id": "75115912", // "type": "deposit", // "sub-type": "NORMAL", // "request-id": "trc20usdt-a2e229a44ef2a948c874366230bb56aa73631cc0a03d177bd8b4c9d38262d7ff-200", // "currency": "usdt", // "chain": "trc20usdt", // "tx-hash": "a2e229a44ef2a948c874366230bb56aa73631cc0a03d177bd8b4c9d38262d7ff", // "amount": "12.000000000000000000", // "from-addr-tag": "", // "address-id": "0", // "address": "TRFTd1FxepQE6CnpwzUEMEbFaLm5bJK67s", // "address-tag": "", // "fee": "0", // "state": "safe", // "wallet-confirm": "2", // "created-at": "1621843808662", // "updated-at": "1621843857137" // }, // ] // } // ch <- this.ParseTransactions(GetValue(response, "data"), currency, since, limit) return nil }() return ch } /** * @method * @name htx#fetchWithdrawals * @description fetch all withdrawals made from an account * @see https://huobiapi.github.io/docs/spot/v1/en/#search-for-existed-withdraws-and-deposits * @param {string} code unified currency code * @param {int} [since] the earliest time in ms to fetch withdrawals for * @param {int} [limit] the maximum number of withdrawals structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *htx) 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 if IsTrue(IsTrue(IsEqual(limit, nil)) || IsTrue(IsGreaterThan(limit, 100))) { limit = 100 } retRes65168 := (<-this.LoadMarkets()) PanicOnError(retRes65168) var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) } var request interface{} = map[string]interface{} { "type": "withdraw", "direct": "next", "from": 0, } if IsTrue(!IsEqual(currency, nil)) { AddElementToObject(request, "currency", GetValue(currency, "id")) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", limit) // max 100 } response:= (<-this.SpotPrivateGetV1QueryDepositWithdraw(this.Extend(request, params))) PanicOnError(response) // // { // "status": "ok", // "data": [ // { // "id": "61335312", // "type": "withdraw", // "sub-type": "NORMAL", // "currency": "usdt", // "chain": "trc20usdt", // "tx-hash": "30a3111f2fead74fae45c6218ca3150fc33cab2aa59cfe41526b96aae79ce4ec", // "amount": "12.000000000000000000", // "from-addr-tag": "", // "address-id": "27321591", // "address": "TRf5JacJQRsF4Nm2zu11W6maDGeiEWQu9e", // "address-tag": "", // "fee": "1.000000000000000000", // "state": "confirmed", // "created-at": "1621852316553", // "updated-at": "1621852467041" // }, // ] // } // ch <- this.ParseTransactions(GetValue(response, "data"), currency, since, limit) return nil }() return ch } func (this *htx) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // fetchDeposits // // { // "id": "75115912", // "type": "deposit", // "sub-type": "NORMAL", // "request-id": "trc20usdt-a2e229a44ef2a948c874366230bb56aa73631cc0a03d177bd8b4c9d38262d7ff-200", // "currency": "usdt", // "chain": "trc20usdt", // "tx-hash": "a2e229a44ef2a948c874366230bb56aa73631cc0a03d177bd8b4c9d38262d7ff", // "amount": "2849.000000000000000000", // "from-addr-tag": "", // "address-id": "0", // "address": "TRFTd1FxepQE6CnpwzUEMEbFaLm5bJK67s", // "address-tag": "", // "fee": "0", // "state": "safe", // "wallet-confirm": "2", // "created-at": "1621843808662", // "updated-at": "1621843857137" // }, // // fetchWithdrawals // // { // "id": "61335312", // "type": "withdraw", // "sub-type": "NORMAL", // "currency": "usdt", // "chain": "trc20usdt", // "tx-hash": "30a3111f2fead74fae45c6218ca3150fc33cab2aa59cfe41526b96aae79ce4ec", // "amount": "12.000000000000000000", // "from-addr-tag": "", // "address-id": "27321591", // "address": "TRf5JacJQRsF4Nm2zu11W6maDGeiEWQu9e", // "address-tag": "", // "fee": "1.000000000000000000", // "state": "confirmed", // "created-at": "1621852316553", // "updated-at": "1621852467041" // } // // withdraw // // { // "status": "ok", // "data": "99562054" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var timestamp interface{} = this.SafeInteger(transaction, "created-at") var code interface{} = this.SafeCurrencyCode(this.SafeString(transaction, "currency")) var typeVar interface{} = this.SafeString(transaction, "type") if IsTrue(IsEqual(typeVar, "withdraw")) { typeVar = "withdrawal" } var feeCost interface{} = this.SafeString(transaction, "fee") if IsTrue(!IsEqual(feeCost, nil)) { feeCost = Precise.StringAbs(feeCost) } var networkId interface{} = this.SafeString(transaction, "chain") var txHash interface{} = this.SafeString(transaction, "tx-hash") if IsTrue(IsTrue(IsEqual(networkId, "ETH")) && IsTrue(IsLessThan(GetIndexOf(txHash, "0x"), 0))) { txHash = Add("0x", txHash) } var subType interface{} = this.SafeString(transaction, "sub-type") var internal interface{} = IsEqual(subType, "FAST") return map[string]interface{} { "info": transaction, "id": this.SafeString2(transaction, "id", "data"), "txid": txHash, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "network": this.NetworkIdToCode(networkId), "address": this.SafeString(transaction, "address"), "addressTo": nil, "addressFrom": nil, "tag": this.SafeString(transaction, "address-tag"), "tagTo": nil, "tagFrom": nil, "type": typeVar, "amount": this.SafeNumber(transaction, "amount"), "currency": code, "status": this.ParseTransactionStatus(this.SafeString(transaction, "state")), "updated": this.SafeInteger(transaction, "updated-at"), "comment": nil, "internal": internal, "fee": map[string]interface{} { "currency": code, "cost": this.ParseNumber(feeCost), "rate": nil, }, } } func (this *htx) ParseTransactionStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "unknown": "failed", "confirming": "pending", "confirmed": "ok", "safe": "ok", "orphan": "failed", "submitted": "pending", "canceled": "canceled", "reexamine": "pending", "reject": "failed", "pass": "pending", "wallet-reject": "failed", "confirm-error": "failed", "repealed": "failed", "wallet-transfer": "pending", "pre-transfer": "pending", } return this.SafeString(statuses, status, status) } /** * @method * @name htx#withdraw * @see https://www.htx.com/en-us/opend/newApiPages/?id=7ec4cc41-7773-11ed-9966-0242ac110003 * @description make a withdrawal * @param {string} code unified currency code * @param {float} amount the amount to withdraw * @param {string} address the address to withdraw to * @param {string} tag * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *htx) Withdraw(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) tag := GetArg(optionalArgs, 0, nil) _ = tag params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params tagparamsVariable := this.HandleWithdrawTagAndParams(tag, params); tag = GetValue(tagparamsVariable,0); params = GetValue(tagparamsVariable,1) retRes66948 := (<-this.LoadMarkets()) PanicOnError(retRes66948) this.CheckAddress(address) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "address": address, "currency": ToLower(GetValue(currency, "id")), } if IsTrue(!IsEqual(tag, nil)) { AddElementToObject(request, "addr-tag", tag) // only for XRP? } var networkCode interface{} = nil networkCodeparamsVariable := this.HandleNetworkCodeAndParams(params); networkCode = GetValue(networkCodeparamsVariable,0); params = GetValue(networkCodeparamsVariable,1) if IsTrue(!IsEqual(networkCode, nil)) { AddElementToObject(request, "chain", this.NetworkCodeToId(networkCode, code)) } amount = ParseFloat(this.CurrencyToPrecision(code, amount, networkCode)) var withdrawOptions interface{} = this.SafeValue(this.Options, "withdraw", map[string]interface{} {}) if IsTrue(this.SafeBool(withdrawOptions, "includeFee", false)) { var fee interface{} = this.SafeNumber(params, "fee") if IsTrue(IsEqual(fee, nil)) { currencies:= (<-this.FetchCurrencies()) PanicOnError(currencies) this.Currencies = this.DeepExtend(this.Currencies, currencies) var targetNetwork interface{} = this.SafeValue(GetValue(currency, "networks"), networkCode, map[string]interface{} {}) fee = this.SafeNumber(targetNetwork, "fee") if IsTrue(IsEqual(fee, nil)) { panic(ArgumentsRequired(Add(this.Id, " withdraw() function can not find withdraw fee for chosen network. You need to re-load markets with \"exchange.loadMarkets(true)\", or provide the \"fee\" parameter"))) } } // fee needs to be deducted from whole amount var feeString interface{} = this.CurrencyToPrecision(code, fee, networkCode) params = this.Omit(params, "fee") var amountString interface{} = this.NumberToString(amount) var amountSubtractedString interface{} = Precise.StringSub(amountString, feeString) var amountSubtracted interface{} = ParseFloat(amountSubtractedString) AddElementToObject(request, "fee", ParseFloat(feeString)) amount = ParseFloat(this.CurrencyToPrecision(code, amountSubtracted, networkCode)) } AddElementToObject(request, "amount", amount) response:= (<-this.SpotPrivatePostV1DwWithdrawApiCreate(this.Extend(request, params))) PanicOnError(response) // // { // "status": "ok", // "data": "99562054" // } // ch <- this.ParseTransaction(response, currency) return nil }() return ch } func (this *htx) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} { // // transfer // // { // "data": 12345, // "status": "ok" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var id interface{} = this.SafeString(transfer, "data") var code interface{} = this.SafeCurrencyCode(nil, currency) return map[string]interface{} { "info": transfer, "id": id, "timestamp": nil, "datetime": nil, "currency": code, "amount": nil, "fromAccount": nil, "toAccount": nil, "status": nil, } } /** * @method * @name htx#transfer * @description transfer currency internally between wallets on the same account * @see https://huobiapi.github.io/docs/dm/v1/en/#transfer-margin-between-spot-account-and-future-account * @see https://huobiapi.github.io/docs/spot/v1/en/#transfer-fund-between-spot-account-and-future-contract-account * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-transfer-margin-between-spot-account-and-usdt-margined-contracts-account * @see https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-spot-trading-account-to-cross-margin-account-cross * @see https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-spot-trading-account-to-isolated-margin-account-isolated * @see https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-cross-margin-account-to-spot-trading-account-cross * @see https://huobiapi.github.io/docs/spot/v1/en/#transfer-asset-from-isolated-margin-account-to-spot-trading-account-isolated * @param {string} code unified currency code * @param {float} amount amount to transfer * @param {string} fromAccount account to transfer from 'spot', 'future', 'swap' * @param {string} toAccount account to transfer to 'spot', 'future', 'swap' * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.symbol] used for isolated margin transfer * @param {string} [params.subType] 'linear' or 'inverse', only used when transfering to/from swap accounts * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure} */ func (this *htx) 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 retRes67878 := (<-this.LoadMarkets()) PanicOnError(retRes67878) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), "amount": ParseFloat(this.CurrencyToPrecision(code, amount)), } var subType interface{} = nil subTypeparamsVariable := this.HandleSubTypeAndParams("transfer", nil, params); subType = GetValue(subTypeparamsVariable,0); params = GetValue(subTypeparamsVariable,1) var fromAccountId interface{} = this.ConvertTypeToAccount(fromAccount) var toAccountId interface{} = this.ConvertTypeToAccount(toAccount) var toCross interface{} = IsEqual(toAccountId, "cross") var fromCross interface{} = IsEqual(fromAccountId, "cross") var toIsolated interface{} = this.InArray(toAccountId, this.Ids) var fromIsolated interface{} = this.InArray(fromAccountId, this.Ids) var fromSpot interface{} = IsEqual(fromAccountId, "pro") var toSpot interface{} = IsEqual(toAccountId, "pro") if IsTrue(IsTrue(fromSpot) && IsTrue(toSpot)) { panic(BadRequest(Add(Add(Add(Add(this.Id, " transfer () cannot make a transfer between "), fromAccount), " and "), toAccount))) } var fromOrToFuturesAccount interface{} = IsTrue((IsEqual(fromAccountId, "futures"))) || IsTrue((IsEqual(toAccountId, "futures"))) var response interface{} = nil if IsTrue(fromOrToFuturesAccount) { var typeVar interface{} = Add(Add(fromAccountId, "-to-"), toAccountId) typeVar = this.SafeString(params, "type", typeVar) AddElementToObject(request, "type", typeVar) response = (<-this.SpotPrivatePostV1FuturesTransfer(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsTrue(fromSpot) && IsTrue(toCross)) { response = (<-this.PrivatePostCrossMarginTransferIn(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsTrue(fromCross) && IsTrue(toSpot)) { response = (<-this.PrivatePostCrossMarginTransferOut(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsTrue(fromSpot) && IsTrue(toIsolated)) { AddElementToObject(request, "symbol", toAccountId) response = (<-this.PrivatePostDwTransferInMargin(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsTrue(fromIsolated) && IsTrue(toSpot)) { AddElementToObject(request, "symbol", fromAccountId) response = (<-this.PrivatePostDwTransferOutMargin(this.Extend(request, params))) PanicOnError(response) } else { if IsTrue(IsEqual(subType, "linear")) { if IsTrue(IsTrue((IsEqual(fromAccountId, "swap"))) || IsTrue((IsEqual(fromAccount, "linear-swap")))) { fromAccountId = "linear-swap" } else { toAccountId = "linear-swap" } // check if cross-margin or isolated var symbol interface{} = this.SafeString(params, "symbol") params = this.Omit(params, "symbol") if IsTrue(!IsEqual(symbol, nil)) { symbol = this.MarketId(symbol) AddElementToObject(request, "margin-account", symbol) } else { AddElementToObject(request, "margin-account", "USDT") // cross-margin } } AddElementToObject(request, "from", Ternary(IsTrue(fromSpot), "spot", fromAccountId)) AddElementToObject(request, "to", Ternary(IsTrue(toSpot), "spot", toAccountId)) response = (<-this.V2PrivatePostAccountTransfer(this.Extend(request, params))) PanicOnError(response) } // // { // "code": "200", // "data": "660150061", // "message": "Succeed", // "success": true, // "print-log": true // } // ch <- this.ParseTransfer(response, currency) return nil }() return ch } /** * @method * @name htx#fetchIsolatedBorrowRates * @description fetch the borrow interest rates of all currencies * @see https://huobiapi.github.io/docs/spot/v1/en/#get-loan-interest-rate-and-quota-isolated * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a list of [isolated borrow rate structures]{@link https://docs.ccxt.com/#/?id=isolated-borrow-rate-structure} */ func (this *htx) FetchIsolatedBorrowRates(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 retRes68658 := (<-this.LoadMarkets()) PanicOnError(retRes68658) response:= (<-this.SpotPrivateGetV1MarginLoanInfo(params)) PanicOnError(response) // // { // "status": "ok", // "data": [ // { // "symbol": "1inchusdt", // "currencies": [ // { // "currency": "1inch", // "interest-rate": "0.00098", // "min-loan-amt": "90.000000000000000000", // "max-loan-amt": "1000.000000000000000000", // "loanable-amt": "0.0", // "actual-rate": "0.00098" // }, // { // "currency": "usdt", // "interest-rate": "0.00098", // "min-loan-amt": "100.000000000000000000", // "max-loan-amt": "1000.000000000000000000", // "loanable-amt": "0.0", // "actual-rate": "0.00098" // } // ] // }, // ... // ] // } // var data interface{} = this.SafeValue(response, "data", []interface{}{}) ch <- this.ParseIsolatedBorrowRates(data) return nil }() return ch } func (this *htx) ParseIsolatedBorrowRate(info interface{}, optionalArgs ...interface{}) interface{} { // // { // "symbol": "1inchusdt", // "currencies": [ // { // "currency": "1inch", // "interest-rate": "0.00098", // "min-loan-amt": "90.000000000000000000", // "max-loan-amt": "1000.000000000000000000", // "loanable-amt": "0.0", // "actual-rate": "0.00098" // }, // { // "currency": "usdt", // "interest-rate": "0.00098", // "min-loan-amt": "100.000000000000000000", // "max-loan-amt": "1000.000000000000000000", // "loanable-amt": "0.0", // "actual-rate": "0.00098" // } // ] // }, // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(info, "symbol") var symbol interface{} = this.SafeSymbol(marketId, market) var currencies interface{} = this.SafeValue(info, "currencies", []interface{}{}) var baseData interface{} = this.SafeValue(currencies, 0) var quoteData interface{} = this.SafeValue(currencies, 1) var baseId interface{} = this.SafeString(baseData, "currency") var quoteId interface{} = this.SafeString(quoteData, "currency") return map[string]interface{} { "symbol": symbol, "base": this.SafeCurrencyCode(baseId), "baseRate": this.SafeNumber(baseData, "actual-rate"), "quote": this.SafeCurrencyCode(quoteId), "quoteRate": this.SafeNumber(quoteData, "actual-rate"), "period": 86400000, "timestamp": nil, "datetime": nil, "info": info, } } /** * @method * @name htx#fetchFundingRateHistory * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-historical-funding-rate * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-historical-funding-rate * @description fetches historical funding rate prices * @param {string} symbol unified symbol of the market to fetch the funding rate history for * @param {int} [since] not used by huobi, but filtered internally by ccxt * @param {int} [limit] not used by huobi, but filtered internally by ccxt * @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 *htx) 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"))) } var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchFundingRateHistory", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes696419 := (<-this.FetchPaginatedCallCursor("fetchFundingRateHistory", symbol, since, limit, params, "page_index", "current_page", 1, 50)) PanicOnError(retRes696419) ch <- retRes696419 return nil } retRes69668 := (<-this.LoadMarkets()) PanicOnError(retRes69668) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "contract_code": GetValue(market, "id"), } var response interface{} = nil if IsTrue(GetValue(market, "inverse")) { response = (<-this.ContractPublicGetSwapApiV1SwapHistoricalFundingRate(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "linear")) { response = (<-this.ContractPublicGetLinearSwapApiV1SwapHistoricalFundingRate(this.Extend(request, params))) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " fetchFundingRateHistory() supports inverse and linear swaps only"))) } // // { // "status": "ok", // "data": { // "total_page": 62, // "current_page": 1, // "total_size": 1237, // "data": [ // { // "avg_premium_index": "-0.000208064395065541", // "funding_rate": "0.000100000000000000", // "realized_rate": "0.000100000000000000", // "funding_time": "1638921600000", // "contract_code": "BTC-USDT", // "symbol": "BTC", // "fee_asset": "USDT" // }, // ] // }, // "ts": 1638939294277 // } // var data interface{} = this.SafeValue(response, "data") var cursor interface{} = this.SafeValue(data, "current_page") var result interface{} = this.SafeValue(data, "data", []interface{}{}) var rates interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(result)); i++ { var entry interface{} = GetValue(result, i) AddElementToObject(entry, "current_page", cursor) var marketId interface{} = this.SafeString(entry, "contract_code") var symbolInner interface{} = this.SafeSymbol(marketId) var timestamp interface{} = this.SafeInteger(entry, "funding_time") AppendToArray(&rates,map[string]interface{} { "info": entry, "symbol": symbolInner, "fundingRate": this.SafeNumber(entry, "funding_rate"), "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 *htx) ParseFundingRate(contract interface{}, optionalArgs ...interface{}) interface{} { // // { // "status": "ok", // "data": { // "estimated_rate": "0.000100000000000000", // "funding_rate": "0.000100000000000000", // "contract_code": "BCH-USD", // "symbol": "BCH", // "fee_asset": "BCH", // "funding_time": "1639094400000", // "next_funding_time": "1639123200000" // }, // "ts": 1639085854775 // } // market := GetArg(optionalArgs, 0, nil) _ = market var nextFundingRate interface{} = this.SafeNumber(contract, "estimated_rate") var fundingTimestamp interface{} = this.SafeInteger(contract, "funding_time") var nextFundingTimestamp interface{} = this.SafeInteger(contract, "next_funding_time") var fundingTimeString interface{} = this.SafeString(contract, "funding_time") var nextFundingTimeString interface{} = this.SafeString(contract, "next_funding_time") var millisecondsInterval interface{} = Precise.StringSub(nextFundingTimeString, fundingTimeString) var marketId interface{} = this.SafeString(contract, "contract_code") var symbol interface{} = this.SafeSymbol(marketId, market) return map[string]interface{} { "info": contract, "symbol": symbol, "markPrice": nil, "indexPrice": nil, "interestRate": nil, "estimatedSettlePrice": nil, "timestamp": nil, "datetime": nil, "fundingRate": this.SafeNumber(contract, "funding_rate"), "fundingTimestamp": fundingTimestamp, "fundingDatetime": this.Iso8601(fundingTimestamp), "nextFundingRate": nextFundingRate, "nextFundingTimestamp": nextFundingTimestamp, "nextFundingDatetime": this.Iso8601(nextFundingTimestamp), "previousFundingRate": nil, "previousFundingTimestamp": nil, "previousFundingDatetime": nil, "interval": this.ParseFundingInterval(millisecondsInterval), } } func (this *htx) ParseFundingInterval(interval interface{}) interface{} { var intervals interface{} = map[string]interface{} { "3600000": "1h", "14400000": "4h", "28800000": "8h", "57600000": "16h", "86400000": "24h", } return this.SafeString(intervals, interval, interval) } /** * @method * @name htx#fetchFundingRate * @description fetch the current funding rate * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-funding-rate * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-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 *htx) 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 retRes70918 := (<-this.LoadMarkets()) PanicOnError(retRes70918) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "contract_code": GetValue(market, "id"), } var response interface{} = nil if IsTrue(GetValue(market, "inverse")) { response = (<-this.ContractPublicGetSwapApiV1SwapFundingRate(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "linear")) { response = (<-this.ContractPublicGetLinearSwapApiV1SwapFundingRate(this.Extend(request, params))) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " fetchFundingRate() supports inverse and linear swaps only"))) } // // { // "status": "ok", // "data": { // "estimated_rate": "0.000100000000000000", // "funding_rate": "0.000100000000000000", // "contract_code": "BTC-USDT", // "symbol": "BTC", // "fee_asset": "USDT", // "funding_time": "1603699200000", // "next_funding_time": "1603728000000" // }, // "ts": 1603696494714 // } // var result interface{} = this.SafeValue(response, "data", map[string]interface{} {}) ch <- this.ParseFundingRate(result, market) return nil }() return ch } /** * @method * @name htx#fetchFundingRates * @description fetch the funding rate for multiple markets * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-a-batch-of-funding-rate * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-a-batch-of-funding-rate * @param {string[]|undefined} symbols list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rates-structure}, indexed by market symbols */ func (this *htx) FetchFundingRates(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 retRes71348 := (<-this.LoadMarkets()) PanicOnError(retRes71348) symbols = this.MarketSymbols(symbols) var options interface{} = this.SafeValue(this.Options, "fetchFundingRates", map[string]interface{} {}) var defaultSubType interface{} = this.SafeString(this.Options, "defaultSubType", "inverse") var subType interface{} = this.SafeString(options, "subType", defaultSubType) subType = this.SafeString(params, "subType", subType) var request interface{} = map[string]interface{} {} params = this.Omit(params, "subType") var response interface{} = nil if IsTrue(IsEqual(subType, "linear")) { response = (<-this.ContractPublicGetLinearSwapApiV1SwapBatchFundingRate(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(subType, "inverse")) { response = (<-this.ContractPublicGetSwapApiV1SwapBatchFundingRate(this.Extend(request, params))) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " fetchFundingRates() not support this market type"))) } // // { // "status": "ok", // "data": [ // { // "estimated_rate": "0.000100000000000000", // "funding_rate": "0.000100000000000000", // "contract_code": "MANA-USDT", // "symbol": "MANA", // "fee_asset": "USDT", // "funding_time": "1643356800000", // "next_funding_time": "1643385600000", // "trade_partition":"USDT" // }, // ], // "ts": 1643346173103 // } // var data interface{} = this.SafeValue(response, "data", []interface{}{}) ch <- this.ParseFundingRates(data, symbols) return nil }() return ch } /** * @method * @name htx#fetchBorrowInterest * @description fetch the interest owed by the user for borrowing currency for margin trading * @see https://huobiapi.github.io/docs/spot/v1/en/#search-past-margin-orders-cross * @see https://huobiapi.github.io/docs/spot/v1/en/#search-past-margin-orders-isolated * @param {string} code unified currency code * @param {string} symbol unified market symbol when fetch interest in isolated markets * @param {int} [since] the earliest time in ms to fetch borrrow interest for * @param {int} [limit] the maximum number of structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [borrow interest structures]{@link https://docs.ccxt.com/#/?id=borrow-interest-structure} */ func (this *htx) FetchBorrowInterest(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code symbol := GetArg(optionalArgs, 1, nil) _ = symbol since := GetArg(optionalArgs, 2, nil) _ = since limit := GetArg(optionalArgs, 3, nil) _ = limit params := GetArg(optionalArgs, 4, map[string]interface{} {}) _ = params retRes71888 := (<-this.LoadMarkets()) PanicOnError(retRes71888) var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchBorrowInterest", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start-date", this.Yyyymmdd(since)) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", limit) } var market interface{} = nil var response interface{} = nil if IsTrue(IsEqual(marginMode, "isolated")) { if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "symbol", GetValue(market, "id")) } response = (<-this.PrivateGetMarginLoanOrders(this.Extend(request, params))) PanicOnError(response) } else { if IsTrue(!IsEqual(code, nil)) { var currency interface{} = this.Currency(code) AddElementToObject(request, "currency", GetValue(currency, "id")) } response = (<-this.PrivateGetCrossMarginLoanOrders(this.Extend(request, params))) PanicOnError(response) } // // { // "status":"ok", // "data":[ // { // "loan-balance":"0.100000000000000000", // "interest-balance":"0.000200000000000000", // "loan-amount":"0.100000000000000000", // "accrued-at":1511169724531, // "interest-amount":"0.000200000000000000", // "filled-points":"0.2", // "filled-ht":"0.2", // "currency":"btc", // "id":394, // "state":"accrual", // "account-id":17747, // "user-id":119913, // "created-at":1511169724531 // } // ] // } // var data interface{} = this.SafeValue(response, "data") var interest interface{} = this.ParseBorrowInterests(data, market) ch <- this.FilterByCurrencySinceLimit(interest, code, since, limit) return nil }() return ch } func (this *htx) ParseBorrowInterest(info interface{}, optionalArgs ...interface{}) interface{} { // isolated // { // "interest-rate":"0.000040830000000000", // "user-id":35930539, // "account-id":48916071, // "updated-at":1649320794195, // "deduct-rate":"1", // "day-interest-rate":"0.000980000000000000", // "hour-interest-rate":"0.000040830000000000", // "loan-balance":"100.790000000000000000", // "interest-balance":"0.004115260000000000", // "loan-amount":"100.790000000000000000", // "paid-coin":"0.000000000000000000", // "accrued-at":1649320794148, // "created-at":1649320794148, // "interest-amount":"0.004115260000000000", // "deduct-amount":"0", // "deduct-currency":"", // "paid-point":"0.000000000000000000", // "currency":"usdt", // "symbol":"ltcusdt", // "id":20242721, // } // // cross // { // "id":3416576, // "user-id":35930539, // "account-id":48956839, // "currency":"usdt", // "loan-amount":"102", // "loan-balance":"102", // "interest-amount":"0.00416466", // "interest-balance":"0.00416466", // "created-at":1649322735333, // "accrued-at":1649322735382, // "state":"accrual", // "filled-points":"0", // "filled-ht":"0" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(info, "symbol") var marginMode interface{} = Ternary(IsTrue((IsEqual(marketId, nil))), "cross", "isolated") market = this.SafeMarket(marketId) var symbol interface{} = this.SafeString(market, "symbol") var timestamp interface{} = this.SafeInteger(info, "accrued-at") return map[string]interface{} { "info": info, "symbol": symbol, "currency": this.SafeCurrencyCode(this.SafeString(info, "currency")), "interest": this.SafeNumber(info, "interest-amount"), "interestRate": this.SafeNumber(info, "interest-rate"), "amountBorrowed": this.SafeNumber(info, "loan-amount"), "marginMode": marginMode, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), } } func (this *htx) Nonce() interface{} { return Subtract(this.Milliseconds(), GetValue(this.Options, "timeDifference")) } func (this *htx) Sign(path interface{}, optionalArgs ...interface{}) interface{} { api := GetArg(optionalArgs, 0, "public") _ = api method := GetArg(optionalArgs, 1, "GET") _ = method params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params headers := GetArg(optionalArgs, 3, nil) _ = headers body := GetArg(optionalArgs, 4, nil) _ = body var url interface{} = "/" var query interface{} = this.Omit(params, this.ExtractParams(path)) if IsTrue(IsString(api)) { // signing implementation for the old endpoints if IsTrue(IsTrue((IsEqual(api, "public"))) || IsTrue((IsEqual(api, "private")))) { url = Add(url, this.Version) } else if IsTrue(IsTrue((IsEqual(api, "v2Public"))) || IsTrue((IsEqual(api, "v2Private")))) { url = Add(url, "v2") } url = Add(url, Add("/", this.ImplodeParams(path, params))) if IsTrue(IsTrue(IsEqual(api, "private")) || IsTrue(IsEqual(api, "v2Private"))) { this.CheckRequiredCredentials() var timestamp interface{} = this.Ymdhms(this.Nonce(), "T") var request interface{} = map[string]interface{} { "SignatureMethod": "HmacSHA256", "SignatureVersion": "2", "AccessKeyId": this.ApiKey, "Timestamp": timestamp, } if IsTrue(!IsEqual(method, "POST")) { request = this.Extend(request, query) } var sortedRequest interface{} = this.Keysort(request) var auth interface{} = this.Urlencode(sortedRequest) // unfortunately, PHP demands double quotes for the escaped newline symbol var payload interface{} = Join([]interface{}{method, this.Hostname, url, auth}, "\n") // eslint-disable-line quotes var signature interface{} = this.Hmac(this.Encode(payload), this.Encode(this.Secret), sha256, "base64") auth = Add(auth, Add("&", this.Urlencode(map[string]interface{} { "Signature": signature, }))) url = Add(url, Add("?", auth)) if IsTrue(IsEqual(method, "POST")) { body = this.Json(query) headers = map[string]interface{} { "Content-Type": "application/json", } } else { headers = map[string]interface{} { "Content-Type": "application/x-www-form-urlencoded", } } } else { if IsTrue(GetArrayLength(ObjectKeys(query))) { url = Add(url, Add("?", this.Urlencode(query))) } } url = Add(this.ImplodeParams(GetValue(GetValue(this.Urls, "api"), api), map[string]interface{} { "hostname": this.Hostname, }), url) } else { // signing implementation for the new endpoints // const [ type, access ] = api; var typeVar interface{} = this.SafeString(api, 0) var access interface{} = this.SafeString(api, 1) var levelOneNestedPath interface{} = this.SafeString(api, 2) var levelTwoNestedPath interface{} = this.SafeString(api, 3) var hostname interface{} = nil var hostnames interface{} = this.SafeValue(GetValue(this.Urls, "hostnames"), typeVar) if IsTrue(!IsString(hostnames)) { hostnames = this.SafeValue(hostnames, levelOneNestedPath) if IsTrue(IsTrue((!IsString(hostnames))) && IsTrue((!IsEqual(levelTwoNestedPath, nil)))) { hostnames = this.SafeValue(hostnames, levelTwoNestedPath) } } hostname = hostnames url = Add(url, this.ImplodeParams(path, params)) if IsTrue(IsEqual(access, "public")) { if IsTrue(GetArrayLength(ObjectKeys(query))) { url = Add(url, Add("?", this.Urlencode(query))) } } else if IsTrue(IsEqual(access, "private")) { this.CheckRequiredCredentials() if IsTrue(IsEqual(method, "POST")) { var options interface{} = this.SafeValue(this.Options, "broker", map[string]interface{} {}) var id interface{} = this.SafeString(options, "id", "AA03022abc") if IsTrue(IsTrue(IsEqual(GetIndexOf(path, "cancel"), OpNeg(1))) && IsTrue(EndsWith(path, "order"))) { // swap order placement var channelCode interface{} = this.SafeString(params, "channel_code") if IsTrue(IsEqual(channelCode, nil)) { AddElementToObject(params, "channel_code", id) } } else if IsTrue(EndsWith(path, "orders/place")) { // spot order placement var clientOrderId interface{} = this.SafeString(params, "client-order-id") if IsTrue(IsEqual(clientOrderId, nil)) { AddElementToObject(params, "client-order-id", Add(id, this.Uuid())) } } } var timestamp interface{} = this.Ymdhms(this.Nonce(), "T") var request interface{} = map[string]interface{} { "SignatureMethod": "HmacSHA256", "SignatureVersion": "2", "AccessKeyId": this.ApiKey, "Timestamp": timestamp, } // sorting needs such flow exactly, before urlencoding (more at: https://github.com/ccxt/ccxt/issues/24930 ) request = this.Keysort(request) if IsTrue(!IsEqual(method, "POST")) { var sortedQuery interface{} = this.Keysort(query) request = this.Extend(request, sortedQuery) } var auth interface{} = Replace(this.Urlencode(request), "%2c", "%2C") // in c# it manually needs to be uppercased // unfortunately, PHP demands double quotes for the escaped newline symbol var payload interface{} = Join([]interface{}{method, hostname, url, auth}, "\n") // eslint-disable-line quotes var signature interface{} = this.Hmac(this.Encode(payload), this.Encode(this.Secret), sha256, "base64") auth = Add(auth, Add("&", this.Urlencode(map[string]interface{} { "Signature": signature, }))) url = Add(url, Add("?", auth)) if IsTrue(IsEqual(method, "POST")) { body = this.Json(query) if IsTrue(IsEqual(GetArrayLength(body), 2)) { body = "{}" } headers = map[string]interface{} { "Content-Type": "application/json", } } else { headers = map[string]interface{} { "Content-Type": "application/x-www-form-urlencoded", } } } url = Add(this.ImplodeParams(GetValue(GetValue(this.Urls, "api"), typeVar), map[string]interface{} { "hostname": hostname, }), url) } return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } func (this *htx) HandleErrors(httpCode interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} { if IsTrue(IsEqual(response, nil)) { return nil // fallback to default error handler } if IsTrue(InOp(response, "status")) { // // {"status":"error","err-code":"order-limitorder-amount-min-error","err-msg":"limit order amount error, min: `0.001`","data":null} // var status interface{} = this.SafeString(response, "status") if IsTrue(IsEqual(status, "error")) { var code interface{} = this.SafeString2(response, "err-code", "err_code") var feedback interface{} = Add(Add(this.Id, " "), body) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), body, feedback) this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), code, feedback) var message interface{} = this.SafeString2(response, "err-msg", "err_msg") this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), message, feedback) panic(ExchangeError(feedback)) } } if IsTrue(InOp(response, "code")) { // {code: '1003', message: 'invalid signature'} var feedback interface{} = Add(Add(this.Id, " "), body) var code interface{} = this.SafeString(response, "code") this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), code, feedback) } return nil } /** * @method * @name htx#fetchFundingHistory * @description fetch the history of funding payments paid and received on this account * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-account-financial-records-via-multiple-fields-new // linear swaps * @see https://huobiapi.github.io/docs/dm/v1/en/#query-financial-records-via-multiple-fields-new // coin-m futures * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-financial-records-via-multiple-fields-new // coin-m swaps * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch funding history for * @param {int} [limit] the maximum number of funding history structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [funding history structure]{@link https://docs.ccxt.com/#/?id=funding-history-structure} */ func (this *htx) FetchFundingHistory(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 retRes74758 := (<-this.LoadMarkets()) PanicOnError(retRes74758) var market interface{} = this.Market(symbol) marketTypequeryVariable := this.HandleMarketTypeAndParams("fetchFundingHistory", market, params); marketType := GetValue(marketTypequeryVariable,0); query := GetValue(marketTypequeryVariable,1) var request interface{} = map[string]interface{} { "type": "30,31", } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start_date", since) } var response interface{} = nil if IsTrue(IsEqual(marketType, "swap")) { AddElementToObject(request, "contract", GetValue(market, "id")) if IsTrue(GetValue(market, "linear")) { // // { // "status": "ok", // "data": { // "financial_record": [ // { // "id": "1320088022", // "type": "30", // "amount": "0.004732510000000000", // "ts": "1641168019321", // "contract_code": "BTC-USDT", // "asset": "USDT", // "margin_account": "BTC-USDT", // "face_margin_account": '' // }, // ], // "remain_size": "0", // "next_id": null // }, // "ts": "1641189898425" // } // var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchFundingHistory", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) if IsTrue(IsEqual(marginMode, "isolated")) { AddElementToObject(request, "mar_acct", GetValue(market, "id")) } else { AddElementToObject(request, "mar_acct", GetValue(market, "quoteId")) } response = (<-this.ContractPrivatePostLinearSwapApiV3SwapFinancialRecordExact(this.Extend(request, query))) PanicOnError(response) } else { // // { // "code": 200, // "msg": "", // "data": [ // { // "query_id": 138798248, // "id": 117840, // "type": 5, // "amount": -0.024464850000000000, // "ts": 1638758435635, // "contract_code": "BTC-USDT-211210", // "asset": "USDT", // "margin_account": "USDT", // "face_margin_account": "" // } // ], // "ts": 1604312615051 // } // response = (<-this.ContractPrivatePostSwapApiV3SwapFinancialRecordExact(this.Extend(request, query))) PanicOnError(response) } } else { AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.ContractPrivatePostApiV3ContractFinancialRecordExact(this.Extend(request, query))) PanicOnError(response) } var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseIncomes(data, market, since, limit) return nil }() return ch } /** * @method * @name htx#setLeverage * @description set the level of leverage for a market * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-switch-leverage * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-switch-leverage * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#switch-leverage * @see https://huobiapi.github.io/docs/dm/v1/en/#switch-leverage // Coin-m futures * @param {float} leverage the rate of leverage * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} response from the exchange */ func (this *htx) 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"))) } retRes75678 := (<-this.LoadMarkets()) PanicOnError(retRes75678) var market interface{} = this.Market(symbol) marketTypequeryVariable := this.HandleMarketTypeAndParams("setLeverage", market, params); marketType := GetValue(marketTypequeryVariable,0); query := GetValue(marketTypequeryVariable,1) var request interface{} = map[string]interface{} { "lever_rate": leverage, } if IsTrue(IsTrue(IsEqual(marketType, "future")) && IsTrue(GetValue(market, "inverse"))) { AddElementToObject(request, "symbol", GetValue(market, "settleId")) } else { AddElementToObject(request, "contract_code", GetValue(market, "id")) } var response interface{} = nil if IsTrue(GetValue(market, "linear")) { var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("setLeverage", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) if IsTrue(IsEqual(marginMode, "isolated")) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapSwitchLeverRate(this.Extend(request, query))) PanicOnError(response) } else if IsTrue(IsEqual(marginMode, "cross")) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossSwitchLeverRate(this.Extend(request, query))) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " setLeverage() not support this market type"))) } } else { if IsTrue(IsEqual(marketType, "future")) { response = (<-this.ContractPrivatePostApiV1ContractSwitchLeverRate(this.Extend(request, query))) PanicOnError(response) } else if IsTrue(IsEqual(marketType, "swap")) { response = (<-this.ContractPrivatePostSwapApiV1SwapSwitchLeverRate(this.Extend(request, query))) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " setLeverage() not support this market type"))) } } ch <- response return nil }() return ch } func (this *htx) ParseIncome(income interface{}, optionalArgs ...interface{}) interface{} { // // { // "id": "1667161118", // "symbol": "BTC", // "type": "31", // "amount": "-2.11306593188E-7", // "ts": "1641139308983", // "contract_code": "BTC-USD" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(income, "contract_code") var symbol interface{} = this.SafeSymbol(marketId, market) var amount interface{} = this.SafeNumber(income, "amount") var timestamp interface{} = this.SafeInteger(income, "ts") var id interface{} = this.SafeString(income, "id") var currencyId interface{} = this.SafeString2(income, "symbol", "asset") var code interface{} = this.SafeCurrencyCode(currencyId) return map[string]interface{} { "info": income, "symbol": symbol, "code": code, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "id": id, "amount": amount, } } func (this *htx) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} { // // { // "symbol": "BTC", // "contract_code": "BTC-USDT", // "volume": "1.000000000000000000", // "available": "1.000000000000000000", // "frozen": "0E-18", // "cost_open": "47162.000000000000000000", // "cost_hold": "47151.300000000000000000", // "profit_unreal": "0.007300000000000000", // "profit_rate": "-0.000144183876850008", // "lever_rate": "2", // "position_margin": "23.579300000000000000", // "direction": "buy", // "profit": "-0.003400000000000000", // "last_price": "47158.6", // "margin_asset": "USDT", // "margin_mode": "isolated", // "margin_account": "BTC-USDT", // "margin_balance": "24.973020070000000000", // "margin_position": "23.579300000000000000", // "margin_frozen": "0", // "margin_available": "1.393720070000000000", // "profit_real": "0E-18", // "risk_rate": "1.044107779705080303", // "withdraw_available": "1.386420070000000000000000000000000000", // "liquidation_price": "22353.229148614609571788", // "adjust_factor": "0.015000000000000000", // "margin_static": "24.965720070000000000" // } // market := GetArg(optionalArgs, 0, nil) _ = market market = this.SafeMarket(this.SafeString(position, "contract_code")) var symbol interface{} = GetValue(market, "symbol") var contracts interface{} = this.SafeString(position, "volume") var contractSize interface{} = this.SafeValue(market, "contractSize") var contractSizeString interface{} = this.NumberToString(contractSize) var entryPrice interface{} = this.SafeNumber(position, "cost_open") var initialMargin interface{} = this.SafeString(position, "position_margin") var rawSide interface{} = this.SafeString(position, "direction") var side interface{} = Ternary(IsTrue((IsEqual(rawSide, "buy"))), "long", "short") var unrealizedProfit interface{} = this.SafeNumber(position, "profit_unreal") var marginMode interface{} = this.SafeString(position, "margin_mode") var leverage interface{} = this.SafeString(position, "lever_rate") var percentage interface{} = Precise.StringMul(this.SafeString(position, "profit_rate"), "100") var lastPrice interface{} = this.SafeString(position, "last_price") var faceValue interface{} = Precise.StringMul(contracts, contractSizeString) var notional interface{} = nil if IsTrue(GetValue(market, "linear")) { notional = Precise.StringMul(faceValue, lastPrice) } else { notional = Precise.StringDiv(faceValue, lastPrice) marginMode = "cross" } var intialMarginPercentage interface{} = Precise.StringDiv(initialMargin, notional) var collateral interface{} = this.SafeString(position, "margin_balance") var liquidationPrice interface{} = this.SafeNumber(position, "liquidation_price") var adjustmentFactor interface{} = this.SafeString(position, "adjust_factor") var maintenanceMarginPercentage interface{} = Precise.StringDiv(adjustmentFactor, leverage) var maintenanceMargin interface{} = Precise.StringMul(maintenanceMarginPercentage, notional) var marginRatio interface{} = Precise.StringDiv(maintenanceMargin, collateral) return this.SafePosition(map[string]interface{} { "info": position, "id": nil, "symbol": symbol, "contracts": this.ParseNumber(contracts), "contractSize": contractSize, "entryPrice": entryPrice, "collateral": this.ParseNumber(collateral), "side": side, "unrealizedPnl": unrealizedProfit, "leverage": this.ParseNumber(leverage), "percentage": this.ParseNumber(percentage), "marginMode": marginMode, "notional": this.ParseNumber(notional), "markPrice": nil, "lastPrice": nil, "liquidationPrice": liquidationPrice, "initialMargin": this.ParseNumber(initialMargin), "initialMarginPercentage": this.ParseNumber(intialMarginPercentage), "maintenanceMargin": this.ParseNumber(maintenanceMargin), "maintenanceMarginPercentage": this.ParseNumber(maintenanceMarginPercentage), "marginRatio": this.ParseNumber(marginRatio), "timestamp": nil, "datetime": nil, "hedged": nil, "lastUpdateTimestamp": nil, "stopLossPrice": nil, "takeProfitPrice": nil, }) } /** * @method * @name htx#fetchPositions * @description fetch all open positions * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-query-user-39-s-position-information * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-query-user-s-position-information * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-user-s-position-information * @see https://huobiapi.github.io/docs/dm/v1/en/#query-user-s-position-information * @param {string[]} [symbols] list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.subType] 'linear' or 'inverse' * @param {string} [params.type] *inverse only* 'future', or 'swap' * @param {string} [params.marginMode] *linear only* 'cross' or 'isolated' * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *htx) 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 retRes77668 := (<-this.LoadMarkets()) PanicOnError(retRes77668) symbols = this.MarketSymbols(symbols) var market interface{} = nil if IsTrue(!IsEqual(symbols, nil)) { var symbolsLength interface{} = GetArrayLength(symbols) if IsTrue(IsGreaterThan(symbolsLength, 0)) { var first interface{} = this.SafeString(symbols, 0) market = this.Market(first) } } var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchPositions", params, "cross"); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) var subType interface{} = nil subTypeparamsVariable := this.HandleSubTypeAndParams("fetchPositions", market, params, "linear"); subType = GetValue(subTypeparamsVariable,0); params = GetValue(subTypeparamsVariable,1) var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchPositions", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) if IsTrue(IsEqual(marketType, "spot")) { marketType = "future" } var response interface{} = nil if IsTrue(IsEqual(subType, "linear")) { if IsTrue(IsEqual(marginMode, "isolated")) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapPositionInfo(params)) PanicOnError(response) } else if IsTrue(IsEqual(marginMode, "cross")) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossPositionInfo(params)) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " fetchPositions() not support this market type"))) } } else { if IsTrue(IsEqual(marketType, "future")) { response = (<-this.ContractPrivatePostApiV1ContractPositionInfo(params)) PanicOnError(response) } else if IsTrue(IsEqual(marketType, "swap")) { response = (<-this.ContractPrivatePostSwapApiV1SwapPositionInfo(params)) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " fetchPositions() not support this market type"))) } } var data interface{} = this.SafeValue(response, "data", []interface{}{}) var timestamp interface{} = this.SafeInteger(response, "ts") var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var position interface{} = GetValue(data, i) var parsed interface{} = this.ParsePosition(position) AppendToArray(&result,this.Extend(parsed, map[string]interface{} { "timestamp": timestamp, "datetime": this.Iso8601(timestamp), })) } ch <- this.FilterByArrayPositions(result, "symbol", symbols, false) return nil }() return ch } /** * @method * @name htx#fetchPosition * @description fetch data on a single open contract trade position * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-query-assets-and-positions * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-query-assets-and-positions * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-assets-and-positions * @see https://huobiapi.github.io/docs/dm/v1/en/#query-assets-and-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 * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *htx) 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 retRes79078 := (<-this.LoadMarkets()) PanicOnError(retRes79078) var market interface{} = this.Market(symbol) var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchPosition", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) marginMode = Ternary(IsTrue((IsEqual(marginMode, nil))), "cross", marginMode) marketTypequeryVariable := this.HandleMarketTypeAndParams("fetchPosition", market, params); marketType := GetValue(marketTypequeryVariable,0); query := GetValue(marketTypequeryVariable,1) var request interface{} = map[string]interface{} {} if IsTrue(IsTrue(GetValue(market, "future")) && IsTrue(GetValue(market, "inverse"))) { AddElementToObject(request, "symbol", GetValue(market, "settleId")) } else { if IsTrue(IsEqual(marginMode, "cross")) { AddElementToObject(request, "margin_account", "USDT") // only allowed value } AddElementToObject(request, "contract_code", GetValue(market, "id")) } var response interface{} = nil if IsTrue(GetValue(market, "linear")) { if IsTrue(IsEqual(marginMode, "isolated")) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapAccountPositionInfo(this.Extend(request, query))) PanicOnError(response) } else if IsTrue(IsEqual(marginMode, "cross")) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossAccountPositionInfo(this.Extend(request, query))) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " fetchPosition() not support this market type"))) } } else { if IsTrue(IsEqual(marketType, "future")) { response = (<-this.ContractPrivatePostApiV1ContractAccountPositionInfo(this.Extend(request, query))) PanicOnError(response) } else if IsTrue(IsEqual(marketType, "swap")) { response = (<-this.ContractPrivatePostSwapApiV1SwapAccountPositionInfo(this.Extend(request, query))) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " setLeverage() not support this market type"))) } } var data interface{} = this.SafeValue(response, "data") var account interface{} = nil if IsTrue(IsEqual(marginMode, "cross")) { account = data } else { account = this.SafeValue(data, 0) } var omitted interface{} = this.Omit(account, []interface{}{"positions"}) var positions interface{} = this.SafeValue(account, "positions") var position interface{} = nil if IsTrue(IsTrue(GetValue(market, "future")) && IsTrue(GetValue(market, "inverse"))) { for i := 0; IsLessThan(i, GetArrayLength(positions)); i++ { var entry interface{} = GetValue(positions, i) if IsTrue(IsEqual(GetValue(entry, "contract_code"), GetValue(market, "id"))) { position = entry break } } } else { position = this.SafeValue(positions, 0) } var timestamp interface{} = this.SafeInteger(response, "ts") var parsed interface{} = this.ParsePosition(this.Extend(position, omitted)) AddElementToObject(parsed, "timestamp", timestamp) AddElementToObject(parsed, "datetime", this.Iso8601(timestamp)) ch <- parsed return nil }() return ch } func (this *htx) ParseLedgerEntryType(typeVar interface{}) interface{} { var types interface{} = map[string]interface{} { "trade": "trade", "etf": "trade", "transact-fee": "fee", "fee-deduction": "fee", "transfer": "transfer", "credit": "credit", "liquidation": "trade", "interest": "credit", "deposit": "deposit", "withdraw": "withdrawal", "withdraw-fee": "fee", "exchange": "exchange", "other-types": "transfer", "rebate": "rebate", } return this.SafeString(types, typeVar, typeVar) } func (this *htx) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} { // // { // "accountId": 10000001, // "currency": "usdt", // "transactAmt": 10.000000000000000000, // "transactType": "transfer", // "transferType": "margin-transfer-out", // "transactId": 0, // "transactTime": 1629882331066, // "transferer": 28483123, // "transferee": 13496526 // } // 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 id interface{} = this.SafeString(item, "transactId") var transferType interface{} = this.SafeString(item, "transferType") var timestamp interface{} = this.SafeInteger(item, "transactTime") var account interface{} = this.SafeString(item, "accountId") return this.SafeLedgerEntry(map[string]interface{} { "info": item, "id": id, "direction": this.SafeString(item, "direction"), "account": account, "referenceId": id, "referenceAccount": account, "type": this.ParseLedgerEntryType(transferType), "currency": code, "amount": this.SafeNumber(item, "transactAmt"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "before": nil, "after": nil, "status": nil, "fee": nil, }, currency) } /** * @method * @name htx#fetchLedger * @description fetch the history of changes, actions done by the user or operations that altered the balance of the user * @see https://huobiapi.github.io/docs/spot/v1/en/#get-account-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 {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 *htx) 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 retRes82288 := (<-this.LoadMarkets()) PanicOnError(retRes82288) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchLedger", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes823219 := (<-this.FetchPaginatedCallDynamic("fetchLedger", code, since, limit, params, 500)) PanicOnError(retRes823219) ch <- retRes823219 return nil } accountId:= (<-this.FetchAccountIdByType("spot", nil, nil, params)) PanicOnError(accountId) var request interface{} = map[string]interface{} { "accountId": accountId, } 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, "startTime", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // max 500 } requestparamsVariable := this.HandleUntilOption("endTime", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.SpotPrivateGetV2AccountLedger(this.Extend(request, params))) PanicOnError(response) // // { // "code": 200, // "message": "success", // "data": [ // { // "accountId": 10000001, // "currency": "usdt", // "transactAmt": 10.000000000000000000, // "transactType": "transfer", // "transferType": "margin-transfer-out", // "transactId": 0, // "transactTime": 1629882331066, // "transferer": 28483123, // "transferee": 13496526 // }, // { // "accountId": 10000001, // "currency": "usdt", // "transactAmt": -10.000000000000000000, // "transactType": "transfer", // "transferType": "margin-transfer-in", // "transactId": 0, // "transactTime": 1629882096562, // "transferer": 13496526, // "transferee": 28483123 // } // ], // "nextId": 1624316679, // "ok": true // } // var data interface{} = this.SafeValue(response, "data", []interface{}{}) ch <- this.ParseLedger(data, currency, since, limit) return nil }() return ch } /** * @method * @name htx#fetchLeverageTiers * @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes * @param {string[]|undefined} symbols list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [leverage tiers structures]{@link https://docs.ccxt.com/#/?id=leverage-tiers-structure}, indexed by market symbols */ func (this *htx) FetchLeverageTiers(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 retRes83038 := (<-this.LoadMarkets()) PanicOnError(retRes83038) response:= (<-this.ContractPublicGetLinearSwapApiV1SwapAdjustfactor(params)) PanicOnError(response) // // { // "status": "ok", // "data": [ // { // "symbol": "MANA", // "contract_code": "MANA-USDT", // "margin_mode": "isolated", // "trade_partition": "USDT", // "list": [ // { // "lever_rate": 75, // "ladders": [ // { // "ladder": 0, // "min_size": 0, // "max_size": 999, // "adjust_factor": 0.7 // }, // ... // ] // } // ... // ] // }, // ... // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseLeverageTiers(data, symbols, "contract_code") return nil }() return ch } func (this *htx) ParseMarketLeverageTiers(info interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market var currencyId interface{} = this.SafeString(info, "trade_partition") var marketId interface{} = this.SafeString(info, "contract_code") var tiers interface{} = []interface{}{} var brackets interface{} = this.SafeList(info, "list", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(brackets)); i++ { var item interface{} = GetValue(brackets, i) var leverage interface{} = this.SafeString(item, "lever_rate") var ladders interface{} = this.SafeList(item, "ladders", []interface{}{}) for k := 0; IsLessThan(k, GetArrayLength(ladders)); k++ { var bracket interface{} = GetValue(ladders, k) var adjustFactor interface{} = this.SafeString(bracket, "adjust_factor") AppendToArray(&tiers,map[string]interface{} { "tier": this.SafeInteger(bracket, "ladder"), "symbol": this.SafeSymbol(marketId, market, nil, "swap"), "currency": this.SafeCurrencyCode(currencyId), "minNotional": this.SafeNumber(bracket, "min_size"), "maxNotional": this.SafeNumber(bracket, "max_size"), "maintenanceMarginRate": this.ParseNumber(Precise.StringDiv(adjustFactor, leverage)), "maxLeverage": this.ParseNumber(leverage), "info": bracket, }) } } return tiers } /** * @method * @name htx#fetchOpenInterestHistory * @description Retrieves the open interest history of a currency * @see https://huobiapi.github.io/docs/dm/v1/en/#query-information-on-open-interest * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-information-on-open-interest * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-information-on-open-interest * @param {string} symbol Unified CCXT market symbol * @param {string} timeframe '1h', '4h', '12h', or '1d' * @param {int} [since] Not used by huobi api, but response parsed by CCXT * @param {int} [limit] Default:48,Data Range [1,200] * @param {object} [params] Exchange specific parameters * @param {int} [params.amount_type] *required* Open interest unit. 1-cont,2-cryptocurrency * @param {int} [params.pair] eg BTC-USDT *Only for USDT-M* * @returns {object} an array of [open interest structures]{@link https://docs.ccxt.com/#/?id=open-interest-structure} */ func (this *htx) FetchOpenInterestHistory(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) timeframe := GetArg(optionalArgs, 0, "1h") _ = timeframe since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params if IsTrue(IsTrue(IsTrue(IsTrue(!IsEqual(timeframe, "1h")) && IsTrue(!IsEqual(timeframe, "4h"))) && IsTrue(!IsEqual(timeframe, "12h"))) && IsTrue(!IsEqual(timeframe, "1d"))) { panic(BadRequest(Add(this.Id, " fetchOpenInterestHistory cannot only use the 1h, 4h, 12h and 1d timeframe"))) } retRes83858 := (<-this.LoadMarkets()) PanicOnError(retRes83858) var timeframes interface{} = map[string]interface{} { "1h": "60min", "4h": "4hour", "12h": "12hour", "1d": "1day", } var market interface{} = this.Market(symbol) var amountType interface{} = this.SafeInteger2(params, "amount_type", "amountType", 2) var request interface{} = map[string]interface{} { "period": GetValue(timeframes, timeframe), "amount_type": amountType, } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "size", limit) } var response interface{} = nil if IsTrue(GetValue(market, "future")) { AddElementToObject(request, "contract_type", this.SafeString(GetValue(market, "info"), "contract_type")) AddElementToObject(request, "symbol", GetValue(market, "baseId")) // currency code on coin-m futures // coin-m futures response = (<-this.ContractPublicGetApiV1ContractHisOpenInterest(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "linear")) { AddElementToObject(request, "contract_type", "swap") AddElementToObject(request, "contract_code", GetValue(market, "id")) AddElementToObject(request, "contract_code", GetValue(market, "id")) // USDT-M response = (<-this.ContractPublicGetLinearSwapApiV1SwapHisOpenInterest(this.Extend(request, params))) PanicOnError(response) } else { AddElementToObject(request, "contract_code", GetValue(market, "id")) // coin-m swaps response = (<-this.ContractPublicGetSwapApiV1SwapHisOpenInterest(this.Extend(request, params))) PanicOnError(response) } // // contractPublicGetlinearSwapApiV1SwapHisOpenInterest // { // "status": "ok", // "data": { // "symbol": "BTC", // "tick": [ // { // "volume": "4385.4350000000000000", // "amount_type": "2", // "ts": "1648220400000", // "value": "194059884.1850000000000000" // }, // ... // ], // "contract_code": "BTC-USDT", // "business_type": "swap", // "pair": "BTC-USDT", // "contract_type": "swap", // "trade_partition": "USDT" // }, // "ts": "1648223733007" // } // // contractPublicGetSwapApiV1SwapHisOpenInterest // { // "status": "ok", // "data": { // "symbol": "CRV", // "tick": [ // { // "volume": 19174.0000000000000000, // "amount_type": 1, // "ts": 1648224000000 // }, // ... // ], // "contract_code": "CRV-USD" // }, // "ts": 1648226554260 // } // // contractPublicGetApiV1ContractHisOpenInterest // { // "status": "ok", // "data": { // "symbol": "BTC", // "contract_type": "this_week", // "tick": [ // { // "volume": "48419.0000000000000000", // "amount_type": 1, // "ts": 1648224000000 // }, // ... // ] // }, // "ts": 1648227062944 // } // var data interface{} = this.SafeValue(response, "data") var tick interface{} = this.SafeList(data, "tick") ch <- this.ParseOpenInterestsHistory(tick, market, since, limit) return nil }() return ch } /** * @method * @name htx#fetchOpenInterests * @description Retrieves the open interest for a list of symbols * @see https://huobiapi.github.io/docs/dm/v1/en/#get-contract-open-interest-information * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-swap-open-interest-information * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-swap-open-interest-information * @param {string[]} [symbols] a list of unified CCXT market symbols * @param {object} [params] exchange specific parameters * @returns {object[]} a list of [open interest structures]{@link https://docs.ccxt.com/#/?id=open-interest-structure} */ func (this *htx) FetchOpenInterests(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 retRes84958 := (<-this.LoadMarkets()) PanicOnError(retRes84958) symbols = this.MarketSymbols(symbols) var market interface{} = nil if IsTrue(!IsEqual(symbols, nil)) { var symbolsLength interface{} = GetArrayLength(symbols) if IsTrue(IsGreaterThan(symbolsLength, 0)) { var first interface{} = this.SafeString(symbols, 0) market = this.Market(first) } } var request interface{} = map[string]interface{} {} var subType interface{} = nil subTypeparamsVariable := this.HandleSubTypeAndParams("fetchPositions", market, params, "linear"); subType = GetValue(subTypeparamsVariable,0); params = GetValue(subTypeparamsVariable,1) var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchPositions", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var response interface{} = nil if IsTrue(IsEqual(marketType, "future")) { response = (<-this.ContractPublicGetApiV1ContractOpenInterest(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(subType, "inverse")) { response = (<-this.ContractPublicGetSwapApiV1SwapOpenInterest(this.Extend(request, params))) PanicOnError(response) } else { AddElementToObject(request, "contract_type", "swap") response = (<-this.ContractPublicGetLinearSwapApiV1SwapOpenInterest(this.Extend(request, params))) PanicOnError(response) } var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOpenInterests(data, symbols) return nil }() return ch } /** * @method * @name htx#fetchOpenInterest * @description Retrieves the open interest of a currency * @see https://huobiapi.github.io/docs/dm/v1/en/#get-contract-open-interest-information * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-swap-open-interest-information * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-swap-open-interest-information * @param {string} symbol Unified CCXT market symbol * @param {object} [params] exchange specific parameters * @returns {object} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure} */ func (this *htx) FetchOpenInterest(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 retRes85928 := (<-this.LoadMarkets()) PanicOnError(retRes85928) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "contract")) { panic(BadRequest(Add(this.Id, " fetchOpenInterest() supports contract markets only"))) } if IsTrue(GetValue(market, "option")) { panic(NotSupported(Add(this.Id, " fetchOpenInterest() does not currently support option markets"))) } var request interface{} = map[string]interface{} { "contract_code": GetValue(market, "id"), } var response interface{} = nil if IsTrue(GetValue(market, "future")) { AddElementToObject(request, "contract_type", this.SafeString(GetValue(market, "info"), "contract_type")) AddElementToObject(request, "symbol", GetValue(market, "baseId")) // COIN-M futures response = (<-this.ContractPublicGetApiV1ContractOpenInterest(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "linear")) { AddElementToObject(request, "contract_type", "swap") // USDT-M response = (<-this.ContractPublicGetLinearSwapApiV1SwapOpenInterest(this.Extend(request, params))) PanicOnError(response) } else { // COIN-M swaps response = (<-this.ContractPublicGetSwapApiV1SwapOpenInterest(this.Extend(request, params))) PanicOnError(response) } // // USDT-M contractPublicGetLinearSwapApiV1SwapOpenInterest // // { // "status": "ok", // "data": [ // { // "volume": 7192610.000000000000000000, // "amount": 7192.610000000000000000, // "symbol": "BTC", // "value": 134654290.332000000000000000, // "contract_code": "BTC-USDT", // "trade_amount": 70692.804, // "trade_volume": 70692804, // "trade_turnover": 1379302592.9518, // "business_type": "swap", // "pair": "BTC-USDT", // "contract_type": "swap", // "trade_partition": "USDT" // } // ], // "ts": 1664336503144 // } // // COIN-M Swap contractPublicGetSwapApiV1SwapOpenInterest // // { // "status": "ok", // "data": [ // { // "volume": 518018.000000000000000000, // "amount": 2769.675777407074725180, // "symbol": "BTC", // "contract_code": "BTC-USD", // "trade_amount": 9544.4032080046491323463688602729806842458, // "trade_volume": 1848448, // "trade_turnover": 184844800.000000000000000000 // } // ], // "ts": 1664337226028 // } // // COIN-M Futures contractPublicGetApiV1ContractOpenInterest // // { // "status": "ok", // "data": [ // { // "volume": 118850.000000000000000000, // "amount": 635.502025211544374189, // "symbol": "BTC", // "contract_type": "this_week", // "contract_code": "BTC220930", // "trade_amount": 1470.9400749347598691119206024033947897351, // "trade_volume": 286286, // "trade_turnover": 28628600.000000000000000000 // } // ], // "ts": 1664337928805 // } // var data interface{} = this.SafeValue(response, "data", []interface{}{}) var openInterest interface{} = this.ParseOpenInterest(GetValue(data, 0), market) var timestamp interface{} = this.SafeInteger(response, "ts") AddElementToObject(openInterest, "timestamp", timestamp) AddElementToObject(openInterest, "datetime", this.Iso8601(timestamp)) ch <- openInterest return nil }() return ch } func (this *htx) ParseOpenInterest(interest interface{}, optionalArgs ...interface{}) interface{} { // // fetchOpenInterestHistory // // { // "volume": "4385.4350000000000000", // "amount_type": "2", // "ts": "1648220400000", // "value": "194059884.1850000000000000" // } // // fetchOpenInterest: USDT-M // // { // "volume": 7192610.000000000000000000, // "amount": 7192.610000000000000000, // "symbol": "BTC", // "value": 134654290.332000000000000000, // "contract_code": "BTC-USDT", // "trade_amount": 70692.804, // "trade_volume": 70692804, // "trade_turnover": 1379302592.9518, // "business_type": "swap", // "pair": "BTC-USDT", // "contract_type": "swap", // "trade_partition": "USDT" // } // // fetchOpenInterest: COIN-M Swap // // { // "volume": 518018.000000000000000000, // "amount": 2769.675777407074725180, // "symbol": "BTC", // "contract_code": "BTC-USD", // "trade_amount": 9544.4032080046491323463688602729806842458, // "trade_volume": 1848448, // "trade_turnover": 184844800.000000000000000000 // } // // fetchOpenInterest: COIN-M Futures // // { // "volume": 118850.000000000000000000, // "amount": 635.502025211544374189, // "symbol": "BTC", // "contract_type": "this_week", // "contract_code": "BTC220930", // "trade_amount": 1470.9400749347598691119206024033947897351, // "trade_volume": 286286, // "trade_turnover": 28628600.000000000000000000 // } // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeInteger(interest, "ts") var amount interface{} = this.SafeNumber(interest, "volume") var value interface{} = this.SafeNumber(interest, "value") var marketId interface{} = this.SafeString(interest, "contract_code") return this.SafeOpenInterest(map[string]interface{} { "symbol": this.SafeSymbol(marketId, market), "baseVolume": amount, "quoteVolume": value, "openInterestAmount": amount, "openInterestValue": value, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "info": interest, }, market) } /** * @method * @name htx#borrowIsolatedMargin * @description create a loan to borrow margin * @see https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-isolated * @see https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-cross * @param {string} symbol unified market symbol, required for isolated margin * @param {string} code unified currency code of the currency to borrow * @param {float} amount the amount to borrow * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure} */ func (this *htx) BorrowIsolatedMargin(symbol interface{}, code interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes87688 := (<-this.LoadMarkets()) PanicOnError(retRes87688) var currency interface{} = this.Currency(code) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), "amount": this.CurrencyToPrecision(code, amount), "symbol": GetValue(market, "id"), } response:= (<-this.PrivatePostMarginOrders(this.Extend(request, params))) PanicOnError(response) // // Isolated // // { // "data": 1000 // } // var transaction interface{} = this.ParseMarginLoan(response, currency) ch <- this.Extend(transaction, map[string]interface{} { "amount": amount, "symbol": symbol, }) return nil }() return ch } /** * @method * @name htx#borrowCrossMargin * @description create a loan to borrow margin * @see https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-isolated * @see https://huobiapi.github.io/docs/spot/v1/en/#request-a-margin-loan-cross * @param {string} code unified currency code of the currency to borrow * @param {float} amount the amount to borrow * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure} */ func (this *htx) BorrowCrossMargin(code interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes88038 := (<-this.LoadMarkets()) PanicOnError(retRes88038) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), "amount": this.CurrencyToPrecision(code, amount), } response:= (<-this.PrivatePostCrossMarginOrders(this.Extend(request, params))) PanicOnError(response) // // Cross // // { // "status": "ok", // "data": null // } // var transaction interface{} = this.ParseMarginLoan(response, currency) ch <- this.Extend(transaction, map[string]interface{} { "amount": amount, }) return nil }() return ch } /** * @method * @name htx#repayIsolatedMargin * @description repay borrowed margin and interest * @see https://huobiapi.github.io/docs/spot/v1/en/#repay-margin-loan-cross-isolated * @param {string} symbol unified market symbol * @param {string} code unified currency code of the currency to repay * @param {float} amount the amount to repay * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure} */ func (this *htx) RepayIsolatedMargin(symbol interface{}, code interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes88368 := (<-this.LoadMarkets()) PanicOnError(retRes88368) var currency interface{} = this.Currency(code) accountId:= (<-this.FetchAccountIdByType("spot", "isolated", symbol, params)) PanicOnError(accountId) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), "amount": this.CurrencyToPrecision(code, amount), "accountId": accountId, } response:= (<-this.V2PrivatePostAccountRepayment(this.Extend(request, params))) PanicOnError(response) // // { // "code":200, // "data": [ // { // "repayId":1174424, // "repayTime":1600747722018 // } // ] // } // var data interface{} = this.SafeValue(response, "Data", []interface{}{}) var loan interface{} = this.SafeValue(data, 0) var transaction interface{} = this.ParseMarginLoan(loan, currency) ch <- this.Extend(transaction, map[string]interface{} { "amount": amount, "symbol": symbol, }) return nil }() return ch } /** * @method * @name htx#repayCrossMargin * @description repay borrowed margin and interest * @see https://huobiapi.github.io/docs/spot/v1/en/#repay-margin-loan-cross-isolated * @param {string} code unified currency code of the currency to repay * @param {float} amount the amount to repay * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure} */ func (this *htx) RepayCrossMargin(code interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes88768 := (<-this.LoadMarkets()) PanicOnError(retRes88768) var currency interface{} = this.Currency(code) accountId:= (<-this.FetchAccountIdByType("spot", "cross", nil, params)) PanicOnError(accountId) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), "amount": this.CurrencyToPrecision(code, amount), "accountId": accountId, } response:= (<-this.V2PrivatePostAccountRepayment(this.Extend(request, params))) PanicOnError(response) // // { // "code":200, // "data": [ // { // "repayId":1174424, // "repayTime":1600747722018 // } // ] // } // var data interface{} = this.SafeValue(response, "Data", []interface{}{}) var loan interface{} = this.SafeValue(data, 0) var transaction interface{} = this.ParseMarginLoan(loan, currency) ch <- this.Extend(transaction, map[string]interface{} { "amount": amount, }) return nil }() return ch } func (this *htx) ParseMarginLoan(info interface{}, optionalArgs ...interface{}) interface{} { // // borrowMargin cross // // { // "status": "ok", // "data": null // } // // borrowMargin isolated // // { // "data": 1000 // } // // repayMargin // // { // "repayId":1174424, // "repayTime":1600747722018 // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var timestamp interface{} = this.SafeInteger(info, "repayTime") return map[string]interface{} { "id": this.SafeString2(info, "repayId", "data"), "currency": this.SafeCurrencyCode(nil, currency), "amount": nil, "symbol": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "info": info, } } /** * @method * @name htx#fetchSettlementHistory * @description Fetches historical settlement records * @see https://huobiapi.github.io/docs/dm/v1/en/#query-historical-settlement-records-of-the-platform-interface * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-historical-settlement-records-of-the-platform-interface * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-historical-settlement-records-of-the-platform-interface * @param {string} symbol unified symbol of the market to fetch the settlement history for * @param {int} [since] timestamp in ms, value range = current time - 90 days,default = current time - 90 days * @param {int} [limit] page items, default 20, shall not exceed 50 * @param {object} [params] exchange specific params * @param {int} [params.until] timestamp in ms, value range = start_time -> current time,default = current time * @param {int} [params.page_index] page index, default page 1 if not filled * @param {int} [params.code] unified currency code, can be used when symbol is undefined * @returns {object[]} a list of [settlement history objects]{@link https://docs.ccxt.com/#/?id=settlement-history-structure} */ func (this *htx) FetchSettlementHistory(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, " fetchSettlementHistory() requires a symbol argument"))) } var until interface{} = this.SafeInteger(params, "until") params = this.Omit(params, []interface{}{"until"}) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} {} if IsTrue(GetValue(market, "future")) { AddElementToObject(request, "symbol", GetValue(market, "baseId")) } else { AddElementToObject(request, "contract_code", GetValue(market, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start_at", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "page_size", limit) } if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "end_at", until) } var response interface{} = nil if IsTrue(GetValue(market, "swap")) { if IsTrue(GetValue(market, "linear")) { response = (<-this.ContractPublicGetLinearSwapApiV1SwapSettlementRecords(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPublicGetSwapApiV1SwapSettlementRecords(this.Extend(request, params))) PanicOnError(response) } } else { response = (<-this.ContractPublicGetApiV1ContractSettlementRecords(this.Extend(request, params))) PanicOnError(response) } // // linear swap, coin-m swap // // { // "status": "ok", // "data": { // "total_page": 14, // "current_page": 1, // "total_size": 270, // "settlement_record": [ // { // "symbol": "ADA", // "contract_code": "ADA-USDT", // "settlement_time": 1652313600000, // "clawback_ratio": 0E-18, // "settlement_price": 0.512303000000000000, // "settlement_type": "settlement", // "business_type": "swap", // "pair": "ADA-USDT", // "trade_partition": "USDT" // }, // ... // ], // "ts": 1652338693256 // } // // coin-m future // // { // "status": "ok", // "data": { // "total_page": 5, // "current_page": 1, // "total_size": 90, // "settlement_record": [ // { // "symbol": "FIL", // "settlement_time": 1652342400000, // "clawback_ratio": 0E-18, // "list": [ // { // "contract_code": "FIL220513", // "settlement_price": 7.016000000000000000, // "settlement_type": "settlement" // }, // ... // ] // }, // ] // } // } // var data interface{} = this.SafeValue(response, "data") var settlementRecord interface{} = this.SafeValue(data, "settlement_record") var settlements interface{} = this.ParseSettlements(settlementRecord, market) ch <- this.SortBy(settlements, "timestamp") return nil }() return ch } /** * @method * @name htx#fetchDepositWithdrawFees * @description fetch deposit and withdraw fees * @see https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-currencies-v2 * @param {string[]|undefined} codes list of unified currency codes * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [fees structures]{@link https://docs.ccxt.com/#/?id=fee-structure} */ func (this *htx) FetchDepositWithdrawFees(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) codes := GetArg(optionalArgs, 0, nil) _ = codes params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes90548 := (<-this.LoadMarkets()) PanicOnError(retRes90548) response:= (<-this.SpotPublicGetV2ReferenceCurrencies(params)) PanicOnError(response) // // { // "code": 200, // "data": [ // { // "currency": "sxp", // "assetType": "1", // "chains": [ // { // "chain": "sxp", // "displayName": "ERC20", // "baseChain": "ETH", // "baseChainProtocol": "ERC20", // "isDynamic": true, // "numOfConfirmations": "12", // "numOfFastConfirmations": "12", // "depositStatus": "allowed", // "minDepositAmt": "0.23", // "withdrawStatus": "allowed", // "minWithdrawAmt": "0.23", // "withdrawPrecision": "8", // "maxWithdrawAmt": "227000.000000000000000000", // "withdrawQuotaPerDay": "227000.000000000000000000", // "withdrawQuotaPerYear": null, // "withdrawQuotaTotal": null, // "withdrawFeeType": "fixed", // "transactFeeWithdraw": "11.1653", // "addrWithTag": false, // "addrDepositTag": false // } // ], // "instStatus": "normal" // } // ] // } // var data interface{} = this.SafeList(response, "data") ch <- this.ParseDepositWithdrawFees(data, codes, "currency") return nil }() return ch } func (this *htx) ParseDepositWithdrawFee(fee interface{}, optionalArgs ...interface{}) interface{} { // // { // "currency": "sxp", // "assetType": "1", // "chains": [ // { // "chain": "sxp", // "displayName": "ERC20", // "baseChain": "ETH", // "baseChainProtocol": "ERC20", // "isDynamic": true, // "numOfConfirmations": "12", // "numOfFastConfirmations": "12", // "depositStatus": "allowed", // "minDepositAmt": "0.23", // "withdrawStatus": "allowed", // "minWithdrawAmt": "0.23", // "withdrawPrecision": "8", // "maxWithdrawAmt": "227000.000000000000000000", // "withdrawQuotaPerDay": "227000.000000000000000000", // "withdrawQuotaPerYear": null, // "withdrawQuotaTotal": null, // "withdrawFeeType": "fixed", // "transactFeeWithdraw": "11.1653", // "addrWithTag": false, // "addrDepositTag": false // } // ], // "instStatus": "normal" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var chains interface{} = this.SafeValue(fee, "chains", []interface{}{}) var result interface{} = this.DepositWithdrawFee(fee) for j := 0; IsLessThan(j, GetArrayLength(chains)); j++ { var chainEntry interface{} = GetValue(chains, j) var networkId interface{} = this.SafeString(chainEntry, "chain") var withdrawFeeType interface{} = this.SafeString(chainEntry, "withdrawFeeType") var networkCode interface{} = this.NetworkIdToCode(networkId) var withdrawFee interface{} = nil var withdrawResult interface{} = nil if IsTrue(IsEqual(withdrawFeeType, "fixed")) { withdrawFee = this.SafeNumber(chainEntry, "transactFeeWithdraw") withdrawResult = map[string]interface{} { "fee": withdrawFee, "percentage": false, } } else { withdrawFee = this.SafeNumber(chainEntry, "transactFeeRateWithdraw") withdrawResult = map[string]interface{} { "fee": withdrawFee, "percentage": true, } } AddElementToObject(GetValue(result, "networks"), networkCode, map[string]interface{} { "withdraw": withdrawResult, "deposit": map[string]interface{} { "fee": nil, "percentage": nil, }, }) result = this.AssignDefaultDepositWithdrawFees(result, currency) } return result } func (this *htx) ParseSettlements(settlements interface{}, market interface{}) interface{} { // // linear swap, coin-m swap, fetchSettlementHistory // // [ // { // "symbol": "ADA", // "contract_code": "ADA-USDT", // "settlement_time": 1652313600000, // "clawback_ratio": 0E-18, // "settlement_price": 0.512303000000000000, // "settlement_type": "settlement", // "business_type": "swap", // "pair": "ADA-USDT", // "trade_partition": "USDT" // }, // ... // ] // // coin-m future, fetchSettlementHistory // // [ // { // "symbol": "FIL", // "settlement_time": 1652342400000, // "clawback_ratio": 0E-18, // "list": [ // { // "contract_code": "FIL220513", // "settlement_price": 7.016000000000000000, // "settlement_type": "settlement" // }, // ... // ] // }, // ] // var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(settlements)); i++ { var settlement interface{} = GetValue(settlements, i) var list interface{} = this.SafeValue(settlement, "list") if IsTrue(!IsEqual(list, nil)) { var timestamp interface{} = this.SafeInteger(settlement, "settlement_time") var timestampDetails interface{} = map[string]interface{} { "timestamp": timestamp, "datetime": this.Iso8601(timestamp), } for j := 0; IsLessThan(j, GetArrayLength(list)); j++ { var item interface{} = GetValue(list, j) var parsedSettlement interface{} = this.ParseSettlement(item, market) AppendToArray(&result,this.Extend(parsedSettlement, timestampDetails)) } } else { AppendToArray(&result,this.ParseSettlement(GetValue(settlements, i), market)) } } return result } func (this *htx) ParseSettlement(settlement interface{}, market interface{}) interface{} { // // linear swap, coin-m swap, fetchSettlementHistory // // { // "symbol": "ADA", // "contract_code": "ADA-USDT", // "settlement_time": 1652313600000, // "clawback_ratio": 0E-18, // "settlement_price": 0.512303000000000000, // "settlement_type": "settlement", // "business_type": "swap", // "pair": "ADA-USDT", // "trade_partition": "USDT" // } // // coin-m future, fetchSettlementHistory // // { // "contract_code": "FIL220513", // "settlement_price": 7.016000000000000000, // "settlement_type": "settlement" // } // var timestamp interface{} = this.SafeInteger(settlement, "settlement_time") var marketId interface{} = this.SafeString(settlement, "contract_code") return map[string]interface{} { "info": settlement, "symbol": this.SafeSymbol(marketId, market), "price": this.SafeNumber(settlement, "settlement_price"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), } } /** * @method * @name htx#fetchLiquidations * @description retrieves the public liquidations of a trading pair * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-liquidation-orders-new * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-liquidation-orders-new * @see https://huobiapi.github.io/docs/dm/v1/en/#query-liquidation-order-information-new * @param {string} symbol unified CCXT market symbol * @param {int} [since] the earliest time in ms to fetch liquidations for * @param {int} [limit] the maximum number of liquidation structures to retrieve * @param {object} [params] exchange specific parameters for the huobi api endpoint * @param {int} [params.until] timestamp in ms of the latest liquidation * @param {int} [params.tradeType] default 0, linear swap 0: all liquidated orders, 5: liquidated longs; 6: liquidated shorts, inverse swap and future 0: filled liquidated orders, 5: liquidated close orders, 6: liquidated open orders * @returns {object} an array of [liquidation structures]{@link https://docs.ccxt.com/#/?id=liquidation-structure} */ func (this *htx) FetchLiquidations(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 retRes92728 := (<-this.LoadMarkets()) PanicOnError(retRes92728) var market interface{} = this.Market(symbol) var tradeType interface{} = this.SafeInteger(params, "trade_type", 0) var request interface{} = map[string]interface{} { "trade_type": tradeType, } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start_time", since) } requestparamsVariable := this.HandleUntilOption("end_time", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) var response interface{} = nil if IsTrue(GetValue(market, "swap")) { AddElementToObject(request, "contract", GetValue(market, "id")) if IsTrue(GetValue(market, "linear")) { response = (<-this.ContractPublicGetLinearSwapApiV3SwapLiquidationOrders(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPublicGetSwapApiV3SwapLiquidationOrders(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "future")) { AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.ContractPublicGetApiV3ContractLiquidationOrders(this.Extend(request, params))) PanicOnError(response) } else { panic(NotSupported(Add(Add(Add(this.Id, " fetchLiquidations() does not support "), GetValue(market, "type")), " orders"))) } // // { // "code": 200, // "msg": "", // "data": [ // { // "query_id": 452057, // "contract_code": "BTC-USDT-211210", // "symbol": "USDT", // "direction": "sell", // "offset": "close", // "volume": 479.000000000000000000, // "price": 51441.700000000000000000, // "created_at": 1638593647864, // "amount": 0.479000000000000000, // "trade_turnover": 24640.574300000000000000, // "business_type": "futures", // "pair": "BTC-USDT" // } // ], // "ts": 1604312615051 // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseLiquidations(data, market, since, limit) return nil }() return ch } func (this *htx) ParseLiquidation(liquidation interface{}, optionalArgs ...interface{}) interface{} { // // { // "query_id": 452057, // "contract_code": "BTC-USDT-211210", // "symbol": "USDT", // "direction": "sell", // "offset": "close", // "volume": 479.000000000000000000, // "price": 51441.700000000000000000, // "created_at": 1638593647864, // "amount": 0.479000000000000000, // "trade_turnover": 24640.574300000000000000, // "business_type": "futures", // "pair": "BTC-USDT" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(liquidation, "contract_code") var timestamp interface{} = this.SafeInteger(liquidation, "created_at") return this.SafeLiquidation(map[string]interface{} { "info": liquidation, "symbol": this.SafeSymbol(marketId, market), "contracts": this.SafeNumber(liquidation, "volume"), "contractSize": this.SafeNumber(market, "contractSize"), "price": this.SafeNumber(liquidation, "price"), "baseValue": this.SafeNumber(liquidation, "amount"), "quoteValue": this.SafeNumber(liquidation, "trade_turnover"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), }) } /** * @method * @name htx#closePositions * @description closes open positions for a contract market, requires 'amount' in params, unlike other exchanges * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-lightning-close-order // USDT-M (isolated) * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-lightning-close-position // USDT-M (cross) * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-lightning-close-order // Coin-M swap * @see https://huobiapi.github.io/docs/dm/v1/en/#place-flash-close-order // Coin-M futures * @param {string} symbol unified CCXT market symbol * @param {string} side 'buy' or 'sell', the side of the closing order, opposite side as position side * @param {object} [params] extra parameters specific to the okx api endpoint * @param {string} [params.clientOrderId] client needs to provide unique API and have to maintain the API themselves afterwards. [1, 9223372036854775807] * @param {object} [params.marginMode] 'cross' or 'isolated', required for linear markets * * EXCHANGE SPECIFIC PARAMETERS * @param {number} [params.amount] order quantity * @param {string} [params.order_price_type] 'lightning' by default, 'lightning_fok': lightning fok type, 'lightning_ioc': lightning ioc type 'market' by default, 'market': market order type, 'lightning_fok': lightning * @returns {object} [an order structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *htx) 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 retRes93758 := (<-this.LoadMarkets()) PanicOnError(retRes93758) var market interface{} = this.Market(symbol) var clientOrderId interface{} = this.SafeString(params, "clientOrderId") if !IsTrue(GetValue(market, "contract")) { panic(BadRequest(Add(this.Id, " closePosition() symbol supports contract markets only"))) } this.CheckRequiredArgument("closePosition", side, "side") var request interface{} = map[string]interface{} { "contract_code": GetValue(market, "id"), "direction": side, } if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "client_order_id", clientOrderId) } if IsTrue(GetValue(market, "inverse")) { var amount interface{} = this.SafeString2(params, "volume", "amount") if IsTrue(IsEqual(amount, nil)) { panic(ArgumentsRequired(Add(this.Id, " closePosition () requires an extra argument params[\"amount\"] for inverse markets"))) } AddElementToObject(request, "volume", this.AmountToPrecision(symbol, amount)) } params = this.Omit(params, []interface{}{"clientOrderId", "volume", "amount"}) var response interface{} = nil if IsTrue(GetValue(market, "inverse")) { if IsTrue(GetValue(market, "swap")) { response = (<-this.ContractPrivatePostSwapApiV1SwapLightningClosePosition(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostApiV1LightningClosePosition(this.Extend(request, params))) PanicOnError(response) } } else { var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("closePosition", params, "cross"); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) if IsTrue(IsEqual(marginMode, "cross")) { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossLightningClosePosition(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.ContractPrivatePostLinearSwapApiV1SwapLightningClosePosition(this.Extend(request, params))) PanicOnError(response) } } ch <- this.ParseOrder(response, market) return nil }() return ch } /** * @method * @name htx#setPositionMode * @description set hedged to true or false * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-switch-position-mode * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-switch-position-mode * @param {bool} hedged set to true to for hedged mode, must be set separately for each market in isolated margin mode, only valid for linear markets * @param {string} [symbol] unified market symbol, required for isolated margin mode * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.marginMode] "cross" (default) or "isolated" * @returns {object} response from the exchange */ func (this *htx) SetPositionMode(hedged 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 retRes94298 := (<-this.LoadMarkets()) PanicOnError(retRes94298) var posMode interface{} = Ternary(IsTrue(hedged), "dual_side", "single_side") var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("setPositionMode", params, "cross"); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) var request interface{} = map[string]interface{} { "position_mode": posMode, } var response interface{} = nil if IsTrue(IsTrue((!IsEqual(market, nil))) && IsTrue((GetValue(market, "inverse")))) { panic(BadRequest(Add(this.Id, " setPositionMode can only be used for linear markets"))) } if IsTrue(IsEqual(marginMode, "isolated")) { if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " setPositionMode requires a symbol argument for isolated margin mode"))) } AddElementToObject(request, "margin_account", GetValue(market, "id")) response = (<-this.ContractPrivatePostLinearSwapApiV1SwapSwitchPositionMode(this.Extend(request, params))) PanicOnError(response) } else { AddElementToObject(request, "margin_account", "USDT") response = (<-this.ContractPrivatePostLinearSwapApiV1SwapCrossSwitchPositionMode(this.Extend(request, params))) PanicOnError(response) } ch <- response return nil }() return ch } func (this *htx) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }