@yuants/vendor-aster 0.0.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.js +37 -0
- package/dist/account.js.map +1 -0
- package/dist/api.js +65 -0
- package/dist/api.js.map +1 -0
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/order.js +27 -0
- package/dist/order.js.map +1 -0
- package/lib/account.d.ts +2 -0
- package/lib/account.d.ts.map +1 -0
- package/lib/account.js +40 -0
- package/lib/account.js.map +1 -0
- package/lib/api.d.ts +67 -0
- package/lib/api.d.ts.map +1 -0
- package/lib/api.js +68 -0
- package/lib/api.js.map +1 -0
- package/lib/cli.d.ts +3 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +5 -0
- package/lib/cli.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +5 -0
- package/lib/index.js.map +1 -0
- package/lib/order.d.ts +2 -0
- package/lib/order.d.ts.map +1 -0
- package/lib/order.js +29 -0
- package/lib/order.js.map +1 -0
- package/package.json +51 -0
- package/temp/package-deps.json +25 -0
package/dist/account.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { provideAccountInfoService } from '@yuants/data-account';
|
|
2
|
+
import { Terminal } from '@yuants/protocol';
|
|
3
|
+
import { getFApiV4Account } from './api';
|
|
4
|
+
const ADDRESS = process.env.ADDRESS;
|
|
5
|
+
export const ACCOUNT_ID = `ASTER/${ADDRESS}`;
|
|
6
|
+
provideAccountInfoService(Terminal.fromNodeEnv(), ACCOUNT_ID, async () => {
|
|
7
|
+
const a = await getFApiV4Account({});
|
|
8
|
+
const profit = +a.totalUnrealizedProfit;
|
|
9
|
+
const balance = +a.totalWalletBalance;
|
|
10
|
+
const equity = balance + profit;
|
|
11
|
+
const free = +a.availableBalance;
|
|
12
|
+
const used = equity - free;
|
|
13
|
+
const money = {
|
|
14
|
+
currency: 'USD',
|
|
15
|
+
equity: equity,
|
|
16
|
+
balance: balance,
|
|
17
|
+
profit: profit,
|
|
18
|
+
free: free,
|
|
19
|
+
used: used,
|
|
20
|
+
};
|
|
21
|
+
const positions = a.positions
|
|
22
|
+
.filter((p) => +p.positionAmt !== 0)
|
|
23
|
+
.map((p) => ({
|
|
24
|
+
position_id: p.symbol,
|
|
25
|
+
product_id: p.symbol,
|
|
26
|
+
datasource_id: 'ASTER',
|
|
27
|
+
direction: p.positionSide === 'BOTH' ? (+p.positionAmt > 0 ? 'LONG' : 'SHORT') : p.positionSide,
|
|
28
|
+
volume: Math.abs(+p.positionAmt),
|
|
29
|
+
free_volume: Math.abs(+p.positionAmt),
|
|
30
|
+
position_price: +p.entryPrice,
|
|
31
|
+
closable_price: Math.abs(+p.notional / +p.positionAmt),
|
|
32
|
+
floating_profit: +p.unrealizedProfit,
|
|
33
|
+
valuation: Math.abs(+p.notional),
|
|
34
|
+
}));
|
|
35
|
+
return { money, positions };
|
|
36
|
+
}, { auto_refresh_interval: 1000 });
|
|
37
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAEzC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAQ,CAAC;AACrC,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,OAAO,EAAE,CAAC;AAE7C,yBAAyB,CACvB,QAAQ,CAAC,WAAW,EAAE,EACtB,UAAU,EACV,KAAK,IAAI,EAAE;IACT,MAAM,CAAC,GAAG,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAErC,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;IACxC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACtC,MAAM,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAChC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC;IACjC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IAE3B,MAAM,KAAK,GAAkB;QAC3B,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,OAAO;QAChB,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI;KACX,CAAC;IACF,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC;SACnC,GAAG,CACF,CAAC,CAAC,EAAa,EAAE,CAAC,CAAC;QACjB,WAAW,EAAE,CAAC,CAAC,MAAM;QACrB,UAAU,EAAE,CAAC,CAAC,MAAM;QACpB,aAAa,EAAE,OAAO;QACtB,SAAS,EAAE,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;QAC/F,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QAChC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QACrC,cAAc,EAAE,CAAC,CAAC,CAAC,UAAU;QAC7B,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;QACtD,eAAe,EAAE,CAAC,CAAC,CAAC,gBAAgB;QACpC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;KACjC,CAAC,CACH,CAAC;IACJ,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC9B,CAAC,EACD,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAChC,CAAC","sourcesContent":["import { IAccountMoney, IPosition, provideAccountInfoService } from '@yuants/data-account';\nimport { Terminal } from '@yuants/protocol';\nimport { getFApiV4Account } from './api';\n\nconst ADDRESS = process.env.ADDRESS!;\nexport const ACCOUNT_ID = `ASTER/${ADDRESS}`;\n\nprovideAccountInfoService(\n Terminal.fromNodeEnv(),\n ACCOUNT_ID,\n async () => {\n const a = await getFApiV4Account({});\n\n const profit = +a.totalUnrealizedProfit;\n const balance = +a.totalWalletBalance;\n const equity = balance + profit;\n const free = +a.availableBalance;\n const used = equity - free;\n\n const money: IAccountMoney = {\n currency: 'USD',\n equity: equity,\n balance: balance,\n profit: profit,\n free: free,\n used: used,\n };\n const positions = a.positions\n .filter((p) => +p.positionAmt !== 0)\n .map(\n (p): IPosition => ({\n position_id: p.symbol,\n product_id: p.symbol,\n datasource_id: 'ASTER',\n direction: p.positionSide === 'BOTH' ? (+p.positionAmt > 0 ? 'LONG' : 'SHORT') : p.positionSide,\n volume: Math.abs(+p.positionAmt),\n free_volume: Math.abs(+p.positionAmt),\n position_price: +p.entryPrice,\n closable_price: Math.abs(+p.notional / +p.positionAmt),\n floating_profit: +p.unrealizedProfit,\n valuation: Math.abs(+p.notional),\n }),\n );\n return { money, positions };\n },\n { auto_refresh_interval: 1000 },\n);\n"]}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const API_KEY = process.env.API_KEY;
|
|
2
|
+
const SECRET_KEY = process.env.SECRET_KEY;
|
|
3
|
+
const BASE_URL = 'https://fapi.asterdex.com';
|
|
4
|
+
function arrayBufferToHex(buffer) {
|
|
5
|
+
const bytes = new Uint8Array(buffer);
|
|
6
|
+
const hexArray = [];
|
|
7
|
+
for (const byte of bytes) {
|
|
8
|
+
const hex = byte.toString(16).padStart(2, '0');
|
|
9
|
+
hexArray.push(hex);
|
|
10
|
+
}
|
|
11
|
+
return hexArray.join('');
|
|
12
|
+
}
|
|
13
|
+
async function opensslEquivalentHMAC(message, secretKey) {
|
|
14
|
+
try {
|
|
15
|
+
const keyBuffer = new TextEncoder().encode(secretKey);
|
|
16
|
+
const messageBuffer = new TextEncoder().encode(message);
|
|
17
|
+
// 导入密钥
|
|
18
|
+
const cryptoKey = await crypto.subtle.importKey('raw', keyBuffer, {
|
|
19
|
+
name: 'HMAC',
|
|
20
|
+
hash: { name: 'SHA-256' },
|
|
21
|
+
}, false, ['sign']);
|
|
22
|
+
// 进行 HMAC-SHA256 签名
|
|
23
|
+
const signature = await crypto.subtle.sign('HMAC', cryptoKey, messageBuffer);
|
|
24
|
+
// 转换为16进制小写(与 openssl 输出格式一致)
|
|
25
|
+
return arrayBufferToHex(signature);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
throw new Error(`HMAC-SHA256 签名失败: ${error}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const request = async (type, method, endpoint, params = {}) => {
|
|
32
|
+
const needApiKey = type !== 'NONE';
|
|
33
|
+
const needSign = type === 'TRADE' || type === 'USER_DATA';
|
|
34
|
+
const url = new URL(BASE_URL);
|
|
35
|
+
url.pathname = endpoint;
|
|
36
|
+
for (const [key, value] of Object.entries(params)) {
|
|
37
|
+
if (value === undefined)
|
|
38
|
+
continue;
|
|
39
|
+
url.searchParams.set(key, `${value}`);
|
|
40
|
+
}
|
|
41
|
+
if (needSign) {
|
|
42
|
+
url.searchParams.set('timestamp', `${Date.now()}`);
|
|
43
|
+
const msg = url.search.slice(1); // 去掉开头的 '?'
|
|
44
|
+
const signature = await opensslEquivalentHMAC(msg, SECRET_KEY);
|
|
45
|
+
url.searchParams.set('signature', signature);
|
|
46
|
+
}
|
|
47
|
+
console.info(url.toString());
|
|
48
|
+
return fetch(url.toString(), {
|
|
49
|
+
method,
|
|
50
|
+
headers: needApiKey
|
|
51
|
+
? {
|
|
52
|
+
'X-MBX-APIKEY': API_KEY,
|
|
53
|
+
}
|
|
54
|
+
: {},
|
|
55
|
+
}).then((response) => response.json());
|
|
56
|
+
};
|
|
57
|
+
const createApi = (type, method, endpoint) => (params) => request(type, method, endpoint, params);
|
|
58
|
+
/**
|
|
59
|
+
* 获取账户信息
|
|
60
|
+
*
|
|
61
|
+
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data
|
|
62
|
+
*/
|
|
63
|
+
export const getFApiV4Account = createApi('USER_DATA', 'GET', '/fapi/v4/account');
|
|
64
|
+
export const postFApiV1Order = createApi('TRADE', 'POST', '/fapi/v1/order');
|
|
65
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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","sourcesContent":["const API_KEY = process.env.API_KEY!;\nconst SECRET_KEY = process.env.SECRET_KEY!;\n\nconst BASE_URL = 'https://fapi.asterdex.com';\n\nfunction arrayBufferToHex(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n const hexArray: string[] = [];\n\n for (const byte of bytes) {\n const hex = byte.toString(16).padStart(2, '0');\n hexArray.push(hex);\n }\n\n return hexArray.join('');\n}\n\nasync function opensslEquivalentHMAC(message: string, secretKey: string): Promise<string> {\n try {\n const keyBuffer = new TextEncoder().encode(secretKey);\n const messageBuffer = new TextEncoder().encode(message);\n\n // 导入密钥\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n keyBuffer,\n {\n name: 'HMAC',\n hash: { name: 'SHA-256' },\n },\n false,\n ['sign'],\n );\n\n // 进行 HMAC-SHA256 签名\n const signature = await crypto.subtle.sign('HMAC', cryptoKey, messageBuffer);\n\n // 转换为16进制小写(与 openssl 输出格式一致)\n return arrayBufferToHex(signature);\n } catch (error) {\n throw new Error(`HMAC-SHA256 签名失败: ${error}`);\n }\n}\n\nconst request = async <T>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n params: any = {},\n): Promise<T> => {\n const needApiKey = type !== 'NONE';\n const needSign = type === 'TRADE' || type === 'USER_DATA';\n\n const url = new URL(BASE_URL);\n url.pathname = endpoint;\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n url.searchParams.set(key, `${value}`);\n }\n\n if (needSign) {\n url.searchParams.set('timestamp', `${Date.now()}`);\n const msg = url.search.slice(1); // 去掉开头的 '?'\n const signature = await opensslEquivalentHMAC(msg, SECRET_KEY);\n url.searchParams.set('signature', signature);\n }\n\n console.info(url.toString());\n return fetch(url.toString(), {\n method,\n headers: needApiKey\n ? {\n 'X-MBX-APIKEY': API_KEY,\n }\n : {},\n }).then((response) => response.json() as any as T);\n};\n\nconst createApi =\n <TReq, TRes>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n ) =>\n (params: TReq) =>\n request<TRes>(type, method, endpoint, params);\n\n/**\n * 获取账户信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data\n */\nexport const getFApiV4Account = createApi<\n {},\n {\n feeTier: number;\n canTrade: boolean;\n canDeposit: boolean;\n canWithdraw: boolean;\n updateTime: number;\n totalInitialMargin: string;\n totalMaintMargin: string;\n totalWalletBalance: string;\n totalUnrealizedProfit: string;\n totalMarginBalance: string;\n totalPositionInitialMargin: string;\n totalOpenOrderInitialMargin: string;\n totalCrossWalletBalance: string;\n totalCrossUnPnl: string;\n availableBalance: string;\n maxWithdrawAmount: string;\n assets: {\n asset: string;\n walletBalance: string;\n unrealizedProfit: string;\n marginBalance: string;\n maintMargin: string;\n initialMargin: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n maxWithdrawAmount: string;\n crossWalletBalance: string;\n crossUnPnl: string;\n availableBalance: string;\n marginAvailable: boolean;\n updateTime: number;\n }[];\n positions: {\n symbol: string;\n initialMargin: string;\n maintMargin: string;\n unrealizedProfit: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n leverage: string;\n isolated: boolean;\n entryPrice: string;\n maxNotional: string;\n positionSide: 'BOTH' | 'LONG' | 'SHORT';\n positionAmt: string;\n notional: string;\n isolatedWallet: string;\n updateTime: number;\n }[];\n }\n>('USER_DATA', 'GET', '/fapi/v4/account');\n\nexport const postFApiV1Order = createApi<\n {\n symbol: string;\n side: 'BUY' | 'SELL';\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n type:\n | 'MARKET'\n | 'LIMIT'\n | 'STOP'\n | 'STOP_MARKET'\n | 'TAKE_PROFIT'\n | 'TAKE_PROFIT_MARKET'\n | 'TRAILING_STOP_MARKET';\n reduceOnly?: 'true' | 'false';\n quantity?: number;\n price?: number;\n timeInForce?: 'GTC' | 'IOC' | 'FOK' | 'GTX' | 'HIDDEN';\n },\n {}\n>('TRADE', 'POST', '/fapi/v1/order');\n"]}
|
package/dist/cli.js
ADDED
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,SAAS,CAAC","sourcesContent":["#!/usr/bin/env node\nimport './index';\n"]}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAC;AACnB,OAAO,SAAS,CAAC","sourcesContent":["import './account';\nimport './order';\n"]}
|
package/dist/order.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Terminal } from '@yuants/protocol';
|
|
2
|
+
import { ACCOUNT_ID } from './account';
|
|
3
|
+
import { postFApiV1Order } from './api';
|
|
4
|
+
const terminal = Terminal.fromNodeEnv();
|
|
5
|
+
terminal.server.provideService('SubmitOrder', { required: ['account_id'], properties: { account_id: { type: 'string', const: ACCOUNT_ID } } }, async (msg) => {
|
|
6
|
+
const order = msg.req;
|
|
7
|
+
const symbol = order.product_id;
|
|
8
|
+
const side = { OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' }[order.order_direction];
|
|
9
|
+
if (!side)
|
|
10
|
+
throw new Error(`Unsupported order_direction: ${order.order_direction}`);
|
|
11
|
+
const type = { MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' }[order.order_type];
|
|
12
|
+
if (!type)
|
|
13
|
+
throw new Error(`Unsupported order_type: ${order.order_type}`);
|
|
14
|
+
const quantity = order.volume;
|
|
15
|
+
const price = order.price;
|
|
16
|
+
const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;
|
|
17
|
+
await postFApiV1Order({
|
|
18
|
+
symbol,
|
|
19
|
+
side,
|
|
20
|
+
type,
|
|
21
|
+
quantity,
|
|
22
|
+
price,
|
|
23
|
+
timeInForce,
|
|
24
|
+
});
|
|
25
|
+
return { res: { code: 0, message: 'OK' } };
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=order.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order.js","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAExC,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,aAAa,EACb,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,EAC/F,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC;IAEtB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC;IAEhC,MAAM,IAAI,GAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAY,CACtG,KAAK,CAAC,eAAgB,CACvB,CAAC;IACF,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC;IAEpF,MAAM,IAAI,GAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAY,CAAC,KAAK,CAAC,UAAW,CAAC,CAAC;IAChG,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAE1E,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;IAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAE1B,MAAM,WAAW,GACf,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAE1F,MAAM,eAAe,CAAC;QACpB,MAAM;QACN,IAAI;QACJ,IAAI;QACJ,QAAQ;QACR,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;AAC7C,CAAC,CACF,CAAC","sourcesContent":["import { Terminal } from '@yuants/protocol';\nimport { IOrder } from '@yuants/data-order';\nimport { ACCOUNT_ID } from './account';\nimport { postFApiV1Order } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<IOrder>(\n 'SubmitOrder',\n { required: ['account_id'], properties: { account_id: { type: 'string', const: ACCOUNT_ID } } },\n async (msg) => {\n const order = msg.req;\n\n const symbol = order.product_id;\n\n const side = ({ OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' } as const)[\n order.order_direction!\n ];\n if (!side) throw new Error(`Unsupported order_direction: ${order.order_direction}`);\n\n const type = ({ MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' } as const)[order.order_type!];\n if (!type) throw new Error(`Unsupported order_type: ${order.order_type}`);\n\n const quantity = order.volume;\n const price = order.price;\n\n const timeInForce =\n order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n\n await postFApiV1Order({\n symbol,\n side,\n type,\n quantity,\n price,\n timeInForce,\n });\n\n return { res: { code: 0, message: 'OK' } };\n },\n);\n"]}
|
package/lib/account.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,UAAU,QAAqB,CAAC"}
|
package/lib/account.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ACCOUNT_ID = void 0;
|
|
4
|
+
const data_account_1 = require("@yuants/data-account");
|
|
5
|
+
const protocol_1 = require("@yuants/protocol");
|
|
6
|
+
const api_1 = require("./api");
|
|
7
|
+
const ADDRESS = process.env.ADDRESS;
|
|
8
|
+
exports.ACCOUNT_ID = `ASTER/${ADDRESS}`;
|
|
9
|
+
(0, data_account_1.provideAccountInfoService)(protocol_1.Terminal.fromNodeEnv(), exports.ACCOUNT_ID, async () => {
|
|
10
|
+
const a = await (0, api_1.getFApiV4Account)({});
|
|
11
|
+
const profit = +a.totalUnrealizedProfit;
|
|
12
|
+
const balance = +a.totalWalletBalance;
|
|
13
|
+
const equity = balance + profit;
|
|
14
|
+
const free = +a.availableBalance;
|
|
15
|
+
const used = equity - free;
|
|
16
|
+
const money = {
|
|
17
|
+
currency: 'USD',
|
|
18
|
+
equity: equity,
|
|
19
|
+
balance: balance,
|
|
20
|
+
profit: profit,
|
|
21
|
+
free: free,
|
|
22
|
+
used: used,
|
|
23
|
+
};
|
|
24
|
+
const positions = a.positions
|
|
25
|
+
.filter((p) => +p.positionAmt !== 0)
|
|
26
|
+
.map((p) => ({
|
|
27
|
+
position_id: p.symbol,
|
|
28
|
+
product_id: p.symbol,
|
|
29
|
+
datasource_id: 'ASTER',
|
|
30
|
+
direction: p.positionSide === 'BOTH' ? (+p.positionAmt > 0 ? 'LONG' : 'SHORT') : p.positionSide,
|
|
31
|
+
volume: Math.abs(+p.positionAmt),
|
|
32
|
+
free_volume: Math.abs(+p.positionAmt),
|
|
33
|
+
position_price: +p.entryPrice,
|
|
34
|
+
closable_price: Math.abs(+p.notional / +p.positionAmt),
|
|
35
|
+
floating_profit: +p.unrealizedProfit,
|
|
36
|
+
valuation: Math.abs(+p.notional),
|
|
37
|
+
}));
|
|
38
|
+
return { money, positions };
|
|
39
|
+
}, { auto_refresh_interval: 1000 });
|
|
40
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":";;;AAAA,uDAA2F;AAC3F,+CAA4C;AAC5C,+BAAyC;AAEzC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAQ,CAAC;AACxB,QAAA,UAAU,GAAG,SAAS,OAAO,EAAE,CAAC;AAE7C,IAAA,wCAAyB,EACvB,mBAAQ,CAAC,WAAW,EAAE,EACtB,kBAAU,EACV,KAAK,IAAI,EAAE;IACT,MAAM,CAAC,GAAG,MAAM,IAAA,sBAAgB,EAAC,EAAE,CAAC,CAAC;IAErC,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;IACxC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACtC,MAAM,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAChC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC;IACjC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IAE3B,MAAM,KAAK,GAAkB;QAC3B,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,OAAO;QAChB,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI;KACX,CAAC;IACF,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC;SACnC,GAAG,CACF,CAAC,CAAC,EAAa,EAAE,CAAC,CAAC;QACjB,WAAW,EAAE,CAAC,CAAC,MAAM;QACrB,UAAU,EAAE,CAAC,CAAC,MAAM;QACpB,aAAa,EAAE,OAAO;QACtB,SAAS,EAAE,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;QAC/F,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QAChC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QACrC,cAAc,EAAE,CAAC,CAAC,CAAC,UAAU;QAC7B,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;QACtD,eAAe,EAAE,CAAC,CAAC,CAAC,gBAAgB;QACpC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;KACjC,CAAC,CACH,CAAC;IACJ,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC9B,CAAC,EACD,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAChC,CAAC","sourcesContent":["import { IAccountMoney, IPosition, provideAccountInfoService } from '@yuants/data-account';\nimport { Terminal } from '@yuants/protocol';\nimport { getFApiV4Account } from './api';\n\nconst ADDRESS = process.env.ADDRESS!;\nexport const ACCOUNT_ID = `ASTER/${ADDRESS}`;\n\nprovideAccountInfoService(\n Terminal.fromNodeEnv(),\n ACCOUNT_ID,\n async () => {\n const a = await getFApiV4Account({});\n\n const profit = +a.totalUnrealizedProfit;\n const balance = +a.totalWalletBalance;\n const equity = balance + profit;\n const free = +a.availableBalance;\n const used = equity - free;\n\n const money: IAccountMoney = {\n currency: 'USD',\n equity: equity,\n balance: balance,\n profit: profit,\n free: free,\n used: used,\n };\n const positions = a.positions\n .filter((p) => +p.positionAmt !== 0)\n .map(\n (p): IPosition => ({\n position_id: p.symbol,\n product_id: p.symbol,\n datasource_id: 'ASTER',\n direction: p.positionSide === 'BOTH' ? (+p.positionAmt > 0 ? 'LONG' : 'SHORT') : p.positionSide,\n volume: Math.abs(+p.positionAmt),\n free_volume: Math.abs(+p.positionAmt),\n position_price: +p.entryPrice,\n closable_price: Math.abs(+p.notional / +p.positionAmt),\n floating_profit: +p.unrealizedProfit,\n valuation: Math.abs(+p.notional),\n }),\n );\n return { money, positions };\n },\n { auto_refresh_interval: 1000 },\n);\n"]}
|
package/lib/api.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 获取账户信息
|
|
3
|
+
*
|
|
4
|
+
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data
|
|
5
|
+
*/
|
|
6
|
+
export declare const getFApiV4Account: (params: {}) => Promise<{
|
|
7
|
+
feeTier: number;
|
|
8
|
+
canTrade: boolean;
|
|
9
|
+
canDeposit: boolean;
|
|
10
|
+
canWithdraw: boolean;
|
|
11
|
+
updateTime: number;
|
|
12
|
+
totalInitialMargin: string;
|
|
13
|
+
totalMaintMargin: string;
|
|
14
|
+
totalWalletBalance: string;
|
|
15
|
+
totalUnrealizedProfit: string;
|
|
16
|
+
totalMarginBalance: string;
|
|
17
|
+
totalPositionInitialMargin: string;
|
|
18
|
+
totalOpenOrderInitialMargin: string;
|
|
19
|
+
totalCrossWalletBalance: string;
|
|
20
|
+
totalCrossUnPnl: string;
|
|
21
|
+
availableBalance: string;
|
|
22
|
+
maxWithdrawAmount: string;
|
|
23
|
+
assets: {
|
|
24
|
+
asset: string;
|
|
25
|
+
walletBalance: string;
|
|
26
|
+
unrealizedProfit: string;
|
|
27
|
+
marginBalance: string;
|
|
28
|
+
maintMargin: string;
|
|
29
|
+
initialMargin: string;
|
|
30
|
+
positionInitialMargin: string;
|
|
31
|
+
openOrderInitialMargin: string;
|
|
32
|
+
maxWithdrawAmount: string;
|
|
33
|
+
crossWalletBalance: string;
|
|
34
|
+
crossUnPnl: string;
|
|
35
|
+
availableBalance: string;
|
|
36
|
+
marginAvailable: boolean;
|
|
37
|
+
updateTime: number;
|
|
38
|
+
}[];
|
|
39
|
+
positions: {
|
|
40
|
+
symbol: string;
|
|
41
|
+
initialMargin: string;
|
|
42
|
+
maintMargin: string;
|
|
43
|
+
unrealizedProfit: string;
|
|
44
|
+
positionInitialMargin: string;
|
|
45
|
+
openOrderInitialMargin: string;
|
|
46
|
+
leverage: string;
|
|
47
|
+
isolated: boolean;
|
|
48
|
+
entryPrice: string;
|
|
49
|
+
maxNotional: string;
|
|
50
|
+
positionSide: 'BOTH' | 'LONG' | 'SHORT';
|
|
51
|
+
positionAmt: string;
|
|
52
|
+
notional: string;
|
|
53
|
+
isolatedWallet: string;
|
|
54
|
+
updateTime: number;
|
|
55
|
+
}[];
|
|
56
|
+
}>;
|
|
57
|
+
export declare const postFApiV1Order: (params: {
|
|
58
|
+
symbol: string;
|
|
59
|
+
side: 'BUY' | 'SELL';
|
|
60
|
+
positionSide?: "BOTH" | "LONG" | "SHORT" | undefined;
|
|
61
|
+
type: 'MARKET' | 'LIMIT' | 'STOP' | 'STOP_MARKET' | 'TAKE_PROFIT' | 'TAKE_PROFIT_MARKET' | 'TRAILING_STOP_MARKET';
|
|
62
|
+
reduceOnly?: "true" | "false" | undefined;
|
|
63
|
+
quantity?: number | undefined;
|
|
64
|
+
price?: number | undefined;
|
|
65
|
+
timeInForce?: "GTC" | "IOC" | "FOK" | "GTX" | "HIDDEN" | undefined;
|
|
66
|
+
}) => Promise<{}>;
|
|
67
|
+
//# sourceMappingURL=api.d.ts.map
|
package/lib/api.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAuFA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;aAGhB,MAAM;cACL,OAAO;gBACL,OAAO;iBACN,OAAO;gBACR,MAAM;wBACE,MAAM;sBACR,MAAM;wBACJ,MAAM;2BACH,MAAM;wBACT,MAAM;gCACE,MAAM;iCACL,MAAM;6BACV,MAAM;qBACd,MAAM;sBACL,MAAM;uBACL,MAAM;YACjB;QACN,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,OAAO,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;KACpB,EAAE;eACQ;QACT,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,gBAAgB,EAAE,MAAM,CAAC;QACzB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;QACxC,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;KACpB,EAAE;EAEkC,CAAC;AAE1C,eAAO,MAAM,eAAe;YAEhB,MAAM;UACR,KAAK,GAAG,MAAM;;UAGhB,QAAQ,GACR,OAAO,GACP,MAAM,GACN,aAAa,GACb,aAAa,GACb,oBAAoB,GACpB,sBAAsB;;;;;iBAOM,CAAC"}
|
package/lib/api.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.postFApiV1Order = exports.getFApiV4Account = void 0;
|
|
4
|
+
const API_KEY = process.env.API_KEY;
|
|
5
|
+
const SECRET_KEY = process.env.SECRET_KEY;
|
|
6
|
+
const BASE_URL = 'https://fapi.asterdex.com';
|
|
7
|
+
function arrayBufferToHex(buffer) {
|
|
8
|
+
const bytes = new Uint8Array(buffer);
|
|
9
|
+
const hexArray = [];
|
|
10
|
+
for (const byte of bytes) {
|
|
11
|
+
const hex = byte.toString(16).padStart(2, '0');
|
|
12
|
+
hexArray.push(hex);
|
|
13
|
+
}
|
|
14
|
+
return hexArray.join('');
|
|
15
|
+
}
|
|
16
|
+
async function opensslEquivalentHMAC(message, secretKey) {
|
|
17
|
+
try {
|
|
18
|
+
const keyBuffer = new TextEncoder().encode(secretKey);
|
|
19
|
+
const messageBuffer = new TextEncoder().encode(message);
|
|
20
|
+
// 导入密钥
|
|
21
|
+
const cryptoKey = await crypto.subtle.importKey('raw', keyBuffer, {
|
|
22
|
+
name: 'HMAC',
|
|
23
|
+
hash: { name: 'SHA-256' },
|
|
24
|
+
}, false, ['sign']);
|
|
25
|
+
// 进行 HMAC-SHA256 签名
|
|
26
|
+
const signature = await crypto.subtle.sign('HMAC', cryptoKey, messageBuffer);
|
|
27
|
+
// 转换为16进制小写(与 openssl 输出格式一致)
|
|
28
|
+
return arrayBufferToHex(signature);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw new Error(`HMAC-SHA256 签名失败: ${error}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const request = async (type, method, endpoint, params = {}) => {
|
|
35
|
+
const needApiKey = type !== 'NONE';
|
|
36
|
+
const needSign = type === 'TRADE' || type === 'USER_DATA';
|
|
37
|
+
const url = new URL(BASE_URL);
|
|
38
|
+
url.pathname = endpoint;
|
|
39
|
+
for (const [key, value] of Object.entries(params)) {
|
|
40
|
+
if (value === undefined)
|
|
41
|
+
continue;
|
|
42
|
+
url.searchParams.set(key, `${value}`);
|
|
43
|
+
}
|
|
44
|
+
if (needSign) {
|
|
45
|
+
url.searchParams.set('timestamp', `${Date.now()}`);
|
|
46
|
+
const msg = url.search.slice(1); // 去掉开头的 '?'
|
|
47
|
+
const signature = await opensslEquivalentHMAC(msg, SECRET_KEY);
|
|
48
|
+
url.searchParams.set('signature', signature);
|
|
49
|
+
}
|
|
50
|
+
console.info(url.toString());
|
|
51
|
+
return fetch(url.toString(), {
|
|
52
|
+
method,
|
|
53
|
+
headers: needApiKey
|
|
54
|
+
? {
|
|
55
|
+
'X-MBX-APIKEY': API_KEY,
|
|
56
|
+
}
|
|
57
|
+
: {},
|
|
58
|
+
}).then((response) => response.json());
|
|
59
|
+
};
|
|
60
|
+
const createApi = (type, method, endpoint) => (params) => request(type, method, endpoint, params);
|
|
61
|
+
/**
|
|
62
|
+
* 获取账户信息
|
|
63
|
+
*
|
|
64
|
+
* https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data
|
|
65
|
+
*/
|
|
66
|
+
exports.getFApiV4Account = createApi('USER_DATA', 'GET', '/fapi/v4/account');
|
|
67
|
+
exports.postFApiV1Order = createApi('TRADE', 'POST', '/fapi/v1/order');
|
|
68
|
+
//# sourceMappingURL=api.js.map
|
package/lib/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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","sourcesContent":["const API_KEY = process.env.API_KEY!;\nconst SECRET_KEY = process.env.SECRET_KEY!;\n\nconst BASE_URL = 'https://fapi.asterdex.com';\n\nfunction arrayBufferToHex(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n const hexArray: string[] = [];\n\n for (const byte of bytes) {\n const hex = byte.toString(16).padStart(2, '0');\n hexArray.push(hex);\n }\n\n return hexArray.join('');\n}\n\nasync function opensslEquivalentHMAC(message: string, secretKey: string): Promise<string> {\n try {\n const keyBuffer = new TextEncoder().encode(secretKey);\n const messageBuffer = new TextEncoder().encode(message);\n\n // 导入密钥\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n keyBuffer,\n {\n name: 'HMAC',\n hash: { name: 'SHA-256' },\n },\n false,\n ['sign'],\n );\n\n // 进行 HMAC-SHA256 签名\n const signature = await crypto.subtle.sign('HMAC', cryptoKey, messageBuffer);\n\n // 转换为16进制小写(与 openssl 输出格式一致)\n return arrayBufferToHex(signature);\n } catch (error) {\n throw new Error(`HMAC-SHA256 签名失败: ${error}`);\n }\n}\n\nconst request = async <T>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n params: any = {},\n): Promise<T> => {\n const needApiKey = type !== 'NONE';\n const needSign = type === 'TRADE' || type === 'USER_DATA';\n\n const url = new URL(BASE_URL);\n url.pathname = endpoint;\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n url.searchParams.set(key, `${value}`);\n }\n\n if (needSign) {\n url.searchParams.set('timestamp', `${Date.now()}`);\n const msg = url.search.slice(1); // 去掉开头的 '?'\n const signature = await opensslEquivalentHMAC(msg, SECRET_KEY);\n url.searchParams.set('signature', signature);\n }\n\n console.info(url.toString());\n return fetch(url.toString(), {\n method,\n headers: needApiKey\n ? {\n 'X-MBX-APIKEY': API_KEY,\n }\n : {},\n }).then((response) => response.json() as any as T);\n};\n\nconst createApi =\n <TReq, TRes>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n ) =>\n (params: TReq) =>\n request<TRes>(type, method, endpoint, params);\n\n/**\n * 获取账户信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data\n */\nexport const getFApiV4Account = createApi<\n {},\n {\n feeTier: number;\n canTrade: boolean;\n canDeposit: boolean;\n canWithdraw: boolean;\n updateTime: number;\n totalInitialMargin: string;\n totalMaintMargin: string;\n totalWalletBalance: string;\n totalUnrealizedProfit: string;\n totalMarginBalance: string;\n totalPositionInitialMargin: string;\n totalOpenOrderInitialMargin: string;\n totalCrossWalletBalance: string;\n totalCrossUnPnl: string;\n availableBalance: string;\n maxWithdrawAmount: string;\n assets: {\n asset: string;\n walletBalance: string;\n unrealizedProfit: string;\n marginBalance: string;\n maintMargin: string;\n initialMargin: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n maxWithdrawAmount: string;\n crossWalletBalance: string;\n crossUnPnl: string;\n availableBalance: string;\n marginAvailable: boolean;\n updateTime: number;\n }[];\n positions: {\n symbol: string;\n initialMargin: string;\n maintMargin: string;\n unrealizedProfit: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n leverage: string;\n isolated: boolean;\n entryPrice: string;\n maxNotional: string;\n positionSide: 'BOTH' | 'LONG' | 'SHORT';\n positionAmt: string;\n notional: string;\n isolatedWallet: string;\n updateTime: number;\n }[];\n }\n>('USER_DATA', 'GET', '/fapi/v4/account');\n\nexport const postFApiV1Order = createApi<\n {\n symbol: string;\n side: 'BUY' | 'SELL';\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n type:\n | 'MARKET'\n | 'LIMIT'\n | 'STOP'\n | 'STOP_MARKET'\n | 'TAKE_PROFIT'\n | 'TAKE_PROFIT_MARKET'\n | 'TRAILING_STOP_MARKET';\n reduceOnly?: 'true' | 'false';\n quantity?: number;\n price?: number;\n timeInForce?: 'GTC' | 'IOC' | 'FOK' | 'GTX' | 'HIDDEN';\n },\n {}\n>('TRADE', 'POST', '/fapi/v1/order');\n"]}
|
package/lib/cli.d.ts
ADDED
package/lib/cli.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,SAAS,CAAC"}
|
package/lib/cli.js
ADDED
package/lib/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,mBAAiB","sourcesContent":["#!/usr/bin/env node\nimport './index';\n"]}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAC;AACnB,OAAO,SAAS,CAAC"}
|
package/lib/index.js
ADDED
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,qBAAmB;AACnB,mBAAiB","sourcesContent":["import './account';\nimport './order';\n"]}
|
package/lib/order.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order.d.ts","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":""}
|
package/lib/order.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const protocol_1 = require("@yuants/protocol");
|
|
4
|
+
const account_1 = require("./account");
|
|
5
|
+
const api_1 = require("./api");
|
|
6
|
+
const terminal = protocol_1.Terminal.fromNodeEnv();
|
|
7
|
+
terminal.server.provideService('SubmitOrder', { required: ['account_id'], properties: { account_id: { type: 'string', const: account_1.ACCOUNT_ID } } }, async (msg) => {
|
|
8
|
+
const order = msg.req;
|
|
9
|
+
const symbol = order.product_id;
|
|
10
|
+
const side = { OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' }[order.order_direction];
|
|
11
|
+
if (!side)
|
|
12
|
+
throw new Error(`Unsupported order_direction: ${order.order_direction}`);
|
|
13
|
+
const type = { MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' }[order.order_type];
|
|
14
|
+
if (!type)
|
|
15
|
+
throw new Error(`Unsupported order_type: ${order.order_type}`);
|
|
16
|
+
const quantity = order.volume;
|
|
17
|
+
const price = order.price;
|
|
18
|
+
const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;
|
|
19
|
+
await (0, api_1.postFApiV1Order)({
|
|
20
|
+
symbol,
|
|
21
|
+
side,
|
|
22
|
+
type,
|
|
23
|
+
quantity,
|
|
24
|
+
price,
|
|
25
|
+
timeInForce,
|
|
26
|
+
});
|
|
27
|
+
return { res: { code: 0, message: 'OK' } };
|
|
28
|
+
});
|
|
29
|
+
//# sourceMappingURL=order.js.map
|
package/lib/order.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order.js","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":";;AAAA,+CAA4C;AAE5C,uCAAuC;AACvC,+BAAwC;AAExC,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,aAAa,EACb,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,oBAAU,EAAE,EAAE,EAAE,EAC/F,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC;IAEtB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC;IAEhC,MAAM,IAAI,GAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAY,CACtG,KAAK,CAAC,eAAgB,CACvB,CAAC;IACF,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC;IAEpF,MAAM,IAAI,GAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAY,CAAC,KAAK,CAAC,UAAW,CAAC,CAAC;IAChG,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAE1E,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;IAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAE1B,MAAM,WAAW,GACf,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAE1F,MAAM,IAAA,qBAAe,EAAC;QACpB,MAAM;QACN,IAAI;QACJ,IAAI;QACJ,QAAQ;QACR,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;AAC7C,CAAC,CACF,CAAC","sourcesContent":["import { Terminal } from '@yuants/protocol';\nimport { IOrder } from '@yuants/data-order';\nimport { ACCOUNT_ID } from './account';\nimport { postFApiV1Order } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<IOrder>(\n 'SubmitOrder',\n { required: ['account_id'], properties: { account_id: { type: 'string', const: ACCOUNT_ID } } },\n async (msg) => {\n const order = msg.req;\n\n const symbol = order.product_id;\n\n const side = ({ OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' } as const)[\n order.order_direction!\n ];\n if (!side) throw new Error(`Unsupported order_direction: ${order.order_direction}`);\n\n const type = ({ MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' } as const)[order.order_type!];\n if (!type) throw new Error(`Unsupported order_type: ${order.order_type}`);\n\n const quantity = order.volume;\n const price = order.price;\n\n const timeInForce =\n order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n\n await postFApiV1Order({\n symbol,\n side,\n type,\n quantity,\n price,\n timeInForce,\n });\n\n return { res: { code: 0, message: 'OK' } };\n },\n);\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yuants/vendor-aster",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"bin": "lib/cli.js",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"lib",
|
|
9
|
+
"temp"
|
|
10
|
+
],
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@yuants/protocol": "0.43.0",
|
|
13
|
+
"@yuants/data-account": "0.4.4",
|
|
14
|
+
"@yuants/utils": "0.8.0",
|
|
15
|
+
"@yuants/data-series": "0.3.27",
|
|
16
|
+
"@yuants/sql": "0.9.6",
|
|
17
|
+
"@yuants/data-product": "0.2.16",
|
|
18
|
+
"@yuants/data-ohlc": "0.3.23",
|
|
19
|
+
"@yuants/data-order": "0.2.12",
|
|
20
|
+
"@yuants/data-interest-rate": "0.1.24",
|
|
21
|
+
"@yuants/transfer": "0.2.15",
|
|
22
|
+
"rxjs": "~7.5.6"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@microsoft/api-extractor": "~7.30.0",
|
|
26
|
+
"@rushstack/heft": "~0.47.5",
|
|
27
|
+
"@rushstack/heft-jest-plugin": "~0.16.8",
|
|
28
|
+
"@rushstack/heft-node-rig": "~1.10.7",
|
|
29
|
+
"@types/heft-jest": "1.0.3",
|
|
30
|
+
"@types/node": "22",
|
|
31
|
+
"@yuants/extension": "0.2.24",
|
|
32
|
+
"@yuants/tool-kit": "0.2.0",
|
|
33
|
+
"typescript": "~4.7.4",
|
|
34
|
+
"ts-node": "~10.9.2"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"registry": "https://registry.npmjs.org",
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"io_ntnl": {
|
|
41
|
+
"deploy_files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"lib",
|
|
44
|
+
"temp"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"dev": "ts-node src/index.ts",
|
|
49
|
+
"build": "heft test --clean && yuan-toolkit post-build"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apps/vendor-aster/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
|
|
3
|
+
"apps/vendor-aster/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
|
|
4
|
+
"apps/vendor-aster/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
|
|
5
|
+
"apps/vendor-aster/package.json": "6cb41e70897cb2351448580da7199b02d4b64832",
|
|
6
|
+
"apps/vendor-aster/src/account.ts": "dfef4baeb4a7f28726cd789e5a2e481e97d3a905",
|
|
7
|
+
"apps/vendor-aster/src/api.ts": "b50b5e0f4a2679eeb1aa53c8109ddced464a6293",
|
|
8
|
+
"apps/vendor-aster/src/cli.ts": "9bf6b5559a6c6f33da20e74cc6c5d702c60ec891",
|
|
9
|
+
"apps/vendor-aster/src/index.ts": "dc5f7588eba080e7098c267fd1218575bb2eb239",
|
|
10
|
+
"apps/vendor-aster/src/order.ts": "546900e63e6e1c72d01086ea5eecc3c418ba7b67",
|
|
11
|
+
"apps/vendor-aster/tsconfig.json": "81da8f78196974b5d15da0edb6b2d9f48641063c",
|
|
12
|
+
"apps/vendor-aster/.rush/temp/shrinkwrap-deps.json": "1f86f5175c8714c481b272c219e0d95bc6e72755",
|
|
13
|
+
"libraries/protocol/temp/package-deps.json": "3b8c7d38aeee5cc1b2858530c0bff8904d8326e4",
|
|
14
|
+
"libraries/data-account/temp/package-deps.json": "5eb844c54c6c70d8cdde8bceb2e3ce337ebbe061",
|
|
15
|
+
"libraries/utils/temp/package-deps.json": "c0ccd6946461153e7eb1b04a3061e075788fad2a",
|
|
16
|
+
"libraries/data-series/temp/package-deps.json": "f26c0a0e5ae88682a502ccaa50da5c33dc32aa2c",
|
|
17
|
+
"libraries/sql/temp/package-deps.json": "58c2368f516d411e6849e82620f1969f34db381e",
|
|
18
|
+
"libraries/data-product/temp/package-deps.json": "54454b1f541b962b2e87f66459d3a2f0cd524d4d",
|
|
19
|
+
"libraries/data-ohlc/temp/package-deps.json": "be3c2f508e0e7a20c4a402da38ac0882fb4e4c2b",
|
|
20
|
+
"libraries/data-order/temp/package-deps.json": "52b60ad284690709bdd3a1b922b50321e54faa81",
|
|
21
|
+
"libraries/data-interest-rate/temp/package-deps.json": "2eb39b7c4946bd07e168d2f8729fd843eddca04a",
|
|
22
|
+
"libraries/transfer/temp/package-deps.json": "55b5e0be5042b445bf9cf2be5b4087baf93de46b",
|
|
23
|
+
"libraries/extension/temp/package-deps.json": "abcd1ce716b9fd88f33173d01f02c4c3a9462009",
|
|
24
|
+
"tools/toolkit/temp/package-deps.json": "3bef053db16659f0cdaceea64c8a8580c0131633"
|
|
25
|
+
}
|