- Documented bug where phantom auto-closure sets status='phantom' but left exitReason=NULL - Startup validator only checks exitReason, not status field - Ghost positions created false runner stop loss alerts (232% size mismatch) - Fix: MUST set exitReason when closing phantom trades - Manual cleanup: UPDATE Trade SET exitReason='manual' WHERE status='phantom' AND exitReason IS NULL - Verified: System now shows 'Found 0 open trades' after cleanup
393 lines
13 KiB
Bash
393 lines
13 KiB
Bash
# Trading Bot v4 - Environment Variables Template
|
||
# Copy this file to .env.local and fill in your values
|
||
#
|
||
# IMPORTANT: Never commit .env.local to git!
|
||
|
||
# ================================
|
||
# REQUIRED - DRIFT PROTOCOL TRADING
|
||
# ================================
|
||
|
||
# Your Solana wallet private key (base58 format)
|
||
# ⚠️ SECURITY: Use a dedicated trading wallet with limited funds
|
||
# Get from: Phantom → Settings → Export Private Key
|
||
# Or: solana-keygen new --outfile ~/trading-wallet.json
|
||
DRIFT_WALLET_PRIVATE_KEY=[91,24,199,66,154,166,231,159,121,123,20,165,118,229,96,114,145,170,28,1,59,164,186,37,170,234,46,107,26,119,205,206,39,1,96,252,82,190,199,68,182,144,131,53,153,66,255,138,238,57,28,249,224,239,172,252,157,230,171,224,154,252,142,171]
|
||
|
||
# Drift environment
|
||
# Options: mainnet-beta (production), devnet (testing)
|
||
DRIFT_ENV=mainnet-beta
|
||
|
||
# Drift Program ID (default - don't change unless using custom program)
|
||
DRIFT_PROGRAM_ID=dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH
|
||
|
||
# API secret key for authenticating n8n webhook requests
|
||
# Generate with: openssl rand -hex 32
|
||
# Or: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
||
API_SECRET_KEY=2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb
|
||
|
||
# ================================
|
||
# REQUIRED - SOLANA RPC ENDPOINT
|
||
# ================================
|
||
|
||
# Solana RPC URL (Required for blockchain access)
|
||
#
|
||
# PRIMARY: Helius (ONLY PROVIDER THAT WORKS RELIABLY)
|
||
# Drift SDK REQUIRES WebSocket subscriptions - Alchemy doesn't support this
|
||
# Alchemy "working" state was temporary - always breaks after first trade or shortly after init
|
||
SOLANA_RPC_URL=https://solana-mainnet.g.alchemy.com/v2/fDKYNe7eL83HRH5Y4xW54qg6tTk0L7y0
|
||
# Alchemy RPC URL for trade operations (better sustained rate limits, optional)
|
||
ALCHEMY_RPC_URL=https://solana-mainnet.g.alchemy.com/v2/fDKYNe7eL83HRH5Y4xW54qg6tTk0L7y0
|
||
|
||
# Alternative RPC providers (reference):
|
||
#
|
||
# QuickNode: https://solana-mainnet.quiknode.pro/YOUR_ENDPOINT/
|
||
# Alchemy: https://solana-mainnet.g.alchemy.com/v2/YOUR_ALCHEMY_KEY
|
||
# Ankr: https://rpc.ankr.com/solana
|
||
# Public (not recommended): https://api.mainnet-beta.solana.com
|
||
|
||
# ================================
|
||
# REQUIRED - PYTH NETWORK (Price Feeds)
|
||
# ================================
|
||
|
||
# Pyth Hermes WebSocket endpoint (for real-time prices)
|
||
# Default: https://hermes.pyth.network (no API key needed)
|
||
PYTH_HERMES_URL=https://hermes.pyth.network
|
||
|
||
# Alternative Pyth endpoints:
|
||
# Stable: https://hermes-beta.pyth.network
|
||
# Devnet: https://hermes-dev.pyth.network
|
||
|
||
# ================================
|
||
# TRADING CONFIGURATION (Optional - Override defaults)
|
||
# ================================
|
||
|
||
# Position sizing
|
||
# Base position size in USD (default: 50 for safe testing)
|
||
# Example: 50 with 10x leverage = $500 notional position
|
||
MAX_POSITION_SIZE_USD=210
|
||
|
||
# Leverage multiplier (1-20, default: 10)
|
||
# Higher leverage = bigger gains AND bigger losses
|
||
LEVERAGE=10
|
||
|
||
# Risk parameters (as percentages)
|
||
# Stop Loss: Close 100% of position when price drops this much
|
||
# Example: -1.5% on 10x = -15% account loss
|
||
STOP_LOSS_PERCENT=-1
|
||
|
||
# ================================
|
||
# DUAL STOP SYSTEM (Advanced)
|
||
# ================================
|
||
# Enable dual stop system to avoid wicks while guaranteeing exit
|
||
# When enabled, places TWO stop orders:
|
||
# 1. Soft Stop (TRIGGER_LIMIT) - Avoids false breakouts/wicks
|
||
# 2. Hard Stop (TRIGGER_MARKET) - Guarantees exit if price keeps falling
|
||
USE_DUAL_STOPS=true
|
||
|
||
# Soft Stop (Primary, Stop-Limit)
|
||
# Triggers first, tries to avoid wicks
|
||
SOFT_STOP_PERCENT=-1.5
|
||
SOFT_STOP_BUFFER=0.4 # Buffer between trigger and limit (0.4% = limit at -1.9%)
|
||
|
||
# Hard Stop (Backup, Stop-Market)
|
||
# Only triggers if soft stop doesn't fill
|
||
# Guarantees exit during strong breakdowns
|
||
HARD_STOP_PERCENT=-2.5
|
||
|
||
# Take Profit 1: Close 50% of position at this profit level
|
||
# Example: +0.7% on 10x = +7% account gain
|
||
TAKE_PROFIT_1_PERCENT=0.4
|
||
|
||
# Take Profit 1 Size: What % of position to close at TP1
|
||
# Example: 50 = close 50% of position
|
||
TAKE_PROFIT_1_SIZE_PERCENT=70
|
||
|
||
# Take Profit 2: Close remaining 50% at this profit level
|
||
# Example: +1.5% on 10x = +15% account gain
|
||
TAKE_PROFIT_2_PERCENT=0.7
|
||
|
||
# Take Profit 2 Size: What % of remaining position to close at TP2
|
||
# Example: 100 = close all remaining position
|
||
TAKE_PROFIT_2_SIZE_PERCENT=0
|
||
|
||
# ATR-based dynamic targets (capture big moves like 4-5% drops)
|
||
# Enable dynamic TP2 based on market volatility
|
||
USE_ATR_BASED_TARGETS=true
|
||
|
||
# ATR multiplier for TP2 calculation (TP2 = ATR × this value)
|
||
# Example: ATR=0.8% × 2.0 = 1.6% TP2 target
|
||
ATR_MULTIPLIER_FOR_TP2=2
|
||
|
||
# Minimum TP2 level regardless of ATR (safety floor)
|
||
MIN_TP2_PERCENT=0.7
|
||
|
||
# Maximum TP2 level cap (prevents excessive targets)
|
||
# Example: 3.0% = 30% account gain at 10x leverage
|
||
MAX_TP2_PERCENT=3
|
||
|
||
# Emergency Stop: Hard stop if this level is breached
|
||
# Example: -2.0% on 10x = -20% account loss (rare but protects from flash crashes)
|
||
EMERGENCY_STOP_PERCENT=-2
|
||
|
||
# Dynamic stop-loss adjustments
|
||
# Move SL to breakeven when profit reaches this level
|
||
PROFIT_LOCK_AFTER_TP1_PERCENT=0.3 # Lock this % profit on remaining position after TP1 (was BREAKEVEN_TRIGGER_PERCENT)
|
||
|
||
# Lock in profit when price reaches this level
|
||
PROFIT_LOCK_TRIGGER_PERCENT=1
|
||
|
||
# How much profit to lock (move SL to this profit level)
|
||
PROFIT_LOCK_PERCENT=0.6
|
||
|
||
# Risk limits
|
||
# Stop trading if daily loss exceeds this amount (USD)
|
||
# Example: -150 = stop trading after losing $150 in a day
|
||
MAX_DAILY_DRAWDOWN=-1000
|
||
|
||
# Maximum number of trades allowed per hour (prevents overtrading)
|
||
MAX_TRADES_PER_HOUR=20
|
||
|
||
# Minimum time between trades in minutes (cooldown period)
|
||
# Example: 10 = 10 minutes between trades
|
||
MIN_TIME_BETWEEN_TRADES=1
|
||
|
||
# DEX execution settings
|
||
# Maximum acceptable slippage on market orders (percentage)
|
||
# Example: 1.0 = accept up to 1% slippage
|
||
SLIPPAGE_TOLERANCE=0.15
|
||
|
||
# How often to check prices (milliseconds)
|
||
# Example: 2000 = check every 2 seconds
|
||
PRICE_CHECK_INTERVAL_MS=2000
|
||
|
||
# Order confirmation timeout (milliseconds)
|
||
# Example: 30000 = wait up to 30 seconds for order confirmation
|
||
CONFIRMATION_TIMEOUT_MS=30000
|
||
|
||
# ================================
|
||
# N8N WORKFLOW INTEGRATION (Optional but recommended)
|
||
# ================================
|
||
|
||
# n8n instance URL (for workflow automation)
|
||
# Get from: https://n8n.io (cloud) or self-hosted
|
||
# Example: https://your-username.app.n8n.cloud
|
||
N8N_WEBHOOK_URL=https://flow.egonetix.de/webhook/3371ad7c-0866-4161-90a4-f251de4aceb8
|
||
|
||
# n8n API key (if using n8n API directly)
|
||
N8N_API_KEY=your_n8n_api_key
|
||
|
||
# TradingView webhook secret (for validating incoming alerts)
|
||
# Must match the secret in your TradingView alert URL
|
||
# Generate with: openssl rand -hex 16
|
||
TRADINGVIEW_WEBHOOK_SECRET=your_tradingview_webhook_secret
|
||
|
||
# ================================
|
||
# NOTIFICATIONS (Optional - for trade alerts)
|
||
# ================================
|
||
|
||
# Telegram Bot (recommended for mobile alerts)
|
||
# 1. Create bot: Message @BotFather on Telegram, send /newbot
|
||
# 2. Get token from BotFather
|
||
# 3. Get chat ID: Message @userinfobot or your bot, it will show your chat ID
|
||
TELEGRAM_BOT_TOKEN=8240234365:AAEm6hg_XOm54x8ctnwpNYreFKRAEvWU3uY
|
||
TELEGRAM_CHAT_ID=579304651
|
||
|
||
# Discord Webhook (good for team channels)
|
||
# 1. Go to Discord channel settings
|
||
# 2. Integrations → Webhooks → New Webhook
|
||
# 3. Copy webhook URL
|
||
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN
|
||
|
||
# Email (SMTP) - for important alerts
|
||
# Gmail setup:
|
||
# 1. Enable 2FA on your Google account
|
||
# 2. Generate App Password: https://myaccount.google.com/apppasswords
|
||
# 3. Use the 16-character app password below
|
||
EMAIL_SMTP_HOST=smtp.gmail.com
|
||
EMAIL_SMTP_PORT=587
|
||
EMAIL_SMTP_SECURE=false
|
||
EMAIL_FROM=your-email@gmail.com
|
||
EMAIL_TO=notification-email@gmail.com
|
||
EMAIL_USER=your-email@gmail.com
|
||
EMAIL_PASSWORD=your_16_character_app_password
|
||
|
||
# Other SMTP providers:
|
||
# Outlook: smtp-mail.outlook.com:587
|
||
# Yahoo: smtp.mail.yahoo.com:587
|
||
# SendGrid: smtp.sendgrid.net:587
|
||
|
||
# ================================
|
||
# DATABASE (Optional - Phase 3 feature)
|
||
# ================================
|
||
|
||
# PostgreSQL connection string
|
||
# Format: postgresql://username:password@host:port/database
|
||
#
|
||
# IMPORTANT: Use different URLs for different environments:
|
||
# - Docker container (runtime): trading-bot-postgres (container name)
|
||
# - Local development (Prisma CLI): localhost:5432
|
||
#
|
||
# The URL below is for Docker runtime. For Prisma migrations from host:
|
||
# DATABASE_URL="postgresql://postgres:postgres@localhost:5432/trading_bot_v4" npx prisma migrate dev
|
||
#
|
||
# PostgreSQL Database (for trade history and analytics)
|
||
DATABASE_URL=postgresql://postgres:postgres@trading-bot-postgres:5432/trading_bot_v4
|
||
|
||
# Cloud PostgreSQL providers:
|
||
# - Supabase: https://supabase.com (free tier available)
|
||
# - Neon: https://neon.tech (serverless, free tier)
|
||
# - Railway: https://railway.app
|
||
# - Heroku Postgres
|
||
|
||
# Database connection pool settings (optional)
|
||
DATABASE_POOL_MIN=2
|
||
DATABASE_POOL_MAX=10
|
||
|
||
# ================================
|
||
# SECURITY & ACCESS CONTROL
|
||
# ================================
|
||
|
||
# JWT secret for API authentication (if implementing auth)
|
||
# Generate with: openssl rand -hex 64
|
||
JWT_SECRET=your_jwt_secret_here
|
||
|
||
# Allowed origins for CORS (comma-separated)
|
||
# Example: http://localhost:3000,https://yourdomain.com
|
||
ALLOWED_ORIGINS=http://localhost:3000
|
||
|
||
# Rate limiting (requests per minute)
|
||
RATE_LIMIT_PER_MINUTE=60
|
||
|
||
# IP whitelist (comma-separated, leave empty to allow all)
|
||
# Example: 192.168.1.100,10.0.0.5
|
||
IP_WHITELIST=
|
||
|
||
# ================================
|
||
# DEVELOPMENT & DEBUGGING
|
||
# ================================
|
||
|
||
# Node environment (development, production, test)
|
||
NODE_ENV=production
|
||
|
||
# Log level (debug, info, warn, error)
|
||
# Use 'debug' for detailed logs during development
|
||
LOG_LEVEL=info
|
||
|
||
# Enable detailed logging for specific modules
|
||
DEBUG=drift:*,pyth:*,trading:*
|
||
|
||
# Enable dry run mode (simulate trades without executing)
|
||
# Set to 'true' for testing without real money
|
||
DRY_RUN=false
|
||
|
||
# API server port (default: 3000)
|
||
PORT=3000
|
||
|
||
# Enable performance monitoring
|
||
ENABLE_METRICS=false
|
||
|
||
# Sentry DSN (for error tracking in production)
|
||
SENTRY_DSN=
|
||
|
||
# ================================
|
||
# MONITORING & ANALYTICS (Optional)
|
||
# ================================
|
||
|
||
# DataDog API key (for metrics and logs)
|
||
DATADOG_API_KEY=
|
||
|
||
# Grafana Cloud endpoint
|
||
GRAFANA_ENDPOINT=
|
||
|
||
# New Relic license key
|
||
NEW_RELIC_LICENSE_KEY=
|
||
|
||
# ================================
|
||
# NOTES & QUICK REFERENCE
|
||
# ================================
|
||
|
||
# Typical Production Setup:
|
||
# - MAX_POSITION_SIZE_USD=1000 (start with $1k)
|
||
# - LEVERAGE=10 (10x multiplier)
|
||
# - Helius RPC (best performance)
|
||
# - Telegram notifications enabled
|
||
# - DRY_RUN=false
|
||
# - LOG_LEVEL=info
|
||
#
|
||
# Safe Testing Setup:
|
||
# - MAX_POSITION_SIZE_USD=50 (only $50 per trade)
|
||
# - LEVERAGE=10 (still test with leverage)
|
||
# - DRY_RUN=false (test with real tiny amounts)
|
||
# - LOG_LEVEL=debug (see everything)
|
||
#
|
||
# Recommended Daily Limits:
|
||
# - MAX_DAILY_DRAWDOWN=-150 (stop at -15% loss)
|
||
# - MAX_TRADES_PER_HOUR=6 (prevent overtrading)
|
||
# - MIN_TIME_BETWEEN_TRADES=10 (10min cooldown)
|
||
#
|
||
# Expected Risk Per Trade (with defaults):
|
||
# - Max Loss: $7.50 (50 * 10 * 0.015)
|
||
# - TP1 Gain: $3.50 (50 * 10 * 0.007)
|
||
# - TP2 Gain: $7.50 (50 * 10 * 0.015)
|
||
# - Full Win: $11.00 (TP1 + TP2)
|
||
#
|
||
# Getting API Keys:
|
||
# - Helius: https://helius.dev (free tier: 100k requests/day)
|
||
# - Telegram: @BotFather on Telegram
|
||
# - Discord: Channel Settings → Integrations → Webhooks
|
||
# - Gmail: myaccount.google.com/apppasswords (need 2FA enabled)
|
||
#
|
||
# Testing Checklist:
|
||
# [ ] Copy this file to .env.local
|
||
# [ ] Fill in DRIFT_WALLET_PRIVATE_KEY
|
||
# [ ] Fill in SOLANA_RPC_URL (Helius recommended)
|
||
# [ ] Fill in API_SECRET_KEY (random 32-byte hex)
|
||
# [ ] Set MAX_POSITION_SIZE_USD=50 for testing
|
||
# [ ] Run: npx tsx v4/test-price-monitor.ts
|
||
# [ ] Run: npx tsx v4/test-position-manager.ts
|
||
# [ ] Run: npx tsx v4/test-full-flow.ts (careful: real trade!)
|
||
# [ ] Configure TradingView alerts
|
||
# [ ] Import n8n-workflow-v4.json
|
||
# [ ] Test with manual TradingView alert
|
||
#
|
||
# Security Reminders:
|
||
# ⚠️ Never commit .env.local to git
|
||
# ⚠️ Use a dedicated trading wallet
|
||
# ⚠️ Start with small position sizes
|
||
# ⚠️ Keep private keys secure
|
||
# ⚠️ Use hardware wallet for large amounts
|
||
# ⚠️ Rotate API keys regularly
|
||
# ⚠️ Monitor for suspicious activity
|
||
#
|
||
# Support & Documentation:
|
||
# - v4/README.md - Project overview
|
||
# - v4/SETUP.md - Detailed setup guide
|
||
# - v4/TESTING.md - Testing procedures
|
||
# - v4/QUICKREF_PHASE2.md - Quick reference
|
||
# - TRADING_BOT_V4_MANUAL.md - Complete manual
|
||
# - PHASE_2_COMPLETE_REPORT.md - Feature summary
|
||
|
||
USE_TRAILING_STOP=true
|
||
TRAILING_STOP_PERCENT=0.3
|
||
TRAILING_STOP_ACTIVATION=0.4
|
||
MIN_QUALITY_SCORE=60
|
||
SOLANA_ENABLED=true
|
||
SOLANA_POSITION_SIZE=50
|
||
SOLANA_LEVERAGE=1
|
||
SOLANA_USE_PERCENTAGE_SIZE=true
|
||
ETHEREUM_ENABLED=false
|
||
ETHEREUM_POSITION_SIZE=50
|
||
ETHEREUM_LEVERAGE=1
|
||
ETHEREUM_USE_PERCENTAGE_SIZE=false
|
||
ENABLE_POSITION_SCALING=false
|
||
MIN_SCALE_QUALITY_SCORE=75
|
||
MIN_PROFIT_FOR_SCALE=0.4
|
||
MAX_SCALE_MULTIPLIER=2
|
||
SCALE_SIZE_PERCENT=50
|
||
MIN_ADX_INCREASE=5
|
||
MAX_PRICE_POSITION_FOR_SCALE=70
|
||
TRAILING_STOP_ATR_MULTIPLIER=1.5
|
||
TRAILING_STOP_MIN_PERCENT=0.25
|
||
TRAILING_STOP_MAX_PERCENT=0.9
|
||
USE_PERCENTAGE_SIZE=false
|