iflow-mcp_dlwjdtn535-mcp-bybit-server 0.1.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- __init__.py +0 -0
- config.py +23 -0
- iflow_mcp_dlwjdtn535_mcp_bybit_server-0.1.4.dist-info/METADATA +246 -0
- iflow_mcp_dlwjdtn535_mcp_bybit_server-0.1.4.dist-info/RECORD +9 -0
- iflow_mcp_dlwjdtn535_mcp_bybit_server-0.1.4.dist-info/WHEEL +4 -0
- iflow_mcp_dlwjdtn535_mcp_bybit_server-0.1.4.dist-info/entry_points.txt +2 -0
- iflow_mcp_dlwjdtn535_mcp_bybit_server-0.1.4.dist-info/licenses/LICENSE +21 -0
- server.py +683 -0
- service.py +531 -0
service.py
ADDED
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Dict, Optional
|
|
3
|
+
from pybit.unified_trading import HTTP
|
|
4
|
+
|
|
5
|
+
from config import Config
|
|
6
|
+
# import pandas as pd # Removed as it was only used for talib
|
|
7
|
+
# from talib import abstract # Removed as talib is no longer used
|
|
8
|
+
|
|
9
|
+
# Logging configuration
|
|
10
|
+
logging.basicConfig(
|
|
11
|
+
level=logging.INFO,
|
|
12
|
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
13
|
+
datefmt='%Y-%m-%d %H:%M:%S'
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BybitService:
|
|
20
|
+
"""A wrapper class for interacting with the Bybit Unified Trading API.
|
|
21
|
+
|
|
22
|
+
Provides methods to call various Bybit API v5 endpoints for market data,
|
|
23
|
+
account management, and order execution.
|
|
24
|
+
Handles initialization of the pybit HTTP client.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self):
|
|
28
|
+
"""
|
|
29
|
+
Initialize BybitService
|
|
30
|
+
"""
|
|
31
|
+
logger.info(f"Initializing Bybit Service - Testnet: {Config.TESTNET}, API Key: {Config.ACCESS_KEY}")
|
|
32
|
+
self.client = HTTP(
|
|
33
|
+
testnet=Config.TESTNET,
|
|
34
|
+
api_key=Config.ACCESS_KEY,
|
|
35
|
+
api_secret=Config.SECRET_KEY
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Market data related methods
|
|
39
|
+
def get_orderbook(self, category: str, symbol: str, limit: int = 50) -> Dict:
|
|
40
|
+
"""
|
|
41
|
+
Get orderbook data
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
category (str): Category (spot, linear, inverse, etc.)
|
|
45
|
+
symbol (str): Symbol (e.g., BTCUSDT)
|
|
46
|
+
limit (int): Number of orderbook entries to retrieve
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Dict: Orderbook data
|
|
50
|
+
"""
|
|
51
|
+
return self.client.get_orderbook(
|
|
52
|
+
category=category,
|
|
53
|
+
symbol=symbol,
|
|
54
|
+
limit=limit
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
def get_kline(self, category: str, symbol: str, interval: str,
|
|
58
|
+
start: Optional[int] = None, end: Optional[int] = None,
|
|
59
|
+
limit: int = 200) -> Dict:
|
|
60
|
+
"""
|
|
61
|
+
Get K-line data
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
category: Category (spot, linear, inverse, etc.)
|
|
65
|
+
symbol: Symbol (e.g., BTCUSDT)
|
|
66
|
+
interval: Time interval (1, 3, 5, 15, 30, 60, 120, 240, 360, 720, D, W, M)
|
|
67
|
+
start: Start time (millisecond timestamp)
|
|
68
|
+
end: End time (millisecond timestamp)
|
|
69
|
+
limit: Number of records to retrieve
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
Dict: K-line data
|
|
73
|
+
"""
|
|
74
|
+
try:
|
|
75
|
+
params = {
|
|
76
|
+
"category": category,
|
|
77
|
+
"symbol": symbol,
|
|
78
|
+
"interval": interval,
|
|
79
|
+
"limit": limit
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if start:
|
|
83
|
+
params["start"] = start
|
|
84
|
+
if end:
|
|
85
|
+
params["end"] = end
|
|
86
|
+
|
|
87
|
+
response = self.client.get_kline(**params)
|
|
88
|
+
return response
|
|
89
|
+
|
|
90
|
+
except Exception as e:
|
|
91
|
+
logger.error(f"Failed to get K-line data: {str(e)}")
|
|
92
|
+
return {"error": str(e)}
|
|
93
|
+
|
|
94
|
+
def get_tickers(self, category: str, symbol: str) -> Dict:
|
|
95
|
+
"""
|
|
96
|
+
Get ticker information
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
category (str): Category (spot, linear, inverse, etc.)
|
|
100
|
+
symbol (str): Symbol (e.g., BTCUSDT)
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Dict: Ticker information
|
|
104
|
+
"""
|
|
105
|
+
return self.client.get_tickers(
|
|
106
|
+
category=category,
|
|
107
|
+
symbol=symbol
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# Account related methods
|
|
111
|
+
def get_wallet_balance(self, accountType: str, coin: Optional[str] = None) -> Dict:
|
|
112
|
+
"""
|
|
113
|
+
Get wallet balance
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
accountType (str): Account type (UNIFIED, CONTRACT, SPOT)
|
|
117
|
+
coin (Optional[str]): Coin symbol
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
Dict: Wallet balance information
|
|
121
|
+
"""
|
|
122
|
+
return self.client.get_wallet_balance(
|
|
123
|
+
accountType=accountType,
|
|
124
|
+
coin=coin
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def get_positions(self, category: str, symbol: Optional[str] = None) -> Dict:
|
|
128
|
+
"""
|
|
129
|
+
Get position information
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
category (str): Category (spot, linear, inverse, etc.)
|
|
133
|
+
symbol (Optional[str]): Symbol (e.g., BTCUSDT)
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
Dict: Position information
|
|
137
|
+
"""
|
|
138
|
+
return self.client.get_positions(
|
|
139
|
+
category=category,
|
|
140
|
+
symbol=symbol
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Order related methods
|
|
144
|
+
def place_order(self, category: str, symbol: str, side: str, orderType: str,
|
|
145
|
+
qty: str, price: Optional[str] = None,
|
|
146
|
+
timeInForce: Optional[str] = None, orderLinkId: Optional[str] = None,
|
|
147
|
+
isLeverage: Optional[int] = None, orderFilter: Optional[str] = None,
|
|
148
|
+
triggerPrice: Optional[str] = None, triggerBy: Optional[str] = None,
|
|
149
|
+
orderIv: Optional[str] = None, positionIdx: Optional[int] = None,
|
|
150
|
+
takeProfit: Optional[str] = None, stopLoss: Optional[str] = None,
|
|
151
|
+
tpTriggerBy: Optional[str] = None, slTriggerBy: Optional[str] = None,
|
|
152
|
+
tpLimitPrice: Optional[str] = None, slLimitPrice: Optional[str] = None,
|
|
153
|
+
tpOrderType: Optional[str] = None, slOrderType: Optional[str] = None) -> Dict:
|
|
154
|
+
"""
|
|
155
|
+
Execute order
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
category (str): Category
|
|
159
|
+
- spot: Spot trading
|
|
160
|
+
* Minimum order quantity: 0.000011 BTC (up to 6 decimal places)
|
|
161
|
+
* Minimum order amount: 5 USDT
|
|
162
|
+
* If buying at market price, qty should be input in USDT units (e.g., "10" = 10 USDT)
|
|
163
|
+
* If selling at market price, qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC)
|
|
164
|
+
* If placing a limit order, qty should be input in BTC units
|
|
165
|
+
* positionIdx is not used
|
|
166
|
+
- linear: Futures trading (USDT margin)
|
|
167
|
+
* positionIdx is required (1: Long, 2: Short)
|
|
168
|
+
- inverse: Futures trading (coin margin)
|
|
169
|
+
* positionIdx is required (1: Long, 2: Short)
|
|
170
|
+
symbol (str): Symbol (e.g., BTCUSDT)
|
|
171
|
+
side (str): Order direction (Buy, Sell)
|
|
172
|
+
orderType (str): Order type (Market, Limit)
|
|
173
|
+
qty (str): Order quantity
|
|
174
|
+
- Market Buy: qty should be input in USDT units (e.g., "10" = 10 USDT)
|
|
175
|
+
- Market Sell: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC, up to 6 decimal places)
|
|
176
|
+
- Limit: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC, up to 6 decimal places)
|
|
177
|
+
price (Optional[str]): Order price (for limit order)
|
|
178
|
+
timeInForce (Optional[str]): Order validity period
|
|
179
|
+
- GTC: Good Till Cancel (default, for limit order)
|
|
180
|
+
- IOC: Immediate or Cancel (market order)
|
|
181
|
+
- FOK: Fill or Kill
|
|
182
|
+
- PostOnly: Post Only
|
|
183
|
+
orderLinkId (Optional[str]): Order link ID (unique value)
|
|
184
|
+
isLeverage (Optional[int]): Use leverage (0: No use, 1: Use)
|
|
185
|
+
orderFilter (Optional[str]): Order filter
|
|
186
|
+
- Order: General order (default)
|
|
187
|
+
- tpslOrder: TP/SL order
|
|
188
|
+
- StopOrder: Stop order
|
|
189
|
+
triggerPrice (Optional[str]): Trigger price
|
|
190
|
+
triggerBy (Optional[str]): Trigger basis
|
|
191
|
+
orderIv (Optional[str]): Order volatility
|
|
192
|
+
positionIdx (Optional[int]): Position index
|
|
193
|
+
- Required for futures (linear/inverse) trading
|
|
194
|
+
- 1: Long position
|
|
195
|
+
- 2: Short position
|
|
196
|
+
- positionIdx is not used for spot trading
|
|
197
|
+
takeProfit (Optional[str]): Take profit price
|
|
198
|
+
stopLoss (Optional[str]): Stop loss price
|
|
199
|
+
tpTriggerBy (Optional[str]): Take profit trigger basis
|
|
200
|
+
slTriggerBy (Optional[str]): Stop loss trigger basis
|
|
201
|
+
tpLimitPrice (Optional[str]): Take profit limit price
|
|
202
|
+
slLimitPrice (Optional[str]): Stop loss limit price
|
|
203
|
+
tpOrderType (Optional[str]): Take profit order type (Market, Limit)
|
|
204
|
+
slOrderType (Optional[str]): Stop loss order type (Market, Limit)
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
Dict: Order result
|
|
208
|
+
|
|
209
|
+
Example:
|
|
210
|
+
# Spot trading (SPOT account balance required)
|
|
211
|
+
place_order("spot", "BTCUSDT", "Buy", "Market", "10") # Buy market price for 10 USDT
|
|
212
|
+
place_order("spot", "BTCUSDT", "Sell", "Market", "0.000100") # Sell market price for 0.0001 BTC
|
|
213
|
+
place_order("spot", "BTCUSDT", "Buy", "Limit", "0.000100", price="50000") # Buy limit order for 0.0001 BTC
|
|
214
|
+
|
|
215
|
+
# Spot trading - limit order + TP/SL
|
|
216
|
+
place_order("spot", "BTCUSDT", "Buy", "Limit", "0.000100", price="50000",
|
|
217
|
+
takeProfit="55000", stopLoss="45000", # TP/SL setting
|
|
218
|
+
tpOrderType="Market", slOrderType="Market") # Execute TP/SL as market order
|
|
219
|
+
|
|
220
|
+
# Futures trading
|
|
221
|
+
place_order("linear", "BTCUSDT", "Buy", "Market", "0.001", positionIdx=1) # Buy market price for long position
|
|
222
|
+
place_order("linear", "BTCUSDT", "Sell", "Market", "0.001", positionIdx=2) # Sell market price for short position
|
|
223
|
+
|
|
224
|
+
Notes:
|
|
225
|
+
1. Spot trading order quantity restrictions:
|
|
226
|
+
- Minimum order quantity: 0.000011 BTC
|
|
227
|
+
- Minimum order amount: 5 USDT
|
|
228
|
+
- BTC quantity is only allowed up to 6 decimal places (e.g., 0.000100 O, 0.0001234 X)
|
|
229
|
+
2. Pay attention to unit when buying/selling at market price:
|
|
230
|
+
- Buying: qty should be input in USDT units (e.g., "10" = 10 USDT)
|
|
231
|
+
- Selling: qty should be input in BTC units (e.g., "0.000100" = 0.0001 BTC)
|
|
232
|
+
3. Futures trading requires positionIdx:
|
|
233
|
+
- Long position: positionIdx=1
|
|
234
|
+
- Short position: positionIdx=2
|
|
235
|
+
4. positionIdx is not used for spot trading
|
|
236
|
+
|
|
237
|
+
Reference site:
|
|
238
|
+
https://bybit-exchange.github.io/docs/v5/order/create-order
|
|
239
|
+
"""
|
|
240
|
+
try:
|
|
241
|
+
# Default settings
|
|
242
|
+
if timeInForce is None:
|
|
243
|
+
timeInForce = "IOC" if orderType == "Market" else "GTC"
|
|
244
|
+
if orderFilter is None:
|
|
245
|
+
orderFilter = "Order"
|
|
246
|
+
if isLeverage is None:
|
|
247
|
+
isLeverage = 0
|
|
248
|
+
|
|
249
|
+
# Check positionIdx for futures trading
|
|
250
|
+
if category in ["linear", "inverse"]:
|
|
251
|
+
if not positionIdx or positionIdx not in ["1", "2"]:
|
|
252
|
+
return {"error": "positionIdx is required for futures trading (1: Long position, 2: Short position)"}
|
|
253
|
+
|
|
254
|
+
# Ignore positionIdx for spot trading
|
|
255
|
+
if category == "spot":
|
|
256
|
+
positionIdx = None
|
|
257
|
+
|
|
258
|
+
# Prepare request data
|
|
259
|
+
request_data = {
|
|
260
|
+
"category": category,
|
|
261
|
+
"symbol": symbol,
|
|
262
|
+
"side": side,
|
|
263
|
+
"orderType": orderType,
|
|
264
|
+
"qty": qty,
|
|
265
|
+
"timeInForce": timeInForce,
|
|
266
|
+
"orderFilter": orderFilter,
|
|
267
|
+
"isLeverage": isLeverage
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
# Add optional parameters
|
|
271
|
+
if price is not None:
|
|
272
|
+
request_data["price"] = price
|
|
273
|
+
if orderLinkId is not None:
|
|
274
|
+
request_data["orderLinkId"] = orderLinkId
|
|
275
|
+
if triggerPrice is not None:
|
|
276
|
+
request_data["triggerPrice"] = triggerPrice
|
|
277
|
+
if triggerBy is not None:
|
|
278
|
+
request_data["triggerBy"] = triggerBy
|
|
279
|
+
if orderIv is not None:
|
|
280
|
+
request_data["orderIv"] = orderIv
|
|
281
|
+
if positionIdx is not None:
|
|
282
|
+
request_data["positionIdx"] = positionIdx
|
|
283
|
+
if takeProfit is not None:
|
|
284
|
+
request_data["takeProfit"] = takeProfit
|
|
285
|
+
if stopLoss is not None:
|
|
286
|
+
request_data["stopLoss"] = stopLoss
|
|
287
|
+
if tpTriggerBy is not None:
|
|
288
|
+
request_data["tpTriggerBy"] = tpTriggerBy
|
|
289
|
+
if slTriggerBy is not None:
|
|
290
|
+
request_data["slTriggerBy"] = slTriggerBy
|
|
291
|
+
if tpLimitPrice is not None:
|
|
292
|
+
request_data["tpLimitPrice"] = tpLimitPrice
|
|
293
|
+
if slLimitPrice is not None:
|
|
294
|
+
request_data["slLimitPrice"] = slLimitPrice
|
|
295
|
+
if tpOrderType is not None:
|
|
296
|
+
request_data["tpOrderType"] = tpOrderType
|
|
297
|
+
if slOrderType is not None:
|
|
298
|
+
request_data["slOrderType"] = slOrderType
|
|
299
|
+
|
|
300
|
+
# Execute order
|
|
301
|
+
result = self.client.place_order(**request_data)
|
|
302
|
+
|
|
303
|
+
# Check minimum order quantity/amount
|
|
304
|
+
if isinstance(result, dict) and "error" in result:
|
|
305
|
+
if "min_qty" in result and "min_amt" in result:
|
|
306
|
+
# Minimum order quantity/amount verification failed
|
|
307
|
+
logger.error(f"Order execution failed: {result['error']}")
|
|
308
|
+
return {
|
|
309
|
+
"error": f"{result['error']} (Minimum order quantity: {result['min_qty']} {symbol.replace('USDT', '')}, Minimum order amount: {result['min_amt']} USDT)"
|
|
310
|
+
}
|
|
311
|
+
else:
|
|
312
|
+
logger.error(f"Order execution failed: {result['error']}")
|
|
313
|
+
return {"error": result['error']}
|
|
314
|
+
elif result.get("retCode") != 0:
|
|
315
|
+
logger.error(f"Order execution failed: {result.get('retMsg')}")
|
|
316
|
+
return {"error": result.get("retMsg")}
|
|
317
|
+
return result
|
|
318
|
+
except Exception as e:
|
|
319
|
+
logger.error(f"Order execution failed: {e}", exc_info=True)
|
|
320
|
+
return {"error": str(e)}
|
|
321
|
+
|
|
322
|
+
def cancel_order(self, category: str, symbol: str, orderId: Optional[str] = None,
|
|
323
|
+
orderLinkId: Optional[str] = None, orderFilter: Optional[str] = None) -> Dict:
|
|
324
|
+
"""
|
|
325
|
+
Cancel order
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
category (str): Category (spot, linear, inverse, etc.)
|
|
329
|
+
symbol (str): Symbol (e.g., BTCUSDT)
|
|
330
|
+
orderId (Optional[str]): Order ID
|
|
331
|
+
orderLinkId (Optional[str]): Order link ID
|
|
332
|
+
orderFilter (Optional[str]): Order filter
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
Dict: Cancel result
|
|
336
|
+
"""
|
|
337
|
+
return self.client.cancel_order(
|
|
338
|
+
category=category,
|
|
339
|
+
symbol=symbol,
|
|
340
|
+
orderId=orderId,
|
|
341
|
+
orderLinkId=orderLinkId,
|
|
342
|
+
orderFilter=orderFilter
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
def get_order_history(self, category: str, symbol: Optional[str] = None,
|
|
346
|
+
orderId: Optional[str] = None, orderLinkId: Optional[str] = None,
|
|
347
|
+
orderFilter: Optional[str] = None, orderStatus: Optional[str] = None,
|
|
348
|
+
startTime: Optional[int] = None, endTime: Optional[int] = None,
|
|
349
|
+
limit: int = 50) -> Dict:
|
|
350
|
+
"""
|
|
351
|
+
Get order history
|
|
352
|
+
|
|
353
|
+
Args:
|
|
354
|
+
category (str): Category (spot, linear, inverse, etc.)
|
|
355
|
+
symbol (Optional[str]): Symbol (e.g., BTCUSDT)
|
|
356
|
+
orderId (Optional[str]): Order ID
|
|
357
|
+
orderLinkId (Optional[str]): Order link ID
|
|
358
|
+
orderFilter (Optional[str]): Order filter
|
|
359
|
+
orderStatus (Optional[str]): Order status
|
|
360
|
+
startTime (Optional[int]): Start time in milliseconds
|
|
361
|
+
endTime (Optional[int]): End time in milliseconds
|
|
362
|
+
limit (int): Number of orders to retrieve
|
|
363
|
+
|
|
364
|
+
Returns:
|
|
365
|
+
Dict: Order history
|
|
366
|
+
"""
|
|
367
|
+
return self.client.get_order_history(
|
|
368
|
+
category=category,
|
|
369
|
+
symbol=symbol,
|
|
370
|
+
orderId=orderId,
|
|
371
|
+
orderLinkId=orderLinkId,
|
|
372
|
+
orderFilter=orderFilter,
|
|
373
|
+
orderStatus=orderStatus,
|
|
374
|
+
startTime=startTime,
|
|
375
|
+
endTime=endTime,
|
|
376
|
+
limit=limit
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
def get_open_orders(self, category: str, symbol: Optional[str] = None,
|
|
380
|
+
orderId: Optional[str] = None, orderLinkId: Optional[str] = None,
|
|
381
|
+
orderFilter: Optional[str] = None, limit: int = 50) -> Dict:
|
|
382
|
+
"""
|
|
383
|
+
Get open orders
|
|
384
|
+
|
|
385
|
+
Args:
|
|
386
|
+
category (str): Category (spot, linear, inverse, etc.)
|
|
387
|
+
symbol (Optional[str]): Symbol (e.g., BTCUSDT)
|
|
388
|
+
orderId (Optional[str]): Order ID
|
|
389
|
+
orderLinkId (Optional[str]): Order link ID
|
|
390
|
+
orderFilter (Optional[str]): Order filter
|
|
391
|
+
limit (int): Number of orders to retrieve
|
|
392
|
+
|
|
393
|
+
Returns:
|
|
394
|
+
Dict: Open orders
|
|
395
|
+
"""
|
|
396
|
+
return self.client.get_open_orders(
|
|
397
|
+
category=category,
|
|
398
|
+
symbol=symbol,
|
|
399
|
+
orderId=orderId,
|
|
400
|
+
orderLinkId=orderLinkId,
|
|
401
|
+
orderFilter=orderFilter,
|
|
402
|
+
limit=limit
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
# Leverage related methods
|
|
406
|
+
def set_leverage(self, category: str, symbol: str, buyLeverage: str,
|
|
407
|
+
sellLeverage: str) -> Dict:
|
|
408
|
+
"""
|
|
409
|
+
Set leverage
|
|
410
|
+
|
|
411
|
+
Args:
|
|
412
|
+
category (str): Category (spot, linear, inverse, etc.)
|
|
413
|
+
symbol (str): Symbol (e.g., BTCUSDT)
|
|
414
|
+
buyLeverage (str): Buy leverage
|
|
415
|
+
sellLeverage (str): Sell leverage
|
|
416
|
+
|
|
417
|
+
Returns:
|
|
418
|
+
Dict: Setting result
|
|
419
|
+
"""
|
|
420
|
+
return self.client.set_leverage(
|
|
421
|
+
category=category,
|
|
422
|
+
symbol=symbol,
|
|
423
|
+
buyLeverage=buyLeverage,
|
|
424
|
+
sellLeverage=sellLeverage
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
def set_trading_stop(self, category: str, symbol: str,
|
|
428
|
+
takeProfit: Optional[str] = None,
|
|
429
|
+
stopLoss: Optional[str] = None,
|
|
430
|
+
trailingStop: Optional[str] = None,
|
|
431
|
+
positionIdx: Optional[int] = None) -> Dict:
|
|
432
|
+
"""
|
|
433
|
+
Set trading stop
|
|
434
|
+
|
|
435
|
+
Args:
|
|
436
|
+
category (str): Category (spot, linear, inverse, etc.)
|
|
437
|
+
symbol (str): Symbol (e.g., BTCUSDT)
|
|
438
|
+
takeProfit (Optional[str]): Take profit price
|
|
439
|
+
stopLoss (Optional[str]): Stop loss price
|
|
440
|
+
trailingStop (Optional[str]): Trailing stop
|
|
441
|
+
positionIdx (Optional[int]): Position index
|
|
442
|
+
|
|
443
|
+
Returns:
|
|
444
|
+
Dict: Setting result
|
|
445
|
+
"""
|
|
446
|
+
return self.client.set_trading_stop(
|
|
447
|
+
category=category,
|
|
448
|
+
symbol=symbol,
|
|
449
|
+
takeProfit=takeProfit,
|
|
450
|
+
stopLoss=stopLoss,
|
|
451
|
+
trailingStop=trailingStop,
|
|
452
|
+
positionIdx=positionIdx
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
def set_margin_mode(self, category: str, symbol: str,
|
|
456
|
+
tradeMode: int, buyLeverage: str,
|
|
457
|
+
sellLeverage: str) -> Dict:
|
|
458
|
+
"""
|
|
459
|
+
Set margin mode
|
|
460
|
+
|
|
461
|
+
Args:
|
|
462
|
+
category (str): Category (spot, linear, inverse, etc.)
|
|
463
|
+
symbol (str): Symbol (e.g., BTCUSDT)
|
|
464
|
+
tradeMode (int): Trading mode (0: Isolated, 1: Cross)
|
|
465
|
+
buyLeverage (str): Buying leverage
|
|
466
|
+
sellLeverage (str): Selling leverage
|
|
467
|
+
|
|
468
|
+
Returns:
|
|
469
|
+
Dict: Setting result
|
|
470
|
+
"""
|
|
471
|
+
return self.client.set_margin_mode(
|
|
472
|
+
category=category,
|
|
473
|
+
symbol=symbol,
|
|
474
|
+
tradeMode=tradeMode,
|
|
475
|
+
buyLeverage=buyLeverage,
|
|
476
|
+
sellLeverage=sellLeverage
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
# Utility methods
|
|
480
|
+
def get_api_key_information(self) -> Dict:
|
|
481
|
+
"""
|
|
482
|
+
Get API key information
|
|
483
|
+
|
|
484
|
+
Returns:
|
|
485
|
+
Dict: API key information
|
|
486
|
+
"""
|
|
487
|
+
return self.client.get_api_key_information()
|
|
488
|
+
|
|
489
|
+
def get_instruments_info(self, category: str, symbol: str,
|
|
490
|
+
status: Optional[str] = None, baseCoin: Optional[str] = None) -> Dict:
|
|
491
|
+
"""
|
|
492
|
+
Get exchange information
|
|
493
|
+
|
|
494
|
+
Args:
|
|
495
|
+
category (str): Category (spot, linear, inverse, etc.)
|
|
496
|
+
symbol (str): Symbol (e.g., BTCUSDT)
|
|
497
|
+
status (Optional[str]): Status
|
|
498
|
+
baseCoin (Optional[str]): Base coin
|
|
499
|
+
|
|
500
|
+
Returns:
|
|
501
|
+
Dict: Exchange information
|
|
502
|
+
"""
|
|
503
|
+
return self.client.get_instruments_info(
|
|
504
|
+
category=category,
|
|
505
|
+
symbol=symbol,
|
|
506
|
+
status=status,
|
|
507
|
+
baseCoin=baseCoin
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
if __name__ == "__main__":
|
|
512
|
+
# Example usage
|
|
513
|
+
bybit_service = BybitService()
|
|
514
|
+
# Example: Get K-line data
|
|
515
|
+
kline_data = bybit_service.get_kline(
|
|
516
|
+
category='spot',
|
|
517
|
+
symbol='BTCUSDT',
|
|
518
|
+
interval='1',
|
|
519
|
+
limit=10
|
|
520
|
+
)
|
|
521
|
+
print("K-line Data:")
|
|
522
|
+
print(kline_data)
|
|
523
|
+
|
|
524
|
+
# Example: Get Orderbook
|
|
525
|
+
# orderbook = bybit_service.get_orderbook(category='spot', symbol='BTCUSDT', limit=5)
|
|
526
|
+
# print("\nOrderbook Data:")
|
|
527
|
+
# print(orderbook)
|
|
528
|
+
|
|
529
|
+
# Removed get_talib_kline example usage
|
|
530
|
+
# data = bybit_service.get_talib_kline(...)
|
|
531
|
+
# print(data)
|