mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-09 08:18:07 +00:00
feat: add maxPositionSize to grid configuration and implement position size guard in GridEngine for enhanced order management
This commit is contained in:
+12
-1
@@ -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;
|
||||
|
||||
@@ -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
@@ -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)}%
|
||||
|
||||
Reference in New Issue
Block a user