stock-bot/apps/stock/orchestrator/docs/technical-indicators.md
2025-07-04 11:24:27 -04:00

5.9 KiB

Technical Analysis Library Documentation

The stock-bot orchestrator includes a high-performance Technical Analysis (TA) library implemented in Rust with TypeScript bindings. This provides efficient calculation of common technical indicators for trading strategies.

Architecture

The TA library consists of:

  1. Rust Core: High-performance indicator calculations in apps/stock/core/src/indicators/
  2. NAPI Bindings: TypeScript interfaces exposed through @stock-bot/engine
  3. TypeScript Wrapper: Convenient API in orchestrator/src/indicators/TechnicalAnalysis.ts

Available Indicators

Simple Moving Average (SMA)

const sma = ta.sma(prices, period);

Exponential Moving Average (EMA)

const ema = ta.ema(prices, period);

Relative Strength Index (RSI)

const rsi = ta.rsi(prices, period); // Returns values 0-100

MACD (Moving Average Convergence Divergence)

const macd = ta.macd(prices, fastPeriod, slowPeriod, signalPeriod);
// Returns: { macd: number[], signal: number[], histogram: number[] }

Bollinger Bands

const bb = ta.bollingerBands(prices, period, stdDev);
// Returns: { upper: number[], middle: number[], lower: number[] }

Stochastic Oscillator

const stoch = ta.stochastic(high, low, close, kPeriod, dPeriod, smoothK);
// Returns: { k: number[], d: number[] }

Average True Range (ATR)

const atr = ta.atr(high, low, close, period);

Usage Examples

Basic Indicator Calculation

import { TechnicalAnalysis } from '../src/indicators/TechnicalAnalysis';

const ta = new TechnicalAnalysis();
const prices = [100, 102, 101, 103, 105, 104, 106];

// Calculate 5-period SMA
const sma5 = ta.sma(prices, 5);
console.log('SMA:', sma5);

// Get latest value
const latestSMA = TechnicalAnalysis.latest(sma5);

Incremental Indicators for Streaming Data

import { IncrementalIndicators } from '../src/indicators/TechnicalAnalysis';

const indicators = new IncrementalIndicators();

// Create indicators
indicators.createSMA('fast', 10);
indicators.createSMA('slow', 20);
indicators.createRSI('rsi', 14);

// Update with new price
const newPrice = 105.50;
const fastSMA = indicators.update('fast', newPrice);
const slowSMA = indicators.update('slow', newPrice);
const rsi = indicators.update('rsi', newPrice);

// Get current values
const currentRSI = indicators.current('rsi');

Signal Generation

import { SignalGenerator } from '../src/indicators/TechnicalAnalysis';

const generator = new SignalGenerator();
const signal = generator.generateSignals(
  'AAPL',
  {
    close: closePrices,
    high: highPrices,
    low: lowPrices,
    volume: volumes
  },
  Date.now()
);

if (signal.action === 'BUY' && signal.strength > 0.7) {
  // Strong buy signal
  console.log(`Buy signal: ${signal.reason}`);
}

Crossover Detection

// Detect when fast MA crosses above slow MA
if (TechnicalAnalysis.crossover(fastMA, slowMA)) {
  console.log('Bullish crossover detected');
}

// Detect when fast MA crosses below slow MA
if (TechnicalAnalysis.crossunder(fastMA, slowMA)) {
  console.log('Bearish crossover detected');
}

Strategy Integration

Example strategy using multiple indicators:

import { BaseStrategy } from '../BaseStrategy';
import { TechnicalAnalysis } from '../../indicators/TechnicalAnalysis';

export class MultiIndicatorStrategy extends BaseStrategy {
  private ta = new TechnicalAnalysis();
  private priceHistory: number[] = [];

  onMarketData(data: any): Order | null {
    this.priceHistory.push(data.close);
    
    if (this.priceHistory.length < 50) return null;
    
    // Calculate indicators
    const rsi = this.ta.rsi(this.priceHistory, 14);
    const macd = this.ta.macd(this.priceHistory);
    const bb = this.ta.bollingerBands(this.priceHistory);
    
    // Get latest values
    const currentRSI = TechnicalAnalysis.latest(rsi);
    const currentPrice = data.close;
    const bbLower = TechnicalAnalysis.latest(bb.lower);
    
    // Generate signals
    if (currentRSI < 30 && currentPrice < bbLower) {
      // Oversold + price below lower band = BUY
      return this.createOrder('market', 'buy', this.positionSize);
    }
    
    return null;
  }
}

Performance Considerations

  1. Batch vs Incremental: Use batch calculations for backtesting, incremental for live trading
  2. Memory Management: The Rust implementation uses efficient rolling windows
  3. Thread Safety: All Rust indicators are thread-safe
  4. Error Handling: Invalid parameters return errors rather than panicking

Testing

Run the indicator tests:

bun run test:indicators

Run the usage examples:

bun run example:indicators

Extending the Library

To add a new indicator:

  1. Create Rust implementation in apps/stock/core/src/indicators/[indicator_name].rs
  2. Implement Indicator and optionally IncrementalIndicator traits
  3. Add NAPI bindings in apps/stock/core/src/api/indicators.rs
  4. Update TypeScript definitions in apps/stock/core/index.d.ts
  5. Add wrapper methods in orchestrator/src/indicators/TechnicalAnalysis.ts
  6. Write tests and examples

Common Patterns

Momentum Indicators

  • RSI < 30: Oversold
  • RSI > 70: Overbought
  • MACD crossover: Trend change

Volatility Indicators

  • Bollinger Band squeeze: Low volatility
  • ATR increase: Higher volatility

Trend Indicators

  • Price > SMA200: Long-term uptrend
  • EMA crossovers: Short-term trend changes

Combined Signals

Best results often come from combining multiple indicators:

  • RSI oversold + MACD bullish crossover
  • Price at Bollinger lower band + Stochastic oversold
  • Volume confirmation with price indicators