---
name: analyze-trends
description: >
  Analyze price trends with technical indicators, pattern recognition,
  and...
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.
