bybit-connector-ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bybit
4
+ # Root class for every failure the SDK raises. `rescue Bybit::Error`
5
+ # catches everything — auth, rate-limit, timeout, network, parse, misconfig.
6
+ class Error < StandardError; end
7
+
8
+ # Configuration mistake caught before the network call (missing api_key,
9
+ # invalid combination of options). Distinct from AuthError which is a
10
+ # server-side rejection.
11
+ class ConfigurationError < Error; end
12
+
13
+ # Transport-level errors that don't fit Timeout / Network / a Bybit body.
14
+ # Faraday::ParsingError / ClientError / ServerError land here.
15
+ class TransportError < Error; end
16
+
17
+ # 5xx HTTP without a decodable Bybit body — infra outage / gateway error.
18
+ class ServerError < TransportError; end
19
+
20
+ # Non-auth 4xx HTTP without a decodable Bybit body — usually WAF / CDN.
21
+ class ClientError < TransportError; end
22
+
23
+ # Raised when the server returns HTTP 200 + retCode != 0 (the V5 norm),
24
+ # or when a transport-level error is enriched with a Bybit body payload.
25
+ class ApiError < Error
26
+ attr_reader :ret_code, :ret_msg, :result, :time, :http_status
27
+
28
+ def initialize(response, http_status: nil)
29
+ @ret_code = response['retCode']
30
+ @ret_msg = response['retMsg']
31
+ @result = response['result']
32
+ @time = response['time']
33
+ @http_status = http_status
34
+ super("[#{@ret_code}] #{@ret_msg}")
35
+ end
36
+ end
37
+
38
+ class AuthError < ApiError; end
39
+ class RateLimitError < ApiError; end
40
+ class TimeoutError < TransportError; end
41
+ class NetworkError < TransportError; end
42
+
43
+ # Body did not parse or didn't match Bybit V5 ApiResponse shape. `body`
44
+ # holds the raw payload (truncated in the message but full in the attr)
45
+ # so consumers can log CDN / maintenance-page HTML for post-mortem.
46
+ class ParseError < TransportError
47
+ attr_reader :body, :http_status
48
+
49
+ def initialize(message, body: nil, http_status: nil)
50
+ @body = body
51
+ @http_status = http_status
52
+ super(message)
53
+ end
54
+ end
55
+
56
+ AUTH_RET_CODES = [10_002, 10_003, 10_004, 10_005, 10_007, 10_009, 10_010, 10_029].freeze
57
+ RATE_LIMIT_RET_CODES = [10_006, 10_018].freeze
58
+
59
+ # Route a V5 response with retCode != 0 to the most specific error subclass.
60
+ def self.api_error_from(response, http_status: nil)
61
+ code = response['retCode']
62
+ return AuthError.new(response, http_status: http_status) if AUTH_RET_CODES.include?(code)
63
+ return RateLimitError.new(response, http_status: http_status) if RATE_LIMIT_RET_CODES.include?(code)
64
+
65
+ ApiError.new(response, http_status: http_status)
66
+ end
67
+ end
@@ -0,0 +1,332 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bybit
4
+ module RestApi
5
+ class AccountService < BaseService
6
+ # Batch Set Collateral
7
+ #
8
+ # POST /v5/account/set-collateral-switch-batch
9
+ #
10
+ # @param request [Array] Array of collateral switch objects
11
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
12
+ # @see https://bybit-exchange.github.io/docs/v5/account/batch-set-collateral
13
+ def batch_set_collateral(request:, **kwargs)
14
+ params = kwargs.merge(request: request)
15
+ params = Bybit::Utils::WireKeys.camelize(params)
16
+ @session.sign_request(method: :post, path: '/v5/account/set-collateral-switch-batch', body: params)
17
+ end
18
+
19
+ # Get Account Info
20
+ #
21
+ # GET /v5/account/info
22
+ #
23
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
24
+ # @see https://bybit-exchange.github.io/docs/v5/account/account-info
25
+ def get_info(**kwargs)
26
+ params = kwargs.dup
27
+ params = Bybit::Utils::WireKeys.camelize(params)
28
+ @session.sign_request(method: :get, path: '/v5/account/info', params: params)
29
+ end
30
+
31
+ # Get Wallet Balance
32
+ #
33
+ # GET /v5/account/wallet-balance
34
+ #
35
+ # @param account_type [String] Account type: UNIFIED / CONTRACT / SPOT / FUND / OPTION.
36
+ # @option kwargs [String] :coin Coin filter — comma-separated, e.g. "USDT,BTC".
37
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
38
+ # @see https://bybit-exchange.github.io/docs/v5/account/wallet-balance
39
+ def get_wallet_balance(account_type:, **kwargs)
40
+ params = kwargs.merge(account_type: account_type)
41
+ params = Bybit::Utils::WireKeys.camelize(params)
42
+ @session.sign_request(method: :get, path: '/v5/account/wallet-balance', params: params)
43
+ end
44
+
45
+ # Get Account Instruments
46
+ #
47
+ # GET /v5/account/instruments-info
48
+ #
49
+ # @param category [String] Product type
50
+ # @option kwargs [String] :symbol Symbol name
51
+ # @option kwargs [Integer] :limit Limit for data size per page
52
+ # @option kwargs [String] :cursor Cursor. Use the nextPageCursor token from the response to retrieve the next page
53
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
54
+ def get_instruments(category:, **kwargs)
55
+ params = kwargs.merge(category: category)
56
+ params = Bybit::Utils::WireKeys.camelize(params)
57
+ @session.sign_request(method: :get, path: '/v5/account/instruments-info', params: params)
58
+ end
59
+
60
+ # Get Borrow History
61
+ #
62
+ # GET /v5/account/borrow-history
63
+ #
64
+ # @option kwargs [String] :currency USDC, USDT, BTC, ETH
65
+ # @option kwargs [Integer] :start_time The start timestamp (ms)
66
+ # @option kwargs [Integer] :end_time The end timestamp (ms)
67
+ # @option kwargs [Integer] :limit Limit for data size per page
68
+ # @option kwargs [String] :cursor Cursor. Use the nextPageCursor token from the response to retrieve the next page
69
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
70
+ # @see https://bybit-exchange.github.io/docs/v5/account/borrow-history
71
+ def get_borrow_history(**kwargs)
72
+ params = kwargs.dup
73
+ params = Bybit::Utils::WireKeys.camelize(params)
74
+ @session.sign_request(method: :get, path: '/v5/account/borrow-history', params: params)
75
+ end
76
+
77
+ # Get Collateral Info
78
+ #
79
+ # GET /v5/account/collateral-info
80
+ #
81
+ # @option kwargs [String] :currency Asset currency of all current collateral
82
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
83
+ # @see https://bybit-exchange.github.io/docs/v5/account/collateral-info
84
+ def get_collateral_info(**kwargs)
85
+ params = kwargs.dup
86
+ params = Bybit::Utils::WireKeys.camelize(params)
87
+ @session.sign_request(method: :get, path: '/v5/account/collateral-info', params: params)
88
+ end
89
+
90
+ # Get DCP Info
91
+ #
92
+ # GET /v5/account/query-dcp-info
93
+ #
94
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
95
+ # @see https://bybit-exchange.github.io/docs/v5/account/dcp-info
96
+ def get_dcp_info(**kwargs)
97
+ params = kwargs.dup
98
+ params = Bybit::Utils::WireKeys.camelize(params)
99
+ @session.sign_request(method: :get, path: '/v5/account/query-dcp-info', params: params)
100
+ end
101
+
102
+ # Get Fee Rate
103
+ #
104
+ # GET /v5/account/fee-rate
105
+ #
106
+ # @param category [String] Product type
107
+ # @option kwargs [String] :symbol Symbol name
108
+ # @option kwargs [String] :base_coin Base coin. SOL, BTC, ETH. Apply to option only
109
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
110
+ # @see https://bybit-exchange.github.io/docs/v5/account/fee-rate
111
+ def get_fee_rate(category:, **kwargs)
112
+ params = kwargs.merge(category: category)
113
+ params = Bybit::Utils::WireKeys.camelize(params)
114
+ @session.sign_request(method: :get, path: '/v5/account/fee-rate', params: params)
115
+ end
116
+
117
+ # Get MMP State
118
+ #
119
+ # GET /v5/account/mmp-state
120
+ #
121
+ # @param base_coin [String] Base coin
122
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
123
+ # @see https://bybit-exchange.github.io/docs/v5/account/get-mmp-state
124
+ def get_mmp_state(base_coin:, **kwargs)
125
+ params = kwargs.merge(base_coin: base_coin)
126
+ params = Bybit::Utils::WireKeys.camelize(params)
127
+ @session.sign_request(method: :get, path: '/v5/account/mmp-state', params: params)
128
+ end
129
+
130
+ # Get SMP Group
131
+ #
132
+ # GET /v5/account/smp-group
133
+ #
134
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
135
+ # @see https://bybit-exchange.github.io/docs/v5/account/smp-group
136
+ def get_smp_group(**kwargs)
137
+ params = kwargs.dup
138
+ params = Bybit::Utils::WireKeys.camelize(params)
139
+ @session.sign_request(method: :get, path: '/v5/account/smp-group', params: params)
140
+ end
141
+
142
+ # Get Transaction Log
143
+ #
144
+ # GET /v5/account/transaction-log
145
+ #
146
+ # @option kwargs [String] :account_type Account type. UNIFIED
147
+ # @option kwargs [String] :category Product type
148
+ # @option kwargs [String] :currency Currency
149
+ # @option kwargs [String] :base_coin BaseCoin. e.g., BTC of BTCPERP
150
+ # @option kwargs [String] :type Types of transaction logs
151
+ # @option kwargs [String] :trans_sub_type Transaction subtype
152
+ # @option kwargs [Integer] :start_time The start timestamp (ms)
153
+ # @option kwargs [Integer] :end_time The end timestamp (ms)
154
+ # @option kwargs [Integer] :limit Limit for data size per page
155
+ # @option kwargs [String] :cursor Cursor. Use the nextPageCursor token from the response to retrieve the next page
156
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
157
+ # @see https://bybit-exchange.github.io/docs/v5/account/transaction-log
158
+ def get_transaction_log(**kwargs)
159
+ params = kwargs.dup
160
+ params = Bybit::Utils::WireKeys.camelize(params)
161
+ @session.sign_request(method: :get, path: '/v5/account/transaction-log', params: params)
162
+ end
163
+
164
+ # Get Transferable Amount
165
+ #
166
+ # GET /v5/account/withdrawal
167
+ #
168
+ # @param coin_name [String] Coin name
169
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
170
+ def get_transferable_amount(coin_name:, **kwargs)
171
+ params = kwargs.merge(coin_name: coin_name)
172
+ params = Bybit::Utils::WireKeys.camelize(params)
173
+ @session.sign_request(method: :get, path: '/v5/account/withdrawal', params: params)
174
+ end
175
+
176
+ # Get User Settings
177
+ #
178
+ # GET /v5/account/user-setting-config
179
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
180
+ def get_user_settings(**kwargs)
181
+ params = kwargs.dup
182
+ params = Bybit::Utils::WireKeys.camelize(params)
183
+ @session.sign_request(method: :get, path: '/v5/account/user-setting-config', params: params)
184
+ end
185
+
186
+ # Manual Borrow
187
+ #
188
+ # POST /v5/account/borrow
189
+ #
190
+ # @param coin [String] Coin name
191
+ # @param amount [String] The amount to borrow
192
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
193
+ def manual_borrow(coin:, amount:, **kwargs)
194
+ params = kwargs.merge(coin: coin, amount: amount)
195
+ params = Bybit::Utils::WireKeys.camelize(params)
196
+ @session.sign_request(method: :post, path: '/v5/account/borrow', body: params)
197
+ end
198
+
199
+ # Manual Repay
200
+ #
201
+ # POST /v5/account/repay
202
+ #
203
+ # @option kwargs [String] :coin Coin name. If not passed, repay all liabilities
204
+ # @option kwargs [String] :amount The amount to repay
205
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
206
+ def manual_repay(**kwargs)
207
+ params = kwargs.dup
208
+ params = Bybit::Utils::WireKeys.camelize(params)
209
+ @session.sign_request(method: :post, path: '/v5/account/repay', body: params)
210
+ end
211
+
212
+ # No-Convert Repay
213
+ #
214
+ # POST /v5/account/no-convert-repay
215
+ #
216
+ # @param coin [String] Coin name
217
+ # @option kwargs [String] :amount The amount to repay
218
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
219
+ # @see https://bybit-exchange.github.io/docs/v5/account/no-convert-repay
220
+ def no_convert_repay(coin:, **kwargs)
221
+ params = kwargs.merge(coin: coin)
222
+ params = Bybit::Utils::WireKeys.camelize(params)
223
+ @session.sign_request(method: :post, path: '/v5/account/no-convert-repay', body: params)
224
+ end
225
+
226
+ # One-Click Repay: convert small balance coins to a specified coin to repay debt in one click.
227
+ #
228
+ # POST /v5/account/quick-repayment
229
+ #
230
+ # @option kwargs [String] :coin Coin to repay debt with
231
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
232
+ def one_click_repay(**kwargs)
233
+ params = kwargs.dup
234
+ params = Bybit::Utils::WireKeys.camelize(params)
235
+ @session.sign_request(method: :post, path: '/v5/account/quick-repayment', body: params)
236
+ end
237
+
238
+ # Reset MMP state for a given base coin.
239
+ #
240
+ # POST /v5/account/mmp-reset
241
+ #
242
+ # @param base_coin [String] Base coin
243
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
244
+ def reset_mmp(base_coin:, **kwargs)
245
+ params = kwargs.merge(base_coin: base_coin)
246
+ params = Bybit::Utils::WireKeys.camelize(params)
247
+ @session.sign_request(method: :post, path: '/v5/account/mmp-reset', body: params)
248
+ end
249
+
250
+ # Enable or disable a coin as collateral for the unified account.
251
+ #
252
+ # POST /v5/account/set-collateral-switch
253
+ #
254
+ # @param coin [String] Coin symbol
255
+ # @param collateral_switch [String] ON or OFF
256
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
257
+ def set_collateral_coin(coin:, collateral_switch:, **kwargs)
258
+ params = kwargs.merge(coin: coin, collateral_switch: collateral_switch)
259
+ params = Bybit::Utils::WireKeys.camelize(params)
260
+ @session.sign_request(method: :post, path: '/v5/account/set-collateral-switch', body: params)
261
+ end
262
+
263
+ # Set margin mode for the unified account (ISOLATED_MARGIN, REGULAR_MARGIN, PORTFOLIO_MARGIN).
264
+ #
265
+ # POST /v5/account/set-margin-mode
266
+ #
267
+ # @param set_margin_mode [String] Margin mode to set
268
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
269
+ # @see https://bybit-exchange.github.io/docs/v5/account/set-margin-mode
270
+ def set_margin_mode(set_margin_mode:, **kwargs)
271
+ params = kwargs.merge(set_margin_mode: set_margin_mode)
272
+ params = Bybit::Utils::WireKeys.camelize(params)
273
+ @session.sign_request(method: :post, path: '/v5/account/set-margin-mode', body: params)
274
+ end
275
+
276
+ # Configure Market Maker Protection parameters for a base coin.
277
+ #
278
+ # POST /v5/account/mmp-modify
279
+ #
280
+ # @param base_coin [String] Base coin
281
+ # @param window [String] Time window (ms)
282
+ # @param frozen_period [String] Frozen period (ms)
283
+ # @param qty_limit [String] Quantity limit
284
+ # @param delta_limit [String] Delta limit
285
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
286
+ # @see https://bybit-exchange.github.io/docs/v5/account/set-mmp
287
+ def set_mmp(base_coin:, window:, frozen_period:, qty_limit:, delta_limit:, **kwargs)
288
+ params = kwargs.merge(base_coin: base_coin, window: window, frozen_period: frozen_period, qty_limit: qty_limit, delta_limit: delta_limit)
289
+ params = Bybit::Utils::WireKeys.camelize(params)
290
+ @session.sign_request(method: :post, path: '/v5/account/mmp-modify', body: params)
291
+ end
292
+
293
+ # Toggle whether the price limit rule applies to modify order actions for a category.
294
+ #
295
+ # POST /v5/account/set-limit-px-action
296
+ #
297
+ # @param category [String] Product type
298
+ # @param modify_enable [Boolean] Enable modify price limit check
299
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
300
+ def set_price_limit(category:, modify_enable:, **kwargs)
301
+ params = kwargs.merge(category: category, modify_enable: modify_enable)
302
+ params = Bybit::Utils::WireKeys.camelize(params)
303
+ @session.sign_request(method: :post, path: '/v5/account/set-limit-px-action', body: params)
304
+ end
305
+
306
+ # Enable or disable spot hedging mode for the unified account.
307
+ #
308
+ # POST /v5/account/set-hedging-mode
309
+ #
310
+ # @param set_hedging_mode [String] ON or OFF
311
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
312
+ # @see https://bybit-exchange.github.io/docs/v5/account/set-spot-hedge
313
+ def set_spot_hedging(set_hedging_mode:, **kwargs)
314
+ params = kwargs.merge(set_hedging_mode: set_hedging_mode)
315
+ params = Bybit::Utils::WireKeys.camelize(params)
316
+ @session.sign_request(method: :post, path: '/v5/account/set-hedging-mode', body: params)
317
+ end
318
+
319
+ # Upgrade the current account to Unified Trading Account (UTA) Pro.
320
+ #
321
+ # POST /v5/account/upgrade-to-uta
322
+ #
323
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
324
+ # @see https://bybit-exchange.github.io/docs/v5/account/upgrade-unified-account
325
+ def upgrade_to_uta_pro(**kwargs)
326
+ params = kwargs.dup
327
+ params = Bybit::Utils::WireKeys.camelize(params)
328
+ @session.sign_request(method: :post, path: '/v5/account/upgrade-to-uta', body: params)
329
+ end
330
+ end
331
+ end
332
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bybit
4
+ module RestApi
5
+ class AffiliateService < BaseService
6
+ # Get affiliate sub-affiliate list
7
+ #
8
+ # GET /v5/affiliate/affiliate-sub-list
9
+ #
10
+ # @option kwargs [String] :cursor Cursor for pagination
11
+ # @option kwargs [Integer] :size Page size
12
+ # @option kwargs [String] :start_date Start date filter
13
+ # @option kwargs [String] :end_date End date filter
14
+ # @option kwargs [Integer] :sub_aff_id Sub-affiliate ID
15
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
16
+ # @see https://bybit-exchange.github.io/docs/v5/affiliate/affiliate-sub-list
17
+ def get_sub_list(**kwargs)
18
+ params = kwargs.dup
19
+ params = Bybit::Utils::WireKeys.camelize(params)
20
+ @session.sign_request(method: :get, path: '/v5/affiliate/affiliate-sub-list', params: params)
21
+ end
22
+
23
+ # Get affiliate user list
24
+ #
25
+ # GET /v5/affiliate/aff-user-list
26
+ #
27
+ # @option kwargs [String] :cursor Cursor for pagination
28
+ # @option kwargs [Integer] :size Page size
29
+ # @option kwargs [Boolean] :need_deposit Whether to include deposit information
30
+ # @option kwargs [Boolean] :need30 Whether to include 30-day statistics
31
+ # @option kwargs [Boolean] :need365 Whether to include 365-day statistics
32
+ # @option kwargs [String] :start_date Start date filter
33
+ # @option kwargs [String] :end_date End date filter
34
+ # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time).
35
+ def get_user_list(**kwargs)
36
+ params = kwargs.dup
37
+ params = Bybit::Utils::WireKeys.camelize(params)
38
+ @session.sign_request(method: :get, path: '/v5/affiliate/aff-user-list', params: params)
39
+ end
40
+ end
41
+ end
42
+ end