@yuants/vendor-hyperliquid 0.3.18 → 0.3.19

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.
@@ -16,9 +16,10 @@ import { createSQLWriter } from '@yuants/sql';
16
16
  import { decodePath, encodePath, formatTime } from '@yuants/utils';
17
17
  import { firstValueFrom, map, mergeAll, timer } from 'rxjs';
18
18
  import { client } from './api';
19
- import { perpetualProduct$ } from './product';
19
+ import { productService } from './product';
20
+ // Use the new product service to get perpetual products
20
21
  createSQLWriter(Terminal.fromNodeEnv(), {
21
- data$: perpetualProduct$.pipe(mergeAll(), map((x) => ({
22
+ data$: productService.products$.pipe(map((products) => products.filter((product) => product.no_interest_rate === false)), mergeAll(), map((x) => ({
22
23
  series_id: encodePath(x.datasource_id, x.product_id),
23
24
  table_name: 'interest_rate',
24
25
  cron_pattern: '0 * * * *',
@@ -1 +1 @@
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, ObservableInput, timer } from 'rxjs';\nimport { client } from './api';\nimport { perpetualProduct$ } from './product';\n\ncreateSQLWriter<ISeriesCollectingTask>(Terminal.fromNodeEnv(), {\n data$: perpetualProduct$.pipe(\n mergeAll(),\n map(\n (x: IProduct): ISeriesCollectingTask => ({\n series_id: encodePath(x.datasource_id, x.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.fromNodeEnv(), {\n tableName: 'interest_rate',\n series_id_prefix_parts: ['HYPERLIQUID'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({\n series_id,\n started_at,\n ended_at,\n }: {\n series_id: string;\n started_at?: number;\n ended_at?: number;\n }): ObservableInput<IInterestRate[]> {\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 // 从 instId 中提取币种名称,例如 \"BTC-USDC\" -> \"BTC\"\n const coin = instId.split('-')[0];\n\n let current_start = start;\n\n while (current_start <= end) {\n try {\n const res = await client.getHistoricalFundingRates({\n coin: coin,\n startTime: current_start,\n endTime: end,\n });\n\n console.info(formatTime(Date.now()), 'getHistoricalFundingRates', coin, `${current_start}-${end}`);\n\n if (!res || res.length === 0) {\n break;\n }\n\n // 过滤并转换数据\n const filteredData = res.filter((v) => v.time >= current_start && v.time <= end);\n\n if (filteredData.length === 0) {\n break;\n }\n\n const data = filteredData.map(\n (v): IInterestRate => ({\n series_id: series_id,\n product_id,\n datasource_id,\n created_at: formatTime(v.time),\n long_rate: `${-parseFloat(v.fundingRate)}`,\n short_rate: `${v.fundingRate}`,\n settlement_price: '',\n }),\n );\n\n yield data;\n\n if (res.length < 500) {\n break;\n }\n\n const latestTime = filteredData[filteredData.length - 1].time;\n current_start = latestTime + 1;\n } catch (error) {\n console.error(formatTime(Date.now()), 'getHistoricalFundingRates failed', coin, error);\n throw error;\n }\n\n // API 限制控制\n await firstValueFrom(timer(1000));\n }\n },\n});\n"]}
1
+ {"version":3,"file":"interest_rate.js","sourceRoot":"","sources":["../src/interest_rate.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,QAAQ,EAAmB,KAAK,EAAE,MAAM,MAAM,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,wDAAwD;AACxD,eAAe,CAAwB,QAAQ,CAAC,WAAW,EAAE,EAAE;IAC7D,KAAK,EAAE,cAAc,CAAC,SAAS,CAAC,IAAI,CAClC,GAAG,CAAC,CAAC,QAAoB,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,gBAAgB,KAAK,KAAK,CAAC,CAAC,EAC/F,QAAQ,EAAE,EACV,GAAG,CACD,CAAC,CAAW,EAAyB,EAAE,CAAC,CAAC;QACvC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,UAAU,CAAC;QACpD,UAAU,EAAE,eAAe;QAC3B,YAAY,EAAE,WAAW;QACzB,aAAa,EAAE,KAAK;QACpB,QAAQ,EAAE,KAAK;QACf,YAAY,EAAE,CAAC;KAChB,CAAC,CACH,CACF;IACD,SAAS,EAAE,wBAAwB;IACnC,aAAa,EAAE,IAAI;IACnB,YAAY,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;CAC1C,CAAC,CAAC;AAEH,oBAAoB,CAAgB,QAAQ,CAAC,WAAW,EAAE,EAAE;IAC1D,SAAS,EAAE,eAAe;IAC1B,sBAAsB,EAAE,CAAC,aAAa,CAAC;IACvC,QAAQ,EAAE,IAAI;IACd,cAAc,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE;IACjC,OAAO,EAAE,UAAiB,EACxB,SAAS,EACT,UAAU,EACV,QAAQ,GAKT;;YACC,MAAM,KAAK,GAAG,UAAU,IAAI,CAAC,CAAC;YAC9B,MAAM,GAAG,GAAG,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACnC,MAAM,CAAC,aAAa,EAAE,UAAU,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;YAC1D,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;YAElD,0CAA0C;YAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAElC,IAAI,aAAa,GAAG,KAAK,CAAC;YAE1B,OAAO,aAAa,IAAI,GAAG,EAAE;gBAC3B,IAAI;oBACF,MAAM,GAAG,GAAG,cAAM,MAAM,CAAC,yBAAyB,CAAC;wBACjD,IAAI,EAAE,IAAI;wBACV,SAAS,EAAE,aAAa;wBACxB,OAAO,EAAE,GAAG;qBACb,CAAC,CAAA,CAAC;oBAEH,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,2BAA2B,EAAE,IAAI,EAAE,GAAG,aAAa,IAAI,GAAG,EAAE,CAAC,CAAC;oBAEnG,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE;wBAC5B,MAAM;qBACP;oBAED,UAAU;oBACV,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,aAAa,IAAI,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;oBAEjF,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE;wBAC7B,MAAM;qBACP;oBAED,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAC3B,CAAC,CAAC,EAAiB,EAAE,CAAC,CAAC;wBACrB,SAAS,EAAE,SAAS;wBACpB,UAAU;wBACV,aAAa;wBACb,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;wBAC9B,SAAS,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE;wBAC1C,UAAU,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE;wBAC9B,gBAAgB,EAAE,EAAE;qBACrB,CAAC,CACH,CAAC;oBAEF,oBAAM,IAAI,CAAA,CAAC;oBAEX,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE;wBACpB,MAAM;qBACP;oBAED,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;oBAC9D,aAAa,GAAG,UAAU,GAAG,CAAC,CAAC;iBAChC;gBAAC,OAAO,KAAK,EAAE;oBACd,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,kCAAkC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;oBACvF,MAAM,KAAK,CAAC;iBACb;gBAED,WAAW;gBACX,cAAM,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA,CAAC;aACnC;QACH,CAAC;KAAA;CACF,CAAC,CAAC","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, ObservableInput, timer } from 'rxjs';\nimport { client } from './api';\nimport { productService } from './product';\n\n// Use the new product service to get perpetual products\ncreateSQLWriter<ISeriesCollectingTask>(Terminal.fromNodeEnv(), {\n data$: productService.products$.pipe(\n map((products: IProduct[]) => products.filter((product) => product.no_interest_rate === false)),\n mergeAll(),\n map(\n (x: IProduct): ISeriesCollectingTask => ({\n series_id: encodePath(x.datasource_id, x.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.fromNodeEnv(), {\n tableName: 'interest_rate',\n series_id_prefix_parts: ['HYPERLIQUID'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({\n series_id,\n started_at,\n ended_at,\n }: {\n series_id: string;\n started_at?: number;\n ended_at?: number;\n }): ObservableInput<IInterestRate[]> {\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 // 从 instId 中提取币种名称,例如 \"BTC-USDC\" -> \"BTC\"\n const coin = instId.split('-')[0];\n\n let current_start = start;\n\n while (current_start <= end) {\n try {\n const res = await client.getHistoricalFundingRates({\n coin: coin,\n startTime: current_start,\n endTime: end,\n });\n\n console.info(formatTime(Date.now()), 'getHistoricalFundingRates', coin, `${current_start}-${end}`);\n\n if (!res || res.length === 0) {\n break;\n }\n\n // 过滤并转换数据\n const filteredData = res.filter((v) => v.time >= current_start && v.time <= end);\n\n if (filteredData.length === 0) {\n break;\n }\n\n const data = filteredData.map(\n (v): IInterestRate => ({\n series_id: series_id,\n product_id,\n datasource_id,\n created_at: formatTime(v.time),\n long_rate: `${-parseFloat(v.fundingRate)}`,\n short_rate: `${v.fundingRate}`,\n settlement_price: '',\n }),\n );\n\n yield data;\n\n if (res.length < 500) {\n break;\n }\n\n const latestTime = filteredData[filteredData.length - 1].time;\n current_start = latestTime + 1;\n } catch (error) {\n console.error(formatTime(Date.now()), 'getHistoricalFundingRates failed', coin, error);\n throw error;\n }\n\n // API 限制控制\n await firstValueFrom(timer(1000));\n }\n },\n});\n"]}
package/dist/product.js CHANGED
@@ -1,13 +1,17 @@
1
+ import { provideQueryProductsService } from '@yuants/data-product';
1
2
  import { Terminal } from '@yuants/protocol';
2
- import { createSQLWriter } from '@yuants/sql';
3
- import { encodePath, formatTime } from '@yuants/utils';
4
- import { defer, repeat, retry, shareReplay, Subject, tap } from 'rxjs';
3
+ import { encodePath } from '@yuants/utils';
5
4
  import { client } from './api';
6
5
  const terminal = Terminal.fromNodeEnv();
7
- const product$ = new Subject();
8
- const tokenProduct$ = defer(async () => {
9
- const res = await client.getSpotMetaData();
10
- return res.tokens.map((token) => ({
6
+ // Provide QueryProducts service for Hyperliquid
7
+ export const productService = provideQueryProductsService(terminal, 'HYPERLIQUID', async (req) => {
8
+ // Fetch both spot and perpetual products
9
+ const [spotMetaData, perpetualsMetaData] = await Promise.all([
10
+ client.getSpotMetaData(),
11
+ client.getPerpetualsMetaData(),
12
+ ]);
13
+ // Convert spot tokens to IProduct format
14
+ const spotProducts = spotMetaData.tokens.map((token) => ({
11
15
  product_id: encodePath('SPOT', `${token.name}-USDC`),
12
16
  datasource_id: 'HYPERLIQUID',
13
17
  quote_currency: 'USDC',
@@ -24,17 +28,11 @@ const tokenProduct$ = defer(async () => {
24
28
  max_volume: 0,
25
29
  allow_long: true,
26
30
  allow_short: false,
27
- market_id: 'Hyperliquid',
31
+ market_id: 'HYPERLIQUID/SPOT',
28
32
  no_interest_rate: true,
29
33
  }));
30
- }).pipe(tap((list) => list.forEach((product) => product$.next(product))), tap({
31
- error: (e) => {
32
- console.error(formatTime(Date.now()), 'SpotProducts', e);
33
- },
34
- }), retry({ delay: 5000 }), repeat({ delay: 86400000 }), shareReplay(1));
35
- export const perpetualProduct$ = defer(async () => {
36
- const res = await client.getPerpetualsMetaData();
37
- return res.universe.map((product) => ({
34
+ // Convert perpetual products to IProduct format
35
+ const perpetualProducts = perpetualsMetaData.universe.map((product) => ({
38
36
  product_id: encodePath('PERPETUAL', `${product.name}-USD`),
39
37
  datasource_id: 'HYPERLIQUID',
40
38
  quote_currency: 'USD',
@@ -51,20 +49,12 @@ export const perpetualProduct$ = defer(async () => {
51
49
  max_volume: 0,
52
50
  allow_long: true,
53
51
  allow_short: true,
54
- market_id: 'Hyperliquid',
52
+ market_id: 'HYPERLIQUID/PERPETUAL',
55
53
  no_interest_rate: false,
56
54
  }));
57
- }).pipe(tap((list) => list.forEach((product) => product$.next(product))), tap({
58
- error: (e) => {
59
- console.error(formatTime(Date.now()), 'PerpetualProducts', e);
60
- },
61
- }), retry({ delay: 5000 }), repeat({ delay: 86400000 }), shareReplay(1));
62
- perpetualProduct$.subscribe();
63
- tokenProduct$.subscribe();
64
- createSQLWriter(terminal, {
65
- data$: product$,
66
- tableName: 'product',
67
- conflictKeys: ['datasource_id', 'product_id'],
68
- writeInterval: 1000,
55
+ // Combine all products
56
+ return [...spotProducts, ...perpetualProducts];
57
+ }, {
58
+ auto_refresh_interval: 86400000, // Refresh daily (24 hours)
69
59
  });
70
60
  //# sourceMappingURL=product.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"product.js","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAY,CAAC;AAEzC,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE;IACrC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,eAAe,EAAE,CAAC;IAC3C,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CACnB,CAAC,KAAK,EAAY,EAAE,CAAC,CAAC;QACpB,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,OAAO,CAAC;QACpD,aAAa,EAAE,aAAa;QAC5B,cAAc,EAAE,MAAM;QACtB,aAAa,EAAE,KAAK,CAAC,IAAI;QACzB,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,UAAU,EAAE,CAAC;QAC7C,IAAI,EAAE,EAAE;QACR,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,EAAE;QACpB,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,CAAC;QACnB,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,CAAC;QACf,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,KAAK;QAClB,SAAS,EAAE,aAAa;QACxB,gBAAgB,EAAE,IAAI;KACvB,CAAC,CACH,CAAC;AACJ,CAAC,CAAC,CAAC,IAAI,CACL,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAChE,GAAG,CAAC;IACF,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;QACX,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;CACF,CAAC,EACF,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACtB,MAAM,CAAC,EAAE,KAAK,EAAE,QAAS,EAAE,CAAC,EAC5B,WAAW,CAAC,CAAC,CAAC,CACf,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE;IAChD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,qBAAqB,EAAE,CAAC;IACjD,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CACrB,CAAC,OAAO,EAAY,EAAE,CAAC,CAAC;QACtB,UAAU,EAAE,UAAU,CAAC,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,MAAM,CAAC;QAC1D,aAAa,EAAE,aAAa;QAC5B,cAAc,EAAE,KAAK;QACrB,aAAa,EAAE,OAAO,CAAC,IAAI;QAC3B,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QAC/C,IAAI,EAAE,EAAE;QACR,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,EAAE;QACpB,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW;QACpC,gBAAgB,EAAE,CAAC;QACnB,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,CAAC;QACf,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,aAAa;QACxB,gBAAgB,EAAE,KAAK;KACxB,CAAC,CACH,CAAC;AACJ,CAAC,CAAC,CAAC,IAAI,CACL,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAChE,GAAG,CAAC;IACF,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;QACX,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC;IAChE,CAAC;CACF,CAAC,EACF,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACtB,MAAM,CAAC,EAAE,KAAK,EAAE,QAAS,EAAE,CAAC,EAC5B,WAAW,CAAC,CAAC,CAAC,CACf,CAAC;AAEF,iBAAiB,CAAC,SAAS,EAAE,CAAC;AAC9B,aAAa,CAAC,SAAS,EAAE,CAAC;AAE1B,eAAe,CAAW,QAAQ,EAAE;IAClC,KAAK,EAAE,QAAQ;IACf,SAAS,EAAE,SAAS;IACpB,YAAY,EAAE,CAAC,eAAe,EAAE,YAAY,CAAC;IAC7C,aAAa,EAAE,IAAI;CACpB,CAAC,CAAC","sourcesContent":["import { IProduct } from '@yuants/data-product';\nimport { Terminal } from '@yuants/protocol';\nimport { createSQLWriter } from '@yuants/sql';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { defer, repeat, retry, shareReplay, Subject, tap } from 'rxjs';\nimport { client } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst product$ = new Subject<IProduct>();\n\nconst tokenProduct$ = defer(async () => {\n const res = await client.getSpotMetaData();\n return res.tokens.map(\n (token): IProduct => ({\n product_id: encodePath('SPOT', `${token.name}-USDC`),\n datasource_id: 'HYPERLIQUID',\n quote_currency: 'USDC',\n base_currency: token.name,\n price_step: 1e-2,\n volume_step: Number(`1e-${token.szDecimals}`),\n name: '',\n value_scale: 1,\n value_scale_unit: '',\n margin_rate: 1,\n value_based_cost: 0,\n volume_based_cost: 0,\n max_position: 0,\n max_volume: 0,\n allow_long: true,\n allow_short: false,\n market_id: 'Hyperliquid',\n no_interest_rate: true,\n }),\n );\n}).pipe(\n tap((list) => list.forEach((product) => product$.next(product))),\n tap({\n error: (e) => {\n console.error(formatTime(Date.now()), 'SpotProducts', e);\n },\n }),\n retry({ delay: 5000 }),\n repeat({ delay: 86400_000 }),\n shareReplay(1),\n);\n\nexport const perpetualProduct$ = defer(async () => {\n const res = await client.getPerpetualsMetaData();\n return res.universe.map(\n (product): IProduct => ({\n product_id: encodePath('PERPETUAL', `${product.name}-USD`),\n datasource_id: 'HYPERLIQUID',\n quote_currency: 'USD',\n base_currency: product.name,\n price_step: 1e-2,\n volume_step: Number(`1e-${product.szDecimals}`),\n name: '',\n value_scale: 1,\n value_scale_unit: '',\n margin_rate: 1 / product.maxLeverage,\n value_based_cost: 0,\n volume_based_cost: 0,\n max_position: 0,\n max_volume: 0,\n allow_long: true,\n allow_short: true,\n market_id: 'Hyperliquid',\n no_interest_rate: false,\n }),\n );\n}).pipe(\n tap((list) => list.forEach((product) => product$.next(product))),\n tap({\n error: (e) => {\n console.error(formatTime(Date.now()), 'PerpetualProducts', e);\n },\n }),\n retry({ delay: 5000 }),\n repeat({ delay: 86400_000 }),\n shareReplay(1),\n);\n\nperpetualProduct$.subscribe();\ntokenProduct$.subscribe();\n\ncreateSQLWriter<IProduct>(terminal, {\n data$: product$,\n tableName: 'product',\n conflictKeys: ['datasource_id', 'product_id'],\n writeInterval: 1000,\n});\n"]}
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,MAAM,EAAE,MAAM,OAAO,CAAC;AAE/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,gDAAgD;AAChD,MAAM,CAAC,MAAM,cAAc,GAAG,2BAA2B,CACvD,QAAQ,EACR,aAAa,EACb,KAAK,EAAE,GAA0B,EAAuB,EAAE;IACxD,yCAAyC;IACzC,MAAM,CAAC,YAAY,EAAE,kBAAkB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC3D,MAAM,CAAC,eAAe,EAAE;QACxB,MAAM,CAAC,qBAAqB,EAAE;KAC/B,CAAC,CAAC;IAEH,yCAAyC;IACzC,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,CAC1C,CAAC,KAAK,EAAY,EAAE,CAAC,CAAC;QACpB,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,OAAO,CAAC;QACpD,aAAa,EAAE,aAAa;QAC5B,cAAc,EAAE,MAAM;QACtB,aAAa,EAAE,KAAK,CAAC,IAAI;QACzB,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,UAAU,EAAE,CAAC;QAC7C,IAAI,EAAE,EAAE;QACR,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,EAAE;QACpB,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,CAAC;QACnB,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,CAAC;QACf,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,KAAK;QAClB,SAAS,EAAE,kBAAkB;QAC7B,gBAAgB,EAAE,IAAI;KACvB,CAAC,CACH,CAAC;IAEF,gDAAgD;IAChD,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,QAAQ,CAAC,GAAG,CACvD,CAAC,OAAO,EAAY,EAAE,CAAC,CAAC;QACtB,UAAU,EAAE,UAAU,CAAC,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,MAAM,CAAC;QAC1D,aAAa,EAAE,aAAa;QAC5B,cAAc,EAAE,KAAK;QACrB,aAAa,EAAE,OAAO,CAAC,IAAI;QAC3B,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QAC/C,IAAI,EAAE,EAAE;QACR,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,EAAE;QACpB,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW;QACpC,gBAAgB,EAAE,CAAC;QACnB,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,CAAC;QACf,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,uBAAuB;QAClC,gBAAgB,EAAE,KAAK;KACxB,CAAC,CACH,CAAC;IAEF,uBAAuB;IACvB,OAAO,CAAC,GAAG,YAAY,EAAE,GAAG,iBAAiB,CAAC,CAAC;AACjD,CAAC,EACD;IACE,qBAAqB,EAAE,QAAS,EAAE,2BAA2B;CAC9D,CACF,CAAC","sourcesContent":["import { IProduct, IQueryProductsRequest, provideQueryProductsService } from '@yuants/data-product';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { client } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\n// Provide QueryProducts service for Hyperliquid\nexport const productService = provideQueryProductsService(\n terminal,\n 'HYPERLIQUID',\n async (req: IQueryProductsRequest): Promise<IProduct[]> => {\n // Fetch both spot and perpetual products\n const [spotMetaData, perpetualsMetaData] = await Promise.all([\n client.getSpotMetaData(),\n client.getPerpetualsMetaData(),\n ]);\n\n // Convert spot tokens to IProduct format\n const spotProducts = spotMetaData.tokens.map(\n (token): IProduct => ({\n product_id: encodePath('SPOT', `${token.name}-USDC`),\n datasource_id: 'HYPERLIQUID',\n quote_currency: 'USDC',\n base_currency: token.name,\n price_step: 1e-2,\n volume_step: Number(`1e-${token.szDecimals}`),\n name: '',\n value_scale: 1,\n value_scale_unit: '',\n margin_rate: 1,\n value_based_cost: 0,\n volume_based_cost: 0,\n max_position: 0,\n max_volume: 0,\n allow_long: true,\n allow_short: false,\n market_id: 'HYPERLIQUID/SPOT',\n no_interest_rate: true,\n }),\n );\n\n // Convert perpetual products to IProduct format\n const perpetualProducts = perpetualsMetaData.universe.map(\n (product): IProduct => ({\n product_id: encodePath('PERPETUAL', `${product.name}-USD`),\n datasource_id: 'HYPERLIQUID',\n quote_currency: 'USD',\n base_currency: product.name,\n price_step: 1e-2,\n volume_step: Number(`1e-${product.szDecimals}`),\n name: '',\n value_scale: 1,\n value_scale_unit: '',\n margin_rate: 1 / product.maxLeverage,\n value_based_cost: 0,\n volume_based_cost: 0,\n max_position: 0,\n max_volume: 0,\n allow_long: true,\n allow_short: true,\n market_id: 'HYPERLIQUID/PERPETUAL',\n no_interest_rate: false,\n }),\n );\n\n // Combine all products\n return [...spotProducts, ...perpetualProducts];\n },\n {\n auto_refresh_interval: 86400_000, // Refresh daily (24 hours)\n },\n);\n"]}
@@ -19,8 +19,9 @@ const utils_1 = require("@yuants/utils");
19
19
  const rxjs_1 = require("rxjs");
20
20
  const api_1 = require("./api");
21
21
  const product_1 = require("./product");
22
+ // Use the new product service to get perpetual products
22
23
  (0, sql_1.createSQLWriter)(protocol_1.Terminal.fromNodeEnv(), {
23
- data$: product_1.perpetualProduct$.pipe((0, rxjs_1.mergeAll)(), (0, rxjs_1.map)((x) => ({
24
+ data$: product_1.productService.products$.pipe((0, rxjs_1.map)((products) => products.filter((product) => product.no_interest_rate === false)), (0, rxjs_1.mergeAll)(), (0, rxjs_1.map)((x) => ({
24
25
  series_id: (0, utils_1.encodePath)(x.datasource_id, x.product_id),
25
26
  table_name: 'interest_rate',
26
27
  cron_pattern: '0 * * * *',
@@ -1 +1 @@
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, ObservableInput, timer } from 'rxjs';\nimport { client } from './api';\nimport { perpetualProduct$ } from './product';\n\ncreateSQLWriter<ISeriesCollectingTask>(Terminal.fromNodeEnv(), {\n data$: perpetualProduct$.pipe(\n mergeAll(),\n map(\n (x: IProduct): ISeriesCollectingTask => ({\n series_id: encodePath(x.datasource_id, x.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.fromNodeEnv(), {\n tableName: 'interest_rate',\n series_id_prefix_parts: ['HYPERLIQUID'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({\n series_id,\n started_at,\n ended_at,\n }: {\n series_id: string;\n started_at?: number;\n ended_at?: number;\n }): ObservableInput<IInterestRate[]> {\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 // 从 instId 中提取币种名称,例如 \"BTC-USDC\" -> \"BTC\"\n const coin = instId.split('-')[0];\n\n let current_start = start;\n\n while (current_start <= end) {\n try {\n const res = await client.getHistoricalFundingRates({\n coin: coin,\n startTime: current_start,\n endTime: end,\n });\n\n console.info(formatTime(Date.now()), 'getHistoricalFundingRates', coin, `${current_start}-${end}`);\n\n if (!res || res.length === 0) {\n break;\n }\n\n // 过滤并转换数据\n const filteredData = res.filter((v) => v.time >= current_start && v.time <= end);\n\n if (filteredData.length === 0) {\n break;\n }\n\n const data = filteredData.map(\n (v): IInterestRate => ({\n series_id: series_id,\n product_id,\n datasource_id,\n created_at: formatTime(v.time),\n long_rate: `${-parseFloat(v.fundingRate)}`,\n short_rate: `${v.fundingRate}`,\n settlement_price: '',\n }),\n );\n\n yield data;\n\n if (res.length < 500) {\n break;\n }\n\n const latestTime = filteredData[filteredData.length - 1].time;\n current_start = latestTime + 1;\n } catch (error) {\n console.error(formatTime(Date.now()), 'getHistoricalFundingRates failed', coin, error);\n throw error;\n }\n\n // API 限制控制\n await firstValueFrom(timer(1000));\n }\n },\n});\n"]}
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, ObservableInput, timer } from 'rxjs';\nimport { client } from './api';\nimport { productService } from './product';\n\n// Use the new product service to get perpetual products\ncreateSQLWriter<ISeriesCollectingTask>(Terminal.fromNodeEnv(), {\n data$: productService.products$.pipe(\n map((products: IProduct[]) => products.filter((product) => product.no_interest_rate === false)),\n mergeAll(),\n map(\n (x: IProduct): ISeriesCollectingTask => ({\n series_id: encodePath(x.datasource_id, x.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.fromNodeEnv(), {\n tableName: 'interest_rate',\n series_id_prefix_parts: ['HYPERLIQUID'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({\n series_id,\n started_at,\n ended_at,\n }: {\n series_id: string;\n started_at?: number;\n ended_at?: number;\n }): ObservableInput<IInterestRate[]> {\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 // 从 instId 中提取币种名称,例如 \"BTC-USDC\" -> \"BTC\"\n const coin = instId.split('-')[0];\n\n let current_start = start;\n\n while (current_start <= end) {\n try {\n const res = await client.getHistoricalFundingRates({\n coin: coin,\n startTime: current_start,\n endTime: end,\n });\n\n console.info(formatTime(Date.now()), 'getHistoricalFundingRates', coin, `${current_start}-${end}`);\n\n if (!res || res.length === 0) {\n break;\n }\n\n // 过滤并转换数据\n const filteredData = res.filter((v) => v.time >= current_start && v.time <= end);\n\n if (filteredData.length === 0) {\n break;\n }\n\n const data = filteredData.map(\n (v): IInterestRate => ({\n series_id: series_id,\n product_id,\n datasource_id,\n created_at: formatTime(v.time),\n long_rate: `${-parseFloat(v.fundingRate)}`,\n short_rate: `${v.fundingRate}`,\n settlement_price: '',\n }),\n );\n\n yield data;\n\n if (res.length < 500) {\n break;\n }\n\n const latestTime = filteredData[filteredData.length - 1].time;\n current_start = latestTime + 1;\n } catch (error) {\n console.error(formatTime(Date.now()), 'getHistoricalFundingRates failed', coin, error);\n throw error;\n }\n\n // API 限制控制\n await firstValueFrom(timer(1000));\n }\n },\n});\n"]}
package/lib/product.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- import { IProduct } from '@yuants/data-product';
2
- export declare const perpetualProduct$: import("rxjs").Observable<IProduct[]>;
1
+ export declare const productService: import("@yuants/data-product").IQueryProductsService;
3
2
  //# sourceMappingURL=product.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AA+ChD,eAAO,MAAM,iBAAiB,uCAkC7B,CAAC"}
1
+ {"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,cAAc,sDAgE1B,CAAC"}
package/lib/product.js CHANGED
@@ -1,16 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.perpetualProduct$ = void 0;
3
+ exports.productService = void 0;
4
+ const data_product_1 = require("@yuants/data-product");
4
5
  const protocol_1 = require("@yuants/protocol");
5
- const sql_1 = require("@yuants/sql");
6
6
  const utils_1 = require("@yuants/utils");
7
- const rxjs_1 = require("rxjs");
8
7
  const api_1 = require("./api");
9
8
  const terminal = protocol_1.Terminal.fromNodeEnv();
10
- const product$ = new rxjs_1.Subject();
11
- const tokenProduct$ = (0, rxjs_1.defer)(async () => {
12
- const res = await api_1.client.getSpotMetaData();
13
- return res.tokens.map((token) => ({
9
+ // Provide QueryProducts service for Hyperliquid
10
+ exports.productService = (0, data_product_1.provideQueryProductsService)(terminal, 'HYPERLIQUID', async (req) => {
11
+ // Fetch both spot and perpetual products
12
+ const [spotMetaData, perpetualsMetaData] = await Promise.all([
13
+ api_1.client.getSpotMetaData(),
14
+ api_1.client.getPerpetualsMetaData(),
15
+ ]);
16
+ // Convert spot tokens to IProduct format
17
+ const spotProducts = spotMetaData.tokens.map((token) => ({
14
18
  product_id: (0, utils_1.encodePath)('SPOT', `${token.name}-USDC`),
15
19
  datasource_id: 'HYPERLIQUID',
16
20
  quote_currency: 'USDC',
@@ -27,17 +31,11 @@ const tokenProduct$ = (0, rxjs_1.defer)(async () => {
27
31
  max_volume: 0,
28
32
  allow_long: true,
29
33
  allow_short: false,
30
- market_id: 'Hyperliquid',
34
+ market_id: 'HYPERLIQUID/SPOT',
31
35
  no_interest_rate: true,
32
36
  }));
33
- }).pipe((0, rxjs_1.tap)((list) => list.forEach((product) => product$.next(product))), (0, rxjs_1.tap)({
34
- error: (e) => {
35
- console.error((0, utils_1.formatTime)(Date.now()), 'SpotProducts', e);
36
- },
37
- }), (0, rxjs_1.retry)({ delay: 5000 }), (0, rxjs_1.repeat)({ delay: 86400000 }), (0, rxjs_1.shareReplay)(1));
38
- exports.perpetualProduct$ = (0, rxjs_1.defer)(async () => {
39
- const res = await api_1.client.getPerpetualsMetaData();
40
- return res.universe.map((product) => ({
37
+ // Convert perpetual products to IProduct format
38
+ const perpetualProducts = perpetualsMetaData.universe.map((product) => ({
41
39
  product_id: (0, utils_1.encodePath)('PERPETUAL', `${product.name}-USD`),
42
40
  datasource_id: 'HYPERLIQUID',
43
41
  quote_currency: 'USD',
@@ -54,20 +52,12 @@ exports.perpetualProduct$ = (0, rxjs_1.defer)(async () => {
54
52
  max_volume: 0,
55
53
  allow_long: true,
56
54
  allow_short: true,
57
- market_id: 'Hyperliquid',
55
+ market_id: 'HYPERLIQUID/PERPETUAL',
58
56
  no_interest_rate: false,
59
57
  }));
60
- }).pipe((0, rxjs_1.tap)((list) => list.forEach((product) => product$.next(product))), (0, rxjs_1.tap)({
61
- error: (e) => {
62
- console.error((0, utils_1.formatTime)(Date.now()), 'PerpetualProducts', e);
63
- },
64
- }), (0, rxjs_1.retry)({ delay: 5000 }), (0, rxjs_1.repeat)({ delay: 86400000 }), (0, rxjs_1.shareReplay)(1));
65
- exports.perpetualProduct$.subscribe();
66
- tokenProduct$.subscribe();
67
- (0, sql_1.createSQLWriter)(terminal, {
68
- data$: product$,
69
- tableName: 'product',
70
- conflictKeys: ['datasource_id', 'product_id'],
71
- writeInterval: 1000,
58
+ // Combine all products
59
+ return [...spotProducts, ...perpetualProducts];
60
+ }, {
61
+ auto_refresh_interval: 86400000, // Refresh daily (24 hours)
72
62
  });
73
63
  //# sourceMappingURL=product.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"product.js","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"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","sourcesContent":["import { IProduct } from '@yuants/data-product';\nimport { Terminal } from '@yuants/protocol';\nimport { createSQLWriter } from '@yuants/sql';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { defer, repeat, retry, shareReplay, Subject, tap } from 'rxjs';\nimport { client } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst product$ = new Subject<IProduct>();\n\nconst tokenProduct$ = defer(async () => {\n const res = await client.getSpotMetaData();\n return res.tokens.map(\n (token): IProduct => ({\n product_id: encodePath('SPOT', `${token.name}-USDC`),\n datasource_id: 'HYPERLIQUID',\n quote_currency: 'USDC',\n base_currency: token.name,\n price_step: 1e-2,\n volume_step: Number(`1e-${token.szDecimals}`),\n name: '',\n value_scale: 1,\n value_scale_unit: '',\n margin_rate: 1,\n value_based_cost: 0,\n volume_based_cost: 0,\n max_position: 0,\n max_volume: 0,\n allow_long: true,\n allow_short: false,\n market_id: 'Hyperliquid',\n no_interest_rate: true,\n }),\n );\n}).pipe(\n tap((list) => list.forEach((product) => product$.next(product))),\n tap({\n error: (e) => {\n console.error(formatTime(Date.now()), 'SpotProducts', e);\n },\n }),\n retry({ delay: 5000 }),\n repeat({ delay: 86400_000 }),\n shareReplay(1),\n);\n\nexport const perpetualProduct$ = defer(async () => {\n const res = await client.getPerpetualsMetaData();\n return res.universe.map(\n (product): IProduct => ({\n product_id: encodePath('PERPETUAL', `${product.name}-USD`),\n datasource_id: 'HYPERLIQUID',\n quote_currency: 'USD',\n base_currency: product.name,\n price_step: 1e-2,\n volume_step: Number(`1e-${product.szDecimals}`),\n name: '',\n value_scale: 1,\n value_scale_unit: '',\n margin_rate: 1 / product.maxLeverage,\n value_based_cost: 0,\n volume_based_cost: 0,\n max_position: 0,\n max_volume: 0,\n allow_long: true,\n allow_short: true,\n market_id: 'Hyperliquid',\n no_interest_rate: false,\n }),\n );\n}).pipe(\n tap((list) => list.forEach((product) => product$.next(product))),\n tap({\n error: (e) => {\n console.error(formatTime(Date.now()), 'PerpetualProducts', e);\n },\n }),\n retry({ delay: 5000 }),\n repeat({ delay: 86400_000 }),\n shareReplay(1),\n);\n\nperpetualProduct$.subscribe();\ntokenProduct$.subscribe();\n\ncreateSQLWriter<IProduct>(terminal, {\n data$: product$,\n tableName: 'product',\n conflictKeys: ['datasource_id', 'product_id'],\n writeInterval: 1000,\n});\n"]}
1
+ {"version":3,"file":"product.js","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":";;;AAAA,uDAAoG;AACpG,+CAA4C;AAC5C,yCAA2C;AAC3C,+BAA+B;AAE/B,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,gDAAgD;AACnC,QAAA,cAAc,GAAG,IAAA,0CAA2B,EACvD,QAAQ,EACR,aAAa,EACb,KAAK,EAAE,GAA0B,EAAuB,EAAE;IACxD,yCAAyC;IACzC,MAAM,CAAC,YAAY,EAAE,kBAAkB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC3D,YAAM,CAAC,eAAe,EAAE;QACxB,YAAM,CAAC,qBAAqB,EAAE;KAC/B,CAAC,CAAC;IAEH,yCAAyC;IACzC,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,CAC1C,CAAC,KAAK,EAAY,EAAE,CAAC,CAAC;QACpB,UAAU,EAAE,IAAA,kBAAU,EAAC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,OAAO,CAAC;QACpD,aAAa,EAAE,aAAa;QAC5B,cAAc,EAAE,MAAM;QACtB,aAAa,EAAE,KAAK,CAAC,IAAI;QACzB,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,UAAU,EAAE,CAAC;QAC7C,IAAI,EAAE,EAAE;QACR,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,EAAE;QACpB,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,CAAC;QACnB,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,CAAC;QACf,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,KAAK;QAClB,SAAS,EAAE,kBAAkB;QAC7B,gBAAgB,EAAE,IAAI;KACvB,CAAC,CACH,CAAC;IAEF,gDAAgD;IAChD,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,QAAQ,CAAC,GAAG,CACvD,CAAC,OAAO,EAAY,EAAE,CAAC,CAAC;QACtB,UAAU,EAAE,IAAA,kBAAU,EAAC,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,MAAM,CAAC;QAC1D,aAAa,EAAE,aAAa;QAC5B,cAAc,EAAE,KAAK;QACrB,aAAa,EAAE,OAAO,CAAC,IAAI;QAC3B,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QAC/C,IAAI,EAAE,EAAE;QACR,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,EAAE;QACpB,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW;QACpC,gBAAgB,EAAE,CAAC;QACnB,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,CAAC;QACf,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,uBAAuB;QAClC,gBAAgB,EAAE,KAAK;KACxB,CAAC,CACH,CAAC;IAEF,uBAAuB;IACvB,OAAO,CAAC,GAAG,YAAY,EAAE,GAAG,iBAAiB,CAAC,CAAC;AACjD,CAAC,EACD;IACE,qBAAqB,EAAE,QAAS,EAAE,2BAA2B;CAC9D,CACF,CAAC","sourcesContent":["import { IProduct, IQueryProductsRequest, provideQueryProductsService } from '@yuants/data-product';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { client } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\n// Provide QueryProducts service for Hyperliquid\nexport const productService = provideQueryProductsService(\n terminal,\n 'HYPERLIQUID',\n async (req: IQueryProductsRequest): Promise<IProduct[]> => {\n // Fetch both spot and perpetual products\n const [spotMetaData, perpetualsMetaData] = await Promise.all([\n client.getSpotMetaData(),\n client.getPerpetualsMetaData(),\n ]);\n\n // Convert spot tokens to IProduct format\n const spotProducts = spotMetaData.tokens.map(\n (token): IProduct => ({\n product_id: encodePath('SPOT', `${token.name}-USDC`),\n datasource_id: 'HYPERLIQUID',\n quote_currency: 'USDC',\n base_currency: token.name,\n price_step: 1e-2,\n volume_step: Number(`1e-${token.szDecimals}`),\n name: '',\n value_scale: 1,\n value_scale_unit: '',\n margin_rate: 1,\n value_based_cost: 0,\n volume_based_cost: 0,\n max_position: 0,\n max_volume: 0,\n allow_long: true,\n allow_short: false,\n market_id: 'HYPERLIQUID/SPOT',\n no_interest_rate: true,\n }),\n );\n\n // Convert perpetual products to IProduct format\n const perpetualProducts = perpetualsMetaData.universe.map(\n (product): IProduct => ({\n product_id: encodePath('PERPETUAL', `${product.name}-USD`),\n datasource_id: 'HYPERLIQUID',\n quote_currency: 'USD',\n base_currency: product.name,\n price_step: 1e-2,\n volume_step: Number(`1e-${product.szDecimals}`),\n name: '',\n value_scale: 1,\n value_scale_unit: '',\n margin_rate: 1 / product.maxLeverage,\n value_based_cost: 0,\n volume_based_cost: 0,\n max_position: 0,\n max_volume: 0,\n allow_long: true,\n allow_short: true,\n market_id: 'HYPERLIQUID/PERPETUAL',\n no_interest_rate: false,\n }),\n );\n\n // Combine all products\n return [...spotProducts, ...perpetualProducts];\n },\n {\n auto_refresh_interval: 86400_000, // Refresh daily (24 hours)\n },\n);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuants/vendor-hyperliquid",
3
- "version": "0.3.18",
3
+ "version": "0.3.19",
4
4
  "bin": "lib/cli.js",
5
5
  "main": "lib/index.js",
6
6
  "files": [
@@ -23,7 +23,7 @@
23
23
  "hyperliquid": "~1.6.2",
24
24
  "ethers": "~6.13.5",
25
25
  "@msgpack/msgpack": "~3.1.2",
26
- "@yuants/data-ohlc": "0.3.25"
26
+ "@yuants/data-ohlc": "0.4.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@microsoft/api-extractor": "~7.30.0",
@@ -1,19 +1,19 @@
1
1
  {
2
- "apps/vendor-hyperliquid/CHANGELOG.json": "1b4efcd8247dfe9eaa5027f435c1fdeaf018163e",
3
- "apps/vendor-hyperliquid/CHANGELOG.md": "77fbed91a9c952d96f5327bd665ccf0be6be29f3",
2
+ "apps/vendor-hyperliquid/CHANGELOG.json": "2563e2441fd434579ed72404f4df6455c00c2f0a",
3
+ "apps/vendor-hyperliquid/CHANGELOG.md": "806ed0a4eb3e3eff7572d814e29d4c5cd00e3a72",
4
4
  "apps/vendor-hyperliquid/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c",
5
5
  "apps/vendor-hyperliquid/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
6
6
  "apps/vendor-hyperliquid/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
7
7
  "apps/vendor-hyperliquid/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
8
8
  "apps/vendor-hyperliquid/etc/vendor-hyperliquid.api.md": "66675bd88afa1fe945f0d4023984c1c9c3e60a34",
9
- "apps/vendor-hyperliquid/package.json": "02d930a0040abe441b9e48da718d3383a8e503fe",
9
+ "apps/vendor-hyperliquid/package.json": "bb3a5f0bcf1625652cc5fb15689040ea3faca68a",
10
10
  "apps/vendor-hyperliquid/src/api.ts": "041aa6e0e322b7c6ea5c822119c695b05d32295a",
11
11
  "apps/vendor-hyperliquid/src/cli.ts": "9bf6b5559a6c6f33da20e74cc6c5d702c60ec891",
12
12
  "apps/vendor-hyperliquid/src/index.ts": "3332583b64a96e0a1126b925a8f5a44a86454b90",
13
- "apps/vendor-hyperliquid/src/interest_rate.ts": "5b46f8a4904734d9801e3ddd1146813918e36835",
13
+ "apps/vendor-hyperliquid/src/interest_rate.ts": "5a4decdc2d18f7d711c5217840d6be9d04d926b2",
14
14
  "apps/vendor-hyperliquid/src/ohlc.ts": "b1272944f0ffe8dd77ef9e7e39429efb7d2e5006",
15
15
  "apps/vendor-hyperliquid/src/order.ts": "de633327cb9ca8c02295f14d2d8a8b8384fdc1b4",
16
- "apps/vendor-hyperliquid/src/product.ts": "36081fdbea85de89a2745cb4815abcb05d1af294",
16
+ "apps/vendor-hyperliquid/src/product.ts": "1fd2995837e894004d9f8684b7e65cb8e85eaa66",
17
17
  "apps/vendor-hyperliquid/src/sign.ts": "94f4e5604a01d197d164b42415b17789ab2b6889",
18
18
  "apps/vendor-hyperliquid/tsconfig.json": "81da8f78196974b5d15da0edb6b2d9f48641063c",
19
19
  "apps/vendor-hyperliquid/.rush/temp/shrinkwrap-deps.json": "d8a15e8163d8abdb142a2024a5b5b13ab444f87b",
@@ -26,7 +26,7 @@
26
26
  "libraries/data-interest-rate/temp/package-deps.json": "246f09881d5bce801a352861086d7e2b90eb5b6b",
27
27
  "libraries/data-order/temp/package-deps.json": "add9a90c23442334f0575f403ef48dc33ceb5fd4",
28
28
  "libraries/data-series/temp/package-deps.json": "dd0d2f8322b484f074ae09c050ceb53fbc1368f4",
29
- "libraries/data-ohlc/temp/package-deps.json": "6ae0a1249855ee2e1aefd88a66f6d0c4a1f61dd5",
29
+ "libraries/data-ohlc/temp/package-deps.json": "01c6d44d10c9b10895a1a30ffee94d98975ce5d0",
30
30
  "libraries/extension/temp/package-deps.json": "1e2fec9acb35353b204eff0d4cc0af65c3b2582a",
31
31
  "tools/toolkit/temp/package-deps.json": "3bef053db16659f0cdaceea64c8a8580c0131633"
32
32
  }