|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { EnhancedMarketMonitor } from './enhanced-market-monitor.js';
|
|
|
import { NotificationManager, NOTIFICATION_PRIORITY } from './enhanced-notification-system.js';
|
|
|
import { AdaptiveRegimeDetector, MARKET_REGIMES } from './adaptive-regime-detector.js';
|
|
|
import { analyzeWithAdvancedStrategy, ADVANCED_STRATEGIES_V2 } from './advanced-strategies-v2.js';
|
|
|
import { analyzeWithStrategy, HYBRID_STRATEGIES } from './trading-strategies.js';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export class IntegratedTradingSystem {
|
|
|
constructor(config = {}) {
|
|
|
this.config = {
|
|
|
symbol: config.symbol || 'BTC',
|
|
|
strategy: config.strategy || 'ict-market-structure',
|
|
|
useAdaptiveStrategy: config.useAdaptiveStrategy !== false,
|
|
|
interval: config.interval || 60000,
|
|
|
enableNotifications: config.enableNotifications !== false,
|
|
|
notificationChannels: config.notificationChannels || ['browser'],
|
|
|
telegram: config.telegram || null,
|
|
|
riskLevel: config.riskLevel || 'medium'
|
|
|
};
|
|
|
|
|
|
|
|
|
this.monitor = new EnhancedMarketMonitor({
|
|
|
symbol: this.config.symbol,
|
|
|
strategy: this.config.strategy,
|
|
|
interval: this.config.interval,
|
|
|
useWebSocket: true
|
|
|
});
|
|
|
|
|
|
this.notificationManager = new NotificationManager({
|
|
|
enabled: this.config.enableNotifications,
|
|
|
channels: this.config.notificationChannels,
|
|
|
telegram: this.config.telegram
|
|
|
});
|
|
|
|
|
|
this.regimeDetector = new AdaptiveRegimeDetector({
|
|
|
lookbackPeriod: 100,
|
|
|
volatilityPeriod: 20,
|
|
|
trendPeriod: 50
|
|
|
});
|
|
|
|
|
|
|
|
|
this.isRunning = false;
|
|
|
this.currentRegime = null;
|
|
|
this.lastAnalysis = null;
|
|
|
this.performanceStats = {
|
|
|
totalSignals: 0,
|
|
|
successfulSignals: 0,
|
|
|
failedSignals: 0,
|
|
|
avgConfidence: 0,
|
|
|
startTime: null
|
|
|
};
|
|
|
|
|
|
|
|
|
this.setupEventHandlers();
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async start() {
|
|
|
if (this.isRunning) {
|
|
|
return { success: false, message: 'Already running' };
|
|
|
}
|
|
|
|
|
|
console.log('[IntegratedSystem] Starting...');
|
|
|
|
|
|
try {
|
|
|
|
|
|
const monitorResult = await this.monitor.start();
|
|
|
|
|
|
if (!monitorResult.success) {
|
|
|
throw new Error(`Monitor failed to start: ${monitorResult.message}`);
|
|
|
}
|
|
|
|
|
|
this.isRunning = true;
|
|
|
this.performanceStats.startTime = Date.now();
|
|
|
|
|
|
|
|
|
if (this.config.enableNotifications) {
|
|
|
await this.notificationManager.send({
|
|
|
type: 'system',
|
|
|
priority: NOTIFICATION_PRIORITY.LOW,
|
|
|
title: '✅ Trading System Started',
|
|
|
message: `Monitoring ${this.config.symbol} with ${this.config.strategy} strategy`,
|
|
|
data: {
|
|
|
symbol: this.config.symbol,
|
|
|
strategy: this.config.strategy,
|
|
|
adaptive: this.config.useAdaptiveStrategy
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
console.log('[IntegratedSystem] Started successfully');
|
|
|
return { success: true, message: 'System started successfully' };
|
|
|
} catch (error) {
|
|
|
console.error('[IntegratedSystem] Start error:', error);
|
|
|
return { success: false, message: error.message };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stop() {
|
|
|
if (!this.isRunning) return;
|
|
|
|
|
|
console.log('[IntegratedSystem] Stopping...');
|
|
|
|
|
|
this.monitor.stop();
|
|
|
this.isRunning = false;
|
|
|
|
|
|
|
|
|
if (this.config.enableNotifications) {
|
|
|
this.notificationManager.send({
|
|
|
type: 'system',
|
|
|
priority: NOTIFICATION_PRIORITY.LOW,
|
|
|
title: '🛑 Trading System Stopped',
|
|
|
message: `Stopped monitoring ${this.config.symbol}`,
|
|
|
data: this.getPerformanceStats()
|
|
|
});
|
|
|
}
|
|
|
|
|
|
console.log('[IntegratedSystem] Stopped');
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setupEventHandlers() {
|
|
|
|
|
|
this.monitor.on('Signal', async (analysis) => {
|
|
|
await this.handleSignal(analysis);
|
|
|
});
|
|
|
|
|
|
|
|
|
this.monitor.on('PriceUpdate', (priceData) => {
|
|
|
this.handlePriceUpdate(priceData);
|
|
|
});
|
|
|
|
|
|
|
|
|
this.monitor.on('Error', (error) => {
|
|
|
this.handleError(error);
|
|
|
});
|
|
|
|
|
|
|
|
|
this.monitor.on('ConnectionChange', (status) => {
|
|
|
this.handleConnectionChange(status);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async handleSignal(analysis) {
|
|
|
try {
|
|
|
console.log('[IntegratedSystem] Signal received:', analysis);
|
|
|
|
|
|
|
|
|
this.performanceStats.totalSignals++;
|
|
|
this.lastAnalysis = analysis;
|
|
|
|
|
|
|
|
|
if (!this.shouldExecuteSignal(analysis)) {
|
|
|
console.log('[IntegratedSystem] Signal filtered based on risk level');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
|
|
|
if (this.config.enableNotifications && analysis.signal !== 'hold') {
|
|
|
await this.notificationManager.sendSignal(analysis);
|
|
|
}
|
|
|
|
|
|
|
|
|
this.emitEvent('signal', analysis);
|
|
|
} catch (error) {
|
|
|
console.error('[IntegratedSystem] Signal handling error:', error);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handlePriceUpdate(priceData) {
|
|
|
|
|
|
this.emitEvent('priceUpdate', priceData);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async handleError(error) {
|
|
|
console.error('[IntegratedSystem] Error:', error);
|
|
|
|
|
|
|
|
|
if (this.config.enableNotifications) {
|
|
|
await this.notificationManager.sendError(error, 'Trading System');
|
|
|
}
|
|
|
|
|
|
|
|
|
this.emitEvent('error', error);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handleConnectionChange(status) {
|
|
|
console.log('[IntegratedSystem] Connection change:', status);
|
|
|
|
|
|
|
|
|
this.emitEvent('connectionChange', status);
|
|
|
|
|
|
|
|
|
if (status.status === 'circuit-breaker-open' && this.config.enableNotifications) {
|
|
|
this.notificationManager.send({
|
|
|
type: 'warning',
|
|
|
priority: NOTIFICATION_PRIORITY.HIGH,
|
|
|
title: '⚠️ Circuit Breaker Activated',
|
|
|
message: 'Too many errors detected. System paused temporarily.',
|
|
|
data: status
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async performAnalysis(ohlcvData) {
|
|
|
try {
|
|
|
let strategy = this.config.strategy;
|
|
|
|
|
|
|
|
|
if (this.config.useAdaptiveStrategy) {
|
|
|
const regimeAnalysis = this.regimeDetector.detectRegime(ohlcvData);
|
|
|
this.currentRegime = regimeAnalysis;
|
|
|
|
|
|
|
|
|
const recommendedStrategies = this.regimeDetector.getRecommendedStrategies();
|
|
|
|
|
|
|
|
|
if (recommendedStrategies && recommendedStrategies.length > 0) {
|
|
|
strategy = recommendedStrategies[0];
|
|
|
console.log(`[IntegratedSystem] Regime: ${regimeAnalysis.regime}, Using: ${strategy}`);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
let analysis;
|
|
|
|
|
|
if (ADVANCED_STRATEGIES_V2[strategy]) {
|
|
|
analysis = await analyzeWithAdvancedStrategy(this.config.symbol, strategy, ohlcvData);
|
|
|
} else if (HYBRID_STRATEGIES[strategy]) {
|
|
|
const marketData = {
|
|
|
price: ohlcvData[ohlcvData.length - 1].close,
|
|
|
volume: ohlcvData[ohlcvData.length - 1].volume,
|
|
|
high24h: Math.max(...ohlcvData.slice(-24).map(c => c.high)),
|
|
|
low24h: Math.min(...ohlcvData.slice(-24).map(c => c.low))
|
|
|
};
|
|
|
analysis = analyzeWithStrategy(this.config.symbol, strategy, marketData);
|
|
|
} else {
|
|
|
throw new Error(`Unknown strategy: ${strategy}`);
|
|
|
}
|
|
|
|
|
|
|
|
|
if (this.currentRegime) {
|
|
|
analysis.regime = this.currentRegime.regime;
|
|
|
analysis.regimeConfidence = this.currentRegime.confidence;
|
|
|
}
|
|
|
|
|
|
return analysis;
|
|
|
} catch (error) {
|
|
|
console.error('[IntegratedSystem] Analysis error:', error);
|
|
|
throw error;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
shouldExecuteSignal(analysis) {
|
|
|
const riskLevels = {
|
|
|
'very-low': { minConfidence: 50 },
|
|
|
'low': { minConfidence: 60 },
|
|
|
'medium': { minConfidence: 70 },
|
|
|
'high': { minConfidence: 80 },
|
|
|
'very-high': { minConfidence: 85 }
|
|
|
};
|
|
|
|
|
|
const levelConfig = riskLevels[this.config.riskLevel] || riskLevels.medium;
|
|
|
|
|
|
|
|
|
if (analysis.signal === 'hold') {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
|
|
|
return analysis.confidence >= levelConfig.minConfidence;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
emitEvent(eventName, data) {
|
|
|
window.dispatchEvent(new CustomEvent(`tradingSystem:${eventName}`, {
|
|
|
detail: data
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
updateConfig(newConfig) {
|
|
|
const needsRestart = this.isRunning && (
|
|
|
newConfig.symbol !== this.config.symbol ||
|
|
|
newConfig.interval !== this.config.interval
|
|
|
);
|
|
|
|
|
|
|
|
|
Object.assign(this.config, newConfig);
|
|
|
|
|
|
|
|
|
if (newConfig.symbol || newConfig.strategy || newConfig.interval) {
|
|
|
this.monitor.updateConfig({
|
|
|
symbol: this.config.symbol,
|
|
|
strategy: this.config.strategy,
|
|
|
interval: this.config.interval
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (newConfig.notificationChannels || newConfig.telegram) {
|
|
|
this.notificationManager.updateConfig({
|
|
|
channels: this.config.notificationChannels,
|
|
|
telegram: this.config.telegram
|
|
|
});
|
|
|
}
|
|
|
|
|
|
|
|
|
if (needsRestart) {
|
|
|
this.stop();
|
|
|
this.start();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getStatus() {
|
|
|
return {
|
|
|
isRunning: this.isRunning,
|
|
|
config: this.config,
|
|
|
monitorStatus: this.monitor.getStatus(),
|
|
|
currentRegime: this.currentRegime,
|
|
|
lastAnalysis: this.lastAnalysis,
|
|
|
performanceStats: this.getPerformanceStats()
|
|
|
};
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getPerformanceStats() {
|
|
|
const runtime = this.performanceStats.startTime
|
|
|
? Date.now() - this.performanceStats.startTime
|
|
|
: 0;
|
|
|
|
|
|
return {
|
|
|
...this.performanceStats,
|
|
|
runtime,
|
|
|
runtimeFormatted: this.formatDuration(runtime),
|
|
|
successRate: this.performanceStats.totalSignals > 0
|
|
|
? (this.performanceStats.successfulSignals / this.performanceStats.totalSignals) * 100
|
|
|
: 0
|
|
|
};
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
formatDuration(ms) {
|
|
|
const seconds = Math.floor(ms / 1000);
|
|
|
const minutes = Math.floor(seconds / 60);
|
|
|
const hours = Math.floor(minutes / 60);
|
|
|
const days = Math.floor(hours / 24);
|
|
|
|
|
|
if (days > 0) return `${days}d ${hours % 24}h`;
|
|
|
if (hours > 0) return `${hours}h ${minutes % 60}m`;
|
|
|
if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
|
|
|
return `${seconds}s`;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async test() {
|
|
|
console.log('[IntegratedSystem] Running system test...');
|
|
|
|
|
|
const results = {
|
|
|
monitor: false,
|
|
|
notifications: false,
|
|
|
regimeDetection: false,
|
|
|
strategy: false
|
|
|
};
|
|
|
|
|
|
try {
|
|
|
|
|
|
const monitorStatus = this.monitor.getStatus();
|
|
|
results.monitor = !!monitorStatus;
|
|
|
|
|
|
|
|
|
const notifResult = await this.notificationManager.test();
|
|
|
results.notifications = notifResult.success;
|
|
|
|
|
|
|
|
|
const sampleData = this.generateSampleData();
|
|
|
const regimeResult = this.regimeDetector.detectRegime(sampleData);
|
|
|
results.regimeDetection = !!regimeResult.regime;
|
|
|
|
|
|
|
|
|
const analysisResult = await this.performAnalysis(sampleData);
|
|
|
results.strategy = !!analysisResult.signal;
|
|
|
|
|
|
console.log('[IntegratedSystem] Test results:', results);
|
|
|
return {
|
|
|
success: Object.values(results).every(r => r),
|
|
|
results
|
|
|
};
|
|
|
} catch (error) {
|
|
|
console.error('[IntegratedSystem] Test error:', error);
|
|
|
return {
|
|
|
success: false,
|
|
|
results,
|
|
|
error: error.message
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
generateSampleData() {
|
|
|
const data = [];
|
|
|
let price = 50000;
|
|
|
|
|
|
for (let i = 0; i < 100; i++) {
|
|
|
const volatility = price * 0.02;
|
|
|
const open = price + (Math.random() - 0.5) * volatility;
|
|
|
const close = open + (Math.random() - 0.5) * volatility;
|
|
|
const high = Math.max(open, close) + Math.random() * volatility * 0.5;
|
|
|
const low = Math.min(open, close) - Math.random() * volatility * 0.5;
|
|
|
const volume = Math.random() * 1000000;
|
|
|
|
|
|
data.push({
|
|
|
timestamp: Date.now() - (99 - i) * 3600000,
|
|
|
open, high, low, close, volume
|
|
|
});
|
|
|
|
|
|
price = close;
|
|
|
}
|
|
|
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static getAvailableStrategies() {
|
|
|
return {
|
|
|
advanced: ADVANCED_STRATEGIES_V2,
|
|
|
hybrid: HYBRID_STRATEGIES
|
|
|
};
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static getMarketRegimes() {
|
|
|
return MARKET_REGIMES;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
export default IntegratedTradingSystem;
|
|
|
|
|
|
|