feat: Add position scaling for strong confirmation signals
**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
This commit is contained in:
@@ -41,6 +41,15 @@ export interface TradingConfig {
|
||||
trailingStopPercent: number // Trail by this % below peak
|
||||
trailingStopActivation: number // Activate when runner profits exceed this %
|
||||
|
||||
// Position Scaling (add to winning positions)
|
||||
enablePositionScaling: boolean // Allow scaling into existing positions
|
||||
minScaleQualityScore: number // Minimum quality score for scaling signal (0-100)
|
||||
minProfitForScale: number // Position must be this % profitable to scale
|
||||
maxScaleMultiplier: number // Max total position size (e.g., 2.0 = 200% of original)
|
||||
scaleSizePercent: number // Scale size as % of original position (e.g., 50)
|
||||
minAdxIncrease: number // ADX must increase by this much for scaling
|
||||
maxPricePositionForScale: number // Don't scale if price position above this %
|
||||
|
||||
// DEX specific
|
||||
priceCheckIntervalMs: number // How often to check prices
|
||||
slippageTolerance: number // Max acceptable slippage (%)
|
||||
@@ -109,6 +118,15 @@ export const DEFAULT_TRADING_CONFIG: TradingConfig = {
|
||||
trailingStopPercent: 0.3, // Trail by 0.3% below peak price
|
||||
trailingStopActivation: 0.5, // Activate trailing when runner is +0.5% in profit
|
||||
|
||||
// Position Scaling (conservative defaults)
|
||||
enablePositionScaling: false, // Disabled by default - enable after testing
|
||||
minScaleQualityScore: 75, // Only scale with strong signals (vs 60 for initial entry)
|
||||
minProfitForScale: 0.4, // Position must be at/past TP1 to scale
|
||||
maxScaleMultiplier: 2.0, // Max 2x original position size total
|
||||
scaleSizePercent: 50, // Scale with 50% of original position size
|
||||
minAdxIncrease: 5, // ADX must increase by 5+ points (trend strengthening)
|
||||
maxPricePositionForScale: 70, // Don't scale if price >70% of range (near resistance)
|
||||
|
||||
// DEX settings
|
||||
priceCheckIntervalMs: 2000, // Check every 2 seconds
|
||||
slippageTolerance: 1.0, // 1% max slippage on market orders
|
||||
@@ -306,6 +324,27 @@ export function getConfigFromEnv(): Partial<TradingConfig> {
|
||||
trailingStopActivation: process.env.TRAILING_STOP_ACTIVATION
|
||||
? parseFloat(process.env.TRAILING_STOP_ACTIVATION)
|
||||
: undefined,
|
||||
enablePositionScaling: process.env.ENABLE_POSITION_SCALING
|
||||
? process.env.ENABLE_POSITION_SCALING === 'true'
|
||||
: undefined,
|
||||
minScaleQualityScore: process.env.MIN_SCALE_QUALITY_SCORE
|
||||
? parseInt(process.env.MIN_SCALE_QUALITY_SCORE)
|
||||
: undefined,
|
||||
minProfitForScale: process.env.MIN_PROFIT_FOR_SCALE
|
||||
? parseFloat(process.env.MIN_PROFIT_FOR_SCALE)
|
||||
: undefined,
|
||||
maxScaleMultiplier: process.env.MAX_SCALE_MULTIPLIER
|
||||
? parseFloat(process.env.MAX_SCALE_MULTIPLIER)
|
||||
: undefined,
|
||||
scaleSizePercent: process.env.SCALE_SIZE_PERCENT
|
||||
? parseFloat(process.env.SCALE_SIZE_PERCENT)
|
||||
: undefined,
|
||||
minAdxIncrease: process.env.MIN_ADX_INCREASE
|
||||
? parseFloat(process.env.MIN_ADX_INCREASE)
|
||||
: undefined,
|
||||
maxPricePositionForScale: process.env.MAX_PRICE_POSITION_FOR_SCALE
|
||||
? parseFloat(process.env.MAX_PRICE_POSITION_FOR_SCALE)
|
||||
: undefined,
|
||||
maxDailyDrawdown: process.env.MAX_DAILY_DRAWDOWN
|
||||
? parseFloat(process.env.MAX_DAILY_DRAWDOWN)
|
||||
: undefined,
|
||||
|
||||
Reference in New Issue
Block a user