ccxt 2.9.11__py2.py3-none-any.whl → 2.9.12__py2.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.
Potentially problematic release.
This version of ccxt might be problematic. Click here for more details.
- ccxt/__init__.py +1 -1
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bybit.py +99 -45
- ccxt/async_support/novadax.py +3 -0
- ccxt/async_support/okx.py +5 -1
- ccxt/base/exchange.py +1 -1
- ccxt/bybit.py +99 -45
- ccxt/novadax.py +3 -0
- ccxt/okx.py +5 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/base/exchange.py +1 -1
- ccxt/pro/binance.py +2 -2
- ccxt/pro/bybit.py +505 -502
- {ccxt-2.9.11.dist-info → ccxt-2.9.12.dist-info}/METADATA +4 -4
- {ccxt-2.9.11.dist-info → ccxt-2.9.12.dist-info}/RECORD +18 -18
- {ccxt-2.9.11.dist-info → ccxt-2.9.12.dist-info}/WHEEL +0 -0
- {ccxt-2.9.11.dist-info → ccxt-2.9.12.dist-info}/top_level.txt +0 -0
ccxt/__init__.py
CHANGED
ccxt/async_support/__init__.py
CHANGED
ccxt/async_support/bybit.py
CHANGED
@@ -1348,7 +1348,7 @@ class bybit(Exchange):
|
|
1348
1348
|
# "baseCoin": "BTC",
|
1349
1349
|
# "quoteCoin": "USDT",
|
1350
1350
|
# "innovation": "0",
|
1351
|
-
# "status": "
|
1351
|
+
# "status": "Trading",
|
1352
1352
|
# "lotSizeFilter": {
|
1353
1353
|
# "basePrecision": "0.000001",
|
1354
1354
|
# "quotePrecision": "0.00000001",
|
@@ -1381,7 +1381,7 @@ class bybit(Exchange):
|
|
1381
1381
|
quote = self.safe_currency_code(quoteId)
|
1382
1382
|
symbol = base + '/' + quote
|
1383
1383
|
status = self.safe_string(market, 'status')
|
1384
|
-
active = (status == '
|
1384
|
+
active = (status == 'Trading')
|
1385
1385
|
lotSizeFilter = self.safe_value(market, 'lotSizeFilter')
|
1386
1386
|
priceFilter = self.safe_value(market, 'priceFilter')
|
1387
1387
|
quotePrecision = self.safe_number(lotSizeFilter, 'quotePrecision')
|
@@ -2388,6 +2388,10 @@ class bybit(Exchange):
|
|
2388
2388
|
marketType = 'contract'
|
2389
2389
|
if market is not None:
|
2390
2390
|
marketType = market['type']
|
2391
|
+
category = self.safe_string(trade, 'category')
|
2392
|
+
if category is not None:
|
2393
|
+
if category == 'spot':
|
2394
|
+
marketType = 'spot'
|
2391
2395
|
market = self.safe_market(marketId, market, None, marketType)
|
2392
2396
|
symbol = market['symbol']
|
2393
2397
|
amountString = self.safe_string_n(trade, ['execQty', 'orderQty', 'size'])
|
@@ -3043,6 +3047,10 @@ class bybit(Exchange):
|
|
3043
3047
|
marketType = 'contract'
|
3044
3048
|
if market is not None:
|
3045
3049
|
marketType = market['type']
|
3050
|
+
category = self.safe_string(order, 'category')
|
3051
|
+
if category is not None:
|
3052
|
+
if category == 'spot':
|
3053
|
+
marketType = 'spot'
|
3046
3054
|
market = self.safe_market(marketId, market, None, marketType)
|
3047
3055
|
symbol = market['symbol']
|
3048
3056
|
timestamp = self.safe_integer(order, 'createdTime')
|
@@ -3240,6 +3248,10 @@ class bybit(Exchange):
|
|
3240
3248
|
async def create_order(self, symbol, type, side, amount, price=None, params={}):
|
3241
3249
|
"""
|
3242
3250
|
create a trade order
|
3251
|
+
see https://bybit-exchange.github.io/docs/v5/order/create-order
|
3252
|
+
see https://bybit-exchange.github.io/docs/spot/trade/place-order
|
3253
|
+
see https://bybit-exchange.github.io/docs/derivatives/unified/place-order
|
3254
|
+
see https://bybit-exchange.github.io/docs/derivatives/contract/place-order
|
3243
3255
|
:param str symbol: unified symbol of the market to create an order in
|
3244
3256
|
:param str type: 'market' or 'limit'
|
3245
3257
|
:param str side: 'buy' or 'sell'
|
@@ -3320,25 +3332,36 @@ class bybit(Exchange):
|
|
3320
3332
|
request['timeInForce'] = 'FOK'
|
3321
3333
|
elif timeInForce == 'ioc':
|
3322
3334
|
request['timeInForce'] = 'IOC'
|
3323
|
-
triggerPrice = self.
|
3324
|
-
|
3325
|
-
|
3326
|
-
|
3327
|
-
|
3328
|
-
|
3329
|
-
|
3330
|
-
|
3331
|
-
|
3335
|
+
triggerPrice = self.safe_number_2(params, 'triggerPrice', 'stopPrice')
|
3336
|
+
stopLossTriggerPrice = self.safe_number(params, 'stopLossPrice', triggerPrice)
|
3337
|
+
takeProfitTriggerPrice = self.safe_number(params, 'takeProfitPrice')
|
3338
|
+
stopLoss = self.safe_number(params, 'stopLoss')
|
3339
|
+
takeProfit = self.safe_number(params, 'takeProfit')
|
3340
|
+
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
3341
|
+
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
3342
|
+
isStopLoss = stopLoss is not None
|
3343
|
+
isTakeProfit = takeProfit is not None
|
3332
3344
|
if triggerPrice is not None:
|
3333
|
-
# logical xor
|
3334
3345
|
isBuy = side == 'buy'
|
3335
|
-
ascending = not isBuy if
|
3346
|
+
ascending = not isBuy if stopLossTriggerPrice else isBuy
|
3336
3347
|
request['triggerDirection'] = 2 if ascending else 1
|
3337
|
-
request['triggerBy'] = 'LastPrice'
|
3338
3348
|
request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
|
3349
|
+
elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
3350
|
+
if isStopLossTriggerOrder:
|
3351
|
+
request['triggerPrice'] = self.price_to_precision(symbol, stopLossTriggerPrice)
|
3352
|
+
request['triggerDirection'] = 2
|
3353
|
+
else:
|
3354
|
+
request['triggerPrice'] = self.price_to_precision(symbol, takeProfitTriggerPrice)
|
3355
|
+
request['triggerDirection'] = 1
|
3356
|
+
request['reduceOnly'] = True
|
3357
|
+
elif isStopLoss or isTakeProfit:
|
3358
|
+
if isStopLoss:
|
3359
|
+
request['stopLoss'] = self.price_to_precision(symbol, stopLoss)
|
3360
|
+
if isTakeProfit:
|
3361
|
+
request['takeProfit'] = self.price_to_precision(symbol, takeProfit)
|
3339
3362
|
if market['spot']:
|
3340
3363
|
# only works for spot market
|
3341
|
-
if triggerPrice is not None or
|
3364
|
+
if triggerPrice is not None or stopLossTriggerPrice is not None or takeProfitTriggerPrice is not None or isStopLoss or isTakeProfit:
|
3342
3365
|
request['orderFilter'] = 'tpslOrder'
|
3343
3366
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
3344
3367
|
if clientOrderId is not None:
|
@@ -3346,7 +3369,7 @@ class bybit(Exchange):
|
|
3346
3369
|
elif market['option']:
|
3347
3370
|
# mandatory field for options
|
3348
3371
|
request['orderLinkId'] = self.uuid16()
|
3349
|
-
params = self.omit(params, ['stopPrice', 'timeInForce', '
|
3372
|
+
params = self.omit(params, ['stopPrice', 'timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId'])
|
3350
3373
|
response = await self.privatePostV5OrderCreate(self.extend(request, params))
|
3351
3374
|
#
|
3352
3375
|
# {
|
@@ -3484,21 +3507,30 @@ class bybit(Exchange):
|
|
3484
3507
|
request['timeInForce'] = 'FillOrKill'
|
3485
3508
|
elif timeInForce == 'ioc':
|
3486
3509
|
request['timeInForce'] = 'ImmediateOrCancel'
|
3487
|
-
triggerPrice = self.
|
3488
|
-
|
3489
|
-
|
3490
|
-
|
3491
|
-
|
3492
|
-
|
3510
|
+
triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
|
3511
|
+
stopLossTriggerPrice = self.safe_number(params, 'stopLossPrice', triggerPrice)
|
3512
|
+
takeProfitTriggerPrice = self.safe_number(params, 'takeProfitPrice')
|
3513
|
+
stopLoss = self.safe_number(params, 'stopLoss')
|
3514
|
+
takeProfit = self.safe_number(params, 'takeProfit')
|
3515
|
+
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
3516
|
+
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
3517
|
+
isStopLoss = stopLoss is not None
|
3518
|
+
isTakeProfit = takeProfit is not None
|
3519
|
+
if isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
3493
3520
|
request['triggerBy'] = 'LastPrice'
|
3494
|
-
triggerAt =
|
3521
|
+
triggerAt = stopLossTriggerPrice if isStopLossTriggerOrder else takeProfitTriggerPrice
|
3495
3522
|
preciseTriggerPrice = self.price_to_precision(symbol, triggerAt)
|
3496
3523
|
request['triggerPrice'] = preciseTriggerPrice
|
3497
3524
|
isBuy = side == 'buy'
|
3498
3525
|
# logical xor
|
3499
|
-
ascending = not isBuy if
|
3526
|
+
ascending = not isBuy if stopLossTriggerPrice else isBuy
|
3500
3527
|
delta = self.number_to_string(market['precision']['price'])
|
3501
3528
|
request['basePrice'] = Precise.string_add(preciseTriggerPrice, delta) if ascending else Precise.string_sub(preciseTriggerPrice, delta)
|
3529
|
+
elif isStopLoss or isTakeProfit:
|
3530
|
+
if isStopLoss:
|
3531
|
+
request['stopLoss'] = self.price_to_precision(symbol, stopLoss)
|
3532
|
+
if isTakeProfit:
|
3533
|
+
request['takeProfit'] = self.price_to_precision(symbol, takeProfit)
|
3502
3534
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
3503
3535
|
if clientOrderId is not None:
|
3504
3536
|
request['orderLinkId'] = clientOrderId
|
@@ -3567,27 +3599,40 @@ class bybit(Exchange):
|
|
3567
3599
|
request['timeInForce'] = 'FillOrKill'
|
3568
3600
|
elif timeInForce == 'ioc':
|
3569
3601
|
request['timeInForce'] = 'ImmediateOrCancel'
|
3570
|
-
triggerPrice = self.
|
3571
|
-
|
3572
|
-
|
3573
|
-
|
3574
|
-
|
3575
|
-
|
3576
|
-
|
3577
|
-
|
3602
|
+
triggerPrice = self.safe_number_2(params, 'triggerPrice', 'stopPrice')
|
3603
|
+
stopLossTriggerPrice = self.safe_number(params, 'stopLossPrice', triggerPrice)
|
3604
|
+
takeProfitTriggerPrice = self.safe_number(params, 'takeProfitPrice')
|
3605
|
+
stopLoss = self.safe_number(params, 'stopLoss')
|
3606
|
+
takeProfit = self.safe_number(params, 'takeProfit')
|
3607
|
+
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
3608
|
+
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
3609
|
+
isStopLoss = stopLoss is not None
|
3610
|
+
isTakeProfit = takeProfit is not None
|
3611
|
+
if triggerPrice:
|
3578
3612
|
isBuy = side == 'buy'
|
3579
|
-
|
3580
|
-
ascending = not isBuy if stopLossPrice else isBuy
|
3613
|
+
ascending = not isBuy if stopLossTriggerPrice else isBuy
|
3581
3614
|
request['triggerDirection'] = 2 if ascending else 1
|
3582
|
-
request['
|
3583
|
-
|
3615
|
+
request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
|
3616
|
+
elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
3617
|
+
if isStopLossTriggerOrder:
|
3618
|
+
request['triggerPrice'] = self.price_to_precision(symbol, stopLossTriggerPrice)
|
3619
|
+
request['triggerDirection'] = 2
|
3620
|
+
else:
|
3621
|
+
request['triggerPrice'] = self.price_to_precision(symbol, takeProfitTriggerPrice)
|
3622
|
+
request['triggerDirection'] = 1
|
3623
|
+
request['reduceOnly'] = True
|
3624
|
+
elif isStopLoss or isTakeProfit:
|
3625
|
+
if isStopLoss:
|
3626
|
+
request['stopLoss'] = self.price_to_precision(symbol, stopLoss)
|
3627
|
+
if isTakeProfit:
|
3628
|
+
request['takeProfit'] = self.price_to_precision(symbol, takeProfit)
|
3584
3629
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
3585
3630
|
if clientOrderId is not None:
|
3586
3631
|
request['orderLinkId'] = clientOrderId
|
3587
3632
|
elif market['option']:
|
3588
3633
|
# mandatory field for options
|
3589
3634
|
request['orderLinkId'] = self.uuid16()
|
3590
|
-
params = self.omit(params, ['stopPrice', 'timeInForce', '
|
3635
|
+
params = self.omit(params, ['stopPrice', 'timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId'])
|
3591
3636
|
response = await self.privatePostContractV3PrivateOrderCreate(self.extend(request, params))
|
3592
3637
|
#
|
3593
3638
|
# {
|
@@ -3648,20 +3693,29 @@ class bybit(Exchange):
|
|
3648
3693
|
elif timeInForce == 'ioc':
|
3649
3694
|
request['time_in_force'] = 'ImmediateOrCancel'
|
3650
3695
|
if market['swap']:
|
3651
|
-
triggerPrice = self.
|
3652
|
-
|
3653
|
-
|
3654
|
-
|
3655
|
-
|
3656
|
-
|
3696
|
+
triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
|
3697
|
+
stopLossTriggerPrice = self.safe_number(params, 'stopLossPrice', triggerPrice)
|
3698
|
+
takeProfitTriggerPrice = self.safe_number(params, 'takeProfitPrice')
|
3699
|
+
stopLoss = self.safe_number(params, 'stopLoss')
|
3700
|
+
takeProfit = self.safe_number(params, 'takeProfit')
|
3701
|
+
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
3702
|
+
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
3703
|
+
isStopLoss = stopLoss is not None
|
3704
|
+
isTakeProfit = takeProfit is not None
|
3705
|
+
isStopOrder = isStopLossTriggerOrder or isTakeProfitTriggerOrder
|
3657
3706
|
if isStopOrder:
|
3658
3707
|
request['orderFilter'] = 'StopOrder'
|
3659
3708
|
request['trigger_by'] = 'LastPrice'
|
3660
|
-
stopPx =
|
3709
|
+
stopPx = stopLossTriggerPrice if isStopLossTriggerOrder else takeProfitTriggerPrice
|
3661
3710
|
preciseStopPrice = self.price_to_precision(symbol, stopPx)
|
3662
3711
|
request['triggerPrice'] = preciseStopPrice
|
3663
3712
|
delta = self.number_to_string(market['precision']['price'])
|
3664
|
-
request['basePrice'] = Precise.string_sub(preciseStopPrice, delta) if
|
3713
|
+
request['basePrice'] = Precise.string_sub(preciseStopPrice, delta) if isStopLossTriggerOrder else Precise.string_add(preciseStopPrice, delta)
|
3714
|
+
elif isStopLoss or isTakeProfit:
|
3715
|
+
if isStopLoss:
|
3716
|
+
request['stopLoss'] = self.price_to_precision(symbol, stopLoss)
|
3717
|
+
if isTakeProfit:
|
3718
|
+
request['takeProfit'] = self.price_to_precision(symbol, takeProfit)
|
3665
3719
|
else:
|
3666
3720
|
request['orderFilter'] = 'Order'
|
3667
3721
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
ccxt/async_support/novadax.py
CHANGED
@@ -55,6 +55,9 @@ class novadax(Exchange):
|
|
55
55
|
'fetchBorrowRates': False,
|
56
56
|
'fetchBorrowRatesPerSymbol': False,
|
57
57
|
'fetchClosedOrders': True,
|
58
|
+
'fetchDepositAddress': False,
|
59
|
+
'fetchDepositAddresses': False,
|
60
|
+
'fetchDepositAddressesByNetwork': False,
|
58
61
|
'fetchDeposits': True,
|
59
62
|
'fetchFundingHistory': False,
|
60
63
|
'fetchFundingRate': False,
|
ccxt/async_support/okx.py
CHANGED
@@ -2458,7 +2458,9 @@ class okx(Exchange):
|
|
2458
2458
|
clientOrderId = self.safe_string(order, 'clOrdId')
|
2459
2459
|
if (clientOrderId is not None) and (len(clientOrderId) < 1):
|
2460
2460
|
clientOrderId = None # fix empty clientOrderId string
|
2461
|
-
|
2461
|
+
stopLossPrice = self.safe_number_2(order, 'slTriggerPx', 'slOrdPx')
|
2462
|
+
takeProfitPrice = self.safe_number_2(order, 'tpTriggerPx', 'tpOrdPx')
|
2463
|
+
stopPrice = self.safe_number_n(order, ['triggerPx', 'moveTriggerPx'])
|
2462
2464
|
reduceOnly = self.safe_string(order, 'reduceOnly')
|
2463
2465
|
if reduceOnly is not None:
|
2464
2466
|
reduceOnly = (reduceOnly == 'true')
|
@@ -2475,6 +2477,8 @@ class okx(Exchange):
|
|
2475
2477
|
'postOnly': postOnly,
|
2476
2478
|
'side': side,
|
2477
2479
|
'price': price,
|
2480
|
+
'stopLossPrice': stopLossPrice,
|
2481
|
+
'takeProfitPrice': takeProfitPrice,
|
2478
2482
|
'stopPrice': stopPrice,
|
2479
2483
|
'triggerPrice': stopPrice,
|
2480
2484
|
'average': average,
|
ccxt/base/exchange.py
CHANGED
ccxt/bybit.py
CHANGED
@@ -1346,7 +1346,7 @@ class bybit(Exchange):
|
|
1346
1346
|
# "baseCoin": "BTC",
|
1347
1347
|
# "quoteCoin": "USDT",
|
1348
1348
|
# "innovation": "0",
|
1349
|
-
# "status": "
|
1349
|
+
# "status": "Trading",
|
1350
1350
|
# "lotSizeFilter": {
|
1351
1351
|
# "basePrecision": "0.000001",
|
1352
1352
|
# "quotePrecision": "0.00000001",
|
@@ -1379,7 +1379,7 @@ class bybit(Exchange):
|
|
1379
1379
|
quote = self.safe_currency_code(quoteId)
|
1380
1380
|
symbol = base + '/' + quote
|
1381
1381
|
status = self.safe_string(market, 'status')
|
1382
|
-
active = (status == '
|
1382
|
+
active = (status == 'Trading')
|
1383
1383
|
lotSizeFilter = self.safe_value(market, 'lotSizeFilter')
|
1384
1384
|
priceFilter = self.safe_value(market, 'priceFilter')
|
1385
1385
|
quotePrecision = self.safe_number(lotSizeFilter, 'quotePrecision')
|
@@ -2386,6 +2386,10 @@ class bybit(Exchange):
|
|
2386
2386
|
marketType = 'contract'
|
2387
2387
|
if market is not None:
|
2388
2388
|
marketType = market['type']
|
2389
|
+
category = self.safe_string(trade, 'category')
|
2390
|
+
if category is not None:
|
2391
|
+
if category == 'spot':
|
2392
|
+
marketType = 'spot'
|
2389
2393
|
market = self.safe_market(marketId, market, None, marketType)
|
2390
2394
|
symbol = market['symbol']
|
2391
2395
|
amountString = self.safe_string_n(trade, ['execQty', 'orderQty', 'size'])
|
@@ -3041,6 +3045,10 @@ class bybit(Exchange):
|
|
3041
3045
|
marketType = 'contract'
|
3042
3046
|
if market is not None:
|
3043
3047
|
marketType = market['type']
|
3048
|
+
category = self.safe_string(order, 'category')
|
3049
|
+
if category is not None:
|
3050
|
+
if category == 'spot':
|
3051
|
+
marketType = 'spot'
|
3044
3052
|
market = self.safe_market(marketId, market, None, marketType)
|
3045
3053
|
symbol = market['symbol']
|
3046
3054
|
timestamp = self.safe_integer(order, 'createdTime')
|
@@ -3238,6 +3246,10 @@ class bybit(Exchange):
|
|
3238
3246
|
def create_order(self, symbol, type, side, amount, price=None, params={}):
|
3239
3247
|
"""
|
3240
3248
|
create a trade order
|
3249
|
+
see https://bybit-exchange.github.io/docs/v5/order/create-order
|
3250
|
+
see https://bybit-exchange.github.io/docs/spot/trade/place-order
|
3251
|
+
see https://bybit-exchange.github.io/docs/derivatives/unified/place-order
|
3252
|
+
see https://bybit-exchange.github.io/docs/derivatives/contract/place-order
|
3241
3253
|
:param str symbol: unified symbol of the market to create an order in
|
3242
3254
|
:param str type: 'market' or 'limit'
|
3243
3255
|
:param str side: 'buy' or 'sell'
|
@@ -3318,25 +3330,36 @@ class bybit(Exchange):
|
|
3318
3330
|
request['timeInForce'] = 'FOK'
|
3319
3331
|
elif timeInForce == 'ioc':
|
3320
3332
|
request['timeInForce'] = 'IOC'
|
3321
|
-
triggerPrice = self.
|
3322
|
-
|
3323
|
-
|
3324
|
-
|
3325
|
-
|
3326
|
-
|
3327
|
-
|
3328
|
-
|
3329
|
-
|
3333
|
+
triggerPrice = self.safe_number_2(params, 'triggerPrice', 'stopPrice')
|
3334
|
+
stopLossTriggerPrice = self.safe_number(params, 'stopLossPrice', triggerPrice)
|
3335
|
+
takeProfitTriggerPrice = self.safe_number(params, 'takeProfitPrice')
|
3336
|
+
stopLoss = self.safe_number(params, 'stopLoss')
|
3337
|
+
takeProfit = self.safe_number(params, 'takeProfit')
|
3338
|
+
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
3339
|
+
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
3340
|
+
isStopLoss = stopLoss is not None
|
3341
|
+
isTakeProfit = takeProfit is not None
|
3330
3342
|
if triggerPrice is not None:
|
3331
|
-
# logical xor
|
3332
3343
|
isBuy = side == 'buy'
|
3333
|
-
ascending = not isBuy if
|
3344
|
+
ascending = not isBuy if stopLossTriggerPrice else isBuy
|
3334
3345
|
request['triggerDirection'] = 2 if ascending else 1
|
3335
|
-
request['triggerBy'] = 'LastPrice'
|
3336
3346
|
request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
|
3347
|
+
elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
3348
|
+
if isStopLossTriggerOrder:
|
3349
|
+
request['triggerPrice'] = self.price_to_precision(symbol, stopLossTriggerPrice)
|
3350
|
+
request['triggerDirection'] = 2
|
3351
|
+
else:
|
3352
|
+
request['triggerPrice'] = self.price_to_precision(symbol, takeProfitTriggerPrice)
|
3353
|
+
request['triggerDirection'] = 1
|
3354
|
+
request['reduceOnly'] = True
|
3355
|
+
elif isStopLoss or isTakeProfit:
|
3356
|
+
if isStopLoss:
|
3357
|
+
request['stopLoss'] = self.price_to_precision(symbol, stopLoss)
|
3358
|
+
if isTakeProfit:
|
3359
|
+
request['takeProfit'] = self.price_to_precision(symbol, takeProfit)
|
3337
3360
|
if market['spot']:
|
3338
3361
|
# only works for spot market
|
3339
|
-
if triggerPrice is not None or
|
3362
|
+
if triggerPrice is not None or stopLossTriggerPrice is not None or takeProfitTriggerPrice is not None or isStopLoss or isTakeProfit:
|
3340
3363
|
request['orderFilter'] = 'tpslOrder'
|
3341
3364
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
3342
3365
|
if clientOrderId is not None:
|
@@ -3344,7 +3367,7 @@ class bybit(Exchange):
|
|
3344
3367
|
elif market['option']:
|
3345
3368
|
# mandatory field for options
|
3346
3369
|
request['orderLinkId'] = self.uuid16()
|
3347
|
-
params = self.omit(params, ['stopPrice', 'timeInForce', '
|
3370
|
+
params = self.omit(params, ['stopPrice', 'timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId'])
|
3348
3371
|
response = self.privatePostV5OrderCreate(self.extend(request, params))
|
3349
3372
|
#
|
3350
3373
|
# {
|
@@ -3482,21 +3505,30 @@ class bybit(Exchange):
|
|
3482
3505
|
request['timeInForce'] = 'FillOrKill'
|
3483
3506
|
elif timeInForce == 'ioc':
|
3484
3507
|
request['timeInForce'] = 'ImmediateOrCancel'
|
3485
|
-
triggerPrice = self.
|
3486
|
-
|
3487
|
-
|
3488
|
-
|
3489
|
-
|
3490
|
-
|
3508
|
+
triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
|
3509
|
+
stopLossTriggerPrice = self.safe_number(params, 'stopLossPrice', triggerPrice)
|
3510
|
+
takeProfitTriggerPrice = self.safe_number(params, 'takeProfitPrice')
|
3511
|
+
stopLoss = self.safe_number(params, 'stopLoss')
|
3512
|
+
takeProfit = self.safe_number(params, 'takeProfit')
|
3513
|
+
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
3514
|
+
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
3515
|
+
isStopLoss = stopLoss is not None
|
3516
|
+
isTakeProfit = takeProfit is not None
|
3517
|
+
if isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
3491
3518
|
request['triggerBy'] = 'LastPrice'
|
3492
|
-
triggerAt =
|
3519
|
+
triggerAt = stopLossTriggerPrice if isStopLossTriggerOrder else takeProfitTriggerPrice
|
3493
3520
|
preciseTriggerPrice = self.price_to_precision(symbol, triggerAt)
|
3494
3521
|
request['triggerPrice'] = preciseTriggerPrice
|
3495
3522
|
isBuy = side == 'buy'
|
3496
3523
|
# logical xor
|
3497
|
-
ascending = not isBuy if
|
3524
|
+
ascending = not isBuy if stopLossTriggerPrice else isBuy
|
3498
3525
|
delta = self.number_to_string(market['precision']['price'])
|
3499
3526
|
request['basePrice'] = Precise.string_add(preciseTriggerPrice, delta) if ascending else Precise.string_sub(preciseTriggerPrice, delta)
|
3527
|
+
elif isStopLoss or isTakeProfit:
|
3528
|
+
if isStopLoss:
|
3529
|
+
request['stopLoss'] = self.price_to_precision(symbol, stopLoss)
|
3530
|
+
if isTakeProfit:
|
3531
|
+
request['takeProfit'] = self.price_to_precision(symbol, takeProfit)
|
3500
3532
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
3501
3533
|
if clientOrderId is not None:
|
3502
3534
|
request['orderLinkId'] = clientOrderId
|
@@ -3565,27 +3597,40 @@ class bybit(Exchange):
|
|
3565
3597
|
request['timeInForce'] = 'FillOrKill'
|
3566
3598
|
elif timeInForce == 'ioc':
|
3567
3599
|
request['timeInForce'] = 'ImmediateOrCancel'
|
3568
|
-
triggerPrice = self.
|
3569
|
-
|
3570
|
-
|
3571
|
-
|
3572
|
-
|
3573
|
-
|
3574
|
-
|
3575
|
-
|
3600
|
+
triggerPrice = self.safe_number_2(params, 'triggerPrice', 'stopPrice')
|
3601
|
+
stopLossTriggerPrice = self.safe_number(params, 'stopLossPrice', triggerPrice)
|
3602
|
+
takeProfitTriggerPrice = self.safe_number(params, 'takeProfitPrice')
|
3603
|
+
stopLoss = self.safe_number(params, 'stopLoss')
|
3604
|
+
takeProfit = self.safe_number(params, 'takeProfit')
|
3605
|
+
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
3606
|
+
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
3607
|
+
isStopLoss = stopLoss is not None
|
3608
|
+
isTakeProfit = takeProfit is not None
|
3609
|
+
if triggerPrice:
|
3576
3610
|
isBuy = side == 'buy'
|
3577
|
-
|
3578
|
-
ascending = not isBuy if stopLossPrice else isBuy
|
3611
|
+
ascending = not isBuy if stopLossTriggerPrice else isBuy
|
3579
3612
|
request['triggerDirection'] = 2 if ascending else 1
|
3580
|
-
request['
|
3581
|
-
|
3613
|
+
request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
|
3614
|
+
elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
3615
|
+
if isStopLossTriggerOrder:
|
3616
|
+
request['triggerPrice'] = self.price_to_precision(symbol, stopLossTriggerPrice)
|
3617
|
+
request['triggerDirection'] = 2
|
3618
|
+
else:
|
3619
|
+
request['triggerPrice'] = self.price_to_precision(symbol, takeProfitTriggerPrice)
|
3620
|
+
request['triggerDirection'] = 1
|
3621
|
+
request['reduceOnly'] = True
|
3622
|
+
elif isStopLoss or isTakeProfit:
|
3623
|
+
if isStopLoss:
|
3624
|
+
request['stopLoss'] = self.price_to_precision(symbol, stopLoss)
|
3625
|
+
if isTakeProfit:
|
3626
|
+
request['takeProfit'] = self.price_to_precision(symbol, takeProfit)
|
3582
3627
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
3583
3628
|
if clientOrderId is not None:
|
3584
3629
|
request['orderLinkId'] = clientOrderId
|
3585
3630
|
elif market['option']:
|
3586
3631
|
# mandatory field for options
|
3587
3632
|
request['orderLinkId'] = self.uuid16()
|
3588
|
-
params = self.omit(params, ['stopPrice', 'timeInForce', '
|
3633
|
+
params = self.omit(params, ['stopPrice', 'timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId'])
|
3589
3634
|
response = self.privatePostContractV3PrivateOrderCreate(self.extend(request, params))
|
3590
3635
|
#
|
3591
3636
|
# {
|
@@ -3646,20 +3691,29 @@ class bybit(Exchange):
|
|
3646
3691
|
elif timeInForce == 'ioc':
|
3647
3692
|
request['time_in_force'] = 'ImmediateOrCancel'
|
3648
3693
|
if market['swap']:
|
3649
|
-
triggerPrice = self.
|
3650
|
-
|
3651
|
-
|
3652
|
-
|
3653
|
-
|
3654
|
-
|
3694
|
+
triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
|
3695
|
+
stopLossTriggerPrice = self.safe_number(params, 'stopLossPrice', triggerPrice)
|
3696
|
+
takeProfitTriggerPrice = self.safe_number(params, 'takeProfitPrice')
|
3697
|
+
stopLoss = self.safe_number(params, 'stopLoss')
|
3698
|
+
takeProfit = self.safe_number(params, 'takeProfit')
|
3699
|
+
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
3700
|
+
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
3701
|
+
isStopLoss = stopLoss is not None
|
3702
|
+
isTakeProfit = takeProfit is not None
|
3703
|
+
isStopOrder = isStopLossTriggerOrder or isTakeProfitTriggerOrder
|
3655
3704
|
if isStopOrder:
|
3656
3705
|
request['orderFilter'] = 'StopOrder'
|
3657
3706
|
request['trigger_by'] = 'LastPrice'
|
3658
|
-
stopPx =
|
3707
|
+
stopPx = stopLossTriggerPrice if isStopLossTriggerOrder else takeProfitTriggerPrice
|
3659
3708
|
preciseStopPrice = self.price_to_precision(symbol, stopPx)
|
3660
3709
|
request['triggerPrice'] = preciseStopPrice
|
3661
3710
|
delta = self.number_to_string(market['precision']['price'])
|
3662
|
-
request['basePrice'] = Precise.string_sub(preciseStopPrice, delta) if
|
3711
|
+
request['basePrice'] = Precise.string_sub(preciseStopPrice, delta) if isStopLossTriggerOrder else Precise.string_add(preciseStopPrice, delta)
|
3712
|
+
elif isStopLoss or isTakeProfit:
|
3713
|
+
if isStopLoss:
|
3714
|
+
request['stopLoss'] = self.price_to_precision(symbol, stopLoss)
|
3715
|
+
if isTakeProfit:
|
3716
|
+
request['takeProfit'] = self.price_to_precision(symbol, takeProfit)
|
3663
3717
|
else:
|
3664
3718
|
request['orderFilter'] = 'Order'
|
3665
3719
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
ccxt/novadax.py
CHANGED
@@ -55,6 +55,9 @@ class novadax(Exchange):
|
|
55
55
|
'fetchBorrowRates': False,
|
56
56
|
'fetchBorrowRatesPerSymbol': False,
|
57
57
|
'fetchClosedOrders': True,
|
58
|
+
'fetchDepositAddress': False,
|
59
|
+
'fetchDepositAddresses': False,
|
60
|
+
'fetchDepositAddressesByNetwork': False,
|
58
61
|
'fetchDeposits': True,
|
59
62
|
'fetchFundingHistory': False,
|
60
63
|
'fetchFundingRate': False,
|
ccxt/okx.py
CHANGED
@@ -2456,7 +2456,9 @@ class okx(Exchange):
|
|
2456
2456
|
clientOrderId = self.safe_string(order, 'clOrdId')
|
2457
2457
|
if (clientOrderId is not None) and (len(clientOrderId) < 1):
|
2458
2458
|
clientOrderId = None # fix empty clientOrderId string
|
2459
|
-
|
2459
|
+
stopLossPrice = self.safe_number_2(order, 'slTriggerPx', 'slOrdPx')
|
2460
|
+
takeProfitPrice = self.safe_number_2(order, 'tpTriggerPx', 'tpOrdPx')
|
2461
|
+
stopPrice = self.safe_number_n(order, ['triggerPx', 'moveTriggerPx'])
|
2460
2462
|
reduceOnly = self.safe_string(order, 'reduceOnly')
|
2461
2463
|
if reduceOnly is not None:
|
2462
2464
|
reduceOnly = (reduceOnly == 'true')
|
@@ -2473,6 +2475,8 @@ class okx(Exchange):
|
|
2473
2475
|
'postOnly': postOnly,
|
2474
2476
|
'side': side,
|
2475
2477
|
'price': price,
|
2478
|
+
'stopLossPrice': stopLossPrice,
|
2479
|
+
'takeProfitPrice': takeProfitPrice,
|
2476
2480
|
'stopPrice': stopPrice,
|
2477
2481
|
'triggerPrice': stopPrice,
|
2478
2482
|
'average': average,
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/base/exchange.py
CHANGED
ccxt/pro/binance.py
CHANGED
@@ -1291,8 +1291,8 @@ class binance(Exchange, ccxt.async_support.binance):
|
|
1291
1291
|
elif executionType == 'TRADE':
|
1292
1292
|
lastTradeTimestamp = T
|
1293
1293
|
fee = None
|
1294
|
-
feeCost = self.
|
1295
|
-
if (feeCost is not None) and (feeCost
|
1294
|
+
feeCost = self.safe_string(order, 'n')
|
1295
|
+
if (feeCost is not None) and (Precise.string_gt(feeCost, '0')):
|
1296
1296
|
feeCurrencyId = self.safe_string(order, 'N')
|
1297
1297
|
feeCurrency = self.safe_currency_code(feeCurrencyId)
|
1298
1298
|
fee = {
|