From 61e6e4cdde108a2da41884c93efb734cf75cc6f2 Mon Sep 17 00:00:00 2001 From: discountry Date: Sat, 7 Feb 2026 23:58:01 +0800 Subject: [PATCH] Add Binance depth monitoring configuration to MakerPoints - Introduced new environment variables `MAKER_POINTS_BINANCE_DEPTH_WINDOW_BPS` and `MAKER_POINTS_BINANCE_DEPTH_IMBALANCE_RATIO` to configure Binance depth monitoring. - Updated `MakerPointsConfig` interface and implementation to include these new parameters. - Enhanced translations to reflect dynamic depth window information in the UI. - Added tests to validate the new configuration options and their integration into the MakerPoints engine. --- .env.example | 4 + docs/standx/maker-points-guide.md | 6 + src/config.ts | 6 + src/i18n/index.ts | 4 +- src/strategy/maker-points-engine.ts | 8 +- src/ui/MakerPointsApp.tsx | 1 + tests/config-inline-comments.test.ts | 5 +- .../maker-points-binance-depth-config.test.ts | 109 ++++++++++++++++++ 8 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 tests/maker-points-binance-depth-config.test.ts diff --git a/.env.example b/.env.example index d10d1c9..0b874ce 100644 --- a/.env.example +++ b/.env.example @@ -59,6 +59,10 @@ MAKER_REFRESH_INTERVAL_MS=500 # Maker refresh cadence (ms) MAKER_MAX_CLOSE_SLIPPAGE_PCT=0.05 # Maker close slippage guard (fallbacks to MAX_CLOSE_SLIPPAGE_PCT) MAKER_PRICE_TICK=0.1 # Maker price tick size (defaults to PRICE_TICK) +# Maker-points Binance depth imbalance monitor +MAKER_POINTS_BINANCE_DEPTH_WINDOW_BPS=5 # Binance depth monitor window around best bid/ask (bps) +MAKER_POINTS_BINANCE_DEPTH_IMBALANCE_RATIO=8 # Imbalance threshold ratio (e.g. 8 => one side >= 8x) + # Grid strategy defaults GRID_LOWER_PRICE=25000 # Grid lower bound price (quote currency) GRID_UPPER_PRICE=35000 # Grid upper bound price diff --git a/docs/standx/maker-points-guide.md b/docs/standx/maker-points-guide.md index 2ad021b..98449ba 100644 --- a/docs/standx/maker-points-guide.md +++ b/docs/standx/maker-points-guide.md @@ -132,6 +132,8 @@ MAKER_POINTS_ORDER_AMOUNT=0.01 MAKER_POINTS_CLOSE_THRESHOLD=0.1 MAKER_POINTS_STOP_LOSS_USD=0 MAKER_POINTS_MIN_REPRICE_BPS=3 +MAKER_POINTS_BINANCE_DEPTH_WINDOW_BPS=5 +MAKER_POINTS_BINANCE_DEPTH_IMBALANCE_RATIO=8 # ===== 挂单档位开关 ===== MAKER_POINTS_BAND_0_10=true @@ -173,6 +175,8 @@ MAKER_POINTS_ORDER_AMOUNT=0.01 MAKER_POINTS_CLOSE_THRESHOLD=0.1 MAKER_POINTS_STOP_LOSS_USD=0 MAKER_POINTS_MIN_REPRICE_BPS=3 +MAKER_POINTS_BINANCE_DEPTH_WINDOW_BPS=5 +MAKER_POINTS_BINANCE_DEPTH_IMBALANCE_RATIO=8 MAKER_POINTS_BAND_0_10=true MAKER_POINTS_BAND_10_30=true MAKER_POINTS_BAND_30_100=true @@ -214,6 +218,8 @@ bun run pm2:start:maker-points | `MAKER_POINTS_ORDER_AMOUNT` | 每笔挂单数量 | 建议 `0.01` 起步 | | `MAKER_POINTS_CLOSE_THRESHOLD` | 持仓达到多少开始平仓 | 设为 `0` 表示不自动平仓 | | `MAKER_POINTS_STOP_LOSS_USD` | 亏损多少美元强制平仓 | 设为 `0` 表示关闭止损 | +| `MAKER_POINTS_BINANCE_DEPTH_WINDOW_BPS` | Binance 失衡检测窗口(bps) | 默认 `5` | +| `MAKER_POINTS_BINANCE_DEPTH_IMBALANCE_RATIO` | Binance 失衡比例阈值 | 默认 `8` | | `MAKER_POINTS_BAND_*` | 三个挂单档位的开关 | 全部 `true` 即可 | | `STANDX_TOKEN_CREATE_DATE` | Token 创建日期 | 推荐配置,格式 YYYY-MM-DD | | `STANDX_TOKEN_VALIDITY_DAYS` | Token 有效期天数 | 推荐配置,与创建日期配合使用 | diff --git a/src/config.ts b/src/config.ts index 5841f46..fcdd9b8 100644 --- a/src/config.ts +++ b/src/config.ts @@ -227,6 +227,10 @@ export interface MakerPointsConfig { minRepriceBps: number; /** 是否根据 Binance 盘口深度失衡自动取消单边挂单,默认 true */ enableBinanceDepthCancel: boolean; + /** Binance 深度监控窗口(bps),默认 5 */ + binanceDepthWindowBps?: number; + /** Binance 深度失衡比例阈值,默认 8 */ + binanceDepthImbalanceRatio?: number; /** 各档位最小深度阈值 (BTC),盘口到目标价之间的挂单量低于此值则跳过该档位,默认 10 */ filterMinDepth: number; } @@ -254,6 +258,8 @@ export const makerPointsConfig: MakerPointsConfig = { band30To100Amount: parseNumber(process.env.MAKER_POINTS_BAND_30_100_AMOUNT, defaultMakerPointsAmount), minRepriceBps: parseNumber(process.env.MAKER_POINTS_MIN_REPRICE_BPS, 3), enableBinanceDepthCancel: parseBoolean(process.env.MAKER_POINTS_BINANCE_DEPTH_CANCEL, true), + binanceDepthWindowBps: parseNumber(process.env.MAKER_POINTS_BINANCE_DEPTH_WINDOW_BPS, 5), + binanceDepthImbalanceRatio: parseNumber(process.env.MAKER_POINTS_BINANCE_DEPTH_IMBALANCE_RATIO, 8), filterMinDepth: parseNumber(process.env.MAKER_POINTS_FILTER_MIN_DEPTH, 10), }; diff --git a/src/i18n/index.ts b/src/i18n/index.ts index b9a32a0..d316996 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -248,8 +248,8 @@ const translations: Record = { en: "Quote mode: {mode} | BUY {buy} | SELL {sell}", }, "makerPoints.binanceLine": { - zh: "Binance 深度(±9bps): 买 {buy} | 卖 {sell} | 状态: {status}", - en: "Binance depth (±9bps): bid {buy} | ask {sell} | Status: {status}", + zh: "Binance 深度(±{windowBps}bps): 买 {buy} | 卖 {sell} | 状态: {status}", + en: "Binance depth (±{windowBps}bps): bid {buy} | ask {sell} | Status: {status}", }, "makerPoints.bandDepthLine": { zh: "StandX 档位 {band}bps 深度: 买 {buy} | 卖 {sell}", diff --git a/src/strategy/maker-points-engine.ts b/src/strategy/maker-points-engine.ts index a828430..87164b2 100644 --- a/src/strategy/maker-points-engine.ts +++ b/src/strategy/maker-points-engine.ts @@ -206,8 +206,12 @@ export class MakerPointsEngine { baseUrl: process.env.BINANCE_SPOT_WS_URL ?? process.env.BINANCE_WS_URL, restBaseUrl: process.env.BINANCE_REST_URL, levels: 20, - ratio: 2, - depthWindowBps: 9, + ratio: Number.isFinite(this.config.binanceDepthImbalanceRatio) + ? Math.max(1.01, Number(this.config.binanceDepthImbalanceRatio)) + : 8, + depthWindowBps: Number.isFinite(this.config.binanceDepthWindowBps) + ? Math.max(1, Number(this.config.binanceDepthWindowBps)) + : 5, speedMs: 100, logger: (context, error) => { this.tradeLog.push("warn", `Binance ${context} 异常: ${extractMessage(error)}`); diff --git a/src/ui/MakerPointsApp.tsx b/src/ui/MakerPointsApp.tsx index c144446..7bb5ed1 100644 --- a/src/ui/MakerPointsApp.tsx +++ b/src/ui/MakerPointsApp.tsx @@ -162,6 +162,7 @@ export function MakerPointsApp({ onExit }: MakerPointsAppProps) { {t("makerPoints.binanceLine", { buy: formatNumber(snapshot.binanceDepth?.buySum ?? 0, 4), sell: formatNumber(snapshot.binanceDepth?.sellSum ?? 0, 4), + windowBps: snapshot.binanceDepth?.windowBps ?? 5, status: imbalanceLabel, })} diff --git a/tests/config-inline-comments.test.ts b/tests/config-inline-comments.test.ts index 1b0a39c..9e104c4 100644 --- a/tests/config-inline-comments.test.ts +++ b/tests/config-inline-comments.test.ts @@ -28,10 +28,14 @@ describe("config env parsing", () => { process.env.EXCHANGE = "standx"; process.env.MAKER_POINTS_STOP_LOSS_USD = "1 # comment"; process.env.MAKER_POINTS_CLOSE_THRESHOLD = "2 ; comment"; + process.env.MAKER_POINTS_BINANCE_DEPTH_WINDOW_BPS = "6 # comment"; + process.env.MAKER_POINTS_BINANCE_DEPTH_IMBALANCE_RATIO = "9 ; comment"; const { makerPointsConfig } = await loadConfig(); expect(makerPointsConfig.stopLossUsd).toBe(1); expect(makerPointsConfig.closeThreshold).toBe(2); + expect(makerPointsConfig.binanceDepthWindowBps).toBe(6); + expect(makerPointsConfig.binanceDepthImbalanceRatio).toBe(9); }); it("parses boolean maker-points env values with inline comments", async () => { @@ -42,4 +46,3 @@ describe("config env parsing", () => { expect(makerPointsConfig.enableBand10To30).toBe(false); }); }); - diff --git a/tests/maker-points-binance-depth-config.test.ts b/tests/maker-points-binance-depth-config.test.ts new file mode 100644 index 0000000..81291e1 --- /dev/null +++ b/tests/maker-points-binance-depth-config.test.ts @@ -0,0 +1,109 @@ +import { describe, expect, it } from "vitest"; +import type { ExchangeAdapter } from "../src/exchanges/adapter"; +import type { AsterAccountSnapshot, AsterDepth, AsterKline, AsterOrder, AsterTicker } from "../src/exchanges/types"; +import { t } from "../src/i18n"; +import { MakerPointsEngine } from "../src/strategy/maker-points-engine"; + +class StubAdapter implements ExchangeAdapter { + id = "standx"; + + supportsTrailingStops(): boolean { + return false; + } + + watchAccount(_cb: (snapshot: AsterAccountSnapshot) => void): void {} + watchOrders(_cb: (orders: AsterOrder[]) => void): void {} + watchDepth(_symbol: string, _cb: (depth: AsterDepth) => void): void {} + watchTicker(_symbol: string, _cb: (ticker: AsterTicker) => void): void {} + watchKlines(_symbol: string, _interval: string, _cb: (klines: AsterKline[]) => void): void {} + + async createOrder(): Promise { + throw new Error("not implemented"); + } + + async cancelOrder(): Promise {} + async cancelOrders(): Promise {} + async cancelAllOrders(): Promise {} +} + +describe("MakerPointsEngine Binance depth monitor config", () => { + it("uses default 5bps window and ratio 8", () => { + const engine = new MakerPointsEngine( + { + symbol: "BTC-USD", + perOrderAmount: 0.01, + closeThreshold: 0, + stopLossUsd: 1, + refreshIntervalMs: 500, + maxLogEntries: 20, + maxCloseSlippagePct: 0.05, + priceTick: 0.1, + qtyStep: 0.001, + enableBand0To10: true, + enableBand10To30: false, + enableBand30To100: false, + band0To10Amount: 0.01, + band10To30Amount: 0.01, + band30To100Amount: 0.01, + minRepriceBps: 3, + enableBinanceDepthCancel: true, + filterMinDepth: 0, + }, + new StubAdapter() + ); + + const trackerOptions = ((engine as any).binanceDepth as { options?: { depthWindowBps?: number; ratio?: number } }) + .options; + + expect(trackerOptions?.depthWindowBps).toBe(5); + expect(trackerOptions?.ratio).toBe(8); + + engine.stop(); + }); + + it("uses configured window and ratio", () => { + const engine = new MakerPointsEngine( + { + symbol: "BTC-USD", + perOrderAmount: 0.01, + closeThreshold: 0, + stopLossUsd: 1, + refreshIntervalMs: 500, + maxLogEntries: 20, + maxCloseSlippagePct: 0.05, + priceTick: 0.1, + qtyStep: 0.001, + enableBand0To10: true, + enableBand10To30: false, + enableBand30To100: false, + band0To10Amount: 0.01, + band10To30Amount: 0.01, + band30To100Amount: 0.01, + minRepriceBps: 3, + enableBinanceDepthCancel: true, + binanceDepthWindowBps: 7, + binanceDepthImbalanceRatio: 11, + filterMinDepth: 0, + }, + new StubAdapter() + ); + + const trackerOptions = ((engine as any).binanceDepth as { options?: { depthWindowBps?: number; ratio?: number } }) + .options; + + expect(trackerOptions?.depthWindowBps).toBe(7); + expect(trackerOptions?.ratio).toBe(11); + + engine.stop(); + }); + + it("renders binance depth line with dynamic window bps", () => { + const line = t( + "makerPoints.binanceLine", + { windowBps: 5, buy: "1.23", sell: "1.11", status: "Balanced" }, + "en" + ); + + expect(line).toContain("±5bps"); + }); +});