ccxt 4.1.37 → 4.1.39

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.
@@ -754,6 +754,9 @@ class bitget extends bitget$1 {
754
754
  /**
755
755
  * @method
756
756
  * @name bitget#watchOrders
757
+ * @see https://bitgetlimited.github.io/apidoc/en/spot/#order-channel
758
+ * @see https://bitgetlimited.github.io/apidoc/en/mix/#order-channel
759
+ * @see https://bitgetlimited.github.io/apidoc/en/mix/#plan-order-channel
757
760
  * @description watches information on multiple orders made by the user
758
761
  * @param {string} symbol unified market symbol of the market orders were made in
759
762
  * @param {int} [since] the earliest time in ms to fetch orders for
@@ -764,7 +767,9 @@ class bitget extends bitget$1 {
764
767
  await this.loadMarkets();
765
768
  let market = undefined;
766
769
  let marketId = undefined;
767
- let messageHash = 'order';
770
+ const isStop = this.safeValue(params, 'stop', false);
771
+ params = this.omit(params, 'stop');
772
+ let messageHash = (isStop) ? 'triggerOrder' : 'order';
768
773
  let subscriptionHash = 'order:trades';
769
774
  if (symbol !== undefined) {
770
775
  market = this.market(symbol);
@@ -772,8 +777,6 @@ class bitget extends bitget$1 {
772
777
  marketId = market['id'];
773
778
  messageHash = messageHash + ':' + symbol;
774
779
  }
775
- const isStop = this.safeValue(params, 'stop', false);
776
- params = this.omit(params, 'stop');
777
780
  let type = undefined;
778
781
  [type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
779
782
  if ((type === 'spot') && (symbol === undefined)) {
@@ -796,6 +799,9 @@ class bitget extends bitget$1 {
796
799
  instType = 'SUMCBL';
797
800
  }
798
801
  }
802
+ if (isStop) {
803
+ subscriptionHash = subscriptionHash + ':stop'; // we don't want to re-use the same subscription hash for stop orders
804
+ }
799
805
  const instId = (type === 'spot') ? marketId : 'default'; // different from other streams here the 'rest' id is required for spot markets, contract markets require default here
800
806
  const channel = isStop ? 'ordersAlgo' : 'orders';
801
807
  const args = {
@@ -837,7 +843,42 @@ class bitget extends bitget$1 {
837
843
  // ]
838
844
  // }
839
845
  //
846
+ // {
847
+ // action: 'snapshot',
848
+ // arg: { instType: 'umcbl', channel: 'ordersAlgo', instId: 'default' },
849
+ // data: [
850
+ // {
851
+ // actualPx: '55.000000000',
852
+ // actualSz: '0.000000000',
853
+ // cOid: '1104372235724890112',
854
+ // cTime: '1699028779917',
855
+ // eps: 'web',
856
+ // hM: 'double_hold',
857
+ // id: '1104372235724890113',
858
+ // instId: 'BTCUSDT_UMCBL',
859
+ // key: '1104372235724890113',
860
+ // ordPx: '55.000000000',
861
+ // ordType: 'limit',
862
+ // planType: 'pl',
863
+ // posSide: 'long',
864
+ // side: 'buy',
865
+ // state: 'not_trigger',
866
+ // sz: '3.557000000',
867
+ // tS: 'open_long',
868
+ // tgtCcy: 'USDT',
869
+ // triggerPx: '55.000000000',
870
+ // triggerPxType: 'last',
871
+ // triggerTime: '1699028779917',
872
+ // uTime: '1699028779917',
873
+ // userId: '3704614084',
874
+ // version: 1104372235586478100
875
+ // }
876
+ // ],
877
+ // ts: 1699028780327
878
+ // }
879
+ //
840
880
  const arg = this.safeValue(message, 'arg', {});
881
+ const channel = this.safeString(arg, 'channel');
841
882
  const instType = this.safeString(arg, 'instType');
842
883
  const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
843
884
  const isContractUpdate = (!sandboxMode) ? (instType === 'umcbl') : (instType === 'sumcbl');
@@ -845,8 +886,10 @@ class bitget extends bitget$1 {
845
886
  if (this.orders === undefined) {
846
887
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
847
888
  this.orders = new Cache.ArrayCacheBySymbolById(limit);
889
+ this.triggerOrders = new Cache.ArrayCacheBySymbolById(limit);
848
890
  }
849
- const stored = this.orders;
891
+ const stored = (channel === 'ordersAlgo') ? this.triggerOrders : this.orders;
892
+ const messageHash = (channel === 'ordersAlgo') ? 'triggerOrder' : 'order';
850
893
  const marketSymbols = {};
851
894
  for (let i = 0; i < data.length; i++) {
852
895
  const order = data[i];
@@ -863,10 +906,10 @@ class bitget extends bitget$1 {
863
906
  const keys = Object.keys(marketSymbols);
864
907
  for (let i = 0; i < keys.length; i++) {
865
908
  const symbol = keys[i];
866
- const messageHash = 'order:' + symbol;
867
- client.resolve(stored, messageHash);
909
+ const innerMessageHash = messageHash + ':' + symbol;
910
+ client.resolve(stored, innerMessageHash);
868
911
  }
869
- client.resolve(stored, 'order');
912
+ client.resolve(stored, messageHash);
870
913
  }
871
914
  parseWsOrder(order, market = undefined) {
872
915
  //
@@ -26,14 +26,23 @@ class wazirx extends wazirx$1 {
26
26
  'swap': false,
27
27
  'future': false,
28
28
  'option': false,
29
+ 'addMargin': false,
30
+ 'borrowMargin': false,
29
31
  'cancelAllOrders': true,
30
32
  'cancelOrder': true,
31
33
  'createOrder': true,
34
+ 'createReduceOnlyOrder': false,
32
35
  'createStopLimitOrder': true,
33
36
  'createStopMarketOrder': true,
34
37
  'createStopOrder': true,
35
38
  'fetchBalance': true,
36
39
  'fetchBidsAsks': false,
40
+ 'fetchBorrowInterest': false,
41
+ 'fetchBorrowRate': false,
42
+ 'fetchBorrowRateHistories': false,
43
+ 'fetchBorrowRateHistory': false,
44
+ 'fetchBorrowRates': false,
45
+ 'fetchBorrowRatesPerSymbol': false,
37
46
  'fetchClosedOrders': false,
38
47
  'fetchCurrencies': false,
39
48
  'fetchDepositAddress': false,
@@ -45,7 +54,11 @@ class wazirx extends wazirx$1 {
45
54
  'fetchFundingRateHistory': false,
46
55
  'fetchFundingRates': false,
47
56
  'fetchIndexOHLCV': false,
57
+ 'fetchIsolatedPositions': false,
58
+ 'fetchLeverage': false,
59
+ 'fetchLeverageTiers': false,
48
60
  'fetchMarginMode': false,
61
+ 'fetchMarketLeverageTiers': false,
49
62
  'fetchMarkets': true,
50
63
  'fetchMarkOHLCV': false,
51
64
  'fetchMyTrades': false,
@@ -55,7 +68,10 @@ class wazirx extends wazirx$1 {
55
68
  'fetchOrder': false,
56
69
  'fetchOrderBook': true,
57
70
  'fetchOrders': true,
71
+ 'fetchPosition': false,
58
72
  'fetchPositionMode': false,
73
+ 'fetchPositions': false,
74
+ 'fetchPositionsRisk': false,
59
75
  'fetchPremiumIndexOHLCV': false,
60
76
  'fetchStatus': true,
61
77
  'fetchTicker': true,
@@ -68,6 +84,12 @@ class wazirx extends wazirx$1 {
68
84
  'fetchTransactions': false,
69
85
  'fetchTransfers': false,
70
86
  'fetchWithdrawals': false,
87
+ 'reduceMargin': false,
88
+ 'repayMargin': false,
89
+ 'setLeverage': false,
90
+ 'setMargin': false,
91
+ 'setMarginMode': false,
92
+ 'setPositionMode': false,
71
93
  'transfer': false,
72
94
  'withdraw': false,
73
95
  },
package/js/ccxt.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
4
4
  import * as errors from './src/base/errors.js';
5
5
  import { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
7
- declare const version = "4.1.36";
7
+ declare const version = "4.1.38";
8
8
  import ace from './src/ace.js';
9
9
  import alpaca from './src/alpaca.js';
10
10
  import ascendex from './src/ascendex.js';
package/js/ccxt.js CHANGED
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
38
38
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.1.37';
41
+ const version = '4.1.39';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -257,6 +257,7 @@ interface Exchange {
257
257
  privateGetV5UserQueryApi(params?: {}): Promise<implicitReturnType>;
258
258
  privateGetV5UserGetMemberType(params?: {}): Promise<implicitReturnType>;
259
259
  privateGetV5UserAffCustomerInfo(params?: {}): Promise<implicitReturnType>;
260
+ privateGetV5UserDelSubmember(params?: {}): Promise<implicitReturnType>;
260
261
  privateGetV5SpotLeverTokenOrderRecord(params?: {}): Promise<implicitReturnType>;
261
262
  privateGetV5SpotMarginTradeState(params?: {}): Promise<implicitReturnType>;
262
263
  privateGetV5SpotCrossMarginTradeLoanInfo(params?: {}): Promise<implicitReturnType>;
@@ -1,11 +1,13 @@
1
1
  import { implicitReturnType } from '../base/types.js';
2
2
  import { Exchange as _Exchange } from '../base/Exchange.js';
3
3
  interface Exchange {
4
+ publicGetFeeschedules(params?: {}): Promise<implicitReturnType>;
4
5
  publicGetInstruments(params?: {}): Promise<implicitReturnType>;
5
6
  publicGetOrderbook(params?: {}): Promise<implicitReturnType>;
6
7
  publicGetTickers(params?: {}): Promise<implicitReturnType>;
7
8
  publicGetHistory(params?: {}): Promise<implicitReturnType>;
8
9
  publicGetHistoricalfundingrates(params?: {}): Promise<implicitReturnType>;
10
+ privateGetFeeschedulesVolumes(params?: {}): Promise<implicitReturnType>;
9
11
  privateGetOpenpositions(params?: {}): Promise<implicitReturnType>;
10
12
  privateGetNotifications(params?: {}): Promise<implicitReturnType>;
11
13
  privateGetAccounts(params?: {}): Promise<implicitReturnType>;
@@ -32,7 +34,6 @@ interface Exchange {
32
34
  historyGetAccountlogcsv(params?: {}): Promise<implicitReturnType>;
33
35
  historyGetMarketSymbolOrders(params?: {}): Promise<implicitReturnType>;
34
36
  historyGetMarketSymbolExecutions(params?: {}): Promise<implicitReturnType>;
35
- feeschedulesGetVolumes(params?: {}): Promise<implicitReturnType>;
36
37
  }
37
38
  declare abstract class Exchange extends _Exchange {
38
39
  }
@@ -29,26 +29,45 @@ export default class bitforex extends Exchange {
29
29
  'swap': false,
30
30
  'future': false,
31
31
  'option': false,
32
+ 'addMargin': false,
33
+ 'borrowMargin': false,
32
34
  'cancelOrder': true,
33
35
  'createOrder': true,
36
+ 'createReduceOnlyOrder': false,
34
37
  'createStopLimitOrder': false,
35
38
  'createStopMarketOrder': false,
36
39
  'createStopOrder': false,
37
40
  'fetchBalance': true,
41
+ 'fetchBorrowInterest': false,
38
42
  'fetchBorrowRate': false,
39
43
  'fetchBorrowRateHistories': false,
40
44
  'fetchBorrowRateHistory': false,
41
45
  'fetchBorrowRates': false,
42
46
  'fetchBorrowRatesPerSymbol': false,
43
47
  'fetchClosedOrders': true,
48
+ 'fetchFundingHistory': false,
49
+ 'fetchFundingRate': false,
50
+ 'fetchFundingRateHistory': false,
51
+ 'fetchFundingRates': false,
52
+ 'fetchIndexOHLCV': false,
53
+ 'fetchIsolatedPositions': false,
54
+ 'fetchLeverage': false,
55
+ 'fetchLeverageTiers': false,
44
56
  'fetchMarginMode': false,
57
+ 'fetchMarketLeverageTiers': false,
45
58
  'fetchMarkets': true,
59
+ 'fetchMarkOHLCV': false,
46
60
  'fetchMyTrades': true,
47
61
  'fetchOHLCV': true,
62
+ 'fetchOpenInterestHistory': false,
48
63
  'fetchOpenOrders': true,
49
64
  'fetchOrder': true,
50
65
  'fetchOrderBook': true,
66
+ 'fetchPosition': false,
51
67
  'fetchPositionMode': false,
68
+ 'fetchPositions': false,
69
+ 'fetchPositionsRisk': false,
70
+ 'fetchPremiumIndexOHLCV': false,
52
71
  'fetchTicker': true,
53
72
  'fetchTickers': false,
54
73
  'fetchTrades': true,
@@ -57,6 +76,12 @@ export default class bitforex extends Exchange {
57
76
  'fetchTransfers': false,
58
77
  'fetchWithdrawal': false,
59
78
  'fetchWithdrawals': false,
79
+ 'reduceMargin': false,
80
+ 'repayMargin': false,
81
+ 'setLeverage': false,
82
+ 'setMargin': false,
83
+ 'setMarginMode': false,
84
+ 'setPositionMode': false,
60
85
  'transfer': false,
61
86
  'withdraw': false,
62
87
  },
package/js/src/bybit.js CHANGED
@@ -430,6 +430,7 @@ export default class bybit extends Exchange {
430
430
  'v5/user/query-api': 5,
431
431
  'v5/user/get-member-type': 5,
432
432
  'v5/user/aff-customer-info': 5,
433
+ 'v5/user/del-submember': 5,
433
434
  // spot leverage token
434
435
  'v5/spot-lever-token/order-record': 1,
435
436
  // spot margin trade
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/digifinex.js';
2
- import { FundingRateHistory, Int, OHLCV, Order, OrderSide, OrderType } from './base/types.js';
2
+ import { FundingRateHistory, Int, OHLCV, Order, OrderSide, OrderType, OrderRequest } from './base/types.js';
3
3
  /**
4
4
  * @class digifinex
5
5
  * @extends Exchange
@@ -29,6 +29,8 @@ export default class digifinex extends Exchange {
29
29
  parseOHLCV(ohlcv: any, market?: any): OHLCV;
30
30
  fetchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
31
31
  createOrder(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): Promise<Order>;
32
+ createOrders(orders: OrderRequest[], params?: {}): Promise<Order[]>;
33
+ createOrderRequest(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): any;
32
34
  cancelOrder(id: string, symbol?: string, params?: {}): Promise<any>;
33
35
  cancelOrders(ids: any, symbol?: string, params?: {}): Promise<any>;
34
36
  parseOrderStatus(status: any): string;
@@ -34,6 +34,7 @@ export default class digifinex extends Exchange {
34
34
  'cancelOrder': true,
35
35
  'cancelOrders': true,
36
36
  'createOrder': true,
37
+ 'createOrders': true,
37
38
  'createPostOnlyOrder': true,
38
39
  'createReduceOnlyOrder': true,
39
40
  'createStopLimitOrder': false,
@@ -291,6 +292,7 @@ export default class digifinex extends Exchange {
291
292
  'options': {
292
293
  'defaultType': 'spot',
293
294
  'types': ['spot', 'margin', 'otc'],
295
+ 'createMarketBuyOrderRequiresPrice': true,
294
296
  'accountsByType': {
295
297
  'spot': '1',
296
298
  'margin': '2',
@@ -1554,28 +1556,173 @@ export default class digifinex extends Exchange {
1554
1556
  * @param {string} symbol unified symbol of the market to create an order in
1555
1557
  * @param {string} type 'market' or 'limit'
1556
1558
  * @param {string} side 'buy' or 'sell'
1557
- * @param {float} amount how much of currency you want to trade in units of base currency
1559
+ * @param {float} amount how much you want to trade in units of the base currency, spot market orders use the quote currency, swap requires the number of contracts
1558
1560
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1559
1561
  * @param {object} [params] extra parameters specific to the digifinex api endpoint
1560
1562
  * @param {string} [params.timeInForce] "GTC", "IOC", "FOK", or "PO"
1561
1563
  * @param {bool} [params.postOnly] true or false
1562
1564
  * @param {bool} [params.reduceOnly] true or false
1565
+ * @param {string} [params.marginMode] 'cross' or 'isolated', for spot margin trading
1563
1566
  * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
1564
1567
  */
1565
1568
  await this.loadMarkets();
1566
1569
  const market = this.market(symbol);
1567
- symbol = market['symbol'];
1570
+ const marginResult = this.handleMarginModeAndParams('createOrder', params);
1571
+ const marginMode = marginResult[0];
1572
+ const request = this.createOrderRequest(symbol, type, side, amount, price, params);
1573
+ let response = undefined;
1574
+ if (market['swap']) {
1575
+ response = await this.privateSwapPostTradeOrderPlace(request);
1576
+ }
1577
+ else {
1578
+ if (marginMode !== undefined) {
1579
+ response = await this.privateSpotPostMarginOrderNew(request);
1580
+ }
1581
+ else {
1582
+ response = await this.privateSpotPostSpotOrderNew(request);
1583
+ }
1584
+ }
1585
+ //
1586
+ // spot and margin
1587
+ //
1588
+ // {
1589
+ // "code": 0,
1590
+ // "order_id": "198361cecdc65f9c8c9bb2fa68faec40"
1591
+ // }
1592
+ //
1593
+ // swap
1594
+ //
1595
+ // {
1596
+ // "code": 0,
1597
+ // "data": "1590873693003714560"
1598
+ // }
1599
+ //
1600
+ const order = this.parseOrder(response, market);
1601
+ order['symbol'] = market['symbol'];
1602
+ order['type'] = type;
1603
+ order['side'] = side;
1604
+ order['amount'] = amount;
1605
+ order['price'] = price;
1606
+ return order;
1607
+ }
1608
+ async createOrders(orders, params = {}) {
1609
+ /**
1610
+ * @method
1611
+ * @name digifinex#createOrders
1612
+ * @description create a list of trade orders (all orders should be of the same symbol)
1613
+ * @see https://docs.digifinex.com/en-ww/spot/v3/rest.html#create-multiple-order
1614
+ * @see https://docs.digifinex.com/en-ww/swap/v2/rest.html#batchorder
1615
+ * @param {array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
1616
+ * @param {object} [params] extra parameters specific to the digifinex api endpoint
1617
+ * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
1618
+ */
1619
+ await this.loadMarkets();
1620
+ const ordersRequests = [];
1621
+ let symbol = undefined;
1622
+ let marginMode = undefined;
1623
+ for (let i = 0; i < orders.length; i++) {
1624
+ const rawOrder = orders[i];
1625
+ const marketId = this.safeString(rawOrder, 'symbol');
1626
+ if (symbol === undefined) {
1627
+ symbol = marketId;
1628
+ }
1629
+ else {
1630
+ if (symbol !== marketId) {
1631
+ throw new BadRequest(this.id + ' createOrders() requires all orders to have the same symbol');
1632
+ }
1633
+ }
1634
+ const type = this.safeString(rawOrder, 'type');
1635
+ const side = this.safeString(rawOrder, 'side');
1636
+ const amount = this.safeValue(rawOrder, 'amount');
1637
+ const price = this.safeValue(rawOrder, 'price');
1638
+ const orderParams = this.safeValue(rawOrder, 'params', {});
1639
+ const marginResult = this.handleMarginModeAndParams('createOrders', params);
1640
+ const currentMarginMode = marginResult[0];
1641
+ if (currentMarginMode !== undefined) {
1642
+ if (marginMode === undefined) {
1643
+ marginMode = currentMarginMode;
1644
+ }
1645
+ else {
1646
+ if (marginMode !== currentMarginMode) {
1647
+ throw new BadRequest(this.id + ' createOrders() requires all orders to have the same margin mode (isolated or cross)');
1648
+ }
1649
+ }
1650
+ }
1651
+ const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
1652
+ ordersRequests.push(orderRequest);
1653
+ }
1654
+ const market = this.market(symbol);
1655
+ const request = {};
1656
+ let response = undefined;
1657
+ if (market['swap']) {
1658
+ response = await this.privateSwapPostTradeBatchOrder(ordersRequests);
1659
+ }
1660
+ else {
1661
+ request['market'] = (marginMode !== undefined) ? 'margin' : 'spot';
1662
+ request['symbol'] = market['id'];
1663
+ request['list'] = this.json(ordersRequests);
1664
+ response = await this.privateSpotPostMarketOrderBatchNew(request);
1665
+ }
1666
+ //
1667
+ // spot
1668
+ //
1669
+ // {
1670
+ // "code": 0,
1671
+ // "order_ids": [
1672
+ // "064290fbe2d26e7b28d7e6c0a5cf70a5",
1673
+ // "24c8f9b73d81e4d9d8d7e3280281c258"
1674
+ // ]
1675
+ // }
1676
+ //
1677
+ // swap
1678
+ //
1679
+ // {
1680
+ // "code": 0,
1681
+ // "data": [
1682
+ // "1720297963537829888",
1683
+ // "1720297963537829889"
1684
+ // ]
1685
+ // }
1686
+ //
1687
+ let data = [];
1688
+ if (market['swap']) {
1689
+ data = this.safeValue(response, 'data', []);
1690
+ }
1691
+ else {
1692
+ data = this.safeValue(response, 'order_ids', []);
1693
+ }
1694
+ const result = [];
1695
+ for (let i = 0; i < orders.length; i++) {
1696
+ const rawOrder = orders[i];
1697
+ const individualOrder = {};
1698
+ individualOrder['order_id'] = data[i];
1699
+ individualOrder['instrument_id'] = market['id'];
1700
+ individualOrder['amount'] = this.safeNumber(rawOrder, 'amount');
1701
+ individualOrder['price'] = this.safeNumber(rawOrder, 'price');
1702
+ result.push(individualOrder);
1703
+ }
1704
+ return this.parseOrders(result, market);
1705
+ }
1706
+ createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
1707
+ /**
1708
+ * @method
1709
+ * @ignore
1710
+ * @name digifinex#createOrderRequest
1711
+ * @description helper function to build request
1712
+ * @param {string} symbol unified symbol of the market to create an order in
1713
+ * @param {string} type 'market' or 'limit'
1714
+ * @param {string} side 'buy' or 'sell'
1715
+ * @param {float} amount how much you want to trade in units of the base currency, spot market orders use the quote currency, swap requires the number of contracts
1716
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1717
+ * @param {object} [params] extra parameters specific to the digifinex api endpoint
1718
+ * @returns {object} request to be sent to the exchange
1719
+ */
1720
+ const market = this.market(symbol);
1568
1721
  let marketType = undefined;
1569
1722
  let marginMode = undefined;
1570
- [marketType, params] = this.handleMarketTypeAndParams('createOrder', market, params);
1571
- let method = this.getSupportedMapping(marketType, {
1572
- 'spot': 'privateSpotPostSpotOrderNew',
1573
- 'margin': 'privateSpotPostMarginOrderNew',
1574
- 'swap': 'privateSwapPostTradeOrderPlace',
1575
- });
1576
- [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
1723
+ [marketType, params] = this.handleMarketTypeAndParams('createOrderRequest', market, params);
1724
+ [marginMode, params] = this.handleMarginModeAndParams('createOrderRequest', params);
1577
1725
  if (marginMode !== undefined) {
1578
- method = 'privateSpotPostMarginOrderNew';
1579
1726
  marketType = 'margin';
1580
1727
  }
1581
1728
  const request = {};
@@ -1632,40 +1779,34 @@ export default class digifinex extends Exchange {
1632
1779
  }
1633
1780
  request['type'] = side + suffix;
1634
1781
  // limit orders require the amount in the base currency, market orders require the amount in the quote currency
1635
- request['amount'] = this.amountToPrecision(symbol, amount);
1782
+ let quantity = undefined;
1783
+ const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice', true);
1784
+ if (createMarketBuyOrderRequiresPrice && isMarketOrder && (side === 'buy')) {
1785
+ if (price === undefined) {
1786
+ throw new InvalidOrder(this.id + ' createOrder() requires a price argument for market buy orders on spot markets to calculate the total amount to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option to false and pass in the cost to spend into the amount parameter');
1787
+ }
1788
+ else {
1789
+ const amountString = this.numberToString(amount);
1790
+ const priceString = this.numberToString(price);
1791
+ const cost = this.parseNumber(Precise.stringMul(amountString, priceString));
1792
+ quantity = this.priceToPrecision(symbol, cost);
1793
+ }
1794
+ }
1795
+ else {
1796
+ quantity = this.amountToPrecision(symbol, amount);
1797
+ }
1798
+ request['amount'] = quantity;
1636
1799
  }
1637
1800
  if (postOnly) {
1638
1801
  if (postOnlyParsed) {
1639
- request['postOnly'] = postOnlyParsed;
1802
+ request['post_only'] = postOnlyParsed;
1640
1803
  }
1641
1804
  else {
1642
- request['postOnly'] = postOnly;
1805
+ request['post_only'] = postOnly;
1643
1806
  }
1644
1807
  }
1645
- const query = this.omit(params, ['postOnly', 'post_only']);
1646
- const response = await this[method](this.extend(request, query));
1647
- //
1648
- // spot and margin
1649
- //
1650
- // {
1651
- // "code": 0,
1652
- // "order_id": "198361cecdc65f9c8c9bb2fa68faec40"
1653
- // }
1654
- //
1655
- // swap
1656
- //
1657
- // {
1658
- // "code": 0,
1659
- // "data": "1590873693003714560"
1660
- // }
1661
- //
1662
- const order = this.parseOrder(response, market);
1663
- order['symbol'] = symbol;
1664
- order['type'] = type;
1665
- order['side'] = side;
1666
- order['amount'] = amount;
1667
- order['price'] = price;
1668
- return order;
1808
+ params = this.omit(params, ['postOnly']);
1809
+ return this.extend(request, params);
1669
1810
  }
1670
1811
  async cancelOrder(id, symbol = undefined, params = {}) {
1671
1812
  /**
@@ -1802,6 +1943,15 @@ export default class digifinex extends Exchange {
1802
1943
  // "data": "1590873693003714560"
1803
1944
  // }
1804
1945
  //
1946
+ // spot and swap: createOrders
1947
+ //
1948
+ // {
1949
+ // "order_id": "d64d92a5e0a120f792f385485bc3d95b",
1950
+ // "instrument_id": "BTC_USDT",
1951
+ // "amount": 0.0001,
1952
+ // "price": 27000
1953
+ // }
1954
+ //
1805
1955
  // spot: fetchOrder, fetchOpenOrders, fetchOrders
1806
1956
  //
1807
1957
  // {
@@ -1847,24 +1997,26 @@ export default class digifinex extends Exchange {
1847
1997
  let type = undefined;
1848
1998
  let side = this.safeString(order, 'type');
1849
1999
  const marketId = this.safeString2(order, 'symbol', 'instrument_id');
1850
- const symbol = this.safeSymbol(marketId, market, '_');
2000
+ const symbol = this.safeSymbol(marketId, market);
1851
2001
  market = this.market(symbol);
1852
2002
  if (market['type'] === 'swap') {
1853
2003
  const orderType = this.safeInteger(order, 'order_type');
1854
- if ((orderType === 9) || (orderType === 10) || (orderType === 11) || (orderType === 12) || (orderType === 15)) {
1855
- timeInForce = 'FOK';
1856
- }
1857
- else if ((orderType === 1) || (orderType === 2) || (orderType === 3) || (orderType === 4) || (orderType === 13)) {
1858
- timeInForce = 'IOC';
1859
- }
1860
- else if ((orderType === 6) || (orderType === 7) || (orderType === 8) || (orderType === 14)) {
1861
- timeInForce = 'GTC';
1862
- }
1863
- if ((orderType === 0) || (orderType === 1) || (orderType === 4) || (orderType === 5) || (orderType === 9) || (orderType === 10)) {
1864
- type = 'limit';
1865
- }
1866
- else {
1867
- type = 'market';
2004
+ if (orderType !== undefined) {
2005
+ if ((orderType === 9) || (orderType === 10) || (orderType === 11) || (orderType === 12) || (orderType === 15)) {
2006
+ timeInForce = 'FOK';
2007
+ }
2008
+ else if ((orderType === 1) || (orderType === 2) || (orderType === 3) || (orderType === 4) || (orderType === 13)) {
2009
+ timeInForce = 'IOC';
2010
+ }
2011
+ else if ((orderType === 6) || (orderType === 7) || (orderType === 8) || (orderType === 14)) {
2012
+ timeInForce = 'GTC';
2013
+ }
2014
+ if ((orderType === 0) || (orderType === 1) || (orderType === 4) || (orderType === 5) || (orderType === 9) || (orderType === 10)) {
2015
+ type = 'limit';
2016
+ }
2017
+ else {
2018
+ type = 'market';
2019
+ }
1868
2020
  }
1869
2021
  if (side === '1') {
1870
2022
  side = 'open long';