Forráskód Böngészése

feat: add bulk init throttling for grid placement

helium3@sina.com 2 hónapja
szülő
commit
af8947a44e

+ 2 - 1
apps/runner/src/index.ts

@@ -320,7 +320,8 @@ const defaultGridSymbol = cfg.grid?.symbol || primarySymbol;
     (sym: string) => shadow.snapshot(sym),
     {
       maxBps: cfg.execution?.max_slippage_bps ?? 5,
-      minIntervalMs: cfg.execution?.min_order_interval_ms ?? 0
+      minIntervalMs: cfg.execution?.min_order_interval_ms ?? 0,
+      bulkInitIntervalMs: cfg.execution?.bulk_init_interval_ms ?? 20
     }
   );
 

+ 2 - 1
config/config.yaml

@@ -103,4 +103,5 @@ hedge:
 
 execution:
   max_slippage_bps: 150
-  min_order_interval_ms: 100
+  min_order_interval_ms: 100         # 正常交易节流间隔
+  bulk_init_interval_ms: 20          # 批量初始化节流间隔(网格布置时)

+ 16 - 3
packages/execution/src/orderRouter.ts

@@ -4,6 +4,7 @@ import type { Order, OrderBook } from "../../domain/src/types";
 export interface OrderRouterConfig {
   maxBps: number;
   minIntervalMs?: number;
+  bulkInitIntervalMs?: number;
   forbidPostOnlyCross?: boolean;
   clientIdCacheSize?: number;
 }
@@ -18,10 +19,12 @@ export type CancelClientFn = (clientId: string) => Promise<void>;
 
 export class OrderRouter {
   private readonly minIntervalMs: number;
+  private readonly bulkInitIntervalMs: number;
   private readonly forbidPostOnlyCross: boolean;
   private readonly maxBps: number;
   private readonly clientIdCacheSize: number;
   private lastSendAt = 0;
+  private bulkInitMode = false;
   private readonly recentClientIds: string[] = [];
   private readonly clientIdSet = new Set<string>();
   private readonly clientIdAlias = new Map<string, string>();
@@ -35,10 +38,19 @@ export class OrderRouter {
   ) {
     this.maxBps = config.maxBps;
     this.minIntervalMs = config.minIntervalMs ?? 0;
+    this.bulkInitIntervalMs = config.bulkInitIntervalMs ?? Math.min(20, this.minIntervalMs);
     this.forbidPostOnlyCross = config.forbidPostOnlyCross ?? true;
     this.clientIdCacheSize = config.clientIdCacheSize ?? 512;
   }
 
+  enableBulkInitMode(): void {
+    this.bulkInitMode = true;
+  }
+
+  disableBulkInitMode(): void {
+    this.bulkInitMode = false;
+  }
+
   async sendLimit(order: Order): Promise<string> {
     order.clientId = this.normalizeClientId(order.clientId);
     await this.ensureThrottle();
@@ -115,11 +127,12 @@ export class OrderRouter {
   }
 
   private async ensureThrottle() {
-    if (this.minIntervalMs <= 0) return;
+    const intervalMs = this.bulkInitMode ? this.bulkInitIntervalMs : this.minIntervalMs;
+    if (intervalMs <= 0) return;
     const now = Date.now();
     const elapsed = now - this.lastSendAt;
-    if (elapsed < this.minIntervalMs) {
-      await new Promise(resolve => setTimeout(resolve, this.minIntervalMs - elapsed));
+    if (elapsed < intervalMs) {
+      await new Promise(resolve => setTimeout(resolve, intervalMs - elapsed));
     }
     this.lastSendAt = Date.now();
   }

+ 12 - 0
packages/strategies/src/gridMaker.ts

@@ -117,6 +117,12 @@ export class GridMaker {
     // 重置连续失败计数
     this.consecutivePlaceFailures = 0;
 
+    // 启用批量初始化模式(降低节流间隔)
+    if (typeof (this.router as any).enableBulkInitMode === 'function') {
+      (this.router as any).enableBulkInitMode();
+      this.logger.debug('Enabled bulk init mode for faster grid placement');
+    }
+
     // 布置网格
     const expectedOrders = actualLayers * 2;
     for (let i = 1; i <= actualLayers; i++) {
@@ -153,6 +159,12 @@ export class GridMaker {
       }
     }
 
+    // 禁用批量初始化模式
+    if (typeof (this.router as any).disableBulkInitMode === 'function') {
+      (this.router as any).disableBulkInitMode();
+      this.logger.debug('Disabled bulk init mode, returning to normal throttling');
+    }
+
     if (this.needsReinit) {
       this.logger.info({ action: 'schedule_reinit', currentGridStepBps: this.currentGridStepBps }, 'Reinitialization scheduled due to placement failures');
       return;