A robust Go application for receiving real-time market data from TradingView's WebSocket API with comprehensive data persistence and HTTP API support.
- Real-time market data streaming with comprehensive quote data
- Support for multiple symbols and exchanges (NASDAQ, BINANCE, HKEX, etc.)
- Automatic WebSocket connection handling with intelligent reconnection
- Dynamic symbol management (add/remove symbols during runtime)
- Database integration with PostgreSQL for historical data
- High-performance caching with Ristretto for real-time quotes
- REST API for data access and subscription management
- Clean interfaces for better testability and dependency injection
- Message router pattern for extensible message processing
- Structured error handling with context and retry logic
- Comprehensive input validation for security and data integrity
- Advanced configuration system with YAML, environment variables, and CLI flags
- Development tooling with Makefile automation and live reload
- Last price and timestamp
- Price change and percentage
- Trading volume and market cap
- Currency information
- Exchange details and session status
- OHLCV candlestick data
- Bid/ask prices and sizes
go get github.com/iiiyu/tradingview-ws-client# Clone the repository
git clone https://github.com/iiiyu/tradingview-ws-client
cd tradingview-ws-client
# Install development tools and dependencies
make setup
# Copy example configuration
cp config.example.yaml config.yamlEdit config.yaml with your settings:
server:
port: "3333"
environment: "development"
database:
host: "localhost"
port: 5432
user: "postgres"
password: "your_password"
db_name: "tradingview"
ssl_mode: "disable"
tradingview:
device_token: "your_device_token_here"
session_id: "your_session_id_here"
session_sign: "your_session_signature_here"
logging:
level: "info"
format: "json"Or use environment variables:
# Database Configuration
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your_password
DB_NAME=tradingview
DB_SSLMODE=disable
# TradingView Configuration (Required)
TRADINGVIEW_DEVICE_TOKEN=your_device_token
TRADINGVIEW_SESSION_ID=your_session_id
TRADINGVIEW_SESSION_SIGN=your_session_signature
# Optional Server Configuration
PORT=3333
LOG_LEVEL=info# Development mode with live reload
make dev
# Or run directly
make run
# Or build and run
make build
./bin/tradingview-ws-clientmake help # Show all available commands
make dev # Start development server with live reload
make build # Build the application
make test # Run tests
make test-cover # Run tests with coverage
make lint # Run linter
make fmt # Format code
make clean # Clean build artifacts
make docker-build # Build Docker image├── cmd/
│ ├── app/ # Main application
│ └── example/ # Example client usage
├── internal/
│ ├── config/ # Configuration management
│ ├── handler/ # HTTP API handlers
│ └── service/ # Business logic
├── pkg/
│ └── tvwsclient/ # WebSocket client library
├── ent/ # Database schema and ORM
├── docs/ # Documentation
└── deploy/ # Deployment configurations
GET /health# Add a symbol subscription
POST /symbols
{
"exchange": "NASDAQ",
"symbol": "AAPL",
"type": "quote" # or "candle"
"timeframe": "1D" # required for candle type
}
# Remove a symbol subscription
DELETE /symbols
{
"exchange": "NASDAQ",
"symbol": "AAPL",
"type": "quote"
}
# List active subscriptions
GET /symbols
# Get subscriptions by exchange/symbol
GET /symbols/NASDAQ/AAPL# Get real-time quote data
GET /quotes/NASDAQ/AAPL
# Get historical candlestick data
GET /candles/NASDAQ/AAPL/1D/100 # exchange/symbol/timeframe/limit
# Force reconnection
GET /reconnectpackage main
import (
"context"
"log/slog"
tvws "github.com/iiiyu/tradingview-ws-client/pkg/tvwsclient"
)
func main() {
// Create client with options
client, err := tvws.NewClient(
tvws.WithMaxRetries(5),
tvws.WithPingInterval(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
defer client.Close()
// Create data channel
dataChan := make(chan tvws.TVResponse, 1000)
// Start reading messages
go func() {
if err := client.ReadMessage(dataChan); err != nil {
slog.Error("Error reading messages", "error", err)
}
}()
// Subscribe to symbols
session := tvws.GenerateSession("qs_")
if err := tvws.SubscriptionQuoteSessionSymbol(client, session, "NASDAQ:AAPL"); err != nil {
log.Fatal(err)
}
// Process incoming data
for data := range dataChan {
slog.Info("Received data", "method", data.Method)
}
}// Clean interfaces for better testability
type TradingViewClient interface {
ReadMessage(chan<- TVResponse) error
Close() error
Reconnect() error
}
type MessageHandler interface {
HandleQuoteData(context.Context, *QuoteDataMessage) error
HandleTimescaleUpdate(context.Context, *TimescaleUpdateMessage) error
}// Extensible message routing
router := tvwsclient.NewMessageRouter(logger)
router.RegisterHandler(tvwsclient.MethodQuoteData, quoteHandler)
router.RegisterHandler(tvwsclient.MethodTimescaleUpdate, candleHandler)// Context-aware error handling
if err := client.Connect(); err != nil {
if tvwsclient.IsConnectionError(err) {
// Handle connection errors specifically
}
if tvwsclient.IsRetryableError(err) {
// Retry logic
}
}- WebSocket Connection → Real-time data from TradingView
- Message Router → Routes messages to appropriate handlers
- Data Processing → Quote data cached, candle data persisted
- REST API → Provides access to cached quotes and historical candles
- Database → PostgreSQL for persistent storage
- Command line flags:
--server.port=3333 - Environment variables:
PORT=3333 - Configuration file:
config.yaml - Default values
server:
port: "3333"
host: "0.0.0.0"
environment: "development" # development, staging, production
read_timeout: "30s"
write_timeout: "30s"
database:
host: "localhost"
port: 5432
user: "postgres"
password: "secret"
db_name: "tradingview"
ssl_mode: "disable"
max_open_conns: 25
max_idle_conns: 5
tradingview:
device_token: "required"
session_id: "required"
session_sign: "required"
base_url: "https://www.tradingview.com"
websocket:
url: "wss://prodata.tradingview.com/socket.io/websocket?from=screener%2F"
max_retries: 5
ping_interval: "30s"
read_timeout: "60s"
cache:
max_cost: 1073741824 # 1GB
num_counters: 10000000
default_ttl: "1h"
logging:
level: "info" # debug, info, warn, error
format: "json" # json, text# Build Docker image
make docker-build
# Run with Docker
docker run -p 3333:3333 \
-e DB_HOST=host.docker.internal \
-e TRADINGVIEW_DEVICE_TOKEN=your_token \
-e TRADINGVIEW_SESSION_ID=your_session_id \
-e TRADINGVIEW_SESSION_SIGN=your_signature \
tradingview-ws-client:latest- All API inputs are validated with structured error responses
- Path parameters validated for format and length
- Request body validation with detailed error messages
- Sensitive values excluded from logs
- Environment variable support for secrets
- Configuration validation on startup
# Run all tests
make test
# Run tests with coverage
make test-cover
# Run benchmarks
make benchmark
# Run with race detection
make test-race# Basic health check
curl http://localhost:3333/health
# Application info
make info- Structured JSON logging with slog
- Configurable log levels
- Request/response logging for HTTP API
- WebSocket connection event logging
- Structured errors with codes and context
- Retryable error detection for automatic recovery
- Error classification for better debugging
- Context preservation through error chains
CONNECTION_ERROR: WebSocket connection issuesAUTH_ERROR: Authentication failuresVALIDATION_ERROR: Input validation failuresRATE_LIMIT_ERROR: Rate limitingTIMEOUT_ERROR: Operation timeouts
See cmd/example/main.go for a comprehensive example showing:
- Configuration setup
- WebSocket client initialization
- Symbol subscription
- Data processing
- Error handling
# Subscribe to Apple stock quotes
curl -X POST http://localhost:3333/symbols \
-H "Content-Type: application/json" \
-d '{"exchange":"NASDAQ","symbol":"AAPL","type":"quote"}'
# Get real-time quote data
curl http://localhost:3333/quotes/NASDAQ/AAPL
# Subscribe to Bitcoin candlestick data
curl -X POST http://localhost:3333/symbols \
-H "Content-Type: application/json" \
-d '{"exchange":"BINANCE","symbol":"BTCUSDT","type":"candle","timeframe":"1D"}'
# Get historical candle data
curl http://localhost:3333/candles/BINANCE/BTCUSDT/1D/50- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
make test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow Go best practices and idioms
- Add tests for new functionality
- Update documentation for API changes
- Use the provided Makefile commands
- Ensure all checks pass (
make check)
- Go 1.24+
- PostgreSQL 12+
- TradingView credentials (device token, session ID, session signature)
This project is licensed under the MIT License - see the LICENSE file for details.
- Project Documentation
- Configuration Examples
- Deployment Guide
- Architecture Overview
- API Documentation
If you encounter any issues:
- Check the troubleshooting guide
- Review the configuration examples
- Enable debug logging (
LOG_LEVEL=debug) - Open an issue with detailed information
- WebSocket API for real-time data streaming
- GraphQL API support
- Advanced charting integrations
- Multi-exchange aggregation
- Real-time alerting system
- Performance dashboards
- Kubernetes deployment manifests