Take Profit Stop Loss SDK
The TPSL (Take Profit Stop Loss) SDK provides functions for managing conditional orders that execute when certain price conditions are met. A conditional order pairs a trigger condition with a pending order. Once the oracle price crosses the trigger price, anyone can execute the pending order on the manager's behalf.
SDK setup
TPSL functions live on the DeepBook client extension. Create a SuiGrpcClient and extend it with deepbook(), passing the margin managers you want to address by key.
import { deepbook } from '@mysten/deepbook-v3';
import { SuiGrpcClient } from '@mysten/sui/grpc';
const client = new SuiGrpcClient({
network: 'testnet',
baseUrl: 'https://fullnode.testnet.sui.io:443',
}).$extend(
deepbook({
address: '<YOUR_ADDRESS>',
marginManagers: {
MARGIN_MANAGER_1: { address: '0x…', poolKey: 'SUI_DBUSDC' },
},
}),
);
All TPSL functions live on client.deepbook.marginTPSL and return a callback that accepts a Transaction object. Pass the returned function to tx.add(...) or call it with an existing Transaction instance. For the full client setup, including keypairs and margin manager keys, see DeepBook Margin SDK.
TPSL functions
The DeepBook Margin SDK provides the following functions for managing conditional orders.
addConditionalOrder
Use addConditionalOrder to add a conditional order that executes when a price condition is met. The call returns a function that takes a Transaction object.
Parameters
marginManagerKey: String that identifies the margin manager.conditionalOrderId: String representing the unique ID for this conditional order.triggerBelowPrice: Boolean indicating whether to trigger once the oracle price falls below the trigger price. Set it tofalseto trigger once the price rises above the trigger price.triggerPrice: Number representing the oracle price at which to trigger the order. The trigger must not already have been crossed, otherwise the call aborts withEInvalidCondition.pendingOrder: Object containing the order details (eitherPendingLimitOrderParams, which includes apricefield for the limit price, orPendingMarketOrderParams, which has nopricefield).
packages/deepbook-v3/src/transactions/marginTPSL.ts. You probably need to run `pnpm prebuild` and restart the site.cancelConditionalOrder
Use cancelConditionalOrder to cancel a specific conditional order. The call returns a function that takes a Transaction object.
Parameters
marginManagerKey: String that identifies the margin manager.conditionalOrderId: String representing the ID of the conditional order to cancel.
packages/deepbook-v3/src/transactions/marginTPSL.ts. You probably need to run `pnpm prebuild` and restart the site.cancelAllConditionalOrders
Use cancelAllConditionalOrders to cancel all conditional orders for a margin manager. The call returns a function that takes a Transaction object.
Parameters
marginManagerKey: String that identifies the margin manager.
packages/deepbook-v3/src/transactions/marginTPSL.ts. You probably need to run `pnpm prebuild` and restart the site.executeConditionalOrders
Use executeConditionalOrders to execute conditional orders that have been triggered. This is a permissionless function that anyone can call. The call returns a function that takes a Transaction object.
Parameters
managerAddress: String representing the address of the margin manager whose orders to execute. Unlike the other functions, this one takes the manager address rather thanmarginManagerKey, the string that identifies the margin manager.poolKey: String that identifies the DeepBook pool.maxOrdersToExecute: Number representing the maximum number of orders to execute in this call.
packages/deepbook-v3/src/transactions/marginTPSL.ts. You probably need to run `pnpm prebuild` and restart the site.Helper functions
These helper functions create conditions and pending orders for conditional orders.
newCondition
Use newCondition to create a trigger condition for a conditional order. The call returns a function that takes a Transaction object.
Parameters
poolKey: String that identifies the pool.triggerBelowPrice: Boolean indicating whether to trigger when price falls below the trigger price.triggerPrice: Number representing the price at which to trigger.
packages/deepbook-v3/src/transactions/marginTPSL.ts. You probably need to run `pnpm prebuild` and restart the site.newPendingLimitOrder
Use newPendingLimitOrder to create a pending limit order for use in conditional orders. The call returns a function that takes a Transaction object.
Parameters
poolKey: String that identifies the pool.params:PendingLimitOrderParamsobject containing:clientOrderId: Number for client tracking.orderType: Optional order type (default:NO_RESTRICTION).selfMatchingOption: Optional self-matching option (default:SELF_MATCHING_ALLOWED).price: Number representing the limit price.quantity: Number representing the order quantity.isBid: Boolean indicating if this is a buy order.payWithDeep: Optional boolean for fee payment (default:true).expireTimestamp: Optional expiration timestamp.
packages/deepbook-v3/src/transactions/marginTPSL.ts. You probably need to run `pnpm prebuild` and restart the site.newPendingMarketOrder
Use newPendingMarketOrder to create a pending market order for use in conditional orders. The call returns a function that takes a Transaction object.
Parameters
poolKey: String that identifies the pool.params:PendingMarketOrderParamsobject containing:clientOrderId: Number for client tracking.selfMatchingOption: Optional self-matching option (default:SELF_MATCHING_ALLOWED).quantity: Number representing the order quantity.isBid: Boolean indicating if this is a buy order.payWithDeep: Optional boolean for fee payment (default:true).
packages/deepbook-v3/src/transactions/marginTPSL.ts. You probably need to run `pnpm prebuild` and restart the site.Read-only functions
conditionalOrderIds
Query all conditional order IDs for a margin manager. Like the other TPSL functions, conditionalOrderIds lives on client.deepbook.marginTPSL. Like the other TPSL functions, conditionalOrderIds lives on client.deepbook.marginTPSL.
packages/deepbook-v3/src/transactions/marginTPSL.ts. You probably need to run `pnpm prebuild` and restart the site.conditionalOrder
Query a specific conditional order by ID.
packages/deepbook-v3/src/transactions/marginTPSL.ts. You probably need to run `pnpm prebuild` and restart the site.lowestTriggerAbovePrice, highestTriggerBelowPrice
Query trigger prices for conditional orders. lowestTriggerAbovePrice returns the lowest trigger price among trigger-above orders (or max_u64 if none exist). highestTriggerBelowPrice returns the highest trigger price among trigger-below orders (or 0 if none exist).
packages/deepbook-v3/src/transactions/marginTPSL.ts. You probably need to run `pnpm prebuild` and restart the site.Examples
Set up a stop loss order
// Example: stop loss on a long position, selling once the oracle price drops below 2.0
const setStopLoss = (tx: Transaction) => {
const managerKey = 'MARGIN_MANAGER_1';
client.deepbook.marginTPSL.addConditionalOrder({
marginManagerKey: managerKey,
conditionalOrderId: '1',
triggerBelowPrice: true, // Fires once the oracle price falls below the trigger
triggerPrice: 2.0,
pendingOrder: {
clientOrderId: '100',
quantity: 50,
isBid: false, // Sell order
payWithDeep: true,
},
})(tx);
};
Set up a take profit order
// Example: take profit on a long position, selling once the oracle price rises above 5.0
const setTakeProfit = (tx: Transaction) => {
const managerKey = 'MARGIN_MANAGER_1';
client.deepbook.marginTPSL.addConditionalOrder({
marginManagerKey: managerKey,
conditionalOrderId: '2',
triggerBelowPrice: false, // Fires once the oracle price rises above the trigger
triggerPrice: 5.0,
pendingOrder: {
clientOrderId: '101',
price: 5.0, // Limit order at 5.0
quantity: 50,
isBid: false, // Sell order
payWithDeep: true,
},
})(tx);
};
Execute triggered orders (keeper)
// Example: Execute conditional orders as a keeper
const executeOrders = (tx: Transaction) => {
const managerAddress = '0x...'; // Address of margin manager
// Execute up to 10 triggered orders
client.deepbook.marginTPSL.executeConditionalOrders(managerAddress, 'SUI_DBUSDC', 10)(tx);
};
Query and cancel orders
// Example: Query all conditional order IDs, then cancel a specific order
const manageOrders = async () => {
const tx = new Transaction();
const managerKey = 'MARGIN_MANAGER_1';
// Query existing conditional order IDs
const orderIds = await client.deepbook.getConditionalOrderIds(managerKey);
// Cancel a specific order by ID
if (orderIds.length > 0) {
tx.add(client.deepbook.marginTPSL.cancelConditionalOrder(managerKey, orderIds[0]));
}
// Or cancel all conditional orders at once
tx.add(client.deepbook.marginTPSL.cancelAllConditionalOrders(managerKey));
};
How conditional orders work
A conditional order consists of two parts: a trigger condition and a pending order. addConditionalOrder stores both on the margin manager. Nothing onchain watches the price, so the order simply sits there until someone calls executeConditionalOrders.
Triggers compare against the margin registry's oracle (Pyth) price, not the order book price. A trigger that the oracle price has already crossed is rejected at registration with EInvalidCondition, so you can only register a condition that is still ahead of the market.
Execution is permissionless. Any caller can invoke executeConditionalOrders for a given margin manager address. Keeper bots typically monitor trigger prices using lowestTriggerAbovePrice and highestTriggerBelowPrice, then call executeConditionalOrders when the oracle price crosses those thresholds. For stop losses, prefer executeConditionalOrdersV3: it repays the loan with each market fill before checking the risk ratio, which lets a stop loss fire when the position is near liquidation, where executeConditionalOrders rejects the fill.
triggerBelowPrice sets the direction of the trigger, not the intent of the order:
triggerBelowPrice: truefires once the oracle price falls belowtriggerPrice. For a long position this is the stop loss; for a short it is the take profit.triggerBelowPrice: falsefires once the oracle price rises abovetriggerPrice. For a long position this is the take profit; for a short it is the stop loss.
Pair the trigger condition with either a limit order (newPendingLimitOrder) for price-controlled execution or a market order (newPendingMarketOrder) for immediate execution at the best available prices. A market order fills against whatever liquidity the book holds at that moment, so it controls timing rather than price.