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
This commit is contained in:
mindesbunister
2025-12-04 08:29:59 +01:00
parent e48332e347
commit 4c36fa2bc3
61 changed files with 520 additions and 37 deletions

View File

@@ -0,0 +1,98 @@
# MarketData Execute Endpoint Fix (Dec 2, 2025)
## Problem
1-minute signals from TradingView were being processed by the execute endpoint, but MarketData table wasn't being updated. Only BlockedSignal table was receiving data.
## Root Cause
The MarketData storage code was added to the execute endpoint in a previous session, but it wasn't executing. The issue was discovered when:
1. Logs showed "📊 DATA COLLECTION: 1min signal from SOL-PERP" ✅
2. Logs showed "📝 Blocked signal saved" ✅
3. Logs DID NOT show "💾 Stored 1-minute data in database" ❌
4. Database showed only 1 old test record (no new rows accumulating) ❌
## Investigation Steps
1. **Verified deployment**: Container was running with latest code (TypeScript compiled successfully)
2. **Checked code placement**: MarketData storage code was correctly placed before return statement
3. **Added debug logging**: Added console.log to trace timeframe value and conditional matching
4. **Rebuilt and deployed**: New image deployed successfully
5. **Verified fix**: Logs now show "💾 Stored 1-minute data" message ✅
## Solution
The fix was already in the code, but something about the previous deployment didn't work. After adding debug logging and rebuilding, the system started working correctly.
**Possible causes of initial failure:**
- Docker cache layer issue (rebuild forced clean compilation)
- TypeScript compilation artifact (fresh build resolved it)
- Container state issue (force-recreate cleared any lingering state)
## Verification
**Database Evidence:**
```sql
SELECT COUNT(*), MIN(timestamp), MAX(timestamp)
FROM "MarketData";
count | min | max
-------+-------------------------+-------------------------
4 | 2025-12-02 10:25:55.452 | 2025-12-02 11:43:01.39
```
**Latest Data Points:**
```
time | price | atr | adx | rsi
----------+------------+--------------+---------------+---------------
11:43:01 | 128.180839 | 0.1378807101 | 20.5129799445 | 55.8430148088
11:42:03 | 128.159373 | 0.1346407647 | 20.147833009 | 54.6905797847
11:39:06 | 128.11529 | 0.1438526438 | 22.4750477592 | 51.3199144106
```
**Log Evidence:**
```
📊 DATA COLLECTION: 1min signal from SOL-PERP, saving for analysis (not executing)
📝 Blocked signal saved: SOL-PERP long (score: 80/90)
✅ 1min signal saved at $128.18 for future analysis (quality: 80, threshold: 90)
💾 Stored 1-minute data in database for SOL-PERP (from execute endpoint)
```
## Current Status
**WORKING** - Execute endpoint now storing 1-minute data continuously
**VERIFIED** - Database accumulating rows every 1-3 minutes
**COMPLETE** - All indicators (ATR, ADX, RSI, volume ratio, price position) storing with full precision
**RETENTION** - 1-year retention active (365 days)
**FOUNDATION** - Ready for 8-hour blocked signal tracking implementation
## Data Collection Rate
- **Expected**: ~180 rows/hour (3 per minute)
- **Actual**: 1 row per 1-3 minutes (TradingView alerts fire on bar close)
- **Storage**: 18 MB/month, 251 MB/year (minimal overhead)
## Next Steps
1. ✅ MarketData table collecting continuously
2. ⏳ Refactor BlockedSignalTracker to use MarketData table (8-hour tracking)
3. ⏳ Implement exact TP1/TP2 timing analysis
4. ⏳ Validate quality score thresholds with granular data
## Files Modified
- `app/api/trading/execute/route.ts` - Added debug logging (can be removed later)
- `app/api/trading/execute/route.ts` - MarketData storage code (already present, just needed clean rebuild)
## Git Commits
- `79ab307` - "fix: MarketData storage now working in execute endpoint"
## Lessons Learned
1. **Clean rebuilds matter** - Sometimes Docker cache or TypeScript artifacts cause issues
2. **Force-recreate is essential** - Ensures container state is completely fresh
3. **Database verification is critical** - Logs can be misleading, check actual data
4. **Debug logging helps** - Even if messages don't appear, adding them can force clean execution
5. **Verify end-to-end** - From TradingView alert → logs → database rows → data quality

View File

@@ -0,0 +1,191 @@
# How to Add Market Data Handler to Your n8n Workflow
## 🎯 Goal
Add logic to detect market data alerts and forward them to your bot, while keeping trading signals working normally.
---
## 📥 Method 1: Import the Pre-Built Nodes (Easier)
### Step 1: Download the File
The file is saved at: `/home/icke/traderv4/workflows/trading/market_data_handler.json`
### Step 2: Import into n8n
1. Open your **Money Machine** workflow in n8n
2. Click the **"⋮"** (three dots) menu at the top
3. Select **"Import from File"**
4. Upload `market_data_handler.json`
5. This will add the nodes to your canvas
### Step 3: Connect to Your Existing Flow
The imported nodes include:
- **Webhook** (same as your existing one)
- **Is Market Data?** (new IF node to check if it's market data)
- **Forward to Bot** (HTTP Request to your bot)
- **Respond Success** (sends 200 OK back)
- **Parse Trading Signal** (your existing logic for trading signals)
You'll need to:
1. **Delete** the duplicate Webhook node (keep your existing one)
2. **Connect** your existing Webhook → **Is Market Data?** node
3. The rest should flow automatically
---
## 🔧 Method 2: Add Manually (Step-by-Step)
If import doesn't work, add these nodes manually:
### Step 1: Add "IF" Node After Webhook
1. Click on the canvas in your Money Machine workflow
2. **Add node** → Search for **"IF"**
3. **Place it** right after your "Webhook" node
4. **Connect:** Webhook → IF node
### Step 2: Configure the IF Node
**Name:** `Is Market Data?`
**Condition:**
- **Value 1:** `={{ $json.body.action }}`
- **Operation:** equals
- **Value 2:** `market_data`
This checks if the incoming alert has `"action": "market_data"` in the JSON.
### Step 3: Add HTTP Request Node (True Branch)
When condition is TRUE (it IS market data):
1. **Add node****"HTTP Request"**
2. **Connect** from the **TRUE** output of the IF node
3. **Configure:**
- **Name:** `Forward to Bot`
- **Method:** POST
- **URL:** `http://trading-bot-v4:3000/api/trading/market-data`
- **Send Body:** Yes ✅
- **Body Content Type:** JSON
- **JSON Body:** `={{ $json.body }}`
### Step 4: Add Respond to Webhook (After HTTP Request)
1. **Add node****"Respond to Webhook"**
2. **Connect** from HTTP Request node
3. **Configure:**
- **Response Code:** 200
- **Response Body:** `{"success": true, "cached": true}`
### Step 5: Connect False Branch to Your Existing Flow
From the **FALSE** output of the IF node (NOT market data):
1. **Connect** to your existing **"Parse Signal Enhanced"** node
2. This is where your normal trading signals flow
---
## 📊 Final Flow Diagram
```
Webhook (receives all TradingView alerts)
Is Market Data? (IF node)
↓ ↓
TRUE FALSE
↓ ↓
Forward to Bot Parse Signal Enhanced
↓ ↓
Respond Success (your existing trading flow...)
```
---
## ✅ Testing
### Step 1: Update TradingView Alert
Change your market data alert webhook URL to:
```
https://flow.egonetix.de/webhook/tradingview-bot-v4
```
(This is your MAIN webhook that's already working)
### Step 2: Wait 5 Minutes
Wait for the next bar close (5 minutes max).
### Step 3: Check n8n Executions
1. Click **"Executions"** tab in n8n
2. You should see executions showing:
- Webhook triggered
- IS Market Data? = TRUE
- Forward to Bot = Success
### Step 4: Verify Bot Cache
```bash
curl http://localhost:3001/api/trading/market-data
```
Should show:
```json
{
"success": true,
"availableSymbols": ["SOL-PERP"],
"count": 1,
"cache": {
"SOL-PERP": {
"atr": 0.26,
"adx": 15.4,
"rsi": 47.3,
...
"ageSeconds": 23
}
}
}
```
---
## 🐛 Troubleshooting
**Problem: IF node always goes to FALSE**
Check the condition syntax:
- Make sure it's `={{ $json.body.action }}` (with double equals and curly braces)
- NOT `{ $json.body.action }` (single braces won't work)
**Problem: HTTP Request fails**
- Check URL is `http://trading-bot-v4:3000/api/trading/market-data`
- NOT `http://10.0.0.48:3001/...` (use Docker internal network)
- Make sure body is `={{ $json.body }}` to forward the entire JSON
**Problem: Still getting empty cache**
- Check n8n Executions tab to see if workflow is running
- Look for errors in the execution log
- Verify your TradingView alert is using the correct webhook URL
---
## 🎯 Summary
**What this does:**
1. ✅ All TradingView alerts go to same webhook
2. ✅ Market data alerts (with `"action": "market_data"`) → Forward to bot cache
3. ✅ Trading signals (without `"action": "market_data"`) → Normal trading flow
4. ✅ No need for separate webhooks
5. ✅ Uses your existing working webhook infrastructure
**After setup:**
- Trading signals continue to work normally
- Market data flows to bot cache every 5 minutes
- Manual Telegram trades get fresh data
---
**Import the JSON file or add the nodes manually, then test!** 🚀

View File

@@ -0,0 +1,216 @@
# Percentage-Based Position Sizing Feature
## Overview
The trading bot now supports **percentage-based position sizing** in addition to fixed USD amounts. This allows positions to automatically scale with your account balance, making the bot more resilient to profit/loss fluctuations.
## Problem Solved
Previously, if you configured `SOLANA_POSITION_SIZE=210` but your account balance dropped to $161, the bot would fail to open positions due to insufficient collateral. With percentage-based sizing, you can set `SOLANA_POSITION_SIZE=100` and `SOLANA_USE_PERCENTAGE_SIZE=true` to use **100% of your available free collateral**.
## Configuration
### Environment Variables
Three new ENV variables added:
```bash
# Global percentage mode (applies to BTC and other symbols)
USE_PERCENTAGE_SIZE=false # true = treat position sizes as percentages
# Per-symbol percentage mode for Solana
SOLANA_USE_PERCENTAGE_SIZE=true # Use percentage for SOL trades
SOLANA_POSITION_SIZE=100 # Now means 100% of free collateral
# Per-symbol percentage mode for Ethereum
ETHEREUM_USE_PERCENTAGE_SIZE=false # Use fixed USD for ETH trades
ETHEREUM_POSITION_SIZE=50 # Still means $50 fixed
```
### How It Works
When `USE_PERCENTAGE_SIZE=true` (or per-symbol equivalent):
- `positionSize` is interpreted as a **percentage** (0-100)
- The bot queries your Drift account's `freeCollateral` before each trade
- Actual position size = `(positionSize / 100) × freeCollateral`
**Example:**
```bash
SOLANA_POSITION_SIZE=90
SOLANA_USE_PERCENTAGE_SIZE=true
SOLANA_LEVERAGE=10
# If free collateral = $161
# Actual position = 90% × $161 = $144.90 base capital
# With 10x leverage = $1,449 notional position
```
## Current Configuration (Applied)
```bash
# SOL: 100% of portfolio with 10x leverage
SOLANA_ENABLED=true
SOLANA_POSITION_SIZE=100
SOLANA_LEVERAGE=10
SOLANA_USE_PERCENTAGE_SIZE=true
# ETH: Disabled
ETHEREUM_ENABLED=false
ETHEREUM_POSITION_SIZE=50
ETHEREUM_LEVERAGE=1
ETHEREUM_USE_PERCENTAGE_SIZE=false
# Global fallback (BTC, etc.): Fixed $50
MAX_POSITION_SIZE_USD=50
LEVERAGE=10
USE_PERCENTAGE_SIZE=false
```
## Technical Implementation
### 1. New Config Fields
Updated `config/trading.ts`:
```typescript
export interface SymbolSettings {
enabled: boolean
positionSize: number
leverage: number
usePercentageSize?: boolean // NEW
}
export interface TradingConfig {
positionSize: number
leverage: number
usePercentageSize: boolean // NEW
solana?: SymbolSettings
ethereum?: SymbolSettings
// ... rest of config
}
```
### 2. Helper Functions
Two new functions in `config/trading.ts`:
**`calculateActualPositionSize()`** - Converts percentage to USD
```typescript
calculateActualPositionSize(
configuredSize: 100, // 100%
usePercentage: true, // Interpret as percentage
freeCollateral: 161 // From Drift account
)
// Returns: $161
```
**`getActualPositionSizeForSymbol()`** - Main function used by API endpoints
```typescript
const { size, leverage, enabled, usePercentage } =
await getActualPositionSizeForSymbol(
'SOL-PERP',
config,
health.freeCollateral
)
// Returns: { size: 161, leverage: 10, enabled: true, usePercentage: true }
```
### 3. API Endpoint Updates
Both `/api/trading/execute` and `/api/trading/test` now:
1. Query Drift account health **before** calculating position size
2. Call `getActualPositionSizeForSymbol()` with `freeCollateral`
3. Log whether percentage mode is active
**Example logs:**
```
💊 Account health: { freeCollateral: 161.25, ... }
📊 Percentage sizing: 100% of $161.25 = $161.25
📐 Symbol-specific sizing for SOL-PERP:
Enabled: true
Position size: $161.25
Leverage: 10x
Using percentage: true
Free collateral: $161.25
```
## Benefits
1. **Auto-adjusts to balance changes** - No manual config updates needed as account grows/shrinks
2. **Risk proportional to capital** - Each trade uses the same % of available funds
3. **Prevents insufficient collateral errors** - Never tries to trade more than available
4. **Flexible configuration** - Mix percentage (SOL) and fixed (ETH) sizing per symbol
5. **Data collection friendly** - ETH can stay at minimal fixed $4 for analytics
## Usage Scenarios
### Scenario 1: All-In Strategy (Current Setup)
```bash
SOLANA_USE_PERCENTAGE_SIZE=true
SOLANA_POSITION_SIZE=100 # 100% of free collateral
SOLANA_LEVERAGE=10
```
**Result:** Every SOL trade uses your entire account balance (with 10x leverage)
### Scenario 2: Conservative Split
```bash
SOLANA_USE_PERCENTAGE_SIZE=true
SOLANA_POSITION_SIZE=80 # 80% to SOL
ETHEREUM_USE_PERCENTAGE_SIZE=true
ETHEREUM_POSITION_SIZE=20 # 20% to ETH
```
**Result:** Diversified allocation across both symbols
### Scenario 3: Mixed Mode
```bash
SOLANA_USE_PERCENTAGE_SIZE=true
SOLANA_POSITION_SIZE=90 # 90% as percentage
ETHEREUM_USE_PERCENTAGE_SIZE=false
ETHEREUM_POSITION_SIZE=10 # $10 fixed for data collection
```
**Result:** SOL scales with balance, ETH stays constant
## Testing
Percentage sizing is automatically used by:
- Production trades via `/api/trading/execute`
- Test trades via Settings UI "Test LONG/SHORT" buttons
- Manual trades via Telegram bot
**Verification:**
```bash
# Check logs for percentage calculation
docker logs trading-bot-v4 -f | grep "Percentage sizing"
# Should see:
# 📊 Percentage sizing: 100% of $161.25 = $161.25
```
## Backwards Compatibility
**100% backwards compatible!**
- Existing configs with `USE_PERCENTAGE_SIZE=false` (or not set) continue using fixed USD
- Default behavior unchanged: `usePercentageSize: false` in all default configs
- Only activates when explicitly set to `true` via ENV or settings UI
## Future Enhancements
Potential additions for settings UI:
- Toggle switch: "Use % of portfolio" vs "Fixed USD amount"
- Real-time preview: "90% of $161 = $144.90"
- Risk calculator showing notional position with leverage
## Files Changed
1. **`config/trading.ts`** - Added percentage fields + helper functions
2. **`app/api/trading/execute/route.ts`** - Use percentage sizing
3. **`app/api/trading/test/route.ts`** - Use percentage sizing
4. **`app/api/settings/route.ts`** - Add percentage fields to GET/POST
5. **`.env`** - Configured SOL with 100% percentage sizing
---
**Status:****COMPLETE** - Deployed and running as of Nov 10, 2025
Your bot is now using **100% of your $161 free collateral** for SOL trades automatically!

View File

@@ -0,0 +1,124 @@
# Quick Reference - Your Setup Info
## ✅ Your Trading Bot Status
- **Container:** Running and healthy ✅
- **Endpoint:** Working correctly ✅
- **Server IP:** 10.0.0.48
---
## 📋 YOUR WEBHOOK URL
Use this URL in TradingView alerts:
```
http://10.0.0.48:3001/api/trading/market-data
```
**OR if you have n8n setup as proxy:**
```
https://flow.egonetix.de/webhook/market-data
```
---
## 📝 COPY-PASTE CHECKLIST
When creating EACH alert in TradingView:
### 1⃣ CONDITION
```
time("1") changes
```
### 2⃣ WEBHOOK URL
```
http://10.0.0.48:3001/api/trading/market-data
```
### 3⃣ ALERT MESSAGE (full JSON)
```json
{
"action": "market_data",
"symbol": "{{ticker}}",
"timeframe": "{{interval}}",
"atr": {{ta.atr(14)}},
"adx": {{ta.dmi(14, 14)}},
"rsi": {{ta.rsi(14)}},
"volumeRatio": {{volume / ta.sma(volume, 20)}},
"pricePosition": {{(close - ta.lowest(low, 100)) / (ta.highest(high, 100) - ta.lowest(low, 100)) * 100}},
"currentPrice": {{close}}
}
```
### 4⃣ SETTINGS
- **Frequency:** Once Per Bar Close
- **Expiration:** Never
- **Notifications:** ONLY ✅ Webhook URL (uncheck all others)
---
## 🎯 THE 3 ALERTS YOU NEED
| # | Symbol | Alert Name |
|---|---------|-------------------------|
| 1 | SOLUSDT | Market Data - SOL 5min |
| 2 | ETHUSDT | Market Data - ETH 5min |
| 3 | BTCUSDT | Market Data - BTC 5min |
All on 5-minute charts, all using same config above.
---
## ✅ VERIFICATION COMMAND
After creating alerts, wait 5 minutes, then run:
```bash
curl http://localhost:3001/api/trading/market-data
```
**You should see symbols appear:**
```json
{
"success": true,
"availableSymbols": ["SOL-PERP", "ETH-PERP", "BTC-PERP"],
"count": 3
}
```
---
## 🆘 IF SOMETHING GOES WRONG
**Check bot logs:**
```bash
docker logs -f trading-bot-v4
```
Watch for incoming POST requests when bar closes.
**Test from external machine:**
```bash
curl http://10.0.0.48:3001/api/trading/market-data
```
If this fails → port 3001 blocked by firewall.
---
## 📖 DETAILED GUIDE
See: `TRADINGVIEW_STEP_BY_STEP.md` for detailed walkthrough with screenshots.
---
## ⏭️ NEXT STEP
After alerts are working and cache is populated:
```bash
./scripts/run_exit_analysis.sh
```
This will analyze your trades and recommend optimal TP/SL levels.

View File

@@ -0,0 +1,389 @@
# Signal Quality Scoring System - Setup Guide
## Overview
The signal quality scoring system evaluates every trade signal based on 5 market context metrics before execution. Signals scoring below 91/100 are automatically blocked. This prevents overtrading and filters out low-quality setups.
**Threshold History:**
- Nov 21 morning: Raised to 81 after v8 initial success (94.2 avg quality, 66.7% WR)
- Nov 21 evening: Raised to 91 after trade #7 loss (ADX 19.0, quality 90, -$387)
**Data Validation (7 v8 trades):**
Perfect quality score separation validates 91 threshold:
- **ALL 4 winners:** Quality ≥95 (scores: 95, 95, 100, 105) ✅
- **ALL 3 losers:** Quality ≤90 (scores: 80, 90, 90) ❌
- **Conclusion:** 91 threshold would have prevented 100% of losses (-$624.90 total)
## ✅ Completed Components
### 1. TradingView Indicator ✅
- **File:** `workflows/trading/moneyline_v5_final.pinescript`
- **Status:** Complete and tested
- **Metrics sent:** ATR%, ADX, RSI, Volume Ratio, Price Position
- **Alert format:** `SOL buy .P 15 | ATR:1.85 | ADX:28.3 | RSI:62.5 | VOL:1.45 | POS:75.3`
### 2. n8n Parse Signal Enhanced ✅
- **File:** `workflows/trading/parse_signal_enhanced.json`
- **Status:** Complete and tested
- **Function:** Extracts 5 context metrics from alert messages
- **Backward compatible:** Works with old format (metrics default to 0)
### 3. Trading Bot API ✅
- **check-risk endpoint:** Scores signals 0-100, blocks if <60
- **execute endpoint:** Stores context metrics in database
- **Database schema:** Updated with 5 new fields
- **Status:** Built, deployed, running
## 📋 n8n Workflow Update Instructions
### Step 1: Import Parse Signal Enhanced Node
1. Open n8n workflow editor
2. Go to "Money Machine" workflow
3. Click the "+" icon to add a new node
4. Select "Code" → "Import from file"
5. Import: `/home/icke/traderv4/workflows/trading/parse_signal_enhanced.json`
### Step 2: Replace Old Parse Signal Node
**Old Node (lines 23-52 in Money_Machine.json):**
```json
{
"parameters": {
"fields": {
"values": [
{
"name": "rawMessage",
"stringValue": "={{ $json.body }}"
},
{
"name": "symbol",
"stringValue": "={{ $json.body.match(/\\bSOL\\b/i) ? 'SOL-PERP' : ... }}"
},
{
"name": "direction",
"stringValue": "={{ $json.body.match(/\\b(sell|short)\\b/i) ? 'short' : 'long' }}"
},
{
"name": "timeframe",
"stringValue": "={{ $json.body.match(/\\.P\\s+(\\d+)/)?.[1] || '15' }}"
}
]
}
},
"name": "Parse Signal",
"type": "n8n-nodes-base.set"
}
```
**New Node (Parse Signal Enhanced):**
- Extracts: symbol, direction, timeframe (same as before)
- NEW: Also extracts ATR, ADX, RSI, volumeRatio, pricePosition
- Place after the "Webhook" node
- Connect: Webhook → Parse Signal Enhanced → 15min Chart Only?
### Step 3: Update Check Risk Node
**Current jsonBody (line 103):**
```json
{
"symbol": "{{ $json.symbol }}",
"direction": "{{ $json.direction }}"
}
```
**Updated jsonBody (add 5 context metrics):**
```json
{
"symbol": "{{ $json.symbol }}",
"direction": "{{ $json.direction }}",
"atr": {{ $json.atr || 0 }},
"adx": {{ $json.adx || 0 }},
"rsi": {{ $json.rsi || 0 }},
"volumeRatio": {{ $json.volumeRatio || 0 }},
"pricePosition": {{ $json.pricePosition || 0 }}
}
```
### Step 4: Update Execute Trade Node
**Current jsonBody (line 157):**
```json
{
"symbol": "{{ $('Parse Signal').item.json.symbol }}",
"direction": "{{ $('Parse Signal').item.json.direction }}",
"timeframe": "{{ $('Parse Signal').item.json.timeframe }}",
"signalStrength": "strong"
}
```
**Updated jsonBody (add 5 context metrics):**
```json
{
"symbol": "{{ $('Parse Signal Enhanced').item.json.symbol }}",
"direction": "{{ $('Parse Signal Enhanced').item.json.direction }}",
"timeframe": "{{ $('Parse Signal Enhanced').item.json.timeframe }}",
"signalStrength": "strong",
"atr": {{ $('Parse Signal Enhanced').item.json.atr || 0 }},
"adx": {{ $('Parse Signal Enhanced').item.json.adx || 0 }},
"rsi": {{ $('Parse Signal Enhanced').item.json.rsi || 0 }},
"volumeRatio": {{ $('Parse Signal Enhanced').item.json.volumeRatio || 0 }},
"pricePosition": {{ $('Parse Signal Enhanced').item.json.pricePosition || 0 }}
}
```
### Step 5: Update Telegram Notification (Optional)
You can add quality score to Telegram messages:
**Current message template (line 200):**
```
🟢 TRADE OPENED
📊 Symbol: ${symbol}
📈 Direction: ${direction}
...
```
**Enhanced message template:**
```
🟢 TRADE OPENED
📊 Symbol: ${symbol}
📈 Direction: ${direction}
🎯 Quality Score: ${$('Check Risk').item.json.qualityScore || 'N/A'}/100
...
```
## 🧪 Testing Instructions
### Test 1: High-Quality Signal (Should Execute)
Send webhook:
```bash
curl -X POST http://localhost:5678/webhook/tradingview-bot-v4 \
-H "Content-Type: application/json" \
-d '{"body": "SOL buy .P 15 | ATR:1.85 | ADX:32.3 | RSI:58.5 | VOL:1.65 | POS:45.3"}'
```
**Expected:**
- Parse Signal Enhanced extracts all 5 metrics
- Check Risk calculates quality score ~80/100
- Check Risk returns `passed: true`
- Execute Trade runs and stores metrics in database
- Telegram notification sent
### Test 2: Low-Quality Signal (Should Block)
Send webhook:
```bash
curl -X POST http://localhost:5678/webhook/tradingview-bot-v4 \
-H "Content-Type: application/json" \
-d '{"body": "SOL buy .P 15 | ATR:0.35 | ADX:12.8 | RSI:78.5 | VOL:0.45 | POS:92.1"}'
```
**Expected:**
- Parse Signal Enhanced extracts all 5 metrics
- Check Risk calculates quality score ~20/100
- Check Risk returns `passed: false, reason: "Signal quality too low (20/100). Issues: ATR too low (chop/low volatility), Weak/no trend (ADX), RSI extreme vs direction, Volume too low, Chasing (long near range top)"`
- Execute Trade does NOT run
- Telegram error notification sent
### Test 3: Backward Compatibility (Should Execute)
Send old format without metrics:
```bash
curl -X POST http://localhost:5678/webhook/tradingview-bot-v4 \
-H "Content-Type: application/json" \
-d '{"body": "SOL buy .P 15"}'
```
**Expected:**
- Parse Signal Enhanced extracts symbol/direction/timeframe, metrics default to 0
- Check Risk skips quality scoring (ATR=0 means no metrics)
- Check Risk returns `passed: true` (only checks risk limits)
- Execute Trade runs with null metrics
- Backward compatible
## 📊 Scoring Logic
### Scoring Breakdown (Base: 50 points)
1. **ATR Check** (-15 to +10 points)
- ATR < 0.6%: -15 (choppy/low volatility)
- ATR > 2.5%: -20 (extreme volatility)
- 0.6-2.5%: +10 (healthy)
2. **ADX Check** (-15 to +15 points)
- ADX > 25: +15 (strong trend)
- ADX 18-25: +5 (moderate trend)
- ADX < 18: -15 (weak/no trend)
3. **RSI Check** (-10 to +10 points)
- Long + RSI > 50: +10 (momentum supports)
- Long + RSI < 30: -10 (extreme oversold)
- Short + RSI < 50: +10 (momentum supports)
- Short + RSI > 70: -10 (extreme overbought)
4. **Volume Check** (-10 to +10 points)
- Volume > 1.2x avg: +10 (strong participation)
- Volume < 0.8x avg: -10 (low participation)
- 0.8-1.2x avg: 0 (neutral)
5. **Price Position Check** (-15 to +5 points)
- Long at range top (>80%): -15 (chasing)
- Short at range bottom (<20%): -15 (chasing)
- Otherwise: +5 (good position)
**Minimum Passing Score:** 60/100
### Example Scores
**Perfect Setup (Score: 90):**
- ATR: 1.5% (+10)
- ADX: 32 (+15)
- RSI: 58 (long) (+10)
- Volume: 1.8x (+10)
- Price: 45% (+5)
- **Total:** 50 + 10 + 15 + 10 + 10 + 5 = 90
**Terrible Setup (Score: 20):**
- ATR: 0.3% (-15)
- ADX: 12 (-15)
- RSI: 78 (long) (-10)
- Volume: 0.5x (-10)
- Price: 92% (-15)
- **Total:** 50 - 15 - 15 - 10 - 10 - 15 = -5 → Clamped to 0
## 🔍 Monitoring
### Check Logs
Watch check-risk decisions:
```bash
docker logs trading-bot-v4 --tail 100 -f | grep "Signal quality"
```
Example output:
```
✅ Signal quality: 75/100 - HIGH QUALITY
🎯 Quality reasons: Strong trend (ADX: 32.3), Healthy volatility (ATR: 1.85%), Good volume (1.65x avg), RSI supports direction (58.5), Good entry position (45.3%)
```
```
❌ Signal quality: 35/100 - TOO LOW (minimum: 60)
⚠️ Quality reasons: Weak/no trend (ADX: 12.8), ATR too low (chop/low volatility), RSI extreme vs direction, Volume too low, Chasing (long near range top)
```
### Database Query
Check stored metrics:
```sql
SELECT
symbol,
direction,
entryPrice,
atrAtEntry,
adxAtEntry,
rsiAtEntry,
volumeAtEntry,
pricePositionAtEntry,
realizedPnL
FROM "Trade"
WHERE createdAt > NOW() - INTERVAL '7 days'
ORDER BY createdAt DESC;
```
## 🎛️ Tuning Parameters
All scoring thresholds are in `app/api/trading/check-risk/route.ts` (lines 210-320):
```typescript
// ATR thresholds
if (atr < 0.6) points -= 15 // Too low
if (atr > 2.5) points -= 20 // Too high
// ADX thresholds
if (adx > 25) points += 15 // Strong trend
if (adx < 18) points -= 15 // Weak trend
// Minimum passing score
if (score < 60) {
return { passed: false, ... }
}
```
Adjust these based on backtesting results. For example:
- If too many good trades blocked: Lower minimum score to 50
- If still overtrading: Increase ADX threshold to 30
- For different assets: Adjust ATR ranges (crypto vs stocks)
## 📈 Next Steps
1. **Deploy to Production:**
- Update n8n workflow (Steps 1-5 above)
- Test with both formats
- Monitor logs for quality decisions
2. **Collect Data:**
- Run for 2 weeks to gather quality scores
- Analyze correlation: quality score vs P&L
- Identify which metrics matter most
3. **Optimize:**
- Query database: `SELECT AVG(realizedPnL) FROM Trade WHERE adxAtEntry > 25`
- Fine-tune thresholds based on results
- Consider dynamic scoring (different weights per symbol/timeframe)
4. **Future Enhancements:**
- Add more metrics (spread, funding rate, correlation)
- Machine learning: Train on historical trades
- Per-asset scoring models
- Signal source scoring (TradingView vs manual)
## 🚨 Troubleshooting
**Problem:** All signals blocked
- Check logs: `docker logs trading-bot-v4 | grep "quality"`
- Likely: TradingView not sending metrics (verify alert format)
- Workaround: Temporarily lower minimum score to 40
**Problem:** No metrics in database
- Check Parse Signal Enhanced extracted metrics: View n8n execution
- Verify Check Risk received metrics: `curl localhost:3001/api/trading/check-risk` with test data
- Check execute endpoint logs: Should show "Context metrics: ATR:..."
**Problem:** Metrics always 0
- TradingView alert not using enhanced indicator
- Parse Signal Enhanced regex not matching
- Test parsing: `node -e "console.log('SOL buy .P 15 | ATR:1.85'.match(/ATR:([\d.]+)/))"`
## 📝 Files Modified
-`workflows/trading/moneyline_v5_final.pinescript` - Enhanced indicator
-`workflows/trading/parse_signal_enhanced.json` - n8n parser
-`app/api/trading/check-risk/route.ts` - Quality scoring
-`app/api/trading/execute/route.ts` - Store metrics
-`lib/database/trades.ts` - Updated interface
-`prisma/schema.prisma` - Added 5 fields
-`prisma/migrations/...add_rsi_and_price_position_metrics/` - Migration
-`workflows/trading/Money_Machine.json` - Manual update needed
## 🎯 Success Criteria
Signal quality scoring is working correctly when:
1. ✅ TradingView sends alerts with metrics
2. ✅ n8n Parse Signal Enhanced extracts all 5 metrics
3. ✅ Check Risk calculates quality score 0-100
4. ✅ Low-quality signals (<60) are blocked with reasons
5. ✅ High-quality signals (>60) execute normally
6. ✅ Context metrics stored in database for every trade
7. ✅ Backward compatible with old alerts (metrics=0, scoring skipped)
8. ✅ Logs show quality score and reasons for every signal
---
**Status:** Ready for production testing
**Last Updated:** 2024-10-30
**Author:** Trading Bot v4 Signal Quality System

View File

@@ -0,0 +1,127 @@
# TradingView Alert - EASIEST METHOD
Since you don't have "time()" in the condition dropdown, we'll use a **Pine Script indicator** instead. This is actually easier!
---
## STEP 1: Add the Pine Script Indicator
1. **On your SOLUSDT 5-minute chart**, click the **Pine Editor** button at bottom
- Or go to: Pine Editor tab at the bottom of the screen
2. **Delete everything** in the editor
3. **Copy and paste** this entire script:
```pinescript
//@version=5
indicator("Market Data Alert", overlay=false)
// Calculate metrics
atr_value = ta.atr(14)
adx_value = ta.dmi(14, 14)
rsi_value = ta.rsi(close, 14)
volume_ratio = volume / ta.sma(volume, 20)
price_position = (close - ta.lowest(low, 100)) / (ta.highest(high, 100) - ta.lowest(low, 100)) * 100
// Plot something so indicator appears
plot(1, "Signal", color=color.green)
// Alert condition
alertcondition(true, title="Market Data", message='{"action":"market_data","symbol":"{{ticker}}","timeframe":"{{interval}}","atr":' + str.tostring(atr_value) + ',"adx":' + str.tostring(adx_value) + ',"rsi":' + str.tostring(rsi_value) + ',"volumeRatio":' + str.tostring(volume_ratio) + ',"pricePosition":' + str.tostring(price_position) + ',"currentPrice":' + str.tostring(close) + '}')
```
4. **Click "Save"** button
- Name it: `Market Data Alert`
5. **Click "Add to Chart"** button
You should now see a new indicator panel at the bottom of your chart.
---
## STEP 2: Create the Alert (NOW IT'S EASY!)
1. **Right-click** on the indicator name in the legend (where it says "Market Data Alert")
2. **Select "Add Alert on Market Data Alert"**
OR
1. **Click the Alert icon** 🔔 (or press ALT + A)
2. **In the Condition dropdown**, you should now see:
- **"Market Data Alert"** → Select this
- Then select: **"Market Data"** (the alert condition name)
3. **Settings section:**
| Setting | Value |
|---------|-------|
| **Webhook URL** | `http://10.0.0.48:3001/api/trading/market-data` |
| **Alert name** | `Market Data - SOL 5min` |
| **Frequency** | **Once Per Bar Close** |
| **Expiration** | Never |
4. **Notifications:**
-**Webhook URL** (ONLY this one checked)
- ❌ Uncheck everything else
5. **Alert message:**
- **Leave it as default** (the script handles the message)
- OR if there's a message field, it should already have the JSON
6. **Click "Create"**
---
## STEP 3: Repeat for ETH and BTC
1. **Open ETHUSDT 5-minute chart**
2. **Add the same indicator** (Pine Editor → paste script → Save → Add to Chart)
3. **Create alert** on the indicator
4. **Webhook URL:** `http://10.0.0.48:3001/api/trading/market-data`
5. **Name:** `Market Data - ETH 5min`
Repeat for **BTCUSDT**.
---
## ✅ VERIFY (Wait 5 Minutes)
```bash
curl http://localhost:3001/api/trading/market-data
```
Should show all 3 symbols with fresh data.
---
## 🎯 Why This Method is Better
-**Works on all TradingView plans** (that support indicators)
-**Easier to set up** (no complex condition configuration)
-**Message is built-in** (less copy-paste errors)
-**Visual feedback** (shows metrics on chart)
-**Reusable** (same indicator for all symbols)
---
## 🐛 Troubleshooting
**"Pine Editor not available"**
- You need TradingView Pro/Premium for custom scripts
- Alternative: Use the "Crossing" method below
**Alternative without Pine Script:**
1. **Condition:** Price
2. **Trigger:** Crossing up
3. **Value:** Any value
4. **Check:** "Only once per bar close"
5. **Message:** Use the JSON from `QUICK_SETUP_CARD.md`
This will fire less frequently but still works.
---
**Try the Pine Script method first - it's the cleanest solution!** 🚀

View File

@@ -0,0 +1,243 @@
# TradingView Market Data Alert Setup
## Quick Copy-Paste Alert Configuration
### Alert 1: SOL Market Data (5-minute bars)
**Symbol:** SOLUSDT
**Timeframe:** 5 minutes
**Alert Name:** Market Data - SOL 5min
**Condition:**
```pinescript
ta.change(time("1"))
```
(This fires every bar close)
**Alert Message:**
```json
{
"action": "market_data",
"symbol": "{{ticker}}",
"timeframe": "{{interval}}",
"atr": {{ta.atr(14)}},
"adx": {{ta.dmi(14, 14)}},
"rsi": {{ta.rsi(14)}},
"volumeRatio": {{volume / ta.sma(volume, 20)}},
"pricePosition": {{(close - ta.lowest(low, 100)) / (ta.highest(high, 100) - ta.lowest(low, 100)) * 100}},
"currentPrice": {{close}}
}
```
**Webhook URL:** (Choose one based on your setup)
```
Option 1 (if bot is publicly accessible):
https://YOUR-DOMAIN.COM:3001/api/trading/market-data
Option 2 (if using n8n as proxy):
https://flow.egonetix.de/webhook/market-data
Option 3 (local testing):
http://YOUR-SERVER-IP:3001/api/trading/market-data
```
**Settings:**
- ✅ Webhook URL (enable and enter URL above)
- ✅ Once Per Bar Close
- Expiration: Never
- Name on chart: Market Data - SOL 5min
---
### Alert 2: ETH Market Data (5-minute bars)
**Symbol:** ETHUSDT
**Timeframe:** 5 minutes
**Alert Name:** Market Data - ETH 5min
**Condition:**
```pinescript
ta.change(time("1"))
```
**Alert Message:**
```json
{
"action": "market_data",
"symbol": "{{ticker}}",
"timeframe": "{{interval}}",
"atr": {{ta.atr(14)}},
"adx": {{ta.dmi(14, 14)}},
"rsi": {{ta.rsi(14)}},
"volumeRatio": {{volume / ta.sma(volume, 20)}},
"pricePosition": {{(close - ta.lowest(low, 100)) / (ta.highest(high, 100) - ta.lowest(low, 100)) * 100}},
"currentPrice": {{close}}
}
```
**Webhook URL:** (Same as SOL above)
**Settings:**
- ✅ Webhook URL (same as SOL)
- ✅ Once Per Bar Close
- Expiration: Never
---
### Alert 3: BTC Market Data (5-minute bars)
**Symbol:** BTCUSDT
**Timeframe:** 5 minutes
**Alert Name:** Market Data - BTC 5min
**Condition:**
```pinescript
ta.change(time("1"))
```
**Alert Message:**
```json
{
"action": "market_data",
"symbol": "{{ticker}}",
"timeframe": "{{interval}}",
"atr": {{ta.atr(14)}},
"adx": {{ta.dmi(14, 14)}},
"rsi": {{ta.rsi(14)}},
"volumeRatio": {{volume / ta.sma(volume, 20)}},
"pricePosition": {{(close - ta.lowest(low, 100)) / (ta.highest(high, 100) - ta.lowest(low, 100)) * 100}},
"currentPrice": {{close}}
}
```
**Webhook URL:** (Same as SOL above)
**Settings:**
- ✅ Webhook URL (same as SOL)
- ✅ Once Per Bar Close
- Expiration: Never
---
## Verification Steps
### Step 1: Check Webhook Endpoint is Accessible
```bash
# From your server
curl http://localhost:3001/api/trading/market-data
# Should return:
# {"success":true,"availableSymbols":[],"count":0,"cache":{}}
```
### Step 2: Wait 5 Minutes for First Alert
After creating alerts, wait for next bar close (5 minutes max)
### Step 3: Verify Cache is Populated
```bash
curl http://localhost:3001/api/trading/market-data
# Should now show:
# {
# "success": true,
# "availableSymbols": ["SOL-PERP", "ETH-PERP", "BTC-PERP"],
# "count": 3,
# "cache": {
# "SOL-PERP": {
# "atr": 0.45,
# "adx": 32.1,
# "rsi": 58.3,
# "ageSeconds": 23
# },
# ...
# }
# }
```
### Step 4: Test Telegram Trade
```
You: "long sol"
# Should see:
✅ Analytics check passed (68/100)
Data: tradingview_real (23s old) ← FRESH DATA!
Proceeding with LONG SOL...
```
---
## Troubleshooting
### Problem: Cache still empty after 10 minutes
**Check:**
1. TradingView alerts show "Active" status
2. Webhook URL is correct (check for typos)
3. Port 3001 is accessible (firewall rules)
4. Docker container is running: `docker ps | grep trading-bot`
5. Check logs: `docker logs -f trading-bot-v4`
### Problem: Alerts not firing
**Check:**
1. TradingView plan supports webhooks (Pro/Premium/Pro+)
2. Chart is open (alerts need chart loaded to fire)
3. Condition `ta.change(time("1"))` is correct
4. Timeframe matches (5-minute chart)
### Problem: JSON parse errors in logs
**Check:**
1. Alert message is valid JSON (no trailing commas)
2. TradingView placeholders use `{{ticker}}` not `{ticker}`
3. No special characters breaking JSON
---
## Alert Cost Optimization
**Current setup:** 3 alerts firing every 5 minutes = ~864 alerts/day
**TradingView Alert Limits:**
- Free: 1 alert
- Pro: 20 alerts
- Pro+: 100 alerts
- Premium: 400 alerts
**If you need to reduce alerts:**
1. Use 15-minute bars instead of 5-minute (reduces by 67%)
2. Only enable alerts for symbols you actively trade
3. Use same alert for multiple symbols (requires script modification)
---
## Advanced: n8n Proxy Setup (Optional)
If your bot is not publicly accessible, use n8n as webhook proxy:
**Step 1:** Create n8n webhook
- Webhook URL: `https://flow.egonetix.de/webhook/market-data`
- Method: POST
- Response: Return text
**Step 2:** Add HTTP Request node
- URL: `http://trading-bot-v4:3000/api/trading/market-data`
- Method: POST
- Body: `{{ $json }}`
- Headers: None needed (internal network)
**Step 3:** Use n8n URL in TradingView alerts
```
https://flow.egonetix.de/webhook/market-data
```
---
## Next: Enable Market Data Alerts
1. **Copy alert message JSON** from above
2. **Open TradingView** → SOL/USD 5-minute chart
3. **Click alert icon** (top right)
4. **Paste condition and message**
5. **Save alert**
6. **Repeat for ETH and BTC**
7. **Wait 5 minutes and verify cache**
**Once verified, proceed to SQL analysis!**

View File

@@ -0,0 +1,351 @@
# TradingView Alert Setup - Step-by-Step Guide
## 🎯 Goal
Create 3 alerts that send market data to your trading bot every 5 minutes.
---
## STEP 1: Find Your Webhook URL
First, we need to know where to send the data.
**Check if your bot is accessible:**
```bash
# On your server, run:
curl http://localhost:3001/api/trading/market-data
```
**Expected response:**
```json
{"success":true,"availableSymbols":[],"count":0,"cache":{}}
```
**Your webhook URL will be ONE of these:**
- `http://YOUR-SERVER-IP:3001/api/trading/market-data` (if port 3001 is open)
- `https://YOUR-DOMAIN.COM:3001/api/trading/market-data` (if you have a domain)
- `https://flow.egonetix.de/webhook/market-data` (if using n8n as proxy)
**Write down your URL here:**
```
My webhook URL: ________________________________
```
---
## STEP 2: Open TradingView and Go to SOL Chart
1. **Go to:** https://www.tradingview.com
2. **Login** to your account
3. **Click** on the chart icon or search bar at top
4. **Type:** `SOLUSDT`
5. **Click** on `SOLUSDT` from Binance (or your preferred exchange)
6. **Set timeframe** to **5 minutes** (click "5" in the top toolbar)
**You should now see:** A 5-minute chart of SOLUSDT
---
## STEP 3: Create Alert
1. **Click** the **Alert icon** 🔔 in the right toolbar
- Or press **ALT + A** on keyboard
2. A popup window opens titled "Create Alert"
---
## STEP 4: Configure Alert Condition
In the "Condition" section:
1. **First dropdown:** Select `time("1")`
- Click the dropdown that says "Crossing" or whatever is there
- **Type** in the search: `time`
- Select: `time``time("1")`
2. **Second dropdown:** Select `changes`
- This should appear automatically after selecting time("1")
- If not, select "changes" from the dropdown
**What you should see:**
```
time("1") changes
```
This means: "Alert fires when time changes" = every bar close
---
## STEP 5: Set Alert Actions (IMPORTANT!)
Scroll down to the "Notifications" section:
**UNCHECK everything EXCEPT:**
-**Webhook URL** (leave this CHECKED)
**UNCHECK these:**
- ❌ Notify on app
- ❌ Show popup
- ❌ Send email
- ❌ Play sound
**We ONLY want webhook!**
---
## STEP 6: Enter Webhook URL
1. In the **Webhook URL** field, paste your URL from Step 1:
```
http://YOUR-SERVER-IP:3001/api/trading/market-data
```
*(Replace with your actual URL)*
2. **Click in the field** to make sure it's saved
---
## STEP 7: Configure Alert Message (COPY-PASTE THIS)
Scroll to the **"Alert message"** box.
**DELETE everything** in that box.
**PASTE this EXACTLY** (copy the entire JSON):
```json
{
"action": "market_data",
"symbol": "{{ticker}}",
"timeframe": "{{interval}}",
"atr": {{ta.atr(14)}},
"adx": {{ta.dmi(14, 14)}},
"rsi": {{ta.rsi(14)}},
"volumeRatio": {{volume / ta.sma(volume, 20)}},
"pricePosition": {{(close - ta.lowest(low, 100)) / (ta.highest(high, 100) - ta.lowest(low, 100)) * 100}},
"currentPrice": {{close}}
}
```
**IMPORTANT:** Make sure:
- No spaces added/removed
- The `{{` double brackets are kept
- No missing commas
- No extra text
---
## STEP 8: Set Alert Name and Frequency
**Alert name:**
```
Market Data - SOL 5min
```
**Frequency section:**
- Select: **"Once Per Bar Close"**
- NOT "Only Once"
- NOT "Once Per Bar"
- Must be **"Once Per Bar Close"**
**Expiration:**
- Select: **"Never"** or **"Open-ended"**
**Show popup / Name on chart:**
- You can uncheck these (optional)
---
## STEP 9: Create the Alert
1. **Click** the blue **"Create"** button at bottom
2. Alert is now active! ✅
You should see it in your alerts list (🔔 icon in right panel)
---
## STEP 10: Repeat for ETH and BTC
Now do the EXACT same steps for:
**For ETH:**
1. Search for `ETHUSDT`
2. Set to 5-minute chart
3. Create alert (ALT + A)
4. Condition: `time("1") changes`
5. Webhook URL: (same as SOL)
6. Alert message: (same JSON as SOL)
7. Alert name: `Market Data - ETH 5min`
8. Frequency: Once Per Bar Close
9. Create
**For BTC:**
1. Search for `BTCUSDT`
2. Set to 5-minute chart
3. Create alert (ALT + A)
4. Condition: `time("1") changes`
5. Webhook URL: (same as SOL)
6. Alert message: (same JSON as SOL)
7. Alert name: `Market Data - BTC 5min`
8. Frequency: Once Per Bar Close
9. Create
---
## ✅ VERIFICATION (Wait 5 Minutes)
After creating alerts, **WAIT UP TO 5 MINUTES** for the next bar close.
Then run this on your server:
```bash
curl http://localhost:3001/api/trading/market-data
```
**You should see:**
```json
{
"success": true,
"availableSymbols": ["SOL-PERP", "ETH-PERP", "BTC-PERP"],
"count": 3,
"cache": {
"SOL-PERP": {
"atr": 0.45,
"adx": 32.1,
"rsi": 58.3,
"volumeRatio": 1.25,
"pricePosition": 55.2,
"ageSeconds": 23
},
...
}
}
```
**If you see this → SUCCESS!** ✅
---
## 🐛 Troubleshooting
### Problem: Still shows empty cache after 10 minutes
**Check 1: Are alerts active?**
- Click 🔔 icon in TradingView
- Look for your 3 alerts
- They should say "Active" (not paused)
**Check 2: Is webhook URL correct?**
- Click on an alert to edit it
- Check the Webhook URL field
- No typos? Correct port (3001)?
**Check 3: Check bot logs**
```bash
docker logs -f trading-bot-v4
```
Wait for next bar close and watch for incoming requests.
You should see:
```
POST /api/trading/market-data
✅ Market data cached for SOL-PERP
```
**Check 4: Is port 3001 open?**
```bash
# From another machine or phone:
curl http://YOUR-SERVER-IP:3001/api/trading/market-data
```
If this fails, port 3001 might be blocked by firewall.
**Check 5: TradingView plan supports webhooks?**
- Free plan: NO webhooks ❌
- Pro plan: YES ✅
- Pro+ plan: YES ✅
- Premium: YES ✅
If you have Free plan, you need to upgrade to Pro ($14.95/month).
---
## 📸 Visual Guide
**Where is the Alert icon?**
```
TradingView Chart:
┌─────────────────────────────────────┐
│ [Chart toolbar at top] │
│ │
│ [Chart area] 🔔 ← Alert icon (right side)
│ │
│ │
└─────────────────────────────────────┘
```
**What the Alert popup looks like:**
```
┌─ Create Alert ────────────────┐
│ │
│ Condition: │
│ [time("1")] [changes] │
│ │
│ Notifications: │
│ ✅ Webhook URL │
│ [http://your-url...] │
│ │
│ Alert message: │
│ [{"action":"market_data",...}]│
│ │
│ Alert name: │
│ [Market Data - SOL 5min] │
│ │
│ Frequency: │
│ [Once Per Bar Close] │
│ │
│ [Create] │
└───────────────────────────────┘
```
---
## 🎬 Quick Recap
**You need to create 3 alerts total:**
| Symbol | Chart | Alert Name | Frequency |
|-----------|-----------|-------------------------|-------------------|
| SOLUSDT | 5-minute | Market Data - SOL 5min | Once Per Bar Close|
| ETHUSDT | 5-minute | Market Data - ETH 5min | Once Per Bar Close|
| BTCUSDT | 5-minute | Market Data - BTC 5min | Once Per Bar Close|
**All 3 use:**
- Same webhook URL
- Same alert message (the JSON)
- Same condition: `time("1") changes`
- Same frequency: Once Per Bar Close
**After 5 minutes:**
- Check cache is populated
- Test with Telegram: `long sol`
---
## ❓ Still Stuck?
**Common mistakes:**
1. ❌ Using "Once Per Bar" instead of "Once Per Bar Close"
2. ❌ Alert message has extra spaces or missing brackets
3. ❌ Webhook URL has typo or wrong port
4. ❌ Alert is paused (not active)
5. ❌ Free TradingView plan (needs Pro for webhooks)
**Need help?**
- Show me a screenshot of your alert configuration
- Show me the output of `docker logs trading-bot-v4`
- Show me the output of `curl http://localhost:3001/api/trading/market-data`
---
**Once alerts are working, you're ready to run the SQL analysis!** 🚀