/** * Trading Bot v4 - Configuration * * Optimized for 5-minute scalping with 10x leverage on Drift Protocol */ export interface TradingConfig { // Position sizing positionSize: number // USD amount to trade leverage: number // Leverage multiplier // Risk management (as percentages of entry price) stopLossPercent: number // Negative number (e.g., -1.5) takeProfit1Percent: number // Positive number (e.g., 0.7) takeProfit2Percent: number // Positive number (e.g., 1.5) emergencyStopPercent: number // Hard stop (e.g., -2.0) // Dynamic adjustments breakEvenTriggerPercent: number // When to move SL to breakeven profitLockTriggerPercent: number // When to lock in profit profitLockPercent: number // How much profit to lock // DEX specific priceCheckIntervalMs: number // How often to check prices slippageTolerance: number // Max acceptable slippage (%) // Risk limits maxDailyDrawdown: number // USD stop trading threshold maxTradesPerHour: number // Limit overtrading minTimeBetweenTrades: number // Cooldown period (seconds) // Execution useMarketOrders: boolean // true = instant execution confirmationTimeout: number // Max time to wait for confirmation } export interface MarketConfig { symbol: string // e.g., 'SOL-PERP' driftMarketIndex: number pythPriceFeedId: string minOrderSize: number tickSize: number } // Default configuration for 5-minute scalping with $1000 capital and 10x leverage export const DEFAULT_TRADING_CONFIG: TradingConfig = { // Position sizing positionSize: 50, // $50 base capital (SAFE FOR TESTING) leverage: 10, // 10x leverage = $500 position size // Risk parameters (wider for DEX slippage/wicks) stopLossPercent: -1.5, // -1.5% price = -15% account loss (closes 100%) takeProfit1Percent: 0.7, // +0.7% price = +7% account gain (closes 50%) takeProfit2Percent: 1.5, // +1.5% price = +15% account gain (closes 50%) emergencyStopPercent: -2.0, // -2% hard stop = -20% account loss // Dynamic adjustments breakEvenTriggerPercent: 0.4, // Move SL to breakeven at +0.4% profitLockTriggerPercent: 1.0, // Lock profit at +1.0% profitLockPercent: 0.4, // Lock +0.4% profit // DEX settings priceCheckIntervalMs: 2000, // Check every 2 seconds slippageTolerance: 1.0, // 1% max slippage on market orders // Risk limits maxDailyDrawdown: -150, // Stop trading if daily loss exceeds $150 (-15%) maxTradesPerHour: 6, // Max 6 trades per hour minTimeBetweenTrades: 600, // 10 minutes cooldown // Execution useMarketOrders: true, // Use market orders for reliable fills confirmationTimeout: 30000, // 30 seconds max wait } // Supported markets on Drift Protocol export const SUPPORTED_MARKETS: Record = { 'SOL-PERP': { symbol: 'SOL-PERP', driftMarketIndex: 0, pythPriceFeedId: '0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d', minOrderSize: 0.1, // 0.1 SOL minimum tickSize: 0.0001, }, 'BTC-PERP': { symbol: 'BTC-PERP', driftMarketIndex: 1, pythPriceFeedId: '0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43', minOrderSize: 0.001, // 0.001 BTC minimum tickSize: 0.01, }, 'ETH-PERP': { symbol: 'ETH-PERP', driftMarketIndex: 2, pythPriceFeedId: '0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace', minOrderSize: 0.01, // 0.01 ETH minimum tickSize: 0.01, }, } // Map TradingView symbols to Drift markets export function normalizeTradingViewSymbol(tvSymbol: string): string { const upper = tvSymbol.toUpperCase() if (upper.includes('SOL')) return 'SOL-PERP' if (upper.includes('BTC')) return 'BTC-PERP' if (upper.includes('ETH')) return 'ETH-PERP' // Default to SOL if unknown console.warn(`Unknown symbol ${tvSymbol}, defaulting to SOL-PERP`) return 'SOL-PERP' } // Get market configuration export function getMarketConfig(symbol: string): MarketConfig { const config = SUPPORTED_MARKETS[symbol] if (!config) { throw new Error(`Unsupported market: ${symbol}`) } return config } // Validate trading configuration export function validateTradingConfig(config: TradingConfig): void { if (config.positionSize <= 0) { throw new Error('Position size must be positive') } if (config.leverage < 1 || config.leverage > 20) { throw new Error('Leverage must be between 1 and 20') } if (config.stopLossPercent >= 0) { throw new Error('Stop loss must be negative') } if (config.takeProfit1Percent <= 0 || config.takeProfit2Percent <= 0) { throw new Error('Take profit values must be positive') } if (config.takeProfit1Percent >= config.takeProfit2Percent) { throw new Error('TP2 must be greater than TP1') } if (config.slippageTolerance < 0 || config.slippageTolerance > 10) { throw new Error('Slippage tolerance must be between 0 and 10%') } } // Environment-based configuration export function getConfigFromEnv(): Partial { return { positionSize: process.env.MAX_POSITION_SIZE_USD ? parseFloat(process.env.MAX_POSITION_SIZE_USD) : undefined, leverage: process.env.LEVERAGE ? parseInt(process.env.LEVERAGE) : undefined, stopLossPercent: process.env.STOP_LOSS_PERCENT ? parseFloat(process.env.STOP_LOSS_PERCENT) : undefined, takeProfit1Percent: process.env.TAKE_PROFIT_1_PERCENT ? parseFloat(process.env.TAKE_PROFIT_1_PERCENT) : undefined, takeProfit2Percent: process.env.TAKE_PROFIT_2_PERCENT ? parseFloat(process.env.TAKE_PROFIT_2_PERCENT) : undefined, maxDailyDrawdown: process.env.MAX_DAILY_DRAWDOWN ? parseFloat(process.env.MAX_DAILY_DRAWDOWN) : undefined, maxTradesPerHour: process.env.MAX_TRADES_PER_HOUR ? parseInt(process.env.MAX_TRADES_PER_HOUR) : undefined, } } // Merge configurations export function getMergedConfig( overrides?: Partial ): TradingConfig { const envConfig = getConfigFromEnv() const config = { ...DEFAULT_TRADING_CONFIG, ...envConfig, ...overrides, } validateTradingConfig(config) return config }