feat: refresh exit orders after TP1 and add dry-run harness

This commit is contained in:
mindesbunister
2025-11-05 10:00:39 +01:00
parent cbb6592153
commit 18e3e73e83
4 changed files with 383 additions and 64 deletions

103
scripts/dry-run-tp1-test.js Normal file
View File

@@ -0,0 +1,103 @@
process.env.TS_NODE_COMPILER_OPTIONS = JSON.stringify({
module: 'CommonJS',
moduleResolution: 'node',
esModuleInterop: true,
allowSyntheticDefaultImports: true,
})
const Module = require('module')
const originalRequire = Module.prototype.require
Module.prototype.require = function mockHelius(moduleId, ...args) {
if (moduleId === 'helius-laserstream' || moduleId.startsWith('helius-laserstream/')) {
console.log('⚠️ Mocking helius-laserstream module for dry run')
return {}
}
return originalRequire.apply(this, [moduleId, ...args])
}
require('ts-node/register')
const { Keypair } = require('@solana/web3.js')
const tradesModule = require('../lib/database/trades')
// Stub Prisma interactions for dry run so we don't need a database
tradesModule.getOpenTrades = async () => {
console.log(' Mock getOpenTrades returning empty list for dry run')
return []
}
tradesModule.updateTradeState = async () => {
console.log(' Mock updateTradeState no-op')
}
const { getInitializedPositionManager } = require('../lib/trading/position-manager')
const driftOrders = require('../lib/drift/orders')
// Stub Drift order helpers so we avoid needing an on-chain connection
driftOrders.cancelAllOrders = async (symbol) => {
console.log(` Mock cancelAllOrders invoked for ${symbol}`)
return { success: true, cancelledCount: 0 }
}
driftOrders.placeExitOrders = async (options) => {
console.log(' Mock placeExitOrders called with:', options)
return { success: true, signatures: ['MOCK_TP', 'MOCK_SL'] }
}
async function main() {
process.env.DRY_RUN = 'true'
process.env.DRIFT_ENV = 'devnet'
process.env.SOLANA_RPC_URL = process.env.SOLANA_RPC_URL || 'https://api.devnet.solana.com'
const kp = Keypair.generate()
process.env.DRIFT_WALLET_PRIVATE_KEY = JSON.stringify(Array.from(kp.secretKey))
console.log('🧪 Starting TP1 refresh dry-run test')
const manager = await getInitializedPositionManager()
const entryPrice = 150
const trade = {
id: `dry-run-${Date.now()}`,
positionId: 'DRY_RUN_POSITION',
symbol: 'SOL-PERP',
direction: 'long',
entryPrice,
entryTime: Date.now(),
positionSize: 200,
leverage: 10,
stopLossPrice: entryPrice * 0.985,
tp1Price: entryPrice * 1.004,
tp2Price: entryPrice * 1.007,
emergencyStopPrice: entryPrice * 0.98,
currentSize: 200 * 0.25,
tp1Hit: true,
tp2Hit: false,
slMovedToBreakeven: false,
slMovedToProfit: false,
trailingStopActive: false,
realizedPnL: 10,
unrealizedPnL: 0,
peakPnL: 12,
peakPrice: entryPrice * 1.01,
maxFavorableExcursion: 1.2,
maxAdverseExcursion: -0.6,
maxFavorablePrice: entryPrice * 1.01,
maxAdversePrice: entryPrice * 0.99,
priceCheckCount: 0,
lastPrice: entryPrice,
lastUpdateTime: Date.now(),
}
await manager.addTrade(trade)
console.log('➡️ Invoking handlePostTp1Adjustments...')
await manager.handlePostTp1Adjustments(trade, 'dry-run script')
console.log('✅ Dry run complete. Review logs above for refreshed exit order placement.')
process.exit(0)
}
main().catch((err) => {
console.error('❌ Dry run test failed:', err)
process.exit(1)
})