Skip to content
Back to skills

2134 Track Price 50e6e54c

ASecurity

Track real-time prices across crypto, stocks, forex, and commodities with...

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
datajavascriptgojavagitapi

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2134-track-price_50e6e54c --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2134 Track Price 50e6e54c?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2134 Track Price 50e6e54c
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2134-track-price-50e6e54c/badge)](https://www.skillsdirectory.com/skills/tools-only-2134-track-price-50e6e54c)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
---
name: track-price
description: >
  Track real-time prices across crypto, stocks, forex, and commodities
  with...
shortcut: tp
---
# Track Market Price

Real-time price tracking system with institutional-grade data feeds from multiple sources for accuracy and reliability.

## Usage

When the user wants to track market prices, implement a comprehensive price monitoring system with these capabilities:

### Required Information
- **Symbol**: Asset ticker (BTC, AAPL, EUR/USD, etc.)
- **Asset Type**: crypto, stock, forex, commodity
- **Interval**: 1s, 5s, 30s, 1m, 5m (real-time streaming)
- **Exchanges**: Specific exchanges or "ALL" for aggregate
- **Alert Conditions**: Price thresholds, percentage changes
- **Duration**: How long to track (continuous or time-limited)

## Implementation

### 1. Multi-Source Price Aggregator

```javascript
class MarketPriceTracker {
    constructor() {
        this.dataSources = {
            crypto: {
                binance: 'wss://stream.binance.com:9443/ws',
                coinbase: 'wss://ws-feed.exchange.coinbase.com',
                kraken: 'wss://ws.kraken.com',
                ftx: 'wss://ftx.com/ws/',
                coingecko: 'https://api.coingecko.com/api/v3',
                messari: 'https://data.messari.io/api/v1'
            },
            stocks: {
                alphaVantage: process.env.ALPHA_VANTAGE_API,
                iex: 'https://api.iextrading.com/1.0',
                polygon: 'wss://socket.polygon.io',
                finnhub: 'wss://ws.finnhub.io',
                yahoo: 'https://query1.finance.yahoo.com/v8'
            },
            forex: {
                oanda: 'wss://stream-fxtrade.oanda.com',
                forexConnect: 'https://api-fxtrade.oanda.com/v3',
                currencyLayer: process.env.CURRENCY_LAYER_API,
                exchangeRates: 'https://api.exchangerate.host'
            },
            commodities: {
                quandl: process.env.QUANDL_API,
                metalsPrices: 'https://api.metals.live/v1',
                oilPrices: 'https://api.oilpriceapi.com/v1'
            }
        };

        this.priceCache = new Map();
        this.connections = new Map();
        this.aggregationStrategy = 'VWAP'; // Volume Weighted Average Price
    }

    async trackPrice(params) {
        const {
            symbol,
            assetType,
            interval = '1s',
            exchanges = 'ALL',
            alertConditions = [],
            duration = 'continuous'
        } = params;

        // Validate symbol format
        this.validateSymbol(symbol, assetType);

        // Initialize tracking
        const trackingSession = {
            id: crypto.randomUUID(),
            symbol,
            assetType,
            interval,
            startTime: Date.now(),
            duration,
            exchanges: this.selectExchanges(exchanges, assetType),
            alerts: this.parseAlertConditions(alertConditions),
            priceHistory: [],
            statistics: {
                high: 0,
                low: Infinity,
                open: 0,
                volume: 0,
                vwap: 0,
                changes: {
                    '1m': 0,
                    '5m': 0,
                    '15m': 0,
                    '1h': 0,
                    '24h': 0
                }
            }
        };

        // Start real-time tracking
        await this.initializeConnections(trackingSession);

        // Begin price aggregation
        this.startPriceAggregation(trackingSession);

        // Monitor alerts
        this.startAlertMonitoring(trackingSession);

        return trackingSession;
    }

    async initializeConnections(session) {
        const connections = [];

        for (const exchange of session.exchanges) {
            try {
                const connection = await this.connectToExchange(
                    exchange,
                    session.symbol,
                    session.assetType
                );

                connections.push({
                    exchange,
                    connection,
                    status: 'connected',
                    latency: 0,
                    lastUpdate: null
                });

                // Subscribe to price updates
                this.subscribeToPrice(connection, session);
            } catch (error) {
                console.error(`Failed to connect to ${exchange}:`, error);
                connections.push({
                    exchange,
                    status: 'failed',
                    error: error.message
                });
            }
        }

        session.connections = connections;
        return connections;
    }

    async connectToExchange(exchange, symbol, assetType) {
        const sourceConfig = this.dataSources[assetType][exchange];

        if (sourceConfig.startsWith('wss://')) {
            // WebSocket connection
            return this.createWebSocketConnection(sourceConfig, symbol, exchange);
        } else {
            // REST API polling
            return this.createPollingConnection(sourceConfig, symbol, exchange);
        }
    }

    createWebSocketConnection(url, symbol, exchange) {
        return new Promise((resolve, reject) => {
            const ws = new WebSocket(url);

            ws.on('open', () => {
                // Subscribe to symbol
                const subscribeMsg = this.getSubscribeMessage(exchange, symbol);
                ws.send(JSON.stringify(subscribeMsg));
                resolve(ws);
            });

            ws.on('error', reject);

            ws.on('message', (data) => {
                this.handlePriceUpdate(exchange, data);
            });
        });
    }

    getSubscribeMessage(exchange, symbol) {
        const messages = {
            binance: {
                method: 'SUBSCRIBE',
                params: [`${symbol.toLowerCase()}@trade`, `${symbol.toLowerCase()}@depth`],
                id: 1
            },
            coinbase: {
                type: 'subscribe',
                product_ids: [symbol],
                channels: ['ticker', 'level2']
            },
            kraken: {
                event: 'subscribe',
                pair: [symbol],
                subscription: { name: 'ticker' }
            }
        };

        return messages[exchange] || {};
    }

    handlePriceUpdate(exchange, data) {
        const parsed = JSON.parse(data);
        const price = this.extractPrice(exchange, parsed);

        if (price) {
            const update = {
                exchange,
                price: price.price,
                volume: price.volume,
                timestamp: Date.now(),
                bid: price.bid,
                ask: price.ask,
                spread: price.ask - price.bid
            };

            // Update cache
            if (!this.priceCache.has(exchange)) {
                this.priceCache.set(exchange, []);
            }
            this.priceCache.get(exchange).push(update);

            // Trigger aggregation
            this.aggregatePrices();
        }
    }

    extractPrice(exchange, data) {
        const extractors = {
            binance: (d) => ({
                price: parseFloat(d.p),
                volume: parseFloat(d.q),
                bid: parseFloat(d.b),
                ask: parseFloat(d.a)
            }),
            coinbase: (d) => ({
                price: parseFloat(d.price),
                volume: parseFloat(d.volume_24h),
                bid: parseFloat(d.best_bid),
                ask: parseFloat(d.best_ask)
            }),
            kraken: (d) => ({
                price: parseFloat(d[1].c[0]),
                volume: parseFloat(d[1].v[1]),
                bid: parseFloat(d[1].b[0]),
                ask: parseFloat(d[1].a[0])
            })
        };

        return extractors[exchange]?.(data);
    }

    aggregatePrices() {
        const allPrices = [];

        for (const [exchange, prices] of this.priceCache.entries()) {
            if (prices.length > 0) {
                const recent = prices.filter(p =>
                    Date.now() - p.timestamp < 5000 // Last 5 seconds
                );
                allPrices.push(...recent);
            }
        }

        if (allPrices.length === 0) return null;

        // Calculate aggregated price based on strategy
        let aggregatedPrice;

        switch (this.aggregationStrategy) {
            case 'VWAP':
                aggregatedPrice = this.calculateVWAP(allPrices);
                break;
            case 'MEDIAN':
                aggregatedPrice = this.calculateMedian(allPrices);
                break;
            case 'WEIGHTED':
                aggregatedPrice = this.calculateWeightedAverage(allPrices);
                break;
            default:
                aggregatedPrice = this.calculateSimpleAverage(allPrices);
        }

        return {
            price: aggregatedPrice,
            sources: allPrices.length,
            timestamp: Date.now(),
            spread: this.calculateSpread(allPrices),
            confidence: this.calculateConfidence(allPrices)
        };
    }

    calculateVWAP(prices) {
        let totalValue = 0;
        let totalVolume = 0;

        for (const p of prices) {
            totalValue += p.price * p.volume;
            totalVolume += p.volume;
        }

        return totalVolume > 0 ? totalValue / totalVolume : 0;
    }

    calculateConfidence(prices) {
        if (prices.length < 2) return 0;

        const values = prices.map(p => p.price);
        const mean = values.reduce((a, b) => a + b) / values.length;
        const variance = values.reduce((sum, val) =>
            sum + Math.pow(val - mean, 2), 0) / values.length;
        const stdDev = Math.sqrt(variance);
        const coefficientOfVariation = (stdDev / mean) * 100;

        // Lower CV means higher confidence
        if (coefficientOfVariation < 0.5) return 99;
        if (coefficientOfVariation < 1) return 95;
        if (coefficientOfVariation < 2) return 90;
        if (coefficientOfVariation < 5) return 75;
        return 50;
    }

    startAlertMonitoring(session) {
        const checkInterval = this.parseInterval(session.interval);

        session.alertMonitor = setInterval(() => {
            const currentPrice = this.getCurrentPrice(session.symbol);
            if (!currentPrice) return;

            for (const alert of session.alerts) {
                if (this.checkAlertCondition(alert, currentPrice, session)) {
                    this.triggerAlert(alert, currentPrice, session);
                }
            }
        }, checkInterval);
    }

    checkAlertCondition(alert, price, session) {
        switch (alert.type) {
            case 'PRICE_ABOVE':
                return price.price > alert.threshold;

            case 'PRICE_BELOW':
                return price.price < alert.threshold;

            case 'PERCENT_CHANGE':
                const changePercent = this.calculatePercentChange(
                    session.statistics.open,
                    price.price
                );
                return Math.abs(changePercent) > alert.threshold;

            case 'VOLUME_SPIKE':
                return price.volume > session.statistics.avgVolume * alert.multiplier;

            case 'SPREAD_WIDE':
                return price.spread > alert.threshold;

            case 'VOLATILITY':
                return this.calculateVolatility(session) > alert.threshold;

            default:
                return false;
        }
    }

    triggerAlert(alert, price, session) {
        const alertData = {
            id: crypto.randomUUID(),
            type: alert.type,
            symbol: session.symbol,
            price: price.price,
            threshold: alert.threshold,
            timestamp: Date.now(),
            message: this.formatAlertMessage(alert, price, session),
            severity: alert.severity || 'INFO',
            action: alert.action || 'NOTIFY'
        };

        // Send alert through notification channels
        this.sendAlert(alertData);

        // Log alert
        if (!session.triggeredAlerts) {
            session.triggeredAlerts = [];
        }
        session.triggeredAlerts.push(alertData);

        // Execute automated actions if configured
        if (alert.action === 'AUTO_TRADE') {
            this.executeAutomatedAction(alert, price, session);
        }
    }
}
```

### 2. Price Display Interface

```javascript
class PriceDisplay {
    constructor() {
        this.displayMode = 'detailed'; // 'simple', 'detailed', 'professional'
        this.updateFrequency = 1000; // milliseconds
    }

    displayPrice(session, aggregatedPrice) {
        const display = `
╔════════════════════════════════════════════════════════════════╗
║                    REAL-TIME PRICE TRACKER                     ║
╠════════════════════════════════════════════════════════════════╣
║ Symbol:        ${session.symbol.padEnd(48)} ║
║ Asset Type:    ${session.assetType.padEnd(48)} ║
║ Current Price: ${this.formatPrice(aggregatedPrice.price).padEnd(48)} ║
║ Confidence:    ${this.formatConfidence(aggregatedPrice.confidence).padEnd(48)} ║
╠════════════════════════════════════════════════════════════════╣
║                        PRICE METRICS                           ║
╠════════════════════════════════════════════════════════════════╣
║ 24H High:      ${this.formatPrice(session.statistics.high).padEnd(48)} ║
║ 24H Low:       ${this.formatPrice(session.statistics.low).padEnd(48)} ║
║ 24H Change:    ${this.formatChange(session.statistics.changes['24h']).padEnd(48)} ║
║ Volume:        ${this.formatVolume(session.statistics.volume).padEnd(48)} ║
║ VWAP:          ${this.formatPrice(session.statistics.vwap).padEnd(48)} ║
╠════════════════════════════════════════════════════════════════╣
║                      EXCHANGE PRICES                           ║
╠════════════════════════════════════════════════════════════════╣
${this.formatExchangePrices(session)}
╠════════════════════════════════════════════════════════════════╣
║                         ALERTS                                 ║
╠════════════════════════════════════════════════════════════════╣
${this.formatAlerts(session)}
╚════════════════════════════════════════════════════════════════╝
`;
        return display;
    }

    formatExchangePrices(session) {
        const lines = [];
        for (const conn of session.connections) {
            if (conn.status === 'connected' && conn.lastPrice) {
                lines.push(`║ ${conn.exchange.padEnd(15)} ${this.formatPrice(conn.lastPrice).padEnd(15)} ${this.formatLatency(conn.latency).padEnd(26)} ║`);
            }
        }
        return lines.join('\n');
    }

    formatAlerts(session) {
        if (!session.alerts || session.alerts.length === 0) {
            return '║ No active alerts                                               ║';
        }

        const lines = [];
        for (const alert of session.alerts) {
            const status = alert.triggered ? '' : '⏳';
            lines.push(`║ ${status} ${alert.type}: ${alert.threshold}                                     ║`);
        }
        return lines.join('\n');
    }

    formatPrice(price) {
        if (price > 1000) {
            return `$${price.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
        } else if (price > 1) {
            return `$${price.toFixed(4)}`;
        } else {
            return `$${price.toFixed(8)}`;
        }
    }

    formatConfidence(confidence) {
        const bars = '█'.repeat(Math.floor(confidence / 10));
        const empty = '░'.repeat(10 - Math.floor(confidence / 10));
        return `${bars}${empty} ${confidence}%`;
    }
}
```

### 3. Advanced Analytics

```javascript
class PriceAnalytics {
    constructor() {
        this.indicators = {};
        this.patterns = [];
    }

    analyzePrice(priceHistory) {
        return {
            technicalIndicators: this.calculateTechnicalIndicators(priceHistory),
            pricePatterns: this.detectPatterns(priceHistory),
            supportResistance: this.findSupportResistance(priceHistory),
            volatility: this.analyzeVolatility(priceHistory),
            momentum: this.analyzeMomentum(priceHistory),
            marketStructure: this.analyzeMarketStructure(priceHistory)
        };
    }

    calculateTechnicalIndicators(prices) {
        return {
            sma: {
                sma20: this.calculateSMA(prices, 20),
                sma50: this.calculateSMA(prices, 50),
                sma200: this.calculateSMA(prices, 200)
            },
            ema: {
                ema12: this.calculateEMA(prices, 12),
                ema26: this.calculateEMA(prices, 26)
            },
            rsi: this.calculateRSI(prices, 14),
            macd: this.calculateMACD(prices),
            bollingerBands: this.calculateBollingerBands(prices, 20, 2),
            atr: this.calculateATR(prices, 14),
            obv: this.calculateOBV(prices),
            vwap: this.calculateDailyVWAP(prices)
        };
    }

    detectPatterns(prices) {
        const patterns = [];

        // Head and Shoulders
        if (this.detectHeadAndShoulders(prices)) {
            patterns.push({
                type: 'HEAD_AND_SHOULDERS',
                direction: 'BEARISH',
                confidence: 85
            });
        }

        // Double Top/Bottom
        const doublePattern = this.detectDoubleTopBottom(prices);
        if (doublePattern) {
            patterns.push(doublePattern);
        }

        // Triangle Patterns
        const triangle = this.detectTriangle(prices);
        if (triangle) {
            patterns.push(triangle);
        }

        // Flag/Pennant
        const flagPattern = this.detectFlagPennant(prices);
        if (flagPattern) {
            patterns.push(flagPattern);
        }

        return patterns;
    }

    findSupportResistance(prices) {
        const levels = [];
        const priceValues = prices.map(p => p.price);

        // Find local maxima and minima
        for (let i = 2; i < priceValues.length - 2; i++) {
            // Resistance (local maximum)
            if (priceValues[i] > priceValues[i-1] &&
                priceValues[i] > priceValues[i-2] &&
                priceValues[i] > priceValues[i+1] &&
                priceValues[i] > priceValues[i+2]) {
                levels.push({
                    type: 'RESISTANCE',
                    price: priceValues[i],
                    strength: this.calculateLevelStrength(prices, priceValues[i]),
                    touches: this.countTouches(prices, priceValues[i])
                });
            }

            // Support (local minimum)
            if (priceValues[i] < priceValues[i-1] &&
                priceValues[i] < priceValues[i-2] &&
                priceValues[i] < priceValues[i+1] &&
                priceValues[i] < priceValues[i+2]) {
                levels.push({
                    type: 'SUPPORT',
                    price: priceValues[i],
                    strength: this.calculateLevelStrength(prices, priceValues[i]),
                    touches: this.countTouches(prices, priceValues[i])
                });
            }
        }

        // Cluster similar levels
        return this.clusterLevels(levels);
    }
}
```

### 4. Alert Configuration

```javascript
class AlertConfiguration {
    parseAlertConditions(conditions) {
        const parsed = [];

        for (const condition of conditions) {
            if (typeof condition === 'string') {
                // Parse string format: "above 50000", "below 45000", "change 5%"
                const match = condition.match(/(\w+)\s+([0-9.]+)(%)?/);
                if (match) {
                    parsed.push(this.createAlert(match[1], parseFloat(match[2]), match[3] === '%'));
                }
            } else {
                // Object format already
                parsed.push(condition);
            }
        }

        return parsed;
    }

    createAlert(type, value, isPercent) {
        const alertTypes = {
            'above': 'PRICE_ABOVE',
            'below': 'PRICE_BELOW',
            'change': 'PERCENT_CHANGE',
            'volume': 'VOLUME_SPIKE',
            'spread': 'SPREAD_WIDE',
            'volatility': 'VOLATILITY'
        };

        return {
            type: alertTypes[type] || 'CUSTOM',
            threshold: value,
            isPercent,
            enabled: true,
            cooldown: 300000, // 5 minutes between repeat alerts
            lastTriggered: 0
        };
    }
}
```

### 5. WebSocket Manager

```javascript
class WebSocketManager {
    constructor() {
        this.connections = new Map();
        this.reconnectAttempts = new Map();
        this.maxReconnectAttempts = 5;
        this.reconnectDelay = 1000;
    }

    async manage(url, handlers) {
        const ws = new WebSocket(url);
        const connectionId = crypto.randomUUID();

        ws.on('open', () => {
            console.log(`WebSocket connected: ${url}`);
            this.connections.set(connectionId, ws);
            this.reconnectAttempts.set(connectionId, 0);
            handlers.onOpen?.(ws);
        });

        ws.on('message', (data) => {
            handlers.onMessage?.(data);
        });

        ws.on('error', (error) => {
            console.error(`WebSocket error: ${url}`, error);
            handlers.onError?.(error);
        });

        ws.on('close', () => {
            console.log(`WebSocket closed: ${url}`);
            this.connections.delete(connectionId);
            this.attemptReconnect(url, handlers, connectionId);
        });

        return connectionId;
    }

    attemptReconnect(url, handlers, connectionId) {
        const attempts = this.reconnectAttempts.get(connectionId) || 0;

        if (attempts < this.maxReconnectAttempts) {
            const delay = this.reconnectDelay * Math.pow(2, attempts);
            console.log(`Reconnecting in ${delay}ms... (attempt ${attempts + 1})`);

            setTimeout(() => {
                this.reconnectAttempts.set(connectionId, attempts + 1);
                this.manage(url, handlers);
            }, delay);
        } else {
            console.error(`Max reconnection attempts reached for ${url}`);
            handlers.onMaxReconnectFailed?.();
        }
    }
}
```

## Error Handling

```javascript
try {
    const tracker = new MarketPriceTracker();
    const session = await tracker.trackPrice({
        symbol: 'BTC/USDT',
        assetType: 'crypto',
        interval: '1s',
        exchanges: ['binance', 'coinbase', 'kraken'],
        alertConditions: [
            'above 50000',
            'below 45000',
            'change 5%',
            'volume 2x'
        ],
        duration: '24h'
    });

    // Display real-time updates
    const display = new PriceDisplay();
    setInterval(async () => {
        const price = tracker.getCurrentPrice(session.symbol);
        console.clear();
        console.log(display.displayPrice(session, price));
    }, 1000);

} catch (error) {
    console.error('Price tracking failed:', error);
    process.exit(1);
}
```

This command provides institutional-grade real-time price tracking with multi-exchange aggregation, advanced alerts, and comprehensive analytics.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.