Skip to main content

Tutorial- Arbitrage Bot

View Full GitHub example:

https://github.com/drift-labs/example-bots/blob/master/src/arbitrage-bot.ts

Getting Started

1. Create a connection and wallet object.

It's important to safely load your private key outside of the code to ensure privacy.

import { Connection, Keypair, PublicKey } from "@solana/web3.js";

// todo: rename to env variable with key
const privateKey = process.env.SOLANA_PRIVATE_KEY;
const keypair = Keypair.fromSecretKey(
Uint8Array.from(privateKey.split(",").map((val) => Number(val)))
);
const wallet = new Wallet(keypair);
const connection = new Connection(endpoint);

2. Install the @drift-labs/sdk.

For more details, peek through SDK Documentation.

import {
convertToNumber,
DriftClient,
initialize,
PositionDirection,
} from "@drift-labs/sdk";

const sdkConfig = initialize({ env: "mainnet-beta" });
const driftClientPublicKey = new PublicKey(sdkConfig.DRIFT_PROGRAM_ID);

const driftClient = DriftClient.from(connection, wallet, driftClientPublicKey);

2. Initialize an account and deposit collateral (USDC) on Drift.

[, userAccountPublicKey] =
await driftClient.initializeUserAccountAndDepositCollateral(
usdcAmount,
userUSDCAccount.publicKey
);

3. Pick a market and load the price.

const marketIndex = new BN(0); // SOL
markPrice = calculateMarkPrice(clearingHouse.getMarket(marketIndexBN));
console.log(convertToNum(markPrice));

4. Based on the current price, make a trade by passing a direction (LONG, SHORT) and size (USDC notional).

Optionally: You can set a limitPrice to place an Immediate or Cancel (IOC) order to help ensure your entryPrice comes as expected.

const direction = PositionDirection.LONG(); // LONG
const amount = new BN(100000); // $1 (1e6 precision)
const limitPrice = markPrice.mul(1001).div(1000); // .1% tolerance (1e10 precision)

await clearingHouse.openPosition(direction, amount, marketIndex, limitPrice);

Advanced

Take advantage of the SDK helpers that we've written for more measured trading:

For instance,calculateTargetPriceTradecalculate the liquidity available between the current markPrice to your targetPrice.

This function is highly recommended for arbitrageurs.

const marketIndex = new BN(0);
const market = clearingHouse.getMarket(marketIndex);
const targetPrice = new BN(250.169 * MARK_PRICE_PRECISION);

const [direction, amount, entryPrice, newMarkPrice] = calculateTargetPriceTrade(
market,
targetPrice
);

await clearingHouse.openPosition(direction, amount, marketIndex, entryPrice);