Files
trading_bot_v4/scripts/test-signals.sh
mindesbunister d2fbd125a0 fix: Make minSignalQualityScore configurable via settings + anti-chop improvements
CRITICAL BUG FIX:
- Settings page saved MIN_SIGNAL_QUALITY_SCORE to .env but check-risk had hardcoded value
- Now reads from config.minSignalQualityScore (defaults to 65, editable via /settings)
- Prevents settings changes from being ignored after restart

ANTI-CHOP FILTER FIXES:
- Fixed volume breakout bonus conflicting with anti-chop filter
- Volume breakout now requires ADX > 18 (trending market)
- Prevents high volume + low ADX from getting rewarded instead of penalized
- Anti-chop filter now properly blocks whipsaw traps at score 60

TESTING INFRASTRUCTURE:
- Added backtest script showing +17.1% P&L improvement (saved $242 in losses)
- Added test-signals.sh for comprehensive signal quality validation
- Added test-recent-signals.sh for analyzing actual trading session signals
- All tests passing: timeframe awareness, anti-chop, score thresholds

CHANGES:
- config/trading.ts: Added minSignalQualityScore to interface and defaults
- app/api/trading/check-risk/route.ts: Use config value instead of hardcoded 65
- lib/trading/signal-quality.ts: Fixed volume breakout bonus logic
- .env: Added MIN_SIGNAL_QUALITY_SCORE=65
- scripts/: Added comprehensive testing tools

BACKTEST RESULTS (Last 30 trades):
- Old system (score ≥60): $1,412.79 P&L
- New system (score ≥65 + anti-chop): $1,654.79 P&L
- Improvement: +$242.00 (+17.1%)
- Blocked 5 losing trades, missed 0 winners
2025-11-10 11:22:52 +01:00

163 lines
5.0 KiB
Bash
Executable File

#!/bin/bash
# Test Script: Verify Anti-Chop Filter & Timeframe Scoring
# Tests the exact signals from today to verify correct behavior
API_URL="http://localhost:3001/api/trading/check-risk"
API_KEY="2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb"
echo "=========================================="
echo "SIGNAL QUALITY TEST SUITE"
echo "=========================================="
echo ""
# Test 1: The SHORT that was TAKEN (should pass with ~85 score)
echo "TEST 1: SHORT at 10:05 (SHOULD PASS)"
echo "Signal: SOL sell .P 5 | ATR:0.26 | ADX:16.9 | RSI:41.6 | VOL:1.37 | POS:24.3"
echo ""
curl -X POST "$API_URL" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"symbol": "SOL-PERP",
"direction": "short",
"timeframe": "5",
"atr": 0.26,
"adx": 16.9,
"rsi": 41.6,
"volumeRatio": 1.37,
"pricePosition": 24.3
}' 2>/dev/null | jq -r '
if .allowed then
"✅ PASSED - Score: \(.qualityScore)/100"
else
"❌ BLOCKED - Score: \(.qualityScore)/100\nReason: \(.reason)\nDetails: \(.details)"
end
'
echo ""
echo "------------------------------------------"
echo ""
# Test 2: The LONG that was BLOCKED (should NOW PASS with ~70 score because timeframe aware)
echo "TEST 2: LONG at 10:10 (WAS BLOCKED AT 55, SHOULD NOW PASS AT 70)"
echo "Signal: SOL buy .P 5 | ATR:0.27 | ADX:16.1 | RSI:47.7 | VOL:1.45 | POS:42"
echo ""
curl -X POST "$API_URL" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"symbol": "SOL-PERP",
"direction": "long",
"timeframe": "5",
"atr": 0.27,
"adx": 16.1,
"rsi": 47.7,
"volumeRatio": 1.45,
"pricePosition": 42
}' 2>/dev/null | jq -r '
if .allowed then
"✅ PASSED - Score: \(.qualityScore)/100 (CORRECT - was wrongly blocked before)"
else
"❌ BLOCKED - Score: \(.qualityScore)/100 (WRONG - should pass!)\nReason: \(.reason)"
end
'
echo ""
echo "------------------------------------------"
echo ""
# Test 3: Anti-chop filter - High volume + low ADX (should be blocked)
echo "TEST 3: Anti-Chop Filter Test (SHOULD BLOCK)"
echo "Signal: SOL sell .P 5 | ATR:0.33 | ADX:14.8 | RSI:37.1 | VOL:2.29 | POS:12"
echo "Expected: BLOCKED by anti-chop filter (ADX<16 + VOL>1.5x = whipsaw trap)"
echo ""
curl -X POST "$API_URL" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"symbol": "SOL-PERP",
"direction": "short",
"timeframe": "5",
"atr": 0.33,
"adx": 14.8,
"rsi": 37.1,
"volumeRatio": 2.29,
"pricePosition": 12
}' 2>/dev/null | jq -r '
if .allowed then
"❌ PASSED - Score: \(.qualityScore)/100 (WRONG - anti-chop should block!)"
else
"✅ BLOCKED - Score: \(.qualityScore)/100 (CORRECT - whipsaw trap detected)"
end
'
echo ""
echo "------------------------------------------"
echo ""
# Test 4: Timeframe NOT passed (should treat as daily chart - different thresholds)
echo "TEST 4: Same signal WITHOUT timeframe (daily chart thresholds)"
echo "Signal: SOL buy | ATR:0.27 | ADX:16.1 | RSI:47.7 | VOL:1.45 | POS:42"
echo "Expected: Should be BLOCKED (ADX 16.1 is weak for daily charts)"
echo ""
curl -X POST "$API_URL" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"symbol": "SOL-PERP",
"direction": "long",
"atr": 0.27,
"adx": 16.1,
"rsi": 47.7,
"volumeRatio": 1.45,
"pricePosition": 42
}' 2>/dev/null | jq -r '
if .allowed then
"❌ PASSED - Score: \(.qualityScore)/100 (WRONG - should block without timeframe)"
else
"✅ BLOCKED - Score: \(.qualityScore)/100 (CORRECT - weak for daily chart)"
end
'
echo ""
echo "------------------------------------------"
echo ""
# Test 5: Strong signal (should definitely pass)
echo "TEST 5: Strong Signal (SHOULD PASS)"
echo "Signal: SOL buy .P 5 | ATR:0.52 | ADX:22.7 | RSI:53.1 | VOL:0.88 | POS:37.9"
echo ""
curl -X POST "$API_URL" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"symbol": "SOL-PERP",
"direction": "long",
"timeframe": "5",
"atr": 0.52,
"adx": 22.7,
"rsi": 53.1,
"volumeRatio": 0.88,
"pricePosition": 37.9
}' 2>/dev/null | jq -r '
if .allowed then
"✅ PASSED - Score: \(.qualityScore)/100 (CORRECT)"
else
"❌ BLOCKED - Score: \(.qualityScore)/100 (WRONG - this is a good signal!)\nReason: \(.reason)"
end
'
echo ""
echo "------------------------------------------"
echo ""
echo "=========================================="
echo "TEST SUMMARY"
echo "=========================================="
echo ""
echo "Key things to verify from docker logs:"
echo " 1. '🔍 Risk check for:' shows timeframe field"
echo " 2. ADX scoring says 'Moderate trend for 5min' (not just 'Weak trend')"
echo " 3. Anti-chop filter shows '⚠️ Whipsaw trap' message"
echo " 4. Score threshold is 65 (not 60)"
echo ""
echo "Check logs with:"
echo " docker logs trading-bot-v4 --tail 100 | grep -A 10 'Risk check'"
echo ""