10875 lines
502 KiB
Go
10875 lines
502 KiB
Go
package ccxt
|
|
|
|
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
|
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
|
|
|
type bybit struct {
|
|
Exchange
|
|
|
|
}
|
|
|
|
func NewBybitCore() bybit {
|
|
p := bybit{}
|
|
setDefaults(&p)
|
|
return p
|
|
}
|
|
|
|
func (this *bybit) Describe() interface{} {
|
|
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
|
|
"id": "bybit",
|
|
"name": "Bybit",
|
|
"countries": []interface{}{"VG"},
|
|
"version": "v5",
|
|
"userAgent": nil,
|
|
"rateLimit": 20,
|
|
"hostname": "bybit.com",
|
|
"pro": true,
|
|
"certified": true,
|
|
"has": map[string]interface{} {
|
|
"CORS": true,
|
|
"spot": true,
|
|
"margin": true,
|
|
"swap": true,
|
|
"future": true,
|
|
"option": true,
|
|
"borrowCrossMargin": true,
|
|
"cancelAllOrders": true,
|
|
"cancelAllOrdersAfter": true,
|
|
"cancelOrder": true,
|
|
"cancelOrders": true,
|
|
"cancelOrdersForSymbols": true,
|
|
"closeAllPositions": false,
|
|
"closePosition": false,
|
|
"createConvertTrade": true,
|
|
"createMarketBuyOrderWithCost": true,
|
|
"createMarketSellOrderWithCost": true,
|
|
"createOrder": true,
|
|
"createOrders": true,
|
|
"createOrderWithTakeProfitAndStopLoss": true,
|
|
"createPostOnlyOrder": true,
|
|
"createReduceOnlyOrder": true,
|
|
"createStopLimitOrder": true,
|
|
"createStopLossOrder": true,
|
|
"createStopMarketOrder": true,
|
|
"createStopOrder": true,
|
|
"createTakeProfitOrder": true,
|
|
"createTrailingAmountOrder": true,
|
|
"createTriggerOrder": true,
|
|
"editOrder": true,
|
|
"editOrders": true,
|
|
"fetchBalance": true,
|
|
"fetchBidsAsks": "emulated",
|
|
"fetchBorrowInterest": false,
|
|
"fetchBorrowRateHistories": false,
|
|
"fetchBorrowRateHistory": false,
|
|
"fetchCanceledAndClosedOrders": true,
|
|
"fetchCanceledOrders": true,
|
|
"fetchClosedOrder": true,
|
|
"fetchClosedOrders": true,
|
|
"fetchConvertCurrencies": true,
|
|
"fetchConvertQuote": true,
|
|
"fetchConvertTrade": true,
|
|
"fetchConvertTradeHistory": true,
|
|
"fetchCrossBorrowRate": true,
|
|
"fetchCrossBorrowRates": false,
|
|
"fetchCurrencies": true,
|
|
"fetchDeposit": false,
|
|
"fetchDepositAddress": true,
|
|
"fetchDepositAddresses": false,
|
|
"fetchDepositAddressesByNetwork": true,
|
|
"fetchDeposits": true,
|
|
"fetchDepositWithdrawFee": "emulated",
|
|
"fetchDepositWithdrawFees": true,
|
|
"fetchFundingHistory": true,
|
|
"fetchFundingRate": "emulated",
|
|
"fetchFundingRateHistory": true,
|
|
"fetchFundingRates": true,
|
|
"fetchGreeks": true,
|
|
"fetchIndexOHLCV": true,
|
|
"fetchIsolatedBorrowRate": false,
|
|
"fetchIsolatedBorrowRates": false,
|
|
"fetchLedger": true,
|
|
"fetchLeverage": true,
|
|
"fetchLeverageTiers": true,
|
|
"fetchLongShortRatio": false,
|
|
"fetchLongShortRatioHistory": true,
|
|
"fetchMarginAdjustmentHistory": false,
|
|
"fetchMarketLeverageTiers": true,
|
|
"fetchMarkets": true,
|
|
"fetchMarkOHLCV": true,
|
|
"fetchMyLiquidations": true,
|
|
"fetchMySettlementHistory": true,
|
|
"fetchMyTrades": true,
|
|
"fetchOHLCV": true,
|
|
"fetchOpenInterest": true,
|
|
"fetchOpenInterestHistory": true,
|
|
"fetchOpenOrder": true,
|
|
"fetchOpenOrders": true,
|
|
"fetchOption": true,
|
|
"fetchOptionChain": true,
|
|
"fetchOrder": true,
|
|
"fetchOrderBook": true,
|
|
"fetchOrders": false,
|
|
"fetchOrderTrades": true,
|
|
"fetchPosition": true,
|
|
"fetchPositionHistory": "emulated",
|
|
"fetchPositions": true,
|
|
"fetchPositionsHistory": true,
|
|
"fetchPremiumIndexOHLCV": true,
|
|
"fetchSettlementHistory": true,
|
|
"fetchTicker": true,
|
|
"fetchTickers": true,
|
|
"fetchTime": true,
|
|
"fetchTrades": true,
|
|
"fetchTradingFee": true,
|
|
"fetchTradingFees": true,
|
|
"fetchTransactions": false,
|
|
"fetchTransfers": true,
|
|
"fetchUnderlyingAssets": false,
|
|
"fetchVolatilityHistory": true,
|
|
"fetchWithdrawals": true,
|
|
"repayCrossMargin": true,
|
|
"sandbox": true,
|
|
"setLeverage": true,
|
|
"setMarginMode": true,
|
|
"setPositionMode": true,
|
|
"transfer": true,
|
|
"withdraw": true,
|
|
},
|
|
"timeframes": map[string]interface{} {
|
|
"1m": "1",
|
|
"3m": "3",
|
|
"5m": "5",
|
|
"15m": "15",
|
|
"30m": "30",
|
|
"1h": "60",
|
|
"2h": "120",
|
|
"4h": "240",
|
|
"6h": "360",
|
|
"12h": "720",
|
|
"1d": "D",
|
|
"1w": "W",
|
|
"1M": "M",
|
|
},
|
|
"urls": map[string]interface{} {
|
|
"test": map[string]interface{} {
|
|
"spot": "https://api-testnet.{hostname}",
|
|
"futures": "https://api-testnet.{hostname}",
|
|
"v2": "https://api-testnet.{hostname}",
|
|
"public": "https://api-testnet.{hostname}",
|
|
"private": "https://api-testnet.{hostname}",
|
|
},
|
|
"logo": "https://github.com/user-attachments/assets/97a5d0b3-de10-423d-90e1-6620960025ed",
|
|
"api": map[string]interface{} {
|
|
"spot": "https://api.{hostname}",
|
|
"futures": "https://api.{hostname}",
|
|
"v2": "https://api.{hostname}",
|
|
"public": "https://api.{hostname}",
|
|
"private": "https://api.{hostname}",
|
|
},
|
|
"demotrading": map[string]interface{} {
|
|
"spot": "https://api-demo.{hostname}",
|
|
"futures": "https://api-demo.{hostname}",
|
|
"v2": "https://api-demo.{hostname}",
|
|
"public": "https://api-demo.{hostname}",
|
|
"private": "https://api-demo.{hostname}",
|
|
},
|
|
"www": "https://www.bybit.com",
|
|
"doc": []interface{}{"https://bybit-exchange.github.io/docs/inverse/", "https://bybit-exchange.github.io/docs/linear/", "https://github.com/bybit-exchange"},
|
|
"fees": "https://help.bybit.com/hc/en-us/articles/360039261154",
|
|
"referral": "https://www.bybit.com/register?affiliate_id=35953",
|
|
},
|
|
"api": map[string]interface{} {
|
|
"public": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"spot/v3/public/symbols": 1,
|
|
"spot/v3/public/quote/depth": 1,
|
|
"spot/v3/public/quote/depth/merged": 1,
|
|
"spot/v3/public/quote/trades": 1,
|
|
"spot/v3/public/quote/kline": 1,
|
|
"spot/v3/public/quote/ticker/24hr": 1,
|
|
"spot/v3/public/quote/ticker/price": 1,
|
|
"spot/v3/public/quote/ticker/bookTicker": 1,
|
|
"spot/v3/public/server-time": 1,
|
|
"spot/v3/public/infos": 1,
|
|
"spot/v3/public/margin-product-infos": 1,
|
|
"spot/v3/public/margin-ensure-tokens": 1,
|
|
"v3/public/time": 1,
|
|
"contract/v3/public/copytrading/symbol/list": 1,
|
|
"derivatives/v3/public/order-book/L2": 1,
|
|
"derivatives/v3/public/kline": 1,
|
|
"derivatives/v3/public/tickers": 1,
|
|
"derivatives/v3/public/instruments-info": 1,
|
|
"derivatives/v3/public/mark-price-kline": 1,
|
|
"derivatives/v3/public/index-price-kline": 1,
|
|
"derivatives/v3/public/funding/history-funding-rate": 1,
|
|
"derivatives/v3/public/risk-limit/list": 1,
|
|
"derivatives/v3/public/delivery-price": 1,
|
|
"derivatives/v3/public/recent-trade": 1,
|
|
"derivatives/v3/public/open-interest": 1,
|
|
"derivatives/v3/public/insurance": 1,
|
|
"v5/announcements/index": 5,
|
|
"v5/market/time": 5,
|
|
"v5/market/kline": 5,
|
|
"v5/market/mark-price-kline": 5,
|
|
"v5/market/index-price-kline": 5,
|
|
"v5/market/premium-index-price-kline": 5,
|
|
"v5/market/instruments-info": 5,
|
|
"v5/market/orderbook": 5,
|
|
"v5/market/tickers": 5,
|
|
"v5/market/funding/history": 5,
|
|
"v5/market/recent-trade": 5,
|
|
"v5/market/open-interest": 5,
|
|
"v5/market/historical-volatility": 5,
|
|
"v5/market/insurance": 5,
|
|
"v5/market/risk-limit": 5,
|
|
"v5/market/delivery-price": 5,
|
|
"v5/market/account-ratio": 5,
|
|
"v5/spot-lever-token/info": 5,
|
|
"v5/spot-lever-token/reference": 5,
|
|
"v5/spot-margin-trade/data": 5,
|
|
"v5/spot-margin-trade/collateral": 5,
|
|
"v5/spot-cross-margin-trade/data": 5,
|
|
"v5/spot-cross-margin-trade/pledge-token": 5,
|
|
"v5/spot-cross-margin-trade/borrow-token": 5,
|
|
"v5/crypto-loan/collateral-data": 5,
|
|
"v5/crypto-loan/loanable-data": 5,
|
|
"v5/ins-loan/product-infos": 5,
|
|
"v5/ins-loan/ensure-tokens-convert": 5,
|
|
},
|
|
},
|
|
"private": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"v5/market/instruments-info": 5,
|
|
"v2/private/wallet/fund/records": 25,
|
|
"spot/v3/private/order": 2.5,
|
|
"spot/v3/private/open-orders": 2.5,
|
|
"spot/v3/private/history-orders": 2.5,
|
|
"spot/v3/private/my-trades": 2.5,
|
|
"spot/v3/private/account": 2.5,
|
|
"spot/v3/private/reference": 2.5,
|
|
"spot/v3/private/record": 2.5,
|
|
"spot/v3/private/cross-margin-orders": 10,
|
|
"spot/v3/private/cross-margin-account": 10,
|
|
"spot/v3/private/cross-margin-loan-info": 10,
|
|
"spot/v3/private/cross-margin-repay-history": 10,
|
|
"spot/v3/private/margin-loan-infos": 10,
|
|
"spot/v3/private/margin-repaid-infos": 10,
|
|
"spot/v3/private/margin-ltv": 10,
|
|
"asset/v3/private/transfer/inter-transfer/list/query": 50,
|
|
"asset/v3/private/transfer/sub-member/list/query": 50,
|
|
"asset/v3/private/transfer/sub-member-transfer/list/query": 50,
|
|
"asset/v3/private/transfer/universal-transfer/list/query": 25,
|
|
"asset/v3/private/coin-info/query": 25,
|
|
"asset/v3/private/deposit/address/query": 10,
|
|
"contract/v3/private/copytrading/order/list": 30,
|
|
"contract/v3/private/copytrading/position/list": 40,
|
|
"contract/v3/private/copytrading/wallet/balance": 25,
|
|
"contract/v3/private/position/limit-info": 25,
|
|
"contract/v3/private/order/unfilled-orders": 1,
|
|
"contract/v3/private/order/list": 1,
|
|
"contract/v3/private/position/list": 1,
|
|
"contract/v3/private/execution/list": 1,
|
|
"contract/v3/private/position/closed-pnl": 1,
|
|
"contract/v3/private/account/wallet/balance": 1,
|
|
"contract/v3/private/account/fee-rate": 1,
|
|
"contract/v3/private/account/wallet/fund-records": 1,
|
|
"unified/v3/private/order/unfilled-orders": 1,
|
|
"unified/v3/private/order/list": 1,
|
|
"unified/v3/private/position/list": 1,
|
|
"unified/v3/private/execution/list": 1,
|
|
"unified/v3/private/delivery-record": 1,
|
|
"unified/v3/private/settlement-record": 1,
|
|
"unified/v3/private/account/wallet/balance": 1,
|
|
"unified/v3/private/account/transaction-log": 1,
|
|
"unified/v3/private/account/borrow-history": 1,
|
|
"unified/v3/private/account/borrow-rate": 1,
|
|
"unified/v3/private/account/info": 1,
|
|
"user/v3/private/frozen-sub-member": 10,
|
|
"user/v3/private/query-sub-members": 5,
|
|
"user/v3/private/query-api": 5,
|
|
"user/v3/private/get-member-type": 1,
|
|
"asset/v3/private/transfer/transfer-coin/list/query": 50,
|
|
"asset/v3/private/transfer/account-coin/balance/query": 50,
|
|
"asset/v3/private/transfer/account-coins/balance/query": 25,
|
|
"asset/v3/private/transfer/asset-info/query": 50,
|
|
"asset/v3/public/deposit/allowed-deposit-list/query": 0.17,
|
|
"asset/v3/private/deposit/record/query": 10,
|
|
"asset/v3/private/withdraw/record/query": 10,
|
|
"v5/order/realtime": 5,
|
|
"v5/order/history": 5,
|
|
"v5/order/spot-borrow-check": 1,
|
|
"v5/position/list": 5,
|
|
"v5/execution/list": 5,
|
|
"v5/position/closed-pnl": 5,
|
|
"v5/position/move-history": 5,
|
|
"v5/pre-upgrade/order/history": 5,
|
|
"v5/pre-upgrade/execution/list": 5,
|
|
"v5/pre-upgrade/position/closed-pnl": 5,
|
|
"v5/pre-upgrade/account/transaction-log": 5,
|
|
"v5/pre-upgrade/asset/delivery-record": 5,
|
|
"v5/pre-upgrade/asset/settlement-record": 5,
|
|
"v5/account/wallet-balance": 1,
|
|
"v5/account/borrow-history": 1,
|
|
"v5/account/collateral-info": 1,
|
|
"v5/asset/coin-greeks": 1,
|
|
"v5/account/fee-rate": 10,
|
|
"v5/account/info": 5,
|
|
"v5/account/transaction-log": 1,
|
|
"v5/account/contract-transaction-log": 1,
|
|
"v5/account/smp-group": 1,
|
|
"v5/account/mmp-state": 5,
|
|
"v5/account/withdrawal": 5,
|
|
"v5/asset/exchange/query-coin-list": 0.5,
|
|
"v5/asset/exchange/convert-result-query": 0.5,
|
|
"v5/asset/exchange/query-convert-history": 0.5,
|
|
"v5/asset/exchange/order-record": 5,
|
|
"v5/asset/delivery-record": 5,
|
|
"v5/asset/settlement-record": 5,
|
|
"v5/asset/transfer/query-asset-info": 50,
|
|
"v5/asset/transfer/query-account-coins-balance": 25,
|
|
"v5/asset/transfer/query-account-coin-balance": 50,
|
|
"v5/asset/transfer/query-transfer-coin-list": 50,
|
|
"v5/asset/transfer/query-inter-transfer-list": 50,
|
|
"v5/asset/transfer/query-sub-member-list": 50,
|
|
"v5/asset/transfer/query-universal-transfer-list": 25,
|
|
"v5/asset/deposit/query-allowed-list": 5,
|
|
"v5/asset/deposit/query-record": 10,
|
|
"v5/asset/deposit/query-sub-member-record": 10,
|
|
"v5/asset/deposit/query-internal-record": 5,
|
|
"v5/asset/deposit/query-address": 10,
|
|
"v5/asset/deposit/query-sub-member-address": 10,
|
|
"v5/asset/coin/query-info": 28,
|
|
"v5/asset/withdraw/query-record": 10,
|
|
"v5/asset/withdraw/withdrawable-amount": 5,
|
|
"v5/asset/withdraw/vasp/list": 5,
|
|
"v5/user/query-sub-members": 5,
|
|
"v5/user/query-api": 5,
|
|
"v5/user/sub-apikeys": 5,
|
|
"v5/user/get-member-type": 5,
|
|
"v5/user/aff-customer-info": 5,
|
|
"v5/user/del-submember": 5,
|
|
"v5/user/submembers": 5,
|
|
"v5/affiliate/aff-user-list": 5,
|
|
"v5/spot-lever-token/order-record": 1,
|
|
"v5/spot-margin-trade/interest-rate-history": 5,
|
|
"v5/spot-margin-trade/state": 5,
|
|
"v5/spot-cross-margin-trade/loan-info": 1,
|
|
"v5/spot-cross-margin-trade/account": 1,
|
|
"v5/spot-cross-margin-trade/orders": 1,
|
|
"v5/spot-cross-margin-trade/repay-history": 1,
|
|
"v5/crypto-loan/borrowable-collateralisable-number": 5,
|
|
"v5/crypto-loan/ongoing-orders": 5,
|
|
"v5/crypto-loan/repayment-history": 5,
|
|
"v5/crypto-loan/borrow-history": 5,
|
|
"v5/crypto-loan/max-collateral-amount": 5,
|
|
"v5/crypto-loan/adjustment-history": 5,
|
|
"v5/ins-loan/product-infos": 5,
|
|
"v5/ins-loan/ensure-tokens-convert": 5,
|
|
"v5/ins-loan/loan-order": 5,
|
|
"v5/ins-loan/repaid-history": 5,
|
|
"v5/ins-loan/ltv-convert": 5,
|
|
"v5/lending/info": 5,
|
|
"v5/lending/history-order": 5,
|
|
"v5/lending/account": 5,
|
|
"v5/broker/earning-record": 5,
|
|
"v5/broker/earnings-info": 5,
|
|
"v5/broker/account-info": 5,
|
|
"v5/broker/asset/query-sub-member-deposit-record": 10,
|
|
},
|
|
"post": map[string]interface{} {
|
|
"spot/v3/private/order": 2.5,
|
|
"spot/v3/private/cancel-order": 2.5,
|
|
"spot/v3/private/cancel-orders": 2.5,
|
|
"spot/v3/private/cancel-orders-by-ids": 2.5,
|
|
"spot/v3/private/purchase": 2.5,
|
|
"spot/v3/private/redeem": 2.5,
|
|
"spot/v3/private/cross-margin-loan": 10,
|
|
"spot/v3/private/cross-margin-repay": 10,
|
|
"asset/v3/private/transfer/inter-transfer": 150,
|
|
"asset/v3/private/withdraw/create": 300,
|
|
"asset/v3/private/withdraw/cancel": 50,
|
|
"asset/v3/private/transfer/sub-member-transfer": 150,
|
|
"asset/v3/private/transfer/transfer-sub-member-save": 150,
|
|
"asset/v3/private/transfer/universal-transfer": 10,
|
|
"user/v3/private/create-sub-member": 10,
|
|
"user/v3/private/create-sub-api": 10,
|
|
"user/v3/private/update-api": 10,
|
|
"user/v3/private/delete-api": 10,
|
|
"user/v3/private/update-sub-api": 10,
|
|
"user/v3/private/delete-sub-api": 10,
|
|
"contract/v3/private/copytrading/order/create": 30,
|
|
"contract/v3/private/copytrading/order/cancel": 30,
|
|
"contract/v3/private/copytrading/order/close": 30,
|
|
"contract/v3/private/copytrading/position/close": 40,
|
|
"contract/v3/private/copytrading/position/set-leverage": 40,
|
|
"contract/v3/private/copytrading/wallet/transfer": 25,
|
|
"contract/v3/private/copytrading/order/trading-stop": 2.5,
|
|
"contract/v3/private/order/create": 1,
|
|
"contract/v3/private/order/cancel": 1,
|
|
"contract/v3/private/order/cancel-all": 1,
|
|
"contract/v3/private/order/replace": 1,
|
|
"contract/v3/private/position/set-auto-add-margin": 1,
|
|
"contract/v3/private/position/switch-isolated": 1,
|
|
"contract/v3/private/position/switch-mode": 1,
|
|
"contract/v3/private/position/switch-tpsl-mode": 1,
|
|
"contract/v3/private/position/set-leverage": 1,
|
|
"contract/v3/private/position/trading-stop": 1,
|
|
"contract/v3/private/position/set-risk-limit": 1,
|
|
"contract/v3/private/account/setMarginMode": 1,
|
|
"unified/v3/private/order/create": 30,
|
|
"unified/v3/private/order/replace": 30,
|
|
"unified/v3/private/order/cancel": 30,
|
|
"unified/v3/private/order/create-batch": 30,
|
|
"unified/v3/private/order/replace-batch": 30,
|
|
"unified/v3/private/order/cancel-batch": 30,
|
|
"unified/v3/private/order/cancel-all": 30,
|
|
"unified/v3/private/position/set-leverage": 2.5,
|
|
"unified/v3/private/position/tpsl/switch-mode": 2.5,
|
|
"unified/v3/private/position/set-risk-limit": 2.5,
|
|
"unified/v3/private/position/trading-stop": 2.5,
|
|
"unified/v3/private/account/upgrade-unified-account": 2.5,
|
|
"unified/v3/private/account/setMarginMode": 2.5,
|
|
"fht/compliance/tax/v3/private/registertime": 50,
|
|
"fht/compliance/tax/v3/private/create": 50,
|
|
"fht/compliance/tax/v3/private/status": 50,
|
|
"fht/compliance/tax/v3/private/url": 50,
|
|
"v5/order/create": 2.5,
|
|
"v5/order/amend": 5,
|
|
"v5/order/cancel": 2.5,
|
|
"v5/order/cancel-all": 50,
|
|
"v5/order/create-batch": 5,
|
|
"v5/order/amend-batch": 5,
|
|
"v5/order/cancel-batch": 5,
|
|
"v5/order/disconnected-cancel-all": 5,
|
|
"v5/position/set-leverage": 5,
|
|
"v5/position/switch-isolated": 5,
|
|
"v5/position/set-tpsl-mode": 5,
|
|
"v5/position/switch-mode": 5,
|
|
"v5/position/set-risk-limit": 5,
|
|
"v5/position/trading-stop": 5,
|
|
"v5/position/set-auto-add-margin": 5,
|
|
"v5/position/add-margin": 5,
|
|
"v5/position/move-positions": 5,
|
|
"v5/position/confirm-pending-mmr": 5,
|
|
"v5/account/upgrade-to-uta": 5,
|
|
"v5/account/quick-repayment": 5,
|
|
"v5/account/set-margin-mode": 5,
|
|
"v5/account/set-hedging-mode": 5,
|
|
"v5/account/mmp-modify": 5,
|
|
"v5/account/mmp-reset": 5,
|
|
"v5/asset/exchange/quote-apply": 1,
|
|
"v5/asset/exchange/convert-execute": 1,
|
|
"v5/asset/transfer/inter-transfer": 50,
|
|
"v5/asset/transfer/save-transfer-sub-member": 150,
|
|
"v5/asset/transfer/universal-transfer": 10,
|
|
"v5/asset/deposit/deposit-to-account": 5,
|
|
"v5/asset/withdraw/create": 50,
|
|
"v5/asset/withdraw/cancel": 50,
|
|
"v5/user/create-sub-member": 10,
|
|
"v5/user/create-sub-api": 10,
|
|
"v5/user/frozen-sub-member": 10,
|
|
"v5/user/update-api": 10,
|
|
"v5/user/update-sub-api": 10,
|
|
"v5/user/delete-api": 10,
|
|
"v5/user/delete-sub-api": 10,
|
|
"v5/spot-lever-token/purchase": 2.5,
|
|
"v5/spot-lever-token/redeem": 2.5,
|
|
"v5/spot-margin-trade/switch-mode": 5,
|
|
"v5/spot-margin-trade/set-leverage": 5,
|
|
"v5/spot-cross-margin-trade/loan": 2.5,
|
|
"v5/spot-cross-margin-trade/repay": 2.5,
|
|
"v5/spot-cross-margin-trade/switch": 2.5,
|
|
"v5/crypto-loan/borrow": 5,
|
|
"v5/crypto-loan/repay": 5,
|
|
"v5/crypto-loan/adjust-ltv": 5,
|
|
"v5/ins-loan/association-uid": 5,
|
|
"v5/lending/purchase": 5,
|
|
"v5/lending/redeem": 5,
|
|
"v5/lending/redeem-cancel": 5,
|
|
"v5/account/set-collateral-switch": 5,
|
|
"v5/account/set-collateral-switch-batch": 5,
|
|
"v5/account/demo-apply-money": 5,
|
|
"v5/broker/award/info": 5,
|
|
"v5/broker/award/distribute-award": 5,
|
|
"v5/broker/award/distribution-record": 5,
|
|
},
|
|
},
|
|
},
|
|
"httpExceptions": map[string]interface{} {
|
|
"403": RateLimitExceeded,
|
|
},
|
|
"exceptions": map[string]interface{} {
|
|
"exact": map[string]interface{} {
|
|
"-10009": BadRequest,
|
|
"-1004": BadRequest,
|
|
"-1021": BadRequest,
|
|
"-1103": BadRequest,
|
|
"-1140": InvalidOrder,
|
|
"-1197": InvalidOrder,
|
|
"-2013": InvalidOrder,
|
|
"-2015": AuthenticationError,
|
|
"-6017": BadRequest,
|
|
"-6025": BadRequest,
|
|
"-6029": BadRequest,
|
|
"5004": ExchangeError,
|
|
"7001": BadRequest,
|
|
"10001": BadRequest,
|
|
"10002": InvalidNonce,
|
|
"10003": AuthenticationError,
|
|
"10004": AuthenticationError,
|
|
"10005": PermissionDenied,
|
|
"10006": RateLimitExceeded,
|
|
"10007": AuthenticationError,
|
|
"10008": AccountSuspended,
|
|
"10009": AuthenticationError,
|
|
"10010": PermissionDenied,
|
|
"10014": BadRequest,
|
|
"10016": ExchangeError,
|
|
"10017": BadRequest,
|
|
"10018": RateLimitExceeded,
|
|
"10020": PermissionDenied,
|
|
"10024": PermissionDenied,
|
|
"10027": PermissionDenied,
|
|
"10028": PermissionDenied,
|
|
"10029": PermissionDenied,
|
|
"12137": InvalidOrder,
|
|
"12201": BadRequest,
|
|
"12141": BadRequest,
|
|
"100028": PermissionDenied,
|
|
"110001": OrderNotFound,
|
|
"110003": InvalidOrder,
|
|
"110004": InsufficientFunds,
|
|
"110005": InvalidOrder,
|
|
"110006": InsufficientFunds,
|
|
"110007": InsufficientFunds,
|
|
"110008": InvalidOrder,
|
|
"110009": InvalidOrder,
|
|
"110010": InvalidOrder,
|
|
"110011": InvalidOrder,
|
|
"110012": InsufficientFunds,
|
|
"110013": BadRequest,
|
|
"110014": InsufficientFunds,
|
|
"110015": BadRequest,
|
|
"110016": InvalidOrder,
|
|
"110017": InvalidOrder,
|
|
"110018": BadRequest,
|
|
"110019": InvalidOrder,
|
|
"110020": InvalidOrder,
|
|
"110021": InvalidOrder,
|
|
"110022": InvalidOrder,
|
|
"110023": InvalidOrder,
|
|
"110024": BadRequest,
|
|
"110025": NoChange,
|
|
"110026": MarginModeAlreadySet,
|
|
"110027": NoChange,
|
|
"110028": BadRequest,
|
|
"110029": BadRequest,
|
|
"110030": InvalidOrder,
|
|
"110031": InvalidOrder,
|
|
"110032": InvalidOrder,
|
|
"110033": InvalidOrder,
|
|
"110034": InvalidOrder,
|
|
"110035": InvalidOrder,
|
|
"110036": InvalidOrder,
|
|
"110037": InvalidOrder,
|
|
"110038": InvalidOrder,
|
|
"110039": InvalidOrder,
|
|
"110040": InvalidOrder,
|
|
"110041": InvalidOrder,
|
|
"110042": InvalidOrder,
|
|
"110043": BadRequest,
|
|
"110044": InsufficientFunds,
|
|
"110045": InsufficientFunds,
|
|
"110046": BadRequest,
|
|
"110047": BadRequest,
|
|
"110048": BadRequest,
|
|
"110049": BadRequest,
|
|
"110050": BadRequest,
|
|
"110051": InsufficientFunds,
|
|
"110052": InsufficientFunds,
|
|
"110053": InsufficientFunds,
|
|
"110054": InvalidOrder,
|
|
"110055": InvalidOrder,
|
|
"110056": InvalidOrder,
|
|
"110057": InvalidOrder,
|
|
"110058": InvalidOrder,
|
|
"110059": InvalidOrder,
|
|
"110060": BadRequest,
|
|
"110061": BadRequest,
|
|
"110062": BadRequest,
|
|
"110063": ExchangeError,
|
|
"110064": InvalidOrder,
|
|
"110065": PermissionDenied,
|
|
"110066": ExchangeError,
|
|
"110067": PermissionDenied,
|
|
"110068": PermissionDenied,
|
|
"110069": PermissionDenied,
|
|
"110070": InvalidOrder,
|
|
"110071": ExchangeError,
|
|
"110072": InvalidOrder,
|
|
"110073": ExchangeError,
|
|
"110092": InvalidOrder,
|
|
"110093": InvalidOrder,
|
|
"110094": InvalidOrder,
|
|
"130006": InvalidOrder,
|
|
"130021": InsufficientFunds,
|
|
"130074": InvalidOrder,
|
|
"131001": InsufficientFunds,
|
|
"131084": ExchangeError,
|
|
"131200": ExchangeError,
|
|
"131201": ExchangeError,
|
|
"131202": BadRequest,
|
|
"131203": BadRequest,
|
|
"131204": BadRequest,
|
|
"131205": BadRequest,
|
|
"131206": ExchangeError,
|
|
"131207": BadRequest,
|
|
"131208": ExchangeError,
|
|
"131209": BadRequest,
|
|
"131210": BadRequest,
|
|
"131211": BadRequest,
|
|
"131212": InsufficientFunds,
|
|
"131213": BadRequest,
|
|
"131214": BadRequest,
|
|
"131215": BadRequest,
|
|
"131216": ExchangeError,
|
|
"131217": ExchangeError,
|
|
"131231": NotSupported,
|
|
"131232": NotSupported,
|
|
"131002": BadRequest,
|
|
"131003": ExchangeError,
|
|
"131004": AuthenticationError,
|
|
"131085": InsufficientFunds,
|
|
"131086": BadRequest,
|
|
"131088": BadRequest,
|
|
"131089": BadRequest,
|
|
"131090": ExchangeError,
|
|
"131091": ExchangeError,
|
|
"131092": ExchangeError,
|
|
"131093": ExchangeError,
|
|
"131094": BadRequest,
|
|
"131095": BadRequest,
|
|
"131096": BadRequest,
|
|
"131097": ExchangeError,
|
|
"131098": ExchangeError,
|
|
"131099": ExchangeError,
|
|
"140001": OrderNotFound,
|
|
"140003": InvalidOrder,
|
|
"140004": InsufficientFunds,
|
|
"140005": InvalidOrder,
|
|
"140006": InsufficientFunds,
|
|
"140007": InsufficientFunds,
|
|
"140008": InvalidOrder,
|
|
"140009": InvalidOrder,
|
|
"140010": InvalidOrder,
|
|
"140011": InvalidOrder,
|
|
"140012": InsufficientFunds,
|
|
"140013": BadRequest,
|
|
"140014": InsufficientFunds,
|
|
"140015": InvalidOrder,
|
|
"140016": InvalidOrder,
|
|
"140017": InvalidOrder,
|
|
"140018": BadRequest,
|
|
"140019": InvalidOrder,
|
|
"140020": InvalidOrder,
|
|
"140021": InvalidOrder,
|
|
"140022": InvalidOrder,
|
|
"140023": InvalidOrder,
|
|
"140024": BadRequest,
|
|
"140025": BadRequest,
|
|
"140026": BadRequest,
|
|
"140027": BadRequest,
|
|
"140028": InvalidOrder,
|
|
"140029": BadRequest,
|
|
"140030": InvalidOrder,
|
|
"140031": BadRequest,
|
|
"140032": InvalidOrder,
|
|
"140033": InvalidOrder,
|
|
"140034": InvalidOrder,
|
|
"140035": InvalidOrder,
|
|
"140036": BadRequest,
|
|
"140037": InvalidOrder,
|
|
"140038": BadRequest,
|
|
"140039": BadRequest,
|
|
"140040": InvalidOrder,
|
|
"140041": InvalidOrder,
|
|
"140042": InvalidOrder,
|
|
"140043": BadRequest,
|
|
"140044": InsufficientFunds,
|
|
"140045": InsufficientFunds,
|
|
"140046": BadRequest,
|
|
"140047": BadRequest,
|
|
"140048": BadRequest,
|
|
"140049": BadRequest,
|
|
"140050": InvalidOrder,
|
|
"140051": InsufficientFunds,
|
|
"140052": InsufficientFunds,
|
|
"140053": InsufficientFunds,
|
|
"140054": InvalidOrder,
|
|
"140055": InvalidOrder,
|
|
"140056": InvalidOrder,
|
|
"140057": InvalidOrder,
|
|
"140058": InvalidOrder,
|
|
"140059": InvalidOrder,
|
|
"140060": BadRequest,
|
|
"140061": BadRequest,
|
|
"140062": BadRequest,
|
|
"140063": ExchangeError,
|
|
"140064": InvalidOrder,
|
|
"140065": PermissionDenied,
|
|
"140066": ExchangeError,
|
|
"140067": PermissionDenied,
|
|
"140068": PermissionDenied,
|
|
"140069": PermissionDenied,
|
|
"140070": InvalidOrder,
|
|
"170001": ExchangeError,
|
|
"170005": InvalidOrder,
|
|
"170007": RequestTimeout,
|
|
"170010": InvalidOrder,
|
|
"170011": InvalidOrder,
|
|
"170019": InvalidOrder,
|
|
"170031": ExchangeError,
|
|
"170032": ExchangeError,
|
|
"170033": InsufficientFunds,
|
|
"170034": InsufficientFunds,
|
|
"170035": BadRequest,
|
|
"170036": BadRequest,
|
|
"170037": BadRequest,
|
|
"170105": BadRequest,
|
|
"170115": InvalidOrder,
|
|
"170116": InvalidOrder,
|
|
"170117": InvalidOrder,
|
|
"170121": InvalidOrder,
|
|
"170124": InvalidOrder,
|
|
"170130": BadRequest,
|
|
"170131": InsufficientFunds,
|
|
"170132": InvalidOrder,
|
|
"170133": InvalidOrder,
|
|
"170134": InvalidOrder,
|
|
"170135": InvalidOrder,
|
|
"170136": InvalidOrder,
|
|
"170137": InvalidOrder,
|
|
"170139": InvalidOrder,
|
|
"170140": InvalidOrder,
|
|
"170141": InvalidOrder,
|
|
"170142": InvalidOrder,
|
|
"170143": InvalidOrder,
|
|
"170144": InvalidOrder,
|
|
"170145": InvalidOrder,
|
|
"170146": InvalidOrder,
|
|
"170147": InvalidOrder,
|
|
"170148": InvalidOrder,
|
|
"170149": ExchangeError,
|
|
"170150": ExchangeError,
|
|
"170151": InvalidOrder,
|
|
"170157": InvalidOrder,
|
|
"170159": InvalidOrder,
|
|
"170190": InvalidOrder,
|
|
"170191": InvalidOrder,
|
|
"170192": InvalidOrder,
|
|
"170193": InvalidOrder,
|
|
"170194": InvalidOrder,
|
|
"170195": InvalidOrder,
|
|
"170196": InvalidOrder,
|
|
"170197": InvalidOrder,
|
|
"170198": InvalidOrder,
|
|
"170199": InvalidOrder,
|
|
"170200": InvalidOrder,
|
|
"170201": PermissionDenied,
|
|
"170202": InvalidOrder,
|
|
"170203": InvalidOrder,
|
|
"170204": InvalidOrder,
|
|
"170206": InvalidOrder,
|
|
"170210": InvalidOrder,
|
|
"170213": OrderNotFound,
|
|
"170217": InvalidOrder,
|
|
"170218": InvalidOrder,
|
|
"170221": BadRequest,
|
|
"170222": RateLimitExceeded,
|
|
"170223": InsufficientFunds,
|
|
"170224": PermissionDenied,
|
|
"170226": InsufficientFunds,
|
|
"170227": ExchangeError,
|
|
"170228": InvalidOrder,
|
|
"170229": InvalidOrder,
|
|
"170234": ExchangeError,
|
|
"170241": ManualInteractionNeeded,
|
|
"175000": InvalidOrder,
|
|
"175001": InvalidOrder,
|
|
"175002": InvalidOrder,
|
|
"175003": InsufficientFunds,
|
|
"175004": InvalidOrder,
|
|
"175005": InvalidOrder,
|
|
"175006": InsufficientFunds,
|
|
"175007": InvalidOrder,
|
|
"175008": InvalidOrder,
|
|
"175009": InvalidOrder,
|
|
"175010": PermissionDenied,
|
|
"175012": InvalidOrder,
|
|
"175013": InvalidOrder,
|
|
"175014": InvalidOrder,
|
|
"175015": InvalidOrder,
|
|
"175016": InvalidOrder,
|
|
"175017": InvalidOrder,
|
|
"175027": ExchangeError,
|
|
"176002": BadRequest,
|
|
"176004": BadRequest,
|
|
"176003": BadRequest,
|
|
"176006": BadRequest,
|
|
"176005": BadRequest,
|
|
"176008": BadRequest,
|
|
"176007": BadRequest,
|
|
"176010": BadRequest,
|
|
"176009": BadRequest,
|
|
"176012": BadRequest,
|
|
"176011": BadRequest,
|
|
"176014": BadRequest,
|
|
"176013": BadRequest,
|
|
"176015": InsufficientFunds,
|
|
"176016": BadRequest,
|
|
"176017": BadRequest,
|
|
"176018": BadRequest,
|
|
"176019": BadRequest,
|
|
"176020": BadRequest,
|
|
"176021": BadRequest,
|
|
"176022": BadRequest,
|
|
"176023": BadRequest,
|
|
"176024": BadRequest,
|
|
"176025": BadRequest,
|
|
"176026": BadRequest,
|
|
"176027": BadRequest,
|
|
"176028": BadRequest,
|
|
"176029": BadRequest,
|
|
"176030": BadRequest,
|
|
"176031": BadRequest,
|
|
"176034": BadRequest,
|
|
"176035": PermissionDenied,
|
|
"176036": PermissionDenied,
|
|
"176037": PermissionDenied,
|
|
"176038": BadRequest,
|
|
"176039": BadRequest,
|
|
"176040": BadRequest,
|
|
"181000": BadRequest,
|
|
"181001": BadRequest,
|
|
"181002": InvalidOrder,
|
|
"181003": InvalidOrder,
|
|
"181004": InvalidOrder,
|
|
"182000": InvalidOrder,
|
|
"181017": BadRequest,
|
|
"20001": OrderNotFound,
|
|
"20003": InvalidOrder,
|
|
"20004": InvalidOrder,
|
|
"20005": InvalidOrder,
|
|
"20006": InvalidOrder,
|
|
"20007": InvalidOrder,
|
|
"20008": InvalidOrder,
|
|
"20009": InvalidOrder,
|
|
"20010": InvalidOrder,
|
|
"20011": InvalidOrder,
|
|
"20012": InvalidOrder,
|
|
"20013": InvalidOrder,
|
|
"20014": InvalidOrder,
|
|
"20015": InvalidOrder,
|
|
"20016": InvalidOrder,
|
|
"20017": InvalidOrder,
|
|
"20018": InvalidOrder,
|
|
"20019": InvalidOrder,
|
|
"20020": InvalidOrder,
|
|
"20021": InvalidOrder,
|
|
"20022": BadRequest,
|
|
"20023": BadRequest,
|
|
"20031": BadRequest,
|
|
"20070": BadRequest,
|
|
"20071": BadRequest,
|
|
"20084": BadRequest,
|
|
"30001": BadRequest,
|
|
"30003": InvalidOrder,
|
|
"30004": InvalidOrder,
|
|
"30005": InvalidOrder,
|
|
"30007": InvalidOrder,
|
|
"30008": InvalidOrder,
|
|
"30009": ExchangeError,
|
|
"30010": InsufficientFunds,
|
|
"30011": PermissionDenied,
|
|
"30012": PermissionDenied,
|
|
"30013": PermissionDenied,
|
|
"30014": InvalidOrder,
|
|
"30015": InvalidOrder,
|
|
"30016": ExchangeError,
|
|
"30017": InvalidOrder,
|
|
"30018": InvalidOrder,
|
|
"30019": InvalidOrder,
|
|
"30020": InvalidOrder,
|
|
"30021": InvalidOrder,
|
|
"30022": InvalidOrder,
|
|
"30023": InvalidOrder,
|
|
"30024": InvalidOrder,
|
|
"30025": InvalidOrder,
|
|
"30026": InvalidOrder,
|
|
"30027": InvalidOrder,
|
|
"30028": InvalidOrder,
|
|
"30029": InvalidOrder,
|
|
"30030": InvalidOrder,
|
|
"30031": InsufficientFunds,
|
|
"30032": InvalidOrder,
|
|
"30033": RateLimitExceeded,
|
|
"30034": OrderNotFound,
|
|
"30035": RateLimitExceeded,
|
|
"30036": ExchangeError,
|
|
"30037": InvalidOrder,
|
|
"30041": ExchangeError,
|
|
"30042": InsufficientFunds,
|
|
"30043": InvalidOrder,
|
|
"30044": InvalidOrder,
|
|
"30045": InvalidOrder,
|
|
"30049": InsufficientFunds,
|
|
"30050": ExchangeError,
|
|
"30051": ExchangeError,
|
|
"30052": ExchangeError,
|
|
"30054": ExchangeError,
|
|
"30057": ExchangeError,
|
|
"30063": ExchangeError,
|
|
"30067": InsufficientFunds,
|
|
"30068": ExchangeError,
|
|
"30074": InvalidOrder,
|
|
"30075": InvalidOrder,
|
|
"30078": ExchangeError,
|
|
"33004": AuthenticationError,
|
|
"34026": ExchangeError,
|
|
"34036": BadRequest,
|
|
"35015": BadRequest,
|
|
"340099": ExchangeError,
|
|
"3400045": ExchangeError,
|
|
"3100116": BadRequest,
|
|
"3100198": BadRequest,
|
|
"3200300": InsufficientFunds,
|
|
},
|
|
"broad": map[string]interface{} {
|
|
"Not supported symbols": BadSymbol,
|
|
"Request timeout": RequestTimeout,
|
|
"unknown orderInfo": OrderNotFound,
|
|
"invalid api_key": AuthenticationError,
|
|
"oc_diff": InsufficientFunds,
|
|
"new_oc": InsufficientFunds,
|
|
"openapi sign params error!": AuthenticationError,
|
|
},
|
|
},
|
|
"precisionMode": TICK_SIZE,
|
|
"options": map[string]interface{} {
|
|
"usePrivateInstrumentsInfo": false,
|
|
"enableDemoTrading": false,
|
|
"fetchMarkets": []interface{}{"spot", "linear", "inverse", "option"},
|
|
"createOrder": map[string]interface{} {
|
|
"method": "privatePostV5OrderCreate",
|
|
},
|
|
"enableUnifiedMargin": nil,
|
|
"enableUnifiedAccount": nil,
|
|
"unifiedMarginStatus": nil,
|
|
"createMarketBuyOrderRequiresPrice": false,
|
|
"createUnifiedMarginAccount": false,
|
|
"defaultType": "swap",
|
|
"defaultSubType": "linear",
|
|
"defaultSettle": "USDT",
|
|
"code": "BTC",
|
|
"recvWindow": Multiply(5, 1000),
|
|
"timeDifference": 0,
|
|
"adjustForTimeDifference": false,
|
|
"loadAllOptions": false,
|
|
"loadExpiredOptions": false,
|
|
"brokerId": "CCXT",
|
|
"accountsByType": map[string]interface{} {
|
|
"spot": "SPOT",
|
|
"margin": "SPOT",
|
|
"future": "CONTRACT",
|
|
"swap": "CONTRACT",
|
|
"option": "OPTION",
|
|
"investment": "INVESTMENT",
|
|
"unified": "UNIFIED",
|
|
"funding": "FUND",
|
|
"fund": "FUND",
|
|
"contract": "CONTRACT",
|
|
},
|
|
"accountsById": map[string]interface{} {
|
|
"SPOT": "spot",
|
|
"MARGIN": "spot",
|
|
"CONTRACT": "contract",
|
|
"OPTION": "option",
|
|
"INVESTMENT": "investment",
|
|
"UNIFIED": "unified",
|
|
"FUND": "fund",
|
|
},
|
|
"networks": map[string]interface{} {
|
|
"ERC20": "ETH",
|
|
"TRC20": "TRX",
|
|
"BEP20": "BSC",
|
|
"SOL": "SOL",
|
|
"ACA": "ACA",
|
|
"ADA": "ADA",
|
|
"ALGO": "ALGO",
|
|
"APT": "APTOS",
|
|
"AR": "AR",
|
|
"ARBONE": "ARBI",
|
|
"AVAXC": "CAVAX",
|
|
"AVAXX": "XAVAX",
|
|
"ATOM": "ATOM",
|
|
"BCH": "BCH",
|
|
"BEP2": "BNB",
|
|
"CHZ": "CHZ",
|
|
"DCR": "DCR",
|
|
"DGB": "DGB",
|
|
"DOGE": "DOGE",
|
|
"DOT": "DOT",
|
|
"EGLD": "EGLD",
|
|
"EOS": "EOS",
|
|
"ETC": "ETC",
|
|
"ETHF": "ETHF",
|
|
"ETHW": "ETHW",
|
|
"FIL": "FIL",
|
|
"STEP": "FITFI",
|
|
"FLOW": "FLOW",
|
|
"FTM": "FTM",
|
|
"GLMR": "GLMR",
|
|
"HBAR": "HBAR",
|
|
"HNT": "HNT",
|
|
"ICP": "ICP",
|
|
"ICX": "ICX",
|
|
"KDA": "KDA",
|
|
"KLAY": "KLAY",
|
|
"KMA": "KMA",
|
|
"KSM": "KSM",
|
|
"LTC": "LTC",
|
|
"MATIC": "MATIC",
|
|
"MINA": "MINA",
|
|
"MOVR": "MOVR",
|
|
"NEAR": "NEAR",
|
|
"NEM": "NEM",
|
|
"OASYS": "OAS",
|
|
"OASIS": "ROSE",
|
|
"OMNI": "OMNI",
|
|
"ONE": "ONE",
|
|
"OPTIMISM": "OP",
|
|
"POKT": "POKT",
|
|
"QTUM": "QTUM",
|
|
"RVN": "RVN",
|
|
"SC": "SC",
|
|
"SCRT": "SCRT",
|
|
"STX": "STX",
|
|
"THETA": "THETA",
|
|
"TON": "TON",
|
|
"WAVES": "WAVES",
|
|
"WAX": "WAXP",
|
|
"XDC": "XDC",
|
|
"XEC": "XEC",
|
|
"XLM": "XLM",
|
|
"XRP": "XRP",
|
|
"XTZ": "XTZ",
|
|
"XYM": "XYM",
|
|
"ZEN": "ZEN",
|
|
"ZIL": "ZIL",
|
|
"ZKSYNC": "ZKSYNC",
|
|
},
|
|
"networksById": map[string]interface{} {
|
|
"ETH": "ERC20",
|
|
"TRX": "TRC20",
|
|
"BSC": "BEP20",
|
|
"OMNI": "OMNI",
|
|
"SPL": "SOL",
|
|
},
|
|
"defaultNetwork": "ERC20",
|
|
"defaultNetworks": map[string]interface{} {
|
|
"USDT": "TRC20",
|
|
},
|
|
"intervals": map[string]interface{} {
|
|
"5m": "5min",
|
|
"15m": "15min",
|
|
"30m": "30min",
|
|
"1h": "1h",
|
|
"4h": "4h",
|
|
"1d": "1d",
|
|
},
|
|
},
|
|
"features": map[string]interface{} {
|
|
"default": map[string]interface{} {
|
|
"sandbox": true,
|
|
"createOrder": map[string]interface{} {
|
|
"marginMode": false,
|
|
"triggerPrice": true,
|
|
"triggerPriceType": map[string]interface{} {
|
|
"last": true,
|
|
"mark": true,
|
|
"index": true,
|
|
},
|
|
"triggerDirection": true,
|
|
"stopLossPrice": true,
|
|
"takeProfitPrice": true,
|
|
"attachedStopLossTakeProfit": map[string]interface{} {
|
|
"triggerPriceType": map[string]interface{} {
|
|
"last": true,
|
|
"mark": true,
|
|
"index": true,
|
|
},
|
|
"price": true,
|
|
},
|
|
"timeInForce": map[string]interface{} {
|
|
"IOC": true,
|
|
"FOK": true,
|
|
"PO": true,
|
|
"GTD": false,
|
|
},
|
|
"hedged": true,
|
|
"selfTradePrevention": true,
|
|
"trailing": true,
|
|
"iceberg": false,
|
|
"leverage": false,
|
|
"marketBuyRequiresPrice": false,
|
|
"marketBuyByCost": true,
|
|
},
|
|
"createOrders": map[string]interface{} {
|
|
"max": 10,
|
|
},
|
|
"fetchMyTrades": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 100,
|
|
"daysBack": Multiply(365, 2),
|
|
"untilDays": 7,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOrder": map[string]interface{} {
|
|
"marginMode": false,
|
|
"trigger": true,
|
|
"trailing": false,
|
|
"symbolRequired": true,
|
|
},
|
|
"fetchOpenOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 50,
|
|
"trigger": true,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOrders": nil,
|
|
"fetchClosedOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 50,
|
|
"daysBack": Multiply(365, 2),
|
|
"daysBackCanceled": 1,
|
|
"untilDays": 7,
|
|
"trigger": true,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOHLCV": map[string]interface{} {
|
|
"limit": 1000,
|
|
},
|
|
"editOrders": map[string]interface{} {
|
|
"max": 10,
|
|
},
|
|
},
|
|
"spot": map[string]interface{} {
|
|
"extends": "default",
|
|
"createOrder": map[string]interface{} {
|
|
"triggerPriceType": nil,
|
|
"triggerDirection": false,
|
|
"attachedStopLossTakeProfit": map[string]interface{} {
|
|
"triggerPriceType": nil,
|
|
"price": true,
|
|
},
|
|
"marketBuyRequiresPrice": true,
|
|
},
|
|
},
|
|
"swap": map[string]interface{} {
|
|
"linear": map[string]interface{} {
|
|
"extends": "default",
|
|
},
|
|
"inverse": map[string]interface{} {
|
|
"extends": "default",
|
|
},
|
|
},
|
|
"future": map[string]interface{} {
|
|
"linear": map[string]interface{} {
|
|
"extends": "default",
|
|
},
|
|
"inverse": map[string]interface{} {
|
|
"extends": "default",
|
|
},
|
|
},
|
|
},
|
|
"fees": map[string]interface{} {
|
|
"trading": map[string]interface{} {
|
|
"feeSide": "get",
|
|
"tierBased": true,
|
|
"percentage": true,
|
|
"taker": 0.00075,
|
|
"maker": 0.0001,
|
|
},
|
|
"funding": map[string]interface{} {
|
|
"tierBased": false,
|
|
"percentage": false,
|
|
"withdraw": map[string]interface{} {},
|
|
"deposit": map[string]interface{} {},
|
|
},
|
|
},
|
|
})
|
|
}
|
|
func (this *bybit) EnableDemoTrading(enable interface{}) {
|
|
/**
|
|
* @method
|
|
* @name bybit#enableDemoTrading
|
|
* @description enables or disables demo trading mode
|
|
* @see https://bybit-exchange.github.io/docs/v5/demo
|
|
* @param {boolean} [enable] true if demo trading should be enabled, false otherwise
|
|
*/
|
|
if IsTrue(this.IsSandboxModeEnabled) {
|
|
panic(NotSupported(Add(this.Id, " demo trading does not support in sandbox environment")))
|
|
}
|
|
// enable demo trading in bybit, see: https://bybit-exchange.github.io/docs/v5/demo
|
|
if IsTrue(enable) {
|
|
AddElementToObject(this.Urls, "apiBackupDemoTrading", GetValue(this.Urls, "api"))
|
|
AddElementToObject(this.Urls, "api", GetValue(this.Urls, "demotrading"))
|
|
} else if IsTrue(InOp(this.Urls, "apiBackupDemoTrading")) {
|
|
AddElementToObject(this.Urls, "api", GetValue(this.Urls, "apiBackupDemoTrading"))
|
|
var newUrls interface{} = this.Omit(this.Urls, "apiBackupDemoTrading")
|
|
this.Urls = newUrls
|
|
}
|
|
AddElementToObject(this.Options, "enableDemoTrading", enable)
|
|
}
|
|
func (this *bybit) Nonce() interface{} {
|
|
return Subtract(this.Milliseconds(), GetValue(this.Options, "timeDifference"))
|
|
}
|
|
func (this *bybit) AddPaginationCursorToResult(response interface{}) interface{} {
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var data interface{} = this.SafeListN(result, []interface{}{"list", "rows", "data", "dataList"}, []interface{}{})
|
|
var paginationCursor interface{} = this.SafeString2(result, "nextPageCursor", "cursor")
|
|
var dataLength interface{} = GetArrayLength(data)
|
|
if IsTrue(IsTrue((!IsEqual(paginationCursor, nil))) && IsTrue((IsGreaterThan(dataLength, 0)))) {
|
|
var first interface{} = GetValue(data, 0)
|
|
AddElementToObject(first, "nextPageCursor", paginationCursor)
|
|
AddElementToObject(data, 0, first)
|
|
}
|
|
return data
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#isUnifiedEnabled
|
|
* @see https://bybit-exchange.github.io/docs/v5/user/apikey-info#http-request
|
|
* @see https://bybit-exchange.github.io/docs/v5/account/account-info
|
|
* @description returns [enableUnifiedMargin, enableUnifiedAccount] so the user can check if unified account is enabled
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {any} [enableUnifiedMargin, enableUnifiedAccount]
|
|
*/
|
|
func (this *bybit) IsUnifiedEnabled(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
// The API key of user id must own one of permissions will be allowed to call following API endpoints:
|
|
// SUB UID: "Account Transfer"
|
|
// MASTER UID: "Account Transfer", "Subaccount Transfer", "Withdrawal"
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
var enableUnifiedMargin interface{} = this.SafeBool(this.Options, "enableUnifiedMargin")
|
|
var enableUnifiedAccount interface{} = this.SafeBool(this.Options, "enableUnifiedAccount")
|
|
if IsTrue(IsTrue(IsEqual(enableUnifiedMargin, nil)) || IsTrue(IsEqual(enableUnifiedAccount, nil))) {
|
|
if IsTrue(GetValue(this.Options, "enableDemoTrading")) {
|
|
// info endpoint is not available in demo trading
|
|
// so we're assuming UTA is enabled
|
|
AddElementToObject(this.Options, "enableUnifiedMargin", false)
|
|
AddElementToObject(this.Options, "enableUnifiedAccount", true)
|
|
AddElementToObject(this.Options, "unifiedMarginStatus", 6)
|
|
|
|
ch <- []interface{}{GetValue(this.Options, "enableUnifiedMargin"), GetValue(this.Options, "enableUnifiedAccount")}
|
|
return nil
|
|
}
|
|
var rawPromises interface{} = []interface{}{this.PrivateGetV5UserQueryApi(params), this.PrivateGetV5AccountInfo(params)}
|
|
|
|
promises:= (<-promiseAll(rawPromises))
|
|
PanicOnError(promises)
|
|
var response interface{} = GetValue(promises, 0)
|
|
var accountInfo interface{} = GetValue(promises, 1)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "",
|
|
// "result": {
|
|
// "id": "13770661",
|
|
// "note": "XXXXXX",
|
|
// "apiKey": "XXXXXX",
|
|
// "readOnly": 0,
|
|
// "secret": "",
|
|
// "permissions": {
|
|
// "ContractTrade": [...],
|
|
// "Spot": [...],
|
|
// "Wallet": [...],
|
|
// "Options": [...],
|
|
// "Derivatives": [...],
|
|
// "CopyTrading": [...],
|
|
// "BlockTrade": [...],
|
|
// "Exchange": [...],
|
|
// "NFT": [...],
|
|
// },
|
|
// "ips": [...],
|
|
// "type": 1,
|
|
// "deadlineDay": 83,
|
|
// "expiredAt": "2023-05-15T03:21:05Z",
|
|
// "createdAt": "2022-10-16T02:24:40Z",
|
|
// "unified": 0,
|
|
// "uta": 0,
|
|
// "userID": 24600000,
|
|
// "inviterID": 0,
|
|
// "vipLevel": "No VIP",
|
|
// "mktMakerLevel": "0",
|
|
// "affiliateID": 0,
|
|
// "rsaPublicKey": "",
|
|
// "isMaster": false
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1676891757649
|
|
// }
|
|
// account info
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "marginMode": "REGULAR_MARGIN",
|
|
// "updatedTime": "1697078946000",
|
|
// "unifiedMarginStatus": 4,
|
|
// "dcpStatus": "OFF",
|
|
// "timeWindow": 10,
|
|
// "smpGroup": 0,
|
|
// "isMasterTrader": false,
|
|
// "spotHedgingStatus": "OFF"
|
|
// }
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var accountResult interface{} = this.SafeDict(accountInfo, "result", map[string]interface{} {})
|
|
AddElementToObject(this.Options, "enableUnifiedMargin", IsEqual(this.SafeInteger(result, "unified"), 1))
|
|
AddElementToObject(this.Options, "enableUnifiedAccount", IsEqual(this.SafeInteger(result, "uta"), 1))
|
|
AddElementToObject(this.Options, "unifiedMarginStatus", this.SafeInteger(accountResult, "unifiedMarginStatus", 6)) // default to uta 2.0 pro if not found
|
|
}
|
|
|
|
ch <- []interface{}{GetValue(this.Options, "enableUnifiedMargin"), GetValue(this.Options, "enableUnifiedAccount")}
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#upgradeUnifiedTradeAccount
|
|
* @description upgrades the account to unified trade account *warning* this is irreversible
|
|
* @see https://bybit-exchange.github.io/docs/v5/account/upgrade-unified-account
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {any} nothing
|
|
*/
|
|
func (this *bybit) UpgradeUnifiedTradeAccount(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
|
|
|
|
retRes142115 := (<-this.PrivatePostV5AccountUpgradeToUta(params))
|
|
PanicOnError(retRes142115)
|
|
ch <- retRes142115
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) CreateExpiredOptionMarket(symbol interface{}) interface{} {
|
|
// support expired option contracts
|
|
var quote interface{} = nil
|
|
var settle interface{} = nil
|
|
var optionParts interface{} = Split(symbol, "-")
|
|
var symbolBase interface{} = Split(symbol, "/")
|
|
var base interface{} = nil
|
|
var expiry interface{} = nil
|
|
if IsTrue(IsGreaterThan(GetIndexOf(symbol, "/"), OpNeg(1))) {
|
|
base = this.SafeString(symbolBase, 0)
|
|
expiry = this.SafeString(optionParts, 1)
|
|
var symbolQuoteAndSettle interface{} = this.SafeString(symbolBase, 1)
|
|
var splitQuote interface{} = Split(symbolQuoteAndSettle, ":")
|
|
var quoteAndSettle interface{} = this.SafeString(splitQuote, 0)
|
|
quote = quoteAndSettle
|
|
settle = quoteAndSettle
|
|
} else {
|
|
base = this.SafeString(optionParts, 0)
|
|
expiry = this.ConvertMarketIdExpireDate(this.SafeString(optionParts, 1))
|
|
if IsTrue(EndsWith(symbol, "-USDT")) {
|
|
quote = "USDT"
|
|
settle = "USDT"
|
|
} else {
|
|
quote = "USDC"
|
|
settle = "USDC"
|
|
}
|
|
}
|
|
var strike interface{} = this.SafeString(optionParts, 2)
|
|
var optionType interface{} = this.SafeString(optionParts, 3)
|
|
var datetime interface{} = this.ConvertExpireDate(expiry)
|
|
var timestamp interface{} = this.Parse8601(datetime)
|
|
var amountPrecision interface{} = nil
|
|
var pricePrecision interface{} = nil
|
|
// hard coded amount and price precisions from fetchOptionMarkets
|
|
if IsTrue(IsEqual(base, "BTC")) {
|
|
amountPrecision = this.ParseNumber("0.01")
|
|
pricePrecision = this.ParseNumber("5")
|
|
} else if IsTrue(IsEqual(base, "ETH")) {
|
|
amountPrecision = this.ParseNumber("0.1")
|
|
pricePrecision = this.ParseNumber("0.1")
|
|
} else if IsTrue(IsEqual(base, "SOL")) {
|
|
amountPrecision = this.ParseNumber("1")
|
|
pricePrecision = this.ParseNumber("0.01")
|
|
}
|
|
return map[string]interface{} {
|
|
"id": Add(Add(Add(Add(Add(Add(base, "-"), this.ConvertExpireDateToMarketIdDate(expiry)), "-"), strike), "-"), optionType),
|
|
"symbol": Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(base, "/"), quote), ":"), settle), "-"), expiry), "-"), strike), "-"), optionType),
|
|
"base": base,
|
|
"quote": quote,
|
|
"settle": settle,
|
|
"baseId": base,
|
|
"quoteId": quote,
|
|
"settleId": settle,
|
|
"active": false,
|
|
"type": "option",
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
"spot": false,
|
|
"swap": false,
|
|
"future": false,
|
|
"option": true,
|
|
"margin": false,
|
|
"contract": true,
|
|
"contractSize": this.ParseNumber("1"),
|
|
"expiry": timestamp,
|
|
"expiryDatetime": datetime,
|
|
"optionType": Ternary(IsTrue((IsEqual(optionType, "C"))), "call", "put"),
|
|
"strike": this.ParseNumber(strike),
|
|
"precision": map[string]interface{} {
|
|
"amount": amountPrecision,
|
|
"price": pricePrecision,
|
|
},
|
|
"limits": map[string]interface{} {
|
|
"amount": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"price": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"cost": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
},
|
|
"info": nil,
|
|
}
|
|
}
|
|
func (this *bybit) SafeMarket(optionalArgs ...interface{}) interface{} {
|
|
marketId := GetArg(optionalArgs, 0, nil)
|
|
_ = marketId
|
|
market := GetArg(optionalArgs, 1, nil)
|
|
_ = market
|
|
delimiter := GetArg(optionalArgs, 2, nil)
|
|
_ = delimiter
|
|
marketType := GetArg(optionalArgs, 3, nil)
|
|
_ = marketType
|
|
var isOption interface{} = IsTrue((!IsEqual(marketId, nil))) && IsTrue((IsTrue((IsGreaterThan(GetIndexOf(marketId, "-C"), OpNeg(1)))) || IsTrue((IsGreaterThan(GetIndexOf(marketId, "-P"), OpNeg(1))))))
|
|
if IsTrue(IsTrue(isOption) && !IsTrue((InOp(this.Markets_by_id, marketId)))) {
|
|
// handle expired option contracts
|
|
return this.CreateExpiredOptionMarket(marketId)
|
|
}
|
|
return this.Exchange.SafeMarket(marketId, market, delimiter, marketType)
|
|
}
|
|
func (this *bybit) GetBybitType(method interface{}, market interface{}, optionalArgs ...interface{}) interface{} {
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.HandleMarketTypeAndParams(method, market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
var subType interface{} = nil
|
|
subTypeparamsVariable := this.HandleSubTypeAndParams(method, market, params);
|
|
subType = GetValue(subTypeparamsVariable,0);
|
|
params = GetValue(subTypeparamsVariable,1)
|
|
if IsTrue(IsTrue(IsEqual(typeVar, "option")) || IsTrue(IsEqual(typeVar, "spot"))) {
|
|
return []interface{}{typeVar, params}
|
|
}
|
|
return []interface{}{subType, params}
|
|
}
|
|
func (this *bybit) GetAmount(symbol interface{}, amount interface{}) interface{} {
|
|
// some markets like options might not have the precision available
|
|
// and we shouldn't crash in those cases
|
|
var market interface{} = this.Market(symbol)
|
|
var emptyPrecisionAmount interface{} = (IsEqual(GetValue(GetValue(market, "precision"), "amount"), nil))
|
|
var amountString interface{} = this.NumberToString(amount)
|
|
if IsTrue(!IsTrue(emptyPrecisionAmount) && IsTrue((!IsEqual(amountString, "0")))) {
|
|
return this.AmountToPrecision(symbol, amount)
|
|
}
|
|
return amountString
|
|
}
|
|
func (this *bybit) GetPrice(symbol interface{}, price interface{}) interface{} {
|
|
if IsTrue(IsEqual(price, nil)) {
|
|
return price
|
|
}
|
|
var market interface{} = this.Market(symbol)
|
|
var emptyPrecisionPrice interface{} = (IsEqual(GetValue(GetValue(market, "precision"), "price"), nil))
|
|
if !IsTrue(emptyPrecisionPrice) {
|
|
return this.PriceToPrecision(symbol, price)
|
|
}
|
|
return price
|
|
}
|
|
func (this *bybit) GetCost(symbol interface{}, cost interface{}) interface{} {
|
|
var market interface{} = this.Market(symbol)
|
|
var emptyPrecisionPrice interface{} = (IsEqual(GetValue(GetValue(market, "precision"), "price"), nil))
|
|
if !IsTrue(emptyPrecisionPrice) {
|
|
return this.CostToPrecision(symbol, cost)
|
|
}
|
|
return cost
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchTime
|
|
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/time
|
|
* @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 *bybit) 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
|
|
|
|
response:= (<-this.PublicGetV5MarketTime(params))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "retCode": "0",
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "timeSecond": "1666879482",
|
|
// "timeNano": "1666879482792685914"
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": "1666879482792"
|
|
// }
|
|
//
|
|
ch <- this.SafeInteger(response, "time")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchCurrencies
|
|
* @description fetches all available currencies on an exchange
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/coin-info
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} an associative dictionary of currencies
|
|
*/
|
|
func (this *bybit) 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
|
|
if !IsTrue(this.CheckRequiredCredentials(false)) {
|
|
|
|
return nil
|
|
}
|
|
if IsTrue(GetValue(this.Options, "enableDemoTrading")) {
|
|
|
|
return nil
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5AssetCoinQueryInfo(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "",
|
|
// "result": {
|
|
// "rows": [
|
|
// {
|
|
// "name": "BTC",
|
|
// "coin": "BTC",
|
|
// "remainAmount": "150",
|
|
// "chains": [
|
|
// {
|
|
// "chainType": "BTC",
|
|
// "confirmation": "10000",
|
|
// "withdrawFee": "0.0005",
|
|
// "depositMin": "0.0005",
|
|
// "withdrawMin": "0.001",
|
|
// "chain": "BTC",
|
|
// "chainDeposit": "1",
|
|
// "chainWithdraw": "1",
|
|
// "minAccuracy": "8"
|
|
// }
|
|
// ]
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672194582264
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var rows interface{} = this.SafeList(data, "rows", []interface{}{})
|
|
var result interface{} = map[string]interface{} {}
|
|
for i := 0; IsLessThan(i, GetArrayLength(rows)); i++ {
|
|
var currency interface{} = GetValue(rows, i)
|
|
var currencyId interface{} = this.SafeString(currency, "coin")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
|
var name interface{} = this.SafeString(currency, "name")
|
|
var chains interface{} = this.SafeList(currency, "chains", []interface{}{})
|
|
var networks interface{} = map[string]interface{} {}
|
|
var minPrecision interface{} = nil
|
|
var minWithdrawFeeString interface{} = nil
|
|
var minWithdrawString interface{} = nil
|
|
var minDepositString interface{} = nil
|
|
var deposit interface{} = false
|
|
var withdraw interface{} = false
|
|
for j := 0; IsLessThan(j, GetArrayLength(chains)); j++ {
|
|
var chain interface{} = GetValue(chains, j)
|
|
var networkId interface{} = this.SafeString(chain, "chain")
|
|
var networkCode interface{} = this.NetworkIdToCode(networkId)
|
|
var precision interface{} = this.ParseNumber(this.ParsePrecision(this.SafeString(chain, "minAccuracy")))
|
|
minPrecision = Ternary(IsTrue((IsEqual(minPrecision, nil))), precision, mathMin(minPrecision, precision))
|
|
var depositAllowed interface{} = IsEqual(this.SafeInteger(chain, "chainDeposit"), 1)
|
|
deposit = Ternary(IsTrue((depositAllowed)), depositAllowed, deposit)
|
|
var withdrawAllowed interface{} = IsEqual(this.SafeInteger(chain, "chainWithdraw"), 1)
|
|
withdraw = Ternary(IsTrue((withdrawAllowed)), withdrawAllowed, withdraw)
|
|
var withdrawFeeString interface{} = this.SafeString(chain, "withdrawFee")
|
|
if IsTrue(!IsEqual(withdrawFeeString, nil)) {
|
|
minWithdrawFeeString = Ternary(IsTrue((IsEqual(minWithdrawFeeString, nil))), withdrawFeeString, Precise.StringMin(withdrawFeeString, minWithdrawFeeString))
|
|
}
|
|
var minNetworkWithdrawString interface{} = this.SafeString(chain, "withdrawMin")
|
|
if IsTrue(!IsEqual(minNetworkWithdrawString, nil)) {
|
|
minWithdrawString = Ternary(IsTrue((IsEqual(minWithdrawString, nil))), minNetworkWithdrawString, Precise.StringMin(minNetworkWithdrawString, minWithdrawString))
|
|
}
|
|
var minNetworkDepositString interface{} = this.SafeString(chain, "depositMin")
|
|
if IsTrue(!IsEqual(minNetworkDepositString, nil)) {
|
|
minDepositString = Ternary(IsTrue((IsEqual(minDepositString, nil))), minNetworkDepositString, Precise.StringMin(minNetworkDepositString, minDepositString))
|
|
}
|
|
AddElementToObject(networks, networkCode, map[string]interface{} {
|
|
"info": chain,
|
|
"id": networkId,
|
|
"network": networkCode,
|
|
"active": IsTrue(depositAllowed) && IsTrue(withdrawAllowed),
|
|
"deposit": depositAllowed,
|
|
"withdraw": withdrawAllowed,
|
|
"fee": this.ParseNumber(withdrawFeeString),
|
|
"precision": precision,
|
|
"limits": map[string]interface{} {
|
|
"withdraw": map[string]interface{} {
|
|
"min": this.ParseNumber(minNetworkWithdrawString),
|
|
"max": nil,
|
|
},
|
|
"deposit": map[string]interface{} {
|
|
"min": this.ParseNumber(minNetworkDepositString),
|
|
"max": nil,
|
|
},
|
|
},
|
|
})
|
|
}
|
|
AddElementToObject(result, code, map[string]interface{} {
|
|
"info": currency,
|
|
"code": code,
|
|
"id": currencyId,
|
|
"name": name,
|
|
"active": IsTrue(deposit) && IsTrue(withdraw),
|
|
"deposit": deposit,
|
|
"withdraw": withdraw,
|
|
"fee": this.ParseNumber(minWithdrawFeeString),
|
|
"precision": minPrecision,
|
|
"limits": map[string]interface{} {
|
|
"amount": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"withdraw": map[string]interface{} {
|
|
"min": this.ParseNumber(minWithdrawString),
|
|
"max": nil,
|
|
},
|
|
"deposit": map[string]interface{} {
|
|
"min": this.ParseNumber(minDepositString),
|
|
"max": nil,
|
|
},
|
|
},
|
|
"networks": networks,
|
|
})
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchMarkets
|
|
* @description retrieves data on all markets for bybit
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/instrument
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} an array of objects representing market data
|
|
*/
|
|
func (this *bybit) 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")) {
|
|
|
|
retRes173712 := (<-this.LoadTimeDifference())
|
|
PanicOnError(retRes173712)
|
|
}
|
|
var promisesUnresolved interface{} = []interface{}{}
|
|
var fetchMarkets interface{} = this.SafeList(this.Options, "fetchMarkets", []interface{}{"spot", "linear", "inverse"})
|
|
for i := 0; IsLessThan(i, GetArrayLength(fetchMarkets)); i++ {
|
|
var marketType interface{} = GetValue(fetchMarkets, i)
|
|
if IsTrue(IsEqual(marketType, "spot")) {
|
|
AppendToArray(&promisesUnresolved,this.FetchSpotMarkets(params))
|
|
} else if IsTrue(IsEqual(marketType, "linear")) {
|
|
AppendToArray(&promisesUnresolved,this.FetchFutureMarkets(map[string]interface{} {
|
|
"category": "linear",
|
|
}))
|
|
} else if IsTrue(IsEqual(marketType, "inverse")) {
|
|
AppendToArray(&promisesUnresolved,this.FetchFutureMarkets(map[string]interface{} {
|
|
"category": "inverse",
|
|
}))
|
|
} else if IsTrue(IsEqual(marketType, "option")) {
|
|
AppendToArray(&promisesUnresolved,this.FetchOptionMarkets(map[string]interface{} {
|
|
"baseCoin": "BTC",
|
|
}))
|
|
AppendToArray(&promisesUnresolved,this.FetchOptionMarkets(map[string]interface{} {
|
|
"baseCoin": "ETH",
|
|
}))
|
|
AppendToArray(&promisesUnresolved,this.FetchOptionMarkets(map[string]interface{} {
|
|
"baseCoin": "SOL",
|
|
}))
|
|
} else {
|
|
panic(ExchangeError(Add(Add(Add(this.Id, " fetchMarkets() this.options fetchMarkets \""), marketType), "\" is not a supported market type")))
|
|
}
|
|
}
|
|
|
|
promises:= (<-promiseAll(promisesUnresolved))
|
|
PanicOnError(promises)
|
|
var spotMarkets interface{} = this.SafeList(promises, 0, []interface{}{})
|
|
var linearMarkets interface{} = this.SafeList(promises, 1, []interface{}{})
|
|
var inverseMarkets interface{} = this.SafeList(promises, 2, []interface{}{})
|
|
var btcOptionMarkets interface{} = this.SafeList(promises, 3, []interface{}{})
|
|
var ethOptionMarkets interface{} = this.SafeList(promises, 4, []interface{}{})
|
|
var solOptionMarkets interface{} = this.SafeList(promises, 5, []interface{}{})
|
|
var futureMarkets interface{} = this.ArrayConcat(linearMarkets, inverseMarkets)
|
|
var optionMarkets interface{} = this.ArrayConcat(btcOptionMarkets, ethOptionMarkets)
|
|
optionMarkets = this.ArrayConcat(optionMarkets, solOptionMarkets)
|
|
var derivativeMarkets interface{} = this.ArrayConcat(futureMarkets, optionMarkets)
|
|
|
|
ch <- this.ArrayConcat(spotMarkets, derivativeMarkets)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) FetchSpotMarkets(params interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
var request interface{} = map[string]interface{} {
|
|
"category": "spot",
|
|
}
|
|
var usePrivateInstrumentsInfo interface{} = this.SafeBool(this.Options, "usePrivateInstrumentsInfo", false)
|
|
var response interface{} = nil
|
|
if IsTrue(usePrivateInstrumentsInfo) {
|
|
|
|
response = (<-this.PrivateGetV5MarketInstrumentsInfo(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
|
|
response = (<-this.PublicGetV5MarketInstrumentsInfo(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "category": "spot",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTCUSDT",
|
|
// "baseCoin": "BTC",
|
|
// "quoteCoin": "USDT",
|
|
// "innovation": "0",
|
|
// "status": "Trading",
|
|
// "marginTrading": "both",
|
|
// "lotSizeFilter": {
|
|
// "basePrecision": "0.000001",
|
|
// "quotePrecision": "0.00000001",
|
|
// "minOrderQty": "0.00004",
|
|
// "maxOrderQty": "63.01197227",
|
|
// "minOrderAmt": "1",
|
|
// "maxOrderAmt": "100000"
|
|
// },
|
|
// "priceFilter": {
|
|
// "tickSize": "0.01"
|
|
// }
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672712468011
|
|
// }
|
|
//
|
|
var responseResult interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var markets interface{} = this.SafeList(responseResult, "list", []interface{}{})
|
|
var result interface{} = []interface{}{}
|
|
var takerFee interface{} = this.ParseNumber("0.001")
|
|
var makerFee interface{} = this.ParseNumber("0.001")
|
|
for i := 0; IsLessThan(i, GetArrayLength(markets)); i++ {
|
|
var market interface{} = GetValue(markets, i)
|
|
var id interface{} = this.SafeString(market, "symbol")
|
|
var baseId interface{} = this.SafeString(market, "baseCoin")
|
|
var quoteId interface{} = this.SafeString(market, "quoteCoin")
|
|
var base interface{} = this.SafeCurrencyCode(baseId)
|
|
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
|
var symbol interface{} = Add(Add(base, "/"), quote)
|
|
var status interface{} = this.SafeString(market, "status")
|
|
var active interface{} = (IsEqual(status, "Trading"))
|
|
var lotSizeFilter interface{} = this.SafeDict(market, "lotSizeFilter")
|
|
var priceFilter interface{} = this.SafeDict(market, "priceFilter")
|
|
var quotePrecision interface{} = this.SafeNumber(lotSizeFilter, "quotePrecision")
|
|
var marginTrading interface{} = this.SafeString(market, "marginTrading", "none")
|
|
var allowsMargin interface{} = !IsEqual(marginTrading, "none")
|
|
AppendToArray(&result,this.SafeMarketStructure(map[string]interface{} {
|
|
"id": id,
|
|
"symbol": symbol,
|
|
"base": base,
|
|
"quote": quote,
|
|
"settle": nil,
|
|
"baseId": baseId,
|
|
"quoteId": quoteId,
|
|
"settleId": nil,
|
|
"type": "spot",
|
|
"spot": true,
|
|
"margin": allowsMargin,
|
|
"swap": false,
|
|
"future": false,
|
|
"option": false,
|
|
"active": active,
|
|
"contract": false,
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
"taker": takerFee,
|
|
"maker": makerFee,
|
|
"contractSize": nil,
|
|
"expiry": nil,
|
|
"expiryDatetime": nil,
|
|
"strike": nil,
|
|
"optionType": nil,
|
|
"precision": map[string]interface{} {
|
|
"amount": this.SafeNumber(lotSizeFilter, "basePrecision"),
|
|
"price": this.SafeNumber(priceFilter, "tickSize", quotePrecision),
|
|
},
|
|
"limits": map[string]interface{} {
|
|
"leverage": map[string]interface{} {
|
|
"min": this.ParseNumber("1"),
|
|
"max": nil,
|
|
},
|
|
"amount": map[string]interface{} {
|
|
"min": this.SafeNumber(lotSizeFilter, "minOrderQty"),
|
|
"max": this.SafeNumber(lotSizeFilter, "maxOrderQty"),
|
|
},
|
|
"price": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"cost": map[string]interface{} {
|
|
"min": this.SafeNumber(lotSizeFilter, "minOrderAmt"),
|
|
"max": this.SafeNumber(lotSizeFilter, "maxOrderAmt"),
|
|
},
|
|
},
|
|
"created": nil,
|
|
"info": market,
|
|
}))
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) FetchFutureMarkets(params interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params = this.Extend(params)
|
|
AddElementToObject(params, "limit", 1000) // minimize number of requests
|
|
var preLaunchMarkets interface{} = []interface{}{}
|
|
var usePrivateInstrumentsInfo interface{} = this.SafeBool(this.Options, "usePrivateInstrumentsInfo", false)
|
|
var response interface{} = nil
|
|
if IsTrue(usePrivateInstrumentsInfo) {
|
|
|
|
response = (<-this.PrivateGetV5MarketInstrumentsInfo(params))
|
|
PanicOnError(response)
|
|
} else {
|
|
var linearPromises interface{} = []interface{}{this.PublicGetV5MarketInstrumentsInfo(params), this.PublicGetV5MarketInstrumentsInfo(this.Extend(params, map[string]interface{} {
|
|
"status": "PreLaunch",
|
|
}))}
|
|
|
|
promises:= (<-promiseAll(linearPromises))
|
|
PanicOnError(promises)
|
|
response = this.SafeDict(promises, 0, map[string]interface{} {})
|
|
preLaunchMarkets = this.SafeDict(promises, 1, map[string]interface{} {})
|
|
}
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var markets interface{} = this.SafeList(data, "list", []interface{}{})
|
|
var paginationCursor interface{} = this.SafeString(data, "nextPageCursor")
|
|
if IsTrue(!IsEqual(paginationCursor, nil)) {
|
|
for !IsEqual(paginationCursor, nil) {
|
|
AddElementToObject(params, "cursor", paginationCursor)
|
|
var responseInner interface{} = nil
|
|
if IsTrue(usePrivateInstrumentsInfo) {
|
|
|
|
responseInner = (<-this.PrivateGetV5MarketInstrumentsInfo(params))
|
|
PanicOnError(responseInner)
|
|
} else {
|
|
|
|
responseInner = (<-this.PublicGetV5MarketInstrumentsInfo(params))
|
|
PanicOnError(responseInner)
|
|
}
|
|
var dataNew interface{} = this.SafeDict(responseInner, "result", map[string]interface{} {})
|
|
var rawMarkets interface{} = this.SafeList(dataNew, "list", []interface{}{})
|
|
var rawMarketsLength interface{} = GetArrayLength(rawMarkets)
|
|
if IsTrue(IsEqual(rawMarketsLength, 0)) {
|
|
break
|
|
}
|
|
markets = this.ArrayConcat(rawMarkets, markets)
|
|
paginationCursor = this.SafeString(dataNew, "nextPageCursor")
|
|
}
|
|
}
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "category": "linear",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTCUSDT",
|
|
// "contractType": "LinearPerpetual",
|
|
// "status": "Trading",
|
|
// "baseCoin": "BTC",
|
|
// "quoteCoin": "USDT",
|
|
// "launchTime": "1585526400000",
|
|
// "deliveryTime": "0",
|
|
// "deliveryFeeRate": "",
|
|
// "priceScale": "2",
|
|
// "leverageFilter": {
|
|
// "minLeverage": "1",
|
|
// "maxLeverage": "100.00",
|
|
// "leverageStep": "0.01"
|
|
// },
|
|
// "priceFilter": {
|
|
// "minPrice": "0.50",
|
|
// "maxPrice": "999999.00",
|
|
// "tickSize": "0.50"
|
|
// },
|
|
// "lotSizeFilter": {
|
|
// "maxOrderQty": "100.000",
|
|
// "minOrderQty": "0.001",
|
|
// "qtyStep": "0.001",
|
|
// "postOnlyMaxOrderQty": "1000.000"
|
|
// },
|
|
// "unifiedMarginTrade": true,
|
|
// "fundingInterval": 480,
|
|
// "settleCoin": "USDT"
|
|
// }
|
|
// ],
|
|
// "nextPageCursor": ""
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672712495660
|
|
// }
|
|
//
|
|
var preLaunchData interface{} = this.SafeDict(preLaunchMarkets, "result", map[string]interface{} {})
|
|
var preLaunchMarketsList interface{} = this.SafeList(preLaunchData, "list", []interface{}{})
|
|
markets = this.ArrayConcat(markets, preLaunchMarketsList)
|
|
var result interface{} = []interface{}{}
|
|
var category interface{} = this.SafeString(data, "category")
|
|
for i := 0; IsLessThan(i, GetArrayLength(markets)); i++ {
|
|
var market interface{} = GetValue(markets, i)
|
|
if IsTrue(IsEqual(category, nil)) {
|
|
category = this.SafeString(market, "category")
|
|
}
|
|
var linear interface{} = (IsEqual(category, "linear"))
|
|
var inverse interface{} = (IsEqual(category, "inverse"))
|
|
var contractType interface{} = this.SafeString(market, "contractType")
|
|
var inverseFutures interface{} = (IsEqual(contractType, "InverseFutures"))
|
|
var linearFutures interface{} = (IsEqual(contractType, "LinearFutures"))
|
|
var linearPerpetual interface{} = (IsEqual(contractType, "LinearPerpetual"))
|
|
var inversePerpetual interface{} = (IsEqual(contractType, "InversePerpetual"))
|
|
var id interface{} = this.SafeString(market, "symbol")
|
|
var baseId interface{} = this.SafeString(market, "baseCoin")
|
|
var quoteId interface{} = this.SafeString(market, "quoteCoin")
|
|
var defaultSettledId interface{} = Ternary(IsTrue(linear), quoteId, baseId)
|
|
var settleId interface{} = this.SafeString(market, "settleCoin", defaultSettledId)
|
|
var base interface{} = this.SafeCurrencyCode(baseId)
|
|
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
|
var settle interface{} = nil
|
|
if IsTrue(IsTrue(linearPerpetual) && IsTrue((IsEqual(settleId, "USD")))) {
|
|
settle = "USDC"
|
|
} else {
|
|
settle = this.SafeCurrencyCode(settleId)
|
|
}
|
|
var symbol interface{} = Add(Add(base, "/"), quote)
|
|
var lotSizeFilter interface{} = this.SafeDict(market, "lotSizeFilter", map[string]interface{} {})
|
|
var priceFilter interface{} = this.SafeDict(market, "priceFilter", map[string]interface{} {})
|
|
var leverage interface{} = this.SafeDict(market, "leverageFilter", map[string]interface{} {})
|
|
var status interface{} = this.SafeString(market, "status")
|
|
var swap interface{} = IsTrue(linearPerpetual) || IsTrue(inversePerpetual)
|
|
var future interface{} = IsTrue(inverseFutures) || IsTrue(linearFutures)
|
|
var typeVar interface{} = nil
|
|
if IsTrue(swap) {
|
|
typeVar = "swap"
|
|
} else if IsTrue(future) {
|
|
typeVar = "future"
|
|
}
|
|
var expiry interface{} = nil
|
|
// some swaps have deliveryTime meaning delisting time
|
|
if !IsTrue(swap) {
|
|
expiry = this.OmitZero(this.SafeString(market, "deliveryTime"))
|
|
if IsTrue(!IsEqual(expiry, nil)) {
|
|
expiry = ParseInt(expiry)
|
|
}
|
|
}
|
|
var expiryDatetime interface{} = this.Iso8601(expiry)
|
|
symbol = Add(Add(symbol, ":"), settle)
|
|
if IsTrue(!IsEqual(expiry, nil)) {
|
|
symbol = Add(Add(symbol, "-"), this.Yymmdd(expiry))
|
|
}
|
|
var contractSize interface{} = Ternary(IsTrue(inverse), this.SafeNumber2(lotSizeFilter, "minTradingQty", "minOrderQty"), this.ParseNumber("1"))
|
|
AppendToArray(&result,this.SafeMarketStructure(map[string]interface{} {
|
|
"id": id,
|
|
"symbol": symbol,
|
|
"base": base,
|
|
"quote": quote,
|
|
"settle": settle,
|
|
"baseId": baseId,
|
|
"quoteId": quoteId,
|
|
"settleId": settleId,
|
|
"type": typeVar,
|
|
"spot": false,
|
|
"margin": nil,
|
|
"swap": swap,
|
|
"future": future,
|
|
"option": false,
|
|
"active": (IsEqual(status, "Trading")),
|
|
"contract": true,
|
|
"linear": linear,
|
|
"inverse": inverse,
|
|
"taker": this.SafeNumber(market, "takerFee", this.ParseNumber("0.0006")),
|
|
"maker": this.SafeNumber(market, "makerFee", this.ParseNumber("0.0001")),
|
|
"contractSize": contractSize,
|
|
"expiry": expiry,
|
|
"expiryDatetime": expiryDatetime,
|
|
"strike": nil,
|
|
"optionType": nil,
|
|
"precision": map[string]interface{} {
|
|
"amount": this.SafeNumber(lotSizeFilter, "qtyStep"),
|
|
"price": this.SafeNumber(priceFilter, "tickSize"),
|
|
},
|
|
"limits": map[string]interface{} {
|
|
"leverage": map[string]interface{} {
|
|
"min": this.SafeNumber(leverage, "minLeverage"),
|
|
"max": this.SafeNumber(leverage, "maxLeverage"),
|
|
},
|
|
"amount": map[string]interface{} {
|
|
"min": this.SafeNumber2(lotSizeFilter, "minTradingQty", "minOrderQty"),
|
|
"max": this.SafeNumber2(lotSizeFilter, "maxTradingQty", "maxOrderQty"),
|
|
},
|
|
"price": map[string]interface{} {
|
|
"min": this.SafeNumber(priceFilter, "minPrice"),
|
|
"max": this.SafeNumber(priceFilter, "maxPrice"),
|
|
},
|
|
"cost": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
},
|
|
"created": this.SafeInteger(market, "launchTime"),
|
|
"info": market,
|
|
}))
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) FetchOptionMarkets(params interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
var request interface{} = map[string]interface{} {
|
|
"category": "option",
|
|
}
|
|
var usePrivateInstrumentsInfo interface{} = this.SafeBool(this.Options, "usePrivateInstrumentsInfo", false)
|
|
var response interface{} = nil
|
|
if IsTrue(usePrivateInstrumentsInfo) {
|
|
|
|
response = (<-this.PrivateGetV5MarketInstrumentsInfo(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
|
|
response = (<-this.PublicGetV5MarketInstrumentsInfo(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var markets interface{} = this.SafeList(data, "list", []interface{}{})
|
|
if IsTrue(GetValue(this.Options, "loadAllOptions")) {
|
|
AddElementToObject(request, "limit", 1000)
|
|
var paginationCursor interface{} = this.SafeString(data, "nextPageCursor")
|
|
if IsTrue(!IsEqual(paginationCursor, nil)) {
|
|
for !IsEqual(paginationCursor, nil) {
|
|
AddElementToObject(request, "cursor", paginationCursor)
|
|
var responseInner interface{} = nil
|
|
if IsTrue(usePrivateInstrumentsInfo) {
|
|
|
|
responseInner = (<-this.PrivateGetV5MarketInstrumentsInfo(this.Extend(request, params)))
|
|
PanicOnError(responseInner)
|
|
} else {
|
|
|
|
responseInner = (<-this.PublicGetV5MarketInstrumentsInfo(this.Extend(request, params)))
|
|
PanicOnError(responseInner)
|
|
}
|
|
var dataNew interface{} = this.SafeDict(responseInner, "result", map[string]interface{} {})
|
|
var rawMarkets interface{} = this.SafeList(dataNew, "list", []interface{}{})
|
|
var rawMarketsLength interface{} = GetArrayLength(rawMarkets)
|
|
if IsTrue(IsEqual(rawMarketsLength, 0)) {
|
|
break
|
|
}
|
|
markets = this.ArrayConcat(rawMarkets, markets)
|
|
paginationCursor = this.SafeString(dataNew, "nextPageCursor")
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "category": "option",
|
|
// "nextPageCursor": "0%2C2",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTC-29DEC23-80000-C",
|
|
// "status": "Trading",
|
|
// "baseCoin": "BTC",
|
|
// "quoteCoin": "USD",
|
|
// "settleCoin": "USDC",
|
|
// "optionsType": "Call",
|
|
// "launchTime": "1688630400000",
|
|
// "deliveryTime": "1703836800000",
|
|
// "deliveryFeeRate": "0.00015",
|
|
// "priceFilter": {
|
|
// "minPrice": "5",
|
|
// "maxPrice": "10000000",
|
|
// "tickSize": "5"
|
|
// },
|
|
// "lotSizeFilter": {
|
|
// "maxOrderQty": "500",
|
|
// "minOrderQty": "0.01",
|
|
// "qtyStep": "0.01"
|
|
// }
|
|
// },
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1688873094448
|
|
// }
|
|
//
|
|
var result interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(markets)); i++ {
|
|
var market interface{} = GetValue(markets, i)
|
|
var id interface{} = this.SafeString(market, "symbol")
|
|
var baseId interface{} = this.SafeString(market, "baseCoin")
|
|
var quoteId interface{} = this.SafeString(market, "quoteCoin")
|
|
var settleId interface{} = this.SafeString(market, "settleCoin")
|
|
var base interface{} = this.SafeCurrencyCode(baseId)
|
|
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
|
var settle interface{} = this.SafeCurrencyCode(settleId)
|
|
var lotSizeFilter interface{} = this.SafeDict(market, "lotSizeFilter", map[string]interface{} {})
|
|
var priceFilter interface{} = this.SafeDict(market, "priceFilter", map[string]interface{} {})
|
|
var status interface{} = this.SafeString(market, "status")
|
|
var expiry interface{} = this.SafeInteger(market, "deliveryTime")
|
|
var splitId interface{} = Split(id, "-")
|
|
var strike interface{} = this.SafeString(splitId, 2)
|
|
var optionLetter interface{} = this.SafeString(splitId, 3)
|
|
var isActive interface{} = (IsEqual(status, "Trading"))
|
|
if IsTrue(IsTrue(IsTrue(isActive) || IsTrue((GetValue(this.Options, "loadAllOptions")))) || IsTrue((GetValue(this.Options, "loadExpiredOptions")))) {
|
|
AppendToArray(&result,this.SafeMarketStructure(map[string]interface{} {
|
|
"id": id,
|
|
"symbol": Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(base, "/"), quote), ":"), settle), "-"), this.Yymmdd(expiry)), "-"), strike), "-"), optionLetter),
|
|
"base": base,
|
|
"quote": quote,
|
|
"settle": settle,
|
|
"baseId": baseId,
|
|
"quoteId": quoteId,
|
|
"settleId": settleId,
|
|
"type": "option",
|
|
"subType": "linear",
|
|
"spot": false,
|
|
"margin": false,
|
|
"swap": false,
|
|
"future": false,
|
|
"option": true,
|
|
"active": isActive,
|
|
"contract": true,
|
|
"linear": true,
|
|
"inverse": false,
|
|
"taker": this.SafeNumber(market, "takerFee", this.ParseNumber("0.0006")),
|
|
"maker": this.SafeNumber(market, "makerFee", this.ParseNumber("0.0001")),
|
|
"contractSize": this.ParseNumber("1"),
|
|
"expiry": expiry,
|
|
"expiryDatetime": this.Iso8601(expiry),
|
|
"strike": this.ParseNumber(strike),
|
|
"optionType": this.SafeStringLower(market, "optionsType"),
|
|
"precision": map[string]interface{} {
|
|
"amount": this.SafeNumber(lotSizeFilter, "qtyStep"),
|
|
"price": this.SafeNumber(priceFilter, "tickSize"),
|
|
},
|
|
"limits": map[string]interface{} {
|
|
"leverage": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"amount": map[string]interface{} {
|
|
"min": this.SafeNumber(lotSizeFilter, "minOrderQty"),
|
|
"max": this.SafeNumber(lotSizeFilter, "maxOrderQty"),
|
|
},
|
|
"price": map[string]interface{} {
|
|
"min": this.SafeNumber(priceFilter, "minPrice"),
|
|
"max": this.SafeNumber(priceFilter, "maxPrice"),
|
|
},
|
|
"cost": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
},
|
|
"created": this.SafeInteger(market, "launchTime"),
|
|
"info": market,
|
|
}))
|
|
}
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// spot
|
|
//
|
|
// {
|
|
// "symbol": "BTCUSDT",
|
|
// "bid1Price": "20517.96",
|
|
// "bid1Size": "2",
|
|
// "ask1Price": "20527.77",
|
|
// "ask1Size": "1.862172",
|
|
// "lastPrice": "20533.13",
|
|
// "prevPrice24h": "20393.48",
|
|
// "price24hPcnt": "0.0068",
|
|
// "highPrice24h": "21128.12",
|
|
// "lowPrice24h": "20318.89",
|
|
// "turnover24h": "243765620.65899866",
|
|
// "volume24h": "11801.27771",
|
|
// "usdIndexPrice": "20784.12009279"
|
|
// }
|
|
//
|
|
// linear/inverse
|
|
//
|
|
// {
|
|
// "symbol": "BTCUSD",
|
|
// "lastPrice": "16597.00",
|
|
// "indexPrice": "16598.54",
|
|
// "markPrice": "16596.00",
|
|
// "prevPrice24h": "16464.50",
|
|
// "price24hPcnt": "0.008047",
|
|
// "highPrice24h": "30912.50",
|
|
// "lowPrice24h": "15700.00",
|
|
// "prevPrice1h": "16595.50",
|
|
// "openInterest": "373504107",
|
|
// "openInterestValue": "22505.67",
|
|
// "turnover24h": "2352.94950046",
|
|
// "volume24h": "49337318",
|
|
// "fundingRate": "-0.001034",
|
|
// "nextFundingTime": "1672387200000",
|
|
// "predictedDeliveryPrice": "",
|
|
// "basisRate": "",
|
|
// "deliveryFeeRate": "",
|
|
// "deliveryTime": "0",
|
|
// "ask1Size": "1",
|
|
// "bid1Price": "16596.00",
|
|
// "ask1Price": "16597.50",
|
|
// "bid1Size": "1"
|
|
// }
|
|
//
|
|
// option
|
|
//
|
|
// {
|
|
// "symbol": "BTC-30DEC22-18000-C",
|
|
// "bid1Price": "0",
|
|
// "bid1Size": "0",
|
|
// "bid1Iv": "0",
|
|
// "ask1Price": "435",
|
|
// "ask1Size": "0.66",
|
|
// "ask1Iv": "5",
|
|
// "lastPrice": "435",
|
|
// "highPrice24h": "435",
|
|
// "lowPrice24h": "165",
|
|
// "markPrice": "0.00000009",
|
|
// "indexPrice": "16600.55",
|
|
// "markIv": "0.7567",
|
|
// "underlyingPrice": "16590.42",
|
|
// "openInterest": "6.3",
|
|
// "turnover24h": "2482.73",
|
|
// "volume24h": "0.15",
|
|
// "totalVolume": "99",
|
|
// "totalTurnover": "1967653",
|
|
// "delta": "0.00000001",
|
|
// "gamma": "0.00000001",
|
|
// "vega": "0.00000004",
|
|
// "theta": "-0.00000152",
|
|
// "predictedDeliveryPrice": "0",
|
|
// "change24h": "86"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var isSpot interface{} = IsEqual(this.SafeString(ticker, "openInterestValue"), nil)
|
|
var timestamp interface{} = this.SafeInteger(ticker, "time")
|
|
var marketId interface{} = this.SafeString(ticker, "symbol")
|
|
var typeVar interface{} = Ternary(IsTrue(isSpot), "spot", "contract")
|
|
market = this.SafeMarket(marketId, market, nil, typeVar)
|
|
var symbol interface{} = this.SafeSymbol(marketId, market, nil, typeVar)
|
|
var last interface{} = this.SafeString(ticker, "lastPrice")
|
|
var open interface{} = this.SafeString(ticker, "prevPrice24h")
|
|
var percentage interface{} = this.SafeString(ticker, "price24hPcnt")
|
|
percentage = Precise.StringMul(percentage, "100")
|
|
var quoteVolume interface{} = this.SafeString(ticker, "turnover24h")
|
|
var baseVolume interface{} = this.SafeString(ticker, "volume24h")
|
|
var bid interface{} = this.SafeString(ticker, "bid1Price")
|
|
var ask interface{} = this.SafeString(ticker, "ask1Price")
|
|
var high interface{} = this.SafeString(ticker, "highPrice24h")
|
|
var low interface{} = this.SafeString(ticker, "lowPrice24h")
|
|
return this.SafeTicker(map[string]interface{} {
|
|
"symbol": symbol,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"high": high,
|
|
"low": low,
|
|
"bid": bid,
|
|
"bidVolume": this.SafeString2(ticker, "bidSize", "bid1Size"),
|
|
"ask": ask,
|
|
"askVolume": this.SafeString2(ticker, "askSize", "ask1Size"),
|
|
"vwap": nil,
|
|
"open": open,
|
|
"close": last,
|
|
"last": last,
|
|
"previousClose": nil,
|
|
"change": nil,
|
|
"percentage": percentage,
|
|
"average": nil,
|
|
"baseVolume": baseVolume,
|
|
"quoteVolume": quoteVolume,
|
|
"markPrice": this.SafeString(ticker, "markPrice"),
|
|
"indexPrice": this.SafeString(ticker, "indexPrice"),
|
|
"info": ticker,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchTicker
|
|
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/tickers
|
|
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchTicker() requires a symbol argument")))
|
|
}
|
|
|
|
retRes23648 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes23648)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
AddElementToObject(request, "category", "spot")
|
|
} else {
|
|
if IsTrue(GetValue(market, "option")) {
|
|
AddElementToObject(request, "category", "option")
|
|
} else if IsTrue(GetValue(market, "linear")) {
|
|
AddElementToObject(request, "category", "linear")
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
AddElementToObject(request, "category", "inverse")
|
|
}
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketTickers(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "category": "inverse",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTCUSD",
|
|
// "lastPrice": "16597.00",
|
|
// "indexPrice": "16598.54",
|
|
// "markPrice": "16596.00",
|
|
// "prevPrice24h": "16464.50",
|
|
// "price24hPcnt": "0.008047",
|
|
// "highPrice24h": "30912.50",
|
|
// "lowPrice24h": "15700.00",
|
|
// "prevPrice1h": "16595.50",
|
|
// "openInterest": "373504107",
|
|
// "openInterestValue": "22505.67",
|
|
// "turnover24h": "2352.94950046",
|
|
// "volume24h": "49337318",
|
|
// "fundingRate": "-0.001034",
|
|
// "nextFundingTime": "1672387200000",
|
|
// "predictedDeliveryPrice": "",
|
|
// "basisRate": "",
|
|
// "deliveryFeeRate": "",
|
|
// "deliveryTime": "0",
|
|
// "ask1Size": "1",
|
|
// "bid1Price": "16596.00",
|
|
// "ask1Price": "16597.50",
|
|
// "bid1Size": "1"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672376496682
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var tickers interface{} = this.SafeList(result, "list", []interface{}{})
|
|
var rawTicker interface{} = this.SafeDict(tickers, 0)
|
|
|
|
ch <- this.ParseTicker(rawTicker, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchTickers
|
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/tickers
|
|
* @param {string[]} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.subType] *contract only* 'linear', 'inverse'
|
|
* @param {string} [params.baseCoin] *option only* base coin, default is 'BTC'
|
|
* @returns {object} an array of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes24398 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes24398)
|
|
var market interface{} = nil
|
|
var parsedSymbols interface{} = nil
|
|
if IsTrue(!IsEqual(symbols, nil)) {
|
|
parsedSymbols = []interface{}{}
|
|
var marketTypeInfo interface{} = this.HandleMarketTypeAndParams("fetchTickers", nil, params)
|
|
var defaultType interface{} = GetValue(marketTypeInfo, 0) // don't omit here
|
|
// we can't use marketSymbols here due to the conflicing ids between markets
|
|
var currentType interface{} = nil
|
|
for i := 0; IsLessThan(i, GetArrayLength(symbols)); i++ {
|
|
var symbol interface{} = GetValue(symbols, i)
|
|
// using safeMarket here because if the user provides for instance BTCUSDT and "type": "spot" in params we should
|
|
// infer the market type from the type provided and not from the conflicting id (BTCUSDT might be swap or spot)
|
|
var isExchangeSpecificSymbol interface{} = (IsEqual(GetIndexOf(symbol, "/"), OpNeg(1)))
|
|
if IsTrue(isExchangeSpecificSymbol) {
|
|
market = this.SafeMarket(symbol, nil, nil, defaultType)
|
|
} else {
|
|
market = this.Market(symbol)
|
|
}
|
|
if IsTrue(IsEqual(currentType, nil)) {
|
|
currentType = GetValue(market, "type")
|
|
} else if IsTrue(!IsEqual(GetValue(market, "type"), currentType)) {
|
|
panic(BadRequest(Add(this.Id, " fetchTickers can only accept a list of symbols of the same type")))
|
|
}
|
|
AppendToArray(&parsedSymbols,GetValue(market, "symbol"))
|
|
}
|
|
}
|
|
var request interface{} = map[string]interface{} {}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchTickers", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
// Calls like `.fetchTickers (undefined, {subType:'inverse'})` should be supported for this exchange, so
|
|
// as "options.defaultSubType" is also set in exchange options, we should consider `params.subType`
|
|
// with higher priority and only default to spot, if `subType` is not set in params
|
|
var passedSubType interface{} = this.SafeString(params, "subType")
|
|
var subType interface{} = nil
|
|
subTypeparamsVariable := this.HandleSubTypeAndParams("fetchTickers", market, params, "linear");
|
|
subType = GetValue(subTypeparamsVariable,0);
|
|
params = GetValue(subTypeparamsVariable,1)
|
|
// only if passedSubType is undefined, then use spot
|
|
if IsTrue(IsTrue(IsEqual(typeVar, "spot")) && IsTrue(IsEqual(passedSubType, nil))) {
|
|
AddElementToObject(request, "category", "spot")
|
|
} else if IsTrue(IsEqual(typeVar, "option")) {
|
|
AddElementToObject(request, "category", "option")
|
|
AddElementToObject(request, "baseCoin", this.SafeString(params, "baseCoin", "BTC"))
|
|
} else if IsTrue(IsTrue(IsTrue(IsEqual(typeVar, "swap")) || IsTrue(IsEqual(typeVar, "future"))) || IsTrue(!IsEqual(subType, nil))) {
|
|
AddElementToObject(request, "category", subType)
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketTickers(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "category": "inverse",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTCUSD",
|
|
// "lastPrice": "16597.00",
|
|
// "indexPrice": "16598.54",
|
|
// "markPrice": "16596.00",
|
|
// "prevPrice24h": "16464.50",
|
|
// "price24hPcnt": "0.008047",
|
|
// "highPrice24h": "30912.50",
|
|
// "lowPrice24h": "15700.00",
|
|
// "prevPrice1h": "16595.50",
|
|
// "openInterest": "373504107",
|
|
// "openInterestValue": "22505.67",
|
|
// "turnover24h": "2352.94950046",
|
|
// "volume24h": "49337318",
|
|
// "fundingRate": "-0.001034",
|
|
// "nextFundingTime": "1672387200000",
|
|
// "predictedDeliveryPrice": "",
|
|
// "basisRate": "",
|
|
// "deliveryFeeRate": "",
|
|
// "deliveryTime": "0",
|
|
// "ask1Size": "1",
|
|
// "bid1Price": "16596.00",
|
|
// "ask1Price": "16597.50",
|
|
// "bid1Size": "1"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672376496682
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var tickerList interface{} = this.SafeList(result, "list", []interface{}{})
|
|
|
|
ch <- this.ParseTickers(tickerList, parsedSymbols)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchBidsAsks
|
|
* @description fetches the bid and ask price and volume for multiple markets
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/tickers
|
|
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.subType] *contract only* 'linear', 'inverse'
|
|
* @param {string} [params.baseCoin] *option only* base coin, default is 'BTC'
|
|
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
*/
|
|
func (this *bybit) FetchBidsAsks(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
|
|
|
|
retRes254415 := (<-this.FetchTickers(symbols, params))
|
|
PanicOnError(retRes254415)
|
|
ch <- retRes254415
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// [
|
|
// "1621162800",
|
|
// "49592.43",
|
|
// "49644.91",
|
|
// "49342.37",
|
|
// "49349.42",
|
|
// "1451.59",
|
|
// "2.4343353100000003"
|
|
// ]
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var volumeIndex interface{} = Ternary(IsTrue((GetValue(market, "inverse"))), 6, 5)
|
|
return []interface{}{this.SafeInteger(ohlcv, 0), this.SafeNumber(ohlcv, 1), this.SafeNumber(ohlcv, 2), this.SafeNumber(ohlcv, 3), this.SafeNumber(ohlcv, 4), this.SafeNumber(ohlcv, volumeIndex)}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOHLCV
|
|
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/kline
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/mark-kline
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/index-kline
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/preimum-index-kline
|
|
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
* @param {string} timeframe the length of time each candle represents
|
|
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
* @param {int} [limit] the maximum amount of candles to fetch
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] the latest time in ms to fetch orders 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 {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
*/
|
|
func (this *bybit) 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
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOHLCV() requires a symbol argument")))
|
|
}
|
|
|
|
retRes25918 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes25918)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes259519 := (<-this.FetchPaginatedCallDeterministic("fetchOHLCV", symbol, since, limit, timeframe, params, 1000))
|
|
PanicOnError(retRes259519)
|
|
ch <- retRes259519
|
|
return nil
|
|
}
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(IsEqual(limit, nil)) {
|
|
limit = 200 // default is 200 when requested with `since`
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "start", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit) // max 1000, default 1000
|
|
}
|
|
requestparamsVariable := this.HandleUntilOption("end", request, params);
|
|
request = GetValue(requestparamsVariable,0);
|
|
params = GetValue(requestparamsVariable,1)
|
|
AddElementToObject(request, "interval", this.SafeString(this.Timeframes, timeframe, timeframe))
|
|
var response interface{} = nil
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
AddElementToObject(request, "category", "spot")
|
|
|
|
response = (<-this.PublicGetV5MarketKline(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
var price interface{} = this.SafeString(params, "price")
|
|
params = this.Omit(params, "price")
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
AddElementToObject(request, "category", "linear")
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
AddElementToObject(request, "category", "inverse")
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " fetchOHLCV() is not supported for option markets")))
|
|
}
|
|
if IsTrue(IsEqual(price, "mark")) {
|
|
|
|
response = (<-this.PublicGetV5MarketMarkPriceKline(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(IsEqual(price, "index")) {
|
|
|
|
response = (<-this.PublicGetV5MarketIndexPriceKline(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(IsEqual(price, "premiumIndex")) {
|
|
|
|
response = (<-this.PublicGetV5MarketPremiumIndexPriceKline(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
|
|
response = (<-this.PublicGetV5MarketKline(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
}
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "symbol": "BTCUSD",
|
|
// "category": "inverse",
|
|
// "list": [
|
|
// [
|
|
// "1670608800000",
|
|
// "17071",
|
|
// "17073",
|
|
// "17027",
|
|
// "17055.5",
|
|
// "268611",
|
|
// "15.74462667"
|
|
// ],
|
|
// [
|
|
// "1670605200000",
|
|
// "17071.5",
|
|
// "17071.5",
|
|
// "17061",
|
|
// "17071",
|
|
// "4177",
|
|
// "0.24469757"
|
|
// ],
|
|
// [
|
|
// "1670601600000",
|
|
// "17086.5",
|
|
// "17088",
|
|
// "16978",
|
|
// "17071.5",
|
|
// "6356",
|
|
// "0.37288112"
|
|
// ]
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672025956592
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var ohlcvs interface{} = this.SafeList(result, "list", []interface{}{})
|
|
|
|
ch <- this.ParseOHLCVs(ohlcvs, market, timeframe, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseFundingRate(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "symbol": "BTCUSDT",
|
|
// "bidPrice": "19255",
|
|
// "askPrice": "19255.5",
|
|
// "lastPrice": "19255.50",
|
|
// "lastTickDirection": "ZeroPlusTick",
|
|
// "prevPrice24h": "18634.50",
|
|
// "price24hPcnt": "0.033325",
|
|
// "highPrice24h": "19675.00",
|
|
// "lowPrice24h": "18610.00",
|
|
// "prevPrice1h": "19278.00",
|
|
// "markPrice": "19255.00",
|
|
// "indexPrice": "19260.68",
|
|
// "openInterest": "48069.549",
|
|
// "turnover24h": "4686694853.047006",
|
|
// "volume24h": "243730.252",
|
|
// "fundingRate": "0.0001",
|
|
// "nextFundingTime": "1663689600000",
|
|
// "predictedDeliveryPrice": "",
|
|
// "basisRate": "",
|
|
// "deliveryFeeRate": "",
|
|
// "deliveryTime": "0"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var timestamp interface{} = this.SafeInteger(ticker, "timestamp") // added artificially to avoid changing the signature
|
|
ticker = this.Omit(ticker, "timestamp")
|
|
var marketId interface{} = this.SafeString(ticker, "symbol")
|
|
var symbol interface{} = this.SafeSymbol(marketId, market, nil, "swap")
|
|
var fundingRate interface{} = this.SafeNumber(ticker, "fundingRate")
|
|
var fundingTimestamp interface{} = this.SafeInteger(ticker, "nextFundingTime")
|
|
var markPrice interface{} = this.SafeNumber(ticker, "markPrice")
|
|
var indexPrice interface{} = this.SafeNumber(ticker, "indexPrice")
|
|
var info interface{} = this.SafeDict(this.SafeMarket(marketId, market, nil, "swap"), "info")
|
|
var fundingInterval interface{} = this.SafeInteger(info, "fundingInterval")
|
|
var intervalString interface{} = nil
|
|
if IsTrue(!IsEqual(fundingInterval, nil)) {
|
|
var interval interface{} = this.ParseToInt(Divide(fundingInterval, 60))
|
|
intervalString = Add(ToString(interval), "h")
|
|
}
|
|
return map[string]interface{} {
|
|
"info": ticker,
|
|
"symbol": symbol,
|
|
"markPrice": markPrice,
|
|
"indexPrice": indexPrice,
|
|
"interestRate": nil,
|
|
"estimatedSettlePrice": nil,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"fundingRate": fundingRate,
|
|
"fundingTimestamp": fundingTimestamp,
|
|
"fundingDatetime": this.Iso8601(fundingTimestamp),
|
|
"nextFundingRate": nil,
|
|
"nextFundingTimestamp": nil,
|
|
"nextFundingDatetime": nil,
|
|
"previousFundingRate": nil,
|
|
"previousFundingTimestamp": nil,
|
|
"previousFundingDatetime": nil,
|
|
"interval": intervalString,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchFundingRates
|
|
* @description fetches funding rates for multiple markets
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/tickers
|
|
* @param {string[]} symbols unified symbols of the markets to fetch the funding rates for, all market funding rates are returned if not assigned
|
|
* @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-rate-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes27558 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes27558)
|
|
var market interface{} = nil
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(!IsEqual(symbols, nil)) {
|
|
symbols = this.MarketSymbols(symbols)
|
|
market = this.Market(GetValue(symbols, 0))
|
|
var symbolsLength interface{} = GetArrayLength(symbols)
|
|
if IsTrue(IsEqual(symbolsLength, 1)) {
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchFundingRates", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
if IsTrue(!IsEqual(typeVar, "swap")) {
|
|
panic(NotSupported(Add(Add(Add(this.Id, " fetchFundingRates() does not support "), typeVar), " markets")))
|
|
} else {
|
|
var subType interface{} = nil
|
|
subTypeparamsVariable := this.HandleSubTypeAndParams("fetchFundingRates", market, params, "linear");
|
|
subType = GetValue(subTypeparamsVariable,0);
|
|
params = GetValue(subTypeparamsVariable,1)
|
|
AddElementToObject(request, "category", subType)
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketTickers(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "category": "linear",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTCUSDT",
|
|
// "bidPrice": "19255",
|
|
// "askPrice": "19255.5",
|
|
// "lastPrice": "19255.50",
|
|
// "lastTickDirection": "ZeroPlusTick",
|
|
// "prevPrice24h": "18634.50",
|
|
// "price24hPcnt": "0.033325",
|
|
// "highPrice24h": "19675.00",
|
|
// "lowPrice24h": "18610.00",
|
|
// "prevPrice1h": "19278.00",
|
|
// "markPrice": "19255.00",
|
|
// "indexPrice": "19260.68",
|
|
// "openInterest": "48069.549",
|
|
// "turnover24h": "4686694853.047006",
|
|
// "volume24h": "243730.252",
|
|
// "fundingRate": "0.0001",
|
|
// "nextFundingTime": "1663689600000",
|
|
// "predictedDeliveryPrice": "",
|
|
// "basisRate": "",
|
|
// "deliveryFeeRate": "",
|
|
// "deliveryTime": "0"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": null,
|
|
// "time": 1663670053454
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var tickerList interface{} = this.SafeList(data, "list", []interface{}{})
|
|
var timestamp interface{} = this.SafeInteger(response, "time")
|
|
for i := 0; IsLessThan(i, GetArrayLength(tickerList)); i++ {
|
|
AddElementToObject(GetValue(tickerList, i), "timestamp", timestamp) // will be removed inside the parser
|
|
}
|
|
|
|
ch <- this.ParseFundingRates(tickerList, symbols)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchFundingRateHistory
|
|
* @description fetches historical funding rate prices
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/history-fund-rate
|
|
* @param {string} symbol unified symbol of the market to fetch the funding rate history for
|
|
* @param {int} [since] timestamp in ms of the earliest funding rate to fetch
|
|
* @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] timestamp in ms of the latest funding rate
|
|
* @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 *bybit) 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")))
|
|
}
|
|
|
|
retRes28388 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes28388)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchFundingRateHistory", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes284219 := (<-this.FetchPaginatedCallDeterministic("fetchFundingRateHistory", symbol, since, limit, "8h", params, 200))
|
|
PanicOnError(retRes284219)
|
|
ch <- retRes284219
|
|
return nil
|
|
}
|
|
if IsTrue(IsEqual(limit, nil)) {
|
|
limit = 200
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"limit": limit,
|
|
}
|
|
var market interface{} = this.Market(symbol)
|
|
symbol = GetValue(market, "symbol")
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchFundingRateHistory", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
if IsTrue(IsTrue(IsEqual(typeVar, "spot")) || IsTrue(IsEqual(typeVar, "option"))) {
|
|
panic(NotSupported(Add(this.Id, " fetchFundingRateHistory() only support linear and inverse market")))
|
|
}
|
|
AddElementToObject(request, "category", typeVar)
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
var until interface{} = this.SafeInteger(params, "until") // unified in milliseconds
|
|
var endTime interface{} = this.SafeInteger(params, "endTime", until) // exchange-specific in milliseconds
|
|
params = this.Omit(params, []interface{}{"endTime", "until"})
|
|
if IsTrue(!IsEqual(endTime, nil)) {
|
|
AddElementToObject(request, "endTime", endTime)
|
|
} else {
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
// end time is required when since is not empty
|
|
var fundingInterval interface{} = Multiply(Multiply(Multiply(60, 60), 8), 1000)
|
|
AddElementToObject(request, "endTime", Add(since, Multiply(limit, fundingInterval)))
|
|
}
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketFundingHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "category": "linear",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "ETHPERP",
|
|
// "fundingRate": "0.0001",
|
|
// "fundingRateTimestamp": "1672041600000"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672051897447
|
|
// }
|
|
//
|
|
var rates interface{} = []interface{}{}
|
|
var result interface{} = this.SafeDict(response, "result")
|
|
var resultList interface{} = this.SafeList(result, "list")
|
|
for i := 0; IsLessThan(i, GetArrayLength(resultList)); i++ {
|
|
var entry interface{} = GetValue(resultList, i)
|
|
var timestamp interface{} = this.SafeInteger(entry, "fundingRateTimestamp")
|
|
AppendToArray(&rates,map[string]interface{} {
|
|
"info": entry,
|
|
"symbol": this.SafeSymbol(this.SafeString(entry, "symbol"), nil, nil, "swap"),
|
|
"fundingRate": this.SafeNumber(entry, "fundingRate"),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
})
|
|
}
|
|
var sorted interface{} = this.SortBy(rates, "timestamp")
|
|
|
|
ch <- this.FilterBySymbolSinceLimit(sorted, symbol, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// public https://bybit-exchange.github.io/docs/v5/market/recent-trade
|
|
//
|
|
// {
|
|
// "execId": "666042b4-50c6-58f3-bd9c-89b2088663ff",
|
|
// "symbol": "ETHUSD",
|
|
// "price": "1162.95",
|
|
// "size": "1",
|
|
// "side": "Sell",
|
|
// "time": "1669191277315",
|
|
// "isBlockTrade": false
|
|
// }
|
|
//
|
|
// private trades classic spot https://bybit-exchange.github.io/docs/v5/position/execution
|
|
//
|
|
// {
|
|
// "symbol": "QNTUSDT",
|
|
// "orderId": "1538686353240339712",
|
|
// "orderLinkId": "",
|
|
// "side": "Sell",
|
|
// "orderPrice": "",
|
|
// "orderQty": "",
|
|
// "leavesQty": "",
|
|
// "orderType": "Limit",
|
|
// "stopOrderType": "",
|
|
// "execFee": "0.040919",
|
|
// "execId": "2210000000097330907",
|
|
// "execPrice": "98.6",
|
|
// "execQty": "0.415",
|
|
// "execType": "",
|
|
// "execValue": "",
|
|
// "execTime": "1698161716634",
|
|
// "isMaker": true,
|
|
// "feeRate": "",
|
|
// "tradeIv": "",
|
|
// "markIv": "",
|
|
// "markPrice": "",
|
|
// "indexPrice": "",
|
|
// "underlyingPrice": "",
|
|
// "blockTradeId": ""
|
|
// }
|
|
//
|
|
// private trades unified https://bybit-exchange.github.io/docs/v5/position/execution
|
|
//
|
|
// {
|
|
// "symbol": "QNTUSDT",
|
|
// "orderType": "Limit",
|
|
// "underlyingPrice": "",
|
|
// "orderLinkId": "1549452573428424449",
|
|
// "orderId": "1549452573428424448",
|
|
// "stopOrderType": "",
|
|
// "execTime": "1699445151998",
|
|
// "feeRate": "0.00025",
|
|
// "tradeIv": "",
|
|
// "blockTradeId": "",
|
|
// "markPrice": "",
|
|
// "execPrice": "102.8",
|
|
// "markIv": "",
|
|
// "orderQty": "3.652",
|
|
// "orderPrice": "102.8",
|
|
// "execValue": "1.028",
|
|
// "closedSize": "",
|
|
// "execType": "Trade",
|
|
// "seq": "19157444346",
|
|
// "side": "Buy",
|
|
// "indexPrice": "",
|
|
// "leavesQty": "3.642",
|
|
// "isMaker": true,
|
|
// "execFee": "0.0000025",
|
|
// "execId": "2210000000101610464",
|
|
// "execQty": "0.01",
|
|
// "nextPageCursor": "267951%3A0%2C38567%3A0"
|
|
// },
|
|
//
|
|
// private USDC settled trades
|
|
//
|
|
// {
|
|
// "symbol": "ETHPERP",
|
|
// "orderLinkId": "",
|
|
// "side": "Buy",
|
|
// "orderId": "aad0ee44-ce12-4112-aeee-b7829f6c3a26",
|
|
// "execFee": "0.0210",
|
|
// "feeRate": "0.000600",
|
|
// "blockTradeId": "",
|
|
// "tradeTime": "1669196417930",
|
|
// "execPrice": "1162.15",
|
|
// "lastLiquidityInd": "TAKER",
|
|
// "execValue": "34.8645",
|
|
// "execType": "Trade",
|
|
// "execQty": "0.030",
|
|
// "tradeId": "0e94eaf5-b08e-5505-b43f-7f1f30b1ca80"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var id interface{} = this.SafeStringN(trade, []interface{}{"execId", "id", "tradeId"})
|
|
var marketId interface{} = this.SafeString(trade, "symbol")
|
|
var marketType interface{} = Ternary(IsTrue((InOp(trade, "createType"))), "contract", "spot")
|
|
if IsTrue(!IsEqual(market, nil)) {
|
|
marketType = GetValue(market, "type")
|
|
}
|
|
var category interface{} = this.SafeString(trade, "category")
|
|
if IsTrue(!IsEqual(category, nil)) {
|
|
if IsTrue(IsEqual(category, "spot")) {
|
|
marketType = "spot"
|
|
}
|
|
}
|
|
market = this.SafeMarket(marketId, market, nil, marketType)
|
|
var symbol interface{} = GetValue(market, "symbol")
|
|
var amountString interface{} = this.SafeStringN(trade, []interface{}{"execQty", "orderQty", "size"})
|
|
var priceString interface{} = this.SafeStringN(trade, []interface{}{"execPrice", "orderPrice", "price"})
|
|
var costString interface{} = this.SafeString(trade, "execValue")
|
|
var timestamp interface{} = this.SafeIntegerN(trade, []interface{}{"time", "execTime", "tradeTime"})
|
|
var side interface{} = this.SafeStringLower(trade, "side")
|
|
if IsTrue(IsEqual(side, nil)) {
|
|
var isBuyer interface{} = this.SafeInteger(trade, "isBuyer")
|
|
if IsTrue(!IsEqual(isBuyer, nil)) {
|
|
side = Ternary(IsTrue(isBuyer), "buy", "sell")
|
|
}
|
|
}
|
|
var isMaker interface{} = this.SafeBool(trade, "isMaker")
|
|
var takerOrMaker interface{} = nil
|
|
if IsTrue(!IsEqual(isMaker, nil)) {
|
|
takerOrMaker = Ternary(IsTrue(isMaker), "maker", "taker")
|
|
} else {
|
|
var lastLiquidityInd interface{} = this.SafeString(trade, "lastLiquidityInd")
|
|
if IsTrue(IsEqual(lastLiquidityInd, "UNKNOWN")) {
|
|
lastLiquidityInd = nil
|
|
}
|
|
if IsTrue(!IsEqual(lastLiquidityInd, nil)) {
|
|
if IsTrue(IsTrue((IsEqual(lastLiquidityInd, "TAKER"))) || IsTrue((IsEqual(lastLiquidityInd, "MAKER")))) {
|
|
takerOrMaker = ToLower(lastLiquidityInd)
|
|
} else {
|
|
takerOrMaker = Ternary(IsTrue((IsEqual(lastLiquidityInd, "AddedLiquidity"))), "maker", "taker")
|
|
}
|
|
}
|
|
}
|
|
var orderType interface{} = this.SafeStringLower(trade, "orderType")
|
|
if IsTrue(IsEqual(orderType, "unknown")) {
|
|
orderType = nil
|
|
}
|
|
var feeCostString interface{} = this.SafeString(trade, "execFee")
|
|
var fee interface{} = nil
|
|
if IsTrue(!IsEqual(feeCostString, nil)) {
|
|
var feeRateString interface{} = this.SafeString(trade, "feeRate")
|
|
var feeCurrencyCode interface{} = nil
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
if IsTrue(Precise.StringGt(feeCostString, "0")) {
|
|
if IsTrue(IsEqual(side, "buy")) {
|
|
feeCurrencyCode = GetValue(market, "base")
|
|
} else {
|
|
feeCurrencyCode = GetValue(market, "quote")
|
|
}
|
|
} else {
|
|
if IsTrue(IsEqual(side, "buy")) {
|
|
feeCurrencyCode = GetValue(market, "quote")
|
|
} else {
|
|
feeCurrencyCode = GetValue(market, "base")
|
|
}
|
|
}
|
|
} else {
|
|
feeCurrencyCode = Ternary(IsTrue(GetValue(market, "inverse")), GetValue(market, "base"), GetValue(market, "settle"))
|
|
}
|
|
fee = map[string]interface{} {
|
|
"cost": feeCostString,
|
|
"currency": feeCurrencyCode,
|
|
"rate": feeRateString,
|
|
}
|
|
}
|
|
return this.SafeTrade(map[string]interface{} {
|
|
"id": id,
|
|
"info": trade,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"symbol": symbol,
|
|
"order": this.SafeString(trade, "orderId"),
|
|
"type": orderType,
|
|
"side": side,
|
|
"takerOrMaker": takerOrMaker,
|
|
"price": priceString,
|
|
"amount": amountString,
|
|
"cost": costString,
|
|
"fee": fee,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchTrades
|
|
* @description get the list of most recent trades for a particular symbol
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/recent-trade
|
|
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
* @param {int} [limit] the maximum amount of trades to fetch
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
*/
|
|
func (this *bybit) FetchTrades(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
since := GetArg(optionalArgs, 0, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 1, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchTrades() requires a symbol argument")))
|
|
}
|
|
|
|
retRes31178 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes31178)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
// spot: [1,60], default: 60.
|
|
// others: [1,1000], default: 500
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchTrades", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
AddElementToObject(request, "category", typeVar)
|
|
|
|
response:= (<-this.PublicGetV5MarketRecentTrade(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "category": "spot",
|
|
// "list": [
|
|
// {
|
|
// "execId": "2100000000007764263",
|
|
// "symbol": "BTCUSDT",
|
|
// "price": "16618.49",
|
|
// "size": "0.00012",
|
|
// "side": "Buy",
|
|
// "time": "1672052955758",
|
|
// "isBlockTrade": false
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672053054358
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var trades interface{} = this.SafeList(result, "list", []interface{}{})
|
|
|
|
ch <- this.ParseTrades(trades, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOrderBook
|
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/orderbook
|
|
* @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 *bybit) 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
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOrderBook() requires a symbol argument")))
|
|
}
|
|
|
|
retRes31748 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes31748)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
var defaultLimit interface{} = 25
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
// limit: [1, 50]. Default: 1
|
|
defaultLimit = 50
|
|
AddElementToObject(request, "category", "spot")
|
|
} else {
|
|
if IsTrue(GetValue(market, "option")) {
|
|
// limit: [1, 25]. Default: 1
|
|
AddElementToObject(request, "category", "option")
|
|
} else if IsTrue(GetValue(market, "linear")) {
|
|
// limit: [1, 500]. Default: 25
|
|
AddElementToObject(request, "category", "linear")
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
// limit: [1, 500]. Default: 25
|
|
AddElementToObject(request, "category", "inverse")
|
|
}
|
|
}
|
|
AddElementToObject(request, "limit", Ternary(IsTrue((!IsEqual(limit, nil))), limit, defaultLimit))
|
|
|
|
response:= (<-this.PublicGetV5MarketOrderbook(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "s": "BTCUSDT",
|
|
// "a": [
|
|
// [
|
|
// "16638.64",
|
|
// "0.008479"
|
|
// ]
|
|
// ],
|
|
// "b": [
|
|
// [
|
|
// "16638.27",
|
|
// "0.305749"
|
|
// ]
|
|
// ],
|
|
// "ts": 1672765737733,
|
|
// "u": 5277055
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672765737734
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var timestamp interface{} = this.SafeInteger(result, "ts")
|
|
|
|
ch <- this.ParseOrderBook(result, symbol, timestamp, "b", "a")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseBalance(response interface{}) interface{} {
|
|
//
|
|
// cross
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "acctBalanceSum": "0.122995614474732872",
|
|
// "debtBalanceSum": "0.011734191124529754",
|
|
// "loanAccountList": [
|
|
// {
|
|
// "free": "0.001143855",
|
|
// "interest": "0",
|
|
// "loan": "0",
|
|
// "locked": "0",
|
|
// "tokenId": "BTC",
|
|
// "total": "0.001143855"
|
|
// },
|
|
// {
|
|
// "free": "200.00005568",
|
|
// "interest": "0.0008391",
|
|
// "loan": "200",
|
|
// "locked": "0",
|
|
// "tokenId": "USDT",
|
|
// "total": "200.00005568"
|
|
// },
|
|
// ],
|
|
// "riskRate": "0.0954",
|
|
// "status": 1
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1669843584123
|
|
// }
|
|
//
|
|
// funding
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "memberId": "533285",
|
|
// "accountType": "FUND",
|
|
// "balance": [
|
|
// {
|
|
// "coin": "USDT",
|
|
// "transferBalance": "1010",
|
|
// "walletBalance": "1010",
|
|
// "bonus": ""
|
|
// },
|
|
// {
|
|
// "coin": "USDC",
|
|
// "transferBalance": "0",
|
|
// "walletBalance": "0",
|
|
// "bonus": ""
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1675865290069
|
|
// }
|
|
//
|
|
// spot & swap
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "totalEquity": "18070.32797922",
|
|
// "accountIMRate": "0.0101",
|
|
// "totalMarginBalance": "18070.32797922",
|
|
// "totalInitialMargin": "182.60183684",
|
|
// "accountType": "UNIFIED",
|
|
// "totalAvailableBalance": "17887.72614237",
|
|
// "accountMMRate": "0",
|
|
// "totalPerpUPL": "-0.11001349",
|
|
// "totalWalletBalance": "18070.43799271",
|
|
// "accountLTV": "0.017",
|
|
// "totalMaintenanceMargin": "0.38106773",
|
|
// "coin": [
|
|
// {
|
|
// "availableToBorrow": "2.5",
|
|
// "bonus": "0",
|
|
// "accruedInterest": "0",
|
|
// "availableToWithdraw": "0.805994",
|
|
// "totalOrderIM": "0",
|
|
// "equity": "0.805994",
|
|
// "totalPositionMM": "0",
|
|
// "usdValue": "12920.95352538",
|
|
// "unrealisedPnl": "0",
|
|
// "borrowAmount": "0",
|
|
// "totalPositionIM": "0",
|
|
// "walletBalance": "0.805994",
|
|
// "cumRealisedPnl": "0",
|
|
// "coin": "BTC"
|
|
// }
|
|
// ]
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672125441042
|
|
// }
|
|
//
|
|
var timestamp interface{} = this.SafeInteger(response, "time")
|
|
var result interface{} = map[string]interface{} {
|
|
"info": response,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
}
|
|
var responseResult interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var currencyList interface{} = this.SafeListN(responseResult, []interface{}{"loanAccountList", "list", "balance"})
|
|
if IsTrue(IsEqual(currencyList, nil)) {
|
|
// usdc wallet
|
|
var code interface{} = "USDC"
|
|
var account interface{} = this.Account()
|
|
AddElementToObject(account, "free", this.SafeString(responseResult, "availableBalance"))
|
|
AddElementToObject(account, "total", this.SafeString(responseResult, "walletBalance"))
|
|
AddElementToObject(result, code, account)
|
|
} else {
|
|
for i := 0; IsLessThan(i, GetArrayLength(currencyList)); i++ {
|
|
var entry interface{} = GetValue(currencyList, i)
|
|
var accountType interface{} = this.SafeString(entry, "accountType")
|
|
if IsTrue(IsTrue(IsTrue(IsEqual(accountType, "UNIFIED")) || IsTrue(IsEqual(accountType, "CONTRACT"))) || IsTrue(IsEqual(accountType, "SPOT"))) {
|
|
var coins interface{} = this.SafeList(entry, "coin")
|
|
for j := 0; IsLessThan(j, GetArrayLength(coins)); j++ {
|
|
var account interface{} = this.Account()
|
|
var coinEntry interface{} = GetValue(coins, j)
|
|
var loan interface{} = this.SafeString(coinEntry, "borrowAmount")
|
|
var interest interface{} = this.SafeString(coinEntry, "accruedInterest")
|
|
if IsTrue(IsTrue((!IsEqual(loan, nil))) && IsTrue((!IsEqual(interest, nil)))) {
|
|
AddElementToObject(account, "debt", Precise.StringAdd(loan, interest))
|
|
}
|
|
AddElementToObject(account, "total", this.SafeString(coinEntry, "walletBalance"))
|
|
var free interface{} = this.SafeString2(coinEntry, "availableToWithdraw", "free")
|
|
if IsTrue(!IsEqual(free, nil)) {
|
|
AddElementToObject(account, "free", free)
|
|
} else {
|
|
var locked interface{} = this.SafeString(coinEntry, "locked", "0")
|
|
var totalPositionIm interface{} = this.SafeString(coinEntry, "totalPositionIM", "0")
|
|
var totalOrderIm interface{} = this.SafeString(coinEntry, "totalOrderIM", "0")
|
|
var totalUsed interface{} = Precise.StringAdd(locked, totalPositionIm)
|
|
totalUsed = Precise.StringAdd(totalUsed, totalOrderIm)
|
|
AddElementToObject(account, "used", totalUsed)
|
|
}
|
|
// account['used'] = this.safeString (coinEntry, 'locked');
|
|
var currencyId interface{} = this.SafeString(coinEntry, "coin")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
|
AddElementToObject(result, code, account)
|
|
}
|
|
} else {
|
|
var account interface{} = this.Account()
|
|
var loan interface{} = this.SafeString(entry, "loan")
|
|
var interest interface{} = this.SafeString(entry, "interest")
|
|
if IsTrue(IsTrue((!IsEqual(loan, nil))) && IsTrue((!IsEqual(interest, nil)))) {
|
|
AddElementToObject(account, "debt", Precise.StringAdd(loan, interest))
|
|
}
|
|
AddElementToObject(account, "total", this.SafeString2(entry, "total", "walletBalance"))
|
|
AddElementToObject(account, "free", this.SafeStringN(entry, []interface{}{"free", "availableBalanceWithoutConvert", "availableBalance", "transferBalance"}))
|
|
AddElementToObject(account, "used", this.SafeString(entry, "locked"))
|
|
var currencyId interface{} = this.SafeStringN(entry, []interface{}{"tokenId", "coin", "currencyCoin"})
|
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
|
AddElementToObject(result, code, account)
|
|
}
|
|
}
|
|
}
|
|
return this.SafeBalance(result)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchBalance
|
|
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
* @see https://bybit-exchange.github.io/docs/v5/spot-margin-normal/account-info
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/all-balance
|
|
* @see https://bybit-exchange.github.io/docs/v5/account/wallet-balance
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.type] wallet type, ['spot', 'swap', 'funding']
|
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes34088 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes34088)
|
|
var request interface{} = map[string]interface{} {}
|
|
enableUnifiedMarginenableUnifiedAccountVariable := (<-this.IsUnifiedEnabled());
|
|
enableUnifiedMargin := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,0);
|
|
enableUnifiedAccount := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,1)
|
|
var isUnifiedAccount interface{} = (IsTrue(enableUnifiedMargin) || IsTrue(enableUnifiedAccount))
|
|
var typeVar interface{} = nil
|
|
// don't use getBybitType here
|
|
typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchBalance", nil, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
var subType interface{} = nil
|
|
subTypeparamsVariable := this.HandleSubTypeAndParams("fetchBalance", nil, params);
|
|
subType = GetValue(subTypeparamsVariable,0);
|
|
params = GetValue(subTypeparamsVariable,1)
|
|
if IsTrue(IsTrue((IsEqual(typeVar, "swap"))) || IsTrue((IsEqual(typeVar, "future")))) {
|
|
typeVar = subType
|
|
}
|
|
var lowercaseRawType interface{} = Ternary(IsTrue((!IsEqual(typeVar, nil))), ToLower(typeVar), nil)
|
|
var isSpot interface{} = (IsEqual(typeVar, "spot"))
|
|
var isLinear interface{} = (IsEqual(typeVar, "linear"))
|
|
var isInverse interface{} = (IsEqual(typeVar, "inverse"))
|
|
var isFunding interface{} = IsTrue((IsEqual(lowercaseRawType, "fund"))) || IsTrue((IsEqual(lowercaseRawType, "funding")))
|
|
if IsTrue(isUnifiedAccount) {
|
|
var unifiedMarginStatus interface{} = this.SafeInteger(this.Options, "unifiedMarginStatus", 6)
|
|
if IsTrue(IsLessThan(unifiedMarginStatus, 5)) {
|
|
// it's not uta.20 where inverse are unified
|
|
if IsTrue(isInverse) {
|
|
typeVar = "contract"
|
|
} else {
|
|
typeVar = "unified"
|
|
}
|
|
} else {
|
|
typeVar = "unified" // uta.20 where inverse are unified
|
|
}
|
|
} else {
|
|
if IsTrue(IsTrue(isLinear) || IsTrue(isInverse)) {
|
|
typeVar = "contract"
|
|
}
|
|
}
|
|
var accountTypes interface{} = this.SafeDict(this.Options, "accountsByType", map[string]interface{} {})
|
|
var unifiedType interface{} = this.SafeStringUpper(accountTypes, typeVar, typeVar)
|
|
var marginMode interface{} = nil
|
|
marginModeparamsVariable := this.HandleMarginModeAndParams("fetchBalance", params);
|
|
marginMode = GetValue(marginModeparamsVariable,0);
|
|
params = GetValue(marginModeparamsVariable,1)
|
|
var response interface{} = nil
|
|
if IsTrue(IsTrue(isSpot) && IsTrue((!IsEqual(marginMode, nil)))) {
|
|
|
|
response = (<-this.PrivateGetV5SpotCrossMarginTradeAccount(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(isFunding) {
|
|
// use this endpoint only we have no other choice
|
|
// because it requires transfer permission
|
|
AddElementToObject(request, "accountType", "FUND")
|
|
|
|
response = (<-this.PrivateGetV5AssetTransferQueryAccountCoinsBalance(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
AddElementToObject(request, "accountType", unifiedType)
|
|
|
|
response = (<-this.PrivateGetV5AccountWalletBalance(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
|
|
//
|
|
// cross
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "acctBalanceSum": "0.122995614474732872",
|
|
// "debtBalanceSum": "0.011734191124529754",
|
|
// "loanAccountList": [
|
|
// {
|
|
// "free": "0.001143855",
|
|
// "interest": "0",
|
|
// "loan": "0",
|
|
// "locked": "0",
|
|
// "tokenId": "BTC",
|
|
// "total": "0.001143855"
|
|
// },
|
|
// {
|
|
// "free": "200.00005568",
|
|
// "interest": "0.0008391",
|
|
// "loan": "200",
|
|
// "locked": "0",
|
|
// "tokenId": "USDT",
|
|
// "total": "200.00005568"
|
|
// },
|
|
// ],
|
|
// "riskRate": "0.0954",
|
|
// "status": 1
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1669843584123
|
|
// }
|
|
//
|
|
// funding
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "memberId": "533285",
|
|
// "accountType": "FUND",
|
|
// "balance": [
|
|
// {
|
|
// "coin": "USDT",
|
|
// "transferBalance": "1010",
|
|
// "walletBalance": "1010",
|
|
// "bonus": ""
|
|
// },
|
|
// {
|
|
// "coin": "USDC",
|
|
// "transferBalance": "0",
|
|
// "walletBalance": "0",
|
|
// "bonus": ""
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1675865290069
|
|
// }
|
|
//
|
|
// spot & swap
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "totalEquity": "18070.32797922",
|
|
// "accountIMRate": "0.0101",
|
|
// "totalMarginBalance": "18070.32797922",
|
|
// "totalInitialMargin": "182.60183684",
|
|
// "accountType": "UNIFIED",
|
|
// "totalAvailableBalance": "17887.72614237",
|
|
// "accountMMRate": "0",
|
|
// "totalPerpUPL": "-0.11001349",
|
|
// "totalWalletBalance": "18070.43799271",
|
|
// "accountLTV": "0.017",
|
|
// "totalMaintenanceMargin": "0.38106773",
|
|
// "coin": [
|
|
// {
|
|
// "availableToBorrow": "2.5",
|
|
// "bonus": "0",
|
|
// "accruedInterest": "0",
|
|
// "availableToWithdraw": "0.805994",
|
|
// "totalOrderIM": "0",
|
|
// "equity": "0.805994",
|
|
// "totalPositionMM": "0",
|
|
// "usdValue": "12920.95352538",
|
|
// "unrealisedPnl": "0",
|
|
// "borrowAmount": "0",
|
|
// "totalPositionIM": "0",
|
|
// "walletBalance": "0.805994",
|
|
// "cumRealisedPnl": "0",
|
|
// "coin": "BTC"
|
|
// }
|
|
// ]
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672125441042
|
|
// }
|
|
//
|
|
ch <- this.ParseBalance(response)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseOrderStatus(status interface{}) interface{} {
|
|
var statuses interface{} = map[string]interface{} {
|
|
"NEW": "open",
|
|
"PARTIALLY_FILLED": "open",
|
|
"FILLED": "closed",
|
|
"CANCELED": "canceled",
|
|
"PENDING_CANCEL": "open",
|
|
"PENDING_NEW": "open",
|
|
"REJECTED": "rejected",
|
|
"PARTIALLY_FILLED_CANCELLED": "closed",
|
|
"Created": "open",
|
|
"New": "open",
|
|
"Rejected": "rejected",
|
|
"PartiallyFilled": "open",
|
|
"PartiallyFilledCanceled": "closed",
|
|
"Filled": "closed",
|
|
"PendingCancel": "open",
|
|
"Cancelled": "canceled",
|
|
"Untriggered": "open",
|
|
"Deactivated": "canceled",
|
|
"Triggered": "open",
|
|
"Active": "open",
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *bybit) ParseTimeInForce(timeInForce interface{}) interface{} {
|
|
var timeInForces interface{} = map[string]interface{} {
|
|
"GoodTillCancel": "GTC",
|
|
"ImmediateOrCancel": "IOC",
|
|
"FillOrKill": "FOK",
|
|
"PostOnly": "PO",
|
|
}
|
|
return this.SafeString(timeInForces, timeInForce, timeInForce)
|
|
}
|
|
func (this *bybit) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// v1 for usdc normal account
|
|
// {
|
|
// "symbol": "BTCPERP",
|
|
// "orderType": "Market",
|
|
// "orderLinkId": "",
|
|
// "orderId": "36190ad3-de08-4b83-9ad3-56942f684b79",
|
|
// "cancelType": "UNKNOWN",
|
|
// "stopOrderType": "UNKNOWN",
|
|
// "orderStatus": "Filled",
|
|
// "updateTimeStamp": "1692769133267",
|
|
// "takeProfit": "0.0000",
|
|
// "cumExecValue": "259.6830",
|
|
// "createdAt": "1692769133261",
|
|
// "blockTradeId": "",
|
|
// "orderPnl": "",
|
|
// "price": "24674.7",
|
|
// "tpTriggerBy": "UNKNOWN",
|
|
// "timeInForce": "ImmediateOrCancel",
|
|
// "updatedAt": "1692769133267",
|
|
// "basePrice": "0.0",
|
|
// "realisedPnl": "0.0000",
|
|
// "side": "Sell",
|
|
// "triggerPrice": "0.0",
|
|
// "cumExecFee": "0.1429",
|
|
// "leavesQty": "0.000",
|
|
// "cashFlow": "",
|
|
// "slTriggerBy": "UNKNOWN",
|
|
// "iv": "",
|
|
// "closeOnTrigger": "UNKNOWN",
|
|
// "cumExecQty": "0.010",
|
|
// "reduceOnly": 0,
|
|
// "qty": "0.010",
|
|
// "stopLoss": "0.0000",
|
|
// "triggerBy": "UNKNOWN",
|
|
// "orderIM": ""
|
|
// }
|
|
//
|
|
// v5
|
|
// {
|
|
// "orderId": "14bad3a1-6454-43d8-bcf2-5345896cf74d",
|
|
// "orderLinkId": "YLxaWKMiHU",
|
|
// "blockTradeId": "",
|
|
// "symbol": "BTCUSDT",
|
|
// "price": "26864.40",
|
|
// "qty": "0.003",
|
|
// "side": "Buy",
|
|
// "isLeverage": "",
|
|
// "positionIdx": 1,
|
|
// "orderStatus": "Cancelled",
|
|
// "cancelType": "UNKNOWN",
|
|
// "rejectReason": "EC_PostOnlyWillTakeLiquidity",
|
|
// "avgPrice": "0",
|
|
// "leavesQty": "0.000",
|
|
// "leavesValue": "0",
|
|
// "cumExecQty": "0.000",
|
|
// "cumExecValue": "0",
|
|
// "cumExecFee": "0",
|
|
// "timeInForce": "PostOnly",
|
|
// "orderType": "Limit",
|
|
// "stopOrderType": "UNKNOWN",
|
|
// "orderIv": "",
|
|
// "triggerPrice": "0.00",
|
|
// "takeProfit": "0.00",
|
|
// "stopLoss": "0.00",
|
|
// "tpTriggerBy": "UNKNOWN",
|
|
// "slTriggerBy": "UNKNOWN",
|
|
// "triggerDirection": 0,
|
|
// "triggerBy": "UNKNOWN",
|
|
// "lastPriceOnCreated": "0.00",
|
|
// "reduceOnly": false,
|
|
// "closeOnTrigger": false,
|
|
// "smpType": "None",
|
|
// "smpGroup": 0,
|
|
// "smpOrderId": "",
|
|
// "tpslMode": "",
|
|
// "tpLimitPrice": "",
|
|
// "slLimitPrice": "",
|
|
// "placeType": "",
|
|
// "createdTime": "1684476068369",
|
|
// "updatedTime": "1684476068372"
|
|
// }
|
|
// createOrders failed order
|
|
// {
|
|
// "category": "linear",
|
|
// "symbol": "LTCUSDT",
|
|
// "orderId": '',
|
|
// "orderLinkId": '',
|
|
// "createAt": '',
|
|
// "code": "10001",
|
|
// "msg": "The number of contracts exceeds maximum limit allowed: too large"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var code interface{} = this.SafeString(order, "code")
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
if IsTrue(!IsEqual(code, "0")) {
|
|
var category interface{} = this.SafeString(order, "category")
|
|
var inferredMarketType interface{} = Ternary(IsTrue((IsEqual(category, "spot"))), "spot", "contract")
|
|
return this.SafeOrder(map[string]interface{} {
|
|
"info": order,
|
|
"status": "rejected",
|
|
"id": this.SafeString(order, "orderId"),
|
|
"clientOrderId": this.SafeString(order, "orderLinkId"),
|
|
"symbol": this.SafeSymbol(this.SafeString(order, "symbol"), nil, nil, inferredMarketType),
|
|
})
|
|
}
|
|
}
|
|
var marketId interface{} = this.SafeString(order, "symbol")
|
|
var isContract interface{} = (InOp(order, "tpslMode"))
|
|
var marketType interface{} = nil
|
|
if IsTrue(!IsEqual(market, nil)) {
|
|
marketType = GetValue(market, "type")
|
|
} else {
|
|
marketType = Ternary(IsTrue(isContract), "contract", "spot")
|
|
}
|
|
market = this.SafeMarket(marketId, market, nil, marketType)
|
|
var symbol interface{} = GetValue(market, "symbol")
|
|
var timestamp interface{} = this.SafeInteger2(order, "createdTime", "createdAt")
|
|
var marketUnit interface{} = this.SafeString(order, "marketUnit", "baseCoin")
|
|
var id interface{} = this.SafeString(order, "orderId")
|
|
var typeVar interface{} = this.SafeStringLower(order, "orderType")
|
|
var price interface{} = this.SafeString(order, "price")
|
|
var amount interface{} = nil
|
|
var cost interface{} = nil
|
|
if IsTrue(IsEqual(marketUnit, "baseCoin")) {
|
|
amount = this.SafeString(order, "qty")
|
|
cost = this.SafeString(order, "cumExecValue")
|
|
} else {
|
|
cost = this.SafeString(order, "cumExecValue")
|
|
}
|
|
var filled interface{} = this.SafeString(order, "cumExecQty")
|
|
var remaining interface{} = this.SafeString(order, "leavesQty")
|
|
var lastTradeTimestamp interface{} = this.SafeInteger2(order, "updatedTime", "updatedAt")
|
|
var rawStatus interface{} = this.SafeString(order, "orderStatus")
|
|
var status interface{} = this.ParseOrderStatus(rawStatus)
|
|
var side interface{} = this.SafeStringLower(order, "side")
|
|
var fee interface{} = nil
|
|
var feeCostString interface{} = this.SafeString(order, "cumExecFee")
|
|
if IsTrue(!IsEqual(feeCostString, nil)) {
|
|
var feeCurrencyCode interface{} = nil
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
if IsTrue(Precise.StringGt(feeCostString, "0")) {
|
|
if IsTrue(IsEqual(side, "buy")) {
|
|
feeCurrencyCode = GetValue(market, "base")
|
|
} else {
|
|
feeCurrencyCode = GetValue(market, "quote")
|
|
}
|
|
} else {
|
|
if IsTrue(IsEqual(side, "buy")) {
|
|
feeCurrencyCode = GetValue(market, "quote")
|
|
} else {
|
|
feeCurrencyCode = GetValue(market, "base")
|
|
}
|
|
}
|
|
} else {
|
|
feeCurrencyCode = Ternary(IsTrue(GetValue(market, "inverse")), GetValue(market, "base"), GetValue(market, "settle"))
|
|
}
|
|
fee = map[string]interface{} {
|
|
"cost": this.ParseNumber(feeCostString),
|
|
"currency": feeCurrencyCode,
|
|
}
|
|
}
|
|
var clientOrderId interface{} = this.SafeString(order, "orderLinkId")
|
|
if IsTrue(IsTrue((!IsEqual(clientOrderId, nil))) && IsTrue((IsLessThan(GetLength(clientOrderId), 1)))) {
|
|
clientOrderId = nil
|
|
}
|
|
var avgPrice interface{} = this.OmitZero(this.SafeString(order, "avgPrice"))
|
|
var rawTimeInForce interface{} = this.SafeString(order, "timeInForce")
|
|
var timeInForce interface{} = this.ParseTimeInForce(rawTimeInForce)
|
|
var triggerPrice interface{} = this.OmitZero(this.SafeString(order, "triggerPrice"))
|
|
var reduceOnly interface{} = this.SafeBool(order, "reduceOnly")
|
|
var takeProfitPrice interface{} = this.OmitZero(this.SafeString(order, "takeProfit"))
|
|
var stopLossPrice interface{} = this.OmitZero(this.SafeString(order, "stopLoss"))
|
|
var triggerDirection interface{} = this.SafeString(order, "triggerDirection")
|
|
var isAscending interface{} = (IsEqual(triggerDirection, "1"))
|
|
var isStopOrderType2 interface{} = IsTrue((!IsEqual(triggerPrice, nil))) && IsTrue(reduceOnly)
|
|
if IsTrue(IsTrue((IsEqual(stopLossPrice, nil))) && IsTrue(isStopOrderType2)) {
|
|
// check if order is stop order type 2 - stopLossPrice
|
|
if IsTrue(IsTrue(isAscending) && IsTrue((IsEqual(side, "buy")))) {
|
|
// stopLoss order against short position
|
|
stopLossPrice = triggerPrice
|
|
}
|
|
if IsTrue(!IsTrue(isAscending) && IsTrue((IsEqual(side, "sell")))) {
|
|
// stopLoss order against a long position
|
|
stopLossPrice = triggerPrice
|
|
}
|
|
}
|
|
if IsTrue(IsTrue((IsEqual(takeProfitPrice, nil))) && IsTrue(isStopOrderType2)) {
|
|
// check if order is stop order type 2 - takeProfitPrice
|
|
if IsTrue(IsTrue(isAscending) && IsTrue((IsEqual(side, "sell")))) {
|
|
// takeprofit order against a long position
|
|
takeProfitPrice = triggerPrice
|
|
}
|
|
if IsTrue(!IsTrue(isAscending) && IsTrue((IsEqual(side, "buy")))) {
|
|
// takeprofit order against a short position
|
|
takeProfitPrice = triggerPrice
|
|
}
|
|
}
|
|
return this.SafeOrder(map[string]interface{} {
|
|
"info": order,
|
|
"id": id,
|
|
"clientOrderId": clientOrderId,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"lastTradeTimestamp": lastTradeTimestamp,
|
|
"lastUpdateTimestamp": lastTradeTimestamp,
|
|
"symbol": symbol,
|
|
"type": typeVar,
|
|
"timeInForce": timeInForce,
|
|
"postOnly": nil,
|
|
"reduceOnly": this.SafeBool(order, "reduceOnly"),
|
|
"side": side,
|
|
"price": price,
|
|
"triggerPrice": triggerPrice,
|
|
"takeProfitPrice": takeProfitPrice,
|
|
"stopLossPrice": stopLossPrice,
|
|
"amount": amount,
|
|
"cost": cost,
|
|
"average": avgPrice,
|
|
"filled": filled,
|
|
"remaining": remaining,
|
|
"status": status,
|
|
"fee": fee,
|
|
"trades": nil,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#createMarketBuyOrderWithCost
|
|
* @description create a market buy order by providing the symbol and cost
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/create-order
|
|
* @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 *bybit) 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
|
|
|
|
retRes38418 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes38418)
|
|
var market interface{} = this.Market(symbol)
|
|
if !IsTrue(GetValue(market, "spot")) {
|
|
panic(NotSupported(Add(this.Id, " createMarketBuyOrderWithCost() supports spot orders only")))
|
|
}
|
|
|
|
retRes384615 := (<-this.CreateOrder(symbol, "market", "buy", cost, 1, params))
|
|
PanicOnError(retRes384615)
|
|
ch <- retRes384615
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#createMarkeSellOrderWithCost
|
|
* @description create a market sell order by providing the symbol and cost
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/create-order
|
|
* @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 *bybit) CreateMarketSellOrderWithCost(symbol interface{}, cost interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes38608 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes38608)
|
|
|
|
types:= (<-this.IsUnifiedEnabled())
|
|
PanicOnError(types)
|
|
var enableUnifiedAccount interface{} = GetValue(types, 1)
|
|
if !IsTrue(enableUnifiedAccount) {
|
|
panic(NotSupported(Add(this.Id, " createMarketSellOrderWithCost() supports UTA accounts only")))
|
|
}
|
|
var market interface{} = this.Market(symbol)
|
|
if !IsTrue(GetValue(market, "spot")) {
|
|
panic(NotSupported(Add(this.Id, " createMarketSellOrderWithCost() supports spot orders only")))
|
|
}
|
|
|
|
retRes387015 := (<-this.CreateOrder(symbol, "market", "sell", cost, 1, params))
|
|
PanicOnError(retRes387015)
|
|
ch <- retRes387015
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#createOrder
|
|
* @description create a trade order
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/create-order
|
|
* @see https://bybit-exchange.github.io/docs/v5/position/trading-stop
|
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
* @param {string} type 'market' or 'limit'
|
|
* @param {string} side 'buy' or 'sell'
|
|
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
* @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.timeInForce] "GTC", "IOC", "FOK"
|
|
* @param {bool} [params.postOnly] true or false whether the order is post-only
|
|
* @param {bool} [params.reduceOnly] true or false whether the order is reduce-only
|
|
* @param {string} [params.positionIdx] *contracts only* 0 for one-way mode, 1 buy side of hedged mode, 2 sell side of hedged mode
|
|
* @param {bool} [params.hedged] *contracts only* true for hedged mode, false for one way mode, default is false
|
|
* @param {int} [params.isLeverage] *unified spot only* false then spot trading true then margin trading
|
|
* @param {string} [params.tpslMode] *contract only* 'full' or 'partial'
|
|
* @param {string} [params.mmp] *option only* market maker protection
|
|
* @param {string} [params.triggerDirection] *contract only* the direction for trigger orders, 'above' or 'below'
|
|
* @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
|
|
* @param {float} [params.stopLossPrice] The price at which a stop loss order is triggered at
|
|
* @param {float} [params.takeProfitPrice] The price at which a take profit order is triggered at
|
|
* @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
|
|
* @param {float} [params.takeProfit.triggerPrice] take profit trigger price
|
|
* @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
|
|
* @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
|
|
* @param {string} [params.trailingAmount] the quote amount to trail away from the current market price
|
|
* @param {string} [params.trailingTriggerPrice] the price to trigger a trailing order, default uses the price argument
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes39068 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes39068)
|
|
var market interface{} = this.Market(symbol)
|
|
|
|
parts:= (<-this.IsUnifiedEnabled())
|
|
PanicOnError(parts)
|
|
var enableUnifiedAccount interface{} = GetValue(parts, 1)
|
|
var trailingAmount interface{} = this.SafeString2(params, "trailingAmount", "trailingStop")
|
|
var isTrailingAmountOrder interface{} = !IsEqual(trailingAmount, nil)
|
|
var orderRequest interface{} = this.CreateOrderRequest(symbol, typeVar, side, amount, price, params, enableUnifiedAccount)
|
|
var options interface{} = this.SafeDict(this.Options, "createOrder", map[string]interface{} {})
|
|
var defaultMethod interface{} = this.SafeString(options, "method", "privatePostV5OrderCreate")
|
|
var response interface{} = nil
|
|
if IsTrue(IsTrue(isTrailingAmountOrder) || IsTrue((IsEqual(defaultMethod, "privatePostV5PositionTradingStop")))) {
|
|
|
|
response = (<-this.PrivatePostV5PositionTradingStop(orderRequest))
|
|
PanicOnError(response)
|
|
} else {
|
|
|
|
response = (<-this.PrivatePostV5OrderCreate(orderRequest))
|
|
PanicOnError(response) // already extended inside createOrderRequest
|
|
}
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "orderId": "1321003749386327552",
|
|
// "orderLinkId": "spot-test-postonly"
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672211918471
|
|
// }
|
|
//
|
|
var order interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
|
|
ch <- this.ParseOrder(order, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) CreateOrderRequest(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) interface{} {
|
|
price := GetArg(optionalArgs, 0, nil)
|
|
_ = price
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
isUTA := GetArg(optionalArgs, 2, true)
|
|
_ = isUTA
|
|
var market interface{} = this.Market(symbol)
|
|
symbol = GetValue(market, "symbol")
|
|
var lowerCaseType interface{} = ToLower(typeVar)
|
|
if IsTrue(IsTrue((IsEqual(price, nil))) && IsTrue((IsEqual(lowerCaseType, "limit")))) {
|
|
panic(ArgumentsRequired(Add(this.Id, " createOrder requires a price argument for limit orders")))
|
|
}
|
|
var defaultMethod interface{} = nil
|
|
defaultMethodparamsVariable := this.HandleOptionAndParams(params, "createOrder", "method", "privatePostV5OrderCreate");
|
|
defaultMethod = GetValue(defaultMethodparamsVariable,0);
|
|
params = GetValue(defaultMethodparamsVariable,1)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
var hedged interface{} = this.SafeBool(params, "hedged", false)
|
|
var reduceOnly interface{} = this.SafeBool(params, "reduceOnly")
|
|
var triggerPrice interface{} = this.SafeValue2(params, "triggerPrice", "stopPrice")
|
|
var stopLossTriggerPrice interface{} = this.SafeValue(params, "stopLossPrice")
|
|
var takeProfitTriggerPrice interface{} = this.SafeValue(params, "takeProfitPrice")
|
|
var stopLoss interface{} = this.SafeValue(params, "stopLoss")
|
|
var takeProfit interface{} = this.SafeValue(params, "takeProfit")
|
|
var trailingTriggerPrice interface{} = this.SafeString2(params, "trailingTriggerPrice", "activePrice", this.NumberToString(price))
|
|
var trailingAmount interface{} = this.SafeString2(params, "trailingAmount", "trailingStop")
|
|
var isTrailingAmountOrder interface{} = !IsEqual(trailingAmount, nil)
|
|
var isTriggerOrder interface{} = !IsEqual(triggerPrice, nil)
|
|
var isStopLossTriggerOrder interface{} = !IsEqual(stopLossTriggerPrice, nil)
|
|
var isTakeProfitTriggerOrder interface{} = !IsEqual(takeProfitTriggerPrice, nil)
|
|
var isStopLoss interface{} = !IsEqual(stopLoss, nil)
|
|
var isTakeProfit interface{} = !IsEqual(takeProfit, nil)
|
|
var isMarket interface{} = IsEqual(lowerCaseType, "market")
|
|
var isLimit interface{} = IsEqual(lowerCaseType, "limit")
|
|
var isBuy interface{} = IsEqual(side, "buy")
|
|
var isAlternativeEndpoint interface{} = IsEqual(defaultMethod, "privatePostV5PositionTradingStop")
|
|
var amountString interface{} = this.GetAmount(symbol, amount)
|
|
var priceString interface{} = Ternary(IsTrue((!IsEqual(price, nil))), this.GetPrice(symbol, this.NumberToString(price)), nil)
|
|
if IsTrue(IsTrue(isTrailingAmountOrder) || IsTrue(isAlternativeEndpoint)) {
|
|
if IsTrue(IsTrue(IsTrue(IsTrue(isStopLoss) || IsTrue(isTakeProfit)) || IsTrue(isTriggerOrder)) || IsTrue(GetValue(market, "spot"))) {
|
|
panic(InvalidOrder(Add(this.Id, " the API endpoint used only supports contract trailingAmount, stopLossPrice and takeProfitPrice orders")))
|
|
}
|
|
if IsTrue(IsTrue(isStopLossTriggerOrder) || IsTrue(isTakeProfitTriggerOrder)) {
|
|
if IsTrue(isStopLossTriggerOrder) {
|
|
AddElementToObject(request, "stopLoss", this.GetPrice(symbol, stopLossTriggerPrice))
|
|
if IsTrue(isLimit) {
|
|
AddElementToObject(request, "tpslMode", "Partial")
|
|
AddElementToObject(request, "slOrderType", "Limit")
|
|
AddElementToObject(request, "slLimitPrice", priceString)
|
|
AddElementToObject(request, "slSize", amountString)
|
|
}
|
|
} else if IsTrue(isTakeProfitTriggerOrder) {
|
|
AddElementToObject(request, "takeProfit", this.GetPrice(symbol, takeProfitTriggerPrice))
|
|
if IsTrue(isLimit) {
|
|
AddElementToObject(request, "tpslMode", "Partial")
|
|
AddElementToObject(request, "tpOrderType", "Limit")
|
|
AddElementToObject(request, "tpLimitPrice", priceString)
|
|
AddElementToObject(request, "tpSize", amountString)
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
AddElementToObject(request, "side", this.Capitalize(side))
|
|
AddElementToObject(request, "orderType", this.Capitalize(lowerCaseType))
|
|
var timeInForce interface{} = this.SafeStringLower(params, "timeInForce") // this is same as exchange specific param
|
|
var postOnly interface{} = nil
|
|
postOnlyparamsVariable := this.HandlePostOnly(isMarket, IsEqual(timeInForce, "postonly"), params);
|
|
postOnly = GetValue(postOnlyparamsVariable,0);
|
|
params = GetValue(postOnlyparamsVariable,1)
|
|
if IsTrue(postOnly) {
|
|
AddElementToObject(request, "timeInForce", "PostOnly")
|
|
} else if IsTrue(IsEqual(timeInForce, "gtc")) {
|
|
AddElementToObject(request, "timeInForce", "GTC")
|
|
} else if IsTrue(IsEqual(timeInForce, "fok")) {
|
|
AddElementToObject(request, "timeInForce", "FOK")
|
|
} else if IsTrue(IsEqual(timeInForce, "ioc")) {
|
|
AddElementToObject(request, "timeInForce", "IOC")
|
|
}
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
// only works for spot market
|
|
if IsTrue(!IsEqual(triggerPrice, nil)) {
|
|
AddElementToObject(request, "orderFilter", "StopOrder")
|
|
} else if IsTrue(IsTrue(IsTrue(IsTrue(!IsEqual(stopLossTriggerPrice, nil)) || IsTrue(!IsEqual(takeProfitTriggerPrice, nil))) || IsTrue(isStopLoss)) || IsTrue(isTakeProfit)) {
|
|
AddElementToObject(request, "orderFilter", "tpslOrder")
|
|
}
|
|
}
|
|
var clientOrderId interface{} = this.SafeString(params, "clientOrderId")
|
|
if IsTrue(!IsEqual(clientOrderId, nil)) {
|
|
AddElementToObject(request, "orderLinkId", clientOrderId)
|
|
} else if IsTrue(GetValue(market, "option")) {
|
|
// mandatory field for options
|
|
AddElementToObject(request, "orderLinkId", this.Uuid16())
|
|
}
|
|
if IsTrue(isLimit) {
|
|
AddElementToObject(request, "price", priceString)
|
|
}
|
|
}
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
AddElementToObject(request, "category", "spot")
|
|
} else if IsTrue(GetValue(market, "linear")) {
|
|
AddElementToObject(request, "category", "linear")
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
AddElementToObject(request, "category", "inverse")
|
|
} else if IsTrue(GetValue(market, "option")) {
|
|
AddElementToObject(request, "category", "option")
|
|
}
|
|
var cost interface{} = this.SafeString(params, "cost")
|
|
params = this.Omit(params, "cost")
|
|
// if the cost is inferable, let's keep the old logic and ignore marketUnit, to minimize the impact of the changes
|
|
var isMarketBuyAndCostInferable interface{} = IsTrue(IsTrue((IsEqual(lowerCaseType, "market"))) && IsTrue((IsEqual(side, "buy")))) && IsTrue((IsTrue((!IsEqual(price, nil))) || IsTrue((!IsEqual(cost, nil)))))
|
|
if IsTrue(IsTrue(IsTrue(IsTrue(GetValue(market, "spot")) && IsTrue((IsEqual(typeVar, "market")))) && IsTrue(isUTA)) && !IsTrue(isMarketBuyAndCostInferable)) {
|
|
// UTA account can specify the cost of the order on both sides
|
|
if IsTrue(IsTrue((!IsEqual(cost, nil))) || IsTrue((!IsEqual(price, nil)))) {
|
|
AddElementToObject(request, "marketUnit", "quoteCoin")
|
|
var orderCost interface{} = nil
|
|
if IsTrue(!IsEqual(cost, nil)) {
|
|
orderCost = cost
|
|
} else {
|
|
var quoteAmount interface{} = Precise.StringMul(amountString, priceString)
|
|
orderCost = quoteAmount
|
|
}
|
|
AddElementToObject(request, "qty", this.GetCost(symbol, orderCost))
|
|
} else {
|
|
AddElementToObject(request, "marketUnit", "baseCoin")
|
|
AddElementToObject(request, "qty", amountString)
|
|
}
|
|
} else if IsTrue(IsTrue(IsTrue(GetValue(market, "spot")) && IsTrue((IsEqual(typeVar, "market")))) && IsTrue((IsEqual(side, "buy")))) {
|
|
// classic accounts
|
|
// for market buy it requires the amount of quote currency to spend
|
|
var createMarketBuyOrderRequiresPrice interface{} = true
|
|
createMarketBuyOrderRequiresPriceparamsVariable := this.HandleOptionAndParams(params, "createOrder", "createMarketBuyOrderRequiresPrice");
|
|
createMarketBuyOrderRequiresPrice = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,0);
|
|
params = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,1)
|
|
if IsTrue(createMarketBuyOrderRequiresPrice) {
|
|
if IsTrue(IsTrue((IsEqual(price, nil))) && IsTrue((IsEqual(cost, 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 {
|
|
var quoteAmount interface{} = Precise.StringMul(amountString, priceString)
|
|
var costRequest interface{} = Ternary(IsTrue((!IsEqual(cost, nil))), cost, quoteAmount)
|
|
AddElementToObject(request, "qty", this.GetCost(symbol, costRequest))
|
|
}
|
|
} else {
|
|
if IsTrue(!IsEqual(cost, nil)) {
|
|
AddElementToObject(request, "qty", this.GetCost(symbol, this.NumberToString(cost)))
|
|
} else if IsTrue(!IsEqual(price, nil)) {
|
|
AddElementToObject(request, "qty", this.GetCost(symbol, Precise.StringMul(amountString, priceString)))
|
|
} else {
|
|
AddElementToObject(request, "qty", amountString)
|
|
}
|
|
}
|
|
} else {
|
|
if IsTrue(!IsTrue(isTrailingAmountOrder) && !IsTrue(isAlternativeEndpoint)) {
|
|
AddElementToObject(request, "qty", amountString)
|
|
}
|
|
}
|
|
if IsTrue(isTrailingAmountOrder) {
|
|
if IsTrue(!IsEqual(trailingTriggerPrice, nil)) {
|
|
AddElementToObject(request, "activePrice", this.GetPrice(symbol, trailingTriggerPrice))
|
|
}
|
|
AddElementToObject(request, "trailingStop", trailingAmount)
|
|
} else if IsTrue(IsTrue(isTriggerOrder) && !IsTrue(isAlternativeEndpoint)) {
|
|
var triggerDirection interface{} = this.SafeString(params, "triggerDirection")
|
|
params = this.Omit(params, []interface{}{"triggerPrice", "stopPrice", "triggerDirection"})
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
if IsTrue(!IsEqual(triggerDirection, nil)) {
|
|
panic(NotSupported(Add(this.Id, " createOrder() : trigger order does not support triggerDirection for spot markets yet")))
|
|
}
|
|
} else {
|
|
if IsTrue(IsEqual(triggerDirection, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " stop/trigger orders require a triggerDirection parameter, either \"above\" or \"below\" to determine the direction of the trigger.")))
|
|
}
|
|
var isAsending interface{} = (IsTrue((IsEqual(triggerDirection, "above"))) || IsTrue((IsEqual(triggerDirection, "1"))))
|
|
AddElementToObject(request, "triggerDirection", Ternary(IsTrue(isAsending), 1, 2))
|
|
}
|
|
AddElementToObject(request, "triggerPrice", this.GetPrice(symbol, triggerPrice))
|
|
} else if IsTrue(IsTrue((IsTrue(isStopLossTriggerOrder) || IsTrue(isTakeProfitTriggerOrder))) && !IsTrue(isAlternativeEndpoint)) {
|
|
if IsTrue(isBuy) {
|
|
AddElementToObject(request, "triggerDirection", Ternary(IsTrue(isStopLossTriggerOrder), 1, 2))
|
|
} else {
|
|
AddElementToObject(request, "triggerDirection", Ternary(IsTrue(isStopLossTriggerOrder), 2, 1))
|
|
}
|
|
triggerPrice = Ternary(IsTrue(isStopLossTriggerOrder), stopLossTriggerPrice, takeProfitTriggerPrice)
|
|
AddElementToObject(request, "triggerPrice", this.GetPrice(symbol, triggerPrice))
|
|
AddElementToObject(request, "reduceOnly", true)
|
|
}
|
|
if IsTrue(IsTrue((IsTrue(isStopLoss) || IsTrue(isTakeProfit))) && !IsTrue(isAlternativeEndpoint)) {
|
|
if IsTrue(isStopLoss) {
|
|
var slTriggerPrice interface{} = this.SafeValue2(stopLoss, "triggerPrice", "stopPrice", stopLoss)
|
|
AddElementToObject(request, "stopLoss", this.GetPrice(symbol, slTriggerPrice))
|
|
var slLimitPrice interface{} = this.SafeValue(stopLoss, "price")
|
|
if IsTrue(!IsEqual(slLimitPrice, nil)) {
|
|
AddElementToObject(request, "tpslMode", "Partial")
|
|
AddElementToObject(request, "slOrderType", "Limit")
|
|
AddElementToObject(request, "slLimitPrice", this.GetPrice(symbol, slLimitPrice))
|
|
}
|
|
}
|
|
if IsTrue(isTakeProfit) {
|
|
var tpTriggerPrice interface{} = this.SafeValue2(takeProfit, "triggerPrice", "stopPrice", takeProfit)
|
|
AddElementToObject(request, "takeProfit", this.GetPrice(symbol, tpTriggerPrice))
|
|
var tpLimitPrice interface{} = this.SafeValue(takeProfit, "price")
|
|
if IsTrue(!IsEqual(tpLimitPrice, nil)) {
|
|
AddElementToObject(request, "tpslMode", "Partial")
|
|
AddElementToObject(request, "tpOrderType", "Limit")
|
|
AddElementToObject(request, "tpLimitPrice", this.GetPrice(symbol, tpLimitPrice))
|
|
}
|
|
}
|
|
}
|
|
if IsTrue(!IsTrue(GetValue(market, "spot")) && IsTrue(hedged)) {
|
|
if IsTrue(reduceOnly) {
|
|
params = this.Omit(params, "reduceOnly")
|
|
side = Ternary(IsTrue((IsEqual(side, "buy"))), "sell", "buy")
|
|
}
|
|
AddElementToObject(request, "positionIdx", Ternary(IsTrue((IsEqual(side, "buy"))), 1, 2))
|
|
}
|
|
params = this.Omit(params, []interface{}{"stopPrice", "timeInForce", "stopLossPrice", "takeProfitPrice", "postOnly", "clientOrderId", "triggerPrice", "stopLoss", "takeProfit", "trailingAmount", "trailingTriggerPrice", "hedged"})
|
|
return this.Extend(request, params)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#createOrders
|
|
* @description create a list of trade orders
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/batch-place
|
|
* @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 *bybit) 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
|
|
|
|
retRes41788 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes41788)
|
|
|
|
accounts:= (<-this.IsUnifiedEnabled())
|
|
PanicOnError(accounts)
|
|
var isUta interface{} = GetValue(accounts, 1)
|
|
var ordersRequests interface{} = []interface{}{}
|
|
var orderSymbols interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ {
|
|
var rawOrder interface{} = GetValue(orders, i)
|
|
var marketId interface{} = this.SafeString(rawOrder, "symbol")
|
|
AppendToArray(&orderSymbols,marketId)
|
|
var typeVar interface{} = this.SafeString(rawOrder, "type")
|
|
var side interface{} = this.SafeString(rawOrder, "side")
|
|
var amount interface{} = this.SafeValue(rawOrder, "amount")
|
|
var price interface{} = this.SafeValue(rawOrder, "price")
|
|
var orderParams interface{} = this.SafeDict(rawOrder, "params", map[string]interface{} {})
|
|
var orderRequest interface{} = this.CreateOrderRequest(marketId, typeVar, side, amount, price, orderParams, isUta)
|
|
Remove(orderRequest, "category")
|
|
AppendToArray(&ordersRequests,orderRequest)
|
|
}
|
|
var symbols interface{} = this.MarketSymbols(orderSymbols, nil, false, true, true)
|
|
var market interface{} = this.Market(GetValue(symbols, 0))
|
|
var unifiedMarginStatus interface{} = this.SafeInteger(this.Options, "unifiedMarginStatus", 6)
|
|
var category interface{} = nil
|
|
categoryparamsVariable := this.GetBybitType("createOrders", market, params);
|
|
category = GetValue(categoryparamsVariable,0);
|
|
params = GetValue(categoryparamsVariable,1)
|
|
if IsTrue(IsTrue((IsEqual(category, "inverse"))) && IsTrue((IsLessThan(unifiedMarginStatus, 5)))) {
|
|
panic(NotSupported(Add(this.Id, " createOrders does not allow inverse orders for non UTA2.0 account")))
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"category": category,
|
|
"request": ordersRequests,
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5OrderCreateBatch(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var data interface{} = this.SafeList(result, "list", []interface{}{})
|
|
var retInfo interface{} = this.SafeDict(response, "retExtInfo", map[string]interface{} {})
|
|
var codes interface{} = this.SafeList(retInfo, "list", []interface{}{})
|
|
// extend the error with the unsuccessful orders
|
|
for i := 0; IsLessThan(i, GetArrayLength(codes)); i++ {
|
|
var code interface{} = GetValue(codes, i)
|
|
var retCode interface{} = this.SafeInteger(code, "code")
|
|
if IsTrue(!IsEqual(retCode, 0)) {
|
|
AddElementToObject(data, i, this.Extend(GetValue(data, i), code))
|
|
}
|
|
}
|
|
|
|
//
|
|
// {
|
|
// "retCode":0,
|
|
// "retMsg":"OK",
|
|
// "result":{
|
|
// "list":[
|
|
// {
|
|
// "category":"linear",
|
|
// "symbol":"LTCUSDT",
|
|
// "orderId":"",
|
|
// "orderLinkId":"",
|
|
// "createAt":""
|
|
// },
|
|
// {
|
|
// "category":"linear",
|
|
// "symbol":"LTCUSDT",
|
|
// "orderId":"3c9f65b6-01ad-4ac0-9741-df17e02a4223",
|
|
// "orderLinkId":"",
|
|
// "createAt":"1698075516029"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo":{
|
|
// "list":[
|
|
// {
|
|
// "code":10001,
|
|
// "msg":"The number of contracts exceeds maximum limit allowed: too large"
|
|
// },
|
|
// {
|
|
// "code":0,
|
|
// "msg":"OK"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "time":1698075516029
|
|
// }
|
|
//
|
|
ch <- this.ParseOrders(data)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) EditOrderRequest(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) interface{} {
|
|
amount := GetArg(optionalArgs, 0, nil)
|
|
_ = amount
|
|
price := GetArg(optionalArgs, 1, nil)
|
|
_ = price
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
"orderId": id,
|
|
}
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
AddElementToObject(request, "category", "spot")
|
|
} else if IsTrue(GetValue(market, "linear")) {
|
|
AddElementToObject(request, "category", "linear")
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
AddElementToObject(request, "category", "inverse")
|
|
} else if IsTrue(GetValue(market, "option")) {
|
|
AddElementToObject(request, "category", "option")
|
|
}
|
|
if IsTrue(!IsEqual(amount, nil)) {
|
|
AddElementToObject(request, "qty", this.GetAmount(symbol, amount))
|
|
}
|
|
if IsTrue(!IsEqual(price, nil)) {
|
|
AddElementToObject(request, "price", this.GetPrice(symbol, this.NumberToString(price)))
|
|
}
|
|
var triggerPrice interface{} = this.SafeString2(params, "triggerPrice", "stopPrice")
|
|
var stopLossTriggerPrice interface{} = this.SafeString(params, "stopLossPrice")
|
|
var takeProfitTriggerPrice interface{} = this.SafeString(params, "takeProfitPrice")
|
|
var stopLoss interface{} = this.SafeValue(params, "stopLoss")
|
|
var takeProfit interface{} = this.SafeValue(params, "takeProfit")
|
|
var isStopLossTriggerOrder interface{} = !IsEqual(stopLossTriggerPrice, nil)
|
|
var isTakeProfitTriggerOrder interface{} = !IsEqual(takeProfitTriggerPrice, nil)
|
|
var isStopLoss interface{} = !IsEqual(stopLoss, nil)
|
|
var isTakeProfit interface{} = !IsEqual(takeProfit, nil)
|
|
if IsTrue(IsTrue(isStopLossTriggerOrder) || IsTrue(isTakeProfitTriggerOrder)) {
|
|
triggerPrice = Ternary(IsTrue(isStopLossTriggerOrder), stopLossTriggerPrice, takeProfitTriggerPrice)
|
|
}
|
|
if IsTrue(!IsEqual(triggerPrice, nil)) {
|
|
var triggerPriceRequest interface{} = Ternary(IsTrue((IsEqual(triggerPrice, "0"))), triggerPrice, this.GetPrice(symbol, triggerPrice))
|
|
AddElementToObject(request, "triggerPrice", triggerPriceRequest)
|
|
var triggerBy interface{} = this.SafeString(params, "triggerBy", "LastPrice")
|
|
AddElementToObject(request, "triggerBy", triggerBy)
|
|
}
|
|
if IsTrue(IsTrue(isStopLoss) || IsTrue(isTakeProfit)) {
|
|
if IsTrue(isStopLoss) {
|
|
var slTriggerPrice interface{} = this.SafeString2(stopLoss, "triggerPrice", "stopPrice", stopLoss)
|
|
var stopLossRequest interface{} = Ternary(IsTrue((IsEqual(slTriggerPrice, "0"))), slTriggerPrice, this.GetPrice(symbol, slTriggerPrice))
|
|
AddElementToObject(request, "stopLoss", stopLossRequest)
|
|
var slTriggerBy interface{} = this.SafeString(params, "slTriggerBy", "LastPrice")
|
|
AddElementToObject(request, "slTriggerBy", slTriggerBy)
|
|
}
|
|
if IsTrue(isTakeProfit) {
|
|
var tpTriggerPrice interface{} = this.SafeString2(takeProfit, "triggerPrice", "stopPrice", takeProfit)
|
|
var takeProfitRequest interface{} = Ternary(IsTrue((IsEqual(tpTriggerPrice, "0"))), tpTriggerPrice, this.GetPrice(symbol, tpTriggerPrice))
|
|
AddElementToObject(request, "takeProfit", takeProfitRequest)
|
|
var tpTriggerBy interface{} = this.SafeString(params, "tpTriggerBy", "LastPrice")
|
|
AddElementToObject(request, "tpTriggerBy", tpTriggerBy)
|
|
}
|
|
}
|
|
var clientOrderId interface{} = this.SafeString(params, "clientOrderId")
|
|
if IsTrue(!IsEqual(clientOrderId, nil)) {
|
|
AddElementToObject(request, "orderLinkId", clientOrderId)
|
|
}
|
|
params = this.Omit(params, []interface{}{"stopPrice", "stopLossPrice", "takeProfitPrice", "triggerPrice", "clientOrderId", "stopLoss", "takeProfit"})
|
|
return request
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#editOrder
|
|
* @description edit a trade order
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/amend-order
|
|
* @see https://bybit-exchange.github.io/docs/derivatives/unified/replace-order
|
|
* @see https://bybit-exchange.github.io/docs/api-explorer/derivatives/trade/contract/replace-order
|
|
* @param {string} id cancel order id
|
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
* @param {string} type 'market' or 'limit'
|
|
* @param {string} side 'buy' or 'sell'
|
|
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
* @param {float} price the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {float} [params.triggerPrice] The price that a trigger order is triggered at
|
|
* @param {float} [params.stopLossPrice] The price that a stop loss order is triggered at
|
|
* @param {float} [params.takeProfitPrice] The price that a take profit order is triggered at
|
|
* @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice that the attached take profit order will be triggered
|
|
* @param {float} [params.takeProfit.triggerPrice] take profit trigger price
|
|
* @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice that the attached stop loss order will be triggered
|
|
* @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
|
|
* @param {string} [params.triggerBy] 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for triggerPrice
|
|
* @param {string} [params.slTriggerBy] 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for stopLoss
|
|
* @param {string} [params.tpTriggerby] 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for takeProfit
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) EditOrder(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
amount := GetArg(optionalArgs, 0, nil)
|
|
_ = amount
|
|
price := GetArg(optionalArgs, 1, nil)
|
|
_ = price
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes43608 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes43608)
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " editOrder() requires a symbol argument")))
|
|
}
|
|
var request interface{} = this.EditOrderRequest(id, symbol, typeVar, side, amount, price, params)
|
|
|
|
response:= (<-this.PrivatePostV5OrderAmend(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "orderId": "c6f055d9-7f21-4079-913d-e6523a9cfffa",
|
|
// "orderLinkId": "linear-004"
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672217093461
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
|
|
ch <- this.SafeOrder(map[string]interface{} {
|
|
"info": response,
|
|
"id": this.SafeString(result, "orderId"),
|
|
})
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#editOrders
|
|
* @description edit a list of trade orders
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/batch-amend
|
|
* @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 *bybit) EditOrders(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
|
|
|
|
retRes43958 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes43958)
|
|
var ordersRequests interface{} = []interface{}{}
|
|
var orderSymbols interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ {
|
|
var rawOrder interface{} = GetValue(orders, i)
|
|
var symbol interface{} = this.SafeString(rawOrder, "symbol")
|
|
AppendToArray(&orderSymbols,symbol)
|
|
var id interface{} = this.SafeString(rawOrder, "id")
|
|
var typeVar interface{} = this.SafeString(rawOrder, "type")
|
|
var side interface{} = this.SafeString(rawOrder, "side")
|
|
var amount interface{} = this.SafeValue(rawOrder, "amount")
|
|
var price interface{} = this.SafeValue(rawOrder, "price")
|
|
var orderParams interface{} = this.SafeDict(rawOrder, "params", map[string]interface{} {})
|
|
var orderRequest interface{} = this.EditOrderRequest(id, symbol, typeVar, side, amount, price, orderParams)
|
|
Remove(orderRequest, "category")
|
|
AppendToArray(&ordersRequests,orderRequest)
|
|
}
|
|
orderSymbols = this.MarketSymbols(orderSymbols, nil, false, true, true)
|
|
var market interface{} = this.Market(GetValue(orderSymbols, 0))
|
|
var unifiedMarginStatus interface{} = this.SafeInteger(this.Options, "unifiedMarginStatus", 6)
|
|
var category interface{} = nil
|
|
categoryparamsVariable := this.GetBybitType("editOrders", market, params);
|
|
category = GetValue(categoryparamsVariable,0);
|
|
params = GetValue(categoryparamsVariable,1)
|
|
if IsTrue(IsTrue((IsEqual(category, "inverse"))) && IsTrue((IsLessThan(unifiedMarginStatus, 5)))) {
|
|
panic(NotSupported(Add(this.Id, " editOrders does not allow inverse orders for non UTA2.0 account")))
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"category": category,
|
|
"request": ordersRequests,
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5OrderAmendBatch(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var data interface{} = this.SafeList(result, "list", []interface{}{})
|
|
var retInfo interface{} = this.SafeDict(response, "retExtInfo", map[string]interface{} {})
|
|
var codes interface{} = this.SafeList(retInfo, "list", []interface{}{})
|
|
// extend the error with the unsuccessful orders
|
|
for i := 0; IsLessThan(i, GetArrayLength(codes)); i++ {
|
|
var code interface{} = GetValue(codes, i)
|
|
var retCode interface{} = this.SafeInteger(code, "code")
|
|
if IsTrue(!IsEqual(retCode, 0)) {
|
|
AddElementToObject(data, i, this.Extend(GetValue(data, i), code))
|
|
}
|
|
}
|
|
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "category": "option",
|
|
// "symbol": "ETH-30DEC22-500-C",
|
|
// "orderId": "b551f227-7059-4fb5-a6a6-699c04dbd2f2",
|
|
// "orderLinkId": ""
|
|
// },
|
|
// {
|
|
// "category": "option",
|
|
// "symbol": "ETH-30DEC22-700-C",
|
|
// "orderId": "fa6a595f-1a57-483f-b9d3-30e9c8235a52",
|
|
// "orderLinkId": ""
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {
|
|
// "list": [
|
|
// {
|
|
// "code": 0,
|
|
// "msg": "OK"
|
|
// },
|
|
// {
|
|
// "code": 0,
|
|
// "msg": "OK"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "time": 1672222808060
|
|
// }
|
|
//
|
|
ch <- this.ParseOrders(data)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) CancelOrderRequest(id interface{}, optionalArgs ...interface{}) interface{} {
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
// only works for spot market
|
|
var isTrigger interface{} = this.SafeBool2(params, "stop", "trigger", false)
|
|
params = this.Omit(params, []interface{}{"stop", "trigger"})
|
|
AddElementToObject(request, "orderFilter", Ternary(IsTrue(isTrigger), "StopOrder", "Order"))
|
|
}
|
|
if IsTrue(!IsEqual(id, nil)) {
|
|
AddElementToObject(request, "orderId", id)
|
|
}
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
AddElementToObject(request, "category", "spot")
|
|
} else if IsTrue(GetValue(market, "linear")) {
|
|
AddElementToObject(request, "category", "linear")
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
AddElementToObject(request, "category", "inverse")
|
|
} else if IsTrue(GetValue(market, "option")) {
|
|
AddElementToObject(request, "category", "option")
|
|
}
|
|
return this.Extend(request, params)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#cancelOrder
|
|
* @description cancels an open order
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/cancel-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] *spot only* whether the order is a trigger order
|
|
* @param {boolean} [params.stop] alias for trigger
|
|
* @param {string} [params.orderFilter] *spot only* 'Order' or 'StopOrder' or 'tpslOrder'
|
|
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) CancelOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " cancelOrder() requires a symbol argument")))
|
|
}
|
|
|
|
retRes45228 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes45228)
|
|
var market interface{} = this.Market(symbol)
|
|
var requestExtended interface{} = this.CancelOrderRequest(id, symbol, params)
|
|
|
|
response:= (<-this.PrivatePostV5OrderCancel(requestExtended))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "orderId": "c6f055d9-7f21-4079-913d-e6523a9cfffa",
|
|
// "orderLinkId": "linear-004"
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672217377164
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
|
|
ch <- this.ParseOrder(result, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#cancelOrders
|
|
* @description cancel multiple orders
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/batch-cancel
|
|
* @param {string[]} ids order ids
|
|
* @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 {string[]} [params.clientOrderIds] client order ids
|
|
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " cancelOrders() requires a symbol argument")))
|
|
}
|
|
|
|
retRes45578 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes45578)
|
|
var market interface{} = this.Market(symbol)
|
|
|
|
types:= (<-this.IsUnifiedEnabled())
|
|
PanicOnError(types)
|
|
var enableUnifiedAccount interface{} = GetValue(types, 1)
|
|
if !IsTrue(enableUnifiedAccount) {
|
|
panic(NotSupported(Add(this.Id, " cancelOrders() supports UTA accounts only")))
|
|
}
|
|
var category interface{} = nil
|
|
categoryparamsVariable := this.GetBybitType("cancelOrders", market, params);
|
|
category = GetValue(categoryparamsVariable,0);
|
|
params = GetValue(categoryparamsVariable,1)
|
|
if IsTrue(IsEqual(category, "inverse")) {
|
|
panic(NotSupported(Add(this.Id, " cancelOrders does not allow inverse orders")))
|
|
}
|
|
var ordersRequests interface{} = []interface{}{}
|
|
var clientOrderIds interface{} = this.SafeList2(params, "clientOrderIds", "clientOids", []interface{}{})
|
|
params = this.Omit(params, []interface{}{"clientOrderIds", "clientOids"})
|
|
for i := 0; IsLessThan(i, GetArrayLength(clientOrderIds)); i++ {
|
|
AppendToArray(&ordersRequests,map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
"orderLinkId": this.SafeString(clientOrderIds, i),
|
|
})
|
|
}
|
|
for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ {
|
|
AppendToArray(&ordersRequests,map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
"orderId": this.SafeString(ids, i),
|
|
})
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"category": category,
|
|
"request": ordersRequests,
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5OrderCancelBatch(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": "0",
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "category": "spot",
|
|
// "symbol": "BTCUSDT",
|
|
// "orderId": "1636282505818800896",
|
|
// "orderLinkId": "1636282505818800897"
|
|
// },
|
|
// {
|
|
// "category": "spot",
|
|
// "symbol": "BTCUSDT",
|
|
// "orderId": "1636282505818800898",
|
|
// "orderLinkId": "1636282505818800899"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {
|
|
// "list": [
|
|
// {
|
|
// "code": "0",
|
|
// "msg": "OK"
|
|
// },
|
|
// {
|
|
// "code": "0",
|
|
// "msg": "OK"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "time": "1709796158501"
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var row interface{} = this.SafeList(result, "list", []interface{}{})
|
|
|
|
ch <- this.ParseOrders(row, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#cancelAllOrdersAfter
|
|
* @description dead man's switch, cancel all orders after the given timeout
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/dcp
|
|
* @param {number} timeout time in milliseconds
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.product] OPTIONS, DERIVATIVES, SPOT, default is 'DERIVATIVES'
|
|
* @returns {object} the api result
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes46408 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes46408)
|
|
var request interface{} = map[string]interface{} {
|
|
"timeWindow": this.ParseToInt(Divide(timeout, 1000)),
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.HandleMarketTypeAndParams("cancelAllOrdersAfter", nil, params, "swap");
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
var productMap interface{} = map[string]interface{} {
|
|
"spot": "SPOT",
|
|
"swap": "DERIVATIVES",
|
|
"option": "OPTIONS",
|
|
}
|
|
var product interface{} = this.SafeString(productMap, typeVar, typeVar)
|
|
AddElementToObject(request, "product", product)
|
|
|
|
response:= (<-this.PrivatePostV5OrderDisconnectedCancelAll(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success"
|
|
// }
|
|
//
|
|
ch <- response
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#cancelOrdersForSymbols
|
|
* @description cancel multiple orders for multiple symbols
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/batch-cancel
|
|
* @param {CancellationRequest[]} orders list of order ids with symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}]
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) CancelOrdersForSymbols(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
|
|
|
|
retRes46738 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes46738)
|
|
|
|
types:= (<-this.IsUnifiedEnabled())
|
|
PanicOnError(types)
|
|
var enableUnifiedAccount interface{} = GetValue(types, 1)
|
|
if !IsTrue(enableUnifiedAccount) {
|
|
panic(NotSupported(Add(this.Id, " cancelOrdersForSymbols() supports UTA accounts only")))
|
|
}
|
|
var ordersRequests interface{} = []interface{}{}
|
|
var category interface{} = nil
|
|
for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ {
|
|
var order interface{} = GetValue(orders, i)
|
|
var symbol interface{} = this.SafeString(order, "symbol")
|
|
var market interface{} = this.Market(symbol)
|
|
var currentCategory interface{} = nil
|
|
currentCategoryparamsVariable := this.GetBybitType("cancelOrders", market, params);
|
|
currentCategory = GetValue(currentCategoryparamsVariable,0);
|
|
params = GetValue(currentCategoryparamsVariable,1)
|
|
if IsTrue(IsEqual(currentCategory, "inverse")) {
|
|
panic(NotSupported(Add(this.Id, " cancelOrdersForSymbols does not allow inverse orders")))
|
|
}
|
|
if IsTrue(IsTrue((!IsEqual(category, nil))) && IsTrue((!IsEqual(category, currentCategory)))) {
|
|
panic(ExchangeError(Add(this.Id, " cancelOrdersForSymbols requires all orders to be of the same category (linear, spot or option))")))
|
|
}
|
|
category = currentCategory
|
|
var id interface{} = this.SafeString(order, "id")
|
|
var clientOrderId interface{} = this.SafeString(order, "clientOrderId")
|
|
var idKey interface{} = "orderId"
|
|
if IsTrue(!IsEqual(clientOrderId, nil)) {
|
|
idKey = "orderLinkId"
|
|
}
|
|
var orderItem interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
AddElementToObject(orderItem, idKey, Ternary(IsTrue((IsEqual(idKey, "orderId"))), id, clientOrderId))
|
|
AppendToArray(&ordersRequests,orderItem)
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"category": category,
|
|
"request": ordersRequests,
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5OrderCancelBatch(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": "0",
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "category": "spot",
|
|
// "symbol": "BTCUSDT",
|
|
// "orderId": "1636282505818800896",
|
|
// "orderLinkId": "1636282505818800897"
|
|
// },
|
|
// {
|
|
// "category": "spot",
|
|
// "symbol": "BTCUSDT",
|
|
// "orderId": "1636282505818800898",
|
|
// "orderLinkId": "1636282505818800899"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {
|
|
// "list": [
|
|
// {
|
|
// "code": "0",
|
|
// "msg": "OK"
|
|
// },
|
|
// {
|
|
// "code": "0",
|
|
// "msg": "OK"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "time": "1709796158501"
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var row interface{} = this.SafeList(result, "list", []interface{}{})
|
|
|
|
ch <- this.ParseOrders(row, nil)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#cancelAllOrders
|
|
* @description cancel all open orders
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/cancel-all
|
|
* @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] true if trigger order
|
|
* @param {boolean} [params.stop] alias for trigger
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @param {string} [params.baseCoin] Base coin. Supports linear, inverse & option
|
|
* @param {string} [params.settleCoin] Settle coin. Supports linear, inverse & option
|
|
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes47678 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes47678)
|
|
enableUnifiedMarginenableUnifiedAccountVariable := (<-this.IsUnifiedEnabled());
|
|
enableUnifiedMargin := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,0);
|
|
enableUnifiedAccount := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,1)
|
|
var isUnifiedAccount interface{} = (IsTrue(enableUnifiedMargin) || IsTrue(enableUnifiedAccount))
|
|
var market interface{} = nil
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("cancelAllOrders", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
AddElementToObject(request, "category", typeVar)
|
|
if IsTrue(IsTrue((IsEqual(typeVar, "option"))) && !IsTrue(isUnifiedAccount)) {
|
|
panic(NotSupported(Add(Add(Add(this.Id, " cancelAllOrders() Normal Account not support "), typeVar), " market")))
|
|
}
|
|
if IsTrue(IsTrue((IsEqual(typeVar, "linear"))) || IsTrue((IsEqual(typeVar, "inverse")))) {
|
|
var baseCoin interface{} = this.SafeString(params, "baseCoin")
|
|
if IsTrue(IsTrue(IsEqual(symbol, nil)) && IsTrue(IsEqual(baseCoin, nil))) {
|
|
var defaultSettle interface{} = this.SafeString(this.Options, "defaultSettle", "USDT")
|
|
AddElementToObject(request, "settleCoin", this.SafeString(params, "settleCoin", defaultSettle))
|
|
}
|
|
}
|
|
var isTrigger interface{} = this.SafeBool2(params, "stop", "trigger", false)
|
|
params = this.Omit(params, []interface{}{"stop", "trigger"})
|
|
if IsTrue(isTrigger) {
|
|
AddElementToObject(request, "orderFilter", "StopOrder")
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5OrderCancelAll(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// linear / inverse / option
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "orderId": "f6a73e1f-39b5-4dee-af21-1460b2e3b27c",
|
|
// "orderLinkId": "a001"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672219780463
|
|
// }
|
|
//
|
|
// spot
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "success": "1"
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1676962409398
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var orders interface{} = this.SafeList(result, "list")
|
|
if !IsTrue(IsArray(orders)) {
|
|
|
|
ch <- response
|
|
return nil
|
|
}
|
|
|
|
ch <- this.ParseOrders(orders, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOrderClassic
|
|
* @description fetches information on an order made by the user *classic accounts only*
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/order-list
|
|
* @param {string} id the 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 *bybit) FetchOrderClassic(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOrder() requires a symbol argument")))
|
|
}
|
|
|
|
retRes48458 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes48458)
|
|
var market interface{} = this.Market(symbol)
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
panic(NotSupported(Add(this.Id, " fetchOrder() is not supported for spot markets")))
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"orderId": id,
|
|
}
|
|
|
|
result:= (<-this.FetchOrders(symbol, nil, nil, this.Extend(request, params)))
|
|
PanicOnError(result)
|
|
var length interface{} = GetArrayLength(result)
|
|
if IsTrue(IsEqual(length, 0)) {
|
|
var isTrigger interface{} = this.SafeBoolN(params, []interface{}{"trigger", "stop"}, false)
|
|
var extra interface{} = Ternary(IsTrue(isTrigger), "", " If you are trying to fetch SL/TP conditional order, you might try setting params[\"trigger\"] = true")
|
|
panic(OrderNotFound(Add(Add(Add("Order ", ToString(id)), " was not found."), extra)))
|
|
}
|
|
if IsTrue(IsGreaterThan(length, 1)) {
|
|
panic(InvalidOrder(Add(this.Id, " returned more than one order")))
|
|
}
|
|
|
|
ch <- this.SafeValue(result, 0)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOrder
|
|
* @description *classic accounts only/ spot not supported* fetches information on an order made by the user *classic accounts only*
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/order-list
|
|
* @param {string} id the 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 {object} [params.acknowledged] to suppress the warning, set to true
|
|
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes48788 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes48788)
|
|
enableUnifiedMarginenableUnifiedAccountVariable := (<-this.IsUnifiedEnabled());
|
|
enableUnifiedMargin := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,0);
|
|
enableUnifiedAccount := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,1)
|
|
var isUnifiedAccount interface{} = (IsTrue(enableUnifiedMargin) || IsTrue(enableUnifiedAccount))
|
|
if !IsTrue(isUnifiedAccount) {
|
|
|
|
retRes488219 := (<-this.FetchOrderClassic(id, symbol, params))
|
|
PanicOnError(retRes488219)
|
|
ch <- retRes488219
|
|
return nil
|
|
}
|
|
var acknowledge interface{} = false
|
|
acknowledgeparamsVariable := this.HandleOptionAndParams(params, "fetchOrder", "acknowledged");
|
|
acknowledge = GetValue(acknowledgeparamsVariable,0);
|
|
params = GetValue(acknowledgeparamsVariable,1)
|
|
if !IsTrue(acknowledge) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOrder() can only access an order if it is in last 500 orders (of any status) for your account. Set params[\"acknowledged\"] = true to hide this warning. Alternatively, we suggest to use fetchOpenOrder or fetchClosedOrder")))
|
|
}
|
|
var market interface{} = this.Market(symbol)
|
|
var marketType interface{} = nil
|
|
marketTypeparamsVariable := this.GetBybitType("fetchOrder", market, params);
|
|
marketType = GetValue(marketTypeparamsVariable,0);
|
|
params = GetValue(marketTypeparamsVariable,1)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
"orderId": id,
|
|
"category": marketType,
|
|
}
|
|
var isTrigger interface{} = nil
|
|
isTriggerparamsVariable := this.HandleParamBool2(params, "trigger", "stop", false);
|
|
isTrigger = GetValue(isTriggerparamsVariable,0);
|
|
params = GetValue(isTriggerparamsVariable,1)
|
|
if IsTrue(isTrigger) {
|
|
AddElementToObject(request, "orderFilter", "StopOrder")
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5OrderRealtime(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "nextPageCursor": "1321052653536515584%3A1672217748287%2C1321052653536515584%3A1672217748287",
|
|
// "category": "spot",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "ETHUSDT",
|
|
// "orderType": "Limit",
|
|
// "orderLinkId": "1672217748277652",
|
|
// "orderId": "1321052653536515584",
|
|
// "cancelType": "UNKNOWN",
|
|
// "avgPrice": "",
|
|
// "stopOrderType": "tpslOrder",
|
|
// "lastPriceOnCreated": "",
|
|
// "orderStatus": "Cancelled",
|
|
// "takeProfit": "",
|
|
// "cumExecValue": "0",
|
|
// "triggerDirection": 0,
|
|
// "isLeverage": "0",
|
|
// "rejectReason": "",
|
|
// "price": "1000",
|
|
// "orderIv": "",
|
|
// "createdTime": "1672217748287",
|
|
// "tpTriggerBy": "",
|
|
// "positionIdx": 0,
|
|
// "timeInForce": "GTC",
|
|
// "leavesValue": "500",
|
|
// "updatedTime": "1672217748287",
|
|
// "side": "Buy",
|
|
// "triggerPrice": "1500",
|
|
// "cumExecFee": "0",
|
|
// "leavesQty": "0",
|
|
// "slTriggerBy": "",
|
|
// "closeOnTrigger": false,
|
|
// "cumExecQty": "0",
|
|
// "reduceOnly": false,
|
|
// "qty": "0.5",
|
|
// "stopLoss": "",
|
|
// "triggerBy": "1192.5"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672219526294
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var innerList interface{} = this.SafeList(result, "list", []interface{}{})
|
|
if IsTrue(IsEqual(GetArrayLength(innerList), 0)) {
|
|
var extra interface{} = Ternary(IsTrue(isTrigger), "", " If you are trying to fetch SL/TP conditional order, you might try setting params[\"trigger\"] = true")
|
|
panic(OrderNotFound(Add(Add(Add("Order ", ToString(id)), " was not found."), extra)))
|
|
}
|
|
var order interface{} = this.SafeDict(innerList, 0, map[string]interface{} {})
|
|
|
|
ch <- this.ParseOrder(order, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) 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
|
|
|
|
res:= (<-this.IsUnifiedEnabled())
|
|
PanicOnError(res)
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOrders
|
|
* @description *classic accounts only/ spot not supported* fetches information on multiple orders made by the user *classic accounts only/ spot not supported*
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/order-list
|
|
* @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 {boolean} [params.trigger] true if trigger order
|
|
* @param {boolean} [params.stop] alias for trigger
|
|
* @param {string} [params.type] market type, ['swap', 'option']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @param {string} [params.orderFilter] 'Order' or 'StopOrder' or 'tpslOrder'
|
|
* @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}
|
|
*/
|
|
var enableUnifiedAccount interface{} = this.SafeBool(res, 1)
|
|
if IsTrue(enableUnifiedAccount) {
|
|
panic(NotSupported(Add(this.Id, " fetchOrders() is not supported after the 5/02 update for UTA accounts, please use fetchOpenOrders, fetchClosedOrders or fetchCanceledOrders")))
|
|
}
|
|
|
|
retRes498615 := (<-this.FetchOrdersClassic(symbol, since, limit, params))
|
|
PanicOnError(retRes498615)
|
|
ch <- retRes498615
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOrdersClassic
|
|
* @description fetches information on multiple orders made by the user *classic accounts only*
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/order-list
|
|
* @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 {boolean} [params.trigger] true if trigger order
|
|
* @param {boolean} [params.stop] alias for trigger
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @param {string} [params.orderFilter] 'Order' or 'StopOrder' or 'tpslOrder'
|
|
* @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 *bybit) FetchOrdersClassic(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
|
|
|
|
retRes50088 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes50088)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOrders", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes501219 := (<-this.FetchPaginatedCallCursor("fetchOrders", symbol, since, limit, params, "nextPageCursor", "cursor", nil, 50))
|
|
PanicOnError(retRes501219)
|
|
ch <- retRes501219
|
|
return nil
|
|
}
|
|
var request interface{} = map[string]interface{} {}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchOrders", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
if IsTrue(IsEqual(typeVar, "spot")) {
|
|
panic(NotSupported(Add(this.Id, " fetchOrders() is not supported for spot markets")))
|
|
}
|
|
AddElementToObject(request, "category", typeVar)
|
|
var isTrigger interface{} = this.SafeBoolN(params, []interface{}{"trigger", "stop"}, false)
|
|
params = this.Omit(params, []interface{}{"trigger", "stop"})
|
|
if IsTrue(isTrigger) {
|
|
AddElementToObject(request, "orderFilter", "StopOrder")
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
var until interface{} = this.SafeInteger(params, "until") // unified in milliseconds
|
|
var endTime interface{} = this.SafeInteger(params, "endTime", until) // exchange-specific in milliseconds
|
|
params = this.Omit(params, []interface{}{"endTime", "until"})
|
|
if IsTrue(!IsEqual(endTime, nil)) {
|
|
AddElementToObject(request, "endTime", endTime)
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5OrderHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "nextPageCursor": "03234de9-1332-41eb-b805-4a9f42c136a3%3A1672220109387%2C03234de9-1332-41eb-b805-4a9f42c136a3%3A1672220109387",
|
|
// "category": "linear",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTCUSDT",
|
|
// "orderType": "Limit",
|
|
// "orderLinkId": "test-001",
|
|
// "orderId": "03234de9-1332-41eb-b805-4a9f42c136a3",
|
|
// "cancelType": "CancelByUser",
|
|
// "avgPrice": "0",
|
|
// "stopOrderType": "UNKNOWN",
|
|
// "lastPriceOnCreated": "16656.5",
|
|
// "orderStatus": "Cancelled",
|
|
// "takeProfit": "",
|
|
// "cumExecValue": "0",
|
|
// "triggerDirection": 0,
|
|
// "blockTradeId": "",
|
|
// "rejectReason": "EC_PerCancelRequest",
|
|
// "isLeverage": "",
|
|
// "price": "18000",
|
|
// "orderIv": "",
|
|
// "createdTime": "1672220109387",
|
|
// "tpTriggerBy": "UNKNOWN",
|
|
// "positionIdx": 0,
|
|
// "timeInForce": "GoodTillCancel",
|
|
// "leavesValue": "0",
|
|
// "updatedTime": "1672220114123",
|
|
// "side": "Sell",
|
|
// "triggerPrice": "",
|
|
// "cumExecFee": "0",
|
|
// "slTriggerBy": "UNKNOWN",
|
|
// "leavesQty": "0",
|
|
// "closeOnTrigger": false,
|
|
// "cumExecQty": "0",
|
|
// "reduceOnly": false,
|
|
// "qty": "0.1",
|
|
// "stopLoss": "",
|
|
// "triggerBy": "UNKNOWN"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672221263862
|
|
// }
|
|
//
|
|
var data interface{} = this.AddPaginationCursorToResult(response)
|
|
|
|
ch <- this.ParseOrders(data, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchClosedOrder
|
|
* @description fetches information on a closed order made by the user
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/order-list
|
|
* @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] set to true for fetching a closed trigger order
|
|
* @param {boolean} [params.stop] alias for trigger
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @param {string} [params.orderFilter] 'Order' or 'StopOrder' or 'tpslOrder'
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) FetchClosedOrder(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
|
|
|
|
retRes51148 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes51148)
|
|
var request interface{} = map[string]interface{} {
|
|
"orderId": id,
|
|
}
|
|
|
|
result:= (<-this.FetchClosedOrders(symbol, nil, nil, this.Extend(request, params)))
|
|
PanicOnError(result)
|
|
var length interface{} = GetArrayLength(result)
|
|
if IsTrue(IsEqual(length, 0)) {
|
|
var isTrigger interface{} = this.SafeBoolN(params, []interface{}{"trigger", "stop"}, false)
|
|
var extra interface{} = Ternary(IsTrue(isTrigger), "", " If you are trying to fetch SL/TP conditional order, you might try setting params[\"trigger\"] = true")
|
|
panic(OrderNotFound(Add(Add(Add("Order ", ToString(id)), " was not found."), extra)))
|
|
}
|
|
if IsTrue(IsGreaterThan(length, 1)) {
|
|
panic(InvalidOrder(Add(this.Id, " returned more than one order")))
|
|
}
|
|
|
|
ch <- this.SafeValue(result, 0)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOpenOrder
|
|
* @description fetches information on an open order made by the user
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/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] set to true for fetching an open trigger order
|
|
* @param {boolean} [params.stop] alias for trigger
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @param {string} [params.baseCoin] Base coin. Supports linear, inverse & option
|
|
* @param {string} [params.settleCoin] Settle coin. Supports linear, inverse & option
|
|
* @param {string} [params.orderFilter] 'Order' or 'StopOrder' or 'tpslOrder'
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) FetchOpenOrder(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
|
|
|
|
retRes51498 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes51498)
|
|
var request interface{} = map[string]interface{} {
|
|
"orderId": id,
|
|
}
|
|
|
|
result:= (<-this.FetchOpenOrders(symbol, nil, nil, this.Extend(request, params)))
|
|
PanicOnError(result)
|
|
var length interface{} = GetArrayLength(result)
|
|
if IsTrue(IsEqual(length, 0)) {
|
|
var isTrigger interface{} = this.SafeBoolN(params, []interface{}{"trigger", "stop"}, false)
|
|
var extra interface{} = Ternary(IsTrue(isTrigger), "", " If you are trying to fetch SL/TP conditional order, you might try setting params[\"trigger\"] = true")
|
|
panic(OrderNotFound(Add(Add(Add("Order ", ToString(id)), " was not found."), extra)))
|
|
}
|
|
if IsTrue(IsGreaterThan(length, 1)) {
|
|
panic(InvalidOrder(Add(this.Id, " returned more than one order")))
|
|
}
|
|
|
|
ch <- this.SafeValue(result, 0)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchCanceledAndClosedOrders
|
|
* @description fetches information on multiple canceled and closed orders made by the user
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/order-list
|
|
* @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 {boolean} [params.trigger] set to true for fetching trigger orders
|
|
* @param {boolean} [params.stop] alias for trigger
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @param {string} [params.orderFilter] 'Order' or 'StopOrder' or 'tpslOrder'
|
|
* @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 {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) FetchCanceledAndClosedOrders(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
|
|
|
|
retRes51858 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes51858)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchCanceledAndClosedOrders", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes518919 := (<-this.FetchPaginatedCallCursor("fetchCanceledAndClosedOrders", symbol, since, limit, params, "nextPageCursor", "cursor", nil, 50))
|
|
PanicOnError(retRes518919)
|
|
ch <- retRes518919
|
|
return nil
|
|
}
|
|
var request interface{} = map[string]interface{} {}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchCanceledAndClosedOrders", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
AddElementToObject(request, "category", typeVar)
|
|
var isTrigger interface{} = this.SafeBoolN(params, []interface{}{"trigger", "stop"}, false)
|
|
params = this.Omit(params, []interface{}{"trigger", "stop"})
|
|
if IsTrue(isTrigger) {
|
|
AddElementToObject(request, "orderFilter", "StopOrder")
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
var until interface{} = this.SafeInteger(params, "until") // unified in milliseconds
|
|
var endTime interface{} = this.SafeInteger(params, "endTime", until) // exchange-specific in milliseconds
|
|
params = this.Omit(params, []interface{}{"endTime", "until"})
|
|
if IsTrue(!IsEqual(endTime, nil)) {
|
|
AddElementToObject(request, "endTime", endTime)
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5OrderHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "nextPageCursor": "03234de9-1332-41eb-b805-4a9f42c136a3%3A1672220109387%2C03234de9-1332-41eb-b805-4a9f42c136a3%3A1672220109387",
|
|
// "category": "linear",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTCUSDT",
|
|
// "orderType": "Limit",
|
|
// "orderLinkId": "test-001",
|
|
// "orderId": "03234de9-1332-41eb-b805-4a9f42c136a3",
|
|
// "cancelType": "CancelByUser",
|
|
// "avgPrice": "0",
|
|
// "stopOrderType": "UNKNOWN",
|
|
// "lastPriceOnCreated": "16656.5",
|
|
// "orderStatus": "Cancelled",
|
|
// "takeProfit": "",
|
|
// "cumExecValue": "0",
|
|
// "triggerDirection": 0,
|
|
// "blockTradeId": "",
|
|
// "rejectReason": "EC_PerCancelRequest",
|
|
// "isLeverage": "",
|
|
// "price": "18000",
|
|
// "orderIv": "",
|
|
// "createdTime": "1672220109387",
|
|
// "tpTriggerBy": "UNKNOWN",
|
|
// "positionIdx": 0,
|
|
// "timeInForce": "GoodTillCancel",
|
|
// "leavesValue": "0",
|
|
// "updatedTime": "1672220114123",
|
|
// "side": "Sell",
|
|
// "triggerPrice": "",
|
|
// "cumExecFee": "0",
|
|
// "slTriggerBy": "UNKNOWN",
|
|
// "leavesQty": "0",
|
|
// "closeOnTrigger": false,
|
|
// "cumExecQty": "0",
|
|
// "reduceOnly": false,
|
|
// "qty": "0.1",
|
|
// "stopLoss": "",
|
|
// "triggerBy": "UNKNOWN"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672221263862
|
|
// }
|
|
//
|
|
var data interface{} = this.AddPaginationCursorToResult(response)
|
|
|
|
ch <- this.ParseOrders(data, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchClosedOrders
|
|
* @description fetches information on multiple closed orders made by the user
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/order-list
|
|
* @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 {boolean} [params.trigger] set to true for fetching closed trigger orders
|
|
* @param {boolean} [params.stop] alias for trigger
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @param {string} [params.orderFilter] 'Order' or 'StopOrder' or 'tpslOrder'
|
|
* @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 {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes52918 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes52918)
|
|
var request interface{} = map[string]interface{} {
|
|
"orderStatus": "Filled",
|
|
}
|
|
|
|
retRes529515 := (<-this.FetchCanceledAndClosedOrders(symbol, since, limit, this.Extend(request, params)))
|
|
PanicOnError(retRes529515)
|
|
ch <- retRes529515
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchCanceledOrders
|
|
* @description fetches information on multiple canceled orders made by the user
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/order-list
|
|
* @param {string} [symbol] unified market symbol of the market orders were made in
|
|
* @param {int} [since] timestamp in ms of the earliest order, default is undefined
|
|
* @param {int} [limit] max number of orders to return, default is undefined
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {boolean} [params.trigger] true if trigger order
|
|
* @param {boolean} [params.stop] alias for trigger
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @param {string} [params.orderFilter] 'Order' or 'StopOrder' or 'tpslOrder'
|
|
* @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 list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bybit) FetchCanceledOrders(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes53178 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes53178)
|
|
var request interface{} = map[string]interface{} {
|
|
"orderStatus": "Cancelled",
|
|
}
|
|
|
|
retRes532115 := (<-this.FetchCanceledAndClosedOrders(symbol, since, limit, this.Extend(request, params)))
|
|
PanicOnError(retRes532115)
|
|
ch <- retRes532115
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOpenOrders
|
|
* @description fetch all unfilled currently open orders
|
|
* @see https://bybit-exchange.github.io/docs/v5/order/open-order
|
|
* @param {string} symbol unified market symbol
|
|
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {boolean} [params.trigger] set to true for fetching open trigger orders
|
|
* @param {boolean} [params.stop] alias for trigger
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @param {string} [params.baseCoin] Base coin. Supports linear, inverse & option
|
|
* @param {string} [params.settleCoin] Settle coin. Supports linear, inverse & option
|
|
* @param {string} [params.orderFilter] 'Order' or 'StopOrder' or 'tpslOrder'
|
|
* @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 *bybit) 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
|
|
|
|
retRes53448 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes53448)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOpenOrders", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes534819 := (<-this.FetchPaginatedCallCursor("fetchOpenOrders", symbol, since, limit, params, "nextPageCursor", "cursor", nil, 50))
|
|
PanicOnError(retRes534819)
|
|
ch <- retRes534819
|
|
return nil
|
|
}
|
|
var request interface{} = map[string]interface{} {}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchOpenOrders", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
if IsTrue(IsTrue(IsEqual(typeVar, "linear")) || IsTrue(IsEqual(typeVar, "inverse"))) {
|
|
var baseCoin interface{} = this.SafeString(params, "baseCoin")
|
|
if IsTrue(IsTrue(IsEqual(symbol, nil)) && IsTrue(IsEqual(baseCoin, nil))) {
|
|
var defaultSettle interface{} = this.SafeString(this.Options, "defaultSettle", "USDT")
|
|
var settleCoin interface{} = this.SafeString(params, "settleCoin", defaultSettle)
|
|
AddElementToObject(request, "settleCoin", settleCoin)
|
|
}
|
|
}
|
|
AddElementToObject(request, "category", typeVar)
|
|
var isTrigger interface{} = this.SafeBool2(params, "stop", "trigger", false)
|
|
params = this.Omit(params, []interface{}{"stop", "trigger"})
|
|
if IsTrue(isTrigger) {
|
|
AddElementToObject(request, "orderFilter", "StopOrder")
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5OrderRealtime(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "nextPageCursor": "1321052653536515584%3A1672217748287%2C1321052653536515584%3A1672217748287",
|
|
// "category": "spot",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "ETHUSDT",
|
|
// "orderType": "Limit",
|
|
// "orderLinkId": "1672217748277652",
|
|
// "orderId": "1321052653536515584",
|
|
// "cancelType": "UNKNOWN",
|
|
// "avgPrice": "",
|
|
// "stopOrderType": "tpslOrder",
|
|
// "lastPriceOnCreated": "",
|
|
// "orderStatus": "Cancelled",
|
|
// "takeProfit": "",
|
|
// "cumExecValue": "0",
|
|
// "triggerDirection": 0,
|
|
// "isLeverage": "0",
|
|
// "rejectReason": "",
|
|
// "price": "1000",
|
|
// "orderIv": "",
|
|
// "createdTime": "1672217748287",
|
|
// "tpTriggerBy": "",
|
|
// "positionIdx": 0,
|
|
// "timeInForce": "GTC",
|
|
// "leavesValue": "500",
|
|
// "updatedTime": "1672217748287",
|
|
// "side": "Buy",
|
|
// "triggerPrice": "1500",
|
|
// "cumExecFee": "0",
|
|
// "leavesQty": "0",
|
|
// "slTriggerBy": "",
|
|
// "closeOnTrigger": false,
|
|
// "cumExecQty": "0",
|
|
// "reduceOnly": false,
|
|
// "qty": "0.5",
|
|
// "stopLoss": "",
|
|
// "triggerBy": "1192.5"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672219526294
|
|
// }
|
|
//
|
|
var data interface{} = this.AddPaginationCursorToResult(response)
|
|
|
|
ch <- this.ParseOrders(data, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOrderTrades
|
|
* @description fetch all the trades made from a single order
|
|
* @see https://bybit-exchange.github.io/docs/v5/position/execution
|
|
* @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 *bybit) 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 request interface{} = map[string]interface{} {}
|
|
var clientOrderId interface{} = this.SafeString2(params, "clientOrderId", "orderLinkId")
|
|
if IsTrue(!IsEqual(clientOrderId, nil)) {
|
|
AddElementToObject(request, "orderLinkId", clientOrderId)
|
|
} else {
|
|
AddElementToObject(request, "orderId", id)
|
|
}
|
|
params = this.Omit(params, []interface{}{"clientOrderId", "orderLinkId"})
|
|
|
|
retRes545015 := (<-this.FetchMyTrades(symbol, since, limit, this.Extend(request, params)))
|
|
PanicOnError(retRes545015)
|
|
ch <- retRes545015
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchMyTrades
|
|
* @description fetch all trades made by the user
|
|
* @see https://bybit-exchange.github.io/docs/api-explorer/v5/position/execution
|
|
* @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 {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @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 *bybit) 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
|
|
|
|
retRes54688 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes54688)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchMyTrades", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes547219 := (<-this.FetchPaginatedCallCursor("fetchMyTrades", symbol, since, limit, params, "nextPageCursor", "cursor", nil, 100))
|
|
PanicOnError(retRes547219)
|
|
ch <- retRes547219
|
|
return nil
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"execType": "Trade",
|
|
}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchMyTrades", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
AddElementToObject(request, "category", typeVar)
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
requestparamsVariable := this.HandleUntilOption("endTime", request, params);
|
|
request = GetValue(requestparamsVariable,0);
|
|
params = GetValue(requestparamsVariable,1)
|
|
|
|
response:= (<-this.PrivateGetV5ExecutionList(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "nextPageCursor": "132766%3A2%2C132766%3A2",
|
|
// "category": "linear",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "ETHPERP",
|
|
// "orderType": "Market",
|
|
// "underlyingPrice": "",
|
|
// "orderLinkId": "",
|
|
// "side": "Buy",
|
|
// "indexPrice": "",
|
|
// "orderId": "8c065341-7b52-4ca9-ac2c-37e31ac55c94",
|
|
// "stopOrderType": "UNKNOWN",
|
|
// "leavesQty": "0",
|
|
// "execTime": "1672282722429",
|
|
// "isMaker": false,
|
|
// "execFee": "0.071409",
|
|
// "feeRate": "0.0006",
|
|
// "execId": "e0cbe81d-0f18-5866-9415-cf319b5dab3b",
|
|
// "tradeIv": "",
|
|
// "blockTradeId": "",
|
|
// "markPrice": "1183.54",
|
|
// "execPrice": "1190.15",
|
|
// "markIv": "",
|
|
// "orderQty": "0.1",
|
|
// "orderPrice": "1236.9",
|
|
// "execValue": "119.015",
|
|
// "execType": "Trade",
|
|
// "execQty": "0.1"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672283754510
|
|
// }
|
|
//
|
|
var trades interface{} = this.AddPaginationCursorToResult(response)
|
|
|
|
ch <- this.ParseTrades(trades, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseDepositAddress(depositAddress interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "chainType": "ERC20",
|
|
// "addressDeposit": "0xf56297c6717c1d1c42c30324468ed50a9b7402ee",
|
|
// "tagDeposit": '',
|
|
// "chain": "ETH"
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var address interface{} = this.SafeString(depositAddress, "addressDeposit")
|
|
var tag interface{} = this.SafeString(depositAddress, "tagDeposit")
|
|
var code interface{} = this.SafeString(currency, "code")
|
|
this.CheckAddress(address)
|
|
return map[string]interface{} {
|
|
"info": depositAddress,
|
|
"currency": code,
|
|
"network": this.NetworkIdToCode(this.SafeString(depositAddress, "chain"), code),
|
|
"address": address,
|
|
"tag": tag,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchDepositAddressesByNetwork
|
|
* @description fetch a dictionary of addresses for a currency, indexed by network
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/master-deposit-addr
|
|
* @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 *bybit) 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
|
|
|
|
retRes55698 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes55698)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"coin": GetValue(currency, "id"),
|
|
}
|
|
var networkCode interface{} = nil
|
|
networkCodeparamsVariable := this.HandleNetworkCodeAndParams(params);
|
|
networkCode = GetValue(networkCodeparamsVariable,0);
|
|
params = GetValue(networkCodeparamsVariable,1)
|
|
if IsTrue(!IsEqual(networkCode, nil)) {
|
|
AddElementToObject(request, "chainType", this.NetworkCodeToId(networkCode, code))
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5AssetDepositQueryAddress(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "coin": "USDT",
|
|
// "chains": [
|
|
// {
|
|
// "chainType": "ERC20",
|
|
// "addressDeposit": "0xd9e1cd77afa0e50b452a62fbb68a3340602286c3",
|
|
// "tagDeposit": "",
|
|
// "chain": "ETH"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672192792860
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var chains interface{} = this.SafeList(result, "chains", []interface{}{})
|
|
var coin interface{} = this.SafeString(result, "coin")
|
|
currency = this.Currency(coin)
|
|
var parsed interface{} = this.ParseDepositAddresses(chains, []interface{}{GetValue(currency, "code")}, false, map[string]interface{} {
|
|
"currency": GetValue(currency, "code"),
|
|
})
|
|
|
|
ch <- this.IndexBy(parsed, "network")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchDepositAddress
|
|
* @description fetch the deposit address for a currency associated with this account
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/master-deposit-addr
|
|
* @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 *bybit) 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
|
|
|
|
retRes56198 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes56198)
|
|
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
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchDeposits
|
|
* @description fetch all deposits made to an account
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/deposit-record
|
|
* @param {string} code unified currency code
|
|
* @param {int} [since] the earliest time in ms to fetch deposits for, default = 30 days before the current time
|
|
* @param {int} [limit] the maximum number of deposits structures to retrieve, default = 50, max = 50
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] the latest time in ms to fetch deposits for, default = 30 days after since
|
|
* EXCHANGE SPECIFIC PARAMETERS
|
|
* @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.cursor] used for pagination
|
|
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes56438 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes56438)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchDeposits", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes564719 := (<-this.FetchPaginatedCallCursor("fetchDeposits", code, since, limit, params, "nextPageCursor", "cursor", nil, 50))
|
|
PanicOnError(retRes564719)
|
|
ch <- retRes564719
|
|
return nil
|
|
}
|
|
var request interface{} = map[string]interface{} {}
|
|
var currency interface{} = nil
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
AddElementToObject(request, "coin", GetValue(currency, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
requestparamsVariable := this.HandleUntilOption("endTime", request, params);
|
|
request = GetValue(requestparamsVariable,0);
|
|
params = GetValue(requestparamsVariable,1)
|
|
|
|
response:= (<-this.PrivateGetV5AssetDepositQueryRecord(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "rows": [
|
|
// {
|
|
// "coin": "USDT",
|
|
// "chain": "ETH",
|
|
// "amount": "10000",
|
|
// "txID": "skip-notification-scene-test-amount-202212270944-533285-USDT",
|
|
// "status": 3,
|
|
// "toAddress": "test-amount-address",
|
|
// "tag": "",
|
|
// "depositFee": "",
|
|
// "successAt": "1672134274000",
|
|
// "confirmations": "10000",
|
|
// "txIndex": "",
|
|
// "blockHash": ""
|
|
// }
|
|
// ],
|
|
// "nextPageCursor": "eyJtaW5JRCI6MTA0NjA0MywibWF4SUQiOjEwNDYwNDN9"
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672191992512
|
|
// }
|
|
//
|
|
var data interface{} = this.AddPaginationCursorToResult(response)
|
|
|
|
ch <- this.ParseTransactions(data, currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchWithdrawals
|
|
* @description fetch all withdrawals made from an account
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/withdraw-record
|
|
* @param {string} code unified currency code
|
|
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes57128 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes57128)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchWithdrawals", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes571619 := (<-this.FetchPaginatedCallCursor("fetchWithdrawals", code, since, limit, params, "nextPageCursor", "cursor", nil, 50))
|
|
PanicOnError(retRes571619)
|
|
ch <- retRes571619
|
|
return nil
|
|
}
|
|
var request interface{} = map[string]interface{} {}
|
|
var currency interface{} = nil
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
AddElementToObject(request, "coin", GetValue(currency, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
requestparamsVariable := this.HandleUntilOption("endTime", request, params);
|
|
request = GetValue(requestparamsVariable,0);
|
|
params = GetValue(requestparamsVariable,1)
|
|
|
|
response:= (<-this.PrivateGetV5AssetWithdrawQueryRecord(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "rows": [
|
|
// {
|
|
// "coin": "USDT",
|
|
// "chain": "ETH",
|
|
// "amount": "77",
|
|
// "txID": "",
|
|
// "status": "SecurityCheck",
|
|
// "toAddress": "0x99ced129603abc771c0dabe935c326ff6c86645d",
|
|
// "tag": "",
|
|
// "withdrawFee": "10",
|
|
// "createTime": "1670922217000",
|
|
// "updateTime": "1670922217000",
|
|
// "withdrawId": "9976",
|
|
// "withdrawType": 0
|
|
// },
|
|
// {
|
|
// "coin": "USDT",
|
|
// "chain": "ETH",
|
|
// "amount": "26",
|
|
// "txID": "",
|
|
// "status": "success",
|
|
// "toAddress": "15638072681@163.com",
|
|
// "tag": "",
|
|
// "withdrawFee": "0",
|
|
// "createTime": "1669711121000",
|
|
// "updateTime": "1669711380000",
|
|
// "withdrawId": "9801",
|
|
// "withdrawType": 1
|
|
// }
|
|
// ],
|
|
// "nextPageCursor": "eyJtaW5JRCI6OTgwMSwibWF4SUQiOjk5NzZ9"
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672194949928
|
|
// }
|
|
//
|
|
var data interface{} = this.AddPaginationCursorToResult(response)
|
|
|
|
ch <- this.ParseTransactions(data, currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseTransactionStatus(status interface{}) interface{} {
|
|
var statuses interface{} = map[string]interface{} {
|
|
"0": "unknown",
|
|
"1": "pending",
|
|
"2": "processing",
|
|
"3": "ok",
|
|
"4": "fail",
|
|
"SecurityCheck": "pending",
|
|
"Pending": "pending",
|
|
"success": "ok",
|
|
"CancelByUser": "canceled",
|
|
"Reject": "rejected",
|
|
"Fail": "failed",
|
|
"BlockchainConfirmed": "ok",
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *bybit) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchWithdrawals
|
|
//
|
|
// {
|
|
// "coin": "USDT",
|
|
// "chain": "TRX",
|
|
// "amount": "12.34",
|
|
// "txID": "de5ea0a2f2e59dc9a714837dd3ddc6d5e151b56ec5d786d351c4f52336f80d3c",
|
|
// "status": "success",
|
|
// "toAddress": "TQdmFKUoe1Lk2iwZuwRJEHJreTUBoN3BAw",
|
|
// "tag": "",
|
|
// "withdrawFee": "0.5",
|
|
// "createTime": "1665144183000",
|
|
// "updateTime": "1665144256000",
|
|
// "withdrawId": "8839035"
|
|
// }
|
|
//
|
|
// fetchDeposits
|
|
//
|
|
// {
|
|
// "coin": "USDT",
|
|
// "chain": "TRX",
|
|
// "amount": "44",
|
|
// "txID": "0b038ea12fa1575e2d66693db3c346b700d4b28347afc39f80321cf089acc960",
|
|
// "status": "3",
|
|
// "toAddress": "TC6NCAC5WSVCCiaD3kWZXyW91ZKKhLm53b",
|
|
// "tag": "",
|
|
// "depositFee": "",
|
|
// "successAt": "1665142507000",
|
|
// "confirmations": "100",
|
|
// "txIndex": "0",
|
|
// "blockHash": "0000000002ac3b1064aee94bca1bd0b58c4c09c65813b084b87a2063d961129e"
|
|
// }
|
|
//
|
|
// withdraw
|
|
//
|
|
// {
|
|
// "id": "9377266"
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var currencyId interface{} = this.SafeString(transaction, "coin")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
|
|
var timestamp interface{} = this.SafeInteger2(transaction, "createTime", "successAt")
|
|
var updated interface{} = this.SafeInteger(transaction, "updateTime")
|
|
var status interface{} = this.ParseTransactionStatus(this.SafeString(transaction, "status"))
|
|
var feeCost interface{} = this.SafeNumber2(transaction, "depositFee", "withdrawFee")
|
|
var typeVar interface{} = Ternary(IsTrue((InOp(transaction, "depositFee"))), "deposit", "withdrawal")
|
|
var fee interface{} = nil
|
|
if IsTrue(!IsEqual(feeCost, nil)) {
|
|
fee = map[string]interface{} {
|
|
"cost": feeCost,
|
|
"currency": code,
|
|
}
|
|
}
|
|
var toAddress interface{} = this.SafeString(transaction, "toAddress")
|
|
return map[string]interface{} {
|
|
"info": transaction,
|
|
"id": this.SafeString2(transaction, "id", "withdrawId"),
|
|
"txid": this.SafeString(transaction, "txID"),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"network": this.NetworkIdToCode(this.SafeString(transaction, "chain")),
|
|
"address": nil,
|
|
"addressTo": toAddress,
|
|
"addressFrom": nil,
|
|
"tag": this.SafeString(transaction, "tag"),
|
|
"tagTo": nil,
|
|
"tagFrom": nil,
|
|
"type": typeVar,
|
|
"amount": this.SafeNumber(transaction, "amount"),
|
|
"currency": code,
|
|
"status": status,
|
|
"updated": updated,
|
|
"fee": fee,
|
|
"internal": nil,
|
|
"comment": nil,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchLedger
|
|
* @description fetch the history of changes, actions done by the user or operations that altered the balance of the user
|
|
* @see https://bybit-exchange.github.io/docs/v5/account/transaction-log
|
|
* @see https://bybit-exchange.github.io/docs/v5/account/contract-transaction-log
|
|
* @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 {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)
|
|
* @param {string} [params.subType] if inverse will use v5/account/contract-transaction-log
|
|
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes58968 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes58968)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchLedger", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes590019 := (<-this.FetchPaginatedCallCursor("fetchLedger", code, since, limit, params, "nextPageCursor", "cursor", nil, 50))
|
|
PanicOnError(retRes590019)
|
|
ch <- retRes590019
|
|
return nil
|
|
}
|
|
var request interface{} = map[string]interface{} {}
|
|
|
|
enableUnified:= (<-this.IsUnifiedEnabled())
|
|
PanicOnError(enableUnified)
|
|
var currency interface{} = nil
|
|
var currencyKey interface{} = "coin"
|
|
if IsTrue(GetValue(enableUnified, 1)) {
|
|
currencyKey = "currency"
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
} else {
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "start_date", this.Yyyymmdd(since))
|
|
}
|
|
}
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
AddElementToObject(request, currencyKey, GetValue(currency, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
var subType interface{} = nil
|
|
subTypeparamsVariable := this.HandleSubTypeAndParams("fetchLedger", nil, params);
|
|
subType = GetValue(subTypeparamsVariable,0);
|
|
params = GetValue(subTypeparamsVariable,1)
|
|
var response interface{} = nil
|
|
if IsTrue(GetValue(enableUnified, 1)) {
|
|
if IsTrue(IsEqual(subType, "inverse")) {
|
|
|
|
response = (<-this.PrivateGetV5AccountContractTransactionLog(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
|
|
response = (<-this.PrivateGetV5AccountTransactionLog(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
} else {
|
|
|
|
response = (<-this.PrivateGetV5AccountContractTransactionLog(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
//
|
|
// {
|
|
// "ret_code": 0,
|
|
// "ret_msg": "ok",
|
|
// "ext_code": "",
|
|
// "result": {
|
|
// "data": [
|
|
// {
|
|
// "id": 234467,
|
|
// "user_id": 1,
|
|
// "coin": "BTC",
|
|
// "wallet_id": 27913,
|
|
// "type": "Realized P&L",
|
|
// "amount": "-0.00000006",
|
|
// "tx_id": "",
|
|
// "address": "BTCUSD",
|
|
// "wallet_balance": "0.03000330",
|
|
// "exec_time": "2019-12-09T00:00:25.000Z",
|
|
// "cross_seq": 0
|
|
// }
|
|
// ]
|
|
// },
|
|
// "ext_info": null,
|
|
// "time_now": "1577481867.115552",
|
|
// "rate_limit_status": 119,
|
|
// "rate_limit_reset_ms": 1577481867122,
|
|
// "rate_limit": 120
|
|
// }
|
|
//
|
|
// v5 transaction log
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "nextPageCursor": "21963%3A1%2C14954%3A1",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "XRPUSDT",
|
|
// "side": "Buy",
|
|
// "funding": "-0.003676",
|
|
// "orderLinkId": "",
|
|
// "orderId": "1672128000-8-592324-1-2",
|
|
// "fee": "0.00000000",
|
|
// "change": "-0.003676",
|
|
// "cashFlow": "0",
|
|
// "transactionTime": "1672128000000",
|
|
// "type": "SETTLEMENT",
|
|
// "feeRate": "0.0001",
|
|
// "size": "100",
|
|
// "qty": "100",
|
|
// "cashBalance": "5086.55825002",
|
|
// "currency": "USDT",
|
|
// "category": "linear",
|
|
// "tradePrice": "0.3676",
|
|
// "tradeId": "534c0003-4bf7-486f-aa02-78cee36825e4"
|
|
// },
|
|
// {
|
|
// "symbol": "XRPUSDT",
|
|
// "side": "Buy",
|
|
// "funding": "",
|
|
// "orderLinkId": "linear-order",
|
|
// "orderId": "592b7e41-78fd-42e2-9aa3-91e1835ef3e1",
|
|
// "fee": "0.01908720",
|
|
// "change": "-0.0190872",
|
|
// "cashFlow": "0",
|
|
// "transactionTime": "1672121182224",
|
|
// "type": "TRADE",
|
|
// "feeRate": "0.0006",
|
|
// "size": "100",
|
|
// "qty": "88",
|
|
// "cashBalance": "5086.56192602",
|
|
// "currency": "USDT",
|
|
// "category": "linear",
|
|
// "tradePrice": "0.3615",
|
|
// "tradeId": "5184f079-88ec-54c7-8774-5173cafd2b4e"
|
|
// },
|
|
// {
|
|
// "symbol": "XRPUSDT",
|
|
// "side": "Buy",
|
|
// "funding": "",
|
|
// "orderLinkId": "linear-order",
|
|
// "orderId": "592b7e41-78fd-42e2-9aa3-91e1835ef3e1",
|
|
// "fee": "0.00260280",
|
|
// "change": "-0.0026028",
|
|
// "cashFlow": "0",
|
|
// "transactionTime": "1672121182224",
|
|
// "type": "TRADE",
|
|
// "feeRate": "0.0006",
|
|
// "size": "12",
|
|
// "qty": "12",
|
|
// "cashBalance": "5086.58101322",
|
|
// "currency": "USDT",
|
|
// "category": "linear",
|
|
// "tradePrice": "0.3615",
|
|
// "tradeId": "8569c10f-5061-5891-81c4-a54929847eb3"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672132481405
|
|
// }
|
|
//
|
|
var data interface{} = this.AddPaginationCursorToResult(response)
|
|
|
|
ch <- this.ParseLedger(data, currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "id": 234467,
|
|
// "user_id": 1,
|
|
// "coin": "BTC",
|
|
// "wallet_id": 27913,
|
|
// "type": "Realized P&L",
|
|
// "amount": "-0.00000006",
|
|
// "tx_id": "",
|
|
// "address": "BTCUSD",
|
|
// "wallet_balance": "0.03000330",
|
|
// "exec_time": "2019-12-09T00:00:25.000Z",
|
|
// "cross_seq": 0
|
|
// }
|
|
//
|
|
// {
|
|
// "symbol": "XRPUSDT",
|
|
// "side": "Buy",
|
|
// "funding": "",
|
|
// "orderLinkId": "linear-order",
|
|
// "orderId": "592b7e41-78fd-42e2-9aa3-91e1835ef3e1",
|
|
// "fee": "0.00260280",
|
|
// "change": "-0.0026028",
|
|
// "cashFlow": "0",
|
|
// "transactionTime": "1672121182224",
|
|
// "type": "TRADE",
|
|
// "feeRate": "0.0006",
|
|
// "size": "12",
|
|
// "qty": "12",
|
|
// "cashBalance": "5086.58101322",
|
|
// "currency": "USDT",
|
|
// "category": "linear",
|
|
// "tradePrice": "0.3615",
|
|
// "tradeId": "8569c10f-5061-5891-81c4-a54929847eb3"
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var currencyId interface{} = this.SafeString2(item, "coin", "currency")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
|
|
currency = this.SafeCurrency(currencyId, currency)
|
|
var amountString interface{} = this.SafeString2(item, "amount", "change")
|
|
var afterString interface{} = this.SafeString2(item, "wallet_balance", "cashBalance")
|
|
var direction interface{} = Ternary(IsTrue(Precise.StringLt(amountString, "0")), "out", "in")
|
|
var before interface{} = nil
|
|
var after interface{} = nil
|
|
var amount interface{} = nil
|
|
if IsTrue(IsTrue(!IsEqual(afterString, nil)) && IsTrue(!IsEqual(amountString, nil))) {
|
|
var difference interface{} = Ternary(IsTrue((IsEqual(direction, "out"))), amountString, Precise.StringNeg(amountString))
|
|
before = this.ParseToNumeric(Precise.StringAdd(afterString, difference))
|
|
after = this.ParseToNumeric(afterString)
|
|
amount = this.ParseToNumeric(Precise.StringAbs(amountString))
|
|
}
|
|
var timestamp interface{} = this.Parse8601(this.SafeString(item, "exec_time"))
|
|
if IsTrue(IsEqual(timestamp, nil)) {
|
|
timestamp = this.SafeInteger(item, "transactionTime")
|
|
}
|
|
return this.SafeLedgerEntry(map[string]interface{} {
|
|
"info": item,
|
|
"id": this.SafeString(item, "id"),
|
|
"direction": direction,
|
|
"account": this.SafeString(item, "wallet_id"),
|
|
"referenceId": this.SafeString(item, "tx_id"),
|
|
"referenceAccount": nil,
|
|
"type": this.ParseLedgerEntryType(this.SafeString(item, "type")),
|
|
"currency": code,
|
|
"amount": amount,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"before": before,
|
|
"after": after,
|
|
"status": "ok",
|
|
"fee": map[string]interface{} {
|
|
"currency": code,
|
|
"cost": this.SafeNumber(item, "fee"),
|
|
},
|
|
}, currency)
|
|
}
|
|
func (this *bybit) ParseLedgerEntryType(typeVar interface{}) interface{} {
|
|
var types interface{} = map[string]interface{} {
|
|
"Deposit": "transaction",
|
|
"Withdraw": "transaction",
|
|
"RealisedPNL": "trade",
|
|
"Commission": "fee",
|
|
"Refund": "cashback",
|
|
"Prize": "prize",
|
|
"ExchangeOrderWithdraw": "transaction",
|
|
"ExchangeOrderDeposit": "transaction",
|
|
"TRANSFER_IN": "transaction",
|
|
"TRANSFER_OUT": "transaction",
|
|
"TRADE": "trade",
|
|
"SETTLEMENT": "trade",
|
|
"DELIVERY": "trade",
|
|
"LIQUIDATION": "trade",
|
|
"BONUS": "Prize",
|
|
"FEE_REFUND": "cashback",
|
|
"INTEREST": "transaction",
|
|
"CURRENCY_BUY": "trade",
|
|
"CURRENCY_SELL": "trade",
|
|
}
|
|
return this.SafeString(types, typeVar, typeVar)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#withdraw
|
|
* @description make a withdrawal
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/withdraw
|
|
* @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 *bybit) 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)
|
|
var accountType interface{} = nil
|
|
accountTypeparamsVariable := this.HandleOptionAndParams(params, "withdraw", "accountType", "SPOT");
|
|
accountType = GetValue(accountTypeparamsVariable,0);
|
|
params = GetValue(accountTypeparamsVariable,1)
|
|
|
|
retRes61808 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes61808)
|
|
this.CheckAddress(address)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"coin": GetValue(currency, "id"),
|
|
"amount": this.NumberToString(amount),
|
|
"address": address,
|
|
"timestamp": this.Milliseconds(),
|
|
"accountType": accountType,
|
|
}
|
|
if IsTrue(!IsEqual(tag, nil)) {
|
|
AddElementToObject(request, "tag", tag)
|
|
}
|
|
networkCodequeryVariable := this.HandleNetworkCodeAndParams(params);
|
|
networkCode := GetValue(networkCodequeryVariable,0);
|
|
query := GetValue(networkCodequeryVariable,1)
|
|
var networkId interface{} = this.NetworkCodeToId(networkCode)
|
|
if IsTrue(!IsEqual(networkId, nil)) {
|
|
AddElementToObject(request, "chain", ToUpper(networkId))
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5AssetWithdrawCreate(this.Extend(request, query)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": "0",
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "id": "9377266"
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": "1666892894902"
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
|
|
ch <- this.ParseTransaction(result, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchPosition
|
|
* @description fetch data on a single open contract trade position
|
|
* @see https://bybit-exchange.github.io/docs/v5/position
|
|
* @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 *bybit) 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
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchPosition() requires a symbol argument")))
|
|
}
|
|
|
|
retRes62278 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes62278)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
var response interface{} = nil
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchPosition", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
AddElementToObject(request, "category", typeVar)
|
|
|
|
response = (<-this.PrivateGetV5PositionList(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "nextPageCursor": "updateAt%3D1672279322668",
|
|
// "category": "linear",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "XRPUSDT",
|
|
// "leverage": "10",
|
|
// "avgPrice": "0.3615",
|
|
// "liqPrice": "0.0001",
|
|
// "riskLimitValue": "200000",
|
|
// "takeProfit": "",
|
|
// "positionValue": "36.15",
|
|
// "tpslMode": "Full",
|
|
// "riskId": 41,
|
|
// "trailingStop": "0",
|
|
// "unrealisedPnl": "-1.83",
|
|
// "markPrice": "0.3432",
|
|
// "cumRealisedPnl": "0.48805876",
|
|
// "positionMM": "0.381021",
|
|
// "createdTime": "1672121182216",
|
|
// "positionIdx": 0,
|
|
// "positionIM": "3.634521",
|
|
// "updatedTime": "1672279322668",
|
|
// "side": "Buy",
|
|
// "bustPrice": "",
|
|
// "size": "100",
|
|
// "positionStatus": "Normal",
|
|
// "stopLoss": "",
|
|
// "tradeMode": 0
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672280219169
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var positions interface{} = this.SafeList2(result, "list", "dataList", []interface{}{})
|
|
var timestamp interface{} = this.SafeInteger(response, "time")
|
|
var first interface{} = this.SafeDict(positions, 0, map[string]interface{} {})
|
|
var position interface{} = this.ParsePosition(first, market)
|
|
AddElementToObject(position, "timestamp", timestamp)
|
|
AddElementToObject(position, "datetime", this.Iso8601(timestamp))
|
|
|
|
ch <- position
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchPositions
|
|
* @description fetch all open positions
|
|
* @see https://bybit-exchange.github.io/docs/v5/position
|
|
* @param {string[]} symbols list of unified market symbols
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @param {string} [params.baseCoin] Base coin. Supports linear, inverse & option
|
|
* @param {string} [params.settleCoin] Settle coin. Supports linear, inverse & option
|
|
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes63018 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes63018)
|
|
var symbol interface{} = nil
|
|
if IsTrue(IsTrue((!IsEqual(symbols, nil))) && IsTrue(IsArray(symbols))) {
|
|
var symbolsLength interface{} = GetArrayLength(symbols)
|
|
if IsTrue(IsGreaterThan(symbolsLength, 1)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchPositions() does not accept an array with more than one symbol")))
|
|
} else if IsTrue(IsEqual(symbolsLength, 1)) {
|
|
symbol = GetValue(symbols, 0)
|
|
}
|
|
symbols = this.MarketSymbols(symbols)
|
|
} else if IsTrue(!IsEqual(symbols, nil)) {
|
|
symbol = symbols
|
|
symbols = []interface{}{this.Symbol(symbol)}
|
|
}
|
|
var request interface{} = map[string]interface{} {}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
symbol = GetValue(market, "symbol")
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchPositions", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
if IsTrue(IsTrue(IsEqual(typeVar, "linear")) || IsTrue(IsEqual(typeVar, "inverse"))) {
|
|
var baseCoin interface{} = this.SafeString(params, "baseCoin")
|
|
if IsTrue(IsEqual(typeVar, "linear")) {
|
|
if IsTrue(IsTrue(IsEqual(symbol, nil)) && IsTrue(IsEqual(baseCoin, nil))) {
|
|
var defaultSettle interface{} = this.SafeString(this.Options, "defaultSettle", "USDT")
|
|
var settleCoin interface{} = this.SafeString(params, "settleCoin", defaultSettle)
|
|
AddElementToObject(request, "settleCoin", settleCoin)
|
|
}
|
|
} else {
|
|
// inverse
|
|
if IsTrue(IsTrue(IsEqual(symbol, nil)) && IsTrue(IsEqual(baseCoin, nil))) {
|
|
AddElementToObject(request, "category", "inverse")
|
|
}
|
|
}
|
|
}
|
|
params = this.Omit(params, []interface{}{"type"})
|
|
AddElementToObject(request, "category", typeVar)
|
|
|
|
response:= (<-this.PrivateGetV5PositionList(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "Success",
|
|
// "result": {
|
|
// "nextPageCursor": "0%3A1657711949945%2C0%3A1657711949945",
|
|
// "category": "linear",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "ETHUSDT",
|
|
// "leverage": "10",
|
|
// "updatedTime": 1657711949945,
|
|
// "side": "Buy",
|
|
// "positionValue": "536.92500000",
|
|
// "takeProfit": "",
|
|
// "tpslMode": "Full",
|
|
// "riskId": 11,
|
|
// "trailingStop": "",
|
|
// "entryPrice": "1073.85000000",
|
|
// "unrealisedPnl": "",
|
|
// "markPrice": "1080.65000000",
|
|
// "size": "0.5000",
|
|
// "positionStatus": "normal",
|
|
// "stopLoss": "",
|
|
// "cumRealisedPnl": "-0.32215500",
|
|
// "positionMM": "2.97456450",
|
|
// "createdTime": 1657711949928,
|
|
// "positionIdx": 0,
|
|
// "positionIM": "53.98243950"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "time": 1657713693182
|
|
// }
|
|
//
|
|
var positions interface{} = this.AddPaginationCursorToResult(response)
|
|
var results interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(positions)); i++ {
|
|
var rawPosition interface{} = GetValue(positions, i)
|
|
if IsTrue(IsTrue((InOp(rawPosition, "data"))) && IsTrue((InOp(rawPosition, "is_valid")))) {
|
|
// futures only
|
|
rawPosition = this.SafeDict(rawPosition, "data")
|
|
}
|
|
AppendToArray(&results,this.ParsePosition(rawPosition))
|
|
}
|
|
|
|
ch <- this.FilterByArrayPositions(results, "symbol", symbols, false)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// linear swap
|
|
//
|
|
// {
|
|
// "positionIdx": 0,
|
|
// "riskId": "11",
|
|
// "symbol": "ETHUSDT",
|
|
// "side": "Buy",
|
|
// "size": "0.10",
|
|
// "positionValue": "119.845",
|
|
// "entryPrice": "1198.45",
|
|
// "tradeMode": 1,
|
|
// "autoAddMargin": 0,
|
|
// "leverage": "4.2",
|
|
// "positionBalance": "28.58931118",
|
|
// "liqPrice": "919.10",
|
|
// "bustPrice": "913.15",
|
|
// "takeProfit": "0.00",
|
|
// "stopLoss": "0.00",
|
|
// "trailingStop": "0.00",
|
|
// "unrealisedPnl": "0.083",
|
|
// "createdTime": "1669097244192",
|
|
// "updatedTime": "1669413126190",
|
|
// "tpSlMode": "Full",
|
|
// "riskLimitValue": "900000",
|
|
// "activePrice": "0.00"
|
|
// }
|
|
//
|
|
// usdc
|
|
// {
|
|
// "symbol":"BTCPERP",
|
|
// "leverage":"1.00",
|
|
// "occClosingFee":"0.0000",
|
|
// "liqPrice":"",
|
|
// "positionValue":"30.8100",
|
|
// "takeProfit":"0.0",
|
|
// "riskId":"10001",
|
|
// "trailingStop":"0.0000",
|
|
// "unrealisedPnl":"0.0000",
|
|
// "createdAt":"1652451795305",
|
|
// "markPrice":"30809.41",
|
|
// "cumRealisedPnl":"0.0000",
|
|
// "positionMM":"0.1541",
|
|
// "positionIM":"30.8100",
|
|
// "updatedAt":"1652451795305",
|
|
// "tpSLMode":"UNKNOWN",
|
|
// "side":"Buy",
|
|
// "bustPrice":"",
|
|
// "deleverageIndicator":"0",
|
|
// "entryPrice":"30810.0",
|
|
// "size":"0.001",
|
|
// "sessionRPL":"0.0000",
|
|
// "positionStatus":"NORMAL",
|
|
// "sessionUPL":"-0.0006",
|
|
// "stopLoss":"0.0",
|
|
// "orderMargin":"0.0000",
|
|
// "sessionAvgPrice":"30810.0"
|
|
// }
|
|
//
|
|
// unified margin
|
|
//
|
|
// {
|
|
// "symbol": "ETHUSDT",
|
|
// "leverage": "10",
|
|
// "updatedTime": 1657711949945,
|
|
// "side": "Buy",
|
|
// "positionValue": "536.92500000",
|
|
// "takeProfit": "",
|
|
// "tpslMode": "Full",
|
|
// "riskId": 11,
|
|
// "trailingStop": "",
|
|
// "entryPrice": "1073.85000000",
|
|
// "unrealisedPnl": "",
|
|
// "markPrice": "1080.65000000",
|
|
// "size": "0.5000",
|
|
// "positionStatus": "normal",
|
|
// "stopLoss": "",
|
|
// "cumRealisedPnl": "-0.32215500",
|
|
// "positionMM": "2.97456450",
|
|
// "createdTime": 1657711949928,
|
|
// "positionIdx": 0,
|
|
// "positionIM": "53.98243950"
|
|
// }
|
|
//
|
|
// unified account
|
|
//
|
|
// {
|
|
// "symbol": "XRPUSDT",
|
|
// "leverage": "10",
|
|
// "avgPrice": "0.3615",
|
|
// "liqPrice": "0.0001",
|
|
// "riskLimitValue": "200000",
|
|
// "takeProfit": "",
|
|
// "positionValue": "36.15",
|
|
// "tpslMode": "Full",
|
|
// "riskId": 41,
|
|
// "trailingStop": "0",
|
|
// "unrealisedPnl": "-1.83",
|
|
// "markPrice": "0.3432",
|
|
// "cumRealisedPnl": "0.48805876",
|
|
// "positionMM": "0.381021",
|
|
// "createdTime": "1672121182216",
|
|
// "positionIdx": 0,
|
|
// "positionIM": "3.634521",
|
|
// "updatedTime": "1672279322668",
|
|
// "side": "Buy",
|
|
// "bustPrice": "",
|
|
// "size": "100",
|
|
// "positionStatus": "Normal",
|
|
// "stopLoss": "",
|
|
// "tradeMode": 0
|
|
// }
|
|
//
|
|
// fetchPositionsHistory
|
|
//
|
|
// {
|
|
// symbol: 'XRPUSDT',
|
|
// orderType: 'Market',
|
|
// leverage: '10',
|
|
// updatedTime: '1712717265572',
|
|
// side: 'Sell',
|
|
// orderId: '071749f3-a9fa-427b-b5ca-27b2f52b81de',
|
|
// closedPnl: '-0.00049568',
|
|
// avgEntryPrice: '0.6045',
|
|
// qty: '3',
|
|
// cumEntryValue: '1.8135',
|
|
// createdTime: '1712717265566',
|
|
// orderPrice: '0.5744',
|
|
// closedSize: '3',
|
|
// avgExitPrice: '0.605',
|
|
// execType: 'Trade',
|
|
// fillCount: '1',
|
|
// cumExitValue: '1.815'
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var closedSize interface{} = this.SafeString(position, "closedSize")
|
|
var isHistory interface{} = (!IsEqual(closedSize, nil))
|
|
var contract interface{} = this.SafeString(position, "symbol")
|
|
market = this.SafeMarket(contract, market, nil, "contract")
|
|
var size interface{} = Precise.StringAbs(this.SafeString2(position, "size", "qty"))
|
|
var side interface{} = this.SafeString(position, "side")
|
|
if IsTrue(!IsEqual(side, nil)) {
|
|
if IsTrue(IsEqual(side, "Buy")) {
|
|
side = Ternary(IsTrue(isHistory), "short", "long")
|
|
} else if IsTrue(IsEqual(side, "Sell")) {
|
|
side = Ternary(IsTrue(isHistory), "long", "short")
|
|
} else {
|
|
side = nil
|
|
}
|
|
}
|
|
var notional interface{} = this.SafeString2(position, "positionValue", "cumExitValue")
|
|
var unrealisedPnl interface{} = this.OmitZero(this.SafeString(position, "unrealisedPnl"))
|
|
var initialMarginString interface{} = this.SafeStringN(position, []interface{}{"positionIM", "cumEntryValue"})
|
|
var maintenanceMarginString interface{} = this.SafeString(position, "positionMM")
|
|
var timestamp interface{} = this.SafeIntegerN(position, []interface{}{"createdTime", "createdAt"})
|
|
var lastUpdateTimestamp interface{} = this.Parse8601(this.SafeString(position, "updated_at"))
|
|
if IsTrue(IsEqual(lastUpdateTimestamp, nil)) {
|
|
lastUpdateTimestamp = this.SafeIntegerN(position, []interface{}{"updatedTime", "updatedAt", "updatedTime"})
|
|
}
|
|
var tradeMode interface{} = this.SafeInteger(position, "tradeMode", 0)
|
|
var marginMode interface{} = nil
|
|
if IsTrue(IsTrue((!IsTrue(GetValue(this.Options, "enableUnifiedAccount")))) || IsTrue((IsTrue(GetValue(this.Options, "enableUnifiedAccount")) && IsTrue(GetValue(market, "inverse"))))) {
|
|
// tradeMode would work for classic and UTA(inverse)
|
|
if !IsTrue(isHistory) {
|
|
marginMode = Ternary(IsTrue((IsEqual(tradeMode, 1))), "isolated", "cross")
|
|
}
|
|
}
|
|
var collateralString interface{} = this.SafeString(position, "positionBalance")
|
|
var entryPrice interface{} = this.OmitZero(this.SafeStringN(position, []interface{}{"entryPrice", "avgPrice", "avgEntryPrice"}))
|
|
var liquidationPrice interface{} = this.OmitZero(this.SafeString(position, "liqPrice"))
|
|
var leverage interface{} = this.SafeString(position, "leverage")
|
|
if IsTrue(!IsEqual(liquidationPrice, nil)) {
|
|
if IsTrue(IsEqual(GetValue(market, "settle"), "USDC")) {
|
|
// (Entry price - Liq price) * Contracts + Maintenance Margin + (unrealised pnl) = Collateral
|
|
var difference interface{} = Precise.StringAbs(Precise.StringSub(entryPrice, liquidationPrice))
|
|
collateralString = Precise.StringAdd(Precise.StringAdd(Precise.StringMul(difference, size), maintenanceMarginString), unrealisedPnl)
|
|
} else {
|
|
var bustPrice interface{} = this.SafeString(position, "bustPrice")
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
// derived from the following formulas
|
|
// (Entry price - Bust price) * Contracts = Collateral
|
|
// (Entry price - Liq price) * Contracts = Collateral - Maintenance Margin
|
|
// Maintenance Margin = (Bust price - Liq price) x Contracts
|
|
var maintenanceMarginPriceDifference interface{} = Precise.StringAbs(Precise.StringSub(liquidationPrice, bustPrice))
|
|
maintenanceMarginString = Precise.StringMul(maintenanceMarginPriceDifference, size)
|
|
// Initial Margin = Contracts x Entry Price / Leverage
|
|
if IsTrue(!IsEqual(entryPrice, nil)) {
|
|
initialMarginString = Precise.StringDiv(Precise.StringMul(size, entryPrice), leverage)
|
|
}
|
|
} else {
|
|
// Contracts * (1 / Entry price - 1 / Bust price) = Collateral
|
|
// Contracts * (1 / Entry price - 1 / Liq price) = Collateral - Maintenance Margin
|
|
// Maintenance Margin = Contracts * (1 / Liq price - 1 / Bust price)
|
|
// Maintenance Margin = Contracts * (Bust price - Liq price) / (Liq price x Bust price)
|
|
var difference interface{} = Precise.StringAbs(Precise.StringSub(bustPrice, liquidationPrice))
|
|
var multiply interface{} = Precise.StringMul(bustPrice, liquidationPrice)
|
|
maintenanceMarginString = Precise.StringDiv(Precise.StringMul(size, difference), multiply)
|
|
// Initial Margin = Leverage x Contracts / EntryPrice
|
|
if IsTrue(!IsEqual(entryPrice, nil)) {
|
|
initialMarginString = Precise.StringDiv(size, Precise.StringMul(entryPrice, leverage))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var maintenanceMarginPercentage interface{} = Precise.StringDiv(maintenanceMarginString, notional)
|
|
var marginRatio interface{} = Precise.StringDiv(maintenanceMarginString, collateralString, 4)
|
|
var positionIdx interface{} = this.SafeString(position, "positionIdx")
|
|
var hedged interface{} = IsTrue((!IsEqual(positionIdx, nil))) && IsTrue((!IsEqual(positionIdx, "0")))
|
|
return this.SafePosition(map[string]interface{} {
|
|
"info": position,
|
|
"id": nil,
|
|
"symbol": GetValue(market, "symbol"),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"lastUpdateTimestamp": lastUpdateTimestamp,
|
|
"initialMargin": this.ParseNumber(initialMarginString),
|
|
"initialMarginPercentage": this.ParseNumber(Precise.StringDiv(initialMarginString, notional)),
|
|
"maintenanceMargin": this.ParseNumber(maintenanceMarginString),
|
|
"maintenanceMarginPercentage": this.ParseNumber(maintenanceMarginPercentage),
|
|
"entryPrice": this.ParseNumber(entryPrice),
|
|
"notional": this.ParseNumber(notional),
|
|
"leverage": this.ParseNumber(leverage),
|
|
"unrealizedPnl": this.ParseNumber(unrealisedPnl),
|
|
"realizedPnl": this.SafeNumber(position, "closedPnl"),
|
|
"contracts": this.ParseNumber(size),
|
|
"contractSize": this.SafeNumber(market, "contractSize"),
|
|
"marginRatio": this.ParseNumber(marginRatio),
|
|
"liquidationPrice": this.ParseNumber(liquidationPrice),
|
|
"markPrice": this.SafeNumber(position, "markPrice"),
|
|
"lastPrice": this.SafeNumber(position, "avgExitPrice"),
|
|
"collateral": this.ParseNumber(collateralString),
|
|
"marginMode": marginMode,
|
|
"side": side,
|
|
"percentage": nil,
|
|
"stopLossPrice": this.SafeNumber2(position, "stop_loss", "stopLoss"),
|
|
"takeProfitPrice": this.SafeNumber2(position, "take_profit", "takeProfit"),
|
|
"hedged": hedged,
|
|
})
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchLeverage
|
|
* @description fetch the set leverage for a market
|
|
* @see https://bybit-exchange.github.io/docs/v5/position
|
|
* @param {string} symbol unified market symbol
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
|
|
*/
|
|
func (this *bybit) FetchLeverage(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes66418 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes66418)
|
|
var market interface{} = this.Market(symbol)
|
|
|
|
position:= (<-this.FetchPosition(symbol, params))
|
|
PanicOnError(position)
|
|
|
|
ch <- this.ParseLeverage(position, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseLeverage(leverage interface{}, optionalArgs ...interface{}) interface{} {
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var marketId interface{} = this.SafeString(leverage, "symbol")
|
|
var leverageValue interface{} = this.SafeInteger(leverage, "leverage")
|
|
return map[string]interface{} {
|
|
"info": leverage,
|
|
"symbol": this.SafeSymbol(marketId, market),
|
|
"marginMode": this.SafeStringLower(leverage, "marginMode"),
|
|
"longLeverage": leverageValue,
|
|
"shortLeverage": leverageValue,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#setMarginMode
|
|
* @description set margin mode (account) or trade mode (symbol)
|
|
* @see https://bybit-exchange.github.io/docs/v5/account/set-margin-mode
|
|
* @see https://bybit-exchange.github.io/docs/v5/position/cross-isolate
|
|
* @param {string} marginMode account mode must be either [isolated, cross, portfolio], trade mode must be either [isolated, cross]
|
|
* @param {string} symbol unified market symbol of the market the position is held in, default is undefined
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.leverage] the rate of leverage, is required if setting trade mode (symbol)
|
|
* @returns {object} response from the exchange
|
|
*/
|
|
func (this *bybit) SetMarginMode(marginMode 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
|
|
|
|
retRes66728 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes66728)
|
|
enableUnifiedMarginenableUnifiedAccountVariable := (<-this.IsUnifiedEnabled());
|
|
enableUnifiedMargin := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,0);
|
|
enableUnifiedAccount := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,1)
|
|
var isUnifiedAccount interface{} = (IsTrue(enableUnifiedMargin) || IsTrue(enableUnifiedAccount))
|
|
var market interface{} = nil
|
|
var response interface{} = nil
|
|
if IsTrue(isUnifiedAccount) {
|
|
if IsTrue(IsEqual(marginMode, "isolated")) {
|
|
marginMode = "ISOLATED_MARGIN"
|
|
} else if IsTrue(IsEqual(marginMode, "cross")) {
|
|
marginMode = "REGULAR_MARGIN"
|
|
} else if IsTrue(IsEqual(marginMode, "portfolio")) {
|
|
marginMode = "PORTFOLIO_MARGIN"
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " setMarginMode() marginMode must be either [isolated, cross, portfolio]")))
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"setMarginMode": marginMode,
|
|
}
|
|
|
|
response = (<-this.PrivatePostV5AccountSetMarginMode(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " setMarginMode() requires a symbol parameter for non unified account")))
|
|
}
|
|
market = this.Market(symbol)
|
|
var isUsdcSettled interface{} = IsEqual(GetValue(market, "settle"), "USDC")
|
|
if IsTrue(isUsdcSettled) {
|
|
if IsTrue(IsEqual(marginMode, "cross")) {
|
|
marginMode = "REGULAR_MARGIN"
|
|
} else if IsTrue(IsEqual(marginMode, "portfolio")) {
|
|
marginMode = "PORTFOLIO_MARGIN"
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " setMarginMode() for usdc market marginMode must be either [cross, portfolio]")))
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"setMarginMode": marginMode,
|
|
}
|
|
|
|
response = (<-this.PrivatePostV5AccountSetMarginMode(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("setPositionMode", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
var tradeMode interface{} = nil
|
|
if IsTrue(IsEqual(marginMode, "cross")) {
|
|
tradeMode = 0
|
|
} else if IsTrue(IsEqual(marginMode, "isolated")) {
|
|
tradeMode = 1
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " setMarginMode() with symbol marginMode must be either [isolated, cross]")))
|
|
}
|
|
var sellLeverage interface{} = nil
|
|
var buyLeverage interface{} = nil
|
|
var leverage interface{} = this.SafeString(params, "leverage")
|
|
if IsTrue(IsEqual(leverage, nil)) {
|
|
sellLeverage = this.SafeString2(params, "sell_leverage", "sellLeverage")
|
|
buyLeverage = this.SafeString2(params, "buy_leverage", "buyLeverage")
|
|
if IsTrue(IsTrue(IsEqual(sellLeverage, nil)) && IsTrue(IsEqual(buyLeverage, nil))) {
|
|
panic(ArgumentsRequired(Add(this.Id, " setMarginMode() requires a leverage parameter or sell_leverage and buy_leverage parameters")))
|
|
}
|
|
if IsTrue(IsEqual(buyLeverage, nil)) {
|
|
buyLeverage = sellLeverage
|
|
}
|
|
if IsTrue(IsEqual(sellLeverage, nil)) {
|
|
sellLeverage = buyLeverage
|
|
}
|
|
params = this.Omit(params, []interface{}{"buy_leverage", "sell_leverage", "sellLeverage", "buyLeverage"})
|
|
} else {
|
|
sellLeverage = leverage
|
|
buyLeverage = leverage
|
|
params = this.Omit(params, "leverage")
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"category": typeVar,
|
|
"symbol": GetValue(market, "id"),
|
|
"tradeMode": tradeMode,
|
|
"buyLeverage": buyLeverage,
|
|
"sellLeverage": sellLeverage,
|
|
}
|
|
|
|
response = (<-this.PrivatePostV5PositionSwitchIsolated(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
}
|
|
|
|
ch <- response
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#setLeverage
|
|
* @description set the level of leverage for a market
|
|
* @see https://bybit-exchange.github.io/docs/v5/position/leverage
|
|
* @param {float} leverage the rate of leverage
|
|
* @param {string} symbol unified market symbol
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.buyLeverage] leverage for buy side
|
|
* @param {string} [params.sellLeverage] leverage for sell side
|
|
* @returns {object} response from the exchange
|
|
*/
|
|
func (this *bybit) 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")))
|
|
}
|
|
|
|
retRes67708 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes67708)
|
|
var market interface{} = this.Market(symbol)
|
|
// WARNING: THIS WILL INCREASE LIQUIDATION PRICE FOR OPEN ISOLATED LONG POSITIONS
|
|
// AND DECREASE LIQUIDATION PRICE FOR OPEN ISOLATED SHORT POSITIONS
|
|
// engage in leverage setting
|
|
// we reuse the code here instead of having two methods
|
|
var leverageString interface{} = this.NumberToString(leverage)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
"buyLeverage": leverageString,
|
|
"sellLeverage": leverageString,
|
|
}
|
|
AddElementToObject(request, "buyLeverage", leverageString)
|
|
AddElementToObject(request, "sellLeverage", leverageString)
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
AddElementToObject(request, "category", "linear")
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
AddElementToObject(request, "category", "inverse")
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " setLeverage() only support linear and inverse market")))
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5PositionSetLeverage(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
ch <- response
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#setPositionMode
|
|
* @description set hedged to true or false for a market
|
|
* @see https://bybit-exchange.github.io/docs/v5/position/position-mode
|
|
* @param {bool} hedged
|
|
* @param {string} symbol used for unified account with inverse market
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} response from the exchange
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes68068 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes68068)
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
}
|
|
var mode interface{} = nil
|
|
if IsTrue(hedged) {
|
|
mode = 3
|
|
} else {
|
|
mode = 0
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"mode": mode,
|
|
}
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
AddElementToObject(request, "coin", "USDT")
|
|
} else {
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
AddElementToObject(request, "category", Ternary(IsTrue(GetValue(market, "linear")), "linear", "inverse"))
|
|
} else {
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("setPositionMode", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
AddElementToObject(request, "category", typeVar)
|
|
}
|
|
params = this.Omit(params, "type")
|
|
|
|
response:= (<-this.PrivatePostV5PositionSwitchMode(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// v5
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {},
|
|
// "retExtInfo": {},
|
|
// "time": 1675249072814
|
|
// }
|
|
ch <- response
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) FetchDerivativesOpenInterestHistory(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
|
|
|
|
retRes68478 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes68478)
|
|
var market interface{} = this.Market(symbol)
|
|
var subType interface{} = Ternary(IsTrue(GetValue(market, "linear")), "linear", "inverse")
|
|
var category interface{} = this.SafeString(params, "category", subType)
|
|
var intervals interface{} = this.SafeDict(this.Options, "intervals")
|
|
var interval interface{} = this.SafeString(intervals, timeframe) // 5min,15min,30min,1h,4h,1d
|
|
if IsTrue(IsEqual(interval, nil)) {
|
|
panic(BadRequest(Add(Add(Add(this.Id, " fetchOpenInterestHistory() cannot use the "), timeframe), " timeframe")))
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
"intervalTime": interval,
|
|
"category": category,
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
var until interface{} = this.SafeInteger(params, "until") // unified in milliseconds
|
|
params = this.Omit(params, []interface{}{"until"})
|
|
if IsTrue(!IsEqual(until, nil)) {
|
|
AddElementToObject(request, "endTime", until)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketOpenInterest(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "symbol": "BTCUSD",
|
|
// "category": "inverse",
|
|
// "list": [
|
|
// {
|
|
// "openInterest": "461134384.00000000",
|
|
// "timestamp": "1669571400000"
|
|
// },
|
|
// {
|
|
// "openInterest": "461134292.00000000",
|
|
// "timestamp": "1669571100000"
|
|
// }
|
|
// ],
|
|
// "nextPageCursor": ""
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672053548579
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var data interface{} = this.AddPaginationCursorToResult(response)
|
|
var id interface{} = this.SafeString(result, "symbol")
|
|
market = this.SafeMarket(id, market, nil, "contract")
|
|
|
|
ch <- this.ParseOpenInterestsHistory(data, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOpenInterest
|
|
* @description Retrieves the open interest of a derivative trading pair
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/open-interest
|
|
* @param {string} symbol Unified CCXT market symbol
|
|
* @param {object} [params] exchange specific parameters
|
|
* @param {string} [params.interval] 5m, 15m, 30m, 1h, 4h, 1d
|
|
* @param {string} [params.category] "linear" or "inverse"
|
|
* @returns {object} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes69158 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes69158)
|
|
var market interface{} = this.Market(symbol)
|
|
if !IsTrue(GetValue(market, "contract")) {
|
|
panic(BadRequest(Add(this.Id, " fetchOpenInterest() supports contract markets only")))
|
|
}
|
|
var timeframe interface{} = this.SafeString(params, "interval", "1h")
|
|
var intervals interface{} = this.SafeDict(this.Options, "intervals")
|
|
var interval interface{} = this.SafeString(intervals, timeframe) // 5min,15min,30min,1h,4h,1d
|
|
if IsTrue(IsEqual(interval, nil)) {
|
|
panic(BadRequest(Add(Add(Add(this.Id, " fetchOpenInterest() cannot use the "), timeframe), " timeframe")))
|
|
}
|
|
var subType interface{} = Ternary(IsTrue(GetValue(market, "linear")), "linear", "inverse")
|
|
var category interface{} = this.SafeString(params, "category", subType)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
"intervalTime": interval,
|
|
"category": category,
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketOpenInterest(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "symbol": "BTCUSD",
|
|
// "category": "inverse",
|
|
// "list": [
|
|
// {
|
|
// "openInterest": "461134384.00000000",
|
|
// "timestamp": "1669571400000"
|
|
// },
|
|
// {
|
|
// "openInterest": "461134292.00000000",
|
|
// "timestamp": "1669571100000"
|
|
// }
|
|
// ],
|
|
// "nextPageCursor": ""
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672053548579
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var id interface{} = this.SafeString(result, "symbol")
|
|
market = this.SafeMarket(id, market, nil, "contract")
|
|
var data interface{} = this.AddPaginationCursorToResult(response)
|
|
|
|
ch <- this.ParseOpenInterest(GetValue(data, 0), market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOpenInterestHistory
|
|
* @description Gets the total amount of unsettled contracts. In other words, the total number of contracts held in open positions
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/open-interest
|
|
* @param {string} symbol Unified market symbol
|
|
* @param {string} timeframe "5m", 15m, 30m, 1h, 4h, 1d
|
|
* @param {int} [since] Not used by Bybit
|
|
* @param {int} [limit] The number of open interest structures to return. Max 200, default 50
|
|
* @param {object} [params] Exchange specific parameters
|
|
* @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 An array of open interest structures
|
|
*/
|
|
func (this *bybit) 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(IsEqual(timeframe, "1m")) {
|
|
panic(BadRequest(Add(this.Id, " fetchOpenInterestHistory cannot use the 1m timeframe")))
|
|
}
|
|
|
|
retRes69818 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes69818)
|
|
var paginate interface{} = this.SafeBool(params, "paginate")
|
|
if IsTrue(paginate) {
|
|
params = this.Omit(params, "paginate")
|
|
AddElementToObject(params, "timeframe", timeframe)
|
|
|
|
retRes698619 := (<-this.FetchPaginatedCallCursor("fetchOpenInterestHistory", symbol, since, limit, params, "nextPageCursor", "cursor", nil, 200))
|
|
PanicOnError(retRes698619)
|
|
ch <- retRes698619
|
|
return nil
|
|
}
|
|
var market interface{} = this.Market(symbol)
|
|
if IsTrue(IsTrue(GetValue(market, "spot")) || IsTrue(GetValue(market, "option"))) {
|
|
panic(BadRequest(Add(Add(this.Id, " fetchOpenInterestHistory() symbol does not support market "), symbol)))
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
retRes699815 := (<-this.FetchDerivativesOpenInterestHistory(symbol, timeframe, since, limit, params))
|
|
PanicOnError(retRes699815)
|
|
ch <- retRes699815
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseOpenInterest(interest interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "openInterest": 64757.62400000,
|
|
// "timestamp": 1665784800000,
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var timestamp interface{} = this.SafeInteger(interest, "timestamp")
|
|
var openInterest interface{} = this.SafeNumber2(interest, "open_interest", "openInterest")
|
|
// the openInterest is in the base asset for linear and quote asset for inverse
|
|
var amount interface{} = Ternary(IsTrue(GetValue(market, "linear")), openInterest, nil)
|
|
var value interface{} = Ternary(IsTrue(GetValue(market, "inverse")), openInterest, nil)
|
|
return this.SafeOpenInterest(map[string]interface{} {
|
|
"symbol": GetValue(market, "symbol"),
|
|
"openInterestAmount": amount,
|
|
"openInterestValue": value,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"info": interest,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchCrossBorrowRate
|
|
* @description fetch the rate of interest to borrow a currency for margin trading
|
|
* @see https://bybit-exchange.github.io/docs/zh-TW/v5/spot-margin-normal/interest-quota
|
|
* @param {string} code unified currency code
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [borrow rate structure]{@link https://docs.ccxt.com/#/?id=borrow-rate-structure}
|
|
*/
|
|
func (this *bybit) FetchCrossBorrowRate(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
|
|
|
|
retRes70338 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes70338)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"coin": GetValue(currency, "id"),
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5SpotCrossMarginTradeLoanInfo(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": "0",
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "coin": "USDT",
|
|
// "interestRate": "0.000107000000",
|
|
// "loanAbleAmount": "",
|
|
// "maxLoanAmount": "79999.999"
|
|
// },
|
|
// "retExtInfo": null,
|
|
// "time": "1666734490778"
|
|
// }
|
|
//
|
|
var timestamp interface{} = this.SafeInteger(response, "time")
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
AddElementToObject(data, "timestamp", timestamp)
|
|
|
|
ch <- this.ParseBorrowRate(data, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseBorrowRate(info interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "coin": "USDT",
|
|
// "interestRate": "0.000107000000",
|
|
// "loanAbleAmount": "",
|
|
// "maxLoanAmount": "79999.999",
|
|
// "timestamp": 1666734490778
|
|
// }
|
|
//
|
|
// fetchBorrowRateHistory
|
|
// {
|
|
// "timestamp": 1721469600000,
|
|
// "currency": "USDC",
|
|
// "hourlyBorrowRate": "0.000014621596",
|
|
// "vipLevel": "No VIP"
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var timestamp interface{} = this.SafeInteger(info, "timestamp")
|
|
var currencyId interface{} = this.SafeString2(info, "coin", "currency")
|
|
var hourlyBorrowRate interface{} = this.SafeNumber(info, "hourlyBorrowRate")
|
|
var period interface{} = Ternary(IsTrue((!IsEqual(hourlyBorrowRate, nil))), 3600000, 86400000) // 1h or 1d
|
|
return map[string]interface{} {
|
|
"currency": this.SafeCurrencyCode(currencyId, currency),
|
|
"rate": this.SafeNumber(info, "interestRate", hourlyBorrowRate),
|
|
"period": period,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"info": info,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchBorrowInterest
|
|
* @description fetch the interest owed by the user for borrowing currency for margin trading
|
|
* @see https://bybit-exchange.github.io/docs/zh-TW/v5/spot-margin-normal/account-info
|
|
* @param {string} code unified currency code
|
|
* @param {string} symbol unified market symbol when fetch interest in isolated markets
|
|
* @param {number} [since] the earliest time in ms to fetch borrrow interest for
|
|
* @param {number} [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 *bybit) 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
|
|
|
|
retRes71048 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes71048)
|
|
var request interface{} = map[string]interface{} {}
|
|
|
|
response:= (<-this.PrivateGetV5SpotCrossMarginTradeAccount(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ret_code": 0,
|
|
// "ret_msg": "",
|
|
// "ext_code": null,
|
|
// "ext_info": null,
|
|
// "result": {
|
|
// "status": "1",
|
|
// "riskRate": "0",
|
|
// "acctBalanceSum": "0.000486213817680857",
|
|
// "debtBalanceSum": "0",
|
|
// "loanAccountList": [
|
|
// {
|
|
// "tokenId": "BTC",
|
|
// "total": "0.00048621",
|
|
// "locked": "0",
|
|
// "loan": "0",
|
|
// "interest": "0",
|
|
// "free": "0.00048621"
|
|
// },
|
|
// ...
|
|
// ]
|
|
// }
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var rows interface{} = this.SafeList(data, "loanAccountList", []interface{}{})
|
|
var interest interface{} = this.ParseBorrowInterests(rows, nil)
|
|
|
|
ch <- this.FilterByCurrencySinceLimit(interest, code, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchBorrowRateHistory
|
|
* @description retrieves a history of a currencies borrow interest rate at specific time slots
|
|
* @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/historical-interest
|
|
* @param {string} code unified currency code
|
|
* @param {int} [since] timestamp for the earliest borrow rate
|
|
* @param {int} [limit] the maximum number of [borrow rate structures]{@link https://docs.ccxt.com/#/?id=borrow-rate-structure} 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
|
|
* @returns {object[]} an array of [borrow rate structures]{@link https://docs.ccxt.com/#/?id=borrow-rate-structure}
|
|
*/
|
|
func (this *bybit) FetchBorrowRateHistory(code 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
|
|
|
|
retRes71518 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes71518)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"currency": GetValue(currency, "id"),
|
|
}
|
|
if IsTrue(IsEqual(since, nil)) {
|
|
since = Subtract(this.Milliseconds(), Multiply(86400000, 30)) // last 30 days
|
|
}
|
|
AddElementToObject(request, "startTime", since)
|
|
var endTime interface{} = this.SafeInteger2(params, "until", "endTime")
|
|
params = this.Omit(params, []interface{}{"until"})
|
|
if IsTrue(IsEqual(endTime, nil)) {
|
|
endTime = Add(since, Multiply(86400000, 30)) // since + 30 days
|
|
}
|
|
AddElementToObject(request, "endTime", endTime)
|
|
|
|
response:= (<-this.PrivateGetV5SpotMarginTradeInterestRateHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "timestamp": 1721469600000,
|
|
// "currency": "USDC",
|
|
// "hourlyBorrowRate": "0.000014621596",
|
|
// "vipLevel": "No VIP"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": "{}",
|
|
// "time": 1721899048991
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "result")
|
|
var rows interface{} = this.SafeList(data, "list", []interface{}{})
|
|
|
|
ch <- this.ParseBorrowRateHistory(rows, code, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseBorrowInterest(info interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "tokenId": "BTC",
|
|
// "total": "0.00048621",
|
|
// "locked": "0",
|
|
// "loan": "0",
|
|
// "interest": "0",
|
|
// "free": "0.00048621"
|
|
// },
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
return map[string]interface{} {
|
|
"info": info,
|
|
"symbol": nil,
|
|
"currency": this.SafeCurrencyCode(this.SafeString(info, "tokenId")),
|
|
"interest": this.SafeNumber(info, "interest"),
|
|
"interestRate": nil,
|
|
"amountBorrowed": this.SafeNumber(info, "loan"),
|
|
"marginMode": "cross",
|
|
"timestamp": nil,
|
|
"datetime": nil,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#transfer
|
|
* @description transfer currency internally between wallets on the same account
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/create-inter-transfer
|
|
* @param {string} code unified currency code
|
|
* @param {float} amount amount to transfer
|
|
* @param {string} fromAccount account to transfer from
|
|
* @param {string} toAccount account to transfer to
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.transferId] UUID, which is unique across the platform
|
|
* @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes72288 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes72288)
|
|
var transferId interface{} = this.SafeString(params, "transferId", this.Uuid())
|
|
var accountTypes interface{} = this.SafeDict(this.Options, "accountsByType", map[string]interface{} {})
|
|
var fromId interface{} = this.SafeString(accountTypes, fromAccount, fromAccount)
|
|
var toId interface{} = this.SafeString(accountTypes, toAccount, toAccount)
|
|
var currency interface{} = this.Currency(code)
|
|
var amountToPrecision interface{} = this.CurrencyToPrecision(code, amount)
|
|
var request interface{} = map[string]interface{} {
|
|
"transferId": transferId,
|
|
"fromAccountType": fromId,
|
|
"toAccountType": toId,
|
|
"coin": GetValue(currency, "id"),
|
|
"amount": amountToPrecision,
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5AssetTransferInterTransfer(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "transferId": "4244af44-f3b0-4cf6-a743-b56560e987bc"
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1666875857205
|
|
// }
|
|
//
|
|
var timestamp interface{} = this.SafeInteger(response, "time")
|
|
var transfer interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var statusRaw interface{} = this.SafeStringN(response, []interface{}{"retCode", "retMsg"})
|
|
var status interface{} = this.ParseTransferStatus(statusRaw)
|
|
|
|
ch <- this.Extend(this.ParseTransfer(transfer, currency), map[string]interface{} {
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"amount": this.ParseNumber(amountToPrecision),
|
|
"fromAccount": fromAccount,
|
|
"toAccount": toAccount,
|
|
"status": status,
|
|
})
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchTransfers
|
|
* @description fetch a history of internal transfers made on an account
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/inter-transfer-list
|
|
* @param {string} code unified currency code of the currency transferred
|
|
* @param {int} [since] the earliest time in ms to fetch transfers for
|
|
* @param {int} [limit] the maximum number of transfer structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
* @returns {object[]} a list of [transfer structures]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
*/
|
|
func (this *bybit) FetchTransfers(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
|
|
|
|
retRes72828 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes72828)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchTransfers", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes728619 := (<-this.FetchPaginatedCallCursor("fetchTransfers", code, since, limit, params, "nextPageCursor", "cursor", nil, 50))
|
|
PanicOnError(retRes728619)
|
|
ch <- retRes728619
|
|
return nil
|
|
}
|
|
var currency interface{} = nil
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.SafeCurrency(code)
|
|
AddElementToObject(request, "coin", GetValue(currency, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
requestparamsVariable := this.HandleUntilOption("endTime", request, params);
|
|
request = GetValue(requestparamsVariable,0);
|
|
params = GetValue(requestparamsVariable,1)
|
|
|
|
response:= (<-this.PrivateGetV5AssetTransferQueryInterTransferList(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "transferId": "selfTransfer_a1091cc7-9364-4b74-8de1-18f02c6f2d5c",
|
|
// "coin": "USDT",
|
|
// "amount": "5000",
|
|
// "fromAccountType": "SPOT",
|
|
// "toAccountType": "UNIFIED",
|
|
// "timestamp": "1667283263000",
|
|
// "status": "SUCCESS"
|
|
// }
|
|
// ],
|
|
// "nextPageCursor": "eyJtaW5JRCI6MTM1ODQ2OCwibWF4SUQiOjEzNTg0Njh9"
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1670988271677
|
|
// }
|
|
//
|
|
var data interface{} = this.AddPaginationCursorToResult(response)
|
|
|
|
ch <- this.ParseTransfers(data, currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#borrowCrossMargin
|
|
* @description create a loan to borrow margin
|
|
* @see https://bybit-exchange.github.io/docs/v5/spot-margin-normal/borrow
|
|
* @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 *bybit) 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
|
|
|
|
retRes73398 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes73398)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"coin": GetValue(currency, "id"),
|
|
"qty": this.CurrencyToPrecision(code, amount),
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5SpotCrossMarginTradeLoan(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "transactId": "14143"
|
|
// },
|
|
// "retExtInfo": null,
|
|
// "time": 1662617848970
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var transaction interface{} = this.ParseMarginLoan(result, currency)
|
|
|
|
ch <- this.Extend(transaction, map[string]interface{} {
|
|
"symbol": nil,
|
|
"amount": amount,
|
|
})
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#repayCrossMargin
|
|
* @description repay borrowed margin and interest
|
|
* @see https://bybit-exchange.github.io/docs/v5/spot-margin-normal/repay
|
|
* @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 *bybit) 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
|
|
|
|
retRes73768 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes73768)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"coin": GetValue(currency, "id"),
|
|
"qty": this.NumberToString(amount),
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5SpotCrossMarginTradeRepay(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "repayId": "12128"
|
|
// },
|
|
// "retExtInfo": null,
|
|
// "time": 1662618298452
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var transaction interface{} = this.ParseMarginLoan(result, currency)
|
|
|
|
ch <- this.Extend(transaction, map[string]interface{} {
|
|
"symbol": nil,
|
|
"amount": amount,
|
|
})
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseMarginLoan(info interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// borrowCrossMargin
|
|
//
|
|
// {
|
|
// "transactId": "14143"
|
|
// }
|
|
//
|
|
// repayCrossMargin
|
|
//
|
|
// {
|
|
// "repayId": "12128"
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
return map[string]interface{} {
|
|
"id": this.SafeString2(info, "transactId", "repayId"),
|
|
"currency": this.SafeString(currency, "code"),
|
|
"amount": nil,
|
|
"symbol": nil,
|
|
"timestamp": nil,
|
|
"datetime": nil,
|
|
"info": info,
|
|
}
|
|
}
|
|
func (this *bybit) ParseTransferStatus(status interface{}) interface{} {
|
|
var statuses interface{} = map[string]interface{} {
|
|
"0": "ok",
|
|
"OK": "ok",
|
|
"SUCCESS": "ok",
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *bybit) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// transfer
|
|
//
|
|
// {
|
|
// "transferId": "22c2bc11-ed5b-49a4-8647-c4e0f5f6f2b2"
|
|
// }
|
|
//
|
|
// fetchTransfers
|
|
//
|
|
// {
|
|
// "transferId": "e9c421c4-b010-4b16-abd6-106179f27702",
|
|
// "coin": "USDT",
|
|
// "amount": "8",
|
|
// "fromAccountType": "FUND",
|
|
// "toAccountType": "SPOT",
|
|
// "timestamp": "1666879426000",
|
|
// "status": "SUCCESS"
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var currencyId interface{} = this.SafeString(transfer, "coin")
|
|
var timestamp interface{} = this.SafeInteger(transfer, "timestamp")
|
|
var fromAccountId interface{} = this.SafeString(transfer, "fromAccountType")
|
|
var toAccountId interface{} = this.SafeString(transfer, "toAccountType")
|
|
var accountIds interface{} = this.SafeDict(this.Options, "accountsById", map[string]interface{} {})
|
|
var fromAccount interface{} = this.SafeString(accountIds, fromAccountId, fromAccountId)
|
|
var toAccount interface{} = this.SafeString(accountIds, toAccountId, toAccountId)
|
|
return map[string]interface{} {
|
|
"info": transfer,
|
|
"id": this.SafeString(transfer, "transferId"),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"currency": this.SafeCurrencyCode(currencyId, currency),
|
|
"amount": this.SafeNumber(transfer, "amount"),
|
|
"fromAccount": fromAccount,
|
|
"toAccount": toAccount,
|
|
"status": this.ParseTransferStatus(this.SafeString(transfer, "status")),
|
|
}
|
|
}
|
|
func (this *bybit) FetchDerivativesMarketLeverageTiers(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
|
|
|
|
retRes74778 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes74778)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
AddElementToObject(request, "category", "linear")
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
AddElementToObject(request, "category", "inverse")
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketRiskLimit(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "category": "inverse",
|
|
// "list": [
|
|
// {
|
|
// "id": 1,
|
|
// "symbol": "BTCUSD",
|
|
// "riskLimitValue": "150",
|
|
// "maintenanceMargin": "0.5",
|
|
// "initialMargin": "1",
|
|
// "isLowestRisk": 1,
|
|
// "maxLeverage": "100.00"
|
|
// },
|
|
// ....
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672054488010
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result")
|
|
var tiers interface{} = this.SafeList(result, "list")
|
|
|
|
ch <- this.ParseMarketLeverageTiers(tiers, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchMarketLeverageTiers
|
|
* @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes for a single market
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/risk-limit
|
|
* @param {string} symbol unified market symbol
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [leverage tiers structure]{@link https://docs.ccxt.com/#/?id=leverage-tiers-structure}
|
|
*/
|
|
func (this *bybit) FetchMarketLeverageTiers(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
|
|
|
|
retRes75268 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes75268)
|
|
var request interface{} = map[string]interface{} {}
|
|
var market interface{} = nil
|
|
market = this.Market(symbol)
|
|
if IsTrue(IsTrue(GetValue(market, "spot")) || IsTrue(GetValue(market, "option"))) {
|
|
panic(BadRequest(Add(Add(this.Id, " fetchMarketLeverageTiers() symbol does not support market "), symbol)))
|
|
}
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
|
|
retRes753415 := (<-this.FetchDerivativesMarketLeverageTiers(symbol, params))
|
|
PanicOnError(retRes753415)
|
|
ch <- retRes753415
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseTradingFee(fee interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "symbol": "ETHUSDT",
|
|
// "makerFeeRate": 0.001,
|
|
// "takerFeeRate": 0.001
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var marketId interface{} = this.SafeString(fee, "symbol")
|
|
var defaultType interface{} = Ternary(IsTrue((!IsEqual(market, nil))), GetValue(market, "type"), "contract")
|
|
var symbol interface{} = this.SafeSymbol(marketId, market, nil, defaultType)
|
|
return map[string]interface{} {
|
|
"info": fee,
|
|
"symbol": symbol,
|
|
"maker": this.SafeNumber(fee, "makerFeeRate"),
|
|
"taker": this.SafeNumber(fee, "takerFeeRate"),
|
|
"percentage": nil,
|
|
"tierBased": nil,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchTradingFee
|
|
* @description fetch the trading fees for a market
|
|
* @see https://bybit-exchange.github.io/docs/v5/account/fee-rate
|
|
* @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 *bybit) 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
|
|
|
|
retRes75688 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes75688)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
var category interface{} = nil
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
category = "linear"
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
category = "inverse"
|
|
} else if IsTrue(GetValue(market, "spot")) {
|
|
category = "spot"
|
|
} else {
|
|
category = "option"
|
|
}
|
|
AddElementToObject(request, "category", category)
|
|
|
|
response:= (<-this.PrivateGetV5AccountFeeRate(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "symbol": "ETHUSDT",
|
|
// "takerFeeRate": "0.0006",
|
|
// "makerFeeRate": "0.0001"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1676360412576
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var fees interface{} = this.SafeList(result, "list", []interface{}{})
|
|
var first interface{} = this.SafeDict(fees, 0, map[string]interface{} {})
|
|
|
|
ch <- this.ParseTradingFee(first, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchTradingFees
|
|
* @description fetch the trading fees for multiple markets
|
|
* @see https://bybit-exchange.github.io/docs/v5/account/fee-rate
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
|
|
*/
|
|
func (this *bybit) FetchTradingFees(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes76188 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes76188)
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.HandleOptionAndParams(params, "fetchTradingFees", "type", "future");
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
if IsTrue(IsEqual(typeVar, "spot")) {
|
|
panic(NotSupported(Add(this.Id, " fetchTradingFees() is not supported for spot market")))
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5AccountFeeRate(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "symbol": "ETHUSDT",
|
|
// "takerFeeRate": "0.0006",
|
|
// "makerFeeRate": "0.0001"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1676360412576
|
|
// }
|
|
//
|
|
var fees interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
fees = this.SafeList(fees, "list", []interface{}{})
|
|
var result interface{} = map[string]interface{} {}
|
|
for i := 0; IsLessThan(i, GetArrayLength(fees)); i++ {
|
|
var fee interface{} = this.ParseTradingFee(GetValue(fees, i))
|
|
var symbol interface{} = GetValue(fee, "symbol")
|
|
AddElementToObject(result, symbol, fee)
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseDepositWithdrawFee(fee interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "name": "BTC",
|
|
// "coin": "BTC",
|
|
// "remainAmount": "150",
|
|
// "chains": [
|
|
// {
|
|
// "chainType": "BTC",
|
|
// "confirmation": "10000",
|
|
// "withdrawFee": "0.0005",
|
|
// "depositMin": "0.0005",
|
|
// "withdrawMin": "0.001",
|
|
// "chain": "BTC",
|
|
// "chainDeposit": "1",
|
|
// "chainWithdraw": "1",
|
|
// "minAccuracy": "8"
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var chains interface{} = this.SafeList(fee, "chains", []interface{}{})
|
|
var chainsLength interface{} = GetArrayLength(chains)
|
|
var result interface{} = map[string]interface{} {
|
|
"info": fee,
|
|
"withdraw": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
"deposit": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
"networks": map[string]interface{} {},
|
|
}
|
|
if IsTrue(!IsEqual(chainsLength, 0)) {
|
|
for i := 0; IsLessThan(i, chainsLength); i++ {
|
|
var chain interface{} = GetValue(chains, i)
|
|
var networkId interface{} = this.SafeString(chain, "chain")
|
|
var currencyCode interface{} = this.SafeString(currency, "code")
|
|
var networkCode interface{} = this.NetworkIdToCode(networkId, currencyCode)
|
|
AddElementToObject(GetValue(result, "networks"), networkCode, map[string]interface{} {
|
|
"deposit": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
"withdraw": map[string]interface{} {
|
|
"fee": this.SafeNumber(chain, "withdrawFee"),
|
|
"percentage": false,
|
|
},
|
|
})
|
|
if IsTrue(IsEqual(chainsLength, 1)) {
|
|
AddElementToObject(GetValue(result, "withdraw"), "fee", this.SafeNumber(chain, "withdrawFee"))
|
|
AddElementToObject(GetValue(result, "withdraw"), "percentage", false)
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchDepositWithdrawFees
|
|
* @description fetch deposit and withdraw fees
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/coin-info
|
|
* @param {string[]} codes list of unified currency codes
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
this.CheckRequiredCredentials()
|
|
|
|
retRes77188 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes77188)
|
|
|
|
response:= (<-this.PrivateGetV5AssetCoinQueryInfo(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "",
|
|
// "result": {
|
|
// "rows": [
|
|
// {
|
|
// "name": "BTC",
|
|
// "coin": "BTC",
|
|
// "remainAmount": "150",
|
|
// "chains": [
|
|
// {
|
|
// "chainType": "BTC",
|
|
// "confirmation": "10000",
|
|
// "withdrawFee": "0.0005",
|
|
// "depositMin": "0.0005",
|
|
// "withdrawMin": "0.001",
|
|
// "chain": "BTC",
|
|
// "chainDeposit": "1",
|
|
// "chainWithdraw": "1",
|
|
// "minAccuracy": "8"
|
|
// }
|
|
// ]
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672194582264
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var rows interface{} = this.SafeList(data, "rows", []interface{}{})
|
|
|
|
ch <- this.ParseDepositWithdrawFees(rows, codes, "coin")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchSettlementHistory
|
|
* @description fetches historical settlement records
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/delivery-price
|
|
* @param {string} symbol unified market symbol of the settlement history
|
|
* @param {int} [since] timestamp in ms
|
|
* @param {int} [limit] number of records
|
|
* @param {object} [params] exchange specific params
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @returns {object[]} a list of [settlement history objects]
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes77698 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes77698)
|
|
var request interface{} = map[string]interface{} {}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchSettlementHistory", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
if IsTrue(IsEqual(typeVar, "spot")) {
|
|
panic(NotSupported(Add(this.Id, " fetchSettlementHistory() is not supported for spot market")))
|
|
}
|
|
AddElementToObject(request, "category", typeVar)
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketDeliveryPrice(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "category": "option",
|
|
// "nextPageCursor": "0%2C3",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "SOL-27JUN23-20-C",
|
|
// "deliveryPrice": "16.62258889",
|
|
// "deliveryTime": "1687852800000"
|
|
// },
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1689043527231
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var data interface{} = this.SafeList(result, "list", []interface{}{})
|
|
var settlements interface{} = this.ParseSettlements(data, market)
|
|
var sorted interface{} = this.SortBy(settlements, "timestamp")
|
|
|
|
ch <- this.FilterBySymbolSinceLimit(sorted, GetValue(market, "symbol"), since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchMySettlementHistory
|
|
* @description fetches historical settlement records of the user
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/delivery
|
|
* @param {string} symbol unified market symbol of the settlement history
|
|
* @param {int} [since] timestamp in ms
|
|
* @param {int} [limit] number of records
|
|
* @param {object} [params] exchange specific params
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @returns {object[]} a list of [settlement history objects]
|
|
*/
|
|
func (this *bybit) FetchMySettlementHistory(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
|
|
|
|
retRes78268 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes78268)
|
|
var request interface{} = map[string]interface{} {}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchMySettlementHistory", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
if IsTrue(IsTrue(IsEqual(typeVar, "spot")) || IsTrue(IsEqual(typeVar, "inverse"))) {
|
|
panic(NotSupported(Add(this.Id, " fetchMySettlementHistory() is not supported for spot market")))
|
|
}
|
|
AddElementToObject(request, "category", "linear")
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5AssetDeliveryRecord(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "success",
|
|
// "result": {
|
|
// "category": "option",
|
|
// "nextPageCursor": "0%2C3",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "SOL-27JUN23-20-C",
|
|
// "deliveryPrice": "16.62258889",
|
|
// "deliveryTime": "1687852800000",
|
|
// "side": "Buy",
|
|
// "strike": "20",
|
|
// "fee": "0.00000000",
|
|
// "position": "0.01",
|
|
// "deliveryRpl": "3.5"
|
|
// },
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1689043527231
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var data interface{} = this.SafeList(result, "list", []interface{}{})
|
|
var settlements interface{} = this.ParseSettlements(data, market)
|
|
var sorted interface{} = this.SortBy(settlements, "timestamp")
|
|
|
|
ch <- this.FilterBySymbolSinceLimit(sorted, GetValue(market, "symbol"), since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseSettlement(settlement interface{}, market interface{}) interface{} {
|
|
//
|
|
// fetchSettlementHistory
|
|
//
|
|
// {
|
|
// "symbol": "SOL-27JUN23-20-C",
|
|
// "deliveryPrice": "16.62258889",
|
|
// "deliveryTime": "1687852800000"
|
|
// }
|
|
//
|
|
// fetchMySettlementHistory
|
|
//
|
|
// {
|
|
// "symbol": "SOL-27JUN23-20-C",
|
|
// "deliveryPrice": "16.62258889",
|
|
// "deliveryTime": "1687852800000",
|
|
// "side": "Buy",
|
|
// "strike": "20",
|
|
// "fee": "0.00000000",
|
|
// "position": "0.01",
|
|
// "deliveryRpl": "3.5"
|
|
// }
|
|
//
|
|
var timestamp interface{} = this.SafeInteger(settlement, "deliveryTime")
|
|
var marketId interface{} = this.SafeString(settlement, "symbol")
|
|
return map[string]interface{} {
|
|
"info": settlement,
|
|
"symbol": this.SafeSymbol(marketId, market),
|
|
"price": this.SafeNumber(settlement, "deliveryPrice"),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
}
|
|
}
|
|
func (this *bybit) ParseSettlements(settlements interface{}, market interface{}) interface{} {
|
|
//
|
|
// fetchSettlementHistory
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol": "SOL-27JUN23-20-C",
|
|
// "deliveryPrice": "16.62258889",
|
|
// "deliveryTime": "1687852800000"
|
|
// }
|
|
// ]
|
|
//
|
|
// fetchMySettlementHistory
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol": "SOL-27JUN23-20-C",
|
|
// "deliveryPrice": "16.62258889",
|
|
// "deliveryTime": "1687852800000",
|
|
// "side": "Buy",
|
|
// "strike": "20",
|
|
// "fee": "0.00000000",
|
|
// "position": "0.01",
|
|
// "deliveryRpl": "3.5"
|
|
// }
|
|
// ]
|
|
//
|
|
var result interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(settlements)); i++ {
|
|
AppendToArray(&result,this.ParseSettlement(GetValue(settlements, i), market))
|
|
}
|
|
return result
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchVolatilityHistory
|
|
* @description fetch the historical volatility of an option market based on an underlying asset
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/iv
|
|
* @param {string} code unified currency code
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.period] the period in days to fetch the volatility for: 7,14,21,30,60,90,180,270
|
|
* @returns {object[]} a list of [volatility history objects]{@link https://docs.ccxt.com/#/?id=volatility-structure}
|
|
*/
|
|
func (this *bybit) FetchVolatilityHistory(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
|
|
|
|
retRes79538 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes79538)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"category": "option",
|
|
"baseCoin": GetValue(currency, "id"),
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketHistoricalVolatility(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "SUCCESS",
|
|
// "category": "option",
|
|
// "result": [
|
|
// {
|
|
// "period": 7,
|
|
// "value": "0.23854072",
|
|
// "time": "1690574400000"
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
var volatility interface{} = this.SafeList(response, "result", []interface{}{})
|
|
|
|
ch <- this.ParseVolatilityHistory(volatility)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseVolatilityHistory(volatility interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "period": 7,
|
|
// "value": "0.23854072",
|
|
// "time": "1690574400000"
|
|
// }
|
|
//
|
|
var result interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(volatility)); i++ {
|
|
var entry interface{} = GetValue(volatility, i)
|
|
var timestamp interface{} = this.SafeInteger(entry, "time")
|
|
AppendToArray(&result,map[string]interface{} {
|
|
"info": volatility,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"volatility": this.SafeNumber(entry, "value"),
|
|
})
|
|
}
|
|
return result
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchGreeks
|
|
* @description fetches an option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
|
|
* @see https://bybit-exchange.github.io/docs/api-explorer/v5/market/tickers
|
|
* @param {string} symbol unified symbol of the market to fetch greeks for
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [greeks structure]{@link https://docs.ccxt.com/#/?id=greeks-structure}
|
|
*/
|
|
func (this *bybit) FetchGreeks(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
|
|
|
|
retRes80108 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes80108)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
"category": "option",
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketTickers(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "SUCCESS",
|
|
// "result": {
|
|
// "category": "option",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTC-26JAN24-39000-C",
|
|
// "bid1Price": "3205",
|
|
// "bid1Size": "7.1",
|
|
// "bid1Iv": "0.5478",
|
|
// "ask1Price": "3315",
|
|
// "ask1Size": "1.98",
|
|
// "ask1Iv": "0.5638",
|
|
// "lastPrice": "3230",
|
|
// "highPrice24h": "3255",
|
|
// "lowPrice24h": "3200",
|
|
// "markPrice": "3273.02263032",
|
|
// "indexPrice": "36790.96",
|
|
// "markIv": "0.5577",
|
|
// "underlyingPrice": "37649.67254894",
|
|
// "openInterest": "19.67",
|
|
// "turnover24h": "170140.33875912",
|
|
// "volume24h": "4.56",
|
|
// "totalVolume": "22",
|
|
// "totalTurnover": "789305",
|
|
// "delta": "0.49640971",
|
|
// "gamma": "0.00004131",
|
|
// "vega": "69.08651675",
|
|
// "theta": "-24.9443226",
|
|
// "predictedDeliveryPrice": "0",
|
|
// "change24h": "0.18532111"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1699584008326
|
|
// }
|
|
//
|
|
var timestamp interface{} = this.SafeInteger(response, "time")
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var data interface{} = this.SafeList(result, "list", []interface{}{})
|
|
var greeks interface{} = this.ParseGreeks(GetValue(data, 0), market)
|
|
|
|
ch <- this.Extend(greeks, map[string]interface{} {
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
})
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseGreeks(greeks interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "symbol": "BTC-26JAN24-39000-C",
|
|
// "bid1Price": "3205",
|
|
// "bid1Size": "7.1",
|
|
// "bid1Iv": "0.5478",
|
|
// "ask1Price": "3315",
|
|
// "ask1Size": "1.98",
|
|
// "ask1Iv": "0.5638",
|
|
// "lastPrice": "3230",
|
|
// "highPrice24h": "3255",
|
|
// "lowPrice24h": "3200",
|
|
// "markPrice": "3273.02263032",
|
|
// "indexPrice": "36790.96",
|
|
// "markIv": "0.5577",
|
|
// "underlyingPrice": "37649.67254894",
|
|
// "openInterest": "19.67",
|
|
// "turnover24h": "170140.33875912",
|
|
// "volume24h": "4.56",
|
|
// "totalVolume": "22",
|
|
// "totalTurnover": "789305",
|
|
// "delta": "0.49640971",
|
|
// "gamma": "0.00004131",
|
|
// "vega": "69.08651675",
|
|
// "theta": "-24.9443226",
|
|
// "predictedDeliveryPrice": "0",
|
|
// "change24h": "0.18532111"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var marketId interface{} = this.SafeString(greeks, "symbol")
|
|
var symbol interface{} = this.SafeSymbol(marketId, market)
|
|
return map[string]interface{} {
|
|
"symbol": symbol,
|
|
"timestamp": nil,
|
|
"datetime": nil,
|
|
"delta": this.SafeNumber(greeks, "delta"),
|
|
"gamma": this.SafeNumber(greeks, "gamma"),
|
|
"theta": this.SafeNumber(greeks, "theta"),
|
|
"vega": this.SafeNumber(greeks, "vega"),
|
|
"rho": nil,
|
|
"bidSize": this.SafeNumber(greeks, "bid1Size"),
|
|
"askSize": this.SafeNumber(greeks, "ask1Size"),
|
|
"bidImpliedVolatility": this.SafeNumber(greeks, "bid1Iv"),
|
|
"askImpliedVolatility": this.SafeNumber(greeks, "ask1Iv"),
|
|
"markImpliedVolatility": this.SafeNumber(greeks, "markIv"),
|
|
"bidPrice": this.SafeNumber(greeks, "bid1Price"),
|
|
"askPrice": this.SafeNumber(greeks, "ask1Price"),
|
|
"markPrice": this.SafeNumber(greeks, "markPrice"),
|
|
"lastPrice": this.SafeNumber(greeks, "lastPrice"),
|
|
"underlyingPrice": this.SafeNumber(greeks, "underlyingPrice"),
|
|
"info": greeks,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchMyLiquidations
|
|
* @description retrieves the users liquidated positions
|
|
* @see https://bybit-exchange.github.io/docs/api-explorer/v5/position/execution
|
|
* @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 exchange API endpoint
|
|
* @param {string} [params.type] market type, ['swap', 'option', 'spot']
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse']
|
|
* @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} an array of [liquidation structures]{@link https://docs.ccxt.com/#/?id=liquidation-structure}
|
|
*/
|
|
func (this *bybit) FetchMyLiquidations(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
|
|
|
|
retRes81378 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes81378)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchMyLiquidations", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes814119 := (<-this.FetchPaginatedCallCursor("fetchMyLiquidations", symbol, since, limit, params, "nextPageCursor", "cursor", nil, 100))
|
|
PanicOnError(retRes814119)
|
|
ch <- retRes814119
|
|
return nil
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"execType": "BustTrade",
|
|
}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchMyLiquidations", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
AddElementToObject(request, "category", typeVar)
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
requestparamsVariable := this.HandleUntilOption("endTime", request, params);
|
|
request = GetValue(requestparamsVariable,0);
|
|
params = GetValue(requestparamsVariable,1)
|
|
|
|
response:= (<-this.PrivateGetV5ExecutionList(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "nextPageCursor": "132766%3A2%2C132766%3A2",
|
|
// "category": "linear",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "ETHPERP",
|
|
// "orderType": "Market",
|
|
// "underlyingPrice": "",
|
|
// "orderLinkId": "",
|
|
// "side": "Buy",
|
|
// "indexPrice": "",
|
|
// "orderId": "8c065341-7b52-4ca9-ac2c-37e31ac55c94",
|
|
// "stopOrderType": "UNKNOWN",
|
|
// "leavesQty": "0",
|
|
// "execTime": "1672282722429",
|
|
// "isMaker": false,
|
|
// "execFee": "0.071409",
|
|
// "feeRate": "0.0006",
|
|
// "execId": "e0cbe81d-0f18-5866-9415-cf319b5dab3b",
|
|
// "tradeIv": "",
|
|
// "blockTradeId": "",
|
|
// "markPrice": "1183.54",
|
|
// "execPrice": "1190.15",
|
|
// "markIv": "",
|
|
// "orderQty": "0.1",
|
|
// "orderPrice": "1236.9",
|
|
// "execValue": "119.015",
|
|
// "execType": "Trade",
|
|
// "execQty": "0.1"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1672283754510
|
|
// }
|
|
//
|
|
var liquidations interface{} = this.AddPaginationCursorToResult(response)
|
|
|
|
ch <- this.ParseLiquidations(liquidations, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseLiquidation(liquidation interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "symbol": "ETHPERP",
|
|
// "orderType": "Market",
|
|
// "underlyingPrice": "",
|
|
// "orderLinkId": "",
|
|
// "side": "Buy",
|
|
// "indexPrice": "",
|
|
// "orderId": "8c065341-7b52-4ca9-ac2c-37e31ac55c94",
|
|
// "stopOrderType": "UNKNOWN",
|
|
// "leavesQty": "0",
|
|
// "execTime": "1672282722429",
|
|
// "isMaker": false,
|
|
// "execFee": "0.071409",
|
|
// "feeRate": "0.0006",
|
|
// "execId": "e0cbe81d-0f18-5866-9415-cf319b5dab3b",
|
|
// "tradeIv": "",
|
|
// "blockTradeId": "",
|
|
// "markPrice": "1183.54",
|
|
// "execPrice": "1190.15",
|
|
// "markIv": "",
|
|
// "orderQty": "0.1",
|
|
// "orderPrice": "1236.9",
|
|
// "execValue": "119.015",
|
|
// "execType": "Trade",
|
|
// "execQty": "0.1"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var marketId interface{} = this.SafeString(liquidation, "symbol")
|
|
var timestamp interface{} = this.SafeInteger(liquidation, "execTime")
|
|
var contractsString interface{} = this.SafeString(liquidation, "execQty")
|
|
var contractSizeString interface{} = this.SafeString(market, "contractSize")
|
|
var priceString interface{} = this.SafeString(liquidation, "execPrice")
|
|
var baseValueString interface{} = Precise.StringMul(contractsString, contractSizeString)
|
|
var quoteValueString interface{} = Precise.StringMul(baseValueString, priceString)
|
|
return this.SafeLiquidation(map[string]interface{} {
|
|
"info": liquidation,
|
|
"symbol": this.SafeSymbol(marketId, market, nil, "contract"),
|
|
"contracts": this.ParseNumber(contractsString),
|
|
"contractSize": this.ParseNumber(contractSizeString),
|
|
"price": this.ParseNumber(priceString),
|
|
"baseValue": this.ParseNumber(baseValueString),
|
|
"quoteValue": this.ParseNumber(quoteValueString),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
})
|
|
}
|
|
func (this *bybit) GetLeverageTiersPaginated(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
|
|
|
|
retRes82568 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes82568)
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
}
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "getLeverageTiersPaginated", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes826419 := (<-this.FetchPaginatedCallCursor("getLeverageTiersPaginated", symbol, nil, nil, params, "nextPageCursor", "cursor", nil, 100))
|
|
PanicOnError(retRes826419)
|
|
ch <- retRes826419
|
|
return nil
|
|
}
|
|
var subType interface{} = nil
|
|
subTypeparamsVariable := this.HandleSubTypeAndParams("getLeverageTiersPaginated", market, params, "linear");
|
|
subType = GetValue(subTypeparamsVariable,0);
|
|
params = GetValue(subTypeparamsVariable,1)
|
|
var request interface{} = map[string]interface{} {
|
|
"category": subType,
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketRiskLimit(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
var result interface{} = this.AddPaginationCursorToResult(response)
|
|
var first interface{} = this.SafeDict(result, 0)
|
|
var total interface{} = GetArrayLength(result)
|
|
var lastIndex interface{} = Subtract(total, 1)
|
|
var last interface{} = this.SafeDict(result, lastIndex)
|
|
var cursorValue interface{} = this.SafeString(first, "nextPageCursor")
|
|
AddElementToObject(last, "info", map[string]interface{} {
|
|
"nextPageCursor": cursorValue,
|
|
})
|
|
AddElementToObject(result, lastIndex, last)
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchLeverageTiers
|
|
* @description retrieve information on the maximum leverage, for different trade sizes
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/risk-limit
|
|
* @param {string[]} [symbols] a list of unified market symbols
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.subType] market subType, ['linear', 'inverse'], default is 'linear'
|
|
* @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 dictionary of [leverage tiers structures]{@link https://docs.ccxt.com/#/?id=leverage-tiers-structure}, indexed by market symbols
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes82978 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes82978)
|
|
var market interface{} = nil
|
|
var symbol interface{} = nil
|
|
if IsTrue(!IsEqual(symbols, nil)) {
|
|
market = this.Market(GetValue(symbols, 0))
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
panic(NotSupported(Add(this.Id, " fetchLeverageTiers() is not supported for spot market")))
|
|
}
|
|
symbol = GetValue(market, "symbol")
|
|
}
|
|
|
|
data:= (<-this.GetLeverageTiersPaginated(symbol, this.Extend(map[string]interface{} {
|
|
"paginate": true,
|
|
"paginationCalls": 40,
|
|
}, params)))
|
|
PanicOnError(data)
|
|
symbols = this.MarketSymbols(symbols)
|
|
|
|
ch <- this.ParseLeverageTiers(data, symbols, "symbol")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseLeverageTiers(response interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// [
|
|
// {
|
|
// "id": 1,
|
|
// "symbol": "BTCUSD",
|
|
// "riskLimitValue": "150",
|
|
// "maintenanceMargin": "0.5",
|
|
// "initialMargin": "1",
|
|
// "isLowestRisk": 1,
|
|
// "maxLeverage": "100.00"
|
|
// }
|
|
// ]
|
|
//
|
|
symbols := GetArg(optionalArgs, 0, nil)
|
|
_ = symbols
|
|
marketIdKey := GetArg(optionalArgs, 1, nil)
|
|
_ = marketIdKey
|
|
var tiers interface{} = map[string]interface{} {}
|
|
var marketIds interface{} = this.MarketIds(symbols)
|
|
var filteredResults interface{} = this.FilterByArray(response, marketIdKey, marketIds, false)
|
|
var grouped interface{} = this.GroupBy(filteredResults, marketIdKey)
|
|
var keys interface{} = ObjectKeys(grouped)
|
|
for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ {
|
|
var marketId interface{} = GetValue(keys, i)
|
|
var entry interface{} = GetValue(grouped, marketId)
|
|
for j := 0; IsLessThan(j, GetArrayLength(entry)); j++ {
|
|
var id interface{} = this.SafeInteger(GetValue(entry, j), "id")
|
|
AddElementToObject(GetValue(entry, j), "id", id)
|
|
}
|
|
var market interface{} = this.SafeMarket(marketId, nil, nil, "contract")
|
|
var symbol interface{} = GetValue(market, "symbol")
|
|
AddElementToObject(tiers, symbol, this.ParseMarketLeverageTiers(this.SortBy(entry, "id"), market))
|
|
}
|
|
return tiers
|
|
}
|
|
func (this *bybit) ParseMarketLeverageTiers(info interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// [
|
|
// {
|
|
// "id": 1,
|
|
// "symbol": "BTCUSD",
|
|
// "riskLimitValue": "150",
|
|
// "maintenanceMargin": "0.5",
|
|
// "initialMargin": "1",
|
|
// "isLowestRisk": 1,
|
|
// "maxLeverage": "100.00"
|
|
// }
|
|
// ]
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var tiers interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(info)); i++ {
|
|
var tier interface{} = GetValue(info, i)
|
|
var marketId interface{} = this.SafeString(info, "symbol")
|
|
market = this.SafeMarket(marketId)
|
|
var minNotional interface{} = this.ParseNumber("0")
|
|
if IsTrue(!IsEqual(i, 0)) {
|
|
minNotional = this.SafeNumber(GetValue(info, Subtract(i, 1)), "riskLimitValue")
|
|
}
|
|
AppendToArray(&tiers,map[string]interface{} {
|
|
"tier": this.SafeInteger(tier, "id"),
|
|
"symbol": this.SafeSymbol(marketId, market),
|
|
"currency": GetValue(market, "settle"),
|
|
"minNotional": minNotional,
|
|
"maxNotional": this.SafeNumber(tier, "riskLimitValue"),
|
|
"maintenanceMarginRate": this.SafeNumber(tier, "maintenanceMargin"),
|
|
"maxLeverage": this.SafeNumber(tier, "maxLeverage"),
|
|
"info": tier,
|
|
})
|
|
}
|
|
return tiers
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchFundingHistory
|
|
* @description fetch the history of funding payments paid and received on this account
|
|
* @see https://bybit-exchange.github.io/docs/api-explorer/v5/position/execution
|
|
* @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
|
|
* @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 [funding history structure]{@link https://docs.ccxt.com/#/?id=funding-history-structure}
|
|
*/
|
|
func (this *bybit) 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
|
|
|
|
retRes83958 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes83958)
|
|
var paginate interface{} = false
|
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchFundingHistory", "paginate");
|
|
paginate = GetValue(paginateparamsVariable,0);
|
|
params = GetValue(paginateparamsVariable,1)
|
|
if IsTrue(paginate) {
|
|
|
|
retRes839919 := (<-this.FetchPaginatedCallCursor("fetchFundingHistory", symbol, since, limit, params, "nextPageCursor", "cursor", nil, 100))
|
|
PanicOnError(retRes839919)
|
|
ch <- retRes839919
|
|
return nil
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"execType": "Funding",
|
|
}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchFundingHistory", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
AddElementToObject(request, "category", typeVar)
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "size", limit)
|
|
} else {
|
|
AddElementToObject(request, "size", 100)
|
|
}
|
|
requestparamsVariable := this.HandleUntilOption("endTime", request, params);
|
|
request = GetValue(requestparamsVariable,0);
|
|
params = GetValue(requestparamsVariable,1)
|
|
|
|
response:= (<-this.PrivateGetV5ExecutionList(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
var fundings interface{} = this.AddPaginationCursorToResult(response)
|
|
|
|
ch <- this.ParseIncomes(fundings, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseIncome(income interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "symbol": "XMRUSDT",
|
|
// "orderType": "UNKNOWN",
|
|
// "underlyingPrice": "",
|
|
// "orderLinkId": "",
|
|
// "orderId": "a11e5fe2-1dbf-4bab-a9b2-af80a14efc5d",
|
|
// "stopOrderType": "UNKNOWN",
|
|
// "execTime": "1710950400000",
|
|
// "feeCurrency": "",
|
|
// "createType": "",
|
|
// "feeRate": "-0.000761",
|
|
// "tradeIv": "",
|
|
// "blockTradeId": "",
|
|
// "markPrice": "136.79",
|
|
// "execPrice": "137.11",
|
|
// "markIv": "",
|
|
// "orderQty": "0",
|
|
// "orderPrice": "0",
|
|
// "execValue": "134.3678",
|
|
// "closedSize": "0",
|
|
// "execType": "Funding",
|
|
// "seq": "28097658790",
|
|
// "side": "Sell",
|
|
// "indexPrice": "",
|
|
// "leavesQty": "0",
|
|
// "isMaker": false,
|
|
// "execFee": "-0.10232512",
|
|
// "execId": "8d1ef156-4ec6-4445-9a6c-1c0c24dbd046",
|
|
// "marketUnit": "",
|
|
// "execQty": "0.98",
|
|
// "nextPageCursor": "5774437%3A0%2C5771289%3A0"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var marketId interface{} = this.SafeString(income, "symbol")
|
|
market = this.SafeMarket(marketId, market, nil, "contract")
|
|
var code interface{} = "USDT"
|
|
if IsTrue(GetValue(market, "inverse")) {
|
|
code = GetValue(market, "quote")
|
|
}
|
|
var timestamp interface{} = this.SafeInteger(income, "execTime")
|
|
return map[string]interface{} {
|
|
"info": income,
|
|
"symbol": this.SafeSymbol(marketId, market, "-", "swap"),
|
|
"code": code,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"id": this.SafeString(income, "execId"),
|
|
"amount": this.SafeNumber(income, "execQty"),
|
|
"rate": this.SafeNumber(income, "feeRate"),
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOption
|
|
* @description fetches option data that is commonly found in an option chain
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/tickers
|
|
* @param {string} symbol unified market symbol
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} an [option chain structure]{@link https://docs.ccxt.com/#/?id=option-chain-structure}
|
|
*/
|
|
func (this *bybit) FetchOption(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
|
|
|
|
retRes84938 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes84938)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"category": "option",
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketTickers(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "SUCCESS",
|
|
// "result": {
|
|
// "category": "option",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTC-27DEC24-55000-P",
|
|
// "bid1Price": "0",
|
|
// "bid1Size": "0",
|
|
// "bid1Iv": "0",
|
|
// "ask1Price": "0",
|
|
// "ask1Size": "0",
|
|
// "ask1Iv": "0",
|
|
// "lastPrice": "10980",
|
|
// "highPrice24h": "0",
|
|
// "lowPrice24h": "0",
|
|
// "markPrice": "11814.66756236",
|
|
// "indexPrice": "63838.92",
|
|
// "markIv": "0.8866",
|
|
// "underlyingPrice": "71690.55303594",
|
|
// "openInterest": "0.01",
|
|
// "turnover24h": "0",
|
|
// "volume24h": "0",
|
|
// "totalVolume": "2",
|
|
// "totalTurnover": "78719",
|
|
// "delta": "-0.23284954",
|
|
// "gamma": "0.0000055",
|
|
// "vega": "191.70757975",
|
|
// "theta": "-30.43617927",
|
|
// "predictedDeliveryPrice": "0",
|
|
// "change24h": "0"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1711162003672
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var resultList interface{} = this.SafeList(result, "list", []interface{}{})
|
|
var chain interface{} = this.SafeDict(resultList, 0, map[string]interface{} {})
|
|
|
|
ch <- this.ParseOption(chain, nil, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchOptionChain
|
|
* @description fetches data for an underlying asset that is commonly found in an option chain
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/tickers
|
|
* @param {string} code base currency to fetch an option chain for
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a list of [option chain structures]{@link https://docs.ccxt.com/#/?id=option-chain-structure}
|
|
*/
|
|
func (this *bybit) FetchOptionChain(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
|
|
|
|
retRes85568 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes85568)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"category": "option",
|
|
"baseCoin": GetValue(currency, "id"),
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketTickers(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "SUCCESS",
|
|
// "result": {
|
|
// "category": "option",
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTC-27DEC24-55000-P",
|
|
// "bid1Price": "0",
|
|
// "bid1Size": "0",
|
|
// "bid1Iv": "0",
|
|
// "ask1Price": "0",
|
|
// "ask1Size": "0",
|
|
// "ask1Iv": "0",
|
|
// "lastPrice": "10980",
|
|
// "highPrice24h": "0",
|
|
// "lowPrice24h": "0",
|
|
// "markPrice": "11814.66756236",
|
|
// "indexPrice": "63838.92",
|
|
// "markIv": "0.8866",
|
|
// "underlyingPrice": "71690.55303594",
|
|
// "openInterest": "0.01",
|
|
// "turnover24h": "0",
|
|
// "volume24h": "0",
|
|
// "totalVolume": "2",
|
|
// "totalTurnover": "78719",
|
|
// "delta": "-0.23284954",
|
|
// "gamma": "0.0000055",
|
|
// "vega": "191.70757975",
|
|
// "theta": "-30.43617927",
|
|
// "predictedDeliveryPrice": "0",
|
|
// "change24h": "0"
|
|
// },
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1711162003672
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var resultList interface{} = this.SafeList(result, "list", []interface{}{})
|
|
|
|
ch <- this.ParseOptionChain(resultList, nil, "symbol")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseOption(chain interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "symbol": "BTC-27DEC24-55000-P",
|
|
// "bid1Price": "0",
|
|
// "bid1Size": "0",
|
|
// "bid1Iv": "0",
|
|
// "ask1Price": "0",
|
|
// "ask1Size": "0",
|
|
// "ask1Iv": "0",
|
|
// "lastPrice": "10980",
|
|
// "highPrice24h": "0",
|
|
// "lowPrice24h": "0",
|
|
// "markPrice": "11814.66756236",
|
|
// "indexPrice": "63838.92",
|
|
// "markIv": "0.8866",
|
|
// "underlyingPrice": "71690.55303594",
|
|
// "openInterest": "0.01",
|
|
// "turnover24h": "0",
|
|
// "volume24h": "0",
|
|
// "totalVolume": "2",
|
|
// "totalTurnover": "78719",
|
|
// "delta": "-0.23284954",
|
|
// "gamma": "0.0000055",
|
|
// "vega": "191.70757975",
|
|
// "theta": "-30.43617927",
|
|
// "predictedDeliveryPrice": "0",
|
|
// "change24h": "0"
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
market := GetArg(optionalArgs, 1, nil)
|
|
_ = market
|
|
var marketId interface{} = this.SafeString(chain, "symbol")
|
|
market = this.SafeMarket(marketId, market)
|
|
return map[string]interface{} {
|
|
"info": chain,
|
|
"currency": nil,
|
|
"symbol": GetValue(market, "symbol"),
|
|
"timestamp": nil,
|
|
"datetime": nil,
|
|
"impliedVolatility": this.SafeNumber(chain, "markIv"),
|
|
"openInterest": this.SafeNumber(chain, "openInterest"),
|
|
"bidPrice": this.SafeNumber(chain, "bid1Price"),
|
|
"askPrice": this.SafeNumber(chain, "ask1Price"),
|
|
"midPrice": nil,
|
|
"markPrice": this.SafeNumber(chain, "markPrice"),
|
|
"lastPrice": this.SafeNumber(chain, "lastPrice"),
|
|
"underlyingPrice": this.SafeNumber(chain, "underlyingPrice"),
|
|
"change": this.SafeNumber(chain, "change24h"),
|
|
"percentage": nil,
|
|
"baseVolume": this.SafeNumber(chain, "totalVolume"),
|
|
"quoteVolume": nil,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchPositionsHistory
|
|
* @description fetches historical positions
|
|
* @see https://bybit-exchange.github.io/docs/v5/position/close-pnl
|
|
* @param {string[]} symbols a list of unified market symbols
|
|
* @param {int} [since] timestamp in ms of the earliest position to fetch, params["until"] - since <= 7 days
|
|
* @param {int} [limit] the maximum amount of records to fetch, default=50, max=100
|
|
* @param {object} params extra parameters specific to the exchange api endpoint
|
|
* @param {int} [params.until] timestamp in ms of the latest position to fetch, params["until"] - since <= 7 days
|
|
* @param {string} [params.subType] 'linear' or 'inverse'
|
|
* @returns {object[]} a list of [position structures]{@link https://docs.ccxt.com/#/?id=position-structure}
|
|
*/
|
|
func (this *bybit) FetchPositionsHistory(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbols := GetArg(optionalArgs, 0, nil)
|
|
_ = symbols
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes86758 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes86758)
|
|
var market interface{} = nil
|
|
var subType interface{} = nil
|
|
var symbolsLength interface{} = 0
|
|
if IsTrue(!IsEqual(symbols, nil)) {
|
|
symbolsLength = GetArrayLength(symbols)
|
|
if IsTrue(IsGreaterThan(symbolsLength, 0)) {
|
|
market = this.Market(GetValue(symbols, 0))
|
|
}
|
|
}
|
|
var until interface{} = this.SafeInteger(params, "until")
|
|
subTypeparamsVariable := this.HandleSubTypeAndParams("fetchPositionsHistory", market, params, "linear");
|
|
subType = GetValue(subTypeparamsVariable,0);
|
|
params = GetValue(subTypeparamsVariable,1)
|
|
params = this.Omit(params, "until")
|
|
var request interface{} = map[string]interface{} {
|
|
"category": subType,
|
|
}
|
|
if IsTrue(IsTrue((!IsEqual(symbols, nil))) && IsTrue((IsEqual(symbolsLength, 1)))) {
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
if IsTrue(!IsEqual(until, nil)) {
|
|
AddElementToObject(request, "endTime", until)
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5PositionClosedPnl(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// retCode: '0',
|
|
// retMsg: 'OK',
|
|
// result: {
|
|
// nextPageCursor: '071749f3-a9fa-427b-b5ca-27b2f52b81de%3A1712717265566520788%2C071749f3-a9fa-427b-b5ca-27b2f52b81de%3A1712717265566520788',
|
|
// category: 'linear',
|
|
// list: [
|
|
// {
|
|
// symbol: 'XRPUSDT',
|
|
// orderType: 'Market',
|
|
// leverage: '10',
|
|
// updatedTime: '1712717265572',
|
|
// side: 'Sell',
|
|
// orderId: '071749f3-a9fa-427b-b5ca-27b2f52b81de',
|
|
// closedPnl: '-0.00049568',
|
|
// avgEntryPrice: '0.6045',
|
|
// qty: '3',
|
|
// cumEntryValue: '1.8135',
|
|
// createdTime: '1712717265566',
|
|
// orderPrice: '0.5744',
|
|
// closedSize: '3',
|
|
// avgExitPrice: '0.605',
|
|
// execType: 'Trade',
|
|
// fillCount: '1',
|
|
// cumExitValue: '1.815'
|
|
// }
|
|
// ]
|
|
// },
|
|
// retExtInfo: {},
|
|
// time: '1712717286073'
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result")
|
|
var rawPositions interface{} = this.SafeList(result, "list")
|
|
var positions interface{} = this.ParsePositions(rawPositions, symbols, params)
|
|
|
|
ch <- this.FilterBySinceLimit(positions, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchConvertCurrencies
|
|
* @description fetches all available currencies that can be converted
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/convert/convert-coin-list
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.accountType] eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
|
|
* @returns {object} an associative dictionary of currencies
|
|
*/
|
|
func (this *bybit) FetchConvertCurrencies(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
|
|
|
|
retRes87538 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes87538)
|
|
var accountType interface{} = nil
|
|
enableUnifiedMarginenableUnifiedAccountVariable := (<-this.IsUnifiedEnabled());
|
|
enableUnifiedMargin := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,0);
|
|
enableUnifiedAccount := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,1)
|
|
var isUnifiedAccount interface{} = (IsTrue(enableUnifiedMargin) || IsTrue(enableUnifiedAccount))
|
|
var accountTypeDefault interface{} = Ternary(IsTrue(isUnifiedAccount), "eb_convert_uta", "eb_convert_spot")
|
|
accountTypeparamsVariable := this.HandleOptionAndParams(params, "fetchConvertCurrencies", "accountType", accountTypeDefault);
|
|
accountType = GetValue(accountTypeparamsVariable,0);
|
|
params = GetValue(accountTypeparamsVariable,1)
|
|
var request interface{} = map[string]interface{} {
|
|
"accountType": accountType,
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5AssetExchangeQueryCoinList(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "ok",
|
|
// "result": {
|
|
// "coins": [
|
|
// {
|
|
// "coin": "MATIC",
|
|
// "fullName": "MATIC",
|
|
// "icon": "https://s1.bycsi.com/app/assets/token/0552ae79c535c3095fa18f7b377dd2e9.svg",
|
|
// "iconNight": "https://t1.bycsi.com/app/assets/token/f59301aef2d6ac2165c4c4603e672fb4.svg",
|
|
// "accuracyLength": 8,
|
|
// "coinType": "crypto",
|
|
// "balance": "0",
|
|
// "uBalance": "0",
|
|
// "timePeriod": 0,
|
|
// "singleFromMinLimit": "1.1",
|
|
// "singleFromMaxLimit": "20001",
|
|
// "singleToMinLimit": "0",
|
|
// "singleToMaxLimit": "0",
|
|
// "dailyFromMinLimit": "0",
|
|
// "dailyFromMaxLimit": "0",
|
|
// "dailyToMinLimit": "0",
|
|
// "dailyToMaxLimit": "0",
|
|
// "disableFrom": false,
|
|
// "disableTo": false
|
|
// },
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1727256416250
|
|
// }
|
|
//
|
|
var result interface{} = map[string]interface{} {}
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var coins interface{} = this.SafeList(data, "coins", []interface{}{})
|
|
for i := 0; IsLessThan(i, GetArrayLength(coins)); i++ {
|
|
var entry interface{} = GetValue(coins, i)
|
|
var id interface{} = this.SafeString(entry, "coin")
|
|
var disableFrom interface{} = this.SafeBool(entry, "disableFrom")
|
|
var disableTo interface{} = this.SafeBool(entry, "disableTo")
|
|
var inactive interface{} = (IsTrue(disableFrom) || IsTrue(disableTo))
|
|
var code interface{} = this.SafeCurrencyCode(id)
|
|
AddElementToObject(result, code, map[string]interface{} {
|
|
"info": entry,
|
|
"id": id,
|
|
"code": code,
|
|
"networks": nil,
|
|
"type": this.SafeString(entry, "coinType"),
|
|
"name": this.SafeString(entry, "fullName"),
|
|
"active": !IsTrue(inactive),
|
|
"deposit": nil,
|
|
"withdraw": this.SafeNumber(entry, "balance"),
|
|
"fee": nil,
|
|
"precision": nil,
|
|
"limits": map[string]interface{} {
|
|
"amount": map[string]interface{} {
|
|
"min": this.SafeNumber(entry, "singleFromMinLimit"),
|
|
"max": this.SafeNumber(entry, "singleFromMaxLimit"),
|
|
},
|
|
"withdraw": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"deposit": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
},
|
|
"created": nil,
|
|
})
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchConvertQuote
|
|
* @description fetch a quote for converting from one currency to another
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/convert/apply-quote
|
|
* @param {string} fromCode the currency that you want to sell and convert from
|
|
* @param {string} toCode the currency that you want to buy and convert into
|
|
* @param {float} [amount] how much you want to trade in units of the from currency
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.accountType] eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
|
|
* @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure}
|
|
*/
|
|
func (this *bybit) FetchConvertQuote(fromCode interface{}, toCode interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
amount := GetArg(optionalArgs, 0, nil)
|
|
_ = amount
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes88518 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes88518)
|
|
var accountType interface{} = nil
|
|
enableUnifiedMarginenableUnifiedAccountVariable := (<-this.IsUnifiedEnabled());
|
|
enableUnifiedMargin := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,0);
|
|
enableUnifiedAccount := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,1)
|
|
var isUnifiedAccount interface{} = (IsTrue(enableUnifiedMargin) || IsTrue(enableUnifiedAccount))
|
|
var accountTypeDefault interface{} = Ternary(IsTrue(isUnifiedAccount), "eb_convert_uta", "eb_convert_spot")
|
|
accountTypeparamsVariable := this.HandleOptionAndParams(params, "fetchConvertQuote", "accountType", accountTypeDefault);
|
|
accountType = GetValue(accountTypeparamsVariable,0);
|
|
params = GetValue(accountTypeparamsVariable,1)
|
|
var request interface{} = map[string]interface{} {
|
|
"fromCoin": fromCode,
|
|
"toCoin": toCode,
|
|
"requestAmount": this.NumberToString(amount),
|
|
"requestCoin": fromCode,
|
|
"accountType": accountType,
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5AssetExchangeQuoteApply(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "ok",
|
|
// "result": {
|
|
// "quoteTxId": "1010020692439481682687668224",
|
|
// "exchangeRate": "0.000015330836780000",
|
|
// "fromCoin": "USDT",
|
|
// "fromCoinType": "crypto",
|
|
// "toCoin": "BTC",
|
|
// "toCoinType": "crypto",
|
|
// "fromAmount": "10",
|
|
// "toAmount": "0.000153308367800000",
|
|
// "expiredTime": "1727257413353",
|
|
// "requestId": ""
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1727257398375
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var fromCurrencyId interface{} = this.SafeString(data, "fromCoin", fromCode)
|
|
var fromCurrency interface{} = this.Currency(fromCurrencyId)
|
|
var toCurrencyId interface{} = this.SafeString(data, "toCoin", toCode)
|
|
var toCurrency interface{} = this.Currency(toCurrencyId)
|
|
|
|
ch <- this.ParseConversion(data, fromCurrency, toCurrency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#createConvertTrade
|
|
* @description convert from one currency to another
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/convert/confirm-quote
|
|
* @param {string} id the id of the trade that you want to make
|
|
* @param {string} fromCode the currency that you want to sell and convert from
|
|
* @param {string} toCode the currency that you want to buy and convert into
|
|
* @param {float} amount how much you want to trade in units of the from currency
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure}
|
|
*/
|
|
func (this *bybit) CreateConvertTrade(id interface{}, fromCode interface{}, toCode interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
amount := GetArg(optionalArgs, 0, nil)
|
|
_ = amount
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes89068 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes89068)
|
|
var request interface{} = map[string]interface{} {
|
|
"quoteTxId": id,
|
|
}
|
|
|
|
response:= (<-this.PrivatePostV5AssetExchangeConvertExecute(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "ok",
|
|
// "result": {
|
|
// "exchangeStatus": "processing",
|
|
// "quoteTxId": "1010020692439483803499737088"
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1727257904969
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
|
|
ch <- this.ParseConversion(data)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchConvertTrade
|
|
* @description fetch the data for a conversion trade
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/convert/get-convert-result
|
|
* @param {string} id the id of the trade that you want to fetch
|
|
* @param {string} [code] the unified currency code of the conversion trade
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.accountType] eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
|
|
* @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure}
|
|
*/
|
|
func (this *bybit) FetchConvertTrade(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes89398 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes89398)
|
|
var accountType interface{} = nil
|
|
enableUnifiedMarginenableUnifiedAccountVariable := (<-this.IsUnifiedEnabled());
|
|
enableUnifiedMargin := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,0);
|
|
enableUnifiedAccount := GetValue(enableUnifiedMarginenableUnifiedAccountVariable,1)
|
|
var isUnifiedAccount interface{} = (IsTrue(enableUnifiedMargin) || IsTrue(enableUnifiedAccount))
|
|
var accountTypeDefault interface{} = Ternary(IsTrue(isUnifiedAccount), "eb_convert_uta", "eb_convert_spot")
|
|
accountTypeparamsVariable := this.HandleOptionAndParams(params, "fetchConvertQuote", "accountType", accountTypeDefault);
|
|
accountType = GetValue(accountTypeparamsVariable,0);
|
|
params = GetValue(accountTypeparamsVariable,1)
|
|
var request interface{} = map[string]interface{} {
|
|
"quoteTxId": id,
|
|
"accountType": accountType,
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5AssetExchangeConvertResultQuery(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "ok",
|
|
// "result": {
|
|
// "result": {
|
|
// "accountType": "eb_convert_uta",
|
|
// "exchangeTxId": "1010020692439483803499737088",
|
|
// "userId": "100406395",
|
|
// "fromCoin": "USDT",
|
|
// "fromCoinType": "crypto",
|
|
// "fromAmount": "10",
|
|
// "toCoin": "BTC",
|
|
// "toCoinType": "crypto",
|
|
// "toAmount": "0.00015344889",
|
|
// "exchangeStatus": "success",
|
|
// "extInfo": {},
|
|
// "convertRate": "0.000015344889",
|
|
// "createdAt": "1727257904726"
|
|
// }
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1727258257216
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var result interface{} = this.SafeDict(data, "result", map[string]interface{} {})
|
|
var fromCurrencyId interface{} = this.SafeString(result, "fromCoin")
|
|
var toCurrencyId interface{} = this.SafeString(result, "toCoin")
|
|
var fromCurrency interface{} = nil
|
|
var toCurrency interface{} = nil
|
|
if IsTrue(!IsEqual(fromCurrencyId, nil)) {
|
|
fromCurrency = this.Currency(fromCurrencyId)
|
|
}
|
|
if IsTrue(!IsEqual(toCurrencyId, nil)) {
|
|
toCurrency = this.Currency(toCurrencyId)
|
|
}
|
|
|
|
ch <- this.ParseConversion(result, fromCurrency, toCurrency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchConvertTradeHistory
|
|
* @description fetch the users history of conversion trades
|
|
* @see https://bybit-exchange.github.io/docs/v5/asset/convert/get-convert-history
|
|
* @param {string} [code] the unified currency code
|
|
* @param {int} [since] the earliest time in ms to fetch conversions for
|
|
* @param {int} [limit] the maximum number of conversion structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.accountType] eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
|
|
* @returns {object[]} a list of [conversion structures]{@link https://docs.ccxt.com/#/?id=conversion-structure}
|
|
*/
|
|
func (this *bybit) FetchConvertTradeHistory(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
|
|
|
|
retRes90038 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes90038)
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.PrivateGetV5AssetExchangeQueryConvertHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "ok",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "accountType": "eb_convert_uta",
|
|
// "exchangeTxId": "1010020692439483803499737088",
|
|
// "userId": "100406395",
|
|
// "fromCoin": "USDT",
|
|
// "fromCoinType": "crypto",
|
|
// "fromAmount": "10",
|
|
// "toCoin": "BTC",
|
|
// "toCoinType": "crypto",
|
|
// "toAmount": "0.00015344889",
|
|
// "exchangeStatus": "success",
|
|
// "extInfo": {},
|
|
// "convertRate": "0.000015344889",
|
|
// "createdAt": "1727257904726"
|
|
// }
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1727258761874
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var dataList interface{} = this.SafeList(data, "list", []interface{}{})
|
|
|
|
ch <- this.ParseConversions(dataList, code, "fromCoin", "toCoin", since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseConversion(conversion interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchConvertQuote
|
|
//
|
|
// {
|
|
// "quoteTxId": "1010020692439481682687668224",
|
|
// "exchangeRate": "0.000015330836780000",
|
|
// "fromCoin": "USDT",
|
|
// "fromCoinType": "crypto",
|
|
// "toCoin": "BTC",
|
|
// "toCoinType": "crypto",
|
|
// "fromAmount": "10",
|
|
// "toAmount": "0.000153308367800000",
|
|
// "expiredTime": "1727257413353",
|
|
// "requestId": ""
|
|
// }
|
|
//
|
|
// createConvertTrade
|
|
//
|
|
// {
|
|
// "exchangeStatus": "processing",
|
|
// "quoteTxId": "1010020692439483803499737088"
|
|
// }
|
|
//
|
|
// fetchConvertTrade, fetchConvertTradeHistory
|
|
//
|
|
// {
|
|
// "accountType": "eb_convert_uta",
|
|
// "exchangeTxId": "1010020692439483803499737088",
|
|
// "userId": "100406395",
|
|
// "fromCoin": "USDT",
|
|
// "fromCoinType": "crypto",
|
|
// "fromAmount": "10",
|
|
// "toCoin": "BTC",
|
|
// "toCoinType": "crypto",
|
|
// "toAmount": "0.00015344889",
|
|
// "exchangeStatus": "success",
|
|
// "extInfo": {},
|
|
// "convertRate": "0.000015344889",
|
|
// "createdAt": "1727257904726"
|
|
// }
|
|
//
|
|
fromCurrency := GetArg(optionalArgs, 0, nil)
|
|
_ = fromCurrency
|
|
toCurrency := GetArg(optionalArgs, 1, nil)
|
|
_ = toCurrency
|
|
var timestamp interface{} = this.SafeInteger2(conversion, "expiredTime", "createdAt")
|
|
var fromCoin interface{} = this.SafeString(conversion, "fromCoin")
|
|
var fromCode interface{} = this.SafeCurrencyCode(fromCoin, fromCurrency)
|
|
var to interface{} = this.SafeString(conversion, "toCoin")
|
|
var toCode interface{} = this.SafeCurrencyCode(to, toCurrency)
|
|
return map[string]interface{} {
|
|
"info": conversion,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"id": this.SafeString2(conversion, "quoteTxId", "exchangeTxId"),
|
|
"fromCurrency": fromCode,
|
|
"fromAmount": this.SafeNumber(conversion, "fromAmount"),
|
|
"toCurrency": toCode,
|
|
"toAmount": this.SafeNumber(conversion, "toAmount"),
|
|
"price": nil,
|
|
"fee": nil,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bybit#fetchLongShortRatioHistory
|
|
* @description fetches the long short ratio history for a unified market symbol
|
|
* @see https://bybit-exchange.github.io/docs/v5/market/long-short-ratio
|
|
* @param {string} symbol unified symbol of the market to fetch the long short ratio for
|
|
* @param {string} [timeframe] the period for the ratio, default is 24 hours
|
|
* @param {int} [since] the earliest time in ms to fetch ratios for
|
|
* @param {int} [limit] the maximum number of long short ratio structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} an array of [long short ratio structures]{@link https://docs.ccxt.com/#/?id=long-short-ratio-structure}
|
|
*/
|
|
func (this *bybit) FetchLongShortRatioHistory(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
timeframe := GetArg(optionalArgs, 1, nil)
|
|
_ = timeframe
|
|
since := GetArg(optionalArgs, 2, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 3, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 4, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes91158 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes91158)
|
|
var market interface{} = this.Market(symbol)
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.GetBybitType("fetchLongShortRatioHistory", market, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
if IsTrue(IsTrue(IsEqual(typeVar, "spot")) || IsTrue(IsEqual(typeVar, "option"))) {
|
|
panic(NotSupported(Add(this.Id, " fetchLongShortRatioHistory() only support linear and inverse markets")))
|
|
}
|
|
if IsTrue(IsEqual(timeframe, nil)) {
|
|
timeframe = "1d"
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
"period": timeframe,
|
|
"category": typeVar,
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.PublicGetV5MarketAccountRatio(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "retCode": 0,
|
|
// "retMsg": "OK",
|
|
// "result": {
|
|
// "list": [
|
|
// {
|
|
// "symbol": "BTCUSDT",
|
|
// "buyRatio": "0.5707",
|
|
// "sellRatio": "0.4293",
|
|
// "timestamp": "1729123200000"
|
|
// },
|
|
// ]
|
|
// },
|
|
// "retExtInfo": {},
|
|
// "time": 1729147842516
|
|
// }
|
|
//
|
|
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
|
|
var data interface{} = this.SafeList(result, "list", []interface{}{})
|
|
|
|
ch <- this.ParseLongShortRatioHistory(data, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bybit) ParseLongShortRatio(info interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "symbol": "BTCUSDT",
|
|
// "buyRatio": "0.5707",
|
|
// "sellRatio": "0.4293",
|
|
// "timestamp": "1729123200000"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var marketId interface{} = this.SafeString(info, "symbol")
|
|
var timestamp interface{} = this.SafeIntegerOmitZero(info, "timestamp")
|
|
var longString interface{} = this.SafeString(info, "buyRatio")
|
|
var shortString interface{} = this.SafeString(info, "sellRatio")
|
|
return map[string]interface{} {
|
|
"info": info,
|
|
"symbol": this.SafeSymbol(marketId, market, nil, "contract"),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"timeframe": nil,
|
|
"longShortRatio": this.ParseToNumeric(Precise.StringDiv(longString, shortString)),
|
|
}
|
|
}
|
|
func (this *bybit) Sign(path interface{}, optionalArgs ...interface{}) interface{} {
|
|
api := GetArg(optionalArgs, 0, "public")
|
|
_ = api
|
|
method := GetArg(optionalArgs, 1, "GET")
|
|
_ = method
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
headers := GetArg(optionalArgs, 3, nil)
|
|
_ = headers
|
|
body := GetArg(optionalArgs, 4, nil)
|
|
_ = body
|
|
var url interface{} = Add(Add(this.ImplodeHostname(GetValue(GetValue(this.Urls, "api"), api)), "/"), path)
|
|
if IsTrue(IsEqual(api, "public")) {
|
|
if IsTrue(GetArrayLength(ObjectKeys(params))) {
|
|
url = Add(url, Add("?", this.Rawencode(params)))
|
|
}
|
|
} else if IsTrue(IsEqual(api, "private")) {
|
|
this.CheckRequiredCredentials()
|
|
var isOpenapi interface{} = IsGreaterThanOrEqual(GetIndexOf(url, "openapi"), 0)
|
|
var isV3UnifiedMargin interface{} = IsGreaterThanOrEqual(GetIndexOf(url, "unified/v3"), 0)
|
|
var isV3Contract interface{} = IsGreaterThanOrEqual(GetIndexOf(url, "contract/v3"), 0)
|
|
var isV5UnifiedAccount interface{} = IsGreaterThanOrEqual(GetIndexOf(url, "v5"), 0)
|
|
var timestamp interface{} = ToString(this.Nonce())
|
|
if IsTrue(isOpenapi) {
|
|
if IsTrue(GetArrayLength(ObjectKeys(params))) {
|
|
body = this.Json(params)
|
|
} else {
|
|
// this fix for PHP is required otherwise it generates
|
|
// '[]' on empty arrays even when forced to use objects
|
|
body = "{}"
|
|
}
|
|
var payload interface{} = Add(Add(timestamp, this.ApiKey), body)
|
|
var signature interface{} = this.Hmac(this.Encode(payload), this.Encode(this.Secret), sha256, "hex")
|
|
headers = map[string]interface{} {
|
|
"Content-Type": "application/json",
|
|
"X-BAPI-API-KEY": this.ApiKey,
|
|
"X-BAPI-TIMESTAMP": timestamp,
|
|
"X-BAPI-SIGN": signature,
|
|
}
|
|
} else if IsTrue(IsTrue(IsTrue(isV3UnifiedMargin) || IsTrue(isV3Contract)) || IsTrue(isV5UnifiedAccount)) {
|
|
headers = map[string]interface{} {
|
|
"Content-Type": "application/json",
|
|
"X-BAPI-API-KEY": this.ApiKey,
|
|
"X-BAPI-TIMESTAMP": timestamp,
|
|
"X-BAPI-RECV-WINDOW": ToString(GetValue(this.Options, "recvWindow")),
|
|
}
|
|
if IsTrue(IsTrue(isV3UnifiedMargin) || IsTrue(isV3Contract)) {
|
|
AddElementToObject(headers, "X-BAPI-SIGN-TYPE", "2")
|
|
}
|
|
var query interface{} = this.Extend(map[string]interface{} {}, params)
|
|
var queryEncoded interface{} = this.Rawencode(query)
|
|
var auth_base interface{} = Add(Add(ToString(timestamp), this.ApiKey), ToString(GetValue(this.Options, "recvWindow")))
|
|
var authFull interface{} = nil
|
|
if IsTrue(IsEqual(method, "POST")) {
|
|
body = this.Json(query)
|
|
authFull = Add(auth_base, body)
|
|
} else {
|
|
authFull = Add(auth_base, queryEncoded)
|
|
url = Add(url, Add("?", this.Rawencode(query)))
|
|
}
|
|
var signature interface{} = nil
|
|
if IsTrue(IsGreaterThan(GetIndexOf(this.Secret, "PRIVATE KEY"), OpNeg(1))) {
|
|
signature = Rsa(authFull, this.Secret, sha256)
|
|
} else {
|
|
signature = this.Hmac(this.Encode(authFull), this.Encode(this.Secret), sha256)
|
|
}
|
|
AddElementToObject(headers, "X-BAPI-SIGN", signature)
|
|
} else {
|
|
var query interface{} = this.Extend(params, map[string]interface{} {
|
|
"api_key": this.ApiKey,
|
|
"recv_window": GetValue(this.Options, "recvWindow"),
|
|
"timestamp": timestamp,
|
|
})
|
|
var sortedQuery interface{} = this.Keysort(query)
|
|
var auth interface{} = this.Rawencode(sortedQuery)
|
|
var signature interface{} = nil
|
|
if IsTrue(IsGreaterThan(GetIndexOf(this.Secret, "PRIVATE KEY"), OpNeg(1))) {
|
|
signature = Rsa(auth, this.Secret, sha256)
|
|
} else {
|
|
signature = this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha256)
|
|
}
|
|
if IsTrue(IsEqual(method, "POST")) {
|
|
var isSpot interface{} = IsGreaterThanOrEqual(GetIndexOf(url, "spot"), 0)
|
|
var extendedQuery interface{} = this.Extend(query, map[string]interface{} {
|
|
"sign": signature,
|
|
})
|
|
if IsTrue(isSpot) {
|
|
body = this.Urlencode(extendedQuery)
|
|
headers = map[string]interface{} {
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
}
|
|
} else {
|
|
body = this.Json(extendedQuery)
|
|
headers = map[string]interface{} {
|
|
"Content-Type": "application/json",
|
|
}
|
|
}
|
|
} else {
|
|
url = Add(url, Add("?", this.Rawencode(sortedQuery)))
|
|
url = Add(url, Add("&sign=", signature))
|
|
}
|
|
}
|
|
}
|
|
if IsTrue(IsEqual(method, "POST")) {
|
|
var brokerId interface{} = this.SafeString(this.Options, "brokerId")
|
|
if IsTrue(!IsEqual(brokerId, nil)) {
|
|
AddElementToObject(headers, "Referer", brokerId)
|
|
}
|
|
}
|
|
return map[string]interface{} {
|
|
"url": url,
|
|
"method": method,
|
|
"body": body,
|
|
"headers": headers,
|
|
}
|
|
}
|
|
func (this *bybit) HandleErrors(httpCode interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} {
|
|
if !IsTrue(response) {
|
|
return nil // fallback to default error handler
|
|
}
|
|
//
|
|
// {
|
|
// "ret_code": 10001,
|
|
// "ret_msg": "ReadMapCB: expect { or n, but found \u0000, error " +
|
|
// "found in #0 byte of ...||..., bigger context " +
|
|
// "...||...",
|
|
// "ext_code": '',
|
|
// "ext_info": '',
|
|
// "result": null,
|
|
// "time_now": "1583934106.590436"
|
|
// }
|
|
//
|
|
// {
|
|
// "retCode":10001,
|
|
// "retMsg":"symbol params err",
|
|
// "result":{"symbol":"","bid":"","bidIv":"","bidSize":"","ask":"","askIv":"","askSize":"","lastPrice":"","openInterest":"","indexPrice":"","markPrice":"","markPriceIv":"","change24h":"","high24h":"","low24h":"","volume24h":"","turnover24h":"","totalVolume":"","totalTurnover":"","fundingRate":"","predictedFundingRate":"","nextFundingTime":"","countdownHour":"0","predictedDeliveryPrice":"","underlyingPrice":"","delta":"","gamma":"","vega":"","theta":""}
|
|
// }
|
|
//
|
|
var errorCode interface{} = this.SafeString2(response, "ret_code", "retCode")
|
|
if IsTrue(!IsEqual(errorCode, "0")) {
|
|
if IsTrue(IsEqual(errorCode, "30084")) {
|
|
// not an error
|
|
// https://github.com/ccxt/ccxt/issues/11268
|
|
// https://github.com/ccxt/ccxt/pull/11624
|
|
// POST https://api.bybit.com/v2/private/position/switch-isolated 200 OK
|
|
// {"ret_code":30084,"ret_msg":"Isolated not modified","ext_code":"","ext_info":"","result":null,"time_now":"1642005219.937988","rate_limit_status":73,"rate_limit_reset_ms":1642005219894,"rate_limit":75}
|
|
return nil
|
|
}
|
|
var feedback interface{} = nil
|
|
if IsTrue(IsTrue(IsEqual(errorCode, "10005")) && IsTrue(IsLessThan(GetIndexOf(url, "order"), 0))) {
|
|
feedback = Add(Add(this.Id, " private api uses /user/v3/private/query-api to check if you have a unified account. The API key of user id must own one of permissions: \"Account Transfer\", \"Subaccount Transfer\", \"Withdrawal\" "), body)
|
|
} else {
|
|
feedback = Add(Add(this.Id, " "), body)
|
|
}
|
|
if IsTrue(GetIndexOf(body, "Withdraw address chain or destination tag are not equal")) {
|
|
feedback = Add(feedback, "; You might also need to ensure the address is whitelisted")
|
|
}
|
|
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), body, feedback)
|
|
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorCode, feedback)
|
|
panic(ExchangeError(feedback))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
|
|
func (this *bybit) Init(userConfig map[string]interface{}) {
|
|
this.Exchange = Exchange{}
|
|
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
|
|
this.Exchange.DerivedExchange = this
|
|
}
|