Add TP1/SL consistency check on trade restore
This commit is contained in:
@@ -136,6 +136,12 @@ export class PositionManager {
|
||||
|
||||
this.activeTrades.set(activeTrade.id, activeTrade)
|
||||
console.log(`✅ Restored trade: ${activeTrade.symbol} ${activeTrade.direction} at $${activeTrade.entryPrice}`)
|
||||
|
||||
// Consistency check: if TP1 hit but SL not moved to breakeven, fix it now
|
||||
if (activeTrade.tp1Hit && !activeTrade.slMovedToBreakeven) {
|
||||
console.log(`🔧 Detected inconsistent state: TP1 hit but SL not at breakeven. Fixing now...`)
|
||||
await this.handlePostTp1Adjustments(activeTrade, 'recovery after restore')
|
||||
}
|
||||
}
|
||||
|
||||
if (this.activeTrades.size > 0) {
|
||||
@@ -207,6 +213,22 @@ export class PositionManager {
|
||||
return Array.from(this.activeTrades.values())
|
||||
}
|
||||
|
||||
async reconcileTrade(symbol: string): Promise<void> {
|
||||
const trade = Array.from(this.activeTrades.values()).find(t => t.symbol === symbol)
|
||||
if (!trade) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const driftService = getDriftService()
|
||||
const marketConfig = getMarketConfig(symbol)
|
||||
const oraclePrice = await driftService.getOraclePrice(marketConfig.driftMarketIndex)
|
||||
await this.checkTradeConditions(trade, oraclePrice)
|
||||
} catch (error) {
|
||||
console.error(`⚠️ Failed to reconcile trade for ${symbol}:`, error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get specific trade
|
||||
*/
|
||||
@@ -322,31 +344,26 @@ export class PositionManager {
|
||||
// Position exists - check if size changed (TP1/TP2 filled)
|
||||
const positionSizeUSD = position.size * currentPrice
|
||||
const trackedSizeUSD = trade.currentSize
|
||||
const sizeDiffPercent = Math.abs(positionSizeUSD - trackedSizeUSD) / Math.max(trackedSizeUSD, 1) * 100
|
||||
|
||||
const reductionUSD = trackedSizeUSD - positionSizeUSD
|
||||
const reductionPercentOfOriginal = trade.positionSize > 0
|
||||
? (reductionUSD / trade.positionSize) * 100
|
||||
: 0
|
||||
const reductionPercentOfTracked = trackedSizeUSD > 0
|
||||
? (reductionUSD / trackedSizeUSD) * 100
|
||||
: 0
|
||||
|
||||
const sizeDiffPercent = Math.abs(positionSizeUSD - trackedSizeUSD) / trackedSizeUSD * 100
|
||||
|
||||
// If position size reduced significantly, TP orders likely filled
|
||||
if (positionSizeUSD < trackedSizeUSD * 0.9 && sizeDiffPercent > 10) {
|
||||
console.log(`📊 Position size changed: tracking $${trackedSizeUSD.toFixed(2)} but found $${positionSizeUSD.toFixed(2)}`)
|
||||
|
||||
if (!trade.tp1Hit && reductionPercentOfOriginal >= (this.config.takeProfit1SizePercent * 0.8)) {
|
||||
|
||||
// Detect which TP filled based on size reduction
|
||||
const reductionPercent = ((trackedSizeUSD - positionSizeUSD) / trade.positionSize) * 100
|
||||
|
||||
if (!trade.tp1Hit && reductionPercent >= (this.config.takeProfit1SizePercent * 0.8)) {
|
||||
// TP1 fired (should be ~75% reduction)
|
||||
console.log(`🎯 TP1 detected as filled! Reduction: ${reductionPercentOfOriginal.toFixed(1)}% of original`)
|
||||
console.log(`🎯 TP1 detected as filled! Reduction: ${reductionPercent.toFixed(1)}%`)
|
||||
trade.tp1Hit = true
|
||||
trade.currentSize = positionSizeUSD
|
||||
|
||||
|
||||
await this.handlePostTp1Adjustments(trade, 'on-chain TP1 detection')
|
||||
|
||||
} else if (trade.tp1Hit && !trade.tp2Hit && reductionPercentOfTracked >= (this.config.takeProfit2SizePercent * 0.8)) {
|
||||
// TP2 fired (should clear remaining runner allocation)
|
||||
console.log(`🎯 TP2 detected as filled! Reduction: ${reductionPercentOfTracked.toFixed(1)}% of remaining`)
|
||||
|
||||
} else if (trade.tp1Hit && !trade.tp2Hit && reductionPercent >= 85) {
|
||||
// TP2 fired (total should be ~95% closed, 5% runner left)
|
||||
console.log(`🎯 TP2 detected as filled! Reduction: ${reductionPercent.toFixed(1)}%`)
|
||||
trade.tp2Hit = true
|
||||
trade.currentSize = positionSizeUSD
|
||||
trade.trailingStopActive = true
|
||||
@@ -354,16 +371,16 @@ export class PositionManager {
|
||||
console.log(
|
||||
`🏃 Runner active: $${positionSizeUSD.toFixed(2)} with trailing buffer ${trade.runnerTrailingPercent?.toFixed(3)}%`
|
||||
)
|
||||
|
||||
|
||||
await this.saveTradeState(trade)
|
||||
|
||||
|
||||
} else {
|
||||
// Partial fill detected but unclear which TP - just update size
|
||||
console.log(`⚠️ Unknown partial fill detected - updating tracked size to $${positionSizeUSD.toFixed(2)}`)
|
||||
trade.currentSize = positionSizeUSD
|
||||
await this.saveTradeState(trade)
|
||||
}
|
||||
|
||||
|
||||
// Continue monitoring the remaining position
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user