ccxt 4.4.72 → 4.4.73
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.
- package/README.md +4 -4
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +1 -6
- package/dist/cjs/src/ace.js +42 -7
- package/dist/cjs/src/alpaca.js +46 -0
- package/dist/cjs/src/ascendex.js +1 -1
- package/dist/cjs/src/base/Exchange.js +6 -16
- package/dist/cjs/src/binance.js +20 -15
- package/dist/cjs/src/bit2c.js +11 -0
- package/dist/cjs/src/bitget.js +7 -5
- package/dist/cjs/src/bitrue.js +1 -1
- package/dist/cjs/src/bybit.js +9 -0
- package/dist/cjs/src/defx.js +1 -1
- package/dist/cjs/src/derive.js +2 -0
- package/dist/cjs/src/pro/bitget.js +1 -1
- package/js/ccxt.d.ts +2 -8
- package/js/ccxt.js +2 -6
- package/js/src/ace.js +42 -7
- package/js/src/alpaca.js +46 -0
- package/js/src/ascendex.js +1 -1
- package/js/src/base/Exchange.d.ts +1 -1
- package/js/src/base/Exchange.js +6 -16
- package/js/src/binance.js +20 -15
- package/js/src/bit2c.js +11 -0
- package/js/src/bitget.js +7 -5
- package/js/src/bitrue.js +1 -1
- package/js/src/bybit.d.ts +4 -20
- package/js/src/bybit.js +9 -0
- package/js/src/defx.js +1 -1
- package/js/src/derive.js +2 -0
- package/js/src/pro/bitget.d.ts +1 -1
- package/js/src/pro/bitget.js +1 -1
- package/package.json +1 -1
- package/js/src/bitfinex1.d.ts +0 -297
- package/js/src/bitfinex1.js +0 -1770
- package/js/src/pro/bitfinex1.d.ts +0 -67
- package/js/src/pro/bitfinex1.js +0 -676
- package/js/src/pro/bitfinex2.d.ts +0 -99
- package/js/src/pro/bitfinex2.js +0 -1165
package/js/src/bitfinex1.js
DELETED
|
@@ -1,1770 +0,0 @@
|
|
|
1
|
-
// ----------------------------------------------------------------------------
|
|
2
|
-
|
|
3
|
-
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
|
4
|
-
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
|
5
|
-
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
|
|
6
|
-
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
import Exchange from './abstract/bitfinex1.js';
|
|
9
|
-
import { NotSupported, RateLimitExceeded, AuthenticationError, PermissionDenied, ArgumentsRequired, ExchangeError, ExchangeNotAvailable, InsufficientFunds, InvalidOrder, OrderNotFound, InvalidNonce, BadSymbol } from './base/errors.js';
|
|
10
|
-
import { Precise } from './base/Precise.js';
|
|
11
|
-
import { SIGNIFICANT_DIGITS, DECIMAL_PLACES, TRUNCATE, ROUND } from './base/functions/number.js';
|
|
12
|
-
import { sha384 } from './static_dependencies/noble-hashes/sha512.js';
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
/**
|
|
15
|
-
* @class bitfinex1
|
|
16
|
-
* @augments Exchange
|
|
17
|
-
*/
|
|
18
|
-
export default class bitfinex1 extends Exchange {
|
|
19
|
-
describe() {
|
|
20
|
-
return this.deepExtend(super.describe(), {
|
|
21
|
-
'id': 'bitfinex1',
|
|
22
|
-
'name': 'Bitfinex',
|
|
23
|
-
'countries': ['VG'],
|
|
24
|
-
'version': 'v1',
|
|
25
|
-
// cheapest is 90 requests a minute = 1.5 requests per second on average => ( 1000ms / 1.5) = 666.666 ms between requests on average
|
|
26
|
-
'rateLimit': 666.666,
|
|
27
|
-
'pro': true,
|
|
28
|
-
// new metainfo interface
|
|
29
|
-
'has': {
|
|
30
|
-
'CORS': undefined,
|
|
31
|
-
'spot': true,
|
|
32
|
-
'margin': undefined,
|
|
33
|
-
'swap': undefined,
|
|
34
|
-
'future': undefined,
|
|
35
|
-
'option': undefined,
|
|
36
|
-
'cancelAllOrders': true,
|
|
37
|
-
'cancelOrder': true,
|
|
38
|
-
'createDepositAddress': true,
|
|
39
|
-
'createOrder': true,
|
|
40
|
-
'editOrder': true,
|
|
41
|
-
'fetchBalance': true,
|
|
42
|
-
'fetchClosedOrders': true,
|
|
43
|
-
'fetchDepositAddress': true,
|
|
44
|
-
'fetchDepositAddresses': false,
|
|
45
|
-
'fetchDepositAddressesByNetwork': false,
|
|
46
|
-
'fetchDeposits': false,
|
|
47
|
-
'fetchDepositsWithdrawals': true,
|
|
48
|
-
'fetchDepositWithdrawFee': 'emulated',
|
|
49
|
-
'fetchDepositWithdrawFees': true,
|
|
50
|
-
'fetchFundingHistory': false,
|
|
51
|
-
'fetchFundingRate': false,
|
|
52
|
-
'fetchFundingRateHistory': false,
|
|
53
|
-
'fetchFundingRates': false,
|
|
54
|
-
'fetchIndexOHLCV': false,
|
|
55
|
-
'fetchLeverageTiers': false,
|
|
56
|
-
'fetchMarginMode': false,
|
|
57
|
-
'fetchMarkets': true,
|
|
58
|
-
'fetchMarkOHLCV': false,
|
|
59
|
-
'fetchMyTrades': true,
|
|
60
|
-
'fetchOHLCV': true,
|
|
61
|
-
'fetchOpenOrders': true,
|
|
62
|
-
'fetchOrder': true,
|
|
63
|
-
'fetchOrderBook': true,
|
|
64
|
-
'fetchPositionMode': false,
|
|
65
|
-
'fetchPositions': true,
|
|
66
|
-
'fetchPremiumIndexOHLCV': false,
|
|
67
|
-
'fetchTicker': true,
|
|
68
|
-
'fetchTickers': true,
|
|
69
|
-
'fetchTime': false,
|
|
70
|
-
'fetchTrades': true,
|
|
71
|
-
'fetchTradingFee': false,
|
|
72
|
-
'fetchTradingFees': true,
|
|
73
|
-
'fetchTransactionFees': true,
|
|
74
|
-
'fetchTransactions': 'emulated',
|
|
75
|
-
'transfer': true,
|
|
76
|
-
'withdraw': true,
|
|
77
|
-
},
|
|
78
|
-
'timeframes': {
|
|
79
|
-
'1m': '1m',
|
|
80
|
-
'5m': '5m',
|
|
81
|
-
'15m': '15m',
|
|
82
|
-
'30m': '30m',
|
|
83
|
-
'1h': '1h',
|
|
84
|
-
'3h': '3h',
|
|
85
|
-
'4h': '4h',
|
|
86
|
-
'6h': '6h',
|
|
87
|
-
'12h': '12h',
|
|
88
|
-
'1d': '1D',
|
|
89
|
-
'1w': '7D',
|
|
90
|
-
'2w': '14D',
|
|
91
|
-
'1M': '1M',
|
|
92
|
-
},
|
|
93
|
-
'urls': {
|
|
94
|
-
'logo': 'https://github.com/user-attachments/assets/9147c6c5-7197-481e-827b-7483672bb0e9',
|
|
95
|
-
'api': {
|
|
96
|
-
'v2': 'https://api-pub.bitfinex.com',
|
|
97
|
-
'public': 'https://api.bitfinex.com',
|
|
98
|
-
'private': 'https://api.bitfinex.com',
|
|
99
|
-
},
|
|
100
|
-
'www': 'https://www.bitfinex.com',
|
|
101
|
-
'referral': 'https://www.bitfinex.com/?refcode=P61eYxFL',
|
|
102
|
-
'doc': [
|
|
103
|
-
'https://docs.bitfinex.com/v1/docs',
|
|
104
|
-
'https://github.com/bitfinexcom/bitfinex-api-node',
|
|
105
|
-
],
|
|
106
|
-
},
|
|
107
|
-
'api': {
|
|
108
|
-
// v2 symbol ids require a 't' prefix
|
|
109
|
-
// just the public part of it (use bitfinex2 for everything else)
|
|
110
|
-
'v2': {
|
|
111
|
-
'get': {
|
|
112
|
-
'platform/status': 3,
|
|
113
|
-
'tickers': 1,
|
|
114
|
-
'ticker/{symbol}': 1,
|
|
115
|
-
'tickers/hist': 1,
|
|
116
|
-
'trades/{symbol}/hist': 1,
|
|
117
|
-
'book/{symbol}/{precision}': 0.375,
|
|
118
|
-
'book/{symbol}/P0': 0.375,
|
|
119
|
-
'book/{symbol}/P1': 0.375,
|
|
120
|
-
'book/{symbol}/P2': 0.375,
|
|
121
|
-
'book/{symbol}/P3': 0.375,
|
|
122
|
-
'book/{symbol}/R0': 0.375,
|
|
123
|
-
'stats1/{key}:{size}:{symbol}:{side}/{section}': 1,
|
|
124
|
-
'stats1/{key}:{size}:{symbol}/{section}': 1,
|
|
125
|
-
'stats1/{key}:{size}:{symbol}:long/last': 1,
|
|
126
|
-
'stats1/{key}:{size}:{symbol}:long/hist': 1,
|
|
127
|
-
'stats1/{key}:{size}:{symbol}:short/last': 1,
|
|
128
|
-
'stats1/{key}:{size}:{symbol}:short/hist': 1,
|
|
129
|
-
'candles/trade:{timeframe}:{symbol}/{section}': 1,
|
|
130
|
-
'candles/trade:{timeframe}:{symbol}/last': 1,
|
|
131
|
-
'candles/trade:{timeframe}:{symbol}/hist': 1,
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
'public': {
|
|
135
|
-
'get': {
|
|
136
|
-
'book/{symbol}': 1,
|
|
137
|
-
// 'candles/{symbol}':0,
|
|
138
|
-
'lendbook/{currency}': 6,
|
|
139
|
-
'lends/{currency}': 3,
|
|
140
|
-
'pubticker/{symbol}': 3,
|
|
141
|
-
'stats/{symbol}': 6,
|
|
142
|
-
'symbols': 18,
|
|
143
|
-
'symbols_details': 18,
|
|
144
|
-
'tickers': 1,
|
|
145
|
-
'trades/{symbol}': 3, // 60 requests a minute = 1 request per second => (1000ms / rateLimit) / 1 = 1.5 ... but only works if set to 3
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
'private': {
|
|
149
|
-
'post': {
|
|
150
|
-
'account_fees': 18,
|
|
151
|
-
'account_infos': 6,
|
|
152
|
-
'balances': 9.036,
|
|
153
|
-
'basket_manage': 6,
|
|
154
|
-
'credits': 6,
|
|
155
|
-
'deposit/new': 18,
|
|
156
|
-
'funding/close': 6,
|
|
157
|
-
'history': 6,
|
|
158
|
-
'history/movements': 6,
|
|
159
|
-
'key_info': 6,
|
|
160
|
-
'margin_infos': 3,
|
|
161
|
-
'mytrades': 3,
|
|
162
|
-
'mytrades_funding': 6,
|
|
163
|
-
'offer/cancel': 6,
|
|
164
|
-
'offer/new': 6,
|
|
165
|
-
'offer/status': 6,
|
|
166
|
-
'offers': 6,
|
|
167
|
-
'offers/hist': 90.03,
|
|
168
|
-
'order/cancel': 0.2,
|
|
169
|
-
'order/cancel/all': 0.2,
|
|
170
|
-
'order/cancel/multi': 0.2,
|
|
171
|
-
'order/cancel/replace': 0.2,
|
|
172
|
-
'order/new': 0.2,
|
|
173
|
-
'order/new/multi': 0.2,
|
|
174
|
-
'order/status': 0.2,
|
|
175
|
-
'orders': 0.2,
|
|
176
|
-
'orders/hist': 90.03,
|
|
177
|
-
'position/claim': 18,
|
|
178
|
-
'position/close': 18,
|
|
179
|
-
'positions': 18,
|
|
180
|
-
'summary': 18,
|
|
181
|
-
'taken_funds': 6,
|
|
182
|
-
'total_taken_funds': 6,
|
|
183
|
-
'transfer': 18,
|
|
184
|
-
'unused_taken_funds': 6,
|
|
185
|
-
'withdraw': 18,
|
|
186
|
-
},
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
'fees': {
|
|
190
|
-
'trading': {
|
|
191
|
-
'feeSide': 'get',
|
|
192
|
-
'tierBased': true,
|
|
193
|
-
'percentage': true,
|
|
194
|
-
'maker': this.parseNumber('0.001'),
|
|
195
|
-
'taker': this.parseNumber('0.002'),
|
|
196
|
-
'tiers': {
|
|
197
|
-
'taker': [
|
|
198
|
-
[this.parseNumber('0'), this.parseNumber('0.002')],
|
|
199
|
-
[this.parseNumber('500000'), this.parseNumber('0.002')],
|
|
200
|
-
[this.parseNumber('1000000'), this.parseNumber('0.002')],
|
|
201
|
-
[this.parseNumber('2500000'), this.parseNumber('0.002')],
|
|
202
|
-
[this.parseNumber('5000000'), this.parseNumber('0.002')],
|
|
203
|
-
[this.parseNumber('7500000'), this.parseNumber('0.002')],
|
|
204
|
-
[this.parseNumber('10000000'), this.parseNumber('0.0018')],
|
|
205
|
-
[this.parseNumber('15000000'), this.parseNumber('0.0016')],
|
|
206
|
-
[this.parseNumber('20000000'), this.parseNumber('0.0014')],
|
|
207
|
-
[this.parseNumber('25000000'), this.parseNumber('0.0012')],
|
|
208
|
-
[this.parseNumber('30000000'), this.parseNumber('0.001')],
|
|
209
|
-
],
|
|
210
|
-
'maker': [
|
|
211
|
-
[this.parseNumber('0'), this.parseNumber('0.001')],
|
|
212
|
-
[this.parseNumber('500000'), this.parseNumber('0.0008')],
|
|
213
|
-
[this.parseNumber('1000000'), this.parseNumber('0.0006')],
|
|
214
|
-
[this.parseNumber('2500000'), this.parseNumber('0.0004')],
|
|
215
|
-
[this.parseNumber('5000000'), this.parseNumber('0.0002')],
|
|
216
|
-
[this.parseNumber('7500000'), this.parseNumber('0')],
|
|
217
|
-
[this.parseNumber('10000000'), this.parseNumber('0')],
|
|
218
|
-
[this.parseNumber('15000000'), this.parseNumber('0')],
|
|
219
|
-
[this.parseNumber('20000000'), this.parseNumber('0')],
|
|
220
|
-
[this.parseNumber('25000000'), this.parseNumber('0')],
|
|
221
|
-
[this.parseNumber('30000000'), this.parseNumber('0')],
|
|
222
|
-
],
|
|
223
|
-
},
|
|
224
|
-
},
|
|
225
|
-
'funding': {
|
|
226
|
-
'tierBased': false,
|
|
227
|
-
'percentage': false,
|
|
228
|
-
// Actually deposit fees are free for larger deposits (> $1000 USD equivalent)
|
|
229
|
-
// these values below are deprecated, we should not hardcode fees and limits anymore
|
|
230
|
-
// to be reimplemented with bitfinex funding fees from their API or web endpoints
|
|
231
|
-
'deposit': {},
|
|
232
|
-
'withdraw': {},
|
|
233
|
-
},
|
|
234
|
-
},
|
|
235
|
-
// todo rewrite for https://api-pub.bitfinex.com//v2/conf/pub:map:tx:method
|
|
236
|
-
'commonCurrencies': {
|
|
237
|
-
'ALG': 'ALGO',
|
|
238
|
-
'AMP': 'AMPL',
|
|
239
|
-
'ATO': 'ATOM',
|
|
240
|
-
'BCHABC': 'XEC',
|
|
241
|
-
'BCHN': 'BCH',
|
|
242
|
-
'DAT': 'DATA',
|
|
243
|
-
'DOG': 'MDOGE',
|
|
244
|
-
'DSH': 'DASH',
|
|
245
|
-
// https://github.com/ccxt/ccxt/issues/7399
|
|
246
|
-
// https://coinmarketcap.com/currencies/pnetwork/
|
|
247
|
-
// https://en.cryptonomist.ch/blog/eidoo/the-edo-to-pnt-upgrade-what-you-need-to-know-updated/
|
|
248
|
-
'EDO': 'PNT',
|
|
249
|
-
'EUS': 'EURS',
|
|
250
|
-
'EUT': 'EURT',
|
|
251
|
-
'IDX': 'ID',
|
|
252
|
-
'IOT': 'IOTA',
|
|
253
|
-
'IQX': 'IQ',
|
|
254
|
-
'LUNA': 'LUNC',
|
|
255
|
-
'LUNA2': 'LUNA',
|
|
256
|
-
'MNA': 'MANA',
|
|
257
|
-
'ORS': 'ORS Group',
|
|
258
|
-
'PAS': 'PASS',
|
|
259
|
-
'QSH': 'QASH',
|
|
260
|
-
'QTM': 'QTUM',
|
|
261
|
-
'RBT': 'RBTC',
|
|
262
|
-
'SNG': 'SNGLS',
|
|
263
|
-
'STJ': 'STORJ',
|
|
264
|
-
'TERRAUST': 'USTC',
|
|
265
|
-
'TSD': 'TUSD',
|
|
266
|
-
'YGG': 'YEED',
|
|
267
|
-
'YYW': 'YOYOW',
|
|
268
|
-
'UDC': 'USDC',
|
|
269
|
-
'UST': 'USDT',
|
|
270
|
-
'VSY': 'VSYS',
|
|
271
|
-
'WAX': 'WAXP',
|
|
272
|
-
'XCH': 'XCHF',
|
|
273
|
-
'ZBT': 'ZB',
|
|
274
|
-
},
|
|
275
|
-
'exceptions': {
|
|
276
|
-
'exact': {
|
|
277
|
-
'temporarily_unavailable': ExchangeNotAvailable,
|
|
278
|
-
'Order could not be cancelled.': OrderNotFound,
|
|
279
|
-
'No such order found.': OrderNotFound,
|
|
280
|
-
'Order price must be positive.': InvalidOrder,
|
|
281
|
-
'Could not find a key matching the given X-BFX-APIKEY.': AuthenticationError,
|
|
282
|
-
'Key price should be a decimal number, e.g. "123.456"': InvalidOrder,
|
|
283
|
-
'Key amount should be a decimal number, e.g. "123.456"': InvalidOrder,
|
|
284
|
-
'ERR_RATE_LIMIT': RateLimitExceeded,
|
|
285
|
-
'Ratelimit': RateLimitExceeded,
|
|
286
|
-
'Nonce is too small.': InvalidNonce,
|
|
287
|
-
'No summary found.': ExchangeError,
|
|
288
|
-
'Cannot evaluate your available balance, please try again': ExchangeNotAvailable,
|
|
289
|
-
'Unknown symbol': BadSymbol,
|
|
290
|
-
'Cannot complete transfer. Exchange balance insufficient.': InsufficientFunds,
|
|
291
|
-
'Momentary balance check. Please wait few seconds and try the transfer again.': ExchangeError,
|
|
292
|
-
},
|
|
293
|
-
'broad': {
|
|
294
|
-
'Invalid X-BFX-SIGNATURE': AuthenticationError,
|
|
295
|
-
'This API key does not have permission': PermissionDenied,
|
|
296
|
-
'not enough exchange balance for ': InsufficientFunds,
|
|
297
|
-
'minimum size for ': InvalidOrder,
|
|
298
|
-
'Invalid order': InvalidOrder,
|
|
299
|
-
'The available balance is only': InsufficientFunds, // {"status":"error","message":"Cannot withdraw 1.0027 ETH from your exchange wallet. The available balance is only 0.0 ETH. If you have limit orders, open positions, unused or active margin funding, this will decrease your available balance. To increase it, you can cancel limit orders or reduce/close your positions.","withdrawal_id":0,"fees":"0.0027"}
|
|
300
|
-
},
|
|
301
|
-
},
|
|
302
|
-
'precisionMode': SIGNIFICANT_DIGITS,
|
|
303
|
-
'options': {
|
|
304
|
-
'currencyNames': {
|
|
305
|
-
'AGI': 'agi',
|
|
306
|
-
'AID': 'aid',
|
|
307
|
-
'AIO': 'aio',
|
|
308
|
-
'ANT': 'ant',
|
|
309
|
-
'AVT': 'aventus',
|
|
310
|
-
'BAT': 'bat',
|
|
311
|
-
// https://github.com/ccxt/ccxt/issues/5833
|
|
312
|
-
'BCH': 'bab',
|
|
313
|
-
// 'BCH': 'bcash', // undocumented
|
|
314
|
-
'BCI': 'bci',
|
|
315
|
-
'BFT': 'bft',
|
|
316
|
-
'BSV': 'bsv',
|
|
317
|
-
'BTC': 'bitcoin',
|
|
318
|
-
'BTG': 'bgold',
|
|
319
|
-
'CFI': 'cfi',
|
|
320
|
-
'COMP': 'comp',
|
|
321
|
-
'DAI': 'dai',
|
|
322
|
-
'DADI': 'dad',
|
|
323
|
-
'DASH': 'dash',
|
|
324
|
-
'DATA': 'datacoin',
|
|
325
|
-
'DTH': 'dth',
|
|
326
|
-
'EDO': 'eidoo',
|
|
327
|
-
'ELF': 'elf',
|
|
328
|
-
'EOS': 'eos',
|
|
329
|
-
'ETC': 'ethereumc',
|
|
330
|
-
'ETH': 'ethereum',
|
|
331
|
-
'ETP': 'metaverse',
|
|
332
|
-
'FUN': 'fun',
|
|
333
|
-
'GNT': 'golem',
|
|
334
|
-
'IOST': 'ios',
|
|
335
|
-
'IOTA': 'iota',
|
|
336
|
-
// https://github.com/ccxt/ccxt/issues/5833
|
|
337
|
-
'LEO': 'let',
|
|
338
|
-
// 'LEO': 'les', // EOS chain
|
|
339
|
-
'LINK': 'link',
|
|
340
|
-
'LRC': 'lrc',
|
|
341
|
-
'LTC': 'litecoin',
|
|
342
|
-
'LYM': 'lym',
|
|
343
|
-
'MANA': 'mna',
|
|
344
|
-
'MIT': 'mit',
|
|
345
|
-
'MKR': 'mkr',
|
|
346
|
-
'MTN': 'mtn',
|
|
347
|
-
'NEO': 'neo',
|
|
348
|
-
'ODE': 'ode',
|
|
349
|
-
'OMG': 'omisego',
|
|
350
|
-
'OMNI': 'mastercoin',
|
|
351
|
-
'QASH': 'qash',
|
|
352
|
-
'QTUM': 'qtum',
|
|
353
|
-
'RCN': 'rcn',
|
|
354
|
-
'RDN': 'rdn',
|
|
355
|
-
'REP': 'rep',
|
|
356
|
-
'REQ': 'req',
|
|
357
|
-
'RLC': 'rlc',
|
|
358
|
-
'SAN': 'santiment',
|
|
359
|
-
'SNGLS': 'sng',
|
|
360
|
-
'SNT': 'status',
|
|
361
|
-
'SPANK': 'spk',
|
|
362
|
-
'STORJ': 'stj',
|
|
363
|
-
'TNB': 'tnb',
|
|
364
|
-
'TRX': 'trx',
|
|
365
|
-
'TUSD': 'tsd',
|
|
366
|
-
'USD': 'wire',
|
|
367
|
-
'USDC': 'udc',
|
|
368
|
-
'UTK': 'utk',
|
|
369
|
-
'USDT': 'tetheruso',
|
|
370
|
-
// 'USDT': 'tetheruse', // Tether on ERC20
|
|
371
|
-
// 'USDT': 'tetherusl', // Tether on Liquid
|
|
372
|
-
// 'USDT': 'tetherusx', // Tether on Tron
|
|
373
|
-
// 'USDT': 'tetheruss', // Tether on EOS
|
|
374
|
-
'VEE': 'vee',
|
|
375
|
-
'WAX': 'wax',
|
|
376
|
-
'XLM': 'xlm',
|
|
377
|
-
'XMR': 'monero',
|
|
378
|
-
'XRP': 'ripple',
|
|
379
|
-
'XVG': 'xvg',
|
|
380
|
-
'YOYOW': 'yoyow',
|
|
381
|
-
'ZEC': 'zcash',
|
|
382
|
-
'ZRX': 'zrx',
|
|
383
|
-
'XTZ': 'xtz',
|
|
384
|
-
},
|
|
385
|
-
'orderTypes': {
|
|
386
|
-
'limit': 'exchange limit',
|
|
387
|
-
'market': 'exchange market',
|
|
388
|
-
},
|
|
389
|
-
'fiat': {
|
|
390
|
-
'USD': 'USD',
|
|
391
|
-
'EUR': 'EUR',
|
|
392
|
-
'JPY': 'JPY',
|
|
393
|
-
'GBP': 'GBP',
|
|
394
|
-
'CNH': 'CNH',
|
|
395
|
-
},
|
|
396
|
-
'accountsByType': {
|
|
397
|
-
'spot': 'exchange',
|
|
398
|
-
'margin': 'trading',
|
|
399
|
-
'funding': 'deposit',
|
|
400
|
-
'swap': 'trading',
|
|
401
|
-
},
|
|
402
|
-
},
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* @method
|
|
407
|
-
* @name bitfinex1#fetchTransactionFees
|
|
408
|
-
* @deprecated
|
|
409
|
-
* @description please use fetchDepositWithdrawFees instead
|
|
410
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-fees
|
|
411
|
-
* @param {string[]|undefined} codes list of unified currency codes
|
|
412
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
413
|
-
* @returns {object[]} a list of [fees structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
414
|
-
*/
|
|
415
|
-
async fetchTransactionFees(codes = undefined, params = {}) {
|
|
416
|
-
await this.loadMarkets();
|
|
417
|
-
const result = {};
|
|
418
|
-
const response = await this.privatePostAccountFees(params);
|
|
419
|
-
//
|
|
420
|
-
// {
|
|
421
|
-
// "withdraw": {
|
|
422
|
-
// "BTC": "0.0004",
|
|
423
|
-
// }
|
|
424
|
-
// }
|
|
425
|
-
//
|
|
426
|
-
const fees = this.safeDict(response, 'withdraw', {});
|
|
427
|
-
const ids = Object.keys(fees);
|
|
428
|
-
for (let i = 0; i < ids.length; i++) {
|
|
429
|
-
const id = ids[i];
|
|
430
|
-
const code = this.safeCurrencyCode(id);
|
|
431
|
-
if ((codes !== undefined) && !this.inArray(code, codes)) {
|
|
432
|
-
continue;
|
|
433
|
-
}
|
|
434
|
-
result[code] = {
|
|
435
|
-
'withdraw': this.safeNumber(fees, id),
|
|
436
|
-
'deposit': {},
|
|
437
|
-
'info': this.safeNumber(fees, id),
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
return result;
|
|
441
|
-
}
|
|
442
|
-
/**
|
|
443
|
-
* @method
|
|
444
|
-
* @name bitfinex1#fetchDepositWithdrawFees
|
|
445
|
-
* @description fetch deposit and withdraw fees
|
|
446
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-fees
|
|
447
|
-
* @param {string[]|undefined} codes list of unified currency codes
|
|
448
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
449
|
-
* @returns {object[]} a list of [fees structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
450
|
-
*/
|
|
451
|
-
async fetchDepositWithdrawFees(codes = undefined, params = {}) {
|
|
452
|
-
await this.loadMarkets();
|
|
453
|
-
const response = await this.privatePostAccountFees(params);
|
|
454
|
-
//
|
|
455
|
-
// {
|
|
456
|
-
// "withdraw": {
|
|
457
|
-
// "BTC": "0.0004",
|
|
458
|
-
// ...
|
|
459
|
-
// }
|
|
460
|
-
// }
|
|
461
|
-
//
|
|
462
|
-
const withdraw = this.safeList(response, 'withdraw');
|
|
463
|
-
return this.parseDepositWithdrawFees(withdraw, codes);
|
|
464
|
-
}
|
|
465
|
-
parseDepositWithdrawFee(fee, currency = undefined) {
|
|
466
|
-
//
|
|
467
|
-
// '0.0004'
|
|
468
|
-
//
|
|
469
|
-
return {
|
|
470
|
-
'withdraw': {
|
|
471
|
-
'fee': this.parseNumber(fee),
|
|
472
|
-
'percentage': undefined,
|
|
473
|
-
},
|
|
474
|
-
'deposit': {
|
|
475
|
-
'fee': undefined,
|
|
476
|
-
'percentage': undefined,
|
|
477
|
-
},
|
|
478
|
-
'networks': {},
|
|
479
|
-
'info': fee,
|
|
480
|
-
};
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* @method
|
|
484
|
-
* @name bitfinex1#fetchTradingFees
|
|
485
|
-
* @description fetch the trading fees for multiple markets
|
|
486
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-summary
|
|
487
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
488
|
-
* @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
|
|
489
|
-
*/
|
|
490
|
-
async fetchTradingFees(params = {}) {
|
|
491
|
-
await this.loadMarkets();
|
|
492
|
-
const response = await this.privatePostSummary(params);
|
|
493
|
-
//
|
|
494
|
-
// {
|
|
495
|
-
// "time": "2022-02-23T16:05:47.659000Z",
|
|
496
|
-
// "status": { resid_hint: null, login_last: "2022-02-23T16:05:48Z" },
|
|
497
|
-
// "is_locked": false,
|
|
498
|
-
// "leo_lev": "0",
|
|
499
|
-
// "leo_amount_avg": "0.0",
|
|
500
|
-
// "trade_vol_30d": [
|
|
501
|
-
// {
|
|
502
|
-
// "curr": "Total (USD)",
|
|
503
|
-
// "vol": "0.0",
|
|
504
|
-
// "vol_safe": "0.0",
|
|
505
|
-
// "vol_maker": "0.0",
|
|
506
|
-
// "vol_BFX": "0.0",
|
|
507
|
-
// "vol_BFX_safe": "0.0",
|
|
508
|
-
// "vol_BFX_maker": "0.0"
|
|
509
|
-
// }
|
|
510
|
-
// ],
|
|
511
|
-
// "fees_funding_30d": {},
|
|
512
|
-
// "fees_funding_total_30d": "0",
|
|
513
|
-
// "fees_trading_30d": {},
|
|
514
|
-
// "fees_trading_total_30d": "0",
|
|
515
|
-
// "rebates_trading_30d": {},
|
|
516
|
-
// "rebates_trading_total_30d": "0",
|
|
517
|
-
// "maker_fee": "0.001",
|
|
518
|
-
// "taker_fee": "0.002",
|
|
519
|
-
// "maker_fee_2crypto": "0.001",
|
|
520
|
-
// "maker_fee_2stablecoin": "0.001",
|
|
521
|
-
// "maker_fee_2fiat": "0.001",
|
|
522
|
-
// "maker_fee_2deriv": "0.0002",
|
|
523
|
-
// "taker_fee_2crypto": "0.002",
|
|
524
|
-
// "taker_fee_2stablecoin": "0.002",
|
|
525
|
-
// "taker_fee_2fiat": "0.002",
|
|
526
|
-
// "taker_fee_2deriv": "0.00065",
|
|
527
|
-
// "deriv_maker_rebate": "0.0002",
|
|
528
|
-
// "deriv_taker_fee": "0.00065",
|
|
529
|
-
// "trade_last": null
|
|
530
|
-
// }
|
|
531
|
-
//
|
|
532
|
-
const result = {};
|
|
533
|
-
const fiat = this.safeDict(this.options, 'fiat', {});
|
|
534
|
-
const makerFee = this.safeNumber(response, 'maker_fee');
|
|
535
|
-
const takerFee = this.safeNumber(response, 'taker_fee');
|
|
536
|
-
const makerFee2Fiat = this.safeNumber(response, 'maker_fee_2fiat');
|
|
537
|
-
const takerFee2Fiat = this.safeNumber(response, 'taker_fee_2fiat');
|
|
538
|
-
const makerFee2Deriv = this.safeNumber(response, 'maker_fee_2deriv');
|
|
539
|
-
const takerFee2Deriv = this.safeNumber(response, 'taker_fee_2deriv');
|
|
540
|
-
for (let i = 0; i < this.symbols.length; i++) {
|
|
541
|
-
const symbol = this.symbols[i];
|
|
542
|
-
const market = this.market(symbol);
|
|
543
|
-
const fee = {
|
|
544
|
-
'info': response,
|
|
545
|
-
'symbol': symbol,
|
|
546
|
-
'percentage': true,
|
|
547
|
-
'tierBased': true,
|
|
548
|
-
};
|
|
549
|
-
if (market['quote'] in fiat) {
|
|
550
|
-
fee['maker'] = makerFee2Fiat;
|
|
551
|
-
fee['taker'] = takerFee2Fiat;
|
|
552
|
-
}
|
|
553
|
-
else if (market['contract']) {
|
|
554
|
-
fee['maker'] = makerFee2Deriv;
|
|
555
|
-
fee['taker'] = takerFee2Deriv;
|
|
556
|
-
}
|
|
557
|
-
else {
|
|
558
|
-
fee['maker'] = makerFee;
|
|
559
|
-
fee['taker'] = takerFee;
|
|
560
|
-
}
|
|
561
|
-
result[symbol] = fee;
|
|
562
|
-
}
|
|
563
|
-
return result;
|
|
564
|
-
}
|
|
565
|
-
/**
|
|
566
|
-
* @method
|
|
567
|
-
* @name bitfinex1#fetchMarkets
|
|
568
|
-
* @description retrieves data on all markets for bitfinex
|
|
569
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-public-symbols
|
|
570
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-public-symbol-details
|
|
571
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
572
|
-
* @returns {object[]} an array of objects representing market data
|
|
573
|
-
*/
|
|
574
|
-
async fetchMarkets(params = {}) {
|
|
575
|
-
const idsPromise = this.publicGetSymbols();
|
|
576
|
-
//
|
|
577
|
-
// [ "btcusd", "ltcusd", "ltcbtc" ]
|
|
578
|
-
//
|
|
579
|
-
const detailsPromise = this.publicGetSymbolsDetails();
|
|
580
|
-
//
|
|
581
|
-
// [
|
|
582
|
-
// {
|
|
583
|
-
// "pair":"btcusd",
|
|
584
|
-
// "price_precision":5,
|
|
585
|
-
// "initial_margin":"10.0",
|
|
586
|
-
// "minimum_margin":"5.0",
|
|
587
|
-
// "maximum_order_size":"2000.0",
|
|
588
|
-
// "minimum_order_size":"0.0002",
|
|
589
|
-
// "expiration":"NA",
|
|
590
|
-
// "margin":true
|
|
591
|
-
// },
|
|
592
|
-
// ]
|
|
593
|
-
//
|
|
594
|
-
const [ids, details] = await Promise.all([idsPromise, detailsPromise]);
|
|
595
|
-
const result = [];
|
|
596
|
-
for (let i = 0; i < details.length; i++) {
|
|
597
|
-
const market = details[i];
|
|
598
|
-
let id = this.safeString(market, 'pair');
|
|
599
|
-
if (!this.inArray(id, ids)) {
|
|
600
|
-
continue;
|
|
601
|
-
}
|
|
602
|
-
id = id.toUpperCase();
|
|
603
|
-
let baseId = undefined;
|
|
604
|
-
let quoteId = undefined;
|
|
605
|
-
if (id.indexOf(':') >= 0) {
|
|
606
|
-
const parts = id.split(':');
|
|
607
|
-
baseId = parts[0];
|
|
608
|
-
quoteId = parts[1];
|
|
609
|
-
}
|
|
610
|
-
else {
|
|
611
|
-
baseId = id.slice(0, 3);
|
|
612
|
-
quoteId = id.slice(3, 6);
|
|
613
|
-
}
|
|
614
|
-
const base = this.safeCurrencyCode(baseId);
|
|
615
|
-
const quote = this.safeCurrencyCode(quoteId);
|
|
616
|
-
const symbol = base + '/' + quote;
|
|
617
|
-
let type = 'spot';
|
|
618
|
-
if (id.indexOf('F0') > -1) {
|
|
619
|
-
type = 'swap';
|
|
620
|
-
}
|
|
621
|
-
result.push({
|
|
622
|
-
'id': id,
|
|
623
|
-
'symbol': symbol,
|
|
624
|
-
'base': base,
|
|
625
|
-
'quote': quote,
|
|
626
|
-
'settle': undefined,
|
|
627
|
-
'baseId': baseId,
|
|
628
|
-
'quoteId': quoteId,
|
|
629
|
-
'settleId': undefined,
|
|
630
|
-
'type': type,
|
|
631
|
-
'spot': (type === 'spot'),
|
|
632
|
-
'margin': this.safeBool(market, 'margin'),
|
|
633
|
-
'swap': (type === 'swap'),
|
|
634
|
-
'future': false,
|
|
635
|
-
'option': false,
|
|
636
|
-
'active': true,
|
|
637
|
-
'contract': (type === 'swap'),
|
|
638
|
-
'linear': undefined,
|
|
639
|
-
'inverse': undefined,
|
|
640
|
-
'contractSize': undefined,
|
|
641
|
-
'expiry': undefined,
|
|
642
|
-
'expiryDatetime': undefined,
|
|
643
|
-
'strike': undefined,
|
|
644
|
-
'optionType': undefined,
|
|
645
|
-
'precision': {
|
|
646
|
-
// https://docs.bitfinex.com/docs/introduction#amount-precision
|
|
647
|
-
// The amount field allows up to 8 decimals.
|
|
648
|
-
// Anything exceeding this will be rounded to the 8th decimal.
|
|
649
|
-
'amount': parseInt('8'),
|
|
650
|
-
'price': this.safeInteger(market, 'price_precision'),
|
|
651
|
-
},
|
|
652
|
-
'limits': {
|
|
653
|
-
'leverage': {
|
|
654
|
-
'min': undefined,
|
|
655
|
-
'max': undefined,
|
|
656
|
-
},
|
|
657
|
-
'amount': {
|
|
658
|
-
'min': this.safeNumber(market, 'minimum_order_size'),
|
|
659
|
-
'max': this.safeNumber(market, 'maximum_order_size'),
|
|
660
|
-
},
|
|
661
|
-
'price': {
|
|
662
|
-
'min': this.parseNumber('1e-8'),
|
|
663
|
-
'max': undefined,
|
|
664
|
-
},
|
|
665
|
-
'cost': {
|
|
666
|
-
'min': undefined,
|
|
667
|
-
'max': undefined,
|
|
668
|
-
},
|
|
669
|
-
},
|
|
670
|
-
'created': undefined,
|
|
671
|
-
'info': market,
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
return result;
|
|
675
|
-
}
|
|
676
|
-
amountToPrecision(symbol, amount) {
|
|
677
|
-
// https://docs.bitfinex.com/docs/introduction#amount-precision
|
|
678
|
-
// The amount field allows up to 8 decimals.
|
|
679
|
-
// Anything exceeding this will be rounded to the 8th decimal.
|
|
680
|
-
symbol = this.safeSymbol(symbol);
|
|
681
|
-
return this.decimalToPrecision(amount, TRUNCATE, this.markets[symbol]['precision']['amount'], DECIMAL_PLACES);
|
|
682
|
-
}
|
|
683
|
-
priceToPrecision(symbol, price) {
|
|
684
|
-
symbol = this.safeSymbol(symbol);
|
|
685
|
-
price = this.decimalToPrecision(price, ROUND, this.markets[symbol]['precision']['price'], this.precisionMode);
|
|
686
|
-
// https://docs.bitfinex.com/docs/introduction#price-precision
|
|
687
|
-
// The precision level of all trading prices is based on significant figures.
|
|
688
|
-
// All pairs on Bitfinex use up to 5 significant digits and up to 8 decimals (e.g. 1.2345, 123.45, 1234.5, 0.00012345).
|
|
689
|
-
// Prices submit with a precision larger than 5 will be cut by the API.
|
|
690
|
-
return this.decimalToPrecision(price, TRUNCATE, 8, DECIMAL_PLACES);
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* @method
|
|
694
|
-
* @name bitfinex1#fetchBalance
|
|
695
|
-
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
696
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-wallet-balances
|
|
697
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
698
|
-
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
699
|
-
*/
|
|
700
|
-
async fetchBalance(params = {}) {
|
|
701
|
-
await this.loadMarkets();
|
|
702
|
-
const accountsByType = this.safeDict(this.options, 'accountsByType', {});
|
|
703
|
-
const requestedType = this.safeString(params, 'type', 'exchange');
|
|
704
|
-
const accountType = this.safeString(accountsByType, requestedType, requestedType);
|
|
705
|
-
if (accountType === undefined) {
|
|
706
|
-
const keys = Object.keys(accountsByType);
|
|
707
|
-
throw new ExchangeError(this.id + ' fetchBalance() type parameter must be one of ' + keys.join(', '));
|
|
708
|
-
}
|
|
709
|
-
const query = this.omit(params, 'type');
|
|
710
|
-
const response = await this.privatePostBalances(query);
|
|
711
|
-
// [ { type: "deposit",
|
|
712
|
-
// "currency": "btc",
|
|
713
|
-
// "amount": "0.00116721",
|
|
714
|
-
// "available": "0.00116721" },
|
|
715
|
-
// { type: "exchange",
|
|
716
|
-
// "currency": "ust",
|
|
717
|
-
// "amount": "0.0000002",
|
|
718
|
-
// "available": "0.0000002" },
|
|
719
|
-
// { type: "trading",
|
|
720
|
-
// "currency": "btc",
|
|
721
|
-
// "amount": "0.0005",
|
|
722
|
-
// "available": "0.0005" } ],
|
|
723
|
-
const result = { 'info': response };
|
|
724
|
-
const isDerivative = requestedType === 'derivatives';
|
|
725
|
-
for (let i = 0; i < response.length; i++) {
|
|
726
|
-
const balance = response[i];
|
|
727
|
-
const type = this.safeString(balance, 'type');
|
|
728
|
-
const currencyId = this.safeStringLower(balance, 'currency', '');
|
|
729
|
-
const start = currencyId.length - 2;
|
|
730
|
-
const isDerivativeCode = currencyId.slice(start) === 'f0';
|
|
731
|
-
// this will only filter the derivative codes if the requestedType is 'derivatives'
|
|
732
|
-
const derivativeCondition = (!isDerivative || isDerivativeCode);
|
|
733
|
-
if ((accountType === type) && derivativeCondition) {
|
|
734
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
735
|
-
// bitfinex had BCH previously, now it's BAB, but the old
|
|
736
|
-
// BCH symbol is kept for backward-compatibility
|
|
737
|
-
// we need a workaround here so that the old BCH balance
|
|
738
|
-
// would not override the new BAB balance (BAB is unified to BCH)
|
|
739
|
-
// https://github.com/ccxt/ccxt/issues/4989
|
|
740
|
-
if (!(code in result)) {
|
|
741
|
-
const account = this.account();
|
|
742
|
-
account['free'] = this.safeString(balance, 'available');
|
|
743
|
-
account['total'] = this.safeString(balance, 'amount');
|
|
744
|
-
result[code] = account;
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
return this.safeBalance(result);
|
|
749
|
-
}
|
|
750
|
-
/**
|
|
751
|
-
* @method
|
|
752
|
-
* @name bitfinex1#transfer
|
|
753
|
-
* @description transfer currency internally between wallets on the same account
|
|
754
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-transfer-between-wallets
|
|
755
|
-
* @param {string} code unified currency code
|
|
756
|
-
* @param {float} amount amount to transfer
|
|
757
|
-
* @param {string} fromAccount account to transfer from
|
|
758
|
-
* @param {string} toAccount account to transfer to
|
|
759
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
760
|
-
* @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
761
|
-
*/
|
|
762
|
-
async transfer(code, amount, fromAccount, toAccount, params = {}) {
|
|
763
|
-
// transferring between derivatives wallet and regular wallet is not documented in their API
|
|
764
|
-
// however we support it in CCXT (from just looking at web inspector)
|
|
765
|
-
await this.loadMarkets();
|
|
766
|
-
const accountsByType = this.safeDict(this.options, 'accountsByType', {});
|
|
767
|
-
const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
|
|
768
|
-
const toId = this.safeString(accountsByType, toAccount, toAccount);
|
|
769
|
-
const currency = this.currency(code);
|
|
770
|
-
const fromCurrencyId = this.convertDerivativesId(currency['id'], fromAccount);
|
|
771
|
-
const toCurrencyId = this.convertDerivativesId(currency['id'], toAccount);
|
|
772
|
-
const requestedAmount = this.currencyToPrecision(code, amount);
|
|
773
|
-
const request = {
|
|
774
|
-
'amount': requestedAmount,
|
|
775
|
-
'currency': fromCurrencyId,
|
|
776
|
-
'currency_to': toCurrencyId,
|
|
777
|
-
'walletfrom': fromId,
|
|
778
|
-
'walletto': toId,
|
|
779
|
-
};
|
|
780
|
-
const response = await this.privatePostTransfer(this.extend(request, params));
|
|
781
|
-
//
|
|
782
|
-
// [
|
|
783
|
-
// {
|
|
784
|
-
// "status": "success",
|
|
785
|
-
// "message": "0.0001 Bitcoin transfered from Margin to Exchange"
|
|
786
|
-
// }
|
|
787
|
-
// ]
|
|
788
|
-
//
|
|
789
|
-
const result = this.safeValue(response, 0);
|
|
790
|
-
const message = this.safeString(result, 'message');
|
|
791
|
-
if (message === undefined) {
|
|
792
|
-
throw new ExchangeError(this.id + ' transfer failed');
|
|
793
|
-
}
|
|
794
|
-
return this.extend(this.parseTransfer(result, currency), {
|
|
795
|
-
'fromAccount': fromAccount,
|
|
796
|
-
'toAccount': toAccount,
|
|
797
|
-
'amount': this.parseNumber(requestedAmount),
|
|
798
|
-
});
|
|
799
|
-
}
|
|
800
|
-
parseTransfer(transfer, currency = undefined) {
|
|
801
|
-
//
|
|
802
|
-
// {
|
|
803
|
-
// "status": "success",
|
|
804
|
-
// "message": "0.0001 Bitcoin transfered from Margin to Exchange"
|
|
805
|
-
// }
|
|
806
|
-
//
|
|
807
|
-
return {
|
|
808
|
-
'info': transfer,
|
|
809
|
-
'id': undefined,
|
|
810
|
-
'timestamp': undefined,
|
|
811
|
-
'datetime': undefined,
|
|
812
|
-
'currency': this.safeCurrencyCode(undefined, currency),
|
|
813
|
-
'amount': undefined,
|
|
814
|
-
'fromAccount': undefined,
|
|
815
|
-
'toAccount': undefined,
|
|
816
|
-
'status': this.parseTransferStatus(this.safeString(transfer, 'status')),
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
|
-
parseTransferStatus(status) {
|
|
820
|
-
const statuses = {
|
|
821
|
-
'SUCCESS': 'ok',
|
|
822
|
-
};
|
|
823
|
-
return this.safeString(statuses, status, status);
|
|
824
|
-
}
|
|
825
|
-
convertDerivativesId(currencyId, type) {
|
|
826
|
-
const start = currencyId.length - 2;
|
|
827
|
-
const isDerivativeCode = currencyId.slice(start) === 'F0';
|
|
828
|
-
if ((type !== 'derivatives' && type !== 'trading' && type !== 'margin') && isDerivativeCode) {
|
|
829
|
-
currencyId = currencyId.slice(0, start);
|
|
830
|
-
}
|
|
831
|
-
else if (type === 'derivatives' && !isDerivativeCode) {
|
|
832
|
-
currencyId = currencyId + 'F0';
|
|
833
|
-
}
|
|
834
|
-
return currencyId;
|
|
835
|
-
}
|
|
836
|
-
/**
|
|
837
|
-
* @method
|
|
838
|
-
* @name bitfinex1#fetchOrderBook
|
|
839
|
-
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
840
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-public-orderbook
|
|
841
|
-
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
842
|
-
* @param {int} [limit] the maximum amount of order book entries to return
|
|
843
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
844
|
-
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
845
|
-
*/
|
|
846
|
-
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
847
|
-
await this.loadMarkets();
|
|
848
|
-
const market = this.market(symbol);
|
|
849
|
-
const request = {
|
|
850
|
-
'symbol': market['id'],
|
|
851
|
-
};
|
|
852
|
-
if (limit !== undefined) {
|
|
853
|
-
request['limit_bids'] = limit;
|
|
854
|
-
request['limit_asks'] = limit;
|
|
855
|
-
}
|
|
856
|
-
const response = await this.publicGetBookSymbol(this.extend(request, params));
|
|
857
|
-
return this.parseOrderBook(response, market['symbol'], undefined, 'bids', 'asks', 'price', 'amount');
|
|
858
|
-
}
|
|
859
|
-
/**
|
|
860
|
-
* @method
|
|
861
|
-
* @name bitfinex1#fetchTickers
|
|
862
|
-
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
863
|
-
* @param {string[]} [symbols] unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
864
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
865
|
-
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
866
|
-
*/
|
|
867
|
-
async fetchTickers(symbols = undefined, params = {}) {
|
|
868
|
-
await this.loadMarkets();
|
|
869
|
-
symbols = this.marketSymbols(symbols);
|
|
870
|
-
const response = await this.publicGetTickers(params);
|
|
871
|
-
const result = {};
|
|
872
|
-
for (let i = 0; i < response.length; i++) {
|
|
873
|
-
const ticker = this.parseTicker(response[i]);
|
|
874
|
-
const symbol = ticker['symbol'];
|
|
875
|
-
result[symbol] = ticker;
|
|
876
|
-
}
|
|
877
|
-
return this.filterByArrayTickers(result, 'symbol', symbols);
|
|
878
|
-
}
|
|
879
|
-
/**
|
|
880
|
-
* @method
|
|
881
|
-
* @name bitfinex1#fetchTicker
|
|
882
|
-
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
883
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-public-ticker
|
|
884
|
-
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
885
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
886
|
-
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
887
|
-
*/
|
|
888
|
-
async fetchTicker(symbol, params = {}) {
|
|
889
|
-
await this.loadMarkets();
|
|
890
|
-
const market = this.market(symbol);
|
|
891
|
-
const request = {
|
|
892
|
-
'symbol': market['id'],
|
|
893
|
-
};
|
|
894
|
-
const ticker = await this.publicGetPubtickerSymbol(this.extend(request, params));
|
|
895
|
-
//
|
|
896
|
-
// {
|
|
897
|
-
// mid: '63560.5',
|
|
898
|
-
// bid: '63560.0',
|
|
899
|
-
// ask: '63561.0',
|
|
900
|
-
// last_price: '63547.0',
|
|
901
|
-
// low: '62812.0',
|
|
902
|
-
// high: '64480.0',
|
|
903
|
-
// volume: '517.25634977',
|
|
904
|
-
// timestamp: '1715102384.9849467'
|
|
905
|
-
// }
|
|
906
|
-
//
|
|
907
|
-
return this.parseTicker(ticker, market);
|
|
908
|
-
}
|
|
909
|
-
parseTicker(ticker, market = undefined) {
|
|
910
|
-
//
|
|
911
|
-
// {
|
|
912
|
-
// mid: '63560.5',
|
|
913
|
-
// bid: '63560.0',
|
|
914
|
-
// ask: '63561.0',
|
|
915
|
-
// last_price: '63547.0',
|
|
916
|
-
// low: '62812.0',
|
|
917
|
-
// high: '64480.0',
|
|
918
|
-
// volume: '517.25634977',
|
|
919
|
-
// timestamp: '1715102384.9849467'
|
|
920
|
-
// }
|
|
921
|
-
//
|
|
922
|
-
const timestamp = this.safeTimestamp(ticker, 'timestamp');
|
|
923
|
-
const marketId = this.safeString(ticker, 'pair');
|
|
924
|
-
market = this.safeMarket(marketId, market);
|
|
925
|
-
const symbol = market['symbol'];
|
|
926
|
-
const last = this.safeString(ticker, 'last_price');
|
|
927
|
-
return this.safeTicker({
|
|
928
|
-
'symbol': symbol,
|
|
929
|
-
'timestamp': timestamp,
|
|
930
|
-
'datetime': this.iso8601(timestamp),
|
|
931
|
-
'high': this.safeString(ticker, 'high'),
|
|
932
|
-
'low': this.safeString(ticker, 'low'),
|
|
933
|
-
'bid': this.safeString(ticker, 'bid'),
|
|
934
|
-
'bidVolume': undefined,
|
|
935
|
-
'ask': this.safeString(ticker, 'ask'),
|
|
936
|
-
'askVolume': undefined,
|
|
937
|
-
'vwap': undefined,
|
|
938
|
-
'open': undefined,
|
|
939
|
-
'close': last,
|
|
940
|
-
'last': last,
|
|
941
|
-
'previousClose': undefined,
|
|
942
|
-
'change': undefined,
|
|
943
|
-
'percentage': undefined,
|
|
944
|
-
'average': this.safeString(ticker, 'mid'),
|
|
945
|
-
'baseVolume': this.safeString(ticker, 'volume'),
|
|
946
|
-
'quoteVolume': undefined,
|
|
947
|
-
'info': ticker,
|
|
948
|
-
}, market);
|
|
949
|
-
}
|
|
950
|
-
parseTrade(trade, market = undefined) {
|
|
951
|
-
//
|
|
952
|
-
// fetchTrades (public) v1
|
|
953
|
-
//
|
|
954
|
-
// {
|
|
955
|
-
// "timestamp":1637258380,
|
|
956
|
-
// "tid":894452833,
|
|
957
|
-
// "price":"0.99941",
|
|
958
|
-
// "amount":"261.38",
|
|
959
|
-
// "exchange":"bitfinex",
|
|
960
|
-
// "type":"sell"
|
|
961
|
-
// }
|
|
962
|
-
//
|
|
963
|
-
// fetchMyTrades (private) v1
|
|
964
|
-
//
|
|
965
|
-
// {
|
|
966
|
-
// "price":"0.99941",
|
|
967
|
-
// "amount":"261.38",
|
|
968
|
-
// "timestamp":"1637258380.0",
|
|
969
|
-
// "type":"Sell",
|
|
970
|
-
// "fee_currency":"UST",
|
|
971
|
-
// "fee_amount":"-0.52245157",
|
|
972
|
-
// "tid":894452833,
|
|
973
|
-
// "order_id":78819731373
|
|
974
|
-
// }
|
|
975
|
-
//
|
|
976
|
-
// {
|
|
977
|
-
// "price":"0.99958",
|
|
978
|
-
// "amount":"261.90514",
|
|
979
|
-
// "timestamp":"1637258238.0",
|
|
980
|
-
// "type":"Buy",
|
|
981
|
-
// "fee_currency":"UDC",
|
|
982
|
-
// "fee_amount":"-0.52381028",
|
|
983
|
-
// "tid":894452800,
|
|
984
|
-
// "order_id":78819504838
|
|
985
|
-
// }
|
|
986
|
-
//
|
|
987
|
-
const id = this.safeString(trade, 'tid');
|
|
988
|
-
const timestamp = this.safeTimestamp(trade, 'timestamp');
|
|
989
|
-
const type = undefined;
|
|
990
|
-
const side = this.safeStringLower(trade, 'type');
|
|
991
|
-
const orderId = this.safeString(trade, 'order_id');
|
|
992
|
-
const priceString = this.safeString(trade, 'price');
|
|
993
|
-
const amountString = this.safeString(trade, 'amount');
|
|
994
|
-
let fee = undefined;
|
|
995
|
-
if ('fee_amount' in trade) {
|
|
996
|
-
const feeCostString = Precise.stringNeg(this.safeString(trade, 'fee_amount'));
|
|
997
|
-
const feeCurrencyId = this.safeString(trade, 'fee_currency');
|
|
998
|
-
const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
|
|
999
|
-
fee = {
|
|
1000
|
-
'cost': feeCostString,
|
|
1001
|
-
'currency': feeCurrencyCode,
|
|
1002
|
-
};
|
|
1003
|
-
}
|
|
1004
|
-
return this.safeTrade({
|
|
1005
|
-
'id': id,
|
|
1006
|
-
'info': trade,
|
|
1007
|
-
'timestamp': timestamp,
|
|
1008
|
-
'datetime': this.iso8601(timestamp),
|
|
1009
|
-
'symbol': market['symbol'],
|
|
1010
|
-
'type': type,
|
|
1011
|
-
'order': orderId,
|
|
1012
|
-
'side': side,
|
|
1013
|
-
'takerOrMaker': undefined,
|
|
1014
|
-
'price': priceString,
|
|
1015
|
-
'amount': amountString,
|
|
1016
|
-
'cost': undefined,
|
|
1017
|
-
'fee': fee,
|
|
1018
|
-
}, market);
|
|
1019
|
-
}
|
|
1020
|
-
/**
|
|
1021
|
-
* @method
|
|
1022
|
-
* @name bitfinex1#fetchTrades
|
|
1023
|
-
* @description get the list of most recent trades for a particular symbol
|
|
1024
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-public-trades
|
|
1025
|
-
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
1026
|
-
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
1027
|
-
* @param {int} [limit] the maximum amount of trades to fetch
|
|
1028
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1029
|
-
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
1030
|
-
*/
|
|
1031
|
-
async fetchTrades(symbol, since = undefined, limit = 50, params = {}) {
|
|
1032
|
-
await this.loadMarkets();
|
|
1033
|
-
const market = this.market(symbol);
|
|
1034
|
-
const request = {
|
|
1035
|
-
'symbol': market['id'],
|
|
1036
|
-
'limit_trades': limit,
|
|
1037
|
-
};
|
|
1038
|
-
if (since !== undefined) {
|
|
1039
|
-
request['timestamp'] = this.parseToInt(since / 1000);
|
|
1040
|
-
}
|
|
1041
|
-
const response = await this.publicGetTradesSymbol(this.extend(request, params));
|
|
1042
|
-
//
|
|
1043
|
-
// [
|
|
1044
|
-
// {
|
|
1045
|
-
// "timestamp": "1694284565",
|
|
1046
|
-
// "tid": "1415415034",
|
|
1047
|
-
// "price": "25862.0",
|
|
1048
|
-
// "amount": "0.00020685",
|
|
1049
|
-
// "exchange": "bitfinex",
|
|
1050
|
-
// "type": "buy"
|
|
1051
|
-
// },
|
|
1052
|
-
// ]
|
|
1053
|
-
//
|
|
1054
|
-
return this.parseTrades(response, market, since, limit);
|
|
1055
|
-
}
|
|
1056
|
-
/**
|
|
1057
|
-
* @method
|
|
1058
|
-
* @name bitfinex1#fetchMyTrades
|
|
1059
|
-
* @description fetch all trades made by the user
|
|
1060
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-past-trades
|
|
1061
|
-
* @param {string} symbol unified market symbol
|
|
1062
|
-
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1063
|
-
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
1064
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1065
|
-
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1066
|
-
*/
|
|
1067
|
-
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1068
|
-
if (symbol === undefined) {
|
|
1069
|
-
throw new ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol argument');
|
|
1070
|
-
}
|
|
1071
|
-
await this.loadMarkets();
|
|
1072
|
-
const market = this.market(symbol);
|
|
1073
|
-
const request = {
|
|
1074
|
-
'symbol': market['id'],
|
|
1075
|
-
};
|
|
1076
|
-
if (limit !== undefined) {
|
|
1077
|
-
request['limit_trades'] = limit;
|
|
1078
|
-
}
|
|
1079
|
-
if (since !== undefined) {
|
|
1080
|
-
request['timestamp'] = this.parseToInt(since / 1000);
|
|
1081
|
-
}
|
|
1082
|
-
const response = await this.privatePostMytrades(this.extend(request, params));
|
|
1083
|
-
return this.parseTrades(response, market, since, limit);
|
|
1084
|
-
}
|
|
1085
|
-
/**
|
|
1086
|
-
* @method
|
|
1087
|
-
* @name bitfinex1#createOrder
|
|
1088
|
-
* @description create a trade order
|
|
1089
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-new-order
|
|
1090
|
-
* @param {string} symbol unified symbol of the market to create an order in
|
|
1091
|
-
* @param {string} type 'market' or 'limit'
|
|
1092
|
-
* @param {string} side 'buy' or 'sell'
|
|
1093
|
-
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1094
|
-
* @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
1095
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1096
|
-
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1097
|
-
*/
|
|
1098
|
-
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1099
|
-
await this.loadMarkets();
|
|
1100
|
-
const market = this.market(symbol);
|
|
1101
|
-
const postOnly = this.safeBool(params, 'postOnly', false);
|
|
1102
|
-
type = type.toLowerCase();
|
|
1103
|
-
params = this.omit(params, ['postOnly']);
|
|
1104
|
-
if (market['spot']) {
|
|
1105
|
-
// although they claim that type needs to be 'exchange limit' or 'exchange market'
|
|
1106
|
-
// in fact that's not the case for swap markets
|
|
1107
|
-
type = this.safeStringLower(this.options['orderTypes'], type, type);
|
|
1108
|
-
}
|
|
1109
|
-
const request = {
|
|
1110
|
-
'symbol': market['id'],
|
|
1111
|
-
'side': side,
|
|
1112
|
-
'amount': this.amountToPrecision(symbol, amount),
|
|
1113
|
-
'type': type,
|
|
1114
|
-
'ocoorder': false,
|
|
1115
|
-
'buy_price_oco': 0,
|
|
1116
|
-
'sell_price_oco': 0,
|
|
1117
|
-
};
|
|
1118
|
-
if (type.indexOf('market') > -1) {
|
|
1119
|
-
request['price'] = this.nonce().toString();
|
|
1120
|
-
}
|
|
1121
|
-
else {
|
|
1122
|
-
request['price'] = this.priceToPrecision(symbol, price);
|
|
1123
|
-
}
|
|
1124
|
-
if (postOnly) {
|
|
1125
|
-
request['is_postonly'] = true;
|
|
1126
|
-
}
|
|
1127
|
-
const response = await this.privatePostOrderNew(this.extend(request, params));
|
|
1128
|
-
return this.parseOrder(response, market);
|
|
1129
|
-
}
|
|
1130
|
-
async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
|
|
1131
|
-
await this.loadMarkets();
|
|
1132
|
-
const order = {
|
|
1133
|
-
'order_id': parseInt(id),
|
|
1134
|
-
};
|
|
1135
|
-
if (price !== undefined) {
|
|
1136
|
-
order['price'] = this.priceToPrecision(symbol, price);
|
|
1137
|
-
}
|
|
1138
|
-
if (amount !== undefined) {
|
|
1139
|
-
order['amount'] = this.numberToString(amount);
|
|
1140
|
-
}
|
|
1141
|
-
if (symbol !== undefined) {
|
|
1142
|
-
order['symbol'] = this.marketId(symbol);
|
|
1143
|
-
}
|
|
1144
|
-
if (side !== undefined) {
|
|
1145
|
-
order['side'] = side;
|
|
1146
|
-
}
|
|
1147
|
-
if (type !== undefined) {
|
|
1148
|
-
order['type'] = this.safeString(this.options['orderTypes'], type, type);
|
|
1149
|
-
}
|
|
1150
|
-
const response = await this.privatePostOrderCancelReplace(this.extend(order, params));
|
|
1151
|
-
return this.parseOrder(response);
|
|
1152
|
-
}
|
|
1153
|
-
/**
|
|
1154
|
-
* @method
|
|
1155
|
-
* @name bitfinex1#cancelOrder
|
|
1156
|
-
* @description cancels an open order
|
|
1157
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-cancel-order
|
|
1158
|
-
* @param {string} id order id
|
|
1159
|
-
* @param {string} symbol not used by bitfinex cancelOrder ()
|
|
1160
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1161
|
-
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1162
|
-
*/
|
|
1163
|
-
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
1164
|
-
await this.loadMarkets();
|
|
1165
|
-
const request = {
|
|
1166
|
-
'order_id': parseInt(id),
|
|
1167
|
-
};
|
|
1168
|
-
const response = await this.privatePostOrderCancel(this.extend(request, params));
|
|
1169
|
-
//
|
|
1170
|
-
// {
|
|
1171
|
-
// id: '161236928925',
|
|
1172
|
-
// cid: '1720172026812',
|
|
1173
|
-
// cid_date: '2024-07-05',
|
|
1174
|
-
// gid: null,
|
|
1175
|
-
// symbol: 'adaust',
|
|
1176
|
-
// exchange: 'bitfinex',
|
|
1177
|
-
// price: '0.33',
|
|
1178
|
-
// avg_execution_price: '0.0',
|
|
1179
|
-
// side: 'buy',
|
|
1180
|
-
// type: 'exchange limit',
|
|
1181
|
-
// timestamp: '1720172026.813',
|
|
1182
|
-
// is_live: true,
|
|
1183
|
-
// is_cancelled: false,
|
|
1184
|
-
// is_hidden: false,
|
|
1185
|
-
// oco_order: null,
|
|
1186
|
-
// was_forced: false,
|
|
1187
|
-
// original_amount: '10.0',
|
|
1188
|
-
// remaining_amount: '10.0',
|
|
1189
|
-
// executed_amount: '0.0',
|
|
1190
|
-
// src: 'api',
|
|
1191
|
-
// meta: {}
|
|
1192
|
-
// }
|
|
1193
|
-
//
|
|
1194
|
-
return this.parseOrder(response);
|
|
1195
|
-
}
|
|
1196
|
-
/**
|
|
1197
|
-
* @method
|
|
1198
|
-
* @name bitfinex1#cancelAllOrders
|
|
1199
|
-
* @description cancel all open orders
|
|
1200
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-cancel-all-orders
|
|
1201
|
-
* @param {string} symbol not used by bitfinex cancelAllOrders
|
|
1202
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1203
|
-
* @returns {object} response from exchange
|
|
1204
|
-
*/
|
|
1205
|
-
async cancelAllOrders(symbol = undefined, params = {}) {
|
|
1206
|
-
const response = await this.privatePostOrderCancelAll(params);
|
|
1207
|
-
//
|
|
1208
|
-
// { result: 'Submitting 1 order cancellations.' }
|
|
1209
|
-
//
|
|
1210
|
-
return [
|
|
1211
|
-
this.safeOrder({
|
|
1212
|
-
'info': response,
|
|
1213
|
-
}),
|
|
1214
|
-
];
|
|
1215
|
-
}
|
|
1216
|
-
parseOrder(order, market = undefined) {
|
|
1217
|
-
//
|
|
1218
|
-
// {
|
|
1219
|
-
// "id": 57334010955,
|
|
1220
|
-
// "cid": 1611584840966,
|
|
1221
|
-
// "cid_date": null,
|
|
1222
|
-
// "gid": null,
|
|
1223
|
-
// "symbol": "ltcbtc",
|
|
1224
|
-
// "exchange": null,
|
|
1225
|
-
// "price": "0.0042125",
|
|
1226
|
-
// "avg_execution_price": "0.0042097",
|
|
1227
|
-
// "side": "sell",
|
|
1228
|
-
// "type": "exchange market",
|
|
1229
|
-
// "timestamp": "1611584841.0",
|
|
1230
|
-
// "is_live": false,
|
|
1231
|
-
// "is_cancelled": false,
|
|
1232
|
-
// "is_hidden": 0,
|
|
1233
|
-
// "oco_order": 0,
|
|
1234
|
-
// "was_forced": false,
|
|
1235
|
-
// "original_amount": "0.205176",
|
|
1236
|
-
// "remaining_amount": "0.0",
|
|
1237
|
-
// "executed_amount": "0.205176",
|
|
1238
|
-
// "src": "web"
|
|
1239
|
-
// }
|
|
1240
|
-
//
|
|
1241
|
-
const side = this.safeString(order, 'side');
|
|
1242
|
-
const open = this.safeBool(order, 'is_live');
|
|
1243
|
-
const canceled = this.safeBool(order, 'is_cancelled');
|
|
1244
|
-
let status = undefined;
|
|
1245
|
-
if (open) {
|
|
1246
|
-
status = 'open';
|
|
1247
|
-
}
|
|
1248
|
-
else if (canceled) {
|
|
1249
|
-
status = 'canceled';
|
|
1250
|
-
}
|
|
1251
|
-
else {
|
|
1252
|
-
status = 'closed';
|
|
1253
|
-
}
|
|
1254
|
-
const marketId = this.safeStringUpper(order, 'symbol');
|
|
1255
|
-
const symbol = this.safeSymbol(marketId, market);
|
|
1256
|
-
let orderType = this.safeString(order, 'type', '');
|
|
1257
|
-
const exchange = orderType.indexOf('exchange ') >= 0;
|
|
1258
|
-
if (exchange) {
|
|
1259
|
-
const parts = order['type'].split(' ');
|
|
1260
|
-
orderType = parts[1];
|
|
1261
|
-
}
|
|
1262
|
-
const timestamp = this.safeTimestamp(order, 'timestamp');
|
|
1263
|
-
const id = this.safeString(order, 'id');
|
|
1264
|
-
return this.safeOrder({
|
|
1265
|
-
'info': order,
|
|
1266
|
-
'id': id,
|
|
1267
|
-
'clientOrderId': undefined,
|
|
1268
|
-
'timestamp': timestamp,
|
|
1269
|
-
'datetime': this.iso8601(timestamp),
|
|
1270
|
-
'lastTradeTimestamp': undefined,
|
|
1271
|
-
'symbol': symbol,
|
|
1272
|
-
'type': orderType,
|
|
1273
|
-
'timeInForce': undefined,
|
|
1274
|
-
'postOnly': undefined,
|
|
1275
|
-
'side': side,
|
|
1276
|
-
'price': this.safeString(order, 'price'),
|
|
1277
|
-
'triggerPrice': undefined,
|
|
1278
|
-
'average': this.safeString(order, 'avg_execution_price'),
|
|
1279
|
-
'amount': this.safeString(order, 'original_amount'),
|
|
1280
|
-
'remaining': this.safeString(order, 'remaining_amount'),
|
|
1281
|
-
'filled': this.safeString(order, 'executed_amount'),
|
|
1282
|
-
'status': status,
|
|
1283
|
-
'fee': undefined,
|
|
1284
|
-
'cost': undefined,
|
|
1285
|
-
'trades': undefined,
|
|
1286
|
-
}, market);
|
|
1287
|
-
}
|
|
1288
|
-
/**
|
|
1289
|
-
* @method
|
|
1290
|
-
* @name bitfinex1#fetchOpenOrders
|
|
1291
|
-
* @description fetch all unfilled currently open orders
|
|
1292
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-active-orders
|
|
1293
|
-
* @param {string} symbol unified market symbol
|
|
1294
|
-
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
1295
|
-
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
1296
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1297
|
-
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1298
|
-
*/
|
|
1299
|
-
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1300
|
-
await this.loadMarkets();
|
|
1301
|
-
if (symbol !== undefined) {
|
|
1302
|
-
if (!(symbol in this.markets)) {
|
|
1303
|
-
throw new ExchangeError(this.id + ' has no symbol ' + symbol);
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1306
|
-
const response = await this.privatePostOrders(params);
|
|
1307
|
-
let orders = this.parseOrders(response, undefined, since, limit);
|
|
1308
|
-
if (symbol !== undefined) {
|
|
1309
|
-
orders = this.filterBy(orders, 'symbol', symbol);
|
|
1310
|
-
}
|
|
1311
|
-
return orders;
|
|
1312
|
-
}
|
|
1313
|
-
/**
|
|
1314
|
-
* @method
|
|
1315
|
-
* @name bitfinex1#fetchClosedOrders
|
|
1316
|
-
* @description fetches information on multiple closed orders made by the user
|
|
1317
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-orders-history
|
|
1318
|
-
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1319
|
-
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1320
|
-
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1321
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1322
|
-
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1323
|
-
*/
|
|
1324
|
-
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1325
|
-
await this.loadMarkets();
|
|
1326
|
-
symbol = this.symbol(symbol);
|
|
1327
|
-
const request = {};
|
|
1328
|
-
if (limit !== undefined) {
|
|
1329
|
-
request['limit'] = limit;
|
|
1330
|
-
}
|
|
1331
|
-
const response = await this.privatePostOrdersHist(this.extend(request, params));
|
|
1332
|
-
let orders = this.parseOrders(response, undefined, since, limit);
|
|
1333
|
-
if (symbol !== undefined) {
|
|
1334
|
-
orders = this.filterBy(orders, 'symbol', symbol);
|
|
1335
|
-
}
|
|
1336
|
-
orders = this.filterByArray(orders, 'status', ['closed', 'canceled'], false);
|
|
1337
|
-
return orders;
|
|
1338
|
-
}
|
|
1339
|
-
/**
|
|
1340
|
-
* @method
|
|
1341
|
-
* @name bitfinex1#fetchOrder
|
|
1342
|
-
* @description fetches information on an order made by the user
|
|
1343
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-order-status
|
|
1344
|
-
* @param {string} id the order id
|
|
1345
|
-
* @param {string} symbol not used by bitfinex fetchOrder
|
|
1346
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1347
|
-
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1348
|
-
*/
|
|
1349
|
-
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
1350
|
-
await this.loadMarkets();
|
|
1351
|
-
const request = {
|
|
1352
|
-
'order_id': parseInt(id),
|
|
1353
|
-
};
|
|
1354
|
-
const response = await this.privatePostOrderStatus(this.extend(request, params));
|
|
1355
|
-
return this.parseOrder(response);
|
|
1356
|
-
}
|
|
1357
|
-
parseOHLCV(ohlcv, market = undefined) {
|
|
1358
|
-
//
|
|
1359
|
-
// [
|
|
1360
|
-
// 1457539800000,
|
|
1361
|
-
// 0.02594,
|
|
1362
|
-
// 0.02594,
|
|
1363
|
-
// 0.02594,
|
|
1364
|
-
// 0.02594,
|
|
1365
|
-
// 0.1
|
|
1366
|
-
// ]
|
|
1367
|
-
//
|
|
1368
|
-
return [
|
|
1369
|
-
this.safeInteger(ohlcv, 0),
|
|
1370
|
-
this.safeNumber(ohlcv, 1),
|
|
1371
|
-
this.safeNumber(ohlcv, 3),
|
|
1372
|
-
this.safeNumber(ohlcv, 4),
|
|
1373
|
-
this.safeNumber(ohlcv, 2),
|
|
1374
|
-
this.safeNumber(ohlcv, 5),
|
|
1375
|
-
];
|
|
1376
|
-
}
|
|
1377
|
-
/**
|
|
1378
|
-
* @method
|
|
1379
|
-
* @name bitfinex1#fetchOHLCV
|
|
1380
|
-
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1381
|
-
* @see https://docs.bitfinex.com/reference/rest-public-candles#aggregate-funding-currency-candles
|
|
1382
|
-
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1383
|
-
* @param {string} timeframe the length of time each candle represents
|
|
1384
|
-
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1385
|
-
* @param {int} [limit] the maximum amount of candles to fetch
|
|
1386
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1387
|
-
* @param {int} [params.until] timestamp in ms of the latest candle to fetch
|
|
1388
|
-
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1389
|
-
*/
|
|
1390
|
-
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
1391
|
-
await this.loadMarkets();
|
|
1392
|
-
if (limit === undefined) {
|
|
1393
|
-
limit = 100;
|
|
1394
|
-
}
|
|
1395
|
-
else {
|
|
1396
|
-
limit = Math.min(limit, 10000);
|
|
1397
|
-
}
|
|
1398
|
-
const market = this.market(symbol);
|
|
1399
|
-
const v2id = 't' + market['id'];
|
|
1400
|
-
const request = {
|
|
1401
|
-
'symbol': v2id,
|
|
1402
|
-
'timeframe': this.safeString(this.timeframes, timeframe, timeframe),
|
|
1403
|
-
'sort': 1,
|
|
1404
|
-
'limit': limit,
|
|
1405
|
-
};
|
|
1406
|
-
const until = this.safeInteger(params, 'until');
|
|
1407
|
-
if (since !== undefined) {
|
|
1408
|
-
request['start'] = since;
|
|
1409
|
-
}
|
|
1410
|
-
else if (until !== undefined) {
|
|
1411
|
-
const duration = this.parseTimeframe(timeframe);
|
|
1412
|
-
request['start'] = until - ((limit - 1) * duration * 1000);
|
|
1413
|
-
}
|
|
1414
|
-
if (until !== undefined) {
|
|
1415
|
-
request['end'] = until;
|
|
1416
|
-
}
|
|
1417
|
-
params = this.omit(params, 'until');
|
|
1418
|
-
const response = await this.v2GetCandlesTradeTimeframeSymbolHist(this.extend(request, params));
|
|
1419
|
-
//
|
|
1420
|
-
// [
|
|
1421
|
-
// [1457539800000,0.02594,0.02594,0.02594,0.02594,0.1],
|
|
1422
|
-
// [1457547300000,0.02577,0.02577,0.02577,0.02577,0.01],
|
|
1423
|
-
// [1457550240000,0.0255,0.0253,0.0255,0.0252,3.2640000000000002],
|
|
1424
|
-
// ]
|
|
1425
|
-
//
|
|
1426
|
-
return this.parseOHLCVs(response, market, timeframe, since, limit);
|
|
1427
|
-
}
|
|
1428
|
-
getCurrencyName(code) {
|
|
1429
|
-
// todo rewrite for https://api-pub.bitfinex.com//v2/conf/pub:map:tx:method
|
|
1430
|
-
if (code in this.options['currencyNames']) {
|
|
1431
|
-
return this.options['currencyNames'][code];
|
|
1432
|
-
}
|
|
1433
|
-
throw new NotSupported(this.id + ' ' + code + ' not supported for withdrawal');
|
|
1434
|
-
}
|
|
1435
|
-
/**
|
|
1436
|
-
* @method
|
|
1437
|
-
* @name bitfinex1#createDepositAddress
|
|
1438
|
-
* @description create a currency deposit address
|
|
1439
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-deposit
|
|
1440
|
-
* @param {string} code unified currency code of the currency for the deposit address
|
|
1441
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1442
|
-
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
1443
|
-
*/
|
|
1444
|
-
async createDepositAddress(code, params = {}) {
|
|
1445
|
-
await this.loadMarkets();
|
|
1446
|
-
const request = {
|
|
1447
|
-
'renew': 1,
|
|
1448
|
-
};
|
|
1449
|
-
return await this.fetchDepositAddress(code, this.extend(request, params));
|
|
1450
|
-
}
|
|
1451
|
-
/**
|
|
1452
|
-
* @method
|
|
1453
|
-
* @name bitfinex1#fetchDepositAddress
|
|
1454
|
-
* @description fetch the deposit address for a currency associated with this account
|
|
1455
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-deposit
|
|
1456
|
-
* @param {string} code unified currency code
|
|
1457
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1458
|
-
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
1459
|
-
*/
|
|
1460
|
-
async fetchDepositAddress(code, params = {}) {
|
|
1461
|
-
await this.loadMarkets();
|
|
1462
|
-
// todo rewrite for https://api-pub.bitfinex.com//v2/conf/pub:map:tx:method
|
|
1463
|
-
const name = this.getCurrencyName(code);
|
|
1464
|
-
const request = {
|
|
1465
|
-
'method': name,
|
|
1466
|
-
'wallet_name': 'exchange',
|
|
1467
|
-
'renew': 0, // a value of 1 will generate a new address
|
|
1468
|
-
};
|
|
1469
|
-
const response = await this.privatePostDepositNew(this.extend(request, params));
|
|
1470
|
-
let address = this.safeValue(response, 'address');
|
|
1471
|
-
let tag = undefined;
|
|
1472
|
-
if ('address_pool' in response) {
|
|
1473
|
-
tag = address;
|
|
1474
|
-
address = response['address_pool'];
|
|
1475
|
-
}
|
|
1476
|
-
this.checkAddress(address);
|
|
1477
|
-
return {
|
|
1478
|
-
'currency': code,
|
|
1479
|
-
'address': address,
|
|
1480
|
-
'tag': tag,
|
|
1481
|
-
'network': undefined,
|
|
1482
|
-
'info': response,
|
|
1483
|
-
};
|
|
1484
|
-
}
|
|
1485
|
-
/**
|
|
1486
|
-
* @method
|
|
1487
|
-
* @name bitfinex1#fetchDepositsWithdrawals
|
|
1488
|
-
* @description fetch history of deposits and withdrawals
|
|
1489
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-deposit-withdrawal-history
|
|
1490
|
-
* @param {string} code unified currency code for the currency of the deposit/withdrawals
|
|
1491
|
-
* @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
|
|
1492
|
-
* @param {int} [limit] max number of deposit/withdrawals to return, default is undefined
|
|
1493
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1494
|
-
* @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1495
|
-
*/
|
|
1496
|
-
async fetchDepositsWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1497
|
-
await this.loadMarkets();
|
|
1498
|
-
let currencyId = this.safeString(params, 'currency');
|
|
1499
|
-
const query = this.omit(params, 'currency');
|
|
1500
|
-
let currency = undefined;
|
|
1501
|
-
if (currencyId === undefined) {
|
|
1502
|
-
if (code === undefined) {
|
|
1503
|
-
throw new ArgumentsRequired(this.id + ' fetchDepositsWithdrawals() requires a currency `code` argument or a `currency` parameter');
|
|
1504
|
-
}
|
|
1505
|
-
else {
|
|
1506
|
-
currency = this.currency(code);
|
|
1507
|
-
currencyId = currency['id'];
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
query['currency'] = currencyId;
|
|
1511
|
-
if (since !== undefined) {
|
|
1512
|
-
query['since'] = this.parseToInt(since / 1000);
|
|
1513
|
-
}
|
|
1514
|
-
const response = await this.privatePostHistoryMovements(this.extend(query, params));
|
|
1515
|
-
//
|
|
1516
|
-
// [
|
|
1517
|
-
// {
|
|
1518
|
-
// "id": 581183,
|
|
1519
|
-
// "txid": 123456,
|
|
1520
|
-
// "currency": "BTC",
|
|
1521
|
-
// "method": "BITCOIN",
|
|
1522
|
-
// "type": "WITHDRAWAL",
|
|
1523
|
-
// "amount": ".01",
|
|
1524
|
-
// "description": "3QXYWgRGX2BPYBpUDBssGbeWEa5zq6snBZ, offchain transfer ",
|
|
1525
|
-
// "address": "3QXYWgRGX2BPYBpUDBssGbeWEa5zq6snBZ",
|
|
1526
|
-
// "status": "COMPLETED",
|
|
1527
|
-
// "timestamp": "1443833327.0",
|
|
1528
|
-
// "timestamp_created": "1443833327.1",
|
|
1529
|
-
// "fee": 0.1,
|
|
1530
|
-
// }
|
|
1531
|
-
// ]
|
|
1532
|
-
//
|
|
1533
|
-
return this.parseTransactions(response, currency, since, limit);
|
|
1534
|
-
}
|
|
1535
|
-
parseTransaction(transaction, currency = undefined) {
|
|
1536
|
-
//
|
|
1537
|
-
// crypto
|
|
1538
|
-
//
|
|
1539
|
-
// {
|
|
1540
|
-
// "id": 12042490,
|
|
1541
|
-
// "fee": "-0.02",
|
|
1542
|
-
// "txid": "EA5B5A66000B66855865EFF2494D7C8D1921FCBE996482157EBD749F2C85E13D",
|
|
1543
|
-
// "type": "DEPOSIT",
|
|
1544
|
-
// "amount": "2099.849999",
|
|
1545
|
-
// "method": "RIPPLE",
|
|
1546
|
-
// "status": "COMPLETED",
|
|
1547
|
-
// "address": "2505189261",
|
|
1548
|
-
// "currency": "XRP",
|
|
1549
|
-
// "timestamp": "1551730524.0",
|
|
1550
|
-
// "description": "EA5B5A66000B66855865EFF2494D7C8D1921FCBE996482157EBD749F2C85E13D",
|
|
1551
|
-
// "timestamp_created": "1551730523.0"
|
|
1552
|
-
// }
|
|
1553
|
-
//
|
|
1554
|
-
// fiat
|
|
1555
|
-
//
|
|
1556
|
-
// {
|
|
1557
|
-
// "id": 12725095,
|
|
1558
|
-
// "fee": "-60.0",
|
|
1559
|
-
// "txid": null,
|
|
1560
|
-
// "type": "WITHDRAWAL",
|
|
1561
|
-
// "amount": "9943.0",
|
|
1562
|
-
// "method": "WIRE",
|
|
1563
|
-
// "status": "SENDING",
|
|
1564
|
-
// "address": null,
|
|
1565
|
-
// "currency": "EUR",
|
|
1566
|
-
// "timestamp": "1561802484.0",
|
|
1567
|
-
// "description": "Name: bob, AccountAddress: some address, Account: someaccountno, Bank: bank address, SWIFT: foo, Country: UK, Details of Payment: withdrawal name, Intermediary Bank Name: , Intermediary Bank Address: , Intermediary Bank City: , Intermediary Bank Country: , Intermediary Bank Account: , Intermediary Bank SWIFT: , Fee: -60.0",
|
|
1568
|
-
// "timestamp_created": "1561716066.0"
|
|
1569
|
-
// }
|
|
1570
|
-
//
|
|
1571
|
-
// withdraw
|
|
1572
|
-
//
|
|
1573
|
-
// {
|
|
1574
|
-
// "status": "success",
|
|
1575
|
-
// "message": "Your withdrawal request has been successfully submitted.",
|
|
1576
|
-
// "withdrawal_id": 586829
|
|
1577
|
-
// }
|
|
1578
|
-
//
|
|
1579
|
-
const timestamp = this.safeTimestamp(transaction, 'timestamp_created');
|
|
1580
|
-
const currencyId = this.safeString(transaction, 'currency');
|
|
1581
|
-
const code = this.safeCurrencyCode(currencyId, currency);
|
|
1582
|
-
let feeCost = this.safeString(transaction, 'fee');
|
|
1583
|
-
if (feeCost !== undefined) {
|
|
1584
|
-
feeCost = Precise.stringAbs(feeCost);
|
|
1585
|
-
}
|
|
1586
|
-
return {
|
|
1587
|
-
'info': transaction,
|
|
1588
|
-
'id': this.safeString2(transaction, 'id', 'withdrawal_id'),
|
|
1589
|
-
'txid': this.safeString(transaction, 'txid'),
|
|
1590
|
-
'type': this.safeStringLower(transaction, 'type'),
|
|
1591
|
-
'currency': code,
|
|
1592
|
-
'network': undefined,
|
|
1593
|
-
'amount': this.safeNumber(transaction, 'amount'),
|
|
1594
|
-
'status': this.parseTransactionStatus(this.safeString(transaction, 'status')),
|
|
1595
|
-
'timestamp': timestamp,
|
|
1596
|
-
'datetime': this.iso8601(timestamp),
|
|
1597
|
-
'address': this.safeString(transaction, 'address'),
|
|
1598
|
-
'addressFrom': undefined,
|
|
1599
|
-
'addressTo': undefined,
|
|
1600
|
-
'tag': this.safeString(transaction, 'description'),
|
|
1601
|
-
'tagFrom': undefined,
|
|
1602
|
-
'tagTo': undefined,
|
|
1603
|
-
'updated': this.safeTimestamp(transaction, 'timestamp'),
|
|
1604
|
-
'comment': undefined,
|
|
1605
|
-
'internal': undefined,
|
|
1606
|
-
'fee': {
|
|
1607
|
-
'currency': code,
|
|
1608
|
-
'cost': this.parseNumber(feeCost),
|
|
1609
|
-
'rate': undefined,
|
|
1610
|
-
},
|
|
1611
|
-
};
|
|
1612
|
-
}
|
|
1613
|
-
parseTransactionStatus(status) {
|
|
1614
|
-
const statuses = {
|
|
1615
|
-
'SENDING': 'pending',
|
|
1616
|
-
'CANCELED': 'canceled',
|
|
1617
|
-
'ZEROCONFIRMED': 'failed',
|
|
1618
|
-
'COMPLETED': 'ok',
|
|
1619
|
-
};
|
|
1620
|
-
return this.safeString(statuses, status, status);
|
|
1621
|
-
}
|
|
1622
|
-
/**
|
|
1623
|
-
* @method
|
|
1624
|
-
* @name bitfinex1#withdraw
|
|
1625
|
-
* @description make a withdrawal
|
|
1626
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-withdrawal
|
|
1627
|
-
* @param {string} code unified currency code
|
|
1628
|
-
* @param {float} amount the amount to withdraw
|
|
1629
|
-
* @param {string} address the address to withdraw to
|
|
1630
|
-
* @param {string} tag
|
|
1631
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1632
|
-
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1633
|
-
*/
|
|
1634
|
-
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
1635
|
-
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
1636
|
-
this.checkAddress(address);
|
|
1637
|
-
await this.loadMarkets();
|
|
1638
|
-
// todo rewrite for https://api-pub.bitfinex.com//v2/conf/pub:map:tx:method
|
|
1639
|
-
const name = this.getCurrencyName(code);
|
|
1640
|
-
const currency = this.currency(code);
|
|
1641
|
-
const request = {
|
|
1642
|
-
'withdraw_type': name,
|
|
1643
|
-
'walletselected': 'exchange',
|
|
1644
|
-
'amount': this.numberToString(amount),
|
|
1645
|
-
'address': address,
|
|
1646
|
-
};
|
|
1647
|
-
if (tag !== undefined) {
|
|
1648
|
-
request['payment_id'] = tag;
|
|
1649
|
-
}
|
|
1650
|
-
const responses = await this.privatePostWithdraw(this.extend(request, params));
|
|
1651
|
-
//
|
|
1652
|
-
// [
|
|
1653
|
-
// {
|
|
1654
|
-
// "status":"success",
|
|
1655
|
-
// "message":"Your withdrawal request has been successfully submitted.",
|
|
1656
|
-
// "withdrawal_id":586829
|
|
1657
|
-
// }
|
|
1658
|
-
// ]
|
|
1659
|
-
//
|
|
1660
|
-
const response = this.safeDict(responses, 0, {});
|
|
1661
|
-
const id = this.safeInteger(response, 'withdrawal_id');
|
|
1662
|
-
const message = this.safeString(response, 'message');
|
|
1663
|
-
const errorMessage = this.findBroadlyMatchedKey(this.exceptions['broad'], message);
|
|
1664
|
-
if (id === 0) {
|
|
1665
|
-
if (errorMessage !== undefined) {
|
|
1666
|
-
const ExceptionClass = this.exceptions['broad'][errorMessage];
|
|
1667
|
-
throw new ExceptionClass(this.id + ' ' + message);
|
|
1668
|
-
}
|
|
1669
|
-
throw new ExchangeError(this.id + ' withdraw returned an id of zero: ' + this.json(response));
|
|
1670
|
-
}
|
|
1671
|
-
return this.parseTransaction(response, currency);
|
|
1672
|
-
}
|
|
1673
|
-
/**
|
|
1674
|
-
* @method
|
|
1675
|
-
* @name bitfinex1#fetchPositions
|
|
1676
|
-
* @description fetch all open positions
|
|
1677
|
-
* @see https://docs.bitfinex.com/v1/reference/rest-auth-active-positions
|
|
1678
|
-
* @param {string[]|undefined} symbols list of unified market symbols
|
|
1679
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1680
|
-
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
|
1681
|
-
*/
|
|
1682
|
-
async fetchPositions(symbols = undefined, params = {}) {
|
|
1683
|
-
await this.loadMarkets();
|
|
1684
|
-
const response = await this.privatePostPositions(params);
|
|
1685
|
-
//
|
|
1686
|
-
// [
|
|
1687
|
-
// {
|
|
1688
|
-
// "id":943715,
|
|
1689
|
-
// "symbol":"btcusd",
|
|
1690
|
-
// "status":"ACTIVE",
|
|
1691
|
-
// "base":"246.94",
|
|
1692
|
-
// "amount":"1.0",
|
|
1693
|
-
// "timestamp":"1444141857.0",
|
|
1694
|
-
// "swap":"0.0",
|
|
1695
|
-
// "pl":"-2.22042"
|
|
1696
|
-
// }
|
|
1697
|
-
// ]
|
|
1698
|
-
//
|
|
1699
|
-
// todo unify parsePosition/parsePositions
|
|
1700
|
-
return response;
|
|
1701
|
-
}
|
|
1702
|
-
nonce() {
|
|
1703
|
-
return this.microseconds();
|
|
1704
|
-
}
|
|
1705
|
-
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
1706
|
-
let request = '/' + this.implodeParams(path, params);
|
|
1707
|
-
if (api === 'v2') {
|
|
1708
|
-
request = '/' + api + request;
|
|
1709
|
-
}
|
|
1710
|
-
else {
|
|
1711
|
-
request = '/' + this.version + request;
|
|
1712
|
-
}
|
|
1713
|
-
let query = this.omit(params, this.extractParams(path));
|
|
1714
|
-
let url = this.urls['api'][api] + request;
|
|
1715
|
-
if ((api === 'public') || (path.indexOf('/hist') >= 0)) {
|
|
1716
|
-
if (Object.keys(query).length) {
|
|
1717
|
-
const suffix = '?' + this.urlencode(query);
|
|
1718
|
-
url += suffix;
|
|
1719
|
-
request += suffix;
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
|
-
if (api === 'private') {
|
|
1723
|
-
this.checkRequiredCredentials();
|
|
1724
|
-
const nonce = this.nonce();
|
|
1725
|
-
query = this.extend({
|
|
1726
|
-
'nonce': nonce.toString(),
|
|
1727
|
-
'request': request,
|
|
1728
|
-
}, query);
|
|
1729
|
-
body = this.json(query);
|
|
1730
|
-
const payload = this.stringToBase64(body);
|
|
1731
|
-
const secret = this.encode(this.secret);
|
|
1732
|
-
const signature = this.hmac(this.encode(payload), secret, sha384);
|
|
1733
|
-
headers = {
|
|
1734
|
-
'X-BFX-APIKEY': this.apiKey,
|
|
1735
|
-
'X-BFX-PAYLOAD': payload,
|
|
1736
|
-
'X-BFX-SIGNATURE': signature,
|
|
1737
|
-
'Content-Type': 'application/json',
|
|
1738
|
-
};
|
|
1739
|
-
}
|
|
1740
|
-
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
1741
|
-
}
|
|
1742
|
-
handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
1743
|
-
if (response === undefined) {
|
|
1744
|
-
return undefined;
|
|
1745
|
-
}
|
|
1746
|
-
let throwError = false;
|
|
1747
|
-
if (code >= 400) {
|
|
1748
|
-
if (body[0] === '{') {
|
|
1749
|
-
throwError = true;
|
|
1750
|
-
}
|
|
1751
|
-
}
|
|
1752
|
-
else {
|
|
1753
|
-
// json response with error, i.e:
|
|
1754
|
-
// [{"status":"error","message":"Momentary balance check. Please wait few seconds and try the transfer again."}]
|
|
1755
|
-
const responseObject = this.safeDict(response, 0, {});
|
|
1756
|
-
const status = this.safeString(responseObject, 'status', '');
|
|
1757
|
-
if (status === 'error') {
|
|
1758
|
-
throwError = true;
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1761
|
-
if (throwError) {
|
|
1762
|
-
const feedback = this.id + ' ' + body;
|
|
1763
|
-
const message = this.safeString2(response, 'message', 'error');
|
|
1764
|
-
this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
|
|
1765
|
-
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
1766
|
-
throw new ExchangeError(feedback); // unknown message
|
|
1767
|
-
}
|
|
1768
|
-
return undefined;
|
|
1769
|
-
}
|
|
1770
|
-
}
|