diff --git a/config/trading.ts b/config/trading.ts index c3c4d27..9c1d209 100644 --- a/config/trading.ts +++ b/config/trading.ts @@ -145,8 +145,9 @@ export const DEFAULT_TRADING_CONFIG: TradingConfig = { // Execution useMarketOrders: true, // Use market orders for reliable fills confirmationTimeout: 30000, // 30 seconds max wait - takeProfit1SizePercent: 75, // Close 75% at TP1 to lock in profit - takeProfit2SizePercent: 80, // Close 80% of remaining 25% at TP2 (leaves 5% as runner) + // Position sizing (percentages of position to close at each TP) + takeProfit1SizePercent: 75, // Close 75% at TP1 (leaves 25% for TP2 + runner) + takeProfit2SizePercent: 0, // Don't close at TP2 - let full 25% remaining become the runner } // Supported markets on Drift Protocol diff --git a/lib/trading/position-manager.ts b/lib/trading/position-manager.ts index 222b14f..703c602 100644 --- a/lib/trading/position-manager.ts +++ b/lib/trading/position-manager.ts @@ -9,7 +9,6 @@ import { closePosition } from '../drift/orders' import { getPythPriceMonitor, PriceUpdate } from '../pyth/price-monitor' import { getMergedConfig, TradingConfig, getMarketConfig } from '../../config/trading' import { updateTradeExit, updateTradeState, getOpenTrades } from '../database/trades' -import { canUseRunner, getViableTP2Percent } from './runner-calculator' export interface ActiveTrade { id: string @@ -704,61 +703,24 @@ export class PositionManager { await this.saveTradeState(trade) } - // 5. Take profit 2 (remaining position) + // 5. TP2 Hit - Activate runner (no close, just start trailing) if (trade.tp1Hit && !trade.tp2Hit && this.shouldTakeProfit2(currentPrice, trade)) { - console.log(`🎊 TP2 HIT: ${trade.symbol} at ${profitPercent.toFixed(2)}%`) + console.log(`🎊 TP2 HIT: ${trade.symbol} at ${profitPercent.toFixed(2)}% - Activating 25% runner!`) - // Check if runner would be viable with current position size - const runnerCheck = canUseRunner( - trade.symbol, - trade.currentSize, - currentPrice, - this.config.takeProfit1SizePercent, - this.config.takeProfit2SizePercent + // Mark TP2 as hit and activate trailing stop on full remaining 25% + trade.tp2Hit = true + trade.peakPrice = currentPrice + trade.runnerTrailingPercent = this.getRunnerTrailingPercent(trade) + + console.log( + `🏃 Runner activated on full remaining position: ${((trade.currentSize / trade.positionSize) * 100).toFixed(1)}% | trailing buffer ${trade.runnerTrailingPercent?.toFixed(3)}%` ) - if (!runnerCheck.viable) { - console.log(`⚠️ Runner not viable: ${runnerCheck.reason}`) - console.log(` Skipping TP2 close, will use trailing stop on full 25% remaining`) - - // Mark TP2 as "hit" but don't close anything - activate trailing on full 25% - trade.tp2Hit = true - trade.trailingStopActive = true - trade.runnerTrailingPercent = this.getRunnerTrailingPercent(trade) - - console.log( - `🏃 Runner activated on full remaining position: ${((trade.currentSize / trade.positionSize) * 100).toFixed(1)}% | trailing buffer ${trade.runnerTrailingPercent?.toFixed(3)}%` - ) - - await this.saveTradeState(trade) - return - } - - // Runner is viable - proceed with TP2 close - const percentToClose = this.config.takeProfit2SizePercent - - console.log(`✅ Runner viable: ${runnerCheck.runnerSizeBase.toFixed(4)} base (${runnerCheck.runnerSizeUSD.toFixed(2)} USD)`) - - await this.executeExit(trade, percentToClose, 'TP2', currentPrice) - - // If some position remains, mark TP2 as hit and activate trailing stop - if (percentToClose < 100) { - trade.tp2Hit = true - trade.currentSize = trade.currentSize * ((100 - percentToClose) / 100) - trade.runnerTrailingPercent = this.getRunnerTrailingPercent(trade) - - console.log( - `🏃 Runner activated: ${((trade.currentSize / trade.positionSize) * 100).toFixed(1)}% remaining | trailing buffer ${trade.runnerTrailingPercent?.toFixed(3)}%` - ) - - // Save state after TP2 - await this.saveTradeState(trade) - } + // Save state after TP2 activation + await this.saveTradeState(trade) return - } - - // 6. Trailing stop for runner (after TP2) + } // 6. Trailing stop for runner (after TP2 activation) if (trade.tp2Hit && this.config.useTrailingStop) { // Check if trailing stop should be activated if (!trade.trailingStopActive && profitPercent >= this.config.trailingStopActivation) {