diff --git a/OrdersEA_Smart_Grid.mq4 b/OrdersEA_Smart_Grid.mq4 new file mode 100644 index 0000000..d186a92 --- /dev/null +++ b/OrdersEA_Smart_Grid.mq4 @@ -0,0 +1,428 @@ +//+------------------------------------------------------------------+ +//| 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 + +#include + +#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=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 + if(RSICurrent != 0) IndicatorRelease(RSICurrent); + if(ADXHandle != 0) IndicatorRelease(ADXHandle); + if(ATRHandle != 0) IndicatorRelease(ATRHandle); + + 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; + } + }