feat: Optimize v6 indicator settings for better signal quality

- Moved confirmBars to separate 'Signal Timing' section (no longer under optional filters)
- Made timing setting always-active status clear in UI with improved tooltip
- Updated default settings based on backtesting analysis:
  * confirmBars: 0 → 1 (wait one bar for confirmation, reduces false signals)
  * ADX filter: Enabled by default (was disabled)
  * ADX Length: 14 → 16 (better trend detection)
  * ADX minimum: 20 → 14 (catches trends earlier)
  * Volume filter: Enabled by default (was disabled)
  * Volume max: 3.0x → 3.5x (allows bigger breakout moves)
  * RSI filter: Enabled by default (was disabled)
  * RSI long minimum: 45 → 35 (catches momentum earlier)
  * RSI short maximum: 55 → 70 (CRITICAL: allows shorts during breakdowns)

Why these changes matter:
- Old RSI short max of 55-61 blocked profitable breakdown entries (RSI 62-70 range)
- ADX 21 minimum missed early trend starts, lowering to 14 catches them
- Volume max 3.5x allows high-volume breakouts (was blocking with 3.0x)
- confirmBars=1 reduces wick flips while still catching good moves

Expected impact: Should fix v6 underperformance (-$47.70 over 25 trades)
Target: Positive P&L and 50%+ win rate over next 20-30 trades

Files modified:
- workflows/trading/moneyline_v6_improved.pinescript
This commit is contained in:
mindesbunister
2025-11-17 09:57:44 +01:00
parent be2410c639
commit 9dfc6da449
2 changed files with 13 additions and 10 deletions

View File

@@ -38,14 +38,17 @@ macdFastLen = input.int(12, "Fast", minval=1, inline="macdLens")
macdSlowLen = input.int(26, "Slow", minval=1, inline="macdLens")
macdSigLen = input.int(9, "Signal", minval=1, inline="macdLens")
// Signal timing (ALWAYS applies to all signals)
groupTiming = "Signal Timing"
confirmBars = input.int(1, "Bars to confirm after flip", minval=0, maxval=2, group=groupTiming, tooltip="ALWAYS ACTIVE: 0 = signal on flip bar (faster, more signals). 1 = wait one bar (safer, confirms trend). 2 = wait two bars (most conservative).")
// Entry filters (optional)
groupFilters = "Entry filters"
useEntryBuffer = input.bool(false, "Require entry buffer (ATR)", group=groupFilters, tooltip="If enabled, the close must be beyond the Money Line by the buffer amount to avoid wick flips.")
entryBufferATR = input.float(0.15, "Buffer size (in ATR)", minval=0.0, step=0.05, group=groupFilters, tooltip="0.100.20 works well on 1h.")
confirmBars = input.int(0, "Bars to confirm after flip", minval=0, maxval=2, group=groupFilters, tooltip="0 = signal on flip bar. 1 = wait one bar.")
useAdx = input.bool(false, "Use ADX trend-strength filter", group=groupFilters, tooltip="If enabled, require ADX to be above a threshold to reduce chop.")
adxLen = input.int(14, "ADX Length", minval=1, group=groupFilters)
adxMin = input.int(20, "ADX minimum", minval=0, maxval=100, group=groupFilters)
useAdx = input.bool(true, "Use ADX trend-strength filter", group=groupFilters, tooltip="If enabled, require ADX to be above a threshold to reduce chop.")
adxLen = input.int(16, "ADX Length", minval=1, group=groupFilters)
adxMin = input.int(14, "ADX minimum", minval=0, maxval=100, group=groupFilters)
// NEW v6 FILTERS
groupV6Filters = "v6 Quality Filters"
@@ -53,15 +56,15 @@ usePricePosition = input.bool(true, "Use price position filter", group=groupV6Fi
longPosMax = input.float(85, "Long max position %", minval=0, maxval=100, group=groupV6Filters, tooltip="Don't buy if price is above this % of 100-bar range (prevents chasing highs).")
shortPosMin = input.float(15, "Short min position %", minval=0, maxval=100, group=groupV6Filters, tooltip="Don't sell if price is below this % of 100-bar range (prevents chasing lows).")
useVolumeFilter = input.bool(false, "Use volume filter", group=groupV6Filters, tooltip="Filter signals with extreme volume (too low = dead, too high = climax).")
useVolumeFilter = input.bool(true, "Use volume filter", group=groupV6Filters, tooltip="Filter signals with extreme volume (too low = dead, too high = climax).")
volMin = input.float(0.7, "Volume min ratio", minval=0.1, step=0.1, group=groupV6Filters, tooltip="Minimum volume relative to 20-bar MA.")
volMax = input.float(3.0, "Volume max ratio", minval=0.5, step=0.5, group=groupV6Filters, tooltip="Maximum volume relative to 20-bar MA.")
volMax = input.float(3.5, "Volume max ratio", minval=0.5, step=0.5, group=groupV6Filters, tooltip="Maximum volume relative to 20-bar MA.")
useRsiFilter = input.bool(false, "Use RSI momentum filter", group=groupV6Filters, tooltip="Ensure momentum confirms direction.")
rsiLongMin = input.float(45, "RSI long minimum", minval=0, maxval=100, group=groupV6Filters)
useRsiFilter = input.bool(true, "Use RSI momentum filter", group=groupV6Filters, tooltip="Ensure momentum confirms direction.")
rsiLongMin = input.float(35, "RSI long minimum", minval=0, maxval=100, group=groupV6Filters)
rsiLongMax = input.float(70, "RSI long maximum", minval=0, maxval=100, group=groupV6Filters)
rsiShortMin = input.float(30, "RSI short minimum", minval=0, maxval=100, group=groupV6Filters)
rsiShortMax = input.float(55, "RSI short maximum", minval=0, maxval=100, group=groupV6Filters)
rsiShortMax = input.float(70, "RSI short maximum", minval=0, maxval=100, group=groupV6Filters)
// Determine effective parameters based on selected mode/profile
var string activeProfile = ""