Files
mql-trading-bots/OrdersEA_Smart_Grid.mq4
Garfield 4bbf470ed6 Fix OrdersEA_Smart_Grid compile errors
- Removed WinUser32.mqh include (path issues)
- Removed IndicatorRelease calls (MT5 only function)
- MT4 doesn't require explicit indicator cleanup
2026-03-24 14:14:50 -04:00

427 lines
13 KiB
Plaintext

//+------------------------------------------------------------------+
//| OrdersEA_Smart_Grid.mq4 |
//| Copyright 2024, Garfield Heron |
//| https://fetcherpay.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Garfield Heron"
#property link "https://fetcherpay.com"
#property version "3.0"
#property strict
// WinUser32.mqh removed - not needed for core functionality
#define VERSION "Version 3.0 Smart Grid"
#define MAX_TRADES 600
#define MAX_LOG_TRADES 1200
//--- Input Parameters
extern string Email= "garfield@fetcherpay.com";
extern int MagicNum= 333;
//--- Smart Grid Settings
extern string GridSettings = "=== Smart Grid Settings ===";
extern bool UseAutoPivots = true; // Auto-calculate pivot points
extern double HIGH= 0; // Manual HIGH (if UseAutoPivots=false)
extern double LOW= 0; // Manual LOW (if UseAutoPivots=false)
extern double Entry= 10; // Grid spacing in pips
extern double TP= 15; // Take profit per level
extern double Lots=0.01; // Lot size per trade
extern int MaxLevels = 10; // Max grid levels per side
//--- Range Filter Settings
extern string FilterSettings = "=== Range Filters ===";
extern bool UseRSIFilter = true; // Enable RSI filter
extern int RSIPeriod = 14; // RSI period
extern int RSILower = 35; // RSI lower bound (buy zone)
extern int RSIUpper = 65; // RSI upper bound (sell zone)
extern bool UseADXFilter = true; // Enable ADX filter
extern int ADXPeriod = 14; // ADX period
extern double ADXMax = 25; // Max ADX for ranging (below=trending)
extern bool UseATRFilter = true; // Enable ATR filter
extern int ATRPeriod = 14; // ATR period
extern double ATRMultiplier = 1.5; // ATR multiplier for range width
//--- Risk Management
extern string RiskSettings = "=== Risk Management ===";
extern int StopLoss=0;
extern int TRADE_RANGE= 50;
extern double LongLimit= 0;
extern double ShortLimit= 0;
extern string GetOut= "N";
extern string OpenNewTrades="Y";
extern bool Opposite= false;
extern int TakeProfitLevelPercent= 50;
extern int TakeProfitLevelDollarAmount= 2000;
extern bool Restart= true;
extern int EquityFactorPercent= 0;
extern int LotsFactorPercent= 0;
extern int BaseEquity= 10000;
extern bool Master= false;
extern bool DiagnosticModeOn= false;
//--- Indicator Handles
int RSICurrent = 0;
int ADXHandle = 0;
int ATRHandle = 0;
//--- Pivot Point Variables
double PivotP = 0;
double PivotR1 = 0;
double PivotR2 = 0;
double PivotS1 = 0;
double PivotS2 = 0;
//--- Original OrdersEA Variables
int initialCycleEquity= 0;
int longs, shorts;
int longsTicket[MAX_TRADES];
int shortsTicket[MAX_TRADES];
int logTickets[MAX_LOG_TRADES];
int logTicketsTime[MAX_LOG_TRADES];
int logTicketsCounter;
int Levels;
double price[MAX_TRADES];
int stoplevel;
bool bFirstTick= false;
int logId;
bool bEnableLongs;
bool bEnableShorts;
double tickValue;
int MaximalLoss;
int lastTicketSentOpen= 0, lastTicketSentClose= 0;
double longAvgPrice= 0, longAvgLots= 0;
double shortAvgPrice= 0, shortAvgLots= 0;
double longProfit= 0;
double shortProfit= 0;
bool bConfirmed;
bool bOpposite;
bool bInit= false;
int TakeProfit=0;
bool AboveHigh;
bool BelowLow;
int tradeLogId;
double closeOnProfit;
bool bGetOutOK, bOpenNewTradesOK;
int initEquity;
int lotDigits;
bool bWithdrawMailSent= false;
bool bGetOutHandled;
int PingTimeMinutes= 240;
bool bAccess;
bool bValidSettings;
string errMsg;
datetime PivotCalculationTime = 0;
bool TradeExecutedToday = false;
bool R1HitToday = false;
bool S1HitToday = false;
double P, R1, R2, S1, S2;
bool PivotsCalculated = false;
//+------------------------------------------------------------------+
//| Calculate Pivot Points |
//+------------------------------------------------------------------+
void CalculatePivotPoints()
{
// Get yesterday's data
datetime yesterday = Time[0] - PeriodSeconds(PERIOD_D1);
int shift = iBarShift(NULL, PERIOD_D1, yesterday);
double prevHigh = iHigh(NULL, PERIOD_D1, shift);
double prevLow = iLow(NULL, PERIOD_D1, shift);
double prevClose = iClose(NULL, PERIOD_D1, shift);
// Standard Pivot Formula
PivotP = (prevHigh + prevLow + prevClose) / 3.0;
PivotR1 = (2.0 * PivotP) - prevLow;
PivotS1 = (2.0 * PivotP) - prevHigh;
PivotR2 = PivotP + (prevHigh - prevLow);
PivotS2 = PivotP - (prevHigh - prevLow);
// Set HIGH/LOW if auto-pivots enabled
if(UseAutoPivots)
{
// Use R1/S1 for narrow range, R2/S2 for wider
double atr = iATR(NULL, 0, ATRPeriod, 0);
if(UseATRFilter && atr > 0)
{
// ATR-based adaptive range
HIGH = NormalizeDouble(PivotP + (atr * ATRMultiplier), Digits);
LOW = NormalizeDouble(PivotP - (atr * ATRMultiplier), Digits);
}
else
{
// Standard pivot-based range
HIGH = PivotR1;
LOW = PivotS1;
}
}
Print("Pivot Calculated: P=", PivotP, " R1=", PivotR1, " S1=", PivotS1);
Print("Grid Range: HIGH=", HIGH, " LOW=", LOW);
}
//+------------------------------------------------------------------+
//| Check if Market is Ranging (Good for Grid) |
//+------------------------------------------------------------------+
bool IsRangingMarket()
{
bool isRanging = true;
//--- RSI Filter
if(UseRSIFilter)
{
double rsi = iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE, 0);
if(rsi < RSILower || rsi > RSIUpper)
{
Print("RSI Filter: Market at extremes (RSI=", rsi, "), skipping grid");
isRanging = false;
}
}
//--- ADX Filter
if(UseADXFilter && isRanging)
{
double adx = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_MAIN, 0);
if(adx > ADXMax)
{
Print("ADX Filter: Market trending (ADX=", adx, "), skipping grid");
isRanging = false;
}
}
//--- Price Position Filter
double currentPrice = Bid;
if(currentPrice > HIGH || currentPrice < LOW)
{
Print("Price outside grid range, waiting for re-entry");
isRanging = false;
}
return isRanging;
}
//+------------------------------------------------------------------+
//| Get Grid Lot Size (Original CalcLots) |
//+------------------------------------------------------------------+
double CalcLots()
{
double tmp= (AccountEquity()-initEquity);
double a= EquityFactorPercent;
double b= LotsFactorPercent;
double lots;
if(0==EquityFactorPercent || 0==LotsFactorPercent)
lots= Lots;
else
{
a=initEquity*a/100;
b=b/100;
if(tmp>0)
tmp= MathPow(1+b,(tmp/a));
else if(tmp<0)
tmp= MathPow(1-b,MathAbs(tmp/a));
else
tmp= 1;
lots= NormalizeDouble(Lots*tmp,lotDigits);
if(lots<MarketInfo(Symbol(),MODE_MINLOT))
lots= MarketInfo(Symbol(),MODE_MINLOT);
}
if(lots<0)
Log("ERROR tmp="+tmp+",a="+a+",b="+b+",AccountEquity()="+AccountEquity());
Log("Equity="+AccountEquity()+",lots="+lots);
return(lots);
}
//+------------------------------------------------------------------+
//| Add Trade to Log |
//+------------------------------------------------------------------+
void AddTradeToLog(int ticket)
{
bool rc= false;
int i=0;
for(i=0; i<logTicketsCounter; i++)
{
if(logTickets[i]==ticket)
{
rc= true;
break;
}
}
if(!rc && i<MAX_LOG_TRADES)
{
logTickets[logTicketsCounter]= ticket;
logTicketsTime[logTicketsCounter]= TimeCurrent();
logTicketsCounter++;
}
}
//+------------------------------------------------------------------+
//| Send Notification |
//+------------------------------------------------------------------+
void SendNotificationEx(string title, string subject)
{
string st= subject;
if(!IsOptimization())
{
st= st + "Price now: " + DoubleToStr(Bid, Digits) + "\n";
st= st +"Longs: " + longs + " @ " + DoubleToStr(longAvgPrice, Digits) + "\n";
st= st +"Shorts: " + shorts + " @ " + DoubleToStr(shortAvgPrice, Digits) + "\n";
st= st +"Account Equity: + "+ AccountEquity() +"\n";
st= st +"Account Balance: + "+ AccountBalance() +"\n";
SendMail(title, st);
}
}
//+------------------------------------------------------------------+
//| Log function |
//+------------------------------------------------------------------+
void Log(string st)
{
if(DiagnosticModeOn)
if(logId>=0)
{
FileWrite(logId, TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS) + ": " + st);
}
}
//+------------------------------------------------------------------+
//| Expert initialization |
//+------------------------------------------------------------------+
int OnInit()
{
// Initialize indicators
if(UseRSIFilter)
RSICurrent = iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE);
if(UseADXFilter)
ADXHandle = iADX(NULL, 0, ADXPeriod);
if(UseATRFilter)
ATRHandle = iATR(NULL, 0, ATRPeriod);
// Calculate initial pivot points
CalculatePivotPoints();
// Rest of original init
PivotsCalculated = false;
stoplevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
if(stoplevel <= 0) stoplevel = 0;
Print("Smart Grid EA Initialized");
Print("AutoPivots: ", UseAutoPivots);
Print("RSI Filter: ", UseRSIFilter, " (", RSILower, "-", RSIUpper, ")");
Print("ADX Filter: ", UseADXFilter, " (<", ADXMax, ")");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Cleanup indicators
// MT4 doesn't require explicit indicator release
if(logId>=0)
FileClose(logId);
Print("Smart Grid EA Deinitialized");
}
//+------------------------------------------------------------------+
//| Expert tick function - Smart Grid Logic |
//+------------------------------------------------------------------+
void OnTick()
{
// Recalculate pivots at new day
datetime TimeNow = TimeCurrent();
if(TimeHour(TimeNow) == 0 && TimeMinute(TimeNow) < 5)
{
CalculatePivotPoints();
}
// Check if we should trade (ranging market?)
if(!IsRangingMarket())
{
// Close existing grid if market starts trending
if(GetOut == "Y" || GetOut == "y")
{
// CloseAllTrades logic here
}
return;
}
// Original OrdersEA grid logic would go here
// (Simplified for this template)
static datetime lastBarTime = 0;
datetime currentBarTime = iTime(NULL, 0, 0);
if(currentBarTime != lastBarTime)
{
lastBarTime = currentBarTime;
// Place grid orders logic
// This is where you'd integrate the full OrdersEA order placement
Print("Smart Grid: RSI=", iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,0),
" ADX=", iADX(NULL,0,ADXPeriod,PRICE_CLOSE,MODE_MAIN,0),
" Range: ", LOW, " - ", HIGH);
}
}
//+------------------------------------------------------------------+
//| Place Buy Order at Level |
//+------------------------------------------------------------------+
bool PlaceBuyLevel(double priceLevel, int level)
{
if(level >= MaxLevels) return false;
double lots = CalcLots();
double sl = (StopLoss > 0) ? priceLevel - (StopLoss * Point) : 0;
double tp = priceLevel + (TP * Point);
int ticket = OrderSend(Symbol(), OP_BUYSTOP, lots, priceLevel, 3, sl, tp,
"Smart Grid Buy " + IntegerToString(level), MagicNum, 0, clrBlue);
if(ticket > 0)
{
Print("Buy Level ", level, " placed at ", priceLevel);
return true;
}
else
{
Print("Error placing buy level: ", GetLastError());
return false;
}
}
//+------------------------------------------------------------------+
//| Place Sell Order at Level |
//+------------------------------------------------------------------+
bool PlaceSellLevel(double priceLevel, int level)
{
if(level >= MaxLevels) return false;
double lots = CalcLots();
double sl = (StopLoss > 0) ? priceLevel + (StopLoss * Point) : 0;
double tp = priceLevel - (TP * Point);
int ticket = OrderSend(Symbol(), OP_SELLSTOP, lots, priceLevel, 3, sl, tp,
"Smart Grid Sell " + IntegerToString(level), MagicNum, 0, clrRed);
if(ticket > 0)
{
Print("Sell Level ", level, " placed at ", priceLevel);
return true;
}
else
{
Print("Error placing sell level: ", GetLastError());
return false;
}
}