@yuants/vendor-aster 0.3.17 → 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.
package/dist/account.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { provideAccountInfoService } from '@yuants/data-account';
2
2
  import { Terminal } from '@yuants/protocol';
3
+ import { encodePath } from '@yuants/utils';
3
4
  import { getFApiV4Account } from './api';
4
5
  const ADDRESS = process.env.ADDRESS;
5
6
  export const ACCOUNT_ID = `ASTER/${ADDRESS}`;
@@ -11,7 +12,7 @@ provideAccountInfoService(Terminal.fromNodeEnv(), ACCOUNT_ID, async () => {
11
12
  .filter((p) => +p.positionAmt !== 0)
12
13
  .map((p) => ({
13
14
  position_id: p.symbol,
14
- product_id: p.symbol,
15
+ product_id: encodePath('PERPETUAL', p.symbol),
15
16
  datasource_id: 'ASTER',
16
17
  direction: p.positionSide === 'BOTH' ? (+p.positionAmt > 0 ? 'LONG' : 'SHORT') : p.positionSide,
17
18
  volume: Math.abs(+p.positionAmt),
@@ -1 +1 @@
1
- {"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAEzC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAQ,CAAC;AACrC,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,OAAO,EAAE,CAAC;AAE7C,yBAAyB,CACvB,QAAQ,CAAC,WAAW,EAAE,EACtB,UAAU,EACV,KAAK,IAAI,EAAE;IACT,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;IAChE,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAEjC,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC;SACnC,GAAG,CACF,CAAC,CAAC,EAAa,EAAE,CAAC,CAAC;QACjB,WAAW,EAAE,CAAC,CAAC,MAAM;QACrB,UAAU,EAAE,CAAC,CAAC,MAAM;QACpB,aAAa,EAAE,OAAO;QACtB,SAAS,EAAE,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;QAC/F,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QAChC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QACrC,cAAc,EAAE,CAAC,CAAC,CAAC,UAAU;QAC7B,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;QACtD,eAAe,EAAE,CAAC,CAAC,CAAC,gBAAgB;QACpC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;KACjC,CAAC,CACH,CAAC;IACJ,OAAO;QACL,KAAK,EAAE;YACL,QAAQ,EAAE,KAAK;YACf,MAAM;YACN,IAAI;SACL;QACD,SAAS;KACV,CAAC;AACJ,CAAC,EACD,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAChC,CAAC","sourcesContent":["import { IPosition, provideAccountInfoService } from '@yuants/data-account';\nimport { Terminal } from '@yuants/protocol';\nimport { getFApiV4Account } from './api';\n\nconst ADDRESS = process.env.ADDRESS!;\nexport const ACCOUNT_ID = `ASTER/${ADDRESS}`;\n\nprovideAccountInfoService(\n Terminal.fromNodeEnv(),\n ACCOUNT_ID,\n async () => {\n const [a] = await Promise.all([getFApiV4Account({})]);\n\n const equity = +a.totalWalletBalance + +a.totalUnrealizedProfit;\n const free = +a.availableBalance;\n\n const positions = a.positions\n .filter((p) => +p.positionAmt !== 0)\n .map(\n (p): IPosition => ({\n position_id: p.symbol,\n product_id: p.symbol,\n datasource_id: 'ASTER',\n direction: p.positionSide === 'BOTH' ? (+p.positionAmt > 0 ? 'LONG' : 'SHORT') : p.positionSide,\n volume: Math.abs(+p.positionAmt),\n free_volume: Math.abs(+p.positionAmt),\n position_price: +p.entryPrice,\n closable_price: Math.abs(+p.notional / +p.positionAmt),\n floating_profit: +p.unrealizedProfit,\n valuation: Math.abs(+p.notional),\n }),\n );\n return {\n money: {\n currency: 'USD',\n equity,\n free,\n },\n positions,\n };\n },\n { auto_refresh_interval: 1000 },\n);\n"]}
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAEzC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAQ,CAAC;AACrC,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,OAAO,EAAE,CAAC;AAE7C,yBAAyB,CACvB,QAAQ,CAAC,WAAW,EAAE,EACtB,UAAU,EACV,KAAK,IAAI,EAAE;IACT,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;IAChE,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAEjC,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC;SACnC,GAAG,CACF,CAAC,CAAC,EAAa,EAAE,CAAC,CAAC;QACjB,WAAW,EAAE,CAAC,CAAC,MAAM;QACrB,UAAU,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QAC7C,aAAa,EAAE,OAAO;QACtB,SAAS,EAAE,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;QAC/F,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QAChC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QACrC,cAAc,EAAE,CAAC,CAAC,CAAC,UAAU;QAC7B,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;QACtD,eAAe,EAAE,CAAC,CAAC,CAAC,gBAAgB;QACpC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;KACjC,CAAC,CACH,CAAC;IACJ,OAAO;QACL,KAAK,EAAE;YACL,QAAQ,EAAE,KAAK;YACf,MAAM;YACN,IAAI;SACL;QACD,SAAS;KACV,CAAC;AACJ,CAAC,EACD,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAChC,CAAC","sourcesContent":["import { IPosition, provideAccountInfoService } from '@yuants/data-account';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { getFApiV4Account } from './api';\n\nconst ADDRESS = process.env.ADDRESS!;\nexport const ACCOUNT_ID = `ASTER/${ADDRESS}`;\n\nprovideAccountInfoService(\n Terminal.fromNodeEnv(),\n ACCOUNT_ID,\n async () => {\n const [a] = await Promise.all([getFApiV4Account({})]);\n\n const equity = +a.totalWalletBalance + +a.totalUnrealizedProfit;\n const free = +a.availableBalance;\n\n const positions = a.positions\n .filter((p) => +p.positionAmt !== 0)\n .map(\n (p): IPosition => ({\n position_id: p.symbol,\n product_id: encodePath('PERPETUAL', p.symbol),\n datasource_id: 'ASTER',\n direction: p.positionSide === 'BOTH' ? (+p.positionAmt > 0 ? 'LONG' : 'SHORT') : p.positionSide,\n volume: Math.abs(+p.positionAmt),\n free_volume: Math.abs(+p.positionAmt),\n position_price: +p.entryPrice,\n closable_price: Math.abs(+p.notional / +p.positionAmt),\n floating_profit: +p.unrealizedProfit,\n valuation: Math.abs(+p.notional),\n }),\n );\n return {\n money: {\n currency: 'USD',\n equity,\n free,\n },\n positions,\n };\n },\n { auto_refresh_interval: 1000 },\n);\n"]}
package/dist/api.js CHANGED
@@ -41,6 +41,8 @@ const createApi = (type, method, endpoint) => (params) => request(type, method,
41
41
  export const getFApiV4Account = createApi('USER_DATA', 'GET', '/fapi/v4/account');
42
42
  export const getFApiV2Balance = createApi('USER_DATA', 'GET', '/fapi/v2/balance');
43
43
  export const postFApiV1Order = createApi('TRADE', 'POST', '/fapi/v1/order');
44
+ export const getFApiV1OpenOrders = createApi('USER_DATA', 'GET', '/fapi/v1/openOrders');
45
+ export const deleteFApiV1Order = createApi('TRADE', 'DELETE', '/fapi/v1/order');
44
46
  /**
45
47
  * 获取交易对信息
46
48
  *
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAQ,CAAC;AACrC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,UAAW,CAAC;AAE3C,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAE7C,MAAM,OAAO,GAAG,KAAK,EACnB,IAAoE,EACpE,MAAc,EACd,QAAgB,EAChB,SAAc,EAAE,EACJ,EAAE;IACd,MAAM,UAAU,GAAG,IAAI,KAAK,MAAM,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,WAAW,CAAC;IAE1D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACjD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;KACvC;IAED,IAAI,QAAQ,EAAE;QACZ,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;QAC7C,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC/D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;KAC9C;IAED,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;QACtC,MAAM;QACN,OAAO,EAAE,UAAU;YACjB,CAAC,CAAC;gBACE,cAAc,EAAE,OAAO;aACxB;YACH,CAAC,CAAC,EAAE;KACP,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE;QAC9B,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;KAC3B;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,SAAS,GACb,CACE,IAAoE,EACpE,MAAc,EACd,QAAgB,EAChB,EAAE,CACJ,CAAC,MAAY,EAAE,EAAE,CACf,OAAO,CAAO,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,CAqDvC,WAAW,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;AAE1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,CAavC,WAAW,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;AAE1C,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,CAmBtC,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAErC;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAkB5C,MAAM,EAAE,KAAK,EAAE,uBAAuB,CAAC,CAAC","sourcesContent":["import { opensslEquivalentHMAC } from './utils';\n\nconst API_KEY = process.env.API_KEY!;\nconst SECRET_KEY = process.env.SECRET_KEY!;\n\nconst BASE_URL = 'https://fapi.asterdex.com';\n\nconst request = async <T>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n params: any = {},\n): Promise<T> => {\n const needApiKey = type !== 'NONE';\n const needSign = type === 'TRADE' || type === 'USER_DATA';\n\n const url = new URL(BASE_URL);\n url.pathname = endpoint;\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n url.searchParams.set(key, `${value}`);\n }\n\n if (needSign) {\n url.searchParams.set('timestamp', `${Date.now()}`);\n const msg = url.search.slice(1); // 去掉开头的 '?'\n const signature = await opensslEquivalentHMAC(msg, SECRET_KEY);\n url.searchParams.set('signature', signature);\n }\n\n console.info(url.toString());\n const res = await fetch(url.toString(), {\n method,\n headers: needApiKey\n ? {\n 'X-MBX-APIKEY': API_KEY,\n }\n : {},\n }).then((response) => response.json());\n if (res.code && res.code !== 0) {\n throw JSON.stringify(res);\n }\n return res;\n};\n\nconst createApi =\n <TReq, TRes>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n ) =>\n (params: TReq) =>\n request<TRes>(type, method, endpoint, params);\n\n/**\n * 获取账户信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data\n */\nexport const getFApiV4Account = createApi<\n {},\n {\n feeTier: number;\n canTrade: boolean;\n canDeposit: boolean;\n canWithdraw: boolean;\n updateTime: number;\n totalInitialMargin: string;\n totalMaintMargin: string;\n totalWalletBalance: string;\n totalUnrealizedProfit: string;\n totalMarginBalance: string;\n totalPositionInitialMargin: string;\n totalOpenOrderInitialMargin: string;\n totalCrossWalletBalance: string;\n totalCrossUnPnl: string;\n availableBalance: string;\n maxWithdrawAmount: string;\n assets: {\n asset: string;\n walletBalance: string;\n unrealizedProfit: string;\n marginBalance: string;\n maintMargin: string;\n initialMargin: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n maxWithdrawAmount: string;\n crossWalletBalance: string;\n crossUnPnl: string;\n availableBalance: string;\n marginAvailable: boolean;\n updateTime: number;\n }[];\n positions: {\n symbol: string;\n initialMargin: string;\n maintMargin: string;\n unrealizedProfit: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n leverage: string;\n isolated: boolean;\n entryPrice: string;\n maxNotional: string;\n positionSide: 'BOTH' | 'LONG' | 'SHORT';\n positionAmt: string;\n notional: string;\n isolatedWallet: string;\n updateTime: number;\n }[];\n }\n>('USER_DATA', 'GET', '/fapi/v4/account');\n\nexport const getFApiV2Balance = createApi<\n {},\n {\n accountAlias: string; // 账户唯一识别码\n asset: string; // 资产\n balance: string; // 总余额\n crossWalletBalance: string; // 全仓余额\n crossUnPnl: string; // 全仓持仓未实现盈亏\n availableBalance: string; // 下单可用余额\n maxWithdrawAmount: string; // 最大可转出余额\n marginAvailable: boolean; // 是否可用作联合保证金\n updateTime: number;\n }[]\n>('USER_DATA', 'GET', '/fapi/v2/balance');\n\nexport const postFApiV1Order = createApi<\n {\n symbol: string;\n side: 'BUY' | 'SELL';\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n type:\n | 'MARKET'\n | 'LIMIT'\n | 'STOP'\n | 'STOP_MARKET'\n | 'TAKE_PROFIT'\n | 'TAKE_PROFIT_MARKET'\n | 'TRAILING_STOP_MARKET';\n reduceOnly?: 'true' | 'false';\n quantity?: number;\n price?: number;\n timeInForce?: 'GTC' | 'IOC' | 'FOK' | 'GTX' | 'HIDDEN';\n },\n {}\n>('TRADE', 'POST', '/fapi/v1/order');\n\n/**\n * 获取交易对信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E4%BA%A4%E6%98%93%E5%AF%B9%E4%BF%A1%E6%81%AF\n */\nexport const getFApiV1ExchangeInfo = createApi<\n {},\n {\n symbols: {\n symbol: string;\n status: 'TRADING' | 'BREAK' | 'HALT';\n baseAsset: string;\n quoteAsset: string;\n pricePrecision: number;\n quantityPrecision: number;\n baseAssetPrecision: number;\n quotePrecision: number;\n filters: {\n filterType: string;\n [key: string]: any;\n }[];\n }[];\n }\n>('NONE', 'GET', '/fapi/v1/exchangeInfo');\n"]}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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","sourcesContent":["import { opensslEquivalentHMAC } from './utils';\n\nconst API_KEY = process.env.API_KEY!;\nconst SECRET_KEY = process.env.SECRET_KEY!;\n\nconst BASE_URL = 'https://fapi.asterdex.com';\n\nconst request = async <T>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n params: any = {},\n): Promise<T> => {\n const needApiKey = type !== 'NONE';\n const needSign = type === 'TRADE' || type === 'USER_DATA';\n\n const url = new URL(BASE_URL);\n url.pathname = endpoint;\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n url.searchParams.set(key, `${value}`);\n }\n\n if (needSign) {\n url.searchParams.set('timestamp', `${Date.now()}`);\n const msg = url.search.slice(1); // 去掉开头的 '?'\n const signature = await opensslEquivalentHMAC(msg, SECRET_KEY);\n url.searchParams.set('signature', signature);\n }\n\n console.info(url.toString());\n const res = await fetch(url.toString(), {\n method,\n headers: needApiKey\n ? {\n 'X-MBX-APIKEY': API_KEY,\n }\n : {},\n }).then((response) => response.json());\n if (res.code && res.code !== 0) {\n throw JSON.stringify(res);\n }\n return res;\n};\n\nconst createApi =\n <TReq, TRes>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n ) =>\n (params: TReq) =>\n request<TRes>(type, method, endpoint, params);\n\n/**\n * 获取账户信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data\n */\nexport const getFApiV4Account = createApi<\n {},\n {\n feeTier: number;\n canTrade: boolean;\n canDeposit: boolean;\n canWithdraw: boolean;\n updateTime: number;\n totalInitialMargin: string;\n totalMaintMargin: string;\n totalWalletBalance: string;\n totalUnrealizedProfit: string;\n totalMarginBalance: string;\n totalPositionInitialMargin: string;\n totalOpenOrderInitialMargin: string;\n totalCrossWalletBalance: string;\n totalCrossUnPnl: string;\n availableBalance: string;\n maxWithdrawAmount: string;\n assets: {\n asset: string;\n walletBalance: string;\n unrealizedProfit: string;\n marginBalance: string;\n maintMargin: string;\n initialMargin: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n maxWithdrawAmount: string;\n crossWalletBalance: string;\n crossUnPnl: string;\n availableBalance: string;\n marginAvailable: boolean;\n updateTime: number;\n }[];\n positions: {\n symbol: string;\n initialMargin: string;\n maintMargin: string;\n unrealizedProfit: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n leverage: string;\n isolated: boolean;\n entryPrice: string;\n maxNotional: string;\n positionSide: 'BOTH' | 'LONG' | 'SHORT';\n positionAmt: string;\n notional: string;\n isolatedWallet: string;\n updateTime: number;\n }[];\n }\n>('USER_DATA', 'GET', '/fapi/v4/account');\n\nexport const getFApiV2Balance = createApi<\n {},\n {\n accountAlias: string; // 账户唯一识别码\n asset: string; // 资产\n balance: string; // 总余额\n crossWalletBalance: string; // 全仓余额\n crossUnPnl: string; // 全仓持仓未实现盈亏\n availableBalance: string; // 下单可用余额\n maxWithdrawAmount: string; // 最大可转出余额\n marginAvailable: boolean; // 是否可用作联合保证金\n updateTime: number;\n }[]\n>('USER_DATA', 'GET', '/fapi/v2/balance');\n\nexport const postFApiV1Order = createApi<\n {\n symbol: string;\n side: 'BUY' | 'SELL';\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n type:\n | 'MARKET'\n | 'LIMIT'\n | 'STOP'\n | 'STOP_MARKET'\n | 'TAKE_PROFIT'\n | 'TAKE_PROFIT_MARKET'\n | 'TRAILING_STOP_MARKET';\n reduceOnly?: 'true' | 'false';\n quantity?: number;\n price?: number;\n timeInForce?: 'GTC' | 'IOC' | 'FOK' | 'GTX' | 'HIDDEN';\n },\n {}\n>('TRADE', 'POST', '/fapi/v1/order');\n\nexport const getFApiV1OpenOrders = createApi<\n {\n symbol?: string;\n },\n {\n orderId: number;\n clientOrderId: string;\n price: string;\n origQty: string;\n executedQty: string;\n status: string;\n timeInForce: string;\n type: string;\n side: 'BUY' | 'SELL';\n updateTime: number;\n avgPrice: string;\n reduceOnly?: boolean;\n closePosition?: boolean;\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n workingType?: string;\n priceProtect?: boolean;\n origType?: string;\n stopPrice?: string;\n symbol: string;\n }[]\n>('USER_DATA', 'GET', '/fapi/v1/openOrders');\n\nexport const deleteFApiV1Order = createApi<\n {\n symbol: string;\n orderId?: string | number;\n origClientOrderId?: string;\n },\n {}\n>('TRADE', 'DELETE', '/fapi/v1/order');\n\n/**\n * 获取交易对信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E4%BA%A4%E6%98%93%E5%AF%B9%E4%BF%A1%E6%81%AF\n */\nexport const getFApiV1ExchangeInfo = createApi<\n {},\n {\n symbols: {\n symbol: string;\n status: 'TRADING' | 'BREAK' | 'HALT';\n baseAsset: string;\n quoteAsset: string;\n pricePrecision: number;\n quantityPrecision: number;\n baseAssetPrecision: number;\n quotePrecision: number;\n filters: {\n filterType: string;\n [key: string]: any;\n }[];\n }[];\n }\n>('NONE', 'GET', '/fapi/v1/exchangeInfo');\n"]}
package/dist/index.js CHANGED
@@ -3,4 +3,5 @@ import './account-spot';
3
3
  import './order';
4
4
  import './order-spot';
5
5
  import './product'; // Import the new product service
6
+ import './pending-orders';
6
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAC;AACnB,OAAO,gBAAgB,CAAC;AACxB,OAAO,SAAS,CAAC;AACjB,OAAO,cAAc,CAAC;AACtB,OAAO,WAAW,CAAC,CAAC,iCAAiC","sourcesContent":["import './account';\nimport './account-spot';\nimport './order';\nimport './order-spot';\nimport './product'; // Import the new product service\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAC;AACnB,OAAO,gBAAgB,CAAC;AACxB,OAAO,SAAS,CAAC;AACjB,OAAO,cAAc,CAAC;AACtB,OAAO,WAAW,CAAC,CAAC,iCAAiC;AACrD,OAAO,kBAAkB,CAAC","sourcesContent":["import './account';\nimport './account-spot';\nimport './order';\nimport './order-spot';\nimport './product'; // Import the new product service\nimport './pending-orders';\n"]}
package/dist/order.js CHANGED
@@ -1,10 +1,15 @@
1
1
  import { Terminal } from '@yuants/protocol';
2
+ import { decodePath } from '@yuants/utils';
2
3
  import { ACCOUNT_ID } from './account';
3
- import { postFApiV1Order } from './api';
4
+ import { deleteFApiV1Order, postFApiV1Order } from './api';
4
5
  const terminal = Terminal.fromNodeEnv();
5
6
  terminal.server.provideService('SubmitOrder', { required: ['account_id'], properties: { account_id: { type: 'string', const: ACCOUNT_ID } } }, async (msg) => {
6
7
  const order = msg.req;
7
- const symbol = order.product_id;
8
+ const [, decodedSymbol] = decodePath(order.product_id);
9
+ if (!decodedSymbol) {
10
+ throw new Error(`Invalid product_id: unable to decode symbol from "${order.product_id}"`);
11
+ }
12
+ const symbol = decodedSymbol;
8
13
  const side = { OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' }[order.order_direction];
9
14
  if (!side)
10
15
  throw new Error(`Unsupported order_direction: ${order.order_direction}`);
@@ -24,4 +29,26 @@ terminal.server.provideService('SubmitOrder', { required: ['account_id'], proper
24
29
  });
25
30
  return { res: { code: 0, message: 'OK' } };
26
31
  });
32
+ terminal.server.provideService('CancelOrder', {
33
+ required: ['account_id', 'order_id', 'product_id'],
34
+ properties: {
35
+ account_id: { type: 'string', const: ACCOUNT_ID },
36
+ order_id: { type: ['string', 'number'] },
37
+ product_id: { type: 'string' },
38
+ },
39
+ }, async (msg) => {
40
+ const order = msg.req;
41
+ const [, decodedSymbol] = decodePath(order.product_id);
42
+ if (!decodedSymbol) {
43
+ throw new Error(`Invalid product_id: unable to decode symbol from "${order.product_id}"`);
44
+ }
45
+ if (!order.order_id) {
46
+ throw new Error('order_id is required for CancelOrder');
47
+ }
48
+ await deleteFApiV1Order({
49
+ symbol: decodedSymbol,
50
+ orderId: order.order_id,
51
+ });
52
+ return { res: { code: 0, message: 'OK' } };
53
+ });
27
54
  //# sourceMappingURL=order.js.map
package/dist/order.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"order.js","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAExC,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,aAAa,EACb,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,EAC/F,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC;IAEtB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC;IAEhC,MAAM,IAAI,GAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAY,CACtG,KAAK,CAAC,eAAgB,CACvB,CAAC;IACF,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC;IAEpF,MAAM,IAAI,GAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAY,CAAC,KAAK,CAAC,UAAW,CAAC,CAAC;IAChG,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAE1E,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;IAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAE1B,MAAM,WAAW,GACf,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAE1F,MAAM,eAAe,CAAC;QACpB,MAAM;QACN,IAAI;QACJ,IAAI;QACJ,QAAQ;QACR,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;AAC7C,CAAC,CACF,CAAC","sourcesContent":["import { Terminal } from '@yuants/protocol';\nimport { IOrder } from '@yuants/data-order';\nimport { ACCOUNT_ID } from './account';\nimport { postFApiV1Order } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<IOrder>(\n 'SubmitOrder',\n { required: ['account_id'], properties: { account_id: { type: 'string', const: ACCOUNT_ID } } },\n async (msg) => {\n const order = msg.req;\n\n const symbol = order.product_id;\n\n const side = ({ OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' } as const)[\n order.order_direction!\n ];\n if (!side) throw new Error(`Unsupported order_direction: ${order.order_direction}`);\n\n const type = ({ MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' } as const)[order.order_type!];\n if (!type) throw new Error(`Unsupported order_type: ${order.order_type}`);\n\n const quantity = order.volume;\n const price = order.price;\n\n const timeInForce =\n order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n\n await postFApiV1Order({\n symbol,\n side,\n type,\n quantity,\n price,\n timeInForce,\n });\n\n return { res: { code: 0, message: 'OK' } };\n },\n);\n"]}
1
+ {"version":3,"file":"order.js","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAE3D,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,aAAa,EACb,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,EAC/F,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC;IAEtB,MAAM,CAAC,EAAE,aAAa,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACvD,IAAI,CAAC,aAAa,EAAE;QAClB,MAAM,IAAI,KAAK,CAAC,qDAAqD,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC;KAC3F;IACD,MAAM,MAAM,GAAG,aAAa,CAAC;IAE7B,MAAM,IAAI,GAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAY,CACtG,KAAK,CAAC,eAAgB,CACvB,CAAC;IACF,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC;IAEpF,MAAM,IAAI,GAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAY,CAAC,KAAK,CAAC,UAAW,CAAC,CAAC;IAChG,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAE1E,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;IAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAE1B,MAAM,WAAW,GACf,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAE1F,MAAM,eAAe,CAAC;QACpB,MAAM;QACN,IAAI;QACJ,IAAI;QACJ,QAAQ;QACR,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;AAC7C,CAAC,CACF,CAAC;AAEF,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,aAAa,EACb;IACE,QAAQ,EAAE,CAAC,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC;IAClD,UAAU,EAAE;QACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE;QACjD,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE;QACxC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC/B;CACF,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC;IACtB,MAAM,CAAC,EAAE,aAAa,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACvD,IAAI,CAAC,aAAa,EAAE;QAClB,MAAM,IAAI,KAAK,CAAC,qDAAqD,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC;KAC3F;IACD,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;QACnB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;KACzD;IAED,MAAM,iBAAiB,CAAC;QACtB,MAAM,EAAE,aAAa;QACrB,OAAO,EAAE,KAAK,CAAC,QAAQ;KACxB,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;AAC7C,CAAC,CACF,CAAC","sourcesContent":["import { Terminal } from '@yuants/protocol';\nimport { IOrder } from '@yuants/data-order';\nimport { decodePath } from '@yuants/utils';\nimport { ACCOUNT_ID } from './account';\nimport { deleteFApiV1Order, postFApiV1Order } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<IOrder>(\n 'SubmitOrder',\n { required: ['account_id'], properties: { account_id: { type: 'string', const: ACCOUNT_ID } } },\n async (msg) => {\n const order = msg.req;\n\n const [, decodedSymbol] = decodePath(order.product_id);\n if (!decodedSymbol) {\n throw new Error(`Invalid product_id: unable to decode symbol from \"${order.product_id}\"`);\n }\n const symbol = decodedSymbol;\n\n const side = ({ OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' } as const)[\n order.order_direction!\n ];\n if (!side) throw new Error(`Unsupported order_direction: ${order.order_direction}`);\n\n const type = ({ MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' } as const)[order.order_type!];\n if (!type) throw new Error(`Unsupported order_type: ${order.order_type}`);\n\n const quantity = order.volume;\n const price = order.price;\n\n const timeInForce =\n order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n\n await postFApiV1Order({\n symbol,\n side,\n type,\n quantity,\n price,\n timeInForce,\n });\n\n return { res: { code: 0, message: 'OK' } };\n },\n);\n\nterminal.server.provideService<IOrder>(\n 'CancelOrder',\n {\n required: ['account_id', 'order_id', 'product_id'],\n properties: {\n account_id: { type: 'string', const: ACCOUNT_ID },\n order_id: { type: ['string', 'number'] },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const order = msg.req;\n const [, decodedSymbol] = decodePath(order.product_id);\n if (!decodedSymbol) {\n throw new Error(`Invalid product_id: unable to decode symbol from \"${order.product_id}\"`);\n }\n if (!order.order_id) {\n throw new Error('order_id is required for CancelOrder');\n }\n\n await deleteFApiV1Order({\n symbol: decodedSymbol,\n orderId: order.order_id,\n });\n\n return { res: { code: 0, message: 'OK' } };\n },\n);\n"]}
@@ -0,0 +1,43 @@
1
+ import { providePendingOrdersService } from '@yuants/data-order';
2
+ import { Terminal } from '@yuants/protocol';
3
+ import { encodePath } from '@yuants/utils';
4
+ import { ACCOUNT_ID } from './account';
5
+ import { getFApiV1OpenOrders } from './api';
6
+ const terminal = Terminal.fromNodeEnv();
7
+ const resolveOrderDirection = (asterOrder) => {
8
+ const reduceOnly = asterOrder.reduceOnly || asterOrder.closePosition;
9
+ if (asterOrder.positionSide === 'LONG') {
10
+ return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'CLOSE_LONG';
11
+ }
12
+ if (asterOrder.positionSide === 'SHORT') {
13
+ return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'OPEN_SHORT';
14
+ }
15
+ if (reduceOnly) {
16
+ return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'CLOSE_LONG';
17
+ }
18
+ return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'OPEN_SHORT';
19
+ };
20
+ providePendingOrdersService(terminal, ACCOUNT_ID, async () => {
21
+ const orders = (await getFApiV1OpenOrders({}));
22
+ return orders.map((order) => {
23
+ const volume = Number(order.origQty);
24
+ const tradedVolume = Number(order.executedQty);
25
+ const price = Number(order.price);
26
+ const avgPrice = Number(order.avgPrice);
27
+ const mapped = {
28
+ order_id: `${order.orderId}`,
29
+ account_id: ACCOUNT_ID,
30
+ product_id: encodePath('PERPETUAL', order.symbol),
31
+ order_type: order.type,
32
+ order_direction: resolveOrderDirection(order),
33
+ volume: Number.isFinite(volume) ? volume : 0,
34
+ price: Number.isFinite(price) ? price : undefined,
35
+ submit_at: order.updateTime,
36
+ traded_volume: Number.isFinite(tradedVolume) ? tradedVolume : undefined,
37
+ traded_price: Number.isFinite(avgPrice) && avgPrice > 0 ? avgPrice : undefined,
38
+ order_status: order.status,
39
+ };
40
+ return mapped;
41
+ });
42
+ }, { auto_refresh_interval: 2000 });
43
+ //# sourceMappingURL=pending-orders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-orders.js","sourceRoot":"","sources":["../src/pending-orders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAE5C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAoBxC,MAAM,qBAAqB,GAAG,CAAC,UAA2B,EAAkB,EAAE;IAC5E,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,IAAI,UAAU,CAAC,aAAa,CAAC;IAErE,IAAI,UAAU,CAAC,YAAY,KAAK,MAAM,EAAE;QACtC,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;KAC/D;IACD,IAAI,UAAU,CAAC,YAAY,KAAK,OAAO,EAAE;QACvC,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC;KACjE;IACD,IAAI,UAAU,EAAE;QACd,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC;KACjE;IACD,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;AAChE,CAAC,CAAC;AAEF,2BAA2B,CACzB,QAAQ,EACR,UAAU,EACV,KAAK,IAAI,EAAE;IACT,MAAM,MAAM,GAAG,CAAC,MAAM,mBAAmB,CAAC,EAAE,CAAC,CAAsB,CAAC;IACpE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAExC,MAAM,MAAM,GAAW;YACrB,QAAQ,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE;YAC5B,UAAU,EAAE,UAAU;YACtB,UAAU,EAAE,UAAU,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC;YACjD,UAAU,EAAE,KAAK,CAAC,IAAI;YACtB,eAAe,EAAE,qBAAqB,CAAC,KAAK,CAAC;YAC7C,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC5C,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;YACjD,SAAS,EAAE,KAAK,CAAC,UAAU;YAC3B,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;YACvE,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YAC9E,YAAY,EAAE,KAAK,CAAC,MAAM;SAC3B,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,EACD,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAChC,CAAC","sourcesContent":["import { IOrder, providePendingOrdersService } from '@yuants/data-order';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { ACCOUNT_ID } from './account';\nimport { getFApiV1OpenOrders } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\ntype OrderDirection = 'OPEN_LONG' | 'OPEN_SHORT' | 'CLOSE_LONG' | 'CLOSE_SHORT';\n\ninterface IAsterOpenOrder {\n orderId: number;\n symbol: string;\n side: 'BUY' | 'SELL';\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n reduceOnly?: boolean;\n closePosition?: boolean;\n type: string;\n origQty: string;\n executedQty: string;\n price: string;\n avgPrice: string;\n status: string;\n updateTime: number;\n}\n\nconst resolveOrderDirection = (asterOrder: IAsterOpenOrder): OrderDirection => {\n const reduceOnly = asterOrder.reduceOnly || asterOrder.closePosition;\n\n if (asterOrder.positionSide === 'LONG') {\n return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'CLOSE_LONG';\n }\n if (asterOrder.positionSide === 'SHORT') {\n return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'OPEN_SHORT';\n }\n if (reduceOnly) {\n return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'CLOSE_LONG';\n }\n return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'OPEN_SHORT';\n};\n\nprovidePendingOrdersService(\n terminal,\n ACCOUNT_ID,\n async () => {\n const orders = (await getFApiV1OpenOrders({})) as IAsterOpenOrder[];\n return orders.map((order) => {\n const volume = Number(order.origQty);\n const tradedVolume = Number(order.executedQty);\n const price = Number(order.price);\n const avgPrice = Number(order.avgPrice);\n\n const mapped: IOrder = {\n order_id: `${order.orderId}`,\n account_id: ACCOUNT_ID,\n product_id: encodePath('PERPETUAL', order.symbol),\n order_type: order.type,\n order_direction: resolveOrderDirection(order),\n volume: Number.isFinite(volume) ? volume : 0,\n price: Number.isFinite(price) ? price : undefined,\n submit_at: order.updateTime,\n traded_volume: Number.isFinite(tradedVolume) ? tradedVolume : undefined,\n traded_price: Number.isFinite(avgPrice) && avgPrice > 0 ? avgPrice : undefined,\n order_status: order.status,\n };\n\n return mapped;\n });\n },\n { auto_refresh_interval: 2000 },\n);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,UAAU,QAAqB,CAAC"}
1
+ {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,UAAU,QAAqB,CAAC"}
package/lib/account.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ACCOUNT_ID = void 0;
4
4
  const data_account_1 = require("@yuants/data-account");
5
5
  const protocol_1 = require("@yuants/protocol");
6
+ const utils_1 = require("@yuants/utils");
6
7
  const api_1 = require("./api");
7
8
  const ADDRESS = process.env.ADDRESS;
8
9
  exports.ACCOUNT_ID = `ASTER/${ADDRESS}`;
@@ -14,7 +15,7 @@ exports.ACCOUNT_ID = `ASTER/${ADDRESS}`;
14
15
  .filter((p) => +p.positionAmt !== 0)
15
16
  .map((p) => ({
16
17
  position_id: p.symbol,
17
- product_id: p.symbol,
18
+ product_id: (0, utils_1.encodePath)('PERPETUAL', p.symbol),
18
19
  datasource_id: 'ASTER',
19
20
  direction: p.positionSide === 'BOTH' ? (+p.positionAmt > 0 ? 'LONG' : 'SHORT') : p.positionSide,
20
21
  volume: Math.abs(+p.positionAmt),
@@ -1 +1 @@
1
- {"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":";;;AAAA,uDAA4E;AAC5E,+CAA4C;AAC5C,+BAAyC;AAEzC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAQ,CAAC;AACxB,QAAA,UAAU,GAAG,SAAS,OAAO,EAAE,CAAC;AAE7C,IAAA,wCAAyB,EACvB,mBAAQ,CAAC,WAAW,EAAE,EACtB,kBAAU,EACV,KAAK,IAAI,EAAE;IACT,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAA,sBAAgB,EAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;IAChE,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAEjC,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC;SACnC,GAAG,CACF,CAAC,CAAC,EAAa,EAAE,CAAC,CAAC;QACjB,WAAW,EAAE,CAAC,CAAC,MAAM;QACrB,UAAU,EAAE,CAAC,CAAC,MAAM;QACpB,aAAa,EAAE,OAAO;QACtB,SAAS,EAAE,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;QAC/F,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QAChC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QACrC,cAAc,EAAE,CAAC,CAAC,CAAC,UAAU;QAC7B,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;QACtD,eAAe,EAAE,CAAC,CAAC,CAAC,gBAAgB;QACpC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;KACjC,CAAC,CACH,CAAC;IACJ,OAAO;QACL,KAAK,EAAE;YACL,QAAQ,EAAE,KAAK;YACf,MAAM;YACN,IAAI;SACL;QACD,SAAS;KACV,CAAC;AACJ,CAAC,EACD,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAChC,CAAC","sourcesContent":["import { IPosition, provideAccountInfoService } from '@yuants/data-account';\nimport { Terminal } from '@yuants/protocol';\nimport { getFApiV4Account } from './api';\n\nconst ADDRESS = process.env.ADDRESS!;\nexport const ACCOUNT_ID = `ASTER/${ADDRESS}`;\n\nprovideAccountInfoService(\n Terminal.fromNodeEnv(),\n ACCOUNT_ID,\n async () => {\n const [a] = await Promise.all([getFApiV4Account({})]);\n\n const equity = +a.totalWalletBalance + +a.totalUnrealizedProfit;\n const free = +a.availableBalance;\n\n const positions = a.positions\n .filter((p) => +p.positionAmt !== 0)\n .map(\n (p): IPosition => ({\n position_id: p.symbol,\n product_id: p.symbol,\n datasource_id: 'ASTER',\n direction: p.positionSide === 'BOTH' ? (+p.positionAmt > 0 ? 'LONG' : 'SHORT') : p.positionSide,\n volume: Math.abs(+p.positionAmt),\n free_volume: Math.abs(+p.positionAmt),\n position_price: +p.entryPrice,\n closable_price: Math.abs(+p.notional / +p.positionAmt),\n floating_profit: +p.unrealizedProfit,\n valuation: Math.abs(+p.notional),\n }),\n );\n return {\n money: {\n currency: 'USD',\n equity,\n free,\n },\n positions,\n };\n },\n { auto_refresh_interval: 1000 },\n);\n"]}
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":";;;AAAA,uDAA4E;AAC5E,+CAA4C;AAC5C,yCAA2C;AAC3C,+BAAyC;AAEzC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAQ,CAAC;AACxB,QAAA,UAAU,GAAG,SAAS,OAAO,EAAE,CAAC;AAE7C,IAAA,wCAAyB,EACvB,mBAAQ,CAAC,WAAW,EAAE,EACtB,kBAAU,EACV,KAAK,IAAI,EAAE;IACT,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAA,sBAAgB,EAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;IAChE,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAEjC,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC;SACnC,GAAG,CACF,CAAC,CAAC,EAAa,EAAE,CAAC,CAAC;QACjB,WAAW,EAAE,CAAC,CAAC,MAAM;QACrB,UAAU,EAAE,IAAA,kBAAU,EAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QAC7C,aAAa,EAAE,OAAO;QACtB,SAAS,EAAE,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;QAC/F,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QAChC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QACrC,cAAc,EAAE,CAAC,CAAC,CAAC,UAAU;QAC7B,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;QACtD,eAAe,EAAE,CAAC,CAAC,CAAC,gBAAgB;QACpC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;KACjC,CAAC,CACH,CAAC;IACJ,OAAO;QACL,KAAK,EAAE;YACL,QAAQ,EAAE,KAAK;YACf,MAAM;YACN,IAAI;SACL;QACD,SAAS;KACV,CAAC;AACJ,CAAC,EACD,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAChC,CAAC","sourcesContent":["import { IPosition, provideAccountInfoService } from '@yuants/data-account';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { getFApiV4Account } from './api';\n\nconst ADDRESS = process.env.ADDRESS!;\nexport const ACCOUNT_ID = `ASTER/${ADDRESS}`;\n\nprovideAccountInfoService(\n Terminal.fromNodeEnv(),\n ACCOUNT_ID,\n async () => {\n const [a] = await Promise.all([getFApiV4Account({})]);\n\n const equity = +a.totalWalletBalance + +a.totalUnrealizedProfit;\n const free = +a.availableBalance;\n\n const positions = a.positions\n .filter((p) => +p.positionAmt !== 0)\n .map(\n (p): IPosition => ({\n position_id: p.symbol,\n product_id: encodePath('PERPETUAL', p.symbol),\n datasource_id: 'ASTER',\n direction: p.positionSide === 'BOTH' ? (+p.positionAmt > 0 ? 'LONG' : 'SHORT') : p.positionSide,\n volume: Math.abs(+p.positionAmt),\n free_volume: Math.abs(+p.positionAmt),\n position_price: +p.entryPrice,\n closable_price: Math.abs(+p.notional / +p.positionAmt),\n floating_profit: +p.unrealizedProfit,\n valuation: Math.abs(+p.notional),\n }),\n );\n return {\n money: {\n currency: 'USD',\n equity,\n free,\n },\n positions,\n };\n },\n { auto_refresh_interval: 1000 },\n);\n"]}
package/lib/api.d.ts CHANGED
@@ -75,6 +75,34 @@ export declare const postFApiV1Order: (params: {
75
75
  price?: number | undefined;
76
76
  timeInForce?: "GTC" | "IOC" | "FOK" | "GTX" | "HIDDEN" | undefined;
77
77
  }) => Promise<{}>;
78
+ export declare const getFApiV1OpenOrders: (params: {
79
+ symbol?: string | undefined;
80
+ }) => Promise<{
81
+ orderId: number;
82
+ clientOrderId: string;
83
+ price: string;
84
+ origQty: string;
85
+ executedQty: string;
86
+ status: string;
87
+ timeInForce: string;
88
+ type: string;
89
+ side: 'BUY' | 'SELL';
90
+ updateTime: number;
91
+ avgPrice: string;
92
+ reduceOnly?: boolean | undefined;
93
+ closePosition?: boolean | undefined;
94
+ positionSide?: "LONG" | "BOTH" | "SHORT" | undefined;
95
+ workingType?: string | undefined;
96
+ priceProtect?: boolean | undefined;
97
+ origType?: string | undefined;
98
+ stopPrice?: string | undefined;
99
+ symbol: string;
100
+ }[]>;
101
+ export declare const deleteFApiV1Order: (params: {
102
+ symbol: string;
103
+ orderId?: string | number | undefined;
104
+ origClientOrderId?: string | undefined;
105
+ }) => Promise<{}>;
78
106
  /**
79
107
  * 获取交易对信息
80
108
  *
package/lib/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAsDA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;aAGhB,MAAM;cACL,OAAO;gBACL,OAAO;iBACN,OAAO;gBACR,MAAM;wBACE,MAAM;sBACR,MAAM;wBACJ,MAAM;2BACH,MAAM;wBACT,MAAM;gCACE,MAAM;iCACL,MAAM;6BACV,MAAM;qBACd,MAAM;sBACL,MAAM;uBACL,MAAM;YACjB;QACN,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,OAAO,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;KACpB,EAAE;eACQ;QACT,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,gBAAgB,EAAE,MAAM,CAAC;QACzB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;QACxC,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;KACpB,EAAE;EAEkC,CAAC;AAE1C,eAAO,MAAM,gBAAgB;kBAGX,MAAM;WACb,MAAM;aACJ,MAAM;wBACK,MAAM;gBACd,MAAM;sBACA,MAAM;uBACL,MAAM;qBACR,OAAO;gBACZ,MAAM;IAEmB,CAAC;AAE1C,eAAO,MAAM,eAAe;YAEhB,MAAM;UACR,KAAK,GAAG,MAAM;;UAGhB,QAAQ,GACR,OAAO,GACP,MAAM,GACN,aAAa,GACb,aAAa,GACb,oBAAoB,GACpB,sBAAsB;;;;;iBAOM,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;gBAIpB,MAAM;gBACN,SAAS,GAAG,OAAO,GAAG,MAAM;mBACzB,MAAM;oBACL,MAAM;wBACF,MAAM;2BACH,MAAM;4BACL,MAAM;wBACV,MAAM;;;wBAER,MAAM;;;EAKe,CAAC"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAsDA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;aAGhB,MAAM;cACL,OAAO;gBACL,OAAO;iBACN,OAAO;gBACR,MAAM;wBACE,MAAM;sBACR,MAAM;wBACJ,MAAM;2BACH,MAAM;wBACT,MAAM;gCACE,MAAM;iCACL,MAAM;6BACV,MAAM;qBACd,MAAM;sBACL,MAAM;uBACL,MAAM;YACjB;QACN,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,OAAO,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;KACpB,EAAE;eACQ;QACT,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,gBAAgB,EAAE,MAAM,CAAC;QACzB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;QACxC,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;KACpB,EAAE;EAEkC,CAAC;AAE1C,eAAO,MAAM,gBAAgB;kBAGX,MAAM;WACb,MAAM;aACJ,MAAM;wBACK,MAAM;gBACd,MAAM;sBACA,MAAM;uBACL,MAAM;qBACR,OAAO;gBACZ,MAAM;IAEmB,CAAC;AAE1C,eAAO,MAAM,eAAe;YAEhB,MAAM;UACR,KAAK,GAAG,MAAM;;UAGhB,QAAQ,GACR,OAAO,GACP,MAAM,GACN,aAAa,GACb,aAAa,GACb,oBAAoB,GACpB,sBAAsB;;;;;iBAOM,CAAC;AAErC,eAAO,MAAM,mBAAmB;;;aAKnB,MAAM;mBACA,MAAM;WACd,MAAM;aACJ,MAAM;iBACF,MAAM;YACX,MAAM;iBACD,MAAM;UACb,MAAM;UACN,KAAK,GAAG,MAAM;gBACR,MAAM;cACR,MAAM;;;;;;;;YAQR,MAAM;IAE0B,CAAC;AAE7C,eAAO,MAAM,iBAAiB;YAElB,MAAM;;;iBAKoB,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;gBAIpB,MAAM;gBACN,SAAS,GAAG,OAAO,GAAG,MAAM;mBACzB,MAAM;oBACL,MAAM;wBACF,MAAM;2BACH,MAAM;4BACL,MAAM;wBACV,MAAM;;;wBAER,MAAM;;;EAKe,CAAC"}
package/lib/api.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFApiV1ExchangeInfo = exports.postFApiV1Order = exports.getFApiV2Balance = exports.getFApiV4Account = void 0;
3
+ exports.getFApiV1ExchangeInfo = exports.deleteFApiV1Order = exports.getFApiV1OpenOrders = exports.postFApiV1Order = exports.getFApiV2Balance = exports.getFApiV4Account = void 0;
4
4
  const utils_1 = require("./utils");
5
5
  const API_KEY = process.env.API_KEY;
6
6
  const SECRET_KEY = process.env.SECRET_KEY;
@@ -44,6 +44,8 @@ const createApi = (type, method, endpoint) => (params) => request(type, method,
44
44
  exports.getFApiV4Account = createApi('USER_DATA', 'GET', '/fapi/v4/account');
45
45
  exports.getFApiV2Balance = createApi('USER_DATA', 'GET', '/fapi/v2/balance');
46
46
  exports.postFApiV1Order = createApi('TRADE', 'POST', '/fapi/v1/order');
47
+ exports.getFApiV1OpenOrders = createApi('USER_DATA', 'GET', '/fapi/v1/openOrders');
48
+ exports.deleteFApiV1Order = createApi('TRADE', 'DELETE', '/fapi/v1/order');
47
49
  /**
48
50
  * 获取交易对信息
49
51
  *
package/lib/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":";;;AAAA,mCAAgD;AAEhD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAQ,CAAC;AACrC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,UAAW,CAAC;AAE3C,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAE7C,MAAM,OAAO,GAAG,KAAK,EACnB,IAAoE,EACpE,MAAc,EACd,QAAgB,EAChB,SAAc,EAAE,EACJ,EAAE;IACd,MAAM,UAAU,GAAG,IAAI,KAAK,MAAM,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,WAAW,CAAC;IAE1D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACjD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;KACvC;IAED,IAAI,QAAQ,EAAE;QACZ,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;QAC7C,MAAM,SAAS,GAAG,MAAM,IAAA,6BAAqB,EAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC/D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;KAC9C;IAED,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;QACtC,MAAM;QACN,OAAO,EAAE,UAAU;YACjB,CAAC,CAAC;gBACE,cAAc,EAAE,OAAO;aACxB;YACH,CAAC,CAAC,EAAE;KACP,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE;QAC9B,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;KAC3B;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,SAAS,GACb,CACE,IAAoE,EACpE,MAAc,EACd,QAAgB,EAChB,EAAE,CACJ,CAAC,MAAY,EAAE,EAAE,CACf,OAAO,CAAO,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAElD;;;;GAIG;AACU,QAAA,gBAAgB,GAAG,SAAS,CAqDvC,WAAW,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;AAE7B,QAAA,gBAAgB,GAAG,SAAS,CAavC,WAAW,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;AAE7B,QAAA,eAAe,GAAG,SAAS,CAmBtC,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAErC;;;;GAIG;AACU,QAAA,qBAAqB,GAAG,SAAS,CAkB5C,MAAM,EAAE,KAAK,EAAE,uBAAuB,CAAC,CAAC","sourcesContent":["import { opensslEquivalentHMAC } from './utils';\n\nconst API_KEY = process.env.API_KEY!;\nconst SECRET_KEY = process.env.SECRET_KEY!;\n\nconst BASE_URL = 'https://fapi.asterdex.com';\n\nconst request = async <T>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n params: any = {},\n): Promise<T> => {\n const needApiKey = type !== 'NONE';\n const needSign = type === 'TRADE' || type === 'USER_DATA';\n\n const url = new URL(BASE_URL);\n url.pathname = endpoint;\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n url.searchParams.set(key, `${value}`);\n }\n\n if (needSign) {\n url.searchParams.set('timestamp', `${Date.now()}`);\n const msg = url.search.slice(1); // 去掉开头的 '?'\n const signature = await opensslEquivalentHMAC(msg, SECRET_KEY);\n url.searchParams.set('signature', signature);\n }\n\n console.info(url.toString());\n const res = await fetch(url.toString(), {\n method,\n headers: needApiKey\n ? {\n 'X-MBX-APIKEY': API_KEY,\n }\n : {},\n }).then((response) => response.json());\n if (res.code && res.code !== 0) {\n throw JSON.stringify(res);\n }\n return res;\n};\n\nconst createApi =\n <TReq, TRes>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n ) =>\n (params: TReq) =>\n request<TRes>(type, method, endpoint, params);\n\n/**\n * 获取账户信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data\n */\nexport const getFApiV4Account = createApi<\n {},\n {\n feeTier: number;\n canTrade: boolean;\n canDeposit: boolean;\n canWithdraw: boolean;\n updateTime: number;\n totalInitialMargin: string;\n totalMaintMargin: string;\n totalWalletBalance: string;\n totalUnrealizedProfit: string;\n totalMarginBalance: string;\n totalPositionInitialMargin: string;\n totalOpenOrderInitialMargin: string;\n totalCrossWalletBalance: string;\n totalCrossUnPnl: string;\n availableBalance: string;\n maxWithdrawAmount: string;\n assets: {\n asset: string;\n walletBalance: string;\n unrealizedProfit: string;\n marginBalance: string;\n maintMargin: string;\n initialMargin: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n maxWithdrawAmount: string;\n crossWalletBalance: string;\n crossUnPnl: string;\n availableBalance: string;\n marginAvailable: boolean;\n updateTime: number;\n }[];\n positions: {\n symbol: string;\n initialMargin: string;\n maintMargin: string;\n unrealizedProfit: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n leverage: string;\n isolated: boolean;\n entryPrice: string;\n maxNotional: string;\n positionSide: 'BOTH' | 'LONG' | 'SHORT';\n positionAmt: string;\n notional: string;\n isolatedWallet: string;\n updateTime: number;\n }[];\n }\n>('USER_DATA', 'GET', '/fapi/v4/account');\n\nexport const getFApiV2Balance = createApi<\n {},\n {\n accountAlias: string; // 账户唯一识别码\n asset: string; // 资产\n balance: string; // 总余额\n crossWalletBalance: string; // 全仓余额\n crossUnPnl: string; // 全仓持仓未实现盈亏\n availableBalance: string; // 下单可用余额\n maxWithdrawAmount: string; // 最大可转出余额\n marginAvailable: boolean; // 是否可用作联合保证金\n updateTime: number;\n }[]\n>('USER_DATA', 'GET', '/fapi/v2/balance');\n\nexport const postFApiV1Order = createApi<\n {\n symbol: string;\n side: 'BUY' | 'SELL';\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n type:\n | 'MARKET'\n | 'LIMIT'\n | 'STOP'\n | 'STOP_MARKET'\n | 'TAKE_PROFIT'\n | 'TAKE_PROFIT_MARKET'\n | 'TRAILING_STOP_MARKET';\n reduceOnly?: 'true' | 'false';\n quantity?: number;\n price?: number;\n timeInForce?: 'GTC' | 'IOC' | 'FOK' | 'GTX' | 'HIDDEN';\n },\n {}\n>('TRADE', 'POST', '/fapi/v1/order');\n\n/**\n * 获取交易对信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E4%BA%A4%E6%98%93%E5%AF%B9%E4%BF%A1%E6%81%AF\n */\nexport const getFApiV1ExchangeInfo = createApi<\n {},\n {\n symbols: {\n symbol: string;\n status: 'TRADING' | 'BREAK' | 'HALT';\n baseAsset: string;\n quoteAsset: string;\n pricePrecision: number;\n quantityPrecision: number;\n baseAssetPrecision: number;\n quotePrecision: number;\n filters: {\n filterType: string;\n [key: string]: any;\n }[];\n }[];\n }\n>('NONE', 'GET', '/fapi/v1/exchangeInfo');\n"]}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":";;;AAAA,mCAAgD;AAEhD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAQ,CAAC;AACrC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,UAAW,CAAC;AAE3C,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAE7C,MAAM,OAAO,GAAG,KAAK,EACnB,IAAoE,EACpE,MAAc,EACd,QAAgB,EAChB,SAAc,EAAE,EACJ,EAAE;IACd,MAAM,UAAU,GAAG,IAAI,KAAK,MAAM,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,WAAW,CAAC;IAE1D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACjD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;KACvC;IAED,IAAI,QAAQ,EAAE;QACZ,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;QAC7C,MAAM,SAAS,GAAG,MAAM,IAAA,6BAAqB,EAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC/D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;KAC9C;IAED,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;QACtC,MAAM;QACN,OAAO,EAAE,UAAU;YACjB,CAAC,CAAC;gBACE,cAAc,EAAE,OAAO;aACxB;YACH,CAAC,CAAC,EAAE;KACP,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE;QAC9B,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;KAC3B;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,SAAS,GACb,CACE,IAAoE,EACpE,MAAc,EACd,QAAgB,EAChB,EAAE,CACJ,CAAC,MAAY,EAAE,EAAE,CACf,OAAO,CAAO,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAElD;;;;GAIG;AACU,QAAA,gBAAgB,GAAG,SAAS,CAqDvC,WAAW,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;AAE7B,QAAA,gBAAgB,GAAG,SAAS,CAavC,WAAW,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;AAE7B,QAAA,eAAe,GAAG,SAAS,CAmBtC,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAExB,QAAA,mBAAmB,GAAG,SAAS,CAyB1C,WAAW,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;AAEhC,QAAA,iBAAiB,GAAG,SAAS,CAOxC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AAEvC;;;;GAIG;AACU,QAAA,qBAAqB,GAAG,SAAS,CAkB5C,MAAM,EAAE,KAAK,EAAE,uBAAuB,CAAC,CAAC","sourcesContent":["import { opensslEquivalentHMAC } from './utils';\n\nconst API_KEY = process.env.API_KEY!;\nconst SECRET_KEY = process.env.SECRET_KEY!;\n\nconst BASE_URL = 'https://fapi.asterdex.com';\n\nconst request = async <T>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n params: any = {},\n): Promise<T> => {\n const needApiKey = type !== 'NONE';\n const needSign = type === 'TRADE' || type === 'USER_DATA';\n\n const url = new URL(BASE_URL);\n url.pathname = endpoint;\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue;\n url.searchParams.set(key, `${value}`);\n }\n\n if (needSign) {\n url.searchParams.set('timestamp', `${Date.now()}`);\n const msg = url.search.slice(1); // 去掉开头的 '?'\n const signature = await opensslEquivalentHMAC(msg, SECRET_KEY);\n url.searchParams.set('signature', signature);\n }\n\n console.info(url.toString());\n const res = await fetch(url.toString(), {\n method,\n headers: needApiKey\n ? {\n 'X-MBX-APIKEY': API_KEY,\n }\n : {},\n }).then((response) => response.json());\n if (res.code && res.code !== 0) {\n throw JSON.stringify(res);\n }\n return res;\n};\n\nconst createApi =\n <TReq, TRes>(\n type: 'NONE' | 'TRADE' | 'USER_DATA' | 'USER_STREAM' | 'MARKET_DATA',\n method: string,\n endpoint: string,\n ) =>\n (params: TReq) =>\n request<TRes>(type, method, endpoint, params);\n\n/**\n * 获取账户信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E8%B4%A6%E6%88%B7%E4%BF%A1%E6%81%AFv4-user_data\n */\nexport const getFApiV4Account = createApi<\n {},\n {\n feeTier: number;\n canTrade: boolean;\n canDeposit: boolean;\n canWithdraw: boolean;\n updateTime: number;\n totalInitialMargin: string;\n totalMaintMargin: string;\n totalWalletBalance: string;\n totalUnrealizedProfit: string;\n totalMarginBalance: string;\n totalPositionInitialMargin: string;\n totalOpenOrderInitialMargin: string;\n totalCrossWalletBalance: string;\n totalCrossUnPnl: string;\n availableBalance: string;\n maxWithdrawAmount: string;\n assets: {\n asset: string;\n walletBalance: string;\n unrealizedProfit: string;\n marginBalance: string;\n maintMargin: string;\n initialMargin: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n maxWithdrawAmount: string;\n crossWalletBalance: string;\n crossUnPnl: string;\n availableBalance: string;\n marginAvailable: boolean;\n updateTime: number;\n }[];\n positions: {\n symbol: string;\n initialMargin: string;\n maintMargin: string;\n unrealizedProfit: string;\n positionInitialMargin: string;\n openOrderInitialMargin: string;\n leverage: string;\n isolated: boolean;\n entryPrice: string;\n maxNotional: string;\n positionSide: 'BOTH' | 'LONG' | 'SHORT';\n positionAmt: string;\n notional: string;\n isolatedWallet: string;\n updateTime: number;\n }[];\n }\n>('USER_DATA', 'GET', '/fapi/v4/account');\n\nexport const getFApiV2Balance = createApi<\n {},\n {\n accountAlias: string; // 账户唯一识别码\n asset: string; // 资产\n balance: string; // 总余额\n crossWalletBalance: string; // 全仓余额\n crossUnPnl: string; // 全仓持仓未实现盈亏\n availableBalance: string; // 下单可用余额\n maxWithdrawAmount: string; // 最大可转出余额\n marginAvailable: boolean; // 是否可用作联合保证金\n updateTime: number;\n }[]\n>('USER_DATA', 'GET', '/fapi/v2/balance');\n\nexport const postFApiV1Order = createApi<\n {\n symbol: string;\n side: 'BUY' | 'SELL';\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n type:\n | 'MARKET'\n | 'LIMIT'\n | 'STOP'\n | 'STOP_MARKET'\n | 'TAKE_PROFIT'\n | 'TAKE_PROFIT_MARKET'\n | 'TRAILING_STOP_MARKET';\n reduceOnly?: 'true' | 'false';\n quantity?: number;\n price?: number;\n timeInForce?: 'GTC' | 'IOC' | 'FOK' | 'GTX' | 'HIDDEN';\n },\n {}\n>('TRADE', 'POST', '/fapi/v1/order');\n\nexport const getFApiV1OpenOrders = createApi<\n {\n symbol?: string;\n },\n {\n orderId: number;\n clientOrderId: string;\n price: string;\n origQty: string;\n executedQty: string;\n status: string;\n timeInForce: string;\n type: string;\n side: 'BUY' | 'SELL';\n updateTime: number;\n avgPrice: string;\n reduceOnly?: boolean;\n closePosition?: boolean;\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n workingType?: string;\n priceProtect?: boolean;\n origType?: string;\n stopPrice?: string;\n symbol: string;\n }[]\n>('USER_DATA', 'GET', '/fapi/v1/openOrders');\n\nexport const deleteFApiV1Order = createApi<\n {\n symbol: string;\n orderId?: string | number;\n origClientOrderId?: string;\n },\n {}\n>('TRADE', 'DELETE', '/fapi/v1/order');\n\n/**\n * 获取交易对信息\n *\n * https://github.com/asterdex/api-docs/blob/master/aster-finance-futures-api_CN.md#%E4%BA%A4%E6%98%93%E5%AF%B9%E4%BF%A1%E6%81%AF\n */\nexport const getFApiV1ExchangeInfo = createApi<\n {},\n {\n symbols: {\n symbol: string;\n status: 'TRADING' | 'BREAK' | 'HALT';\n baseAsset: string;\n quoteAsset: string;\n pricePrecision: number;\n quantityPrecision: number;\n baseAssetPrecision: number;\n quotePrecision: number;\n filters: {\n filterType: string;\n [key: string]: any;\n }[];\n }[];\n }\n>('NONE', 'GET', '/fapi/v1/exchangeInfo');\n"]}
package/lib/index.d.ts CHANGED
@@ -3,4 +3,5 @@ import './account-spot';
3
3
  import './order';
4
4
  import './order-spot';
5
5
  import './product';
6
+ import './pending-orders';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAC;AACnB,OAAO,gBAAgB,CAAC;AACxB,OAAO,SAAS,CAAC;AACjB,OAAO,cAAc,CAAC;AACtB,OAAO,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAC;AACnB,OAAO,gBAAgB,CAAC;AACxB,OAAO,SAAS,CAAC;AACjB,OAAO,cAAc,CAAC;AACtB,OAAO,WAAW,CAAC;AACnB,OAAO,kBAAkB,CAAC"}
package/lib/index.js CHANGED
@@ -5,4 +5,5 @@ require("./account-spot");
5
5
  require("./order");
6
6
  require("./order-spot");
7
7
  require("./product"); // Import the new product service
8
+ require("./pending-orders");
8
9
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,qBAAmB;AACnB,0BAAwB;AACxB,mBAAiB;AACjB,wBAAsB;AACtB,qBAAmB,CAAC,iCAAiC","sourcesContent":["import './account';\nimport './account-spot';\nimport './order';\nimport './order-spot';\nimport './product'; // Import the new product service\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,qBAAmB;AACnB,0BAAwB;AACxB,mBAAiB;AACjB,wBAAsB;AACtB,qBAAmB,CAAC,iCAAiC;AACrD,4BAA0B","sourcesContent":["import './account';\nimport './account-spot';\nimport './order';\nimport './order-spot';\nimport './product'; // Import the new product service\nimport './pending-orders';\n"]}
package/lib/order.js CHANGED
@@ -1,12 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const protocol_1 = require("@yuants/protocol");
4
+ const utils_1 = require("@yuants/utils");
4
5
  const account_1 = require("./account");
5
6
  const api_1 = require("./api");
6
7
  const terminal = protocol_1.Terminal.fromNodeEnv();
7
8
  terminal.server.provideService('SubmitOrder', { required: ['account_id'], properties: { account_id: { type: 'string', const: account_1.ACCOUNT_ID } } }, async (msg) => {
8
9
  const order = msg.req;
9
- const symbol = order.product_id;
10
+ const [, decodedSymbol] = (0, utils_1.decodePath)(order.product_id);
11
+ if (!decodedSymbol) {
12
+ throw new Error(`Invalid product_id: unable to decode symbol from "${order.product_id}"`);
13
+ }
14
+ const symbol = decodedSymbol;
10
15
  const side = { OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' }[order.order_direction];
11
16
  if (!side)
12
17
  throw new Error(`Unsupported order_direction: ${order.order_direction}`);
@@ -26,4 +31,26 @@ terminal.server.provideService('SubmitOrder', { required: ['account_id'], proper
26
31
  });
27
32
  return { res: { code: 0, message: 'OK' } };
28
33
  });
34
+ terminal.server.provideService('CancelOrder', {
35
+ required: ['account_id', 'order_id', 'product_id'],
36
+ properties: {
37
+ account_id: { type: 'string', const: account_1.ACCOUNT_ID },
38
+ order_id: { type: ['string', 'number'] },
39
+ product_id: { type: 'string' },
40
+ },
41
+ }, async (msg) => {
42
+ const order = msg.req;
43
+ const [, decodedSymbol] = (0, utils_1.decodePath)(order.product_id);
44
+ if (!decodedSymbol) {
45
+ throw new Error(`Invalid product_id: unable to decode symbol from "${order.product_id}"`);
46
+ }
47
+ if (!order.order_id) {
48
+ throw new Error('order_id is required for CancelOrder');
49
+ }
50
+ await (0, api_1.deleteFApiV1Order)({
51
+ symbol: decodedSymbol,
52
+ orderId: order.order_id,
53
+ });
54
+ return { res: { code: 0, message: 'OK' } };
55
+ });
29
56
  //# sourceMappingURL=order.js.map
package/lib/order.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"order.js","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":";;AAAA,+CAA4C;AAE5C,uCAAuC;AACvC,+BAAwC;AAExC,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,aAAa,EACb,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,oBAAU,EAAE,EAAE,EAAE,EAC/F,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC;IAEtB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC;IAEhC,MAAM,IAAI,GAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAY,CACtG,KAAK,CAAC,eAAgB,CACvB,CAAC;IACF,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC;IAEpF,MAAM,IAAI,GAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAY,CAAC,KAAK,CAAC,UAAW,CAAC,CAAC;IAChG,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAE1E,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;IAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAE1B,MAAM,WAAW,GACf,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAE1F,MAAM,IAAA,qBAAe,EAAC;QACpB,MAAM;QACN,IAAI;QACJ,IAAI;QACJ,QAAQ;QACR,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;AAC7C,CAAC,CACF,CAAC","sourcesContent":["import { Terminal } from '@yuants/protocol';\nimport { IOrder } from '@yuants/data-order';\nimport { ACCOUNT_ID } from './account';\nimport { postFApiV1Order } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<IOrder>(\n 'SubmitOrder',\n { required: ['account_id'], properties: { account_id: { type: 'string', const: ACCOUNT_ID } } },\n async (msg) => {\n const order = msg.req;\n\n const symbol = order.product_id;\n\n const side = ({ OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' } as const)[\n order.order_direction!\n ];\n if (!side) throw new Error(`Unsupported order_direction: ${order.order_direction}`);\n\n const type = ({ MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' } as const)[order.order_type!];\n if (!type) throw new Error(`Unsupported order_type: ${order.order_type}`);\n\n const quantity = order.volume;\n const price = order.price;\n\n const timeInForce =\n order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n\n await postFApiV1Order({\n symbol,\n side,\n type,\n quantity,\n price,\n timeInForce,\n });\n\n return { res: { code: 0, message: 'OK' } };\n },\n);\n"]}
1
+ {"version":3,"file":"order.js","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":"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","sourcesContent":["import { Terminal } from '@yuants/protocol';\nimport { IOrder } from '@yuants/data-order';\nimport { decodePath } from '@yuants/utils';\nimport { ACCOUNT_ID } from './account';\nimport { deleteFApiV1Order, postFApiV1Order } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<IOrder>(\n 'SubmitOrder',\n { required: ['account_id'], properties: { account_id: { type: 'string', const: ACCOUNT_ID } } },\n async (msg) => {\n const order = msg.req;\n\n const [, decodedSymbol] = decodePath(order.product_id);\n if (!decodedSymbol) {\n throw new Error(`Invalid product_id: unable to decode symbol from \"${order.product_id}\"`);\n }\n const symbol = decodedSymbol;\n\n const side = ({ OPEN_LONG: 'BUY', OPEN_SHORT: 'SELL', CLOSE_LONG: 'SELL', CLOSE_SHORT: 'BUY' } as const)[\n order.order_direction!\n ];\n if (!side) throw new Error(`Unsupported order_direction: ${order.order_direction}`);\n\n const type = ({ MARKET: 'MARKET', LIMIT: 'LIMIT', MAKER: 'LIMIT' } as const)[order.order_type!];\n if (!type) throw new Error(`Unsupported order_type: ${order.order_type}`);\n\n const quantity = order.volume;\n const price = order.price;\n\n const timeInForce =\n order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n\n await postFApiV1Order({\n symbol,\n side,\n type,\n quantity,\n price,\n timeInForce,\n });\n\n return { res: { code: 0, message: 'OK' } };\n },\n);\n\nterminal.server.provideService<IOrder>(\n 'CancelOrder',\n {\n required: ['account_id', 'order_id', 'product_id'],\n properties: {\n account_id: { type: 'string', const: ACCOUNT_ID },\n order_id: { type: ['string', 'number'] },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const order = msg.req;\n const [, decodedSymbol] = decodePath(order.product_id);\n if (!decodedSymbol) {\n throw new Error(`Invalid product_id: unable to decode symbol from \"${order.product_id}\"`);\n }\n if (!order.order_id) {\n throw new Error('order_id is required for CancelOrder');\n }\n\n await deleteFApiV1Order({\n symbol: decodedSymbol,\n orderId: order.order_id,\n });\n\n return { res: { code: 0, message: 'OK' } };\n },\n);\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pending-orders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-orders.d.ts","sourceRoot":"","sources":["../src/pending-orders.ts"],"names":[],"mappings":""}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const data_order_1 = require("@yuants/data-order");
4
+ const protocol_1 = require("@yuants/protocol");
5
+ const utils_1 = require("@yuants/utils");
6
+ const account_1 = require("./account");
7
+ const api_1 = require("./api");
8
+ const terminal = protocol_1.Terminal.fromNodeEnv();
9
+ const resolveOrderDirection = (asterOrder) => {
10
+ const reduceOnly = asterOrder.reduceOnly || asterOrder.closePosition;
11
+ if (asterOrder.positionSide === 'LONG') {
12
+ return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'CLOSE_LONG';
13
+ }
14
+ if (asterOrder.positionSide === 'SHORT') {
15
+ return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'OPEN_SHORT';
16
+ }
17
+ if (reduceOnly) {
18
+ return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'CLOSE_LONG';
19
+ }
20
+ return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'OPEN_SHORT';
21
+ };
22
+ (0, data_order_1.providePendingOrdersService)(terminal, account_1.ACCOUNT_ID, async () => {
23
+ const orders = (await (0, api_1.getFApiV1OpenOrders)({}));
24
+ return orders.map((order) => {
25
+ const volume = Number(order.origQty);
26
+ const tradedVolume = Number(order.executedQty);
27
+ const price = Number(order.price);
28
+ const avgPrice = Number(order.avgPrice);
29
+ const mapped = {
30
+ order_id: `${order.orderId}`,
31
+ account_id: account_1.ACCOUNT_ID,
32
+ product_id: (0, utils_1.encodePath)('PERPETUAL', order.symbol),
33
+ order_type: order.type,
34
+ order_direction: resolveOrderDirection(order),
35
+ volume: Number.isFinite(volume) ? volume : 0,
36
+ price: Number.isFinite(price) ? price : undefined,
37
+ submit_at: order.updateTime,
38
+ traded_volume: Number.isFinite(tradedVolume) ? tradedVolume : undefined,
39
+ traded_price: Number.isFinite(avgPrice) && avgPrice > 0 ? avgPrice : undefined,
40
+ order_status: order.status,
41
+ };
42
+ return mapped;
43
+ });
44
+ }, { auto_refresh_interval: 2000 });
45
+ //# sourceMappingURL=pending-orders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-orders.js","sourceRoot":"","sources":["../src/pending-orders.ts"],"names":[],"mappings":";;AAAA,mDAAyE;AACzE,+CAA4C;AAC5C,yCAA2C;AAC3C,uCAAuC;AACvC,+BAA4C;AAE5C,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAoBxC,MAAM,qBAAqB,GAAG,CAAC,UAA2B,EAAkB,EAAE;IAC5E,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,IAAI,UAAU,CAAC,aAAa,CAAC;IAErE,IAAI,UAAU,CAAC,YAAY,KAAK,MAAM,EAAE;QACtC,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;KAC/D;IACD,IAAI,UAAU,CAAC,YAAY,KAAK,OAAO,EAAE;QACvC,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC;KACjE;IACD,IAAI,UAAU,EAAE;QACd,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC;KACjE;IACD,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;AAChE,CAAC,CAAC;AAEF,IAAA,wCAA2B,EACzB,QAAQ,EACR,oBAAU,EACV,KAAK,IAAI,EAAE;IACT,MAAM,MAAM,GAAG,CAAC,MAAM,IAAA,yBAAmB,EAAC,EAAE,CAAC,CAAsB,CAAC;IACpE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAExC,MAAM,MAAM,GAAW;YACrB,QAAQ,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE;YAC5B,UAAU,EAAE,oBAAU;YACtB,UAAU,EAAE,IAAA,kBAAU,EAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC;YACjD,UAAU,EAAE,KAAK,CAAC,IAAI;YACtB,eAAe,EAAE,qBAAqB,CAAC,KAAK,CAAC;YAC7C,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC5C,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;YACjD,SAAS,EAAE,KAAK,CAAC,UAAU;YAC3B,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;YACvE,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YAC9E,YAAY,EAAE,KAAK,CAAC,MAAM;SAC3B,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,EACD,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAChC,CAAC","sourcesContent":["import { IOrder, providePendingOrdersService } from '@yuants/data-order';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { ACCOUNT_ID } from './account';\nimport { getFApiV1OpenOrders } from './api';\n\nconst terminal = Terminal.fromNodeEnv();\n\ntype OrderDirection = 'OPEN_LONG' | 'OPEN_SHORT' | 'CLOSE_LONG' | 'CLOSE_SHORT';\n\ninterface IAsterOpenOrder {\n orderId: number;\n symbol: string;\n side: 'BUY' | 'SELL';\n positionSide?: 'BOTH' | 'LONG' | 'SHORT';\n reduceOnly?: boolean;\n closePosition?: boolean;\n type: string;\n origQty: string;\n executedQty: string;\n price: string;\n avgPrice: string;\n status: string;\n updateTime: number;\n}\n\nconst resolveOrderDirection = (asterOrder: IAsterOpenOrder): OrderDirection => {\n const reduceOnly = asterOrder.reduceOnly || asterOrder.closePosition;\n\n if (asterOrder.positionSide === 'LONG') {\n return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'CLOSE_LONG';\n }\n if (asterOrder.positionSide === 'SHORT') {\n return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'OPEN_SHORT';\n }\n if (reduceOnly) {\n return asterOrder.side === 'BUY' ? 'CLOSE_SHORT' : 'CLOSE_LONG';\n }\n return asterOrder.side === 'BUY' ? 'OPEN_LONG' : 'OPEN_SHORT';\n};\n\nprovidePendingOrdersService(\n terminal,\n ACCOUNT_ID,\n async () => {\n const orders = (await getFApiV1OpenOrders({})) as IAsterOpenOrder[];\n return orders.map((order) => {\n const volume = Number(order.origQty);\n const tradedVolume = Number(order.executedQty);\n const price = Number(order.price);\n const avgPrice = Number(order.avgPrice);\n\n const mapped: IOrder = {\n order_id: `${order.orderId}`,\n account_id: ACCOUNT_ID,\n product_id: encodePath('PERPETUAL', order.symbol),\n order_type: order.type,\n order_direction: resolveOrderDirection(order),\n volume: Number.isFinite(volume) ? volume : 0,\n price: Number.isFinite(price) ? price : undefined,\n submit_at: order.updateTime,\n traded_volume: Number.isFinite(tradedVolume) ? tradedVolume : undefined,\n traded_price: Number.isFinite(avgPrice) && avgPrice > 0 ? avgPrice : undefined,\n order_status: order.status,\n };\n\n return mapped;\n });\n },\n { auto_refresh_interval: 2000 },\n);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuants/vendor-aster",
3
- "version": "0.3.17",
3
+ "version": "0.3.19",
4
4
  "bin": "lib/cli.js",
5
5
  "main": "lib/index.js",
6
6
  "files": [
@@ -9,16 +9,16 @@
9
9
  "temp"
10
10
  ],
11
11
  "dependencies": {
12
- "@yuants/protocol": "0.49.1",
13
- "@yuants/data-account": "0.6.9",
12
+ "@yuants/protocol": "0.50.0",
13
+ "@yuants/data-account": "0.6.10",
14
14
  "@yuants/utils": "0.10.0",
15
- "@yuants/data-series": "0.3.40",
16
- "@yuants/sql": "0.9.19",
17
- "@yuants/data-product": "0.4.10",
18
- "@yuants/data-ohlc": "0.4.11",
19
- "@yuants/data-order": "0.3.7",
20
- "@yuants/data-interest-rate": "0.1.37",
21
- "@yuants/transfer": "0.2.28",
15
+ "@yuants/data-series": "0.3.41",
16
+ "@yuants/sql": "0.9.20",
17
+ "@yuants/data-product": "0.4.11",
18
+ "@yuants/data-ohlc": "0.4.12",
19
+ "@yuants/data-order": "0.3.8",
20
+ "@yuants/data-interest-rate": "0.1.38",
21
+ "@yuants/transfer": "0.2.29",
22
22
  "rxjs": "~7.5.6"
23
23
  },
24
24
  "devDependencies": {
@@ -1,32 +1,33 @@
1
1
  {
2
- "apps/vendor-aster/CHANGELOG.json": "1532f639661b35031e645e5e05bd0a7d4a53f8c2",
3
- "apps/vendor-aster/CHANGELOG.md": "3c67fefc280b6abcdab101cef192af3a50394126",
2
+ "apps/vendor-aster/CHANGELOG.json": "9a3a5082d909e0084e0a270d8fcd13ef527a8b7f",
3
+ "apps/vendor-aster/CHANGELOG.md": "5af6d6231ea4418a0f780598b367651df693367a",
4
4
  "apps/vendor-aster/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
5
5
  "apps/vendor-aster/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
6
6
  "apps/vendor-aster/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
7
- "apps/vendor-aster/package.json": "49a8e05931af14e6e757d51016a8b029ca93ad51",
7
+ "apps/vendor-aster/package.json": "0894a8a0c95f769f9dfc1afc58cc7d02b6f1ce86",
8
8
  "apps/vendor-aster/src/account-spot.ts": "e5162a9c7f00fde4d1f143c3f85ef04ae8877b56",
9
- "apps/vendor-aster/src/account.ts": "0b9bcc884cb4b1cdba11997806db5cddd2f1d3c3",
10
- "apps/vendor-aster/src/api.ts": "0778c64a95fc5a8760f1bac35ed83a1036c662da",
9
+ "apps/vendor-aster/src/account.ts": "6163105ce1de2d1b9747b8080936357bbcada559",
10
+ "apps/vendor-aster/src/api.ts": "8d26c56b3956d84a785d74b3c711af439d47abce",
11
11
  "apps/vendor-aster/src/cli.ts": "9bf6b5559a6c6f33da20e74cc6c5d702c60ec891",
12
- "apps/vendor-aster/src/index.ts": "af43c8eef43536749a777d473f8b7707da3e6d55",
12
+ "apps/vendor-aster/src/index.ts": "ae0a059c38210108a3a73b6152a4895b6998b9d5",
13
13
  "apps/vendor-aster/src/order-spot.ts": "e17f728347f3c49d4311493a47b1ed72d5a29f37",
14
- "apps/vendor-aster/src/order.ts": "546900e63e6e1c72d01086ea5eecc3c418ba7b67",
14
+ "apps/vendor-aster/src/order.ts": "855a8e009770b9f55def8a4725c82094b231e70f",
15
+ "apps/vendor-aster/src/pending-orders.ts": "e047fcb2f9098583856513677f90b2e3d6e26441",
15
16
  "apps/vendor-aster/src/product.ts": "665becdfc3aa0f9239d008831b1304a17edb01dc",
16
17
  "apps/vendor-aster/src/sapi.ts": "40214de87500f9fb6647c11d3999e0e449a6fa0b",
17
18
  "apps/vendor-aster/src/utils.ts": "f732922ea47951ddf0889bba9a70fd8e270cae2f",
18
19
  "apps/vendor-aster/tsconfig.json": "81da8f78196974b5d15da0edb6b2d9f48641063c",
19
20
  "apps/vendor-aster/.rush/temp/shrinkwrap-deps.json": "16e9a5a82223d7134aa224dfc050a24c5b53e862",
20
- "libraries/protocol/temp/package-deps.json": "0a3f80906e99efffe686a474d0f15c9410ee8874",
21
- "libraries/data-account/temp/package-deps.json": "bfa01200dc996e34f59d2768caf5077467df5573",
21
+ "libraries/protocol/temp/package-deps.json": "b798d038ca8307c5c1da842400ce9b64a81b8bb4",
22
+ "libraries/data-account/temp/package-deps.json": "927914a42877bd5e5eece519e427c0b4743f5e2d",
22
23
  "libraries/utils/temp/package-deps.json": "00132af02f003a95edfc2b9e1e9ec298a59fb89c",
23
- "libraries/data-series/temp/package-deps.json": "678eae040552d81b455284857d187123decd832d",
24
- "libraries/sql/temp/package-deps.json": "1d1d91dcd9a6cc28f3309fe7fd45de952aacb4fb",
25
- "libraries/data-product/temp/package-deps.json": "722dbd45b5a7433c9fa26e450c39a2b5f9d7045f",
26
- "libraries/data-ohlc/temp/package-deps.json": "3403664dcd950637b25c293f2699453bcff384d0",
27
- "libraries/data-order/temp/package-deps.json": "3a98bb6bed777858bc9b6a6ab4067fd86cddd6cf",
28
- "libraries/data-interest-rate/temp/package-deps.json": "2ecad524c89f84f7b8528305ac396080d2ab1b07",
29
- "libraries/transfer/temp/package-deps.json": "d73a9ba8f08848ccf0aa1ae8f1debc0d6862325b",
24
+ "libraries/data-series/temp/package-deps.json": "f0ac273595ca98049fe361a4a4f9c02e3f2af689",
25
+ "libraries/sql/temp/package-deps.json": "e2a073b3cedae605bf3be4eba0df3bf9e6ce1cda",
26
+ "libraries/data-product/temp/package-deps.json": "b3db51796835c2bb4a5a307b1ab693ba12379ddd",
27
+ "libraries/data-ohlc/temp/package-deps.json": "9a2c1de185e0a9d54d7c28b35a62077a69435245",
28
+ "libraries/data-order/temp/package-deps.json": "61701a3a0578d8c0bc50dfda8f54349c19cf1521",
29
+ "libraries/data-interest-rate/temp/package-deps.json": "c349130b331ab41396ac04722cb5463f0ce41a1c",
30
+ "libraries/transfer/temp/package-deps.json": "bdb70a9e16eed15573c12f44a97b136d4df0439b",
30
31
  "libraries/extension/temp/package-deps.json": "baf08ab93278543b640b68f31261ffd3705bd9e7",
31
32
  "tools/toolkit/temp/package-deps.json": "3bef053db16659f0cdaceea64c8a8580c0131633"
32
33
  }