Features: - Autonomous trading system with Drift Protocol on Solana - Real-time position monitoring with Pyth price feeds - Dynamic stop-loss and take-profit management - n8n workflow integration for TradingView signals - Beautiful web UI for settings management - REST API for trade execution and monitoring - Next.js 15 with standalone output mode - TypeScript with strict typing - Docker containerization with multi-stage builds - PostgreSQL database for trade history - Singleton pattern for Drift client connection pooling - BN.js for BigNumber handling (Drift SDK requirement) - Configurable stop-loss and take-profit levels - Breakeven trigger and profit locking - Daily loss limits and trade cooldowns - Slippage tolerance controls - DRY_RUN mode for safe testing - Real-time risk calculator - Interactive sliders for all parameters - Live preview of trade outcomes - Position sizing and leverage controls - Beautiful gradient design with Tailwind CSS - POST /api/trading/execute - Execute trades - POST /api/trading/close - Close positions - GET /api/trading/positions - Monitor active trades - GET /api/trading/check-risk - Validate trade signals - GET /api/settings - View configuration - POST /api/settings - Update configuration - Fixed Borsh serialization errors (simplified order params) - Resolved RPC rate limiting with singleton pattern - Fixed BigInt vs BN type mismatches - Corrected order execution flow - Improved position state management - Complete setup guides - Docker deployment instructions - n8n workflow configuration - API reference documentation - Risk management guidelines - Runs on port 3001 (external), 3000 (internal) - Uses Helius RPC for optimal performance - Production-ready with error handling - Health monitoring and logging
381 lines
9.1 KiB
JSON
381 lines
9.1 KiB
JSON
{
|
|
"name": "TradingView → Trading Bot v4",
|
|
"nodes": [
|
|
{
|
|
"parameters": {
|
|
"httpMethod": "POST",
|
|
"path": "tradingview-bot-v4",
|
|
"options": {}
|
|
},
|
|
"id": "webhook-node",
|
|
"name": "Webhook",
|
|
"type": "n8n-nodes-base.webhook",
|
|
"typeVersion": 1,
|
|
"position": [240, 400],
|
|
"webhookId": "tradingview-bot-v4"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"fields": {
|
|
"values": [
|
|
{
|
|
"name": "rawMessage",
|
|
"stringValue": "={{ $json.body }}"
|
|
},
|
|
{
|
|
"name": "symbol",
|
|
"stringValue": "={{ $json.body.match(/\\bSOL\\b/i) ? 'SOL-PERP' : ($json.body.match(/\\bBTC\\b/i) ? 'BTC-PERP' : ($json.body.match(/\\bETH\\b/i) ? 'ETH-PERP' : 'SOL-PERP')) }}"
|
|
},
|
|
{
|
|
"name": "direction",
|
|
"stringValue": "={{ $json.body.match(/\\b(sell|short)\\b/i) ? 'short' : 'long' }}"
|
|
},
|
|
{
|
|
"name": "timeframe",
|
|
"stringValue": "5"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"id": "parse-fields",
|
|
"name": "Parse Signal",
|
|
"type": "n8n-nodes-base.set",
|
|
"typeVersion": 3.2,
|
|
"position": [440, 400]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "POST",
|
|
"url": "http://10.0.0.48:3001/api/trading/check-risk",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "Authorization",
|
|
"value": "Bearer 2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb"
|
|
},
|
|
{
|
|
"name": "Content-Type",
|
|
"value": "application/json"
|
|
}
|
|
]
|
|
},
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={\n \"symbol\": \"{{ $json.symbol }}\",\n \"direction\": \"{{ $json.direction }}\"\n}",
|
|
"options": {}
|
|
},
|
|
"id": "check-risk",
|
|
"name": "Check Risk",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4,
|
|
"position": [640, 400]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"conditions": {
|
|
"boolean": [
|
|
{
|
|
"value1": "={{ $json.allowed }}",
|
|
"value2": true
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"id": "risk-if",
|
|
"name": "Risk Passed?",
|
|
"type": "n8n-nodes-base.if",
|
|
"typeVersion": 1,
|
|
"position": [840, 400]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "POST",
|
|
"url": "http://10.0.0.48:3001/api/trading/execute",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "Authorization",
|
|
"value": "Bearer 2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb"
|
|
},
|
|
{
|
|
"name": "Content-Type",
|
|
"value": "application/json"
|
|
}
|
|
]
|
|
},
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={\n \"symbol\": \"{{ $('Parse Signal').item.json.symbol }}\",\n \"direction\": \"{{ $('Parse Signal').item.json.direction }}\",\n \"timeframe\": \"{{ $('Parse Signal').item.json.timeframe }}\",\n \"signalStrength\": \"strong\"\n}",
|
|
"options": {
|
|
"timeout": 30000
|
|
}
|
|
},
|
|
"id": "execute-trade",
|
|
"name": "Execute Trade",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4,
|
|
"position": [1040, 300]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"conditions": {
|
|
"boolean": [
|
|
{
|
|
"value1": "={{ $json.success }}",
|
|
"value2": true
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"id": "trade-if",
|
|
"name": "Trade Success?",
|
|
"type": "n8n-nodes-base.if",
|
|
"typeVersion": 1,
|
|
"position": [1240, 300]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"fields": {
|
|
"values": [
|
|
{
|
|
"name": "message",
|
|
"stringValue": "🟢 TRADE OPENED\\n\\n{{ $('Parse Signal').item.json.rawMessage }}\\n\\n📊 Symbol: {{ $('Parse Signal').item.json.symbol }}\\n📈 Direction: {{ $('Parse Signal').item.json.direction }}\\n⏰ {{ $now.toFormat('HH:mm') }}\\n\\n✅ Position monitored automatically"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"id": "format-success",
|
|
"name": "Format Success",
|
|
"type": "n8n-nodes-base.set",
|
|
"typeVersion": 3.2,
|
|
"position": [1440, 200]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"fields": {
|
|
"values": [
|
|
{
|
|
"name": "message",
|
|
"stringValue": "🔴 TRADE FAILED\\n\\n{{ $('Parse Signal').item.json.rawMessage }}\\n\\n❌ Error: {{ $json.error || $json.message }}\\n⏰ {{ $now.toFormat('HH:mm') }}"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"id": "format-error",
|
|
"name": "Format Error",
|
|
"type": "n8n-nodes-base.set",
|
|
"typeVersion": 3.2,
|
|
"position": [1440, 400]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"fields": {
|
|
"values": [
|
|
{
|
|
"name": "message",
|
|
"stringValue": "⚠️ TRADE BLOCKED\\n\\n{{ $('Parse Signal').item.json.rawMessage }}\\n\\n🛑 Risk limits exceeded\\n⏰ {{ $now.toFormat('HH:mm') }}"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"id": "format-risk",
|
|
"name": "Format Risk",
|
|
"type": "n8n-nodes-base.set",
|
|
"typeVersion": 3.2,
|
|
"position": [1040, 500]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"chatId": "579304651",
|
|
"text": "={{ $json.message }}",
|
|
"additionalFields": {
|
|
"appendAttribution": false
|
|
}
|
|
},
|
|
"id": "telegram-success",
|
|
"name": "Telegram Success",
|
|
"type": "n8n-nodes-base.telegram",
|
|
"typeVersion": 1.1,
|
|
"position": [1640, 200],
|
|
"credentials": {
|
|
"telegramApi": {
|
|
"id": "Csk5cg4HtaSqP5jJ",
|
|
"name": "Telegram account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"chatId": "579304651",
|
|
"text": "={{ $json.message }}",
|
|
"additionalFields": {
|
|
"appendAttribution": false
|
|
}
|
|
},
|
|
"id": "telegram-error",
|
|
"name": "Telegram Error",
|
|
"type": "n8n-nodes-base.telegram",
|
|
"typeVersion": 1.1,
|
|
"position": [1640, 400],
|
|
"credentials": {
|
|
"telegramApi": {
|
|
"id": "Csk5cg4HtaSqP5jJ",
|
|
"name": "Telegram account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"chatId": "579304651",
|
|
"text": "={{ $json.message }}",
|
|
"additionalFields": {
|
|
"appendAttribution": false
|
|
}
|
|
},
|
|
"id": "telegram-risk",
|
|
"name": "Telegram Risk",
|
|
"type": "n8n-nodes-base.telegram",
|
|
"typeVersion": 1.1,
|
|
"position": [1240, 500],
|
|
"credentials": {
|
|
"telegramApi": {
|
|
"id": "Csk5cg4HtaSqP5jJ",
|
|
"name": "Telegram account"
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"connections": {
|
|
"Webhook": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Parse Signal",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Parse Signal": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Check Risk",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Check Risk": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Risk Passed?",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Risk Passed?": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Execute Trade",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "Format Risk",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Execute Trade": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Trade Success?",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Trade Success?": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Format Success",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "Format Error",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Format Success": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Telegram Success",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Format Error": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Telegram Error",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Format Risk": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Telegram Risk",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
}
|
|
},
|
|
"pinData": {},
|
|
"active": false,
|
|
"settings": {
|
|
"executionOrder": "v1"
|
|
},
|
|
"versionId": "1",
|
|
"tags": []
|
|
}
|