feat: Add phantom trade detection and database tracking
- Detect position size mismatches (>50% variance) after opening - Save phantom trades to database with expectedSizeUSD, actualSizeUSD, phantomReason - Return error from execute endpoint to prevent Position Manager tracking - Add comprehensive documentation of phantom trade issue and solution - Enable data collection for pattern analysis and future optimization Fixes oracle price lag issue during volatile markets where transactions confirm but positions don't actually open at expected size.
This commit is contained in:
@@ -29,6 +29,8 @@ export interface OpenPositionResult {
|
||||
fillSize?: number
|
||||
slippage?: number
|
||||
error?: string
|
||||
isPhantom?: boolean // Position opened but size mismatch detected
|
||||
actualSizeUSD?: number // Actual position size if different from requested
|
||||
}
|
||||
|
||||
export interface ClosePositionParams {
|
||||
@@ -179,16 +181,37 @@ export async function openPosition(
|
||||
const fillPrice = position.entryPrice
|
||||
const slippage = Math.abs((fillPrice - oraclePrice) / oraclePrice) * 100
|
||||
|
||||
// CRITICAL: Validate actual position size vs expected
|
||||
// Phantom trade detection: Check if position is significantly smaller than expected
|
||||
const actualSizeUSD = position.size * fillPrice
|
||||
const expectedSizeUSD = params.sizeUSD
|
||||
const sizeRatio = actualSizeUSD / expectedSizeUSD
|
||||
|
||||
console.log(`💰 Fill details:`)
|
||||
console.log(` Fill price: $${fillPrice.toFixed(4)}`)
|
||||
console.log(` Slippage: ${slippage.toFixed(3)}%`)
|
||||
console.log(` Expected size: $${expectedSizeUSD.toFixed(2)}`)
|
||||
console.log(` Actual size: $${actualSizeUSD.toFixed(2)}`)
|
||||
console.log(` Size ratio: ${(sizeRatio * 100).toFixed(1)}%`)
|
||||
|
||||
// Flag as phantom if actual size is less than 50% of expected
|
||||
const isPhantom = sizeRatio < 0.5
|
||||
|
||||
if (isPhantom) {
|
||||
console.error(`🚨 PHANTOM POSITION DETECTED!`)
|
||||
console.error(` Expected: $${expectedSizeUSD.toFixed(2)}`)
|
||||
console.error(` Actual: $${actualSizeUSD.toFixed(2)}`)
|
||||
console.error(` This indicates the order was rejected or partially filled by Drift`)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
transactionSignature: txSig,
|
||||
fillPrice,
|
||||
fillSize: baseAssetSize,
|
||||
fillSize: position.size, // Use actual size from Drift, not calculated
|
||||
slippage,
|
||||
isPhantom,
|
||||
actualSizeUSD,
|
||||
}
|
||||
} else {
|
||||
// Position not found yet (may be DRY_RUN mode)
|
||||
|
||||
Reference in New Issue
Block a user