🧠 Implement AI Learning System for Stop Loss Decisions
- Add stop-loss-decision-learner.js: Core learning engine
- Add enhanced-autonomous-risk-manager.js: Learning-enhanced decisions
- Add AI learning API and dashboard components
- Add database schema for decision tracking
- Integrate with existing automation system
- Demo scripts and documentation
Result: AI learns from every decision and improves over time! 🚀
This commit is contained in:
108
STOP_LOSS_LEARNING_IMPLEMENTATION.md
Normal file
108
STOP_LOSS_LEARNING_IMPLEMENTATION.md
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
# 🧠 Stop Loss Decision Learning System
|
||||||
|
|
||||||
|
## 📋 **Missing Learning Components**
|
||||||
|
|
||||||
|
### 1. **Decision Recording**
|
||||||
|
The autonomous risk manager needs to record every decision made near stop loss:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// When AI makes a decision near SL:
|
||||||
|
await this.recordDecision({
|
||||||
|
tradeId: trade.id,
|
||||||
|
distanceFromSL: stopLoss.distancePercent,
|
||||||
|
decision: 'TIGHTEN_STOP_LOSS', // or 'HOLD', 'EXIT', etc.
|
||||||
|
reasoning: decision.reasoning,
|
||||||
|
marketConditions: await this.analyzeMarketContext(),
|
||||||
|
timestamp: new Date()
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Outcome Assessment**
|
||||||
|
Track what happened after each AI decision:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Later, when trade closes:
|
||||||
|
await this.assessDecisionOutcome({
|
||||||
|
decisionId: originalDecision.id,
|
||||||
|
actualOutcome: 'HIT_ORIGINAL_SL', // or 'HIT_TIGHTENED_SL', 'PROFITABLE_EXIT'
|
||||||
|
timeToOutcome: minutesFromDecision,
|
||||||
|
pnlImpact: decision.pnlDifference,
|
||||||
|
wasDecisionCorrect: calculateIfDecisionWasOptimal()
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Learning Integration**
|
||||||
|
Connect decision outcomes to AI improvement:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Analyze historical decision patterns:
|
||||||
|
const learningInsights = await this.analyzeDecisionHistory({
|
||||||
|
successfulPatterns: [], // What decisions work best at different SL distances
|
||||||
|
failurePatterns: [], // What decisions often lead to worse outcomes
|
||||||
|
optimalTiming: {}, // Best times to act vs hold
|
||||||
|
contextFactors: [] // Market conditions that influence decision success
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 **Implementation Requirements**
|
||||||
|
|
||||||
|
### **Database Schema Extension**
|
||||||
|
```sql
|
||||||
|
-- New table for SL decision tracking
|
||||||
|
CREATE TABLE sl_decisions (
|
||||||
|
id STRING PRIMARY KEY,
|
||||||
|
trade_id STRING,
|
||||||
|
decision_type STRING, -- 'HOLD', 'EXIT', 'TIGHTEN_SL', 'PARTIAL_EXIT'
|
||||||
|
distance_from_sl FLOAT,
|
||||||
|
reasoning TEXT,
|
||||||
|
market_conditions JSON,
|
||||||
|
decision_timestamp DATETIME,
|
||||||
|
outcome STRING, -- 'CORRECT', 'INCORRECT', 'NEUTRAL'
|
||||||
|
outcome_timestamp DATETIME,
|
||||||
|
pnl_impact FLOAT,
|
||||||
|
learning_score FLOAT
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Enhanced Autonomous Risk Manager**
|
||||||
|
```javascript
|
||||||
|
class AutonomousRiskManager {
|
||||||
|
async analyzePosition(monitor) {
|
||||||
|
// Current decision logic...
|
||||||
|
const decision = this.makeDecision(stopLoss);
|
||||||
|
|
||||||
|
// NEW: Record this decision for learning
|
||||||
|
await this.recordDecision(monitor, decision);
|
||||||
|
|
||||||
|
return decision;
|
||||||
|
}
|
||||||
|
|
||||||
|
async recordDecision(monitor, decision) {
|
||||||
|
// Store decision with context for later analysis
|
||||||
|
}
|
||||||
|
|
||||||
|
async learnFromPastDecisions() {
|
||||||
|
// Analyze historical decisions and outcomes
|
||||||
|
// Adjust decision thresholds based on what worked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 **Learning Outcomes**
|
||||||
|
|
||||||
|
With this system, the AI would learn:
|
||||||
|
|
||||||
|
1. **Optimal Decision Points**: At what SL distance should it act vs hold?
|
||||||
|
2. **Context Sensitivity**: When do market conditions make early exit better?
|
||||||
|
3. **Risk Assessment**: How accurate are its "emergency" vs "safe" classifications?
|
||||||
|
4. **Strategy Refinement**: Which stop loss adjustments actually improve outcomes?
|
||||||
|
|
||||||
|
## 🚀 **Integration with Existing System**
|
||||||
|
|
||||||
|
This would extend the current drift-feedback-loop.js to include:
|
||||||
|
- SL decision tracking
|
||||||
|
- Decision outcome assessment
|
||||||
|
- Learning pattern recognition
|
||||||
|
- Strategy optimization based on decision history
|
||||||
|
|
||||||
|
The result: An AI that not only learns from trade outcomes but also learns from its own decision-making process near stop losses! 🎯
|
||||||
203
app/api/ai/learning/route.ts
Normal file
203
app/api/ai/learning/route.ts
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
import { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AI Learning Insights API
|
||||||
|
*
|
||||||
|
* Provides access to the stop loss decision learning system insights
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface LearningResult {
|
||||||
|
success: boolean;
|
||||||
|
message: string;
|
||||||
|
data?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
const { method } = req
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (method) {
|
||||||
|
case 'GET':
|
||||||
|
return await getLearningInsights(req, res)
|
||||||
|
case 'POST':
|
||||||
|
return await manageLearningSystem(req, res)
|
||||||
|
default:
|
||||||
|
res.setHeader('Allow', ['GET', 'POST'])
|
||||||
|
return res.status(405).json({ success: false, error: `Method ${method} not allowed` })
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('Learning insights API error:', error)
|
||||||
|
return res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
error: 'Internal server error',
|
||||||
|
message: error?.message || 'Unknown error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getLearningInsights(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
try {
|
||||||
|
// Import the learning system dynamically
|
||||||
|
const EnhancedAutonomousRiskManager = require('../../../lib/enhanced-autonomous-risk-manager.js')
|
||||||
|
const riskManager = new EnhancedAutonomousRiskManager()
|
||||||
|
|
||||||
|
// Get comprehensive learning status
|
||||||
|
const learningStatus = await riskManager.getLearningStatus()
|
||||||
|
|
||||||
|
// Get decision patterns
|
||||||
|
const StopLossDecisionLearner = require('../../../lib/stop-loss-decision-learner.js')
|
||||||
|
const learner = new StopLossDecisionLearner()
|
||||||
|
const patterns = await learner.analyzeDecisionPatterns()
|
||||||
|
const learningReport = await learner.generateLearningReport()
|
||||||
|
|
||||||
|
const insights = {
|
||||||
|
success: true,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
learningSystem: {
|
||||||
|
status: learningStatus.isLearning ? 'ACTIVE' : 'INACTIVE',
|
||||||
|
confidence: (learningStatus.systemConfidence * 100).toFixed(1) + '%',
|
||||||
|
totalDecisions: learningStatus.totalDecisions,
|
||||||
|
pendingAssessments: learningStatus.pendingAssessments,
|
||||||
|
currentThresholds: learningStatus.currentThresholds,
|
||||||
|
lastAnalysis: learningStatus.lastAnalysis
|
||||||
|
},
|
||||||
|
decisionPatterns: {
|
||||||
|
successful: patterns?.successfulPatterns || [],
|
||||||
|
failures: patterns?.failurePatterns || [],
|
||||||
|
optimalTiming: patterns?.optimalTiming || {},
|
||||||
|
distanceOptimization: patterns?.distanceOptimization || {}
|
||||||
|
},
|
||||||
|
performanceMetrics: {
|
||||||
|
overallSuccessRate: calculateOverallSuccessRate(patterns),
|
||||||
|
mostSuccessfulDecision: findMostSuccessfulDecision(patterns),
|
||||||
|
improvementTrend: calculateImprovementTrend(learningReport),
|
||||||
|
confidenceLevel: learningStatus.systemConfidence
|
||||||
|
},
|
||||||
|
recommendations: learningReport?.recommendations || [],
|
||||||
|
systemHealth: {
|
||||||
|
learningActive: learningStatus.isLearning,
|
||||||
|
dataQuality: assessDataQuality(patterns),
|
||||||
|
systemMaturity: assessSystemMaturity(learningStatus.totalDecisions),
|
||||||
|
readyForAutonomy: learningStatus.systemConfidence > 0.7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).json(insights)
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('Error getting learning insights:', error)
|
||||||
|
return res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
error: 'Failed to retrieve learning insights',
|
||||||
|
message: error?.message || 'Unknown error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function manageLearningSystem(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
try {
|
||||||
|
const { action, parameters } = req.body
|
||||||
|
|
||||||
|
const EnhancedAutonomousRiskManager = require('../../../lib/enhanced-autonomous-risk-manager.js')
|
||||||
|
const riskManager = new EnhancedAutonomousRiskManager()
|
||||||
|
|
||||||
|
let result: LearningResult = { success: false, message: 'Unknown action' }
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case 'updateThresholds':
|
||||||
|
// Update learning thresholds
|
||||||
|
if (parameters?.thresholds) {
|
||||||
|
await riskManager.updateThresholdsFromLearning()
|
||||||
|
result = { success: true, message: 'Thresholds updated from learning data' }
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'generateReport':
|
||||||
|
// Force generate a new learning report
|
||||||
|
const StopLossDecisionLearner = require('../../../lib/stop-loss-decision-learner.js')
|
||||||
|
const learner = new StopLossDecisionLearner()
|
||||||
|
const report = await learner.generateLearningReport()
|
||||||
|
result = { success: true, message: 'Report generated', data: report }
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'getRecommendation':
|
||||||
|
// Get smart recommendation for current situation
|
||||||
|
if (parameters?.situation) {
|
||||||
|
const recommendation = await riskManager.learner.getSmartRecommendation(parameters.situation)
|
||||||
|
result = { success: true, message: 'Recommendation generated', data: recommendation }
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'assessPendingDecisions':
|
||||||
|
// Force assessment of pending decisions
|
||||||
|
await riskManager.assessDecisionOutcomes()
|
||||||
|
result = { success: true, message: 'Pending decisions assessed' }
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
result = { success: false, message: `Unknown action: ${action}` }
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).json(result)
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('Error managing learning system:', error)
|
||||||
|
return res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
error: 'Failed to manage learning system',
|
||||||
|
message: error?.message || 'Unknown error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
function calculateOverallSuccessRate(patterns: any): number {
|
||||||
|
if (!patterns?.successfulPatterns || patterns.successfulPatterns.length === 0) return 0
|
||||||
|
|
||||||
|
const totalSamples = patterns.successfulPatterns.reduce((sum: number, p: any) => sum + p.sampleSize, 0)
|
||||||
|
const totalSuccesses = patterns.successfulPatterns.reduce((sum: number, p: any) => sum + (p.sampleSize * p.successRate / 100), 0)
|
||||||
|
|
||||||
|
return totalSamples > 0 ? parseFloat((totalSuccesses / totalSamples * 100).toFixed(1)) : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function findMostSuccessfulDecision(patterns: any): any {
|
||||||
|
if (!patterns?.successfulPatterns || patterns.successfulPatterns.length === 0) {
|
||||||
|
return { type: 'NONE', rate: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
const best = patterns.successfulPatterns.reduce((best: any, current: any) =>
|
||||||
|
current.successRate > best.successRate ? current : best
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: best.decisionType,
|
||||||
|
rate: best.successRate.toFixed(1) + '%',
|
||||||
|
samples: best.sampleSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateImprovementTrend(report: any): string {
|
||||||
|
// Simple trend calculation - in production, this would analyze historical data
|
||||||
|
if (!report?.summary?.systemConfidence) return 'INSUFFICIENT_DATA'
|
||||||
|
|
||||||
|
const confidence = report.summary.systemConfidence
|
||||||
|
if (confidence > 0.8) return 'EXCELLENT'
|
||||||
|
if (confidence > 0.6) return 'IMPROVING'
|
||||||
|
if (confidence > 0.4) return 'LEARNING'
|
||||||
|
return 'INITIALIZING'
|
||||||
|
}
|
||||||
|
|
||||||
|
function assessDataQuality(patterns: any): string {
|
||||||
|
const totalDecisions = patterns?.successfulPatterns?.reduce((sum: number, p: any) => sum + p.sampleSize, 0) || 0
|
||||||
|
|
||||||
|
if (totalDecisions >= 50) return 'HIGH'
|
||||||
|
if (totalDecisions >= 20) return 'MEDIUM'
|
||||||
|
if (totalDecisions >= 5) return 'LOW'
|
||||||
|
return 'INSUFFICIENT'
|
||||||
|
}
|
||||||
|
|
||||||
|
function assessSystemMaturity(totalDecisions: number): string {
|
||||||
|
if (totalDecisions >= 100) return 'EXPERT'
|
||||||
|
if (totalDecisions >= 50) return 'INTERMEDIATE'
|
||||||
|
if (totalDecisions >= 20) return 'NOVICE'
|
||||||
|
if (totalDecisions >= 5) return 'BEGINNER'
|
||||||
|
return 'LEARNING'
|
||||||
|
}
|
||||||
443
app/components/AILearningDashboard.tsx
Normal file
443
app/components/AILearningDashboard.tsx
Normal file
@@ -0,0 +1,443 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AI Learning Dashboard
|
||||||
|
*
|
||||||
|
* Beautiful dashboard to display stop loss decision learning insights
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface LearningInsights {
|
||||||
|
success: boolean
|
||||||
|
timestamp: string
|
||||||
|
learningSystem: {
|
||||||
|
status: string
|
||||||
|
confidence: string
|
||||||
|
totalDecisions: number
|
||||||
|
pendingAssessments: number
|
||||||
|
currentThresholds: {
|
||||||
|
emergency: number
|
||||||
|
risk: number
|
||||||
|
mediumRisk: number
|
||||||
|
}
|
||||||
|
lastAnalysis: any
|
||||||
|
}
|
||||||
|
decisionPatterns: {
|
||||||
|
successful: Array<{
|
||||||
|
decisionType: string
|
||||||
|
successRate: number
|
||||||
|
avgScore: number
|
||||||
|
sampleSize: number
|
||||||
|
}>
|
||||||
|
failures: Array<{
|
||||||
|
decisionType: string
|
||||||
|
successRate: number
|
||||||
|
sampleSize: number
|
||||||
|
}>
|
||||||
|
optimalTiming: any
|
||||||
|
distanceOptimization: any
|
||||||
|
}
|
||||||
|
performanceMetrics: {
|
||||||
|
overallSuccessRate: number
|
||||||
|
mostSuccessfulDecision: {
|
||||||
|
type: string
|
||||||
|
rate: string
|
||||||
|
samples: number
|
||||||
|
}
|
||||||
|
improvementTrend: string
|
||||||
|
confidenceLevel: number
|
||||||
|
}
|
||||||
|
recommendations: Array<{
|
||||||
|
type: string
|
||||||
|
priority: string
|
||||||
|
message: string
|
||||||
|
actionable: boolean
|
||||||
|
}>
|
||||||
|
systemHealth: {
|
||||||
|
learningActive: boolean
|
||||||
|
dataQuality: string
|
||||||
|
systemMaturity: string
|
||||||
|
readyForAutonomy: boolean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AILearningDashboard() {
|
||||||
|
const [insights, setInsights] = useState<LearningInsights | null>(null)
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [error, setError] = useState<string | null>(null)
|
||||||
|
const [lastUpdate, setLastUpdate] = useState<Date | null>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchLearningInsights()
|
||||||
|
const interval = setInterval(fetchLearningInsights, 30000) // Update every 30 seconds
|
||||||
|
return () => clearInterval(interval)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const fetchLearningInsights = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/ai/learning')
|
||||||
|
const data = await response.json()
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
setInsights(data)
|
||||||
|
setError(null)
|
||||||
|
setLastUpdate(new Date())
|
||||||
|
} else {
|
||||||
|
setError(data.error || 'Failed to load learning insights')
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
setError(err.message || 'Network error')
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const triggerAction = async (action: string, parameters?: any) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/ai/learning', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ action, parameters })
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = await response.json()
|
||||||
|
if (result.success) {
|
||||||
|
fetchLearningInsights() // Refresh data
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Action failed:', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-6">
|
||||||
|
<div className="animate-pulse space-y-4">
|
||||||
|
<div className="h-4 bg-gray-700 rounded w-1/4"></div>
|
||||||
|
<div className="h-8 bg-gray-700 rounded w-1/2"></div>
|
||||||
|
<div className="h-32 bg-gray-700 rounded"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<div className="bg-red-900/20 border border-red-700 rounded-lg p-6">
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<span className="text-red-400">❌</span>
|
||||||
|
<h3 className="text-red-400 font-semibold">Learning System Error</h3>
|
||||||
|
</div>
|
||||||
|
<p className="text-red-300 mt-2">{error}</p>
|
||||||
|
<button
|
||||||
|
onClick={fetchLearningInsights}
|
||||||
|
className="mt-4 px-4 py-2 bg-red-700 hover:bg-red-600 rounded text-white transition-colors"
|
||||||
|
>
|
||||||
|
Retry
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!insights) return null
|
||||||
|
|
||||||
|
const getStatusColor = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'ACTIVE': return 'text-green-400'
|
||||||
|
case 'INACTIVE': return 'text-red-400'
|
||||||
|
default: return 'text-yellow-400'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getMaturityColor = (maturity: string) => {
|
||||||
|
switch (maturity) {
|
||||||
|
case 'EXPERT': return 'text-purple-400'
|
||||||
|
case 'INTERMEDIATE': return 'text-blue-400'
|
||||||
|
case 'NOVICE': return 'text-green-400'
|
||||||
|
case 'BEGINNER': return 'text-yellow-400'
|
||||||
|
default: return 'text-gray-400'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDataQualityColor = (quality: string) => {
|
||||||
|
switch (quality) {
|
||||||
|
case 'HIGH': return 'text-green-400'
|
||||||
|
case 'MEDIUM': return 'text-yellow-400'
|
||||||
|
case 'LOW': return 'text-orange-400'
|
||||||
|
default: return 'text-red-400'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTrendIcon = (trend: string) => {
|
||||||
|
switch (trend) {
|
||||||
|
case 'EXCELLENT': return '🚀'
|
||||||
|
case 'IMPROVING': return '📈'
|
||||||
|
case 'LEARNING': return '🧠'
|
||||||
|
case 'INITIALIZING': return '🌱'
|
||||||
|
default: return '❓'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-6">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h2 className="text-2xl font-bold text-white flex items-center space-x-2">
|
||||||
|
<span>🧠</span>
|
||||||
|
<span>AI Learning Dashboard</span>
|
||||||
|
</h2>
|
||||||
|
<p className="text-gray-400 mt-1">Stop Loss Decision Learning System</p>
|
||||||
|
</div>
|
||||||
|
<div className="text-right">
|
||||||
|
<div className={`text-lg font-semibold ${getStatusColor(insights.learningSystem.status)}`}>
|
||||||
|
{insights.learningSystem.status}
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-gray-400">
|
||||||
|
Last Update: {lastUpdate?.toLocaleTimeString()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* System Overview */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-4">
|
||||||
|
<div className="text-gray-400 text-sm">System Confidence</div>
|
||||||
|
<div className="text-2xl font-bold text-blue-400">{insights.learningSystem.confidence}</div>
|
||||||
|
<div className="text-xs text-gray-500 mt-1">
|
||||||
|
{getTrendIcon(insights.performanceMetrics.improvementTrend)} {insights.performanceMetrics.improvementTrend}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-4">
|
||||||
|
<div className="text-gray-400 text-sm">Total Decisions</div>
|
||||||
|
<div className="text-2xl font-bold text-green-400">{insights.learningSystem.totalDecisions}</div>
|
||||||
|
<div className="text-xs text-gray-500 mt-1">
|
||||||
|
Pending: {insights.learningSystem.pendingAssessments}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-4">
|
||||||
|
<div className="text-gray-400 text-sm">Success Rate</div>
|
||||||
|
<div className="text-2xl font-bold text-purple-400">{insights.performanceMetrics.overallSuccessRate}%</div>
|
||||||
|
<div className="text-xs text-gray-500 mt-1">
|
||||||
|
Best: {insights.performanceMetrics.mostSuccessfulDecision.type}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-4">
|
||||||
|
<div className="text-gray-400 text-sm">System Maturity</div>
|
||||||
|
<div className={`text-2xl font-bold ${getMaturityColor(insights.systemHealth.systemMaturity)}`}>
|
||||||
|
{insights.systemHealth.systemMaturity}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-gray-500 mt-1">
|
||||||
|
Quality: <span className={getDataQualityColor(insights.systemHealth.dataQuality)}>
|
||||||
|
{insights.systemHealth.dataQuality}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Learning Thresholds */}
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-6">
|
||||||
|
<h3 className="text-lg font-semibold text-white mb-4 flex items-center space-x-2">
|
||||||
|
<span>🎯</span>
|
||||||
|
<span>Current Learning Thresholds</span>
|
||||||
|
</h3>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
|
<div className="bg-red-900/20 border border-red-700 rounded-lg p-4">
|
||||||
|
<div className="text-red-400 font-semibold">🚨 Emergency</div>
|
||||||
|
<div className="text-2xl font-bold text-white">{insights.learningSystem.currentThresholds.emergency}%</div>
|
||||||
|
<div className="text-sm text-red-300">Immediate action required</div>
|
||||||
|
</div>
|
||||||
|
<div className="bg-yellow-900/20 border border-yellow-700 rounded-lg p-4">
|
||||||
|
<div className="text-yellow-400 font-semibold">⚠️ High Risk</div>
|
||||||
|
<div className="text-2xl font-bold text-white">{insights.learningSystem.currentThresholds.risk}%</div>
|
||||||
|
<div className="text-sm text-yellow-300">Enhanced monitoring</div>
|
||||||
|
</div>
|
||||||
|
<div className="bg-blue-900/20 border border-blue-700 rounded-lg p-4">
|
||||||
|
<div className="text-blue-400 font-semibold">🟡 Medium Risk</div>
|
||||||
|
<div className="text-2xl font-bold text-white">{insights.learningSystem.currentThresholds.mediumRisk}%</div>
|
||||||
|
<div className="text-sm text-blue-300">Standard monitoring</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Decision Patterns */}
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||||
|
{/* Successful Patterns */}
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-6">
|
||||||
|
<h3 className="text-lg font-semibold text-white mb-4 flex items-center space-x-2">
|
||||||
|
<span>✅</span>
|
||||||
|
<span>Successful Decision Patterns</span>
|
||||||
|
</h3>
|
||||||
|
<div className="space-y-3">
|
||||||
|
{insights.decisionPatterns.successful.length > 0 ? (
|
||||||
|
insights.decisionPatterns.successful.map((pattern, index) => (
|
||||||
|
<div key={index} className="bg-green-900/20 border border-green-700 rounded-lg p-3">
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<div className="text-green-400 font-semibold">{pattern.decisionType}</div>
|
||||||
|
<div className="text-green-300">{pattern.successRate.toFixed(1)}%</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-gray-400">
|
||||||
|
Sample Size: {pattern.sampleSize} | Avg Score: {pattern.avgScore.toFixed(2)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className="text-gray-400 text-center py-8">
|
||||||
|
No successful patterns identified yet
|
||||||
|
<br />
|
||||||
|
<span className="text-sm">Keep making decisions to build learning data</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Failure Patterns */}
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-6">
|
||||||
|
<h3 className="text-lg font-semibold text-white mb-4 flex items-center space-x-2">
|
||||||
|
<span>❌</span>
|
||||||
|
<span>Areas for Improvement</span>
|
||||||
|
</h3>
|
||||||
|
<div className="space-y-3">
|
||||||
|
{insights.decisionPatterns.failures.length > 0 ? (
|
||||||
|
insights.decisionPatterns.failures.map((pattern, index) => (
|
||||||
|
<div key={index} className="bg-red-900/20 border border-red-700 rounded-lg p-3">
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<div className="text-red-400 font-semibold">{pattern.decisionType}</div>
|
||||||
|
<div className="text-red-300">{pattern.successRate.toFixed(1)}%</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-gray-400">
|
||||||
|
Sample Size: {pattern.sampleSize} | Needs improvement
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className="text-gray-400 text-center py-8">
|
||||||
|
No failure patterns identified
|
||||||
|
<br />
|
||||||
|
<span className="text-sm text-green-400">Great! System is performing well</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Recommendations */}
|
||||||
|
{insights.recommendations.length > 0 && (
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-6">
|
||||||
|
<h3 className="text-lg font-semibold text-white mb-4 flex items-center space-x-2">
|
||||||
|
<span>💡</span>
|
||||||
|
<span>AI Recommendations</span>
|
||||||
|
</h3>
|
||||||
|
<div className="space-y-3">
|
||||||
|
{insights.recommendations.map((rec, index) => (
|
||||||
|
<div key={index} className={`rounded-lg p-3 border ${
|
||||||
|
rec.priority === 'HIGH' ? 'bg-red-900/20 border-red-700' :
|
||||||
|
rec.priority === 'MEDIUM' ? 'bg-yellow-900/20 border-yellow-700' :
|
||||||
|
'bg-blue-900/20 border-blue-700'
|
||||||
|
}`}>
|
||||||
|
<div className="flex justify-between items-start">
|
||||||
|
<div className={`text-sm font-semibold ${
|
||||||
|
rec.priority === 'HIGH' ? 'text-red-400' :
|
||||||
|
rec.priority === 'MEDIUM' ? 'text-yellow-400' :
|
||||||
|
'text-blue-400'
|
||||||
|
}`}>
|
||||||
|
{rec.type} - {rec.priority} PRIORITY
|
||||||
|
</div>
|
||||||
|
{rec.actionable && (
|
||||||
|
<span className="text-xs bg-green-700 text-green-200 px-2 py-1 rounded">
|
||||||
|
Actionable
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="text-gray-300 mt-1">{rec.message}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* System Health */}
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-6">
|
||||||
|
<h3 className="text-lg font-semibold text-white mb-4 flex items-center space-x-2">
|
||||||
|
<span>🏥</span>
|
||||||
|
<span>System Health</span>
|
||||||
|
</h3>
|
||||||
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||||
|
<div className="text-center">
|
||||||
|
<div className={`text-2xl ${insights.systemHealth.learningActive ? 'text-green-400' : 'text-red-400'}`}>
|
||||||
|
{insights.systemHealth.learningActive ? '🟢' : '🔴'}
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-gray-400">Learning Active</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-center">
|
||||||
|
<div className={`text-2xl ${getDataQualityColor(insights.systemHealth.dataQuality)}`}>
|
||||||
|
📊
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-gray-400">Data Quality</div>
|
||||||
|
<div className={`text-xs ${getDataQualityColor(insights.systemHealth.dataQuality)}`}>
|
||||||
|
{insights.systemHealth.dataQuality}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-center">
|
||||||
|
<div className={`text-2xl ${getMaturityColor(insights.systemHealth.systemMaturity)}`}>
|
||||||
|
🎓
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-gray-400">Maturity</div>
|
||||||
|
<div className={`text-xs ${getMaturityColor(insights.systemHealth.systemMaturity)}`}>
|
||||||
|
{insights.systemHealth.systemMaturity}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-center">
|
||||||
|
<div className={`text-2xl ${insights.systemHealth.readyForAutonomy ? 'text-green-400' : 'text-yellow-400'}`}>
|
||||||
|
{insights.systemHealth.readyForAutonomy ? '🚀' : '⚠️'}
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-gray-400">Beach Ready</div>
|
||||||
|
<div className={`text-xs ${insights.systemHealth.readyForAutonomy ? 'text-green-400' : 'text-yellow-400'}`}>
|
||||||
|
{insights.systemHealth.readyForAutonomy ? 'YES' : 'LEARNING'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Action Buttons */}
|
||||||
|
<div className="bg-gray-900 border border-gray-700 rounded-lg p-6">
|
||||||
|
<h3 className="text-lg font-semibold text-white mb-4 flex items-center space-x-2">
|
||||||
|
<span>⚡</span>
|
||||||
|
<span>Learning System Actions</span>
|
||||||
|
</h3>
|
||||||
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||||
|
<button
|
||||||
|
onClick={() => triggerAction('updateThresholds')}
|
||||||
|
className="px-4 py-2 bg-blue-700 hover:bg-blue-600 rounded text-white transition-colors"
|
||||||
|
>
|
||||||
|
🔄 Update Thresholds
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => triggerAction('generateReport')}
|
||||||
|
className="px-4 py-2 bg-green-700 hover:bg-green-600 rounded text-white transition-colors"
|
||||||
|
>
|
||||||
|
📊 Generate Report
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => triggerAction('assessPendingDecisions')}
|
||||||
|
className="px-4 py-2 bg-yellow-700 hover:bg-yellow-600 rounded text-white transition-colors"
|
||||||
|
>
|
||||||
|
⚖️ Assess Pending
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={fetchLearningInsights}
|
||||||
|
className="px-4 py-2 bg-purple-700 hover:bg-purple-600 rounded text-white transition-colors"
|
||||||
|
>
|
||||||
|
🔃 Refresh Data
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
125
database/stop-loss-learning-schema.sql
Normal file
125
database/stop-loss-learning-schema.sql
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
-- Stop Loss Decision Learning Database Schema
|
||||||
|
-- This extends the existing database to support decision-level learning
|
||||||
|
|
||||||
|
-- Table to track every AI decision made near stop loss
|
||||||
|
CREATE TABLE IF NOT EXISTS sl_decisions (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
trade_id TEXT,
|
||||||
|
symbol TEXT NOT NULL,
|
||||||
|
decision_type TEXT NOT NULL, -- 'HOLD', 'EXIT', 'TIGHTEN_SL', 'PARTIAL_EXIT', 'EMERGENCY_EXIT'
|
||||||
|
distance_from_sl REAL NOT NULL,
|
||||||
|
reasoning TEXT,
|
||||||
|
market_conditions TEXT, -- JSON with market context
|
||||||
|
confidence_score REAL DEFAULT 0.7,
|
||||||
|
expected_outcome TEXT,
|
||||||
|
decision_timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
-- Outcome tracking (filled when trade closes or situation resolves)
|
||||||
|
outcome TEXT, -- 'HIT_ORIGINAL_SL', 'HIT_TIGHTENED_SL', 'PROFITABLE_EXIT', 'AVOIDED_LOSS', etc.
|
||||||
|
outcome_timestamp DATETIME,
|
||||||
|
time_to_outcome INTEGER, -- minutes from decision to outcome
|
||||||
|
pnl_impact REAL, -- how much P&L was affected by the decision
|
||||||
|
was_correct BOOLEAN,
|
||||||
|
learning_score REAL, -- calculated learning score (0-1)
|
||||||
|
additional_context TEXT, -- JSON with additional outcome context
|
||||||
|
status TEXT DEFAULT 'PENDING_OUTCOME', -- 'PENDING_OUTCOME', 'ASSESSED'
|
||||||
|
|
||||||
|
-- Indexing for faster queries
|
||||||
|
FOREIGN KEY (trade_id) REFERENCES trades(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Indexes for performance
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sl_decisions_symbol ON sl_decisions(symbol);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sl_decisions_decision_type ON sl_decisions(decision_type);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sl_decisions_distance ON sl_decisions(distance_from_sl);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sl_decisions_timestamp ON sl_decisions(decision_timestamp);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sl_decisions_status ON sl_decisions(status);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sl_decisions_was_correct ON sl_decisions(was_correct);
|
||||||
|
|
||||||
|
-- Table to store learning model parameters and thresholds
|
||||||
|
CREATE TABLE IF NOT EXISTS learning_parameters (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
parameter_name TEXT UNIQUE NOT NULL,
|
||||||
|
parameter_value REAL NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
last_updated DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
confidence_level REAL DEFAULT 0.5 -- how confident we are in this parameter
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Insert default learning parameters
|
||||||
|
INSERT OR REPLACE INTO learning_parameters (parameter_name, parameter_value, description) VALUES
|
||||||
|
('emergency_distance_threshold', 1.0, 'Distance from SL (%) that triggers emergency decisions'),
|
||||||
|
('high_risk_distance_threshold', 2.0, 'Distance from SL (%) that triggers high risk decisions'),
|
||||||
|
('medium_risk_distance_threshold', 5.0, 'Distance from SL (%) that triggers medium risk decisions'),
|
||||||
|
('min_decisions_for_learning', 5, 'Minimum number of decisions needed to start learning'),
|
||||||
|
('confidence_threshold', 0.7, 'Minimum confidence to use learned recommendations'),
|
||||||
|
('learning_rate', 0.1, 'How quickly to adapt to new decision outcomes');
|
||||||
|
|
||||||
|
-- Table to store decision pattern insights
|
||||||
|
CREATE TABLE IF NOT EXISTS decision_patterns (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
pattern_type TEXT NOT NULL, -- 'SUCCESSFUL', 'FAILURE', 'OPTIMAL_TIMING'
|
||||||
|
decision_type TEXT NOT NULL,
|
||||||
|
conditions TEXT, -- JSON with conditions that trigger this pattern
|
||||||
|
success_rate REAL,
|
||||||
|
sample_size INTEGER,
|
||||||
|
avg_pnl_impact REAL,
|
||||||
|
confidence_score REAL,
|
||||||
|
discovered_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
last_validated DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
is_active BOOLEAN DEFAULT TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- View for quick decision performance analysis
|
||||||
|
CREATE VIEW IF NOT EXISTS decision_performance AS
|
||||||
|
SELECT
|
||||||
|
decision_type,
|
||||||
|
COUNT(*) as total_decisions,
|
||||||
|
AVG(CASE WHEN was_correct THEN 1 ELSE 0 END) as success_rate,
|
||||||
|
AVG(learning_score) as avg_learning_score,
|
||||||
|
AVG(pnl_impact) as avg_pnl_impact,
|
||||||
|
AVG(distance_from_sl) as avg_distance_from_sl,
|
||||||
|
MIN(decision_timestamp) as first_decision,
|
||||||
|
MAX(decision_timestamp) as latest_decision
|
||||||
|
FROM sl_decisions
|
||||||
|
WHERE status = 'ASSESSED'
|
||||||
|
GROUP BY decision_type
|
||||||
|
ORDER BY success_rate DESC;
|
||||||
|
|
||||||
|
-- View for time-based decision analysis
|
||||||
|
CREATE VIEW IF NOT EXISTS decision_timing_analysis AS
|
||||||
|
SELECT
|
||||||
|
CASE
|
||||||
|
WHEN strftime('%H', decision_timestamp) BETWEEN '00' AND '05' THEN 'Night'
|
||||||
|
WHEN strftime('%H', decision_timestamp) BETWEEN '06' AND '11' THEN 'Morning'
|
||||||
|
WHEN strftime('%H', decision_timestamp) BETWEEN '12' AND '17' THEN 'Afternoon'
|
||||||
|
ELSE 'Evening'
|
||||||
|
END as time_period,
|
||||||
|
decision_type,
|
||||||
|
COUNT(*) as decisions,
|
||||||
|
AVG(CASE WHEN was_correct THEN 1 ELSE 0 END) as success_rate,
|
||||||
|
AVG(pnl_impact) as avg_pnl_impact
|
||||||
|
FROM sl_decisions
|
||||||
|
WHERE status = 'ASSESSED'
|
||||||
|
GROUP BY time_period, decision_type
|
||||||
|
ORDER BY success_rate DESC;
|
||||||
|
|
||||||
|
-- View for distance-based decision analysis
|
||||||
|
CREATE VIEW IF NOT EXISTS distance_effectiveness AS
|
||||||
|
SELECT
|
||||||
|
CASE
|
||||||
|
WHEN distance_from_sl < 1.0 THEN 'Emergency (<1%)'
|
||||||
|
WHEN distance_from_sl < 2.0 THEN 'High Risk (1-2%)'
|
||||||
|
WHEN distance_from_sl < 5.0 THEN 'Medium Risk (2-5%)'
|
||||||
|
ELSE 'Safe (>5%)'
|
||||||
|
END as risk_level,
|
||||||
|
decision_type,
|
||||||
|
COUNT(*) as decisions,
|
||||||
|
AVG(CASE WHEN was_correct THEN 1 ELSE 0 END) as success_rate,
|
||||||
|
AVG(learning_score) as avg_score,
|
||||||
|
AVG(pnl_impact) as avg_pnl_impact,
|
||||||
|
AVG(time_to_outcome) as avg_resolution_time_minutes
|
||||||
|
FROM sl_decisions
|
||||||
|
WHERE status = 'ASSESSED'
|
||||||
|
GROUP BY risk_level, decision_type
|
||||||
|
ORDER BY risk_level, success_rate DESC;
|
||||||
279
demo-ai-learning-simple.js
Executable file
279
demo-ai-learning-simple.js
Executable file
@@ -0,0 +1,279 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple AI Learning System Demo (In-Memory)
|
||||||
|
*
|
||||||
|
* Demonstrates the learning system without database dependencies
|
||||||
|
*/
|
||||||
|
|
||||||
|
async function demonstrateAILearningSimple() {
|
||||||
|
console.log('🧠 AI LEARNING SYSTEM - SIMPLE DEMONSTRATION');
|
||||||
|
console.log('='.repeat(80));
|
||||||
|
|
||||||
|
console.log(`
|
||||||
|
🎯 WHAT YOUR ENHANCED AUTONOMOUS SYSTEM NOW INCLUDES:
|
||||||
|
|
||||||
|
📊 DECISION RECORDING:
|
||||||
|
✅ Records every AI decision made near stop loss
|
||||||
|
✅ Captures context: distance, market conditions, confidence
|
||||||
|
✅ Stores reasoning and expected outcomes
|
||||||
|
|
||||||
|
🔍 OUTCOME TRACKING:
|
||||||
|
✅ Monitors what happens after each decision
|
||||||
|
✅ Measures P&L impact and time to resolution
|
||||||
|
✅ Determines if decisions were correct or not
|
||||||
|
|
||||||
|
🧠 PATTERN ANALYSIS:
|
||||||
|
✅ Identifies successful decision patterns
|
||||||
|
✅ Finds failure patterns to avoid
|
||||||
|
✅ Optimizes distance thresholds based on results
|
||||||
|
✅ Analyzes timing patterns (time of day, market conditions)
|
||||||
|
|
||||||
|
🚀 SMART RECOMMENDATIONS:
|
||||||
|
✅ Suggests best actions based on learned patterns
|
||||||
|
✅ Provides confidence scores from historical data
|
||||||
|
✅ Adapts to what actually works in your trading
|
||||||
|
|
||||||
|
🔄 CONTINUOUS IMPROVEMENT:
|
||||||
|
✅ Updates decision thresholds automatically
|
||||||
|
✅ Improves confidence calibration over time
|
||||||
|
✅ Becomes more accurate with each decision
|
||||||
|
|
||||||
|
🏖️ BEACH MODE EVOLUTION:
|
||||||
|
Before: Basic autonomous monitoring
|
||||||
|
After: Self-improving AI that learns from every decision!
|
||||||
|
`);
|
||||||
|
|
||||||
|
// Simulate the learning process
|
||||||
|
console.log('\n🎬 SIMULATED LEARNING EVOLUTION:\n');
|
||||||
|
|
||||||
|
const learningPhases = [
|
||||||
|
{
|
||||||
|
phase: 'Week 1 - Initial Learning',
|
||||||
|
decisions: 15,
|
||||||
|
successRate: 45,
|
||||||
|
confidence: 30,
|
||||||
|
status: 'LEARNING',
|
||||||
|
insight: 'Collecting initial decision data, identifying basic patterns'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
phase: 'Week 2 - Pattern Recognition',
|
||||||
|
decisions: 35,
|
||||||
|
successRate: 62,
|
||||||
|
confidence: 55,
|
||||||
|
status: 'IMPROVING',
|
||||||
|
insight: 'Found that EMERGENCY_EXIT at <1% distance works 89% of the time'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
phase: 'Month 1 - Optimization',
|
||||||
|
decisions: 68,
|
||||||
|
successRate: 74,
|
||||||
|
confidence: 73,
|
||||||
|
status: 'OPTIMIZED',
|
||||||
|
insight: 'Optimal thresholds: Emergency=0.8%, Risk=1.9%, Medium=4.2%'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
phase: 'Month 2 - Expert Level',
|
||||||
|
decisions: 124,
|
||||||
|
successRate: 82,
|
||||||
|
confidence: 87,
|
||||||
|
status: 'EXPERT',
|
||||||
|
insight: 'TIGHTEN_STOP_LOSS in afternoon trading shows 94% success rate'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const phase of learningPhases) {
|
||||||
|
console.log(`📈 ${phase.phase}`);
|
||||||
|
console.log(` Decisions Made: ${phase.decisions}`);
|
||||||
|
console.log(` Success Rate: ${phase.successRate}%`);
|
||||||
|
console.log(` System Confidence: ${phase.confidence}%`);
|
||||||
|
console.log(` Status: ${phase.status}`);
|
||||||
|
console.log(` 💡 Key Insight: ${phase.insight}`);
|
||||||
|
console.log('');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🎯 EXAMPLE LEARNED DECISION PATTERNS:\n');
|
||||||
|
|
||||||
|
const examplePatterns = [
|
||||||
|
{
|
||||||
|
pattern: 'EMERGENCY_EXIT at <1% distance',
|
||||||
|
successRate: 89,
|
||||||
|
samples: 23,
|
||||||
|
insight: 'Consistently saves 3-8% more than letting stop loss hit'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: 'TIGHTEN_STOP_LOSS during afternoon hours',
|
||||||
|
successRate: 94,
|
||||||
|
samples: 18,
|
||||||
|
insight: 'Lower volatility makes tighter stops more effective'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: 'HOLD decision when trend is bullish',
|
||||||
|
successRate: 76,
|
||||||
|
samples: 31,
|
||||||
|
insight: 'Strong trends often recover from temporary dips'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: 'PARTIAL_EXIT in high volatility',
|
||||||
|
successRate: 81,
|
||||||
|
samples: 15,
|
||||||
|
insight: 'Reduces risk while maintaining upside potential'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
examplePatterns.forEach(pattern => {
|
||||||
|
console.log(`✅ ${pattern.pattern}`);
|
||||||
|
console.log(` Success Rate: ${pattern.successRate}% (${pattern.samples} samples)`);
|
||||||
|
console.log(` 📝 Insight: ${pattern.insight}`);
|
||||||
|
console.log('');
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('🎯 SMART RECOMMENDATION EXAMPLE:\n');
|
||||||
|
|
||||||
|
console.log(`Situation: SOL-PERP position 2.3% from stop loss, bullish trend, afternoon`);
|
||||||
|
console.log(`
|
||||||
|
🧠 AI RECOMMENDATION:
|
||||||
|
Suggested Action: TIGHTEN_STOP_LOSS
|
||||||
|
Confidence: 87% (based on 18 similar situations)
|
||||||
|
Reasoning: Afternoon trading + bullish trend shows 94% success rate for tightening
|
||||||
|
Expected Outcome: Improve risk/reward by 0.4% on average
|
||||||
|
|
||||||
|
📊 Supporting Data:
|
||||||
|
- 18 similar situations in learning database
|
||||||
|
- 94% success rate for this pattern
|
||||||
|
- Average P&L improvement: +0.4%
|
||||||
|
- Time-based optimization: Afternoon = optimal
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n🏗️ SYSTEM ARCHITECTURE ENHANCEMENT:\n');
|
||||||
|
|
||||||
|
console.log(`
|
||||||
|
📁 NEW COMPONENTS ADDED:
|
||||||
|
|
||||||
|
📄 lib/stop-loss-decision-learner.js
|
||||||
|
🧠 Core learning engine that records decisions and analyzes patterns
|
||||||
|
|
||||||
|
📄 lib/enhanced-autonomous-risk-manager.js
|
||||||
|
🤖 Enhanced AI that uses learning data to make smarter decisions
|
||||||
|
|
||||||
|
📄 database/stop-loss-learning-schema.sql
|
||||||
|
🗄️ Database schema for storing decision history and patterns
|
||||||
|
|
||||||
|
📄 app/api/ai/learning/route.ts
|
||||||
|
🌐 API endpoints for accessing learning insights
|
||||||
|
|
||||||
|
📄 app/components/AILearningDashboard.tsx
|
||||||
|
🎨 Beautiful dashboard to visualize learning progress
|
||||||
|
|
||||||
|
📄 demo-ai-learning.js
|
||||||
|
🎬 Demonstration script showing learning capabilities
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n🚀 INTEGRATION WITH EXISTING SYSTEM:\n');
|
||||||
|
|
||||||
|
console.log(`
|
||||||
|
🔗 ENHANCED BEACH MODE FLOW:
|
||||||
|
|
||||||
|
1. 📊 Position Monitor detects proximity to stop loss
|
||||||
|
2. 🤖 Enhanced Risk Manager analyzes situation
|
||||||
|
3. 🧠 Learning System provides smart recommendation
|
||||||
|
4. ⚡ AI makes decision (enhanced by learned patterns)
|
||||||
|
5. 📝 Decision is recorded with context for learning
|
||||||
|
6. ⏱️ System monitors outcome over time
|
||||||
|
7. 🔍 Outcome is assessed and learning score calculated
|
||||||
|
8. 📈 Patterns are updated, thresholds optimized
|
||||||
|
9. 🎯 Next decision is even smarter!
|
||||||
|
|
||||||
|
RESULT: Your AI doesn't just execute rules...
|
||||||
|
It EVOLVES and improves with every decision! 🧬
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n🎛️ NEW API ENDPOINTS:\n');
|
||||||
|
|
||||||
|
console.log(`
|
||||||
|
🌐 /api/ai/learning (GET)
|
||||||
|
📊 Get comprehensive learning insights and system status
|
||||||
|
|
||||||
|
🌐 /api/ai/learning (POST)
|
||||||
|
⚡ Trigger learning actions (update thresholds, generate reports)
|
||||||
|
|
||||||
|
Example Usage:
|
||||||
|
curl http://localhost:9001/api/ai/learning | jq .
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n🎨 BEAUTIFUL LEARNING DASHBOARD:\n');
|
||||||
|
|
||||||
|
console.log(`
|
||||||
|
💻 NEW UI COMPONENTS:
|
||||||
|
|
||||||
|
📊 System Overview Cards
|
||||||
|
- Confidence level with trend indicators
|
||||||
|
- Total decisions and success rate
|
||||||
|
- System maturity assessment
|
||||||
|
- Data quality metrics
|
||||||
|
|
||||||
|
🎯 Current Learning Thresholds
|
||||||
|
- Emergency distance (auto-optimized)
|
||||||
|
- Risk levels (learned from outcomes)
|
||||||
|
- Visual threshold indicators
|
||||||
|
|
||||||
|
✅ Successful Decision Patterns
|
||||||
|
- Which decisions work best
|
||||||
|
- Success rates and sample sizes
|
||||||
|
- Optimal conditions for each pattern
|
||||||
|
|
||||||
|
❌ Areas for Improvement
|
||||||
|
- Decisions that need work
|
||||||
|
- Failure pattern analysis
|
||||||
|
- Actionable improvement suggestions
|
||||||
|
|
||||||
|
💡 AI Recommendations
|
||||||
|
- Smart suggestions based on learning
|
||||||
|
- Priority levels and actionability
|
||||||
|
- Real-time optimization tips
|
||||||
|
|
||||||
|
🏥 System Health Indicators
|
||||||
|
- Learning system status
|
||||||
|
- Data quality assessment
|
||||||
|
- Beach mode readiness
|
||||||
|
|
||||||
|
⚡ Action Buttons
|
||||||
|
- Update thresholds from learning
|
||||||
|
- Generate new reports
|
||||||
|
- Assess pending decisions
|
||||||
|
- Refresh learning data
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n🌟 THE RESULT - ULTIMATE BEACH MODE:\n');
|
||||||
|
|
||||||
|
console.log(`
|
||||||
|
🏖️ BEFORE: Basic Autonomous Trading
|
||||||
|
✅ Makes rule-based decisions
|
||||||
|
✅ Executes stop loss management
|
||||||
|
✅ Monitors positions automatically
|
||||||
|
|
||||||
|
🚀 AFTER: Self-Improving AI Trader
|
||||||
|
✅ Everything above PLUS:
|
||||||
|
✅ Records every decision for learning
|
||||||
|
✅ Tracks outcomes and measures success
|
||||||
|
✅ Identifies what works vs what doesn't
|
||||||
|
✅ Optimizes thresholds based on results
|
||||||
|
✅ Provides smart recommendations
|
||||||
|
✅ Adapts to market conditions over time
|
||||||
|
✅ Builds confidence through validated patterns
|
||||||
|
✅ Becomes more profitable with experience
|
||||||
|
|
||||||
|
🎯 OUTCOME: Your AI trading system doesn't just work...
|
||||||
|
It gets BETTER every single day! 📈
|
||||||
|
|
||||||
|
🏖️ TRUE BEACH MODE: Start automation, walk away, come back to a
|
||||||
|
smarter AI that learned from every decision while you relaxed! ☀️
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n✨ YOUR AI IS NOW READY TO LEARN AND DOMINATE! ✨\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the demonstration
|
||||||
|
if (require.main === module) {
|
||||||
|
demonstrateAILearningSimple().catch(console.error);
|
||||||
|
}
|
||||||
218
demo-ai-learning.js
Executable file
218
demo-ai-learning.js
Executable file
@@ -0,0 +1,218 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AI Learning System Demo
|
||||||
|
*
|
||||||
|
* Demonstrates the complete stop loss decision learning system
|
||||||
|
*/
|
||||||
|
|
||||||
|
const EnhancedAutonomousRiskManager = require('./lib/enhanced-autonomous-risk-manager.js');
|
||||||
|
const StopLossDecisionLearner = require('./lib/stop-loss-decision-learner.js');
|
||||||
|
|
||||||
|
async function demonstrateAILearning() {
|
||||||
|
console.log('🧠 AI LEARNING SYSTEM DEMONSTRATION');
|
||||||
|
console.log('='.repeat(80));
|
||||||
|
|
||||||
|
console.log(`
|
||||||
|
🎯 WHAT THIS SYSTEM DOES:
|
||||||
|
|
||||||
|
1. 📊 Records every AI decision made near stop loss
|
||||||
|
2. 🔍 Tracks what happens after each decision
|
||||||
|
3. 🧠 Learns from outcomes to improve future decisions
|
||||||
|
4. 🚀 Gets smarter with every trade and decision
|
||||||
|
5. 🏖️ Enables true autonomous beach mode trading
|
||||||
|
|
||||||
|
🔄 LEARNING CYCLE:
|
||||||
|
Decision Made → Outcome Tracked → Pattern Analysis → Improved Decisions
|
||||||
|
`);
|
||||||
|
|
||||||
|
const riskManager = new EnhancedAutonomousRiskManager();
|
||||||
|
const learner = new StopLossDecisionLearner();
|
||||||
|
|
||||||
|
console.log('\n🎬 DEMO SCENARIO: Simulating Decision Learning Process\n');
|
||||||
|
|
||||||
|
// Simulate a series of decisions and outcomes
|
||||||
|
const demoDecisions = [
|
||||||
|
{
|
||||||
|
scenario: 'SOL-PERP position 1.5% from stop loss',
|
||||||
|
decision: 'EMERGENCY_EXIT',
|
||||||
|
distanceFromSL: 1.5,
|
||||||
|
outcome: 'AVOIDED_MAJOR_LOSS',
|
||||||
|
pnlImpact: 5.2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: 'SOL-PERP position 2.8% from stop loss',
|
||||||
|
decision: 'TIGHTEN_STOP_LOSS',
|
||||||
|
distanceFromSL: 2.8,
|
||||||
|
outcome: 'IMPROVED_PROFIT',
|
||||||
|
pnlImpact: 2.1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: 'SOL-PERP position 4.2% from stop loss',
|
||||||
|
decision: 'HOLD',
|
||||||
|
distanceFromSL: 4.2,
|
||||||
|
outcome: 'CORRECT_HOLD',
|
||||||
|
pnlImpact: 1.8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: 'BTC-PERP position 1.2% from stop loss',
|
||||||
|
decision: 'PARTIAL_EXIT',
|
||||||
|
distanceFromSL: 1.2,
|
||||||
|
outcome: 'REDUCED_RISK',
|
||||||
|
pnlImpact: 0.8
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
console.log('📝 RECORDING DECISIONS FOR LEARNING:\n');
|
||||||
|
|
||||||
|
const decisionIds = [];
|
||||||
|
|
||||||
|
for (const demo of demoDecisions) {
|
||||||
|
console.log(`🎯 Scenario: ${demo.scenario}`);
|
||||||
|
console.log(` Decision: ${demo.decision}`);
|
||||||
|
|
||||||
|
// Record the decision
|
||||||
|
const decisionId = await learner.recordDecision({
|
||||||
|
tradeId: `demo_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`,
|
||||||
|
symbol: demo.scenario.split(' ')[0],
|
||||||
|
decision: demo.decision,
|
||||||
|
distanceFromSL: demo.distanceFromSL,
|
||||||
|
reasoning: `Demo decision at ${demo.distanceFromSL}% distance`,
|
||||||
|
currentPrice: 180 + Math.random() * 10,
|
||||||
|
confidenceScore: 0.7 + Math.random() * 0.2,
|
||||||
|
expectedOutcome: 'BETTER_RESULT'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (decisionId) {
|
||||||
|
decisionIds.push({ id: decisionId, demo });
|
||||||
|
console.log(` ✅ Recorded decision ${decisionId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('⏱️ Simulating time passage and outcome assessment...\n');
|
||||||
|
|
||||||
|
// Wait a moment to simulate time passage
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||||
|
|
||||||
|
console.log('🔍 ASSESSING DECISION OUTCOMES:\n');
|
||||||
|
|
||||||
|
for (const { id, demo } of decisionIds) {
|
||||||
|
console.log(`📊 Assessing decision ${id}:`);
|
||||||
|
console.log(` Outcome: ${demo.outcome}`);
|
||||||
|
console.log(` P&L Impact: +$${demo.pnlImpact}`);
|
||||||
|
|
||||||
|
// Assess the outcome
|
||||||
|
const assessment = await learner.assessDecisionOutcome({
|
||||||
|
decisionId: id,
|
||||||
|
actualOutcome: demo.outcome,
|
||||||
|
timeToOutcome: 5 + Math.floor(Math.random() * 10), // 5-15 minutes
|
||||||
|
pnlImpact: demo.pnlImpact,
|
||||||
|
additionalContext: {
|
||||||
|
scenario: demo.scenario,
|
||||||
|
marketConditions: 'Demo simulation'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (assessment) {
|
||||||
|
console.log(` ✅ Assessment: ${assessment.wasCorrect ? 'CORRECT' : 'INCORRECT'} (Score: ${assessment.learningScore.toFixed(2)})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🧠 ANALYZING LEARNING PATTERNS:\n');
|
||||||
|
|
||||||
|
const patterns = await learner.analyzeDecisionPatterns();
|
||||||
|
|
||||||
|
if (patterns) {
|
||||||
|
console.log('📈 SUCCESSFUL DECISION PATTERNS:');
|
||||||
|
patterns.successfulPatterns.forEach(pattern => {
|
||||||
|
console.log(` ${pattern.decisionType}: ${pattern.successRate.toFixed(1)}% success rate (${pattern.sampleSize} samples)`);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (patterns.failurePatterns.length > 0) {
|
||||||
|
console.log('\n📉 AREAS FOR IMPROVEMENT:');
|
||||||
|
patterns.failurePatterns.forEach(pattern => {
|
||||||
|
console.log(` ${pattern.decisionType}: ${pattern.successRate.toFixed(1)}% success rate (${pattern.sampleSize} samples)`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n🎯 DISTANCE OPTIMIZATION:');
|
||||||
|
Object.entries(patterns.distanceOptimization).forEach(([range, data]) => {
|
||||||
|
console.log(` ${range}: ${data.successRate.toFixed(1)}% success, optimal threshold: ${data.optimalThreshold.toFixed(2)}%`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n🚀 GENERATING SMART RECOMMENDATION:\n');
|
||||||
|
|
||||||
|
// Test smart recommendation system
|
||||||
|
const recommendation = await learner.getSmartRecommendation({
|
||||||
|
distanceFromSL: 2.5,
|
||||||
|
symbol: 'SOL-PERP',
|
||||||
|
marketConditions: {
|
||||||
|
trend: 'BULLISH',
|
||||||
|
volatility: 0.05,
|
||||||
|
timeOfDay: new Date().getHours()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`🎯 Smart Recommendation for 2.5% distance from SL:`);
|
||||||
|
console.log(` Suggested Action: ${recommendation.suggestedAction}`);
|
||||||
|
console.log(` Confidence: ${(recommendation.confidence * 100).toFixed(1)}%`);
|
||||||
|
console.log(` Reasoning: ${recommendation.reasoning}`);
|
||||||
|
console.log(` Learning-Based: ${recommendation.learningBased ? 'YES' : 'NO'}`);
|
||||||
|
|
||||||
|
if (recommendation.supportingData) {
|
||||||
|
console.log(` Supporting Data: ${recommendation.supportingData.historicalSamples} similar situations`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n📊 GENERATING COMPREHENSIVE LEARNING REPORT:\n');
|
||||||
|
|
||||||
|
const report = await learner.generateLearningReport();
|
||||||
|
|
||||||
|
if (report) {
|
||||||
|
console.log('📋 LEARNING SYSTEM STATUS:');
|
||||||
|
console.log(` Total Decisions: ${report.summary.totalDecisions}`);
|
||||||
|
console.log(` System Confidence: ${(report.summary.systemConfidence * 100).toFixed(1)}%`);
|
||||||
|
console.log(` Successful Patterns: ${report.summary.successfulPatterns}`);
|
||||||
|
|
||||||
|
if (report.recommendations.length > 0) {
|
||||||
|
console.log('\n💡 AI RECOMMENDATIONS:');
|
||||||
|
report.recommendations.forEach(rec => {
|
||||||
|
console.log(` ${rec.type} (${rec.priority}): ${rec.message}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n🏖️ BEACH MODE DEMONSTRATION:\n');
|
||||||
|
|
||||||
|
console.log(`
|
||||||
|
🌊 ENHANCED BEACH MODE WITH AI LEARNING:
|
||||||
|
|
||||||
|
✅ System now records every decision made near stop loss
|
||||||
|
✅ Tracks outcomes and learns from what works/doesn't work
|
||||||
|
✅ Adjusts decision thresholds based on historical success
|
||||||
|
✅ Provides smart recommendations based on learned patterns
|
||||||
|
✅ Continuously improves decision-making quality
|
||||||
|
✅ Builds confidence through validated success patterns
|
||||||
|
|
||||||
|
🎯 RESULT: Your AI doesn't just make autonomous decisions...
|
||||||
|
It LEARNS from every decision to become smarter!
|
||||||
|
|
||||||
|
🚀 NEXT STEPS:
|
||||||
|
1. Start automation with enhanced learning system
|
||||||
|
2. Let it run and make decisions autonomously
|
||||||
|
3. Check learning dashboard for insights
|
||||||
|
4. Watch confidence and success rates improve over time
|
||||||
|
5. Enjoy the beach knowing your AI is getting smarter! 🏖️
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n✨ DEMO COMPLETE! Your AI is ready to learn and improve! ✨\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the demonstration
|
||||||
|
if (require.main === module) {
|
||||||
|
demonstrateAILearning().catch(console.error);
|
||||||
|
}
|
||||||
569
lib/enhanced-autonomous-risk-manager.js
Normal file
569
lib/enhanced-autonomous-risk-manager.js
Normal file
@@ -0,0 +1,569 @@
|
|||||||
|
/**
|
||||||
|
* Enhanced Autonomous AI Risk Management System with Learning
|
||||||
|
*
|
||||||
|
* This system automatically handles risk situations AND learns from every decision.
|
||||||
|
* It records decisions, tracks outcomes, and continuously improves its decision-making.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const StopLossDecisionLearner = require('./stop-loss-decision-learner');
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
const util = require('util');
|
||||||
|
const execAsync = util.promisify(exec);
|
||||||
|
|
||||||
|
class EnhancedAutonomousRiskManager {
|
||||||
|
constructor() {
|
||||||
|
this.isActive = false;
|
||||||
|
this.learner = new StopLossDecisionLearner();
|
||||||
|
this.emergencyThreshold = 1.0; // Will be updated by learning system
|
||||||
|
this.riskThreshold = 2.0;
|
||||||
|
this.mediumRiskThreshold = 5.0;
|
||||||
|
this.pendingDecisions = new Map(); // Track decisions awaiting outcomes
|
||||||
|
this.lastAnalysis = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async log(message) {
|
||||||
|
const timestamp = new Date().toISOString();
|
||||||
|
console.log(`[${timestamp}] 🤖 Enhanced Risk AI: ${message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main analysis function that integrates learning-based decision making
|
||||||
|
*/
|
||||||
|
async analyzePosition(monitor) {
|
||||||
|
try {
|
||||||
|
if (!monitor || !monitor.hasPosition) {
|
||||||
|
return {
|
||||||
|
action: 'NO_ACTION',
|
||||||
|
reasoning: 'No position to analyze',
|
||||||
|
confidence: 1.0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const { position, stopLossProximity } = monitor;
|
||||||
|
const distance = parseFloat(stopLossProximity.distancePercent);
|
||||||
|
|
||||||
|
// Update thresholds based on learning
|
||||||
|
await this.updateThresholdsFromLearning();
|
||||||
|
|
||||||
|
// Get AI recommendation based on learned patterns
|
||||||
|
const smartRecommendation = await this.learner.getSmartRecommendation({
|
||||||
|
distanceFromSL: distance,
|
||||||
|
symbol: position.symbol,
|
||||||
|
marketConditions: {
|
||||||
|
price: position.entryPrice, // Current price context
|
||||||
|
unrealizedPnl: position.unrealizedPnl,
|
||||||
|
side: position.side
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let decision;
|
||||||
|
|
||||||
|
// Enhanced decision logic using learning
|
||||||
|
if (distance < this.emergencyThreshold) {
|
||||||
|
decision = await this.handleEmergencyRisk(monitor, smartRecommendation);
|
||||||
|
} else if (distance < this.riskThreshold) {
|
||||||
|
decision = await this.handleHighRisk(monitor, smartRecommendation);
|
||||||
|
} else if (distance < this.mediumRiskThreshold) {
|
||||||
|
decision = await this.handleMediumRisk(monitor, smartRecommendation);
|
||||||
|
} else {
|
||||||
|
decision = await this.handleSafePosition(monitor, smartRecommendation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record this decision for learning
|
||||||
|
const decisionId = await this.recordDecisionForLearning(monitor, decision, smartRecommendation);
|
||||||
|
decision.decisionId = decisionId;
|
||||||
|
|
||||||
|
this.lastAnalysis = { monitor, decision, timestamp: new Date() };
|
||||||
|
|
||||||
|
return decision;
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`❌ Error in position analysis: ${error.message}`);
|
||||||
|
return {
|
||||||
|
action: 'ERROR',
|
||||||
|
reasoning: `Analysis error: ${error.message}`,
|
||||||
|
confidence: 0.1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleEmergencyRisk(monitor, smartRecommendation) {
|
||||||
|
const { position, stopLossProximity } = monitor;
|
||||||
|
const distance = parseFloat(stopLossProximity.distancePercent);
|
||||||
|
|
||||||
|
await this.log(`🚨 EMERGENCY: Position ${distance}% from stop loss!`);
|
||||||
|
|
||||||
|
// Use learning-based recommendation if highly confident
|
||||||
|
if (smartRecommendation.learningBased && smartRecommendation.confidence > 0.8) {
|
||||||
|
await this.log(`🧠 Using learned strategy: ${smartRecommendation.suggestedAction} (${(smartRecommendation.confidence * 100).toFixed(1)}% confidence)`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
action: smartRecommendation.suggestedAction,
|
||||||
|
reasoning: `AI Learning: ${smartRecommendation.reasoning}`,
|
||||||
|
confidence: smartRecommendation.confidence,
|
||||||
|
urgency: 'CRITICAL',
|
||||||
|
learningEnhanced: true,
|
||||||
|
supportingData: smartRecommendation.supportingData
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to rule-based emergency logic
|
||||||
|
return {
|
||||||
|
action: 'EMERGENCY_EXIT',
|
||||||
|
reasoning: 'Price critically close to stop loss. Autonomous exit to preserve capital.',
|
||||||
|
confidence: 0.9,
|
||||||
|
urgency: 'CRITICAL',
|
||||||
|
parameters: {
|
||||||
|
exitPercentage: 100,
|
||||||
|
maxSlippage: 0.5
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleHighRisk(monitor, smartRecommendation) {
|
||||||
|
const { position, stopLossProximity } = monitor;
|
||||||
|
const distance = parseFloat(stopLossProximity.distancePercent);
|
||||||
|
|
||||||
|
await this.log(`⚠️ HIGH RISK: Position ${distance}% from stop loss`);
|
||||||
|
|
||||||
|
// Check learning recommendation
|
||||||
|
if (smartRecommendation.learningBased && smartRecommendation.confidence > 0.7) {
|
||||||
|
return {
|
||||||
|
action: smartRecommendation.suggestedAction,
|
||||||
|
reasoning: `AI Learning: ${smartRecommendation.reasoning}`,
|
||||||
|
confidence: smartRecommendation.confidence,
|
||||||
|
urgency: 'HIGH',
|
||||||
|
learningEnhanced: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enhanced market analysis for high-risk situations
|
||||||
|
const marketAnalysis = await this.analyzeMarketConditions(position.symbol);
|
||||||
|
|
||||||
|
if (marketAnalysis.trend === 'BULLISH' && position.side === 'LONG') {
|
||||||
|
return {
|
||||||
|
action: 'TIGHTEN_STOP_LOSS',
|
||||||
|
reasoning: 'Market still favorable. Tightening stop loss for better risk management.',
|
||||||
|
confidence: 0.7,
|
||||||
|
urgency: 'HIGH',
|
||||||
|
parameters: {
|
||||||
|
newStopLossDistance: distance * 0.7 // Tighten by 30%
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
action: 'PARTIAL_EXIT',
|
||||||
|
reasoning: 'Market conditions uncertain. Reducing position size to manage risk.',
|
||||||
|
confidence: 0.75,
|
||||||
|
urgency: 'HIGH',
|
||||||
|
parameters: {
|
||||||
|
exitPercentage: 50,
|
||||||
|
keepStopLoss: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleMediumRisk(monitor, smartRecommendation) {
|
||||||
|
const { position, stopLossProximity } = monitor;
|
||||||
|
const distance = parseFloat(stopLossProximity.distancePercent);
|
||||||
|
|
||||||
|
await this.log(`🟡 MEDIUM RISK: Position ${distance}% from stop loss`);
|
||||||
|
|
||||||
|
// Learning-based decision for medium risk
|
||||||
|
if (smartRecommendation.learningBased && smartRecommendation.confidence > 0.6) {
|
||||||
|
return {
|
||||||
|
action: smartRecommendation.suggestedAction,
|
||||||
|
reasoning: `AI Learning: ${smartRecommendation.reasoning}`,
|
||||||
|
confidence: smartRecommendation.confidence,
|
||||||
|
urgency: 'MEDIUM',
|
||||||
|
learningEnhanced: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default medium risk response
|
||||||
|
return {
|
||||||
|
action: 'ENHANCED_MONITORING',
|
||||||
|
reasoning: 'Increased monitoring frequency. Preparing contingency plans.',
|
||||||
|
confidence: 0.6,
|
||||||
|
urgency: 'MEDIUM',
|
||||||
|
parameters: {
|
||||||
|
monitoringInterval: 30, // seconds
|
||||||
|
alertThreshold: this.riskThreshold
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleSafePosition(monitor, smartRecommendation) {
|
||||||
|
const { position } = monitor;
|
||||||
|
|
||||||
|
// Even in safe positions, check for optimization opportunities
|
||||||
|
if (smartRecommendation.learningBased && smartRecommendation.confidence > 0.8) {
|
||||||
|
if (smartRecommendation.suggestedAction === 'SCALE_POSITION') {
|
||||||
|
return {
|
||||||
|
action: 'SCALE_POSITION',
|
||||||
|
reasoning: `AI Learning: ${smartRecommendation.reasoning}`,
|
||||||
|
confidence: smartRecommendation.confidence,
|
||||||
|
urgency: 'LOW',
|
||||||
|
learningEnhanced: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
action: 'MONITOR',
|
||||||
|
reasoning: 'Position is safe. Continuing standard monitoring.',
|
||||||
|
confidence: 0.8,
|
||||||
|
urgency: 'LOW'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record decision for learning purposes
|
||||||
|
*/
|
||||||
|
async recordDecisionForLearning(monitor, decision, smartRecommendation) {
|
||||||
|
try {
|
||||||
|
const { position, stopLossProximity } = monitor;
|
||||||
|
const distance = parseFloat(stopLossProximity.distancePercent);
|
||||||
|
|
||||||
|
const decisionData = {
|
||||||
|
tradeId: position.id || `position_${Date.now()}`,
|
||||||
|
symbol: position.symbol,
|
||||||
|
decision: decision.action,
|
||||||
|
distanceFromSL: distance,
|
||||||
|
reasoning: decision.reasoning,
|
||||||
|
currentPrice: position.entryPrice,
|
||||||
|
confidenceScore: decision.confidence,
|
||||||
|
expectedOutcome: this.predictOutcome(decision.action, distance),
|
||||||
|
marketConditions: await this.getCurrentMarketConditions(position.symbol),
|
||||||
|
learningRecommendation: smartRecommendation
|
||||||
|
};
|
||||||
|
|
||||||
|
const decisionId = await this.learner.recordDecision(decisionData);
|
||||||
|
|
||||||
|
// Store decision for outcome tracking
|
||||||
|
this.pendingDecisions.set(decisionId, {
|
||||||
|
...decisionData,
|
||||||
|
timestamp: new Date(),
|
||||||
|
monitor: monitor
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.log(`📝 Recorded decision ${decisionId} for learning: ${decision.action}`);
|
||||||
|
|
||||||
|
return decisionId;
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`❌ Error recording decision for learning: ${error.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assess outcomes of previous decisions
|
||||||
|
*/
|
||||||
|
async assessDecisionOutcomes() {
|
||||||
|
try {
|
||||||
|
for (const [decisionId, decisionData] of this.pendingDecisions.entries()) {
|
||||||
|
const timeSinceDecision = Date.now() - decisionData.timestamp.getTime();
|
||||||
|
|
||||||
|
// Assess after sufficient time has passed (5 minutes minimum)
|
||||||
|
if (timeSinceDecision > 5 * 60 * 1000) {
|
||||||
|
const outcome = await this.determineDecisionOutcome(decisionData);
|
||||||
|
|
||||||
|
if (outcome) {
|
||||||
|
await this.learner.assessDecisionOutcome({
|
||||||
|
decisionId,
|
||||||
|
actualOutcome: outcome.result,
|
||||||
|
timeToOutcome: Math.floor(timeSinceDecision / 60000), // minutes
|
||||||
|
pnlImpact: outcome.pnlImpact,
|
||||||
|
additionalContext: outcome.context
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove from pending decisions
|
||||||
|
this.pendingDecisions.delete(decisionId);
|
||||||
|
await this.log(`✅ Assessed outcome for decision ${decisionId}: ${outcome.result}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`❌ Error assessing decision outcomes: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async determineDecisionOutcome(decisionData) {
|
||||||
|
try {
|
||||||
|
// Get current position status
|
||||||
|
const currentStatus = await this.getCurrentPositionStatus(decisionData.symbol);
|
||||||
|
|
||||||
|
if (!currentStatus) {
|
||||||
|
return {
|
||||||
|
result: 'POSITION_CLOSED',
|
||||||
|
pnlImpact: 0,
|
||||||
|
context: { reason: 'Position no longer exists' }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare current situation with when decision was made
|
||||||
|
const originalDistance = decisionData.distanceFromSL;
|
||||||
|
const currentDistance = currentStatus.distanceFromSL;
|
||||||
|
const pnlChange = currentStatus.unrealizedPnl - (decisionData.monitor.position?.unrealizedPnl || 0);
|
||||||
|
|
||||||
|
// Determine if decision was beneficial
|
||||||
|
if (decisionData.decision === 'EMERGENCY_EXIT' && currentDistance < 0.5) {
|
||||||
|
return {
|
||||||
|
result: 'AVOIDED_MAJOR_LOSS',
|
||||||
|
pnlImpact: Math.abs(pnlChange), // Positive impact
|
||||||
|
context: { originalDistance, currentDistance }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decisionData.decision === 'TIGHTEN_STOP_LOSS' && pnlChange > 0) {
|
||||||
|
return {
|
||||||
|
result: 'IMPROVED_PROFIT',
|
||||||
|
pnlImpact: pnlChange,
|
||||||
|
context: { originalDistance, currentDistance }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decisionData.decision === 'HOLD' && currentDistance > originalDistance) {
|
||||||
|
return {
|
||||||
|
result: 'CORRECT_HOLD',
|
||||||
|
pnlImpact: pnlChange,
|
||||||
|
context: { distanceImproved: currentDistance - originalDistance }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default assessment
|
||||||
|
return {
|
||||||
|
result: pnlChange >= 0 ? 'NEUTRAL_POSITIVE' : 'NEUTRAL_NEGATIVE',
|
||||||
|
pnlImpact: pnlChange,
|
||||||
|
context: { originalDistance, currentDistance }
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`❌ Error determining decision outcome: ${error.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCurrentPositionStatus(symbol) {
|
||||||
|
try {
|
||||||
|
const { stdout } = await execAsync('curl -s http://localhost:9001/api/automation/position-monitor');
|
||||||
|
const data = JSON.parse(stdout);
|
||||||
|
|
||||||
|
if (data.success && data.monitor?.hasPosition) {
|
||||||
|
return {
|
||||||
|
distanceFromSL: parseFloat(data.monitor.stopLossProximity?.distancePercent || 0),
|
||||||
|
unrealizedPnl: data.monitor.position?.unrealizedPnl || 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateThresholdsFromLearning() {
|
||||||
|
try {
|
||||||
|
// Get learned optimal thresholds
|
||||||
|
const patterns = await this.learner.analyzeDecisionPatterns();
|
||||||
|
|
||||||
|
if (patterns?.distanceOptimization) {
|
||||||
|
const optimization = patterns.distanceOptimization;
|
||||||
|
|
||||||
|
if (optimization.emergencyRange?.optimalThreshold) {
|
||||||
|
this.emergencyThreshold = optimization.emergencyRange.optimalThreshold;
|
||||||
|
}
|
||||||
|
if (optimization.highRiskRange?.optimalThreshold) {
|
||||||
|
this.riskThreshold = optimization.highRiskRange.optimalThreshold;
|
||||||
|
}
|
||||||
|
if (optimization.mediumRiskRange?.optimalThreshold) {
|
||||||
|
this.mediumRiskThreshold = optimization.mediumRiskRange.optimalThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.log(`🔄 Updated thresholds from learning: Emergency=${this.emergencyThreshold.toFixed(2)}%, Risk=${this.riskThreshold.toFixed(2)}%, Medium=${this.mediumRiskThreshold.toFixed(2)}%`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`❌ Error updating thresholds from learning: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
predictOutcome(action, distance) {
|
||||||
|
// Predict what we expect to happen based on the action
|
||||||
|
const predictions = {
|
||||||
|
'EMERGENCY_EXIT': 'AVOID_MAJOR_LOSS',
|
||||||
|
'PARTIAL_EXIT': 'REDUCE_RISK',
|
||||||
|
'TIGHTEN_STOP_LOSS': 'BETTER_RISK_REWARD',
|
||||||
|
'SCALE_POSITION': 'INCREASED_PROFIT',
|
||||||
|
'HOLD': 'MAINTAIN_POSITION',
|
||||||
|
'ENHANCED_MONITORING': 'EARLY_WARNING'
|
||||||
|
};
|
||||||
|
|
||||||
|
return predictions[action] || 'UNKNOWN_OUTCOME';
|
||||||
|
}
|
||||||
|
|
||||||
|
async analyzeMarketConditions(symbol) {
|
||||||
|
// Enhanced market analysis for better decision making
|
||||||
|
try {
|
||||||
|
const { stdout } = await execAsync('curl -s http://localhost:9001/api/automation/position-monitor');
|
||||||
|
const data = JSON.parse(stdout);
|
||||||
|
|
||||||
|
if (data.success && data.monitor?.position) {
|
||||||
|
const pnl = data.monitor.position.unrealizedPnl;
|
||||||
|
const trend = pnl > 0 ? 'BULLISH' : pnl < -1 ? 'BEARISH' : 'SIDEWAYS';
|
||||||
|
|
||||||
|
return {
|
||||||
|
trend,
|
||||||
|
strength: Math.abs(pnl),
|
||||||
|
timeOfDay: new Date().getHours(),
|
||||||
|
volatility: Math.random() * 0.1 // Mock volatility
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Fallback analysis
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
trend: 'UNKNOWN',
|
||||||
|
strength: 0,
|
||||||
|
timeOfDay: new Date().getHours(),
|
||||||
|
volatility: 0.05
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCurrentMarketConditions(symbol) {
|
||||||
|
const conditions = await this.analyzeMarketConditions(symbol);
|
||||||
|
return {
|
||||||
|
...conditions,
|
||||||
|
dayOfWeek: new Date().getDay(),
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enhanced Beach Mode with learning integration
|
||||||
|
*/
|
||||||
|
async beachMode() {
|
||||||
|
await this.log('🏖️ ENHANCED BEACH MODE: Autonomous operation with AI learning');
|
||||||
|
this.isActive = true;
|
||||||
|
|
||||||
|
// Main monitoring loop
|
||||||
|
const monitoringLoop = async () => {
|
||||||
|
if (!this.isActive) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Check current positions
|
||||||
|
const { stdout } = await execAsync('curl -s http://localhost:9001/api/automation/position-monitor');
|
||||||
|
const data = JSON.parse(stdout);
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
const decision = await this.analyzePosition(data.monitor);
|
||||||
|
await this.executeDecision(decision);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assess outcomes of previous decisions
|
||||||
|
await this.assessDecisionOutcomes();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`Error in beach mode cycle: ${error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schedule next check
|
||||||
|
if (this.isActive) {
|
||||||
|
setTimeout(monitoringLoop, 60000); // Check every minute
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start monitoring
|
||||||
|
monitoringLoop();
|
||||||
|
|
||||||
|
// Generate learning reports periodically
|
||||||
|
setInterval(async () => {
|
||||||
|
if (this.isActive) {
|
||||||
|
const report = await this.learner.generateLearningReport();
|
||||||
|
if (report) {
|
||||||
|
await this.log(`📊 Learning Update: ${report.summary.totalDecisions} decisions, ${(report.summary.systemConfidence * 100).toFixed(1)}% confidence`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 15 * 60 * 1000); // Every 15 minutes
|
||||||
|
}
|
||||||
|
|
||||||
|
async executeDecision(decision) {
|
||||||
|
await this.log(`🎯 Executing decision: ${decision.action} - ${decision.reasoning} (Confidence: ${(decision.confidence * 100).toFixed(1)}%)`);
|
||||||
|
|
||||||
|
// Add learning enhancement indicators
|
||||||
|
if (decision.learningEnhanced) {
|
||||||
|
await this.log(`🧠 Decision enhanced by AI learning system`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation would depend on your trading API
|
||||||
|
switch (decision.action) {
|
||||||
|
case 'EMERGENCY_EXIT':
|
||||||
|
await this.log('🚨 Implementing emergency exit protocol');
|
||||||
|
break;
|
||||||
|
case 'PARTIAL_EXIT':
|
||||||
|
await this.log('📉 Executing partial position closure');
|
||||||
|
break;
|
||||||
|
case 'TIGHTEN_STOP_LOSS':
|
||||||
|
await this.log('🎯 Adjusting stop loss parameters');
|
||||||
|
break;
|
||||||
|
case 'SCALE_POSITION':
|
||||||
|
await this.log('📈 Scaling position size');
|
||||||
|
break;
|
||||||
|
case 'ENHANCED_MONITORING':
|
||||||
|
await this.log('👁️ Activating enhanced monitoring');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
await this.log(`ℹ️ Monitoring: ${decision.reasoning}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
this.isActive = false;
|
||||||
|
this.log('🛑 Enhanced autonomous risk management stopped');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get learning system status and insights
|
||||||
|
*/
|
||||||
|
async getLearningStatus() {
|
||||||
|
try {
|
||||||
|
const report = await this.learner.generateLearningReport();
|
||||||
|
return {
|
||||||
|
isLearning: true,
|
||||||
|
totalDecisions: this.pendingDecisions.size + (report?.summary?.totalDecisions || 0),
|
||||||
|
systemConfidence: report?.summary?.systemConfidence || 0.3,
|
||||||
|
currentThresholds: {
|
||||||
|
emergency: this.emergencyThreshold,
|
||||||
|
risk: this.riskThreshold,
|
||||||
|
mediumRisk: this.mediumRiskThreshold
|
||||||
|
},
|
||||||
|
pendingAssessments: this.pendingDecisions.size,
|
||||||
|
lastAnalysis: this.lastAnalysis,
|
||||||
|
insights: report?.insights
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
isLearning: false,
|
||||||
|
error: error.message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export for use in other modules
|
||||||
|
module.exports = EnhancedAutonomousRiskManager;
|
||||||
|
|
||||||
|
// Direct execution for testing
|
||||||
|
if (require.main === module) {
|
||||||
|
const riskManager = new EnhancedAutonomousRiskManager();
|
||||||
|
|
||||||
|
console.log('🤖 Enhanced Autonomous Risk Manager with AI Learning');
|
||||||
|
console.log('🧠 Now learning from every decision to become smarter!');
|
||||||
|
console.log('🏖️ Perfect for beach mode - gets better while you relax!');
|
||||||
|
|
||||||
|
riskManager.beachMode();
|
||||||
|
|
||||||
|
process.on('SIGINT', () => {
|
||||||
|
riskManager.stop();
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -11,14 +11,21 @@ async function importAILeverageCalculator() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import Stable Risk Monitor for reliable beach mode operation
|
// Import Enhanced Risk Manager with Learning for intelligent beach mode operation
|
||||||
async function importStableRiskMonitor() {
|
async function importEnhancedRiskManager() {
|
||||||
try {
|
try {
|
||||||
const StableRiskMonitor = require('./stable-risk-monitor.js');
|
const EnhancedAutonomousRiskManager = require('./enhanced-autonomous-risk-manager.js');
|
||||||
return StableRiskMonitor;
|
return EnhancedAutonomousRiskManager;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('⚠️ Stable Risk Monitor not available, using basic monitoring');
|
console.warn('⚠️ Enhanced Risk Manager not available, falling back to stable monitor');
|
||||||
return null;
|
// Fallback to stable risk monitor
|
||||||
|
try {
|
||||||
|
const StableRiskMonitor = require('./stable-risk-monitor.js');
|
||||||
|
return StableRiskMonitor;
|
||||||
|
} catch (fallbackError) {
|
||||||
|
console.warn('⚠️ Stable Risk Monitor also not available, using basic monitoring');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,22 +66,25 @@ class SimpleAutomation {
|
|||||||
console.log('🎯 LIVE TRADING:', this.config.enableTrading ? 'ENABLED' : 'DISABLED');
|
console.log('🎯 LIVE TRADING:', this.config.enableTrading ? 'ENABLED' : 'DISABLED');
|
||||||
this.stats.totalCycles = 0;
|
this.stats.totalCycles = 0;
|
||||||
|
|
||||||
// Initialize Stable Risk Monitor for reliable beach mode operation
|
// Initialize Enhanced AI Risk Manager with Learning Capabilities
|
||||||
try {
|
try {
|
||||||
const StableMonitorClass = await importStableRiskMonitor();
|
const EnhancedRiskManagerClass = await importEnhancedRiskManager();
|
||||||
if (StableMonitorClass) {
|
if (EnhancedRiskManagerClass) {
|
||||||
this.riskManager = new StableMonitorClass();
|
this.riskManager = new EnhancedRiskManagerClass();
|
||||||
console.log('🏖️ BEACH MODE READY: Stable autonomous monitoring activated');
|
console.log('🧠 ENHANCED BEACH MODE: AI learning system activated');
|
||||||
// Start stable monitoring
|
console.log('🎯 System will learn from every decision and improve over time');
|
||||||
|
|
||||||
|
// Start enhanced autonomous operation
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.riskManager) {
|
if (this.riskManager && this.riskManager.beachMode) {
|
||||||
this.riskManager.startMonitoring();
|
this.riskManager.beachMode();
|
||||||
|
console.log('🏖️ Full autonomous operation with AI learning active');
|
||||||
}
|
}
|
||||||
}, 3000); // Wait 3 seconds for system stabilization
|
}, 2000);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('⚠️ Risk Monitor initialization failed:', error.message);
|
console.log('🔄 Continuing without enhanced autonomous risk monitoring');
|
||||||
console.log('🔄 Continuing without autonomous risk monitoring');
|
console.error('Risk manager initialization error:', error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-enable trading when in LIVE mode
|
// Auto-enable trading when in LIVE mode
|
||||||
|
|||||||
592
lib/stop-loss-decision-learner.js
Normal file
592
lib/stop-loss-decision-learner.js
Normal file
@@ -0,0 +1,592 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop Loss Decision Learning System
|
||||||
|
*
|
||||||
|
* This system makes the AI learn from its own decision-making process near stop loss.
|
||||||
|
* It records every decision, tracks outcomes, and continuously improves decision-making.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { PrismaClient } = require('@prisma/client');
|
||||||
|
|
||||||
|
class StopLossDecisionLearner {
|
||||||
|
constructor() {
|
||||||
|
this.prisma = new PrismaClient();
|
||||||
|
this.decisionHistory = [];
|
||||||
|
this.learningThresholds = {
|
||||||
|
emergencyDistance: 1.0,
|
||||||
|
highRiskDistance: 2.0,
|
||||||
|
mediumRiskDistance: 5.0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async log(message) {
|
||||||
|
const timestamp = new Date().toISOString();
|
||||||
|
console.log(`[${timestamp}] 🧠 SL Learner: ${message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record an AI decision made near stop loss for learning purposes
|
||||||
|
*/
|
||||||
|
async recordDecision(decisionData) {
|
||||||
|
try {
|
||||||
|
const decision = {
|
||||||
|
id: `decision_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
||||||
|
tradeId: decisionData.tradeId,
|
||||||
|
symbol: decisionData.symbol,
|
||||||
|
decisionType: decisionData.decision, // 'HOLD', 'EXIT', 'TIGHTEN_SL', 'PARTIAL_EXIT', 'EMERGENCY_EXIT'
|
||||||
|
distanceFromSL: decisionData.distanceFromSL,
|
||||||
|
reasoning: decisionData.reasoning,
|
||||||
|
marketConditions: {
|
||||||
|
price: decisionData.currentPrice,
|
||||||
|
trend: await this.analyzeMarketTrend(decisionData.symbol),
|
||||||
|
volatility: await this.calculateVolatility(decisionData.symbol),
|
||||||
|
volume: decisionData.volume || 'unknown',
|
||||||
|
timeOfDay: new Date().getHours(),
|
||||||
|
dayOfWeek: new Date().getDay()
|
||||||
|
},
|
||||||
|
confidenceScore: decisionData.confidenceScore || 0.7,
|
||||||
|
expectedOutcome: decisionData.expectedOutcome || 'BETTER_RESULT',
|
||||||
|
decisionTimestamp: new Date(),
|
||||||
|
status: 'PENDING_OUTCOME'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store in database
|
||||||
|
await this.prisma.sLDecision.create({
|
||||||
|
data: {
|
||||||
|
id: decision.id,
|
||||||
|
tradeId: decision.tradeId,
|
||||||
|
symbol: decision.symbol,
|
||||||
|
decisionType: decision.decisionType,
|
||||||
|
distanceFromSL: decision.distanceFromSL,
|
||||||
|
reasoning: decision.reasoning,
|
||||||
|
marketConditions: JSON.stringify(decision.marketConditions),
|
||||||
|
confidenceScore: decision.confidenceScore,
|
||||||
|
expectedOutcome: decision.expectedOutcome,
|
||||||
|
decisionTimestamp: decision.decisionTimestamp,
|
||||||
|
status: decision.status
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Keep in memory for quick access
|
||||||
|
this.decisionHistory.push(decision);
|
||||||
|
|
||||||
|
await this.log(`📝 Recorded decision: ${decision.decisionType} at ${decision.distanceFromSL}% from SL - ${decision.reasoning}`);
|
||||||
|
|
||||||
|
return decision.id;
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`❌ Error recording decision: ${error.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assess the outcome of a previous decision when trade closes or conditions change
|
||||||
|
*/
|
||||||
|
async assessDecisionOutcome(assessmentData) {
|
||||||
|
try {
|
||||||
|
const { decisionId, actualOutcome, timeToOutcome, pnlImpact, additionalContext } = assessmentData;
|
||||||
|
|
||||||
|
// Determine if the decision was correct
|
||||||
|
const wasCorrect = this.evaluateDecisionCorrectness(actualOutcome, pnlImpact);
|
||||||
|
const learningScore = this.calculateLearningScore(wasCorrect, pnlImpact, timeToOutcome);
|
||||||
|
|
||||||
|
// Update decision record
|
||||||
|
await this.prisma.sLDecision.update({
|
||||||
|
where: { id: decisionId },
|
||||||
|
data: {
|
||||||
|
outcome: actualOutcome,
|
||||||
|
outcomeTimestamp: new Date(),
|
||||||
|
timeToOutcome,
|
||||||
|
pnlImpact,
|
||||||
|
wasCorrect,
|
||||||
|
learningScore,
|
||||||
|
additionalContext: JSON.stringify(additionalContext || {}),
|
||||||
|
status: 'ASSESSED'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update in-memory history
|
||||||
|
const decision = this.decisionHistory.find(d => d.id === decisionId);
|
||||||
|
if (decision) {
|
||||||
|
Object.assign(decision, {
|
||||||
|
outcome: actualOutcome,
|
||||||
|
outcomeTimestamp: new Date(),
|
||||||
|
wasCorrect,
|
||||||
|
learningScore,
|
||||||
|
status: 'ASSESSED'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.log(`✅ Assessed decision ${decisionId}: ${wasCorrect ? 'CORRECT' : 'INCORRECT'} - Score: ${learningScore.toFixed(2)}`);
|
||||||
|
|
||||||
|
// Trigger learning update
|
||||||
|
await this.updateLearningModel();
|
||||||
|
|
||||||
|
return { wasCorrect, learningScore };
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`❌ Error assessing decision outcome: ${error.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyze historical decisions to identify patterns and optimize future decisions
|
||||||
|
*/
|
||||||
|
async analyzeDecisionPatterns() {
|
||||||
|
try {
|
||||||
|
const decisions = await this.prisma.sLDecision.findMany({
|
||||||
|
where: { status: 'ASSESSED' },
|
||||||
|
orderBy: { decisionTimestamp: 'desc' },
|
||||||
|
take: 100 // Analyze last 100 decisions
|
||||||
|
});
|
||||||
|
|
||||||
|
const patterns = {
|
||||||
|
successfulPatterns: [],
|
||||||
|
failurePatterns: [],
|
||||||
|
optimalTiming: {},
|
||||||
|
contextFactors: {},
|
||||||
|
distanceOptimization: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Analyze success patterns by decision type
|
||||||
|
const decisionTypes = ['HOLD', 'EXIT', 'TIGHTEN_SL', 'PARTIAL_EXIT', 'EMERGENCY_EXIT'];
|
||||||
|
|
||||||
|
for (const type of decisionTypes) {
|
||||||
|
const typeDecisions = decisions.filter(d => d.decisionType === type);
|
||||||
|
const successRate = typeDecisions.length > 0 ?
|
||||||
|
typeDecisions.filter(d => d.wasCorrect).length / typeDecisions.length : 0;
|
||||||
|
|
||||||
|
const avgScore = typeDecisions.length > 0 ?
|
||||||
|
typeDecisions.reduce((sum, d) => sum + (d.learningScore || 0), 0) / typeDecisions.length : 0;
|
||||||
|
|
||||||
|
if (successRate > 0.6) { // 60%+ success rate
|
||||||
|
patterns.successfulPatterns.push({
|
||||||
|
decisionType: type,
|
||||||
|
successRate: successRate * 100,
|
||||||
|
avgScore,
|
||||||
|
sampleSize: typeDecisions.length,
|
||||||
|
optimalConditions: this.identifyOptimalConditions(typeDecisions.filter(d => d.wasCorrect))
|
||||||
|
});
|
||||||
|
} else if (typeDecisions.length >= 5) {
|
||||||
|
patterns.failurePatterns.push({
|
||||||
|
decisionType: type,
|
||||||
|
successRate: successRate * 100,
|
||||||
|
avgScore,
|
||||||
|
sampleSize: typeDecisions.length,
|
||||||
|
commonFailureReasons: this.identifyFailureReasons(typeDecisions.filter(d => !d.wasCorrect))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Analyze optimal distance thresholds
|
||||||
|
patterns.distanceOptimization = await this.optimizeDistanceThresholds(decisions);
|
||||||
|
|
||||||
|
// Analyze timing patterns
|
||||||
|
patterns.optimalTiming = await this.analyzeTimingPatterns(decisions);
|
||||||
|
|
||||||
|
await this.log(`📊 Pattern analysis complete: ${patterns.successfulPatterns.length} successful patterns, ${patterns.failurePatterns.length} failure patterns identified`);
|
||||||
|
|
||||||
|
return patterns;
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`❌ Error analyzing decision patterns: ${error.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get AI recommendation for current situation based on learned patterns
|
||||||
|
*/
|
||||||
|
async getSmartRecommendation(situationData) {
|
||||||
|
try {
|
||||||
|
const { distanceFromSL, symbol, marketConditions } = situationData;
|
||||||
|
|
||||||
|
// Get historical patterns for similar situations
|
||||||
|
const patterns = await this.analyzeDecisionPatterns();
|
||||||
|
const currentConditions = marketConditions || await this.getCurrentMarketConditions(symbol);
|
||||||
|
|
||||||
|
// Find most similar historical situations
|
||||||
|
const similarSituations = await this.findSimilarSituations({
|
||||||
|
distanceFromSL,
|
||||||
|
marketConditions: currentConditions
|
||||||
|
});
|
||||||
|
|
||||||
|
// Generate recommendation based on learned patterns
|
||||||
|
const recommendation = {
|
||||||
|
suggestedAction: 'HOLD', // Default
|
||||||
|
confidence: 0.5,
|
||||||
|
reasoning: 'Insufficient learning data',
|
||||||
|
learningBased: false,
|
||||||
|
supportingData: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (similarSituations.length >= 3) {
|
||||||
|
const successfulActions = similarSituations
|
||||||
|
.filter(s => s.wasCorrect)
|
||||||
|
.map(s => s.decisionType);
|
||||||
|
|
||||||
|
const mostSuccessfulAction = this.getMostCommonAction(successfulActions);
|
||||||
|
const successRate = successfulActions.length / similarSituations.length;
|
||||||
|
|
||||||
|
recommendation.suggestedAction = mostSuccessfulAction;
|
||||||
|
recommendation.confidence = Math.min(0.95, successRate + 0.1);
|
||||||
|
recommendation.reasoning = `Based on ${similarSituations.length} similar situations, ${mostSuccessfulAction} succeeded ${(successRate * 100).toFixed(1)}% of the time`;
|
||||||
|
recommendation.learningBased = true;
|
||||||
|
recommendation.supportingData = {
|
||||||
|
historicalSamples: similarSituations.length,
|
||||||
|
successRate: successRate * 100,
|
||||||
|
avgPnlImpact: similarSituations.reduce((sum, s) => sum + (s.pnlImpact || 0), 0) / similarSituations.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.log(`🎯 Smart recommendation: ${recommendation.suggestedAction} (${(recommendation.confidence * 100).toFixed(1)}% confidence) - ${recommendation.reasoning}`);
|
||||||
|
|
||||||
|
return recommendation;
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`❌ Error generating smart recommendation: ${error.message}`);
|
||||||
|
return {
|
||||||
|
suggestedAction: 'HOLD',
|
||||||
|
confidence: 0.3,
|
||||||
|
reasoning: `Error in recommendation system: ${error.message}`,
|
||||||
|
learningBased: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update learning model based on new decision outcomes
|
||||||
|
*/
|
||||||
|
async updateLearningModel() {
|
||||||
|
try {
|
||||||
|
const patterns = await this.analyzeDecisionPatterns();
|
||||||
|
|
||||||
|
if (patterns && patterns.distanceOptimization) {
|
||||||
|
// Update decision thresholds based on learning
|
||||||
|
this.learningThresholds = {
|
||||||
|
emergencyDistance: patterns.distanceOptimization.optimalEmergencyThreshold || 1.0,
|
||||||
|
highRiskDistance: patterns.distanceOptimization.optimalHighRiskThreshold || 2.0,
|
||||||
|
mediumRiskDistance: patterns.distanceOptimization.optimalMediumRiskThreshold || 5.0
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.log(`🔄 Updated learning thresholds: Emergency=${this.learningThresholds.emergencyDistance}%, High Risk=${this.learningThresholds.highRiskDistance}%, Medium Risk=${this.learningThresholds.mediumRiskDistance}%`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`❌ Error updating learning model: ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper methods for analysis
|
||||||
|
*/
|
||||||
|
evaluateDecisionCorrectness(actualOutcome, pnlImpact) {
|
||||||
|
// Define what constitutes a "correct" decision
|
||||||
|
const correctOutcomes = [
|
||||||
|
'BETTER_THAN_ORIGINAL_SL',
|
||||||
|
'AVOIDED_LOSS',
|
||||||
|
'IMPROVED_PROFIT',
|
||||||
|
'SUCCESSFUL_EXIT'
|
||||||
|
];
|
||||||
|
|
||||||
|
return correctOutcomes.includes(actualOutcome) || (pnlImpact && pnlImpact > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateLearningScore(wasCorrect, pnlImpact, timeToOutcome) {
|
||||||
|
let score = wasCorrect ? 0.7 : 0.3; // Base score
|
||||||
|
|
||||||
|
// Adjust for P&L impact
|
||||||
|
if (pnlImpact) {
|
||||||
|
score += Math.min(0.2, pnlImpact / 100); // Max 0.2 bonus for positive P&L
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust for timing (faster good decisions are better)
|
||||||
|
if (timeToOutcome && wasCorrect) {
|
||||||
|
const timingBonus = Math.max(0, 0.1 - (timeToOutcome / 3600)); // Bonus for decisions resolved within an hour
|
||||||
|
score += timingBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.max(0, Math.min(1, score));
|
||||||
|
}
|
||||||
|
|
||||||
|
identifyOptimalConditions(successfulDecisions) {
|
||||||
|
// Analyze common conditions in successful decisions
|
||||||
|
const conditions = {};
|
||||||
|
|
||||||
|
successfulDecisions.forEach(decision => {
|
||||||
|
try {
|
||||||
|
const market = JSON.parse(decision.marketConditions || '{}');
|
||||||
|
|
||||||
|
// Track successful decision contexts
|
||||||
|
if (market.trend) {
|
||||||
|
conditions.trend = conditions.trend || {};
|
||||||
|
conditions.trend[market.trend] = (conditions.trend[market.trend] || 0) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (market.timeOfDay) {
|
||||||
|
conditions.timeOfDay = conditions.timeOfDay || {};
|
||||||
|
const hour = market.timeOfDay;
|
||||||
|
conditions.timeOfDay[hour] = (conditions.timeOfDay[hour] || 0) + 1;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Skip malformed data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
identifyFailureReasons(failedDecisions) {
|
||||||
|
// Analyze what went wrong in failed decisions
|
||||||
|
return failedDecisions.map(decision => ({
|
||||||
|
reasoning: decision.reasoning,
|
||||||
|
distanceFromSL: decision.distanceFromSL,
|
||||||
|
outcome: decision.outcome,
|
||||||
|
pnlImpact: decision.pnlImpact
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
async optimizeDistanceThresholds(decisions) {
|
||||||
|
// Analyze optimal distance thresholds for different decision types
|
||||||
|
const optimization = {};
|
||||||
|
|
||||||
|
// Group decisions by distance ranges
|
||||||
|
const ranges = [
|
||||||
|
{ min: 0, max: 1, label: 'emergency' },
|
||||||
|
{ min: 1, max: 2, label: 'highRisk' },
|
||||||
|
{ min: 2, max: 5, label: 'mediumRisk' },
|
||||||
|
{ min: 5, max: 100, label: 'safe' }
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const range of ranges) {
|
||||||
|
const rangeDecisions = decisions.filter(d =>
|
||||||
|
d.distanceFromSL >= range.min && d.distanceFromSL < range.max
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rangeDecisions.length >= 3) {
|
||||||
|
const successRate = rangeDecisions.filter(d => d.wasCorrect).length / rangeDecisions.length;
|
||||||
|
const avgScore = rangeDecisions.reduce((sum, d) => sum + (d.learningScore || 0), 0) / rangeDecisions.length;
|
||||||
|
|
||||||
|
optimization[`${range.label}Range`] = {
|
||||||
|
successRate: successRate * 100,
|
||||||
|
avgScore,
|
||||||
|
sampleSize: rangeDecisions.length,
|
||||||
|
optimalThreshold: this.calculateOptimalThreshold(rangeDecisions)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return optimization;
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateOptimalThreshold(decisions) {
|
||||||
|
// Find the distance threshold that maximizes success rate
|
||||||
|
const sortedDecisions = decisions.sort((a, b) => a.distanceFromSL - b.distanceFromSL);
|
||||||
|
let bestThreshold = 1.0;
|
||||||
|
let bestScore = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < sortedDecisions.length - 1; i++) {
|
||||||
|
const threshold = sortedDecisions[i].distanceFromSL;
|
||||||
|
const aboveThreshold = sortedDecisions.slice(i);
|
||||||
|
const successRate = aboveThreshold.filter(d => d.wasCorrect).length / aboveThreshold.length;
|
||||||
|
|
||||||
|
if (successRate > bestScore && aboveThreshold.length >= 3) {
|
||||||
|
bestScore = successRate;
|
||||||
|
bestThreshold = threshold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
async analyzeTimingPatterns(decisions) {
|
||||||
|
// Analyze when decisions work best (time of day, day of week, etc.)
|
||||||
|
const timing = {
|
||||||
|
timeOfDay: {},
|
||||||
|
dayOfWeek: {},
|
||||||
|
marketSession: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
decisions.forEach(decision => {
|
||||||
|
try {
|
||||||
|
const market = JSON.parse(decision.marketConditions || '{}');
|
||||||
|
const wasCorrect = decision.wasCorrect;
|
||||||
|
|
||||||
|
if (market.timeOfDay !== undefined) {
|
||||||
|
const hour = market.timeOfDay;
|
||||||
|
timing.timeOfDay[hour] = timing.timeOfDay[hour] || { total: 0, correct: 0 };
|
||||||
|
timing.timeOfDay[hour].total++;
|
||||||
|
if (wasCorrect) timing.timeOfDay[hour].correct++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (market.dayOfWeek !== undefined) {
|
||||||
|
const day = market.dayOfWeek;
|
||||||
|
timing.dayOfWeek[day] = timing.dayOfWeek[day] || { total: 0, correct: 0 };
|
||||||
|
timing.dayOfWeek[day].total++;
|
||||||
|
if (wasCorrect) timing.dayOfWeek[day].correct++;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Skip malformed data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return timing;
|
||||||
|
}
|
||||||
|
|
||||||
|
async findSimilarSituations(currentSituation) {
|
||||||
|
const { distanceFromSL, marketConditions } = currentSituation;
|
||||||
|
const tolerance = 0.5; // 0.5% tolerance for distance matching
|
||||||
|
|
||||||
|
const decisions = await this.prisma.sLDecision.findMany({
|
||||||
|
where: {
|
||||||
|
status: 'ASSESSED',
|
||||||
|
distanceFromSL: {
|
||||||
|
gte: distanceFromSL - tolerance,
|
||||||
|
lte: distanceFromSL + tolerance
|
||||||
|
}
|
||||||
|
},
|
||||||
|
orderBy: { decisionTimestamp: 'desc' },
|
||||||
|
take: 20
|
||||||
|
});
|
||||||
|
|
||||||
|
return decisions;
|
||||||
|
}
|
||||||
|
|
||||||
|
getMostCommonAction(actions) {
|
||||||
|
const counts = {};
|
||||||
|
actions.forEach(action => {
|
||||||
|
counts[action] = (counts[action] || 0) + 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.entries(counts).reduce((a, b) => counts[a] > counts[b] ? a : b)[0] || 'HOLD';
|
||||||
|
}
|
||||||
|
|
||||||
|
async analyzeMarketTrend(symbol) {
|
||||||
|
// Simplified trend analysis - in real implementation, use technical indicators
|
||||||
|
try {
|
||||||
|
const response = await fetch(`http://localhost:9001/api/automation/position-monitor`);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.success && data.monitor && data.monitor.position) {
|
||||||
|
const pnl = data.monitor.position.unrealizedPnl;
|
||||||
|
if (pnl > 0) return 'BULLISH';
|
||||||
|
if (pnl < 0) return 'BEARISH';
|
||||||
|
return 'SIDEWAYS';
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'UNKNOWN';
|
||||||
|
}
|
||||||
|
|
||||||
|
async calculateVolatility(symbol) {
|
||||||
|
// Simplified volatility calculation
|
||||||
|
// In real implementation, calculate based on price history
|
||||||
|
return Math.random() * 0.1; // Mock volatility 0-10%
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCurrentMarketConditions(symbol) {
|
||||||
|
return {
|
||||||
|
trend: await this.analyzeMarketTrend(symbol),
|
||||||
|
volatility: await this.calculateVolatility(symbol),
|
||||||
|
timeOfDay: new Date().getHours(),
|
||||||
|
dayOfWeek: new Date().getDay()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate learning insights report
|
||||||
|
*/
|
||||||
|
async generateLearningReport() {
|
||||||
|
try {
|
||||||
|
const patterns = await this.analyzeDecisionPatterns();
|
||||||
|
|
||||||
|
const report = {
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
summary: {
|
||||||
|
totalDecisions: this.decisionHistory.length,
|
||||||
|
successfulPatterns: patterns?.successfulPatterns?.length || 0,
|
||||||
|
learningThresholds: this.learningThresholds,
|
||||||
|
systemConfidence: this.calculateSystemConfidence()
|
||||||
|
},
|
||||||
|
insights: patterns,
|
||||||
|
recommendations: await this.generateSystemRecommendations(patterns)
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.log(`📊 Learning report generated: ${report.summary.totalDecisions} decisions analyzed`);
|
||||||
|
|
||||||
|
return report;
|
||||||
|
} catch (error) {
|
||||||
|
await this.log(`❌ Error generating learning report: ${error.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateSystemConfidence() {
|
||||||
|
const recentDecisions = this.decisionHistory.slice(-20); // Last 20 decisions
|
||||||
|
if (recentDecisions.length < 5) return 0.3; // Low confidence with insufficient data
|
||||||
|
|
||||||
|
const successRate = recentDecisions.filter(d => d.wasCorrect).length / recentDecisions.length;
|
||||||
|
return Math.min(0.95, successRate + 0.1); // Cap at 95%
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateSystemRecommendations(patterns) {
|
||||||
|
const recommendations = [];
|
||||||
|
|
||||||
|
if (patterns?.failurePatterns?.length > 0) {
|
||||||
|
patterns.failurePatterns.forEach(pattern => {
|
||||||
|
recommendations.push({
|
||||||
|
type: 'IMPROVEMENT',
|
||||||
|
priority: 'HIGH',
|
||||||
|
message: `Consider avoiding ${pattern.decisionType} decisions - only ${pattern.successRate.toFixed(1)}% success rate`,
|
||||||
|
actionable: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patterns?.successfulPatterns?.length > 0) {
|
||||||
|
const bestPattern = patterns.successfulPatterns.reduce((best, current) =>
|
||||||
|
current.successRate > best.successRate ? current : best
|
||||||
|
);
|
||||||
|
|
||||||
|
recommendations.push({
|
||||||
|
type: 'OPTIMIZATION',
|
||||||
|
priority: 'MEDIUM',
|
||||||
|
message: `${bestPattern.decisionType} decisions show ${bestPattern.successRate.toFixed(1)}% success rate - consider using more often`,
|
||||||
|
actionable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return recommendations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export for use in other modules
|
||||||
|
module.exports = StopLossDecisionLearner;
|
||||||
|
|
||||||
|
// Direct execution for testing
|
||||||
|
if (require.main === module) {
|
||||||
|
const learner = new StopLossDecisionLearner();
|
||||||
|
|
||||||
|
console.log('🧠 Stop Loss Decision Learning System');
|
||||||
|
console.log('📊 Ready to make your AI smarter with every decision!');
|
||||||
|
|
||||||
|
// Demo decision recording
|
||||||
|
setTimeout(async () => {
|
||||||
|
await learner.recordDecision({
|
||||||
|
tradeId: 'demo_001',
|
||||||
|
symbol: 'SOL-PERP',
|
||||||
|
decision: 'TIGHTEN_SL',
|
||||||
|
distanceFromSL: 2.3,
|
||||||
|
reasoning: 'Market showing weakness, reducing risk exposure',
|
||||||
|
currentPrice: 182.45,
|
||||||
|
confidenceScore: 0.8,
|
||||||
|
expectedOutcome: 'BETTER_RESULT'
|
||||||
|
});
|
||||||
|
|
||||||
|
const report = await learner.generateLearningReport();
|
||||||
|
console.log('\n📊 LEARNING REPORT:', JSON.stringify(report, null, 2));
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
Binary file not shown.
Reference in New Issue
Block a user