Skip to Content
DevelopersMarket MakersNormal MM

Normal MM

“Normal” market making on Drift means placing resting two-sided quotes on the decentralized orderbook (orderbook / DLOB) and earning maker rebates when takers trade against you. You can also participate in JIT when relevant. For protocol background, see Market Maker Participation and JIT FAQ.

Maker vs taker

  • Maker: provides liquidity (resting order), earns rebate.
  • Taker: removes liquidity (crosses spread), pays fee.

Always use post-only for maker quotes

import { PostOnlyParams } from "@drift-labs/sdk";
Class PostOnlyParamsReference ↗
TypeScript docs unavailable for PostOnlyParams.
import { OrderType, PositionDirection, PostOnlyParams } from "@drift-labs/sdk"; await driftClient.placePerpOrder({ orderType: OrderType.LIMIT, marketIndex: 0, direction: PositionDirection.LONG, baseAssetAmount: driftClient.convertToPerpPrecision(1), price: driftClient.convertToPricePrecision(99), postOnly: PostOnlyParams.MUST_POST_ONLY, });
Method DriftClient.placePerpOrderReference ↗
Parameters:
NameTypeDefault
orderParamsOptionalOrderParams
txParamsTxParams
subAccountIdnumber
isolatedPositionDepositAmountany
Returns:
Promise<string>

Two-sided quotes (place in one tx)

import { MarketType, OrderType, PositionDirection, PostOnlyParams } from "@drift-labs/sdk"; await driftClient.placeOrders([ { orderType: OrderType.LIMIT, marketType: MarketType.PERP, marketIndex: 0, direction: PositionDirection.LONG, baseAssetAmount: driftClient.convertToPerpPrecision(1), price: driftClient.convertToPricePrecision(99.5), postOnly: PostOnlyParams.MUST_POST_ONLY, }, { orderType: OrderType.LIMIT, marketType: MarketType.PERP, marketIndex: 0, direction: PositionDirection.SHORT, baseAssetAmount: driftClient.convertToPerpPrecision(1), price: driftClient.convertToPricePrecision(100.5), postOnly: PostOnlyParams.MUST_POST_ONLY, }, ]);
Method DriftClient.placeOrdersReference ↗
Parameters:
NameTypeDefault
paramsOrderParams[]
txParamsTxParams
subAccountIdnumber
optionalIxsTransactionInstruction[]
isolatedPositionDepositAmountany
Returns:
Promise<string>

Quote around oracle

import { PRICE_PRECISION, convertToNumber } from "@drift-labs/sdk"; const oracle = driftClient.getOracleDataForPerpMarket(0); const oraclePrice = convertToNumber(oracle.price, PRICE_PRECISION); console.log(oraclePrice);
Method DriftClient.getOracleDataForPerpMarketReference ↗
Parameters:
NameTypeDefault
marketIndexnumber
Returns:
OraclePriceData

Inventory-aware quoting (basic)

You can widen/tighten one side of your spread based on current inventory to reduce drift.

const user = driftClient.getUser(); const position = user.getPerpPosition(0); console.log(position?.baseAssetAmount.toString());
Method User.getPerpPositionReference ↗
Parameters:
NameTypeDefault
marketIndexnumber
Returns:
PerpPosition | undefined

JIT maker (on-chain “place-and-make”)

If you’re reacting to on-chain taker auctions, Drift exposes a helper that “places a maker order and fills against a taker” atomically.

// `takerInfo` comes from your taker discovery / order intake logic. await driftClient.placeAndMakePerpOrder(makerOrderParams, takerInfo);
Method DriftClient.placeAndMakePerpOrderReference ↗
Parameters:
NameTypeDefault
orderParamsOptionalOrderParams
takerInfoTakerInfo
referrerInfoReferrerInfo
txParamsTxParams
subAccountIdnumber
Returns:
Promise<string>

Risk management basics

Common MM guardrails:

  • position limits (max long/short)
  • minimum free collateral
  • health / leverage checks
  • cancel all orders on errors / volatility spikes
import { MarketType } from "@drift-labs/sdk"; await driftClient.cancelOrders(MarketType.PERP, 0);
Method DriftClient.cancelOrdersReference ↗
Parameters:
NameTypeDefault
marketTypeMarketType
marketIndexnumber
directionPositionDirection
txParamsTxParams
subAccountIdnumber
Returns:
Promise<string>

For production patterns (subscription loops, throttling, priority fees), see Bot architecture patterns.

Last updated on