@blackcube/xgate-sdk 0.56.3 → 0.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1323,6 +1323,8 @@ interface IOrder {
1323
1323
  type: OrderType;
1324
1324
  /** `null` pour un ordre au marché. */
1325
1325
  price: string | null;
1326
+ /** Prix de DÉCLENCHEMENT d'un ordre conditionnel (stop, take-profit) ; `null` pour un ordre ordinaire. */
1327
+ triggerPrice: string | null;
1326
1328
  /** Taille demandée, **en unités de base**. */
1327
1329
  size: string;
1328
1330
  /** Taille déjà exécutée, **en unités de base**. */
@@ -1335,6 +1337,24 @@ interface IOrder {
1335
1337
  placedAt: Date;
1336
1338
  xtras?: Record<string, unknown>;
1337
1339
  }
1340
+ /** Le rôle d'un ordre dans un trade : l'entrée, le stop, ou un take-profit. */
1341
+ type TradeOrderRole = 'entry' | 'sl' | 'tp';
1342
+ /**
1343
+ * UN ORDRE DU TRADE — ce que {@link TradingService.openWithProtection} rend, une ligne par ordre posé.
1344
+ *
1345
+ * La même forme sur toutes les venues : l'appelant garde cette liste avec son trade et la gère sans savoir
1346
+ * comment chaque venue a posé ses protections (hyperliquid en lot, aster une à une, pacifica embarquées dans
1347
+ * l'entrée). C'est XGate qui fait le pont.
1348
+ *
1349
+ * **L'identifiant n'est vide que si l'ordre n'existe pas ou plus** — refusé, ou déjà consommé (un stop touché
1350
+ * dans la seconde) : `status` dit lequel. Une venue qui ne rend pas l'identifiant d'une protection à l'envoi
1351
+ * (hyperliquid `normalTpsl`, pacifica embarqué) le voit retrouvé au carnet par XGate.
1352
+ */
1353
+ interface ITradeOrder extends IOrder {
1354
+ role: TradeOrderRole;
1355
+ /** La fraction de la position initiale que l'ordre couvre : 1 pour l'entrée et le stop. */
1356
+ part: number;
1357
+ }
1338
1358
  /**
1339
1359
  * UNE POSITION ouverte.
1340
1360
  *
@@ -1562,8 +1582,11 @@ declare class TradingService {
1562
1582
  /**
1563
1583
  * OUVRE UNE POSITION AVEC SA PROTECTION, en un geste atomique.
1564
1584
  *
1565
- * Le premier ordre rendu est **l'entrée** ; les suivants sont le stop et les take-profits, dans
1566
- * l'ordre où ils ont été posés.
1585
+ * **Ce qui revient est la liste des ORDRES DU TRADE** ({@link ITradeOrder}), la même sur toutes les
1586
+ * venues : l'entrée, le stop, puis chaque take-profit dans l'ordre du plan — chacun avec son rôle, sa
1587
+ * part et un identifiant réel, retrouvé au carnet quand la venue ne l'a pas rendu à l'envoi (0.58.0,
1588
+ * cf. `ordresDuTrade`). L'appelant la garde avec son trade : annuler une protection, c'est
1589
+ * {@link cancel} sur son identifiant, quel que soit le rôle.
1567
1590
  *
1568
1591
  * Chaque venue applique son mécanisme natif — hyperliquid groupe les enfants sous l'entrée et les
1569
1592
  * annule lui-même si elle rate, pacifica les embarque dans l'ordre, aster envoie un lot de
@@ -1584,7 +1607,27 @@ declare class TradingService {
1584
1607
  * complète par {@link completeProtection} quand il le constate. Jusqu'en 0.56.0 ces cibles n'étaient
1585
1608
  * posées par personne : une position tide à trois paliers sur pacifica partait sans sa dernière.
1586
1609
  */
1587
- openWithProtection(access: ITradingAccess, input: IEntryWithProtection): Promise<IOrder[]>;
1610
+ openWithProtection(access: ITradingAccess, input: IEntryWithProtection): Promise<ITradeOrder[]>;
1611
+ /**
1612
+ * LES ORDRES DU TRADE, rangés par rôle — la même liste sur toutes les venues.
1613
+ *
1614
+ * Chaque venue rend ses ordres à sa façon (mesuré sur testnet le 2026-10-01) : hyperliquid en lot `'na'` rend
1615
+ * tous les identifiants, en `normalTpsl` (un seul take-profit) AUCUN pour le stop et la cible (`waitingForFill`,
1616
+ * `waitingForTrigger`) ; pacifica ne rend que l'entrée, le stop et la première cible embarqués naissant au
1617
+ * carnet sans lien (`parent_id: null`) ; aster pose une à une et rend tout.
1618
+ *
1619
+ * On range donc ce qui est revenu : l'entrée est le premier ordre non reduce-only ; le stop et chaque cible
1620
+ * sont reconnus par leur TYPE et leur PRIX DE DÉCLENCHEMENT — ceux qu'XGate vient de calculer, arrondis à la
1621
+ * grille, donc ceux que la venue a posés. Ce qui manque est cherché au CARNET de la paire, par la même
1622
+ * reconnaissance — le procédé que le SDK pacifica applique déjà à ses take-profits (`placeTakeProfit`).
1623
+ *
1624
+ * Un ordre introuvable garde un identifiant VIDE : refusé, ou déjà consommé (un stop touché dans la seconde,
1625
+ * DOT le 2026-10-01). **Mais une position ouverte dont le stop est introuvable lève** : c'est la position
1626
+ * nue que ce service existe pour empêcher, et l'appelant doit le savoir tout de suite.
1627
+ */
1628
+ private ordresDuTrade;
1629
+ /** Un ordre du trade que la venue n'a pas posé, ou qui n'existe déjà plus — identifiant VIDE. */
1630
+ private ordreAbsent;
1588
1631
  /**
1589
1632
  * POSE LES CIBLES QUE LA VENUE N'A PAS EMBARQUÉES, une fois l'entrée remplie.
1590
1633
  *
@@ -1960,4 +2003,4 @@ declare function expiryOf(xtras?: Record<string, unknown>): Date | undefined;
1960
2003
  */
1961
2004
  declare function isDated(xtras?: Record<string, unknown>): boolean;
1962
2005
 
1963
- export { type AssetClass, CANDLES_MAX_HISTORY, CANDLES_PER_CALL, CandlesService, CandlesStreamRegistry, CandlesStreamService, CatalogService, type Direction, type IAccountState, type IBalance, type ICandle, type ICandlesQuery, type IEntryWithProtection, type IEquityPoint, type IFundingPaid, type IMoveStop, type IMovement, type IOrder, type IPair, type IPosition, type IPrice, type IProtection, type IProtectionInput, type IProtectionLeg, type IPublicTrade, type ITarget, type ITrade, type ITradingAccess, type IWalletAccess, type IXexAccess, type IXexSpotSource, type MarketKind, type MovementKind, type MovementStatus, ORDER_STATUSES, type OrderStatus, type OrderType, PricesService, REST_THROTTLE_MS, SPOT_XEXES, type Side, SpotCandlesService, SpotCatalogService, SpotPricesService, SpotWsCandlesService, TIMEFRAME_MINUTES, type TimeInForce, Timeframe, TradingService, type Unsubscribe, WALLET_XEXES, WS_SUBSCRIPTION_LIMITS, WalletService, WsCandlesService, WsTradesService, XGATE_EXCHANGES, XgateEx, XgateModule, assetClassOf, buildLevels, buildProtection, candlesMaxHistoryOf, candlesPerCallOf, canonicalFromBase, canonicalFromXex, expiryOf, isDated, multiplierFromXex, restThrottleOf, roundPrice, roundToStep, servesNatively, servesSpot, sourceFor, subscriptionLimitOf, timeframeMs };
2006
+ export { type AssetClass, CANDLES_MAX_HISTORY, CANDLES_PER_CALL, CandlesService, CandlesStreamRegistry, CandlesStreamService, CatalogService, type Direction, type IAccountState, type IBalance, type ICandle, type ICandlesQuery, type IEntryWithProtection, type IEquityPoint, type IFundingPaid, type IMoveStop, type IMovement, type IOrder, type IPair, type IPosition, type IPrice, type IProtection, type IProtectionInput, type IProtectionLeg, type IPublicTrade, type ITarget, type ITrade, type ITradeOrder, type ITradingAccess, type IWalletAccess, type IXexAccess, type IXexSpotSource, type MarketKind, type MovementKind, type MovementStatus, ORDER_STATUSES, type OrderStatus, type OrderType, PricesService, REST_THROTTLE_MS, SPOT_XEXES, type Side, SpotCandlesService, SpotCatalogService, SpotPricesService, SpotWsCandlesService, TIMEFRAME_MINUTES, type TimeInForce, Timeframe, type TradeOrderRole, TradingService, type Unsubscribe, WALLET_XEXES, WS_SUBSCRIPTION_LIMITS, WalletService, WsCandlesService, WsTradesService, XGATE_EXCHANGES, XgateEx, XgateModule, assetClassOf, buildLevels, buildProtection, candlesMaxHistoryOf, candlesPerCallOf, canonicalFromBase, canonicalFromXex, expiryOf, isDated, multiplierFromXex, restThrottleOf, roundPrice, roundToStep, servesNatively, servesSpot, sourceFor, subscriptionLimitOf, timeframeMs };
package/dist/index.d.ts CHANGED
@@ -1323,6 +1323,8 @@ interface IOrder {
1323
1323
  type: OrderType;
1324
1324
  /** `null` pour un ordre au marché. */
1325
1325
  price: string | null;
1326
+ /** Prix de DÉCLENCHEMENT d'un ordre conditionnel (stop, take-profit) ; `null` pour un ordre ordinaire. */
1327
+ triggerPrice: string | null;
1326
1328
  /** Taille demandée, **en unités de base**. */
1327
1329
  size: string;
1328
1330
  /** Taille déjà exécutée, **en unités de base**. */
@@ -1335,6 +1337,24 @@ interface IOrder {
1335
1337
  placedAt: Date;
1336
1338
  xtras?: Record<string, unknown>;
1337
1339
  }
1340
+ /** Le rôle d'un ordre dans un trade : l'entrée, le stop, ou un take-profit. */
1341
+ type TradeOrderRole = 'entry' | 'sl' | 'tp';
1342
+ /**
1343
+ * UN ORDRE DU TRADE — ce que {@link TradingService.openWithProtection} rend, une ligne par ordre posé.
1344
+ *
1345
+ * La même forme sur toutes les venues : l'appelant garde cette liste avec son trade et la gère sans savoir
1346
+ * comment chaque venue a posé ses protections (hyperliquid en lot, aster une à une, pacifica embarquées dans
1347
+ * l'entrée). C'est XGate qui fait le pont.
1348
+ *
1349
+ * **L'identifiant n'est vide que si l'ordre n'existe pas ou plus** — refusé, ou déjà consommé (un stop touché
1350
+ * dans la seconde) : `status` dit lequel. Une venue qui ne rend pas l'identifiant d'une protection à l'envoi
1351
+ * (hyperliquid `normalTpsl`, pacifica embarqué) le voit retrouvé au carnet par XGate.
1352
+ */
1353
+ interface ITradeOrder extends IOrder {
1354
+ role: TradeOrderRole;
1355
+ /** La fraction de la position initiale que l'ordre couvre : 1 pour l'entrée et le stop. */
1356
+ part: number;
1357
+ }
1338
1358
  /**
1339
1359
  * UNE POSITION ouverte.
1340
1360
  *
@@ -1562,8 +1582,11 @@ declare class TradingService {
1562
1582
  /**
1563
1583
  * OUVRE UNE POSITION AVEC SA PROTECTION, en un geste atomique.
1564
1584
  *
1565
- * Le premier ordre rendu est **l'entrée** ; les suivants sont le stop et les take-profits, dans
1566
- * l'ordre où ils ont été posés.
1585
+ * **Ce qui revient est la liste des ORDRES DU TRADE** ({@link ITradeOrder}), la même sur toutes les
1586
+ * venues : l'entrée, le stop, puis chaque take-profit dans l'ordre du plan — chacun avec son rôle, sa
1587
+ * part et un identifiant réel, retrouvé au carnet quand la venue ne l'a pas rendu à l'envoi (0.58.0,
1588
+ * cf. `ordresDuTrade`). L'appelant la garde avec son trade : annuler une protection, c'est
1589
+ * {@link cancel} sur son identifiant, quel que soit le rôle.
1567
1590
  *
1568
1591
  * Chaque venue applique son mécanisme natif — hyperliquid groupe les enfants sous l'entrée et les
1569
1592
  * annule lui-même si elle rate, pacifica les embarque dans l'ordre, aster envoie un lot de
@@ -1584,7 +1607,27 @@ declare class TradingService {
1584
1607
  * complète par {@link completeProtection} quand il le constate. Jusqu'en 0.56.0 ces cibles n'étaient
1585
1608
  * posées par personne : une position tide à trois paliers sur pacifica partait sans sa dernière.
1586
1609
  */
1587
- openWithProtection(access: ITradingAccess, input: IEntryWithProtection): Promise<IOrder[]>;
1610
+ openWithProtection(access: ITradingAccess, input: IEntryWithProtection): Promise<ITradeOrder[]>;
1611
+ /**
1612
+ * LES ORDRES DU TRADE, rangés par rôle — la même liste sur toutes les venues.
1613
+ *
1614
+ * Chaque venue rend ses ordres à sa façon (mesuré sur testnet le 2026-10-01) : hyperliquid en lot `'na'` rend
1615
+ * tous les identifiants, en `normalTpsl` (un seul take-profit) AUCUN pour le stop et la cible (`waitingForFill`,
1616
+ * `waitingForTrigger`) ; pacifica ne rend que l'entrée, le stop et la première cible embarqués naissant au
1617
+ * carnet sans lien (`parent_id: null`) ; aster pose une à une et rend tout.
1618
+ *
1619
+ * On range donc ce qui est revenu : l'entrée est le premier ordre non reduce-only ; le stop et chaque cible
1620
+ * sont reconnus par leur TYPE et leur PRIX DE DÉCLENCHEMENT — ceux qu'XGate vient de calculer, arrondis à la
1621
+ * grille, donc ceux que la venue a posés. Ce qui manque est cherché au CARNET de la paire, par la même
1622
+ * reconnaissance — le procédé que le SDK pacifica applique déjà à ses take-profits (`placeTakeProfit`).
1623
+ *
1624
+ * Un ordre introuvable garde un identifiant VIDE : refusé, ou déjà consommé (un stop touché dans la seconde,
1625
+ * DOT le 2026-10-01). **Mais une position ouverte dont le stop est introuvable lève** : c'est la position
1626
+ * nue que ce service existe pour empêcher, et l'appelant doit le savoir tout de suite.
1627
+ */
1628
+ private ordresDuTrade;
1629
+ /** Un ordre du trade que la venue n'a pas posé, ou qui n'existe déjà plus — identifiant VIDE. */
1630
+ private ordreAbsent;
1588
1631
  /**
1589
1632
  * POSE LES CIBLES QUE LA VENUE N'A PAS EMBARQUÉES, une fois l'entrée remplie.
1590
1633
  *
@@ -1960,4 +2003,4 @@ declare function expiryOf(xtras?: Record<string, unknown>): Date | undefined;
1960
2003
  */
1961
2004
  declare function isDated(xtras?: Record<string, unknown>): boolean;
1962
2005
 
1963
- export { type AssetClass, CANDLES_MAX_HISTORY, CANDLES_PER_CALL, CandlesService, CandlesStreamRegistry, CandlesStreamService, CatalogService, type Direction, type IAccountState, type IBalance, type ICandle, type ICandlesQuery, type IEntryWithProtection, type IEquityPoint, type IFundingPaid, type IMoveStop, type IMovement, type IOrder, type IPair, type IPosition, type IPrice, type IProtection, type IProtectionInput, type IProtectionLeg, type IPublicTrade, type ITarget, type ITrade, type ITradingAccess, type IWalletAccess, type IXexAccess, type IXexSpotSource, type MarketKind, type MovementKind, type MovementStatus, ORDER_STATUSES, type OrderStatus, type OrderType, PricesService, REST_THROTTLE_MS, SPOT_XEXES, type Side, SpotCandlesService, SpotCatalogService, SpotPricesService, SpotWsCandlesService, TIMEFRAME_MINUTES, type TimeInForce, Timeframe, TradingService, type Unsubscribe, WALLET_XEXES, WS_SUBSCRIPTION_LIMITS, WalletService, WsCandlesService, WsTradesService, XGATE_EXCHANGES, XgateEx, XgateModule, assetClassOf, buildLevels, buildProtection, candlesMaxHistoryOf, candlesPerCallOf, canonicalFromBase, canonicalFromXex, expiryOf, isDated, multiplierFromXex, restThrottleOf, roundPrice, roundToStep, servesNatively, servesSpot, sourceFor, subscriptionLimitOf, timeframeMs };
2006
+ export { type AssetClass, CANDLES_MAX_HISTORY, CANDLES_PER_CALL, CandlesService, CandlesStreamRegistry, CandlesStreamService, CatalogService, type Direction, type IAccountState, type IBalance, type ICandle, type ICandlesQuery, type IEntryWithProtection, type IEquityPoint, type IFundingPaid, type IMoveStop, type IMovement, type IOrder, type IPair, type IPosition, type IPrice, type IProtection, type IProtectionInput, type IProtectionLeg, type IPublicTrade, type ITarget, type ITrade, type ITradeOrder, type ITradingAccess, type IWalletAccess, type IXexAccess, type IXexSpotSource, type MarketKind, type MovementKind, type MovementStatus, ORDER_STATUSES, type OrderStatus, type OrderType, PricesService, REST_THROTTLE_MS, SPOT_XEXES, type Side, SpotCandlesService, SpotCatalogService, SpotPricesService, SpotWsCandlesService, TIMEFRAME_MINUTES, type TimeInForce, Timeframe, type TradeOrderRole, TradingService, type Unsubscribe, WALLET_XEXES, WS_SUBSCRIPTION_LIMITS, WalletService, WsCandlesService, WsTradesService, XGATE_EXCHANGES, XgateEx, XgateModule, assetClassOf, buildLevels, buildProtection, candlesMaxHistoryOf, candlesPerCallOf, canonicalFromBase, canonicalFromXex, expiryOf, isDated, multiplierFromXex, restThrottleOf, roundPrice, roundToStep, servesNatively, servesSpot, sourceFor, subscriptionLimitOf, timeframeMs };
package/dist/index.js CHANGED
@@ -1250,8 +1250,11 @@ var TradingService = class {
1250
1250
  /**
1251
1251
  * OUVRE UNE POSITION AVEC SA PROTECTION, en un geste atomique.
1252
1252
  *
1253
- * Le premier ordre rendu est **l'entrée** ; les suivants sont le stop et les take-profits, dans
1254
- * l'ordre où ils ont été posés.
1253
+ * **Ce qui revient est la liste des ORDRES DU TRADE** ({@link ITradeOrder}), la même sur toutes les
1254
+ * venues : l'entrée, le stop, puis chaque take-profit dans l'ordre du plan — chacun avec son rôle, sa
1255
+ * part et un identifiant réel, retrouvé au carnet quand la venue ne l'a pas rendu à l'envoi (0.58.0,
1256
+ * cf. `ordresDuTrade`). L'appelant la garde avec son trade : annuler une protection, c'est
1257
+ * {@link cancel} sur son identifiant, quel que soit le rôle.
1255
1258
  *
1256
1259
  * Chaque venue applique son mécanisme natif — hyperliquid groupe les enfants sous l'entrée et les
1257
1260
  * annule lui-même si elle rate, pacifica les embarque dans l'ordre, aster envoie un lot de
@@ -1314,27 +1317,25 @@ var TradingService = class {
1314
1317
  tps: protection.tps,
1315
1318
  clientId: input.clientId
1316
1319
  };
1320
+ let posees;
1317
1321
  try {
1318
1322
  const orders = await perp.createEntryWithProtection(entry, consigne);
1319
- const posees = orders.map((order) => this.toOrder(order, access.xex));
1323
+ posees = orders.map((order) => this.toOrder(order, access.xex));
1320
1324
  const enAttente = this.ciblesEnAttente(perp, consigne);
1321
- if (enAttente.length === 0) {
1322
- return posees;
1323
- }
1324
- if (tif !== "ioc" && tif !== "fok") {
1325
+ if (enAttente.length > 0 && (tif === "ioc" || tif === "fok")) {
1326
+ const complement = await this.poserCiblesEnAttente(
1327
+ access,
1328
+ perp,
1329
+ input.symbolXex,
1330
+ side,
1331
+ enAttente
1332
+ );
1333
+ posees = [...posees, ...complement];
1334
+ } else if (enAttente.length > 0) {
1325
1335
  this.logger.warn(
1326
1336
  `openWithProtection(${access.xex}/${input.symbolXex}) : ${enAttente.length} cible(s) que la venue n'embarque pas \u2014 l'entr\xE9e ${tif} peut rester au carnet, appeler completeProtection une fois remplie.`
1327
1337
  );
1328
- return posees;
1329
1338
  }
1330
- const complement = await this.poserCiblesEnAttente(
1331
- access,
1332
- perp,
1333
- input.symbolXex,
1334
- side,
1335
- enAttente
1336
- );
1337
- return [...posees, ...complement];
1338
1339
  } catch (error) {
1339
1340
  const message = error instanceof Error ? error.message : String(error);
1340
1341
  if (message.includes(ASTER_TIMEOUT) === false) {
@@ -1343,8 +1344,119 @@ var TradingService = class {
1343
1344
  this.logger.warn(
1344
1345
  `openWithProtection(${access.xex}) : la venue a coup\xE9 avant de r\xE9pondre. Statut inconnu \u2014 relecture de l'\xE9tat r\xE9el.`
1345
1346
  );
1346
- return await this.etatApres(access, input.symbolXex);
1347
+ posees = await this.etatApres(access, input.symbolXex);
1347
1348
  }
1349
+ return await this.ordresDuTrade(access, perp, input, side, protection, posees);
1350
+ }
1351
+ /**
1352
+ * LES ORDRES DU TRADE, rangés par rôle — la même liste sur toutes les venues.
1353
+ *
1354
+ * Chaque venue rend ses ordres à sa façon (mesuré sur testnet le 2026-10-01) : hyperliquid en lot `'na'` rend
1355
+ * tous les identifiants, en `normalTpsl` (un seul take-profit) AUCUN pour le stop et la cible (`waitingForFill`,
1356
+ * `waitingForTrigger`) ; pacifica ne rend que l'entrée, le stop et la première cible embarqués naissant au
1357
+ * carnet sans lien (`parent_id: null`) ; aster pose une à une et rend tout.
1358
+ *
1359
+ * On range donc ce qui est revenu : l'entrée est le premier ordre non reduce-only ; le stop et chaque cible
1360
+ * sont reconnus par leur TYPE et leur PRIX DE DÉCLENCHEMENT — ceux qu'XGate vient de calculer, arrondis à la
1361
+ * grille, donc ceux que la venue a posés. Ce qui manque est cherché au CARNET de la paire, par la même
1362
+ * reconnaissance — le procédé que le SDK pacifica applique déjà à ses take-profits (`placeTakeProfit`).
1363
+ *
1364
+ * Un ordre introuvable garde un identifiant VIDE : refusé, ou déjà consommé (un stop touché dans la seconde,
1365
+ * DOT le 2026-10-01). **Mais une position ouverte dont le stop est introuvable lève** : c'est la position
1366
+ * nue que ce service existe pour empêcher, et l'appelant doit le savoir tout de suite.
1367
+ */
1368
+ async ordresDuTrade(access, perp, input, side, protection, posees) {
1369
+ const exit = side === "buy" ? "sell" : "buy";
1370
+ const part = (size) => Number(size) / input.size;
1371
+ const entree = posees.find((order) => order.reduceOnly !== true) ?? null;
1372
+ const rejetee = entree !== null && entree.status === "rejected";
1373
+ const pris = /* @__PURE__ */ new Set();
1374
+ const attendus = [
1375
+ { role: "sl", leg: protection.sl },
1376
+ ...protection.tps.map((leg) => ({ role: "tp", leg }))
1377
+ ];
1378
+ const reconnaitre = (pool, role, leg) => pool.find(
1379
+ (order) => order.id !== "" && pris.has(order.id) === false && estDuRole(order.type, role) === true && (order.triggerPrice === null || memePrix(order.triggerPrice, leg.triggerPrice) === true)
1380
+ );
1381
+ let carnet = null;
1382
+ const lireCarnet = async () => {
1383
+ if (carnet === null) {
1384
+ carnet = (await perp.getOpens()).map((order) => this.toOrder(order, access.xex)).filter((order) => order.symbolXex === input.symbolXex && order.reduceOnly === true);
1385
+ }
1386
+ return carnet;
1387
+ };
1388
+ const ordres = [
1389
+ entree === null ? this.ordreAbsent(
1390
+ access,
1391
+ input,
1392
+ "entry",
1393
+ side,
1394
+ "limit",
1395
+ 1,
1396
+ null,
1397
+ String(input.size),
1398
+ "other"
1399
+ ) : { ...entree, role: "entry", part: 1 }
1400
+ ];
1401
+ for (const { role, leg } of attendus) {
1402
+ let trouve = reconnaitre(posees, role, leg);
1403
+ if (trouve === void 0 && rejetee === false) {
1404
+ trouve = reconnaitre(await lireCarnet(), role, leg);
1405
+ }
1406
+ if (trouve !== void 0) {
1407
+ pris.add(trouve.id);
1408
+ ordres.push({ ...trouve, role, part: part(leg.size) });
1409
+ } else {
1410
+ ordres.push(
1411
+ this.ordreAbsent(
1412
+ access,
1413
+ input,
1414
+ role,
1415
+ exit,
1416
+ role === "sl" ? "stopMarket" : "takeProfitMarket",
1417
+ part(leg.size),
1418
+ leg.triggerPrice,
1419
+ leg.size,
1420
+ rejetee === true ? "canceled" : "other"
1421
+ )
1422
+ );
1423
+ }
1424
+ }
1425
+ const stop = ordres.find((order) => order.role === "sl");
1426
+ if (rejetee === false && stop !== void 0 && stop.id === "") {
1427
+ const positions = await perp.getPositions({ name: input.symbolXex });
1428
+ const ouverte = positions.find(
1429
+ (candidate) => candidate.name === input.symbolXex && Number(candidate.size) !== 0
1430
+ );
1431
+ if (ouverte !== void 0) {
1432
+ throw new Error(
1433
+ `openWithProtection(${access.xex}/${input.symbolXex}) : POSITION NUE \u2014 ${ouverte.size} ouvert, stop introuvable au carnet. \xC0 prot\xE9ger imm\xE9diatement.`
1434
+ );
1435
+ }
1436
+ }
1437
+ return ordres;
1438
+ }
1439
+ /** Un ordre du trade que la venue n'a pas posé, ou qui n'existe déjà plus — identifiant VIDE. */
1440
+ ordreAbsent(access, input, role, side, type, part, triggerPrice, size, status) {
1441
+ return {
1442
+ xex: access.xex,
1443
+ symbolXex: input.symbolXex,
1444
+ kind: "perp",
1445
+ id: "",
1446
+ clientId: null,
1447
+ side,
1448
+ type,
1449
+ price: null,
1450
+ triggerPrice,
1451
+ size,
1452
+ filled: "0",
1453
+ status,
1454
+ tif: null,
1455
+ reduceOnly: role !== "entry",
1456
+ placedAt: /* @__PURE__ */ new Date(),
1457
+ role,
1458
+ part
1459
+ };
1348
1460
  }
1349
1461
  /**
1350
1462
  * POSE LES CIBLES QUE LA VENUE N'A PAS EMBARQUÉES, une fois l'entrée remplie.
@@ -1870,6 +1982,7 @@ var TradingService = class {
1870
1982
  side: order.side,
1871
1983
  type: order.type,
1872
1984
  price: order.price,
1985
+ triggerPrice: order.triggerPrice,
1873
1986
  size: order.size,
1874
1987
  filled: order.filled,
1875
1988
  status: this.toStatus(order.status),
@@ -1883,6 +1996,14 @@ var TradingService = class {
1883
1996
  TradingService = __decorateClass([
1884
1997
  Injectable()
1885
1998
  ], TradingService);
1999
+ function estDuRole(type, role) {
2000
+ return role === "sl" ? type === "stop" || type === "stopMarket" : type === "takeProfit" || type === "takeProfitMarket";
2001
+ }
2002
+ function memePrix(lu, pose) {
2003
+ const a = Number(lu);
2004
+ const b = Number(pose);
2005
+ return Math.abs(a - b) <= 1e-9 * Math.max(1, Math.abs(b));
2006
+ }
1886
2007
  function toXexDate(date) {
1887
2008
  return date.toISOString().slice(0, 19).replace("T", " ");
1888
2009
  }
@@ -2261,6 +2382,7 @@ var WsTradesService = class {
2261
2382
  side: order.side,
2262
2383
  type: order.type,
2263
2384
  price: order.price,
2385
+ triggerPrice: order.triggerPrice,
2264
2386
  size: order.size,
2265
2387
  filled: order.filled,
2266
2388
  status: ORDER_STATUSES.includes(order.status) ? order.status : "other",