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
891 lines
No EOL
29 KiB
MQL5
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 |