Drift supports multiple order types including market, limit, trigger, and oracle orders. This guide covers how to place each type using the SDK.
Order Types
Market Orders Execute immediately at the best available price
Limit Orders Execute at a specified price or better
Trigger Orders Activate when a condition is met
Oracle Orders Reference oracle price with offset
Placing a Market Order
Market orders execute immediately at the best available price:
import { BN } from '@coral-xyz/anchor' ;
import {
DriftClient ,
getMarketOrderParams ,
PositionDirection ,
BASE_PRECISION ,
MarketType ,
} from '@drift-labs/sdk' ;
// Buy 1 SOL-PERP at market price
const marketIndex = 0 ; // SOL-PERP
const baseAssetAmount = new BN ( 1 ). mul ( BASE_PRECISION ); // 1 SOL
const orderParams = getMarketOrderParams ({
marketIndex ,
direction: PositionDirection . LONG ,
baseAssetAmount ,
marketType: MarketType . PERP ,
});
const txSig = await driftClient . placePerpOrder ( orderParams );
console . log ( 'Market order placed:' , txSig );
Market Order with Price Limits
Set a maximum acceptable price to prevent slippage:
import { PRICE_PRECISION } from '@drift-labs/sdk' ;
// Buy SOL-PERP but not above $150
const maxPrice = new BN ( 150 ). mul ( PRICE_PRECISION );
const orderParams = getMarketOrderParams ({
marketIndex: 0 ,
direction: PositionDirection . LONG ,
baseAssetAmount: new BN ( 1 ). mul ( BASE_PRECISION ),
price: maxPrice ,
marketType: MarketType . PERP ,
});
await driftClient . placePerpOrder ( orderParams );
Placing a Limit Order
Limit orders execute only at your specified price or better:
import {
getLimitOrderParams ,
PositionDirection ,
PostOnlyParams ,
BASE_PRECISION ,
PRICE_PRECISION ,
} from '@drift-labs/sdk' ;
// Buy 1 SOL-PERP at $145 or better
const limitPrice = new BN ( 145 ). mul ( PRICE_PRECISION );
const baseAmount = new BN ( 1 ). mul ( BASE_PRECISION );
const orderParams = getLimitOrderParams ({
marketIndex: 0 ,
direction: PositionDirection . LONG ,
baseAssetAmount: baseAmount ,
price: limitPrice ,
marketType: MarketType . PERP ,
});
const txSig = await driftClient . placePerpOrder ( orderParams );
console . log ( 'Limit order placed:' , txSig );
Post-Only Orders
Ensure your order only adds liquidity (maker fee):
const orderParams = getLimitOrderParams ({
marketIndex: 0 ,
direction: PositionDirection . LONG ,
baseAssetAmount: baseAmount ,
price: limitPrice ,
postOnly: PostOnlyParams . MUST_POST_ONLY ,
marketType: MarketType . PERP ,
});
await driftClient . placePerpOrder ( orderParams );
Post-only orders are rejected if they would match immediately. Use PostOnlyParams.TRY_POST_ONLY to allow fallback to taker.
Reduce-Only Orders
Limit orders to only reduce existing positions:
const orderParams = getLimitOrderParams ({
marketIndex: 0 ,
direction: PositionDirection . SHORT , // Close a long position
baseAssetAmount: baseAmount ,
price: limitPrice ,
reduceOnly: true ,
marketType: MarketType . PERP ,
});
await driftClient . placePerpOrder ( orderParams );
Placing a Trigger Order
Trigger orders (stop-loss/take-profit) activate when a price condition is met:
Stop-Loss Order
import {
getTriggerMarketOrderParams ,
OrderTriggerCondition ,
PositionDirection ,
} from '@drift-labs/sdk' ;
// Close long position if SOL drops below $140
const triggerPrice = new BN ( 140 ). mul ( PRICE_PRECISION );
const orderParams = getTriggerMarketOrderParams ({
marketIndex: 0 ,
direction: PositionDirection . SHORT ,
baseAssetAmount: new BN ( 1 ). mul ( BASE_PRECISION ),
triggerPrice ,
triggerCondition: OrderTriggerCondition . BELOW ,
marketType: MarketType . PERP ,
});
await driftClient . placePerpOrder ( orderParams );
Take-Profit Order
// Take profit if SOL rises above $160
const takeProfitPrice = new BN ( 160 ). mul ( PRICE_PRECISION );
const orderParams = getTriggerMarketOrderParams ({
marketIndex: 0 ,
direction: PositionDirection . SHORT , // Close long
baseAssetAmount: new BN ( 1 ). mul ( BASE_PRECISION ),
triggerPrice: takeProfitPrice ,
triggerCondition: OrderTriggerCondition . ABOVE ,
marketType: MarketType . PERP ,
});
await driftClient . placePerpOrder ( orderParams );
Trigger Limit Orders
Combine trigger activation with limit execution:
import { getTriggerLimitOrderParams } from '@drift-labs/sdk' ;
// Trigger at $140, execute as limit at $139
const orderParams = getTriggerLimitOrderParams ({
marketIndex: 0 ,
direction: PositionDirection . SHORT ,
baseAssetAmount: new BN ( 1 ). mul ( BASE_PRECISION ),
price: new BN ( 139 ). mul ( PRICE_PRECISION ), // Limit price
triggerPrice: new BN ( 140 ). mul ( PRICE_PRECISION ), // Trigger price
triggerCondition: OrderTriggerCondition . BELOW ,
marketType: MarketType . PERP ,
});
await driftClient . placePerpOrder ( orderParams );
Placing an Oracle Order
Oracle orders reference the oracle price with an offset:
import { OrderType } from '@drift-labs/sdk' ;
// Buy 5% below oracle price
const orderParams = {
orderType: OrderType . ORACLE ,
marketIndex: 0 ,
direction: PositionDirection . LONG ,
baseAssetAmount: new BN ( 1 ). mul ( BASE_PRECISION ),
oraclePrice Offset: new BN ( - 5 ). mul ( PRICE_PRECISION ). div ( new BN ( 100 )), // -5%
marketType: MarketType . PERP ,
};
await driftClient . placePerpOrder ( orderParams );
Spot Market Orders
Place orders on spot markets (lending/borrowing):
import { getMarketOrderParams , MarketType } from '@drift-labs/sdk' ;
// Swap USDC for SOL (borrow if needed)
const orderParams = getMarketOrderParams ({
marketIndex: 1 , // SOL spot market
direction: PositionDirection . LONG ,
baseAssetAmount: new BN ( 10 ). mul ( BASE_PRECISION ), // 10 SOL
marketType: MarketType . SPOT ,
});
await driftClient . placeSpotOrder ( orderParams );
Scale Orders
Place multiple orders across a price range:
import { ScaleOrderParams , SizeDistribution } from '@drift-labs/sdk' ;
// Place 10 orders from $140 to $150
const scaleOrderParams : ScaleOrderParams = {
orderCount: 10 ,
marketIndex: 0 ,
direction: PositionDirection . LONG ,
baseAssetAmount: new BN ( 10 ). mul ( BASE_PRECISION ), // Total 10 SOL
minPrice: new BN ( 140 ). mul ( PRICE_PRECISION ),
maxPrice: new BN ( 150 ). mul ( PRICE_PRECISION ),
sizeDistribution: SizeDistribution . UNIFORM ,
};
const txSig = await driftClient . placeScaleOrder ( scaleOrderParams );
console . log ( 'Scale orders placed:' , txSig );
Order Parameters
Market index (0 = SOL-PERP, 1 = BTC-PERP, etc.)
direction
PositionDirection
required
PositionDirection.LONG or PositionDirection.SHORT
Amount in base asset (use BASE_PRECISION for standard precision)
Limit price (use PRICE_PRECISION for $1 = 1,000,000)
MarketType.PERP or MarketType.SPOT (default: PERP)
If true, order can only reduce existing positions
MUST_POST_ONLY, TRY_POST_ONLY, or NONE
If true, cancel unfilled portion immediately
Price at which trigger order activates
ABOVE or BELOW for trigger orders
Price offset from oracle for oracle orders
Unix timestamp for order expiration
Custom order ID for tracking (1-255)
Best Practices
Use appropriate order types
Market orders : When you need immediate execution
Limit orders : When you want price control and maker fees
Trigger orders : For risk management (stop-loss/take-profit)
Oracle orders : For fair pricing relative to oracle
Set price limits on market orders
// Protect against extreme slippage
const currentPrice = calculateBidAskPrice (
perpMarket . amm ,
oracleData
)[ 1 ]; // Ask price
const maxPrice = currentPrice . mul ( new BN ( 105 )). div ( new BN ( 100 )); // +5%
const orderParams = getMarketOrderParams ({
// ... other params
price: maxPrice ,
});
Use user order IDs for tracking
// Track your orders with custom IDs
const orderParams = getMarketOrderParams ({
// ... other params
userOrderId: 42 ,
});
await driftClient . placePerpOrder ( orderParams );
// Later, find your order
const order = user . getOrderByUserOrderId ( 42 );
if ( order ) {
console . log ( 'Order status:' , order . status );
}
Handle order placement errors
try {
await driftClient . placePerpOrder ( orderParams );
} catch ( error ) {
if ( error . message . includes ( 'Insufficient collateral' )) {
console . error ( 'Need to deposit more collateral' );
} else if ( error . message . includes ( 'Market orders paused' )) {
console . error ( 'Market is currently paused' );
} else {
console . error ( 'Order failed:' , error );
}
}
Examples
Opening a Leveraged Long Position
// Open 10x leveraged SOL long with $1000 collateral
const collateral = new BN ( 1000 ). mul ( QUOTE_PRECISION );
const leverage = 10 ;
const notionalValue = collateral . mul ( new BN ( leverage ));
// Get current SOL price
const solPrice = driftClient . getOracleDataForPerpMarket ( 0 ). price ;
const baseAmount = notionalValue . mul ( PRICE_PRECISION ). div ( solPrice );
const orderParams = getMarketOrderParams ({
marketIndex: 0 ,
direction: PositionDirection . LONG ,
baseAssetAmount: baseAmount ,
});
await driftClient . placePerpOrder ( orderParams );
Closing a Position
// Get your current position
const position = user . getPerpPosition ( 0 );
if ( position && position . baseAssetAmount . gt ( ZERO )) {
// Close the entire position
const orderParams = getMarketOrderParams ({
marketIndex: 0 ,
direction: findDirectionToClose ( position ),
baseAssetAmount: position . baseAssetAmount . abs (),
reduceOnly: true ,
});
await driftClient . placePerpOrder ( orderParams );
}
Next Steps
Modify Orders Learn to modify existing orders
Cancel Orders Cancel individual or all orders
Manage Positions Monitor and manage open positions
Order Params API Complete order parameters reference