Fix: Save MAE/MFE values when trades exit
Bug: MAE/MFE was tracked in memory during trades but not saved to database on exit Cause: updateTradeExit() wasn't receiving or saving MAE/MFE parameters Changes: - Added MAE/MFE fields to UpdateTradeExitParams interface - Modified updateTradeExit() to save maxFavorableExcursion, maxAdverseExcursion, maxFavorablePrice, maxAdversePrice - Updated both updateTradeExit() calls in Position Manager to pass MAE/MFE values - Enhanced exit logging to show final MAE/MFE percentages Impact: Future trades will now properly save MAE/MFE data for analytics Note: Past 2 trades (from before this fix) don't have MAE/MFE saved
This commit is contained in:
@@ -77,6 +77,11 @@ export interface UpdateTradeExitParams {
|
|||||||
holdTimeSeconds: number
|
holdTimeSeconds: number
|
||||||
maxDrawdown?: number
|
maxDrawdown?: number
|
||||||
maxGain?: number
|
maxGain?: number
|
||||||
|
// MAE/MFE final values
|
||||||
|
maxFavorableExcursion?: number
|
||||||
|
maxAdverseExcursion?: number
|
||||||
|
maxFavorablePrice?: number
|
||||||
|
maxAdversePrice?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createTrade(params: CreateTradeParams) {
|
export async function createTrade(params: CreateTradeParams) {
|
||||||
@@ -165,6 +170,11 @@ export async function updateTradeExit(params: UpdateTradeExitParams) {
|
|||||||
holdTimeSeconds: params.holdTimeSeconds,
|
holdTimeSeconds: params.holdTimeSeconds,
|
||||||
maxDrawdown: params.maxDrawdown,
|
maxDrawdown: params.maxDrawdown,
|
||||||
maxGain: params.maxGain,
|
maxGain: params.maxGain,
|
||||||
|
// Save final MAE/MFE values
|
||||||
|
maxFavorableExcursion: params.maxFavorableExcursion,
|
||||||
|
maxAdverseExcursion: params.maxAdverseExcursion,
|
||||||
|
maxFavorablePrice: params.maxFavorablePrice,
|
||||||
|
maxAdversePrice: params.maxAdversePrice,
|
||||||
status: 'closed',
|
status: 'closed',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -348,8 +348,13 @@ export class PositionManager {
|
|||||||
holdTimeSeconds,
|
holdTimeSeconds,
|
||||||
maxDrawdown: 0,
|
maxDrawdown: 0,
|
||||||
maxGain: trade.peakPnL,
|
maxGain: trade.peakPnL,
|
||||||
|
// Save final MAE/MFE values
|
||||||
|
maxFavorableExcursion: trade.maxFavorableExcursion,
|
||||||
|
maxAdverseExcursion: trade.maxAdverseExcursion,
|
||||||
|
maxFavorablePrice: trade.maxFavorablePrice,
|
||||||
|
maxAdversePrice: trade.maxAdversePrice,
|
||||||
})
|
})
|
||||||
console.log(`💾 External closure recorded: ${exitReason} at $${currentPrice} | P&L: $${realizedPnL.toFixed(2)}`)
|
console.log(`💾 External closure recorded: ${exitReason} at $${currentPrice} | P&L: $${realizedPnL.toFixed(2)} | MFE: ${trade.maxFavorableExcursion.toFixed(2)}% | MAE: ${trade.maxAdverseExcursion.toFixed(2)}%`)
|
||||||
} catch (dbError) {
|
} catch (dbError) {
|
||||||
console.error('❌ Failed to save external closure:', dbError)
|
console.error('❌ Failed to save external closure:', dbError)
|
||||||
}
|
}
|
||||||
@@ -616,8 +621,13 @@ export class PositionManager {
|
|||||||
holdTimeSeconds,
|
holdTimeSeconds,
|
||||||
maxDrawdown: 0, // TODO: Track this
|
maxDrawdown: 0, // TODO: Track this
|
||||||
maxGain: trade.peakPnL,
|
maxGain: trade.peakPnL,
|
||||||
|
// Save final MAE/MFE values
|
||||||
|
maxFavorableExcursion: trade.maxFavorableExcursion,
|
||||||
|
maxAdverseExcursion: trade.maxAdverseExcursion,
|
||||||
|
maxFavorablePrice: trade.maxFavorablePrice,
|
||||||
|
maxAdversePrice: trade.maxAdversePrice,
|
||||||
})
|
})
|
||||||
console.log('💾 Trade saved to database')
|
console.log('💾 Trade saved to database with MAE: ' + trade.maxAdverseExcursion.toFixed(2) + '% | MFE: ' + trade.maxFavorableExcursion.toFixed(2) + '%')
|
||||||
} catch (dbError) {
|
} catch (dbError) {
|
||||||
console.error('❌ Failed to save trade exit to database:', dbError)
|
console.error('❌ Failed to save trade exit to database:', dbError)
|
||||||
// Don't fail the close if database fails
|
// Don't fail the close if database fails
|
||||||
|
|||||||
Reference in New Issue
Block a user