none of the EA works to disable the autotrading after profitable trades,what do i do,please someone code this for me whever you are free,please please.
Similar Threads
I will code your pivot EAs for no charge 28 replies
I will code your scalping EAs for no charge 163 replies
Oanda MT4 - Indicators and EAs not showing 2 replies
EAs and indicators relating to moutaki... 22 replies
InterbankFX has loaded its MT4 platform with custom EAs, indicators and scripts 1 reply
The StopOnProfitAndDisableAT.mq4
Once your profit target is hit, it will Close your trades (all of them, or only the winning ones — depending on your setting).
There are two simple modes:
Money Mode (default & safer) → if you start with for instance $1000 and set target to $50, it triggers at $1050.
Floating Pips Mode → adds up all open trades in pips. Less precise if you trade many symbols.
And one more thing:
If you set CloseOnlyProfitable = false → it closes all trades.
If you set CloseOnlyProfitable = true → it closes only winners, leaves losers running.
Once your profit target is hit, it will Close your trades (all of them, or only the winning ones — depending on your setting).
There are two simple modes:
Money Mode (default & safer) → if you start with for instance $1000 and set target to $50, it triggers at $1050.
Floating Pips Mode → adds up all open trades in pips. Less precise if you trade many symbols.
And one more thing:
If you set CloseOnlyProfitable = false → it closes all trades.
If you set CloseOnlyProfitable = true → it closes only winners, leaves losers running.
Attached File(s)
If I follow my system, the outcome doesn’t define me — the process does.
1
Dislikednone of the EA works to disable the autotrading after profitable trades,what do i do,please someone code this for me whever you are free,please please.Ignored
You have two choices: either find someone with very high skills capable of hacking the software, or accept the current situation and find another solution.
My ideas to solve this issue:
Step 1: Create a backup profile and load and save it every day onto another profile, so that when the charts are closed, the next day you don’t have to constantly set up the same charts and the same experts again.
Step 2: Write an expert advisor and place it on a separate chart that deletes other expert advisors from the charts once you reach a profit, or that when a specific profit is reached, the expert advisor or an indicator closes all the charts where that automatic expert advisor is running. The chart gets closed as if the expert advisor itself has been closed. In this way, having the automatic trade button active practically won’t be troublesome because no expert advisor exists on any chart that can trade.
Theory of Everything is Liquidity...https://www.youtube.com/@FxArt.Trader
- #78,844
- Aug 22, 2025 9:31am Aug 22, 2025 9:31am
- Joined Mar 2022 | Status: Trader | 6,558 Posts
Dislikednone of the EA works to disable the autotrading after profitable trades,what do i do,please someone code this for me whever you are free,please please.Ignored
I tested it.
Attached File(s)
Attached File(s)
.ex4/.ex5 files can't be fixed or modified / I'm not a coder!
2
- #78,845
- Aug 22, 2025 9:32am Aug 22, 2025 9:32am
- Joined Mar 2022 | Status: Trader | 6,558 Posts
Disliked{quote} Certainly, none of them will work after this either, because MetaTrader does not provide any access in the MQL code for the button that enables automatic trading. The only solution is, in a way, hacking the software and finding a way to access it. And I don't think anyone would want to spend time hacking a software just for a button that you are trying to turn on or off—unless you really set aside a good amount of money for this and request help from people who have such capability in a separate thread. You have two choices: either find...Ignored
Look at the source code which I posted above.
BTW, I already posted those before, a few days ago.
Inserted Code
//--- Import Windows API #import "user32.dll" void keybd_event(int bVk, int bScan, int dwFlags, int dwExtraInfo); #import //--- Key codes #define REL 0x0002 #define CTRL 0x11 #define E 0x45
Inserted Code
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
{
Print("AutoTrading is ON. Disabling with Ctrl+E...");
keybd_event(CTRL,0,0,0);
keybd_event(E,0,0,0);
keybd_event(CTRL,0,REL,0);
keybd_event(E,0,REL,0);
}
else
{
Print("AutoTrading already disabled. No action taken.");
} .ex4/.ex5 files can't be fixed or modified / I'm not a coder!
1
- #78,846
- Edited 12:16pm Aug 22, 2025 11:47am | Edited 12:16pm
Disliked{quote} This just provides HL lines extending to the live candle, of a target candle or the range from the target candle. The target candle is on the current chart and located by index or dragging the vline about. {image} {file}Ignored
Regards
- #78,847
- Aug 22, 2025 4:38pm Aug 22, 2025 4:38pm
- Joined Dec 2010 | Status: Trader | 2,136 Posts
Disliked{quote} Thank you so much, would it be possible that the HL only shows for a time period ex (on 60 min TF from 15h00 - 18h00) ? RegardsIgnored
Disliked...ex on the 15m TF (10h00 - 16h00), only the 10h00 (15m candle) extends till 16h00...Ignored
Candle_Target_HL_start-end-times
- high/low lines drawn on candle at a start time
- lines extend to the end time
- styling
Pic shows hl lines at the 0500 candle extending to 1500-
Attached File(s)
- #78,848
- Aug 22, 2025 7:21pm Aug 22, 2025 7:21pm
- Joined Feb 2012 | Status: Trader | 3,923 Posts
DislikedYikes, my bad!apologies for your keyboard rage
, Ill keep it mind from now on dude.
Ignored
Inserted Code
//+------------------------------------------------------------------+
//| PBZZEA1_Fixed.mq5 |
//| Copyright 2025, 1bzY2002 |
//| [url="https://www.mql5.com/"]https://www.mql5.com[/url] |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, 1bzY2002"
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Expert Advisor based on ZigZag Percentage Indicator - Fixed with Pending Orders"
#include <Trade\Trade.mqh>
//--- Input parameters
input group "=== ZigZag Settings ==="
input double ZZPercent = 0.1; // ZigZag Percentage Change
input int MinBarsForSignal = 2; // Minimum bars after ZZ point for signal
input group "=== Trade Settings ==="
input double LotSize = 0.01; // Lot Size
input int StopLossPips = 25; // Stop Loss in pips
input int TakeProfitPips = 25; // Take Profit in pips
input int TriggerPips = 25; // Pips to trigger pending order
input bool UseTrailingStop = false; // Use Trailing Stop
input int TrailingStopPips = 25; // Trailing Stop in pips
input int TrailingStepPips = 5; // Trailing Step in pips
input group "=== Risk Management ==="
input double MaxRiskPercent = 2.0; // Maximum Risk per Trade (%)
input int MaxSpread = 30; // Maximum Spread in points
input bool UseRiskBasedLots = false; // Calculate lot size based on risk
input group "=== EA Settings ==="
input int MagicNumber = 123456; // Magic Number
input bool TradeOnNewBar = true; // Trade only on new bar
input string TradeComment = "ZZ_EA"; // Trade Comment
//--- Global variables
CTrade trade;
double ZigZagHigh[], ZigZagLow[], ZigZagType[], ZigZagCol[];
double HighLast[], LowLast[];
double HighBarZZ[], LowBarZZ[];
datetime lastBarTime;
double point;
int symbolDigits;
ulong pendingOrderTicket = 0; // Track pending order ticket
//--- ZigZag calculation variables
bool initialized = false;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Initialize trade object
trade.SetExpertMagicNumber(MagicNumber);
// Get symbol properties
point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
symbolDigits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
// Initialize arrays for ZigZag calculation
ArrayResize(ZigZagHigh, Bars(_Symbol, PERIOD_CURRENT));
ArrayResize(ZigZagLow, Bars(_Symbol, PERIOD_CURRENT));
ArrayResize(ZigZagType, Bars(_Symbol, PERIOD_CURRENT));
ArrayResize(ZigZagCol, Bars(_Symbol, PERIOD_CURRENT));
ArrayResize(HighLast, Bars(_Symbol, PERIOD_CURRENT));
ArrayResize(LowLast, Bars(_Symbol, PERIOD_CURRENT));
ArrayResize(HighBarZZ, Bars(_Symbol, PERIOD_CURRENT));
ArrayResize(LowBarZZ, Bars(_Symbol, PERIOD_CURRENT));
ArraySetAsSeries(ZigZagHigh, true);
ArraySetAsSeries(ZigZagLow, true);
ArraySetAsSeries(ZigZagType, true);
ArraySetAsSeries(ZigZagCol, true);
ArraySetAsSeries(HighLast, true);
ArraySetAsSeries(LowLast, true);
ArraySetAsSeries(HighBarZZ, true);
ArraySetAsSeries(LowBarZZ, true);
Print("ZigZag Percentage EA with Pending Orders initialized successfully");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Clean up any pending orders
ClosePendingOrder();
Print("ZigZag Percentage EA deinitialized");
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Check if trading is allowed
if(!IsTradeAllowed()) return;
// Check spread
if(SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) > MaxSpread)
{
return;
}
// Trade only on new bar if enabled
if(TradeOnNewBar)
{
datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
if(lastBarTime == currentBarTime) return;
lastBarTime = currentBarTime;
}
// Calculate ZigZag
if(!CalculateZigZag()) return;
// Manage existing positions
ManagePositions();
// Check for new trade signals and manage pending orders
CheckTradeSignals();
}
//+------------------------------------------------------------------+
//| Calculate ZigZag values |
//+------------------------------------------------------------------+
bool CalculateZigZag()
{
int bars = Bars(_Symbol, PERIOD_CURRENT);
if(bars < 50) return false;
// Handle array resizing and shifting for new bars
int old_size = ArraySize(ZigZagHigh);
if(bars > old_size)
{
int add = bars - old_size;
// Resize and shift all arrays
ArrayResize(ZigZagHigh, bars);
ArrayCopy(ZigZagHigh, ZigZagHigh, add, 0, old_size);
for(int k = 0; k < add; k++) ZigZagHigh[k] = EMPTY_VALUE;
ArrayResize(ZigZagLow, bars);
ArrayCopy(ZigZagLow, ZigZagLow, add, 0, old_size);
for(int k = 0; k < add; k++) ZigZagLow[k] = EMPTY_VALUE;
ArrayResize(ZigZagType, bars);
ArrayCopy(ZigZagType, ZigZagType, add, 0, old_size);
for(int k = 0; k < add; k++) ZigZagType[k] = EMPTY_VALUE;
ArrayResize(ZigZagCol, bars);
ArrayCopy(ZigZagCol, ZigZagCol, add, 0, old_size);
for(int k = 0; k < add; k++) ZigZagCol[k] = EMPTY_VALUE;
ArrayResize(HighLast, bars);
ArrayCopy(HighLast, HighLast, add, 0, old_size);
for(int k = 0; k < add; k++) HighLast[k] = EMPTY_VALUE;
ArrayResize(LowLast, bars);
ArrayCopy(LowLast, LowLast, add, 0, old_size);
for(int k = 0; k < add; k++) LowLast[k] = EMPTY_VALUE;
ArrayResize(HighBarZZ, bars);
ArrayCopy(HighBarZZ, HighBarZZ, add, 0, old_size);
for(int k = 0; k < add; k++) HighBarZZ[k] = EMPTY_VALUE;
for(int k = add; k < bars; k++) if(HighBarZZ[k] != EMPTY_VALUE) HighBarZZ[k] += add;
ArrayResize(LowBarZZ, bars);
ArrayCopy(LowBarZZ, LowBarZZ, add, 0, old_size);
for(int k = 0; k < add; k++) LowBarZZ[k] = EMPTY_VALUE;
for(int k = add; k < bars; k++) if(LowBarZZ[k] != EMPTY_VALUE) LowBarZZ[k] += add;
}
// Get price data
double high[], low[], close[];
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
if(CopyHigh(_Symbol, PERIOD_CURRENT, 0, bars, high) <= 0) return false;
if(CopyLow(_Symbol, PERIOD_CURRENT, 0, bars, low) <= 0) return false;
if(CopyClose(_Symbol, PERIOD_CURRENT, 0, bars, close) <= 0) return false;
int limit;
if(!initialized)
{
ArrayInitialize(ZigZagHigh, EMPTY_VALUE);
ArrayInitialize(ZigZagLow, EMPTY_VALUE);
ArrayInitialize(ZigZagType, EMPTY_VALUE);
ArrayInitialize(ZigZagCol, EMPTY_VALUE);
ArrayInitialize(HighLast, EMPTY_VALUE);
ArrayInitialize(LowLast, EMPTY_VALUE);
ArrayInitialize(HighBarZZ, EMPTY_VALUE);
ArrayInitialize(LowBarZZ, EMPTY_VALUE);
int period_start = CalcStartingExtremes(bars - 1, high, low);
if(period_start < 0) return false;
limit = period_start - 1;
if(limit >= 0)
{
for(int i = limit; i >= 0; i--)
{
ZigZagHigh[i] = EMPTY_VALUE;
ZigZagLow[i] = EMPTY_VALUE;
if(ZigZagType[i + 1] != EMPTY_VALUE && ZigZagType[i + 1] > 0)
{
HighZZPoint(i, high, low);
}
if(ZigZagType[i + 1] != EMPTY_VALUE && ZigZagType[i + 1] < 0)
{
LowZZPoint(i, high, low);
}
}
}
initialized = true;
}
else
{
limit = MathMin(100, bars - 1);
for(int i = limit; i >= 0; i--)
{
ZigZagHigh[i] = EMPTY_VALUE;
ZigZagLow[i] = EMPTY_VALUE;
if(i < bars - 1)
{
if(ZigZagType[i + 1] != EMPTY_VALUE && ZigZagType[i + 1] > 0)
{
HighZZPoint(i, high, low);
}
if(ZigZagType[i + 1] != EMPTY_VALUE && ZigZagType[i + 1] < 0)
{
LowZZPoint(i, high, low);
}
}
}
}
return true;
}
//+------------------------------------------------------------------+
//| Calculate starting extremes |
//+------------------------------------------------------------------+
int CalcStartingExtremes(int limit, const double &high[], const double &low[])
{
for(int i = limit - 1; i >= 0; i--)
{
int period_start = i;
int count = Bars(_Symbol, PERIOD_CURRENT) - period_start;
int maxBar = ArrayMaximum(high, period_start, count);
int minBar = ArrayMinimum(low, period_start, count);
if(maxBar < 0 || minBar < 0) continue;
double maxPrice = high[maxBar];
double minPrice = low[minBar];
if(minPrice == 0.0) continue;
double rangePercent = MathAbs((maxPrice - minPrice) / minPrice) * 100.0;
if(maxBar != minBar && maxBar < minBar && rangePercent >= ZZPercent)
{
ZigZagType[period_start] = 1;
ZigZagHigh[maxBar] = maxPrice;
ZigZagLow[minBar] = minPrice;
HighBarZZ[period_start] = maxBar;
LowBarZZ[period_start] = minBar;
HighLast[period_start] = maxPrice;
LowLast[period_start] = minPrice;
return period_start;
}
if(maxBar != minBar && minBar < maxBar && rangePercent >= ZZPercent)
{
ZigZagType[period_start] = -1;
ZigZagHigh[maxBar] = maxPrice;
ZigZagLow[minBar] = minPrice;
HighBarZZ[period_start] = maxBar;
LowBarZZ[period_start] = minBar;
HighLast[period_start] = maxPrice;
LowLast[period_start] = minPrice;
return period_start;
}
}
return -1;
}
//+------------------------------------------------------------------+
//| High ZigZag Point calculation |
//+------------------------------------------------------------------+
void HighZZPoint(const int index, const double &high[], const double &low[])
{
if(index + 1 >= ArraySize(HighLast)) return;
double PriceHigh = high[index];
double PriceLow = low[index];
bool EventHigh = false;
bool EventLow = false;
double R_Step = 0.0;
if(HighLast[index + 1] != 0.0 && HighLast[index + 1] != EMPTY_VALUE)
{
R_Step = MathAbs((HighLast[index + 1] - PriceLow) / HighLast[index + 1]) * 100.0;
}
if(PriceHigh > HighLast[index + 1])
{
EventHigh = true;
ZigZagType[index] = 1;
int prev_high_index = (int)HighBarZZ[index + 1];
if(prev_high_index >= 0 && prev_high_index < ArraySize(ZigZagHigh))
ZigZagHigh[prev_high_index] = EMPTY_VALUE;
ZigZagHigh[index] = PriceHigh;
HighBarZZ[index] = index;
LowBarZZ[index] = LowBarZZ[index + 1];
HighLast[index] = PriceHigh;
LowLast[index] = LowLast[index + 1];
ZigZagCol[index] = 1;
}
if(R_Step >= ZZPercent && !EventHigh)
{
EventLow = true;
ZigZagType[index] = -1;
ZigZagLow[index] = PriceLow;
LowLast[index] = PriceLow;
HighLast[index] = HighLast[index + 1];
HighBarZZ[index] = HighBarZZ[index + 1];
LowBarZZ[index] = index;
ZigZagCol[index] = 0;
}
if(!EventHigh && !EventLow)
{
ZigZagType[index] = ZigZagType[index + 1];
HighBarZZ[index] = HighBarZZ[index + 1];
LowBarZZ[index] = LowBarZZ[index + 1];
HighLast[index] = HighLast[index + 1];
LowLast[index] = LowLast[index + 1];
}
}
//+------------------------------------------------------------------+
//| Low ZigZag Point calculation |
//+------------------------------------------------------------------+
void LowZZPoint(const int index, const double &high[], const double &low[])
{
if(index + 1 >= ArraySize(LowLast)) return;
double PriceHigh = high[index];
double PriceLow = low[index];
bool EventLow = false;
bool EventHigh = false;
double R_Step = 0.0;
if(LowLast[index + 1] != 0.0 && LowLast[index + 1] != EMPTY_VALUE)
{
R_Step = MathAbs((LowLast[index + 1] - PriceHigh) / LowLast[index + 1]) * 100.0;
}
if(PriceLow < LowLast[index + 1])
{
EventLow = true;
ZigZagType[index] = -1;
int prev_low_index = (int)LowBarZZ[index + 1];
if(prev_low_index >= 0 && prev_low_index < ArraySize(ZigZagLow))
ZigZagLow[prev_low_index] = EMPTY_VALUE;
ZigZagLow[index] = PriceLow;
LowBarZZ[index] = index;
HighBarZZ[index] = HighBarZZ[index + 1];
HighLast[index] = HighLast[index + 1];
LowLast[index] = PriceLow;
ZigZagCol[index] = 0;
}
if(R_Step >= ZZPercent && !EventLow)
{
EventHigh = true;
ZigZagType[index] = 1;
ZigZagHigh[index] = PriceHigh;
HighLast[index] = PriceHigh;
LowLast[index] = LowLast[index + 1];
HighBarZZ[index] = index;
LowBarZZ[index] = LowBarZZ[index + 1];
ZigZagCol[index] = 1;
}
if(!EventHigh && !EventLow)
{
ZigZagType[index] = ZigZagType[index + 1];
HighBarZZ[index] = HighBarZZ[index + 1];
LowBarZZ[index] = LowBarZZ[index + 1];
HighLast[index] = HighLast[index + 1];
LowLast[index] = LowLast[index + 1];
}
}
//+------------------------------------------------------------------+
//| Check for trade signals |
//+------------------------------------------------------------------+
void CheckTradeSignals()
{
// Don't place pending orders if a position is already open
if(PositionSelect(_Symbol)) return;
// Find the last two ZigZag points
double lastZZHigh = EMPTY_VALUE;
double lastZZLow = EMPTY_VALUE;
int lastHighBar = -1;
int lastLowBar = -1;
int search_limit = MathMin(500, Bars(_Symbol, PERIOD_CURRENT) - 1);
// Find last ZigZag points
for(int i = MinBarsForSignal; i < search_limit; i++)
{
if(ZigZagHigh[i] != EMPTY_VALUE && lastZZHigh == EMPTY_VALUE)
{
lastZZHigh = ZigZagHigh[i];
lastHighBar = i;
}
if(ZigZagLow[i] != EMPTY_VALUE && lastZZLow == EMPTY_VALUE)
{
lastZZLow = ZigZagLow[i];
lastLowBar = i;
}
if(lastZZHigh != EMPTY_VALUE && lastZZLow != EMPTY_VALUE)
break;
}
if(lastZZHigh == EMPTY_VALUE || lastZZLow == EMPTY_VALUE) return;
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
// Check for new pivot in opposite direction to cancel existing order
if(lastLowBar < lastHighBar && lastLowBar >= MinBarsForSignal)
{
// New low pivot formed; cancel any Sell Stop order
if(pendingOrderTicket > 0 && IsSellStopOrder())
{
ClosePendingOrder();
}
// Check if price has moved TriggerPips above the ZigZag low
double triggerPrice = lastZZLow + TriggerPips * point * 10;
if(currentPrice >= triggerPrice)
{
PlaceBuyStopOrder(triggerPrice, lastZZLow);
}
}
else if(lastHighBar < lastLowBar && lastHighBar >= MinBarsForSignal)
{
// New high pivot formed; cancel any Buy Stop order
if(pendingOrderTicket > 0 && IsBuyStopOrder())
{
ClosePendingOrder();
}
// Check if price has moved TriggerPips below the ZigZag high
double triggerPrice = lastZZHigh - TriggerPips * point * 10;
if(currentPrice <= triggerPrice)
{
PlaceSellStopOrder(triggerPrice, lastZZHigh);
}
}
}
//+------------------------------------------------------------------+
//| Place Buy Stop Order |
//+------------------------------------------------------------------+
void PlaceBuyStopOrder(double triggerPrice, double pivotPrice)
{
// Close any existing pending order
ClosePendingOrder();
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double lots = LotSize;
if(UseRiskBasedLots)
{
lots = CalculateRiskBasedLots();
}
double sl = 0;
double tp = 0;
if(StopLossPips > 0)
sl = triggerPrice - StopLossPips * point * 10;
if(TakeProfitPips > 0)
tp = triggerPrice + TakeProfitPips * point * 10;
// Check minimum stop level
int stopLevel = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
if(MathAbs(triggerPrice - ask) < stopLevel * point)
{
Print("Cannot place Buy Stop: price too close to market (Stop Level: ", stopLevel, " points)");
return;
}
if(trade.BuyStop(lots, triggerPrice, _Symbol, sl, tp, ORDER_TIME_GTC, 0, TradeComment))
{
pendingOrderTicket = trade.ResultOrder();
Print("Buy Stop order placed at ", triggerPrice, " SL: ", sl, " TP: ", tp, " Ticket: ", pendingOrderTicket);
}
else
{
Print("Failed to place Buy Stop order. Error: ", trade.ResultRetcode());
}
}
//+------------------------------------------------------------------+
//| Place Sell Stop Order |
//+------------------------------------------------------------------+
void PlaceSellStopOrder(double triggerPrice, double pivotPrice)
{
// Close any existing pending order
ClosePendingOrder();
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double lots = LotSize;
if(UseRiskBasedLots)
{
lots = CalculateRiskBasedLots();
}
double sl = 0;
double tp = 0;
if(StopLossPips > 0)
sl = triggerPrice + StopLossPips * point * 10;
if(TakeProfitPips > 0)
tp = triggerPrice - TakeProfitPips * point * 10;
// Check minimum stop level
int stopLevel = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
if(MathAbs(bid - triggerPrice) < stopLevel * point)
{
Print("Cannot place Sell Stop: price too close to market (Stop Level: ", stopLevel, " points)");
return;
}
if(trade.SellStop(lots, triggerPrice, _Symbol, sl, tp, ORDER_TIME_GTC, 0, TradeComment))
{
pendingOrderTicket = trade.ResultOrder();
Print("Sell Stop order placed at ", triggerPrice, " SL: ", sl, " TP: ", tp, " Ticket: ", pendingOrderTicket);
}
else
{
Print("Failed to place Sell Stop order. Error: ", trade.ResultRetcode());
}
}
//+------------------------------------------------------------------+
//| Check if existing pending order is a Buy Stop |
//+------------------------------------------------------------------+
bool IsBuyStopOrder()
{
if(pendingOrderTicket == 0) return false;
if(OrderSelect(pendingOrderTicket))
{
return OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP;
}
return false;
}
//+------------------------------------------------------------------+
//| Check if existing pending order is a Sell Stop |
//+------------------------------------------------------------------+
bool IsSellStopOrder()
{
if(pendingOrderTicket == 0) return false;
if(OrderSelect(pendingOrderTicket))
{
return OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP;
}
return false;
}
//+------------------------------------------------------------------+
//| Close existing pending order |
//+------------------------------------------------------------------+
void ClosePendingOrder()
{
if(pendingOrderTicket == 0) return;
if(OrderSelect(pendingOrderTicket))
{
if(trade.OrderDelete(pendingOrderTicket))
{
Print("Pending order deleted. Ticket: ", pendingOrderTicket);
pendingOrderTicket = 0;
}
else
{
Print("Failed to delete pending order. Ticket: ", pendingOrderTicket, " Error: ", trade.ResultRetcode());
}
}
else
{
pendingOrderTicket = 0; // Reset if order no longer exists
}
}
//+------------------------------------------------------------------+
//| Calculate risk-based lot size |
//+------------------------------------------------------------------+
double CalculateRiskBasedLots()
{
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double riskAmount = balance * MaxRiskPercent / 100.0;
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double stopLossPoints = StopLossPips * 10;
if(tickValue == 0 || stopLossPoints == 0) return LotSize;
double lots = riskAmount / (stopLossPoints * tickValue);
// Normalize lot size
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
lots = MathFloor(lots / lotStep) * lotStep;
lots = MathMax(lots, minLot);
lots = MathMin(lots, maxLot);
return lots;
}
//+------------------------------------------------------------------+
//| Manage existing positions |
//+------------------------------------------------------------------+
void ManagePositions()
{
if(!PositionSelect(_Symbol)) return;
if(UseTrailingStop)
{
TrailingStop();
}
}
//+------------------------------------------------------------------+
//| Trailing Stop function |
//+------------------------------------------------------------------+
void TrailingStop()
{
if(!PositionSelect(_Symbol)) return;
double positionOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double currentSL = PositionGetDouble(POSITION_SL);
long positionType = PositionGetInteger(POSITION_TYPE);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
if(positionType == POSITION_TYPE_BUY)
{
double newSL = bid - TrailingStopPips * point * 10;
if(newSL > currentSL + TrailingStepPips * point * 10)
{
trade.PositionModify(_Symbol, newSL, PositionGetDouble(POSITION_TP));
}
}
else if(positionType == POSITION_TYPE_SELL)
{
double newSL = ask + TrailingStopPips * point * 10;
if(newSL < currentSL - TrailingStepPips * point * 10 || currentSL == 0)
{
trade.PositionModify(_Symbol, newSL, PositionGetDouble(POSITION_TP));
}
}
}
//+------------------------------------------------------------------+
//| Check if trading is allowed |
//+------------------------------------------------------------------+
bool IsTradeAllowed()
{
if(!MQLInfoInteger(MQL_TRADE_ALLOWED)) return false;
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) return false;
long tradeMode = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE);
if(tradeMode == SYMBOL_TRADE_MODE_DISABLED) return false;
return true;
}
SECOND
//+------------------------------------------------------------------+
//| ZigZag Breakout Expert Advisor - Final Clean Version |
//| Copyright 2025, Created for GitHub User 1bzY2002 |
//| Complete EA with all warnings eliminated |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, 1bzY2002"
#property link "https://github.com/1bzY2002"
#property version "1.02"
#property strict
#property tester_indicator "Examples\\ZigZag"
#include <Trade\Trade.mqh>
//+------------------------------------------------------------------+
//| Input Parameters |
//+------------------------------------------------------------------+
input group "=== ZigZag Settings ==="
input int ZigZagDepth = 12; // ZigZag Depth
input int ZigZagDeviation = 5; // ZigZag Deviation
input int ZigZagBackstep = 3; // ZigZag Backstep
input int MinBarsForSignal = 3; // Minimum bars for signal confirmation
input group "=== Trade Settings ==="
input double TriggerPips = 100; // Trigger distance from pivot (pips)
input double StopLossPips = 100; // Stop Loss (pips)
input double TakeProfitPips = 100; // Take Profit (pips)
input string TradeComment = "ZigZag_EA"; // Trade Comment
input group "=== Money Management ==="
input bool UseRiskBasedLots = true; // Use risk-based lot sizing
input double LotSize = 0.1; // Fixed lot size (if not risk-based)
input double MaxRiskPercent = 2.0; // Maximum risk per trade (%)
input group "=== Trailing Stop ==="
input bool UseTrailingStop = true; // Enable trailing stop
input double TrailingStopPips = 15.0; // Trailing stop distance (pips)
input double TrailingStepPips = 5.0; // Trailing step (pips)
input group "=== Time Filter ==="
input bool UseTimeFilter = false; // Enable time filter
input string StartTime = "08:00"; // Start trading time
input string EndTime = "18:00"; // End trading time
//+------------------------------------------------------------------+
//| ZigZag Point Structure - Warning-Free Version |
//+------------------------------------------------------------------+
struct ZigZagPoint
{
double price;
int bar;
datetime time;
bool isHigh;
// Initialize with specific values
void Set(double p, int b, datetime t, bool h)
{
price = p;
bar = b;
time = t;
isHigh = h;
}
// Clear/reset values
void Clear()
{
price = 0.0;
bar = 0;
time = 0;
isHigh = false;
}
// Get a copy of this point
void GetCopy(ZigZagPoint &dest)
{
dest.price = price;
dest.bar = bar;
dest.time = time;
dest.isHigh = isHigh;
}
};
//+------------------------------------------------------------------+
//| Global Variables |
//+------------------------------------------------------------------+
CTrade trade; // Trade object
int zigzagHandle; // ZigZag indicator handle
double ZigZagBuffer[]; // ZigZag main buffer
double point; // Point value
double pointMultiplier; // Point multiplier for 5-digit brokers
ulong pendingOrderTicket = 0; // Current pending order ticket
// Arrays for ZigZag analysis
double ZigZagHigh[]; // High values from ZigZag
double ZigZagLow[]; // Low values from ZigZag
datetime ZigZagTime[]; // Time values from ZigZag
// Last known ZigZag points
ZigZagPoint lastZZPoints[10]; // Store last 10 ZigZag points
int zzPointCount = 0; // Number of stored points
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Initialize trade object
trade.SetExpertMagicNumber(123456);
trade.SetDeviationInPoints(10);
trade.SetTypeFilling(ORDER_FILLING_FOK);
// Get symbol properties
point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
pointMultiplier = (digits == 3 || digits == 5) ? 10.0 : 1.0;
// Initialize ZigZag indicator
zigzagHandle = iCustom(_Symbol, PERIOD_CURRENT, "Examples\\ZigZag", ZigZagDepth, ZigZagDeviation, ZigZagBackstep);
if(zigzagHandle == INVALID_HANDLE)
{
Print("Failed to create ZigZag indicator handle");
return INIT_FAILED;
}
// Set array properties
ArraySetAsSeries(ZigZagBuffer, true);
ArraySetAsSeries(ZigZagHigh, true);
ArraySetAsSeries(ZigZagLow, true);
ArraySetAsSeries(ZigZagTime, true);
// Initialize ZigZag point storage - Clear all points
for(int i = 0; i < 10; i++)
{
lastZZPoints[i].Clear();
}
zzPointCount = 0;
Print("ZigZag Breakout EA initialized successfully");
Print("Symbol: ", _Symbol, ", Period: ", PeriodToString(PERIOD_CURRENT));
Print("Point: ", point, ", Point Multiplier: ", pointMultiplier);
Print("ZigZag Parameters: Depth=", ZigZagDepth, ", Deviation=", ZigZagDeviation, ", Backstep=", ZigZagBackstep);
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Close any pending orders on EA removal
if(reason == REASON_REMOVE)
{
ClosePendingOrder();
}
// Release indicator handle
if(zigzagHandle != INVALID_HANDLE)
{
IndicatorRelease(zigzagHandle);
}
Print("ZigZag Breakout EA deinitialized. Reason: ", reason);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Check if trading is allowed
if(!IsTradeAllowed())
return;
// Check time filter
if(UseTimeFilter && !IsTimeToTrade())
return;
// Update ZigZag data
if(!UpdateZigZagData())
return;
// Check for trade signals
CheckTradeSignals();
// Manage existing positions
ManagePositions();
}
//+------------------------------------------------------------------+
//| Update ZigZag data and find pivot points |
//+------------------------------------------------------------------+
bool UpdateZigZagData()
{
// Copy ZigZag buffer
if(CopyBuffer(zigzagHandle, 0, 0, 500, ZigZagBuffer) <= 0)
{
Print("Failed to copy ZigZag buffer");
return false;
}
// Clear previous arrays
ArrayFree(ZigZagHigh);
ArrayFree(ZigZagLow);
ArrayFree(ZigZagTime);
ArrayResize(ZigZagHigh, 500);
ArrayResize(ZigZagLow, 500);
ArrayResize(ZigZagTime, 500);
ArrayInitialize(ZigZagHigh, EMPTY_VALUE);
ArrayInitialize(ZigZagLow, EMPTY_VALUE);
// Extract high and low points
zzPointCount = 0;
for(int i = 0; i < 500 && zzPointCount < 10; i++)
{
if(ZigZagBuffer[i] != 0.0 && ZigZagBuffer[i] != EMPTY_VALUE)
{
datetime barTime = iTime(_Symbol, PERIOD_CURRENT, i);
double high = iHigh(_Symbol, PERIOD_CURRENT, i);
double low = iLow(_Symbol, PERIOD_CURRENT, i);
// Determine if it's a high or low point
bool isHigh = (MathAbs(ZigZagBuffer[i] - high) < MathAbs(ZigZagBuffer[i] - low));
if(isHigh)
{
ZigZagHigh[i] = ZigZagBuffer[i];
ZigZagLow[i] = EMPTY_VALUE;
}
else
{
ZigZagHigh[i] = EMPTY_VALUE;
ZigZagLow[i] = ZigZagBuffer[i];
}
ZigZagTime[i] = barTime;
// Store in our point array - Warning-free assignment
if(zzPointCount < 10)
{
lastZZPoints[zzPointCount].Set(ZigZagBuffer[i], i, barTime, isHigh);
zzPointCount++;
}
}
}
return (zzPointCount >= 2); // Need at least 2 points for analysis
}
//+------------------------------------------------------------------+
//| Check if current time is within trading hours |
//+------------------------------------------------------------------+
bool IsTimeToTrade()
{
if(!UseTimeFilter)
return true;
datetime currentTime = TimeCurrent();
MqlDateTime dt;
TimeToStruct(currentTime, dt);
// Convert time strings to minutes
string startParts[];
string endParts[];
StringSplit(StartTime, ':', startParts);
StringSplit(EndTime, ':', endParts);
if(ArraySize(startParts) < 2 || ArraySize(endParts) < 2)
return true; // Invalid time format, allow trading
int startMinutes = (int)StringToInteger(startParts[0]) * 60 + (int)StringToInteger(startParts[1]);
int endMinutes = (int)StringToInteger(endParts[0]) * 60 + (int)StringToInteger(endParts[1]);
int currentMinutes = dt.hour * 60 + dt.min;
if(startMinutes <= endMinutes)
{
return (currentMinutes >= startMinutes && currentMinutes <= endMinutes);
}
else
{
// Overnight session
return (currentMinutes >= startMinutes || currentMinutes <= endMinutes);
}
}
//+------------------------------------------------------------------+
//| Convert period to string |
//+------------------------------------------------------------------+
string PeriodToString(ENUM_TIMEFRAMES period)
{
switch(period)
{
case PERIOD_M1: return "M1";
case PERIOD_M5: return "M5";
case PERIOD_M15: return "M15";
case PERIOD_M30: return "M30";
case PERIOD_H1: return "H1";
case PERIOD_H4: return "H4";
case PERIOD_D1: return "D1";
case PERIOD_W1: return "W1";
case PERIOD_MN1: return "MN1";
default: return "Unknown";
}
}
//+------------------------------------------------------------------+
//| Check for trade signals |
//+------------------------------------------------------------------+
void CheckTradeSignals()
{
// Don't place pending orders if a position is already open
if(PositionSelect(_Symbol)) return;
// Need at least 2 ZigZag points for analysis
if(zzPointCount < 2) return;
// Get the last two ZigZag points - Warning-free access
ZigZagPoint lastPoint, prevPoint;
lastZZPoints[0].GetCopy(lastPoint); // Most recent point
lastZZPoints[1].GetCopy(prevPoint); // Previous point
// Ensure we have valid points with minimum age
if(lastPoint.bar < MinBarsForSignal) return;
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double triggerDistance = TriggerPips * point * pointMultiplier;
// Check for bullish setup (last point is a low)
if(!lastPoint.isHigh && prevPoint.isHigh)
{
// Cancel any existing Sell Stop order
if(pendingOrderTicket > 0 && IsSellStopOrder())
{
ClosePendingOrder();
}
// Check if price has moved TriggerPips above the ZigZag low
double triggerPrice = lastPoint.price + triggerDistance;
if(currentPrice >= triggerPrice && pendingOrderTicket == 0)
{
PlaceBuyStopOrder(triggerPrice, lastPoint.price);
}
}
// Check for bearish setup (last point is a high)
else if(lastPoint.isHigh && !prevPoint.isHigh)
{
// Cancel any existing Buy Stop order
if(pendingOrderTicket > 0 && IsBuyStopOrder())
{
ClosePendingOrder();
}
// Check if price has moved TriggerPips below the ZigZag high
double triggerPrice = lastPoint.price - triggerDistance;
if(currentPrice <= triggerPrice && pendingOrderTicket == 0)
{
PlaceSellStopOrder(triggerPrice, lastPoint.price);
}
}
}
//+------------------------------------------------------------------+
//| Place Buy Stop Order |
//+------------------------------------------------------------------+
void PlaceBuyStopOrder(double triggerPrice, double pivotPrice)
{
// Close any existing pending order
ClosePendingOrder();
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double lots = LotSize;
if(UseRiskBasedLots)
{
lots = CalculateRiskBasedLots();
}
// Normalize lot size
lots = NormalizeLotSize(lots);
if(lots <= 0)
{
Print("Invalid lot size calculated: ", lots);
return;
}
double sl = 0;
double tp = 0;
if(StopLossPips > 0)
sl = triggerPrice - StopLossPips * point * pointMultiplier;
if(TakeProfitPips > 0)
tp = triggerPrice + TakeProfitPips * point * pointMultiplier;
// Check minimum stop level
long stopLevelLong = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
int stopLevel = (int)stopLevelLong;
double minDistance = stopLevel * point;
if(MathAbs(triggerPrice - ask) < minDistance)
{
Print("Cannot place Buy Stop: price too close to market (Stop Level: ", stopLevel, " points)");
return;
}
// Validate stop loss and take profit levels
if(sl > 0 && (triggerPrice - sl) < minDistance)
{
sl = triggerPrice - minDistance;
Print("Stop loss adjusted to minimum distance: ", sl);
}
if(tp > 0 && (tp - triggerPrice) < minDistance)
{
tp = triggerPrice + minDistance;
Print("Take profit adjusted to minimum distance: ", tp);
}
if(trade.BuyStop(lots, triggerPrice, _Symbol, sl, tp, ORDER_TIME_GTC, 0, TradeComment))
{
pendingOrderTicket = trade.ResultOrder();
Print("✓ Buy Stop order placed successfully");
Print(" Price: ", DoubleToString(triggerPrice, _Digits));
Print(" SL: ", DoubleToString(sl, _Digits));
Print(" TP: ", DoubleToString(tp, _Digits));
Print(" Lots: ", DoubleToString(lots, 2));
Print(" Ticket: ", pendingOrderTicket);
Print(" Pivot Price: ", DoubleToString(pivotPrice, _Digits));
}
else
{
uint errorCode = trade.ResultRetcode();
Print("✗ Failed to place Buy Stop order");
Print(" Error Code: ", errorCode);
Print(" Error Description: ", GetTradeErrorDescription((int)errorCode));
LogTradeError((int)errorCode);
}
}
//+------------------------------------------------------------------+
//| Place Sell Stop Order |
//+------------------------------------------------------------------+
void PlaceSellStopOrder(double triggerPrice, double pivotPrice)
{
// Close any existing pending order
ClosePendingOrder();
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double lots = LotSize;
if(UseRiskBasedLots)
{
lots = CalculateRiskBasedLots();
}
// Normalize lot size
lots = NormalizeLotSize(lots);
if(lots <= 0)
{
Print("Invalid lot size calculated: ", lots);
return;
}
double sl = 0;
double tp = 0;
if(StopLossPips > 0)
sl = triggerPrice + StopLossPips * point * pointMultiplier;
if(TakeProfitPips > 0)
tp = triggerPrice - TakeProfitPips * point * pointMultiplier;
// Check minimum stop level
long stopLevelLong = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
int stopLevel = (int)stopLevelLong;
double minDistance = stopLevel * point;
if(MathAbs(bid - triggerPrice) < minDistance)
{
Print("Cannot place Sell Stop: price too close to market (Stop Level: ", stopLevel, " points)");
return;
}
// Validate stop loss and take profit levels
if(sl > 0 && (sl - triggerPrice) < minDistance)
{
sl = triggerPrice + minDistance;
Print("Stop loss adjusted to minimum distance: ", sl);
}
if(tp > 0 && (triggerPrice - tp) < minDistance)
{
tp = triggerPrice - minDistance;
Print("Take profit adjusted to minimum distance: ", tp);
}
if(trade.SellStop(lots, triggerPrice, _Symbol, sl, tp, ORDER_TIME_GTC, 0, TradeComment))
{
pendingOrderTicket = trade.ResultOrder();
Print("✓ Sell Stop order placed successfully");
Print(" Price: ", DoubleToString(triggerPrice, _Digits));
Print(" SL: ", DoubleToString(sl, _Digits));
Print(" TP: ", DoubleToString(tp, _Digits));
Print(" Lots: ", DoubleToString(lots, 2));
Print(" Ticket: ", pendingOrderTicket);
Print(" Pivot Price: ", DoubleToString(pivotPrice, _Digits));
}
else
{
uint errorCode = trade.ResultRetcode();
Print("✗ Failed to place Sell Stop order");
Print(" Error Code: ", errorCode);
Print(" Error Description: ", GetTradeErrorDescription((int)errorCode));
LogTradeError((int)errorCode);
}
}
//+------------------------------------------------------------------+
//| Check if existing pending order is a Buy Stop |
//+------------------------------------------------------------------+
bool IsBuyStopOrder()
{
if(pendingOrderTicket == 0) return false;
if(OrderSelect(pendingOrderTicket))
{
return OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP;
}
return false;
}
//+------------------------------------------------------------------+
//| Check if existing pending order is a Sell Stop |
//+------------------------------------------------------------------+
bool IsSellStopOrder()
{
if(pendingOrderTicket == 0) return false;
if(OrderSelect(pendingOrderTicket))
{
return OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP;
}
return false;
}
//+------------------------------------------------------------------+
//| Close existing pending order |
//+------------------------------------------------------------------+
void ClosePendingOrder()
{
if(pendingOrderTicket == 0) return;
if(OrderSelect(pendingOrderTicket))
{
ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
string orderTypeStr = (orderType == ORDER_TYPE_BUY_STOP) ? "Buy Stop" : "Sell Stop";
if(trade.OrderDelete(pendingOrderTicket))
{
Print("✓ ", orderTypeStr, " order deleted successfully. Ticket: ", pendingOrderTicket);
pendingOrderTicket = 0;
}
else
{
Print("✗ Failed to delete ", orderTypeStr, " order. Ticket: ", pendingOrderTicket, " Error: ", trade.ResultRetcode());
}
}
else
{
// Order no longer exists, reset ticket
pendingOrderTicket = 0;
}
}
//+------------------------------------------------------------------+
//| Calculate risk-based lot size |
//+------------------------------------------------------------------+
double CalculateRiskBasedLots()
{
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double riskAmount = balance * MaxRiskPercent / 100.0;
double stopLossPoints = StopLossPips * pointMultiplier;
if(stopLossPoints <= 0)
{
Print("Invalid stop loss for risk calculation, using fixed lot size");
return LotSize;
}
// Calculate tick value
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
if(tickValue == 0 || tickSize == 0)
{
Print("Cannot get tick value/size, using fixed lot size");
return LotSize;
}
// Calculate value per point
double valuePerPoint = (tickValue / tickSize) * point;
// Calculate lot size based on risk
double lots = riskAmount / (stopLossPoints * valuePerPoint);
return lots;
}
//+------------------------------------------------------------------+
//| Normalize lot size according to symbol specifications |
//+------------------------------------------------------------------+
double NormalizeLotSize(double lots)
{
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
if(lotStep == 0) lotStep = 0.01;
// Round to lot step
lots = MathFloor(lots / lotStep) * lotStep;
// Apply min/max limits
lots = MathMax(lots, minLot);
lots = MathMin(lots, maxLot);
return lots;
}
//+------------------------------------------------------------------+
//| Manage existing positions |
//+------------------------------------------------------------------+
void ManagePositions()
{
if(!PositionSelect(_Symbol)) return;
if(UseTrailingStop)
{
TrailingStop();
}
// Reset pending order ticket if position exists (order was executed)
if(pendingOrderTicket > 0)
{
pendingOrderTicket = 0;
}
}
//+------------------------------------------------------------------+
//| Trailing Stop function |
//+------------------------------------------------------------------+
void TrailingStop()
{
if(!PositionSelect(_Symbol)) return;
double positionOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double currentSL = PositionGetDouble(POSITION_SL);
double currentTP = PositionGetDouble(POSITION_TP);
long positionType = PositionGetInteger(POSITION_TYPE);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double trailDistance = TrailingStopPips * point * pointMultiplier;
double trailStep = TrailingStepPips * point * pointMultiplier;
bool modifyRequired = false;
double newSL = currentSL;
if(positionType == POSITION_TYPE_BUY)
{
double proposedSL = bid - trailDistance;
// Only move SL if it's better than current and meets step requirement
if(proposedSL > currentSL + trailStep || (currentSL == 0 && bid > positionOpenPrice + trailDistance))
{
newSL = proposedSL;
modifyRequired = true;
}
}
else if(positionType == POSITION_TYPE_SELL)
{
double proposedSL = ask + trailDistance;
// Only move SL if it's better than current and meets step requirement
if(proposedSL < currentSL - trailStep || (currentSL == 0 && ask < positionOpenPrice - trailDistance))
{
newSL = proposedSL;
modifyRequired = true;
}
}
if(modifyRequired)
{
if(trade.PositionModify(_Symbol, newSL, currentTP))
{
Print("✓ Trailing stop updated. New SL: ", DoubleToString(newSL, _Digits));
}
else
{
Print("✗ Failed to update trailing stop. Error: ", trade.ResultRetcode());
}
}
}
//+------------------------------------------------------------------+
//| Check if trading is allowed |
//+------------------------------------------------------------------+
bool IsTradeAllowed()
{
// Check if automated trading is allowed in the terminal
if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
{
static datetime lastWarning = 0;
if(TimeCurrent() - lastWarning > 300) // Warning every 5 minutes
{
Print("Automated trading is not allowed in the terminal");
lastWarning = TimeCurrent();
}
return false;
}
// Check if trading is allowed in the terminal
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
{
static datetime lastWarning = 0;
if(TimeCurrent() - lastWarning > 300)
{
Print("Trading is disabled in the terminal");
lastWarning = TimeCurrent();
}
return false;
}
// Check symbol trade mode
long tradeMode = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE);
if(tradeMode == SYMBOL_TRADE_MODE_DISABLED)
{
static datetime lastWarning = 0;
if(TimeCurrent() - lastWarning > 300)
{
Print("Trading is disabled for symbol ", _Symbol);
lastWarning = TimeCurrent();
}
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Get trade error description |
//+------------------------------------------------------------------+
string GetTradeErrorDescription(int errorCode)
{
switch(errorCode)
{
case TRADE_RETCODE_REQUOTE: return "Requote";
case TRADE_RETCODE_REJECT: return "Request rejected";
case TRADE_RETCODE_CANCEL: return "Request canceled";
case TRADE_RETCODE_PLACED: return "Order placed";
case TRADE_RETCODE_DONE: return "Request completed";
case TRADE_RETCODE_DONE_PARTIAL: return "Request completed partially";
case TRADE_RETCODE_ERROR: return "Request processing error";
case TRADE_RETCODE_TIMEOUT: return "Request canceled by timeout";
case TRADE_RETCODE_INVALID: return "Invalid request";
case TRADE_RETCODE_INVALID_VOLUME: return "Invalid volume";
case TRADE_RETCODE_INVALID_PRICE: return "Invalid price";
case TRADE_RETCODE_INVALID_STOPS: return "Invalid stops";
case TRADE_RETCODE_TRADE_DISABLED: return "Trade disabled";
case TRADE_RETCODE_MARKET_CLOSED: return "Market closed";
case TRADE_RETCODE_NO_MONEY: return "No money";
case TRADE_RETCODE_PRICE_CHANGED: return "Price changed";
case TRADE_RETCODE_PRICE_OFF: return "Off quotes";
case TRADE_RETCODE_INVALID_EXPIRATION: return "Invalid expiration";
case TRADE_RETCODE_ORDER_CHANGED: return "Order state changed";
case TRADE_RETCODE_TOO_MANY_REQUESTS: return "Too frequent requests";
case TRADE_RETCODE_NO_CHANGES: return "No changes";
case TRADE_RETCODE_SERVER_DISABLES_AT: return "Autotrading disabled by server";
case TRADE_RETCODE_CLIENT_DISABLES_AT: return "Autotrading disabled by client";
case TRADE_RETCODE_LOCKED: return "Request locked";
case TRADE_RETCODE_FROZEN: return "Order or position frozen";
case TRADE_RETCODE_INVALID_FILL: return "Invalid fill";
case TRADE_RETCODE_CONNECTION: return "No connection";
case TRADE_RETCODE_ONLY_REAL: return "Only real accounts allowed";
case TRADE_RETCODE_LIMIT_ORDERS: return "Orders limit reached";
case TRADE_RETCODE_LIMIT_VOLUME: return "Volume limit reached";
default: return "Unknown error";
}
}
//+------------------------------------------------------------------+
//| Log detailed trade error information |
//+------------------------------------------------------------------+
void LogTradeError(int errorCode)
{
Print("=== TRADE ERROR DETAILS ===");
Print("Error Code: ", errorCode);
Print("Description: ", GetTradeErrorDescription(errorCode));
Print("Symbol: ", _Symbol);
Print("Account Balance: ", DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE), 2));
Print("Account Equity: ", DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY), 2));
Print("Account Margin: ", DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN), 2));
Print("Symbol Spread: ", (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD));
Print("===========================");
}
//+------------------------------------------------------------------+
//| Expert Advisor Event Handlers |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
const MqlTradeRequest& request,
const MqlTradeResult& result)
{
// Handle order execution
if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
{
if(trans.order == pendingOrderTicket)
{
Print("✓ Pending order executed. Deal ID: ", trans.deal);
pendingOrderTicket = 0; // Reset ticket
}
}
// Handle order deletion
if(trans.type == TRADE_TRANSACTION_ORDER_DELETE)
{
if(trans.order == pendingOrderTicket)
{
Print(":information_source: Pending order deleted. Order ID: ", trans.order);
pendingOrderTicket = 0; // Reset ticket
}
}
}
//+------------------------------------------------------------------+
[list][*][/list] TSLA: 30-Dec-22 123.18 // 16-Jun-23 260.54 **111.51%**
1
- #78,849
- Edited 4:49am Aug 23, 2025 1:19am | Edited 4:49am
Hi everyone, it is possible to add multi timeframe on this indicator. TQ
Attached File(s)
- #78,850
- Aug 23, 2025 2:16am Aug 23, 2025 2:16am
- Joined Apr 2017 | Status: Trader | 1,111 Posts
Masters Please we have custom timeframe candle for mt4 are there custom timeframes Moving Averages for MT4 , please kindly share if you have or any reference will help( where user have options of 5-10 MA;S and can apply highlow or crosses functions)
- #78,851
- Aug 23, 2025 4:43am Aug 23, 2025 4:43am
- Joined Mar 2022 | Status: Trader | 6,558 Posts
DislikedMasters Please we have custom timeframe candle for mt4 are there custom timeframes Moving Averages for MT4 , please kindly share if you have or any reference will help( where user have options of 5-10 MA;S and can apply highlow or crosses functions)Ignored
.ex4/.ex5 files can't be fixed or modified / I'm not a coder!
- #78,852
- Aug 23, 2025 5:32am Aug 23, 2025 5:32am
- Joined Feb 2012 | Status: Trader | 1,994 Posts
Disliked{quote} I bet that you already have such an indicator, because it was posted here many times, and on other forums, too. {image}Ignored
Attached File(s)
- #78,853
- Aug 23, 2025 6:04am Aug 23, 2025 6:04am
- Joined Apr 2017 | Status: Trader | 1,111 Posts
Disliked{quote} I bet that you already have such an indicator, because it was posted here many times, and on other forums, too. {image}Ignored
please can it be with up to 10MA'S options in one indicator? i currently use one of Jeanlouies MA'S its up to 8 but has no custom timeframes options
- #78,854
- Aug 23, 2025 7:13am Aug 23, 2025 7:13am
- Joined Sep 2018 | Status: Trader Man | 2,123 Posts
Hello fellow programmers, I'm conducting a study and would like to know if anyone can help me with this indicator.
This indicator isn't displaying completely on the chart. If possible, adjusting it to display it completely and also making the connecting points (yellow) magnetic would be a good idea.
Drag the two yellow points (Trig_Point1 and Trig_Point2) to the desired maximum and minimum values.
The square tilts automatically; the circle and radii adjust; the quadrant text appears inside.
Thank you in advance for your generous attention and help with this.
This indicator isn't displaying completely on the chart. If possible, adjusting it to display it completely and also making the connecting points (yellow) magnetic would be a good idea.
Drag the two yellow points (Trig_Point1 and Trig_Point2) to the desired maximum and minimum values.
The square tilts automatically; the circle and radii adjust; the quadrant text appears inside.
Thank you in advance for your generous attention and help with this.
Attached File(s)
"No pain no gain"
- #78,855
- Aug 23, 2025 7:25am Aug 23, 2025 7:25am
- Joined Sep 2017 | Status: Trader | 2,686 Posts
i am a big fan of grid trading,adding to the profitable ones,can please someone guide me as waht should be the pipstep and lot multiplier? there is a science behind it,i want a seasoned trader to please mentor me on it,thanking you.I want to learn the recipe of success behind this concept.
- #78,856
- Aug 23, 2025 7:37am Aug 23, 2025 7:37am
Disliked{quote} No source, but to change the source prices of zz to something else, there are only a few areas to change, and the change would be like- //extremum=low[iLowest(NULL,0,MODE_LOW,InpDepth,i)]; extremum=b_ma[ArrayMinimum(b_ma,InpDepth,i)]; //if(low[i]-extremum>InpDeviation*Point) if(b_ma[i]-extremum>InpDeviation*Point) ZZ_on_MA - regular zz but based on a ma {file} {image}Ignored
Can we have a draggable trendline parrallel to the straight trendline created by the ma please
Cheers Eamonn
- #78,857
- Edited 6:04pm Aug 23, 2025 10:37am | Edited 6:04pm
- Joined Dec 2010 | Status: Trader | 2,136 Posts
Disliked{quote}...draggable trendline parrallel to the straight trendline created by the ma...Ignored
ZZ_on_ma
- v1.1
- optional channel on the zz
- point distance
- optional draggable trendlines on the channel section to ray
gif
Attached File(s)
3
DislikedHello fellow programmers, I'm conducting a study and would like to know if anyone can help me with this indicator. This indicator isn't displaying completely on the chart. If possible, adjusting it to display it completely and also making the connecting points (yellow) magnetic would be a good idea. Drag the two yellow points (Trig_Point1 and Trig_Point2) to the desired maximum and minimum values. The square tilts automatically; the circle and radii adjust; the quadrant text appears inside. Thank you in advance for your generous attention and help...Ignored
How to Use It
Lock Point 1 on a swing high and Point 2 on a swing low.
Middle = balance point, edges = boundaries, lines = timing/targets.
Range trade: if price rejects at an edge + line, trade back toward the middle. Stop just outside, aim for middle then next line.
Breakout trade: if price closes past an edge, wait for retest, then enter. Stop inside, target the next line or opposite edge, trail line by line.
Look for extra confirmation with support/resistance, trendlines, EMAs, or volume.
Risk small (1–2%). Always use stops. If price crosses the middle against you, cut or exit.
Tip: use 10–15° spacing for clean grids; snap anchors to real highs/lows.
Let me know.
Attached File(s)
If I follow my system, the outcome doesn’t define me — the process does.
- #78,860
- Aug 23, 2025 1:14pm Aug 23, 2025 1:14pm
- Joined Sep 2018 | Status: Trader Man | 2,123 Posts
Disliked{quote} How to Use It Lock Point 1 on a swing high and Point 2 on a swing low. Middle = balance point, edges = boundaries, lines = timing/targets. Range trade: if price rejects at an edge + line, trade back toward the middle. Stop just outside, aim for middle then next line. Breakout trade: if price closes past an edge, wait for retest, then enter. Stop inside, target the next line or opposite edge, trail line by line. Look for extra confirmation with support/resistance, trendlines, EMAs, or volume. Risk small (1–2%). Always use stops. If price...Ignored
First of all, thank you very much for responding to my request.
I tried the chart, but without success. Could you check if there's a bug or if it's just unavailable on my MT4?
If possible, please send a screenshot of the indicator working on your chart.
Thank you for your attention!
"No pain no gain"