mql5/Shared Projects/ERMT-ML/Modules-ML8x/EntrySystem_v71.mqh
darashikoh 0fb1bd1b0a 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

891 lines
No EOL
29 KiB
MQL5

//+------------------------------------------------------------------+
//| 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