Skip to content

Commit 53ae28a

Browse files
authored
Merge pull request #528 from drift-labs/master
master -> mainnet
2 parents 6c1c43d + 11178d8 commit 53ae28a

File tree

3 files changed

+1154
-68
lines changed

3 files changed

+1154
-68
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"main": "lib/index.js",
66
"license": "Apache-2.0",
77
"dependencies": {
8-
"@drift-labs/jit-proxy": "0.20.18",
9-
"@drift-labs/sdk": "2.137.0-beta.1",
8+
"@drift-labs/jit-proxy": "0.20.19",
9+
"@drift-labs/sdk": "2.137.0-beta.2",
1010
"@drift/common": "file:./drift-common/common-ts",
1111
"@opentelemetry/api": "1.7.0",
1212
"@opentelemetry/auto-instrumentations-node": "^0.62.1",
@@ -61,7 +61,7 @@
6161
"@types/chai": "4.3.11",
6262
"@types/mocha": "10.0.6",
6363
"@typescript-eslint/eslint-plugin": "5.62.0",
64-
"@typescript-eslint/parser": "4.33.0",
64+
"@typescript-eslint/parser": "4.33.0",
6565
"chai": "4.3.10",
6666
"esbuild": "0.24.0",
6767
"eslint": "7.32.0",

src/bots/userPnlSettler.ts

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,10 @@ const SLEEP_MS = 500;
5858
const CU_EST_MULTIPLIER = 1.25;
5959

6060
const FILTER_FOR_MARKET = undefined; // undefined;
61-
const EMPTY_USER_SETTLE_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
62-
const POSITIVE_PNL_SETTLE_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
63-
const ALL_NEGATIVE_PNL_SETTLE_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
61+
62+
const EMPTY_USER_SETTLE_INTERVAL_MS = 60 * 60 * 1000; // 1 hour (after initial delay)
63+
const POSITIVE_PNL_SETTLE_INTERVAL_MS = 60 * 60 * 1000; // 1 hour (after initial delay)
64+
const ALL_NEGATIVE_PNL_SETTLE_INTERVAL_MS = 60 * 60 * 1000; // 1 hour (after initial delay)
6465
const MIN_MARGIN_RATIO_FOR_POSITIVE_PNL = 0.1; // 10% of account value
6566

6667
const errorCodesToSuppress = [
@@ -115,6 +116,7 @@ export class UserPnlSettlerBot implements Bot {
115116
// =============================================================================
116117

117118
private intervalIds: Array<NodeJS.Timer> = [];
119+
private timeoutIds: Array<NodeJS.Timeout> = [];
118120
private inProgress = false;
119121
private watchdogTimerMutex = new Mutex();
120122
private watchdogTimerLastPatTime = Date.now();
@@ -182,6 +184,11 @@ export class UserPnlSettlerBot implements Bot {
182184
}
183185
this.intervalIds = [];
184186

187+
for (const timeoutId of this.timeoutIds) {
188+
clearTimeout(timeoutId);
189+
}
190+
this.timeoutIds = [];
191+
185192
await this.priorityFeeSubscriber!.unsubscribe();
186193
await this.userMap?.unsubscribe();
187194
}
@@ -205,26 +212,54 @@ export class UserPnlSettlerBot implements Bot {
205212
this.intervalIds.push(
206213
setInterval(this.trySettleNegativePnl.bind(this), negativeInterval)
207214
);
208-
// Comprehensive negative PnL settlement every hour
209-
this.intervalIds.push(
210-
setInterval(
211-
this.trySettleAllNegativePnl.bind(this),
212-
ALL_NEGATIVE_PNL_SETTLE_INTERVAL_MS
213-
)
215+
216+
// Calculate delay until next hour's 1st minute for hourly tasks
217+
const delayUntilNextHourFirstMinute =
218+
this.getMillisecondsUntilNextHourFirstMinute();
219+
const nextRunTime = new Date(Date.now() + delayUntilNextHourFirstMinute);
220+
logger.info(
221+
`Hourly settlement tasks will start at ${nextRunTime.toISOString()} (in ${Math.round(
222+
delayUntilNextHourFirstMinute / 1000
223+
)}s)`
214224
);
215-
// Users with no positions every hour
216-
this.intervalIds.push(
217-
setInterval(
218-
this.trySettleUsersWithNoPositions.bind(this),
219-
EMPTY_USER_SETTLE_INTERVAL_MS
220-
)
225+
226+
// Comprehensive negative PnL settlement - start at next hour's 1st minute, then every hour
227+
this.timeoutIds.push(
228+
setTimeout(() => {
229+
this.trySettleAllNegativePnl();
230+
this.intervalIds.push(
231+
setInterval(
232+
this.trySettleAllNegativePnl.bind(this),
233+
ALL_NEGATIVE_PNL_SETTLE_INTERVAL_MS
234+
)
235+
);
236+
}, delayUntilNextHourFirstMinute)
221237
);
222-
// Positive PnL settlement for low margin users every hour
223-
this.intervalIds.push(
224-
setInterval(
225-
this.trySettlePositivePnlForLowMargin.bind(this),
226-
POSITIVE_PNL_SETTLE_INTERVAL_MS
227-
)
238+
239+
// Users with no positions - start at next hour's 1st minute, then every hour
240+
this.timeoutIds.push(
241+
setTimeout(() => {
242+
this.trySettleUsersWithNoPositions();
243+
this.intervalIds.push(
244+
setInterval(
245+
this.trySettleUsersWithNoPositions.bind(this),
246+
EMPTY_USER_SETTLE_INTERVAL_MS
247+
)
248+
);
249+
}, delayUntilNextHourFirstMinute)
250+
);
251+
252+
// Positive PnL settlement for low margin users - start at next hour's 1st minute, then every hour
253+
this.timeoutIds.push(
254+
setTimeout(() => {
255+
this.trySettlePositivePnlForLowMargin();
256+
this.intervalIds.push(
257+
setInterval(
258+
this.trySettlePositivePnlForLowMargin.bind(this),
259+
POSITIVE_PNL_SETTLE_INTERVAL_MS
260+
)
261+
);
262+
}, delayUntilNextHourFirstMinute)
228263
);
229264
}
230265
}
@@ -1074,6 +1109,13 @@ export class UserPnlSettlerBot implements Bot {
10741109
// UTILITY METHODS
10751110
// =============================================================================
10761111

1112+
private getMillisecondsUntilNextHourFirstMinute(): number {
1113+
const now = new Date();
1114+
const nextHour = new Date(now);
1115+
nextHour.setHours(now.getHours() + 1, 1, 0, 0); // Next hour, 1st minute, 0 seconds, 0 ms
1116+
return nextHour.getTime() - now.getTime();
1117+
}
1118+
10771119
private async updateWatchdogTimer() {
10781120
await this.watchdogTimerMutex.runExclusive(async () => {
10791121
this.watchdogTimerLastPatTime = Date.now();

0 commit comments

Comments
 (0)