ccxt 4.4.75 → 4.4.78

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.
Files changed (114) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.min.js +7 -7
  3. package/dist/cjs/ccxt.js +8 -4
  4. package/dist/cjs/src/abstract/apex.js +9 -0
  5. package/dist/cjs/src/apex.js +1949 -0
  6. package/dist/cjs/src/base/Exchange.js +49 -3
  7. package/dist/cjs/src/binance.js +44 -220
  8. package/dist/cjs/src/bitget.js +139 -71
  9. package/dist/cjs/src/bitmex.js +4 -4
  10. package/dist/cjs/src/bitrue.js +48 -0
  11. package/dist/cjs/src/cex.js +1 -1
  12. package/dist/cjs/src/coinbase.js +32 -3
  13. package/dist/cjs/src/coincatch.js +68 -0
  14. package/dist/cjs/src/coinex.js +3 -0
  15. package/dist/cjs/src/coinlist.js +85 -1
  16. package/dist/cjs/src/hitbtc.js +3 -0
  17. package/dist/cjs/src/hyperliquid.js +13 -4
  18. package/dist/cjs/src/mexc.js +50 -57
  19. package/dist/cjs/src/okx.js +23 -8
  20. package/dist/cjs/src/paradex.js +3 -12
  21. package/dist/cjs/src/phemex.js +2 -1
  22. package/dist/cjs/src/poloniex.js +1 -1
  23. package/dist/cjs/src/pro/apex.js +1043 -0
  24. package/dist/cjs/src/pro/coinbase.js +4 -8
  25. package/dist/cjs/src/pro/gate.js +27 -2
  26. package/dist/cjs/src/pro/hollaex.js +2 -2
  27. package/dist/cjs/src/pro/hyperliquid.js +1 -1
  28. package/dist/cjs/src/pro/p2b.js +2 -2
  29. package/dist/cjs/src/pro/tradeogre.js +283 -0
  30. package/dist/cjs/src/probit.js +1 -0
  31. package/dist/cjs/src/static_dependencies/zklink/zklink-sdk-web.js +2645 -0
  32. package/dist/cjs/src/tradeogre.js +2 -1
  33. package/dist/cjs/src/upbit.js +299 -93
  34. package/dist/cjs/src/whitebit.js +1 -0
  35. package/dist/cjs/src/woo.js +3 -1
  36. package/dist/cjs/src/xt.js +131 -4
  37. package/js/ccxt.d.ts +11 -5
  38. package/js/ccxt.js +8 -4
  39. package/js/src/abstract/apex.d.ts +34 -0
  40. package/js/src/abstract/myokx.d.ts +4 -0
  41. package/js/src/abstract/okx.d.ts +4 -0
  42. package/js/src/abstract/upbit.d.ts +15 -1
  43. package/js/src/abstract/xt.d.ts +3 -0
  44. package/js/src/apex.d.ts +333 -0
  45. package/js/src/apex.js +1951 -0
  46. package/js/src/ascendex.d.ts +3 -3
  47. package/js/src/base/Exchange.d.ts +3 -0
  48. package/js/src/base/Exchange.js +49 -2
  49. package/js/src/binance.d.ts +9 -7
  50. package/js/src/binance.js +44 -220
  51. package/js/src/bitfinex.d.ts +3 -3
  52. package/js/src/bitflyer.d.ts +2 -2
  53. package/js/src/bitget.d.ts +2 -0
  54. package/js/src/bitget.js +139 -71
  55. package/js/src/bitmart.d.ts +4 -4
  56. package/js/src/bitmex.d.ts +3 -3
  57. package/js/src/bitmex.js +4 -4
  58. package/js/src/bitrue.js +48 -0
  59. package/js/src/cex.js +1 -1
  60. package/js/src/coinbase.d.ts +6 -4
  61. package/js/src/coinbase.js +32 -3
  62. package/js/src/coinbaseexchange.d.ts +1 -1
  63. package/js/src/coincatch.d.ts +11 -0
  64. package/js/src/coincatch.js +68 -0
  65. package/js/src/coinex.js +3 -0
  66. package/js/src/coinlist.d.ts +12 -1
  67. package/js/src/coinlist.js +85 -1
  68. package/js/src/cryptocom.d.ts +4 -4
  69. package/js/src/deribit.d.ts +4 -4
  70. package/js/src/derive.d.ts +3 -3
  71. package/js/src/digifinex.d.ts +4 -4
  72. package/js/src/hitbtc.js +3 -0
  73. package/js/src/htx.d.ts +4 -4
  74. package/js/src/hyperliquid.d.ts +1 -0
  75. package/js/src/hyperliquid.js +13 -4
  76. package/js/src/kraken.d.ts +3 -3
  77. package/js/src/krakenfutures.d.ts +2 -2
  78. package/js/src/kucoinfutures.d.ts +5 -5
  79. package/js/src/mexc.d.ts +1 -0
  80. package/js/src/mexc.js +50 -57
  81. package/js/src/okx.js +23 -8
  82. package/js/src/oxfun.d.ts +3 -3
  83. package/js/src/paradex.js +3 -12
  84. package/js/src/phemex.d.ts +3 -3
  85. package/js/src/phemex.js +2 -1
  86. package/js/src/poloniex.d.ts +3 -3
  87. package/js/src/poloniex.js +1 -1
  88. package/js/src/pro/apex.d.ts +160 -0
  89. package/js/src/pro/apex.js +1044 -0
  90. package/js/src/pro/coinbase.js +4 -8
  91. package/js/src/pro/gate.js +27 -2
  92. package/js/src/pro/hollaex.js +2 -2
  93. package/js/src/pro/hyperliquid.js +1 -1
  94. package/js/src/pro/p2b.js +2 -2
  95. package/js/src/pro/tradeogre.d.ts +49 -0
  96. package/js/src/pro/tradeogre.js +284 -0
  97. package/js/src/probit.js +1 -0
  98. package/js/src/static_dependencies/zklink/zklink-sdk-web.d.ts +1279 -0
  99. package/js/src/static_dependencies/zklink/zklink-sdk-web.js +4282 -0
  100. package/js/src/tradeogre.js +2 -1
  101. package/js/src/upbit.d.ts +34 -4
  102. package/js/src/upbit.js +299 -93
  103. package/js/src/vertex.d.ts +3 -3
  104. package/js/src/whitebit.js +1 -0
  105. package/js/src/woo.d.ts +4 -4
  106. package/js/src/woo.js +3 -1
  107. package/js/src/woofipro.d.ts +4 -4
  108. package/js/src/xt.d.ts +23 -4
  109. package/js/src/xt.js +131 -4
  110. package/package.json +2 -2
  111. package/js/src/abstract/ace.d.ts +0 -18
  112. package/js/src/ace.d.ts +0 -158
  113. package/js/src/ace.js +0 -1181
  114. /package/js/src/abstract/{ace.js → apex.js} +0 -0
@@ -21,7 +21,7 @@ export default class tradeogre extends Exchange {
21
21
  'countries': [],
22
22
  'rateLimit': 100,
23
23
  'version': 'v2',
24
- 'pro': false,
24
+ 'pro': true,
25
25
  'has': {
26
26
  'CORS': undefined,
27
27
  'spot': true,
@@ -532,6 +532,7 @@ export default class tradeogre extends Exchange {
532
532
  'asks': rawAsks,
533
533
  };
534
534
  const orderbook = this.parseOrderBook(rawOrderbook, symbol);
535
+ orderbook['nonce'] = this.safeInteger(response, 's');
535
536
  return orderbook;
536
537
  }
537
538
  parseBidsAsks(bidasks, priceKey = 0, amountKey = 1, countOrIdKey = 2) {
package/js/src/upbit.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/upbit.js';
2
- import type { Balances, Currency, Dict, Int, Market, Num, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, int, DepositAddress, OrderBooks } from './base/types.js';
2
+ import type { Balances, Currency, Dict, Int, Market, Num, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, int, DepositAddress, OrderBooks, TradingFees } from './base/types.js';
3
3
  /**
4
4
  * @class upbit
5
5
  * @augments Exchange
@@ -124,6 +124,14 @@ export default class upbit extends Exchange {
124
124
  * @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
125
125
  */
126
126
  fetchTradingFee(symbol: string, params?: {}): Promise<TradingFeeInterface>;
127
+ /**
128
+ * @method
129
+ * @name upbit#fetchTradingFees
130
+ * @description fetch the trading fees for markets
131
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
132
+ * @returns {object} a [trading fee structure]{@link https://docs.ccxt.com/#/?id=trading-fee-structure}
133
+ */
134
+ fetchTradingFees(params?: {}): Promise<TradingFees>;
127
135
  parseOHLCV(ohlcv: any, market?: Market): OHLCV;
128
136
  /**
129
137
  * @method
@@ -138,6 +146,7 @@ export default class upbit extends Exchange {
138
146
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
139
147
  */
140
148
  fetchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
149
+ calcOrderPrice(symbol: string, amount: number, price?: Num, params?: {}): string;
141
150
  /**
142
151
  * @method
143
152
  * @name upbit#createOrder
@@ -145,13 +154,14 @@ export default class upbit extends Exchange {
145
154
  * @see https://docs.upbit.com/reference/%EC%A3%BC%EB%AC%B8%ED%95%98%EA%B8%B0
146
155
  * @see https://global-docs.upbit.com/reference/order
147
156
  * @param {string} symbol unified symbol of the market to create an order in
148
- * @param {string} type 'market' or 'limit'
157
+ * @param {string} type supports 'market' and 'limit'. if params.ordType is set to best, a best-type order will be created regardless of the value of type.
149
158
  * @param {string} side 'buy' or 'sell'
150
159
  * @param {float} amount how much you want to trade in units of the base currency
151
160
  * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
152
161
  * @param {object} [params] extra parameters specific to the exchange API endpoint
153
- * @param {float} [params.cost] for market buy orders, the quote quantity that can be used as an alternative for the amount
154
- * @param {string} [params.timeInForce] 'IOC' or 'FOK'
162
+ * @param {float} [params.cost] for market buy and best buy orders, the quote quantity that can be used as an alternative for the amount
163
+ * @param {string} [params.ordType] this field can be used to place a ‘best’ type order
164
+ * @param {string} [params.timeInForce] 'IOC' or 'FOK'. only for limit or best type orders. this field is required when the order type is 'best'.
155
165
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
156
166
  */
157
167
  createOrder(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
@@ -166,6 +176,26 @@ export default class upbit extends Exchange {
166
176
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
167
177
  */
168
178
  cancelOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
179
+ /**
180
+ * @method
181
+ * @name upbit#editOrder
182
+ * @see https://docs.upbit.com/reference/%EC%B7%A8%EC%86%8C-%ED%9B%84-%EC%9E%AC%EC%A3%BC%EB%AC%B8
183
+ * @description canceled existing order and create new order. It's only generated same side and symbol as the canceled order. it returns the data of the canceled order, except for `new_order_uuid` and `new_identifier`. to get the details of the new order, use `fetchOrder(new_order_uuid)`.
184
+ * @param {string} id the uuid of the previous order you want to edit.
185
+ * @param {string} symbol the symbol of the new order. it must be the same as the symbol of the previous order.
186
+ * @param {string} type the type of the new order. only limit or market is accepted. if params.newOrdType is set to best, a best-type order will be created regardless of the value of type.
187
+ * @param {string} side the side of the new order. it must be the same as the side of the previous order.
188
+ * @param {number} amount the amount of the asset you want to buy or sell. It could be overridden by specifying the new_volume parameter in params.
189
+ * @param {number} price the price of the asset you want to buy or sell. It could be overridden by specifying the new_price parameter in params.
190
+ * @param {object} [params] extra parameters specific to the exchange API endpoint.
191
+ * @param {string} [params.clientOrderId] to identify the previous order, either the id or this field is required in this method.
192
+ * @param {float} [params.cost] for market buy and best buy orders, the quote quantity that can be used as an alternative for the amount.
193
+ * @param {string} [params.newTimeInForce] 'IOC' or 'FOK'. only for limit or best type orders. this field is required when the order type is 'best'.
194
+ * @param {string} [params.newClientOrderId] the order ID that the user can define.
195
+ * @param {string} [params.newOrdType] this field only accepts limit, price, market, or best. You can refer to the Upbit developer documentation for details on how to use this field.
196
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
197
+ */
198
+ editOrder(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
169
199
  /**
170
200
  * @method
171
201
  * @name upbit#fetchDeposits
package/js/src/upbit.js CHANGED
@@ -24,7 +24,7 @@ export default class upbit extends Exchange {
24
24
  'name': 'Upbit',
25
25
  'countries': ['KR'],
26
26
  'version': 'v1',
27
- 'rateLimit': 1000,
27
+ 'rateLimit': 50,
28
28
  'pro': true,
29
29
  // new metainfo interface
30
30
  'has': {
@@ -41,6 +41,7 @@ export default class upbit extends Exchange {
41
41
  'createMarketOrderWithCost': false,
42
42
  'createMarketSellOrderWithCost': false,
43
43
  'createOrder': true,
44
+ 'editOrder': true,
44
45
  'fetchBalance': true,
45
46
  'fetchCanceledOrders': true,
46
47
  'fetchClosedOrders': true,
@@ -71,7 +72,7 @@ export default class upbit extends Exchange {
71
72
  'fetchTickers': true,
72
73
  'fetchTrades': true,
73
74
  'fetchTradingFee': true,
74
- 'fetchTradingFees': false,
75
+ 'fetchTradingFees': true,
75
76
  'fetchTransactions': false,
76
77
  'fetchWithdrawal': true,
77
78
  'fetchWithdrawals': true,
@@ -79,6 +80,7 @@ export default class upbit extends Exchange {
79
80
  'withdraw': true,
80
81
  },
81
82
  'timeframes': {
83
+ '1s': 'seconds',
82
84
  '1m': 'minutes',
83
85
  '3m': 'minutes',
84
86
  '5m': 'minutes',
@@ -90,6 +92,7 @@ export default class upbit extends Exchange {
90
92
  '1d': 'days',
91
93
  '1w': 'weeks',
92
94
  '1M': 'months',
95
+ '1y': 'years',
93
96
  },
94
97
  'hostname': 'api.upbit.com',
95
98
  'urls': {
@@ -103,54 +106,70 @@ export default class upbit extends Exchange {
103
106
  'fees': 'https://upbit.com/service_center/guide',
104
107
  },
105
108
  'api': {
109
+ // 'endpoint','API Cost'
110
+ // cost = 1000 / (rateLimit * RPS)
106
111
  'public': {
107
- 'get': [
108
- 'market/all',
109
- 'candles/{timeframe}',
110
- 'candles/{timeframe}/{unit}',
111
- 'candles/minutes/{unit}',
112
- 'candles/minutes/1',
113
- 'candles/minutes/3',
114
- 'candles/minutes/5',
115
- 'candles/minutes/10',
116
- 'candles/minutes/15',
117
- 'candles/minutes/30',
118
- 'candles/minutes/60',
119
- 'candles/minutes/240',
120
- 'candles/days',
121
- 'candles/weeks',
122
- 'candles/months',
123
- 'trades/ticks',
124
- 'ticker',
125
- 'orderbook',
126
- ],
112
+ 'get': {
113
+ 'market/all': 2,
114
+ 'candles/{timeframe}': 2,
115
+ 'candles/{timeframe}/{unit}': 2,
116
+ 'candles/seconds': 2,
117
+ 'candles/minutes/{unit}': 2,
118
+ 'candles/minutes/1': 2,
119
+ 'candles/minutes/3': 2,
120
+ 'candles/minutes/5': 2,
121
+ 'candles/minutes/10': 2,
122
+ 'candles/minutes/15': 2,
123
+ 'candles/minutes/30': 2,
124
+ 'candles/minutes/60': 2,
125
+ 'candles/minutes/240': 2,
126
+ 'candles/days': 2,
127
+ 'candles/weeks': 2,
128
+ 'candles/months': 2,
129
+ 'candles/years': 2,
130
+ 'trades/ticks': 2,
131
+ 'ticker': 2,
132
+ 'ticker/all': 2,
133
+ 'orderbook': 2,
134
+ 'orderbook/supported_levels': 2, // Upbit KR only
135
+ },
127
136
  },
128
137
  'private': {
129
- 'get': [
130
- 'accounts',
131
- 'orders/chance',
132
- 'order',
133
- 'orders',
134
- 'orders/closed',
135
- 'orders/open',
136
- 'orders/uuids',
137
- 'withdraws',
138
- 'withdraw',
139
- 'withdraws/chance',
140
- 'deposits',
141
- 'deposit',
142
- 'deposits/coin_addresses',
143
- 'deposits/coin_address',
144
- ],
145
- 'post': [
146
- 'orders',
147
- 'withdraws/coin',
148
- 'withdraws/krw',
149
- 'deposits/generate_coin_address',
150
- ],
151
- 'delete': [
152
- 'order',
153
- ],
138
+ 'get': {
139
+ 'accounts': 0.67,
140
+ 'orders/chance': 0.67,
141
+ 'order': 0.67,
142
+ 'orders/closed': 0.67,
143
+ 'orders/open': 0.67,
144
+ 'orders/uuids': 0.67,
145
+ 'withdraws': 0.67,
146
+ 'withdraw': 0.67,
147
+ 'withdraws/chance': 0.67,
148
+ 'withdraws/coin_addresses': 0.67,
149
+ 'deposits': 0.67,
150
+ 'deposits/chance/coin': 0.67,
151
+ 'deposit': 0.67,
152
+ 'deposits/coin_addresses': 0.67,
153
+ 'deposits/coin_address': 0.67,
154
+ 'travel_rule/vasps': 0.67,
155
+ 'status/wallet': 0.67,
156
+ 'api_keys': 0.67, // Upbit KR only
157
+ },
158
+ 'post': {
159
+ 'orders': 2.5,
160
+ 'orders/cancel_and_new': 2.5,
161
+ 'withdraws/coin': 0.67,
162
+ 'withdraws/krw': 0.67,
163
+ 'deposits/krw': 0.67,
164
+ 'deposits/generate_coin_address': 0.67,
165
+ 'travel_rule/deposit/uuid': 0.67,
166
+ 'travel_rule/deposit/txid': 0.67, // RPS: 30, but each deposit can only be queried once every 10 minutes
167
+ },
168
+ 'delete': {
169
+ 'order': 0.67,
170
+ 'orders/open': 40,
171
+ 'orders/uuids': 0.67,
172
+ },
154
173
  },
155
174
  },
156
175
  'fees': {
@@ -253,8 +272,6 @@ export default class upbit extends Exchange {
253
272
  },
254
273
  'options': {
255
274
  'createMarketBuyOrderRequiresPrice': true,
256
- 'fetchTickersMaxLength': 4096,
257
- 'fetchOrderBooksMaxLength': 4096,
258
275
  'tradingFeesByQuoteCurrency': {
259
276
  'KRW': 0.0005,
260
277
  },
@@ -609,11 +626,6 @@ export default class upbit extends Exchange {
609
626
  let ids = undefined;
610
627
  if (symbols === undefined) {
611
628
  ids = this.ids.join(',');
612
- // max URL length is 2083 symbols, including http schema, hostname, tld, etc...
613
- if (ids.length > this.options['fetchOrderBooksMaxLength']) {
614
- const numIds = this.ids.length;
615
- throw new ExchangeError(this.id + ' fetchOrderBooks() has ' + numIds.toString() + ' symbols (' + ids.length.toString() + ' characters) exceeding max URL length (' + this.options['fetchOrderBooksMaxLength'].toString() + ' characters), you are required to specify a list of symbols in the first argument to fetchOrderBooks');
616
- }
617
629
  }
618
630
  else {
619
631
  ids = this.marketIds(symbols);
@@ -753,11 +765,6 @@ export default class upbit extends Exchange {
753
765
  let ids = undefined;
754
766
  if (symbols === undefined) {
755
767
  ids = this.ids.join(',');
756
- // max URL length is 2083 symbols, including http schema, hostname, tld, etc...
757
- if (ids.length > this.options['fetchTickersMaxLength']) {
758
- const numIds = this.ids.length;
759
- throw new ExchangeError(this.id + ' fetchTickers() has ' + numIds.toString() + ' symbols exceeding max URL length, you are required to specify a list of symbols in the first argument to fetchTickers');
760
- }
761
768
  }
762
769
  else {
763
770
  ids = this.marketIds(symbols);
@@ -999,6 +1006,29 @@ export default class upbit extends Exchange {
999
1006
  'tierBased': false,
1000
1007
  };
1001
1008
  }
1009
+ /**
1010
+ * @method
1011
+ * @name upbit#fetchTradingFees
1012
+ * @description fetch the trading fees for markets
1013
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1014
+ * @returns {object} a [trading fee structure]{@link https://docs.ccxt.com/#/?id=trading-fee-structure}
1015
+ */
1016
+ async fetchTradingFees(params = {}) {
1017
+ await this.loadMarkets();
1018
+ const fetchMarketResponse = await this.fetchMarkets(params);
1019
+ const response = {};
1020
+ for (let i = 0; i < fetchMarketResponse.length; i++) {
1021
+ const element = {};
1022
+ element['maker'] = this.safeNumber(fetchMarketResponse[i], 'maker');
1023
+ element['taker'] = this.safeNumber(fetchMarketResponse[i], 'taker');
1024
+ element['symbol'] = this.safeString(fetchMarketResponse[i], 'symbol');
1025
+ element['percentage'] = true;
1026
+ element['tierBased'] = false;
1027
+ element['info'] = fetchMarketResponse[i];
1028
+ response[this.safeString(fetchMarketResponse[i], 'symbol')] = element;
1029
+ }
1030
+ return response;
1031
+ }
1002
1032
  parseOHLCV(ohlcv, market = undefined) {
1003
1033
  //
1004
1034
  // {
@@ -1094,6 +1124,30 @@ export default class upbit extends Exchange {
1094
1124
  //
1095
1125
  return this.parseOHLCVs(response, market, timeframe, since, limit);
1096
1126
  }
1127
+ calcOrderPrice(symbol, amount, price = undefined, params = {}) {
1128
+ let quoteAmount = undefined;
1129
+ const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice');
1130
+ const cost = this.safeString(params, 'cost');
1131
+ if (cost !== undefined) {
1132
+ quoteAmount = this.costToPrecision(symbol, cost);
1133
+ }
1134
+ else if (createMarketBuyOrderRequiresPrice) {
1135
+ if (price === undefined || amount === undefined) {
1136
+ throw new InvalidOrder(this.id + ' createOrder() requires the price and amount argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend (quote quantity) in the amount argument');
1137
+ }
1138
+ const amountString = this.numberToString(amount);
1139
+ const priceString = this.numberToString(price);
1140
+ const costRequest = Precise.stringMul(amountString, priceString);
1141
+ quoteAmount = this.costToPrecision(symbol, costRequest);
1142
+ }
1143
+ else {
1144
+ if (amount === undefined) {
1145
+ throw new ArgumentsRequired(this.id + ' When createMarketBuyOrderRequiresPrice is false, "amount" is required and should be the total quote amount to spend.');
1146
+ }
1147
+ quoteAmount = this.costToPrecision(symbol, amount);
1148
+ }
1149
+ return quoteAmount;
1150
+ }
1097
1151
  /**
1098
1152
  * @method
1099
1153
  * @name upbit#createOrder
@@ -1101,13 +1155,14 @@ export default class upbit extends Exchange {
1101
1155
  * @see https://docs.upbit.com/reference/%EC%A3%BC%EB%AC%B8%ED%95%98%EA%B8%B0
1102
1156
  * @see https://global-docs.upbit.com/reference/order
1103
1157
  * @param {string} symbol unified symbol of the market to create an order in
1104
- * @param {string} type 'market' or 'limit'
1158
+ * @param {string} type supports 'market' and 'limit'. if params.ordType is set to best, a best-type order will be created regardless of the value of type.
1105
1159
  * @param {string} side 'buy' or 'sell'
1106
1160
  * @param {float} amount how much you want to trade in units of the base currency
1107
1161
  * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1108
1162
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1109
- * @param {float} [params.cost] for market buy orders, the quote quantity that can be used as an alternative for the amount
1110
- * @param {string} [params.timeInForce] 'IOC' or 'FOK'
1163
+ * @param {float} [params.cost] for market buy and best buy orders, the quote quantity that can be used as an alternative for the amount
1164
+ * @param {string} [params.ordType] this field can be used to place a ‘best’ type order
1165
+ * @param {string} [params.timeInForce] 'IOC' or 'FOK'. only for limit or best type orders. this field is required when the order type is 'best'.
1111
1166
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1112
1167
  */
1113
1168
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
@@ -1121,58 +1176,69 @@ export default class upbit extends Exchange {
1121
1176
  orderSide = 'ask';
1122
1177
  }
1123
1178
  else {
1124
- throw new InvalidOrder(this.id + ' createOrder() allows buy or sell side only!');
1179
+ throw new InvalidOrder(this.id + ' createOrder() supports only buy or sell in the side argument.');
1125
1180
  }
1126
1181
  const request = {
1127
1182
  'market': market['id'],
1128
1183
  'side': orderSide,
1129
1184
  };
1130
1185
  if (type === 'limit') {
1186
+ if (price === undefined || amount === undefined) {
1187
+ throw new ArgumentsRequired(this.id + ' the limit type order in createOrder() is required price and amount.');
1188
+ }
1189
+ request['ord_type'] = 'limit';
1131
1190
  request['price'] = this.priceToPrecision(symbol, price);
1191
+ request['volume'] = this.amountToPrecision(symbol, amount);
1132
1192
  }
1133
- if ((type === 'market') && (side === 'buy')) {
1134
- // for market buy it requires the amount of quote currency to spend
1135
- let quoteAmount = undefined;
1136
- let createMarketBuyOrderRequiresPrice = true;
1137
- [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
1138
- const cost = this.safeNumber(params, 'cost');
1139
- params = this.omit(params, 'cost');
1140
- if (cost !== undefined) {
1141
- quoteAmount = this.costToPrecision(symbol, cost);
1142
- }
1143
- else if (createMarketBuyOrderRequiresPrice) {
1144
- if (price === undefined) {
1145
- throw new InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend (quote quantity) in the amount argument');
1146
- }
1147
- else {
1148
- const amountString = this.numberToString(amount);
1149
- const priceString = this.numberToString(price);
1150
- const costRequest = Precise.stringMul(amountString, priceString);
1151
- quoteAmount = this.costToPrecision(symbol, costRequest);
1152
- }
1193
+ else if (type === 'market') {
1194
+ if (side === 'buy') {
1195
+ request['ord_type'] = 'price';
1196
+ const orderPrice = this.calcOrderPrice(symbol, amount, price, params);
1197
+ request['price'] = orderPrice;
1153
1198
  }
1154
1199
  else {
1155
- quoteAmount = this.costToPrecision(symbol, amount);
1200
+ if (amount === undefined) {
1201
+ throw new ArgumentsRequired(this.id + ' the market sell type order in createOrder() is required amount.');
1202
+ }
1203
+ request['ord_type'] = 'market';
1204
+ request['volume'] = this.amountToPrecision(symbol, amount);
1156
1205
  }
1157
- request['ord_type'] = 'price';
1158
- request['price'] = quoteAmount;
1159
1206
  }
1160
1207
  else {
1161
- request['ord_type'] = type;
1162
- request['volume'] = this.amountToPrecision(symbol, amount);
1208
+ throw new InvalidOrder(this.id + ' createOrder() supports only limit or market types in the type argument.');
1163
1209
  }
1164
- const clientOrderId = this.safeString2(params, 'clientOrderId', 'identifier');
1210
+ const customType = this.safeString2(params, 'ordType', 'ord_type');
1211
+ if (customType === 'best') {
1212
+ params = this.omit(params, ['ordType', 'ord_type']);
1213
+ request['ord_type'] = 'best';
1214
+ if (side === 'buy') {
1215
+ const orderPrice = this.calcOrderPrice(symbol, amount, price, params);
1216
+ request['price'] = orderPrice;
1217
+ }
1218
+ else {
1219
+ if (amount === undefined) {
1220
+ throw new ArgumentsRequired(this.id + ' the best sell type order in createOrder() is required amount.');
1221
+ }
1222
+ request['volume'] = this.amountToPrecision(symbol, amount);
1223
+ }
1224
+ }
1225
+ const clientOrderId = this.safeString(params, 'clientOrderId');
1165
1226
  if (clientOrderId !== undefined) {
1166
1227
  request['identifier'] = clientOrderId;
1167
1228
  }
1168
- if (type !== 'market') {
1229
+ if (request['ord_type'] !== 'market' && request['ord_type'] !== 'price') {
1169
1230
  const timeInForce = this.safeStringLower2(params, 'timeInForce', 'time_in_force');
1170
- params = this.omit(params, 'timeInForce');
1231
+ params = this.omit(params, ['timeInForce']);
1171
1232
  if (timeInForce !== undefined) {
1172
1233
  request['time_in_force'] = timeInForce;
1173
1234
  }
1235
+ else {
1236
+ if (request['ord_type'] === 'best') {
1237
+ throw new ArgumentsRequired(this.id + ' the best type order in createOrder() is required timeInForce.');
1238
+ }
1239
+ }
1174
1240
  }
1175
- params = this.omit(params, ['clientOrderId', 'identifier']);
1241
+ params = this.omit(params, ['clientOrderId', 'cost']);
1176
1242
  const response = await this.privatePostOrders(this.extend(request, params));
1177
1243
  //
1178
1244
  // {
@@ -1233,6 +1299,125 @@ export default class upbit extends Exchange {
1233
1299
  //
1234
1300
  return this.parseOrder(response);
1235
1301
  }
1302
+ /**
1303
+ * @method
1304
+ * @name upbit#editOrder
1305
+ * @see https://docs.upbit.com/reference/%EC%B7%A8%EC%86%8C-%ED%9B%84-%EC%9E%AC%EC%A3%BC%EB%AC%B8
1306
+ * @description canceled existing order and create new order. It's only generated same side and symbol as the canceled order. it returns the data of the canceled order, except for `new_order_uuid` and `new_identifier`. to get the details of the new order, use `fetchOrder(new_order_uuid)`.
1307
+ * @param {string} id the uuid of the previous order you want to edit.
1308
+ * @param {string} symbol the symbol of the new order. it must be the same as the symbol of the previous order.
1309
+ * @param {string} type the type of the new order. only limit or market is accepted. if params.newOrdType is set to best, a best-type order will be created regardless of the value of type.
1310
+ * @param {string} side the side of the new order. it must be the same as the side of the previous order.
1311
+ * @param {number} amount the amount of the asset you want to buy or sell. It could be overridden by specifying the new_volume parameter in params.
1312
+ * @param {number} price the price of the asset you want to buy or sell. It could be overridden by specifying the new_price parameter in params.
1313
+ * @param {object} [params] extra parameters specific to the exchange API endpoint.
1314
+ * @param {string} [params.clientOrderId] to identify the previous order, either the id or this field is required in this method.
1315
+ * @param {float} [params.cost] for market buy and best buy orders, the quote quantity that can be used as an alternative for the amount.
1316
+ * @param {string} [params.newTimeInForce] 'IOC' or 'FOK'. only for limit or best type orders. this field is required when the order type is 'best'.
1317
+ * @param {string} [params.newClientOrderId] the order ID that the user can define.
1318
+ * @param {string} [params.newOrdType] this field only accepts limit, price, market, or best. You can refer to the Upbit developer documentation for details on how to use this field.
1319
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1320
+ */
1321
+ async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1322
+ await this.loadMarkets();
1323
+ const request = {};
1324
+ const prevClientOrderId = this.safeString(params, 'clientOrderId');
1325
+ params = this.omit(params, 'clientOrderId');
1326
+ if (id !== undefined) {
1327
+ request['prev_order_uuid'] = id;
1328
+ }
1329
+ else if (prevClientOrderId !== undefined) {
1330
+ request['prev_order_identifier'] = prevClientOrderId;
1331
+ }
1332
+ else {
1333
+ throw new ArgumentsRequired(this.id + ' editOrder() is required id or clientOrderId.');
1334
+ }
1335
+ if (type === 'limit') {
1336
+ if (price === undefined || amount === undefined) {
1337
+ throw new ArgumentsRequired(this.id + ' editOrder() is required price and amount to create limit type order.');
1338
+ }
1339
+ request['new_ord_type'] = 'limit';
1340
+ request['new_price'] = this.priceToPrecision(symbol, price);
1341
+ request['new_volume'] = this.amountToPrecision(symbol, amount);
1342
+ }
1343
+ else if (type === 'market') {
1344
+ if (side === 'buy') {
1345
+ request['new_ord_type'] = 'price';
1346
+ const orderPrice = this.calcOrderPrice(symbol, amount, price, params);
1347
+ request['new_price'] = orderPrice;
1348
+ }
1349
+ else {
1350
+ if (amount === undefined) {
1351
+ throw new ArgumentsRequired(this.id + ' editOrder() is required amount to create market sell type order.');
1352
+ }
1353
+ request['new_ord_type'] = 'market';
1354
+ request['new_volume'] = this.amountToPrecision(symbol, amount);
1355
+ }
1356
+ }
1357
+ else {
1358
+ throw new InvalidOrder(this.id + ' editOrder() supports only limit or market types in the type argument.');
1359
+ }
1360
+ const customType = this.safeString2(params, 'newOrdType', 'new_ord_type');
1361
+ if (customType === 'best') {
1362
+ params = this.omit(params, ['newOrdType', 'new_ord_type']);
1363
+ request['new_ord_type'] = 'best';
1364
+ if (side === 'buy') {
1365
+ const orderPrice = this.calcOrderPrice(symbol, amount, price, params);
1366
+ request['new_price'] = orderPrice;
1367
+ }
1368
+ else {
1369
+ if (amount === undefined) {
1370
+ throw new ArgumentsRequired(this.id + ' editOrder() is required amount to create best sell order.');
1371
+ }
1372
+ request['new_volume'] = this.amountToPrecision(symbol, amount);
1373
+ }
1374
+ }
1375
+ const clientOrderId = this.safeString(params, 'newClientOrderId');
1376
+ if (clientOrderId !== undefined) {
1377
+ request['new_identifier'] = clientOrderId;
1378
+ }
1379
+ if (request['new_ord_type'] !== 'market' && request['new_ord_type'] !== 'price') {
1380
+ const timeInForce = this.safeStringLower2(params, 'newTimeInForce', 'new_time_in_force');
1381
+ params = this.omit(params, ['newTimeInForce', 'new_time_in_force']);
1382
+ if (timeInForce !== undefined) {
1383
+ request['new_time_in_force'] = timeInForce;
1384
+ }
1385
+ else {
1386
+ if (request['new_ord_type'] === 'best') {
1387
+ throw new ArgumentsRequired(this.id + ' the best type order is required timeInForce.');
1388
+ }
1389
+ }
1390
+ }
1391
+ params = this.omit(params, ['newClientOrderId', 'cost']);
1392
+ // console.log ('check the each request params: ', request);
1393
+ const response = await this.privatePostOrdersCancelAndNew(this.extend(request, params));
1394
+ // {
1395
+ // uuid: '63b38774-27db-4439-ac20-1be16a24d18e', //previous order data
1396
+ // side: 'bid', //previous order data
1397
+ // ord_type: 'limit', //previous order data
1398
+ // price: '100000000', //previous order data
1399
+ // state: 'wait', //previous order data
1400
+ // market: 'KRW-BTC', //previous order data
1401
+ // created_at: '2025-04-01T15:30:47+09:00', //previous order data
1402
+ // volume: '0.00008', //previous order data
1403
+ // remaining_volume: '0.00008', //previous order data
1404
+ // reserved_fee: '4', //previous order data
1405
+ // remaining_fee: '4', //previous order data
1406
+ // paid_fee: '0', //previous order data
1407
+ // locked: '8004', //previous order data
1408
+ // executed_volume: '0', //previous order data
1409
+ // trades_count: '0', //previous order data
1410
+ // identifier: '21', //previous order data
1411
+ // new_order_uuid: 'cb1cce56-6237-4a78-bc11-4cfffc1bb4c2', // new order data
1412
+ // new_order_identifier: '22' // new order data
1413
+ // }
1414
+ const result = {};
1415
+ result['uuid'] = this.safeString(response, 'new_order_uuid');
1416
+ result['identifier'] = this.safeString(response, 'new_order_identifier');
1417
+ result['side'] = this.safeString(response, 'side');
1418
+ result['market'] = this.safeString(response, 'market');
1419
+ return this.parseOrder(result);
1420
+ }
1236
1421
  /**
1237
1422
  * @method
1238
1423
  * @name upbit#fetchDeposits
@@ -1553,6 +1738,26 @@ export default class upbit extends Exchange {
1553
1738
  // "time_in_force": "ioc"
1554
1739
  // }
1555
1740
  //
1741
+ // {
1742
+ // uuid: '63b38774-27db-4439-ac20-1be16a24d18e',
1743
+ // side: 'bid',
1744
+ // ord_type: 'limit',
1745
+ // price: '100000000',
1746
+ // state: 'wait',
1747
+ // market: 'KRW-BTC',
1748
+ // created_at: '2025-04-01T15:30:47+09:00',
1749
+ // volume: '0.00008',
1750
+ // remaining_volume: '0.00008',
1751
+ // reserved_fee: '4',
1752
+ // remaining_fee: '4',
1753
+ // paid_fee: '0',
1754
+ // locked: '8004',
1755
+ // executed_volume: '0',
1756
+ // trades_count: '0',
1757
+ // identifier: '21',
1758
+ // new_order_uuid: 'cb1cce56-6237-4a78-bc11-4cfffc1bb4c2',
1759
+ // new_order_identifier: '22'
1760
+ // }
1556
1761
  const id = this.safeString(order, 'uuid');
1557
1762
  let side = this.safeString(order, 'side');
1558
1763
  if (side === 'bid') {
@@ -1561,6 +1766,7 @@ export default class upbit extends Exchange {
1561
1766
  else {
1562
1767
  side = 'sell';
1563
1768
  }
1769
+ const identifier = this.safeString(order, 'identifier');
1564
1770
  let type = this.safeString(order, 'ord_type');
1565
1771
  const timestamp = this.parse8601(this.safeString(order, 'created_at'));
1566
1772
  const status = this.parseOrderStatus(this.safeString(order, 'state'));
@@ -1617,7 +1823,7 @@ export default class upbit extends Exchange {
1617
1823
  return this.safeOrder({
1618
1824
  'info': order,
1619
1825
  'id': id,
1620
- 'clientOrderId': undefined,
1826
+ 'clientOrderId': identifier,
1621
1827
  'timestamp': timestamp,
1622
1828
  'datetime': this.iso8601(timestamp),
1623
1829
  'lastTradeTimestamp': lastTradeTimestamp,