From 1245e40de65520c7a1773a74dc2c6d8b7302287c Mon Sep 17 00:00:00 2001 From: doris-xiao-bybit Date: Fri, 6 Nov 2026 11:16:25 +0800 Subject: [PATCH 1/5] docs: design SDK review fixes --- .../2026-11-06-sdk-review-fixes-design.md | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 docs/superpowers/specs/2026-11-06-sdk-review-fixes-design.md diff --git a/docs/superpowers/specs/2026-11-06-sdk-review-fixes-design.md b/docs/superpowers/specs/2026-11-06-sdk-review-fixes-design.md new file mode 100644 index 0000000..7586252 --- /dev/null +++ b/docs/superpowers/specs/2026-11-06-sdk-review-fixes-design.md @@ -0,0 +1,44 @@ +# SDK Review Fixes Design + +## Scope + +Correct the defects found while reviewing the `doris-main` branch without +changing unrelated REST behavior or issuing state-changing testnet requests. + +## API contract corrections + +- Align Alpha Prediction request parameters with the current official API + documentation. +- `get_prediction_group_stage_detail` accepts required `event_type` and + optional `group_name`; it sends `eventType` and `groupName`. +- `get_prediction_match_list` keeps required `event_type` and accepts the + documented optional filters and pagination arguments through keyword args. +- `get_prediction_timeline_stages` requires `event_type`. +- `get_prediction_portfolio_summary` accepts the optional `event_type` filter. +- `get_prediction_price_history` requires singular `token_id` and `interval`. +- Do not preserve aliases for invalid, unreleased 0.1.3 parameter contracts. + +## Documentation corrections + +- Replace generated `@see` URLs with the actual public documentation routes + listed in the official sitemap. +- Where no public documentation page exists, omit the dead link and retain an + explicit note that the endpoint comes from the OpenAPI source. +- Move the 0.1.3 entry below the `# Changelog` introduction and use the + existing Keep a Changelog heading format. +- Add the newly exposed client services to the README service inventory. + +## Tests and verification + +- Update generated contract examples to assert the corrected Alpha wire keys. +- Add explicit examples for required arguments and optional filters so a + self-consistent generated implementation cannot conceal source drift. +- Run the focused examples red before production edits, then green afterward. +- Run the complete RSpec suite, RuboCop, `git diff --check`, and read-only + testnet calls for corrected Alpha query methods. + +## Compatibility and safety + +The affected 0.1.3 API is unreleased, so correctness takes precedence over +compatibility with its invalid staged signatures. Testnet verification remains +read-only; no orders, loans, transfers, or account settings are changed. From 1ce418c12f160a488b6495c779391a5e205748d3 Mon Sep 17 00:00:00 2001 From: doris-xiao-bybit Date: Fri, 6 Nov 2026 11:37:02 +0800 Subject: [PATCH 2/5] docs: design Stocks API removal --- .../2026-11-06-remove-stocks-api-design.md | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 docs/superpowers/specs/2026-11-06-remove-stocks-api-design.md diff --git a/docs/superpowers/specs/2026-11-06-remove-stocks-api-design.md b/docs/superpowers/specs/2026-11-06-remove-stocks-api-design.md new file mode 100644 index 0000000..f453edf --- /dev/null +++ b/docs/superpowers/specs/2026-11-06-remove-stocks-api-design.md @@ -0,0 +1,38 @@ +# Remove Stocks API Design + +## Goal + +Remove every `/v5/rwa/stocks/*` endpoint from the unreleased Ruby SDK surface +because these APIs are not currently needed. + +## Public API changes + +- Delete `Bybit::RestApi::StocksService` and its source file. +- Remove the service require, `Client#stocks` reader, and client initializer + registration. +- Remove all generated request-contract examples for `/v5/rwa/stocks/*`. +- Remove Stocks entries from the README service inventory and the 0.1.3 + changelog. +- Leave unrelated RWA APIs, including Earn RWA endpoints, unchanged. + +## Regression protection + +Add a focused client-surface example asserting that a new `Bybit::Client` does +not expose `stocks`. Run it before implementation to confirm it fails against +the current client, then remove the Stocks surface and run it again. + +## Verification + +- Search tracked and untracked project sources for `StocksService`, + `client.stocks`, and `/v5/rwa/stocks`; no runtime, test, README, or changelog + references may remain. +- Run the complete RSpec suite and RuboCop. +- Run `git diff --check main` and separately check untracked files. +- Preserve the user's existing staged state; do not stage or commit SDK code. + +## Compatibility + +This removes an unreleased 0.1.3 API surface. No compatibility alias or hidden +service remains. The existing design and implementation-plan documents may +retain historical discussion of the review, but they are not runtime or public +SDK surfaces. From c993c0ebd3bf9c9fb3938c99ee3f74e4a8b2f750 Mon Sep 17 00:00:00 2001 From: doris-xiao-bybit Date: Fri, 6 Nov 2026 11:43:47 +0800 Subject: [PATCH 3/5] sdk update --- CHANGELOG.md | 97 + lib/bybit/client.rb | 63 +- lib/bybit/rest_api/alpha_service.rb | 535 ++++++ lib/bybit/rest_api/event_service.rb | 92 + lib/bybit/rest_api/fiat_service.rb | 110 ++ .../rest_api/institutional_loan_service.rb | 22 + lib/bybit/rest_api/referral_service.rb | 61 + lib/bybit/rest_api/spot_margin_service.rb | 27 + lib/bybit/rest_api/spot_x_service.rb | 142 ++ lib/bybit/rest_api/spread_trade_service.rb | 202 ++ lib/bybit/rest_api/stocks_service.rb | 154 ++ lib/bybit/rest_api/strategy_service.rb | 105 ++ lib/bybit/rest_api/tax_service.rb | 37 + lib/bybit/version.rb | 2 +- spec/generated/rest_api_generated_spec.rb | 1641 +++++++++++++++++ 15 files changed, 3269 insertions(+), 21 deletions(-) create mode 100644 lib/bybit/rest_api/alpha_service.rb create mode 100644 lib/bybit/rest_api/event_service.rb create mode 100644 lib/bybit/rest_api/fiat_service.rb create mode 100644 lib/bybit/rest_api/referral_service.rb create mode 100644 lib/bybit/rest_api/spot_x_service.rb create mode 100644 lib/bybit/rest_api/spread_trade_service.rb create mode 100644 lib/bybit/rest_api/stocks_service.rb create mode 100644 lib/bybit/rest_api/strategy_service.rb create mode 100644 lib/bybit/rest_api/tax_service.rb create mode 100644 spec/generated/rest_api_generated_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c35a89..27aa80b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,100 @@ +## 0.1.3 — 2026-11-06 + +### Added +- `AlphaService#get_lp_order_list(...)` +- `AlphaService#get_lp_pay_token_list(...)` +- `AlphaService#get_lp_pay_token_price(...)` +- `AlphaService#get_lp_pool_info(...)` +- `AlphaService#get_lp_pool_list(...)` +- `AlphaService#get_lp_position_list(...)` +- `AlphaService#execute_lp_redeem(...)` +- `AlphaService#execute_lp_stake(...)` +- `AlphaService#execute_prediction_buy(...)` +- `AlphaService#get_prediction_engine_status(...)` +- `AlphaService#get_prediction_event_detail(...)` +- `AlphaService#get_prediction_order_book(...)` +- `AlphaService#get_prediction_order_estimate(...)` +- `AlphaService#get_prediction_order_list(...)` +- `AlphaService#get_prediction_pay_token_list(...)` +- `AlphaService#get_prediction_portfolio_summary(...)` +- `AlphaService#get_prediction_position_history(...)` +- `AlphaService#get_prediction_position_list(...)` +- `AlphaService#get_prediction_price_history(...)` +- `AlphaService#execute_prediction_sell(...)` +- `AlphaService#get_prediction_side_market_list(...)` +- `AlphaService#get_prediction_group_stage_detail(...)` +- `AlphaService#get_prediction_match_list(...)` +- `AlphaService#get_prediction_timeline_stages(...)` +- `AlphaService#get_prediction_token_price(...)` +- `AlphaService#get_asset_detail(...)` +- `AlphaService#get_asset_list(...)` +- `AlphaService#get_biz_token_details(...)` +- `AlphaService#get_biz_token_list(...)` +- `AlphaService#get_biz_token_price_list(...)` +- `AlphaService#get_order_list(...)` +- `AlphaService#get_pay_token_list(...)` +- `AlphaService#execute_purchase(...)` +- `AlphaService#get_trade_quote(...)` +- `AlphaService#execute_redeem(...)` +- `EventService#get_ec_order_history(...)` +- `EventService#get_ec_active_orders(...)` +- `EventService#get_ec_position_info(...)` +- `EventService#get_ec_settlements(...)` +- `EventService#get_ec_trade_history(...)` +- `TaxService#batch_create_tax_reports(...)` +- `TaxService#batch_query_tax_reports(...)` +- `FiatService#query_balance(...)` +- `FiatService#query_coin_list(...)` +- `FiatService#query_trade_history(...)` +- `FiatService#apply_quote(...)` +- `FiatService#get_reference_price(...)` +- `FiatService#confirm_quote(...)` +- `FiatService#query_trade(...)` +- `InstitutionalLoanService#ins_loan_coin_delta_amount(...)` +- `InstitutionalLoanService#ins_loan_delay_liq_status(...)` +- `ReferralService#get_campaign_rewards(...)` +- `ReferralService#get_commission_records(...)` +- `ReferralService#get_user_identity_profile(...)` +- `ReferralService#get_user_invitations(...)` +- `StocksService#get_convert_detail(...)` +- `StocksService#get_convert_list(...)` +- `StocksService#submit_convert(...)` +- `StocksService#get_multiplier_list(...)` +- `StocksService#get_market_session(...)` +- `StocksService#place_order(...)` +- `StocksService#cancel_order(...)` +- `StocksService#get_order_detail(...)` +- `StocksService#get_positions(...)` +- `SpotMarginService#query_fixed_borrow_penalty_interest(...)` +- `SpotMarginService#cancel_fixed_borrow_order(...)` +- `SpotXService#get_launchpool_project_list(...)` +- `SpotXService#get_launchpool_user_activity_log(...)` +- `SpotXService#get_launchpool_user_current_staking(...)` +- `SpotXService#get_launchpool_user_history(...)` +- `SpotXService#get_puzzle_project_list(...)` +- `SpotXService#get_token_splash_project_list(...)` +- `SpotXService#get_token_splash_user_activity_params(...)` +- `SpreadTradeService#get_history(...)` +- `SpreadTradeService#get_spread_instruments_info(...)` +- `SpreadTradeService#get_spread_max_qty(...)` +- `SpreadTradeService#amend_spread_order(...)` +- `SpreadTradeService#cancel_spread_order(...)` +- `SpreadTradeService#cancel_all_spread_orders(...)` +- `SpreadTradeService#create_spread_order(...)` +- `SpreadTradeService#get_spread_order_history(...)` +- `SpreadTradeService#get_spread_open_orders(...)` +- `SpreadTradeService#get_spread_orderbook(...)` +- `SpreadTradeService#get_spread_recent_trades(...)` +- `SpreadTradeService#get_spread_tickers(...)` +- `StrategyService#create_strategy(...)` +- `StrategyService#query_list(...)` +- `StrategyService#query_order_list(...)` +- `StrategyService#stop_strategy(...)` + +### Sources +- OpenAPI: `705f49bf6dba27ecc5b9b402f46ab2423cfb5dd9` +- Docs: `9cde0843c270dd1e6009fb4593272f43f60cccf0` + # Changelog All notable changes to this project will be documented in this file. diff --git a/lib/bybit/client.rb b/lib/bybit/client.rb index c18bf98..661d13d 100644 --- a/lib/bybit/client.rb +++ b/lib/bybit/client.rb @@ -18,6 +18,15 @@ require 'bybit/rest_api/spot_margin_service' require 'bybit/rest_api/trade_service' require 'bybit/rest_api/user_service' +require 'bybit/rest_api/alpha_service' +require 'bybit/rest_api/event_service' +require 'bybit/rest_api/fiat_service' +require 'bybit/rest_api/referral_service' +require 'bybit/rest_api/spot_x_service' +require 'bybit/rest_api/spread_trade_service' +require 'bybit/rest_api/stocks_service' +require 'bybit/rest_api/strategy_service' +require 'bybit/rest_api/tax_service' # gen-sdk-ruby:service-requires:end module Bybit @@ -36,9 +45,10 @@ def configure class Client # gen-sdk-ruby:client-readers:start - attr_reader :account, :affiliate, :asset, :bot, :broker, :crypto_loan, :earn, - :institutional_loan, :market, :misc, :p2p, :position, :pre_upgrade, - :rfq, :spot_margin, :trade, :user + attr_reader :account, :affiliate, :alpha, :asset, :bot, :broker, :crypto_loan, :earn, + :event, :fiat, :institutional_loan, :market, :misc, :p2p, :position, + :pre_upgrade, :referral, :rfq, :spot_margin, :spot_x, :spread_trade, + :stocks, :strategy, :tax, :trade, :user # gen-sdk-ruby:client-readers:end @@ -49,23 +59,36 @@ def initialize(config = nil, **overrides) @config = cfg # gen-sdk-ruby:client-inits:start - @account = RestApi::AccountService.new(session) - @affiliate = RestApi::AffiliateService.new(session) - @asset = RestApi::AssetService.new(session) - @bot = RestApi::BotService.new(session) - @broker = RestApi::BrokerService.new(session) - @crypto_loan = RestApi::CryptoLoanService.new(session) - @earn = RestApi::EarnService.new(session) - @institutional_loan = RestApi::InstitutionalLoanService.new(session) - @market = RestApi::MarketService.new(session) - @misc = RestApi::MiscService.new(session) - @p2p = RestApi::P2pService.new(session) - @position = RestApi::PositionService.new(session) - @pre_upgrade = RestApi::PreUpgradeService.new(session) - @rfq = RestApi::RfqService.new(session) - @spot_margin = RestApi::SpotMarginService.new(session) - @trade = RestApi::TradeService.new(session) - @user = RestApi::UserService.new(session) + { + account: RestApi::AccountService, + affiliate: RestApi::AffiliateService, + alpha: RestApi::AlphaService, + asset: RestApi::AssetService, + bot: RestApi::BotService, + broker: RestApi::BrokerService, + crypto_loan: RestApi::CryptoLoanService, + earn: RestApi::EarnService, + event: RestApi::EventService, + fiat: RestApi::FiatService, + institutional_loan: RestApi::InstitutionalLoanService, + market: RestApi::MarketService, + misc: RestApi::MiscService, + p2p: RestApi::P2pService, + position: RestApi::PositionService, + pre_upgrade: RestApi::PreUpgradeService, + referral: RestApi::ReferralService, + rfq: RestApi::RfqService, + spot_margin: RestApi::SpotMarginService, + spot_x: RestApi::SpotXService, + spread_trade: RestApi::SpreadTradeService, + stocks: RestApi::StocksService, + strategy: RestApi::StrategyService, + tax: RestApi::TaxService, + trade: RestApi::TradeService, + user: RestApi::UserService + }.each do |name, service_class| + instance_variable_set("@#{name}", service_class.new(session)) + end # gen-sdk-ruby:client-inits:end end diff --git a/lib/bybit/rest_api/alpha_service.rb b/lib/bybit/rest_api/alpha_service.rb new file mode 100644 index 0000000..0143fb4 --- /dev/null +++ b/lib/bybit/rest_api/alpha_service.rb @@ -0,0 +1,535 @@ +# frozen_string_literal: true + +module Bybit + module RestApi + class AlphaService < BaseService + # Get LP order history with status and execution details + # + # POST /v5/alpha/lp/order-list + # + # @option kwargs [Integer] :order_type Filter by order type. + # - `0`: All (default) + # - `1`: Stake + # - `2`: Redeem + # @option kwargs [String] :token_code Filter by token code. + # @option kwargs [Array] :order_status Filter by order status (multiple values allowed). + # - `1`: Processing + # - `2`: Success + # - `3`: Failed + # @option kwargs [Integer] :days Query last N days. + # @option kwargs [Integer] :limit Results per page. + # @option kwargs [Integer] :page_index Page number (1-based). + # @option kwargs [String] :pool_address Filter by pool address. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/lp/order-list + def get_lp_order_list(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/alpha/lp/order-list', body: params) + end + + # Get list of supported payment tokens + # + # POST /v5/alpha/lp/pay-token-list + # + # @option kwargs [String] :chain_code Optional - filter by blockchain identifier. + # @option kwargs [String] :token_address Optional - filter by token contract address. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/lp/pay-token-list + def get_lp_pay_token_list(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/alpha/lp/pay-token-list', body: params) + end + + # Get current prices for payment tokens + # + # POST /v5/alpha/lp/pay-token-price + # + # @param token_code [Array] Array of token codes to query (e.g., ["CEX_1", "CEX_2"]). + # @option kwargs [String] :chain_code Optional - filter by blockchain. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/lp/pay-token-price + def get_lp_pay_token_price(token_code:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(tokenCode: token_code)) + @session.sign_request(method: :post, path: '/v5/alpha/lp/pay-token-price', body: params) + end + + # Get detailed information for a specific LP pool + # + # POST /v5/alpha/lp/pool-info + # + # @param pool_address [String] Pool contract address (from getLPPoolList). + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/lp/pool-info + def get_lp_pool_info(pool_address:) + params = Bybit::Utils::WireKeys.camelize({ poolAddress: pool_address }) + @session.sign_request(method: :post, path: '/v5/alpha/lp/pool-info', body: params) + end + + # Get LP pool list with optional filters + # + # POST /v5/alpha/lp/pool-list + # + # @option kwargs [String] :token_symbol Search pools containing this token symbol (e.g., "ETH", "USDC"). + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/lp/pool-list + def get_lp_pool_list(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/alpha/lp/pool-list', body: params) + end + + # Get user's LP positions with rewards and current value + # + # POST /v5/alpha/lp/position-list + # + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/lp/position-list + def get_lp_position_list + @session.sign_request(method: :post, path: '/v5/alpha/lp/position-list') + end + + # Redeem (withdraw) liquidity from a position + # + # POST /v5/alpha/lp/redeem + # + # @param position_id [Integer] Position ID (from getLPPositionList). + # @param pool_address [String] Pool contract address. + # @param derc_ratio [String] Reduction ratio (0-1). + # - "0.25" = redeem 25% + # - "0.5" = redeem 50% + # - "1" = close entire position (redeem 100%) + # @option kwargs [String] :receive_token_code Token code for receiving the redeemed amount. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/lp/redeem + def execute_lp_redeem(position_id:, pool_address:, derc_ratio:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(positionId: position_id, poolAddress: pool_address, dercRatio: derc_ratio)) + @session.sign_request(method: :post, path: '/v5/alpha/lp/redeem', body: params) + end + + # Stake tokens into an LP pool + # + # POST /v5/alpha/lp/stake + # + # @param position_id [Integer] Position ID. Use `0` to create a new position, or provide an existing position ID to add liquidity. + # @param pool_address [String] Pool contract address (from getLPPoolInfo). + # @param pay_token_amount [String] Payment token amount (positive decimal as string). + # @param pay_token_code [String] Payment token code (e.g., "CEX_1" for USDT). + # @option kwargs [String] :range_upper Range order - upper limit. Use this OR priceUpper, not both. + # @option kwargs [String] :range_lower Range order - lower limit. Use this OR priceLower, not both. + # @option kwargs [String] :price_upper Price order - upper limit (price priority). Use this OR rangeUpper, not both. + # @option kwargs [String] :price_lower Price order - lower limit (price priority). Use this OR rangeLower, not both. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/lp/stake + def execute_lp_stake(position_id:, pool_address:, pay_token_amount:, pay_token_code:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(positionId: position_id, poolAddress: pool_address, payTokenAmount: pay_token_amount, payTokenCode: pay_token_code)) + @session.sign_request(method: :post, path: '/v5/alpha/lp/stake', body: params) + end + + # Buy prediction outcome tokens with USDC + # + # POST /v5/alpha/prediction/buy + # + # @param token_id [String] Outcome token ID to buy (from getPredictionEventDetail). + # @param amount [String] USDC amount to invest (positive decimal as string). + # @param pay_token_code [String] Payment token code. Phase 1 fixed to "USDC". + # @param order_type [String] + # @param slippage [String] Maximum acceptable price slippage as decimal (e.g., "0.05" = 5% tolerance). + # @param event_id [String] Event ID associated with the token. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/buy + def execute_prediction_buy(token_id:, amount:, pay_token_code:, order_type:, slippage:, event_id:) + params = Bybit::Utils::WireKeys.camelize({ tokenId: token_id, amount: amount, payTokenCode: pay_token_code, orderType: order_type, slippage: slippage, eventId: event_id }) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/buy', body: params) + end + + # Get prediction market matching engine availability status + # + # GET /v5/alpha/prediction/engine-status + # + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/engine-status + def get_prediction_engine_status + @session.sign_request(method: :get, path: '/v5/alpha/prediction/engine-status') + end + + # Get prediction event detail with all markets and outcomes + # + # POST /v5/alpha/prediction/event-detail + # + # @option kwargs [String] :event_id Event ID. Use slug when available (takes priority). + # @option kwargs [String] :slug URL-friendly event slug. Takes priority over eventId when both provided. + # @option kwargs [Boolean] :has_more_markets Whether to merge markets from related sub-events. Default false. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/event-detail + def get_prediction_event_detail(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/event-detail', body: params) + end + + # Get full order book snapshot for prediction tokens + # + # POST /v5/alpha/prediction/order-book + # + # @param token_ids [Array] List of outcome token IDs. Maximum 20. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/order-book + def get_prediction_order_book(token_ids:) + params = Bybit::Utils::WireKeys.camelize({ tokenIds: token_ids }) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/order-book', body: params) + end + + # Estimate buy or sell order fill amount and fees before execution + # + # POST /v5/alpha/prediction/order-estimate + # + # @param token_id [String] Outcome token ID (from getPredictionEventDetail or getPredictionMarketList). + # @param side [String] + # @param event_id [String] Event ID associated with this token. + # @param amount [String] For BUY: USDC amount to invest (e.g., "100"). + # For SELL: number of shares to sell (e.g., "50"). + # @param order_type [String] + # @option kwargs [String] :pay_token_code Payment token code. Required for BUY. Phase 1 fixed to "USDC". + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/order-estimate + def get_prediction_order_estimate(token_id:, side:, event_id:, amount:, order_type:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(tokenId: token_id, side: side, eventId: event_id, amount: amount, orderType: order_type)) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/order-estimate', body: params) + end + + # Get user's prediction market order history + # + # POST /v5/alpha/prediction/order-list + # + # @option kwargs [String] :status + # @option kwargs [String] :token_id Optional. Filter by specific outcome token ID. + # @option kwargs [Integer] :limit Number of records per page. + # @option kwargs [Integer] :page_index Page number starting from 1. + # @option kwargs [String] :event_id Optional. Filter by event ID. + # @option kwargs [String] :side + # @option kwargs [Integer] :days Look back N days. Maximum 90. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/order-list + def get_prediction_order_list(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/order-list', body: params) + end + + # Get available payment tokens (USDC) for prediction market + # + # GET /v5/alpha/prediction/pay-token-list + # + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/pay-token-list + def get_prediction_pay_token_list + @session.sign_request(method: :get, path: '/v5/alpha/prediction/pay-token-list') + end + + # Get user's prediction market portfolio overview + # + # POST /v5/alpha/prediction/portfolio-summary + # + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/portfolio-summary + def get_prediction_portfolio_summary + @session.sign_request(method: :post, path: '/v5/alpha/prediction/portfolio-summary') + end + + # Get user's historical closed prediction market positions + # + # POST /v5/alpha/prediction/position-history + # + # @option kwargs [Integer] :limit Number of records per page. + # @option kwargs [Integer] :page_index Page number starting from 1. + # @option kwargs [String] :direction Pagination cursor direction. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/position-history + def get_prediction_position_history(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/position-history', body: params) + end + + # Get user's current open prediction market positions + # + # POST /v5/alpha/prediction/position-list + # + # @option kwargs [Integer] :limit Number of records per page. + # @option kwargs [Integer] :page_index Page number starting from 1. + # @option kwargs [String] :direction Pagination cursor direction. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/position-list + def get_prediction_position_list(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/position-list', body: params) + end + + # Get historical price chart data for prediction tokens + # + # POST /v5/alpha/prediction/price-history + # + # @param interval [String] + # @option kwargs [Array] :token_ids Option 1 — List of outcome token IDs. Maximum 20. Mutually exclusive with eventId. + # @option kwargs [String] :event_id Option 2 — Event ID to get price history for all tokens in the event. + # @option kwargs [Integer] :fidelity Minutes between data points. 0 means auto (system default). + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/price-history + def get_prediction_price_history(interval:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(interval: interval)) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/price-history', body: params) + end + + # Sell prediction outcome token shares for USDC + # + # POST /v5/alpha/prediction/sell + # + # @param token_id [String] Outcome token ID to sell (from getPredictionPositionList). + # @param size [String] Number of shares to sell (positive decimal as string). + # @param order_type [String] + # @param slippage [String] Maximum acceptable price slippage as decimal (e.g., "0.05" = 5% tolerance). + # @param event_id [String] Event ID associated with the token. + # @option kwargs [String] :to_token_code Destination token code. Phase 1 fixed to "USDC". + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/sell + def execute_prediction_sell(token_id:, size:, order_type:, slippage:, event_id:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(tokenId: token_id, size: size, orderType: order_type, slippage: slippage, eventId: event_id)) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/sell', body: params) + end + + # Get related side markets for a sports event + # + # POST /v5/alpha/prediction/side-market-list + # + # @param event_type [String] + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/side-market-list + def get_prediction_side_market_list(event_type:) + params = Bybit::Utils::WireKeys.camelize({ eventType: event_type }) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/side-market-list', body: params) + end + + # Get group standings and results for a tournament stage + # + # POST /v5/alpha/prediction/sports/group-stage-detail + # + # @param event_type [String] + # @param stage_code [String] + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/sports/group-stage-detail + def get_prediction_group_stage_detail(event_type:, stage_code:) + params = Bybit::Utils::WireKeys.camelize({ eventType: event_type, stageCode: stage_code }) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/sports/group-stage-detail', body: params) + end + + # Get match list for a sports prediction event + # + # POST /v5/alpha/prediction/sports/match-list + # + # @param event_type [String] + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/sports/match-list + def get_prediction_match_list(event_type:) + params = Bybit::Utils::WireKeys.camelize({ eventType: event_type }) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/sports/match-list', body: params) + end + + # Get tournament timeline stages for a sports event + # + # GET /v5/alpha/prediction/sports/timeline-stages + # + # @option kwargs [String] :event_type Sports event type. `1` = FIFA_2026. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/sports/timeline-stages + def get_prediction_timeline_stages(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/alpha/prediction/sports/timeline-stages', params: params) + end + + # Get real-time prices for prediction outcome tokens + # + # POST /v5/alpha/prediction/token-price + # + # @param token_ids [Array] List of outcome token IDs to query. Maximum 20. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/token-price + def get_prediction_token_price(token_ids:) + params = Bybit::Utils::WireKeys.camelize({ tokenIds: token_ids }) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/token-price', body: params) + end + + # Get holding details for a specific token including quantity, PnL, and cost basis + # + # POST /v5/alpha/trade/asset-detail + # + # @param chain_code [String] Blockchain code (ETH, SOL, BSC, etc.). + # @param token_address [String] Token contract address on chain. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/asset-detail + def get_asset_detail(chain_code:, token_address:) + params = Bybit::Utils::WireKeys.camelize({ chainCode: chain_code, tokenAddress: token_address }) + @session.sign_request(method: :post, path: '/v5/alpha/trade/asset-detail', body: params) + end + + # Get user's on-chain token portfolio with holdings, PnL, and market value + # + # POST /v5/alpha/trade/asset-list + # + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/asset-list + def get_asset_list + @session.sign_request(method: :post, path: '/v5/alpha/trade/asset-list') + end + + # Get token project details including description, social links, risk flag, and order limits + # + # POST /v5/alpha/trade/biz-token-details + # + # @param chain_code [String] Blockchain code (ETH, SOL, BSC, etc.). + # @param token_address [String] Token contract address on chain. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/biz-token-details + def get_biz_token_details(chain_code:, token_address:) + params = Bybit::Utils::WireKeys.camelize({ chainCode: chain_code, tokenAddress: token_address }) + @session.sign_request(method: :post, path: '/v5/alpha/trade/biz-token-details', body: params) + end + + # Get on-chain tradable tokens with DEX token codes, risk flags, and order limits + # + # POST /v5/alpha/trade/biz-token-list + # + # @option kwargs [Integer] :token_tag Token tag filter. + # - `0`: All (no filter, default) + # - `1`: New token sniping + # - `2`: On-chain hot token + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/biz-token-list + def get_biz_token_list(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/alpha/trade/biz-token-list', body: params) + end + + # Batch query token prices, 24h change, volume, market cap, liquidity, and holders by chain+address + # + # POST /v5/alpha/trade/biz-token-price-list + # + # @param token_address_info [Array] List of token identifiers to query. Maximum 20 items per request. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/biz-token-price-list + def get_biz_token_price_list(token_address_info:) + params = Bybit::Utils::WireKeys.camelize({ tokenAddressInfo: token_address_info }) + @session.sign_request(method: :post, path: '/v5/alpha/trade/biz-token-price-list', body: params) + end + + # Get trade order history with status, fees, and execution details + # + # POST /v5/alpha/trade/order-list + # + # @option kwargs [Integer] :trade_type Filter by trade type. + # - `0`: All (default) + # - `1`: Purchase (buy) + # - `2`: Redeem (sell) + # @option kwargs [String] :token_code Filter by token code. + # @option kwargs [Array] :order_status Filter by order status (multiple values allowed). + # - `1`: Processing + # - `2`: Success + # - `3`: Failed + # @option kwargs [Integer] :days Query last N days. Maximum 90. `0` means use system default (90 days). + # @option kwargs [Integer] :limit Results per page. + # @option kwargs [Integer] :page_index Page number (1-based). + # @option kwargs [String] :direction Pagination direction. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/order-list + def get_order_list(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/alpha/trade/order-list', body: params) + end + + # Get available payment tokens (USDT, USDC, etc.) with CEX token codes and supported chains + # + # POST /v5/alpha/trade/pay-token-list + # + # @param chain_code [String] Blockchain code (e.g. SOL, MANTLE). + # @param token_address [String] Token contract address on chain. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/pay-token-list + def get_pay_token_list(chain_code:, token_address:) + params = Bybit::Utils::WireKeys.camelize({ chainCode: chain_code, tokenAddress: token_address }) + @session.sign_request(method: :post, path: '/v5/alpha/trade/pay-token-list', body: params) + end + + # Execute a buy order to purchase on-chain tokens with USDT/USDC, returns order number + # + # POST /v5/alpha/trade/purchase + # + # @param from_token_code [String] Payment token code (`CEX_`, e.g. `CEX_1` for USDT). Must match the quote request. + # @param from_token_amount [String] Payment amount (positive decimal as string). Must match the quote request. + # @param to_token_code [String] Target on-chain token code (`DEX_`). Must match the quote request. + # @param slippage [String] Slippage tolerance as decimal. + # - `0.005` = 0.5% + # - `0.01` = 1% + # - `0.05` = 5% + # @param quote_data [String] Base64-encoded quote data. **Must pass as-is from `/quote` response.** + # @param gas [String] Estimated gas fee. **Must pass as-is from `/quote` response.** + # @param quote_mode [Integer] Quote mode. Must be consistent with the `/quote` request. + # - `0`: Auto + # - `1`: Price Priority + # - `2`: Success Rate Priority + # @param correcting_code [String] MD5 checksum for data integrity. **Must pass as-is from `/quote` response.** + # @option kwargs [String] :tenant Optional tenant identifier. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/purchase + def execute_purchase(from_token_code:, from_token_amount:, to_token_code:, slippage:, quote_data:, gas:, quote_mode:, correcting_code:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(fromTokenCode: from_token_code, fromTokenAmount: from_token_amount, toTokenCode: to_token_code, slippage: slippage, quoteData: quote_data, gas: gas, quoteMode: quote_mode, correctingCode: correcting_code)) + @session.sign_request(method: :post, path: '/v5/alpha/trade/purchase', body: params) + end + + # Get estimated price, fees, slippage, and gas for an on-chain token trade + # + # POST /v5/alpha/trade/quote + # + # @param trade_type [Integer] Trade type. + # - `1`: Purchase (buy on-chain token with payment token) + # - `2`: Redeem (sell on-chain token for payment token) + # @param from_token_code [String] Source token code. Format: `CEX_` or `DEX_`. + # - Purchase: CEX token code (e.g. `CEX_1` for USDT). Get from `getPayTokenList`. + # - Redeem: DEX token code (e.g. `DEX_123`). Get from `getBizTokenList` or `getAssetList`. + # @param from_token_amount [String] Amount to pay (string-formatted positive decimal for precision). Must be greater than 0. + # @param to_token_code [String] Target token code. Format: `CEX_` or `DEX_`. + # - Purchase: DEX token code (e.g. `DEX_123`). Get from `getBizTokenList`. + # - Redeem: CEX token code (e.g. `CEX_1` for USDT). Get from `getPayTokenList`. + # @option kwargs [Integer] :quote_mode Quote mode. + # - `0`: Auto (default) - system selects optimal mode + # - `1`: Price Priority - best price, may have higher failure rate + # - `2`: Success Rate Priority - guaranteed execution, price may be slightly worse + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/quote + def get_trade_quote(trade_type:, from_token_code:, from_token_amount:, to_token_code:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(tradeType: trade_type, fromTokenCode: from_token_code, fromTokenAmount: from_token_amount, toTokenCode: to_token_code)) + @session.sign_request(method: :post, path: '/v5/alpha/trade/quote', body: params) + end + + # Execute a sell order to redeem on-chain tokens for USDT/USDC, returns order number + # + # POST /v5/alpha/trade/redeem + # + # @param from_token_code [String] On-chain token to sell (`DEX_`). Must match the quote request. + # @param from_token_amount [String] Amount to sell (positive decimal as string). Must match the quote request. + # @param to_token_code [String] Payment token to receive (`CEX_`, e.g. `CEX_1` for USDT). Must match the quote request. + # @param slippage [String] Slippage tolerance as decimal. + # - `0.005` = 0.5% + # - `0.01` = 1% + # - `0.05` = 5% + # @param quote_data [String] Base64-encoded quote data. **Must pass as-is from `/quote` response.** + # @param gas [String] Estimated gas fee. **Must pass as-is from `/quote` response.** + # @param quote_mode [Integer] Quote mode. Must be consistent with the `/quote` request. + # - `0`: Auto + # - `1`: Price Priority + # - `2`: Success Rate Priority + # @param correcting_code [String] MD5 checksum for data integrity. **Must pass as-is from `/quote` response.** + # @option kwargs [String] :tenant Optional tenant identifier. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/redeem + def execute_redeem(from_token_code:, from_token_amount:, to_token_code:, slippage:, quote_data:, gas:, quote_mode:, correcting_code:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(fromTokenCode: from_token_code, fromTokenAmount: from_token_amount, toTokenCode: to_token_code, slippage: slippage, quoteData: quote_data, gas: gas, quoteMode: quote_mode, correctingCode: correcting_code)) + @session.sign_request(method: :post, path: '/v5/alpha/trade/redeem', body: params) + end + end + end +end diff --git a/lib/bybit/rest_api/event_service.rb b/lib/bybit/rest_api/event_service.rb new file mode 100644 index 0000000..55dfecb --- /dev/null +++ b/lib/bybit/rest_api/event_service.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +module Bybit + module RestApi + class EventService < BaseService + # Get Event Contract Order History + # + # GET /v5/event/order-list + # + # @option kwargs [String] :symbol Symbol name, e.g. `BTCUSDT-EC` + # @option kwargs [String] :order_id Order ID + # @option kwargs [String] :order_link_id User-defined order ID + # @option kwargs [Integer] :start_time Start time in milliseconds. Default: 7 days ago + # @option kwargs [Integer] :end_time End time in milliseconds. Default: now + # @option kwargs [Integer] :limit Number of items per page. Default: `50`, Range: [`1`, `100`] + # @option kwargs [String] :cursor Pagination cursor + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/event/order-list + def get_ec_order_history(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/event/order-list', params: params) + end + + # Get Event Contract Active Orders + # + # GET /v5/event/order-realtime + # + # @option kwargs [String] :symbol Symbol name, e.g. `BTCUSDT-EC` + # @option kwargs [String] :order_id Order ID. If both `orderId` and `orderLinkId` are passed, `orderId` takes priority + # @option kwargs [String] :order_link_id User-defined order ID + # @option kwargs [Integer] :limit Number of items per page. Default: `20`, Range: [`1`, `50`] + # @option kwargs [String] :cursor Pagination cursor. Use `nextPageCursor` from the response to retrieve the next page + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/event/order-realtime + def get_ec_active_orders(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/event/order-realtime', params: params) + end + + # Get Event Contract Position Info + # + # GET /v5/event/positions + # + # @option kwargs [String] :symbol Symbol name, e.g. `BTCUSDT-EC`. If not passed, returns all EC positions + # @option kwargs [String] :base_coin Base coin filter, e.g. `BTC` + # @option kwargs [String] :settle_coin Settle coin filter, e.g. `USDT` + # @option kwargs [Integer] :limit Number of items per page. Default: `20`, Range: [`1`, `50`] + # @option kwargs [String] :cursor Pagination cursor. Use `nextPageCursor` from the response to retrieve the next page + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/event/positions + def get_ec_position_info(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/event/positions', params: params) + end + + # Get Event Contract Settlement Records + # + # GET /v5/event/settlements + # + # @param symbol [String] Symbol name, e.g. `BTCUSDT-EC` + # @option kwargs [String] :order_id Order ID filter + # @option kwargs [Integer] :start_time Start time in milliseconds. Default: 7 days ago + # @option kwargs [Integer] :end_time End time in milliseconds. Default: now + # @option kwargs [Integer] :limit Number of items per page. Default: `50`, Range: [`1`, `100`] + # @option kwargs [String] :cursor Pagination cursor + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/event/settlements + def get_ec_settlements(symbol:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) + @session.sign_request(method: :get, path: '/v5/event/settlements', params: params) + end + + # Get Event Contract Trade History + # + # GET /v5/event/trades + # + # @param symbol [String] Symbol name, e.g. `BTCUSDT-EC` + # @option kwargs [String] :order_id Order ID filter + # @option kwargs [String] :order_link_id User-defined order ID + # @option kwargs [Integer] :start_time Start time in milliseconds. Default: 7 days ago + # @option kwargs [Integer] :end_time End time in milliseconds. Default: now + # @option kwargs [Integer] :limit Number of items per page. Default: `50`, Range: [`1`, `100`] + # @option kwargs [String] :cursor Pagination cursor + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/event/trades + def get_ec_trade_history(symbol:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) + @session.sign_request(method: :get, path: '/v5/event/trades', params: params) + end + end + end +end diff --git a/lib/bybit/rest_api/fiat_service.rb b/lib/bybit/rest_api/fiat_service.rb new file mode 100644 index 0000000..67c6954 --- /dev/null +++ b/lib/bybit/rest_api/fiat_service.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +module Bybit + module RestApi + class FiatService < BaseService + # Query Account Balance + # + # GET /v5/fiat/balance-query + # + # @option kwargs [String] :account_category Account type (reserved field) + # @option kwargs [String] :currency Currency code: + # - Fiat: ISO 4217 standard code, e.g., EUR, GEL, KZT + # - Crypto: e.g., USDT, BTC, ETH + # - Omit to query all balances + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/fiat/balance-query + def query_balance(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/fiat/balance-query', params: params) + end + + # Get Trading Pairs + # + # GET /v5/fiat/query-coin-list + # + # @option kwargs [Integer] :side Trading direction: + # - `0`: buy - Buy crypto, sell fiat + # - `1`: sell - Sell crypto, buy fiat + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/fiat/query-coin-list + def query_coin_list(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/fiat/query-coin-list', params: params) + end + + # Query Trade History + # + # GET /v5/fiat/query-trade-history + # + # @option kwargs [Integer] :index Page number, starts from 1 + # @option kwargs [Integer] :limit Page size, maximum 100 + # @option kwargs [String] :start_time Query start time (millisecond timestamp) + # @option kwargs [String] :end_time Query end time (millisecond timestamp) + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/fiat/query-trade-history + def query_trade_history(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/fiat/query-trade-history', params: params) + end + + # Request a Quote + # + # POST /v5/fiat/quote-apply + # + # @param from_coin [String] Convert from coin (coin to sell) + # @param from_coin_type [String] From coin type + # @param to_coin [String] Convert to coin (coin to buy) + # @param to_coin_type [String] To coin type + # @param request_amount [String] Request coin amount (the amount you want to sell) + # @option kwargs [String] :request_coin_type Coin type you want to sell, defaults to fiat + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/fiat/quote-apply + def apply_quote(from_coin:, from_coin_type:, to_coin:, to_coin_type:, request_amount:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(fromCoin: from_coin, fromCoinType: from_coin_type, toCoin: to_coin, toCoinType: to_coin_type, requestAmount: request_amount)) + @session.sign_request(method: :post, path: '/v5/fiat/quote-apply', body: params) + end + + # Get Reference Price + # + # GET /v5/fiat/reference-price + # + # @param symbol [String] Coin pair, format: "FIAT-CRYPTO", e.g., "EUR-USDT" + # @option kwargs [String] :payment_method Payment method (reserved field) + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/fiat/reference-price + def get_reference_price(symbol:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) + @session.sign_request(method: :get, path: '/v5/fiat/reference-price', params: params) + end + + # Confirm Quote and Execute Trade + # + # POST /v5/fiat/trade-execute + # + # @param quote_tx_id [String] Quote transaction ID from the quote request + # @param sub_user_id [String] The user's sub userId in Bybit + # @option kwargs [String] :webhook_url Optional webhook URL to receive trade status notifications (max 256 characters) + # @option kwargs [String] :merchant_request_id Customised request ID (max 36 characters). Generally it is useless, but convenient for internal tracking + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/fiat/trade-execute + def confirm_quote(quote_tx_id:, sub_user_id:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(quoteTxId: quote_tx_id, subUserId: sub_user_id)) + @session.sign_request(method: :post, path: '/v5/fiat/trade-execute', body: params) + end + + # Query Trade Status + # + # GET /v5/fiat/trade-query + # + # @option kwargs [String] :trade_no Trade order number (either tradeNo or merchantRequestId must be provided) + # @option kwargs [String] :merchant_request_id Merchant request ID (either tradeNo or merchantRequestId must be provided) + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/fiat/trade-query + def query_trade(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/fiat/trade-query', params: params) + end + end + end +end diff --git a/lib/bybit/rest_api/institutional_loan_service.rb b/lib/bybit/rest_api/institutional_loan_service.rb index 048b771..40915d6 100644 --- a/lib/bybit/rest_api/institutional_loan_service.rb +++ b/lib/bybit/rest_api/institutional_loan_service.rb @@ -101,6 +101,28 @@ def repay_loan(order_id:, amount:, **kwargs) params = Bybit::Utils::WireKeys.camelize(params) @session.sign_request(method: :post, path: '/v5/ins-loan/repay-loan', body: params) end + + # Get Coin Delta Amount + # + # GET /v5/ins-loan/coin-delta-amount + # + # @option kwargs [String] :coin Coin name to filter, uppercase only. e.g. `BTC`. If not passed, returns all coins. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/ins-loan/coin-delta-amount + def ins_loan_coin_delta_amount(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/ins-loan/coin-delta-amount', params: params) + end + + # Get Delay Liquidation Status + # + # GET /v5/ins-loan/delay-liq-status + # + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/ins-loan/delay-liq-status + def ins_loan_delay_liq_status + @session.sign_request(method: :get, path: '/v5/ins-loan/delay-liq-status') + end end end end diff --git a/lib/bybit/rest_api/referral_service.rb b/lib/bybit/rest_api/referral_service.rb new file mode 100644 index 0000000..d7e9dfc --- /dev/null +++ b/lib/bybit/rest_api/referral_service.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module Bybit + module RestApi + class ReferralService < BaseService + # Get referral rules and campaign task rewards for the current site + # + # POST /v5/referral/campaign/rewards + # + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/referral/campaign/rewards + def get_campaign_rewards + @session.sign_request(method: :post, path: '/v5/referral/campaign/rewards') + end + + # Get Referral Commission Records + # + # POST /v5/referral/commission/records + # + # @option kwargs [Array] :user_id_list Invitee ID list; an empty list does not filter by invitee. + # @option kwargs [String] :start_time Query start time in YYYY-MM-DD HH:mm:ss format; an invalid value is passed downstream as an empty string, whose handling is unverified. + # @option kwargs [String] :end_time Query end time in YYYY-MM-DD HH:mm:ss format; an invalid value is passed downstream as an empty string, whose handling is unverified. + # @option kwargs [Integer] :page One-based page number; 0 is treated as 1. + # @option kwargs [Integer] :page_size Number of records per page; 0 or a value greater than 200 is treated as 10. + # @option kwargs [Integer] :product_line Product lines: 0=unknown; 1=spot; 2=contracts; 3=options; 4=USDC perpetual; 6=TradeFi; 9=Alpha. Unrecognized downstream product lines map to 0. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/referral/commission/records + def get_commission_records(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/referral/commission/records', body: params) + end + + # Get Referral User Identity Profile + # + # POST /v5/referral/user/identity-profile + # + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/referral/user/identity-profile + def get_user_identity_profile + @session.sign_request(method: :post, path: '/v5/referral/user/identity-profile') + end + + # Get referral user invitations + # + # POST /v5/referral/user/invitations + # + # @option kwargs [Array] :user_id_list + # @option kwargs [String] :start_time Recommended format: YYYY-MM-DD HH:mm:ss; invalid or empty values are passed downstream as 0. + # @option kwargs [String] :end_time Recommended format: YYYY-MM-DD HH:mm:ss; invalid or empty values are passed downstream as 0. + # @option kwargs [Integer] :page + # @option kwargs [Integer] :page_size Values 0 and greater than 200 are reset to 10 by the current service implementation. + # @option kwargs [Integer] :friend_status + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/referral/user/invitations + def get_user_invitations(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/referral/user/invitations', body: params) + end + end + end +end diff --git a/lib/bybit/rest_api/spot_margin_service.rb b/lib/bybit/rest_api/spot_margin_service.rb index d6a967e..69b78a2 100644 --- a/lib/bybit/rest_api/spot_margin_service.rb +++ b/lib/bybit/rest_api/spot_margin_service.rb @@ -288,6 +288,33 @@ def spot_margin_switch_mode(spot_margin_mode:) params = Bybit::Utils::WireKeys.camelize({ spotMarginMode: spot_margin_mode }) @session.sign_request(method: :post, path: '/v5/spot-margin-trade/switch-mode', body: params) end + + # Query Fixed-Rate Borrow Penalty Interest + # + # GET /v5/spot-margin-trade/fixedborrow-interest-accrued + # + # @option kwargs [String] :order_id Filter by fixed-rate borrow order ID. + # @option kwargs [String] :order_currency Filter by a single borrow coin, such as `USDT`. + # @option kwargs [String] :limit Page size as a string, from 1 to 100; defaults to 10. + # @option kwargs [String] :cursor Opaque `nextPageCursor` returned by the previous page. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spot-margin-trade/fixedborrow-interest-accrued + def query_fixed_borrow_penalty_interest(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/spot-margin-trade/fixedborrow-interest-accrued', params: params) + end + + # Cancel Fixed-Rate Borrow Order + # + # POST /v5/spot-margin-trade/fixedborrow-order-cancel + # + # @param order_id [String] Fixed-rate borrow order ID, not the contract match ID. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spot-margin-trade/fixedborrow-order-cancel + def cancel_fixed_borrow_order(order_id:) + params = Bybit::Utils::WireKeys.camelize({ orderId: order_id }) + @session.sign_request(method: :post, path: '/v5/spot-margin-trade/fixedborrow-order-cancel', body: params) + end end end end diff --git a/lib/bybit/rest_api/spot_x_service.rb b/lib/bybit/rest_api/spot_x_service.rb new file mode 100644 index 0000000..57531f5 --- /dev/null +++ b/lib/bybit/rest_api/spot_x_service.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +module Bybit + module RestApi + class SpotXService < BaseService + # Get Launchpool project (activity) list + # + # GET /v5/spot-x/launchpool/project/list + # + # @param status [Integer] Activity phase filter. + # - `0` — Upcoming + # - `1` — Ongoing + # - `2` — Ended + # @option kwargs [String] :activity_coin Filter by activity (reward) coin symbol (case-insensitive), e.g. `BTC`, `ETH`. + # @option kwargs [String] :project_id Exact activity code. Use to query a single project. + # @option kwargs [String] :cursor Pagination cursor returned as `nextPageCursor` in the previous response. Omit for the first page. + # @option kwargs [Integer] :limit Number of items per page. Defaults to `10`. Maximum `10`. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spot-x/launchpool/project/list + def get_launchpool_project_list(status:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(status: status)) + @session.public_request(path: '/v5/spot-x/launchpool/project/list', params: params) + end + + # Get user's staking operation records + # + # POST /v5/spot-x/launchpool/user/activity-log + # + # @option kwargs [String] :stake_coin Filter by stake coin symbol (case-sensitive). + # @option kwargs [Integer] :type Filter by operation type. Omit to return all types. + # - `0` PLEDGE — manual stake-in + # - `1` REDEEM — manual redeem + # - `2` INTEREST — reward/interest credit + # - `3` AUTO_REDEEM — auto principal return on maturity + # - `4` LOAN_PLEDGE — leveraged stake-in + # - `5` LOAN_REDEEM — manual leveraged redeem + # - `6` LOAN_AUTO_REDEEM — auto leveraged maturity redemption + # - `7` LOAN_RISKRATE_AUTO_REDEEM — leveraged liquidation + # - `8` RISK_USER_AUTO_REDEEM — risk-control forced redeem (non-leveraged) + # - `9` LOAN_RISK_USER_AUTO_REDEEM — risk-control forced redeem (leveraged) + # - `10` EARN_REWARD — earn product reward credit + # @option kwargs [Integer] :status Filter by record status. Omit to return all statuses. + # - `0` — Pending + # - `1` — Success + # - `2` — Failed + # @option kwargs [String] :start_time Query start time — 13-digit Unix millisecond timestamp string. + # Must be provided together with `endTime`. + # @option kwargs [String] :end_time Query end time — 13-digit Unix millisecond timestamp string. + # Must be provided together with `startTime`. + # @option kwargs [Integer] :page_size Number of records per page. Defaults to `10`. Maximum `10`. + # @option kwargs [Integer] :current Page number (1-based). Defaults to `1`. Maximum `100`. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spot-x/launchpool/user/activity-log + def get_launchpool_user_activity_log(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/spot-x/launchpool/user/activity-log', body: params) + end + + # Get user's active staking positions + # + # GET /v5/spot-x/launchpool/user/current-staking + # + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spot-x/launchpool/user/current-staking + def get_launchpool_user_current_staking + @session.sign_request(method: :get, path: '/v5/spot-x/launchpool/user/current-staking') + end + + # Get user's completed staking position history + # + # POST /v5/spot-x/launchpool/user/history + # + # @option kwargs [String] :stake_coin Filter by stake coin symbol. + # @option kwargs [String] :reward_coin Filter by reward coin symbol. + # @option kwargs [String] :start_time Staking period start filter — 13-digit Unix millisecond timestamp string. + # Filters positions whose `stakeBeginTime` is on or after this value. + # Must be provided together with `endTime`. + # @option kwargs [String] :end_time Staking period end filter — 13-digit Unix millisecond timestamp string. + # Filters positions whose `stakeEndTime` is on or before this value. + # Must be provided together with `startTime`. + # @option kwargs [Integer] :page_size Number of records per page. Defaults to `10`. Maximum `10`. + # @option kwargs [Integer] :current Page number (1-based). Defaults to `1`. Maximum `100`. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spot-x/launchpool/user/history + def get_launchpool_user_history(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/spot-x/launchpool/user/history', body: params) + end + + # Get Puzzle project (activity) list + # + # GET /v5/spot-x/puzzle/project/list + # + # @param status [Integer] Activity phase filter. + # - `0` — Upcoming (not yet started) + # - `1` — Ongoing (in progress) + # - `2` — Ended + # @option kwargs [String] :project_id Exact activity code (unique project identifier). Use to query a single project. + # @option kwargs [String] :activity_coin Filter by activity coin symbol (case-insensitive), e.g. `BTC`, `ETH`. + # @option kwargs [String] :cursor Pagination cursor returned as `nextPageCursor` in the previous response. Omit for the first page. + # @option kwargs [Integer] :limit Number of items per page. Defaults to `10`. Maximum `10`. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spot-x/puzzle/project/list + def get_puzzle_project_list(status:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(status: status)) + @session.public_request(path: '/v5/spot-x/puzzle/project/list', params: params) + end + + # Get Token Splash project (activity) list + # + # GET /v5/spot-x/token-splash/project/list + # + # @param status [Integer] Activity phase filter. + # - `0` — Upcoming (registration not yet started) + # - `1` — Ongoing (activity in progress) + # - `2` — Ended (announcement time has passed) + # @option kwargs [String] :project_id Exact activity code. Use to query a single project. + # @option kwargs [String] :activity_coin Filter by activity coin symbol (case-insensitive), e.g. `BTC`, `ETH`. + # @option kwargs [String] :cursor Pagination cursor returned as `nextPageCursor` in the previous response. Omit for the first page. + # @option kwargs [Integer] :limit Number of items per page. Defaults to `10`. Maximum `10`. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spot-x/token-splash/project/list + def get_token_splash_project_list(status:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(status: status)) + @session.public_request(path: '/v5/spot-x/token-splash/project/list', params: params) + end + + # Get user's Token Splash trade-task progress + # + # GET /v5/spot-x/token-splash/user/activity-params + # + # @option kwargs [String] :project_id Filter by exact activity code. Returns data for a single project when provided. + # @option kwargs [String] :activity_coin Filter by activity coin symbol (case-insensitive), e.g. `BTC`, `ETH`. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spot-x/token-splash/user/activity-params + def get_token_splash_user_activity_params(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/spot-x/token-splash/user/activity-params', params: params) + end + end + end +end diff --git a/lib/bybit/rest_api/spread_trade_service.rb b/lib/bybit/rest_api/spread_trade_service.rb new file mode 100644 index 0000000..646eb02 --- /dev/null +++ b/lib/bybit/rest_api/spread_trade_service.rb @@ -0,0 +1,202 @@ +# frozen_string_literal: true + +module Bybit + module RestApi + class SpreadTradeService < BaseService + # Get Trade History + # + # GET /v5/spread/execution/list + # + # @option kwargs [String] :symbol Spread combination symbol name. + # @option kwargs [String] :order_id Spread combination order ID. + # @option kwargs [String] :order_link_id User-defined custom order ID. + # @option kwargs [Integer] :start_time Start timestamp in milliseconds. See time range logic in description. + # @option kwargs [Integer] :end_time End timestamp in milliseconds. See time range logic in description. + # @option kwargs [Integer] :limit Number of results per page. Range `[1, 50]`. Default `20`. + # @option kwargs [String] :cursor Pagination cursor token from `nextPageCursor` in a previous response. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/execution/list + def get_history(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/spread/execution/list', params: params) + end + + # Get Spread Instruments Info + # + # GET /v5/spread/instrument + # + # @option kwargs [String] :symbol Spread combination symbol name, e.g. `SOLUSDT_SOL/USDT` + # @option kwargs [String] :base_coin Base coin in uppercase, e.g. `SOL` + # @option kwargs [Integer] :limit Number of records per page, range `[1, 500]`. Default is `200` + # @option kwargs [String] :cursor Pagination cursor; use `nextPageCursor` from the previous response + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/instrument + def get_spread_instruments_info(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.public_request(path: '/v5/spread/instrument', params: params) + end + + # Get Spread Wallet Balance + # + # GET /v5/spread/max-qty + # + # @param symbol [String] Spread trading pair. + # @param side [String] Order side: + # - `1`: Buy + # - `2`: Sell + # @param order_price [String] Order price. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/max-qty + def get_spread_max_qty(symbol:, side:, order_price:) + params = Bybit::Utils::WireKeys.camelize({ symbol: symbol, side: side, orderPrice: order_price }) + @session.sign_request(method: :get, path: '/v5/spread/max-qty', params: params) + end + + # Amend Order + # + # POST /v5/spread/order/amend + # + # @param symbol [String] Spread combination symbol name. + # @option kwargs [String] :order_id Spread combination order ID. Either `orderId` or `orderLinkId` is required. + # @option kwargs [String] :order_link_id User-defined custom order ID. Either `orderId` or `orderLinkId` is required. + # @option kwargs [String] :qty New order quantity after modification (string-formatted number). + # At least one of `qty` or `price` must be provided. + # @option kwargs [String] :price New order price after modification (string-formatted number). + # At least one of `qty` or `price` must be provided. + # - `""` (empty string): keeps the existing price unchanged. + # - `"0"`: updates the price to zero. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/order/amend + def amend_spread_order(symbol:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) + @session.sign_request(method: :post, path: '/v5/spread/order/amend', body: params) + end + + # Cancel Order + # + # POST /v5/spread/order/cancel + # + # @option kwargs [String] :order_id Spread combination order ID. Either `orderId` or `orderLinkId` is required. + # @option kwargs [String] :order_link_id User-defined custom order ID. Either `orderId` or `orderLinkId` is required. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/order/cancel + def cancel_spread_order(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/spread/order/cancel', body: params) + end + + # Cancel All Orders + # + # POST /v5/spread/order/cancel-all + # + # @option kwargs [String] :symbol Spread combination symbol name. When specified, all orders for this symbol + # are cancelled and `cancelAll` is ignored. + # @option kwargs [Boolean] :cancel_all Set to `true` to cancel all open orders across all symbols. + # Ignored when `symbol` is provided. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/order/cancel-all + def cancel_all_spread_orders(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/spread/order/cancel-all', body: params) + end + + # Create Order + # + # POST /v5/spread/order/create + # + # @param symbol [String] Spread combination symbol name. + # @param side [String] Order direction. + # @param order_type [String] Order type. + # @param qty [String] Order quantity (string-formatted number). + # @option kwargs [String] :price Order price (string-formatted number). Required for Limit orders. + # Not required for Market orders. + # @option kwargs [String] :order_link_id User-defined custom order identifier. Maximum 45 characters. + # Supports alphanumeric characters, dashes, and underscores. + # @option kwargs [String] :time_in_force Time-in-force strategy for order execution. + # - `GTC`: Good Till Cancel (default for Limit). + # - `IOC`: Immediate or Cancel. + # - `FOK`: Fill or Kill. + # - `PostOnly`: Maker-only; rejected if it would take liquidity. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/order/create + def create_spread_order(symbol:, side:, order_type:, qty:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol, side: side, orderType: order_type, qty: qty)) + @session.sign_request(method: :post, path: '/v5/spread/order/create', body: params) + end + + # Get Order History + # + # GET /v5/spread/order/history + # + # @option kwargs [String] :symbol Spread combination symbol name. + # @option kwargs [String] :base_coin Base coin to filter by. + # @option kwargs [String] :order_id Spread combination order ID. Has higher priority than time-based filters. + # @option kwargs [String] :order_link_id User-defined custom order ID. Has higher priority than time-based filters. + # @option kwargs [Integer] :start_time Start timestamp in milliseconds. See time range logic in description. + # @option kwargs [Integer] :end_time End timestamp in milliseconds. See time range logic in description. + # @option kwargs [Integer] :limit Number of results per page. Range `[1, 50]`. Default `20`. + # @option kwargs [String] :cursor Pagination cursor token from `nextPageCursor` in a previous response. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/order/history + def get_spread_order_history(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/spread/order/history', params: params) + end + + # Get Open Orders + # + # GET /v5/spread/order/realtime + # + # @option kwargs [String] :symbol Spread combination symbol name. + # @option kwargs [String] :base_coin Base coin to filter by. + # @option kwargs [String] :order_id Spread combination order ID. + # @option kwargs [String] :order_link_id User-defined custom order ID. + # @option kwargs [Integer] :limit Number of results per page. Range `[1, 50]`. Default `20`. + # @option kwargs [String] :cursor Pagination cursor token from `nextPageCursor` in a previous response. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/order/realtime + def get_spread_open_orders(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/spread/order/realtime', params: params) + end + + # Get Spread Orderbook + # + # GET /v5/spread/orderbook + # + # @param symbol [String] Spread combination symbol name, e.g. `SOLUSDT_SOL/USDT` + # @option kwargs [Integer] :limit Number of bid/ask levels per side, range `[1, 25]`. Default is `1` + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/orderbook + def get_spread_orderbook(symbol:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) + @session.public_request(path: '/v5/spread/orderbook', params: params) + end + + # Get Spread Recent Public Trades + # + # GET /v5/spread/recent-trade + # + # @param symbol [String] Spread combination symbol name, e.g. `SOLUSDT_SOL/USDT` + # @option kwargs [Integer] :limit Number of records per page, range `[1, 1000]`. Default is `500` + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/recent-trade + def get_spread_recent_trades(symbol:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) + @session.public_request(path: '/v5/spread/recent-trade', params: params) + end + + # Get Spread Tickers + # + # GET /v5/spread/tickers + # + # @param symbol [String] Spread combination symbol name, e.g. `SOLUSDT_SOL/USDT` + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/spread/tickers + def get_spread_tickers(symbol:) + params = Bybit::Utils::WireKeys.camelize({ symbol: symbol }) + @session.public_request(path: '/v5/spread/tickers', params: params) + end + end + end +end diff --git a/lib/bybit/rest_api/stocks_service.rb b/lib/bybit/rest_api/stocks_service.rb new file mode 100644 index 0000000..960fdd2 --- /dev/null +++ b/lib/bybit/rest_api/stocks_service.rb @@ -0,0 +1,154 @@ +# frozen_string_literal: true + +module Bybit + module RestApi + class StocksService < BaseService + # 查询 Convert 订单详情 + # + # GET /v5/rwa/stocks/convert/detail + # + # @option kwargs [String] :order_no Convert 订单号;与 `requestId` 二选一 + # @option kwargs [String] :request_id 提交时使用的幂等键;与 `orderNo` 二选一 + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/convert/detail + def get_convert_detail(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/rwa/stocks/convert/detail', params: params) + end + + # 获取 Convert 交易对列表 + # + # GET /v5/rwa/stocks/convert/list + # + # @option kwargs [String] :symbol 按标的过滤,如 `AAPL-US`;不传则返回全部 + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/convert/list + def get_convert_list(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/rwa/stocks/convert/list', params: params) + end + + # 提交 Convert 订单(Mint / Redeem) + # + # POST /v5/rwa/stocks/convert/submit + # + # @param convert_type [String] 方向:MINT(正股→Token)/ REDEEM(Token→正股) + # @param symbol [String] 底层股票代码,如 `AAPL-US` + # @param input_amount [String] 输入数量(MINT 时为正股数量,REDEEM 时为 Token 数量) + # @param front_multiplier [String] 前端快照的转换比例,服务端会与当前值校验 + # @param request_id [String] 幂等键,字母数字与 `-_`,同一 MM 账号下 24 小时内唯一 + # @param flow [String] 链路类型。 + # - `CEX`:中心化交易所链路,Mint/Burn 均通过 Bybit 主站处理 + # - `DEX`:去中心化链路,Mint 到指定合约地址;Burn 流程见 `burnScene` + # @option kwargs [String] :account_type 仅 `REDEEM` 生效,默认 `all`。 + # - `all`:自动选择账户 + # - `uta`:指定划入统一交易账户(UTA) + # - `fund`:指定划入资金账户 + # @option kwargs [String] :contract_addr MINT 时代币接收地址;DEX Burn DEP 场景时代币提供地址。 + # DEX 链路 NDP 场景不传。 + # @option kwargs [String] :burn_scene 仅 DEX Burn(`flow=DEX` + `convertType=REDEEM`)时有效。 + # - `DEP`:走 Bybit 主站(Deposit)Burn——MM 先将 DEX 合约 mStocks 入金到 UID1 再 Redeem + # - `NDP`:不经主站(Non-Deposit)Burn——MM DEX 合约授权 TokenIssuer,链上直接划转 + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/convert/submit + def submit_convert(convert_type:, symbol:, input_amount:, front_multiplier:, request_id:, flow:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(convertType: convert_type, symbol: symbol, inputAmount: input_amount, frontMultiplier: front_multiplier, requestId: request_id, flow: flow)) + @session.sign_request(method: :post, path: '/v5/rwa/stocks/convert/submit', body: params) + end + + # 获取 Multiplier 列表 + # + # GET /v5/rwa/stocks/market/getMultiplierList + # + # @param current [Integer] 当前页码(从 1 开始) + # @param page_size [Integer] 每页条数,默认 10 + # @option kwargs [String] :symbol 按股票代码过滤,如 `TSLA-US`;不传则返回全部 + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/market/getMultiplierList + def get_multiplier_list(current:, page_size:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(current: current, pageSize: page_size)) + @session.sign_request(method: :get, path: '/v5/rwa/stocks/market/getMultiplierList', params: params) + end + + # 获取交易日历与市场状态 + # + # GET /v5/rwa/stocks/market/session + # + # @option kwargs [String] :symbol 内部股票代码,如 `TSLA-US`;不传则返回通用日历 + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/market/session + def get_market_session(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/rwa/stocks/market/session', params: params) + end + + # 下单(买入 / 卖出股票) + # + # POST /v5/rwa/stocks/order + # + # @param symbol [String] 股票代码,如 `TSLA-US`、`AAPL-US` + # @param quote_token [String] 计价资产,当前仅支持 `USDC` + # @param side [String] 方向 + # @param type [String] 订单类型 + # @param time_in_force [String] 订单有效期: + # - `DAY`:当日有效,北美主市场收盘时自动撤单 + # - `GTC`:撤销前持续有效(Good Till Cancelled) + # - `IOC`:立即成交,未成交部分立即取消;仅支持 `LIMIT + 整股 + RTH` + # - `SELL` 仅支持 `DAY` / `GTC` + # @param order_time [Integer] 客户端下单毫秒时间戳 + # @param request_id [String] 幂等键,字母数字与 `-_`,同一 MM 账号下 24 小时内唯一 + # @option kwargs [String] :qty 委托数量(股)。`SELL` 必填;`BUY` 的 `LIMIT`/`STOP`/`STOP_LIMIT` 必填;与 `notional` 互斥 + # @option kwargs [String] :notional 名义额(USDC)。仅 `BUY` 且 `type=MARKET` 时使用;与 `qty` 互斥 + # @option kwargs [String] :limit_price 限价,`type=LIMIT` 或 `STOP_LIMIT` 时必填 + # @option kwargs [String] :stop_price 触发价,`type=STOP` 或 `STOP_LIMIT` 时必填 + # @option kwargs [String] :trading_session 交易时段,默认 `RTH`。 + # - `RTH`:Regular Trading Hours,正常交易时段 + # - `24H`:全天候,包含盘前/盘后/夜盘;非 RTH 时段只允许 LIMIT 单 + # @option kwargs [Boolean] :tokenize 成交后是否自动 tokenize,默认 `false`;仅对 `BUY` 生效 + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/order + def place_order(symbol:, quote_token:, side:, type:, time_in_force:, order_time:, request_id:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol, quoteToken: quote_token, side: side, type: type, timeInForce: time_in_force, orderTime: order_time, requestId: request_id)) + @session.sign_request(method: :post, path: '/v5/rwa/stocks/order', body: params) + end + + # 撤单 + # + # POST /v5/rwa/stocks/order/cancel + # + # @param order_no [String] 系统订单号 + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/order/cancel + def cancel_order(order_no:) + params = Bybit::Utils::WireKeys.camelize({ orderNo: order_no }) + @session.sign_request(method: :post, path: '/v5/rwa/stocks/order/cancel', body: params) + end + + # 查询股票订单详情 + # + # GET /v5/rwa/stocks/order/detail + # + # @option kwargs [String] :order_no 系统订单号;与 `requestId` 二选一 + # @option kwargs [String] :request_id 客户端幂等 ID;与 `orderNo` 二选一 + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/order/detail + def get_order_detail(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/rwa/stocks/order/detail', params: params) + end + + # 获取所有正股仓位 + # + # GET /v5/rwa/stocks/positions + # + # @option kwargs [String] :symbol 按标的过滤;不传则返回全部持仓 + # @option kwargs [Boolean] :show_zero 是否返回零持仓,默认 `false` + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/positions + def get_positions(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/rwa/stocks/positions', params: params) + end + end + end +end diff --git a/lib/bybit/rest_api/strategy_service.rb b/lib/bybit/rest_api/strategy_service.rb new file mode 100644 index 0000000..505002e --- /dev/null +++ b/lib/bybit/rest_api/strategy_service.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +module Bybit + module RestApi + class StrategyService < BaseService + # Create a strategy order + # + # POST /v5/strategy/create + # + # @param params [Hash] Request payload. strategy_type: chaseOrder | iceberg | pov | twap. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/strategy/create + def create_strategy(**params) + body = Bybit::Utils::WireKeys.camelize(params) + @session.sign_request(method: :post, path: '/v5/strategy/create', body: body) + end + + # Query trading strategy list with filters + # + # GET /v5/strategy/list + # + # @option kwargs [String] :strategy_id Strategy ID for exact lookup (UUID format). + # If provided, returns only this specific strategy. + # Useful for checking status of a known strategy. + # @option kwargs [String] :status Filter by strategy status. + # - "2": Running (currently executing) + # - "3" or "4": Terminated (stopped) + # - "5": Paused (temporarily halted) + # - "6": Untriggered (waiting for trigger price) + # Can provide multiple values separated by comma. + # @option kwargs [String] :symbol Filter by trading pair symbol. + # Case-sensitive, must match exactly. + # Example: "BTCUSDT", "ETHUSDT" + # @option kwargs [String] :category Filter by product category. + # Useful to separate spot from derivatives strategies. + # @option kwargs [String] :strategy_type Filter by strategy type. + # Useful to view only specific algorithm strategies. + # @option kwargs [Integer] :begin_time_e0 Start time filter (Unix timestamp in seconds). + # Returns strategies created on or after this time. + # Example: 1673214964 (Jan 9, 2023) + # @option kwargs [Integer] :end_time_e0 End time filter (Unix timestamp in seconds). + # Returns strategies created before this time. + # Must be greater than beginTimeE0 if both provided. + # @option kwargs [Integer] :page_size Number of results per page. + # Default: 20 + # Maximum: 50 + # @option kwargs [String] :cursor Pagination cursor from previous response. + # Use nextCursor value from previous query to get next page. + # Empty for first page. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/strategy/list + def query_list(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :get, path: '/v5/strategy/list', params: params) + end + + # Query orders created by a specific strategy + # + # GET /v5/strategy/order-list + # + # @param strategy_id [String] Strategy ID to query orders for (UUID format). + # This is the parent strategy whose child orders you want to retrieve. + # Obtain from strategy creation response or strategy list query. + # @option kwargs [String] :status Filter by order status. + # - "1": Created (active, not filled yet) + # - "2": PartiallyFilled (some quantity executed) + # - "3": Filled (fully executed) + # - "4": Cancelled (order canceled) + # - "5": Rejected (order rejected by exchange) + # Can filter by multiple statuses. + # @option kwargs [String] :symbol Filter by trading pair symbol. + # Useful if strategy could trade multiple symbols. + # @option kwargs [Integer] :begin_time_e0 Start time filter (Unix timestamp in seconds). + # Returns orders created on or after this time. + # @option kwargs [Integer] :end_time_e0 End time filter (Unix timestamp in seconds). + # Returns orders created before this time. + # @option kwargs [Integer] :page_size Number of results per page. + # Default: 20, Maximum: 50 + # @option kwargs [String] :cursor Pagination cursor from previous response. + # Use nextCursor from previous query for next page. + # @option kwargs [String] :strategy_type Filter by strategy type. + # Should match the parent strategy type. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/strategy/order-list + def query_order_list(strategy_id:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(strategyId: strategy_id)) + @session.sign_request(method: :get, path: '/v5/strategy/order-list', params: params) + end + + # Stop a running strategy + # + # POST /v5/strategy/stop + # + # @param strategy_id [String] Strategy ID to stop (UUID format). + # Obtained from strategy creation response or strategy list query. + # Only Running or Untriggered strategies can be stopped. + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/strategy/stop + def stop_strategy(strategy_id:) + params = Bybit::Utils::WireKeys.camelize({ strategyId: strategy_id }) + @session.sign_request(method: :post, path: '/v5/strategy/stop', body: params) + end + end + end +end diff --git a/lib/bybit/rest_api/tax_service.rb b/lib/bybit/rest_api/tax_service.rb new file mode 100644 index 0000000..805dfce --- /dev/null +++ b/lib/bybit/rest_api/tax_service.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Bybit + module RestApi + class TaxService < BaseService + # Batch create tax report files + # + # POST /v5/fht/compliance/tax/private/batch_create + # + # @param start_time [Integer] Tax report start time (Unix timestamp, seconds) + # @param end_time [Integer] Tax report end time (Unix timestamp, seconds); interval must not exceed 12 months + # @param items [Array] Non-empty list of tax report export items + # @option kwargs [String] :source_institution Optional source institution identifier + # @option kwargs [String] :export_file_type Export file format: + # - `csv` — CSV text format + # - `orc` — ORC columnar format (default) + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/fht/compliance/tax/private/batch_create + def batch_create_tax_reports(start_time:, end_time:, items:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(startTime: start_time, endTime: end_time, items: items)) + @session.sign_request(method: :post, path: '/v5/fht/compliance/tax/private/batch_create', body: params) + end + + # Query batch tax report status + # + # GET /v5/fht/compliance/tax/private/batch_query + # + # @param batch_id [String] Batch ID returned by `batch_create` + # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + # @see https://bybit-exchange.github.io/docs/v5/fht/compliance/tax/private/batch_query + def batch_query_tax_reports(batch_id:) + params = Bybit::Utils::WireKeys.camelize({ batchId: batch_id }) + @session.sign_request(method: :get, path: '/v5/fht/compliance/tax/private/batch_query', params: params) + end + end + end +end diff --git a/lib/bybit/version.rb b/lib/bybit/version.rb index 692ef55..29be168 100644 --- a/lib/bybit/version.rb +++ b/lib/bybit/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Bybit - VERSION = '0.1.2' + VERSION = '0.1.3' end diff --git a/spec/generated/rest_api_generated_spec.rb b/spec/generated/rest_api_generated_spec.rb new file mode 100644 index 0000000..ad08b45 --- /dev/null +++ b/spec/generated/rest_api_generated_spec.rb @@ -0,0 +1,1641 @@ +# frozen_string_literal: true + +RSpec.describe 'generated REST API contracts' do + # gen-sdk-ruby:generated-service-specs:start + # endpoint: GET /v5/alpha/prediction/engine-status + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/alpha/prediction/engine-status' + ) + service.get_prediction_engine_status + end + + # endpoint: GET /v5/alpha/prediction/pay-token-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/alpha/prediction/pay-token-list' + ) + service.get_prediction_pay_token_list + end + + # endpoint: GET /v5/alpha/prediction/sports/timeline-stages + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/alpha/prediction/sports/timeline-stages', + params: { eventType: 'event_type-value' } + ) + service.get_prediction_timeline_stages(event_type: 'event_type-value') + end + + # endpoint: GET /v5/event/order-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::EventService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/event/order-list', + params: { + symbol: 'symbol-value', + orderId: 'order_id-value', + orderLinkId: 'order_link_id-value', + startTime: 1, + endTime: 1, + limit: 1, + cursor: 'cursor-value' + } + ) + service.get_ec_order_history( + symbol: 'symbol-value', + order_id: 'order_id-value', + order_link_id: 'order_link_id-value', + start_time: 1, + end_time: 1, + limit: 1, + cursor: 'cursor-value' + ) + end + + # endpoint: GET /v5/event/order-realtime + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::EventService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/event/order-realtime', + params: { + symbol: 'symbol-value', + orderId: 'order_id-value', + orderLinkId: 'order_link_id-value', + limit: 1, + cursor: 'cursor-value' + } + ) + service.get_ec_active_orders( + symbol: 'symbol-value', + order_id: 'order_id-value', + order_link_id: 'order_link_id-value', + limit: 1, + cursor: 'cursor-value' + ) + end + + # endpoint: GET /v5/event/positions + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::EventService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/event/positions', + params: { + symbol: 'symbol-value', + baseCoin: 'base_coin-value', + settleCoin: 'settle_coin-value', + limit: 1, + cursor: 'cursor-value' + } + ) + service.get_ec_position_info( + symbol: 'symbol-value', + base_coin: 'base_coin-value', + settle_coin: 'settle_coin-value', + limit: 1, + cursor: 'cursor-value' + ) + end + + # endpoint: GET /v5/event/settlements + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::EventService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/event/settlements', + params: { + symbol: 'symbol-value', + orderId: 'order_id-value', + startTime: 1, + endTime: 1, + limit: 1, + cursor: 'cursor-value' + } + ) + service.get_ec_settlements( + symbol: 'symbol-value', + order_id: 'order_id-value', + start_time: 1, + end_time: 1, + limit: 1, + cursor: 'cursor-value' + ) + end + + # endpoint: GET /v5/event/trades + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::EventService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/event/trades', + params: { + symbol: 'symbol-value', + orderId: 'order_id-value', + orderLinkId: 'order_link_id-value', + startTime: 1, + endTime: 1, + limit: 1, + cursor: 'cursor-value' + } + ) + service.get_ec_trade_history( + symbol: 'symbol-value', + order_id: 'order_id-value', + order_link_id: 'order_link_id-value', + start_time: 1, + end_time: 1, + limit: 1, + cursor: 'cursor-value' + ) + end + + # endpoint: GET /v5/fht/compliance/tax/private/batch_query + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::TaxService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/fht/compliance/tax/private/batch_query', + params: { batchId: 'batch_id-value' } + ) + service.batch_query_tax_reports(batch_id: 'batch_id-value') + end + + # endpoint: GET /v5/fiat/balance-query + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::FiatService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/fiat/balance-query', + params: { accountCategory: 'fiat', currency: 'currency-value' } + ) + service.query_balance(account_category: 'fiat', currency: 'currency-value') + end + + # endpoint: GET /v5/fiat/query-coin-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::FiatService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/fiat/query-coin-list', + params: { side: 0 } + ) + service.query_coin_list(side: 0) + end + + # endpoint: GET /v5/fiat/query-trade-history + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::FiatService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/fiat/query-trade-history', + params: { index: 1, limit: 1, startTime: 'start_time-value', endTime: 'end_time-value' } + ) + service.query_trade_history( + index: 1, + limit: 1, + start_time: 'start_time-value', + end_time: 'end_time-value' + ) + end + + # endpoint: GET /v5/fiat/reference-price + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::FiatService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/fiat/reference-price', + params: { symbol: 'symbol-value', paymentMethod: 'payment_method-value' } + ) + service.get_reference_price(symbol: 'symbol-value', payment_method: 'payment_method-value') + end + + # endpoint: GET /v5/fiat/trade-query + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::FiatService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/fiat/trade-query', + params: { tradeNo: 'trade_no-value', merchantRequestId: 'merchant_request_id-value' } + ) + service.query_trade( + trade_no: 'trade_no-value', + merchant_request_id: 'merchant_request_id-value' + ) + end + + # endpoint: GET /v5/ins-loan/coin-delta-amount + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::InstitutionalLoanService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/ins-loan/coin-delta-amount', + params: { coin: 'coin-value' } + ) + service.ins_loan_coin_delta_amount(coin: 'coin-value') + end + + # endpoint: GET /v5/ins-loan/delay-liq-status + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::InstitutionalLoanService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/ins-loan/delay-liq-status' + ) + service.ins_loan_delay_liq_status + end + + # endpoint: GET /v5/rwa/stocks/convert/detail + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StocksService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/rwa/stocks/convert/detail', + params: { orderNo: 'order_no-value', requestId: 'request_id-value' } + ) + service.get_convert_detail(order_no: 'order_no-value', request_id: 'request_id-value') + end + + # endpoint: GET /v5/rwa/stocks/convert/list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StocksService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/rwa/stocks/convert/list', + params: { symbol: 'symbol-value' } + ) + service.get_convert_list(symbol: 'symbol-value') + end + + # endpoint: GET /v5/rwa/stocks/market/getMultiplierList + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StocksService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/rwa/stocks/market/getMultiplierList', + params: { symbol: 'symbol-value', current: 1, pageSize: 1 } + ) + service.get_multiplier_list(symbol: 'symbol-value', current: 1, page_size: 1) + end + + # endpoint: GET /v5/rwa/stocks/market/session + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StocksService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/rwa/stocks/market/session', + params: { symbol: 'symbol-value' } + ) + service.get_market_session(symbol: 'symbol-value') + end + + # endpoint: GET /v5/rwa/stocks/order/detail + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StocksService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/rwa/stocks/order/detail', + params: { orderNo: 'order_no-value', requestId: 'request_id-value' } + ) + service.get_order_detail(order_no: 'order_no-value', request_id: 'request_id-value') + end + + # endpoint: GET /v5/rwa/stocks/positions + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StocksService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/rwa/stocks/positions', + params: { symbol: 'symbol-value', showZero: true } + ) + service.get_positions(symbol: 'symbol-value', show_zero: true) + end + + # endpoint: GET /v5/spot-margin-trade/fixedborrow-interest-accrued + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpotMarginService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/spot-margin-trade/fixedborrow-interest-accrued', + params: { + orderId: 'order_id-value', + orderCurrency: 'order_currency-value', + limit: 'limit-value', + cursor: 'cursor-value' + } + ) + service.query_fixed_borrow_penalty_interest( + order_id: 'order_id-value', + order_currency: 'order_currency-value', + limit: 'limit-value', + cursor: 'cursor-value' + ) + end + + # endpoint: GET /v5/spot-x/launchpool/project/list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpotXService.new(session) + expect(session).to receive(:public_request).with( + path: '/v5/spot-x/launchpool/project/list', + params: { + status: 1, + activityCoin: 'activity_coin-value', + projectId: 'project_id-value', + cursor: 'cursor-value', + limit: 1 + } + ) + service.get_launchpool_project_list( + status: 1, + activity_coin: 'activity_coin-value', + project_id: 'project_id-value', + cursor: 'cursor-value', + limit: 1 + ) + end + + # endpoint: GET /v5/spot-x/launchpool/user/current-staking + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpotXService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/spot-x/launchpool/user/current-staking' + ) + service.get_launchpool_user_current_staking + end + + # endpoint: GET /v5/spot-x/puzzle/project/list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpotXService.new(session) + expect(session).to receive(:public_request).with( + path: '/v5/spot-x/puzzle/project/list', + params: { + status: 1, + projectId: 'project_id-value', + activityCoin: 'activity_coin-value', + cursor: 'cursor-value', + limit: 1 + } + ) + service.get_puzzle_project_list( + status: 1, + project_id: 'project_id-value', + activity_coin: 'activity_coin-value', + cursor: 'cursor-value', + limit: 1 + ) + end + + # endpoint: GET /v5/spot-x/token-splash/project/list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpotXService.new(session) + expect(session).to receive(:public_request).with( + path: '/v5/spot-x/token-splash/project/list', + params: { + status: 1, + projectId: 'project_id-value', + activityCoin: 'activity_coin-value', + cursor: 'cursor-value', + limit: 1 + } + ) + service.get_token_splash_project_list( + status: 1, + project_id: 'project_id-value', + activity_coin: 'activity_coin-value', + cursor: 'cursor-value', + limit: 1 + ) + end + + # endpoint: GET /v5/spot-x/token-splash/user/activity-params + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpotXService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/spot-x/token-splash/user/activity-params', + params: { projectId: 'project_id-value', activityCoin: 'activity_coin-value' } + ) + service.get_token_splash_user_activity_params( + project_id: 'project_id-value', + activity_coin: 'activity_coin-value' + ) + end + + # endpoint: GET /v5/spread/execution/list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/spread/execution/list', + params: { + symbol: 'symbol-value', + orderId: 'order_id-value', + orderLinkId: 'order_link_id-value', + startTime: 1, + endTime: 1, + limit: 1, + cursor: 'cursor-value' + } + ) + service.get_history( + symbol: 'symbol-value', + order_id: 'order_id-value', + order_link_id: 'order_link_id-value', + start_time: 1, + end_time: 1, + limit: 1, + cursor: 'cursor-value' + ) + end + + # endpoint: GET /v5/spread/instrument + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:public_request).with( + path: '/v5/spread/instrument', + params: { symbol: 'symbol-value', baseCoin: 'base_coin-value', limit: 1, cursor: 'cursor-value' } + ) + service.get_spread_instruments_info( + symbol: 'symbol-value', + base_coin: 'base_coin-value', + limit: 1, + cursor: 'cursor-value' + ) + end + + # endpoint: GET /v5/spread/max-qty + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/spread/max-qty', + params: { symbol: 'symbol-value', side: '1', orderPrice: 'order_price-value' } + ) + service.get_spread_max_qty(symbol: 'symbol-value', side: '1', order_price: 'order_price-value') + end + + # endpoint: GET /v5/spread/order/history + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/spread/order/history', + params: { + symbol: 'symbol-value', + baseCoin: 'base_coin-value', + orderId: 'order_id-value', + orderLinkId: 'order_link_id-value', + startTime: 1, + endTime: 1, + limit: 1, + cursor: 'cursor-value' + } + ) + service.get_spread_order_history( + symbol: 'symbol-value', + base_coin: 'base_coin-value', + order_id: 'order_id-value', + order_link_id: 'order_link_id-value', + start_time: 1, + end_time: 1, + limit: 1, + cursor: 'cursor-value' + ) + end + + # endpoint: GET /v5/spread/order/realtime + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/spread/order/realtime', + params: { + symbol: 'symbol-value', + baseCoin: 'base_coin-value', + orderId: 'order_id-value', + orderLinkId: 'order_link_id-value', + limit: 1, + cursor: 'cursor-value' + } + ) + service.get_spread_open_orders( + symbol: 'symbol-value', + base_coin: 'base_coin-value', + order_id: 'order_id-value', + order_link_id: 'order_link_id-value', + limit: 1, + cursor: 'cursor-value' + ) + end + + # endpoint: GET /v5/spread/orderbook + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:public_request).with( + path: '/v5/spread/orderbook', + params: { symbol: 'symbol-value', limit: 1 } + ) + service.get_spread_orderbook(symbol: 'symbol-value', limit: 1) + end + + # endpoint: GET /v5/spread/recent-trade + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:public_request).with( + path: '/v5/spread/recent-trade', + params: { symbol: 'symbol-value', limit: 1 } + ) + service.get_spread_recent_trades(symbol: 'symbol-value', limit: 1) + end + + # endpoint: GET /v5/spread/tickers + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:public_request).with( + path: '/v5/spread/tickers', + params: { symbol: 'symbol-value' } + ) + service.get_spread_tickers(symbol: 'symbol-value') + end + + # endpoint: GET /v5/strategy/list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StrategyService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/strategy/list', + params: { + strategyId: 'strategy_id-value', + status: '2', + symbol: 'symbol-value', + category: 'UTA_USDT', + strategyType: 'twap', + beginTimeE0: 1, + endTimeE0: 1, + pageSize: 1, + cursor: 'cursor-value' + } + ) + service.query_list( + strategy_id: 'strategy_id-value', + status: '2', + symbol: 'symbol-value', + category: 'UTA_USDT', + strategy_type: 'twap', + begin_time_e0: 1, + end_time_e0: 1, + page_size: 1, + cursor: 'cursor-value' + ) + end + + # endpoint: GET /v5/strategy/order-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StrategyService.new(session) + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/strategy/order-list', + params: { + strategyId: 'strategy_id-value', + status: '1', + symbol: 'symbol-value', + beginTimeE0: 1, + endTimeE0: 1, + pageSize: 1, + cursor: 'cursor-value', + strategyType: 'twap' + } + ) + service.query_order_list( + strategy_id: 'strategy_id-value', + status: '1', + symbol: 'symbol-value', + begin_time_e0: 1, + end_time_e0: 1, + page_size: 1, + cursor: 'cursor-value', + strategy_type: 'twap' + ) + end + + # endpoint: POST /v5/alpha/lp/order-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/lp/order-list', + body: { + orderType: 0, + tokenCode: 'token_code-value', + orderStatus: ['order_status-value'], + days: 1, + limit: 1, + pageIndex: 1, + poolAddress: 'pool_address-value' + } + ) + service.get_lp_order_list( + order_type: 0, + token_code: 'token_code-value', + order_status: ['order_status-value'], + days: 1, + limit: 1, + page_index: 1, + pool_address: 'pool_address-value' + ) + end + + # endpoint: POST /v5/alpha/lp/pay-token-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/lp/pay-token-list', + body: { chainCode: 'chain_code-value', tokenAddress: 'token_address-value' } + ) + service.get_lp_pay_token_list( + chain_code: 'chain_code-value', + token_address: 'token_address-value' + ) + end + + # endpoint: POST /v5/alpha/lp/pay-token-price + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/lp/pay-token-price', + body: { tokenCode: ['token_code-value'], chainCode: 'chain_code-value' } + ) + service.get_lp_pay_token_price(token_code: ['token_code-value'], chain_code: 'chain_code-value') + end + + # endpoint: POST /v5/alpha/lp/pool-info + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/lp/pool-info', + body: { poolAddress: 'pool_address-value' } + ) + service.get_lp_pool_info(pool_address: 'pool_address-value') + end + + # endpoint: POST /v5/alpha/lp/pool-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/lp/pool-list', + body: { tokenSymbol: 'token_symbol-value' } + ) + service.get_lp_pool_list(token_symbol: 'token_symbol-value') + end + + # endpoint: POST /v5/alpha/lp/position-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/lp/position-list' + ) + service.get_lp_position_list + end + + # endpoint: POST /v5/alpha/lp/redeem + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/lp/redeem', + body: { + positionId: 1, + poolAddress: 'pool_address-value', + dercRatio: 'derc_ratio-value', + receiveTokenCode: 'receive_token_code-value' + } + ) + service.execute_lp_redeem( + position_id: 1, + pool_address: 'pool_address-value', + derc_ratio: 'derc_ratio-value', + receive_token_code: 'receive_token_code-value' + ) + end + + # endpoint: POST /v5/alpha/lp/stake + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/lp/stake', + body: { + positionId: 1, + poolAddress: 'pool_address-value', + payTokenAmount: 'pay_token_amount-value', + payTokenCode: 'pay_token_code-value', + rangeUpper: 'range_upper-value', + rangeLower: 'range_lower-value', + priceUpper: 'price_upper-value', + priceLower: 'price_lower-value' + } + ) + service.execute_lp_stake( + position_id: 1, + pool_address: 'pool_address-value', + pay_token_amount: 'pay_token_amount-value', + pay_token_code: 'pay_token_code-value', + range_upper: 'range_upper-value', + range_lower: 'range_lower-value', + price_upper: 'price_upper-value', + price_lower: 'price_lower-value' + ) + end + + # endpoint: POST /v5/alpha/prediction/buy + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/buy', + body: { + tokenId: 'token_id-value', + amount: 'amount-value', + payTokenCode: 'pay_token_code-value', + orderType: 'order_type-value', + slippage: 'slippage-value', + eventId: 'event_id-value' + } + ) + service.execute_prediction_buy( + token_id: 'token_id-value', + amount: 'amount-value', + pay_token_code: 'pay_token_code-value', + order_type: 'order_type-value', + slippage: 'slippage-value', + event_id: 'event_id-value' + ) + end + + # endpoint: POST /v5/alpha/prediction/event-detail + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/event-detail', + body: { eventId: 'event_id-value', slug: 'slug-value', hasMoreMarkets: true } + ) + service.get_prediction_event_detail( + event_id: 'event_id-value', + slug: 'slug-value', + has_more_markets: true + ) + end + + # endpoint: POST /v5/alpha/prediction/order-book + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/order-book', + body: { tokenIds: ['token_ids-value'] } + ) + service.get_prediction_order_book(token_ids: ['token_ids-value']) + end + + # endpoint: POST /v5/alpha/prediction/order-estimate + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/order-estimate', + body: { + tokenId: 'token_id-value', + side: 'side-value', + eventId: 'event_id-value', + amount: 'amount-value', + orderType: 'order_type-value', + payTokenCode: 'pay_token_code-value' + } + ) + service.get_prediction_order_estimate( + token_id: 'token_id-value', + side: 'side-value', + event_id: 'event_id-value', + amount: 'amount-value', + order_type: 'order_type-value', + pay_token_code: 'pay_token_code-value' + ) + end + + # endpoint: POST /v5/alpha/prediction/order-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/order-list', + body: { + status: 'status-value', + tokenId: 'token_id-value', + limit: 1, + pageIndex: 1, + eventId: 'event_id-value', + side: 'side-value', + days: 1 + } + ) + service.get_prediction_order_list( + status: 'status-value', + token_id: 'token_id-value', + limit: 1, + page_index: 1, + event_id: 'event_id-value', + side: 'side-value', + days: 1 + ) + end + + # endpoint: POST /v5/alpha/prediction/portfolio-summary + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/portfolio-summary' + ) + service.get_prediction_portfolio_summary + end + + # endpoint: POST /v5/alpha/prediction/position-history + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/position-history', + body: { limit: 1, pageIndex: 1, direction: 'prev' } + ) + service.get_prediction_position_history(limit: 1, page_index: 1, direction: 'prev') + end + + # endpoint: POST /v5/alpha/prediction/position-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/position-list', + body: { limit: 1, pageIndex: 1, direction: 'prev' } + ) + service.get_prediction_position_list(limit: 1, page_index: 1, direction: 'prev') + end + + # endpoint: POST /v5/alpha/prediction/price-history + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/price-history', + body: { + tokenIds: ['token_ids-value'], + eventId: 'event_id-value', + interval: 'interval-value', + fidelity: 1 + } + ) + service.get_prediction_price_history( + token_ids: ['token_ids-value'], + event_id: 'event_id-value', + interval: 'interval-value', + fidelity: 1 + ) + end + + # endpoint: POST /v5/alpha/prediction/sell + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/sell', + body: { + tokenId: 'token_id-value', + size: 'size-value', + orderType: 'order_type-value', + slippage: 'slippage-value', + eventId: 'event_id-value', + toTokenCode: 'to_token_code-value' + } + ) + service.execute_prediction_sell( + token_id: 'token_id-value', + size: 'size-value', + order_type: 'order_type-value', + slippage: 'slippage-value', + event_id: 'event_id-value', + to_token_code: 'to_token_code-value' + ) + end + + # endpoint: POST /v5/alpha/prediction/side-market-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/side-market-list', + body: { eventType: 'event_type-value' } + ) + service.get_prediction_side_market_list(event_type: 'event_type-value') + end + + # endpoint: POST /v5/alpha/prediction/sports/group-stage-detail + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/sports/group-stage-detail', + body: { eventType: 'event_type-value', stageCode: 'stage_code-value' } + ) + service.get_prediction_group_stage_detail( + event_type: 'event_type-value', + stage_code: 'stage_code-value' + ) + end + + # endpoint: POST /v5/alpha/prediction/sports/match-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/sports/match-list', + body: { eventType: 'event_type-value' } + ) + service.get_prediction_match_list(event_type: 'event_type-value') + end + + # endpoint: POST /v5/alpha/prediction/token-price + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/token-price', + body: { tokenIds: ['token_ids-value'] } + ) + service.get_prediction_token_price(token_ids: ['token_ids-value']) + end + + # endpoint: POST /v5/alpha/trade/asset-detail + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/trade/asset-detail', + body: { chainCode: 'chain_code-value', tokenAddress: 'token_address-value' } + ) + service.get_asset_detail(chain_code: 'chain_code-value', token_address: 'token_address-value') + end + + # endpoint: POST /v5/alpha/trade/asset-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/trade/asset-list' + ) + service.get_asset_list + end + + # endpoint: POST /v5/alpha/trade/biz-token-details + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/trade/biz-token-details', + body: { chainCode: 'chain_code-value', tokenAddress: 'token_address-value' } + ) + service.get_biz_token_details( + chain_code: 'chain_code-value', + token_address: 'token_address-value' + ) + end + + # endpoint: POST /v5/alpha/trade/biz-token-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/trade/biz-token-list', + body: { tokenTag: 0 } + ) + service.get_biz_token_list(token_tag: 0) + end + + # endpoint: POST /v5/alpha/trade/biz-token-price-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/trade/biz-token-price-list', + body: { tokenAddressInfo: ['token_address_info-value'] } + ) + service.get_biz_token_price_list(token_address_info: ['token_address_info-value']) + end + + # endpoint: POST /v5/alpha/trade/order-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/trade/order-list', + body: { + tradeType: 0, + tokenCode: 'token_code-value', + orderStatus: ['order_status-value'], + days: 1, + limit: 1, + pageIndex: 1, + direction: 'prev' + } + ) + service.get_order_list( + trade_type: 0, + token_code: 'token_code-value', + order_status: ['order_status-value'], + days: 1, + limit: 1, + page_index: 1, + direction: 'prev' + ) + end + + # endpoint: POST /v5/alpha/trade/pay-token-list + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/trade/pay-token-list', + body: { chainCode: 'chain_code-value', tokenAddress: 'token_address-value' } + ) + service.get_pay_token_list(chain_code: 'chain_code-value', token_address: 'token_address-value') + end + + # endpoint: POST /v5/alpha/trade/purchase + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/trade/purchase', + body: { + fromTokenCode: 'from_token_code-value', + fromTokenAmount: 'from_token_amount-value', + toTokenCode: 'to_token_code-value', + slippage: 'slippage-value', + quoteData: 'quote_data-value', + gas: 'gas-value', + quoteMode: 0, + correctingCode: 'correcting_code-value', + tenant: 'tenant-value' + } + ) + service.execute_purchase( + from_token_code: 'from_token_code-value', + from_token_amount: 'from_token_amount-value', + to_token_code: 'to_token_code-value', + slippage: 'slippage-value', + quote_data: 'quote_data-value', + gas: 'gas-value', + quote_mode: 0, + correcting_code: 'correcting_code-value', + tenant: 'tenant-value' + ) + end + + # endpoint: POST /v5/alpha/trade/quote + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/trade/quote', + body: { + tradeType: 1, + fromTokenCode: 'from_token_code-value', + fromTokenAmount: 'from_token_amount-value', + toTokenCode: 'to_token_code-value', + quoteMode: 0 + } + ) + service.get_trade_quote( + trade_type: 1, + from_token_code: 'from_token_code-value', + from_token_amount: 'from_token_amount-value', + to_token_code: 'to_token_code-value', + quote_mode: 0 + ) + end + + # endpoint: POST /v5/alpha/trade/redeem + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::AlphaService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/trade/redeem', + body: { + fromTokenCode: 'from_token_code-value', + fromTokenAmount: 'from_token_amount-value', + toTokenCode: 'to_token_code-value', + slippage: 'slippage-value', + quoteData: 'quote_data-value', + gas: 'gas-value', + quoteMode: 0, + correctingCode: 'correcting_code-value', + tenant: 'tenant-value' + } + ) + service.execute_redeem( + from_token_code: 'from_token_code-value', + from_token_amount: 'from_token_amount-value', + to_token_code: 'to_token_code-value', + slippage: 'slippage-value', + quote_data: 'quote_data-value', + gas: 'gas-value', + quote_mode: 0, + correcting_code: 'correcting_code-value', + tenant: 'tenant-value' + ) + end + + # endpoint: POST /v5/fht/compliance/tax/private/batch_create + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::TaxService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/fht/compliance/tax/private/batch_create', + body: { + startTime: 1, + endTime: 1, + items: ['items-value'], + sourceInstitution: 'source_institution-value', + exportFileType: 'csv' + } + ) + service.batch_create_tax_reports( + start_time: 1, + end_time: 1, + items: ['items-value'], + source_institution: 'source_institution-value', + export_file_type: 'csv' + ) + end + + # endpoint: POST /v5/fiat/quote-apply + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::FiatService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/fiat/quote-apply', + body: { + fromCoin: 'from_coin-value', + fromCoinType: 'fiat', + toCoin: 'to_coin-value', + toCoinType: 'fiat', + requestAmount: 'request_amount-value', + requestCoinType: 'fiat' + } + ) + service.apply_quote( + from_coin: 'from_coin-value', + from_coin_type: 'fiat', + to_coin: 'to_coin-value', + to_coin_type: 'fiat', + request_amount: 'request_amount-value', + request_coin_type: 'fiat' + ) + end + + # endpoint: POST /v5/fiat/trade-execute + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::FiatService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/fiat/trade-execute', + body: { + quoteTxId: 'quote_tx_id-value', + subUserId: 'sub_user_id-value', + webhookUrl: 'webhook_url-value', + merchantRequestId: 'merchant_request_id-value' + } + ) + service.confirm_quote( + quote_tx_id: 'quote_tx_id-value', + sub_user_id: 'sub_user_id-value', + webhook_url: 'webhook_url-value', + merchant_request_id: 'merchant_request_id-value' + ) + end + + # endpoint: POST /v5/referral/campaign/rewards + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::ReferralService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/referral/campaign/rewards' + ) + service.get_campaign_rewards + end + + # endpoint: POST /v5/referral/commission/records + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::ReferralService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/referral/commission/records', + body: { + userIdList: ['user_id_list-value'], + startTime: 'start_time-value', + endTime: 'end_time-value', + page: 1, + pageSize: 1, + productLine: 0 + } + ) + service.get_commission_records( + user_id_list: ['user_id_list-value'], + start_time: 'start_time-value', + end_time: 'end_time-value', + page: 1, + page_size: 1, + product_line: 0 + ) + end + + # endpoint: POST /v5/referral/user/identity-profile + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::ReferralService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/referral/user/identity-profile' + ) + service.get_user_identity_profile + end + + # endpoint: POST /v5/referral/user/invitations + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::ReferralService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/referral/user/invitations', + body: { + userIdList: ['user_id_list-value'], + startTime: 'start_time-value', + endTime: 'end_time-value', + page: 1, + pageSize: 1, + friendStatus: 0 + } + ) + service.get_user_invitations( + user_id_list: ['user_id_list-value'], + start_time: 'start_time-value', + end_time: 'end_time-value', + page: 1, + page_size: 1, + friend_status: 0 + ) + end + + # endpoint: POST /v5/rwa/stocks/convert/submit + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StocksService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/rwa/stocks/convert/submit', + body: { + convertType: 'MINT', + symbol: 'symbol-value', + inputAmount: 'input_amount-value', + frontMultiplier: 'front_multiplier-value', + accountType: 'all', + requestId: 'request_id-value', + contractAddr: 'contract_addr-value', + flow: 'CEX', + burnScene: 'DEP' + } + ) + service.submit_convert( + convert_type: 'MINT', + symbol: 'symbol-value', + input_amount: 'input_amount-value', + front_multiplier: 'front_multiplier-value', + account_type: 'all', + request_id: 'request_id-value', + contract_addr: 'contract_addr-value', + flow: 'CEX', + burn_scene: 'DEP' + ) + end + + # endpoint: POST /v5/rwa/stocks/order + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StocksService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/rwa/stocks/order', + body: { + symbol: 'symbol-value', + quoteToken: 'USDC', + side: 'BUY', + type: 'MARKET', + qty: 'qty-value', + notional: 'notional-value', + limitPrice: 'limit_price-value', + stopPrice: 'stop_price-value', + timeInForce: 'DAY', + tradingSession: 'RTH', + tokenize: true, + orderTime: 1, + requestId: 'request_id-value' + } + ) + service.place_order( + symbol: 'symbol-value', + quote_token: 'USDC', + side: 'BUY', + type: 'MARKET', + qty: 'qty-value', + notional: 'notional-value', + limit_price: 'limit_price-value', + stop_price: 'stop_price-value', + time_in_force: 'DAY', + trading_session: 'RTH', + tokenize: true, + order_time: 1, + request_id: 'request_id-value' + ) + end + + # endpoint: POST /v5/rwa/stocks/order/cancel + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StocksService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/rwa/stocks/order/cancel', + body: { orderNo: 'order_no-value' } + ) + service.cancel_order(order_no: 'order_no-value') + end + + # endpoint: POST /v5/spot-margin-trade/fixedborrow-order-cancel + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpotMarginService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/spot-margin-trade/fixedborrow-order-cancel', + body: { orderId: 'order_id-value' } + ) + service.cancel_fixed_borrow_order(order_id: 'order_id-value') + end + + # endpoint: POST /v5/spot-x/launchpool/user/activity-log + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpotXService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/spot-x/launchpool/user/activity-log', + body: { + stakeCoin: 'stake_coin-value', + type: 1, + status: 1, + startTime: 'start_time-value', + endTime: 'end_time-value', + pageSize: 1, + current: 1 + } + ) + service.get_launchpool_user_activity_log( + stake_coin: 'stake_coin-value', + type: 1, + status: 1, + start_time: 'start_time-value', + end_time: 'end_time-value', + page_size: 1, + current: 1 + ) + end + + # endpoint: POST /v5/spot-x/launchpool/user/history + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpotXService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/spot-x/launchpool/user/history', + body: { + stakeCoin: 'stake_coin-value', + rewardCoin: 'reward_coin-value', + startTime: 'start_time-value', + endTime: 'end_time-value', + pageSize: 1, + current: 1 + } + ) + service.get_launchpool_user_history( + stake_coin: 'stake_coin-value', + reward_coin: 'reward_coin-value', + start_time: 'start_time-value', + end_time: 'end_time-value', + page_size: 1, + current: 1 + ) + end + + # endpoint: POST /v5/spread/order/amend + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/spread/order/amend', + body: { + symbol: 'symbol-value', + orderId: 'order_id-value', + orderLinkId: 'order_link_id-value', + qty: 'qty-value', + price: 'price-value' + } + ) + service.amend_spread_order( + symbol: 'symbol-value', + order_id: 'order_id-value', + order_link_id: 'order_link_id-value', + qty: 'qty-value', + price: 'price-value' + ) + end + + # endpoint: POST /v5/spread/order/cancel + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/spread/order/cancel', + body: { orderId: 'order_id-value', orderLinkId: 'order_link_id-value' } + ) + service.cancel_spread_order(order_id: 'order_id-value', order_link_id: 'order_link_id-value') + end + + # endpoint: POST /v5/spread/order/cancel-all + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/spread/order/cancel-all', + body: { symbol: 'symbol-value', cancelAll: true } + ) + service.cancel_all_spread_orders(symbol: 'symbol-value', cancel_all: true) + end + + # endpoint: POST /v5/spread/order/create + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::SpreadTradeService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/spread/order/create', + body: { + symbol: 'symbol-value', + side: 'Buy', + orderType: 'Limit', + qty: 'qty-value', + price: 'price-value', + orderLinkId: 'order_link_id-value', + timeInForce: 'GTC' + } + ) + service.create_spread_order( + symbol: 'symbol-value', + side: 'Buy', + order_type: 'Limit', + qty: 'qty-value', + price: 'price-value', + order_link_id: 'order_link_id-value', + time_in_force: 'GTC' + ) + end + + # endpoint: POST /v5/strategy/create + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StrategyService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/strategy/create', + body: { strategyType: 'chaseOrder', nestedOption: { innerKey: 'inner-value' } } + ) + service.create_strategy( + strategy_type: 'chaseOrder', + nested_option: { inner_key: 'inner-value' } + ) + end + + # endpoint: POST /v5/strategy/stop + it 'dispatches this generated endpoint' do + session = instance_double(Bybit::Session) + service = Bybit::RestApi::StrategyService.new(session) + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/strategy/stop', + body: { strategyId: 'strategy_id-value' } + ) + service.stop_strategy(strategy_id: 'strategy_id-value') + end + # gen-sdk-ruby:generated-service-specs:end +end From 4797a66ef2e33e984515531fb8b4c7cd4c8046a6 Mon Sep 17 00:00:00 2001 From: doris-xiao-bybit Date: Fri, 6 Nov 2026 11:44:01 +0800 Subject: [PATCH 4/5] sdk update --- CHANGELOG.md | 25 +-- README.md | 8 + .../plans/2026-11-06-remove-stocks-api.md | 150 +++++++++++++ .../plans/2026-11-06-sdk-review-fixes.md | 196 +++++++++++++++++ lib/bybit/client.rb | 4 +- lib/bybit/rest_api/alpha_service.rb | 54 ++--- lib/bybit/rest_api/event_service.rb | 10 +- lib/bybit/rest_api/fiat_service.rb | 14 +- .../rest_api/institutional_loan_service.rb | 6 +- lib/bybit/rest_api/referral_service.rb | 8 +- lib/bybit/rest_api/spot_margin_service.rb | 4 +- lib/bybit/rest_api/spot_x_service.rb | 14 +- lib/bybit/rest_api/spread_trade_service.rb | 24 +-- lib/bybit/rest_api/stocks_service.rb | 154 -------------- lib/bybit/rest_api/strategy_service.rb | 6 +- lib/bybit/rest_api/tax_service.rb | 4 +- spec/bybit_spec.rb | 6 + spec/generated/rest_api_generated_spec.rb | 197 +++--------------- spec/services/alpha_service_spec.rb | 94 +++++++++ 19 files changed, 565 insertions(+), 413 deletions(-) create mode 100644 docs/superpowers/plans/2026-11-06-remove-stocks-api.md create mode 100644 docs/superpowers/plans/2026-11-06-sdk-review-fixes.md delete mode 100644 lib/bybit/rest_api/stocks_service.rb create mode 100644 spec/services/alpha_service_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 27aa80b..38423d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,11 @@ -## 0.1.3 — 2026-11-06 +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.1.3] - 2026-11-06 ### Added - `AlphaService#get_lp_order_list(...)` @@ -56,15 +63,6 @@ - `ReferralService#get_commission_records(...)` - `ReferralService#get_user_identity_profile(...)` - `ReferralService#get_user_invitations(...)` -- `StocksService#get_convert_detail(...)` -- `StocksService#get_convert_list(...)` -- `StocksService#submit_convert(...)` -- `StocksService#get_multiplier_list(...)` -- `StocksService#get_market_session(...)` -- `StocksService#place_order(...)` -- `StocksService#cancel_order(...)` -- `StocksService#get_order_detail(...)` -- `StocksService#get_positions(...)` - `SpotMarginService#query_fixed_borrow_penalty_interest(...)` - `SpotMarginService#cancel_fixed_borrow_order(...)` - `SpotXService#get_launchpool_project_list(...)` @@ -95,13 +93,6 @@ - OpenAPI: `705f49bf6dba27ecc5b9b402f46ab2423cfb5dd9` - Docs: `9cde0843c270dd1e6009fb4593272f43f60cccf0` -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - ## [0.1.2] - 2026-10-13 ### Added diff --git a/README.md b/README.md index ebdc600..2a62e94 100644 --- a/README.md +++ b/README.md @@ -128,18 +128,26 @@ Each API group is a property on `Bybit::Client`: - `client.trade` — orders (create / amend / cancel / batch / history) - `client.position` — positions, leverage, TP/SL, move-position - `client.account` — wallet, margin, collateral, fee-rate, transaction log +- `client.alpha` — Alpha liquidity pools, prediction markets, and on-chain token trading - `client.asset` — coin balance, coin greeks, funding history - `client.user` — sub-accounts, API-key management - `client.affiliate` — sub-affiliate lists - `client.broker` — broker earnings, distributions - `client.crypto_loan` — flexible / fixed crypto loans +- `client.event` — event contracts, positions, settlements, and executions +- `client.fiat` — fiat convert balances, quotes, trades, and history - `client.institutional_loan` — /v5/ins-loan/* (OTC institutional loans) - `client.rfq` — request-for-quote (block trades) - `client.spot_margin` — UTA spot margin +- `client.spot_x` — Launchpool, Puzzle Hunt, and Token Splash +- `client.spread_trade` — spread instruments, orders, orderbook, and executions +- `client.strategy` — strategy creation, queries, and lifecycle operations +- `client.tax` — private tax report generation and status queries - `client.earn` — earn, liquidity mining, RWA, PWM, hold-to-earn - `client.p2p` — P2P advertise / order / chat - `client.bot` — DCA / grid / futures-combo / futures-grid / martingale - `client.pre_upgrade` — /v5/pre-upgrade/* historical queries for Classic → UTA upgrades +- `client.referral` — campaign rewards, commissions, profiles, and invitations - `client.misc` — /v5/announcements/index, /v5/system/status ## Error Handling diff --git a/docs/superpowers/plans/2026-11-06-remove-stocks-api.md b/docs/superpowers/plans/2026-11-06-remove-stocks-api.md new file mode 100644 index 0000000..8e4e350 --- /dev/null +++ b/docs/superpowers/plans/2026-11-06-remove-stocks-api.md @@ -0,0 +1,150 @@ +# Remove Stocks API Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Remove every `/v5/rwa/stocks/*` endpoint and the `client.stocks` public surface from the unreleased Ruby SDK. + +**Architecture:** Remove the dedicated service at its client composition boundary, then remove its generated request contracts and public documentation. A negative client-surface regression example prevents the service from remaining accidentally exposed. + +**Tech Stack:** Ruby 3.3, RSpec 3, RuboCop, generated REST contract specs. + +--- + +### Task 1: Lock the removed client surface with a failing example + +**Files:** +- Modify: `spec/bybit_spec.rb` + +- [x] **Step 1: Add the negative public-surface example** + +Add this example inside `RSpec.describe Bybit`: + +```ruby +it 'does not expose the deferred Stocks API' do + client = Bybit::Client.new + + expect(client).not_to respond_to(:stocks) +end +``` + +- [x] **Step 2: Run the example and verify RED** + +Run: + +```bash +bundle exec rspec spec/bybit_spec.rb +``` + +Expected: the new example fails because the current client still responds to +`stocks`. Ignore the repository-wide coverage gate from a focused run; inspect +the RSpec example result itself. + +### Task 2: Remove the Stocks runtime and generated contracts + +**Files:** +- Delete: `lib/bybit/rest_api/stocks_service.rb` +- Modify: `lib/bybit/client.rb` +- Modify: `spec/generated/rest_api_generated_spec.rb` +- Modify: `README.md` +- Modify: `CHANGELOG.md` + +- [x] **Step 1: Remove the service from client composition** + +Delete this require: + +```ruby +require 'bybit/rest_api/stocks_service' +``` + +Remove `:stocks` from `Client`'s `attr_reader` declaration and remove this +initializer entry: + +```ruby +stocks: RestApi::StocksService, +``` + +- [x] **Step 2: Delete the dedicated service implementation** + +Delete `lib/bybit/rest_api/stocks_service.rb` in full. Do not move its methods +or retain a compatibility constant. + +- [x] **Step 3: Delete every generated Stocks contract example** + +From `spec/generated/rest_api_generated_spec.rb`, delete all nine complete +examples whose endpoint comments are: + +```text +GET /v5/rwa/stocks/convert/detail +GET /v5/rwa/stocks/convert/list +GET /v5/rwa/stocks/market/getMultiplierList +GET /v5/rwa/stocks/market/session +GET /v5/rwa/stocks/order/detail +GET /v5/rwa/stocks/positions +POST /v5/rwa/stocks/convert/submit +POST /v5/rwa/stocks/order +POST /v5/rwa/stocks/order/cancel +``` + +- [x] **Step 4: Remove public documentation entries** + +Delete this README inventory line: + +```markdown +- `client.stocks` — RWA stock conversion, trading, and positions +``` + +Delete all nine `StocksService#...` entries from the 0.1.3 `Added` section in +`CHANGELOG.md`. + +- [x] **Step 5: Verify the focused client example is GREEN** + +Run: + +```bash +bundle exec rspec spec/bybit_spec.rb +``` + +Expected: all examples in `spec/bybit_spec.rb` pass. The focused command may +still exit nonzero only because the global SimpleCov thresholds require the +complete suite. + +### Task 3: Prove complete removal and run project gates + +**Files:** +- Verify only. + +- [x] **Step 1: Search for remaining public/runtime references** + +Run: + +```bash +rg -n -i 'StocksService|client\.stocks|/v5/rwa/stocks' \ + README.md CHANGELOG.md lib spec +``` + +Expected: no matches. + +- [x] **Step 2: Run the complete test and lint gates** + +Run: + +```bash +bundle exec rspec +bundle exec rubocop +``` + +Expected: zero RSpec failures, coverage gates pass, and RuboCop reports no +offenses. + +- [x] **Step 3: Check whitespace and final scope** + +Run: + +```bash +git diff --check main +rg -n '[[:blank:]]+$' spec/bybit_spec.rb docs/superpowers/plans/2026-11-06-remove-stocks-api.md +git status --short +``` + +Expected: no whitespace matches or errors. Confirm the existing staged state +is preserved and SDK changes remain uncommitted. diff --git a/docs/superpowers/plans/2026-11-06-sdk-review-fixes.md b/docs/superpowers/plans/2026-11-06-sdk-review-fixes.md new file mode 100644 index 0000000..1313f55 --- /dev/null +++ b/docs/superpowers/plans/2026-11-06-sdk-review-fixes.md @@ -0,0 +1,196 @@ +# SDK Review Fixes Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Correct the reviewed API contracts and documentation defects while preserving all unrelated staged SDK work. + +**Architecture:** Keep the existing service/session design. Correct only the Alpha method signatures and wire hashes that diverge from the current API contract, add focused service specs, then mechanically repair documentation URLs and release-document structure. + +**Tech Stack:** Ruby 3.3, RSpec 3, Faraday 2, RuboCop, YARD comments. + +--- + +### Task 1: Correct Alpha Prediction contracts + +**Files:** +- Create: `spec/services/alpha_service_spec.rb` +- Modify: `lib/bybit/rest_api/alpha_service.rb:226-343` +- Modify: `spec/generated/rest_api_generated_spec.rb` + +- [ ] **Step 1: Write failing service contract examples** + +Add examples using an `instance_double(Bybit::Session)` that require these calls: + +```ruby +service.get_prediction_portfolio_summary(event_type: 1) +# body: { eventType: 1 } + +service.get_prediction_group_stage_detail(event_type: 1, group_name: 'A') +# body: { eventType: 1, groupName: 'A' } + +service.get_prediction_match_list( + event_type: 1, status: 1, start_time: 1, end_time: 2, + stage_code: 'GROUP', limit: 10, page_index: 1 +) +# body contains every corresponding camelCase key + +service.get_prediction_timeline_stages(event_type: 1) +# params: { eventType: 1 } + +service.get_prediction_price_history(token_id: 'token-id', interval: '1h') +# body: { tokenId: 'token-id', interval: '1h' } +``` + +Also assert that omitting `event_type` from timeline stages and omitting +`token_id` from price history raises `ArgumentError` before dispatch. + +- [ ] **Step 2: Verify the examples fail for the reviewed defects** + +Run: + +```bash +bundle exec rspec spec/services/alpha_service_spec.rb +``` + +Expected: failures showing the old no-argument/`stageCode`/`tokenIds` method contracts. + +- [ ] **Step 3: Implement the minimal corrected methods** + +Use these public signatures and wire mappings: + +```ruby +def get_prediction_portfolio_summary(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request( + method: :post, + path: '/v5/alpha/prediction/portfolio-summary', + body: params + ) +end + +def get_prediction_price_history(token_id:, interval:) + params = Bybit::Utils::WireKeys.camelize(tokenId: token_id, interval: interval) + @session.sign_request( + method: :post, + path: '/v5/alpha/prediction/price-history', + body: params + ) +end + +def get_prediction_group_stage_detail(event_type:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(eventType: event_type)) + @session.sign_request( + method: :post, + path: '/v5/alpha/prediction/sports/group-stage-detail', + body: params + ) +end + +def get_prediction_match_list(event_type:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(eventType: event_type)) + @session.sign_request( + method: :post, + path: '/v5/alpha/prediction/sports/match-list', + body: params + ) +end + +def get_prediction_timeline_stages(event_type:) + params = Bybit::Utils::WireKeys.camelize(eventType: event_type) + @session.sign_request( + method: :get, + path: '/v5/alpha/prediction/sports/timeline-stages', + params: params + ) +end +``` + +Update their YARD parameter comments to match the official request tables. + +- [ ] **Step 4: Update generated expectations and verify green** + +Replace the affected generated calls with the corrected arguments and expected +wire keys, then run: + +```bash +bundle exec rspec spec/services/alpha_service_spec.rb spec/generated/rest_api_generated_spec.rb +``` + +Expected: all focused examples pass. + +### Task 2: Repair documentation surfaces + +**Files:** +- Modify: `lib/bybit/rest_api/alpha_service.rb` +- Modify: `lib/bybit/rest_api/event_service.rb` +- Modify: `lib/bybit/rest_api/fiat_service.rb` +- Modify: `lib/bybit/rest_api/institutional_loan_service.rb` +- Modify: `lib/bybit/rest_api/referral_service.rb` +- Modify: `lib/bybit/rest_api/spot_margin_service.rb` +- Modify: `lib/bybit/rest_api/spot_x_service.rb` +- Modify: `lib/bybit/rest_api/spread_trade_service.rb` +- Modify: `lib/bybit/rest_api/stocks_service.rb` +- Modify: `lib/bybit/rest_api/strategy_service.rb` +- Modify: `lib/bybit/rest_api/tax_service.rb` +- Modify: `README.md` +- Modify: `CHANGELOG.md` + +- [ ] **Step 1: Replace dead YARD links** + +Apply the official sitemap route families: + +```text +alpha/prediction/sports/* -> alpha/prediction/sports-* +alpha/trade/{purchase,quote,redeem} -> alpha/trade/trade-* +event/* -> event/trade/{order-list,open-order,position,settlement,execution} +fiat/* -> asset/fiat-convert/* +ins-loan/* -> otc/* +referral/* -> referral/referral-* +spot-x/* -> finance/spot-x/* with the published leaf names +spread/* -> spread/{market,trade}/* +strategy/{create,list,stop} -> strategy/{create-strategy,strategy-list,stop-strategy} +``` + +For Stocks and the private FHT Tax endpoints, remove dead `@see` URLs and add: + +```ruby +# @note Generated from the Bybit OpenAPI specification; no public documentation page is currently available. +``` + +- [ ] **Step 2: Validate every added documentation URL** + +Compare all changed `@see` URLs to `https://bybit-exchange.github.io/docs/sitemap.xml`. +Expected: zero changed URLs missing from the sitemap. + +- [ ] **Step 3: Repair release documentation** + +Move `## [0.1.3] - 2026-11-06` below the changelog introduction, update README's +service inventory with the newly exposed services, and preserve all endpoint +entries and source hashes. + +### Task 3: Full verification + +**Files:** +- Verify only; no new production files. + +- [ ] **Step 1: Run all local gates** + +```bash +bundle exec rspec +bundle exec rubocop +git diff --check main +``` + +Expected: 0 failures, 0 offenses, and no whitespace errors. + +- [ ] **Step 2: Run read-only testnet checks** + +Use environment-only credentials and call the corrected Alpha query methods. +Do not create orders or change account settings. Confirm request signing works +and record API-level availability or validation responses without printing +credentials or account values. + +- [ ] **Step 3: Review the final diff** + +Confirm only the approved service, specs, README, CHANGELOG, and documentation +comments changed. Do not stage or commit the user's pre-existing SDK changes. diff --git a/lib/bybit/client.rb b/lib/bybit/client.rb index 661d13d..c9313bf 100644 --- a/lib/bybit/client.rb +++ b/lib/bybit/client.rb @@ -24,7 +24,6 @@ require 'bybit/rest_api/referral_service' require 'bybit/rest_api/spot_x_service' require 'bybit/rest_api/spread_trade_service' -require 'bybit/rest_api/stocks_service' require 'bybit/rest_api/strategy_service' require 'bybit/rest_api/tax_service' # gen-sdk-ruby:service-requires:end @@ -48,7 +47,7 @@ class Client attr_reader :account, :affiliate, :alpha, :asset, :bot, :broker, :crypto_loan, :earn, :event, :fiat, :institutional_loan, :market, :misc, :p2p, :position, :pre_upgrade, :referral, :rfq, :spot_margin, :spot_x, :spread_trade, - :stocks, :strategy, :tax, :trade, :user + :strategy, :tax, :trade, :user # gen-sdk-ruby:client-readers:end @@ -81,7 +80,6 @@ def initialize(config = nil, **overrides) spot_margin: RestApi::SpotMarginService, spot_x: RestApi::SpotXService, spread_trade: RestApi::SpreadTradeService, - stocks: RestApi::StocksService, strategy: RestApi::StrategyService, tax: RestApi::TaxService, trade: RestApi::TradeService, diff --git a/lib/bybit/rest_api/alpha_service.rb b/lib/bybit/rest_api/alpha_service.rb index 0143fb4..1c624d4 100644 --- a/lib/bybit/rest_api/alpha_service.rb +++ b/lib/bybit/rest_api/alpha_service.rb @@ -227,10 +227,12 @@ def get_prediction_pay_token_list # # POST /v5/alpha/prediction/portfolio-summary # + # @option kwargs [Integer] :event_type Optional sports event type filter. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/portfolio-summary - def get_prediction_portfolio_summary - @session.sign_request(method: :post, path: '/v5/alpha/prediction/portfolio-summary') + def get_prediction_portfolio_summary(**kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs) + @session.sign_request(method: :post, path: '/v5/alpha/prediction/portfolio-summary', body: params) end # Get user's historical closed prediction market positions @@ -265,14 +267,12 @@ def get_prediction_position_list(**kwargs) # # POST /v5/alpha/prediction/price-history # - # @param interval [String] - # @option kwargs [Array] :token_ids Option 1 — List of outcome token IDs. Maximum 20. Mutually exclusive with eventId. - # @option kwargs [String] :event_id Option 2 — Event ID to get price history for all tokens in the event. - # @option kwargs [Integer] :fidelity Minutes between data points. 0 means auto (system default). + # @param token_id [String] Outcome token ID. + # @param interval [String] Price history interval. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/price-history - def get_prediction_price_history(interval:, **kwargs) - params = Bybit::Utils::WireKeys.camelize(kwargs.merge(interval: interval)) + def get_prediction_price_history(token_id:, interval:) + params = Bybit::Utils::WireKeys.camelize(tokenId: token_id, interval: interval) @session.sign_request(method: :post, path: '/v5/alpha/prediction/price-history', body: params) end @@ -309,12 +309,12 @@ def get_prediction_side_market_list(event_type:) # # POST /v5/alpha/prediction/sports/group-stage-detail # - # @param event_type [String] - # @param stage_code [String] + # @param event_type [Integer] Sports event type. `1` = FIFA_2026. + # @option kwargs [String] :group_name Optional group name filter. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/sports/group-stage-detail - def get_prediction_group_stage_detail(event_type:, stage_code:) - params = Bybit::Utils::WireKeys.camelize({ eventType: event_type, stageCode: stage_code }) + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/sports-group-stage-detail + def get_prediction_group_stage_detail(event_type:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(eventType: event_type)) @session.sign_request(method: :post, path: '/v5/alpha/prediction/sports/group-stage-detail', body: params) end @@ -322,11 +322,17 @@ def get_prediction_group_stage_detail(event_type:, stage_code:) # # POST /v5/alpha/prediction/sports/match-list # - # @param event_type [String] + # @param event_type [Integer] Sports event type. `1` = FIFA_2026. + # @option kwargs [Integer] :status Optional match status filter. + # @option kwargs [Integer] :start_time Optional start timestamp in milliseconds. + # @option kwargs [Integer] :end_time Optional end timestamp in milliseconds. + # @option kwargs [String] :stage_code Optional tournament stage code. + # @option kwargs [Integer] :limit Number of records per page. + # @option kwargs [Integer] :page_index Page number starting from 1. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/sports/match-list - def get_prediction_match_list(event_type:) - params = Bybit::Utils::WireKeys.camelize({ eventType: event_type }) + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/sports-match-list + def get_prediction_match_list(event_type:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(eventType: event_type)) @session.sign_request(method: :post, path: '/v5/alpha/prediction/sports/match-list', body: params) end @@ -334,11 +340,11 @@ def get_prediction_match_list(event_type:) # # GET /v5/alpha/prediction/sports/timeline-stages # - # @option kwargs [String] :event_type Sports event type. `1` = FIFA_2026. + # @param event_type [Integer] Sports event type. `1` = FIFA_2026. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/sports/timeline-stages - def get_prediction_timeline_stages(**kwargs) - params = Bybit::Utils::WireKeys.camelize(kwargs) + # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/sports-timeline-stages + def get_prediction_timeline_stages(event_type:) + params = Bybit::Utils::WireKeys.camelize(eventType: event_type) @session.sign_request(method: :get, path: '/v5/alpha/prediction/sports/timeline-stages', params: params) end @@ -474,7 +480,7 @@ def get_pay_token_list(chain_code:, token_address:) # @param correcting_code [String] MD5 checksum for data integrity. **Must pass as-is from `/quote` response.** # @option kwargs [String] :tenant Optional tenant identifier. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/purchase + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/trade-purchase def execute_purchase(from_token_code:, from_token_amount:, to_token_code:, slippage:, quote_data:, gas:, quote_mode:, correcting_code:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(fromTokenCode: from_token_code, fromTokenAmount: from_token_amount, toTokenCode: to_token_code, slippage: slippage, quoteData: quote_data, gas: gas, quoteMode: quote_mode, correctingCode: correcting_code)) @session.sign_request(method: :post, path: '/v5/alpha/trade/purchase', body: params) @@ -499,7 +505,7 @@ def execute_purchase(from_token_code:, from_token_amount:, to_token_code:, slipp # - `1`: Price Priority - best price, may have higher failure rate # - `2`: Success Rate Priority - guaranteed execution, price may be slightly worse # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/quote + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/trade-quote def get_trade_quote(trade_type:, from_token_code:, from_token_amount:, to_token_code:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(tradeType: trade_type, fromTokenCode: from_token_code, fromTokenAmount: from_token_amount, toTokenCode: to_token_code)) @session.sign_request(method: :post, path: '/v5/alpha/trade/quote', body: params) @@ -525,7 +531,7 @@ def get_trade_quote(trade_type:, from_token_code:, from_token_amount:, to_token_ # @param correcting_code [String] MD5 checksum for data integrity. **Must pass as-is from `/quote` response.** # @option kwargs [String] :tenant Optional tenant identifier. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/redeem + # @see https://bybit-exchange.github.io/docs/v5/alpha/trade/trade-redeem def execute_redeem(from_token_code:, from_token_amount:, to_token_code:, slippage:, quote_data:, gas:, quote_mode:, correcting_code:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(fromTokenCode: from_token_code, fromTokenAmount: from_token_amount, toTokenCode: to_token_code, slippage: slippage, quoteData: quote_data, gas: gas, quoteMode: quote_mode, correctingCode: correcting_code)) @session.sign_request(method: :post, path: '/v5/alpha/trade/redeem', body: params) diff --git a/lib/bybit/rest_api/event_service.rb b/lib/bybit/rest_api/event_service.rb index 55dfecb..aa9dd88 100644 --- a/lib/bybit/rest_api/event_service.rb +++ b/lib/bybit/rest_api/event_service.rb @@ -15,7 +15,7 @@ class EventService < BaseService # @option kwargs [Integer] :limit Number of items per page. Default: `50`, Range: [`1`, `100`] # @option kwargs [String] :cursor Pagination cursor # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/event/order-list + # @see https://bybit-exchange.github.io/docs/v5/event/trade/order-list def get_ec_order_history(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/event/order-list', params: params) @@ -31,7 +31,7 @@ def get_ec_order_history(**kwargs) # @option kwargs [Integer] :limit Number of items per page. Default: `20`, Range: [`1`, `50`] # @option kwargs [String] :cursor Pagination cursor. Use `nextPageCursor` from the response to retrieve the next page # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/event/order-realtime + # @see https://bybit-exchange.github.io/docs/v5/event/trade/open-order def get_ec_active_orders(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/event/order-realtime', params: params) @@ -47,7 +47,7 @@ def get_ec_active_orders(**kwargs) # @option kwargs [Integer] :limit Number of items per page. Default: `20`, Range: [`1`, `50`] # @option kwargs [String] :cursor Pagination cursor. Use `nextPageCursor` from the response to retrieve the next page # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/event/positions + # @see https://bybit-exchange.github.io/docs/v5/event/trade/position def get_ec_position_info(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/event/positions', params: params) @@ -64,7 +64,7 @@ def get_ec_position_info(**kwargs) # @option kwargs [Integer] :limit Number of items per page. Default: `50`, Range: [`1`, `100`] # @option kwargs [String] :cursor Pagination cursor # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/event/settlements + # @see https://bybit-exchange.github.io/docs/v5/event/trade/settlement def get_ec_settlements(symbol:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) @session.sign_request(method: :get, path: '/v5/event/settlements', params: params) @@ -82,7 +82,7 @@ def get_ec_settlements(symbol:, **kwargs) # @option kwargs [Integer] :limit Number of items per page. Default: `50`, Range: [`1`, `100`] # @option kwargs [String] :cursor Pagination cursor # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/event/trades + # @see https://bybit-exchange.github.io/docs/v5/event/trade/execution def get_ec_trade_history(symbol:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) @session.sign_request(method: :get, path: '/v5/event/trades', params: params) diff --git a/lib/bybit/rest_api/fiat_service.rb b/lib/bybit/rest_api/fiat_service.rb index 67c6954..5e8f4f0 100644 --- a/lib/bybit/rest_api/fiat_service.rb +++ b/lib/bybit/rest_api/fiat_service.rb @@ -13,7 +13,7 @@ class FiatService < BaseService # - Crypto: e.g., USDT, BTC, ETH # - Omit to query all balances # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/fiat/balance-query + # @see https://bybit-exchange.github.io/docs/v5/asset/fiat-convert/balance-query def query_balance(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/fiat/balance-query', params: params) @@ -27,7 +27,7 @@ def query_balance(**kwargs) # - `0`: buy - Buy crypto, sell fiat # - `1`: sell - Sell crypto, buy fiat # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/fiat/query-coin-list + # @see https://bybit-exchange.github.io/docs/v5/asset/fiat-convert/query-coin-list def query_coin_list(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/fiat/query-coin-list', params: params) @@ -42,7 +42,7 @@ def query_coin_list(**kwargs) # @option kwargs [String] :start_time Query start time (millisecond timestamp) # @option kwargs [String] :end_time Query end time (millisecond timestamp) # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/fiat/query-trade-history + # @see https://bybit-exchange.github.io/docs/v5/asset/fiat-convert/query-trade-history def query_trade_history(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/fiat/query-trade-history', params: params) @@ -59,7 +59,7 @@ def query_trade_history(**kwargs) # @param request_amount [String] Request coin amount (the amount you want to sell) # @option kwargs [String] :request_coin_type Coin type you want to sell, defaults to fiat # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/fiat/quote-apply + # @see https://bybit-exchange.github.io/docs/v5/asset/fiat-convert/quote-apply def apply_quote(from_coin:, from_coin_type:, to_coin:, to_coin_type:, request_amount:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(fromCoin: from_coin, fromCoinType: from_coin_type, toCoin: to_coin, toCoinType: to_coin_type, requestAmount: request_amount)) @session.sign_request(method: :post, path: '/v5/fiat/quote-apply', body: params) @@ -72,7 +72,7 @@ def apply_quote(from_coin:, from_coin_type:, to_coin:, to_coin_type:, request_am # @param symbol [String] Coin pair, format: "FIAT-CRYPTO", e.g., "EUR-USDT" # @option kwargs [String] :payment_method Payment method (reserved field) # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/fiat/reference-price + # @see https://bybit-exchange.github.io/docs/v5/asset/fiat-convert/reference-price def get_reference_price(symbol:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) @session.sign_request(method: :get, path: '/v5/fiat/reference-price', params: params) @@ -87,7 +87,7 @@ def get_reference_price(symbol:, **kwargs) # @option kwargs [String] :webhook_url Optional webhook URL to receive trade status notifications (max 256 characters) # @option kwargs [String] :merchant_request_id Customised request ID (max 36 characters). Generally it is useless, but convenient for internal tracking # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/fiat/trade-execute + # @see https://bybit-exchange.github.io/docs/v5/asset/fiat-convert/confirm-quote def confirm_quote(quote_tx_id:, sub_user_id:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(quoteTxId: quote_tx_id, subUserId: sub_user_id)) @session.sign_request(method: :post, path: '/v5/fiat/trade-execute', body: params) @@ -100,7 +100,7 @@ def confirm_quote(quote_tx_id:, sub_user_id:, **kwargs) # @option kwargs [String] :trade_no Trade order number (either tradeNo or merchantRequestId must be provided) # @option kwargs [String] :merchant_request_id Merchant request ID (either tradeNo or merchantRequestId must be provided) # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/fiat/trade-query + # @see https://bybit-exchange.github.io/docs/v5/asset/fiat-convert/query-trade def query_trade(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/fiat/trade-query', params: params) diff --git a/lib/bybit/rest_api/institutional_loan_service.rb b/lib/bybit/rest_api/institutional_loan_service.rb index 40915d6..95d8122 100644 --- a/lib/bybit/rest_api/institutional_loan_service.rb +++ b/lib/bybit/rest_api/institutional_loan_service.rb @@ -95,7 +95,7 @@ def bind_or_unbind_uid(uid:, operate:, **kwargs) # @param order_id [String] Loan order ID to repay # @param amount [String] Repayment amount # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/otc/repay-loan + # @see https://bybit-exchange.github.io/docs/v5/otc/repay def repay_loan(order_id:, amount:, **kwargs) params = kwargs.merge(order_id: order_id, amount: amount) params = Bybit::Utils::WireKeys.camelize(params) @@ -108,7 +108,7 @@ def repay_loan(order_id:, amount:, **kwargs) # # @option kwargs [String] :coin Coin name to filter, uppercase only. e.g. `BTC`. If not passed, returns all coins. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/ins-loan/coin-delta-amount + # @see https://bybit-exchange.github.io/docs/v5/otc/coin-delta-amount def ins_loan_coin_delta_amount(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/ins-loan/coin-delta-amount', params: params) @@ -119,7 +119,7 @@ def ins_loan_coin_delta_amount(**kwargs) # GET /v5/ins-loan/delay-liq-status # # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/ins-loan/delay-liq-status + # @see https://bybit-exchange.github.io/docs/v5/otc/delay-liq-status def ins_loan_delay_liq_status @session.sign_request(method: :get, path: '/v5/ins-loan/delay-liq-status') end diff --git a/lib/bybit/rest_api/referral_service.rb b/lib/bybit/rest_api/referral_service.rb index d7e9dfc..da2b436 100644 --- a/lib/bybit/rest_api/referral_service.rb +++ b/lib/bybit/rest_api/referral_service.rb @@ -8,7 +8,7 @@ class ReferralService < BaseService # POST /v5/referral/campaign/rewards # # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/referral/campaign/rewards + # @see https://bybit-exchange.github.io/docs/v5/referral/referral-campaign-rewards def get_campaign_rewards @session.sign_request(method: :post, path: '/v5/referral/campaign/rewards') end @@ -24,7 +24,7 @@ def get_campaign_rewards # @option kwargs [Integer] :page_size Number of records per page; 0 or a value greater than 200 is treated as 10. # @option kwargs [Integer] :product_line Product lines: 0=unknown; 1=spot; 2=contracts; 3=options; 4=USDC perpetual; 6=TradeFi; 9=Alpha. Unrecognized downstream product lines map to 0. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/referral/commission/records + # @see https://bybit-exchange.github.io/docs/v5/referral/referral-commission-records def get_commission_records(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :post, path: '/v5/referral/commission/records', body: params) @@ -35,7 +35,7 @@ def get_commission_records(**kwargs) # POST /v5/referral/user/identity-profile # # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/referral/user/identity-profile + # @see https://bybit-exchange.github.io/docs/v5/referral/referral-user-identity-profile def get_user_identity_profile @session.sign_request(method: :post, path: '/v5/referral/user/identity-profile') end @@ -51,7 +51,7 @@ def get_user_identity_profile # @option kwargs [Integer] :page_size Values 0 and greater than 200 are reset to 10 by the current service implementation. # @option kwargs [Integer] :friend_status # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/referral/user/invitations + # @see https://bybit-exchange.github.io/docs/v5/referral/referral-user-invitations def get_user_invitations(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :post, path: '/v5/referral/user/invitations', body: params) diff --git a/lib/bybit/rest_api/spot_margin_service.rb b/lib/bybit/rest_api/spot_margin_service.rb index 69b78a2..7b547cb 100644 --- a/lib/bybit/rest_api/spot_margin_service.rb +++ b/lib/bybit/rest_api/spot_margin_service.rb @@ -298,7 +298,7 @@ def spot_margin_switch_mode(spot_margin_mode:) # @option kwargs [String] :limit Page size as a string, from 1 to 100; defaults to 10. # @option kwargs [String] :cursor Opaque `nextPageCursor` returned by the previous page. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spot-margin-trade/fixedborrow-interest-accrued + # @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/fixedborrow-interest-accrued def query_fixed_borrow_penalty_interest(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/spot-margin-trade/fixedborrow-interest-accrued', params: params) @@ -310,7 +310,7 @@ def query_fixed_borrow_penalty_interest(**kwargs) # # @param order_id [String] Fixed-rate borrow order ID, not the contract match ID. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spot-margin-trade/fixedborrow-order-cancel + # @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/fixedborrow-order-cancel def cancel_fixed_borrow_order(order_id:) params = Bybit::Utils::WireKeys.camelize({ orderId: order_id }) @session.sign_request(method: :post, path: '/v5/spot-margin-trade/fixedborrow-order-cancel', body: params) diff --git a/lib/bybit/rest_api/spot_x_service.rb b/lib/bybit/rest_api/spot_x_service.rb index 57531f5..e256e3c 100644 --- a/lib/bybit/rest_api/spot_x_service.rb +++ b/lib/bybit/rest_api/spot_x_service.rb @@ -16,7 +16,7 @@ class SpotXService < BaseService # @option kwargs [String] :cursor Pagination cursor returned as `nextPageCursor` in the previous response. Omit for the first page. # @option kwargs [Integer] :limit Number of items per page. Defaults to `10`. Maximum `10`. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spot-x/launchpool/project/list + # @see https://bybit-exchange.github.io/docs/v5/finance/spot-x/launchpool/launchpool-project-list def get_launchpool_project_list(status:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(status: status)) @session.public_request(path: '/v5/spot-x/launchpool/project/list', params: params) @@ -50,7 +50,7 @@ def get_launchpool_project_list(status:, **kwargs) # @option kwargs [Integer] :page_size Number of records per page. Defaults to `10`. Maximum `10`. # @option kwargs [Integer] :current Page number (1-based). Defaults to `1`. Maximum `100`. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spot-x/launchpool/user/activity-log + # @see https://bybit-exchange.github.io/docs/v5/finance/spot-x/launchpool/launchpool-activity-log def get_launchpool_user_activity_log(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :post, path: '/v5/spot-x/launchpool/user/activity-log', body: params) @@ -61,7 +61,7 @@ def get_launchpool_user_activity_log(**kwargs) # GET /v5/spot-x/launchpool/user/current-staking # # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spot-x/launchpool/user/current-staking + # @see https://bybit-exchange.github.io/docs/v5/finance/spot-x/launchpool/launchpool-current-staking def get_launchpool_user_current_staking @session.sign_request(method: :get, path: '/v5/spot-x/launchpool/user/current-staking') end @@ -81,7 +81,7 @@ def get_launchpool_user_current_staking # @option kwargs [Integer] :page_size Number of records per page. Defaults to `10`. Maximum `10`. # @option kwargs [Integer] :current Page number (1-based). Defaults to `1`. Maximum `100`. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spot-x/launchpool/user/history + # @see https://bybit-exchange.github.io/docs/v5/finance/spot-x/launchpool/launchpool-user-history def get_launchpool_user_history(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :post, path: '/v5/spot-x/launchpool/user/history', body: params) @@ -100,7 +100,7 @@ def get_launchpool_user_history(**kwargs) # @option kwargs [String] :cursor Pagination cursor returned as `nextPageCursor` in the previous response. Omit for the first page. # @option kwargs [Integer] :limit Number of items per page. Defaults to `10`. Maximum `10`. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spot-x/puzzle/project/list + # @see https://bybit-exchange.github.io/docs/v5/finance/spot-x/puzzle/puzzle-project-list def get_puzzle_project_list(status:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(status: status)) @session.public_request(path: '/v5/spot-x/puzzle/project/list', params: params) @@ -119,7 +119,7 @@ def get_puzzle_project_list(status:, **kwargs) # @option kwargs [String] :cursor Pagination cursor returned as `nextPageCursor` in the previous response. Omit for the first page. # @option kwargs [Integer] :limit Number of items per page. Defaults to `10`. Maximum `10`. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spot-x/token-splash/project/list + # @see https://bybit-exchange.github.io/docs/v5/finance/spot-x/token-splash/token-splash-project-list def get_token_splash_project_list(status:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(status: status)) @session.public_request(path: '/v5/spot-x/token-splash/project/list', params: params) @@ -132,7 +132,7 @@ def get_token_splash_project_list(status:, **kwargs) # @option kwargs [String] :project_id Filter by exact activity code. Returns data for a single project when provided. # @option kwargs [String] :activity_coin Filter by activity coin symbol (case-insensitive), e.g. `BTC`, `ETH`. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spot-x/token-splash/user/activity-params + # @see https://bybit-exchange.github.io/docs/v5/finance/spot-x/token-splash/token-splash-user-activity-params def get_token_splash_user_activity_params(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/spot-x/token-splash/user/activity-params', params: params) diff --git a/lib/bybit/rest_api/spread_trade_service.rb b/lib/bybit/rest_api/spread_trade_service.rb index 646eb02..2823070 100644 --- a/lib/bybit/rest_api/spread_trade_service.rb +++ b/lib/bybit/rest_api/spread_trade_service.rb @@ -15,7 +15,7 @@ class SpreadTradeService < BaseService # @option kwargs [Integer] :limit Number of results per page. Range `[1, 50]`. Default `20`. # @option kwargs [String] :cursor Pagination cursor token from `nextPageCursor` in a previous response. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/execution/list + # @see https://bybit-exchange.github.io/docs/v5/spread/trade/trade-history def get_history(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/spread/execution/list', params: params) @@ -30,7 +30,7 @@ def get_history(**kwargs) # @option kwargs [Integer] :limit Number of records per page, range `[1, 500]`. Default is `200` # @option kwargs [String] :cursor Pagination cursor; use `nextPageCursor` from the previous response # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/instrument + # @see https://bybit-exchange.github.io/docs/v5/spread/market/instrument def get_spread_instruments_info(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.public_request(path: '/v5/spread/instrument', params: params) @@ -46,7 +46,7 @@ def get_spread_instruments_info(**kwargs) # - `2`: Sell # @param order_price [String] Order price. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/max-qty + # @see https://bybit-exchange.github.io/docs/v5/spread/trade/max-qty def get_spread_max_qty(symbol:, side:, order_price:) params = Bybit::Utils::WireKeys.camelize({ symbol: symbol, side: side, orderPrice: order_price }) @session.sign_request(method: :get, path: '/v5/spread/max-qty', params: params) @@ -66,7 +66,7 @@ def get_spread_max_qty(symbol:, side:, order_price:) # - `""` (empty string): keeps the existing price unchanged. # - `"0"`: updates the price to zero. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/order/amend + # @see https://bybit-exchange.github.io/docs/v5/spread/trade/amend-order def amend_spread_order(symbol:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) @session.sign_request(method: :post, path: '/v5/spread/order/amend', body: params) @@ -79,7 +79,7 @@ def amend_spread_order(symbol:, **kwargs) # @option kwargs [String] :order_id Spread combination order ID. Either `orderId` or `orderLinkId` is required. # @option kwargs [String] :order_link_id User-defined custom order ID. Either `orderId` or `orderLinkId` is required. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/order/cancel + # @see https://bybit-exchange.github.io/docs/v5/spread/trade/cancel-order def cancel_spread_order(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :post, path: '/v5/spread/order/cancel', body: params) @@ -94,7 +94,7 @@ def cancel_spread_order(**kwargs) # @option kwargs [Boolean] :cancel_all Set to `true` to cancel all open orders across all symbols. # Ignored when `symbol` is provided. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/order/cancel-all + # @see https://bybit-exchange.github.io/docs/v5/spread/trade/cancel-all def cancel_all_spread_orders(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :post, path: '/v5/spread/order/cancel-all', body: params) @@ -118,7 +118,7 @@ def cancel_all_spread_orders(**kwargs) # - `FOK`: Fill or Kill. # - `PostOnly`: Maker-only; rejected if it would take liquidity. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/order/create + # @see https://bybit-exchange.github.io/docs/v5/spread/trade/create-order def create_spread_order(symbol:, side:, order_type:, qty:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol, side: side, orderType: order_type, qty: qty)) @session.sign_request(method: :post, path: '/v5/spread/order/create', body: params) @@ -137,7 +137,7 @@ def create_spread_order(symbol:, side:, order_type:, qty:, **kwargs) # @option kwargs [Integer] :limit Number of results per page. Range `[1, 50]`. Default `20`. # @option kwargs [String] :cursor Pagination cursor token from `nextPageCursor` in a previous response. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/order/history + # @see https://bybit-exchange.github.io/docs/v5/spread/trade/order-history def get_spread_order_history(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/spread/order/history', params: params) @@ -154,7 +154,7 @@ def get_spread_order_history(**kwargs) # @option kwargs [Integer] :limit Number of results per page. Range `[1, 50]`. Default `20`. # @option kwargs [String] :cursor Pagination cursor token from `nextPageCursor` in a previous response. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/order/realtime + # @see https://bybit-exchange.github.io/docs/v5/spread/trade/open-order def get_spread_open_orders(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/spread/order/realtime', params: params) @@ -167,7 +167,7 @@ def get_spread_open_orders(**kwargs) # @param symbol [String] Spread combination symbol name, e.g. `SOLUSDT_SOL/USDT` # @option kwargs [Integer] :limit Number of bid/ask levels per side, range `[1, 25]`. Default is `1` # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/orderbook + # @see https://bybit-exchange.github.io/docs/v5/spread/market/orderbook def get_spread_orderbook(symbol:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) @session.public_request(path: '/v5/spread/orderbook', params: params) @@ -180,7 +180,7 @@ def get_spread_orderbook(symbol:, **kwargs) # @param symbol [String] Spread combination symbol name, e.g. `SOLUSDT_SOL/USDT` # @option kwargs [Integer] :limit Number of records per page, range `[1, 1000]`. Default is `500` # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/recent-trade + # @see https://bybit-exchange.github.io/docs/v5/spread/market/recent-trade def get_spread_recent_trades(symbol:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol)) @session.public_request(path: '/v5/spread/recent-trade', params: params) @@ -192,7 +192,7 @@ def get_spread_recent_trades(symbol:, **kwargs) # # @param symbol [String] Spread combination symbol name, e.g. `SOLUSDT_SOL/USDT` # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/spread/tickers + # @see https://bybit-exchange.github.io/docs/v5/spread/market/tickers def get_spread_tickers(symbol:) params = Bybit::Utils::WireKeys.camelize({ symbol: symbol }) @session.public_request(path: '/v5/spread/tickers', params: params) diff --git a/lib/bybit/rest_api/stocks_service.rb b/lib/bybit/rest_api/stocks_service.rb deleted file mode 100644 index 960fdd2..0000000 --- a/lib/bybit/rest_api/stocks_service.rb +++ /dev/null @@ -1,154 +0,0 @@ -# frozen_string_literal: true - -module Bybit - module RestApi - class StocksService < BaseService - # 查询 Convert 订单详情 - # - # GET /v5/rwa/stocks/convert/detail - # - # @option kwargs [String] :order_no Convert 订单号;与 `requestId` 二选一 - # @option kwargs [String] :request_id 提交时使用的幂等键;与 `orderNo` 二选一 - # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/convert/detail - def get_convert_detail(**kwargs) - params = Bybit::Utils::WireKeys.camelize(kwargs) - @session.sign_request(method: :get, path: '/v5/rwa/stocks/convert/detail', params: params) - end - - # 获取 Convert 交易对列表 - # - # GET /v5/rwa/stocks/convert/list - # - # @option kwargs [String] :symbol 按标的过滤,如 `AAPL-US`;不传则返回全部 - # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/convert/list - def get_convert_list(**kwargs) - params = Bybit::Utils::WireKeys.camelize(kwargs) - @session.sign_request(method: :get, path: '/v5/rwa/stocks/convert/list', params: params) - end - - # 提交 Convert 订单(Mint / Redeem) - # - # POST /v5/rwa/stocks/convert/submit - # - # @param convert_type [String] 方向:MINT(正股→Token)/ REDEEM(Token→正股) - # @param symbol [String] 底层股票代码,如 `AAPL-US` - # @param input_amount [String] 输入数量(MINT 时为正股数量,REDEEM 时为 Token 数量) - # @param front_multiplier [String] 前端快照的转换比例,服务端会与当前值校验 - # @param request_id [String] 幂等键,字母数字与 `-_`,同一 MM 账号下 24 小时内唯一 - # @param flow [String] 链路类型。 - # - `CEX`:中心化交易所链路,Mint/Burn 均通过 Bybit 主站处理 - # - `DEX`:去中心化链路,Mint 到指定合约地址;Burn 流程见 `burnScene` - # @option kwargs [String] :account_type 仅 `REDEEM` 生效,默认 `all`。 - # - `all`:自动选择账户 - # - `uta`:指定划入统一交易账户(UTA) - # - `fund`:指定划入资金账户 - # @option kwargs [String] :contract_addr MINT 时代币接收地址;DEX Burn DEP 场景时代币提供地址。 - # DEX 链路 NDP 场景不传。 - # @option kwargs [String] :burn_scene 仅 DEX Burn(`flow=DEX` + `convertType=REDEEM`)时有效。 - # - `DEP`:走 Bybit 主站(Deposit)Burn——MM 先将 DEX 合约 mStocks 入金到 UID1 再 Redeem - # - `NDP`:不经主站(Non-Deposit)Burn——MM DEX 合约授权 TokenIssuer,链上直接划转 - # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/convert/submit - def submit_convert(convert_type:, symbol:, input_amount:, front_multiplier:, request_id:, flow:, **kwargs) - params = Bybit::Utils::WireKeys.camelize(kwargs.merge(convertType: convert_type, symbol: symbol, inputAmount: input_amount, frontMultiplier: front_multiplier, requestId: request_id, flow: flow)) - @session.sign_request(method: :post, path: '/v5/rwa/stocks/convert/submit', body: params) - end - - # 获取 Multiplier 列表 - # - # GET /v5/rwa/stocks/market/getMultiplierList - # - # @param current [Integer] 当前页码(从 1 开始) - # @param page_size [Integer] 每页条数,默认 10 - # @option kwargs [String] :symbol 按股票代码过滤,如 `TSLA-US`;不传则返回全部 - # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/market/getMultiplierList - def get_multiplier_list(current:, page_size:, **kwargs) - params = Bybit::Utils::WireKeys.camelize(kwargs.merge(current: current, pageSize: page_size)) - @session.sign_request(method: :get, path: '/v5/rwa/stocks/market/getMultiplierList', params: params) - end - - # 获取交易日历与市场状态 - # - # GET /v5/rwa/stocks/market/session - # - # @option kwargs [String] :symbol 内部股票代码,如 `TSLA-US`;不传则返回通用日历 - # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/market/session - def get_market_session(**kwargs) - params = Bybit::Utils::WireKeys.camelize(kwargs) - @session.sign_request(method: :get, path: '/v5/rwa/stocks/market/session', params: params) - end - - # 下单(买入 / 卖出股票) - # - # POST /v5/rwa/stocks/order - # - # @param symbol [String] 股票代码,如 `TSLA-US`、`AAPL-US` - # @param quote_token [String] 计价资产,当前仅支持 `USDC` - # @param side [String] 方向 - # @param type [String] 订单类型 - # @param time_in_force [String] 订单有效期: - # - `DAY`:当日有效,北美主市场收盘时自动撤单 - # - `GTC`:撤销前持续有效(Good Till Cancelled) - # - `IOC`:立即成交,未成交部分立即取消;仅支持 `LIMIT + 整股 + RTH` - # - `SELL` 仅支持 `DAY` / `GTC` - # @param order_time [Integer] 客户端下单毫秒时间戳 - # @param request_id [String] 幂等键,字母数字与 `-_`,同一 MM 账号下 24 小时内唯一 - # @option kwargs [String] :qty 委托数量(股)。`SELL` 必填;`BUY` 的 `LIMIT`/`STOP`/`STOP_LIMIT` 必填;与 `notional` 互斥 - # @option kwargs [String] :notional 名义额(USDC)。仅 `BUY` 且 `type=MARKET` 时使用;与 `qty` 互斥 - # @option kwargs [String] :limit_price 限价,`type=LIMIT` 或 `STOP_LIMIT` 时必填 - # @option kwargs [String] :stop_price 触发价,`type=STOP` 或 `STOP_LIMIT` 时必填 - # @option kwargs [String] :trading_session 交易时段,默认 `RTH`。 - # - `RTH`:Regular Trading Hours,正常交易时段 - # - `24H`:全天候,包含盘前/盘后/夜盘;非 RTH 时段只允许 LIMIT 单 - # @option kwargs [Boolean] :tokenize 成交后是否自动 tokenize,默认 `false`;仅对 `BUY` 生效 - # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/order - def place_order(symbol:, quote_token:, side:, type:, time_in_force:, order_time:, request_id:, **kwargs) - params = Bybit::Utils::WireKeys.camelize(kwargs.merge(symbol: symbol, quoteToken: quote_token, side: side, type: type, timeInForce: time_in_force, orderTime: order_time, requestId: request_id)) - @session.sign_request(method: :post, path: '/v5/rwa/stocks/order', body: params) - end - - # 撤单 - # - # POST /v5/rwa/stocks/order/cancel - # - # @param order_no [String] 系统订单号 - # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/order/cancel - def cancel_order(order_no:) - params = Bybit::Utils::WireKeys.camelize({ orderNo: order_no }) - @session.sign_request(method: :post, path: '/v5/rwa/stocks/order/cancel', body: params) - end - - # 查询股票订单详情 - # - # GET /v5/rwa/stocks/order/detail - # - # @option kwargs [String] :order_no 系统订单号;与 `requestId` 二选一 - # @option kwargs [String] :request_id 客户端幂等 ID;与 `orderNo` 二选一 - # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/order/detail - def get_order_detail(**kwargs) - params = Bybit::Utils::WireKeys.camelize(kwargs) - @session.sign_request(method: :get, path: '/v5/rwa/stocks/order/detail', params: params) - end - - # 获取所有正股仓位 - # - # GET /v5/rwa/stocks/positions - # - # @option kwargs [String] :symbol 按标的过滤;不传则返回全部持仓 - # @option kwargs [Boolean] :show_zero 是否返回零持仓,默认 `false` - # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/rwa/stocks/positions - def get_positions(**kwargs) - params = Bybit::Utils::WireKeys.camelize(kwargs) - @session.sign_request(method: :get, path: '/v5/rwa/stocks/positions', params: params) - end - end - end -end diff --git a/lib/bybit/rest_api/strategy_service.rb b/lib/bybit/rest_api/strategy_service.rb index 505002e..065fbd3 100644 --- a/lib/bybit/rest_api/strategy_service.rb +++ b/lib/bybit/rest_api/strategy_service.rb @@ -9,7 +9,7 @@ class StrategyService < BaseService # # @param params [Hash] Request payload. strategy_type: chaseOrder | iceberg | pov | twap. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/strategy/create + # @see https://bybit-exchange.github.io/docs/v5/strategy/create-strategy def create_strategy(**params) body = Bybit::Utils::WireKeys.camelize(params) @session.sign_request(method: :post, path: '/v5/strategy/create', body: body) @@ -48,7 +48,7 @@ def create_strategy(**params) # Use nextCursor value from previous query to get next page. # Empty for first page. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/strategy/list + # @see https://bybit-exchange.github.io/docs/v5/strategy/strategy-list def query_list(**kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs) @session.sign_request(method: :get, path: '/v5/strategy/list', params: params) @@ -95,7 +95,7 @@ def query_order_list(strategy_id:, **kwargs) # Obtained from strategy creation response or strategy list query. # Only Running or Untriggered strategies can be stopped. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/strategy/stop + # @see https://bybit-exchange.github.io/docs/v5/strategy/stop-strategy def stop_strategy(strategy_id:) params = Bybit::Utils::WireKeys.camelize({ strategyId: strategy_id }) @session.sign_request(method: :post, path: '/v5/strategy/stop', body: params) diff --git a/lib/bybit/rest_api/tax_service.rb b/lib/bybit/rest_api/tax_service.rb index 805dfce..3c537b5 100644 --- a/lib/bybit/rest_api/tax_service.rb +++ b/lib/bybit/rest_api/tax_service.rb @@ -15,7 +15,7 @@ class TaxService < BaseService # - `csv` — CSV text format # - `orc` — ORC columnar format (default) # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/fht/compliance/tax/private/batch_create + # @note Generated from the Bybit OpenAPI specification; no public documentation page is currently available. def batch_create_tax_reports(start_time:, end_time:, items:, **kwargs) params = Bybit::Utils::WireKeys.camelize(kwargs.merge(startTime: start_time, endTime: end_time, items: items)) @session.sign_request(method: :post, path: '/v5/fht/compliance/tax/private/batch_create', body: params) @@ -27,7 +27,7 @@ def batch_create_tax_reports(start_time:, end_time:, items:, **kwargs) # # @param batch_id [String] Batch ID returned by `batch_create` # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). - # @see https://bybit-exchange.github.io/docs/v5/fht/compliance/tax/private/batch_query + # @note Generated from the Bybit OpenAPI specification; no public documentation page is currently available. def batch_query_tax_reports(batch_id:) params = Bybit::Utils::WireKeys.camelize({ batchId: batch_id }) @session.sign_request(method: :get, path: '/v5/fht/compliance/tax/private/batch_query', params: params) diff --git a/spec/bybit_spec.rb b/spec/bybit_spec.rb index 128cb8d..3e887d4 100644 --- a/spec/bybit_spec.rb +++ b/spec/bybit_spec.rb @@ -10,4 +10,10 @@ client = Bybit::Client.new expect(client).to be_a(Bybit::Client) end + + it 'does not expose the deferred Stocks API' do + client = Bybit::Client.new + + expect(client).not_to respond_to(:stocks) + end end diff --git a/spec/generated/rest_api_generated_spec.rb b/spec/generated/rest_api_generated_spec.rb index ad08b45..4ae8a85 100644 --- a/spec/generated/rest_api_generated_spec.rb +++ b/spec/generated/rest_api_generated_spec.rb @@ -269,78 +269,6 @@ service.ins_loan_delay_liq_status end - # endpoint: GET /v5/rwa/stocks/convert/detail - it 'dispatches this generated endpoint' do - session = instance_double(Bybit::Session) - service = Bybit::RestApi::StocksService.new(session) - expect(session).to receive(:sign_request).with( - method: :get, - path: '/v5/rwa/stocks/convert/detail', - params: { orderNo: 'order_no-value', requestId: 'request_id-value' } - ) - service.get_convert_detail(order_no: 'order_no-value', request_id: 'request_id-value') - end - - # endpoint: GET /v5/rwa/stocks/convert/list - it 'dispatches this generated endpoint' do - session = instance_double(Bybit::Session) - service = Bybit::RestApi::StocksService.new(session) - expect(session).to receive(:sign_request).with( - method: :get, - path: '/v5/rwa/stocks/convert/list', - params: { symbol: 'symbol-value' } - ) - service.get_convert_list(symbol: 'symbol-value') - end - - # endpoint: GET /v5/rwa/stocks/market/getMultiplierList - it 'dispatches this generated endpoint' do - session = instance_double(Bybit::Session) - service = Bybit::RestApi::StocksService.new(session) - expect(session).to receive(:sign_request).with( - method: :get, - path: '/v5/rwa/stocks/market/getMultiplierList', - params: { symbol: 'symbol-value', current: 1, pageSize: 1 } - ) - service.get_multiplier_list(symbol: 'symbol-value', current: 1, page_size: 1) - end - - # endpoint: GET /v5/rwa/stocks/market/session - it 'dispatches this generated endpoint' do - session = instance_double(Bybit::Session) - service = Bybit::RestApi::StocksService.new(session) - expect(session).to receive(:sign_request).with( - method: :get, - path: '/v5/rwa/stocks/market/session', - params: { symbol: 'symbol-value' } - ) - service.get_market_session(symbol: 'symbol-value') - end - - # endpoint: GET /v5/rwa/stocks/order/detail - it 'dispatches this generated endpoint' do - session = instance_double(Bybit::Session) - service = Bybit::RestApi::StocksService.new(session) - expect(session).to receive(:sign_request).with( - method: :get, - path: '/v5/rwa/stocks/order/detail', - params: { orderNo: 'order_no-value', requestId: 'request_id-value' } - ) - service.get_order_detail(order_no: 'order_no-value', request_id: 'request_id-value') - end - - # endpoint: GET /v5/rwa/stocks/positions - it 'dispatches this generated endpoint' do - session = instance_double(Bybit::Session) - service = Bybit::RestApi::StocksService.new(session) - expect(session).to receive(:sign_request).with( - method: :get, - path: '/v5/rwa/stocks/positions', - params: { symbol: 'symbol-value', showZero: true } - ) - service.get_positions(symbol: 'symbol-value', show_zero: true) - end - # endpoint: GET /v5/spot-margin-trade/fixedborrow-interest-accrued it 'dispatches this generated endpoint' do session = instance_double(Bybit::Session) @@ -921,9 +849,10 @@ service = Bybit::RestApi::AlphaService.new(session) expect(session).to receive(:sign_request).with( method: :post, - path: '/v5/alpha/prediction/portfolio-summary' + path: '/v5/alpha/prediction/portfolio-summary', + body: { eventType: 'event_type-value' } ) - service.get_prediction_portfolio_summary + service.get_prediction_portfolio_summary(event_type: 'event_type-value') end # endpoint: POST /v5/alpha/prediction/position-history @@ -958,17 +887,13 @@ method: :post, path: '/v5/alpha/prediction/price-history', body: { - tokenIds: ['token_ids-value'], - eventId: 'event_id-value', - interval: 'interval-value', - fidelity: 1 + tokenId: 'token_id-value', + interval: 'interval-value' } ) service.get_prediction_price_history( - token_ids: ['token_ids-value'], - event_id: 'event_id-value', - interval: 'interval-value', - fidelity: 1 + token_id: 'token_id-value', + interval: 'interval-value' ) end @@ -1017,11 +942,11 @@ expect(session).to receive(:sign_request).with( method: :post, path: '/v5/alpha/prediction/sports/group-stage-detail', - body: { eventType: 'event_type-value', stageCode: 'stage_code-value' } + body: { eventType: 'event_type-value', groupName: 'group_name-value' } ) service.get_prediction_group_stage_detail( event_type: 'event_type-value', - stage_code: 'stage_code-value' + group_name: 'group_name-value' ) end @@ -1032,9 +957,25 @@ expect(session).to receive(:sign_request).with( method: :post, path: '/v5/alpha/prediction/sports/match-list', - body: { eventType: 'event_type-value' } + body: { + eventType: 'event_type-value', + status: 1, + startTime: 1, + endTime: 1, + stageCode: 'stage_code-value', + limit: 1, + pageIndex: 1 + } + ) + service.get_prediction_match_list( + event_type: 'event_type-value', + status: 1, + start_time: 1, + end_time: 1, + stage_code: 'stage_code-value', + limit: 1, + page_index: 1 ) - service.get_prediction_match_list(event_type: 'event_type-value') end # endpoint: POST /v5/alpha/prediction/token-price @@ -1385,90 +1326,6 @@ ) end - # endpoint: POST /v5/rwa/stocks/convert/submit - it 'dispatches this generated endpoint' do - session = instance_double(Bybit::Session) - service = Bybit::RestApi::StocksService.new(session) - expect(session).to receive(:sign_request).with( - method: :post, - path: '/v5/rwa/stocks/convert/submit', - body: { - convertType: 'MINT', - symbol: 'symbol-value', - inputAmount: 'input_amount-value', - frontMultiplier: 'front_multiplier-value', - accountType: 'all', - requestId: 'request_id-value', - contractAddr: 'contract_addr-value', - flow: 'CEX', - burnScene: 'DEP' - } - ) - service.submit_convert( - convert_type: 'MINT', - symbol: 'symbol-value', - input_amount: 'input_amount-value', - front_multiplier: 'front_multiplier-value', - account_type: 'all', - request_id: 'request_id-value', - contract_addr: 'contract_addr-value', - flow: 'CEX', - burn_scene: 'DEP' - ) - end - - # endpoint: POST /v5/rwa/stocks/order - it 'dispatches this generated endpoint' do - session = instance_double(Bybit::Session) - service = Bybit::RestApi::StocksService.new(session) - expect(session).to receive(:sign_request).with( - method: :post, - path: '/v5/rwa/stocks/order', - body: { - symbol: 'symbol-value', - quoteToken: 'USDC', - side: 'BUY', - type: 'MARKET', - qty: 'qty-value', - notional: 'notional-value', - limitPrice: 'limit_price-value', - stopPrice: 'stop_price-value', - timeInForce: 'DAY', - tradingSession: 'RTH', - tokenize: true, - orderTime: 1, - requestId: 'request_id-value' - } - ) - service.place_order( - symbol: 'symbol-value', - quote_token: 'USDC', - side: 'BUY', - type: 'MARKET', - qty: 'qty-value', - notional: 'notional-value', - limit_price: 'limit_price-value', - stop_price: 'stop_price-value', - time_in_force: 'DAY', - trading_session: 'RTH', - tokenize: true, - order_time: 1, - request_id: 'request_id-value' - ) - end - - # endpoint: POST /v5/rwa/stocks/order/cancel - it 'dispatches this generated endpoint' do - session = instance_double(Bybit::Session) - service = Bybit::RestApi::StocksService.new(session) - expect(session).to receive(:sign_request).with( - method: :post, - path: '/v5/rwa/stocks/order/cancel', - body: { orderNo: 'order_no-value' } - ) - service.cancel_order(order_no: 'order_no-value') - end - # endpoint: POST /v5/spot-margin-trade/fixedborrow-order-cancel it 'dispatches this generated endpoint' do session = instance_double(Bybit::Session) diff --git a/spec/services/alpha_service_spec.rb b/spec/services/alpha_service_spec.rb new file mode 100644 index 0000000..35ac111 --- /dev/null +++ b/spec/services/alpha_service_spec.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +RSpec.describe Bybit::RestApi::AlphaService do + let(:session) { instance_double(Bybit::Session) } + let(:service) { described_class.new(session) } + + describe '#get_prediction_portfolio_summary' do + it 'camelizes optional filters in the request body' do + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/portfolio-summary', + body: { eventType: 1 } + ) + + service.get_prediction_portfolio_summary(event_type: 1) + end + end + + describe '#get_prediction_group_stage_detail' do + it 'sends the event type and optional group name' do + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/sports/group-stage-detail', + body: { eventType: 1, groupName: 'A' } + ) + + service.get_prediction_group_stage_detail(event_type: 1, group_name: 'A') + end + end + + describe '#get_prediction_match_list' do + it 'camelizes all optional filters in the request body' do + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/sports/match-list', + body: { + eventType: 1, + status: 1, + startTime: 1, + endTime: 2, + stageCode: 'GROUP', + limit: 10, + pageIndex: 1 + } + ) + + service.get_prediction_match_list( + event_type: 1, + status: 1, + start_time: 1, + end_time: 2, + stage_code: 'GROUP', + limit: 10, + page_index: 1 + ) + end + end + + describe '#get_prediction_timeline_stages' do + it 'requires and sends the event type' do + expect(session).to receive(:sign_request).with( + method: :get, + path: '/v5/alpha/prediction/sports/timeline-stages', + params: { eventType: 1 } + ) + + service.get_prediction_timeline_stages(event_type: 1) + end + + it 'rejects a request without an event type before dispatch' do + expect(session).not_to receive(:sign_request) + + expect { service.get_prediction_timeline_stages }.to raise_error(ArgumentError) + end + end + + describe '#get_prediction_price_history' do + it 'requires and sends one token ID and the interval' do + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/price-history', + body: { tokenId: 'token-id', interval: '1h' } + ) + + service.get_prediction_price_history(token_id: 'token-id', interval: '1h') + end + + it 'rejects a request without a token ID before dispatch' do + expect(session).not_to receive(:sign_request) + + expect { service.get_prediction_price_history(interval: '1h') }.to raise_error(ArgumentError) + end + end +end From 11b23961a1f41ef346a867bc9e023365cdf6b7fd Mon Sep 17 00:00:00 2001 From: "johnny.wang" Date: Fri, 6 Nov 2026 15:02:45 +0700 Subject: [PATCH 5/5] fix: send prediction side market event ID and filters --- CHANGELOG.md | 3 +++ lib/bybit/rest_api/alpha_service.rb | 10 +++++++--- spec/generated/rest_api_generated_spec.rb | 4 ++-- spec/services/alpha_service_spec.rb | 24 +++++++++++++++++++++++ 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38423d1..4c50a27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,6 +89,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `StrategyService#query_order_list(...)` - `StrategyService#stop_strategy(...)` +### Fixed +- `AlphaService#get_prediction_side_market_list(...)` now requires `event_id` and accepts the documented filters and pagination options. + ### Sources - OpenAPI: `705f49bf6dba27ecc5b9b402f46ab2423cfb5dd9` - Docs: `9cde0843c270dd1e6009fb4593272f43f60cccf0` diff --git a/lib/bybit/rest_api/alpha_service.rb b/lib/bybit/rest_api/alpha_service.rb index 1c624d4..526a2b0 100644 --- a/lib/bybit/rest_api/alpha_service.rb +++ b/lib/bybit/rest_api/alpha_service.rb @@ -297,11 +297,15 @@ def execute_prediction_sell(token_id:, size:, order_type:, slippage:, event_id:, # # POST /v5/alpha/prediction/side-market-list # - # @param event_type [String] + # @param event_id [String] Event ID to query markets for. + # @option kwargs [String] :sort_by Sort by volume, liquidity, or endDate. + # @option kwargs [Integer] :market_type Filter by market type. + # @option kwargs [Integer] :limit Number of records per page. + # @option kwargs [Integer] :page_index Page number starting from 1. # @return [Hash] Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). # @see https://bybit-exchange.github.io/docs/v5/alpha/prediction/side-market-list - def get_prediction_side_market_list(event_type:) - params = Bybit::Utils::WireKeys.camelize({ eventType: event_type }) + def get_prediction_side_market_list(event_id:, **kwargs) + params = Bybit::Utils::WireKeys.camelize(kwargs.merge(eventId: event_id)) @session.sign_request(method: :post, path: '/v5/alpha/prediction/side-market-list', body: params) end diff --git a/spec/generated/rest_api_generated_spec.rb b/spec/generated/rest_api_generated_spec.rb index 4ae8a85..0d3fbb4 100644 --- a/spec/generated/rest_api_generated_spec.rb +++ b/spec/generated/rest_api_generated_spec.rb @@ -930,9 +930,9 @@ expect(session).to receive(:sign_request).with( method: :post, path: '/v5/alpha/prediction/side-market-list', - body: { eventType: 'event_type-value' } + body: { eventId: 'event_id-value' } ) - service.get_prediction_side_market_list(event_type: 'event_type-value') + service.get_prediction_side_market_list(event_id: 'event_id-value') end # endpoint: POST /v5/alpha/prediction/sports/group-stage-detail diff --git a/spec/services/alpha_service_spec.rb b/spec/services/alpha_service_spec.rb index 35ac111..f569fdc 100644 --- a/spec/services/alpha_service_spec.rb +++ b/spec/services/alpha_service_spec.rb @@ -4,6 +4,30 @@ let(:session) { instance_double(Bybit::Session) } let(:service) { described_class.new(session) } + describe '#get_prediction_side_market_list' do + it 'sends the event ID and camelizes optional filters' do + expect(session).to receive(:sign_request).with( + method: :post, + path: '/v5/alpha/prediction/side-market-list', + body: { eventId: 'event-id', sortBy: 'volume', marketType: 1, limit: 20, pageIndex: 1 } + ) + + service.get_prediction_side_market_list( + event_id: 'event-id', + sort_by: 'volume', + market_type: 1, + limit: 20, + page_index: 1 + ) + end + + it 'rejects a request without an event ID before dispatch' do + expect(session).not_to receive(:sign_request) + + expect { service.get_prediction_side_market_list }.to raise_error(ArgumentError) + end + end + describe '#get_prediction_portfolio_summary' do it 'camelizes optional filters in the request body' do expect(session).to receive(:sign_request).with(