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