Bi-Directional Fixed Lot Grid Recovery EA - Gold Auto Trading Bot 0.01
//+------------------------------------------------------------------+
//| Karlos_Safe_Gold_Magic.mq5 |
//| Copyright 2026, Daniyen Aline |
//+------------------------------------------------------------------+
#property strict
#include <Trade/Trade.mqh>
CTrade trade;
//--- Input Parameters
input double FixedLot = 0.01; // Sirf 0.01 trades (Sabse Safe)
input int MaxTradesSide = 15; // Ek side par max 15 trades
input int GridDistance = 300; // Gold ke liye distance
input double TargetProfit = 1.0; // $1 profit par exit target
input double TrailingProfit = 0.3; // Profit trail karne ke liye
input double MaxDDPercent = 20; // 20% loss par safety exit
//--- Global Variables
datetime lastCandleTime = 0;
double maxSeenProfitBuy = 0;
double maxSeenProfitSell = 0;
//+------------------------------------------------------------------+
void OnTick()
{
if(CheckEquityProtection()) return;
// Manage Profits
ManageSmartExit(POSITION_TYPE_BUY);
ManageSmartExit(POSITION_TYPE_SELL);
// Continuous Activity check
datetime currentCandle = (datetime)SeriesInfoInteger(_Symbol, PERIOD_M1, SERIES_LASTBAR_DATE);
if(currentCandle != lastCandleTime)
{
CheckInitialEntry();
lastCandleTime = currentCandle;
}
// Grid Recovery
ExecuteGrid(POSITION_TYPE_BUY);
ExecuteGrid(POSITION_TYPE_SELL);
}
//--- Entry Logic
void CheckInitialEntry()
{
if(CountPositions(POSITION_TYPE_BUY) == 0) trade.Buy(FixedLot, _Symbol);
if(CountPositions(POSITION_TYPE_SELL) == 0) trade.Sell(FixedLot, _Symbol);
}
//--- Grid Logic
void ExecuteGrid(ENUM_POSITION_TYPE type)
{
if(CountPositions(type) >= MaxTradesSide) return;
double lastPrice = GetLastTradePrice(type);
if(lastPrice == 0) return;
double currPrice = (type == POSITION_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID);
bool canTrade = false;
if(type == POSITION_TYPE_BUY && currPrice < (lastPrice - GridDistance * _Point)) canTrade = true;
if(type == POSITION_TYPE_SELL && currPrice > (lastPrice + GridDistance * _Point)) canTrade = true;
if(canTrade)
{
if(type == POSITION_TYPE_BUY) trade.Buy(FixedLot, _Symbol);
else trade.Sell(FixedLot, _Symbol);
}
}
//--- Trailing Exit Logic
void ManageSmartExit(ENUM_POSITION_TYPE type)
{
double p = GetTotalProfit(type);
if(type == POSITION_TYPE_BUY)
{
if(p > TargetProfit)
{
if(p > maxSeenProfitBuy) maxSeenProfitBuy = p;
if(p < maxSeenProfitBuy - TrailingProfit) { CloseAll(type); maxSeenProfitBuy = 0; }
}
else maxSeenProfitBuy = 0;
}
if(type == POSITION_TYPE_SELL)
{
if(p > TargetProfit)
{
if(p > maxSeenProfitSell) maxSeenProfitSell = p;
if(p < maxSeenProfitSell - TrailingProfit) { CloseAll(type); maxSeenProfitSell = 0; }
}
else maxSeenProfitSell = 0;
}
}
//--- Safety: Equity Guard
bool CheckEquityProtection()
{
double bal = AccountInfoDouble(ACCOUNT_BALANCE);
double eq = AccountInfoDouble(ACCOUNT_EQUITY);
if(eq < bal * (1 - MaxDDPercent/100))
{
CloseAll(POSITION_TYPE_BUY);
CloseAll(POSITION_TYPE_SELL);
return true;
}
return false;
}
//--- Helper Functions
int CountPositions(ENUM_POSITION_TYPE type)
{
int c = 0;
for(int i=0; i<PositionsTotal(); i++)
{
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket) && PositionGetInteger(POSITION_TYPE) == type && PositionGetString(POSITION_SYMBOL) == _Symbol) c++;
}
return c;
}
double GetTotalProfit(ENUM_POSITION_TYPE type)
{
double tp = 0;
for(int i=0; i<PositionsTotal(); i++)
{
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket) && PositionGetInteger(POSITION_TYPE) == type && PositionGetString(POSITION_SYMBOL) == _Symbol)
tp += PositionGetDouble(POSITION_PROFIT);
}
return tp;
}
double GetLastTradePrice(ENUM_POSITION_TYPE type)
{
double lp = 0; datetime lt = 0;
for(int i=0; i<PositionsTotal(); i++)
{
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket) && PositionGetInteger(POSITION_TYPE) == type && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
if(PositionGetInteger(POSITION_TIME) > lt)
{
lt = (datetime)PositionGetInteger(POSITION_TIME);
lp = PositionGetDouble(POSITION_PRICE_OPEN);
}
}
}
return lp;
}
void CloseAll(ENUM_POSITION_TYPE type)
{
for(int i=PositionsTotal()-1; i>=0; i--)
{
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket) && PositionGetInteger(POSITION_TYPE) == type && PositionGetString(POSITION_SYMBOL) == _Symbol)
trade.PositionClose(ticket);
}
}
Comments
Post a Comment