candle_iq
v1.0.3
Published
In-app trading signal engine for React Native/Expo applications
Maintainers
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-signalsRequired 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
- 📧 Email: [email protected]
- 🐛 Issues: GitHub Issues
- 📚 Documentation: Full API Docs
- 💬 Discord: Join our community
📋 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.
