feat: Add n8n workflow for TradingView webhook automation
- Complete 13-node workflow connecting TradingView alerts to trade execution - Webhook validation, risk checking, and trade execution via v4 API - Telegram notifications for all scenarios (success/error/blocked) - Comprehensive setup guide with testing and troubleshooting - Supports SOL/BTC/ETH and LONG/SHORT signals from TradingView
This commit is contained in:
500
v4/N8N_WORKFLOW_GUIDE.md
Normal file
500
v4/N8N_WORKFLOW_GUIDE.md
Normal file
@@ -0,0 +1,500 @@
|
||||
# n8n Workflow Setup Guide - Trading Bot v4
|
||||
|
||||
Complete guide to set up the automated trading workflow in n8n.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Workflow Overview
|
||||
|
||||
```
|
||||
TradingView Alert (Webhook)
|
||||
↓
|
||||
Validate Secret
|
||||
↓
|
||||
Parse Signal (SOL/BTC/ETH, LONG/SHORT)
|
||||
↓
|
||||
Check Risk Limits (API call to /api/trading/check-risk)
|
||||
↓
|
||||
Execute Trade (API call to /api/trading/execute)
|
||||
↓
|
||||
Format Message (Success/Error/Blocked)
|
||||
↓
|
||||
Send Telegram Notification
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Setup
|
||||
|
||||
### Step 1: Import Workflow
|
||||
|
||||
1. Open your n8n instance
|
||||
2. Click **"+ New Workflow"**
|
||||
3. Click **"⋮"** (three dots) → **"Import from File"**
|
||||
4. Select `n8n-workflow-complete.json`
|
||||
5. Click **"Import"**
|
||||
|
||||
### Step 2: Configure Environment Variables
|
||||
|
||||
In n8n, go to **Settings** → **Environment Variables** and add:
|
||||
|
||||
```bash
|
||||
# Your trading bot API URL
|
||||
TRADING_BOT_API_URL=http://your-server:3000
|
||||
|
||||
# API secret key (must match .env in v4)
|
||||
API_SECRET_KEY=your_secret_key_from_env
|
||||
|
||||
# TradingView webhook validation
|
||||
TRADINGVIEW_WEBHOOK_SECRET=your_tradingview_secret
|
||||
|
||||
# Telegram credentials
|
||||
TELEGRAM_CHAT_ID=your_telegram_chat_id
|
||||
```
|
||||
|
||||
### Step 3: Configure Telegram Credentials
|
||||
|
||||
1. In n8n, click **"Telegram - Send Notification"** node
|
||||
2. Click **"Create New Credential"**
|
||||
3. Enter your **Telegram Bot Token**
|
||||
4. Save credential
|
||||
|
||||
### Step 4: Get Webhook URL
|
||||
|
||||
1. Click **"Webhook - TradingView Alert"** node
|
||||
2. Click **"Test URL"** or **"Production URL"**
|
||||
3. Copy the webhook URL (looks like: `https://your-n8n.com/webhook/tradingview-webhook`)
|
||||
4. Save this for TradingView setup
|
||||
|
||||
### Step 5: Activate Workflow
|
||||
|
||||
1. Toggle **"Active"** switch at top right
|
||||
2. Workflow is now listening for webhooks!
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Detailed Configuration
|
||||
|
||||
### Webhook Node Configuration
|
||||
|
||||
**Node:** `Webhook - TradingView Alert`
|
||||
|
||||
- **HTTP Method:** POST
|
||||
- **Path:** `tradingview-webhook` (or customize)
|
||||
- **Response:** Return on Last Node
|
||||
- **Raw Body:** Enabled
|
||||
|
||||
**What it does:** Receives TradingView alerts via webhook
|
||||
|
||||
### Validate Secret Node
|
||||
|
||||
**Node:** `Validate Secret`
|
||||
|
||||
- **Type:** IF condition
|
||||
- **Condition:** `{{$json.body.secret}} equals {{$env.TRADINGVIEW_WEBHOOK_SECRET}}`
|
||||
|
||||
**What it does:** Prevents unauthorized trade execution
|
||||
|
||||
**Important:** Make sure TradingView webhook includes `?secret=YOUR_SECRET` in URL
|
||||
|
||||
### Parse TradingView Signal Node
|
||||
|
||||
**Node:** `Parse TradingView Signal`
|
||||
|
||||
- **Type:** Code (Function)
|
||||
- **Language:** JavaScript
|
||||
|
||||
**What it does:**
|
||||
- Extracts symbol, action, timeframe from TradingView alert
|
||||
- Normalizes data for v4 API
|
||||
- Supports various TradingView alert formats
|
||||
|
||||
**Supported formats:**
|
||||
```json
|
||||
{
|
||||
"symbol": "SOLUSDT",
|
||||
"action": "buy",
|
||||
"timeframe": "5",
|
||||
"price": "140.25",
|
||||
"timestamp": "2025-10-23T10:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
Or:
|
||||
```json
|
||||
{
|
||||
"ticker": "SOL-PERP",
|
||||
"signal_type": "long",
|
||||
"interval": "5m",
|
||||
"close": "140.25"
|
||||
}
|
||||
```
|
||||
|
||||
### Check Risk Limits Node
|
||||
|
||||
**Node:** `Check Risk Limits`
|
||||
|
||||
- **URL:** `{{$env.TRADING_BOT_API_URL}}/api/trading/check-risk`
|
||||
- **Method:** POST
|
||||
- **Headers:**
|
||||
- `Authorization: Bearer {{$env.API_SECRET_KEY}}`
|
||||
- `Content-Type: application/json`
|
||||
- **Body:**
|
||||
```json
|
||||
{
|
||||
"symbol": "{{$json.apiPayload.symbol}}",
|
||||
"direction": "{{$json.apiPayload.direction}}"
|
||||
}
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
- Checks daily drawdown limits
|
||||
- Validates trades per hour
|
||||
- Ensures cooldown period passed
|
||||
|
||||
### Execute Trade Node
|
||||
|
||||
**Node:** `Execute Trade on Drift`
|
||||
|
||||
- **URL:** `{{$env.TRADING_BOT_API_URL}}/api/trading/execute`
|
||||
- **Method:** POST
|
||||
- **Timeout:** 30000ms (30 seconds)
|
||||
- **Headers:**
|
||||
- `Authorization: Bearer {{$env.API_SECRET_KEY}}`
|
||||
- `Content-Type: application/json`
|
||||
- **Body:**
|
||||
```json
|
||||
{
|
||||
"symbol": "SOLUSDT",
|
||||
"direction": "long",
|
||||
"timeframe": "5",
|
||||
"signalStrength": "strong",
|
||||
"signalPrice": 140.25
|
||||
}
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
- Opens position on Drift Protocol
|
||||
- Starts automatic monitoring
|
||||
- Returns trade details (entry price, TP/SL levels)
|
||||
|
||||
### Format Message Nodes
|
||||
|
||||
**Three formatting nodes for different scenarios:**
|
||||
|
||||
1. **Format Success Message** - Trade executed successfully
|
||||
2. **Format Error Message** - Trade execution failed
|
||||
3. **Format Risk Blocked Message** - Trade blocked by risk limits
|
||||
|
||||
**Output example (Success):**
|
||||
```
|
||||
🟢 TRADE EXECUTED
|
||||
|
||||
📊 Symbol: SOL-PERP
|
||||
📈 Direction: LONG
|
||||
💰 Entry Price: $140.2350
|
||||
💵 Position Size: $500.00
|
||||
⚡ Leverage: 10x
|
||||
|
||||
🎯 Targets:
|
||||
Stop Loss: $137.90 (-1.5%)
|
||||
TP1: $140.98 (+0.7%)
|
||||
TP2: $142.10 (+1.5%)
|
||||
|
||||
📊 Slippage: 0.015%
|
||||
⏰ Time: 10/23/2025, 10:00:00 AM
|
||||
|
||||
✅ Position is now being monitored automatically.
|
||||
Auto-exit at TP/SL levels.
|
||||
```
|
||||
|
||||
### Telegram Node
|
||||
|
||||
**Node:** `Telegram - Send Notification`
|
||||
|
||||
- **Chat ID:** `{{$env.TELEGRAM_CHAT_ID}}`
|
||||
- **Text:** `{{$json.message}}`
|
||||
- **Parse Mode:** Markdown
|
||||
|
||||
**What it does:** Sends formatted notification to your Telegram
|
||||
|
||||
---
|
||||
|
||||
## 🎯 TradingView Alert Setup
|
||||
|
||||
### Alert Configuration
|
||||
|
||||
1. **In TradingView:** Right-click chart → Add Alert
|
||||
2. **Condition:** Your indicator/strategy
|
||||
3. **Alert Name:** "SOL Long Signal" (or similar)
|
||||
4. **Webhook URL:**
|
||||
```
|
||||
https://your-n8n.com/webhook/tradingview-webhook?secret=YOUR_SECRET
|
||||
```
|
||||
|
||||
### Alert Message (JSON)
|
||||
|
||||
Use this format in the **Message** field:
|
||||
|
||||
```json
|
||||
{
|
||||
"symbol": "{{ticker}}",
|
||||
"action": "{{strategy.order.action}}",
|
||||
"timeframe": "{{interval}}",
|
||||
"price": "{{close}}",
|
||||
"timestamp": "{{timenow}}",
|
||||
"secret": "YOUR_TRADINGVIEW_SECRET",
|
||||
"strategy": "5min_scalp",
|
||||
"strength": "strong"
|
||||
}
|
||||
```
|
||||
|
||||
**Important fields:**
|
||||
- `symbol`: Stock/crypto symbol (SOLUSDT, BTCUSD, etc.)
|
||||
- `action`: "buy"/"sell" or "long"/"short"
|
||||
- `secret`: Must match `TRADINGVIEW_WEBHOOK_SECRET` in n8n env
|
||||
|
||||
### Notification Settings
|
||||
|
||||
✅ **Enable:**
|
||||
- Webhook URL
|
||||
- Notify on app
|
||||
- Play sound (optional)
|
||||
|
||||
❌ **Disable:**
|
||||
- Send email (n8n handles notifications)
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing
|
||||
|
||||
### Test 1: Webhook Connection
|
||||
|
||||
```bash
|
||||
# Send test webhook from command line
|
||||
curl -X POST https://your-n8n.com/webhook/tradingview-webhook \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"symbol": "SOLUSDT",
|
||||
"action": "buy",
|
||||
"timeframe": "5",
|
||||
"price": "140.25",
|
||||
"timestamp": "2025-10-23T10:00:00Z",
|
||||
"secret": "YOUR_SECRET"
|
||||
}'
|
||||
```
|
||||
|
||||
### Test 2: Check n8n Executions
|
||||
|
||||
1. In n8n, click **"Executions"** tab
|
||||
2. Find your test execution
|
||||
3. Click to view detailed flow
|
||||
4. Check each node for errors
|
||||
|
||||
### Test 3: Verify API Response
|
||||
|
||||
Expected response from `/api/trading/execute`:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"trade": {
|
||||
"id": "trade-1234567890",
|
||||
"symbol": "SOL-PERP",
|
||||
"direction": "long",
|
||||
"entryPrice": 140.235,
|
||||
"positionSize": 500,
|
||||
"leverage": 10,
|
||||
"stopLoss": 137.90,
|
||||
"takeProfit1": 140.98,
|
||||
"takeProfit2": 142.10
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Test 4: Telegram Message
|
||||
|
||||
You should receive a formatted Telegram message with trade details.
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Troubleshooting
|
||||
|
||||
### Webhook Not Receiving Data
|
||||
|
||||
**Problem:** n8n workflow not triggering
|
||||
|
||||
**Solutions:**
|
||||
1. Check webhook is **Active** (toggle at top)
|
||||
2. Verify webhook URL in TradingView matches n8n
|
||||
3. Test with curl command (see Testing section)
|
||||
4. Check n8n logs for errors
|
||||
|
||||
### Invalid Secret Error
|
||||
|
||||
**Problem:** "Unauthorized Webhook" message
|
||||
|
||||
**Solutions:**
|
||||
1. Verify `secret` in TradingView alert matches `TRADINGVIEW_WEBHOOK_SECRET`
|
||||
2. Check environment variable is set in n8n
|
||||
3. Secret is case-sensitive!
|
||||
|
||||
### API Authentication Failed
|
||||
|
||||
**Problem:** "401 Unauthorized" from trading bot
|
||||
|
||||
**Solutions:**
|
||||
1. Verify `API_SECRET_KEY` in n8n matches v4 `.env`
|
||||
2. Check `Authorization` header format: `Bearer YOUR_KEY`
|
||||
3. Regenerate key if needed: `openssl rand -hex 32`
|
||||
|
||||
### Trade Not Executing
|
||||
|
||||
**Problem:** Risk check passed but no position opened
|
||||
|
||||
**Solutions:**
|
||||
1. Check v4 API logs: `docker-compose logs -f trading-bot`
|
||||
2. Verify Drift wallet has sufficient collateral
|
||||
3. Check SOLANA_RPC_URL is working
|
||||
4. Ensure DRIFT_WALLET_PRIVATE_KEY is correct
|
||||
5. Test with curl:
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/trading/execute \
|
||||
-H "Authorization: Bearer YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"symbol":"SOLUSDT","direction":"long","timeframe":"5"}'
|
||||
```
|
||||
|
||||
### Telegram Not Sending
|
||||
|
||||
**Problem:** No Telegram notifications
|
||||
|
||||
**Solutions:**
|
||||
1. Verify Telegram Bot Token in credentials
|
||||
2. Check TELEGRAM_CHAT_ID is correct
|
||||
3. Ensure bot is started (send /start to your bot)
|
||||
4. Test Telegram node individually in n8n
|
||||
|
||||
---
|
||||
|
||||
## 📊 Monitoring
|
||||
|
||||
### View Executions
|
||||
|
||||
In n8n:
|
||||
1. Click **"Executions"** tab
|
||||
2. Filter by **"Success"** or **"Error"**
|
||||
3. Click execution to see detailed flow
|
||||
|
||||
### Check Active Positions
|
||||
|
||||
Query via API:
|
||||
```bash
|
||||
curl -H "Authorization: Bearer YOUR_API_KEY" \
|
||||
http://localhost:3000/api/trading/positions
|
||||
```
|
||||
|
||||
Or check Drift UI: https://drift.trade
|
||||
|
||||
### View Bot Logs
|
||||
|
||||
```bash
|
||||
# Docker logs
|
||||
docker-compose logs -f trading-bot
|
||||
|
||||
# Or if using scripts
|
||||
cd v4 && ./docker-logs.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Security Best Practices
|
||||
|
||||
1. **Use Strong Secrets**
|
||||
```bash
|
||||
# Generate secure random secrets
|
||||
openssl rand -hex 32 # For API keys
|
||||
openssl rand -hex 16 # For webhook secrets
|
||||
```
|
||||
|
||||
2. **Protect Environment Variables**
|
||||
- Never commit `.env` files
|
||||
- Use n8n's environment variable encryption
|
||||
- Rotate secrets regularly
|
||||
|
||||
3. **IP Whitelisting** (optional)
|
||||
- Restrict webhook access to TradingView IPs
|
||||
- Use n8n's IP filtering if available
|
||||
|
||||
4. **Monitor Failed Attempts**
|
||||
- Set up alerts for unauthorized webhook attempts
|
||||
- Review n8n execution logs regularly
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Advanced Configuration
|
||||
|
||||
### Custom Risk Parameters
|
||||
|
||||
Modify `Check Risk Limits` node to send additional parameters:
|
||||
|
||||
```json
|
||||
{
|
||||
"symbol": "SOL-PERP",
|
||||
"direction": "long",
|
||||
"customPositionSize": 100,
|
||||
"customLeverage": 5
|
||||
}
|
||||
```
|
||||
|
||||
### Multiple Strategies
|
||||
|
||||
Clone the workflow for different strategies:
|
||||
1. Duplicate workflow
|
||||
2. Change webhook path: `/webhook/tradingview-5min` vs `/webhook/tradingview-15min`
|
||||
3. Use different risk parameters per timeframe
|
||||
|
||||
### Advanced Notifications
|
||||
|
||||
Add Discord/Email nodes in parallel with Telegram:
|
||||
1. Add Discord webhook node
|
||||
2. Add SMTP email node
|
||||
3. Connect all to message formatter nodes
|
||||
|
||||
---
|
||||
|
||||
## 📞 Support
|
||||
|
||||
**Workflow Issues:**
|
||||
- Check n8n documentation: https://docs.n8n.io
|
||||
- Review execution logs in n8n
|
||||
|
||||
**API Issues:**
|
||||
- See `v4/TESTING.md` for API testing
|
||||
- Check `v4/DOCKER.md` for container logs
|
||||
|
||||
**Trading Issues:**
|
||||
- See `TRADING_BOT_V4_MANUAL.md` for complete guide
|
||||
- Check Drift Protocol status
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist
|
||||
|
||||
Before going live:
|
||||
|
||||
- [ ] Import workflow to n8n
|
||||
- [ ] Configure all environment variables
|
||||
- [ ] Add Telegram credentials
|
||||
- [ ] Copy webhook URL
|
||||
- [ ] Configure TradingView alert with webhook
|
||||
- [ ] Test with small position size ($10-50)
|
||||
- [ ] Verify Telegram notification received
|
||||
- [ ] Check position opened on Drift
|
||||
- [ ] Monitor first 5-10 trades closely
|
||||
- [ ] Gradually increase position size
|
||||
|
||||
---
|
||||
|
||||
**Your automated trading system is now complete! 🎉**
|
||||
|
||||
When TradingView fires an alert → n8n executes the trade → You get a Telegram notification → Bot monitors and auto-exits at TP/SL!
|
||||
395
v4/n8n-workflow-complete.json
Normal file
395
v4/n8n-workflow-complete.json
Normal file
@@ -0,0 +1,395 @@
|
||||
{
|
||||
"name": "Trading Bot v4 - Execute Trade",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "tradingview-webhook",
|
||||
"options": {
|
||||
"rawBody": true
|
||||
}
|
||||
},
|
||||
"name": "Webhook - TradingView Alert",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
250,
|
||||
300
|
||||
],
|
||||
"webhookId": "your-unique-webhook-id",
|
||||
"id": "webhook-node"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"string": [
|
||||
{
|
||||
"value1": "={{$json.body.secret}}",
|
||||
"operation": "equals",
|
||||
"value2": "={{$env.TRADINGVIEW_WEBHOOK_SECRET}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "Validate Secret",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
450,
|
||||
300
|
||||
],
|
||||
"id": "validate-secret-node"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "// Parse TradingView alert data\nconst body = $input.item.json.body;\n\n// Extract signal information\nconst signal = {\n symbol: body.symbol || body.ticker || 'SOLUSDT',\n action: body.action || body.signal_type || 'buy',\n timeframe: body.timeframe || body.interval || '5',\n price: body.price || body.close,\n timestamp: body.timestamp || body.timenow || new Date().toISOString(),\n strength: body.strength || 'strong',\n strategy: body.strategy || '5min_scalp_v4'\n};\n\n// Normalize action to 'long' or 'short'\nlet direction = 'long';\nif (signal.action) {\n const actionLower = signal.action.toLowerCase();\n if (actionLower.includes('sell') || actionLower.includes('short')) {\n direction = 'short';\n }\n}\n\n// Build API payload for v4 execute endpoint\nconst payload = {\n symbol: signal.symbol,\n direction: direction,\n timeframe: signal.timeframe,\n signalStrength: signal.strength,\n signalPrice: parseFloat(signal.price)\n};\n\n// Pass through original data + processed payload\nreturn {\n json: {\n original: body,\n signal: signal,\n apiPayload: payload,\n timestamp: new Date().toISOString()\n }\n};"
|
||||
},
|
||||
"name": "Parse TradingView Signal",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
650,
|
||||
200
|
||||
],
|
||||
"id": "parse-signal-node"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "={{$env.TRADING_BOT_API_URL}}/api/trading/check-risk",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "Bearer {{$env.API_SECRET_KEY}}"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "symbol",
|
||||
"value": "={{$json.apiPayload.symbol}}"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"value": "={{$json.apiPayload.direction}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"name": "Check Risk Limits",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.1,
|
||||
"position": [
|
||||
850,
|
||||
200
|
||||
],
|
||||
"id": "check-risk-node"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{$json.allowed}}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "Risk Check Passed?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1050,
|
||||
200
|
||||
],
|
||||
"id": "risk-check-if-node"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "={{$env.TRADING_BOT_API_URL}}/api/trading/execute",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "Bearer {{$env.API_SECRET_KEY}}"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"contentType": "json",
|
||||
"body": "={{JSON.stringify($('Parse TradingView Signal').item.json.apiPayload)}}",
|
||||
"options": {
|
||||
"timeout": 30000
|
||||
}
|
||||
},
|
||||
"name": "Execute Trade on Drift",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.1,
|
||||
"position": [
|
||||
1250,
|
||||
100
|
||||
],
|
||||
"id": "execute-trade-node"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{$json.success}}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"name": "Trade Executed?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1450,
|
||||
100
|
||||
],
|
||||
"id": "trade-executed-if-node"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "// Format success message for Telegram\nconst trade = $json.trade || {};\nconst signal = $('Parse TradingView Signal').item.json.signal;\n\nconst direction = trade.direction?.toUpperCase() || signal.action?.toUpperCase();\nconst emoji = direction === 'LONG' ? '🟢' : '🔴';\n\nconst message = `${emoji} **TRADE EXECUTED**\\n\\n` +\n `📊 **Symbol:** ${trade.symbol || signal.symbol}\\n` +\n `📈 **Direction:** ${direction}\\n` +\n `💰 **Entry Price:** $${trade.entryPrice?.toFixed(4) || signal.price}\\n` +\n `💵 **Position Size:** $${trade.positionSize?.toFixed(2) || 'N/A'}\\n` +\n `⚡ **Leverage:** ${trade.leverage || 10}x\\n` +\n `\\n` +\n `🎯 **Targets:**\\n` +\n ` Stop Loss: $${trade.stopLoss?.toFixed(4) || 'N/A'} (${trade.stopLossPercent || -1.5}%)\\n` +\n ` TP1: $${trade.takeProfit1?.toFixed(4) || 'N/A'} (+${trade.tp1Percent || 0.7}%)\\n` +\n ` TP2: $${trade.takeProfit2?.toFixed(4) || 'N/A'} (+${trade.tp2Percent || 1.5}%)\\n` +\n `\\n` +\n `📊 **Slippage:** ${trade.entrySlippage?.toFixed(3) || '0'}%\\n` +\n `⏰ **Time:** ${new Date(trade.timestamp || Date.now()).toLocaleString()}\\n` +\n `\\n` +\n `✅ Position is now being monitored automatically.\\n` +\n `Auto-exit at TP/SL levels.`;\n\nreturn {\n json: {\n message: message,\n trade: trade,\n signal: signal\n }\n};"
|
||||
},
|
||||
"name": "Format Success Message",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1650,
|
||||
50
|
||||
],
|
||||
"id": "format-success-node"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "// Format error message for Telegram\nconst error = $json.error || $json.message || 'Unknown error';\nconst signal = $('Parse TradingView Signal').item.json.signal;\n\nconst message = `❌ **TRADE FAILED**\\n\\n` +\n `📊 **Symbol:** ${signal.symbol}\\n` +\n `📈 **Direction:** ${signal.action?.toUpperCase()}\\n` +\n `⏰ **Time:** ${new Date().toLocaleString()}\\n` +\n `\\n` +\n `🚫 **Error:** ${error}\\n` +\n `\\n` +\n `Please check logs and try again.`;\n\nreturn {\n json: {\n message: message,\n error: error,\n signal: signal\n }\n};"
|
||||
},
|
||||
"name": "Format Error Message",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1650,
|
||||
200
|
||||
],
|
||||
"id": "format-error-node"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "// Format risk blocked message\nconst reason = $json.reason || 'Risk limit exceeded';\nconst signal = $('Parse TradingView Signal').item.json.signal;\n\nconst message = `⚠️ **TRADE BLOCKED**\\n\\n` +\n `📊 **Symbol:** ${signal.symbol}\\n` +\n `📈 **Direction:** ${signal.action?.toUpperCase()}\\n` +\n `⏰ **Time:** ${new Date().toLocaleString()}\\n` +\n `\\n` +\n `🛑 **Reason:** ${reason}\\n` +\n `\\n` +\n `Trade was not executed due to risk limits.`;\n\nreturn {\n json: {\n message: message,\n reason: reason,\n signal: signal\n }\n};"
|
||||
},
|
||||
"name": "Format Risk Blocked Message",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1250,
|
||||
300
|
||||
],
|
||||
"id": "format-risk-blocked-node"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "={{$env.TELEGRAM_CHAT_ID}}",
|
||||
"text": "={{$json.message}}",
|
||||
"additionalFields": {
|
||||
"parse_mode": "Markdown"
|
||||
}
|
||||
},
|
||||
"name": "Telegram - Send Notification",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1850,
|
||||
150
|
||||
],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "1",
|
||||
"name": "Telegram Bot"
|
||||
}
|
||||
},
|
||||
"id": "telegram-node"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "// Invalid webhook secret\nconst message = `🚨 **UNAUTHORIZED WEBHOOK**\\n\\n` +\n `⚠️ Someone tried to trigger a trade with invalid credentials.\\n` +\n `\\n` +\n `⏰ **Time:** ${new Date().toLocaleString()}\\n` +\n `\\n` +\n `Please check your TradingView webhook configuration.`;\n\nreturn {\n json: {\n message: message\n }\n};"
|
||||
},
|
||||
"name": "Format Invalid Secret",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
650,
|
||||
400
|
||||
],
|
||||
"id": "format-invalid-secret-node"
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook - TradingView Alert": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Validate Secret",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Validate Secret": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse TradingView Signal",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Format Invalid Secret",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse TradingView Signal": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check Risk Limits",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check Risk Limits": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Risk Check Passed?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Risk Check Passed?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Execute Trade on Drift",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Format Risk Blocked Message",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Trade on Drift": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Trade Executed?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Trade Executed?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Format Success Message",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Format Error Message",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Success Message": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram - Send Notification",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Error Message": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram - Send Notification",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Risk Blocked Message": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram - Send Notification",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Invalid Secret": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram - Send Notification",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user