mql5/Experts/Motivated/Utils/CommonHelper.mqh
younglubah-gmail 9639b8b362
2026-06-23 21:44:37 +02:00

459 lines
12 KiB
MQL5

//+------------------------------------------------------------------+
//| CommonHelper.mqh |
//| Copyright 2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#include <Mql5Book\Barsbydate.mqh>
#include <Mql5Book\Timer.mqh>
#include "Indicator.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class StructureLevels
{
public:
TimePrice protectedHigh;
TimePrice protectedLow;
TimePrice bullNoBos;
TimePrice bearNoBos;
TimePrice bullConfirmedLow;
TimePrice bearConfirmedHigh;
int direction;
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CommonHelper
{
private:
ENUM_TIMEFRAMES timeframe;
string symbol;
CBarsbydate bar;
CNewBar newBar;
public:
CommonHelper();
~CommonHelper();
Swing swing;
void UpdateBars(ENUM_TIMEFRAMES timefrme, string symbl, bool useMonths = false, int monthsBack = 100)
{
timeframe = timefrme;
symbol = symbl;
bar.UpdateFromMonthsBack(symbol, timeframe, monthsBack, useMonths);
swing.UpdateFromMonthsBack(monthsBack, useMonths);
}
int OnInit(string s, ENUM_TIMEFRAMES tf, int lr = 3, int look = 1)
{
symbol = s;
timeframe = tf;
bar.SetAsSeries(false);
swing.SetAsSeries(false);
if(swing.Init("Fractal", s, tf, lr, look) == -1)
{
Print("Error creating Swing Indicator: ", GetLastError());
return INIT_FAILED;
}
return INIT_SUCCEEDED;
}
void SetAsSeries(bool isAsSeries)
{
bar.SetAsSeries(isAsSeries);
}
bool OnNewBar()
{
return newBar.CheckNewBar(symbol, timeframe);
}
int Bars()
{
return bar.Size();
}
int LastBar()
{
return bar.Size() - 1;
}
bool HasBars(int count)
{
return bar.Size() >= count;
}
bool IsValidIndex(int index = 0)
{
return (index >= 0 && index < bar.Size());
}
datetime TimeAt(int index = 0)
{
return bar.Time(index);
}
double OpenAt(int index = 0)
{
return bar.Open(index);
}
double HighAt(int index = 0)
{
return bar.High(index);
}
double LowAt(int index = 0)
{
return bar.Low(index);
}
double CloseAt(int index = 0)
{
return bar.Close(index);
}
double RangeAt(int index = 0)
{
return bar.High(index) - bar.Low(index);
}
double BodyTop(int index = 0)
{
return MathMax(bar.Open(index), bar.Close(index));
}
double BodyBottom(int index = 0)
{
return MathMin(bar.Open(index), bar.Close(index));
}
double BodySize(int index = 0)
{
return MathAbs(bar.Close(index) - bar.Open(index));
}
double UpperWick(int index = 0)
{
return bar.High(index) - BodyTop(index);
}
double LowerWick(int index = 0)
{
return BodyBottom(index) - bar.Low(index);
}
double MidPrice(double a, double b)
{
return (a + b) * 0.5;
}
double CandleMid(int index = 0)
{
return MidPrice(bar.High(index), bar.Low(index));
}
int TimeIndex(datetime t)
{
if(t <= 0)
return -1;
return bar.IndexByTime(t);
}
//========================
// Price helpers
//========================
double PointValue()
{
return bar.Point();
}
double PointsToPrice(int points)
{
return points * PointValue();
}
bool NearPrice(double a, double b, int tolerancePoints)
{
return MathAbs(a - b) <= PointsToPrice(tolerancePoints);
}
//========================
// Break helpers
//========================
bool BreakAboveHigh(int refIndex = 0, int barIndex = 0)
{
if(!IsValidIndex(refIndex) || !IsValidIndex(barIndex))
return false;
return bar.Close(barIndex) > bar.High(refIndex);
}
bool BreakBelowLow(int refIndex = 0, int barIndex = 0)
{
if(!IsValidIndex(refIndex) || !IsValidIndex(barIndex))
return false;
return bar.Close(barIndex) < bar.Low(refIndex);
}
bool WickAboveHigh(int refIndex = 0, int barIndex = 0)
{
if(!IsValidIndex(refIndex) || !IsValidIndex(barIndex))
return false;
return bar.High(barIndex) > bar.High(refIndex);
}
bool WickBelowLow(int refIndex = 0, int barIndex = 0)
{
if(!IsValidIndex(refIndex) || !IsValidIndex(barIndex))
return false;
return bar.Low(barIndex) < bar.Low(refIndex);
}
//========================
// Candle state
//========================
bool IsBullishCandle(int index = 0)
{
if(!IsValidIndex(index))
return false;
return bar.Close(index) > bar.Open(index);
}
bool IsBearishCandle(int index = 0)
{
if(!IsValidIndex(index))
return false;
return bar.Close(index) < bar.Open(index);
}
bool IsDojiCandle(int index = 0, double maxBodyToRange = 0.10)
{
if(!IsValidIndex(index))
return false;
double range = RangeAt(index);
if(range <= 0.0)
return false;
return (BodySize(index) / range) <= maxBodyToRange;
}
bool IsSellToBuyCandle(int index = 0, double wickToBodyRatio = 1.2)
{
if(!IsValidIndex(index))
return false;
double body = BodySize(index);
if(body <= 0.0)
body = _Point;
return LowerWick(index) >= body * wickToBodyRatio;
}
bool IsBuyToSellCandle(int index = 0, double wickToBodyRatio = 1.2)
{
if(!IsValidIndex(index))
return false;
double body = BodySize(index);
if(body <= 0.0)
body = _Point;
return UpperWick(index) >= body * wickToBodyRatio;
}
//========================
// Extremes in range
//========================
int FindLowestIndex(int fromIndex = 0, int toIndex = 0, bool inclusive = false)
{
if(fromIndex > toIndex)
{
int temp = fromIndex;
fromIndex = toIndex;
toIndex = temp;
}
int start = (inclusive ? fromIndex : fromIndex + 1);
int end = (inclusive ? toIndex : toIndex - 1);
if(start > end)
return -1;
int lowestIndex = -1;
for(int i = start; i <= end; i++)
{
if(!IsValidIndex(i))
continue;
if(lowestIndex == -1 || bar.Low(i) < bar.Low(lowestIndex))
lowestIndex = i;
}
return lowestIndex;
}
int FindHighestIndex(int fromIndex = 0, int toIndex = 0, bool inclusive = false)
{
if(fromIndex > toIndex)
{
int temp = fromIndex;
fromIndex = toIndex;
toIndex = temp;
}
int start = (inclusive ? fromIndex : fromIndex + 1);
int end = (inclusive ? toIndex : toIndex - 1);
if(start > end)
return -1;
int highestIndex = -1;
for(int i = start; i <= end; i++)
{
if(!IsValidIndex(i))
continue;
if(highestIndex == -1 || bar.High(i) > bar.High(highestIndex))
highestIndex = i;
}
return highestIndex;
}
//========================
// Swing helpers
//========================
bool IsValidSwingValue(double value)
{
return swing.IsValidValue(value);
}
bool IsSwingHigh(int index = 0)
{
if(!IsValidIndex(index))
return false;
return swing.IsValidValue(swing.FullHigh(index));
}
bool IsSwingLow(int index = 0)
{
if(!IsValidIndex(index))
return false;
return swing.IsValidValue(swing.FullLow(index));
}
double SwingHigh(int index = 0)
{
if(!IsValidIndex(index))
return 0;
if(!swing.IsValidValue(swing.FullHigh(index)))
return 0;
return swing.High(index);
}
double SwingLow(int index = 0)
{
if(!IsValidIndex(index))
return false;
if(!swing.IsValidValue(swing.FullLow(index)))
return false;
return swing.Low(index);
}
int PrevSwingHighIndex(int anchor = 0, int n = 1)
{
int found = -1;
for(int i = anchor; i >= 0; i--)
{
if(IsSwingHigh(i))
{
found++;
if(found == n)
return i;
}
}
return -1;
}
bool HasValidTime(datetime t)
{
return t > 0;
}
bool IsOlderTime(datetime olderTime, datetime newerTime)
{
if(!HasValidTime(olderTime) || !HasValidTime(newerTime))
return false;
return olderTime < newerTime;
}
bool IsOlderOrSameTime(datetime olderTime, datetime newerTime)
{
if(!HasValidTime(olderTime) || !HasValidTime(newerTime))
return false;
return olderTime <= newerTime;
}
int CountClosedBarsAfterTime(datetime anchorTime, datetime currentTime)
{
if(!IsOlderTime(anchorTime, currentTime))
return -1;
int anchorIndex = TimeIndex(anchorTime);
int currentIndex = TimeIndex(currentTime);
if(!IsValidIndex(anchorIndex) || !IsValidIndex(currentIndex))
return -1;
if(currentIndex <= anchorIndex)
return -1;
return (currentIndex - anchorIndex - 1);
}
//+------------------------------------------------------------------+
//| |
//+---------------------------j---------------------------------------+
bool AnchorIsMatureForBreak(int minCandles, datetime anchorTime, datetime currentTime)
{
int closedBars = MathAbs(TimeIndex(anchorTime) - TimeIndex(currentTime));
Print(closedBars);
return closedBars >= minCandles;
}
void SyncIndexFromTime(TimePrice &tp)
{
if(tp.x == 0)
{
tp.i = -1;
return;
}
tp.i = TimeIndex(tp.x);
}
int TimeframeMinutes()
{
return PeriodSeconds(timeframe) / 60;
}
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CommonHelper::CommonHelper()
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CommonHelper::~CommonHelper()
{
}
//+------------------------------------------------------------------+