@yuants/vendor-binance 0.10.16 → 0.10.18

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.
@@ -30,7 +30,8 @@ export const getUnifiedAccountInfo = async (credential) => {
30
30
  volume: Math.abs(+position.positionAmt),
31
31
  free_volume: Math.abs(+position.positionAmt),
32
32
  position_price: +position.entryPrice,
33
- closable_price: +position.entryPrice + +position.unrealizedProfit / Math.abs(+position.positionAmt),
33
+ // ISSUE: positionAmt 有正负,这里计算有个 trick,不需要区分仓位方向
34
+ closable_price: +position.entryPrice + +position.unrealizedProfit / +position.positionAmt,
34
35
  floating_profit: +position.unrealizedProfit,
35
36
  valuation: +position.positionAmt *
36
37
  (+position.entryPrice +
@@ -1 +1 @@
1
- {"version":3,"file":"unified.js","sourceRoot":"","sources":["../../../src/services/accounts/unified.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition, makeSpotPosition } from '@yuants/data-account';\nimport { encodePath } from '@yuants/utils';\nimport { isApiError } from '../../api/client';\nimport { getUnifiedAccountBalance, getUnifiedUmAccount, ICredential } from '../../api/private-api';\nimport { getSpotTickerPrice } from '../../api/public-api';\n\nexport const getUnifiedAccountInfo = async (credential: ICredential): Promise<IPosition[]> => {\n const [balanceRes, umAccountRes] = await Promise.all([\n getUnifiedAccountBalance(credential),\n getUnifiedUmAccount(credential),\n ]);\n if (isApiError(balanceRes)) {\n throw new Error(balanceRes.msg);\n }\n if (isApiError(umAccountRes)) {\n throw new Error(umAccountRes.msg);\n }\n\n const positions: IPosition[] = umAccountRes.positions\n .filter((position) => +position.positionAmt !== 0)\n .map((position) => ({\n position_id: `${position.symbol}/${position.positionSide}`,\n datasource_id: 'BINANCE',\n product_id: encodePath('BINANCE', 'USDT-FUTURE', position.symbol),\n direction:\n position.positionSide === 'LONG'\n ? 'LONG'\n : position.positionSide === 'SHORT'\n ? 'SHORT'\n : position.positionSide === 'BOTH'\n ? 'BOTH'\n : 'UNKNOWN',\n volume: Math.abs(+position.positionAmt),\n free_volume: Math.abs(+position.positionAmt),\n position_price: +position.entryPrice,\n closable_price: +position.entryPrice + +position.unrealizedProfit / Math.abs(+position.positionAmt),\n floating_profit: +position.unrealizedProfit,\n valuation:\n +position.positionAmt *\n (+position.entryPrice +\n (+position.positionAmt === 0 ? 0 : +position.unrealizedProfit / +position.positionAmt)),\n }));\n\n const prices = await getSpotTickerPrice({\n symbols: JSON.stringify([\n ...new Set([\n ...balanceRes\n .map((balance) => {\n const match = balance.asset.match(/^LD(\\w+)$/);\n let symbol = balance.asset;\n if (match) {\n symbol = match[1];\n }\n if (symbol === 'USDT') return '';\n return `${symbol}USDT`;\n })\n .filter(Boolean),\n ]),\n ]),\n });\n const balancePositions: IPosition[] = balanceRes.map((position) =>\n makeSpotPosition({\n position_id: `UNIFIED-SPOT/${position.asset}`,\n datasource_id: 'BINANCE',\n product_id: encodePath('BINANCE', 'UNIFIED-SPOT', position.asset),\n volume: +position.totalWalletBalance + +position.umUnrealizedPNL,\n free_volume: +position.crossMarginFree,\n closable_price:\n position.asset === 'USDT'\n ? 1\n : Array.isArray(prices)\n ? +(prices.find((item) => item.symbol === `${position.asset}USDT`)?.price ?? 0)\n : 0,\n }),\n );\n return [...balancePositions, ...positions];\n};\n"]}
1
+ {"version":3,"file":"unified.js","sourceRoot":"","sources":["../../../src/services/accounts/unified.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition, makeSpotPosition } from '@yuants/data-account';\nimport { encodePath } from '@yuants/utils';\nimport { isApiError } from '../../api/client';\nimport { getUnifiedAccountBalance, getUnifiedUmAccount, ICredential } from '../../api/private-api';\nimport { getSpotTickerPrice } from '../../api/public-api';\n\nexport const getUnifiedAccountInfo = async (credential: ICredential): Promise<IPosition[]> => {\n const [balanceRes, umAccountRes] = await Promise.all([\n getUnifiedAccountBalance(credential),\n getUnifiedUmAccount(credential),\n ]);\n if (isApiError(balanceRes)) {\n throw new Error(balanceRes.msg);\n }\n if (isApiError(umAccountRes)) {\n throw new Error(umAccountRes.msg);\n }\n\n const positions: IPosition[] = umAccountRes.positions\n .filter((position) => +position.positionAmt !== 0)\n .map((position) => ({\n position_id: `${position.symbol}/${position.positionSide}`,\n datasource_id: 'BINANCE',\n product_id: encodePath('BINANCE', 'USDT-FUTURE', position.symbol),\n direction:\n position.positionSide === 'LONG'\n ? 'LONG'\n : position.positionSide === 'SHORT'\n ? 'SHORT'\n : position.positionSide === 'BOTH'\n ? 'BOTH'\n : 'UNKNOWN',\n volume: Math.abs(+position.positionAmt),\n free_volume: Math.abs(+position.positionAmt),\n position_price: +position.entryPrice,\n // ISSUE: positionAmt 有正负,这里计算有个 trick,不需要区分仓位方向\n closable_price: +position.entryPrice + +position.unrealizedProfit / +position.positionAmt,\n floating_profit: +position.unrealizedProfit,\n valuation:\n +position.positionAmt *\n (+position.entryPrice +\n (+position.positionAmt === 0 ? 0 : +position.unrealizedProfit / +position.positionAmt)),\n }));\n\n const prices = await getSpotTickerPrice({\n symbols: JSON.stringify([\n ...new Set([\n ...balanceRes\n .map((balance) => {\n const match = balance.asset.match(/^LD(\\w+)$/);\n let symbol = balance.asset;\n if (match) {\n symbol = match[1];\n }\n if (symbol === 'USDT') return '';\n return `${symbol}USDT`;\n })\n .filter(Boolean),\n ]),\n ]),\n });\n const balancePositions: IPosition[] = balanceRes.map((position) =>\n makeSpotPosition({\n position_id: `UNIFIED-SPOT/${position.asset}`,\n datasource_id: 'BINANCE',\n product_id: encodePath('BINANCE', 'UNIFIED-SPOT', position.asset),\n volume: +position.totalWalletBalance + +position.umUnrealizedPNL,\n free_volume: +position.crossMarginFree,\n closable_price:\n position.asset === 'USDT'\n ? 1\n : Array.isArray(prices)\n ? +(prices.find((item) => item.symbol === `${position.asset}USDT`)?.price ?? 0)\n : 0,\n }),\n );\n return [...balancePositions, ...positions];\n};\n"]}
@@ -7,11 +7,17 @@ const submitUnifiedOrder = async (credential, order) => {
7
7
  if (!order.volume) {
8
8
  throw new Error('Binance submitOrder requires order.volume to be set');
9
9
  }
10
+ // 单向持仓模式 (single side mode) 下
11
+ const isSingleSideMode = false; // TODO: fetch from account info API and cache it
10
12
  const side = mapOrderDirectionToSide(order.order_direction);
11
- const positionSide = mapOrderDirectionToPositionSide(order.order_direction);
13
+ const positionSide = isSingleSideMode ? undefined : mapOrderDirectionToPositionSide(order.order_direction);
12
14
  const type = mapOrderTypeToOrdType(order.order_type);
13
15
  const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;
14
- const reduceOnly = order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT' ? 'true' : undefined;
16
+ const reduceOnly = isSingleSideMode
17
+ ? order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT'
18
+ ? 'true'
19
+ : undefined
20
+ : undefined;
15
21
  const res = await postUmOrder(credential, {
16
22
  symbol,
17
23
  side,
@@ -1 +1 @@
1
- {"version":3,"file":"submitOrder.js","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"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","sourcesContent":["import { IActionHandlerOfSubmitOrder } from '@yuants/data-order';\nimport { decodePath, newError } from '@yuants/utils';\nimport { isApiError } from '../../api/client';\nimport { ICredential, postSpotOrder, postUmOrder } from '../../api/private-api';\nimport {\n decodeFutureSymbol,\n decodeSpotSymbol,\n deriveClientOrderId,\n mapOrderDirectionToPositionSide,\n mapOrderDirectionToSide,\n mapOrderTypeToOrdType,\n} from './order-utils';\n\nconst submitUnifiedOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const symbol = decodeFutureSymbol(order.product_id);\n if (!order.volume) {\n throw new Error('Binance submitOrder requires order.volume to be set');\n }\n const side = mapOrderDirectionToSide(order.order_direction);\n const positionSide = mapOrderDirectionToPositionSide(order.order_direction);\n const type = mapOrderTypeToOrdType(order.order_type);\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n const reduceOnly =\n order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT' ? 'true' : undefined;\n\n const res = await postUmOrder(credential, {\n symbol,\n side,\n positionSide,\n type,\n quantity: order.volume,\n price: order.price,\n timeInForce,\n reduceOnly,\n newClientOrderId: deriveClientOrderId(order),\n });\n if (isApiError(res)) {\n throw new Error(`Binance submit unified order failed: ${res.code} ${res.msg}`);\n }\n return { order_id: `${res.orderId}` };\n};\n\nconst submitSpotOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const symbol = decodeSpotSymbol(order.product_id);\n if (!order.volume) {\n throw new Error('Binance submitOrder requires order.volume to be set');\n }\n const side = mapOrderDirectionToSide(order.order_direction);\n const type = mapOrderTypeToOrdType(order.order_type);\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n const params: Parameters<typeof postSpotOrder>[1] = {\n symbol,\n side,\n type,\n quantity: order.volume,\n newClientOrderId: deriveClientOrderId(order),\n };\n if (type === 'LIMIT') {\n if (order.price === undefined) {\n throw new Error('Binance spot LIMIT order requires price');\n }\n params.price = order.price;\n params.timeInForce = timeInForce;\n }\n if (order.price !== undefined && type === 'MARKET') {\n params.price = order.price;\n }\n const res = await postSpotOrder(credential, params);\n if (isApiError(res)) {\n throw new Error(`Binance submit spot order failed: ${res.code} ${res.msg}`);\n }\n return { order_id: `${res.orderId}` };\n};\n\nexport const submitOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const [, TYPE] = decodePath(order.product_id);\n\n if (TYPE === 'USDT-FUTURE') {\n return submitUnifiedOrder(credential, order);\n }\n if (TYPE === 'SPOT') {\n return submitSpotOrder(credential, order);\n }\n\n throw newError('BINANCE_SUBMIT_ORDER_UNSUPPORTED_PRODUCT_TYPE', { order });\n};\n"]}
1
+ {"version":3,"file":"submitOrder.js","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"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","sourcesContent":["import { IActionHandlerOfSubmitOrder } from '@yuants/data-order';\nimport { decodePath, newError } from '@yuants/utils';\nimport { isApiError } from '../../api/client';\nimport { ICredential, postSpotOrder, postUmOrder } from '../../api/private-api';\nimport {\n decodeFutureSymbol,\n decodeSpotSymbol,\n deriveClientOrderId,\n mapOrderDirectionToPositionSide,\n mapOrderDirectionToSide,\n mapOrderTypeToOrdType,\n} from './order-utils';\n\nconst submitUnifiedOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const symbol = decodeFutureSymbol(order.product_id);\n if (!order.volume) {\n throw new Error('Binance submitOrder requires order.volume to be set');\n }\n // 单向持仓模式 (single side mode) 下\n const isSingleSideMode = false; // TODO: fetch from account info API and cache it\n const side = mapOrderDirectionToSide(order.order_direction);\n const positionSide = isSingleSideMode ? undefined : mapOrderDirectionToPositionSide(order.order_direction);\n const type = mapOrderTypeToOrdType(order.order_type);\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n const reduceOnly = isSingleSideMode\n ? order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT'\n ? 'true'\n : undefined\n : undefined;\n\n const res = await postUmOrder(credential, {\n symbol,\n side,\n positionSide,\n type,\n quantity: order.volume,\n price: order.price,\n timeInForce,\n reduceOnly,\n newClientOrderId: deriveClientOrderId(order),\n });\n if (isApiError(res)) {\n throw new Error(`Binance submit unified order failed: ${res.code} ${res.msg}`);\n }\n return { order_id: `${res.orderId}` };\n};\n\nconst submitSpotOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const symbol = decodeSpotSymbol(order.product_id);\n if (!order.volume) {\n throw new Error('Binance submitOrder requires order.volume to be set');\n }\n const side = mapOrderDirectionToSide(order.order_direction);\n const type = mapOrderTypeToOrdType(order.order_type);\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n const params: Parameters<typeof postSpotOrder>[1] = {\n symbol,\n side,\n type,\n quantity: order.volume,\n newClientOrderId: deriveClientOrderId(order),\n };\n if (type === 'LIMIT') {\n if (order.price === undefined) {\n throw new Error('Binance spot LIMIT order requires price');\n }\n params.price = order.price;\n params.timeInForce = timeInForce;\n }\n if (order.price !== undefined && type === 'MARKET') {\n params.price = order.price;\n }\n const res = await postSpotOrder(credential, params);\n if (isApiError(res)) {\n throw new Error(`Binance submit spot order failed: ${res.code} ${res.msg}`);\n }\n return { order_id: `${res.orderId}` };\n};\n\nexport const submitOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const [, TYPE] = decodePath(order.product_id);\n\n if (TYPE === 'USDT-FUTURE') {\n return submitUnifiedOrder(credential, order);\n }\n if (TYPE === 'SPOT') {\n return submitSpotOrder(credential, order);\n }\n\n throw newError('BINANCE_SUBMIT_ORDER_UNSUPPORTED_PRODUCT_TYPE', { order });\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"unified.d.ts","sourceRoot":"","sources":["../../../src/services/accounts/unified.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAC;AAGnE,OAAO,EAAiD,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGnG,eAAO,MAAM,qBAAqB,eAAsB,WAAW,KAAG,QAAQ,SAAS,EAAE,CAsExF,CAAC"}
1
+ {"version":3,"file":"unified.d.ts","sourceRoot":"","sources":["../../../src/services/accounts/unified.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAC;AAGnE,OAAO,EAAiD,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGnG,eAAO,MAAM,qBAAqB,eAAsB,WAAW,KAAG,QAAQ,SAAS,EAAE,CAuExF,CAAC"}
@@ -33,7 +33,8 @@ const getUnifiedAccountInfo = async (credential) => {
33
33
  volume: Math.abs(+position.positionAmt),
34
34
  free_volume: Math.abs(+position.positionAmt),
35
35
  position_price: +position.entryPrice,
36
- closable_price: +position.entryPrice + +position.unrealizedProfit / Math.abs(+position.positionAmt),
36
+ // ISSUE: positionAmt 有正负,这里计算有个 trick,不需要区分仓位方向
37
+ closable_price: +position.entryPrice + +position.unrealizedProfit / +position.positionAmt,
37
38
  floating_profit: +position.unrealizedProfit,
38
39
  valuation: +position.positionAmt *
39
40
  (+position.entryPrice +
@@ -1 +1 @@
1
- {"version":3,"file":"unified.js","sourceRoot":"","sources":["../../../src/services/accounts/unified.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition, makeSpotPosition } from '@yuants/data-account';\nimport { encodePath } from '@yuants/utils';\nimport { isApiError } from '../../api/client';\nimport { getUnifiedAccountBalance, getUnifiedUmAccount, ICredential } from '../../api/private-api';\nimport { getSpotTickerPrice } from '../../api/public-api';\n\nexport const getUnifiedAccountInfo = async (credential: ICredential): Promise<IPosition[]> => {\n const [balanceRes, umAccountRes] = await Promise.all([\n getUnifiedAccountBalance(credential),\n getUnifiedUmAccount(credential),\n ]);\n if (isApiError(balanceRes)) {\n throw new Error(balanceRes.msg);\n }\n if (isApiError(umAccountRes)) {\n throw new Error(umAccountRes.msg);\n }\n\n const positions: IPosition[] = umAccountRes.positions\n .filter((position) => +position.positionAmt !== 0)\n .map((position) => ({\n position_id: `${position.symbol}/${position.positionSide}`,\n datasource_id: 'BINANCE',\n product_id: encodePath('BINANCE', 'USDT-FUTURE', position.symbol),\n direction:\n position.positionSide === 'LONG'\n ? 'LONG'\n : position.positionSide === 'SHORT'\n ? 'SHORT'\n : position.positionSide === 'BOTH'\n ? 'BOTH'\n : 'UNKNOWN',\n volume: Math.abs(+position.positionAmt),\n free_volume: Math.abs(+position.positionAmt),\n position_price: +position.entryPrice,\n closable_price: +position.entryPrice + +position.unrealizedProfit / Math.abs(+position.positionAmt),\n floating_profit: +position.unrealizedProfit,\n valuation:\n +position.positionAmt *\n (+position.entryPrice +\n (+position.positionAmt === 0 ? 0 : +position.unrealizedProfit / +position.positionAmt)),\n }));\n\n const prices = await getSpotTickerPrice({\n symbols: JSON.stringify([\n ...new Set([\n ...balanceRes\n .map((balance) => {\n const match = balance.asset.match(/^LD(\\w+)$/);\n let symbol = balance.asset;\n if (match) {\n symbol = match[1];\n }\n if (symbol === 'USDT') return '';\n return `${symbol}USDT`;\n })\n .filter(Boolean),\n ]),\n ]),\n });\n const balancePositions: IPosition[] = balanceRes.map((position) =>\n makeSpotPosition({\n position_id: `UNIFIED-SPOT/${position.asset}`,\n datasource_id: 'BINANCE',\n product_id: encodePath('BINANCE', 'UNIFIED-SPOT', position.asset),\n volume: +position.totalWalletBalance + +position.umUnrealizedPNL,\n free_volume: +position.crossMarginFree,\n closable_price:\n position.asset === 'USDT'\n ? 1\n : Array.isArray(prices)\n ? +(prices.find((item) => item.symbol === `${position.asset}USDT`)?.price ?? 0)\n : 0,\n }),\n );\n return [...balancePositions, ...positions];\n};\n"]}
1
+ {"version":3,"file":"unified.js","sourceRoot":"","sources":["../../../src/services/accounts/unified.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition, makeSpotPosition } from '@yuants/data-account';\nimport { encodePath } from '@yuants/utils';\nimport { isApiError } from '../../api/client';\nimport { getUnifiedAccountBalance, getUnifiedUmAccount, ICredential } from '../../api/private-api';\nimport { getSpotTickerPrice } from '../../api/public-api';\n\nexport const getUnifiedAccountInfo = async (credential: ICredential): Promise<IPosition[]> => {\n const [balanceRes, umAccountRes] = await Promise.all([\n getUnifiedAccountBalance(credential),\n getUnifiedUmAccount(credential),\n ]);\n if (isApiError(balanceRes)) {\n throw new Error(balanceRes.msg);\n }\n if (isApiError(umAccountRes)) {\n throw new Error(umAccountRes.msg);\n }\n\n const positions: IPosition[] = umAccountRes.positions\n .filter((position) => +position.positionAmt !== 0)\n .map((position) => ({\n position_id: `${position.symbol}/${position.positionSide}`,\n datasource_id: 'BINANCE',\n product_id: encodePath('BINANCE', 'USDT-FUTURE', position.symbol),\n direction:\n position.positionSide === 'LONG'\n ? 'LONG'\n : position.positionSide === 'SHORT'\n ? 'SHORT'\n : position.positionSide === 'BOTH'\n ? 'BOTH'\n : 'UNKNOWN',\n volume: Math.abs(+position.positionAmt),\n free_volume: Math.abs(+position.positionAmt),\n position_price: +position.entryPrice,\n // ISSUE: positionAmt 有正负,这里计算有个 trick,不需要区分仓位方向\n closable_price: +position.entryPrice + +position.unrealizedProfit / +position.positionAmt,\n floating_profit: +position.unrealizedProfit,\n valuation:\n +position.positionAmt *\n (+position.entryPrice +\n (+position.positionAmt === 0 ? 0 : +position.unrealizedProfit / +position.positionAmt)),\n }));\n\n const prices = await getSpotTickerPrice({\n symbols: JSON.stringify([\n ...new Set([\n ...balanceRes\n .map((balance) => {\n const match = balance.asset.match(/^LD(\\w+)$/);\n let symbol = balance.asset;\n if (match) {\n symbol = match[1];\n }\n if (symbol === 'USDT') return '';\n return `${symbol}USDT`;\n })\n .filter(Boolean),\n ]),\n ]),\n });\n const balancePositions: IPosition[] = balanceRes.map((position) =>\n makeSpotPosition({\n position_id: `UNIFIED-SPOT/${position.asset}`,\n datasource_id: 'BINANCE',\n product_id: encodePath('BINANCE', 'UNIFIED-SPOT', position.asset),\n volume: +position.totalWalletBalance + +position.umUnrealizedPNL,\n free_volume: +position.crossMarginFree,\n closable_price:\n position.asset === 'USDT'\n ? 1\n : Array.isArray(prices)\n ? +(prices.find((item) => item.symbol === `${position.asset}USDT`)?.price ?? 0)\n : 0,\n }),\n );\n return [...balancePositions, ...positions];\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"submitOrder.d.ts","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAGjE,OAAO,EAAE,WAAW,EAA8B,MAAM,uBAAuB,CAAC;AAuEhF,eAAO,MAAM,WAAW,EAAE,2BAA2B,CAAC,WAAW,CAWhE,CAAC"}
1
+ {"version":3,"file":"submitOrder.d.ts","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAGjE,OAAO,EAAE,WAAW,EAA8B,MAAM,uBAAuB,CAAC;AA4EhF,eAAO,MAAM,WAAW,EAAE,2BAA2B,CAAC,WAAW,CAWhE,CAAC"}
@@ -10,11 +10,17 @@ const submitUnifiedOrder = async (credential, order) => {
10
10
  if (!order.volume) {
11
11
  throw new Error('Binance submitOrder requires order.volume to be set');
12
12
  }
13
+ // 单向持仓模式 (single side mode) 下
14
+ const isSingleSideMode = false; // TODO: fetch from account info API and cache it
13
15
  const side = (0, order_utils_1.mapOrderDirectionToSide)(order.order_direction);
14
- const positionSide = (0, order_utils_1.mapOrderDirectionToPositionSide)(order.order_direction);
16
+ const positionSide = isSingleSideMode ? undefined : (0, order_utils_1.mapOrderDirectionToPositionSide)(order.order_direction);
15
17
  const type = (0, order_utils_1.mapOrderTypeToOrdType)(order.order_type);
16
18
  const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;
17
- const reduceOnly = order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT' ? 'true' : undefined;
19
+ const reduceOnly = isSingleSideMode
20
+ ? order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT'
21
+ ? 'true'
22
+ : undefined
23
+ : undefined;
18
24
  const res = await (0, private_api_1.postUmOrder)(credential, {
19
25
  symbol,
20
26
  side,
@@ -1 +1 @@
1
- {"version":3,"file":"submitOrder.js","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"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","sourcesContent":["import { IActionHandlerOfSubmitOrder } from '@yuants/data-order';\nimport { decodePath, newError } from '@yuants/utils';\nimport { isApiError } from '../../api/client';\nimport { ICredential, postSpotOrder, postUmOrder } from '../../api/private-api';\nimport {\n decodeFutureSymbol,\n decodeSpotSymbol,\n deriveClientOrderId,\n mapOrderDirectionToPositionSide,\n mapOrderDirectionToSide,\n mapOrderTypeToOrdType,\n} from './order-utils';\n\nconst submitUnifiedOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const symbol = decodeFutureSymbol(order.product_id);\n if (!order.volume) {\n throw new Error('Binance submitOrder requires order.volume to be set');\n }\n const side = mapOrderDirectionToSide(order.order_direction);\n const positionSide = mapOrderDirectionToPositionSide(order.order_direction);\n const type = mapOrderTypeToOrdType(order.order_type);\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n const reduceOnly =\n order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT' ? 'true' : undefined;\n\n const res = await postUmOrder(credential, {\n symbol,\n side,\n positionSide,\n type,\n quantity: order.volume,\n price: order.price,\n timeInForce,\n reduceOnly,\n newClientOrderId: deriveClientOrderId(order),\n });\n if (isApiError(res)) {\n throw new Error(`Binance submit unified order failed: ${res.code} ${res.msg}`);\n }\n return { order_id: `${res.orderId}` };\n};\n\nconst submitSpotOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const symbol = decodeSpotSymbol(order.product_id);\n if (!order.volume) {\n throw new Error('Binance submitOrder requires order.volume to be set');\n }\n const side = mapOrderDirectionToSide(order.order_direction);\n const type = mapOrderTypeToOrdType(order.order_type);\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n const params: Parameters<typeof postSpotOrder>[1] = {\n symbol,\n side,\n type,\n quantity: order.volume,\n newClientOrderId: deriveClientOrderId(order),\n };\n if (type === 'LIMIT') {\n if (order.price === undefined) {\n throw new Error('Binance spot LIMIT order requires price');\n }\n params.price = order.price;\n params.timeInForce = timeInForce;\n }\n if (order.price !== undefined && type === 'MARKET') {\n params.price = order.price;\n }\n const res = await postSpotOrder(credential, params);\n if (isApiError(res)) {\n throw new Error(`Binance submit spot order failed: ${res.code} ${res.msg}`);\n }\n return { order_id: `${res.orderId}` };\n};\n\nexport const submitOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const [, TYPE] = decodePath(order.product_id);\n\n if (TYPE === 'USDT-FUTURE') {\n return submitUnifiedOrder(credential, order);\n }\n if (TYPE === 'SPOT') {\n return submitSpotOrder(credential, order);\n }\n\n throw newError('BINANCE_SUBMIT_ORDER_UNSUPPORTED_PRODUCT_TYPE', { order });\n};\n"]}
1
+ {"version":3,"file":"submitOrder.js","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"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","sourcesContent":["import { IActionHandlerOfSubmitOrder } from '@yuants/data-order';\nimport { decodePath, newError } from '@yuants/utils';\nimport { isApiError } from '../../api/client';\nimport { ICredential, postSpotOrder, postUmOrder } from '../../api/private-api';\nimport {\n decodeFutureSymbol,\n decodeSpotSymbol,\n deriveClientOrderId,\n mapOrderDirectionToPositionSide,\n mapOrderDirectionToSide,\n mapOrderTypeToOrdType,\n} from './order-utils';\n\nconst submitUnifiedOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const symbol = decodeFutureSymbol(order.product_id);\n if (!order.volume) {\n throw new Error('Binance submitOrder requires order.volume to be set');\n }\n // 单向持仓模式 (single side mode) 下\n const isSingleSideMode = false; // TODO: fetch from account info API and cache it\n const side = mapOrderDirectionToSide(order.order_direction);\n const positionSide = isSingleSideMode ? undefined : mapOrderDirectionToPositionSide(order.order_direction);\n const type = mapOrderTypeToOrdType(order.order_type);\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n const reduceOnly = isSingleSideMode\n ? order.order_direction === 'CLOSE_LONG' || order.order_direction === 'CLOSE_SHORT'\n ? 'true'\n : undefined\n : undefined;\n\n const res = await postUmOrder(credential, {\n symbol,\n side,\n positionSide,\n type,\n quantity: order.volume,\n price: order.price,\n timeInForce,\n reduceOnly,\n newClientOrderId: deriveClientOrderId(order),\n });\n if (isApiError(res)) {\n throw new Error(`Binance submit unified order failed: ${res.code} ${res.msg}`);\n }\n return { order_id: `${res.orderId}` };\n};\n\nconst submitSpotOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const symbol = decodeSpotSymbol(order.product_id);\n if (!order.volume) {\n throw new Error('Binance submitOrder requires order.volume to be set');\n }\n const side = mapOrderDirectionToSide(order.order_direction);\n const type = mapOrderTypeToOrdType(order.order_type);\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n const params: Parameters<typeof postSpotOrder>[1] = {\n symbol,\n side,\n type,\n quantity: order.volume,\n newClientOrderId: deriveClientOrderId(order),\n };\n if (type === 'LIMIT') {\n if (order.price === undefined) {\n throw new Error('Binance spot LIMIT order requires price');\n }\n params.price = order.price;\n params.timeInForce = timeInForce;\n }\n if (order.price !== undefined && type === 'MARKET') {\n params.price = order.price;\n }\n const res = await postSpotOrder(credential, params);\n if (isApiError(res)) {\n throw new Error(`Binance submit spot order failed: ${res.code} ${res.msg}`);\n }\n return { order_id: `${res.orderId}` };\n};\n\nexport const submitOrder: IActionHandlerOfSubmitOrder<ICredential> = async (credential, order) => {\n const [, TYPE] = decodePath(order.product_id);\n\n if (TYPE === 'USDT-FUTURE') {\n return submitUnifiedOrder(credential, order);\n }\n if (TYPE === 'SPOT') {\n return submitSpotOrder(credential, order);\n }\n\n throw newError('BINANCE_SUBMIT_ORDER_UNSUPPORTED_PRODUCT_TYPE', { order });\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuants/vendor-binance",
3
- "version": "0.10.16",
3
+ "version": "0.10.18",
4
4
  "main": "lib/index.js",
5
5
  "files": [
6
6
  "dist",
@@ -13,7 +13,7 @@
13
13
  "@yuants/cache": "0.3.3",
14
14
  "@yuants/data-quote": "0.2.43",
15
15
  "@yuants/utils": "0.14.0",
16
- "@yuants/data-series": "0.3.51",
16
+ "@yuants/data-series": "0.3.52",
17
17
  "@yuants/sql": "0.9.30",
18
18
  "@yuants/data-product": "0.5.0",
19
19
  "@yuants/data-ohlc": "0.4.22",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "apps/vendor-binance/AGENTS.md": "378369925bffa237cd5e8ef459fe2bc2a141337c",
3
- "apps/vendor-binance/CHANGELOG.json": "1880833645a9b7178d28d8fa24c92ff20fc0f615",
4
- "apps/vendor-binance/CHANGELOG.md": "63eadc6d786733ca7e8b19c389c8059683d53984",
3
+ "apps/vendor-binance/CHANGELOG.json": "7887fccfbebb44305b1e002abef86b9f96bbbf33",
4
+ "apps/vendor-binance/CHANGELOG.md": "f19805398df888be73f115b97681d075f78a35a1",
5
5
  "apps/vendor-binance/README.md": "4ab94c08b3d07398aee74c3264a4f87d554d20fa",
6
6
  "apps/vendor-binance/SESSION_NOTES.md": "dd49b3364394c502fdcaf687ed5942811d89abe9",
7
7
  "apps/vendor-binance/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c",
@@ -9,7 +9,7 @@
9
9
  "apps/vendor-binance/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
10
10
  "apps/vendor-binance/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
11
11
  "apps/vendor-binance/etc/vendor-binance.api.md": "2094b84e9b5e7503f5c42b31fffee8d7db47fe7b",
12
- "apps/vendor-binance/package.json": "c927a693e1f2c6da1943f151428ed4e78bccd6f6",
12
+ "apps/vendor-binance/package.json": "7287336462db0cab55ac59737f121097e8a10560",
13
13
  "apps/vendor-binance/src/api/client.ts": "fab85d85d10577f0b6430a551dab46d7c1d2258a",
14
14
  "apps/vendor-binance/src/api/private-api.ts": "982c1902b8417aba1f75df5fa63db76dfc416dac",
15
15
  "apps/vendor-binance/src/api/public-api.ts": "70dc33214e05ec3ead45271bfae70abdb0623c1e",
@@ -21,13 +21,13 @@
21
21
  "apps/vendor-binance/src/public-data/quote.ts": "0445513ea3b36e1ba9bd05d577ac7050503168f0",
22
22
  "apps/vendor-binance/src/services/accounts/profile.ts": "1d23b04d19c078e8c21f41efd6ca3db37b0bd206",
23
23
  "apps/vendor-binance/src/services/accounts/spot.ts": "7561d3054c967b48711a4dcedf96946eeab9fab4",
24
- "apps/vendor-binance/src/services/accounts/unified.ts": "feb19cb0e3dc67669ff5da60a0e859ff5412d3f3",
24
+ "apps/vendor-binance/src/services/accounts/unified.ts": "c9c53e33bd68cd37e61a8bc7494b534af97c3985",
25
25
  "apps/vendor-binance/src/services/exchange.ts": "c989e025b771f5d5c49efcc779ca388dfb1d488d",
26
26
  "apps/vendor-binance/src/services/orders/cancelOrder.ts": "7177ca56fd09b11651edbb38e1962363ac67d4ff",
27
27
  "apps/vendor-binance/src/services/orders/listOrders.ts": "baa21b8e858c1ec593415145cc63fb38a6841d3f",
28
28
  "apps/vendor-binance/src/services/orders/modifyOrder.ts": "0d1ec4d683e43876e9d53ee29cdc5324301b287e",
29
29
  "apps/vendor-binance/src/services/orders/order-utils.ts": "e5278e306dc0e21f7e010424ead327249b1139cc",
30
- "apps/vendor-binance/src/services/orders/submitOrder.ts": "1e05c8900c9d5e774953a4df22b07639fa927b29",
30
+ "apps/vendor-binance/src/services/orders/submitOrder.ts": "ffee0eb2cefd027c857167bfaa9f36edb14e8c8c",
31
31
  "apps/vendor-binance/tsconfig.json": "81da8f78196974b5d15da0edb6b2d9f48641063c",
32
32
  "apps/vendor-binance/.rush/temp/shrinkwrap-deps.json": "0408a4d9b00c1701e07aa22f8350e585241c4581",
33
33
  "libraries/protocol/temp/package-deps.json": "0bd43721e96039b52d7b59c834dc6df45cf75e3f",
@@ -35,7 +35,7 @@
35
35
  "libraries/cache/temp/package-deps.json": "a4afa15e6462983f9d3735d31dc1ed8a683fb4dc",
36
36
  "libraries/data-quote/temp/package-deps.json": "34d079eab44d2bf65e07b112ac2099c6e92a015e",
37
37
  "libraries/utils/temp/package-deps.json": "6d58e9b325e8d16de8a878c32010f626b12a01da",
38
- "libraries/data-series/temp/package-deps.json": "c89ebffe302757903aa54eff78f76cb855486b8c",
38
+ "libraries/data-series/temp/package-deps.json": "e12b4c97d2b8c8b21d1a033cdd3683e01f81401a",
39
39
  "libraries/sql/temp/package-deps.json": "4a9a7ec55f04b20459e664e81e76fa74b6c77b39",
40
40
  "libraries/data-product/temp/package-deps.json": "a03f08f30800d5fb52c5d019bda4f8e7ec04e344",
41
41
  "libraries/data-ohlc/temp/package-deps.json": "c0059a14c647112486ad561d730a4427b9f6f832",