npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

candle_iq

v1.0.3

Published

In-app trading signal engine for React Native/Expo applications

Readme

React Native Trading Signal Engine 📱📈

A comprehensive, mobile-optimized trading signal generation engine for React Native and Expo applications. Generate real-time forex, stock, and crypto trading signals with advanced technical analysis, risk management, and market timing features.

🚀 Features

  • 📊 Real-time Signal Generation: Multi-timeframe technical analysis with 15+ indicators
  • 📱 Mobile Optimized: Built specifically for React Native/Expo with performance optimizations
  • 🛡️ Advanced Risk Management: Customizable risk profiles and alert systems
  • ⏰ Market Timing: Intelligent market hours detection and optimal trading time suggestions
  • 💾 Offline Support: Local caching with AsyncStorage for offline functionality
  • 🔔 Event-Driven: Real-time updates via EventEmitter for reactive UIs
  • ⚙️ Highly Customizable: Configurable indicators, thresholds, and trading parameters
  • 📈 Multiple Markets: Support for Forex, Stocks, and Cryptocurrency
  • 🔐 Secure: Local storage of API keys with secure configuration management

📦 Installation

npm install react-native-trading-signals
# or
yarn add react-native-trading-signals

Required Dependencies

npm install @react-native-async-storage/async-storage
# or
expo install @react-native-async-storage/async-storage

🏃‍♂️ Quick Start

Basic Setup

import TradingSignalEngine from 'react-native-trading-signals';

// Initialize the engine
const engine = new TradingSignalEngine({
  apiKeys: {
    binance: 'your-binance-api-key',
    finnhub: 'your-finnhub-token',
    taapi: 'your-taapi-token'
  },
  symbols: {
    forex: ['EURUSD', 'GBPUSD', 'USDJPY']
  }
});

// Initialize and start
async function startTrading() {
  try {
    await engine.initialize();
    
    // Generate a single signal
    const signal = await engine.generateSignal();
    console.log('Generated Signal:', signal);
    
    // Start continuous signals every 2 minutes
    await engine.startContinuousSignals({ interval: 120000 });
    
  } catch (error) {
    console.error('Failed to start engine:', error);
  }
}

startTrading();

React Native Component Integration

import React, { useEffect, useState } from 'react';
import { View, Text, FlatList, Alert } from 'react-native';
import TradingSignalEngine from 'react-native-trading-signals';

export default function TradingSignalsScreen() {
  const [engine] = useState(() => new TradingSignalEngine({
    apiKeys: {
      binance: process.env.BINANCE_API_KEY,
      finnhub: process.env.FINNHUB_TOKEN
    },
    riskManager: {
      riskTolerance: 'moderate'
    }
  }));
  
  const [signals, setSignals] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [marketStatus, setMarketStatus] = useState(null);

  useEffect(() => {
    initializeEngine();
    
    return () => {
      engine.shutdown();
    };
  }, []);

  const initializeEngine = async () => {
    try {
      // Initialize engine
      await engine.initialize({
        timezone: 'America/New_York',
        riskProfile: {
          riskTolerance: 'conservative',
          maxDailyRisk: 0.02
        }
      });

      // Listen for signals
      engine.on('signalGenerated', (signal) => {
        setSignals(prev => [signal, ...prev.slice(0, 9)]);
        
        // Show notification for high-confidence signals
        if (signal.confidence > 0.8) {
          Alert.alert(
            'High Confidence Signal',
            `${signal.signal} ${signal.symbol} - ${Math.round(signal.confidence * 100)}%`,
            [{ text: 'OK' }]
          );
        }
      });

      // Listen for risk alerts
      engine.on('riskAlert', (alert) => {
        Alert.alert('Risk Alert', alert.message);
      });

      // Listen for market status changes
      engine.on('marketStatusChanged', (status) => {
        setMarketStatus(status);
      });

      // Start continuous signals
      await engine.startContinuousSignals({ interval: 180000 }); // 3 minutes
      
      setIsLoading(false);
    } catch (error) {
      Alert.alert('Error', 'Failed to initialize trading engine');
      setIsLoading(false);
    }
  };

  const renderSignal = ({ item }) => (
    <View style={styles.signalCard}>
      <Text style={styles.symbol}>{item.symbol}</Text>
      <Text style={[styles.signal, { color: item.signal === 'BUY' ? '#4CAF50' : '#F44336' }]}>
        {item.signal}
      </Text>
      <Text style={styles.confidence}>
        Confidence: {Math.round(item.confidence * 100)}%
      </Text>
      <Text style={styles.timestamp}>
        {new Date(item.timestamp).toLocaleTimeString()}
      </Text>
    </View>
  );

  if (isLoading) {
    return (
      <View style={styles.loading}>
        <Text>Loading Trading Engine...</Text>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Live Trading Signals</Text>
      
      {marketStatus && (
        <View style={styles.marketStatus}>
          <Text>Market Status: {marketStatus.current.markets.forex ? 'Open' : 'Closed'}</Text>
        </View>
      )}
      
      <FlatList
        data={signals}
        keyExtractor={(item) => item.id}
        renderItem={renderSignal}
        ListEmptyComponent={<Text>No signals yet...</Text>}
      />
    </View>
  );
}

const styles = {
  container: { flex: 1, padding: 20 },
  title: { fontSize: 24, fontWeight: 'bold', marginBottom: 20 },
  signalCard: { 
    backgroundColor: '#f5f5f5', 
    padding: 15, 
    marginBottom: 10, 
    borderRadius: 8 
  },
  symbol: { fontSize: 18, fontWeight: 'bold' },
  signal: { fontSize: 16, fontWeight: '600', marginTop: 5 },
  confidence: { fontSize: 14, color: '#666', marginTop: 5 },
  timestamp: { fontSize: 12, color: '#999', marginTop: 5 },
  loading: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  marketStatus: { padding: 10, backgroundColor: '#e3f2fd', borderRadius: 5, marginBottom: 15 }
};

📚 Advanced Usage

Custom Risk Management

const engine = new TradingSignalEngine({
  riskManager: {
    riskTolerance: 'aggressive', // conservative, moderate, aggressive
    maxDailyRisk: 0.05, // 5% max daily risk
    maxPositionSize: 0.1, // 10% max position
    stopLossRequired: true,
    alertPreferences: {
      highRisk: true,
      marketClosed: true,
      lowConfidence: false
    }
  }
});

// Listen for risk events
engine.on('riskAlert', (alert) => {
  console.log('Risk Alert:', alert);
  // Handle risk alert in UI
});

engine.on('signalBlocked', (data) => {
  console.log('Signal blocked due to risk:', data.reason);
});

Price Subscriptions

// Subscribe to real-time price updates
const subscription = engine.subscribeToPrice(
  { display: 'EURUSD', binance: 'EURUSDT' },
  (price, symbol) => {
    console.log(`${symbol.display}: ${price}`);
    // Update UI with new price
  },
  { interval: 5000 } // Update every 5 seconds
);

// Unsubscribe when done
// engine.unsubscribe(subscription);

Market Timing

// Check if market is open
const isForexOpen = engine.timeManager.isMarketOpen('forex');
console.log('Forex market open:', isForexOpen);

// Get optimal trading times
const optimalTimes = engine.timeManager.getOptimalTradingTimes('forex');
console.log('Best trading sessions:', optimalTimes);

// Listen for market status changes
engine.on('marketStatusChanged', (status) => {
  console.log('Market status changed:', status);
});

Custom Indicators

// Customize technical analysis parameters
engine.technicalAnalysis.updateIndicatorParams({
  rsi: { period: 21, overbought: 75, oversold: 25 },
  macd: { fast: 10, slow: 21, signal: 9 },
  bb: { period: 25, deviation: 2.5 }
});

// Custom signal processing weights
engine.signalProcessor.updateWeights({
  confidence: 0.5,
  trendAlignment: 0.3,
  volumeConfirmation: 0.2
});

Data Export/Import

// Export configuration and history
const exportData = await engine.exportData();
console.log('Exported data:', exportData);

// Save to file or cloud storage
await AsyncStorage.setItem('trading_backup', JSON.stringify(exportData));

// Import configuration
const importData = JSON.parse(await AsyncStorage.getItem('trading_backup'));
await engine.importData(importData);

📋 API Reference

TradingSignalEngine

Constructor Options

const engine = new TradingSignalEngine({
  // API Configuration
  apiKeys: {
    binance: 'your-api-key',
    finnhub: 'your-token',
    taapi: 'your-token',
    alphaVantage: 'your-key'
  },
  
  // Symbol Configuration
  symbols: {
    forex: [
      { display: 'EURUSD', binance: 'EURUSDT', finnhub: 'OANDA:EUR_USD' },
      { display: 'GBPUSD', binance: 'GBPUSDT', finnhub: 'OANDA:GBP_USD' }
    ]
  },
  
  // Component Settings
  riskManager: { /* risk settings */ },
  technicalAnalysis: { /* indicator settings */ },
  timeManager: { /* timezone settings */ },
  // ... other components
});

Main Methods

initialize(userConfig)

Initialize the engine with optional user configuration.

await engine.initialize({
  timezone: 'America/New_York',
  riskProfile: {
    riskTolerance: 'conservative',
    maxDailyRisk: 0.02
  }
});
generateSignal(symbols, options)

Generate trading signals for specified symbols.

const signal = await engine.generateSignal(null, {
  timeframe: 1, // 1-minute
  minScore: 0.7,
  respectMarketHours: true
});
startContinuousSignals(options)

Start continuous signal generation.

await engine.startContinuousSignals({
  interval: 120000, // 2 minutes
  respectMarketHours: true
});
subscribeToPrice(symbol, callback, options)

Subscribe to real-time price updates.

const subscriptionId = engine.subscribeToPrice(
  symbol,
  (price, symbol) => console.log(price),
  { interval: 5000 }
);

Events

// Signal events
engine.on('signalGenerated', (signal) => {});
engine.on('signalBlocked', (data) => {});
engine.on('noSignalGenerated', (data) => {});

// Risk events
engine.on('riskAlert', (alert) => {});

// Market events
engine.on('marketStatusChanged', (status) => {});
engine.on('priceUpdate', (data) => {});

// System events
engine.on('error', (error) => {});
engine.on('initialized', (status) => {});

Signal Object Structure

{
  id: "unique-signal-id",
  symbol: "EURUSD",
  signal: "BUY", // or "SELL"
  confidence: 0.85, // 0-1
  signalStrength: 0.72,
  signalStrengthRatio: 0.68,
  
  // Technical metrics
  trendAlignment: 0.8,
  volatility: 0.015,
  momentum: 0.65,
  volumeConfirmation: true,
  
  // Metadata
  timeframe: 1,
  timestamp: "2024-01-01T12:00:00.000Z",
  dataQuality: "LIVE", // LIVE, DELAYED, SYNTHETIC
  indicatorCount: 8,
  processingTime: 1250,
  
  // Risk assessment
  riskScore: 0.3,
  conflictingSignals: 1
}

⚙️ Configuration

Complete Configuration Example

const config = {
  version: '1.0.0',
  
  // API Keys (store securely)
  apiKeys: {
    binance: process.env.BINANCE_API_KEY,
    finnhub: process.env.FINNHUB_TOKEN,
    taapi: process.env.TAAPI_TOKEN,
    alphaVantage: process.env.ALPHA_VANTAGE_KEY
  },
  
  // Trading symbols
  symbols: {
    forex: [
      { 
        display: 'EURUSD', 
        binance: 'EURUSDT', 
        finnhub: 'OANDA:EUR_USD',
        taapi: 'EUR/USD',
        type: 'forex'
      }
    ]
  },
  
  // Signal generation settings
  signalInterval: 120000, // 2 minutes
  minConfidence: 0.65,
  
  // Risk Management
  riskManager: {
    riskTolerance: 'conservative', // conservative, moderate, aggressive
    maxDailyRisk: 0.02,
    maxPositionSize: 0.05,
    stopLossRequired: true,
    marketHoursOnly: true,
    thresholds: {
      HIGH_VOLATILITY: 0.04,
      MIN_CONFIDENCE: 0.70,
      MAX_CONSECUTIVE_LOSSES: 3
    }
  },
  
  // Technical Analysis
  technicalAnalysis: {
    indicatorParams: {
      rsi: { period: 14, overbought: 70, oversold: 30 },
      macd: { fast: 12, slow: 26, signal: 9 },
      bb: { period: 20, deviation: 2 },
      sma: { periods: [20, 50, 200] },
      ema: { periods: [12, 26, 50] }
    }
  },
  
  // Signal Processing
  signalProcessor: {
    weights: {
      confidence: 0.4,
      trendAlignment: 0.25,
      volumeConfirmation: 0.15,
      riskScore: 0.1,
      momentum: 0.1
    },
    thresholds: {
      minConfidence: 0.65,
      minTrendAlignment: 0.6,
      signalStrengthRatio: 0.3
    }
  },
  
  // Time Management
  timeManager: {
    defaultTimezone: 'UTC',
    respectMarketHours: true
  }
};

🔐 Security Best Practices

API Key Management

// ❌ Don't do this - hardcoded keys
const engine = new TradingSignalEngine({
  apiKeys: {
    binance: 'hardcoded-api-key'
  }
});

// ✅ Use environment variables
const engine = new TradingSignalEngine({
  apiKeys: {
    binance: process.env.BINANCE_API_KEY,
    finnhub: process.env.FINNHUB_TOKEN
  }
});

// ✅ Or use secure storage
import * as SecureStore from 'expo-secure-store';

const apiKey = await SecureStore.getItemAsync('binance-api-key');
const engine = new TradingSignalEngine({
  apiKeys: {
    binance: apiKey
  }
});

Environment Setup (.env)

BINANCE_API_KEY=your_binance_api_key_here
FINNHUB_TOKEN=your_finnhub_token_here
TAAPI_TOKEN=your_taapi_token_here
ALPHA_VANTAGE_KEY=your_alpha_vantage_key_here

📊 Performance Optimization

Memory Management

// Clean up subscriptions
useEffect(() => {
  const subscription = engine.subscribeToPrice(symbol, callback);
  
  return () => {
    engine.unsubscribe(subscription);
  };
}, []);

// Regular cleanup
useEffect(() => {
  const interval = setInterval(() => {
    // Engine automatically cleans up old data
    console.log('Active signals:', engine.getActiveSignals().length);
  }, 300000); // 5 minutes
  
  return () => clearInterval(interval);
}, []);

Background Processing

import { AppState } from 'react-native';

// Handle app state changes
useEffect(() => {
  const handleAppStateChange = (nextAppState) => {
    if (nextAppState === 'background') {
      // Reduce signal frequency in background
      engine.stopContinuousSignals();
      engine.startContinuousSignals({ interval: 300000 }); // 5 minutes
    } else if (nextAppState === 'active') {
      // Resume normal frequency
      engine.stopContinuousSignals();
      engine.startContinuousSignals({ interval: 120000 }); // 2 minutes
    }
  };

  const subscription = AppState.addEventListener('change', handleAppStateChange);
  return () => subscription?.remove();
}, []);

🧪 Testing

Unit Testing Example

import TradingSignalEngine from 'react-native-trading-signals';

describe('TradingSignalEngine', () => {
  let engine;
  
  beforeEach(() => {
    engine = new TradingSignalEngine({
      apiKeys: { binance: 'test-key' }
    });
  });
  
  afterEach(async () => {
    await engine.shutdown();
  });
  
  test('should initialize successfully', async () => {
    const result = await engine.initialize();
    expect(result.success).toBe(true);
  });
  
  test('should generate signals', async () => {
    await engine.initialize();
    
    const signal = await engine.generateSignal();
    expect(signal).toBeDefined();
    expect(['BUY', 'SELL'].includes(signal.signal)).toBe(true);
    expect(signal.confidence).toBeGreaterThan(0);
  });
  
  test('should handle market hours', () => {
    const isOpen = engine.timeManager.isMarketOpen('forex');
    expect(typeof isOpen).toBe('boolean');
  });
});

📈 Monitoring & Analytics

Performance Tracking

// Get comprehensive statistics
const stats = engine.getEngineStatus();
console.log('Engine Performance:', {
  uptime: stats.uptime,
  signalsGenerated: stats.stats.totalSignalsGenerated,
  successRate: stats.stats.successfulSignals / stats.stats.totalSignalsGenerated,
  averageProcessingTime: stats.stats.averageProcessingTime,
  activeSignals: stats.activeSignals,
  componentHealth: Object.keys(stats.components).map(comp => ({
    component: comp,
    status: stats.components[comp].errors || 0
  }))
});

// Monitor signal history
const recentSignals = engine.getSignalHistory({
  limit: 50,
  minConfidence: 0.7,
  since: new Date(Date.now() - 24 * 60 * 60 * 1000) // Last 24 hours
});

Error Handling

engine.on('error', (error) => {
  console.error('Engine Error:', error);
  
  // Log to analytics service
  analytics.track('TradingEngineError', {
    type: error.type,
    message: error.error,
    timestamp: error.timestamp
  });
  
  // Show user-friendly message
  if (error.type === 'rateLimit') {
    Alert.alert('Rate Limit', 'API rate limit reached. Signals may be delayed.');
  } else if (error.type === 'network') {
    Alert.alert('Network Error', 'Check your internet connection.');
  }
});

🎯 Best Practices

1. Proper Initialization

// Always initialize before use
const [isReady, setIsReady] = useState(false);

useEffect(() => {
  initializeEngine();
}, []);

const initializeEngine = async () => {
  try {
    await engine.initialize();
    setIsReady(true);
  } catch (error) {
    console.error('Initialization failed:', error);
  }
};

// Only use engine when ready
if (isReady) {
  // Use engine methods
}

2. Resource Management

// Always cleanup on unmount
useEffect(() => {
  return () => {
    engine.shutdown();
  };
}, []);

3. Error Boundaries

import React from 'react';

class TradingErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  
  static getDerivedStateFromError(error) {
    return { hasError: true };
  }
  
  componentDidCatch(error, errorInfo) {
    console.error('Trading Engine Error:', error, errorInfo);
  }
  
  render() {
    if (this.state.hasError) {
      return <Text>Something went wrong with the trading engine.</Text>;
    }
    
    return this.props.children;
  }
}

// Wrap your trading components
<TradingErrorBoundary>
  <TradingSignalsScreen />
</TradingErrorBoundary>

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

📄 License

MIT License - see LICENSE file for details.

🆘 Support

📋 Changelog

v1.0.0

  • Initial release with full trading signal generation
  • React Native/Expo optimization
  • Multi-market support (Forex, Stocks, Crypto)
  • Advanced risk management
  • Real-time price feeds
  • Market timing intelligence

⚠️ Disclaimer: This library is for educational and research purposes. Trading involves risk and you should never trade with money you cannot afford to lose. Past performance does not guarantee future results.

🔒 Security: Always keep your API keys secure and never commit them to version control.