@yuants/vendor-huobi 0.11.41 → 0.13.0
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/dist/account-info.js +235 -0
- package/dist/account-info.js.map +1 -0
- package/dist/api/private-api.js +251 -0
- package/dist/api/private-api.js.map +1 -0
- package/dist/api/public-api.js +145 -0
- package/dist/api/public-api.js.map +1 -0
- package/dist/api.js +0 -279
- package/dist/api.js.map +1 -1
- package/dist/index.js +28 -524
- package/dist/index.js.map +1 -1
- package/dist/interest_rate.js +2 -2
- package/dist/interest_rate.js.map +1 -1
- package/dist/order-actions-with-credentials.js +15 -0
- package/dist/order-actions-with-credentials.js.map +1 -0
- package/dist/order-actions.js +17 -0
- package/dist/order-actions.js.map +1 -0
- package/dist/orders/submitOrder.js +93 -0
- package/dist/orders/submitOrder.js.map +1 -0
- package/dist/product.js +4 -4
- package/dist/product.js.map +1 -1
- package/dist/quote.js +5 -5
- package/dist/quote.js.map +1 -1
- package/dist/transfer.js +248 -0
- package/dist/transfer.js.map +1 -0
- package/dist/uid.js +22 -0
- package/dist/uid.js.map +1 -0
- package/lib/account-info.d.ts +35 -0
- package/lib/account-info.d.ts.map +1 -0
- package/lib/account-info.js +243 -0
- package/lib/account-info.js.map +1 -0
- package/lib/api/private-api.d.ts +474 -0
- package/lib/api/private-api.d.ts.map +1 -0
- package/lib/api/private-api.js +280 -0
- package/lib/api/private-api.js.map +1 -0
- package/lib/api/public-api.d.ts +308 -0
- package/lib/api/public-api.d.ts.map +1 -0
- package/lib/api/public-api.js +158 -0
- package/lib/api/public-api.js.map +1 -0
- package/lib/api.d.ts +2 -621
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +0 -279
- package/lib/api.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +26 -522
- package/lib/index.js.map +1 -1
- package/lib/interest_rate.js +2 -2
- package/lib/interest_rate.js.map +1 -1
- package/lib/order-actions-with-credentials.d.ts +2 -0
- package/lib/order-actions-with-credentials.d.ts.map +1 -0
- package/lib/order-actions-with-credentials.js +17 -0
- package/lib/order-actions-with-credentials.js.map +1 -0
- package/lib/order-actions.d.ts +7 -0
- package/lib/order-actions.d.ts.map +1 -0
- package/lib/order-actions.js +21 -0
- package/lib/order-actions.js.map +1 -0
- package/lib/orders/submitOrder.d.ts +6 -0
- package/lib/orders/submitOrder.d.ts.map +1 -0
- package/lib/orders/submitOrder.js +97 -0
- package/lib/orders/submitOrder.js.map +1 -0
- package/lib/product.js +4 -4
- package/lib/product.js.map +1 -1
- package/lib/quote.js +5 -5
- package/lib/quote.js.map +1 -1
- package/lib/transfer.d.ts +19 -0
- package/lib/transfer.d.ts.map +1 -0
- package/lib/transfer.js +255 -0
- package/lib/transfer.js.map +1 -0
- package/lib/uid.d.ts +13 -0
- package/lib/uid.d.ts.map +1 -0
- package/lib/uid.js +26 -0
- package/lib/uid.js.map +1 -0
- package/package.json +3 -3
- package/temp/package-deps.json +18 -11
- package/dist/logger.js +0 -91
- package/dist/logger.js.map +0 -1
- package/lib/logger.d.ts +0 -21
- package/lib/logger.d.ts.map +0 -1
- package/lib/logger.js +0 -98
- package/lib/logger.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,547 +1,51 @@
|
|
|
1
|
-
import { addAccountMarket
|
|
1
|
+
import { addAccountMarket } from '@yuants/data-account';
|
|
2
2
|
import { Terminal } from '@yuants/protocol';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { client } from './api';
|
|
3
|
+
import { formatTime } from '@yuants/utils';
|
|
4
|
+
import { provideSpotAccountInfoService, provideSwapAccountInfoService } from './account-info';
|
|
5
|
+
import { getAccount, getDefaultCredential, getSubUserList, getSwapUnifiedAccountType, getUid, postSwapSwitchAccountType, } from './api/private-api';
|
|
7
6
|
import './interest_rate';
|
|
8
|
-
import {
|
|
7
|
+
import { provideOrderSubmitService } from './order-actions';
|
|
8
|
+
import './order-actions-with-credentials';
|
|
9
9
|
import './quote';
|
|
10
|
+
import { setupSpotSuperMarginTransfer, setupSpotSwapTransfer, setupSubAccountTransfers, setupTrc20WithdrawalAddresses, } from './transfer';
|
|
11
|
+
import { spotAccountUidCache } from './uid';
|
|
10
12
|
const terminal = Terminal.fromNodeEnv();
|
|
13
|
+
const credential = getDefaultCredential();
|
|
11
14
|
(async () => {
|
|
12
|
-
var _a
|
|
13
|
-
|
|
15
|
+
var _a;
|
|
16
|
+
// 账户类型切换
|
|
17
|
+
const swapAccountTypeRes = await getSwapUnifiedAccountType(credential);
|
|
14
18
|
if (((_a = swapAccountTypeRes.data) === null || _a === void 0 ? void 0 : _a.account_type) === 1) {
|
|
15
19
|
console.info(formatTime(Date.now()), 'SwitchingAccountType', `previous: ${swapAccountTypeRes.data.account_type}, switching to 2 (unified account)`);
|
|
16
|
-
const switchRes = await
|
|
20
|
+
const switchRes = await postSwapSwitchAccountType(credential, { account_type: 2 });
|
|
17
21
|
console.info(formatTime(Date.now()), 'SwitchingAccountType', `current: ${switchRes.data.account_type}`);
|
|
18
22
|
}
|
|
19
|
-
const huobiUid = (await
|
|
23
|
+
const huobiUid = (await getUid(credential)).data;
|
|
20
24
|
console.info(formatTime(Date.now()), 'UID', huobiUid);
|
|
21
|
-
const huobiAccounts = await
|
|
22
|
-
const
|
|
23
|
-
const spotAccountUid = (_c = huobiAccounts.data.find((v) => v.type === 'spot')) === null || _c === void 0 ? void 0 : _c.id;
|
|
25
|
+
const huobiAccounts = await getAccount(credential);
|
|
26
|
+
const spotAccountUid = (await spotAccountUidCache.query(JSON.stringify(credential)));
|
|
24
27
|
console.info(formatTime(Date.now()), 'huobiAccount', JSON.stringify(huobiAccounts));
|
|
25
28
|
const account_id = `huobi/${huobiUid}`;
|
|
26
29
|
const SPOT_ACCOUNT_ID = `${account_id}/spot/usdt`;
|
|
27
30
|
const SUPER_MARGIN_ACCOUNT_ID = `${account_id}/super-margin`;
|
|
28
31
|
const SWAP_ACCOUNT_ID = `${account_id}/swap`;
|
|
29
|
-
const subUsersRes = await
|
|
32
|
+
const subUsersRes = await getSubUserList(credential);
|
|
30
33
|
const subAccounts = subUsersRes.data;
|
|
31
34
|
const isMainAccount = subUsersRes.ok;
|
|
32
35
|
console.info(formatTime(Date.now()), 'subAccounts', JSON.stringify(subAccounts));
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
throw new Error('Failed to get unified account info');
|
|
38
|
-
}
|
|
39
|
-
const balanceData = balance.data.find((v) => v.margin_asset === 'USDT');
|
|
40
|
-
if (!balanceData) {
|
|
41
|
-
throw new Error('No USDT balance found in unified account');
|
|
42
|
-
}
|
|
43
|
-
const equity = balanceData.margin_balance;
|
|
44
|
-
const free = balanceData.withdraw_available;
|
|
45
|
-
// positions
|
|
46
|
-
const positionsRes = await client.getSwapCrossPositionInfo();
|
|
47
|
-
const mapProductIdToPerpetualProduct = await firstValueFrom(swapProductService.mapProductIdToProduct$);
|
|
48
|
-
const positions = (positionsRes.data || []).map((v) => {
|
|
49
|
-
const product_id = v.contract_code;
|
|
50
|
-
const theProduct = mapProductIdToPerpetualProduct === null || mapProductIdToPerpetualProduct === void 0 ? void 0 : mapProductIdToPerpetualProduct.get(product_id);
|
|
51
|
-
const valuation = v.volume * v.last_price * ((theProduct === null || theProduct === void 0 ? void 0 : theProduct.value_scale) || 1);
|
|
52
|
-
return {
|
|
53
|
-
position_id: `${v.contract_code}/${v.contract_type}/${v.direction}/${v.margin_mode}`,
|
|
54
|
-
datasource_id: 'HUOBI-SWAP',
|
|
55
|
-
product_id,
|
|
56
|
-
direction: v.direction === 'buy' ? 'LONG' : 'SHORT',
|
|
57
|
-
volume: v.volume,
|
|
58
|
-
free_volume: v.available,
|
|
59
|
-
position_price: v.cost_hold,
|
|
60
|
-
closable_price: v.last_price,
|
|
61
|
-
floating_profit: v.profit_unreal,
|
|
62
|
-
valuation,
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
|
-
// orders
|
|
66
|
-
// const orders: IOrder[] = [];
|
|
67
|
-
// let page_index = 1;
|
|
68
|
-
// const page_size = 50;
|
|
69
|
-
// while (true) {
|
|
70
|
-
// const ordersRes = await client.getSwapOpenOrders({ page_index, page_size });
|
|
71
|
-
// if (!ordersRes.data?.orders || ordersRes.data.orders.length === 0) {
|
|
72
|
-
// break;
|
|
73
|
-
// }
|
|
74
|
-
// const pageOrders: IOrder[] = ordersRes.data.orders.map((v): IOrder => {
|
|
75
|
-
// return {
|
|
76
|
-
// order_id: v.order_id_str,
|
|
77
|
-
// account_id: SWAP_ACCOUNT_ID,
|
|
78
|
-
// product_id: v.contract_code,
|
|
79
|
-
// order_type: ['lightning'].includes(v.order_price_type)
|
|
80
|
-
// ? 'MARKET'
|
|
81
|
-
// : ['limit', 'opponent', 'post_only', 'optimal_5', 'optimal_10', 'optimal_20'].includes(
|
|
82
|
-
// v.order_price_type,
|
|
83
|
-
// )
|
|
84
|
-
// ? 'LIMIT'
|
|
85
|
-
// : ['fok'].includes(v.order_price_type)
|
|
86
|
-
// ? 'FOK'
|
|
87
|
-
// : v.order_price_type.includes('ioc')
|
|
88
|
-
// ? 'IOC'
|
|
89
|
-
// : 'STOP', // unreachable code
|
|
90
|
-
// order_direction:
|
|
91
|
-
// v.direction === 'open'
|
|
92
|
-
// ? v.offset === 'buy'
|
|
93
|
-
// ? 'OPEN_LONG'
|
|
94
|
-
// : 'OPEN_SHORT'
|
|
95
|
-
// : v.offset === 'buy'
|
|
96
|
-
// ? 'CLOSE_SHORT'
|
|
97
|
-
// : 'CLOSE_LONG',
|
|
98
|
-
// volume: v.volume,
|
|
99
|
-
// submit_at: v.created_at,
|
|
100
|
-
// price: v.price,
|
|
101
|
-
// traded_volume: v.trade_volume,
|
|
102
|
-
// };
|
|
103
|
-
// });
|
|
104
|
-
// orders.push(...pageOrders);
|
|
105
|
-
// page_index++;
|
|
106
|
-
// }
|
|
107
|
-
return {
|
|
108
|
-
money: {
|
|
109
|
-
currency: 'USDT',
|
|
110
|
-
equity,
|
|
111
|
-
free,
|
|
112
|
-
},
|
|
113
|
-
positions,
|
|
114
|
-
};
|
|
115
|
-
}, { auto_refresh_interval: 1000 });
|
|
116
|
-
const superMarginUnifiedRawAccountBalance$ = defer(() => client.getSpotAccountBalance(superMarginAccountUid)).pipe(
|
|
117
|
-
//
|
|
118
|
-
map((res) => res.data), repeat({ delay: 1000 }), tap({
|
|
119
|
-
error: (e) => {
|
|
120
|
-
console.error(formatTime(Date.now()), 'unifiedRaw', e);
|
|
121
|
-
},
|
|
122
|
-
}), retry({ delay: 5000 }), shareReplay(1));
|
|
123
|
-
const subscriptions = new Set();
|
|
124
|
-
from(client.spot_ws.connection$).subscribe(() => {
|
|
125
|
-
subscriptions.clear();
|
|
126
|
-
});
|
|
127
|
-
// subscribe the symbols of positions we held
|
|
128
|
-
superMarginUnifiedRawAccountBalance$
|
|
129
|
-
.pipe(
|
|
130
|
-
//
|
|
131
|
-
mergeMap((res) => from((res === null || res === void 0 ? void 0 : res.list) || []).pipe(filter((v) => v.currency !== 'usdt'), map((v) => v.currency), distinct(), toArray(), map((v) => new Set(v)))))
|
|
132
|
-
.subscribe((v) => {
|
|
133
|
-
const toUnsubscribe = [...subscriptions].filter((x) => !v.has(x));
|
|
134
|
-
const toSubscribe = [...v].filter((x) => !subscriptions.has(x));
|
|
135
|
-
for (const symbol of toUnsubscribe) {
|
|
136
|
-
client.spot_ws.output$.next({
|
|
137
|
-
unsub: `market.${symbol}usdt.ticker`,
|
|
138
|
-
});
|
|
139
|
-
subscriptions.delete(symbol);
|
|
140
|
-
}
|
|
141
|
-
for (const symbol of toSubscribe) {
|
|
142
|
-
client.spot_ws.output$.next({
|
|
143
|
-
sub: `market.${symbol}usdt.ticker`,
|
|
144
|
-
});
|
|
145
|
-
subscriptions.add(symbol);
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
provideAccountInfoService(terminal, SUPER_MARGIN_ACCOUNT_ID, async () => {
|
|
149
|
-
var _a;
|
|
150
|
-
// get account balance
|
|
151
|
-
const accountBalance = await client.getSpotAccountBalance(superMarginAccountUid);
|
|
152
|
-
const balanceList = ((_a = accountBalance.data) === null || _a === void 0 ? void 0 : _a.list) || [];
|
|
153
|
-
// calculate usdt balance
|
|
154
|
-
const usdtBalance = balanceList
|
|
155
|
-
.filter((v) => v.currency === 'usdt')
|
|
156
|
-
.reduce((acc, cur) => acc + +cur.balance, 0);
|
|
157
|
-
// get positions (non-usdt currencies)
|
|
158
|
-
const positions = [];
|
|
159
|
-
const nonUsdtCurrencies = balanceList
|
|
160
|
-
.filter((v) => v.currency !== 'usdt')
|
|
161
|
-
.reduce((acc, cur) => {
|
|
162
|
-
const existing = acc.find((item) => item.currency === cur.currency);
|
|
163
|
-
if (existing) {
|
|
164
|
-
existing.balance += +cur.balance;
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
acc.push({ currency: cur.currency, balance: +cur.balance });
|
|
168
|
-
}
|
|
169
|
-
return acc;
|
|
170
|
-
}, []);
|
|
171
|
-
// get prices and create positions
|
|
172
|
-
for (const currencyData of nonUsdtCurrencies) {
|
|
173
|
-
if (currencyData.balance > 0) {
|
|
174
|
-
try {
|
|
175
|
-
// get current price from websocket or fallback to REST API
|
|
176
|
-
let price;
|
|
177
|
-
try {
|
|
178
|
-
const tickPrice = await firstValueFrom(client.spot_ws.input$.pipe(
|
|
179
|
-
//
|
|
180
|
-
first((v) => { var _a, _b; return ((_a = v.ch) === null || _a === void 0 ? void 0 : _a.includes('ticker')) && ((_b = v.ch) === null || _b === void 0 ? void 0 : _b.includes(currencyData.currency)) && v.tick; }), map((v) => v.tick.bid), timeout(5000), tap({
|
|
181
|
-
error: (e) => {
|
|
182
|
-
subscriptions.clear();
|
|
183
|
-
},
|
|
184
|
-
})));
|
|
185
|
-
price = tickPrice;
|
|
186
|
-
}
|
|
187
|
-
catch (_b) {
|
|
188
|
-
// fallback to REST API
|
|
189
|
-
const tickerRes = await client.getSpotTick({ symbol: `${currencyData.currency}usdt` });
|
|
190
|
-
price = tickerRes.tick.close;
|
|
191
|
-
}
|
|
192
|
-
positions.push({
|
|
193
|
-
position_id: `${currencyData.currency}/usdt/spot`,
|
|
194
|
-
product_id: `${currencyData.currency}usdt`,
|
|
195
|
-
direction: 'LONG',
|
|
196
|
-
volume: currencyData.balance,
|
|
197
|
-
free_volume: currencyData.balance,
|
|
198
|
-
position_price: price,
|
|
199
|
-
closable_price: price,
|
|
200
|
-
floating_profit: 0,
|
|
201
|
-
valuation: currencyData.balance * price,
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
catch (error) {
|
|
205
|
-
console.warn(formatTime(Date.now()), `Failed to get price for ${currencyData.currency}:`, error);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
// calculate equity
|
|
210
|
-
const equity = positions.reduce((acc, cur) => acc + cur.closable_price * cur.volume, 0) + usdtBalance;
|
|
211
|
-
return {
|
|
212
|
-
money: {
|
|
213
|
-
currency: 'USDT',
|
|
214
|
-
equity,
|
|
215
|
-
free: equity,
|
|
216
|
-
},
|
|
217
|
-
positions,
|
|
218
|
-
};
|
|
219
|
-
}, { auto_refresh_interval: 1000 });
|
|
220
|
-
provideAccountInfoService(terminal, SPOT_ACCOUNT_ID, async () => {
|
|
221
|
-
var _a, _b;
|
|
222
|
-
const spotBalance = await client.getSpotAccountBalance(spotAccountUid);
|
|
223
|
-
const equity = +((_b = (_a = spotBalance.data.list.find((v) => v.currency === 'usdt')) === null || _a === void 0 ? void 0 : _a.balance) !== null && _b !== void 0 ? _b : 0);
|
|
224
|
-
const free = equity;
|
|
225
|
-
return {
|
|
226
|
-
money: {
|
|
227
|
-
currency: 'USDT',
|
|
228
|
-
equity,
|
|
229
|
-
free,
|
|
230
|
-
},
|
|
231
|
-
positions: [],
|
|
232
|
-
};
|
|
233
|
-
}, { auto_refresh_interval: 1000 });
|
|
36
|
+
// 设置账户信息服务
|
|
37
|
+
provideSwapAccountInfoService(terminal, SWAP_ACCOUNT_ID, credential);
|
|
38
|
+
provideSpotAccountInfoService(terminal, SPOT_ACCOUNT_ID, credential, spotAccountUid);
|
|
39
|
+
// 设置账户市场关联
|
|
234
40
|
addAccountMarket(terminal, { account_id: SPOT_ACCOUNT_ID, market_id: 'HUOBI/SPOT' });
|
|
235
41
|
addAccountMarket(terminal, { account_id: SUPER_MARGIN_ACCOUNT_ID, market_id: 'HUOBI/SUPER-MARGIN' });
|
|
236
42
|
addAccountMarket(terminal, { account_id: SWAP_ACCOUNT_ID, market_id: 'HUOBI/SWAP' });
|
|
237
|
-
//
|
|
238
|
-
terminal
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
},
|
|
245
|
-
}, (msg) => {
|
|
246
|
-
const { account_id: req_account_id } = msg.req;
|
|
247
|
-
console.info(formatTime(Date.now()), `SubmitOrder for ${account_id}`, JSON.stringify(msg));
|
|
248
|
-
if (req_account_id === SWAP_ACCOUNT_ID) {
|
|
249
|
-
return defer(() => client.getSwapCrossPositionInfo()).pipe(mergeMap((res) => res.data), map((v) => [v.contract_code, v.lever_rate]), toArray(), map((v) => Object.fromEntries(v)), mergeMap((mapContractCodeToRate) => {
|
|
250
|
-
var _a;
|
|
251
|
-
const lever_rate = (_a = mapContractCodeToRate[msg.req.product_id]) !== null && _a !== void 0 ? _a : 20;
|
|
252
|
-
const params = {
|
|
253
|
-
contract_code: msg.req.product_id,
|
|
254
|
-
contract_type: 'swap',
|
|
255
|
-
price: msg.req.price,
|
|
256
|
-
volume: msg.req.volume,
|
|
257
|
-
offset: msg.req.order_direction === 'OPEN_LONG' || msg.req.order_direction === 'OPEN_SHORT'
|
|
258
|
-
? 'open'
|
|
259
|
-
: 'close',
|
|
260
|
-
direction: msg.req.order_direction === 'OPEN_LONG' || msg.req.order_direction === 'CLOSE_SHORT'
|
|
261
|
-
? 'buy'
|
|
262
|
-
: 'sell',
|
|
263
|
-
// dynamically adjust the leverage
|
|
264
|
-
lever_rate,
|
|
265
|
-
order_price_type: msg.req.order_type === 'MARKET' ? 'market' : 'limit',
|
|
266
|
-
};
|
|
267
|
-
return client.postSwapOrder(params).then((v) => {
|
|
268
|
-
console.info(formatTime(Date.now()), 'SubmitOrder', JSON.stringify(v), JSON.stringify(params));
|
|
269
|
-
return v;
|
|
270
|
-
});
|
|
271
|
-
}), map((v) => {
|
|
272
|
-
if (v.status !== 'ok') {
|
|
273
|
-
return { res: { code: 500, message: v.status } };
|
|
274
|
-
}
|
|
275
|
-
return { res: { code: 0, message: 'OK' } };
|
|
276
|
-
}), catchError((e) => {
|
|
277
|
-
console.error(formatTime(Date.now()), 'SubmitOrder', e);
|
|
278
|
-
return of({ res: { code: 500, message: `${e}` } });
|
|
279
|
-
}));
|
|
280
|
-
}
|
|
281
|
-
// for super-margin orders, we need to denote the amount of usdt to borrow, therefore we need to:
|
|
282
|
-
// 1. get the loanable amount
|
|
283
|
-
// 2. get the current balance
|
|
284
|
-
// 3. get the current price
|
|
285
|
-
// 4. combine the information to submit the order
|
|
286
|
-
return defer(() => client.getCrossMarginLoanInfo()).pipe(
|
|
287
|
-
//
|
|
288
|
-
mergeMap((res) => res.data), first((v) => v.currency === 'usdt'), map((v) => +v['loanable-amt']), combineLatestWith(superMarginUnifiedRawAccountBalance$.pipe(first(), mergeMap((res) => from(res.list).pipe(
|
|
289
|
-
// we only need the amount of usdt that can be used to trade
|
|
290
|
-
filter((v) => v.currency === 'usdt' && v.type === 'trade'), reduce((acc, cur) => acc + +cur.balance, 0))))), combineLatestWith(spotProductService.mapProductIdToProduct$.pipe(first())), mergeMap(async ([[loanable, balance], mapProductIdToProduct]) => {
|
|
291
|
-
const priceRes = await client.getSpotTick({ symbol: msg.req.product_id });
|
|
292
|
-
const theProduct = mapProductIdToProduct.get(msg.req.product_id);
|
|
293
|
-
const price = priceRes.tick.close;
|
|
294
|
-
const borrow_amount = msg.req.order_direction === 'OPEN_LONG' || msg.req.order_direction === 'CLOSE_SHORT'
|
|
295
|
-
? Math.max(Math.min(loanable, msg.req.volume * price - balance), 0)
|
|
296
|
-
: undefined;
|
|
297
|
-
const params = {
|
|
298
|
-
symbol: msg.req.product_id,
|
|
299
|
-
'account-id': '' + superMarginAccountUid,
|
|
300
|
-
// amount: msg.req.type === OrderType.MARKET ? 0 : '' + msg.req.volume,
|
|
301
|
-
// 'market-amount': msg.req.type === OrderType.MARKET ? '' + msg.req.volume : undefined,
|
|
302
|
-
amount: '' +
|
|
303
|
-
(msg.req.order_direction === 'OPEN_LONG' || msg.req.order_direction === 'CLOSE_SHORT'
|
|
304
|
-
? roundToStep(msg.req.volume * price, theProduct === null || theProduct === void 0 ? void 0 : theProduct.volume_step)
|
|
305
|
-
: msg.req.volume),
|
|
306
|
-
'borrow-amount': '' + borrow_amount,
|
|
307
|
-
type: `${msg.req.order_direction === 'OPEN_LONG' || msg.req.order_direction === 'CLOSE_SHORT'
|
|
308
|
-
? 'buy'
|
|
309
|
-
: 'sell'}-${'LIMIT' === msg.req.order_type ? 'limit' : 'market'}`,
|
|
310
|
-
'trade-purpose': msg.req.order_direction === 'OPEN_LONG' || msg.req.order_direction === 'CLOSE_SHORT'
|
|
311
|
-
? '1' // auto borrow
|
|
312
|
-
: '2',
|
|
313
|
-
price: msg.req.order_type === 'MARKET' ? undefined : '' + msg.req.price,
|
|
314
|
-
source: 'super-margin-api',
|
|
315
|
-
};
|
|
316
|
-
return client.postSpotOrder(params).then((v) => {
|
|
317
|
-
console.info(formatTime(Date.now()), 'SubmitOrder', JSON.stringify(v), JSON.stringify(params));
|
|
318
|
-
return v;
|
|
319
|
-
});
|
|
320
|
-
}), map((v) => {
|
|
321
|
-
if (v.success === false) {
|
|
322
|
-
return { res: { code: v.code, message: v.message } };
|
|
323
|
-
}
|
|
324
|
-
return { res: { code: 0, message: 'OK' } };
|
|
325
|
-
}), catchError((e) => {
|
|
326
|
-
console.error(formatTime(Date.now()), 'SubmitOrder', e);
|
|
327
|
-
return of({ res: { code: 500, message: `${e}` } });
|
|
328
|
-
}));
|
|
329
|
-
});
|
|
330
|
-
// Update Spot TRC20 Addresses (Only Main Account)
|
|
331
|
-
if (isMainAccount) {
|
|
332
|
-
const res = await client.getSpotAccountDepositAddresses({ currency: 'usdt' });
|
|
333
|
-
const addresses = res.data.filter((v) => v.chain === 'trc20usdt').map((v) => v.address);
|
|
334
|
-
for (const address of addresses) {
|
|
335
|
-
addAccountTransferAddress({
|
|
336
|
-
terminal,
|
|
337
|
-
account_id: SPOT_ACCOUNT_ID,
|
|
338
|
-
currency: 'USDT',
|
|
339
|
-
address: address,
|
|
340
|
-
network_id: 'TRC20',
|
|
341
|
-
onApply: {
|
|
342
|
-
INIT: async (order) => {
|
|
343
|
-
var _a, _b;
|
|
344
|
-
const res0 = await client.getV2ReferenceCurrencies({ currency: 'usdt' });
|
|
345
|
-
const fee = (_b = (_a = res0.data
|
|
346
|
-
.find((v) => v.currency === 'usdt')) === null || _a === void 0 ? void 0 : _a.chains.find((v) => v.chain === 'trc20usdt')) === null || _b === void 0 ? void 0 : _b.transactFeeWithdraw;
|
|
347
|
-
if (!fee) {
|
|
348
|
-
return { state: 'ERROR', message: 'MISSING FEE' };
|
|
349
|
-
}
|
|
350
|
-
const res = await client.postWithdraw({
|
|
351
|
-
address: order.current_rx_address,
|
|
352
|
-
amount: '' + (order.expected_amount - +fee),
|
|
353
|
-
currency: 'usdt',
|
|
354
|
-
fee: fee,
|
|
355
|
-
chain: 'trc20usdt',
|
|
356
|
-
});
|
|
357
|
-
if (res.status != 'ok') {
|
|
358
|
-
return { state: 'INIT', message: `${res.status}` };
|
|
359
|
-
}
|
|
360
|
-
return { state: 'PENDING', context: `${res.data}` };
|
|
361
|
-
},
|
|
362
|
-
PENDING: async (order) => {
|
|
363
|
-
var _a;
|
|
364
|
-
if (!order.current_tx_context) {
|
|
365
|
-
return { state: 'ERROR', message: 'MISSING CONTEXT' };
|
|
366
|
-
}
|
|
367
|
-
const wdId = +order.current_tx_context;
|
|
368
|
-
const res = await client.getDepositWithdrawHistory({
|
|
369
|
-
currency: 'usdt',
|
|
370
|
-
type: 'withdraw',
|
|
371
|
-
from: `${wdId}`,
|
|
372
|
-
});
|
|
373
|
-
const txId = (_a = res.data.find((v) => v.id === wdId)) === null || _a === void 0 ? void 0 : _a['tx-hash'];
|
|
374
|
-
if (!txId) {
|
|
375
|
-
return { state: 'PENDING', context: `${wdId}` };
|
|
376
|
-
}
|
|
377
|
-
return {
|
|
378
|
-
state: 'COMPLETE',
|
|
379
|
-
transaction_id: txId,
|
|
380
|
-
};
|
|
381
|
-
},
|
|
382
|
-
},
|
|
383
|
-
onEval: async (order) => {
|
|
384
|
-
const res = await client.getDepositWithdrawHistory({
|
|
385
|
-
currency: 'usdt',
|
|
386
|
-
type: 'deposit',
|
|
387
|
-
direct: 'next',
|
|
388
|
-
});
|
|
389
|
-
const theItem = res.data.find((v) => v['tx-hash'] === order.current_transaction_id && v.state === 'safe');
|
|
390
|
-
if (!theItem) {
|
|
391
|
-
return { state: 'PENDING' };
|
|
392
|
-
}
|
|
393
|
-
return { received_amount: +theItem.amount, state: 'COMPLETE' };
|
|
394
|
-
},
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
addAccountTransferAddress({
|
|
399
|
-
terminal,
|
|
400
|
-
account_id: SPOT_ACCOUNT_ID,
|
|
401
|
-
currency: 'USDT',
|
|
402
|
-
network_id: `Huobi/${huobiUid}/SPOT-SUPER_MARGIN`,
|
|
403
|
-
address: 'SPOT',
|
|
404
|
-
onApply: {
|
|
405
|
-
INIT: async (order) => {
|
|
406
|
-
const transferInResult = await client.postSuperMarginAccountTransferIn({
|
|
407
|
-
currency: 'usdt',
|
|
408
|
-
amount: '' + (order.current_amount || order.expected_amount),
|
|
409
|
-
});
|
|
410
|
-
if (transferInResult.status !== 'ok') {
|
|
411
|
-
return { state: 'INIT' };
|
|
412
|
-
}
|
|
413
|
-
return { state: 'COMPLETE' };
|
|
414
|
-
},
|
|
415
|
-
},
|
|
416
|
-
onEval: async (order) => {
|
|
417
|
-
return { received_amount: order.current_amount || order.expected_amount, state: 'COMPLETE' };
|
|
418
|
-
},
|
|
419
|
-
});
|
|
420
|
-
addAccountTransferAddress({
|
|
421
|
-
terminal,
|
|
422
|
-
account_id: SUPER_MARGIN_ACCOUNT_ID,
|
|
423
|
-
currency: 'USDT',
|
|
424
|
-
network_id: `Huobi/${huobiUid}/SPOT-SUPER_MARGIN`,
|
|
425
|
-
address: 'SUPER_MARGIN',
|
|
426
|
-
onApply: {
|
|
427
|
-
INIT: async (order) => {
|
|
428
|
-
const transferOutResult = await client.postSuperMarginAccountTransferOut({
|
|
429
|
-
currency: 'usdt',
|
|
430
|
-
amount: '' + (order.current_amount || order.expected_amount),
|
|
431
|
-
});
|
|
432
|
-
if (transferOutResult.status !== 'ok') {
|
|
433
|
-
return { state: 'INIT' };
|
|
434
|
-
}
|
|
435
|
-
return { state: 'COMPLETE' };
|
|
436
|
-
},
|
|
437
|
-
},
|
|
438
|
-
onEval: async (order) => {
|
|
439
|
-
return { received_amount: order.current_amount || order.expected_amount, state: 'COMPLETE' };
|
|
440
|
-
},
|
|
441
|
-
});
|
|
442
|
-
addAccountTransferAddress({
|
|
443
|
-
terminal,
|
|
444
|
-
account_id: SPOT_ACCOUNT_ID,
|
|
445
|
-
currency: 'USDT',
|
|
446
|
-
network_id: `Huobi/${huobiUid}/SPOT-SWAP`,
|
|
447
|
-
address: 'SPOT',
|
|
448
|
-
onApply: {
|
|
449
|
-
INIT: async (order) => {
|
|
450
|
-
const transferResult = await client.postSpotAccountTransfer({
|
|
451
|
-
from: 'spot',
|
|
452
|
-
to: 'linear-swap',
|
|
453
|
-
currency: 'usdt',
|
|
454
|
-
amount: order.current_amount || order.expected_amount,
|
|
455
|
-
'margin-account': 'USDT',
|
|
456
|
-
});
|
|
457
|
-
if (!transferResult.success) {
|
|
458
|
-
return { state: 'INIT' };
|
|
459
|
-
}
|
|
460
|
-
return { state: 'COMPLETE' };
|
|
461
|
-
},
|
|
462
|
-
},
|
|
463
|
-
onEval: async (order) => {
|
|
464
|
-
return { received_amount: order.current_amount || order.expected_amount, state: 'COMPLETE' };
|
|
465
|
-
},
|
|
466
|
-
});
|
|
467
|
-
addAccountTransferAddress({
|
|
468
|
-
terminal,
|
|
469
|
-
account_id: SWAP_ACCOUNT_ID,
|
|
470
|
-
currency: 'USDT',
|
|
471
|
-
network_id: `Huobi/${huobiUid}/SPOT-SWAP`,
|
|
472
|
-
address: 'SWAP',
|
|
473
|
-
onApply: {
|
|
474
|
-
INIT: async (order) => {
|
|
475
|
-
const transferResult = await client.postSpotAccountTransfer({
|
|
476
|
-
from: 'linear-swap',
|
|
477
|
-
to: 'spot',
|
|
478
|
-
currency: 'usdt',
|
|
479
|
-
amount: order.current_amount || order.expected_amount,
|
|
480
|
-
'margin-account': 'USDT',
|
|
481
|
-
});
|
|
482
|
-
if (!transferResult.success) {
|
|
483
|
-
return { state: 'INIT' };
|
|
484
|
-
}
|
|
485
|
-
return { state: 'COMPLETE' };
|
|
486
|
-
},
|
|
487
|
-
},
|
|
488
|
-
onEval: async (order) => {
|
|
489
|
-
return { received_amount: order.current_amount || order.expected_amount, state: 'COMPLETE' };
|
|
490
|
-
},
|
|
491
|
-
});
|
|
492
|
-
if (isMainAccount) {
|
|
493
|
-
for (const subAccount of subAccounts) {
|
|
494
|
-
const SPOT_SUB_ACCOUNT_ID = `huobi/${subAccount.uid}/spot/usdt`;
|
|
495
|
-
const SUB_ACCOUNT_NETWORK_ID = `Huobi/${huobiUid}/SubAccount/${subAccount.uid}`;
|
|
496
|
-
addAccountTransferAddress({
|
|
497
|
-
terminal,
|
|
498
|
-
account_id: SPOT_ACCOUNT_ID,
|
|
499
|
-
currency: 'USDT',
|
|
500
|
-
network_id: SUB_ACCOUNT_NETWORK_ID,
|
|
501
|
-
address: '#main',
|
|
502
|
-
onApply: {
|
|
503
|
-
INIT: async (order) => {
|
|
504
|
-
const transferResult = await client.postSubUserTransfer({
|
|
505
|
-
'sub-uid': +order.current_rx_address,
|
|
506
|
-
currency: 'usdt',
|
|
507
|
-
amount: order.current_amount || order.expected_amount,
|
|
508
|
-
type: 'master-transfer-out',
|
|
509
|
-
});
|
|
510
|
-
if (transferResult.status !== 'ok') {
|
|
511
|
-
return { state: 'INIT' };
|
|
512
|
-
}
|
|
513
|
-
return { state: 'COMPLETE' };
|
|
514
|
-
},
|
|
515
|
-
},
|
|
516
|
-
onEval: async (order) => {
|
|
517
|
-
return { received_amount: order.current_amount || order.expected_amount, state: 'COMPLETE' };
|
|
518
|
-
},
|
|
519
|
-
});
|
|
520
|
-
addAccountTransferAddress({
|
|
521
|
-
terminal,
|
|
522
|
-
account_id: SPOT_SUB_ACCOUNT_ID,
|
|
523
|
-
currency: 'USDT',
|
|
524
|
-
network_id: SUB_ACCOUNT_NETWORK_ID,
|
|
525
|
-
address: `${subAccount.uid}`,
|
|
526
|
-
onApply: {
|
|
527
|
-
INIT: async (order) => {
|
|
528
|
-
const transferResult = await client.postSubUserTransfer({
|
|
529
|
-
'sub-uid': +order.current_tx_address,
|
|
530
|
-
currency: 'usdt',
|
|
531
|
-
amount: order.current_amount || order.expected_amount,
|
|
532
|
-
type: 'master-transfer-in',
|
|
533
|
-
});
|
|
534
|
-
if (transferResult.status !== 'ok') {
|
|
535
|
-
return { state: 'INIT' };
|
|
536
|
-
}
|
|
537
|
-
return { state: 'COMPLETE' };
|
|
538
|
-
},
|
|
539
|
-
},
|
|
540
|
-
onEval: async (order) => {
|
|
541
|
-
return { received_amount: order.current_amount || order.expected_amount, state: 'COMPLETE' };
|
|
542
|
-
},
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
}
|
|
43
|
+
// 设置订单提交服务
|
|
44
|
+
provideOrderSubmitService(terminal, SWAP_ACCOUNT_ID, SUPER_MARGIN_ACCOUNT_ID, credential);
|
|
45
|
+
// 设置转账功能
|
|
46
|
+
await setupTrc20WithdrawalAddresses(terminal, SPOT_ACCOUNT_ID, credential, isMainAccount);
|
|
47
|
+
setupSpotSuperMarginTransfer(terminal, SPOT_ACCOUNT_ID, SUPER_MARGIN_ACCOUNT_ID, credential, huobiUid);
|
|
48
|
+
setupSpotSwapTransfer(terminal, SPOT_ACCOUNT_ID, SWAP_ACCOUNT_ID, credential, huobiUid);
|
|
49
|
+
setupSubAccountTransfers(terminal, SPOT_ACCOUNT_ID, credential, huobiUid, subAccounts, isMainAccount);
|
|
546
50
|
})();
|
|
547
51
|
//# sourceMappingURL=index.js.map
|