feat: add maxPositionSize to grid configuration and implement position size guard in GridEngine for enhanced order management

This commit is contained in:
discountry
2025-11-19 02:16:45 +08:00
parent 511cf8669d
commit ffd62fd481
3 changed files with 28 additions and 2 deletions
+12 -1
View File
@@ -126,6 +126,7 @@ export interface GridConfig {
spacingPct: number;
stopLossBufferPct: number;
maxLogEntries: number;
maxPositionSize: number;
}
const resolveBasisSymbol = (envKeys: string[], fallback: string): string => {
@@ -153,18 +154,28 @@ export const basisConfig: BasisArbConfig = {
arbAmount: parseNumber(process.env.ARB_AMOUNT, parseNumber(process.env.TRADE_AMOUNT, 0)),
};
const resolveGridMaxPosition = (tradeAmount: number): number => {
const fallback = Math.max(tradeAmount * 10, tradeAmount);
const raw = process.env.GRID_MAX_POSITION_SIZE ?? process.env.GRID_MAX_POSITION ?? process.env.GRID_POSITION_CAP;
const parsed = parseNumber(raw, fallback);
return parsed > 0 ? parsed : fallback;
};
export const gridConfig: GridConfig = {
symbol: resolveSymbolFromEnv(),
tradeAmount: parseNumber(process.env.TRADE_AMOUNT, 0.001),
refreshIntervalMs: parseNumber(process.env.GRID_REFRESH_INTERVAL_MS, 800),
priceTick: parseNumber(process.env.GRID_PRICE_TICK ?? process.env.PRICE_TICK, 0.1),
qtyStep: parseNumber(process.env.GRID_QTY_STEP ?? process.env.QTY_STEP, 0.001),
levelsPerSide: Math.max(5, Math.floor(parseNumber(process.env.GRID_LEVELS_PER_SIDE, 36))),
levelsPerSide: Math.max(5, Math.floor(parseNumber(process.env.GRID_LEVELS_PER_SIDE, 15))),
spacingPct: Math.max(0.0001, parseNumber(process.env.GRID_SPACING_PCT, 0.00025)),
stopLossBufferPct: Math.max(0.001, parseNumber(process.env.GRID_STOP_BUFFER_PCT, 0.003)),
maxLogEntries: parseNumber(process.env.GRID_MAX_LOG_ENTRIES, 200),
maxPositionSize: 0, // placeholder updated below
};
gridConfig.maxPositionSize = resolveGridMaxPosition(gridConfig.tradeAmount);
export function isBasisStrategyEnabled(): boolean {
const raw = process.env.ENABLE_BASIS_STRATEGY;
if (!raw) return false;
+15
View File
@@ -381,6 +381,7 @@ export class GridEngine {
private buildDesiredOrders(): DesiredGridOrder[] {
if (!this.gridReady || this.gridSpacing == null) return [];
const desired: DesiredGridOrder[] = [];
const absPos = Math.abs(this.position.positionAmt);
for (const level of this.levels) {
if (level.blockedUntil && this.now() < level.blockedUntil) {
continue;
@@ -406,6 +407,20 @@ export class GridEngine {
});
}
}
// Apply max position guard: if net仓位已达上限,跳过会增大仓位的开仓单
if (this.config.maxPositionSize > 0) {
return desired.filter((order) => {
if (order.intent !== "ENTRY") return true;
// opening in same direction as current position increases abs position
if (this.position.positionAmt >= 0 && order.side === "BUY") {
return absPos + order.amount <= this.config.maxPositionSize + EPSILON;
}
if (this.position.positionAmt <= 0 && order.side === "SELL") {
return absPos + order.amount <= this.config.maxPositionSize + EPSILON;
}
return true;
});
}
return desired;
}
+1 -1
View File
@@ -139,7 +139,7 @@ export function GridApp({ onExit }: GridAppProps) {
<Box flexDirection="column" marginRight={4}>
<Text color="greenBright"></Text>
<Text>
: {formatNumber(gridConfig.tradeAmount, 6)} : {gridConfig.levelsPerSide}
: {formatNumber(gridConfig.tradeAmount, 6)} : {gridConfig.levelsPerSide} : {formatNumber(gridConfig.maxPositionSize, 6)}
</Text>
<Text>
: {(gridConfig.spacingPct * 100).toFixed(3)}% : {(gridConfig.stopLossBufferPct * 100).toFixed(3)}%