feat: implement dynamic risk-based analysis intervals
- Replace fixed 10-minute intervals with adaptive timing based on position risk - CRITICAL/HIGH risk: 5 minutes (minimum to protect ChatGPT budget) - MEDIUM risk: 10 minutes for regular monitoring - LOW risk: 15 minutes for relaxed monitoring - NO POSITION: 10 minutes for entry signal detection - Dynamic monitoring queries position monitor API each cycle for risk assessment - Budget protection: minimum 5-minute intervals (no 1-2 minute excessive usage) - Fallback safety: defaults to 10 minutes if risk assessment fails - Changed from setInterval to setTimeout chain for true dynamic adjustment
This commit is contained in:
@@ -113,10 +113,9 @@ class SimpleAutomation {
|
|||||||
console.log('TIMEFRAMES: [' + timeframes.join(', ') + ']');
|
console.log('TIMEFRAMES: [' + timeframes.join(', ') + ']');
|
||||||
console.log('MODE: ' + (config.mode || 'SIMULATION'));
|
console.log('MODE: ' + (config.mode || 'SIMULATION'));
|
||||||
|
|
||||||
// Start simple monitoring cycle (10 minutes for safety)
|
// Start dynamic monitoring cycle with risk-based intervals
|
||||||
this.intervalId = setInterval(() => {
|
this.currentInterval = 10 * 60 * 1000; // Start with 10 minutes
|
||||||
this.runCycle();
|
this.startDynamicMonitoring();
|
||||||
}, 10 * 60 * 1000); // 10 minutes
|
|
||||||
|
|
||||||
// First cycle after 30 seconds
|
// First cycle after 30 seconds
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -144,7 +143,7 @@ class SimpleAutomation {
|
|||||||
console.log('✅ AUTOMATION STATUS: isRunning =', this.isRunning);
|
console.log('✅ AUTOMATION STATUS: isRunning =', this.isRunning);
|
||||||
|
|
||||||
if (this.intervalId) {
|
if (this.intervalId) {
|
||||||
clearInterval(this.intervalId);
|
clearTimeout(this.intervalId); // Changed from clearInterval to clearTimeout
|
||||||
this.intervalId = null;
|
this.intervalId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,6 +162,75 @@ class SimpleAutomation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dynamic monitoring with risk-based intervals
|
||||||
|
startDynamicMonitoring() {
|
||||||
|
const runMonitoringCycle = async () => {
|
||||||
|
if (!this.isRunning) return;
|
||||||
|
|
||||||
|
await this.runCycle();
|
||||||
|
|
||||||
|
// Get current risk level from position monitor
|
||||||
|
const nextInterval = await this.getNextInterval();
|
||||||
|
|
||||||
|
// Schedule next cycle with dynamic interval
|
||||||
|
this.intervalId = setTimeout(runMonitoringCycle, nextInterval);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start the dynamic cycle
|
||||||
|
this.intervalId = setTimeout(runMonitoringCycle, this.currentInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine next interval based on risk level
|
||||||
|
async getNextInterval() {
|
||||||
|
try {
|
||||||
|
// Check position monitor for current risk level
|
||||||
|
const baseUrl = process.env.INTERNAL_API_URL || 'http://localhost:3000';
|
||||||
|
const response = await fetch(`${baseUrl}/api/automation/position-monitor`, {
|
||||||
|
cache: 'no-store',
|
||||||
|
headers: { 'Cache-Control': 'no-cache' }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
const riskLevel = data.monitor?.riskLevel || 'NONE';
|
||||||
|
|
||||||
|
// Dynamic intervals based on risk (5 min minimum to protect ChatGPT budget)
|
||||||
|
let intervalMinutes;
|
||||||
|
switch (riskLevel) {
|
||||||
|
case 'CRITICAL':
|
||||||
|
intervalMinutes = 5; // Most frequent: 5 minutes (was 1-2 min)
|
||||||
|
break;
|
||||||
|
case 'HIGH':
|
||||||
|
intervalMinutes = 5; // High risk: 5 minutes
|
||||||
|
break;
|
||||||
|
case 'MEDIUM':
|
||||||
|
intervalMinutes = 10; // Medium risk: 10 minutes
|
||||||
|
break;
|
||||||
|
case 'LOW':
|
||||||
|
intervalMinutes = 15; // Low risk: 15 minutes
|
||||||
|
break;
|
||||||
|
case 'NONE':
|
||||||
|
default:
|
||||||
|
intervalMinutes = 10; // No position: 10 minutes (looking for entries)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const intervalMs = intervalMinutes * 60 * 1000;
|
||||||
|
|
||||||
|
console.log(`📊 DYNAMIC INTERVAL: Risk level ${riskLevel} → Next analysis in ${intervalMinutes} minutes`);
|
||||||
|
|
||||||
|
this.currentInterval = intervalMs;
|
||||||
|
return intervalMs;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('⚠️ Failed to get risk level for dynamic interval, using default 10 minutes:', error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to 10 minutes
|
||||||
|
this.currentInterval = 10 * 60 * 1000;
|
||||||
|
return this.currentInterval;
|
||||||
|
}
|
||||||
|
|
||||||
async runCycle() {
|
async runCycle() {
|
||||||
try {
|
try {
|
||||||
// Check if automation should still be running
|
// Check if automation should still be running
|
||||||
@@ -200,7 +268,7 @@ class SimpleAutomation {
|
|||||||
this.stats.status = 'Stopped due to errors';
|
this.stats.status = 'Stopped due to errors';
|
||||||
|
|
||||||
if (this.intervalId) {
|
if (this.intervalId) {
|
||||||
clearInterval(this.intervalId);
|
clearTimeout(this.intervalId); // Changed from clearInterval to clearTimeout
|
||||||
this.intervalId = null;
|
this.intervalId = null;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user