Some checks failed
CI Pipeline / changes (push) Has been cancelled
CI Pipeline / core (push) Has been cancelled
CI Pipeline / trading-backend (push) Has been cancelled
CI Pipeline / trading-data-service (push) Has been cancelled
CI Pipeline / trading-frontend (push) Has been cancelled
CI Pipeline / erp-core (push) Has been cancelled
CI Pipeline / erp-mecanicas (push) Has been cancelled
CI Pipeline / gamilit-backend (push) Has been cancelled
CI Pipeline / gamilit-frontend (push) Has been cancelled
378 lines
9.3 KiB
TypeScript
378 lines
9.3 KiB
TypeScript
/**
|
|
* ML Engine Service
|
|
* Client for connecting to the ML Engine API
|
|
*/
|
|
|
|
const ML_API_URL = import.meta.env.VITE_ML_URL || 'http://localhost:8001';
|
|
|
|
// ============================================================================
|
|
// Types
|
|
// ============================================================================
|
|
|
|
export interface MLSignal {
|
|
signal_id: string;
|
|
symbol: string;
|
|
direction: 'long' | 'short';
|
|
entry_price: number;
|
|
stop_loss: number;
|
|
take_profit: number;
|
|
risk_reward_ratio: number;
|
|
confidence_score: number;
|
|
prob_tp_first: number;
|
|
amd_phase: string;
|
|
volatility_regime: string;
|
|
valid_until: string;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface AMDPhase {
|
|
symbol: string;
|
|
phase: 'accumulation' | 'manipulation' | 'distribution' | 'unknown';
|
|
confidence: number;
|
|
phase_duration_bars: number;
|
|
next_phase_probability: {
|
|
accumulation: number;
|
|
manipulation: number;
|
|
distribution: number;
|
|
};
|
|
key_levels: {
|
|
support: number;
|
|
resistance: number;
|
|
};
|
|
}
|
|
|
|
export interface RangePrediction {
|
|
symbol: string;
|
|
timeframe: string;
|
|
current_price: number;
|
|
predicted_high: number;
|
|
predicted_low: number;
|
|
expected_range_percent: number;
|
|
volatility_regime: 'low' | 'normal' | 'high' | 'extreme';
|
|
prediction_confidence: number;
|
|
}
|
|
|
|
export interface BacktestResult {
|
|
strategy: string;
|
|
symbol: string;
|
|
start_date: string;
|
|
end_date: string;
|
|
total_trades: number;
|
|
winning_trades: number;
|
|
losing_trades: number;
|
|
win_rate: number;
|
|
total_pnl: number;
|
|
max_drawdown: number;
|
|
sharpe_ratio: number;
|
|
profit_factor: number;
|
|
}
|
|
|
|
// ============================================================================
|
|
// API Functions
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Get the latest ML signal for a symbol
|
|
*/
|
|
export async function getLatestSignal(symbol: string): Promise<MLSignal | null> {
|
|
try {
|
|
const response = await fetch(`${ML_API_URL}/api/v1/signals/latest/${symbol}`);
|
|
if (!response.ok) {
|
|
if (response.status === 404) return null;
|
|
throw new Error(`API error: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
return data.signal || null;
|
|
} catch (error) {
|
|
console.error('Error fetching latest signal:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get active signals for all symbols
|
|
*/
|
|
export async function getActiveSignals(): Promise<MLSignal[]> {
|
|
try {
|
|
const response = await fetch(`${ML_API_URL}/api/v1/signals/active`);
|
|
if (!response.ok) {
|
|
throw new Error(`API error: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
return data.signals || [];
|
|
} catch (error) {
|
|
console.error('Error fetching active signals:', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get AMD phase detection for a symbol
|
|
*/
|
|
export async function getAMDPhase(symbol: string): Promise<AMDPhase | null> {
|
|
try {
|
|
const response = await fetch(`${ML_API_URL}/api/v1/amd/detect/${symbol}`);
|
|
if (!response.ok) {
|
|
if (response.status === 404) return null;
|
|
throw new Error(`API error: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error fetching AMD phase:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get range prediction for a symbol
|
|
*/
|
|
export async function getRangePrediction(
|
|
symbol: string,
|
|
timeframe: string = '1h'
|
|
): Promise<RangePrediction | null> {
|
|
try {
|
|
const response = await fetch(
|
|
`${ML_API_URL}/api/v1/predict/range/${symbol}?timeframe=${timeframe}`
|
|
);
|
|
if (!response.ok) {
|
|
if (response.status === 404) return null;
|
|
throw new Error(`API error: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error fetching range prediction:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate a new signal for a symbol
|
|
*/
|
|
export async function generateSignal(symbol: string): Promise<MLSignal | null> {
|
|
try {
|
|
const response = await fetch(`${ML_API_URL}/api/v1/signals/generate`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ symbol }),
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`API error: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
return data.signal || null;
|
|
} catch (error) {
|
|
console.error('Error generating signal:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Run backtest for a strategy
|
|
*/
|
|
export async function runBacktest(params: {
|
|
strategy: string;
|
|
symbol: string;
|
|
start_date: string;
|
|
end_date: string;
|
|
initial_capital?: number;
|
|
}): Promise<BacktestResult | null> {
|
|
try {
|
|
const response = await fetch(`${ML_API_URL}/api/v1/backtest/run`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(params),
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`API error: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error running backtest:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check ML Engine health
|
|
*/
|
|
export async function checkHealth(): Promise<boolean> {
|
|
try {
|
|
const response = await fetch(`${ML_API_URL}/health`);
|
|
return response.ok;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// ICT/SMC Analysis Types & Functions
|
|
// ============================================================================
|
|
|
|
export interface OrderBlock {
|
|
type: 'bullish' | 'bearish';
|
|
high: number;
|
|
low: number;
|
|
midpoint: number;
|
|
strength: number;
|
|
valid: boolean;
|
|
touched: boolean;
|
|
}
|
|
|
|
export interface FairValueGap {
|
|
type: 'bullish' | 'bearish';
|
|
high: number;
|
|
low: number;
|
|
midpoint: number;
|
|
size_percent: number;
|
|
filled: boolean;
|
|
}
|
|
|
|
export interface ICTAnalysis {
|
|
symbol: string;
|
|
timeframe: string;
|
|
market_bias: 'bullish' | 'bearish' | 'neutral';
|
|
bias_confidence: number;
|
|
current_trend: string;
|
|
order_blocks: OrderBlock[];
|
|
fair_value_gaps: FairValueGap[];
|
|
entry_zone?: { low: number; high: number };
|
|
stop_loss?: number;
|
|
take_profits: { tp1?: number; tp2?: number; tp3?: number };
|
|
risk_reward?: number;
|
|
signals: string[];
|
|
score: number;
|
|
premium_zone: { low: number; high: number };
|
|
discount_zone: { low: number; high: number };
|
|
equilibrium: number;
|
|
}
|
|
|
|
export interface EnsembleSignal {
|
|
symbol: string;
|
|
timeframe: string;
|
|
action: 'BUY' | 'SELL' | 'HOLD';
|
|
strength: 'strong' | 'moderate' | 'weak';
|
|
confidence: number;
|
|
net_score: number;
|
|
strategy_signals: {
|
|
amd: { action: string; score: number; weight: number };
|
|
ict: { action: string; score: number; weight: number };
|
|
range: { action: string; score: number; weight: number };
|
|
tpsl: { action: string; score: number; weight: number };
|
|
};
|
|
entry?: number;
|
|
stop_loss?: number;
|
|
take_profit?: number;
|
|
risk_reward?: number;
|
|
reasoning: string[];
|
|
timestamp: string;
|
|
}
|
|
|
|
export interface ScanResult {
|
|
symbol: string;
|
|
signal: EnsembleSignal;
|
|
priority: number;
|
|
}
|
|
|
|
/**
|
|
* Get ICT/SMC Analysis for a symbol
|
|
*/
|
|
export async function getICTAnalysis(
|
|
symbol: string,
|
|
timeframe: string = '1H'
|
|
): Promise<ICTAnalysis | null> {
|
|
try {
|
|
const response = await fetch(
|
|
`${ML_API_URL}/api/ict/${symbol}?timeframe=${timeframe}`,
|
|
{ method: 'POST' }
|
|
);
|
|
if (!response.ok) {
|
|
if (response.status === 404) return null;
|
|
throw new Error(`API error: ${response.status}`);
|
|
}
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error('Error fetching ICT analysis:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get Ensemble Signal for a symbol
|
|
*/
|
|
export async function getEnsembleSignal(
|
|
symbol: string,
|
|
timeframe: string = '1H'
|
|
): Promise<EnsembleSignal | null> {
|
|
try {
|
|
const response = await fetch(
|
|
`${ML_API_URL}/api/ensemble/${symbol}?timeframe=${timeframe}`,
|
|
{ method: 'POST' }
|
|
);
|
|
if (!response.ok) {
|
|
if (response.status === 404) return null;
|
|
throw new Error(`API error: ${response.status}`);
|
|
}
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error('Error fetching ensemble signal:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get Quick Signal (fast, cached)
|
|
*/
|
|
export async function getQuickSignal(symbol: string): Promise<{
|
|
symbol: string;
|
|
action: string;
|
|
confidence: number;
|
|
score: number;
|
|
} | null> {
|
|
try {
|
|
const response = await fetch(`${ML_API_URL}/api/ensemble/quick/${symbol}`);
|
|
if (!response.ok) {
|
|
if (response.status === 404) return null;
|
|
throw new Error(`API error: ${response.status}`);
|
|
}
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error('Error fetching quick signal:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Scan multiple symbols for trading opportunities
|
|
*/
|
|
export async function scanSymbols(
|
|
symbols: string[],
|
|
minConfidence: number = 0.6
|
|
): Promise<ScanResult[]> {
|
|
try {
|
|
const response = await fetch(`${ML_API_URL}/api/scan`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
symbols,
|
|
min_confidence: minConfidence,
|
|
timeframe: '1H',
|
|
}),
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`API error: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
return data.results || [];
|
|
} catch (error) {
|
|
console.error('Error scanning symbols:', error);
|
|
return [];
|
|
}
|
|
}
|