- Add ATR-based dynamic TP2 scaling from 0.7% to 3.0% based on volatility
- New config options: useAtrBasedTargets, atrMultiplierForTp2, minTp2Percent, maxTp2Percent
- Enhanced settings UI with ATR controls and updated risk calculator
- Fix external closure P&L calculation using unrealized P&L instead of volatile current price
- Update execute and test endpoints to use calculateDynamicTp2() function
- Maintain 25% runner system for capturing extended moves (4-5% targets)
- Add environment variables for ATR-based configuration
- Better P&L accuracy for manual position closures
CHANGE: TP2 now activates trailing stop on full 25% remaining instead
of closing 80% and leaving 5% runner.
Benefits:
- 5x larger runner (25% vs 5%) = 25 vs 05 on 100 position
- Eliminates Drift minimum size issues completely
- Simplifies logic - no more canUseRunner() viability checks
- Better R:R on extended moves
New flow:
- TP1 (+0.4%): Close 75%, keep 25%
- TP2 (+0.7%): Skip close, activate trailing stop on full 25%
- Runner: 25% with ATR-based trailing (0.25-0.9%)
Config change: takeProfit2SizePercent: 80 → 0
Position Manager: Remove canUseRunner logic, activate trailing at TP2 hit
**Problem:**
Config had minOrderSize: 0.01 ETH for ETH-PERP, but user successfully opens positions as small as $4-8 (0.001-0.002 ETH at ~$4000/ETH).
Database shows successful ETH trades:
- $8 positions = 0.002 ETH at $4000/ETH
- $4 positions = 0.001 ETH at $4000/ETH
**Actual Drift Minimum:**
0.001 ETH (~$4 at $4000/ETH), NOT 0.01 ETH
**Fix:**
Updated config/trading.ts:
- minOrderSize: 0.01 → 0.001 ETH
- Updated comment to reflect actual minimum
**Impact:**
- ✅ Accurate minimum validation
- ✅ Small runner positions (0.0005-0.001 ETH) won't be falsely flagged
- ✅ Prevents incorrect "forcing 100% close" on valid sizes
- ✅ Allows proper data collection at $4 position size
**Note:**
The previous fix for checking minOrderSize before close is still valid and needed - it just now uses the correct minimum (0.001 instead of 0.01).
**Feature: Position Scaling**
Allows adding to existing profitable positions when high-quality signals confirm trend strength.
**Configuration (config/trading.ts):**
- enablePositionScaling: false (disabled by default - enable after testing)
- minScaleQualityScore: 75 (higher bar than initial 60)
- minProfitForScale: 0.4% (must be at/past TP1)
- maxScaleMultiplier: 2.0 (max 200% of original size)
- scaleSizePercent: 50% (add 50% of original position)
- minAdxIncrease: 5 (ADX must strengthen)
- maxPricePositionForScale: 70% (don't chase resistance)
**Validation Logic (check-risk endpoint):**
Same-direction signal triggers scaling check if enabled:
1. Quality score ≥75 (stronger than initial entry)
2. Position profitable ≥0.4% (at/past TP1)
3. ADX increased ≥5 points (trend strengthening)
4. Price position <70% (not near resistance)
5. Total size <2x original (risk management)
6. Returns 'allowed: true, reason: Position scaling' if all pass
**Execution (execute endpoint):**
- Opens additional position at scale size (50% of original)
- Updates ActiveTrade: timesScaled, totalScaleAdded, currentSize
- Tracks originalAdx from first entry for comparison
- Returns 'action: scaled' with scale details
**ActiveTrade Interface:**
Added fields:
- originalAdx?: number (for scaling validation)
- timesScaled?: number (track scaling count)
- totalScaleAdded?: number (total USD added)
**Example Scenario:**
1. LONG SOL at $176 (quality: 45, ADX: 13.4) - weak but entered
2. Price hits $176.70 (+0.4%) - at TP1
3. New LONG signal (quality: 78, ADX: 19) - strong confirmation
4. Scaling validation: ✅ Quality 78 ✅ Profit +0.4% ✅ ADX +5.6 ✅ Price 68%
5. Adds 50% more position at $176.70
6. Total position: 150% of original size
**Conservative Design:**
- Disabled by default (requires manual enabling)
- Only scales INTO profitable positions (never averaging down)
- Requires significant quality improvement (75 vs 60)
- Requires trend confirmation (ADX increase)
- Hard cap at 2x original size
- Won't chase near resistance levels
**Next Steps:**
1. Enable in settings: ENABLE_POSITION_SCALING=true
2. Test with small positions first
3. Monitor data: do scaled positions outperform?
4. Adjust thresholds based on results
**Safety:**
- All existing duplicate prevention logic intact
- Flip logic unchanged (still requires quality check)
- Position Manager tracks scaling state
- Can be toggled on/off without code changes
- Add SymbolSettings interface with enabled/positionSize/leverage fields
- Implement per-symbol ENV variables (SOLANA_*, ETHEREUM_*)
- Add SOL and ETH sections to settings UI with enable/disable toggles
- Add symbol-specific test buttons (SOL LONG/SHORT, ETH LONG/SHORT)
- Update execute and test endpoints to check symbol enabled status
- Add real-time risk/reward calculator per symbol
- Rename 'Position Sizing' to 'Global Fallback' for clarity
- Fix position manager P&L calculation for externally closed positions
- Fix zero P&L bug affecting 12 historical trades
- Add SQL scripts for recalculating historical P&L data
- Move archive TypeScript files to .archive to fix build
Defaults:
- SOL: 10 base × 10x leverage = 100 notional (profit trading)
- ETH: base × 1x leverage = notional (data collection)
- Global: 10 × 10x for BTC and other symbols
Configuration priority: Per-symbol ENV > Market config > Global ENV > Defaults
- Add qualityScore to ExecuteTradeResponse interface and response object
- Update analytics page to always show Signal Quality card (N/A if unavailable)
- Fix n8n workflow to pass context metrics and qualityScore to execute endpoint
- Fix timezone in Telegram notifications (Europe/Berlin)
- Fix symbol normalization in /api/trading/close endpoint
- Update Drift ETH-PERP minimum order size (0.002 ETH not 0.01)
- Add transaction confirmation to closePosition() to prevent phantom closes
- Add 30-second grace period for new trades in Position Manager
- Fix execution order: database save before Position Manager.addTrade()
- Update copilot instructions with transaction confirmation pattern
- Added minQualityScore to TradingConfig (default: 60)
- Updated settings UI with slider control (0-100, step 5)
- Updated check-risk endpoint to use config value
- Made scoreSignalQuality function accept minScore parameter
- Updated API to read/write MIN_QUALITY_SCORE env variable
- Allows users to adjust quality threshold from settings page
- Extended MarketConfig with optional positionSize and leverage fields
- Configured ETH-PERP at @ 1x leverage for minimal-risk data collection
- Created getPositionSizeForSymbol() helper function in config/trading.ts
- Integrated symbol-specific sizing into execute endpoint
- Added comprehensive guide in docs/guides/SYMBOL_SPECIFIC_SIZING.md
Purpose: Enable ETH trading for faster signal quality data collection
while preserving SOL's profit-generation sizing (0 @ 10x)
Next: Create ETH alert in TradingView and restart bot
- Updated minTimeBetweenTrades config to use minutes instead of seconds
- Changed default from 600 seconds to 10 minutes
- Updated Settings UI label from 'seconds' to 'minutes' and adjusted range (0-60 min)
- Updated .env comments to reflect new unit
- No functional change since cooldown enforcement not yet implemented (TODO in check-risk route)
- Change takeProfit2SizePercent from 100% to 80% to leave 5% runner
- Fix cancelAllOrders() to detect trigger orders using orderId > 0
- Trigger orders (TRIGGER_MARKET, TRIGGER_LIMIT) now properly canceled
- Trailing stop will now activate on 5% runner position
- Implemented trailing stop logic in Position Manager for remaining position after TP2
- Added new ActiveTrade fields: tp2Hit, trailingStopActive, peakPrice
- New config settings: useTrailingStop, trailingStopPercent, trailingStopActivation
- Added trailing stop UI section in settings page with explanations
- Fixed env file parsing regex to support numbers in variable names (A-Z0-9_)
- Settings now persist correctly across container restarts
- Added back arrow navigation on settings page
- Updated all API endpoints and test files with new fields
- Trailing stop activates when runner reaches configured profit level
- SL trails below peak price by configurable percentage
- Add PostgreSQL database with Prisma ORM
- Trade model: tracks entry/exit, P&L, order signatures, config snapshots
- PriceUpdate model: tracks price movements for drawdown analysis
- SystemEvent model: logs errors and system events
- DailyStats model: aggregated performance metrics
- Implement dual stop loss system (enabled by default)
- Soft stop (TRIGGER_LIMIT) at -1.5% to avoid wicks
- Hard stop (TRIGGER_MARKET) at -2.5% to guarantee exit
- Configurable via USE_DUAL_STOPS, SOFT_STOP_PERCENT, HARD_STOP_PERCENT
- Backward compatible with single stop modes
- Add database service layer (lib/database/trades.ts)
- createTrade(): save new trades with all details
- updateTradeExit(): close trades with P&L calculations
- addPriceUpdate(): track price movements during trade
- getTradeStats(): calculate win rate, profit factor, avg win/loss
- logSystemEvent(): log errors and system events
- Update execute endpoint to use dual stops and save to database
- Calculate dual stop prices when enabled
- Pass dual stop parameters to placeExitOrders
- Save complete trade record to database after execution
- Add test trade button to settings page
- New /api/trading/test endpoint for executing test trades
- Displays detailed results including dual stop prices
- Confirmation dialog before execution
- Shows entry price, position size, stops, and TX signature
- Generate Prisma client in Docker build
- Update DATABASE_URL for container networking
- Add placeExitOrders() to create reduce-only LIMIT orders for TP1, TP2, and SL
- Orders now visible in Drift UI
- Tested with real tiny position (0 base x 5x = 0)
- All 3 exit orders placed successfully on-chain
- Position manager continues monitoring as backup
- Added test script and results documentation
Features:
- Autonomous trading system with Drift Protocol on Solana
- Real-time position monitoring with Pyth price feeds
- Dynamic stop-loss and take-profit management
- n8n workflow integration for TradingView signals
- Beautiful web UI for settings management
- REST API for trade execution and monitoring
- Next.js 15 with standalone output mode
- TypeScript with strict typing
- Docker containerization with multi-stage builds
- PostgreSQL database for trade history
- Singleton pattern for Drift client connection pooling
- BN.js for BigNumber handling (Drift SDK requirement)
- Configurable stop-loss and take-profit levels
- Breakeven trigger and profit locking
- Daily loss limits and trade cooldowns
- Slippage tolerance controls
- DRY_RUN mode for safe testing
- Real-time risk calculator
- Interactive sliders for all parameters
- Live preview of trade outcomes
- Position sizing and leverage controls
- Beautiful gradient design with Tailwind CSS
- POST /api/trading/execute - Execute trades
- POST /api/trading/close - Close positions
- GET /api/trading/positions - Monitor active trades
- GET /api/trading/check-risk - Validate trade signals
- GET /api/settings - View configuration
- POST /api/settings - Update configuration
- Fixed Borsh serialization errors (simplified order params)
- Resolved RPC rate limiting with singleton pattern
- Fixed BigInt vs BN type mismatches
- Corrected order execution flow
- Improved position state management
- Complete setup guides
- Docker deployment instructions
- n8n workflow configuration
- API reference documentation
- Risk management guidelines
- Runs on port 3001 (external), 3000 (internal)
- Uses Helius RPC for optimal performance
- Production-ready with error handling
- Health monitoring and logging