@yuants/vendor-aster 0.5.8 → 0.7.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.
Files changed (144) hide show
  1. package/dist/api/private-api.js +69 -0
  2. package/dist/api/private-api.js.map +1 -0
  3. package/dist/api/public-api.js +44 -0
  4. package/dist/api/public-api.js.map +1 -0
  5. package/dist/index.js +6 -8
  6. package/dist/index.js.map +1 -1
  7. package/dist/services/account-actions-with-credential.js +34 -0
  8. package/dist/services/account-actions-with-credential.js.map +1 -0
  9. package/dist/{account.js → services/accounts/perp.js} +5 -9
  10. package/dist/services/accounts/perp.js.map +1 -0
  11. package/dist/{account-spot.js → services/accounts/spot.js} +8 -9
  12. package/dist/services/accounts/spot.js.map +1 -0
  13. package/dist/services/legacy.js +69 -0
  14. package/dist/services/legacy.js.map +1 -0
  15. package/dist/{interest_rate.js → services/markets/interest_rate.js} +1 -1
  16. package/dist/services/markets/interest_rate.js.map +1 -0
  17. package/dist/{product.js → services/markets/product.js} +1 -1
  18. package/dist/services/markets/product.js.map +1 -0
  19. package/dist/{quote.js → services/markets/quote.js} +1 -1
  20. package/dist/services/markets/quote.js.map +1 -0
  21. package/dist/services/order-actions-with-credential.js +19 -0
  22. package/dist/services/order-actions-with-credential.js.map +1 -0
  23. package/dist/services/orders/cancelOrder.js +40 -0
  24. package/dist/services/orders/cancelOrder.js.map +1 -0
  25. package/dist/services/orders/listOrders.js +67 -0
  26. package/dist/services/orders/listOrders.js.map +1 -0
  27. package/dist/services/orders/submitOrder.js +101 -0
  28. package/dist/services/orders/submitOrder.js.map +1 -0
  29. package/dist/utils.js +1 -20
  30. package/dist/utils.js.map +1 -1
  31. package/lib/api/private-api.d.ts +192 -0
  32. package/lib/api/private-api.d.ts.map +1 -0
  33. package/lib/api/private-api.js +72 -0
  34. package/lib/api/private-api.js.map +1 -0
  35. package/lib/api/public-api.d.ts +59 -0
  36. package/lib/api/public-api.d.ts.map +1 -0
  37. package/lib/api/public-api.js +47 -0
  38. package/lib/api/public-api.js.map +1 -0
  39. package/lib/index.d.ts +6 -8
  40. package/lib/index.d.ts.map +1 -1
  41. package/lib/index.js +6 -8
  42. package/lib/index.js.map +1 -1
  43. package/lib/services/account-actions-with-credential.d.ts +2 -0
  44. package/lib/services/account-actions-with-credential.d.ts.map +1 -0
  45. package/lib/services/account-actions-with-credential.js +36 -0
  46. package/lib/services/account-actions-with-credential.js.map +1 -0
  47. package/lib/services/accounts/perp.d.ts +4 -0
  48. package/lib/services/accounts/perp.d.ts.map +1 -0
  49. package/lib/{account.js → services/accounts/perp.js} +7 -10
  50. package/lib/services/accounts/perp.js.map +1 -0
  51. package/lib/services/accounts/spot.d.ts +4 -0
  52. package/lib/services/accounts/spot.d.ts.map +1 -0
  53. package/lib/{account-spot.js → services/accounts/spot.js} +10 -10
  54. package/lib/services/accounts/spot.js.map +1 -0
  55. package/lib/services/legacy.d.ts +2 -0
  56. package/lib/services/legacy.d.ts.map +1 -0
  57. package/lib/services/legacy.js +71 -0
  58. package/lib/services/legacy.js.map +1 -0
  59. package/lib/services/markets/interest_rate.d.ts.map +1 -0
  60. package/lib/{interest_rate.js → services/markets/interest_rate.js} +2 -2
  61. package/lib/services/markets/interest_rate.js.map +1 -0
  62. package/lib/services/markets/product.d.ts.map +1 -0
  63. package/lib/{product.js → services/markets/product.js} +2 -2
  64. package/lib/services/markets/product.js.map +1 -0
  65. package/lib/{quote.d.ts.map → services/markets/quote.d.ts.map} +1 -1
  66. package/lib/{quote.js → services/markets/quote.js} +3 -3
  67. package/lib/services/markets/quote.js.map +1 -0
  68. package/lib/services/order-actions-with-credential.d.ts +2 -0
  69. package/lib/services/order-actions-with-credential.d.ts.map +1 -0
  70. package/lib/services/order-actions-with-credential.js +21 -0
  71. package/lib/services/order-actions-with-credential.js.map +1 -0
  72. package/lib/services/orders/cancelOrder.d.ts +4 -0
  73. package/lib/services/orders/cancelOrder.d.ts.map +1 -0
  74. package/lib/services/orders/cancelOrder.js +44 -0
  75. package/lib/services/orders/cancelOrder.js.map +1 -0
  76. package/lib/services/orders/listOrders.d.ts +4 -0
  77. package/lib/services/orders/listOrders.d.ts.map +1 -0
  78. package/lib/services/orders/listOrders.js +71 -0
  79. package/lib/services/orders/listOrders.js.map +1 -0
  80. package/lib/services/orders/submitOrder.d.ts +4 -0
  81. package/lib/services/orders/submitOrder.d.ts.map +1 -0
  82. package/lib/services/orders/submitOrder.js +105 -0
  83. package/lib/services/orders/submitOrder.js.map +1 -0
  84. package/lib/utils.d.ts +1 -2
  85. package/lib/utils.d.ts.map +1 -1
  86. package/lib/utils.js +3 -23
  87. package/lib/utils.js.map +1 -1
  88. package/package.json +3 -4
  89. package/temp/package-deps.json +22 -18
  90. package/dist/account-spot.js.map +0 -1
  91. package/dist/account.js.map +0 -1
  92. package/dist/api.js +0 -55
  93. package/dist/api.js.map +0 -1
  94. package/dist/cli.js +0 -3
  95. package/dist/cli.js.map +0 -1
  96. package/dist/interest_rate.js.map +0 -1
  97. package/dist/order-spot.js +0 -38
  98. package/dist/order-spot.js.map +0 -1
  99. package/dist/order.js +0 -70
  100. package/dist/order.js.map +0 -1
  101. package/dist/pending-orders.js +0 -43
  102. package/dist/pending-orders.js.map +0 -1
  103. package/dist/product.js.map +0 -1
  104. package/dist/quote.js.map +0 -1
  105. package/dist/sapi.js +0 -48
  106. package/dist/sapi.js.map +0 -1
  107. package/lib/account-spot.d.ts +0 -2
  108. package/lib/account-spot.d.ts.map +0 -1
  109. package/lib/account-spot.js.map +0 -1
  110. package/lib/account.d.ts +0 -2
  111. package/lib/account.d.ts.map +0 -1
  112. package/lib/account.js.map +0 -1
  113. package/lib/api.d.ts +0 -149
  114. package/lib/api.d.ts.map +0 -1
  115. package/lib/api.js +0 -58
  116. package/lib/api.js.map +0 -1
  117. package/lib/cli.d.ts +0 -3
  118. package/lib/cli.d.ts.map +0 -1
  119. package/lib/cli.js +0 -5
  120. package/lib/cli.js.map +0 -1
  121. package/lib/interest_rate.d.ts.map +0 -1
  122. package/lib/interest_rate.js.map +0 -1
  123. package/lib/order-spot.d.ts +0 -2
  124. package/lib/order-spot.d.ts.map +0 -1
  125. package/lib/order-spot.js +0 -40
  126. package/lib/order-spot.js.map +0 -1
  127. package/lib/order.d.ts +0 -2
  128. package/lib/order.d.ts.map +0 -1
  129. package/lib/order.js +0 -72
  130. package/lib/order.js.map +0 -1
  131. package/lib/pending-orders.d.ts +0 -2
  132. package/lib/pending-orders.d.ts.map +0 -1
  133. package/lib/pending-orders.js +0 -45
  134. package/lib/pending-orders.js.map +0 -1
  135. package/lib/product.d.ts.map +0 -1
  136. package/lib/product.js.map +0 -1
  137. package/lib/quote.js.map +0 -1
  138. package/lib/sapi.d.ts +0 -37
  139. package/lib/sapi.d.ts.map +0 -1
  140. package/lib/sapi.js +0 -51
  141. package/lib/sapi.js.map +0 -1
  142. /package/lib/{interest_rate.d.ts → services/markets/interest_rate.d.ts} +0 -0
  143. /package/lib/{product.d.ts → services/markets/product.d.ts} +0 -0
  144. /package/lib/{quote.d.ts → services/markets/quote.d.ts} +0 -0
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleSubmitOrder = void 0;
4
+ const utils_1 = require("@yuants/utils");
5
+ const private_api_1 = require("../../api/private-api");
6
+ const parseProductId = (productId) => {
7
+ if (!productId) {
8
+ return { category: undefined, symbol: undefined };
9
+ }
10
+ const parts = (0, utils_1.decodePath)(productId);
11
+ if (parts.length >= 2) {
12
+ return { category: parts[0], symbol: parts.slice(1).join('/') };
13
+ }
14
+ return { category: undefined, symbol: parts[0] };
15
+ };
16
+ const handleSubmitOrderOfSpot = async (credential, order) => {
17
+ var _a;
18
+ const { symbol } = parseProductId(order.product_id);
19
+ const resolvedSymbol = symbol !== null && symbol !== void 0 ? symbol : order.product_id;
20
+ if (!resolvedSymbol) {
21
+ throw new Error(`Invalid product_id: unable to resolve spot symbol from "${order.product_id}"`);
22
+ }
23
+ const type = { MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' }[order.order_type];
24
+ if (!type)
25
+ throw new Error(`Unsupported order_type: ${order.order_type}`);
26
+ const side = { OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' }[order.order_direction];
27
+ if (!side)
28
+ throw new Error(`Unsupported order_direction: ${order.order_direction}`);
29
+ const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;
30
+ const price = order.price;
31
+ let quantity = order.volume;
32
+ let quoteOrderQty;
33
+ if (type === 'MARKET' && side === 'BUY') {
34
+ const spotPrice = await (0, private_api_1.getApiV1TickerPrice)(credential, {});
35
+ const thePrice = (_a = spotPrice.find((x) => x.symbol === resolvedSymbol)) === null || _a === void 0 ? void 0 : _a.price;
36
+ if (!thePrice)
37
+ throw new Error(`Cannot get price for symbol ${resolvedSymbol}`);
38
+ quantity = undefined;
39
+ quoteOrderQty = (0, utils_1.roundToStep)(order.volume * +thePrice, 0.01);
40
+ }
41
+ const res = await (0, private_api_1.postApiV1Order)(credential, {
42
+ symbol: resolvedSymbol,
43
+ type,
44
+ side,
45
+ timeInForce,
46
+ price,
47
+ quantity,
48
+ quoteOrderQty,
49
+ });
50
+ if (!res.orderId) {
51
+ throw new Error('Failed to retrieve order ID from response');
52
+ }
53
+ return { order_id: '' + res.orderId };
54
+ };
55
+ const handleSubmitOrderOfPerp = async (credential, order) => {
56
+ var _a, _b, _c, _d, _e;
57
+ const { symbol } = parseProductId(order.product_id);
58
+ if (!symbol) {
59
+ throw new Error(`Invalid product_id: unable to decode symbol from "${order.product_id}"`);
60
+ }
61
+ const side = { OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' }[order.order_direction];
62
+ if (!side)
63
+ throw new Error(`Unsupported order_direction: ${order.order_direction}`);
64
+ const type = { MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' }[order.order_type];
65
+ if (!type)
66
+ throw new Error(`Unsupported order_type: ${order.order_type}`);
67
+ const quantity = order.volume;
68
+ const price = order.price;
69
+ const positionSide = order.order_direction === 'OPEN_LONG' || order.order_direction === 'CLOSE_LONG'
70
+ ? 'LONG'
71
+ : order.order_direction === 'OPEN_SHORT' || order.order_direction === 'CLOSE_SHORT'
72
+ ? 'SHORT'
73
+ : undefined;
74
+ const reduceOnly = order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT' ? 'true' : undefined;
75
+ const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;
76
+ const res = await (0, private_api_1.postFApiV1Order)(credential, {
77
+ symbol,
78
+ side,
79
+ type,
80
+ quantity,
81
+ price,
82
+ timeInForce,
83
+ positionSide,
84
+ reduceOnly,
85
+ });
86
+ const orderId = (_d = (_b = (_a = res === null || res === void 0 ? void 0 : res.orderId) !== null && _a !== void 0 ? _a : res === null || res === void 0 ? void 0 : res.order_id) !== null && _b !== void 0 ? _b : (_c = res === null || res === void 0 ? void 0 : res.data) === null || _c === void 0 ? void 0 : _c.orderId) !== null && _d !== void 0 ? _d : (_e = res === null || res === void 0 ? void 0 : res.data) === null || _e === void 0 ? void 0 : _e.order_id;
87
+ if (!orderId)
88
+ throw new Error('Failed to retrieve order ID from response');
89
+ return { order_id: `${orderId}` };
90
+ };
91
+ const handleSubmitOrder = async (credential, order) => {
92
+ var _a, _b;
93
+ const accountId = (_b = (_a = order.account_id) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== null && _b !== void 0 ? _b : order.account_id;
94
+ const { category } = parseProductId(order.product_id);
95
+ const productType = category === null || category === void 0 ? void 0 : category.toUpperCase();
96
+ if ((accountId === null || accountId === void 0 ? void 0 : accountId.includes('/SPOT')) || productType === 'SPOT') {
97
+ return handleSubmitOrderOfSpot(credential, order);
98
+ }
99
+ if ((accountId === null || accountId === void 0 ? void 0 : accountId.includes('/PERP')) || productType === 'PERPETUAL') {
100
+ return handleSubmitOrderOfPerp(credential, order);
101
+ }
102
+ throw new Error(`Unsupported account_id for SubmitOrder: ${order.account_id}`);
103
+ };
104
+ exports.handleSubmitOrder = handleSubmitOrder;
105
+ //# sourceMappingURL=submitOrder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submitOrder.js","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"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","sourcesContent":["import { IActionHandlerOfSubmitOrder } from '@yuants/data-order';\nimport { decodePath, roundToStep } from '@yuants/utils';\nimport { getApiV1TickerPrice, ICredential, postApiV1Order, postFApiV1Order } from '../../api/private-api';\n\nconst parseProductId = (productId?: string) => {\n if (!productId) {\n return { category: undefined as string | undefined, symbol: undefined as string | undefined };\n }\n const parts = decodePath(productId);\n if (parts.length >= 2) {\n return { category: parts[0], symbol: parts.slice(1).join('/') };\n }\n return { category: undefined, symbol: parts[0] };\n};\n\nconst handleSubmitOrderOfSpot: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const { symbol } = parseProductId(order.product_id);\n const resolvedSymbol = symbol ?? order.product_id;\n if (!resolvedSymbol) {\n throw new Error(`Invalid product_id: unable to resolve spot symbol from \"${order.product_id}\"`);\n }\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 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 timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n\n const price = order.price;\n\n let quantity: number | undefined = order.volume;\n let quoteOrderQty: number | undefined;\n\n if (type === 'MARKET' && side === 'BUY') {\n const spotPrice = await getApiV1TickerPrice(credential, {});\n const thePrice = spotPrice.find((x) => x.symbol === resolvedSymbol)?.price;\n if (!thePrice) throw new Error(`Cannot get price for symbol ${resolvedSymbol}`);\n quantity = undefined;\n quoteOrderQty = roundToStep(order.volume * +thePrice, 0.01);\n }\n\n const res = await postApiV1Order(credential, {\n symbol: resolvedSymbol,\n type,\n side,\n timeInForce,\n price,\n quantity,\n quoteOrderQty,\n });\n\n if (!res.orderId) {\n throw new Error('Failed to retrieve order ID from response');\n }\n\n return { order_id: '' + res.orderId };\n};\n\nconst handleSubmitOrderOfPerp: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const { symbol } = parseProductId(order.product_id);\n if (!symbol) {\n throw new Error(`Invalid product_id: unable to decode symbol from \"${order.product_id}\"`);\n }\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 positionSide =\n order.order_direction === 'OPEN_LONG' || order.order_direction === 'CLOSE_LONG'\n ? 'LONG'\n : order.order_direction === 'OPEN_SHORT' || order.order_direction === 'CLOSE_SHORT'\n ? 'SHORT'\n : undefined;\n\n const reduceOnly =\n order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT' ? 'true' : undefined;\n\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n\n const res = await postFApiV1Order(credential, {\n symbol,\n side,\n type,\n quantity,\n price,\n timeInForce,\n positionSide,\n reduceOnly,\n });\n\n const orderId =\n (res as any)?.orderId ??\n (res as any)?.order_id ??\n (res as any)?.data?.orderId ??\n (res as any)?.data?.order_id;\n\n if (!orderId) throw new Error('Failed to retrieve order ID from response');\n\n return { order_id: `${orderId}` };\n};\n\nexport const handleSubmitOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const accountId = order.account_id?.toUpperCase() ?? order.account_id;\n const { category } = parseProductId(order.product_id);\n const productType = category?.toUpperCase();\n\n if (accountId?.includes('/SPOT') || productType === 'SPOT') {\n return handleSubmitOrderOfSpot(credential, order);\n }\n if (accountId?.includes('/PERP') || productType === 'PERPETUAL') {\n return handleSubmitOrderOfPerp(credential, order);\n }\n throw new Error(`Unsupported account_id for SubmitOrder: ${order.account_id}`);\n};\n"]}
package/lib/utils.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- export declare function arrayBufferToHex(buffer: ArrayBuffer): string;
2
- export declare function opensslEquivalentHMAC(message: string, secretKey: string): Promise<string>;
1
+ export declare function uint8ArrayToHex(bytes: Uint8Array): string;
3
2
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAU5D;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyB/F"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CASzD"}
package/lib/utils.js CHANGED
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.opensslEquivalentHMAC = exports.arrayBufferToHex = void 0;
4
- function arrayBufferToHex(buffer) {
5
- const bytes = new Uint8Array(buffer);
3
+ exports.uint8ArrayToHex = void 0;
4
+ function uint8ArrayToHex(bytes) {
6
5
  const hexArray = [];
7
6
  for (const byte of bytes) {
8
7
  const hex = byte.toString(16).padStart(2, '0');
@@ -10,24 +9,5 @@ function arrayBufferToHex(buffer) {
10
9
  }
11
10
  return hexArray.join('');
12
11
  }
13
- exports.arrayBufferToHex = arrayBufferToHex;
14
- async function opensslEquivalentHMAC(message, secretKey) {
15
- try {
16
- const keyBuffer = new TextEncoder().encode(secretKey);
17
- const messageBuffer = new TextEncoder().encode(message);
18
- // 导入密钥
19
- const cryptoKey = await crypto.subtle.importKey('raw', keyBuffer, {
20
- name: 'HMAC',
21
- hash: { name: 'SHA-256' },
22
- }, false, ['sign']);
23
- // 进行 HMAC-SHA256 签名
24
- const signature = await crypto.subtle.sign('HMAC', cryptoKey, messageBuffer);
25
- // 转换为16进制小写(与 openssl 输出格式一致)
26
- return arrayBufferToHex(signature);
27
- }
28
- catch (error) {
29
- throw new Error(`HMAC-SHA256 签名失败: ${error}`);
30
- }
31
- }
32
- exports.opensslEquivalentHMAC = opensslEquivalentHMAC;
12
+ exports.uint8ArrayToHex = uint8ArrayToHex;
33
13
  //# sourceMappingURL=utils.js.map
package/lib/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA,SAAgB,gBAAgB,CAAC,MAAmB;IAClD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/C,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KACpB;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3B,CAAC;AAVD,4CAUC;AAEM,KAAK,UAAU,qBAAqB,CAAC,OAAe,EAAE,SAAiB;IAC5E,IAAI;QACF,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAExD,OAAO;QACP,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAC7C,KAAK,EACL,SAAS,EACT;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC1B,EACD,KAAK,EACL,CAAC,MAAM,CAAC,CACT,CAAC;QAEF,oBAAoB;QACpB,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;QAE7E,8BAA8B;QAC9B,OAAO,gBAAgB,CAAC,SAAS,CAAC,CAAC;KACpC;IAAC,OAAO,KAAK,EAAE;QACd,MAAM,IAAI,KAAK,CAAC,qBAAqB,KAAK,EAAE,CAAC,CAAC;KAC/C;AACH,CAAC;AAzBD,sDAyBC","sourcesContent":["export function 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\nexport async 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"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA,SAAgB,eAAe,CAAC,KAAiB;IAC/C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/C,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KACpB;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3B,CAAC;AATD,0CASC","sourcesContent":["export function uint8ArrayToHex(bytes: Uint8Array): string {\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"]}
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "@yuants/vendor-aster",
3
- "version": "0.5.8",
4
- "bin": "lib/cli.js",
3
+ "version": "0.7.0",
5
4
  "main": "lib/index.js",
6
5
  "files": [
7
6
  "dist",
@@ -11,13 +10,13 @@
11
10
  "dependencies": {
12
11
  "@yuants/protocol": "0.50.4",
13
12
  "@yuants/cache": "0.3.0",
14
- "@yuants/data-account": "0.7.0",
13
+ "@yuants/data-account": "0.7.1",
15
14
  "@yuants/utils": "0.11.0",
16
15
  "@yuants/data-series": "0.3.45",
17
16
  "@yuants/sql": "0.9.24",
18
17
  "@yuants/data-product": "0.4.15",
19
18
  "@yuants/data-ohlc": "0.4.16",
20
- "@yuants/data-order": "0.5.0",
19
+ "@yuants/data-order": "0.6.0",
21
20
  "@yuants/data-interest-rate": "0.1.42",
22
21
  "@yuants/transfer": "0.2.33",
23
22
  "@yuants/data-quote": "0.2.37",
@@ -1,34 +1,38 @@
1
1
  {
2
- "apps/vendor-aster/CHANGELOG.json": "fd035fafbc5d4844b869a863647b6aa43f1be06b",
3
- "apps/vendor-aster/CHANGELOG.md": "30578e509850550bbc1a13de9ed6688c7f810dc3",
2
+ "apps/vendor-aster/AGENTS.md": "6774bd2a0fc2930c359462dc4e0c1180a7a75291",
3
+ "apps/vendor-aster/CHANGELOG.json": "fd20ea495712ea190959253773104c60fda1288c",
4
+ "apps/vendor-aster/CHANGELOG.md": "6ff6c3cdb0f7a6193ccef5ed397d0de36b5f4d28",
5
+ "apps/vendor-aster/SESSION_NOTES.md": "f54c13cf4182d8a5e720f6db5d3acc323655ea49",
4
6
  "apps/vendor-aster/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
5
7
  "apps/vendor-aster/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
6
8
  "apps/vendor-aster/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
7
- "apps/vendor-aster/package.json": "59160a48447aba45c07649858edb69dd5868cbc7",
8
- "apps/vendor-aster/src/account-spot.ts": "e5162a9c7f00fde4d1f143c3f85ef04ae8877b56",
9
- "apps/vendor-aster/src/account.ts": "6163105ce1de2d1b9747b8080936357bbcada559",
10
- "apps/vendor-aster/src/api.ts": "fc108fb205aa77ba0f4e58f62b8794337c5ed209",
11
- "apps/vendor-aster/src/cli.ts": "9bf6b5559a6c6f33da20e74cc6c5d702c60ec891",
12
- "apps/vendor-aster/src/index.ts": "ec461c856e78211a16e3529e20ba6bcb643512f9",
13
- "apps/vendor-aster/src/interest_rate.ts": "40366d0cc1d78d77e7852432cbe5df2847ccfda4",
14
- "apps/vendor-aster/src/order-spot.ts": "e17f728347f3c49d4311493a47b1ed72d5a29f37",
15
- "apps/vendor-aster/src/order.ts": "f4c905309ffabf2122bf7079b4f5faf6c1e3f744",
16
- "apps/vendor-aster/src/pending-orders.ts": "e047fcb2f9098583856513677f90b2e3d6e26441",
17
- "apps/vendor-aster/src/product.ts": "665becdfc3aa0f9239d008831b1304a17edb01dc",
18
- "apps/vendor-aster/src/quote.ts": "6852b4c72980adbec4520baaa1c3e0c044f45954",
19
- "apps/vendor-aster/src/sapi.ts": "40214de87500f9fb6647c11d3999e0e449a6fa0b",
20
- "apps/vendor-aster/src/utils.ts": "f732922ea47951ddf0889bba9a70fd8e270cae2f",
9
+ "apps/vendor-aster/package.json": "d2b43af18b854581206deff153952b767bfdde86",
10
+ "apps/vendor-aster/src/api/private-api.ts": "db39f7dd41a67b9e306159828393be80971e638e",
11
+ "apps/vendor-aster/src/api/public-api.ts": "bfc642fff0ae31319c23e198f365a4a3372d4b10",
12
+ "apps/vendor-aster/src/index.ts": "603b5c4e487389ce5c815ed5122a408abde43e17",
13
+ "apps/vendor-aster/src/services/account-actions-with-credential.ts": "2d78127a969acaa4b0b39b8a93fcd3f0b76fd158",
14
+ "apps/vendor-aster/src/services/accounts/perp.ts": "3d01893b6531aa72c50b147123293043ec0a9ce1",
15
+ "apps/vendor-aster/src/services/accounts/spot.ts": "dfc0756a473c5d21fabd2554dff115a11a7b3d43",
16
+ "apps/vendor-aster/src/services/legacy.ts": "72d322567eb377e490c9fe26e6247f11de40154b",
17
+ "apps/vendor-aster/src/services/markets/interest_rate.ts": "15befd821b9cefd892210d26228f0c84a124a28e",
18
+ "apps/vendor-aster/src/services/markets/product.ts": "ddab6fc348a0fff17ef717683cbc2caf48c38513",
19
+ "apps/vendor-aster/src/services/markets/quote.ts": "9cf8055d9c373c5a390c9704c7f8bde4e0b1cea5",
20
+ "apps/vendor-aster/src/services/order-actions-with-credential.ts": "05a9a4e403ddee7b0b7de4308ee244d52174f3a3",
21
+ "apps/vendor-aster/src/services/orders/cancelOrder.ts": "51adab5d66ba739779ceb98a5831c9434ae1ef0a",
22
+ "apps/vendor-aster/src/services/orders/listOrders.ts": "ef6ea64f94d0bc59527f74699892e92e235f525a",
23
+ "apps/vendor-aster/src/services/orders/submitOrder.ts": "ad7b62c9f9f63f89dec9ec9661949ce3c11bb68b",
24
+ "apps/vendor-aster/src/utils.ts": "cf133a98161e868ef766bd3e3c340149345889f4",
21
25
  "apps/vendor-aster/tsconfig.json": "81da8f78196974b5d15da0edb6b2d9f48641063c",
22
26
  "apps/vendor-aster/.rush/temp/shrinkwrap-deps.json": "8909c2a52371c1bd644b09b7ccbb4bbaf29d53dd",
23
27
  "libraries/protocol/temp/package-deps.json": "35bc77333a1c85db1cd130579963e8cefa00f56c",
24
28
  "libraries/cache/temp/package-deps.json": "49789a92426969daa31f0c956bb56bd783929765",
25
- "libraries/data-account/temp/package-deps.json": "23ce351fb7d34192c8885a00c1f0e8d49f592a9c",
29
+ "libraries/data-account/temp/package-deps.json": "e7b28ee5c9f5236a894a8034de5a037cc7ecb088",
26
30
  "libraries/utils/temp/package-deps.json": "c58f1ca8f498315d9a0219ca8c498299a41d297b",
27
31
  "libraries/data-series/temp/package-deps.json": "d5269fad8f63460b1b5f29ba701ad3a9457e0061",
28
32
  "libraries/sql/temp/package-deps.json": "e3b6f24485a429fb24cacbf0d6150f55ca394706",
29
33
  "libraries/data-product/temp/package-deps.json": "0a4e14971c7dc350b84712fb16c07fefad351619",
30
34
  "libraries/data-ohlc/temp/package-deps.json": "6e10227e1c394ad0b5a71e0f810914760e9b7956",
31
- "libraries/data-order/temp/package-deps.json": "921c6745e9a502669524f7a7d276bff69c25491c",
35
+ "libraries/data-order/temp/package-deps.json": "0e2f026ee9847657a72801c106c040fcf905e7b5",
32
36
  "libraries/data-interest-rate/temp/package-deps.json": "11bb199efb64628f67b1165e11d6c85dd7114a9a",
33
37
  "libraries/transfer/temp/package-deps.json": "708a4caf79d042cad56a39f0b00d399bca04af40",
34
38
  "libraries/data-quote/temp/package-deps.json": "752ea44d75cbe7a652ace79629c02ca92a92cf1d",
@@ -1 +0,0 @@
1
- {"version":3,"file":"account-spot.js","sourceRoot":"","sources":["../src/account-spot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAE9D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAQ,CAAC;AACrC,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,OAAO,OAAO,CAAC;AAEvD,yBAAyB,CACvB,QAAQ,CAAC,WAAW,EAAE,EACtB,eAAe,EACf,KAAK,IAAI,EAAE;IACT,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,EAAE,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtF,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAa,EAAE;;QAChD,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAA,MAAA,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,0CAAE,KAAK,mCAAI,CAAC,CAAC;QAExG,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;QAEnC,MAAM,cAAc,GAAG,CAAC,QAAQ,CAAC;QACjC,MAAM,cAAc,GAAG,CAAC,QAAQ,CAAC;QACjC,MAAM,SAAS,GAAG,MAAM,GAAG,cAAc,CAAC;QAC1C,MAAM,eAAe,GAAG,CAAC,CAAC;QAE1B,OAAO;YACL,WAAW,EAAE,CAAC,CAAC,KAAK;YACpB,aAAa,EAAE,OAAO;YACtB,UAAU,EAAE,CAAC,CAAC,KAAK;YACnB,SAAS,EAAE,MAAM;YACjB,MAAM;YACN,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI;YACpB,cAAc;YACd,cAAc;YACd,eAAe;YACf,SAAS;SACV,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7C,OAAO;QACL,KAAK,EAAE;YACL,QAAQ,EAAE,MAAM;YAChB,MAAM;YACN,IAAI;SACL;QACD,SAAS;KACV,CAAC;AACJ,CAAC,EACD,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAChC,CAAC","sourcesContent":["import { IPosition, provideAccountInfoService } from '@yuants/data-account';\nimport { Terminal } from '@yuants/protocol';\nimport { getApiV1Account, getApiV1TickerPrice } from './sapi';\n\nconst ADDRESS = process.env.ADDRESS!;\nexport const SPOT_ACCOUNT_ID = `ASTER/${ADDRESS}/SPOT`;\n\nprovideAccountInfoService(\n Terminal.fromNodeEnv(),\n SPOT_ACCOUNT_ID,\n async () => {\n const [x, prices] = await Promise.all([getApiV1Account({}), getApiV1TickerPrice({})]);\n\n const positions = x.balances.map((b): IPosition => {\n const thePrice = b.asset === 'USDT' ? 1 : prices.find((p) => p.symbol === b.asset + 'USDT')?.price ?? 0;\n\n const volume = +b.free + +b.locked;\n\n const position_price = +thePrice;\n const closable_price = +thePrice;\n const valuation = volume * closable_price;\n const floating_profit = 0;\n\n return {\n position_id: b.asset,\n datasource_id: 'ASTER',\n product_id: b.asset,\n direction: 'LONG',\n volume,\n free_volume: +b.free,\n position_price,\n closable_price,\n floating_profit,\n valuation,\n };\n });\n\n const usdtAsset = x.balances.find((b) => b.asset === 'USDT');\n const equity = positions.reduce((a, b) => a + b.valuation, 0);\n const free = usdtAsset ? +usdtAsset.free : 0;\n\n return {\n money: {\n currency: 'USDT',\n equity,\n free,\n },\n positions,\n };\n },\n { auto_refresh_interval: 1000 },\n);\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,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,CAAC,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;IAChE,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAEjC,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,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QAC7C,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;QACL,KAAK,EAAE;YACL,QAAQ,EAAE,KAAK;YACf,MAAM;YACN,IAAI;SACL;QACD,SAAS;KACV,CAAC;AACJ,CAAC,EACD,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAChC,CAAC","sourcesContent":["import { IPosition, provideAccountInfoService } from '@yuants/data-account';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\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 Promise.all([getFApiV4Account({})]);\n\n const equity = +a.totalWalletBalance + +a.totalUnrealizedProfit;\n const free = +a.availableBalance;\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: encodePath('PERPETUAL', 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 {\n money: {\n currency: 'USD',\n equity,\n free,\n },\n positions,\n };\n },\n { auto_refresh_interval: 1000 },\n);\n"]}
package/dist/api.js DELETED
@@ -1,55 +0,0 @@
1
- import { opensslEquivalentHMAC } from './utils';
2
- const API_KEY = process.env.API_KEY;
3
- const SECRET_KEY = process.env.SECRET_KEY;
4
- const BASE_URL = 'https://fapi.asterdex.com';
5
- const request = async (type, method, endpoint, params = {}) => {
6
- const needApiKey = type !== 'NONE';
7
- const needSign = type === 'TRADE' || type === 'USER_DATA';
8
- const url = new URL(BASE_URL);
9
- url.pathname = endpoint;
10
- for (const [key, value] of Object.entries(params)) {
11
- if (value === undefined)
12
- continue;
13
- url.searchParams.set(key, `${value}`);
14
- }
15
- if (needSign) {
16
- url.searchParams.set('timestamp', `${Date.now()}`);
17
- const msg = url.search.slice(1); // 去掉开头的 '?'
18
- const signature = await opensslEquivalentHMAC(msg, SECRET_KEY);
19
- url.searchParams.set('signature', signature);
20
- }
21
- console.info(url.toString());
22
- const res = await fetch(url.toString(), {
23
- method,
24
- headers: needApiKey
25
- ? {
26
- 'X-MBX-APIKEY': API_KEY,
27
- }
28
- : {},
29
- }).then((response) => response.json());
30
- if (res.code && res.code !== 0) {
31
- throw JSON.stringify(res);
32
- }
33
- return res;
34
- };
35
- const createApi = (type, method, endpoint) => (params) => request(type, method, endpoint, params);
36
- /**
37
- * 获取账户信息
38
- *
39
- * 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
40
- */
41
- export const getFApiV4Account = createApi('USER_DATA', 'GET', '/fapi/v4/account');
42
- export const getFApiV2Balance = createApi('USER_DATA', 'GET', '/fapi/v2/balance');
43
- export const getFApiV1TickerPrice = createApi('MARKET_DATA', 'GET', '/fapi/v1/ticker/price');
44
- export const getFApiV1OpenInterest = createApi('MARKET_DATA', 'GET', '/fapi/v1/openInterest');
45
- export const getFApiV1FundingRate = createApi('NONE', 'GET', '/fapi/v1/fundingRate');
46
- export const postFApiV1Order = createApi('TRADE', 'POST', '/fapi/v1/order');
47
- export const getFApiV1OpenOrders = createApi('USER_DATA', 'GET', '/fapi/v1/openOrders');
48
- export const deleteFApiV1Order = createApi('TRADE', 'DELETE', '/fapi/v1/order');
49
- /**
50
- * 获取交易对信息
51
- *
52
- * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E4%BA%A4%E6%98%93%E5%AF%B9%E4%BF%A1%E6%81%AF
53
- */
54
- export const getFApiV1ExchangeInfo = createApi('NONE', 'GET', '/fapi/v1/exchangeInfo');
55
- //# sourceMappingURL=api.js.map
package/dist/api.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAQ,CAAC;AACrC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,UAAW,CAAC;AAE3C,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAE7C,MAAM,OAAO,GAAG,KAAK,EACnB,IAAoE,EACpE,MAAc,EACd,QAAgB,EAChB,SAAc,EAAE,EACJ,EAAE;IACd,MAAM,UAAU,GAAG,IAAI,KAAK,MAAM,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,WAAW,CAAC;IAE1D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACjD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;KACvC;IAED,IAAI,QAAQ,EAAE;QACZ,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;QAC7C,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC/D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;KAC9C;IAED,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;QACtC,MAAM;QACN,OAAO,EAAE,UAAU;YACjB,CAAC,CAAC;gBACE,cAAc,EAAE,OAAO;aACxB;YACH,CAAC,CAAC,EAAE;KACP,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE;QAC9B,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;KAC3B;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,SAAS,GACb,CACE,IAAoE,EACpE,MAAc,EACd,QAAgB,EAChB,EAAE,CACJ,CAAC,MAAY,EAAE,EAAE,CACf,OAAO,CAAO,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,CAqDvC,WAAW,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;AAE1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,CAavC,WAAW,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;AAE1C,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAO3C,aAAa,EAAE,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAEjD,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAS5C,aAAa,EAAE,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAEjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAY3C,MAAM,EAAE,KAAK,EAAE,sBAAsB,CAAC,CAAC;AAEzC,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,CAmBtC,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAyB1C,WAAW,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;AAE7C,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAOxC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAkB5C,MAAM,EAAE,KAAK,EAAE,uBAAuB,CAAC,CAAC","sourcesContent":["import { opensslEquivalentHMAC } from './utils';\n\nconst API_KEY = process.env.API_KEY!;\nconst SECRET_KEY = process.env.SECRET_KEY!;\n\nconst BASE_URL = 'https://fapi.asterdex.com';\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 const res = await fetch(url.toString(), {\n method,\n headers: needApiKey\n ? {\n 'X-MBX-APIKEY': API_KEY,\n }\n : {},\n }).then((response) => response.json());\n if (res.code && res.code !== 0) {\n throw JSON.stringify(res);\n }\n return res;\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 getFApiV2Balance = createApi<\n {},\n {\n accountAlias: string; // 账户唯一识别码\n asset: string; // 资产\n balance: string; // 总余额\n crossWalletBalance: string; // 全仓余额\n crossUnPnl: string; // 全仓持仓未实现盈亏\n availableBalance: string; // 下单可用余额\n maxWithdrawAmount: string; // 最大可转出余额\n marginAvailable: boolean; // 是否可用作联合保证金\n updateTime: number;\n }[]\n>('USER_DATA', 'GET', '/fapi/v2/balance');\n\nexport const getFApiV1TickerPrice = createApi<\n {},\n {\n symbol: string;\n price: string;\n time?: number;\n }[]\n>('MARKET_DATA', 'GET', '/fapi/v1/ticker/price');\n\nexport const getFApiV1OpenInterest = createApi<\n {\n symbol: string;\n },\n {\n symbol: string;\n openInterest: string;\n time: number;\n }\n>('MARKET_DATA', 'GET', '/fapi/v1/openInterest');\n\nexport const getFApiV1FundingRate = createApi<\n {\n symbol?: string;\n startTime?: number;\n endTime?: number;\n limit?: number;\n },\n {\n symbol: string;\n fundingRate: string;\n fundingTime: number;\n }[]\n>('NONE', 'GET', '/fapi/v1/fundingRate');\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\nexport const getFApiV1OpenOrders = createApi<\n {\n symbol?: string;\n },\n {\n orderId: number;\n clientOrderId: string;\n price: string;\n origQty: string;\n executedQty: string;\n status: string;\n timeInForce: string;\n type: string;\n side: 'BUY' | 'SELL';\n updateTime: number;\n avgPrice: string;\n reduceOnly?: boolean;\n closePosition?: boolean;\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n workingType?: string;\n priceProtect?: boolean;\n origType?: string;\n stopPrice?: string;\n symbol: string;\n }[]\n>('USER_DATA', 'GET', '/fapi/v1/openOrders');\n\nexport const deleteFApiV1Order = createApi<\n {\n symbol: string;\n orderId?: string | number;\n origClientOrderId?: string;\n },\n {}\n>('TRADE', 'DELETE', '/fapi/v1/order');\n\n/**\n * 获取交易对信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E4%BA%A4%E6%98%93%E5%AF%B9%E4%BF%A1%E6%81%AF\n */\nexport const getFApiV1ExchangeInfo = createApi<\n {},\n {\n symbols: {\n symbol: string;\n status: 'TRADING' | 'BREAK' | 'HALT';\n baseAsset: string;\n quoteAsset: string;\n pricePrecision: number;\n quantityPrecision: number;\n baseAssetPrecision: number;\n quotePrecision: number;\n filters: {\n filterType: string;\n [key: string]: any;\n }[];\n }[];\n }\n>('NONE', 'GET', '/fapi/v1/exchangeInfo');\n"]}
package/dist/cli.js DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- import './index';
3
- //# sourceMappingURL=cli.js.map
package/dist/cli.js.map DELETED
@@ -1 +0,0 @@
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"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"interest_rate.js","sourceRoot":"","sources":["../src/interest_rate.ts"],"names":[],"mappings":"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","sourcesContent":["import { IInterestRate } from '@yuants/data-interest-rate';\nimport { IProduct } from '@yuants/data-product';\nimport { createSeriesProvider, ISeriesCollectingTask } from '@yuants/data-series';\nimport { Terminal } from '@yuants/protocol';\nimport { createSQLWriter } from '@yuants/sql';\nimport { decodePath, encodePath, formatTime } from '@yuants/utils';\nimport { firstValueFrom, map, mergeAll, timer } from 'rxjs';\nimport { getFApiV1FundingRate } from './api';\nimport { productService } from './product';\n\nconst terminal = Terminal.fromNodeEnv();\n\ncreateSQLWriter<ISeriesCollectingTask>(terminal, {\n data$: productService.products$.pipe(\n map((products: IProduct[]) => products.filter((product) => product.no_interest_rate === false)),\n mergeAll(),\n map(\n (product: IProduct): ISeriesCollectingTask => ({\n series_id: encodePath(product.datasource_id, product.product_id),\n table_name: 'interest_rate',\n cron_pattern: '0 * * * *',\n cron_timezone: 'UTC',\n disabled: false,\n replay_count: 0,\n }),\n ),\n ),\n tableName: 'series_collecting_task',\n writeInterval: 1000,\n conflictKeys: ['series_id', 'table_name'],\n});\n\ncreateSeriesProvider<IInterestRate>(terminal, {\n tableName: 'interest_rate',\n series_id_prefix_parts: ['ASTER'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({ series_id, started_at, ended_at }) {\n const start = started_at ?? 0;\n const end = ended_at ?? Date.now();\n const [datasource_id, product_id] = decodePath(series_id);\n const [instType, instId] = decodePath(product_id);\n\n if (instType !== 'PERPETUAL') {\n return;\n }\n\n let currentStart = start;\n\n while (currentStart <= end) {\n const res = await getFApiV1FundingRate({\n symbol: instId,\n startTime: currentStart,\n endTime: end,\n limit: 1000,\n });\n\n if (!Array.isArray(res) || res.length === 0) {\n break;\n }\n\n const filtered = res.filter((item) => item.fundingTime >= currentStart && item.fundingTime <= end);\n\n if (filtered.length === 0) {\n const lastRecord = res[res.length - 1];\n const nextStart = lastRecord.fundingTime + 1;\n if (nextStart <= currentStart) {\n break;\n }\n currentStart = nextStart;\n await firstValueFrom(timer(1000));\n continue;\n }\n\n const data = filtered.map((item): IInterestRate => {\n const rate = Number(item.fundingRate);\n return {\n series_id,\n product_id,\n datasource_id,\n created_at: formatTime(item.fundingTime),\n long_rate: `${-rate}`,\n short_rate: `${rate}`,\n settlement_price: '',\n };\n });\n\n yield data;\n\n const lastTime = filtered[filtered.length - 1].fundingTime;\n if (lastTime >= end) {\n break;\n }\n\n currentStart = lastTime + 1;\n\n if (res.length < 1000) {\n break;\n }\n\n await firstValueFrom(timer(1000));\n }\n },\n});\n"]}
@@ -1,38 +0,0 @@
1
- import { Terminal } from '@yuants/protocol';
2
- import { roundToStep } from '@yuants/utils';
3
- import { SPOT_ACCOUNT_ID } from './account-spot';
4
- import { getApiV1TickerPrice, postApiV1Order } from './sapi';
5
- Terminal.fromNodeEnv().server.provideService('SubmitOrder', { required: ['account_id'], properties: { account_id: { type: 'string', const: SPOT_ACCOUNT_ID } } }, async (msg) => {
6
- var _a;
7
- const order = msg.req;
8
- const symbol = order.product_id;
9
- const type = { MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' }[order.order_type];
10
- if (!type)
11
- throw new Error(`Unsupported order_type: ${order.order_type}`);
12
- const side = { OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' }[order.order_direction];
13
- if (!side)
14
- throw new Error(`Unsupported order_direction: ${order.order_direction}`);
15
- const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;
16
- const price = order.price;
17
- let quantity = order.volume;
18
- let quoteOrderQty;
19
- if (type === 'MARKET' && side === 'BUY') {
20
- const spotPrice = await getApiV1TickerPrice({});
21
- const thePrice = (_a = spotPrice.find((x) => x.symbol === symbol)) === null || _a === void 0 ? void 0 : _a.price;
22
- if (!thePrice)
23
- throw new Error(`Cannot get price for symbol ${symbol}`);
24
- quantity = undefined;
25
- quoteOrderQty = roundToStep(order.volume * +thePrice, 0.01);
26
- }
27
- await postApiV1Order({
28
- symbol,
29
- type,
30
- side,
31
- timeInForce,
32
- price,
33
- quantity,
34
- quoteOrderQty,
35
- });
36
- return { res: { code: 0, message: 'OK' } };
37
- });
38
- //# sourceMappingURL=order-spot.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"order-spot.js","sourceRoot":"","sources":["../src/order-spot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7D,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,cAAc,CAC1C,aAAa,EACb,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,EAAE,EACpG,KAAK,EAAE,GAAG,EAAE,EAAE;;IACZ,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC;IACtB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC;IAEhC,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,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,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,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAE1B,IAAI,QAAQ,GAAuB,KAAK,CAAC,MAAM,CAAC;IAChD,IAAI,aAAiC,CAAC;IAEtC,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,KAAK,EAAE;QACvC,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,EAAE,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,MAAA,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,0CAAE,KAAK,CAAC;QACnE,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,EAAE,CAAC,CAAC;QACxE,QAAQ,GAAG,SAAS,CAAC;QACrB,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;KAC7D;IAED,MAAM,cAAc,CAAC;QACnB,MAAM;QACN,IAAI;QACJ,IAAI;QACJ,WAAW;QACX,KAAK;QACL,QAAQ;QACR,aAAa;KACd,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;AAC7C,CAAC,CACF,CAAC","sourcesContent":["import { IOrder } from '@yuants/data-order';\nimport { Terminal } from '@yuants/protocol';\nimport { roundToStep } from '@yuants/utils';\nimport { SPOT_ACCOUNT_ID } from './account-spot';\nimport { getApiV1TickerPrice, postApiV1Order } from './sapi';\n\nTerminal.fromNodeEnv().server.provideService<IOrder>(\n 'SubmitOrder',\n { required: ['account_id'], properties: { account_id: { type: 'string', const: SPOT_ACCOUNT_ID } } },\n async (msg) => {\n const order = msg.req;\n const symbol = order.product_id;\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 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 timeInForce =\n order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n\n const price = order.price;\n\n let quantity: number | undefined = order.volume;\n let quoteOrderQty: number | undefined;\n\n if (type === 'MARKET' && side === 'BUY') {\n const spotPrice = await getApiV1TickerPrice({});\n const thePrice = spotPrice.find((x) => x.symbol === symbol)?.price;\n if (!thePrice) throw new Error(`Cannot get price for symbol ${symbol}`);\n quantity = undefined;\n quoteOrderQty = roundToStep(order.volume * +thePrice, 0.01);\n }\n\n await postApiV1Order({\n symbol,\n type,\n side,\n timeInForce,\n price,\n quantity,\n quoteOrderQty,\n });\n\n return { res: { code: 0, message: 'OK' } };\n },\n);\n"]}
package/dist/order.js DELETED
@@ -1,70 +0,0 @@
1
- import { Terminal } from '@yuants/protocol';
2
- import { decodePath } from '@yuants/utils';
3
- import { ACCOUNT_ID } from './account';
4
- import { deleteFApiV1Order, postFApiV1Order } from './api';
5
- const terminal = Terminal.fromNodeEnv();
6
- terminal.server.provideService('SubmitOrder', { required: ['account_id'], properties: { account_id: { type: 'string', const: ACCOUNT_ID } } }, async (msg) => {
7
- var _a, _b, _c, _d, _e;
8
- const order = msg.req;
9
- const [, decodedSymbol] = decodePath(order.product_id);
10
- if (!decodedSymbol) {
11
- throw new Error(`Invalid product_id: unable to decode symbol from "${order.product_id}"`);
12
- }
13
- const symbol = decodedSymbol;
14
- const side = { OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' }[order.order_direction];
15
- if (!side)
16
- throw new Error(`Unsupported order_direction: ${order.order_direction}`);
17
- const type = { MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' }[order.order_type];
18
- if (!type)
19
- throw new Error(`Unsupported order_type: ${order.order_type}`);
20
- const quantity = order.volume;
21
- const price = order.price;
22
- const positionSide = order.order_direction === 'OPEN_LONG' || order.order_direction === 'CLOSE_LONG'
23
- ? 'LONG'
24
- : order.order_direction === 'OPEN_SHORT' || order.order_direction === 'CLOSE_SHORT'
25
- ? 'SHORT'
26
- : undefined;
27
- const reduceOnly = order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT' ? 'true' : undefined;
28
- const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;
29
- const res = await postFApiV1Order({
30
- symbol,
31
- side,
32
- type,
33
- quantity,
34
- price,
35
- timeInForce,
36
- positionSide,
37
- reduceOnly,
38
- });
39
- const orderId = (_d = (_b = (_a = res === null || res === void 0 ? void 0 : res.orderId) !== null && _a !== void 0 ? _a : res === null || res === void 0 ? void 0 : res.order_id) !== null && _b !== void 0 ? _b : (_c = res === null || res === void 0 ? void 0 : res.data) === null || _c === void 0 ? void 0 : _c.orderId) !== null && _d !== void 0 ? _d : (_e = res === null || res === void 0 ? void 0 : res.data) === null || _e === void 0 ? void 0 : _e.order_id;
40
- return {
41
- res: {
42
- code: 0,
43
- message: 'OK',
44
- data: orderId ? { order_id: `${orderId}` } : undefined,
45
- },
46
- };
47
- });
48
- terminal.server.provideService('CancelOrder', {
49
- required: ['account_id', 'order_id', 'product_id'],
50
- properties: {
51
- account_id: { type: 'string', const: ACCOUNT_ID },
52
- order_id: { type: ['string', 'number'] },
53
- product_id: { type: 'string' },
54
- },
55
- }, async (msg) => {
56
- const order = msg.req;
57
- const [, decodedSymbol] = decodePath(order.product_id);
58
- if (!decodedSymbol) {
59
- throw new Error(`Invalid product_id: unable to decode symbol from "${order.product_id}"`);
60
- }
61
- if (!order.order_id) {
62
- throw new Error('order_id is required for CancelOrder');
63
- }
64
- await deleteFApiV1Order({
65
- symbol: decodedSymbol,
66
- orderId: order.order_id,
67
- });
68
- return { res: { code: 0, message: 'OK' } };
69
- });
70
- //# sourceMappingURL=order.js.map
package/dist/order.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"order.js","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":"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","sourcesContent":["import { Terminal } from '@yuants/protocol';\nimport { IOrder } from '@yuants/data-order';\nimport { decodePath } from '@yuants/utils';\nimport { ACCOUNT_ID } from './account';\nimport { deleteFApiV1Order, postFApiV1Order } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<IOrder, { order_id?: string }>(\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 [, decodedSymbol] = decodePath(order.product_id);\n if (!decodedSymbol) {\n throw new Error(`Invalid product_id: unable to decode symbol from \"${order.product_id}\"`);\n }\n const symbol = decodedSymbol;\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 positionSide =\n order.order_direction === 'OPEN_LONG' || order.order_direction === 'CLOSE_LONG'\n ? 'LONG'\n : order.order_direction === 'OPEN_SHORT' || order.order_direction === 'CLOSE_SHORT'\n ? 'SHORT'\n : undefined;\n\n const reduceOnly =\n order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT' ? 'true' : undefined;\n\n const timeInForce =\n order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n\n const res = await postFApiV1Order({\n symbol,\n side,\n type,\n quantity,\n price,\n timeInForce,\n positionSide,\n reduceOnly,\n });\n\n const orderId =\n (res as any)?.orderId ??\n (res as any)?.order_id ??\n (res as any)?.data?.orderId ??\n (res as any)?.data?.order_id;\n\n return {\n res: {\n code: 0,\n message: 'OK',\n data: orderId ? { order_id: `${orderId}` } : undefined,\n },\n };\n },\n);\n\nterminal.server.provideService<IOrder>(\n 'CancelOrder',\n {\n required: ['account_id', 'order_id', 'product_id'],\n properties: {\n account_id: { type: 'string', const: ACCOUNT_ID },\n order_id: { type: ['string', 'number'] },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const order = msg.req;\n const [, decodedSymbol] = decodePath(order.product_id);\n if (!decodedSymbol) {\n throw new Error(`Invalid product_id: unable to decode symbol from \"${order.product_id}\"`);\n }\n if (!order.order_id) {\n throw new Error('order_id is required for CancelOrder');\n }\n\n await deleteFApiV1Order({\n symbol: decodedSymbol,\n orderId: order.order_id,\n });\n\n return { res: { code: 0, message: 'OK' } };\n },\n);\n"]}
@@ -1,43 +0,0 @@
1
- import { providePendingOrdersService } from '@yuants/data-order';
2
- import { Terminal } from '@yuants/protocol';
3
- import { encodePath } from '@yuants/utils';
4
- import { ACCOUNT_ID } from './account';
5
- import { getFApiV1OpenOrders } from './api';
6
- const terminal = Terminal.fromNodeEnv();
7
- const resolveOrderDirection = (asterOrder) => {
8
- const reduceOnly = asterOrder.reduceOnly || asterOrder.closePosition;
9
- if (asterOrder.positionSide === 'LONG') {
10
- return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'CLOSE_LONG';
11
- }
12
- if (asterOrder.positionSide === 'SHORT') {
13
- return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'OPEN_SHORT';
14
- }
15
- if (reduceOnly) {
16
- return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'CLOSE_LONG';
17
- }
18
- return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'OPEN_SHORT';
19
- };
20
- providePendingOrdersService(terminal, ACCOUNT_ID, async () => {
21
- const orders = (await getFApiV1OpenOrders({}));
22
- return orders.map((order) => {
23
- const volume = Number(order.origQty);
24
- const tradedVolume = Number(order.executedQty);
25
- const price = Number(order.price);
26
- const avgPrice = Number(order.avgPrice);
27
- const mapped = {
28
- order_id: `${order.orderId}`,
29
- account_id: ACCOUNT_ID,
30
- product_id: encodePath('PERPETUAL', order.symbol),
31
- order_type: order.type,
32
- order_direction: resolveOrderDirection(order),
33
- volume: Number.isFinite(volume) ? volume : 0,
34
- price: Number.isFinite(price) ? price : undefined,
35
- submit_at: order.updateTime,
36
- traded_volume: Number.isFinite(tradedVolume) ? tradedVolume : undefined,
37
- traded_price: Number.isFinite(avgPrice) && avgPrice > 0 ? avgPrice : undefined,
38
- order_status: order.status,
39
- };
40
- return mapped;
41
- });
42
- }, { auto_refresh_interval: 2000 });
43
- //# sourceMappingURL=pending-orders.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pending-orders.js","sourceRoot":"","sources":["../src/pending-orders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAE5C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAoBxC,MAAM,qBAAqB,GAAG,CAAC,UAA2B,EAAkB,EAAE;IAC5E,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,IAAI,UAAU,CAAC,aAAa,CAAC;IAErE,IAAI,UAAU,CAAC,YAAY,KAAK,MAAM,EAAE;QACtC,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;KAC/D;IACD,IAAI,UAAU,CAAC,YAAY,KAAK,OAAO,EAAE;QACvC,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC;KACjE;IACD,IAAI,UAAU,EAAE;QACd,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC;KACjE;IACD,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;AAChE,CAAC,CAAC;AAEF,2BAA2B,CACzB,QAAQ,EACR,UAAU,EACV,KAAK,IAAI,EAAE;IACT,MAAM,MAAM,GAAG,CAAC,MAAM,mBAAmB,CAAC,EAAE,CAAC,CAAsB,CAAC;IACpE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAExC,MAAM,MAAM,GAAW;YACrB,QAAQ,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE;YAC5B,UAAU,EAAE,UAAU;YACtB,UAAU,EAAE,UAAU,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC;YACjD,UAAU,EAAE,KAAK,CAAC,IAAI;YACtB,eAAe,EAAE,qBAAqB,CAAC,KAAK,CAAC;YAC7C,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC5C,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;YACjD,SAAS,EAAE,KAAK,CAAC,UAAU;YAC3B,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;YACvE,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YAC9E,YAAY,EAAE,KAAK,CAAC,MAAM;SAC3B,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,EACD,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAChC,CAAC","sourcesContent":["import { IOrder, providePendingOrdersService } from '@yuants/data-order';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { ACCOUNT_ID } from './account';\nimport { getFApiV1OpenOrders } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\ntype OrderDirection = 'OPEN_LONG' | 'OPEN_SHORT' | 'CLOSE_LONG' | 'CLOSE_SHORT';\n\ninterface IAsterOpenOrder {\n orderId: number;\n symbol: string;\n side: 'BUY' | 'SELL';\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n reduceOnly?: boolean;\n closePosition?: boolean;\n type: string;\n origQty: string;\n executedQty: string;\n price: string;\n avgPrice: string;\n status: string;\n updateTime: number;\n}\n\nconst resolveOrderDirection = (asterOrder: IAsterOpenOrder): OrderDirection => {\n const reduceOnly = asterOrder.reduceOnly || asterOrder.closePosition;\n\n if (asterOrder.positionSide === 'LONG') {\n return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'CLOSE_LONG';\n }\n if (asterOrder.positionSide === 'SHORT') {\n return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'OPEN_SHORT';\n }\n if (reduceOnly) {\n return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'CLOSE_LONG';\n }\n return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'OPEN_SHORT';\n};\n\nprovidePendingOrdersService(\n terminal,\n ACCOUNT_ID,\n async () => {\n const orders = (await getFApiV1OpenOrders({})) as IAsterOpenOrder[];\n return orders.map((order) => {\n const volume = Number(order.origQty);\n const tradedVolume = Number(order.executedQty);\n const price = Number(order.price);\n const avgPrice = Number(order.avgPrice);\n\n const mapped: IOrder = {\n order_id: `${order.orderId}`,\n account_id: ACCOUNT_ID,\n product_id: encodePath('PERPETUAL', order.symbol),\n order_type: order.type,\n order_direction: resolveOrderDirection(order),\n volume: Number.isFinite(volume) ? volume : 0,\n price: Number.isFinite(price) ? price : undefined,\n submit_at: order.updateTime,\n traded_volume: Number.isFinite(tradedVolume) ? tradedVolume : undefined,\n traded_price: Number.isFinite(avgPrice) && avgPrice > 0 ? avgPrice : undefined,\n order_status: order.status,\n };\n\n return mapped;\n });\n },\n { auto_refresh_interval: 2000 },\n);\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"product.js","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACpG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAE9C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,cAAc,GAAG,2BAA2B,CACvD,QAAQ,EACR,OAAO,EACP,KAAK,EAAE,GAA0B,EAAuB,EAAE;IACxD,qCAAqC;IACrC,MAAM,YAAY,GAAG,MAAM,qBAAqB,CAAC,EAAE,CAAC,CAAC;IAErD,qCAAqC;IACrC,OAAO,YAAY,CAAC,OAAO;SACxB,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,sCAAsC;SACtF,GAAG,CAAC,CAAC,MAAM,EAAY,EAAE;QACxB,mCAAmC;QACnC,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,KAAK,cAAc,CAAC,CAAC;QAC1F,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;QAE7D,uCAAuC;QACvC,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;QACxF,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAEtG,OAAO;YACL,aAAa,EAAE,OAAO;YACtB,UAAU,EAAE,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC;YAClD,IAAI,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,OAAO;YACrD,cAAc,EAAE,MAAM,CAAC,UAAU;YACjC,aAAa,EAAE,MAAM,CAAC,SAAS;YAC/B,gBAAgB,EAAE,EAAE;YACpB,gBAAgB,EAAE,CAAC;YACnB,iBAAiB,EAAE,CAAC;YACpB,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,SAAS;YACrB,WAAW,EAAE,UAAU;YACvB,WAAW,EAAE,CAAC;YACd,UAAU,EAAE,IAAI;YAChB,WAAW,EAAE,IAAI;YACjB,WAAW,EAAE,GAAG;YAChB,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,iBAAiB;YAC5B,gBAAgB,EAAE,KAAK;SACxB,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC,EACD;IACE,qBAAqB,EAAE,OAAQ,EAAE,iBAAiB;CACnD,CACF,CAAC","sourcesContent":["import { IProduct, IQueryProductsRequest, provideQueryProductsService } from '@yuants/data-product';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { getFApiV1ExchangeInfo } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\n// Provide QueryProducts service for ASTER\nexport const productService = provideQueryProductsService(\n terminal,\n 'ASTER',\n async (req: IQueryProductsRequest): Promise<IProduct[]> => {\n // Fetch exchange info from ASTER API\n const exchangeInfo = await getFApiV1ExchangeInfo({});\n\n // Convert symbols to IProduct format\n return exchangeInfo.symbols\n .filter((symbol) => symbol.status === 'TRADING') // Only include active trading symbols\n .map((symbol): IProduct => {\n // Find price filter for price step\n const priceFilter = symbol.filters.find((filter) => filter.filterType === 'PRICE_FILTER');\n const priceStep = priceFilter ? +priceFilter.tickSize : 1e-2;\n\n // Find lot size filter for volume step\n const lotSizeFilter = symbol.filters.find((filter) => filter.filterType === 'LOT_SIZE');\n const volumeStep = lotSizeFilter ? +lotSizeFilter.stepSize : Number(`1e-${symbol.quantityPrecision}`);\n\n return {\n datasource_id: 'ASTER',\n product_id: encodePath('PERPETUAL', symbol.symbol),\n name: `${symbol.baseAsset}/${symbol.quoteAsset} PERP`,\n quote_currency: symbol.quoteAsset,\n base_currency: symbol.baseAsset,\n value_scale_unit: '',\n value_based_cost: 0,\n volume_based_cost: 0,\n max_volume: 0,\n price_step: priceStep,\n volume_step: volumeStep,\n value_scale: 1,\n allow_long: true,\n allow_short: true,\n margin_rate: 0.1, // Default margin rate, can be adjusted based on actual requirements\n max_position: 0,\n market_id: 'ASTER/PERPETUAL',\n no_interest_rate: false,\n };\n });\n },\n {\n auto_refresh_interval: 3600_000, // Refresh hourly\n },\n);\n"]}