commit 8b1c32716c3a7fca414badee424298db6942700d Author: Zhongwei Li Date: Sat Nov 29 18:53:22 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..f27dce8 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,16 @@ +{ + "name": "market-price-tracker", + "description": "Real-time market price tracking with multi-exchange feeds and advanced alerts", + "version": "1.0.0", + "author": { + "name": "Intent Solutions IO", + "email": "jeremy@intentsolutions.ai", + "url": "https://intentsolutions.ai" + }, + "skills": [ + "./skills" + ], + "commands": [ + "./commands" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..7ec9a0f --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# market-price-tracker + +Real-time market price tracking with multi-exchange feeds and advanced alerts diff --git a/commands/analyze-trends.md b/commands/analyze-trends.md new file mode 100644 index 0000000..4303923 --- /dev/null +++ b/commands/analyze-trends.md @@ -0,0 +1,640 @@ +--- +description: Analyze price trends with technical indicators, pattern recognition, and market structure analysis +shortcut: at +--- + +# Analyze Market Trends + +Advanced trend analysis system using technical indicators, chart patterns, and market structure to identify trading opportunities. + +## Usage + +When the user wants to analyze market trends, implement comprehensive technical analysis with these components: + +### Required Parameters +- **Symbol**: Asset to analyze +- **Timeframe**: 1m, 5m, 15m, 1h, 4h, 1d, 1w +- **Period**: How far back to analyze (e.g., "30 days", "6 months") +- **Analysis Type**: technical, fundamental, sentiment, or combined +- **Output Format**: report, signals, dashboard + +## Implementation + +### 1. Technical Analysis Engine + +```javascript +class TrendAnalyzer { + constructor() { + this.indicators = new TechnicalIndicators(); + this.patterns = new PatternRecognition(); + this.marketStructure = new MarketStructureAnalysis(); + this.signals = new SignalGenerator(); + } + + async analyzeTrends(params) { + const { + symbol, + timeframe = '1h', + period = '30d', + analysisType = 'technical', + includeVolume = true + } = params; + + // Fetch historical data + const historicalData = await this.fetchHistoricalData(symbol, timeframe, period); + + // Perform analysis based on type + const analysis = { + timestamp: Date.now(), + symbol, + timeframe, + period, + dataPoints: historicalData.length, + trend: await this.identifyTrend(historicalData), + momentum: await this.analyzeMomentum(historicalData), + volatility: await this.analyzeVolatility(historicalData), + patterns: await this.detectPatterns(historicalData), + indicators: await this.calculateIndicators(historicalData), + structure: await this.analyzeStructure(historicalData), + signals: await this.generateSignals(historicalData), + forecast: await this.generateForecast(historicalData) + }; + + // Add volume analysis if requested + if (includeVolume) { + analysis.volume = await this.analyzeVolume(historicalData); + } + + // Generate trading recommendations + analysis.recommendations = this.generateRecommendations(analysis); + + return analysis; + } + + async identifyTrend(data) { + const prices = data.map(d => d.close); + const highs = data.map(d => d.high); + const lows = data.map(d => d.low); + + // Calculate trend using multiple methods + const methods = { + movingAverage: this.trendByMovingAverage(prices), + higherHighsLows: this.trendByHigherHighsLows(highs, lows), + linearRegression: this.trendByLinearRegression(prices), + adx: this.trendByADX(data) + }; + + // Determine overall trend + const trendVotes = Object.values(methods); + const bullishCount = trendVotes.filter(v => v === 'BULLISH').length; + const bearishCount = trendVotes.filter(v => v === 'BEARISH').length; + + let overallTrend; + if (bullishCount > bearishCount + 1) { + overallTrend = 'STRONG_BULLISH'; + } else if (bullishCount > bearishCount) { + overallTrend = 'BULLISH'; + } else if (bearishCount > bullishCount + 1) { + overallTrend = 'STRONG_BEARISH'; + } else if (bearishCount > bullishCount) { + overallTrend = 'BEARISH'; + } else { + overallTrend = 'NEUTRAL'; + } + + return { + overall: overallTrend, + strength: this.calculateTrendStrength(data), + duration: this.calculateTrendDuration(data), + methods, + confidence: (Math.max(bullishCount, bearishCount) / trendVotes.length) * 100 + }; + } + + trendByMovingAverage(prices) { + const ma20 = this.calculateSMA(prices, 20); + const ma50 = this.calculateSMA(prices, 50); + const ma200 = this.calculateSMA(prices, 200); + + const currentPrice = prices[prices.length - 1]; + + if (currentPrice > ma20 && ma20 > ma50 && ma50 > ma200) { + return 'BULLISH'; + } else if (currentPrice < ma20 && ma20 < ma50 && ma50 < ma200) { + return 'BEARISH'; + } else { + return 'NEUTRAL'; + } + } + + trendByHigherHighsLows(highs, lows) { + const recentHighs = highs.slice(-10); + const recentLows = lows.slice(-10); + + let higherHighs = 0; + let lowerLows = 0; + let higherLows = 0; + let lowerHighs = 0; + + for (let i = 1; i < recentHighs.length; i++) { + if (recentHighs[i] > recentHighs[i-1]) higherHighs++; + if (recentHighs[i] < recentHighs[i-1]) lowerHighs++; + if (recentLows[i] > recentLows[i-1]) higherLows++; + if (recentLows[i] < recentLows[i-1]) lowerLows++; + } + + if (higherHighs > lowerHighs && higherLows > lowerLows) { + return 'BULLISH'; + } else if (lowerHighs > higherHighs && lowerLows > higherLows) { + return 'BEARISH'; + } else { + return 'NEUTRAL'; + } + } + + calculateTrendStrength(data) { + const adx = this.calculateADX(data, 14); + const currentADX = adx[adx.length - 1]; + + if (currentADX > 50) return 'VERY_STRONG'; + if (currentADX > 40) return 'STRONG'; + if (currentADX > 25) return 'MODERATE'; + if (currentADX > 20) return 'WEAK'; + return 'VERY_WEAK'; + } + + async analyzeMomentum(data) { + const prices = data.map(d => d.close); + + return { + rsi: this.calculateRSI(prices, 14), + stochastic: this.calculateStochastic(data, 14, 3, 3), + macd: this.calculateMACD(prices), + momentum: this.calculateMomentum(prices, 10), + roc: this.calculateROC(prices, 12), + williamsPR: this.calculateWilliamsPR(data, 14), + cci: this.calculateCCI(data, 20), + mfi: this.calculateMFI(data, 14), + interpretation: this.interpretMomentum(prices) + }; + } + + calculateRSI(prices, period = 14) { + if (prices.length < period + 1) return null; + + const gains = []; + const losses = []; + + for (let i = 1; i < prices.length; i++) { + const change = prices[i] - prices[i - 1]; + gains.push(change > 0 ? change : 0); + losses.push(change < 0 ? Math.abs(change) : 0); + } + + const avgGain = gains.slice(-period).reduce((a, b) => a + b) / period; + const avgLoss = losses.slice(-period).reduce((a, b) => a + b) / period; + + if (avgLoss === 0) return 100; + + const rs = avgGain / avgLoss; + const rsi = 100 - (100 / (1 + rs)); + + return { + value: rsi, + signal: rsi > 70 ? 'OVERBOUGHT' : rsi < 30 ? 'OVERSOLD' : 'NEUTRAL', + divergence: this.checkDivergence(prices, rsi) + }; + } + + calculateMACD(prices) { + const ema12 = this.calculateEMA(prices, 12); + const ema26 = this.calculateEMA(prices, 26); + const macdLine = []; + + for (let i = 0; i < Math.min(ema12.length, ema26.length); i++) { + macdLine.push(ema12[i] - ema26[i]); + } + + const signal = this.calculateEMA(macdLine, 9); + const histogram = []; + + for (let i = 0; i < Math.min(macdLine.length, signal.length); i++) { + histogram.push(macdLine[i] - signal[i]); + } + + return { + macd: macdLine[macdLine.length - 1], + signal: signal[signal.length - 1], + histogram: histogram[histogram.length - 1], + crossover: this.detectCrossover(macdLine, signal), + trend: histogram[histogram.length - 1] > 0 ? 'BULLISH' : 'BEARISH' + }; + } + + async detectPatterns(data) { + const patterns = []; + const prices = data.map(d => ({ open: d.open, high: d.high, low: d.low, close: d.close })); + + // Chart Patterns + const chartPatterns = { + headAndShoulders: this.detectHeadAndShoulders(prices), + doubleTop: this.detectDoubleTop(prices), + doubleBottom: this.detectDoubleBottom(prices), + triangle: this.detectTriangle(prices), + wedge: this.detectWedge(prices), + flag: this.detectFlag(prices), + pennant: this.detectPennant(prices), + cup: this.detectCupAndHandle(prices) + }; + + // Candlestick Patterns + const candlePatterns = { + hammer: this.detectHammer(prices), + doji: this.detectDoji(prices), + engulfing: this.detectEngulfing(prices), + morningStar: this.detectMorningStar(prices), + eveningStar: this.detectEveningStar(prices), + shootingStar: this.detectShootingStar(prices), + harami: this.detectHarami(prices), + threeWhiteSoldiers: this.detectThreeWhiteSoldiers(prices) + }; + + // Combine and score patterns + for (const [name, result] of Object.entries(chartPatterns)) { + if (result.detected) { + patterns.push({ + type: 'CHART', + name: name.toUpperCase(), + confidence: result.confidence, + direction: result.direction, + target: result.target, + stopLoss: result.stopLoss + }); + } + } + + for (const [name, result] of Object.entries(candlePatterns)) { + if (result.detected) { + patterns.push({ + type: 'CANDLE', + name: name.toUpperCase(), + confidence: result.confidence, + signal: result.signal, + position: result.position + }); + } + } + + return patterns; + } + + detectHeadAndShoulders(prices) { + const highs = prices.map(p => p.high); + const result = { detected: false, confidence: 0, direction: null }; + + if (highs.length < 50) return result; + + // Look for pattern in recent data + const recent = highs.slice(-50); + const peaks = this.findPeaks(recent); + + if (peaks.length >= 3) { + const [leftShoulder, head, rightShoulder] = peaks.slice(-3); + + // Check if middle peak is highest (head) + if (head.value > leftShoulder.value && + head.value > rightShoulder.value && + Math.abs(leftShoulder.value - rightShoulder.value) / leftShoulder.value < 0.03) { + + result.detected = true; + result.confidence = 85; + result.direction = 'BEARISH'; + result.neckline = Math.min( + ...recent.slice(leftShoulder.index, rightShoulder.index + 1) + ); + result.target = result.neckline - (head.value - result.neckline); + result.stopLoss = head.value * 1.01; + } + } + + return result; + } + + async analyzeVolume(data) { + const volumes = data.map(d => d.volume); + const prices = data.map(d => d.close); + + return { + average: volumes.reduce((a, b) => a + b) / volumes.length, + trend: this.analyzeVolumeTrend(volumes), + obv: this.calculateOBV(prices, volumes), + adl: this.calculateADL(data), + mfi: this.calculateMFI(data, 14), + vwap: this.calculateVWAP(data), + volumeProfile: this.calculateVolumeProfile(data), + accumulation: this.detectAccumulationDistribution(data), + spikes: this.detectVolumeSpikes(volumes) + }; + } + + calculateOBV(prices, volumes) { + const obv = [volumes[0]]; + + for (let i = 1; i < prices.length; i++) { + if (prices[i] > prices[i - 1]) { + obv.push(obv[i - 1] + volumes[i]); + } else if (prices[i] < prices[i - 1]) { + obv.push(obv[i - 1] - volumes[i]); + } else { + obv.push(obv[i - 1]); + } + } + + return { + values: obv, + current: obv[obv.length - 1], + trend: this.calculateTrend(obv.slice(-20)), + divergence: this.checkVolumePriceDivergence(prices, obv) + }; + } + + async generateSignals(data) { + const signals = []; + const analysis = { + trend: await this.identifyTrend(data), + momentum: await this.analyzeMomentum(data), + patterns: await this.detectPatterns(data) + }; + + // Trend-based signals + if (analysis.trend.overall === 'STRONG_BULLISH') { + signals.push({ + type: 'BUY', + strength: 'STRONG', + reason: 'Strong bullish trend confirmed', + confidence: analysis.trend.confidence + }); + } + + // Momentum signals + if (analysis.momentum.rsi.value < 30) { + signals.push({ + type: 'BUY', + strength: 'MEDIUM', + reason: 'RSI oversold condition', + confidence: 70 + }); + } + + // Pattern signals + for (const pattern of analysis.patterns) { + if (pattern.type === 'CHART' && pattern.confidence > 80) { + signals.push({ + type: pattern.direction === 'BULLISH' ? 'BUY' : 'SELL', + strength: 'STRONG', + reason: `${pattern.name} pattern detected`, + confidence: pattern.confidence, + target: pattern.target, + stopLoss: pattern.stopLoss + }); + } + } + + // MACD crossover signals + if (analysis.momentum.macd.crossover === 'BULLISH') { + signals.push({ + type: 'BUY', + strength: 'MEDIUM', + reason: 'MACD bullish crossover', + confidence: 65 + }); + } + + return this.prioritizeSignals(signals); + } + + prioritizeSignals(signals) { + // Sort by confidence and strength + return signals.sort((a, b) => { + const strengthScore = { STRONG: 3, MEDIUM: 2, WEAK: 1 }; + const scoreA = a.confidence * strengthScore[a.strength]; + const scoreB = b.confidence * strengthScore[b.strength]; + return scoreB - scoreA; + }).slice(0, 5); // Top 5 signals + } +} +``` + +### 2. Market Structure Analysis + +```javascript +class MarketStructureAnalysis { + analyzeStructure(data) { + return { + marketPhase: this.identifyMarketPhase(data), + keyLevels: this.identifyKeyLevels(data), + liquidityZones: this.findLiquidityZones(data), + orderFlow: this.analyzeOrderFlow(data), + marketProfile: this.createMarketProfile(data), + supplyDemand: this.identifySupplyDemandZones(data) + }; + } + + identifyMarketPhase(data) { + const volatility = this.calculateVolatility(data); + const trend = this.calculateTrendStrength(data); + const volume = this.analyzeVolumeCharacteristics(data); + + if (volatility < 0.01 && trend < 25) { + return { + phase: 'ACCUMULATION', + characteristics: 'Low volatility, sideways movement, smart money accumulating', + tradingStrategy: 'Buy at support, sell at resistance' + }; + } else if (trend > 40 && volume.trend === 'INCREASING') { + return { + phase: 'MARK_UP', + characteristics: 'Strong trend, increasing volume, institutional buying', + tradingStrategy: 'Trend following, buy dips' + }; + } else if (volatility > 0.03 && trend < 25) { + return { + phase: 'DISTRIBUTION', + characteristics: 'High volatility, topping pattern, smart money distributing', + tradingStrategy: 'Take profits, short at resistance' + }; + } else if (trend > 40 && volume.trend === 'DECREASING') { + return { + phase: 'MARK_DOWN', + characteristics: 'Downtrend, panic selling, capitulation', + tradingStrategy: 'Stay out or short rallies' + }; + } else { + return { + phase: 'TRANSITION', + characteristics: 'Changing market dynamics', + tradingStrategy: 'Wait for confirmation' + }; + } + } + + identifyKeyLevels(data) { + const levels = []; + const highs = data.map(d => d.high); + const lows = data.map(d => d.low); + const closes = data.map(d => d.close); + + // Psychological levels (round numbers) + const currentPrice = closes[closes.length - 1]; + const roundLevels = this.findRoundNumbers(currentPrice); + + // Historical support/resistance + const historicalLevels = this.findHistoricalLevels(highs, lows, closes); + + // Volume-based levels + const volumeLevels = this.findVolumeLevels(data); + + // Fibonacci levels + const fibLevels = this.calculateFibonacciLevels( + Math.min(...lows), + Math.max(...highs) + ); + + return { + psychological: roundLevels, + historical: historicalLevels, + volume: volumeLevels, + fibonacci: fibLevels, + combined: this.combineAndRankLevels([ + ...roundLevels, + ...historicalLevels, + ...volumeLevels, + ...fibLevels + ]) + }; + } + + findLiquidityZones(data) { + const zones = []; + const volumes = data.map(d => d.volume); + const avgVolume = volumes.reduce((a, b) => a + b) / volumes.length; + + for (let i = 0; i < data.length - 10; i++) { + const window = data.slice(i, i + 10); + const windowVolume = window.reduce((sum, d) => sum + d.volume, 0); + + if (windowVolume > avgVolume * 10 * 1.5) { + const highPrice = Math.max(...window.map(d => d.high)); + const lowPrice = Math.min(...window.map(d => d.low)); + + zones.push({ + type: 'HIGH_LIQUIDITY', + upperBound: highPrice, + lowerBound: lowPrice, + volume: windowVolume, + strength: windowVolume / (avgVolume * 10) + }); + } + } + + return zones; + } +} +``` + +### 3. Display and Reporting + +```javascript +class TrendReport { + generateReport(analysis) { + return ` +╔════════════════════════════════════════════════════════════════╗ +║ TREND ANALYSIS REPORT ║ +╠════════════════════════════════════════════════════════════════╣ +║ Symbol: ${analysis.symbol.padEnd(48)} ║ +║ Timeframe: ${analysis.timeframe.padEnd(48)} ║ +║ Period: ${analysis.period.padEnd(48)} ║ +║ Data Points: ${analysis.dataPoints.toString().padEnd(48)} ║ +╠════════════════════════════════════════════════════════════════╣ +║ TREND ║ +╠════════════════════════════════════════════════════════════════╣ +║ Direction: ${this.formatTrend(analysis.trend.overall).padEnd(48)} ║ +║ Strength: ${analysis.trend.strength.padEnd(48)} ║ +║ Duration: ${analysis.trend.duration.padEnd(48)} ║ +║ Confidence: ${this.formatPercentage(analysis.trend.confidence).padEnd(48)} ║ +╠════════════════════════════════════════════════════════════════╣ +║ MOMENTUM ║ +╠════════════════════════════════════════════════════════════════╣ +║ RSI (14): ${this.formatRSI(analysis.momentum.rsi).padEnd(48)} ║ +║ MACD: ${this.formatMACD(analysis.momentum.macd).padEnd(48)} ║ +║ Stochastic: ${this.formatStochastic(analysis.momentum.stochastic).padEnd(48)} ║ +╠════════════════════════════════════════════════════════════════╣ +║ PATTERNS ║ +╠════════════════════════════════════════════════════════════════╣ +${this.formatPatterns(analysis.patterns)} +╠════════════════════════════════════════════════════════════════╣ +║ TOP SIGNALS ║ +╠════════════════════════════════════════════════════════════════╣ +${this.formatSignals(analysis.signals)} +╠════════════════════════════════════════════════════════════════╣ +║ RECOMMENDATIONS ║ +╠════════════════════════════════════════════════════════════════╣ +${this.formatRecommendations(analysis.recommendations)} +╚════════════════════════════════════════════════════════════════╝ +`; + } + + formatTrend(trend) { + const icons = { + STRONG_BULLISH: ' Strong Bullish', + BULLISH: ' Bullish', + NEUTRAL: ' Neutral', + BEARISH: ' Bearish', + STRONG_BEARISH: ' Strong Bearish' + }; + return icons[trend] || trend; + } + + formatPatterns(patterns) { + if (patterns.length === 0) { + return '║ No significant patterns detected ║'; + } + + return patterns.slice(0, 3).map(p => + `║ ${p.name.padEnd(20)} Confidence: ${p.confidence}% ${p.direction.padEnd(20)} ║` + ).join('\n'); + } + + formatSignals(signals) { + if (signals.length === 0) { + return '║ No strong signals at this time ║'; + } + + return signals.slice(0, 3).map(s => + `║ ${s.type} - ${s.reason.padEnd(35)} [${s.confidence}%] ║` + ).join('\n'); + } +} +``` + +## Error Handling + +```javascript +try { + const analyzer = new TrendAnalyzer(); + const analysis = await analyzer.analyzeTrends({ + symbol: 'BTC/USDT', + timeframe: '4h', + period: '30d', + analysisType: 'technical' + }); + + const report = new TrendReport(); + console.log(report.generateReport(analysis)); + +} catch (error) { + console.error('Trend analysis failed:', error); +} +``` + +This command provides comprehensive trend analysis with technical indicators, pattern recognition, and actionable trading signals. \ No newline at end of file diff --git a/commands/track-price.md b/commands/track-price.md new file mode 100644 index 0000000..591de55 --- /dev/null +++ b/commands/track-price.md @@ -0,0 +1,727 @@ +--- +description: Track real-time prices across crypto, stocks, forex, and commodities with multi-source feeds +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. \ No newline at end of file diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..4df2ed4 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,89 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:jeremylongshore/claude-code-plugins-plus:plugins/crypto/market-price-tracker", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "16ca5701c9d9fd3b3bda7c4ec84bfad58cb652c9", + "treeHash": "de3aa04d54e8feb5414004b0507da6a0f0c7c15c4866dca481050e4389863ee4", + "generatedAt": "2025-11-28T10:18:33.430628Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "market-price-tracker", + "description": "Real-time market price tracking with multi-exchange feeds and advanced alerts", + "version": "1.0.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "1037f0e86eed8da073444155dcad3bb51a90233b9c839390c47cd70e1d0dc910" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "f237a6bf67e7da0ede495e2ba80ff9a74c3f763f8737cfa5c3bc3c47a242d3f4" + }, + { + "path": "commands/analyze-trends.md", + "sha256": "f17d18d08a685fde5a545da6574fd8ff86bcf9fbd740e560b75e94512621fa82" + }, + { + "path": "commands/track-price.md", + "sha256": "664434cbc19c96845b84e314c792791e1c38cdd7179be744c774829c34179b4e" + }, + { + "path": "skills/skill-adapter/references/examples.md", + "sha256": "922bbc3c4ebf38b76f515b5c1998ebde6bf902233e00e2c5a0e9176f975a7572" + }, + { + "path": "skills/skill-adapter/references/best-practices.md", + "sha256": "c8f32b3566252f50daacd346d7045a1060c718ef5cfb07c55a0f2dec5f1fb39e" + }, + { + "path": "skills/skill-adapter/references/README.md", + "sha256": "7cf039498448a36e5480704b748b4d17d2c341966c16b583285d5b88ae7da658" + }, + { + "path": "skills/skill-adapter/scripts/helper-template.sh", + "sha256": "0881d5660a8a7045550d09ae0acc15642c24b70de6f08808120f47f86ccdf077" + }, + { + "path": "skills/skill-adapter/scripts/validation.sh", + "sha256": "92551a29a7f512d2036e4f1fb46c2a3dc6bff0f7dde4a9f699533e446db48502" + }, + { + "path": "skills/skill-adapter/scripts/README.md", + "sha256": "7b79d99b557e0d4201ed110cff55aa6640d2e0cc4abb699c20959cff5a62f3f6" + }, + { + "path": "skills/skill-adapter/assets/test-data.json", + "sha256": "ac17dca3d6e253a5f39f2a2f1b388e5146043756b05d9ce7ac53a0042eee139d" + }, + { + "path": "skills/skill-adapter/assets/README.md", + "sha256": "33f9548da8bf39202af0b1f55321de502708306bc5f64a3be1eb932e858f73bc" + }, + { + "path": "skills/skill-adapter/assets/skill-schema.json", + "sha256": "f5639ba823a24c9ac4fb21444c0717b7aefde1a4993682897f5bf544f863c2cd" + }, + { + "path": "skills/skill-adapter/assets/config-template.json", + "sha256": "0c2ba33d2d3c5ccb266c0848fc43caa68a2aa6a80ff315d4b378352711f83e1c" + } + ], + "dirSha256": "de3aa04d54e8feb5414004b0507da6a0f0c7c15c4866dca481050e4389863ee4" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/skill-adapter/assets/README.md b/skills/skill-adapter/assets/README.md new file mode 100644 index 0000000..23adac1 --- /dev/null +++ b/skills/skill-adapter/assets/README.md @@ -0,0 +1,7 @@ +# Assets + +Bundled resources for market-price-tracker skill + +- [ ] alert_templates.json: JSON templates for different types of price alerts (e.g., price above threshold, percentage change). +- [ ] example_data.json: Example data structures for real-time price feeds and technical analysis results. +- [ ] config_template.json: Configuration template for setting up data sources, API keys, and alert preferences. diff --git a/skills/skill-adapter/assets/config-template.json b/skills/skill-adapter/assets/config-template.json new file mode 100644 index 0000000..16f1712 --- /dev/null +++ b/skills/skill-adapter/assets/config-template.json @@ -0,0 +1,32 @@ +{ + "skill": { + "name": "skill-name", + "version": "1.0.0", + "enabled": true, + "settings": { + "verbose": false, + "autoActivate": true, + "toolRestrictions": true + } + }, + "triggers": { + "keywords": [ + "example-trigger-1", + "example-trigger-2" + ], + "patterns": [] + }, + "tools": { + "allowed": [ + "Read", + "Grep", + "Bash" + ], + "restricted": [] + }, + "metadata": { + "author": "Plugin Author", + "category": "general", + "tags": [] + } +} diff --git a/skills/skill-adapter/assets/skill-schema.json b/skills/skill-adapter/assets/skill-schema.json new file mode 100644 index 0000000..8dc154c --- /dev/null +++ b/skills/skill-adapter/assets/skill-schema.json @@ -0,0 +1,28 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Claude Skill Configuration", + "type": "object", + "required": ["name", "description"], + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z0-9-]+$", + "maxLength": 64, + "description": "Skill identifier (lowercase, hyphens only)" + }, + "description": { + "type": "string", + "maxLength": 1024, + "description": "What the skill does and when to use it" + }, + "allowed-tools": { + "type": "string", + "description": "Comma-separated list of allowed tools" + }, + "version": { + "type": "string", + "pattern": "^\\d+\\.\\d+\\.\\d+$", + "description": "Semantic version (x.y.z)" + } + } +} diff --git a/skills/skill-adapter/assets/test-data.json b/skills/skill-adapter/assets/test-data.json new file mode 100644 index 0000000..f0cd871 --- /dev/null +++ b/skills/skill-adapter/assets/test-data.json @@ -0,0 +1,27 @@ +{ + "testCases": [ + { + "name": "Basic activation test", + "input": "trigger phrase example", + "expected": { + "activated": true, + "toolsUsed": ["Read", "Grep"], + "success": true + } + }, + { + "name": "Complex workflow test", + "input": "multi-step trigger example", + "expected": { + "activated": true, + "steps": 3, + "toolsUsed": ["Read", "Write", "Bash"], + "success": true + } + } + ], + "fixtures": { + "sampleInput": "example data", + "expectedOutput": "processed result" + } +} diff --git a/skills/skill-adapter/references/README.md b/skills/skill-adapter/references/README.md new file mode 100644 index 0000000..235eb2a --- /dev/null +++ b/skills/skill-adapter/references/README.md @@ -0,0 +1,8 @@ +# References + +Bundled resources for market-price-tracker skill + +- [ ] crypto_exchanges_api.md: API documentation for various crypto exchanges like Binance, Coinbase, Kraken. +- [ ] stock_data_api.md: API documentation for stock data providers like Alpha Vantage, IEX Cloud, Polygon.io. +- [ ] forex_feeds_api.md: API documentation for forex data feeds like OANDA, Forex Connect, Currency Layer. +- [ ] technical_indicators.md: Detailed explanations and formulas for technical indicators like RSI, MACD, Bollinger Bands. diff --git a/skills/skill-adapter/references/best-practices.md b/skills/skill-adapter/references/best-practices.md new file mode 100644 index 0000000..3505048 --- /dev/null +++ b/skills/skill-adapter/references/best-practices.md @@ -0,0 +1,69 @@ +# Skill Best Practices + +Guidelines for optimal skill usage and development. + +## For Users + +### Activation Best Practices + +1. **Use Clear Trigger Phrases** + - Match phrases from skill description + - Be specific about intent + - Provide necessary context + +2. **Provide Sufficient Context** + - Include relevant file paths + - Specify scope of analysis + - Mention any constraints + +3. **Understand Tool Permissions** + - Check allowed-tools in frontmatter + - Know what the skill can/cannot do + - Request appropriate actions + +### Workflow Optimization + +- Start with simple requests +- Build up to complex workflows +- Verify each step before proceeding +- Use skill consistently for related tasks + +## For Developers + +### Skill Development Guidelines + +1. **Clear Descriptions** + - Include explicit trigger phrases + - Document all capabilities + - Specify limitations + +2. **Proper Tool Permissions** + - Use minimal necessary tools + - Document security implications + - Test with restricted tools + +3. **Comprehensive Documentation** + - Provide usage examples + - Document common pitfalls + - Include troubleshooting guide + +### Maintenance + +- Keep version updated +- Test after tool updates +- Monitor user feedback +- Iterate on descriptions + +## Performance Tips + +- Scope skills to specific domains +- Avoid overlapping trigger phrases +- Keep descriptions under 1024 chars +- Test activation reliability + +## Security Considerations + +- Never include secrets in skill files +- Validate all inputs +- Use read-only tools when possible +- Document security requirements diff --git a/skills/skill-adapter/references/examples.md b/skills/skill-adapter/references/examples.md new file mode 100644 index 0000000..b1d8bd2 --- /dev/null +++ b/skills/skill-adapter/references/examples.md @@ -0,0 +1,70 @@ +# Skill Usage Examples + +This document provides practical examples of how to use this skill effectively. + +## Basic Usage + +### Example 1: Simple Activation + +**User Request:** +``` +[Describe trigger phrase here] +``` + +**Skill Response:** +1. Analyzes the request +2. Performs the required action +3. Returns results + +### Example 2: Complex Workflow + +**User Request:** +``` +[Describe complex scenario] +``` + +**Workflow:** +1. Step 1: Initial analysis +2. Step 2: Data processing +3. Step 3: Result generation +4. Step 4: Validation + +## Advanced Patterns + +### Pattern 1: Chaining Operations + +Combine this skill with other tools: +``` +Step 1: Use this skill for [purpose] +Step 2: Chain with [other tool] +Step 3: Finalize with [action] +``` + +### Pattern 2: Error Handling + +If issues occur: +- Check trigger phrase matches +- Verify context is available +- Review allowed-tools permissions + +## Tips & Best Practices + +- ✅ Be specific with trigger phrases +- ✅ Provide necessary context +- ✅ Check tool permissions match needs +- ❌ Avoid vague requests +- ❌ Don't mix unrelated tasks + +## Common Issues + +**Issue:** Skill doesn't activate +**Solution:** Use exact trigger phrases from description + +**Issue:** Unexpected results +**Solution:** Check input format and context + +## See Also + +- Main SKILL.md for full documentation +- scripts/ for automation helpers +- assets/ for configuration examples diff --git a/skills/skill-adapter/scripts/README.md b/skills/skill-adapter/scripts/README.md new file mode 100644 index 0000000..b3b57f4 --- /dev/null +++ b/skills/skill-adapter/scripts/README.md @@ -0,0 +1,7 @@ +# Scripts + +Bundled resources for market-price-tracker skill + +- [ ] price_tracker.py: Script to track prices of crypto, stocks, forex, commodities using WebSocket connections and data aggregation. +- [ ] alert_manager.py: Script to manage price alerts based on user-defined conditions and send notifications. +- [ ] technical_analysis.py: Script to calculate technical indicators like RSI, MACD, and moving averages. diff --git a/skills/skill-adapter/scripts/helper-template.sh b/skills/skill-adapter/scripts/helper-template.sh new file mode 100755 index 0000000..c4aae90 --- /dev/null +++ b/skills/skill-adapter/scripts/helper-template.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Helper script template for skill automation +# Customize this for your skill's specific needs + +set -e + +function show_usage() { + echo "Usage: $0 [options]" + echo "" + echo "Options:" + echo " -h, --help Show this help message" + echo " -v, --verbose Enable verbose output" + echo "" +} + +# Parse arguments +VERBOSE=false + +while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + show_usage + exit 0 + ;; + -v|--verbose) + VERBOSE=true + shift + ;; + *) + echo "Unknown option: $1" + show_usage + exit 1 + ;; + esac +done + +# Your skill logic here +if [ "$VERBOSE" = true ]; then + echo "Running skill automation..." +fi + +echo "✅ Complete" diff --git a/skills/skill-adapter/scripts/validation.sh b/skills/skill-adapter/scripts/validation.sh new file mode 100755 index 0000000..590af58 --- /dev/null +++ b/skills/skill-adapter/scripts/validation.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Skill validation helper +# Validates skill activation and functionality + +set -e + +echo "🔍 Validating skill..." + +# Check if SKILL.md exists +if [ ! -f "../SKILL.md" ]; then + echo "❌ Error: SKILL.md not found" + exit 1 +fi + +# Validate frontmatter +if ! grep -q "^---$" "../SKILL.md"; then + echo "❌ Error: No frontmatter found" + exit 1 +fi + +# Check required fields +if ! grep -q "^name:" "../SKILL.md"; then + echo "❌ Error: Missing 'name' field" + exit 1 +fi + +if ! grep -q "^description:" "../SKILL.md"; then + echo "❌ Error: Missing 'description' field" + exit 1 +fi + +echo "✅ Skill validation passed"