Closed tiagosiebler closed 3 years ago
One way to organize support for the linear API is to introduce a lib/linear-client.js
that's very similar to lib/rest-client.js
except that it uses the endpoints for the linear API when applicable. The main goal would be to break as little existing code as possible, and this shouldn't break anything. index.js
would still export DefaultLogger
, WebsocketClient
, RestClient
, and it would also export a new LinearClient
. It would then be the responsibility of the user of this library to know which client is needed to trade a particular market.
RestClient
called InverseClient
could also be exported by index.js
. That would make the inverse versus linear distinction more clear, and the name RestClient
could be deprecated.lib/rest-client.js
could be renamed lib/inverse-client.js
.You don't have to do it this way, but I just wanted to put some ideas out there. Also, I haven't looked at how other bybit API client libraries try to tackle this problem, but that's probably worth looking into as well.
Thanks for the ideas @beppu! These are definitely helpful and I definitely share some of these thoughts too. Adding a LinearClient without introducing breaking changes into the current clients seems the most logical step to get this done.
While we're adding support for another subset of APIs I do wonder whether this is an opportunity to introduce a v2 client.
One of the python libraries (pybit, I think?) handles the selection of the correct API automatically depending on the params used. I don't want to affect existing implementations, so I'd like to avoid breaking changes in rest-client for as long as constructively possible (although we can add a deprecation warning if a successor is ready).
That still brings an architectural question though in how we organise this, which might bring us to your idea of LinearClient
vs InverseClient
again...
Even if we have a singular "RestClientV2" it could wrap around both of these, automatically deciding which to use. It would keep things organised, allow implementation of a singular client if desired, but also allow "lazy" use of the 2-in-1 V2 client, which can automatically decide which to use.
I've edited the post to summarise the ideas so far. I think I'm leaning towards (4), which is essentially in line with your thoughts although we try to avoid breaking changes in the existing rest-client
. Linear-only users could then specifically only require the linear part, or they could use RestClientV2
without worrying about the details on how a client is chosen (and the underlying logic passes calls to the LinearClient
as needed).
When you proposed (3), I started imagining something like (4) as well, so I'm glad you arrived at a similar idea on your own. The only thing I would advise against is having rest-client.js
wrap inverse-client.js
or vice versa. To solve the problem of not duplicating code for the shared endpoints, I would introduce another new file called shared-endpoints.js
. This file would export an object that contained the methods for those shared endpoints. Then I would have both InverseClient
and LinearClient
mix in SharedEndpoints
.
const SharedEndpoints = require('./shared-endpoints')
class LinearClient {
// only implement methods specific to the linear API
}
class InverseClient {
// only implement methods specific to the inverse API
}
Object.assign(LinearClient.prototype, SharedEndpoints)
Object.assign(InverseClient.prototype, SharedEndpoints)
This would keep the client code sufficiently DRY.
Regarding adding a v2 client that's smart enough to know which market needs which client, I think that's a good idea.
I do agree with your point on wrapping inverse, but overall seems like (4) is the way to go!
I went through the official Bybit API docs, and I mapped out the inverse and linear endpoints. I also isolated the shared endpoints. I noticed you were doing some TypeScript work, and I was wondering if the LinearClient work should be done against that branch instead of master. Anyway, here's the table of endpoints:
method | inverse endpoint | linear endpoint | shared endpoint |
---|---|---|---|
getOrderBook | /v2/public/orderBook/L2 | ||
getKline | /v2/public/kline/list | /public/linear/kline | |
getLatestInformation | /v2/public/tickers | ||
getPublicTradingRecords | /v2/public/trading-records | /public/linear/recent-trading-records | |
getSymbols | /v2/public/symbols | ||
getPublicLiquidations | /v2/public/liq-records | ||
getMarkPriceKline * | /v2/public/mark-price-kline | /public/linear/mark-price-kline | |
getOpenInterest | /v2/public/open-interest | ||
getLatestBigDeal | /v2/public/big-deal | ||
getLongShortRatio | /v2/public/account-ratio | ||
placeActiveOrder | /v2/private/order/create | /private/linear/order/create | |
getActiveOrder | /v2/private/order/list | /private/linear/order/list | |
cancelActiveOrder | /v2/private/order/cancel | /private/linear/order/cancel | |
cancelAllActiveOrders | /v2/private/order/cancelAll | /private/linear/order/cancel-all | |
replaceActiveOrder | /v2/private/order/replace | /private/linear/order/replace | |
queryActiveOrder | /v2/private/order | /private/linear/order/search | |
placeConditionalOrder | /v2/private/stop-order/create | /private/linear/stop-order/create | |
getConditionalOrder | /v2/private/stop-order/list | /private/linear/stop-order/list | |
cancelConditionalOrder | /v2/private/stop-order/cancel | /private/linear/stop-order/cancel | |
cancelAllConditionalOrders | /v2/private/stop-order/cancelAll | /private/linear/stop-order/cancel-all | |
replaceConditionalOrder | /v2/private/stop-order/replace | /private/linear/stop-order/replace | |
queryConditionalOrder | /v2/private/stop-order | /private/linear/stop-order/search | |
getPosition | /v2/private/position/list | /private/linear/position/list | |
setAutoAddMargin | /private/linear/position/set-auto-add-margin | ||
switchIsolated | /private/linear/position/switch-isolated | ||
switchMode | /private/linear/tpsl/switch-mode | ||
addMargin | /private/linear/position/add-margin | ||
setLeverage | /private/linear/position/set-leverage | ||
changePositionMargin | /position/change-position-margin | ||
setTradingStop | /open-api/position/trading-stop | /private/linear/position/trading-stop | |
changeUserLeverage | /user/leverage/save | ||
getTradeRecords | /v2/private/execution/list | /private/linear/trade/execution/list | |
getClosedPNL * | /v2/private/trade/closed-pnl/list | /private/linear/trade/closed-pnl/list | |
getRiskLimitList | /open-api/wallet/risk-limit/list | /public/linear/risk-limit | |
setRiskLimit | /open-api/wallet/risk-limit | ||
getLastFundingRate | /open-api/funding/prev-funding-rate | ||
getMyLastFundingFee | /open-api/funding/prev-funding | /private/linear/funding/prev-funding | |
getPredictedFunding | /open-api/funding/predicted-funding | /private/linear/funding/predicted-funding | |
getAPIKeyInfo * | /open-api/api-key | ||
getLCPInfo * | /v2/private/account/lcp | ||
getWalletBalance | /v2/private/wallet/balance | ||
getWalletFundRecords | /open-api/wallet/fund/records | ||
getWithdrawRecords | /open-api/wallet/withdraw/list | ||
getAssetExchangeRecords | /v2/private/exchange-order/list | ||
getServerTime | /v2/public/time | ||
getAnnouncements * | /v2/public/announcement |
Hey @beppu - that's extremely useful! Yes please, I'm looking to get a very basic typescript transition done at first (introducing almost no changes where possible, meaning types will be relatively flexible at first).
If you're happy to start working on this, please base it on the typescript branch. It's up to date, just pending some more sanity checks I want to run on my side as well as some input from bybit's team.
TS Version Update: #75
Resolved with version 2.0.0, see #75
Explore plans to support linear contracts for bybit. The linear APIs may have differences to the inverse APIs, but there should be reusable logic: https://bybit-exchange.github.io/docs/linear/#t-introduction
Proposals
These are in no particular order:
1. Introduce dedicated
linear-client.js
See beppu's post below:
lib/linear-client.js
dedicated to linear contracts, very similar tolib/rest-client.js
.2. Expand existing
rest-client.js
for automatic handling3. Introduce new
rest-clientv2.js
for automatic handlingrest-client
.rest-clientv2.js
. TBC.rest-client
with deprecation warning).4.
inverse-client
vslinear-client
vsrest-clientv2
rest-client
will remain for a while, albeit deprecated.rest-client
(such as endpoints) could be taken from a separate module, to reduce repetition.rest-clientv2
, which works like (3).