Add OrdersEA_Smart_Grid v3.0 - Auto pivot + RSI/ADX filters
This commit is contained in:
428
OrdersEA_Smart_Grid.mq4
Normal file
428
OrdersEA_Smart_Grid.mq4
Normal file
@@ -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 <WinUser32.mqh>
|
||||
|
||||
#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
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user