//+------------------------------------------------------------------+
//| MA_Cross_Stoch_DynamicExit_EA.mq5 |
//| Copyright 2025, Generated by AI |
//| [Link] |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Generated by AI"
#property link "[Link]
#property version "2.01" // Fixed OnInit error
#property description "EA based on MA Cross Filter (14/200), Stochastic Signal
Entry,"
#property description "Dynamic SL on MA Reverse Cross, Dynamic TP on Stoch Level."
#include <Trade\[Link]> // Include the Trade library
//--- Input parameters
input group "Moving Average Settings"
input int InpFastMAPeriod = 14; // Fast MA Period
input ENUM_MA_METHOD InpFastMAMethod = MODE_SMA; // Fast MA Method
input ENUM_APPLIED_PRICE InpFastMAAppliedPrice = PRICE_CLOSE;// Fast MA Applied
Price
input int InpSlowMAPeriod = 200; // Slow MA Period
input ENUM_MA_METHOD InpSlowMAMethod = MODE_SMA; // Slow MA Method
input ENUM_APPLIED_PRICE InpSlowMAAppliedPrice = PRICE_CLOSE;// Slow MA Applied
Price
input group "Stochastic Settings"
input int InpKPeriod = 5; // Stochastic K Period
input int InpDPeriod = 3; // Stochastic D Period
input int InpSlowing = 3; // Stochastic Slowing
input double InpOverboughtLevel = 80.0; // Stochastic Overbought
Level (TP for Sell, SL check for Buy)
input double InpOversoldLevel = 20.0; // Stochastic Oversold
Level (TP for Buy, SL check for Sell)
input ENUM_STO_PRICE InpStoPriceField = STO_LOWHIGH;// Stochastic Price Field
input group "Trade Settings"
input double InpLots = 0.01; // Lots size
input ulong InpMagicNumber = 12347; // Magic Number
//--- Global variables
int hFastMA; // Fast MA handle
int hSlowMA; // Slow MA handle
int hStochastic; // Stochastic handle
CTrade trade; // Trading object
double point; // Point size for the current symbol
int digits; // Number of digits after decimal point
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Initialize indicators
hFastMA = iMA(_Symbol, _Period, InpFastMAPeriod, 0, InpFastMAMethod,
InpFastMAAppliedPrice);
if(hFastMA == INVALID_HANDLE)
{
printf("Error creating Fast MA indicator handle - Error code %d",
GetLastError());
return(INIT_FAILED);
}
hSlowMA = iMA(_Symbol, _Period, InpSlowMAPeriod, 0, InpSlowMAMethod,
InpSlowMAAppliedPrice);
if(hSlowMA == INVALID_HANDLE)
{
printf("Error creating Slow MA indicator handle - Error code %d",
GetLastError());
IndicatorRelease(hFastMA); // Release previously created handle
return(INIT_FAILED);
}
// CORRECTED LINE: Using MODE_SMA directly for Stochastic's internal MA method
hStochastic = iStochastic(_Symbol, _Period, InpKPeriod, InpDPeriod, InpSlowing,
MODE_SMA, InpStoPriceField);
if(hStochastic == INVALID_HANDLE)
{
printf("Error creating Stochastic indicator handle - Error code %d",
GetLastError());
IndicatorRelease(hFastMA);
IndicatorRelease(hSlowMA);
return(INIT_FAILED);
}
//--- Initialize trading object
[Link](InpMagicNumber);
[Link](10);
[Link](_Symbol);
//--- Get symbol properties
point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
if(point == 0)
{
printf("Error getting symbol point size for %s", _Symbol);
IndicatorRelease(hFastMA);
IndicatorRelease(hSlowMA);
IndicatorRelease(hStochastic);
return(INIT_FAILED);
}
//--- Initialization successful
printf("MA Cross Stoch Dynamic Exit EA Initialized Successfully.");
printf("Symbol: %s, Timeframe: %s", _Symbol, EnumToString(_Period));
printf("Fast MA(%d), Slow MA(%d), Stoch(%d,%d,%d), Lots: %.2f", InpFastMAPeriod,
InpSlowMAPeriod, InpKPeriod, InpDPeriod, InpSlowing, InpLots);
printf("Entry: Stoch Signal Cross confirmed by MA trend.");
printf("SL: MA Reverse Cross. TP: Stoch Level Reached.");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- Release indicator handles
if(hFastMA != INVALID_HANDLE) IndicatorRelease(hFastMA);
if(hSlowMA != INVALID_HANDLE) IndicatorRelease(hSlowMA);
if(hStochastic != INVALID_HANDLE) IndicatorRelease(hStochastic);
printf("MA Cross Stoch Dynamic Exit EA Deinitialized. Reason: %d", reason);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- Check if handles are valid
if(hFastMA == INVALID_HANDLE || hSlowMA == INVALID_HANDLE || hStochastic ==
INVALID_HANDLE)
{
// Consider adding re-initialization logic here if desired
return;
}
//--- Check for enough bars (Need at least 3 for cross checks)
// Ensure enough bars for the slowest indicator + 3 (for index 0, 1, 2)
int barsNeeded = MathMax(InpFastMAPeriod, MathMax(InpSlowMAPeriod,
MathMax(InpKPeriod, MathMax(InpDPeriod, InpSlowing)))) + 3;
if(Bars(_Symbol, _Period) < barsNeeded)
{
//printf("Not enough bars for calculation yet.");
return;
}
//--- Get indicator data arrays (requesting 3 bars for cross checks)
// Index 0 = current forming bar, 1 = last completed bar, 2 = bar before last
completed
double fastMA[3];
double slowMA[3];
double stochMain[3]; // Stochastic Main line (for TP)
double stochSignal[3]; // Stochastic Signal line (for Entry)
// Copy data, check for errors
if(CopyBuffer(hFastMA, 0, 0, 3, fastMA) < 3 ||
CopyBuffer(hSlowMA, 0, 0, 3, slowMA) < 3 ||
CopyBuffer(hStochastic, 0, 0, 3, stochMain) < 3 || // Main line buffer
index 0
CopyBuffer(hStochastic, 1, 0, 3, stochSignal) < 3) // Signal line buffer
index 1
{
printf("Error copying indicator data - Error code %d", GetLastError());
return;
}
//--- Check for Open Position (Manage Exits First)
bool positionOpen = PositionSelect(_Symbol);
if(positionOpen)
{
long positionType = PositionGetInteger(POSITION_TYPE); // 0 for buy, 1 for
sell
string closeReason = "";
// 1. Check Stop Loss Condition (MA Reverse Cross on last completed bar:
index 1)
if(positionType == POSITION_TYPE_BUY && fastMA[1] <= slowMA[1]) // Fast MA
crossed below Slow MA
{
closeReason = "SL: Fast MA crossed below Slow MA";
}
else if(positionType == POSITION_TYPE_SELL && fastMA[1] >= slowMA[1]) // Fast
MA crossed above Slow MA
{
closeReason = "SL: Fast MA crossed above Slow MA";
}
// 2. Check Take Profit Condition (Stochastic Level Reached on last completed
bar: index 1), only if SL not triggered
if(closeReason == "") // Only check TP if SL condition is not met
{
// Use Stochastic MAIN line for TP check
if(positionType == POSITION_TYPE_BUY && stochMain[1] >=
InpOverboughtLevel)
{
closeReason = "TP: Stochastic Main reached Overbought";
}
else if(positionType == POSITION_TYPE_SELL && stochMain[1] <=
InpOversoldLevel)
{
closeReason = "TP: Stochastic Main reached Oversold";
}
}
// 3. Close Position if SL or TP condition met
if(closeReason != "")
{
printf("Closing %s Position. Reason: %s", (positionType ==
POSITION_TYPE_BUY ? "BUY" : "SELL"), closeReason);
// Attempt to close the position identified by PositionSelect() for the
current symbol
if() // Close by symbol with deviation 3
points
{
// Log error details from CTrade object
printf("Error closing position: %d - %s", [Link](),
[Link]());
}
return; // Exit OnTick after attempting closure
}
}
//--- No Open Position or No Exit Signal -> Check for Entry Signals
else
{
// Define Trend State based on last completed bar's MAs (index 1)
bool isUptrend = fastMA[1] > slowMA[1];
bool isDowntrend = fastMA[1] < slowMA[1];
// Check Stochastic Signal Crosses (using index 2 vs index 1)
bool stochBuySignal = stochSignal[2] < InpOversoldLevel && stochSignal[1] >=
InpOversoldLevel;
bool stochSellSignal = stochSignal[2] > InpOverboughtLevel && stochSignal[1]
<= InpOverboughtLevel;
// Check Buy Entry Condition
if(isUptrend && stochBuySignal)
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
printf("BUY Entry Signal: MA Trend UP (%.*f > %.*f) AND Stoch Signal
crossed %.1f UP (%.2f -> %.2f)",
digits, fastMA[1], digits, slowMA[1], InpOversoldLevel,
stochSignal[2], stochSignal[1]);
// Place order with NO initial SL/TP (set to 0)
if()
{
printf("Error opening BUY position: %d - %s", [Link](),
[Link]());
}
return; // Exit after attempting entry
}
// Check Sell Entry Condition
if(isDowntrend && stochSellSignal)
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
printf("SELL Entry Signal: MA Trend DOWN (%.*f < %.*f) AND Stoch Signal
crossed %.1f DOWN (%.2f -> %.2f)",
digits, fastMA[1], digits, slowMA[1], InpOverboughtLevel,
stochSignal[2], stochSignal[1]);
// Place order with NO initial SL/TP (set to 0)
if()
{
printf("Error opening SELL position: %d - %s", [Link](),
[Link]());
}
return; // Exit after attempting entry
}
} // End of Entry Logic Check
}
//+------------------------------------------------------------------+