New EA and Indi

This commit is contained in:
Kunthawat Greethong
2026-01-25 10:34:54 +07:00
parent 39ce46877e
commit 04aa2eb2e6
37 changed files with 17051 additions and 0 deletions

View File

@@ -0,0 +1,665 @@
//+------------------------------------------------------------------+
//| Universal_Buffer_Reader_EA.mq5 |
//| Universal Buffer Reader EA v2.0 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025"
#property link ""
#property version "2.0"
#property strict
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include "Include\SignalDetector.mqh"
#include "Include\TimeFilter.mqh"
#include "Include\MoneyManager.mqh"
#include "Include\RiskManager.mqh"
#include "Include\PartialCloseManager.mqh"
#include "Include\TradeExecutor.mqh"
#include "Include\StateManager.mqh"
#include "Include\LoggingManager.mqh"
#include "Include\UIManager.mqh"
//+------------------------------------------------------------------+
//| Trade Mode Enum |
//+------------------------------------------------------------------+
enum ENUM_TRADE_MODE
{
MODE_INDICATOR,
MODE_MANUAL
};
//+------------------------------------------------------------------+
//| Input Parameters |
//+------------------------------------------------------------------+
// --- General Settings ---
input string General_Settings = "--- General Settings ---";
input ENUM_TRADE_MODE Trade_Mode = MODE_INDICATOR;
input double LotSize = 0.03;
input int Slippage = 3;
input int MagicNumber = 24680;
input bool TakeScreenshotOnOpen = true;
input bool EnableDebugPrints = true;
input bool ExitOnOppositeSignal = false;
// --- Money Management Settings ---
input string Money_Management_Settings = "--- Money Management Settings ---";
input bool UsePercentBalanceLot = true;
input double PercentOfBalanceForProfit = 1.0;
input double DailyProfitTargetPercent = 2.0;
// --- Time Filtering Settings ---
input string Time_Filter_Settings = "--- Time Filtering Settings ---";
input bool EnableTimeFiltering = false;
input string Day_Filter_Header = "--- Day of Week Filter ---";
input bool TradeMondayEnabled = true;
input bool TradeTuesdayEnabled = true;
input bool TradeWednesdayEnabled = true;
input bool TradeThursdayEnabled = true;
input bool TradeFridayEnabled = true;
input bool TradeSaturdayEnabled = false;
input bool TradeSundayEnabled = false;
input string Session_Filter_Header = "--- Trading Session Filter ---";
input bool TradeAsianSessionEnabled = true;
input bool TradeEuropeSessionEnabled = true;
input bool TradeAmericaSessionEnabled = true;
// --- Risk Management Settings ---
input string Risk_Management_Settings = "--- Risk Management Settings ---";
input bool UseBreakeven = true;
input int BreakevenPips = 30;
input bool UseTrailingStop = false;
input int TrailingStopPips = 300;
input int MinimumTakeProfitPips = 300;
// --- Indicator Settings ---
input string Indicator_Settings = "--- Indicator Settings ---";
input string IndicatorFileName = "My_Indicator";
input int BuySignalBuffer = 0;
input int SellSignalBuffer = 1;
// --- SL/TP Mode Settings ---
input string SLTP_Settings = "--- SL/TP Mode Settings ---";
input int SLTP_Mode = 0; // 0=ATR, 1=Indicator
// --- ATR Settings (Mode 0) ---
input string ATR_Settings = "--- (Mode 0) ATR Settings ---";
input int AtrPeriod = 14;
input double StopLossAtrMultiplier = 1.5;
input double TakeProfitAtrMultiplier = 3.0;
// --- Indicator SL/TP Buffers (Mode 1) ---
input string Indicator_SLTP_Settings = "--- (Mode 1) Indicator SL/TP ---";
input int BuyStopLossBuffer = 2;
input int BuyTP1Buffer = 3;
input int BuyTP2Buffer = 4;
input int BuyTP3Buffer = 5;
input int SellStopLossBuffer = 6;
input int SellTP1Buffer = 7;
input int SellTP2Buffer = 8;
input int SellTP3Buffer = 9;
// --- Partial Close Settings ---
input string Partial_Close_Settings = "--- Partial Close Settings ---";
input bool EnablePartialClose = true;
input bool UseEqualDivision = true;
input double TP1_ClosePercent = 50.0;
input double TP2_ClosePercent = 30.0;
input double TP3_ClosePercent = 20.0;
//+------------------------------------------------------------------+
//| Global Variables |
//+------------------------------------------------------------------+
// Component instances
CSignalDetector *g_signal_detector;
CTimeFilter *g_time_filter;
CMoneyManager *g_money_manager;
CRiskManager *g_risk_manager;
CPartialCloseManager *g_partial_close_manager;
CTradeExecutor *g_trade_executor;
CStateManager *g_state_manager;
CLoggingManager *g_logging_manager;
CUIManager *g_ui_manager;
// Symbol info
string g_symbol;
int g_digits;
double g_point_value;
double g_pip_value;
double m_tick_value;
double m_stop_level_points;
// Lot info
double g_min_lot;
double g_max_lot;
double g_lot_step;
// Time tracking
datetime g_last_bar_time;
datetime g_last_daily_reset_time;
// State
double g_accumulated_loss;
int g_consecutive_losses;
double g_daily_profit_accumulated;
double g_daily_start_balance;
// Chart
long g_chart_id;
// Manual mode
bool g_manual_trade_button_pressed;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Initialize logging first
g_logging_manager = new CLoggingManager();
g_logging_manager.SetParameters(EnableDebugPrints);
g_logging_manager.LogInfo("========== EA Initializing ==========");
// Get symbol info
g_symbol = _Symbol;
g_digits = (int)SymbolInfoInteger(g_symbol, SYMBOL_DIGITS);
g_point_value = SymbolInfoDouble(g_symbol, SYMBOL_POINT);
g_pip_value = (g_digits == 3 || g_digits == 5) ? g_point_value * 10 : g_point_value;
m_tick_value = SymbolInfoDouble(g_symbol, SYMBOL_TRADE_TICK_VALUE);
m_stop_level_points = (double)SymbolInfoInteger(g_symbol, SYMBOL_TRADE_STOPS_LEVEL);
// Get lot info
g_min_lot = SymbolInfoDouble(g_symbol, SYMBOL_VOLUME_MIN);
g_max_lot = SymbolInfoDouble(g_symbol, SYMBOL_VOLUME_MAX);
g_lot_step = SymbolInfoDouble(g_symbol, SYMBOL_VOLUME_STEP);
g_chart_id = ChartID();
// Initialize state manager
g_state_manager = new CStateManager();
g_state_manager.SetParameters(g_symbol, MagicNumber, EnableDebugPrints);
g_state_manager.LoadState(g_accumulated_loss, g_consecutive_losses);
// Initialize time filter
g_time_filter = new CTimeFilter();
g_time_filter.SetParameters(
EnableTimeFiltering,
TradeMondayEnabled, TradeTuesdayEnabled, TradeWednesdayEnabled,
TradeThursdayEnabled, TradeFridayEnabled, TradeSaturdayEnabled, TradeSundayEnabled,
TradeAsianSessionEnabled, TradeEuropeSessionEnabled, TradeAmericaSessionEnabled,
EnableDebugPrints
);
// Initialize money manager
g_money_manager = new CMoneyManager();
g_money_manager.SetParameters(
LotSize,
UsePercentBalanceLot, PercentOfBalanceForProfit,
DailyProfitTargetPercent,
g_min_lot, g_max_lot, g_lot_step,
g_point_value, m_tick_value,
EnableDebugPrints
);
// Initialize signal detector
g_signal_detector = new CSignalDetector();
g_signal_detector.SetParameters(
IndicatorFileName,
BuySignalBuffer, SellSignalBuffer,
BuyStopLossBuffer, SellStopLossBuffer,
SLTP_Mode, AtrPeriod,
StopLossAtrMultiplier, TakeProfitAtrMultiplier,
MinimumTakeProfitPips, g_pip_value, g_digits,
g_symbol,
EnableDebugPrints
);
// Set TP buffers
int buy_tp_buffers[] = {BuyTP1Buffer, BuyTP2Buffer, BuyTP3Buffer};
int sell_tp_buffers[] = {SellTP1Buffer, SellTP2Buffer, SellTP3Buffer};
g_signal_detector.SetBuyTPBuffers(buy_tp_buffers);
g_signal_detector.SetSellTPBuffers(sell_tp_buffers);
if(!g_signal_detector.Initialize())
{
g_logging_manager.LogError(GetLastError(), "OnInit - SignalDetector initialization");
return INIT_FAILED;
}
// Initialize risk manager
g_risk_manager = new CRiskManager();
g_risk_manager.SetParameters(
UseTrailingStop,
TrailingStopPips,
UseBreakeven,
BreakevenPips,
g_pip_value,
g_digits,
m_stop_level_points,
MagicNumber,
g_symbol,
EnableDebugPrints
);
g_risk_manager.EnablePartialClose(EnablePartialClose);
// Initialize partial close manager
g_partial_close_manager = new CPartialCloseManager();
double partial_close_percentages[] = {TP1_ClosePercent, TP2_ClosePercent, TP3_ClosePercent};
g_partial_close_manager.SetParameters(
EnablePartialClose,
UseEqualDivision,
partial_close_percentages,
MagicNumber,
g_symbol,
EnableDebugPrints
);
// Initialize trade executor
g_trade_executor = new CTradeExecutor();
g_trade_executor.SetParameters(
Slippage,
MagicNumber,
g_symbol,
g_digits,
TakeScreenshotOnOpen,
g_chart_id,
IndicatorFileName,
EnableDebugPrints
);
// Initialize UI manager
g_ui_manager = new CUIManager();
g_ui_manager.SetParameters(
g_chart_id,
(Trade_Mode == MODE_MANUAL),
MagicNumber,
g_symbol,
0, // High loss threshold (not used in v2.0)
EnableDebugPrints
);
g_ui_manager.CreateUI();
// Initialize time tracking
g_last_bar_time = 0;
g_last_daily_reset_time = 0;
g_manual_trade_button_pressed = false;
// Reset daily profit if needed
ResetDailyProfitIfNeeded();
g_logging_manager.LogInfo("========== EA Initialized Successfully ==========");
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
g_logging_manager.LogInfo("========== EA Deinitializing ==========");
// Save state
if(g_state_manager != NULL)
{
g_state_manager.SaveState(g_accumulated_loss, g_consecutive_losses);
}
// Delete UI
if(g_ui_manager != NULL)
{
g_ui_manager.DeleteUI();
}
// Delete components
if(g_signal_detector != NULL)
{
delete g_signal_detector;
g_signal_detector = NULL;
}
if(g_time_filter != NULL)
{
delete g_time_filter;
g_time_filter = NULL;
}
if(g_money_manager != NULL)
{
delete g_money_manager;
g_money_manager = NULL;
}
if(g_risk_manager != NULL)
{
delete g_risk_manager;
g_risk_manager = NULL;
}
if(g_partial_close_manager != NULL)
{
delete g_partial_close_manager;
g_partial_close_manager = NULL;
}
if(g_trade_executor != NULL)
{
delete g_trade_executor;
g_trade_executor = NULL;
}
if(g_state_manager != NULL)
{
delete g_state_manager;
g_state_manager = NULL;
}
if(g_ui_manager != NULL)
{
delete g_ui_manager;
g_ui_manager = NULL;
}
if(g_logging_manager != NULL)
{
delete g_logging_manager;
g_logging_manager = NULL;
}
g_logging_manager.LogInfo("========== EA Deinitialized ==========");
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Update UI
UpdateUI();
// Manage risk (breakeven, trailing)
g_risk_manager.ManageRiskManagement();
// Check partial closes
g_partial_close_manager.CheckAndExecutePartialCloses();
// Check new bar
if(!IsNewBar()) return;
g_logging_manager.LogInfo("========== New Bar Detected ==========");
// Update daily profit tracking
UpdateDailyProfitTracking();
// Process based on trade mode
if(Trade_Mode == MODE_MANUAL)
{
ProcessManualTrade();
}
else if(Trade_Mode == MODE_INDICATOR)
{
ProcessIndicatorTrade();
}
}
//+------------------------------------------------------------------+
//| Chart event function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
if(id == CHARTEVENT_OBJECT_CLICK && Trade_Mode == MODE_MANUAL && sparam == "ManualTradeButton")
{
g_manual_trade_button_pressed = true;
g_logging_manager.LogDebug("Manual trade button clicked");
}
}
//+------------------------------------------------------------------+
//| Check if new bar |
//+------------------------------------------------------------------+
bool IsNewBar()
{
datetime current_bar_time = iTime(g_symbol, PERIOD_CURRENT, 0);
if(current_bar_time != g_last_bar_time)
{
g_last_bar_time = current_bar_time;
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| Update UI |
//+------------------------------------------------------------------+
void UpdateUI()
{
double account_balance = AccountInfoDouble(ACCOUNT_BALANCE);
double loss_percent = 0;
if(account_balance > 0)
{
loss_percent = (g_accumulated_loss / account_balance) * 100.0;
}
g_ui_manager.UpdateLossDisplay(g_accumulated_loss, loss_percent);
}
//+------------------------------------------------------------------+
//| Reset daily profit if needed |
//+------------------------------------------------------------------+
void ResetDailyProfitIfNeeded()
{
datetime now = TimeCurrent();
datetime midnight = now - (now % 86400);
datetime reset_time = midnight + 3600; // 01:00 GMT
if(now >= reset_time &&
(g_last_daily_reset_time < reset_time ||
TimeToString(now, TIME_DATE) != TimeToString(g_last_daily_reset_time, TIME_DATE)))
{
double current_balance = AccountInfoDouble(ACCOUNT_BALANCE);
g_money_manager.ResetDailyProfit(current_balance);
g_last_daily_reset_time = now;
g_logging_manager.LogInfo("Daily Profit Tracking Reset at 01:00. Start Balance: " + DoubleToString(current_balance, 2));
}
}
//+------------------------------------------------------------------+
//| Update daily profit tracking |
//+------------------------------------------------------------------+
void UpdateDailyProfitTracking()
{
ResetDailyProfitIfNeeded();
// Calculate daily profit from history
double daily_profit = 0;
for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
{
if(HistoryDealSelect(i))
{
string symbol;
long magic, entry_type, deal_time;
double profit, commission, swap;
if(HistoryDealGetString(i, DEAL_SYMBOL, symbol) &&
HistoryDealGetInteger(i, DEAL_MAGIC, magic) &&
HistoryDealGetInteger(i, DEAL_ENTRY, entry_type) &&
HistoryDealGetInteger(i, DEAL_TIME, deal_time) &&
HistoryDealGetDouble(i, DEAL_PROFIT, profit) &&
HistoryDealGetDouble(i, DEAL_COMMISSION, commission) &&
HistoryDealGetDouble(i, DEAL_SWAP, swap))
{
if(symbol == g_symbol &&
magic == MagicNumber &&
entry_type == DEAL_ENTRY_OUT &&
deal_time > g_last_daily_reset_time)
{
daily_profit += profit + commission + swap;
}
}
}
}
g_money_manager.SetDailyProfitAccumulated(daily_profit);
}
//+------------------------------------------------------------------+
//| Process manual trade |
//+------------------------------------------------------------------+
void ProcessManualTrade()
{
if(!g_manual_trade_button_pressed) return;
g_manual_trade_button_pressed = false;
double manual_tp = g_ui_manager.GetManualTP();
double manual_sl = g_ui_manager.GetManualSL();
if(manual_tp == 0 || manual_sl == 0)
{
g_logging_manager.LogWarning("Please fill both Stop Loss and Take Profit values for manual trade.");
return;
}
double bid = SymbolInfoDouble(g_symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(g_symbol, SYMBOL_ASK);
bool is_buy = (manual_tp > bid && manual_sl < bid);
bool is_sell = (manual_tp < bid && manual_sl > bid);
if(!is_buy && !is_sell)
{
g_logging_manager.LogWarning("Invalid SL/TP values for a market order.");
return;
}
// Calculate lot size
double lot_size = g_money_manager.CalculateLotSize(is_buy, is_buy ? ask : bid, manual_tp, AccountInfoDouble(ACCOUNT_BALANCE));
// Validate SL/TP
double tp_prices[] = {manual_tp};
CRiskManager::ValidatedSLTP validated = g_risk_manager.ValidateSLTP(is_buy, is_buy ? ask : bid, manual_sl, tp_prices, 1);
if(!validated.is_valid)
{
g_logging_manager.LogWarning("SL/TP validation failed: ", validated.error_message);
return;
}
// Execute trade
CTradeExecutor::TradeResult result = g_trade_executor.ExecuteTrade(
is_buy,
lot_size,
is_buy ? ask : bid,
validated.sl_price,
validated.tp_prices,
validated.tp_count
);
if(!result.success)
{
g_logging_manager.LogError(GetLastError(), "ProcessManualTrade - ExecuteTrade");
}
}
//+------------------------------------------------------------------+
//| Process indicator trade |
//+------------------------------------------------------------------+
void ProcessIndicatorTrade()
{
// Check daily profit target
if(g_money_manager.IsDailyProfitTargetReached())
{
g_logging_manager.LogInfo("Daily profit target reached. Skipping trade.");
return;
}
// Check time filter
if(!g_time_filter.IsTimeAllowed())
{
g_logging_manager.LogDebug("Time filter not allowed. Skipping trade.");
return;
}
// Check if trade is already open
if(g_trade_executor.IsTradeOpen())
{
g_logging_manager.LogDebug("Trade already open. Skipping new signal.");
return;
}
// Detect signal
CSignalDetector::SignalData signal = g_signal_detector.DetectSignal(1);
if(!signal.has_signal)
{
g_logging_manager.LogDebug("No signal detected.");
return;
}
g_logging_manager.LogInfo(signal.is_buy ? "BUY signal detected" : "SELL signal detected");
g_logging_manager.LogInfo("Signal Price: " + DoubleToString(signal.signal_price, g_digits));
g_logging_manager.LogInfo("SL: " + DoubleToString(signal.sl_price, g_digits));
for(int i = 0; i < signal.tp_count; i++)
{
g_logging_manager.LogInfo("TP", i + 1, ": ", DoubleToString(signal.tp_prices[i], g_digits));
}
if(signal.used_atr_fallback)
{
g_logging_manager.LogInfo("ATR fallback used for SL/TP");
}
// Exit opposite trade if enabled
if(ExitOnOppositeSignal)
{
g_trade_executor.CloseOppositeTrade(signal.is_buy);
}
// Calculate lot size
double open_price = SymbolInfoDouble(g_symbol, SYMBOL_BID);
double lot_size = g_money_manager.CalculateLotSize(
signal.is_buy,
open_price,
signal.tp_prices[0], // Use first TP for lot calculation
AccountInfoDouble(ACCOUNT_BALANCE)
);
g_logging_manager.LogInfo("Lot size: " + DoubleToString(lot_size, 2));
// Validate SL/TP
CRiskManager::ValidatedSLTP validated = g_risk_manager.ValidateSLTP(
signal.is_buy,
open_price,
signal.sl_price,
signal.tp_prices,
signal.tp_count
);
if(!validated.is_valid)
{
g_logging_manager.LogWarning("SL/TP validation failed: ", validated.error_message);
return;
}
// Execute trade
CTradeExecutor::TradeResult result = g_trade_executor.ExecuteTrade(
signal.is_buy,
lot_size,
open_price,
validated.sl_price,
validated.tp_prices,
validated.tp_count
);
if(!result.success)
{
g_logging_manager.LogError(GetLastError(), "ProcessIndicatorTrade - ExecuteTrade");
}
}
//+------------------------------------------------------------------+