stock-bot/apps/stock/orchestrator/examples/indicator-usage.ts
2025-07-04 11:24:27 -04:00

217 lines
No EOL
7.6 KiB
TypeScript

/**
* Examples of using the Rust-based Technical Analysis library
*/
import { IncrementalIndicators, SignalGenerator, TechnicalAnalysis } from '../src/indicators/TechnicalAnalysis';
// Example 1: Basic indicator calculations
async function basicIndicatorExample() {
console.log('=== Basic Indicator Example ===');
const ta = new TechnicalAnalysis();
// Sample price data
const prices = [
100, 102, 101, 103, 105, 104, 106, 108, 107, 109,
111, 110, 112, 114, 113, 115, 117, 116, 118, 120
];
// Calculate various indicators
const sma10 = ta.sma(prices, 10);
const ema10 = ta.ema(prices, 10);
const rsi14 = ta.rsi(prices, 14);
console.log(`SMA(10): ${sma10.map(v => v.toFixed(2)).join(', ')}`);
console.log(`EMA(10): ${ema10.map(v => v.toFixed(2)).join(', ')}`);
console.log(`RSI(14): ${rsi14.map(v => v.toFixed(2)).join(', ')}`);
// Latest values
console.log(`\nLatest SMA: ${TechnicalAnalysis.latest(sma10)?.toFixed(2)}`);
console.log(`Latest EMA: ${TechnicalAnalysis.latest(ema10)?.toFixed(2)}`);
console.log(`Latest RSI: ${TechnicalAnalysis.latest(rsi14)?.toFixed(2)}`);
}
// Example 2: Real-time streaming indicators
async function streamingIndicatorExample() {
console.log('\n=== Streaming Indicator Example ===');
const manager = new IncrementalIndicators();
// Create indicators
manager.createSMA('sma_fast', 5);
manager.createSMA('sma_slow', 10);
manager.createEMA('ema', 10);
manager.createRSI('rsi', 14);
// Simulate real-time price updates
console.log('Processing real-time price updates...');
for (let i = 0; i < 20; i++) {
const price = 100 + Math.sin(i * 0.3) * 5 + Math.random() * 2;
const smaFast = manager.update('sma_fast', price);
const smaSlow = manager.update('sma_slow', price);
const ema = manager.update('ema', price);
const rsi = manager.update('rsi', price);
if (i >= 14) { // Once we have enough data
console.log(`Price: ${price.toFixed(2)} | SMA5: ${smaFast?.toFixed(2)} | SMA10: ${smaSlow?.toFixed(2)} | EMA: ${ema?.toFixed(2)} | RSI: ${rsi?.toFixed(2)}`);
}
}
}
// Example 3: Complex indicators (MACD, Bollinger Bands, Stochastic)
async function complexIndicatorExample() {
console.log('\n=== Complex Indicator Example ===');
const ta = new TechnicalAnalysis();
// Generate more realistic price data
const generatePrices = (count: number) => {
const prices = { close: [], high: [], low: [], volume: [] } as any;
let basePrice = 100;
for (let i = 0; i < count; i++) {
const change = (Math.random() - 0.5) * 2;
basePrice += change;
const high = basePrice + Math.random() * 1;
const low = basePrice - Math.random() * 1;
const close = low + Math.random() * (high - low);
prices.close.push(close);
prices.high.push(high);
prices.low.push(low);
prices.volume.push(Math.random() * 1000000 + 500000);
}
return prices;
};
const prices = generatePrices(50);
// Calculate MACD
const macd = ta.macd(prices.close);
console.log(`MACD Line: ${TechnicalAnalysis.latest(macd.macd)?.toFixed(3)}`);
console.log(`Signal Line: ${TechnicalAnalysis.latest(macd.signal)?.toFixed(3)}`);
console.log(`Histogram: ${TechnicalAnalysis.latest(macd.histogram)?.toFixed(3)}`);
// Calculate Bollinger Bands
const bb = ta.bollingerBands(prices.close, 20, 2);
const currentPrice = prices.close[prices.close.length - 1];
const bbPercent = (currentPrice - TechnicalAnalysis.latest(bb.lower)!) /
(TechnicalAnalysis.latest(bb.upper)! - TechnicalAnalysis.latest(bb.lower)!);
console.log(`\nBollinger Bands:`);
console.log(`Upper: ${TechnicalAnalysis.latest(bb.upper)?.toFixed(2)}`);
console.log(`Middle: ${TechnicalAnalysis.latest(bb.middle)?.toFixed(2)}`);
console.log(`Lower: ${TechnicalAnalysis.latest(bb.lower)?.toFixed(2)}`);
console.log(`%B: ${(bbPercent * 100).toFixed(2)}%`);
// Calculate Stochastic
const stoch = ta.stochastic(prices.high, prices.low, prices.close, 14, 3, 3);
console.log(`\nStochastic:`);
console.log(`%K: ${TechnicalAnalysis.latest(stoch.k)?.toFixed(2)}`);
console.log(`%D: ${TechnicalAnalysis.latest(stoch.d)?.toFixed(2)}`);
// Calculate ATR
const atr = ta.atr(prices.high, prices.low, prices.close, 14);
console.log(`\nATR(14): ${TechnicalAnalysis.latest(atr)?.toFixed(3)}`);
}
// Example 4: Trading signal generation
async function signalGenerationExample() {
console.log('\n=== Signal Generation Example ===');
const generator = new SignalGenerator();
// Generate trending market data
const generateTrendingPrices = (count: number, trend: 'up' | 'down' | 'sideways') => {
const prices = { close: [], high: [], low: [], volume: [] } as any;
let basePrice = 100;
for (let i = 0; i < count; i++) {
const trendComponent = trend === 'up' ? 0.1 : trend === 'down' ? -0.1 : 0;
const noise = (Math.random() - 0.5) * 2;
basePrice += trendComponent + noise;
const high = basePrice + Math.random() * 1;
const low = basePrice - Math.random() * 1;
const close = low + Math.random() * (high - low);
prices.close.push(close);
prices.high.push(high);
prices.low.push(low);
prices.volume.push(Math.random() * 1000000 + 500000);
}
return prices;
};
// Test different market conditions
const scenarios = [
{ name: 'Uptrend', data: generateTrendingPrices(50, 'up') },
{ name: 'Downtrend', data: generateTrendingPrices(50, 'down') },
{ name: 'Sideways', data: generateTrendingPrices(50, 'sideways') }
];
for (const scenario of scenarios) {
const signal = generator.generateSignals('TEST', scenario.data, Date.now());
console.log(`\n${scenario.name} Market:`);
console.log(`Signal: ${signal.action} (strength: ${signal.strength.toFixed(2)})`);
console.log(`Reason: ${signal.reason}`);
console.log(`Indicators: RSI=${signal.indicators.rsi?.toFixed(2)}, MACD=${signal.indicators.macd?.toFixed(3)}`);
}
}
// Example 5: Crossover detection
async function crossoverExample() {
console.log('\n=== Crossover Detection Example ===');
const ta = new TechnicalAnalysis();
// Generate price data with clear trend changes
const prices: number[] = [];
for (let i = 0; i < 100; i++) {
if (i < 30) {
prices.push(100 + i * 0.3); // Uptrend
} else if (i < 60) {
prices.push(109 - (i - 30) * 0.3); // Downtrend
} else {
prices.push(100 + (i - 60) * 0.2); // Uptrend again
}
}
// Calculate moving averages
const fastMA = ta.sma(prices, 10);
const slowMA = ta.sma(prices, 20);
// Detect crossovers
console.log('Checking for crossovers in the last 10 bars:');
for (let i = Math.max(0, fastMA.length - 10); i < fastMA.length; i++) {
const fast = fastMA.slice(0, i + 1);
const slow = slowMA.slice(0, i + 1);
if (TechnicalAnalysis.crossover(fast, slow)) {
console.log(`Bullish crossover at index ${i + 20}`);
} else if (TechnicalAnalysis.crossunder(fast, slow)) {
console.log(`Bearish crossover at index ${i + 20}`);
}
}
}
// Run all examples
async function runExamples() {
try {
await basicIndicatorExample();
await streamingIndicatorExample();
await complexIndicatorExample();
await signalGenerationExample();
await crossoverExample();
} catch (error) {
console.error('Error running examples:', error);
}
}
// Execute if running directly
if (require.main === module) {
runExamples();
}