mql5/Shared Projects/ERMT-ML/Modules-ML8x/EntrySystem_v71.mqh

891 lines
29 KiB
MQL5
Raw Permalink Normal View History

Module Integration Summary for External Trade Management Overview To fully integrate the enhanced external trade management system, updates are required to 5 out of 7 existing modules. The updates maintain backward compatibility while adding new functionality for external trade handling. Module Update Requirements 🟢 No Updates Required (2 modules) TechnicalAnalysis.mqh - Already provides necessary calculations EntrySystem.mqh - Only handles EA's own entry signals 🟡 Minor Updates (2 modules) DataTypes.mqh - Add external trade structures and fields Utilities.mqh - Enhanced logging for external trades 🟠 Moderate Updates (3 modules) RiskManager.mqh - Enhanced risk enforcement methods TradeManager.mqh - Improved stop management for externals Dashboard.mqh - Display external trade information Integration Steps Phase 1: Data Structures (DataTypes.mqh) Add ENUM_EXTERNAL_STATUS enumeration Extend ManagedTrade structure with external-specific fields Add ExternalTradeStats structure for metrics Update DashboardConfig with show_external flag Key additions: external_status - Track state of external trade source_name - Identify where trade came from stops_modified - Track if we modified the trade original_sl/tp - Store original values for comparison Phase 2: Risk Management (RiskManager.mqh) Add EnforceRiskRulesEnhanced() method Implement GetExternalExposure() for risk aggregation Add UpdateExternalStats() for tracking Enhance ValidateAndAdjustRiskExternal() method Key features: Separate risk calculation for external trades Cache mechanism for performance Statistical tracking of external positions Smart risk adjustment without closing trades Phase 3: Trade Management (TradeManager.mqh) Add ApplyDefaultStopsEnhanced() with better logic Implement OverrideExternalStops() with smart override Create ManageExternalTrade() with different rules Add ApplyBreakevenExternal() with wider triggers Key features: Smart stop override (only improve, never worsen) Different management rules for external trades Respect minimum broker distances Track modification success/failure rates Phase 4: User Interface (Dashboard.mqh) Add CreateExternalSection() for display area Implement UpdateExternalSection() for real-time updates Add SetCustomText() for flexible display Create ShowExternalTrades() toggle method Key features: Real-time external trade count and risk Color-coded risk warnings List of active external positions Modification statistics display Phase 5: Logging (Utilities.mqh) Add LogExternalTrade() for detailed event logging Create separate CSV log for external trades Enhance GenerateReportEnhanced() with external section Add IdentifyTradeSource() for magic number interpretation Key features: Separate CSV log for external trade events Detailed tracking of all modifications Source identification from magic numbers Enhanced reporting with external statistics
2025-08-27 14:21:02 +01:00
//+------------------------------------------------------------------+
//| EntrySystem_v71.mqh |
//| ML-Enhanced Entry System Module v7.1 |
//| Machine Learning & Order Flow Integration |
//+------------------------------------------------------------------+
#ifndef ENTRY_SYSTEM_V71_MQH
#define ENTRY_SYSTEM_V71_MQH
#include "DataTypes_v71.mqh"
#include <Indicators/Indicators.mqh>
//+------------------------------------------------------------------+
//| Entry System Class - ML & Order Flow Enhanced |
//+------------------------------------------------------------------+
class CEntrySystemV71
{
private:
//--- Configuration
EntrySystemConfigV71 m_config;
//--- Technical indicators
int m_ma_fast_handle;
int m_ma_slow_handle;
int m_rsi_handle;
int m_bb_handle;
int m_atr_handle;
int m_macd_handle;
int m_adx_handle;
int m_stoch_handle;
//--- ML prediction cache
struct MLCache
{
string symbol;
ENUM_ORDER_TYPE predicted_direction;
double confidence;
double feature_importance[10];
datetime cache_time;
};
MLCache m_ml_cache[50];
int m_cache_size;
//--- Order flow cache
struct FlowCache
{
string symbol;
double bid_volume;
double ask_volume;
double imbalance;
double large_order_ratio;
datetime update_time;
};
FlowCache m_flow_cache[50];
//--- Signal generation methods
EntrySignalV71 CheckMACrossSignal(string symbol);
EntrySignalV71 CheckMAPullbackSignal(string symbol);
EntrySignalV71 CheckMomentumSignal(string symbol);
EntrySignalV71 CheckContrarianSignal(string symbol);
EntrySignalV71 CheckBreakoutSignal(string symbol);
EntrySignalV71 CheckMultiStrategySignal(string symbol);
EntrySignalV71 CheckMLEnhancedSignal(string symbol);
EntrySignalV71 CheckOrderFlowSignal(string symbol);
EntrySignalV71 CheckMultiFactorSignal(string symbol);
//--- ML feature extraction
void ExtractFeatures(string symbol, double &features[]);
double CalculateFeatureImportance(double &features[], int index);
//--- Helper methods
bool IsValidSignal(EntrySignalV71 &signal);
void EnhanceSignalWithML(EntrySignalV71 &signal);
void EnhanceSignalWithFlow(EntrySignalV71 &signal);
double CalculateSignalStrength(EntrySignalV71 &signal);
void SetStopLossTarget(EntrySignalV71 &signal, double atr);
public:
CEntrySystemV71();
~CEntrySystemV71();
//--- Initialization
bool Initialize(const EntrySystemConfigV71 &config);
void Deinitialize();
//--- Main signal generation
EntrySignalV71 CheckSignal(string symbol);
EntrySignalV71 CheckSignalEnhanced(string symbol, MarketConditionsV71 &conditions);
//--- ML integration
void UpdateMLPrediction(string symbol, MLPrediction &prediction);
double GetMLConfidence(string symbol);
//--- Order flow integration
void UpdateOrderFlow(string symbol, OrderFlowData &flow_data);
double GetFlowImbalance(string symbol);
//--- Signal validation
bool ValidateSignal(EntrySignalV71 &signal, MarketConditionsV71 &conditions);
double GetMinSignalStrength() { return 0.6; }
//--- Multi-timeframe analysis
EntrySignalV71 CheckMTFSignal(string symbol, ENUM_TIMEFRAMES timeframes[], int count);
//--- Signal filtering
bool PassesFilters(string symbol, ENUM_ORDER_TYPE direction);
bool CheckNewsFilter(string symbol);
bool CheckVolatilityFilter(string symbol);
bool CheckCorrelationFilter(string symbol);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CEntrySystemV71::CEntrySystemV71()
{
m_ma_fast_handle = INVALID_HANDLE;
m_ma_slow_handle = INVALID_HANDLE;
m_rsi_handle = INVALID_HANDLE;
m_bb_handle = INVALID_HANDLE;
m_atr_handle = INVALID_HANDLE;
m_macd_handle = INVALID_HANDLE;
m_adx_handle = INVALID_HANDLE;
m_stoch_handle = INVALID_HANDLE;
m_cache_size = 0;
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CEntrySystemV71::~CEntrySystemV71()
{
Deinitialize();
}
//+------------------------------------------------------------------+
//| Initialize entry system |
//+------------------------------------------------------------------+
bool CEntrySystemV71::Initialize(const EntrySystemConfigV71 &config)
{
m_config = config;
//--- Initialize technical indicators
m_ma_fast_handle = iMA(_Symbol, PERIOD_CURRENT, m_config.ma_fast, 0, MODE_EMA, PRICE_CLOSE);
m_ma_slow_handle = iMA(_Symbol, PERIOD_CURRENT, m_config.ma_slow, 0, MODE_EMA, PRICE_CLOSE);
m_rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, m_config.rsi_period, PRICE_CLOSE);
m_bb_handle = iBands(_Symbol, PERIOD_CURRENT, m_config.bb_period, 0, m_config.bb_deviation, PRICE_CLOSE);
m_atr_handle = iATR(_Symbol, PERIOD_CURRENT, m_config.atr_period);
m_macd_handle = iMACD(_Symbol, PERIOD_CURRENT, 12, 26, 9, PRICE_CLOSE);
m_adx_handle = iADX(_Symbol, PERIOD_CURRENT, 14);
m_stoch_handle = iStochastic(_Symbol, PERIOD_CURRENT, 14, 3, 3, MODE_SMA, STO_LOWHIGH);
//--- Check handles
if(m_ma_fast_handle == INVALID_HANDLE || m_ma_slow_handle == INVALID_HANDLE ||
m_rsi_handle == INVALID_HANDLE || m_bb_handle == INVALID_HANDLE ||
m_atr_handle == INVALID_HANDLE)
{
Print("Failed to initialize entry system indicators");
return false;
}
Print("EntrySystemV71 initialized with mode: ", EnumToString(m_config.mode));
return true;
}
//+------------------------------------------------------------------+
//| Check signal with enhanced logic |
//+------------------------------------------------------------------+
EntrySignalV71 CEntrySystemV71::CheckSignalEnhanced(string symbol, MarketConditionsV71 &conditions)
{
EntrySignalV71 signal;
signal.valid = false;
signal.symbol = symbol;
signal.signal_time = TimeCurrent();
//--- Route to appropriate strategy
switch(m_config.mode)
{
case ENTRY_DISABLED:
return signal;
case ENTRY_MA_CROSS:
signal = CheckMACrossSignal(symbol);
break;
case ENTRY_MA_PULLBACK:
signal = CheckMAPullbackSignal(symbol);
break;
case ENTRY_MOMENTUM:
signal = CheckMomentumSignal(symbol);
break;
case ENTRY_CONTRARIAN:
signal = CheckContrarianSignal(symbol);
break;
case ENTRY_BREAKOUT:
signal = CheckBreakoutSignal(symbol);
break;
case ENTRY_MULTI_STRATEGY:
signal = CheckMultiStrategySignal(symbol);
break;
case ENTRY_ML_ENHANCED:
signal = CheckMLEnhancedSignal(symbol);
break;
case ENTRY_ORDER_FLOW:
signal = CheckOrderFlowSignal(symbol);
break;
case ENTRY_MULTI_FACTOR:
signal = CheckMultiFactorSignal(symbol);
break;
}
//--- Enhance with ML if enabled
if(m_config.use_ml && signal.valid)
{
EnhanceSignalWithML(signal);
}
//--- Enhance with order flow if enabled
if(m_config.use_order_flow && signal.valid)
{
EnhanceSignalWithFlow(signal);
}
//--- Validate against market conditions
if(signal.valid)
{
signal.valid = ValidateSignal(signal, conditions);
}
//--- Calculate final signal strength
if(signal.valid)
{
signal.strength = CalculateSignalStrength(signal);
}
return signal;
}
//+------------------------------------------------------------------+
//| Check ML-enhanced signal |
//+------------------------------------------------------------------+
EntrySignalV71 CEntrySystemV71::CheckMLEnhancedSignal(string symbol)
{
EntrySignalV71 signal;
signal.valid = false;
signal.symbol = symbol;
//--- Extract features for ML
double features[20];
ExtractFeatures(symbol, features);
//--- Get ML prediction from cache
int cache_index = -1;
for(int i = 0; i < m_cache_size; i++)
{
if(m_ml_cache[i].symbol == symbol &&
TimeCurrent() - m_ml_cache[i].cache_time < 60) // 1-minute cache
{
cache_index = i;
break;
}
}
if(cache_index >= 0 && m_ml_cache[cache_index].confidence >= m_config.ml_threshold)
{
signal.valid = true;
signal.direction = m_ml_cache[cache_index].predicted_direction;
signal.ml_confidence = m_ml_cache[cache_index].confidence;
signal.ml_enhanced = true;
//--- Set base strength from ML confidence
signal.strength = m_ml_cache[cache_index].confidence;
//--- Get ATR for stops
double atr_buffer[1];
if(CopyBuffer(m_atr_handle, 0, 0, 1, atr_buffer) > 0)
{
SetStopLossTarget(signal, atr_buffer[0]);
}
//--- Set primary indicator
signal.primary_indicator = "ML_Prediction";
//--- Calculate expected return and win probability
signal.expected_return = 2.5; // Default 2.5R target
signal.win_probability = m_ml_cache[cache_index].confidence;
//--- Add feature importance to comment
string important_features = "Features: ";
for(int i = 0; i < 3; i++) // Top 3 features
{
if(m_ml_cache[cache_index].feature_importance[i] > 0.1)
{
important_features += StringFormat("F%d(%.2f) ", i,
m_ml_cache[cache_index].feature_importance[i]);
}
}
signal.comment = "ML: " + important_features;
}
return signal;
}
//+------------------------------------------------------------------+
//| Check order flow signal |
//+------------------------------------------------------------------+
EntrySignalV71 CEntrySystemV71::CheckOrderFlowSignal(string symbol)
{
EntrySignalV71 signal;
signal.valid = false;
signal.symbol = symbol;
//--- Get order flow data from cache
int cache_index = -1;
for(int i = 0; i < ArraySize(m_flow_cache); i++)
{
if(m_flow_cache[i].symbol == symbol &&
TimeCurrent() - m_flow_cache[i].update_time < 5) // 5-second cache
{
cache_index = i;
break;
}
}
if(cache_index >= 0)
{
FlowCache &flow = m_flow_cache[cache_index];
//--- Check for significant imbalance
if(MathAbs(flow.imbalance) >= m_config.flow_threshold)
{
signal.valid = true;
signal.direction = (flow.imbalance > 0) ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
signal.order_flow_score = MathAbs(flow.imbalance);
//--- Check for large order activity
if(flow.large_order_ratio > 0.3) // 30% large orders
{
signal.strength = 0.8;
signal.comment = "Institutional flow detected";
}
else
{
signal.strength = 0.6;
signal.comment = "Order flow imbalance";
}
//--- Set stops based on liquidity
double atr_buffer[1];
if(CopyBuffer(m_atr_handle, 0, 0, 1, atr_buffer) > 0)
{
//--- Tighter stops if high liquidity
double multiplier = (flow.bid_volume + flow.ask_volume > 1000000) ? 1.5 : 2.0;
SetStopLossTarget(signal, atr_buffer[0] * multiplier);
}
signal.primary_indicator = "OrderFlow";
signal.liquidity_score = (flow.bid_volume + flow.ask_volume) / 1000000.0;
}
}
return signal;
}
//+------------------------------------------------------------------+
//| Check multi-factor signal |
//+------------------------------------------------------------------+
EntrySignalV71 CEntrySystemV71::CheckMultiFactorSignal(string symbol)
{
EntrySignalV71 signal;
signal.valid = false;
signal.symbol = symbol;
//--- Get signals from different systems
EntrySignalV71 ta_signal = CheckMomentumSignal(symbol);
EntrySignalV71 ml_signal = CheckMLEnhancedSignal(symbol);
EntrySignalV71 flow_signal = CheckOrderFlowSignal(symbol);
//--- Count valid signals
int valid_count = 0;
double total_strength = 0;
ENUM_ORDER_TYPE consensus_direction = ORDER_TYPE_BUY;
//--- Technical analysis factor
if(ta_signal.valid)
{
valid_count++;
total_strength += ta_signal.strength * m_config.factor_weight_ta;
consensus_direction = ta_signal.direction;
}
//--- ML factor
if(ml_signal.valid && ml_signal.ml_confidence >= m_config.ml_threshold)
{
valid_count++;
total_strength += ml_signal.strength * m_config.factor_weight_ml;
//--- ML has higher weight in direction decision
if(m_config.factor_weight_ml > m_config.factor_weight_ta)
consensus_direction = ml_signal.direction;
}
//--- Order flow factor
if(flow_signal.valid)
{
valid_count++;
total_strength += flow_signal.strength * m_config.factor_weight_flow;
//--- Flow confirms direction
if(flow_signal.direction != consensus_direction)
total_strength *= 0.7; // Reduce strength on disagreement
}
//--- Need at least 2 factors to agree
if(valid_count >= 2 && total_strength >= 0.6)
{
signal.valid = true;
signal.direction = consensus_direction;
signal.strength = total_strength / (m_config.factor_weight_ta +
m_config.factor_weight_ml +
m_config.factor_weight_flow);
//--- Combine features
signal.ml_enhanced = ml_signal.valid;
signal.ml_confidence = ml_signal.ml_confidence;
signal.order_flow_score = flow_signal.order_flow_score;
signal.liquidity_score = flow_signal.liquidity_score;
//--- Set stops (use most conservative)
double atr_buffer[1];
if(CopyBuffer(m_atr_handle, 0, 0, 1, atr_buffer) > 0)
{
SetStopLossTarget(signal, atr_buffer[0] * 2.5);
}
signal.primary_indicator = "MultiFactorConsensus";
signal.comment = StringFormat("Factors: %d/3, Strength: %.2f", valid_count, signal.strength);
}
return signal;
}
//+------------------------------------------------------------------+
//| Extract features for ML |
//+------------------------------------------------------------------+
void CEntrySystemV71::ExtractFeatures(string symbol, double &features[])
{
ArrayResize(features, 20);
ArrayInitialize(features, 0);
//--- Price features
double close = iClose(symbol, PERIOD_CURRENT, 0);
double open = iOpen(symbol, PERIOD_CURRENT, 0);
double high = iHigh(symbol, PERIOD_CURRENT, 0);
double low = iLow(symbol, PERIOD_CURRENT, 0);
features[0] = (close - open) / open * 100; // Return
features[1] = (high - low) / low * 100; // Range
features[2] = (close - low) / (high - low); // Position in range
//--- Technical indicators
double ma_fast[1], ma_slow[1], rsi[1], atr[1];
double bb_upper[1], bb_lower[1], bb_middle[1];
double macd_main[1], macd_signal[1];
double adx[1], stoch_main[1], stoch_signal[1];
if(CopyBuffer(m_ma_fast_handle, 0, 0, 1, ma_fast) > 0 &&
CopyBuffer(m_ma_slow_handle, 0, 0, 1, ma_slow) > 0)
{
features[3] = (ma_fast[0] - ma_slow[0]) / ma_slow[0] * 100;
features[4] = (close - ma_fast[0]) / ma_fast[0] * 100;
}
if(CopyBuffer(m_rsi_handle, 0, 0, 1, rsi) > 0)
{
features[5] = rsi[0] / 100.0;
features[6] = (rsi[0] > 70) ? 1 : (rsi[0] < 30) ? -1 : 0;
}
if(CopyBuffer(m_bb_handle, 0, 0, 1, bb_upper) > 0 &&
CopyBuffer(m_bb_handle, 1, 0, 1, bb_middle) > 0 &&
CopyBuffer(m_bb_handle, 2, 0, 1, bb_lower) > 0)
{
features[7] = (close - bb_middle[0]) / (bb_upper[0] - bb_middle[0]);
features[8] = (bb_upper[0] - bb_lower[0]) / bb_middle[0] * 100;
}
if(CopyBuffer(m_atr_handle, 0, 0, 1, atr) > 0)
{
features[9] = atr[0] / close * 100;
}
if(CopyBuffer(m_macd_handle, 0, 0, 1, macd_main) > 0 &&
CopyBuffer(m_macd_handle, 1, 0, 1, macd_signal) > 0)
{
features[10] = macd_main[0] - macd_signal[0];
features[11] = (macd_main[0] > 0) ? 1 : -1;
}
if(CopyBuffer(m_adx_handle, 0, 0, 1, adx) > 0)
{
features[12] = adx[0] / 100.0;
}
if(CopyBuffer(m_stoch_handle, 0, 0, 1, stoch_main) > 0 &&
CopyBuffer(m_stoch_handle, 1, 0, 1, stoch_signal) > 0)
{
features[13] = stoch_main[0] / 100.0;
features[14] = (stoch_main[0] - stoch_signal[0]) / 100.0;
}
//--- Market microstructure features
long spread = SymbolInfoInteger(symbol, SYMBOL_SPREAD);
long volume = iVolume(symbol, PERIOD_CURRENT, 0);
features[15] = spread / 10.0; // Normalized spread
features[16] = MathLog(volume + 1); // Log volume
//--- Time features
MqlDateTime time;
TimeToStruct(TimeCurrent(), time);
features[17] = time.hour / 24.0;
features[18] = time.day_of_week / 7.0;
features[19] = time.day / 31.0;
}
//+------------------------------------------------------------------+
//| Enhance signal with ML predictions |
//+------------------------------------------------------------------+
void CEntrySystemV71::EnhanceSignalWithML(EntrySignalV71 &signal)
{
//--- Find ML prediction for symbol
for(int i = 0; i < m_cache_size; i++)
{
if(m_ml_cache[i].symbol == signal.symbol &&
TimeCurrent() - m_ml_cache[i].cache_time < 60)
{
//--- Adjust signal strength based on ML confidence
if(m_ml_cache[i].predicted_direction == signal.direction)
{
//--- ML confirms direction
signal.strength *= (1.0 + m_ml_cache[i].confidence * 0.5);
signal.ml_confidence = m_ml_cache[i].confidence;
signal.ml_enhanced = true;
//--- Adjust targets based on ML
if(m_ml_cache[i].confidence > 0.8)
{
signal.expected_return *= 1.2; // Increase target
}
}
else if(m_ml_cache[i].confidence > 0.7)
{
//--- ML disagrees with high confidence
signal.strength *= 0.5;
signal.comment += " (ML disagrees)";
}
break;
}
}
}
//+------------------------------------------------------------------+
//| Enhance signal with order flow |
//+------------------------------------------------------------------+
void CEntrySystemV71::EnhanceSignalWithFlow(EntrySignalV71 &signal)
{
//--- Find flow data for symbol
for(int i = 0; i < ArraySize(m_flow_cache); i++)
{
if(m_flow_cache[i].symbol == signal.symbol &&
TimeCurrent() - m_flow_cache[i].update_time < 5)
{
//--- Check if flow confirms direction
bool flow_confirms = (signal.direction == ORDER_TYPE_BUY && m_flow_cache[i].imbalance > 0) ||
(signal.direction == ORDER_TYPE_SELL && m_flow_cache[i].imbalance < 0);
if(flow_confirms)
{
signal.strength *= (1.0 + MathAbs(m_flow_cache[i].imbalance) * 0.3);
signal.order_flow_score = MathAbs(m_flow_cache[i].imbalance);
//--- Check for institutional activity
if(m_flow_cache[i].large_order_ratio > 0.3)
{
signal.strength *= 1.2;
signal.comment += " (Institutional)";
signal.execution_urgency = 0.8; // High urgency
}
}
else if(MathAbs(m_flow_cache[i].imbalance) > 0.5)
{
//--- Strong flow against signal
signal.strength *= 0.6;
signal.comment += " (Flow conflict)";
}
//--- Set liquidity score
signal.liquidity_score = (m_flow_cache[i].bid_volume + m_flow_cache[i].ask_volume) / 1000000.0;
break;
}
}
}
//+------------------------------------------------------------------+
//| Set stop loss and take profit based on ATR |
//+------------------------------------------------------------------+
void CEntrySystemV71::SetStopLossTarget(EntrySignalV71 &signal, double atr)
{
double current_price = (signal.direction == ORDER_TYPE_BUY) ?
SymbolInfoDouble(signal.symbol, SYMBOL_ASK) :
SymbolInfoDouble(signal.symbol, SYMBOL_BID);
signal.entry_price = current_price;
//--- Calculate stop loss
double stop_distance = atr * 2.0; // Default 2 ATR
//--- Adjust based on signal strength
if(signal.strength > 0.8)
stop_distance = atr * 1.5; // Tighter stop for strong signals
else if(signal.strength < 0.6)
stop_distance = atr * 2.5; // Wider stop for weak signals
//--- Set levels
if(signal.direction == ORDER_TYPE_BUY)
{
signal.stop_loss = current_price - stop_distance;
signal.take_profit = current_price + stop_distance * 3.0; // 3:1 RR
}
else
{
signal.stop_loss = current_price + stop_distance;
signal.take_profit = current_price - stop_distance * 3.0;
}
//--- Calculate risk-reward ratio
signal.risk_reward_ratio = 3.0;
//--- Adjust TP based on ML confidence
if(signal.ml_enhanced && signal.ml_confidence > 0.8)
{
signal.risk_reward_ratio = 4.0;
signal.take_profit = (signal.direction == ORDER_TYPE_BUY) ?
current_price + stop_distance * 4.0 :
current_price - stop_distance * 4.0;
}
}
//+------------------------------------------------------------------+
//| Update ML prediction cache |
//+------------------------------------------------------------------+
void CEntrySystemV71::UpdateMLPrediction(string symbol, MLPrediction &prediction)
{
//--- Find or create cache entry
int index = -1;
for(int i = 0; i < m_cache_size; i++)
{
if(m_ml_cache[i].symbol == symbol)
{
index = i;
break;
}
}
if(index < 0 && m_cache_size < 50)
{
index = m_cache_size;
m_cache_size++;
}
else if(index < 0)
{
//--- Replace oldest entry
index = 0;
datetime oldest = TimeCurrent();
for(int i = 0; i < m_cache_size; i++)
{
if(m_ml_cache[i].cache_time < oldest)
{
oldest = m_ml_cache[i].cache_time;
index = i;
}
}
}
//--- Update cache
m_ml_cache[index].symbol = symbol;
m_ml_cache[index].predicted_direction = prediction.direction;
m_ml_cache[index].confidence = prediction.confidence;
m_ml_cache[index].cache_time = TimeCurrent();
//--- Calculate feature importance (simplified)
for(int i = 0; i < 10; i++)
{
m_ml_cache[index].feature_importance[i] = MathRand() / 32768.0; // Placeholder
}
}
//+------------------------------------------------------------------+
//| Update order flow cache |
//+------------------------------------------------------------------+
void CEntrySystemV71::UpdateOrderFlow(string symbol, OrderFlowData &flow_data)
{
//--- Find or create cache entry
int index = -1;
for(int i = 0; i < ArraySize(m_flow_cache); i++)
{
if(m_flow_cache[i].symbol == symbol)
{
index = i;
break;
}
}
if(index < 0)
{
//--- Find empty slot
for(int i = 0; i < ArraySize(m_flow_cache); i++)
{
if(m_flow_cache[i].symbol == "")
{
index = i;
break;
}
}
}
if(index >= 0)
{
m_flow_cache[index].symbol = symbol;
m_flow_cache[index].bid_volume = flow_data.bid_volume;
m_flow_cache[index].ask_volume = flow_data.ask_volume;
m_flow_cache[index].imbalance = flow_data.imbalance;
m_flow_cache[index].large_order_ratio = (flow_data.large_bid_count + flow_data.large_ask_count) /
MathMax(1, flow_data.bid_volume + flow_data.ask_volume);
m_flow_cache[index].update_time = TimeCurrent();
}
}
//+------------------------------------------------------------------+
//| Validate signal against market conditions |
//+------------------------------------------------------------------+
bool CEntrySystemV71::ValidateSignal(EntrySignalV71 &signal, MarketConditionsV71 &conditions)
{
//--- Check volatility
if(conditions.volatility < m_config.min_atr)
{
signal.comment += " (Low volatility)";
return false;
}
//--- Check regime alignment
if(conditions.regime == REGIME_RANGING && m_config.mode == ENTRY_MOMENTUM)
{
signal.comment += " (Wrong regime)";
return false;
}
//--- Check spread
if(conditions.bid_ask_spread > 5)
{
signal.comment += " (Wide spread)";
return false;
}
//--- Additional filters
if(!PassesFilters(signal.symbol, signal.direction))
{
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Calculate final signal strength |
//+------------------------------------------------------------------+
double CEntrySystemV71::CalculateSignalStrength(EntrySignalV71 &signal)
{
double strength = signal.strength;
//--- Boost for ML confirmation
if(signal.ml_enhanced && signal.ml_confidence > 0.7)
{
strength *= (1.0 + (signal.ml_confidence - 0.7));
}
//--- Boost for order flow confirmation
if(signal.order_flow_score > 0.5)
{
strength *= (1.0 + signal.order_flow_score * 0.2);
}
//--- Boost for high liquidity
if(signal.liquidity_score > 1.0)
{
strength *= 1.1;
}
//--- Cap at 1.0
return MathMin(1.0, strength);
}
//+------------------------------------------------------------------+
//| Check standard momentum signal |
//+------------------------------------------------------------------+
EntrySignalV71 CEntrySystemV71::CheckMomentumSignal(string symbol)
{
EntrySignalV71 signal;
signal.valid = false;
signal.symbol = symbol;
//--- Get indicator values
double rsi[1], adx[1], macd_main[1], macd_signal[1];
double ma_fast[1], ma_slow[1];
if(CopyBuffer(m_rsi_handle, 0, 0, 1, rsi) <= 0 ||
CopyBuffer(m_adx_handle, 0, 0, 1, adx) <= 0 ||
CopyBuffer(m_macd_handle, 0, 0, 1, macd_main) <= 0 ||
CopyBuffer(m_macd_handle, 1, 0, 1, macd_signal) <= 0 ||
CopyBuffer(m_ma_fast_handle, 0, 0, 1, ma_fast) <= 0 ||
CopyBuffer(m_ma_slow_handle, 0, 0, 1, ma_slow) <= 0)
{
return signal;
}
//--- Strong trend conditions
if(adx[0] > 25)
{
//--- Bullish momentum
if(ma_fast[0] > ma_slow[0] &&
macd_main[0] > macd_signal[0] &&
rsi[0] > 50 && rsi[0] < 70)
{
signal.valid = true;
signal.direction = ORDER_TYPE_BUY;
signal.strength = 0.7 + (adx[0] - 25) / 100.0;
signal.primary_indicator = "Momentum";
signal.comment = "Bullish momentum";
}
//--- Bearish momentum
else if(ma_fast[0] < ma_slow[0] &&
macd_main[0] < macd_signal[0] &&
rsi[0] < 50 && rsi[0] > 30)
{
signal.valid = true;
signal.direction = ORDER_TYPE_SELL;
signal.strength = 0.7 + (adx[0] - 25) / 100.0;
signal.primary_indicator = "Momentum";
signal.comment = "Bearish momentum";
}
}
//--- Set stops if valid
if(signal.valid)
{
double atr[1];
if(CopyBuffer(m_atr_handle, 0, 0, 1, atr) > 0)
{
SetStopLossTarget(signal, atr[0]);
}
}
return signal;
}
//+------------------------------------------------------------------+
//| Deinitialize indicators |
//+------------------------------------------------------------------+
void CEntrySystemV71::Deinitialize()
{
if(m_ma_fast_handle != INVALID_HANDLE) IndicatorRelease(m_ma_fast_handle);
if(m_ma_slow_handle != INVALID_HANDLE) IndicatorRelease(m_ma_slow_handle);
if(m_rsi_handle != INVALID_HANDLE) IndicatorRelease(m_rsi_handle);
if(m_bb_handle != INVALID_HANDLE) IndicatorRelease(m_bb_handle);
if(m_atr_handle != INVALID_HANDLE) IndicatorRelease(m_atr_handle);
if(m_macd_handle != INVALID_HANDLE) IndicatorRelease(m_macd_handle);
if(m_adx_handle != INVALID_HANDLE) IndicatorRelease(m_adx_handle);
if(m_stoch_handle != INVALID_HANDLE) IndicatorRelease(m_stoch_handle);
}
#endif // ENTRY_SYSTEM_V71_MQH