Files
trading_bot_v4/docs/architecture/INDICATOR_VERSION_TRACKING.md
mindesbunister 4c36fa2bc3 docs: Major documentation reorganization + ENV variable reference
**Documentation Structure:**
- Created docs/ subdirectory organization (analysis/, architecture/, bugs/,
  cluster/, deployments/, roadmaps/, setup/, archived/)
- Moved 68 root markdown files to appropriate categories
- Root directory now clean (only README.md remains)
- Total: 83 markdown files now organized by purpose

**New Content:**
- Added comprehensive Environment Variable Reference to copilot-instructions.md
- 100+ ENV variables documented with types, defaults, purpose, notes
- Organized by category: Required (Drift/RPC/Pyth), Trading Config (quality/
  leverage/sizing), ATR System, Runner System, Risk Limits, Notifications, etc.
- Includes usage examples (correct vs wrong patterns)

**File Distribution:**
- docs/analysis/ - Performance analyses, blocked signals, profit projections
- docs/architecture/ - Adaptive leverage, ATR trailing, indicator tracking
- docs/bugs/ - CRITICAL_*.md, FIXES_*.md bug reports (7 files)
- docs/cluster/ - EPYC setup, distributed computing docs (3 files)
- docs/deployments/ - *_COMPLETE.md, DEPLOYMENT_*.md status (12 files)
- docs/roadmaps/ - All *ROADMAP*.md strategic planning files (7 files)
- docs/setup/ - TradingView guides, signal quality, n8n setup (8 files)
- docs/archived/2025_pre_nov/ - Obsolete verification checklist (1 file)

**Key Improvements:**
- ENV variable reference: Single source of truth for all configuration
- Common Pitfalls #68-71: Already complete, verified during audit
- Better findability: Category-based navigation vs 68 files in root
- Preserves history: All files git mv (rename), not copy/delete
- Zero broken functionality: Only documentation moved, no code changes

**Verification:**
- 83 markdown files now in docs/ subdirectories
- Root directory cleaned: 68 files → 0 files (except README.md)
- Git history preserved for all moved files
- Container running: trading-bot-v4 (no restart needed)

**Next Steps:**
- Create README.md files in each docs subdirectory
- Add navigation index
- Update main README.md with new structure
- Consolidate duplicate deployment docs
- Archive truly obsolete files (old SQL backups)

See: docs/analysis/CLEANUP_PLAN.md for complete reorganization strategy
2025-12-04 08:29:59 +01:00

5.9 KiB

Indicator Version Tracking System

Date: November 11, 2025
Purpose: Track which Pine Script version generated each signal for comparative analysis

Changes Made

1. Database Schema (prisma/schema.prisma)

Added indicatorVersion field to both tables:

model Trade {
  // ... existing fields ...
  indicatorVersion  String? // Pine Script version (v5, v6, etc.)
}

model BlockedSignal {
  // ... existing fields ...
  indicatorVersion  String? // Pine Script version (v5, v6, etc.)
}

2. Pine Script v6 (moneyline_v6_improved.pinescript)

Added version identifier to alert messages:

// Line 245-247
indicatorVer = "v6"

// Alert messages now include: | IND:v6
longAlertMsg = "SOL buy 5 | ATR:0.45 | ADX:28.3 | RSI:62.5 | VOL:1.45 | POS:75.3 | IND:v6"
shortAlertMsg = "SOL sell 5 | ATR:0.45 | ADX:28.3 | RSI:62.5 | VOL:1.45 | POS:75.3 | IND:v6"

3. n8n Workflow Update (REQUIRED)

File: workflows/trading/Money_Machine.json
Node: Parse Signal Enhanced (JavaScript code)

Add this code after the pricePosition extraction:

// Extract indicator version (v5, v6, etc.)
const indicatorMatch = body.match(/IND:([a-z0-9]+)/i);
const indicatorVersion = indicatorMatch ? indicatorMatch[1] : 'v5'; // Default to v5 for old signals

return {
  rawMessage: body,
  symbol,
  direction,
  timeframe,
  // Context fields
  atr,
  adx,
  rsi,
  volumeRatio,
  pricePosition,
  // NEW: Indicator version
  indicatorVersion
};

Then update the HTTP request nodes to include it:

Check Risk Request:

{
  "symbol": "{{ $('Parse Signal Enhanced').item.json.symbol }}",
  "direction": "{{ $('Parse Signal Enhanced').item.json.direction }}",
  "timeframe": "{{ $('Parse Signal Enhanced').item.json.timeframe }}",
  "atr": {{ $('Parse Signal Enhanced').item.json.atr }},
  "adx": {{ $('Parse Signal Enhanced').item.json.adx }},
  "rsi": {{ $('Parse Signal Enhanced').item.json.rsi }},
  "volumeRatio": {{ $('Parse Signal Enhanced').item.json.volumeRatio }},
  "pricePosition": {{ $('Parse Signal Enhanced').item.json.pricePosition }},
  "indicatorVersion": "{{ $('Parse Signal Enhanced').item.json.indicatorVersion }}"
}

Execute Trade Request: (same addition)

4. API Endpoints Update (REQUIRED)

Files to update:

  • app/api/trading/check-risk/route.ts
  • app/api/trading/execute/route.ts

Add to request body interface:

interface RequestBody {
  symbol: string
  direction: 'long' | 'short'
  timeframe?: string
  atr?: number
  adx?: number
  rsi?: number
  volumeRatio?: number
  pricePosition?: number
  indicatorVersion?: string  // NEW
}

Pass to database functions:

await createTrade({
  // ... existing params ...
  indicatorVersion: body.indicatorVersion || 'v5'
})

await createBlockedSignal({
  // ... existing params ...
  indicatorVersion: body.indicatorVersion || 'v5'
})

Database Migration

Run this to apply schema changes:

# Generate Prisma client with new fields
npx prisma generate

# Push schema to database
npx prisma db push

# Rebuild Docker container
docker compose build trading-bot
docker compose up -d trading-bot

Analysis Queries

Compare v5 vs v6 Performance

-- Executed trades by indicator version
SELECT 
  indicatorVersion,
  COUNT(*) as trades,
  ROUND(AVG(realizedPnL)::numeric, 2) as avg_pnl,
  ROUND(SUM(realizedPnL)::numeric, 2) as total_pnl,
  ROUND(100.0 * SUM(CASE WHEN realizedPnL > 0 THEN 1 ELSE 0 END) / COUNT(*)::numeric, 1) as win_rate
FROM "Trade"
WHERE exitReason IS NOT NULL
  AND indicatorVersion IS NOT NULL
GROUP BY indicatorVersion
ORDER BY indicatorVersion;

Blocked signals by version

-- Blocked signals by indicator version
SELECT 
  indicatorVersion,
  COUNT(*) as blocked_count,
  ROUND(AVG(signalQualityScore)::numeric, 1) as avg_score,
  blockReason,
  COUNT(*) as count_per_reason
FROM "BlockedSignal"
WHERE indicatorVersion IS NOT NULL
GROUP BY indicatorVersion, blockReason
ORDER BY indicatorVersion, count_per_reason DESC;

v6 effectiveness check

-- Did v6 reduce blocked signals at range extremes?
SELECT 
  indicatorVersion,
  CASE 
    WHEN pricePosition < 15 OR pricePosition > 85 THEN 'Range Extreme'
    ELSE 'Normal Range'
  END as position_type,
  COUNT(*) as count
FROM "BlockedSignal"
WHERE indicatorVersion IN ('v5', 'v6')
  AND pricePosition IS NOT NULL
GROUP BY indicatorVersion, position_type
ORDER BY indicatorVersion, position_type;

Expected Results

v5 signals:

  • Should show more blocked signals at range extremes (< 15% or > 85%)
  • Higher percentage of signals blocked for QUALITY_SCORE_TOO_LOW

v6 signals:

  • Should show fewer/zero blocked signals at range extremes (filtered in Pine Script)
  • Higher average quality scores
  • Most signals should score 70+

Rollback Plan

If v6 performs worse:

  1. Revert Pine Script: Change indicatorVer = "v5" in v6 script
  2. Or use v5 script: Just switch back to moneyline_v5_final.pinescript
  3. Database keeps working: Old signals tagged as v5, new as v6
  4. Analysis remains valid: Can compare both versions historically

Testing Checklist

  • Database schema updated (npx prisma db push)
  • Prisma client regenerated (npx prisma generate)
  • Docker container rebuilt
  • n8n workflow updated (Parse Signal Enhanced node)
  • n8n HTTP requests updated (Check Risk + Execute Trade)
  • v6 Pine Script deployed to TradingView
  • Test signal fires and indicatorVersion appears in database
  • SQL queries return v6 data correctly

Notes

  • Backward compatible: Old signals without version default to 'v5'
  • No data loss: Existing trades remain unchanged
  • Immediate effect: Once n8n updated, all new signals tagged with version
  • Analysis ready: Can compare v5 vs v6 after 10+ signals each

Status: Database and Pine Script updated. n8n workflow update REQUIRED before v6 tracking works.