@yuants/vendor-aster 0.7.20 → 0.7.22

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.
@@ -1,9 +1,8 @@
1
- const BASE_URL = 'https://fapi.asterdex.com';
2
1
  import { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';
3
2
  const MetricsAsterApiCallCounter = GlobalPrometheusRegistry.counter('aster_api_call', 'Number of aster api call');
4
3
  const terminal = Terminal.fromNodeEnv();
5
- const request = async (method, endpoint, params = {}) => {
6
- const url = new URL(BASE_URL);
4
+ const request = async (method, baseUrl, endpoint, params = {}) => {
5
+ const url = new URL(baseUrl);
7
6
  url.pathname = endpoint;
8
7
  for (const [key, value] of Object.entries(params)) {
9
8
  if (value === undefined)
@@ -20,34 +19,42 @@ const request = async (method, endpoint, params = {}) => {
20
19
  }
21
20
  return res;
22
21
  };
23
- const createApi = (method, endpoint) => (params) => request(method, endpoint, params);
22
+ const createApi = (baseUrl) => (method, endpoint) => (params) => request(method, baseUrl, endpoint, params);
23
+ const createFutureApi = createApi('https://fapi.asterdex.com');
24
+ const createSpotApi = createApi('https://sapi.asterdex.com');
24
25
  /**
25
26
  * 获取资金费率历史
26
27
  *
27
28
  * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9F%A5%E8%AF%A2%E8%B5%84%E9%87%91%E8%B4%B9%E7%8E%87%E5%8E%86%E5%8F%B2
28
29
  */
29
- export const getFApiV1FundingRate = createApi('GET', '/fapi/v1/fundingRate');
30
+ export const getFApiV1FundingRate = createFutureApi('GET', '/fapi/v1/fundingRate');
30
31
  /**
31
32
  * 获取交易对信息
32
33
  *
33
34
  * 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
34
35
  */
35
- export const getFApiV1ExchangeInfo = createApi('GET', '/fapi/v1/exchangeInfo');
36
+ export const getFApiV1ExchangeInfo = createFutureApi('GET', '/fapi/v1/exchangeInfo');
37
+ /**
38
+ * 获取现货交易对信息
39
+ *
40
+ * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1080-L1145
41
+ */
42
+ export const getApiV1ExchangeInfo = createSpotApi('GET', '/api/v1/exchangeInfo');
36
43
  /**
37
44
  * 获取未平仓合约数量
38
45
  *
39
46
  * 无 API 文档 (weird)
40
47
  */
41
- export const getFApiV1OpenInterest = createApi('GET', '/fapi/v1/openInterest');
48
+ export const getFApiV1OpenInterest = createFutureApi('GET', '/fapi/v1/openInterest');
42
49
  /**
43
50
  * 获取最新价格
44
51
  *
45
52
  * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC
46
53
  */
47
- export const getFApiV1TickerPrice = createApi('GET', '/fapi/v1/ticker/price');
54
+ export const getFApiV1TickerPrice = createFutureApi('GET', '/fapi/v1/ticker/price');
48
55
  /**
49
56
  * 获取资金费率
50
57
  * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md
51
58
  */
52
- export const getFApiV1PremiumIndex = createApi('GET', '/fapi/v1/premiumIndex');
59
+ export const getFApiV1PremiumIndex = createFutureApi('GET', '/fapi/v1/premiumIndex');
53
60
  //# sourceMappingURL=public-api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../src/api/public-api.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAC7C,OAAO,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEtE,MAAM,0BAA0B,GAAG,wBAAwB,CAAC,OAAO,CACjE,gBAAgB,EAChB,0BAA0B,CAC3B,CAAC;AACF,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AACxC,MAAM,OAAO,GAAG,KAAK,EAAK,MAAc,EAAE,QAAgB,EAAE,SAAc,EAAE,EAAc,EAAE;IAC1F,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,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7B,0BAA0B,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IACnG,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;QACtC,MAAM;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,CAAa,MAAc,EAAE,QAAgB,EAAE,EAAE,CACjD,CAAC,MAAY,EAAE,EAAE,CACf,OAAO,CAAO,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAE5C;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAY3C,KAAK,EAAE,sBAAsB,CAAC,CAAC;AA2BjC;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAAyB,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAEvG;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAS5C,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAElC;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAO3C,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAElC;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAwB5C,KAAK,EAAE,uBAAuB,CAAC,CAAC","sourcesContent":["const BASE_URL = 'https://fapi.asterdex.com';\nimport { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';\n\nconst MetricsAsterApiCallCounter = GlobalPrometheusRegistry.counter(\n 'aster_api_call',\n 'Number of aster api call',\n);\nconst terminal = Terminal.fromNodeEnv();\nconst request = async <T>(method: string, endpoint: string, params: any = {}): Promise<T> => {\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 console.info(url.toString());\n MetricsAsterApiCallCounter.labels({ path: url.pathname, terminal_id: terminal.terminal_id }).inc();\n const res = await fetch(url.toString(), {\n method,\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>(method: string, endpoint: string) =>\n (params: TReq) =>\n request<TRes>(method, endpoint, params);\n\n/**\n * 获取资金费率历史\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9F%A5%E8%AF%A2%E8%B5%84%E9%87%91%E8%B4%B9%E7%8E%87%E5%8E%86%E5%8F%B2\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>('GET', '/fapi/v1/fundingRate');\n\nexport interface IAsterRateLimit {\n rateLimitType?: string;\n interval?: string;\n intervalNum?: number;\n limit?: number;\n}\n\nexport interface IAsterExchangeInfo {\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 rateLimits?: IAsterRateLimit[];\n}\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<{}, IAsterExchangeInfo>('GET', '/fapi/v1/exchangeInfo');\n\n/**\n * 获取未平仓合约数量\n *\n * 无 API 文档 (weird)\n */\nexport const getFApiV1OpenInterest = createApi<\n {\n symbol: string;\n },\n {\n symbol: string;\n openInterest: string;\n time: number;\n }\n>('GET', '/fapi/v1/openInterest');\n\n/**\n * 获取最新价格\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC\n */\nexport const getFApiV1TickerPrice = createApi<\n {},\n {\n symbol: string;\n price: string;\n time?: number;\n }[]\n>('GET', '/fapi/v1/ticker/price');\n\n/**\n * 获取资金费率\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md\n */\nexport const getFApiV1PremiumIndex = createApi<\n {\n symbol?: string;\n },\n | {\n symbol: string; // 交易对\n markPrice: string; // 标记价格\n indexPrice: string; // 指数价格\n estimatedSettlePrice: string; // 预估结算价,仅在交割开始前最后一小时有意义\n lastFundingRate: string; // 最近更新的资金费率\n nextFundingTime: number; // 下次资金费时间\n interestRate: string; // 标的资产基础利率\n time: number; // 更新时间\n }\n | {\n symbol: string; // 交易对\n markPrice: string; // 标记价格\n indexPrice: string; // 指数价格\n estimatedSettlePrice: string; // 预估结算价,仅在交割开始前最后一小时有意义\n lastFundingRate: string; // 最近更新的资金费率\n nextFundingTime: number; // 下次资金费时间\n interestRate: string; // 标的资产基础利率\n time: number; // 更新时间\n }[]\n>('GET', '/fapi/v1/premiumIndex');\n"]}
1
+ {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../src/api/public-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEtE,MAAM,0BAA0B,GAAG,wBAAwB,CAAC,OAAO,CACjE,gBAAgB,EAChB,0BAA0B,CAC3B,CAAC;AACF,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AACxC,MAAM,OAAO,GAAG,KAAK,EACnB,MAAc,EACd,OAAe,EACf,QAAgB,EAChB,SAAc,EAAE,EACJ,EAAE;IACd,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,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,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7B,0BAA0B,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IACnG,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;QACtC,MAAM;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,CAAC,OAAe,EAAE,EAAE,CACpB,CAAa,MAAc,EAAE,QAAgB,EAAE,EAAE,CACjD,CAAC,MAAY,EAAE,EAAE,CACf,OAAO,CAAO,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAErD,MAAM,eAAe,GAAG,SAAS,CAAC,2BAA2B,CAAC,CAAC;AAC/D,MAAM,aAAa,GAAG,SAAS,CAAC,2BAA2B,CAAC,CAAC;AAE7D;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAYjD,KAAK,EAAE,sBAAsB,CAAC,CAAC;AA2BjC;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,eAAe,CAAyB,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAE7G;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAyB,KAAK,EAAE,sBAAsB,CAAC,CAAC;AAEzG;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,eAAe,CASlD,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAElC;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAOjD,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAElC;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,eAAe,CAwBlD,KAAK,EAAE,uBAAuB,CAAC,CAAC","sourcesContent":["import { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';\n\nconst MetricsAsterApiCallCounter = GlobalPrometheusRegistry.counter(\n 'aster_api_call',\n 'Number of aster api call',\n);\nconst terminal = Terminal.fromNodeEnv();\nconst request = async <T>(\n method: string,\n baseUrl: string,\n endpoint: string,\n params: any = {},\n): Promise<T> => {\n const url = new URL(baseUrl);\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 console.info(url.toString());\n MetricsAsterApiCallCounter.labels({ path: url.pathname, terminal_id: terminal.terminal_id }).inc();\n const res = await fetch(url.toString(), {\n method,\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 (baseUrl: string) =>\n <TReq, TRes>(method: string, endpoint: string) =>\n (params: TReq) =>\n request<TRes>(method, baseUrl, endpoint, params);\n\nconst createFutureApi = createApi('https://fapi.asterdex.com');\nconst createSpotApi = createApi('https://sapi.asterdex.com');\n\n/**\n * 获取资金费率历史\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9F%A5%E8%AF%A2%E8%B5%84%E9%87%91%E8%B4%B9%E7%8E%87%E5%8E%86%E5%8F%B2\n */\nexport const getFApiV1FundingRate = createFutureApi<\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>('GET', '/fapi/v1/fundingRate');\n\nexport interface IAsterRateLimit {\n rateLimitType?: string;\n interval?: string;\n intervalNum?: number;\n limit?: number;\n}\n\nexport interface IAsterExchangeInfo {\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 rateLimits?: IAsterRateLimit[];\n}\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 = createFutureApi<{}, IAsterExchangeInfo>('GET', '/fapi/v1/exchangeInfo');\n\n/**\n * 获取现货交易对信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1080-L1145\n */\nexport const getApiV1ExchangeInfo = createSpotApi<{}, IAsterExchangeInfo>('GET', '/api/v1/exchangeInfo');\n\n/**\n * 获取未平仓合约数量\n *\n * 无 API 文档 (weird)\n */\nexport const getFApiV1OpenInterest = createFutureApi<\n {\n symbol: string;\n },\n {\n symbol: string;\n openInterest: string;\n time: number;\n }\n>('GET', '/fapi/v1/openInterest');\n\n/**\n * 获取最新价格\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC\n */\nexport const getFApiV1TickerPrice = createFutureApi<\n {},\n {\n symbol: string;\n price: string;\n time?: number;\n }[]\n>('GET', '/fapi/v1/ticker/price');\n\n/**\n * 获取资金费率\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md\n */\nexport const getFApiV1PremiumIndex = createFutureApi<\n {\n symbol?: string;\n },\n | {\n symbol: string; // 交易对\n markPrice: string; // 标记价格\n indexPrice: string; // 指数价格\n estimatedSettlePrice: string; // 预估结算价,仅在交割开始前最后一小时有意义\n lastFundingRate: string; // 最近更新的资金费率\n nextFundingTime: number; // 下次资金费时间\n interestRate: string; // 标的资产基础利率\n time: number; // 更新时间\n }\n | {\n symbol: string; // 交易对\n markPrice: string; // 标记价格\n indexPrice: string; // 指数价格\n estimatedSettlePrice: string; // 预估结算价,仅在交割开始前最后一小时有意义\n lastFundingRate: string; // 最近更新的资金费率\n nextFundingTime: number; // 下次资金费时间\n interestRate: string; // 标的资产基础利率\n time: number; // 更新时间\n }[]\n>('GET', '/fapi/v1/premiumIndex');\n"]}
@@ -1,40 +1,62 @@
1
- import { Terminal } from '@yuants/protocol';
2
1
  import { encodePath } from '@yuants/utils';
3
- import { getFApiV1ExchangeInfo } from '../../api/public-api';
4
- const terminal = Terminal.fromNodeEnv();
2
+ import { getApiV1ExchangeInfo, getFApiV1ExchangeInfo } from '../../api/public-api';
5
3
  export const listProducts = async () => {
6
- // Fetch exchange info from ASTER API
7
- const exchangeInfo = await getFApiV1ExchangeInfo({});
8
- // Convert symbols to IProduct format
9
- return exchangeInfo.symbols
10
- .filter((symbol) => symbol.status === 'TRADING') // Only include active trading symbols
11
- .map((symbol) => {
12
- // Find price filter for price step
4
+ const [perpExchangeInfo, spotExchangeInfo] = await Promise.all([
5
+ getFApiV1ExchangeInfo({}),
6
+ getApiV1ExchangeInfo({}),
7
+ ]);
8
+ const pickPriceStep = (symbol) => {
13
9
  const priceFilter = symbol.filters.find((filter) => filter.filterType === 'PRICE_FILTER');
14
- const priceStep = priceFilter ? +priceFilter.tickSize : 1e-2;
15
- // Find lot size filter for volume step
10
+ return priceFilter ? +priceFilter.tickSize : Number(`1e-${symbol.pricePrecision}`);
11
+ };
12
+ const pickVolumeStep = (symbol) => {
16
13
  const lotSizeFilter = symbol.filters.find((filter) => filter.filterType === 'LOT_SIZE');
17
- const volumeStep = lotSizeFilter ? +lotSizeFilter.stepSize : Number(`1e-${symbol.quantityPrecision}`);
18
- return {
19
- datasource_id: 'ASTER',
20
- product_id: encodePath('ASTER', 'PERP', symbol.symbol),
21
- name: `${symbol.baseAsset}/${symbol.quoteAsset} PERP`,
22
- quote_currency: symbol.quoteAsset,
23
- base_currency: symbol.baseAsset,
24
- value_scale_unit: '',
25
- value_based_cost: 0,
26
- volume_based_cost: 0,
27
- max_volume: 0,
28
- price_step: priceStep,
29
- volume_step: volumeStep,
30
- value_scale: 1,
31
- allow_long: true,
32
- allow_short: true,
33
- margin_rate: 0.1,
34
- max_position: 0,
35
- market_id: 'ASTER/PERPETUAL',
36
- no_interest_rate: false,
37
- };
38
- });
14
+ return lotSizeFilter ? +lotSizeFilter.stepSize : Number(`1e-${symbol.quantityPrecision}`);
15
+ };
16
+ const perpProducts = perpExchangeInfo.symbols
17
+ .filter((symbol) => symbol.status === 'TRADING')
18
+ .map((symbol) => ({
19
+ datasource_id: 'ASTER',
20
+ product_id: encodePath('ASTER', 'PERP', symbol.symbol),
21
+ name: `${symbol.baseAsset}/${symbol.quoteAsset} PERP`,
22
+ quote_currency: symbol.quoteAsset,
23
+ base_currency: symbol.baseAsset,
24
+ value_scale_unit: '',
25
+ value_based_cost: 0,
26
+ volume_based_cost: 0,
27
+ max_volume: 0,
28
+ price_step: pickPriceStep(symbol),
29
+ volume_step: pickVolumeStep(symbol),
30
+ value_scale: 1,
31
+ allow_long: true,
32
+ allow_short: true,
33
+ margin_rate: 0.1,
34
+ max_position: 0,
35
+ market_id: 'ASTER/PERPETUAL',
36
+ no_interest_rate: false,
37
+ }));
38
+ const spotProducts = spotExchangeInfo.symbols
39
+ .filter((symbol) => symbol.status === 'TRADING')
40
+ .map((symbol) => ({
41
+ datasource_id: 'ASTER',
42
+ product_id: encodePath('ASTER', 'SPOT', symbol.symbol),
43
+ name: `${symbol.baseAsset}/${symbol.quoteAsset} SPOT`,
44
+ quote_currency: symbol.quoteAsset,
45
+ base_currency: symbol.baseAsset,
46
+ value_scale_unit: '',
47
+ value_based_cost: 0,
48
+ volume_based_cost: 0,
49
+ max_volume: 0,
50
+ price_step: pickPriceStep(symbol),
51
+ volume_step: pickVolumeStep(symbol),
52
+ value_scale: 1,
53
+ allow_long: true,
54
+ allow_short: false,
55
+ margin_rate: 1,
56
+ max_position: 0,
57
+ market_id: 'ASTER/SPOT',
58
+ no_interest_rate: true,
59
+ }));
60
+ return [...perpProducts, ...spotProducts];
39
61
  };
40
62
  //# sourceMappingURL=product.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"product.js","sourceRoot":"","sources":["../../../src/services/markets/product.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,IAAyB,EAAE;IAC1D,qCAAqC;IACrC,MAAM,YAAY,GAAG,MAAM,qBAAqB,CAAC,EAAE,CAAC,CAAC;IACrD,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,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;YACtD,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,CAAC","sourcesContent":["import { IProduct } from '@yuants/data-product';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { getFApiV1ExchangeInfo } from '../../api/public-api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nexport const listProducts = async (): Promise<IProduct[]> => {\n // Fetch exchange info from ASTER API\n const exchangeInfo = await getFApiV1ExchangeInfo({});\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('ASTER', 'PERP', 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"]}
1
+ {"version":3,"file":"product.js","sourceRoot":"","sources":["../../../src/services/markets/product.ts"],"names":[],"mappings":"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","sourcesContent":["import { IProduct } from '@yuants/data-product';\nimport { encodePath } from '@yuants/utils';\nimport { getApiV1ExchangeInfo, getFApiV1ExchangeInfo } from '../../api/public-api';\n\nexport const listProducts = async (): Promise<IProduct[]> => {\n const [perpExchangeInfo, spotExchangeInfo] = await Promise.all([\n getFApiV1ExchangeInfo({}),\n getApiV1ExchangeInfo({}),\n ]);\n\n const pickPriceStep = (symbol: {\n filters: { filterType: string; tickSize?: string }[];\n pricePrecision: number;\n }) => {\n const priceFilter = symbol.filters.find((filter) => filter.filterType === 'PRICE_FILTER');\n return priceFilter ? +priceFilter.tickSize! : Number(`1e-${symbol.pricePrecision}`);\n };\n\n const pickVolumeStep = (symbol: {\n filters: { filterType: string; stepSize?: string }[];\n quantityPrecision: number;\n }) => {\n const lotSizeFilter = symbol.filters.find((filter) => filter.filterType === 'LOT_SIZE');\n return lotSizeFilter ? +lotSizeFilter.stepSize! : Number(`1e-${symbol.quantityPrecision}`);\n };\n\n const perpProducts: IProduct[] = perpExchangeInfo.symbols\n .filter((symbol) => symbol.status === 'TRADING')\n .map(\n (symbol): IProduct => ({\n datasource_id: 'ASTER',\n product_id: encodePath('ASTER', 'PERP', 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: pickPriceStep(symbol),\n volume_step: pickVolumeStep(symbol),\n value_scale: 1,\n allow_long: true,\n allow_short: true,\n margin_rate: 0.1,\n max_position: 0,\n market_id: 'ASTER/PERPETUAL',\n no_interest_rate: false,\n }),\n );\n\n const spotProducts: IProduct[] = spotExchangeInfo.symbols\n .filter((symbol) => symbol.status === 'TRADING')\n .map(\n (symbol): IProduct => ({\n datasource_id: 'ASTER',\n product_id: encodePath('ASTER', 'SPOT', symbol.symbol),\n name: `${symbol.baseAsset}/${symbol.quoteAsset} SPOT`,\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: pickPriceStep(symbol),\n volume_step: pickVolumeStep(symbol),\n value_scale: 1,\n allow_long: true,\n allow_short: false,\n margin_rate: 1,\n max_position: 0,\n market_id: 'ASTER/SPOT',\n no_interest_rate: true,\n }),\n );\n\n return [...perpProducts, ...spotProducts];\n};\n"]}
@@ -42,6 +42,12 @@ export interface IAsterExchangeInfo {
42
42
  * 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
43
43
  */
44
44
  export declare const getFApiV1ExchangeInfo: (params: {}) => Promise<IAsterExchangeInfo>;
45
+ /**
46
+ * 获取现货交易对信息
47
+ *
48
+ * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1080-L1145
49
+ */
50
+ export declare const getApiV1ExchangeInfo: (params: {}) => Promise<IAsterExchangeInfo>;
45
51
  /**
46
52
  * 获取未平仓合约数量
47
53
  *
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../../src/api/public-api.ts"],"names":[],"mappings":"AAgCA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;YAQrB,MAAM;iBACD,MAAM;iBACN,MAAM;IAES,CAAC;AAEjC,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;QACrC,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE;YACP,UAAU,EAAE,MAAM,CAAC;YACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;SACpB,EAAE,CAAC;KACL,EAAE,CAAC;IACJ,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,6CAAoE,CAAC;AAEvG;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;YAEtB,MAAM;;YAGN,MAAM;kBACA,MAAM;UACd,MAAM;EAEiB,CAAC;AAElC;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;YAGrB,MAAM;WACP,MAAM;;IAGgB,CAAC;AAElC;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;YAKpB,MAAM;eACH,MAAM;gBACL,MAAM;0BACI,MAAM;qBACX,MAAM;qBACN,MAAM;kBACT,MAAM;UACd,MAAM;;YAGJ,MAAM;eACH,MAAM;gBACL,MAAM;0BACI,MAAM;qBACX,MAAM;qBACN,MAAM;kBACT,MAAM;UACd,MAAM;IAEe,CAAC"}
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../../src/api/public-api.ts"],"names":[],"mappings":"AAwCA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;YAQrB,MAAM;iBACD,MAAM;iBACN,MAAM;IAES,CAAC;AAEjC,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;QACrC,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE;YACP,UAAU,EAAE,MAAM,CAAC;YACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;SACpB,EAAE,CAAC;KACL,EAAE,CAAC;IACJ,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,6CAA0E,CAAC;AAE7G;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,6CAAuE,CAAC;AAEzG;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;YAEtB,MAAM;;YAGN,MAAM;kBACA,MAAM;UACd,MAAM;EAEiB,CAAC;AAElC;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;YAGrB,MAAM;WACP,MAAM;;IAGgB,CAAC;AAElC;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;YAKpB,MAAM;eACH,MAAM;gBACL,MAAM;0BACI,MAAM;qBACX,MAAM;qBACN,MAAM;kBACT,MAAM;UACd,MAAM;;YAGJ,MAAM;eACH,MAAM;gBACL,MAAM;0BACI,MAAM;qBACX,MAAM;qBACN,MAAM;kBACT,MAAM;UACd,MAAM;IAEe,CAAC"}
@@ -1,12 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFApiV1PremiumIndex = exports.getFApiV1TickerPrice = exports.getFApiV1OpenInterest = exports.getFApiV1ExchangeInfo = exports.getFApiV1FundingRate = void 0;
4
- const BASE_URL = 'https://fapi.asterdex.com';
3
+ exports.getFApiV1PremiumIndex = exports.getFApiV1TickerPrice = exports.getFApiV1OpenInterest = exports.getApiV1ExchangeInfo = exports.getFApiV1ExchangeInfo = exports.getFApiV1FundingRate = void 0;
5
4
  const protocol_1 = require("@yuants/protocol");
6
5
  const MetricsAsterApiCallCounter = protocol_1.GlobalPrometheusRegistry.counter('aster_api_call', 'Number of aster api call');
7
6
  const terminal = protocol_1.Terminal.fromNodeEnv();
8
- const request = async (method, endpoint, params = {}) => {
9
- const url = new URL(BASE_URL);
7
+ const request = async (method, baseUrl, endpoint, params = {}) => {
8
+ const url = new URL(baseUrl);
10
9
  url.pathname = endpoint;
11
10
  for (const [key, value] of Object.entries(params)) {
12
11
  if (value === undefined)
@@ -23,34 +22,42 @@ const request = async (method, endpoint, params = {}) => {
23
22
  }
24
23
  return res;
25
24
  };
26
- const createApi = (method, endpoint) => (params) => request(method, endpoint, params);
25
+ const createApi = (baseUrl) => (method, endpoint) => (params) => request(method, baseUrl, endpoint, params);
26
+ const createFutureApi = createApi('https://fapi.asterdex.com');
27
+ const createSpotApi = createApi('https://sapi.asterdex.com');
27
28
  /**
28
29
  * 获取资金费率历史
29
30
  *
30
31
  * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9F%A5%E8%AF%A2%E8%B5%84%E9%87%91%E8%B4%B9%E7%8E%87%E5%8E%86%E5%8F%B2
31
32
  */
32
- exports.getFApiV1FundingRate = createApi('GET', '/fapi/v1/fundingRate');
33
+ exports.getFApiV1FundingRate = createFutureApi('GET', '/fapi/v1/fundingRate');
33
34
  /**
34
35
  * 获取交易对信息
35
36
  *
36
37
  * 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
37
38
  */
38
- exports.getFApiV1ExchangeInfo = createApi('GET', '/fapi/v1/exchangeInfo');
39
+ exports.getFApiV1ExchangeInfo = createFutureApi('GET', '/fapi/v1/exchangeInfo');
40
+ /**
41
+ * 获取现货交易对信息
42
+ *
43
+ * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1080-L1145
44
+ */
45
+ exports.getApiV1ExchangeInfo = createSpotApi('GET', '/api/v1/exchangeInfo');
39
46
  /**
40
47
  * 获取未平仓合约数量
41
48
  *
42
49
  * 无 API 文档 (weird)
43
50
  */
44
- exports.getFApiV1OpenInterest = createApi('GET', '/fapi/v1/openInterest');
51
+ exports.getFApiV1OpenInterest = createFutureApi('GET', '/fapi/v1/openInterest');
45
52
  /**
46
53
  * 获取最新价格
47
54
  *
48
55
  * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC
49
56
  */
50
- exports.getFApiV1TickerPrice = createApi('GET', '/fapi/v1/ticker/price');
57
+ exports.getFApiV1TickerPrice = createFutureApi('GET', '/fapi/v1/ticker/price');
51
58
  /**
52
59
  * 获取资金费率
53
60
  * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md
54
61
  */
55
- exports.getFApiV1PremiumIndex = createApi('GET', '/fapi/v1/premiumIndex');
62
+ exports.getFApiV1PremiumIndex = createFutureApi('GET', '/fapi/v1/premiumIndex');
56
63
  //# sourceMappingURL=public-api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../src/api/public-api.ts"],"names":[],"mappings":";;;AAAA,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAC7C,+CAAsE;AAEtE,MAAM,0BAA0B,GAAG,mCAAwB,CAAC,OAAO,CACjE,gBAAgB,EAChB,0BAA0B,CAC3B,CAAC;AACF,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AACxC,MAAM,OAAO,GAAG,KAAK,EAAK,MAAc,EAAE,QAAgB,EAAE,SAAc,EAAE,EAAc,EAAE;IAC1F,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,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7B,0BAA0B,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IACnG,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;QACtC,MAAM;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,CAAa,MAAc,EAAE,QAAgB,EAAE,EAAE,CACjD,CAAC,MAAY,EAAE,EAAE,CACf,OAAO,CAAO,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAE5C;;;;GAIG;AACU,QAAA,oBAAoB,GAAG,SAAS,CAY3C,KAAK,EAAE,sBAAsB,CAAC,CAAC;AA2BjC;;;;GAIG;AACU,QAAA,qBAAqB,GAAG,SAAS,CAAyB,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAEvG;;;;GAIG;AACU,QAAA,qBAAqB,GAAG,SAAS,CAS5C,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAElC;;;;GAIG;AACU,QAAA,oBAAoB,GAAG,SAAS,CAO3C,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAElC;;;GAGG;AACU,QAAA,qBAAqB,GAAG,SAAS,CAwB5C,KAAK,EAAE,uBAAuB,CAAC,CAAC","sourcesContent":["const BASE_URL = 'https://fapi.asterdex.com';\nimport { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';\n\nconst MetricsAsterApiCallCounter = GlobalPrometheusRegistry.counter(\n 'aster_api_call',\n 'Number of aster api call',\n);\nconst terminal = Terminal.fromNodeEnv();\nconst request = async <T>(method: string, endpoint: string, params: any = {}): Promise<T> => {\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 console.info(url.toString());\n MetricsAsterApiCallCounter.labels({ path: url.pathname, terminal_id: terminal.terminal_id }).inc();\n const res = await fetch(url.toString(), {\n method,\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>(method: string, endpoint: string) =>\n (params: TReq) =>\n request<TRes>(method, endpoint, params);\n\n/**\n * 获取资金费率历史\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9F%A5%E8%AF%A2%E8%B5%84%E9%87%91%E8%B4%B9%E7%8E%87%E5%8E%86%E5%8F%B2\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>('GET', '/fapi/v1/fundingRate');\n\nexport interface IAsterRateLimit {\n rateLimitType?: string;\n interval?: string;\n intervalNum?: number;\n limit?: number;\n}\n\nexport interface IAsterExchangeInfo {\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 rateLimits?: IAsterRateLimit[];\n}\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<{}, IAsterExchangeInfo>('GET', '/fapi/v1/exchangeInfo');\n\n/**\n * 获取未平仓合约数量\n *\n * 无 API 文档 (weird)\n */\nexport const getFApiV1OpenInterest = createApi<\n {\n symbol: string;\n },\n {\n symbol: string;\n openInterest: string;\n time: number;\n }\n>('GET', '/fapi/v1/openInterest');\n\n/**\n * 获取最新价格\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC\n */\nexport const getFApiV1TickerPrice = createApi<\n {},\n {\n symbol: string;\n price: string;\n time?: number;\n }[]\n>('GET', '/fapi/v1/ticker/price');\n\n/**\n * 获取资金费率\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md\n */\nexport const getFApiV1PremiumIndex = createApi<\n {\n symbol?: string;\n },\n | {\n symbol: string; // 交易对\n markPrice: string; // 标记价格\n indexPrice: string; // 指数价格\n estimatedSettlePrice: string; // 预估结算价,仅在交割开始前最后一小时有意义\n lastFundingRate: string; // 最近更新的资金费率\n nextFundingTime: number; // 下次资金费时间\n interestRate: string; // 标的资产基础利率\n time: number; // 更新时间\n }\n | {\n symbol: string; // 交易对\n markPrice: string; // 标记价格\n indexPrice: string; // 指数价格\n estimatedSettlePrice: string; // 预估结算价,仅在交割开始前最后一小时有意义\n lastFundingRate: string; // 最近更新的资金费率\n nextFundingTime: number; // 下次资金费时间\n interestRate: string; // 标的资产基础利率\n time: number; // 更新时间\n }[]\n>('GET', '/fapi/v1/premiumIndex');\n"]}
1
+ {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../src/api/public-api.ts"],"names":[],"mappings":";;;AAAA,+CAAsE;AAEtE,MAAM,0BAA0B,GAAG,mCAAwB,CAAC,OAAO,CACjE,gBAAgB,EAChB,0BAA0B,CAC3B,CAAC;AACF,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AACxC,MAAM,OAAO,GAAG,KAAK,EACnB,MAAc,EACd,OAAe,EACf,QAAgB,EAChB,SAAc,EAAE,EACJ,EAAE;IACd,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,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,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7B,0BAA0B,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IACnG,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;QACtC,MAAM;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,CAAC,OAAe,EAAE,EAAE,CACpB,CAAa,MAAc,EAAE,QAAgB,EAAE,EAAE,CACjD,CAAC,MAAY,EAAE,EAAE,CACf,OAAO,CAAO,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAErD,MAAM,eAAe,GAAG,SAAS,CAAC,2BAA2B,CAAC,CAAC;AAC/D,MAAM,aAAa,GAAG,SAAS,CAAC,2BAA2B,CAAC,CAAC;AAE7D;;;;GAIG;AACU,QAAA,oBAAoB,GAAG,eAAe,CAYjD,KAAK,EAAE,sBAAsB,CAAC,CAAC;AA2BjC;;;;GAIG;AACU,QAAA,qBAAqB,GAAG,eAAe,CAAyB,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAE7G;;;;GAIG;AACU,QAAA,oBAAoB,GAAG,aAAa,CAAyB,KAAK,EAAE,sBAAsB,CAAC,CAAC;AAEzG;;;;GAIG;AACU,QAAA,qBAAqB,GAAG,eAAe,CASlD,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAElC;;;;GAIG;AACU,QAAA,oBAAoB,GAAG,eAAe,CAOjD,KAAK,EAAE,uBAAuB,CAAC,CAAC;AAElC;;;GAGG;AACU,QAAA,qBAAqB,GAAG,eAAe,CAwBlD,KAAK,EAAE,uBAAuB,CAAC,CAAC","sourcesContent":["import { GlobalPrometheusRegistry, Terminal } from '@yuants/protocol';\n\nconst MetricsAsterApiCallCounter = GlobalPrometheusRegistry.counter(\n 'aster_api_call',\n 'Number of aster api call',\n);\nconst terminal = Terminal.fromNodeEnv();\nconst request = async <T>(\n method: string,\n baseUrl: string,\n endpoint: string,\n params: any = {},\n): Promise<T> => {\n const url = new URL(baseUrl);\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 console.info(url.toString());\n MetricsAsterApiCallCounter.labels({ path: url.pathname, terminal_id: terminal.terminal_id }).inc();\n const res = await fetch(url.toString(), {\n method,\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 (baseUrl: string) =>\n <TReq, TRes>(method: string, endpoint: string) =>\n (params: TReq) =>\n request<TRes>(method, baseUrl, endpoint, params);\n\nconst createFutureApi = createApi('https://fapi.asterdex.com');\nconst createSpotApi = createApi('https://sapi.asterdex.com');\n\n/**\n * 获取资金费率历史\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9F%A5%E8%AF%A2%E8%B5%84%E9%87%91%E8%B4%B9%E7%8E%87%E5%8E%86%E5%8F%B2\n */\nexport const getFApiV1FundingRate = createFutureApi<\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>('GET', '/fapi/v1/fundingRate');\n\nexport interface IAsterRateLimit {\n rateLimitType?: string;\n interval?: string;\n intervalNum?: number;\n limit?: number;\n}\n\nexport interface IAsterExchangeInfo {\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 rateLimits?: IAsterRateLimit[];\n}\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 = createFutureApi<{}, IAsterExchangeInfo>('GET', '/fapi/v1/exchangeInfo');\n\n/**\n * 获取现货交易对信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-spot-api_CN.md#L1080-L1145\n */\nexport const getApiV1ExchangeInfo = createSpotApi<{}, IAsterExchangeInfo>('GET', '/api/v1/exchangeInfo');\n\n/**\n * 获取未平仓合约数量\n *\n * 无 API 文档 (weird)\n */\nexport const getFApiV1OpenInterest = createFutureApi<\n {\n symbol: string;\n },\n {\n symbol: string;\n openInterest: string;\n time: number;\n }\n>('GET', '/fapi/v1/openInterest');\n\n/**\n * 获取最新价格\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E6%9C%80%E6%96%B0%E4%BB%B7%E6%A0%BC\n */\nexport const getFApiV1TickerPrice = createFutureApi<\n {},\n {\n symbol: string;\n price: string;\n time?: number;\n }[]\n>('GET', '/fapi/v1/ticker/price');\n\n/**\n * 获取资金费率\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md\n */\nexport const getFApiV1PremiumIndex = createFutureApi<\n {\n symbol?: string;\n },\n | {\n symbol: string; // 交易对\n markPrice: string; // 标记价格\n indexPrice: string; // 指数价格\n estimatedSettlePrice: string; // 预估结算价,仅在交割开始前最后一小时有意义\n lastFundingRate: string; // 最近更新的资金费率\n nextFundingTime: number; // 下次资金费时间\n interestRate: string; // 标的资产基础利率\n time: number; // 更新时间\n }\n | {\n symbol: string; // 交易对\n markPrice: string; // 标记价格\n indexPrice: string; // 指数价格\n estimatedSettlePrice: string; // 预估结算价,仅在交割开始前最后一小时有意义\n lastFundingRate: string; // 最近更新的资金费率\n nextFundingTime: number; // 下次资金费时间\n interestRate: string; // 标的资产基础利率\n time: number; // 更新时间\n }[]\n>('GET', '/fapi/v1/premiumIndex');\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../../../src/services/markets/product.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAOhD,eAAO,MAAM,YAAY,QAAa,QAAQ,QAAQ,EAAE,CAoCvD,CAAC"}
1
+ {"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../../../src/services/markets/product.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAIhD,eAAO,MAAM,YAAY,QAAa,QAAQ,QAAQ,EAAE,CAyEvD,CAAC"}
@@ -1,44 +1,66 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.listProducts = void 0;
4
- const protocol_1 = require("@yuants/protocol");
5
4
  const utils_1 = require("@yuants/utils");
6
5
  const public_api_1 = require("../../api/public-api");
7
- const terminal = protocol_1.Terminal.fromNodeEnv();
8
6
  const listProducts = async () => {
9
- // Fetch exchange info from ASTER API
10
- const exchangeInfo = await (0, public_api_1.getFApiV1ExchangeInfo)({});
11
- // Convert symbols to IProduct format
12
- return exchangeInfo.symbols
13
- .filter((symbol) => symbol.status === 'TRADING') // Only include active trading symbols
14
- .map((symbol) => {
15
- // Find price filter for price step
7
+ const [perpExchangeInfo, spotExchangeInfo] = await Promise.all([
8
+ (0, public_api_1.getFApiV1ExchangeInfo)({}),
9
+ (0, public_api_1.getApiV1ExchangeInfo)({}),
10
+ ]);
11
+ const pickPriceStep = (symbol) => {
16
12
  const priceFilter = symbol.filters.find((filter) => filter.filterType === 'PRICE_FILTER');
17
- const priceStep = priceFilter ? +priceFilter.tickSize : 1e-2;
18
- // Find lot size filter for volume step
13
+ return priceFilter ? +priceFilter.tickSize : Number(`1e-${symbol.pricePrecision}`);
14
+ };
15
+ const pickVolumeStep = (symbol) => {
19
16
  const lotSizeFilter = symbol.filters.find((filter) => filter.filterType === 'LOT_SIZE');
20
- const volumeStep = lotSizeFilter ? +lotSizeFilter.stepSize : Number(`1e-${symbol.quantityPrecision}`);
21
- return {
22
- datasource_id: 'ASTER',
23
- product_id: (0, utils_1.encodePath)('ASTER', 'PERP', symbol.symbol),
24
- name: `${symbol.baseAsset}/${symbol.quoteAsset} PERP`,
25
- quote_currency: symbol.quoteAsset,
26
- base_currency: symbol.baseAsset,
27
- value_scale_unit: '',
28
- value_based_cost: 0,
29
- volume_based_cost: 0,
30
- max_volume: 0,
31
- price_step: priceStep,
32
- volume_step: volumeStep,
33
- value_scale: 1,
34
- allow_long: true,
35
- allow_short: true,
36
- margin_rate: 0.1,
37
- max_position: 0,
38
- market_id: 'ASTER/PERPETUAL',
39
- no_interest_rate: false,
40
- };
41
- });
17
+ return lotSizeFilter ? +lotSizeFilter.stepSize : Number(`1e-${symbol.quantityPrecision}`);
18
+ };
19
+ const perpProducts = perpExchangeInfo.symbols
20
+ .filter((symbol) => symbol.status === 'TRADING')
21
+ .map((symbol) => ({
22
+ datasource_id: 'ASTER',
23
+ product_id: (0, utils_1.encodePath)('ASTER', 'PERP', symbol.symbol),
24
+ name: `${symbol.baseAsset}/${symbol.quoteAsset} PERP`,
25
+ quote_currency: symbol.quoteAsset,
26
+ base_currency: symbol.baseAsset,
27
+ value_scale_unit: '',
28
+ value_based_cost: 0,
29
+ volume_based_cost: 0,
30
+ max_volume: 0,
31
+ price_step: pickPriceStep(symbol),
32
+ volume_step: pickVolumeStep(symbol),
33
+ value_scale: 1,
34
+ allow_long: true,
35
+ allow_short: true,
36
+ margin_rate: 0.1,
37
+ max_position: 0,
38
+ market_id: 'ASTER/PERPETUAL',
39
+ no_interest_rate: false,
40
+ }));
41
+ const spotProducts = spotExchangeInfo.symbols
42
+ .filter((symbol) => symbol.status === 'TRADING')
43
+ .map((symbol) => ({
44
+ datasource_id: 'ASTER',
45
+ product_id: (0, utils_1.encodePath)('ASTER', 'SPOT', symbol.symbol),
46
+ name: `${symbol.baseAsset}/${symbol.quoteAsset} SPOT`,
47
+ quote_currency: symbol.quoteAsset,
48
+ base_currency: symbol.baseAsset,
49
+ value_scale_unit: '',
50
+ value_based_cost: 0,
51
+ volume_based_cost: 0,
52
+ max_volume: 0,
53
+ price_step: pickPriceStep(symbol),
54
+ volume_step: pickVolumeStep(symbol),
55
+ value_scale: 1,
56
+ allow_long: true,
57
+ allow_short: false,
58
+ margin_rate: 1,
59
+ max_position: 0,
60
+ market_id: 'ASTER/SPOT',
61
+ no_interest_rate: true,
62
+ }));
63
+ return [...perpProducts, ...spotProducts];
42
64
  };
43
65
  exports.listProducts = listProducts;
44
66
  //# sourceMappingURL=product.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"product.js","sourceRoot":"","sources":["../../../src/services/markets/product.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,yCAA2C;AAC3C,qDAA6D;AAE7D,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAEjC,MAAM,YAAY,GAAG,KAAK,IAAyB,EAAE;IAC1D,qCAAqC;IACrC,MAAM,YAAY,GAAG,MAAM,IAAA,kCAAqB,EAAC,EAAE,CAAC,CAAC;IACrD,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,IAAA,kBAAU,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;YACtD,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,CAAC;AApCW,QAAA,YAAY,gBAoCvB","sourcesContent":["import { IProduct } from '@yuants/data-product';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { getFApiV1ExchangeInfo } from '../../api/public-api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nexport const listProducts = async (): Promise<IProduct[]> => {\n // Fetch exchange info from ASTER API\n const exchangeInfo = await getFApiV1ExchangeInfo({});\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('ASTER', 'PERP', 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"]}
1
+ {"version":3,"file":"product.js","sourceRoot":"","sources":["../../../src/services/markets/product.ts"],"names":[],"mappings":"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","sourcesContent":["import { IProduct } from '@yuants/data-product';\nimport { encodePath } from '@yuants/utils';\nimport { getApiV1ExchangeInfo, getFApiV1ExchangeInfo } from '../../api/public-api';\n\nexport const listProducts = async (): Promise<IProduct[]> => {\n const [perpExchangeInfo, spotExchangeInfo] = await Promise.all([\n getFApiV1ExchangeInfo({}),\n getApiV1ExchangeInfo({}),\n ]);\n\n const pickPriceStep = (symbol: {\n filters: { filterType: string; tickSize?: string }[];\n pricePrecision: number;\n }) => {\n const priceFilter = symbol.filters.find((filter) => filter.filterType === 'PRICE_FILTER');\n return priceFilter ? +priceFilter.tickSize! : Number(`1e-${symbol.pricePrecision}`);\n };\n\n const pickVolumeStep = (symbol: {\n filters: { filterType: string; stepSize?: string }[];\n quantityPrecision: number;\n }) => {\n const lotSizeFilter = symbol.filters.find((filter) => filter.filterType === 'LOT_SIZE');\n return lotSizeFilter ? +lotSizeFilter.stepSize! : Number(`1e-${symbol.quantityPrecision}`);\n };\n\n const perpProducts: IProduct[] = perpExchangeInfo.symbols\n .filter((symbol) => symbol.status === 'TRADING')\n .map(\n (symbol): IProduct => ({\n datasource_id: 'ASTER',\n product_id: encodePath('ASTER', 'PERP', 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: pickPriceStep(symbol),\n volume_step: pickVolumeStep(symbol),\n value_scale: 1,\n allow_long: true,\n allow_short: true,\n margin_rate: 0.1,\n max_position: 0,\n market_id: 'ASTER/PERPETUAL',\n no_interest_rate: false,\n }),\n );\n\n const spotProducts: IProduct[] = spotExchangeInfo.symbols\n .filter((symbol) => symbol.status === 'TRADING')\n .map(\n (symbol): IProduct => ({\n datasource_id: 'ASTER',\n product_id: encodePath('ASTER', 'SPOT', symbol.symbol),\n name: `${symbol.baseAsset}/${symbol.quoteAsset} SPOT`,\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: pickPriceStep(symbol),\n volume_step: pickVolumeStep(symbol),\n value_scale: 1,\n allow_long: true,\n allow_short: false,\n margin_rate: 1,\n max_position: 0,\n market_id: 'ASTER/SPOT',\n no_interest_rate: true,\n }),\n );\n\n return [...perpProducts, ...spotProducts];\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuants/vendor-aster",
3
- "version": "0.7.20",
3
+ "version": "0.7.22",
4
4
  "main": "lib/index.js",
5
5
  "files": [
6
6
  "dist",
@@ -10,7 +10,7 @@
10
10
  "dependencies": {
11
11
  "@yuants/protocol": "0.53.2",
12
12
  "@yuants/cache": "0.3.3",
13
- "@yuants/data-account": "0.8.4",
13
+ "@yuants/data-account": "0.9.0",
14
14
  "@yuants/utils": "0.14.0",
15
15
  "@yuants/data-series": "0.3.51",
16
16
  "@yuants/sql": "0.9.30",
@@ -20,7 +20,7 @@
20
20
  "@yuants/data-interest-rate": "0.1.48",
21
21
  "@yuants/transfer": "0.2.39",
22
22
  "@yuants/data-quote": "0.2.43",
23
- "@yuants/exchange": "0.3.1",
23
+ "@yuants/exchange": "0.4.0",
24
24
  "rxjs": "~7.5.6"
25
25
  },
26
26
  "devDependencies": {
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "apps/vendor-aster/AGENTS.md": "dcd006d19a5c3b73081525d7c0afea68cd6d058b",
3
- "apps/vendor-aster/CHANGELOG.json": "ed645a9b95139905994bbb3a49d1d28721a31619",
4
- "apps/vendor-aster/CHANGELOG.md": "7fe7f275a2fc807b58d175dea35ff3afb510e414",
5
- "apps/vendor-aster/SESSION_NOTES.md": "8a7aaa694e6428ef6e1ef14096e5c3ee00c42152",
3
+ "apps/vendor-aster/CHANGELOG.json": "e1e7142b3a58a4440cff1aee9c7ce694054cc22f",
4
+ "apps/vendor-aster/CHANGELOG.md": "84df4f698cf51afea36677ad9a1f2c2fc2061d29",
5
+ "apps/vendor-aster/SESSION_NOTES.md": "6d9df0bc0989959d8f3f834a99a288a9e852b700",
6
6
  "apps/vendor-aster/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
7
7
  "apps/vendor-aster/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
8
8
  "apps/vendor-aster/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
9
- "apps/vendor-aster/package.json": "1976fd5c4f36a4fd6627001e889958bcf2100b75",
9
+ "apps/vendor-aster/package.json": "111b87f24477173ac957d6fced724d59503837f8",
10
10
  "apps/vendor-aster/src/api/private-api.ts": "71f2f794377a45c64f688a663111318e36463bdb",
11
- "apps/vendor-aster/src/api/public-api.ts": "4cd51f4b64e0c673fb3840fd3b6b13ddc3a7977e",
11
+ "apps/vendor-aster/src/api/public-api.ts": "ced2ae976ee7a74a5c1fe704b2c5fb2e25f13ab7",
12
12
  "apps/vendor-aster/src/index.ts": "509ef4c18ec2deb8a6e11ed5682334433cb2bcb2",
13
13
  "apps/vendor-aster/src/services/accounts/profile.ts": "fc57e7d2c865790dd257c043c8dd5cf5c641b7fd",
14
14
  "apps/vendor-aster/src/services/accounts/spot.ts": "d04bf81c9025cae2b49b1ae0099c9525d888e7af",
15
15
  "apps/vendor-aster/src/services/exchange.ts": "71a555ceec0d84b6f12a9c2002834676f1370d51",
16
16
  "apps/vendor-aster/src/services/markets/interest_rate.ts": "8512bb506f3d66b16aceb9d153d1b3a4671de5ef",
17
- "apps/vendor-aster/src/services/markets/product.ts": "027646b5af638bacc0f943cefc14e32e71bbb6ce",
17
+ "apps/vendor-aster/src/services/markets/product.ts": "cae86f69c6f019747ebad07569ed2bc862a78ac6",
18
18
  "apps/vendor-aster/src/services/markets/quote.ts": "ba022abb87d0114a922030bfba56bce1cd23f135",
19
19
  "apps/vendor-aster/src/services/orders/cancelOrder.ts": "09a6d3b10a218ad226346dd68d0ff0207083a7f1",
20
20
  "apps/vendor-aster/src/services/orders/listOrders.ts": "579e83c45f6c4435ad3f5a2d3fe163a036bb9fd1",
@@ -23,7 +23,7 @@
23
23
  "apps/vendor-aster/.rush/temp/shrinkwrap-deps.json": "5ded440ffb547a8aa495353d5b13c1fd1b164b4a",
24
24
  "libraries/protocol/temp/package-deps.json": "0bd43721e96039b52d7b59c834dc6df45cf75e3f",
25
25
  "libraries/cache/temp/package-deps.json": "a4afa15e6462983f9d3735d31dc1ed8a683fb4dc",
26
- "libraries/data-account/temp/package-deps.json": "ae6b0c69040d0d1989525e843717b6e303d95ef2",
26
+ "libraries/data-account/temp/package-deps.json": "711aeba1f1f5f03741475a4290e56d18b39e5305",
27
27
  "libraries/utils/temp/package-deps.json": "6d58e9b325e8d16de8a878c32010f626b12a01da",
28
28
  "libraries/data-series/temp/package-deps.json": "c89ebffe302757903aa54eff78f76cb855486b8c",
29
29
  "libraries/sql/temp/package-deps.json": "4a9a7ec55f04b20459e664e81e76fa74b6c77b39",
@@ -33,7 +33,7 @@
33
33
  "libraries/data-interest-rate/temp/package-deps.json": "cef1e1cb0116ad593c24635684e0cbf03488d67c",
34
34
  "libraries/transfer/temp/package-deps.json": "36c58299bd6c841c5ba7252d71881a881570d08c",
35
35
  "libraries/data-quote/temp/package-deps.json": "34d079eab44d2bf65e07b112ac2099c6e92a015e",
36
- "libraries/exchange/temp/package-deps.json": "ee94ff641b8afcd48484829a1d6d66ffede2a69c",
36
+ "libraries/exchange/temp/package-deps.json": "d30a450879e4d67f56466262bd88a72506594d68",
37
37
  "libraries/extension/temp/package-deps.json": "9569c553c2f9a7d50b70d8f101fc2d3825aaccb9",
38
38
  "tools/toolkit/temp/package-deps.json": "23e053490eb8feade23e4d45de4e54883e322711"
39
39
  }