Skip to content

Commit

Permalink
Merge pull request #290 from drift-labs/partition-markets
Browse files Browse the repository at this point in the history
add paritionied markets for bots
  • Loading branch information
NourAlharithi authored Nov 12, 2024
2 parents 783417a + f9f149b commit 023edd2
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 161 deletions.
17 changes: 15 additions & 2 deletions src/bots/pythCranker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,20 @@ export class PythCrankerBot implements Bot {
await this.driftClient.fetchMarketLookupTableAccount()
);

for (const marketConfig of PerpMarkets[this.globalConfig.driftEnv]) {
const perpMarketIndexes = this.driftClient
.getPerpMarketAccounts()
.map((market) => market.marketIndex);
const perpMarketConfigs = PerpMarkets[this.globalConfig.driftEnv].filter(
(market) => perpMarketIndexes.includes(market.marketIndex)
);
const spotMarketIndexes = this.driftClient
.getSpotMarketAccounts()
.map((market) => market.marketIndex);
const spotMarketConfigs = SpotMarkets[this.globalConfig.driftEnv].filter(
(market) => spotMarketIndexes.includes(market.marketIndex)
);

for (const marketConfig of perpMarketConfigs) {
const feedId = marketConfig.pythFeedId;
if (!feedId) {
logger.warn(`No pyth feed id for market ${marketConfig.symbol}`);
Expand Down Expand Up @@ -165,7 +178,7 @@ export class PythCrankerBot implements Bot {
});
}

for (const marketConfig of SpotMarkets[this.globalConfig.driftEnv]) {
for (const marketConfig of spotMarketConfigs) {
if (
this.feedIdsToCrank.findIndex(
(feedId) => feedId.baseSymbol === marketConfig.symbol
Expand Down
47 changes: 8 additions & 39 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import YAML from 'yaml';
import {
loadCommaDelimitToArray,
loadCommaDelimitToStringArray,
parsePositiveIntArray,
} from './utils';
import { OrderExecutionAlgoType } from './types';
import {
Expand All @@ -21,17 +22,6 @@ export type BaseBotConfig = {
runOnce?: boolean;
};

export type JitMakerConfig = BaseBotConfig & {
subaccounts?: Array<number>;
marketType: string;
/// @deprecated, use {@link JitMakerConfig.marketIndexes} and {@link JitMakerConfig.marketType}
perpMarketIndicies?: Array<number>;
marketIndexes?: Array<number>;
targetLeverage?: number;
aggressivenessBps?: number;
jitCULimit?: number;
};

export type UserPnlSettlerConfig = BaseBotConfig & {
/// perp market indexes to filter for settling pnl
perpMarketIndicies?: Array<number>;
Expand Down Expand Up @@ -137,14 +127,12 @@ export type BotConfigMap = {
trigger?: BaseBotConfig;
liquidator?: LiquidatorConfig;
floatingMaker?: BaseBotConfig;
jitMaker?: JitMakerConfig;
ifRevenueSettler?: BaseBotConfig;
fundingRateUpdater?: BaseBotConfig;
userPnlSettler?: UserPnlSettlerConfig;
userLpSettler?: BaseBotConfig;
userIdleFlipper?: BaseBotConfig;
markTwapCrank?: BaseBotConfig;
uncrossArb?: BaseBotConfig;
pythCranker?: PythCrankerBotConfig;
switchboardCranker?: SwitchboardCrankerBotConfig;
swiftTaker?: BaseBotConfig;
Expand All @@ -160,6 +148,10 @@ export interface GlobalConfig {
hermesEndpoint?: string;
numNonActiveOraclesToPush?: number;

// Optional to specify markets loaded by drift client
perpMarketsToLoad?: Array<number>;
spotMarketsToLoad?: Array<number>;

/// helius endpoint to use helius priority fee strategy
heliusEndpoint?: string;
/// additional rpc endpoints to send transactions to
Expand Down Expand Up @@ -232,6 +224,9 @@ const defaultConfig: Partial<Config> = {
debug: false,
subaccounts: [0],

perpMarketsToLoad: parsePositiveIntArray(process.env.PERP_MARKETS_TO_LOAD),
spotMarketsToLoad: parsePositiveIntArray(process.env.SPOT_MARKETS_TO_LOAD),

eventSubscriberPollingInterval: 5000,
bulkAccountLoaderPollingInterval: 5000,

Expand Down Expand Up @@ -455,21 +450,6 @@ export function loadConfigFromOpts(opts: any): Config {
runOnce: opts.runOnce ?? false,
};
}
if (opts.jitMaker) {
config.enabledBots.push('jitMaker');
config.botConfigs!.jitMaker = {
dryRun: opts.dryRun ?? false,
botId: process.env.BOT_ID ?? 'jitMaker',
metricsPort: 9464,
runOnce: opts.runOnce ?? false,
perpMarketIndicies: loadCommaDelimitToArray(opts.perpMarketIndicies) ?? [
0,
],
subaccounts: loadCommaDelimitToArray(opts.subaccounts) ?? [0],
marketType: opts.marketType ?? 'perp',
targetLeverage: 1,
};
}
if (opts.ifRevenueSettler) {
config.enabledBots.push('ifRevenueSettler');
config.botConfigs!.ifRevenueSettler = {
Expand Down Expand Up @@ -528,17 +508,6 @@ export function loadConfigFromOpts(opts: any): Config {
runOnce: opts.runOnce ?? false,
};
}

if (opts.uncrossArb) {
config.enabledBots.push('uncrossArb');
config.botConfigs!.uncrossArb = {
dryRun: opts.dryRun ?? false,
botId: process.env.BOT_ID ?? 'uncrossArb',
metricsPort: 9464,
runOnce: opts.runOnce ?? false,
};
}

return mergeDefaults(defaultConfig, config) as Config;
}

Expand Down
130 changes: 10 additions & 120 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ import {
TokenFaucet,
DriftClientSubscriptionConfig,
LogProviderConfig,
getMarketsAndOraclesForSubscription,
AuctionSubscriber,
FastSingleTxSender,
OracleInfo,
UserMap,
Wallet,
RetryTxSender,
Expand All @@ -48,7 +45,6 @@ import { constants } from './types';
import { FillerBot } from './bots/filler';
import { SpotFillerBot } from './bots/spotFiller';
import { TriggerBot } from './bots/trigger';
import { JitMaker } from './bots/jitMaker';
import { LiquidatorBot } from './bots/liquidator';
import { FloatingPerpMakerBot } from './bots/floatingMaker';
import { Bot } from './types';
Expand All @@ -62,6 +58,7 @@ import {
TOKEN_FAUCET_PROGRAM_ID,
getWallet,
loadKeypair,
getMarketsAndOracleInfosToLoad,
} from './utils';
import {
Config,
Expand All @@ -71,9 +68,7 @@ import {
} from './config';
import { FundingRateUpdaterBot } from './bots/fundingRateUpdater';
import { FillerLiteBot } from './bots/fillerLite';
import { JitProxyClient, JitterShotgun } from '@drift-labs/jit-proxy/lib';
import { MakerBidAskTwapCrank } from './bots/makerBidAskTwapCrank';
import { UncrossArbBot } from './bots/uncrossArbBot';
import { BundleSender } from './bundleSender';
import { DriftStateWatcher, StateChecks } from './driftStateWatcher';
import { webhookMessage } from './webhook';
Expand Down Expand Up @@ -382,16 +377,15 @@ const runBot = async () => {

// keeping these arrays undefined will prompt DriftClient to call `findAllMarketAndOracles`
// and load all markets and oracle accounts from on-chain
let perpMarketIndexes: number[] | undefined;
let spotMarketIndexes: number[] | undefined;
let oracleInfos: OracleInfo[] | undefined;
if (configHasBot(config, 'jitMaker')) {
({ perpMarketIndexes, spotMarketIndexes, oracleInfos } =
getMarketsAndOraclesForSubscription(config.global.driftEnv!));
}
const marketLookupTable = config.global?.lutPubkey
? new PublicKey(config.global.lutPubkey)
: new PublicKey(configs[config.global.driftEnv!].MARKET_LOOKUP_TABLE);
const marketsAndOracleInfos = getMarketsAndOracleInfosToLoad(
sdkConfig,
config.global.perpMarketsToLoad,
config.global.spotMarketsToLoad
);
const oracleInfos = marketsAndOracleInfos.oracleInfos;
const driftClientConfig = {
connection,
wallet,
Expand All @@ -400,9 +394,9 @@ const runBot = async () => {
accountSubscription,
env: config.global.driftEnv,
userStats: true,
perpMarketIndexes,
spotMarketIndexes,
oracleInfos,
perpMarketIndexes: marketsAndOracleInfos.perpMarketIndicies,
spotMarketIndexes: marketsAndOracleInfos.spotMarketIndicies,
oracleInfos: oracleInfos.length > 0 ? oracleInfos : undefined,
activeSubAccountId: config.global.subaccounts![0],
subAccountIds: config.global.subaccounts ?? [0],
txVersion: 0 as TransactionVersion,
Expand Down Expand Up @@ -696,60 +690,6 @@ const runBot = async () => {
);
}

let auctionSubscriber: AuctionSubscriber | undefined = undefined;
let jitter: JitterShotgun | undefined = undefined;
if (configHasBot(config, 'jitMaker')) {
// Subscribe to drift client

needCheckDriftUser = true;
needForceCollateral = true;
needPriorityFeeSubscriber = true;

const jitProxyClient = new JitProxyClient({
driftClient,
programId: new PublicKey(sdkConfig.JIT_PROXY_PROGRAM_ID!),
});

auctionSubscriber = new AuctionSubscriber({
driftClient,
opts: { commitment: stateCommitment },
});
await auctionSubscriber.subscribe();

jitter = new JitterShotgun({
auctionSubscriber,
driftClient,
jitProxyClient,
});
await jitter.subscribe();

const txSenderConnection = new Connection(endpoint, {
wsEndpoint: wsEndpoint,
commitment: stateCommitment,
disableRetryOnRateLimit: true,
});
driftClient.txSender = new FastSingleTxSender({
connection: txSenderConnection,
wallet,
blockhashRefreshInterval: 1000,
opts: {
preflightCommitment: 'processed',
skipPreflight: false,
commitment: 'processed',
},
});

bots.push(
new JitMaker(
driftClient,
jitter,
config.botConfigs!.jitMaker!,
config.global.driftEnv!,
priorityFeeSubscriber
)
);
}

if (configHasBot(config, 'liquidator')) {
needCheckDriftUser = true;
needUserMapSubscribe = true;
Expand Down Expand Up @@ -872,33 +812,11 @@ const runBot = async () => {
);
}

if (configHasBot(config, 'uncrossArb')) {
needCheckDriftUser = true;
needPriorityFeeSubscriber = true;
const jitProxyClient = new JitProxyClient({
driftClient,
programId: new PublicKey(sdkConfig.JIT_PROXY_PROGRAM_ID!),
});

bots.push(
new UncrossArbBot(
driftClient,
jitProxyClient,
slotSubscriber,
config.botConfigs!.uncrossArb!,
config.global.driftEnv!,
priorityFeeSubscriber
)
);
}

// Run subscribe functions once
if (
needCheckDriftUser ||
needForceCollateral ||
eventSubscriber ||
auctionSubscriber ||
jitter ||
needUserMapSubscribe ||
needPythPriceSubscriber ||
needDriftStateWatcher
Expand Down Expand Up @@ -932,34 +850,6 @@ const runBot = async () => {
logger.info(`userMap.subscribe took: ${hrEnd[0]}s ${hrEnd[1] / 1e6}ms`);
}

logger.info(
`Checking if need auctionSubscriber: ${auctionSubscriber !== undefined}`
);
if (auctionSubscriber) {
const hrStart = process.hrtime();
await auctionSubscriber.subscribe();
const hrEnd = process.hrtime(hrStart);
logger.info(
`auctionSubscriber.subscribe took: ${hrEnd[0]}s ${hrEnd[1] / 1e6}ms`
);
}

logger.info(`Checking if need jitter: ${jitter !== undefined}`);
if (jitter) {
const freeCollateral = driftClient
.getUser()
.getFreeCollateral('Maintenance');
if (freeCollateral.isZero()) {
throw new Error(
`No collateral in account, collateral is required to run JitMakerBot, run with --force-deposit flag to deposit collateral`
);
}
const hrStart = process.hrtime();
await jitter.subscribe();
const hrEnd = process.hrtime(hrStart);
logger.info(`jitter.subscribe took: ${hrEnd[0]}s ${hrEnd[1] / 1e6}ms`);
}

logger.info(`Checking if need pythConnection: ${needPythPriceSubscriber}`);
if (needPythPriceSubscriber && pythPriceSubscriber) {
const feedIds: string[] = Array.from(
Expand Down
Loading

0 comments on commit 023edd2

Please sign in to comment.