last backup ...

This commit is contained in:
2026-01-08 11:39:42 +03:30
parent afafeca00a
commit 963e045e65
249 changed files with 328192 additions and 0 deletions
@@ -0,0 +1,344 @@
//+------------------------------------------------------------------+
//| TestRegresser.mq5 |
//| SaherElm IT Center |
//| https://www.saherelm.ir |
//+------------------------------------------------------------------+
#property copyright "SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
//
// Imports ...
#include "../Libraries/x-saherelm.common.lib.mq5"
#include <ChartObjects/ChartObjectsLines.mqh>
//
// Inputs ...
input int mLoopbackLength = 200;
input ENUM_X_PRICE mPriceType = X_PRICE_HIGH;
//
// Calculation ...
input group "Calculation";
input int zigzagDepth = 12; // Depth
input int zigzagDeviation = 5; // Deviation
input int zigzagBackStep = 3; // Back Step
//
// Variables ...
//
int mZigZagHandler = INVALID_HANDLE;
//
// double mSumX = 0;
// double mSumY = 0;
// double mSumXY = 0;
// double mSumX2 = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//
double xData[];
double yData[];
int xDataCount = CollectData(
xData,
yData //
);
//
// Initialize ZigZag Handler ...
mZigZagHandler = iCustom(
_Symbol,
_Period,
"ZigZagColor",
zigzagDepth,
zigzagDeviation,
zigzagBackStep //
);
if (mZigZagHandler == INVALID_HANDLE)
{
Print("Error creating ZigZag handle");
return (INIT_FAILED);
}
// //
// for (int i = 0; i < mLoopbackLength; i++)
// {
// //
// double iY = yData[i];
// double iX = xData[i];
// //
// mSumX += iX;
// mSumY += iY;
// mSumXY += (iX * iY);
// mSumX2 += (iX * iX);
// }
// //
// for (int i = 0; i < mLoopbackLength; i++)
// {
// //
// double iY = GetAppliedPrice(
// _Symbol,
// _Period,
// i,
// mPriceType //
// );
// double iX = i + 1;
// //
// mSumX += iX;
// mSumY += iY;
// mSumXY += (iX * iY);
// mSumX2 += (iX * iX);
// }
//
// int n = mLoopbackLength;
// double slope = (n * mSumXY - mSumX * mSumY) / (n * mSumX2 - mSumX * mSumX);
// double intercept = (mSumY - slope * mSumX) / n;
// //
// double xData[];
// double yData[];
// int xDataCount = CollectData(
// xData,
// yData //
// );
double _cSlope;
double _cIntercept;
int calculatedCount = CalculateSlopeandIntercept(
_cSlope,
_cIntercept,
xData,
yData //
);
//
datetime time1 = iTime(_Symbol, _Period, mLoopbackLength);
datetime time2 = iTime(_Symbol, _Period, 0);
// //
// double price1 = (intercept + slope * mLoopbackLength);
// double price2 = (intercept + slope);
//
double cPrice1 = PredictValue(
_cSlope,
_cIntercept,
time1 //
);
double cPrice2 = PredictValue(
_cSlope,
_cIntercept,
time2 //
);
//
string name = "TrendLine";
string cName = "cTrendLine";
//
// CChartObjectTrend *iTrend = new CChartObjectTrend();
// bool isCreated = iTrend.Create(
// ChartID(),
// name,
// 0,
// time1,
// price1,
// time2,
// price2 //
// );
// if (isCreated)
// {
// //
// // Styling Trend Line ...
// }
//
CChartObjectTrend *iCTrend = new CChartObjectTrend();
bool isCreated = iCTrend.Create(
ChartID(),
cName,
0,
time1,
cPrice1,
time2,
cPrice2 //
);
if (isCreated)
{
//
// Styling Trend Line ...
}
//
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//
int CollectData(
double &xData[],
double &yData[],
int barIndex = 0 //
)
{
//
int result = false;
//
SpecifiedClean(xData);
SpecifiedClean(yData);
//
barIndex = NormalizeInt(barIndex, 0);
//
int start = barIndex;
int end = start + mLoopbackLength;
for (int i = start; i < end; i++)
{
//
double iY = GetAppliedPrice(
_Symbol,
_Period,
i //
);
//
datetime iTime = iTime(
_Symbol,
_Period,
i //
);
double iX = i + 1; // (double)TimeToSeconds(iTime);
//
Add(
iX,
xData //
);
//
Add(
iY,
yData //
);
}
//
result = ArraySize(xData);
//
return result;
}
//
int CalculateSlopeandIntercept(
double &_slope,
double &_intercept,
double &xData[],
double &yData[] //
)
{
//
int result = 0;
//
bool has = false;
//
_slope = 0;
_intercept = 0;
//
if (!HasChild(xData) ||
!HasChild(yData))
{
return result;
}
//
double sumX = 0;
double sumY = 0;
double sumXY = 0;
double sumX2 = 0;
//
double x = 0;
double y = 0;
int end = MathMin(ArraySize(xData), ArraySize(yData));
for (int i = 0; i < end; i++)
{
//
double x = xData[i];
double y = yData[i];
//
sumX += x;
sumY += y;
sumXY += x * y;
sumX2 += x * x;
}
//
int n = end;
_slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
_intercept = (sumY - _slope * sumX) / n;
//
result = n;
//
return result;
}
//
double PredictValue(
double &_slope,
double &_intercept,
datetime forTime //
)
{
//
double result = 0;
//
if (!IsSpecifiedValid(forTime))
{
return result;
}
//
double forX = iBarShift(
_Symbol,
_Period,
forTime //
); // (double)TimeToSeconds(forTime);
result = (_intercept + _slope * forX);
//
return result;
}
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,320 @@
// #region Signals ...
// #region POI ...
bool IsBullishPOILongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
// IMPORTANT: Use near Support/Resistance ...
bool result = poiDetector.IsBullishPOI(barIndex) &&
kiParser.IsSafeBullishEntry(barIndex) &&
IsTFBullishPattern(barIndex, lowerTF);
//
return result;
}
bool IsBearishPOIShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
// IMPORTANT: Use near Support/Resistance ...
bool result = poiDetector.IsBearishPOI(barIndex) &&
kiParser.IsSafeBearishEntry(barIndex) &&
IsTFBearishPattern(barIndex, lowerTF);
//
return result;
}
bool ExitBullishPOILong(int barIndex = 0)
{
//
bool result =
poiDetector.IsBearishReversalPOI(barIndex) ||
poiDetector.IsBearishBreakoutPOI(barIndex) ||
poiDetector.IsBearishExhaustionPOI(barIndex);
//
return result;
}
bool ExitBearishPOIShort(int barIndex = 0)
{
//
bool result =
poiDetector.IsBullishReversalPOI(barIndex) ||
poiDetector.IsBullishBreakoutPOI(barIndex) ||
poiDetector.IsBullishExhaustionPOI(barIndex);
//
return result;
}
// #endregion
// #region Breakout ...
bool IsBreakoutLongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result = false;
//
result =
kiParser.IsVolatilityHigh(barIndex) &&
IsTFBullishPattern(barIndex, lowerTF) &&
poiDetector.IsBullishBreakoutPOI(barIndex);
//
return result;
}
bool IsBreakoutShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result = false;
//
result =
kiParser.IsVolatilityHigh(barIndex) &&
IsTFBearishPattern(barIndex, lowerTF) &&
poiDetector.IsBearishBreakoutPOI(barIndex);
//
return result;
}
bool ExitBreakoutLong(int barIndex = 0)
{
//
bool result =
poiDetector.IsBearishReversalPOI(barIndex) ||
poiDetector.IsBearishExhaustionPOI(barIndex);
//
return result;
}
bool ExitBreakoutShort(int barIndex = 0)
{
//
bool result =
poiDetector.IsBullishReversalPOI(barIndex) ||
poiDetector.IsBullishExhaustionPOI(barIndex);
//
return result;
}
// #endregion
// #region Reversal ...
bool IsReversalLongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
kiParser.IsRSIBullish(barIndex) &&
IsTFBullishPattern(barIndex, lowerTF) &&
poiDetector.IsBullishReversalPOI(barIndex);
//
return result;
}
bool IsReversalShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
kiParser.IsRSIBearish(barIndex) &&
IsTFBearishPattern(barIndex, lowerTF) &&
poiDetector.IsBearishReversalPOI(barIndex);
//
return result;
}
bool ExitReversalLong(int barIndex = 0)
{
//
bool result =
poiDetector.IsBearishBreakoutPOI(barIndex) ||
poiDetector.IsBearishContinuationPOI(barIndex);
//
return result;
}
bool ExitReversalShort(int barIndex = 0)
{
//
bool result =
poiDetector.IsBullishBreakoutPOI(barIndex) ||
poiDetector.IsBullishContinuationPOI(barIndex);
//
return result;
}
// #endregion
// #region Continuation ...
bool IsContinuationLongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBullishPattern(barIndex, lowerTF) &&
kiParser.IsTrendStrongBullish(barIndex) &&
poiDetector.IsBullishContinuationPOI(barIndex);
//
return result;
}
bool IsContinuationShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBearishPattern(barIndex, lowerTF) &&
kiParser.IsTrendStrongBearish(barIndex) &&
poiDetector.IsBearishContinuationPOI(barIndex);
//
return result;
}
bool ExitContinuationLong(int barIndex = 0)
{
//
bool result =
poiDetector.IsBearishReversalPOI(barIndex) ||
poiDetector.IsBearishExhaustionPOI(barIndex);
//
return result;
}
bool ExitContinuationShort(int barIndex = 0)
{
//
bool result =
poiDetector.IsBullishReversalPOI(barIndex) ||
poiDetector.IsBullishExhaustionPOI(barIndex);
//
return result;
}
// #endregion
// #region Exhaustion ...
bool IsExhaustionLongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBullishPattern(barIndex, lowerTF) &&
poiDetector.IsBearishExhaustionPOI(barIndex);
//
return result;
}
bool IsExhaustionShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBearishPattern(barIndex, lowerTF) &&
poiDetector.IsBullishExhaustionPOI(barIndex);
//
return result;
}
bool ExitExhaustionLong(int barIndex = 0)
{
return poiDetector.IsBearishBreakoutPOI(barIndex);
}
bool ExitExhaustionShort(int barIndex = 0)
{
return poiDetector.IsBullishBreakoutPOI(barIndex);
}
// #endregion
// #region Trend Exhaustion ...
bool IsTrendExhaustionLongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBullishPattern(barIndex, lowerTF) &&
poiDetector.IsBearishTrendExhaustedPOI(barIndex);
//
return result;
}
bool IsTrendExhaustionShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBearishPattern(barIndex, lowerTF) &&
poiDetector.IsBullishTrendExhaustedPOI(barIndex);
//
return result;
}
bool ExitTrendExhaustionLong(int barIndex = 0)
{
//
bool result =
poiDetector.IsBearishBreakoutPOI(barIndex) ||
poiDetector.IsBearishContinuationPOI(barIndex);
//
return result;
}
bool ExitTrendExhaustionShort(int barIndex = 0)
{
//
bool result =
poiDetector.IsBullishBreakoutPOI(barIndex) ||
poiDetector.IsBullishContinuationPOI(barIndex);
//
return result;
}
// #endregion
// #endregion
@@ -0,0 +1,825 @@
int CountKIFastTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetKIFast(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountKISlowTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetKISlow(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountKISuperSlowTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetKISuperSlow(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountKIUpperTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetKIUpper(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountKILowerTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetKILower(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountMAFastTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetMAFast(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountMASlowTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetMASlow(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountMASuperSlowTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetMASuperSlow(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
@@ -0,0 +1,458 @@
int CounteZoneTouches(
XBoxZone &zone,
double threshold = 10,
int loopback = 100 //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
threshold = NormalizeDouble(threshold, 10);
//
if (!zone.IsValid())
{
return result;
}
//
XOHCL tmpBar;
int start = zone.ToIndex();
bool isUpperTouched = false;
bool isLowerTouched = false;
double points = GetPoints(zone.symbol);
double distance = points * threshold;
int end = MathMin(start + loopback, zone.FromIndex());
for (int i = start; i < end; i++)
{
//
if (tmpBar.Init(zone.symbol, zone.period, i))
{
//
isUpperTouched = MathAbs(tmpBar.high - zone.upper) <= distance;
isLowerTouched = MathAbs(tmpBar.low - zone.lower) <= distance;
//
if (
(zone.IsBullish() &&
(isLowerTouched ||
MathAbs(tmpBar.close - zone.lower) <= distance)) ||
(zone.IsBearish() &&
(isUpperTouched ||
MathAbs(tmpBar.close - zone.upper) <= distance)))
{
//
result++;
Add(
tmpBar.time,
zone.tests //
);
}
//
tmpBar.Clean();
}
}
//
tmpBar.Clean();
//
return result;
}
bool HasNearZone(
int &index,
double price,
double threshold,
XBoxZone &zones[] //
)
{
//
bool result = false;
//
index = -1;
//
// Validate ...
result = HasChild(zones) &&
NotEmptyZero(price) &&
NotEmptyZero(threshold) &&
price > 0 &&
threshold > 0;
if (!result)
{
return result;
}
//
double points = GetPoints(zones[0].symbol);
double distance = points * threshold;
for (int i = 0; i < ArraySize(zones); i++)
{
//
// Check Price Distance by Upper ...
result = price >= zones[i].lower - distance &&
price <= zones[i].upper + distance;
if (result)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
bool IsNearZone(
double price,
XBoxZone &zone,
double threshold = 0 //
)
{
//
bool result = false;
//
result =
zone.IsValid() &&
NotEmptyZero(price);
if (!result)
{
return result;
}
//
double points = GetPoints(zone.symbol);
double distance = points * threshold;
//
result = price >= zone.lower - distance &&
price <= zone.upper + distance;
//
return result;
}
/*
* Check Recently Pattern Zone is Touched or not ...
*
* @param zone: XBoxZone, Touched Zone ...
* @param patterns: ENUM_X_BAR_PATTERN, Allowed to Check Patterns ...
* @param patternsDir: ENUM_X_DIRECTION, Allowed Directions ...
* @param price: double, a Price to Check Toch or Reject ...
* @param barIndex: int, Bar Index to Start Checking ...
* @param loopback: int, Loopback for Pattern Formations ...
* @param threshold: double, threshold for Pattern touch ...
* @param forPeriod: ENUM_TIMEFRAMES, Time Frame to Check Patterns ...
* @param forDir: ENUM_X_DIRECTION, Directions for Pattern's Formation Check ...
*
* @return ( bool )
*/
bool HasRecentPatternTouched(
XBoxZone &zone,
ENUM_X_BAR_PATTERN &patterns[],
ENUM_X_DIRECTION &patternsDir[],
double price,
int barIndex = 0,
int loopback = 5,
double threshold = 5,
ENUM_TIMEFRAMES forPeriod = NULL,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
bool result = false;
//
zone.Clean();
//
// Validate ...
result =
HasChild(patterns) &&
NotEmptyZero(price) &&
HasChild(patternsDir) &&
ArraySize(patterns) == ArraySize(patternsDir);
if (!result)
{
return result;
}
//
// Normalize ...
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
if (IsXValid(forPeriod))
{
forPeriod = period;
}
//
XOHCL iBar;
bool has = false;
int iBullishIDX = -1;
int iBearishIDX = -1;
bool isBullish = false;
bool isBearish = false;
XBoxZone iBullishZones[];
XBoxZone iBearishZones[];
XPatternAnalysis iAnalysis;
XPatternAnalysisConfig iConfig;
//
// Preparing Pattern Analysis Config ...
iConfig.Default();
//
Copy(
patterns,
iConfig.allowedPatterns //
);
Copy(
patternsDir,
iConfig.allowedDirs //
);
//
// XAUUSD ...
iConfig.AddPattern(X_BAR_PATTERN_FVG);
iConfig.AddPattern(X_BAR_PATTERN_PIERCING);
//
// Looping Back ...
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
// Initialize Bar ...
has = iBar.Init(symbol, forPeriod, i);
if (!has)
{
continue;
}
//
// Analyse Patterns ...
has = AnalyseBarPatterns(iBar, iAnalysis, iConfig);
if (!has)
{
//
iBar.Clean();
continue;
}
//
// Bullish ...
has = iAnalysis.Count(X_DIRECTION_BULLISH) > 0;
if (has)
{
//
iAnalysis.GetPatterns(iBullishZones, X_DIRECTION_BULLISH);
has = HasChild(iBullishZones);
if (has)
{
//
has = HasNearZone(
iBullishIDX,
price,
threshold,
iBullishZones //
);
if (has)
{
isBullish = true;
}
}
}
//
// Bearish ...
has = iAnalysis.Count(X_DIRECTION_BEARISH) > 0;
if (has)
{
//
iAnalysis.GetPatterns(iBearishZones, X_DIRECTION_BEARISH);
has = HasChild(iBearishZones);
if (has)
{
//
has = HasNearZone(
iBearishIDX,
price,
threshold,
iBearishZones //
);
if (has)
{
isBearish = true;
}
}
}
//
// Summarizing Result ...
has =
HasDirection(forDir)
? (isBullish && !isBearish && IsXBullish(forDir)) ||
(isBearish && !isBullish && IsXBearish(forDir))
: (isBullish && !isBearish) || (isBearish && !isBullish);
if (has)
{
//
// Fill Zones ...
if (isBullish)
{
zone = iBullishZones[iBullishIDX];
}
else
{
zone = iBearishZones[iBearishIDX];
}
break;
}
//
// Cleanup Resource ...
iBar.Clean();
iAnalysis.Clean();
XClean(iBullishZones);
XClean(iBearishZones);
}
//
// Cleanup Resources ...
iBar.Clean();
iConfig.Clean();
iAnalysis.Clean();
XClean(iBullishZones);
XClean(iBearishZones);
//
return result;
}
void ValidateZones(
XBoxZone &zones[],
int barIndex = 0,
int minimumRetests = 2,
double retestThreshold = 10,
int retestLoopback = 100,
ENUM_X_BOUNDARY_PRICE forPriceType = X_BOUNDARY_PRICE_UP_DOWN //
)
{
//
bool has = false;
//
// Validation ...
has = HasChild(zones) &&
IsXValid(forPriceType);
if (!has)
{
return;
}
//
// Normalizetion ...
barIndex = kiParser.NormalizeBarIndex(barIndex);
minimumRetests = NormalizeInt(minimumRetests, 0);
retestLoopback = NormalizeInt(retestLoopback, 50);
retestThreshold = NormalizeDouble(retestThreshold, 5, 10);
//
XOHCL tmpBar;
XBoxZone tmp;
XBoxZone tmps[];
double tmpValue = 0;
for (int i = 0; i < ArraySize(zones); i++)
{
//
tmp = zones[i];
//
if (minimumRetests > 0)
{
//
int retests = CounteZoneTouches(tmp, retestThreshold, retestLoopback);
if (retests < minimumRetests)
{
continue;
}
}
//
// Validate Zone ...
has = false;
for (int j = barIndex; j < tmp.FromIndex(); j++)
{
//
// Initial Bar ...
if (tmpBar.Init(tmp.symbol, tmp.period, j))
{
//
tmpValue = forPriceType == X_BOUNDARY_PRICE_UP_DOWN
? tmp.IsBullish()
? tmpBar.GetDown()
: tmpBar.GetUp()
: forPriceType == X_BOUNDARY_PRICE_HIGH_LOW
? tmp.IsBullish()
? tmpBar.low
: tmpBar.high
: EMPTY_VALUE;
if (NotEmptyZero(tmpValue))
{
//
// Check Break ...
has = tmp.IsBullish()
? tmpValue < tmp.lower
: tmpValue > tmp.upper;
//
// If Breakes ...
if (has)
{
break;
}
}
//
tmpBar.Clean();
}
}
//
// Not Breaked ...
if (!has)
{
//
AddIfNotExists(
tmp,
tmps //
);
}
//
tmp.Clean();
}
//
// Update Zones ...
XClean(zones);
Copy(
tmps,
zones //
);
XClean(tmps);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,33 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Expert Advisor
// -------------------------------------------------
// Name: X121XKIEA
// Description: Base Expert Advisor as Template ...
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property icon "../Images/SaherElm_Logo_Color.ico"
#property description "SaherElm XFIMA Expert Advisor"
#property strict
//
#define ShortName "X121XKIEA"
//
// Importts ...
#include "../X121XKIEA/Classes/x-saherelm.x121xki.expert.class.mq5"
//
// Inputs ...
//#region Inputs ...
//#endregion
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,843 @@
//
// Order Flow ...
//
bool drawOrderFlow;
XBoxZone orderFlow[];
bool manageOrderFlow;
ENUM_X_DIRECTION orderFlowDir;
//
bool HasOrderFlow()
{
//
return HasChild(orderFlow) &&
HasDirection(orderFlowDir);
}
//
bool HasBullishOrderFlow()
{
return HasOrderFlow() &&
IsXBullish(orderFlowDir);
}
//
bool HasBearishOrderFlow()
{
return HasOrderFlow() &&
IsXBearish(orderFlowDir);
}
//
bool GetOrderFlowBoundary(
double &upper,
double &lower //
)
{
//
bool result = false;
//
// Prepare ...
upper = EMPTY_VALUE;
lower = EMPTY_VALUE;
//
// Validate ...
result = HasOrderFlow();
if (!result)
{
return result;
}
//
int idx = -1;
//
// Upper ...
idx = GetHighest(orderFlow);
if (IsValidIndex(idx))
{
upper = orderFlow[idx].upper;
}
//
// Lower ...
idx = GetLowest(orderFlow);
if (IsValidIndex(idx))
{
lower = orderFlow[idx].lower;
}
//
result = NotEmptyZero(upper) &&
NotEmptyZero(lower) &&
upper > lower;
//
// Cleanup ...
if (!result)
{
//
upper = EMPTY_VALUE;
lower = EMPTY_VALUE;
}
//
return result;
}
//
bool ValidateOrderFlow(XOHCL &bar)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasOrderFlow();
if (!result)
{
return result;
}
//
double upper = EMPTY_VALUE;
double lower = EMPTY_VALUE;
result = GetOrderFlowBoundary(upper, lower);
result = result &&
HasBullishOrderFlow()
? bar.low > lower
: bar.high < upper;
//
return result;
}
//
void DrawOrderFlow()
{
//
if (!drawOrderFlow || !HasOrderFlow())
{
return;
}
//
poiDrawer.DrawZones(orderFlow, structureDrawConfig.drawConfig);
}
//
void ManageOrderFlow(XOHCL &bar)
{
//
// Validate Exists ...
if (HasOrderFlow())
{
//
if (!ValidateOrderFlow(bar))
{
//
// Invalidate OrderFlow ...
XClean(orderFlow);
orderFlowDir = X_DIRECTION_NONE;
}
}
//
// Detect New ...
if (!HasOrderFlow())
{
//
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
// patternConfig.Default();
// patternConfig.supportAndResistanceLoopbackLength = 21;
// patternConfig.supportAndResistanceValidationLength = 7;
//
poiDetector.HasOrderFlow(
bar,
orderFlowDir,
orderFlow,
structureConfig.orderFlowValidation,
structureConfig.orderFlowUseOB,
structureConfig.orderFlowUseFVG,
structureConfig.orderFlowUseSupportAndResistance,
patternConfig.supportAndResistanceLoopbackLength,
patternConfig.supportAndResistanceValidationLength,
structureConfig.loopback //
);
}
//
// Update Exists ...
if (HasOrderFlow())
{
//
// Update to Times ...
UpdateToTime(orderFlow, TimeCurrent());
//
DrawOrderFlow();
}
}
//
// Zone ...
//
XBoxZone support;
XBoxZone resistance;
bool drawZones;
bool drawSupport;
bool manageZones;
bool drawResistance;
//
bool HasZones()
{
return HasSupport() ||
HasResistance();
}
//
bool HasSupport()
{
return support.IsValid();
}
//
bool HasResistance()
{
return resistance.IsValid();
}
//
bool ValidateZones(XOHCL &bar)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasZones();
if (!result)
{
return result;
}
//
// Support ...
bool hasSupport = HasSupport();
if (hasSupport)
{
//
result = bar.close > support.lower &&
!IsBreaked(support, X_PRICE_CLOSE);
if (!result)
{
//
iResistance = support;
iResistance.breakAt = NULL;
iResistance.dir = X_DIRECTION_BEARISH;
iResistance.to = bar.time + (PeriodSeconds(bar.period));
iResistance.from = bar.time - (PeriodSeconds(bar.period));
//
support.breakAt = bar.time;
support.Clean();
}
}
//
// Resistance ...
bool hasResistance = HasResistance();
if (hasResistance)
{
//
result = bar.close < resistance.upper &&
!IsBreaked(resistance, X_PRICE_CLOSE);
if (!result)
{
//
iSupport = resistance;
iSupport.breakAt = NULL;
iSupport.dir = X_DIRECTION_BULLISH;
iSupport.to = bar.time + (PeriodSeconds(bar.period));
iSupport.from = bar.time - (PeriodSeconds(bar.period));
//
resistance.breakAt = bar.time;
resistance.Clean();
}
}
//
result =
(hasSupport && !HasSupport()) ||
(hasResistance && !HasResistance());
//
return result;
}
//
void DrawZones()
{
//
if (!drawZones || !HasZones())
{
return;
}
//
if (drawSupport && HasSupport())
{
poiDrawer.DrawZone(support, structureDrawConfig.drawConfig);
}
//
if (drawResistance && HasResistance())
{
poiDrawer.DrawZone(resistance, structureDrawConfig.drawConfig);
}
}
//
void ManageZones(XOHCL &bar)
{
//
// Validate Exists ...
if (HasZones())
{
//
if (!ValidateZones(bar))
{
//
// Invalidate Zones ...
//
// Support ...
if (IsXValid(support.breakAt))
{
//
iResistance = support;
iResistance.breakAt = NULL;
iResistance.dir = X_DIRECTION_BEARISH;
iResistance.to = bar.time + (PeriodSeconds(bar.period));
iResistance.from = bar.time - (PeriodSeconds(bar.period));
//
support.Clean();
}
//
// Resistance ...
if (IsXValid(resistance.breakAt))
{
//
iSupport = resistance;
iSupport.breakAt = NULL;
iSupport.dir = X_DIRECTION_BULLISH;
iSupport.to = bar.time + (PeriodSeconds(bar.period));
iSupport.from = bar.time - (PeriodSeconds(bar.period));
//
resistance.Clean();
}
}
}
//
// Detect New ...
XOHCL tmpBar;
bool has = false;
//
// Detect Support ...
if (!HasSupport())
{
//
has = poiDetector.HasSupport(
bar,
tmpBar,
structureConfig.barsAnalysisConfig.supportAndResistanceValidationLength,
structureConfig.barsAnalysisConfig.supportAndResistanceLoopbackLength //
);
if (has)
{
//
has = ToSupportBox(tmpBar, support, bar.time);
has =
has &&
!IsBreaked(support, X_PRICE_CLOSE);
if (!has)
{
//
if (support.IsValid())
{
//
iResistance = support;
iResistance.breakAt = NULL;
iResistance.dir = X_DIRECTION_BEARISH;
iResistance.to = bar.time + (PeriodSeconds(bar.period));
iResistance.from = bar.time - (PeriodSeconds(bar.period));
}
//
support.Clean();
}
}
}
//
// Detect Resistance ...
if (!HasResistance())
{
//
has = poiDetector.HasResistance(
bar,
tmpBar,
structureConfig.barsAnalysisConfig.supportAndResistanceValidationLength,
structureConfig.barsAnalysisConfig.supportAndResistanceLoopbackLength //
);
if (has)
{
//
has = ToResistanceBox(tmpBar, resistance, bar.time);
has =
has &&
!IsBreaked(resistance, X_PRICE_CLOSE);
if (!has)
{
//
if (resistance.IsValid())
{
//
iSupport = resistance;
iSupport.breakAt = NULL;
iSupport.dir = X_DIRECTION_BULLISH;
iSupport.to = bar.time + (PeriodSeconds(bar.period));
iSupport.from = bar.time - (PeriodSeconds(bar.period));
}
//
resistance.Clean();
}
}
}
//
// Update Exists ...
if (HasZones())
{
//
if (HasSupport())
{
//
support.to = bar.time;
support.type = "XFIMASup";
}
//
if (HasResistance())
{
//
resistance.to = bar.time;
resistance.type = "XFIMARes";
}
//
DrawZones();
}
//
// Cleanup ...
tmpBar.Clean();
}
//
XBoxZone iSupport;
XBoxZone iResistance;
bool drawIZones;
bool drawISupport;
bool manageIZones;
bool drawIResistance;
//
bool HasIZones()
{
//
return HasISupport() ||
HasIResistance();
}
//
bool HasISupport()
{
return iSupport.IsValid();
}
//
bool HasIResistance()
{
return iResistance.IsValid();
}
//
void DrawIZones()
{
//
if (!drawIZones || !HasIZones())
{
return;
}
//
if (drawISupport && HasISupport())
{
poiDrawer.DrawZone(iSupport, structureDrawConfig.drawConfig);
}
//
if (drawIResistance && HasIResistance())
{
poiDrawer.DrawZone(iResistance, structureDrawConfig.drawConfig);
}
}
//
bool ValidateIZones(XOHCL &bar)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasIZones();
if (!result)
{
return result;
}
//
//
// Support ...
bool hasSupport = HasISupport();
if (hasSupport)
{
//
result = bar.close > iSupport.lower &&
!IsBreaked(iSupport, X_PRICE_CLOSE);
if (!result)
{
//
iSupport.breakAt = bar.time;
iSupport.Clean();
}
}
//
// Resistance ...
bool hasResistance = HasIResistance();
if (hasResistance)
{
//
result = bar.close < iResistance.upper &&
!IsBreaked(iResistance, X_PRICE_CLOSE);
if (!result)
{
//
iResistance.breakAt = bar.time;
iResistance.Clean();
}
}
//
result =
(hasSupport && !HasISupport()) ||
(hasResistance && !HasIResistance());
//
return result;
}
//
void ManageIZones(XOHCL &bar)
{
//
// Validate Exists ...
if (HasIZones())
{
//
if (!ValidateIZones(bar))
{
//
// Invalidate Zones ...
//
// Support ...
if (IsXValid(iSupport.breakAt))
{
iSupport.Clean();
}
//
// Resistance ...
if (IsXValid(iResistance.breakAt))
{
iResistance.Clean();
}
}
}
//
// Update Exists ...
if (HasIZones())
{
//
if (HasISupport())
{
//
iSupport.to = bar.time;
iSupport.type = "XFIMAISup";
}
//
if (HasIResistance())
{
//
iResistance.to = bar.time;
iResistance.type = "XFIMAIRes";
}
//
DrawIZones();
}
}
//
// Trends ...
//
XTrend scTrend;
XTrend mcTrend;
XTrend lcTrend;
XTrend hcTrend;
//
bool drawTrends;
bool drawSCTrend;
bool drawMCTrend;
bool drawLCTrend;
bool drawHCTrend;
bool manageTrends;
//
bool HasTrend()
{
//
bool result =
HasSCTrend() ||
HasMCTrend() ||
HasLCTrend() ||
HasHCTrend();
//
return result;
}
//
bool HasSCTrend()
{
return scTrend.IsValid() &&
scTrend.HasTrend();
}
//
bool HasMCTrend()
{
return mcTrend.IsValid() &&
mcTrend.HasTrend();
}
//
bool HasLCTrend()
{
return lcTrend.IsValid() &&
lcTrend.HasTrend();
}
//
bool HasHCTrend()
{
return hcTrend.IsValid() &&
hcTrend.HasTrend();
}
//
void DrawTrends()
{
//
if (!drawTrends || !HasTrend())
{
return;
}
//
// SC ...
if (drawSCTrend && HasSCTrend())
{
poiDrawer.DrawTrendLine(scTrend, structureDrawConfig.drawConfig);
}
//
// MC ...
if (drawMCTrend && HasMCTrend())
{
poiDrawer.DrawTrendLine(mcTrend, structureDrawConfig.drawConfig);
}
//
// LC ...
if (drawLCTrend && HasLCTrend())
{
poiDrawer.DrawTrendLine(lcTrend, structureDrawConfig.drawConfig);
}
//
// HC ...
if (drawHCTrend && HasHCTrend())
{
poiDrawer.DrawTrendLine(hcTrend, structureDrawConfig.drawConfig);
}
}
//
void ManageTrends(XOHCL &bar)
{
//
// Validate ...
bool has = bar.IsValid();
if (!has)
{
return;
}
//
XTrend tmpTrend;
//
// SC ...
tmpTrend.Clean();
has = fimaParser.HasSCTrend(tmpTrend, bar.Index());
if (has)
{
scTrend = tmpTrend;
}
//
// MC ...
tmpTrend.Clean();
has = fimaParser.HasMCTrend(tmpTrend, bar.Index());
if (has)
{
mcTrend = tmpTrend;
}
//
// LC ...
tmpTrend.Clean();
has = fimaParser.HasLCTrend(tmpTrend, bar.Index());
if (has)
{
lcTrend = tmpTrend;
}
//
// HC ...
tmpTrend.Clean();
has = fimaParser.HasHCTrend(tmpTrend, bar.Index());
if (has)
{
hcTrend = tmpTrend;
}
//
DrawTrends();
//
// Cleanup ...
tmpTrend.Clean();
}
//
void Manage(XOHCL &bar)
{
//
bool has = bar.IsValid();
if (!has)
{
return;
}
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
has = bar.GetPreviousBar(pBar);
has = has &&
pBar.GetPreviousBar(p2Bar);
has = has &&
p2Bar.GetPreviousBar(p3Bar);
if (!has)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
}
//
ManageTrends(bar);
ManageZones(p2Bar);
ManageIZones(p2Bar);
ManageOrderFlow(p3Bar);
//
// Cleanup ...
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
}
//
// Configure ...
drawZones = false;
drawIZones = false;
drawTrends = false;
drawSCTrend = false;
drawMCTrend = false;
drawLCTrend = false;
drawHCTrend = false;
drawSupport = false;
drawISupport = false;
drawOrderFlow = false;
drawResistance = false;
drawIResistance = false;
//
manageZones = true;
manageIZones = true;
manageTrends = false;
manageOrderFlow = true;
//
// Manage ...
Manage(iBar);
@@ -0,0 +1,496 @@
/**
* Check Bar Has Signal Based on Strategy 3 ...
*
* @param bar: XOHCL, reference to Bar ...
* @param zone: XBoxZone, reference to holds affected zone ...
* @param targets: XTarget, reference to detected Signal's Targets collections ...
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
*
* @return ( bool )
*/
bool Strategy1HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Validator Flags ...
bool validateByZones = true;
bool validateByPinBar = true;
bool validateByBarPatterns = true;
bool validateByCyclesTrend = true;
bool validateByMaFastSlowGrows = true;
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
bool isBullish = false;
bool isBearish = false;
XPatternAnalysis pBarPatterns;
XPatternAnalysis p2BarPatterns;
XPatternAnalysis p3BarPatterns;
XPatternAnalysisConfig iPatternsConfig;
//
// Reading Bars ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Reading Bar Patterns ...
iPatternsConfig.Default();
iPatternsConfig.FullPattern();
result =
result &&
poiDetector.AnalyseBarPatterns(
pBar,
pBarPatterns,
iPatternsConfig //
);
result =
result &&
poiDetector.AnalyseBarPatterns(
p2Bar,
p2BarPatterns,
iPatternsConfig //
);
result =
result &&
poiDetector.AnalyseBarPatterns(
p3Bar,
p3BarPatterns,
iPatternsConfig //
);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
pBarPatterns.Clean();
p2BarPatterns.Clean();
p3BarPatterns.Clean();
iPatternsConfig.Clean();
//
return result;
}
//
// Detect a Cross of MAs ...
bool isFastCrossedOverSlow = fimaParser.IsMAFastCrossedOverSlow(p2Bar.Index());
bool isFastCrossedUnderSlow = fimaParser.IsMAFastCrossedUnderSlow(p2Bar.Index());
//
isBullish = isFastCrossedOverSlow;
isBearish = isFastCrossedUnderSlow;
//
result = isBullish || isBearish;
//
// Validate Cross By Over/Under Last ...
if (result && validateByMaFastSlowGrows)
{
//
// Bullish ...
bool isFastOverLast = fimaParser.IsMAFastOverLast(pBar.Index());
bool isSlowOverLast = fimaParser.IsMASlowOverLast(pBar.Index());
bool isOverLast = isFastOverLast && isSlowOverLast;
//
// Bearish ...
bool isFastUnderLast = fimaParser.IsMAFastUnderLast(pBar.Index());
bool isSlowUnderLast = fimaParser.IsMASlowUnderLast(pBar.Index());
bool isUnderLast = isFastUnderLast && isSlowUnderLast;
//
isBullish =
isBullish &&
isOverLast;
//
isBearish =
isBearish &&
isUnderLast;
//
result = isBullish || isBearish;
}
//
// Validate By Cycles Trend ...
if (result && validateByCyclesTrend)
{
//
// Reading Cycles Trend ...
//
// Bullish ...
//
bool isLCMABullish = fimaParser.IsLCMABullish(pBar.Index());
bool isHCMABullish = fimaParser.IsHCMABullish(pBar.Index());
//
bool isLCMAOverLast = fimaParser.IsLCMAOverLast(pBar.Index());
bool isHCMAOverLast = fimaParser.IsHCMAOverLast(pBar.Index());
//
bool isCyclesMABullish = isLCMABullish && isHCMABullish && isLCMAOverLast && isHCMAOverLast;
//
// Bearish ...
//
bool isLCMABearish = fimaParser.IsLCMABearish(pBar.Index());
bool isHCMABearish = fimaParser.IsHCMABearish(pBar.Index());
//
bool isLCMAUnderLast = fimaParser.IsLCMAUnderLast(pBar.Index());
bool isHCMAUnderLast = fimaParser.IsHCMAUnderLast(pBar.Index());
//
bool isCyclesMABearish = isLCMABearish && isHCMABearish && isLCMAUnderLast && isHCMAUnderLast;
//
isBullish =
isBullish &&
isCyclesMABullish;
//
isBearish =
isBearish &&
isCyclesMABearish;
//
result = isBullish || isBearish;
}
//
// Validate Has a PinBar ...
if (result && validateByPinBar)
{
//
bool isPBarIsPinBar = poiDetector.IsPinnedBar(pBar, dir);
bool isPBarIsPinBarBullish = isPBarIsPinBar && IsXBullish(dir);
bool isPBarIsPinBarBearish = isPBarIsPinBar && IsXBearish(dir);
//
bool isP2BarIsPinBar = poiDetector.IsPinnedBar(p2Bar, dir);
bool isP2BarIsPinBarBullish = isP2BarIsPinBar && IsXBullish(dir);
bool isP2BarIsPinBarBearish = isP2BarIsPinBar && IsXBearish(dir);
//
bool isBullishPin = isPBarIsPinBarBullish || isP2BarIsPinBarBullish;
bool isBearishPin = isPBarIsPinBarBearish || isP2BarIsPinBarBearish;
//
isBullish =
isBullish &&
isBullishPin;
//
isBearish =
isBearish &&
isBearishPin;
//
result = isBullish || isBearish;
}
//
// Validate By Bar Patterns ...
if (result && validateByBarPatterns)
{
//
int count = 0;
int bullishCount = 0;
int bearishCount = 0;
//
count = pBarPatterns.Count(X_DIRECTION_BULLISH);
bullishCount += count;
//
count = p2BarPatterns.Count(X_DIRECTION_BULLISH);
bullishCount += count;
//
count = pBarPatterns.Count(X_DIRECTION_BEARISH);
bearishCount += count;
//
count = p2BarPatterns.Count(X_DIRECTION_BEARISH);
bearishCount += count;
//
bool hasBullishScore = IsValidSize(bullishCount) &&
bullishCount > bearishCount;
//
bool hasBearishScore = IsValidSize(bearishCount) &&
bearishCount > bullishCount;
//
// Reading Bar Patterns ...
//
// Bullish ...
bool isPBarHasBullishPatterns =
(pBarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BULLISH));
bool isP2BarHasBullishPatterns =
(p2BarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BULLISH));
bool hasBullishPatterns = isPBarHasBullishPatterns || isP2BarHasBullishPatterns;
//
// Bearish ...
bool isPBarHasBearishPatterns =
(pBarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BEARISH));
bool isP2BarHasBearishPatterns =
(p2BarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BEARISH));
bool hasBearishPatterns = isPBarHasBearishPatterns || isP2BarHasBearishPatterns;
//
isBullish =
isBullish &&
hasBullishScore &&
hasBullishPatterns;
//
isBearish =
isBearish &&
hasBearishScore &&
hasBearishPatterns;
//
result = isBullish || isBearish;
}
//
// Validate By Zones ...
if (result && validateByZones)
{
//
XBoxZone zones[];
int count = poiDetector.DetectZones(
pBar,
zones,
true, // Validate Zones ...
false, // OB ...
true, // FVG ...
true, // Supports ...
true, // Resistances ...
X_DIRECTION_NONE, // All Directions ...
X_SORT_BY_DATE, // Sort By ...
X_DIRECTION_BEARISH, // Sort Direction ...
5, // Zones Loopback ...
5, // Zones Validation ...
100 // Loopback ...
);
//
bool has = IsValidSize(count);
if (has)
{
poiDrawer.DrawZones(zones, structureDrawConfig.drawConfig);
}
}
//
if (result)
{
//
DebugBreak();
//
result = false;
isBullish = false;
isBearish = false;
}
//
// Detecting Direction ...
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
// Since Zone Prepared in Above Steps ...
// here we only Validate it ...
result = zone.IsValid();
}
//
// Draws ...
if (result)
{
//
XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
XPatternAnalysisDrawConfig iPatternsConfig = structureDrawConfig.barAnalysisDrawConfig;
iConfig.trendRayLeft = false;
iConfig.trendRayRight = false;
//
// Draw Zone ...
if (zone.IsValid())
{
//
iConfig.zonesStyle = STYLE_DASHDOT;
iConfig.bullishColor = clrYellow;
iConfig.bearishColor = clrDarkOrange;
//
poiDrawer.DrawZone(zone, iConfig);
}
//
// poiDrawer.DrawZone(mcPVZone, iConfig);
// poiDrawer.DrawZone(lcPVZone, iConfig);
// poiDrawer.DrawZone(hcPVZone, iConfig);
//
// poiDrawer.DrawZone(pinBarZone, iConfig);
// poiDrawer.DrawZone(pullbackZone, iConfig);
// poiDrawer.DrawTrendLine(pinBarZoneTrend, iConfig);
//
poiDrawer.DrawPatternAnalysis(pBarPatterns, iPatternsConfig);
poiDrawer.DrawPatternAnalysis(p2BarPatterns, iPatternsConfig);
poiDrawer.DrawPatternAnalysis(p3BarPatterns, iPatternsConfig);
//
// if (hasATRBox)
// {
// poiDrawer.DrawZone(atrBox, iConfig);
// }
//
// if (hasDoublePatterns)
// {
// //
// poiDrawer.DrawPatternAnalysis(iPatterns, iPatternsConfig);
// poiDrawer.DrawPatternAnalysis(iPPatterns, iPatternsConfig);
// }
//
iConfig.Clean();
iPatternsConfig.Clean();
//
DebugBreak();
// //
// result = false;
// isBullish = false;
// isBearish = false;
// zone.Clean();
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
pBarPatterns.Clean();
p2BarPatterns.Clean();
p3BarPatterns.Clean();
iPatternsConfig.Clean();
//
return result;
}
@@ -0,0 +1,949 @@
/**
* Check Bar Has Signal Based on Strategy 4 ...
*
* @param bar: XOHCL, reference to Bar ...
* @param zone: XBoxZone, reference to holds affected zone ...
* @param targets: XTarget, reference to detected Signal's Targets collections ...
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
*
* @return ( bool )
*/
bool Strategy3HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Validation Flags ...
bool validateByBarPatterns = true;
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Do ...
//
// Retrieve pBar Patterns ...
XPatternAnalysis pBarPatterns;
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
//
poiDetector.AnalyseBarPatterns(
pBar,
pBarPatterns,
patternConfig //
);
//
bool isConsolidation = poiDetector.DetectXPVZone(zone, p2Bar.Index());
//
isBullish =
isConsolidation &&
zone.IsBullish();
//
isBearish =
isConsolidation &&
zone.IsBearish();
//
// Summarize Result ...
result = isBullish || isBearish;
//
// Force PBar Has Pattern ...
if (result && validateByBarPatterns)
{
//
// Analyse Bar Patterns ...
result = pBarPatterns.IsValid();
//
// Bullish ...
bool isPBarHasBullishPatterns =
result &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
//
);
//
// Bearish ...
bool isPBarHasBearishPatterns =
result &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
isBullish =
isBullish &&
isPBarHasBullishPatterns &&
!isPBarHasBearishPatterns;
//
isBearish =
isBearish &&
isPBarHasBearishPatterns &&
!isPBarHasBullishPatterns;
//
// Summarize Result ...
result = isBullish || isBearish;
//
// Reset Flags ...
if (!result)
{
//
isBullish = false;
isBearish = false;
}
}
//
if (result)
{
//
poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
DebugBreak();
//
result = false;
isBullish = false;
isBearish = false;
}
// //
// // Validate based on Bars Patterns ...
// bool validateByBarPatterns = true;
// if (validateByBarPatterns)
// {
// //
// // Reading pBar Patterns ...
// XPatternAnalysis pBarAnalysis;
// poiDetector.AnalyseBarPatterns(
// pBar,
// pBarAnalysis,
// structureConfig.barsAnalysisConfig //
// );
// //
// // Bullish ...
// bool isPBarHasBullishPatterns =
// (bar.close > pBar.low ||
// bar.open > pBar.low) &&
// (
// //
// pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
// //
// );
// //
// // Bearish ...
// bool isPBarHasBearishPatterns =
// (bar.close < pBar.high ||
// bar.open < pBar.high) &&
// (
// //
// pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
// //
// );
// //
// isBullish =
// isBullish &&
// isPBarHasBullishPatterns &&
// !isPBarHasBearishPatterns;
// //
// isBearish =
// isBearish &&
// isPBarHasBearishPatterns &&
// !isPBarHasBullishPatterns;
// //
// // Summarize Result ...
// result = isBullish ||
// isBearish;
// }
// //
// // Checking PullBack ...
// bool validateByPullback = false;
// if (validateByPullback)
// {
// //
// XBoxZone pullback;
// ENUM_X_DIRECTION pullbackDir;
// bool isPullBack = result &&
// poiDetector.IsPullbackPattern(
// pBar,
// pullback,
// pullbackDir,
// 2,
// false // Force Break ...
// );
// bool isPullbackBullish = isPullBack &&
// IsXBullish(pullbackDir);
// bool isPullbackBearish = isPullBack &&
// IsXBearish(pullbackDir);
// //
// isBullish =
// isBullish &&
// isPullbackBullish;
// //
// isBearish =
// isBearish &&
// isPullbackBearish;
// //
// // Summarize Result ...
// result = isBullish ||
// isBearish;
// }
//
// Validate ...
result = isBullish ||
isBearish;
//
// Prepare Zone ...
if (result)
{
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
pBarPatterns.Clean();
//
return result;
}
// //
// bool isConsolidation = poiDetector.DetectXPVZone(zone, p2Bar.Index());
// //
// isBullish =
// isConsolidation &&
// zone.IsBullish();
// //
// isBearish =
// isConsolidation &&
// zone.IsBearish();
// //
// // Summarize Result ...
// result = isBullish || isBearish;
// //
// // Force PBar Has Pattern ...
// if (result && validateByBarPatterns)
// {
// //
// // Analyse Bar Patterns ...
// result = pBarPatterns.IsValid();
// //
// // Bullish ...
// bool isPBarHasBullishPatterns =
// result &&
// (
// //
// pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
// //
// );
// //
// // Bearish ...
// bool isPBarHasBearishPatterns =
// result &&
// (
// //
// pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
// //
// );
// //
// isBullish =
// isBullish &&
// isPBarHasBullishPatterns &&
// !isPBarHasBearishPatterns;
// //
// isBearish =
// isBearish &&
// isPBarHasBearishPatterns &&
// !isPBarHasBullishPatterns;
// //
// // Summarize Result ...
// result = isBullish || isBearish;
// //
// // Reset Flags ...
// if (!result)
// {
// //
// isBullish = false;
// isBearish = false;
// }
// }
// //
// if (result)
// {
// //
// poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
// poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
// DebugBreak();
// //
// result = false;
// isBullish = false;
// isBearish = false;
// }
// //
// // Validate based on Bars Patterns ...
// bool validateByBarPatterns = true;
// if (validateByBarPatterns)
// {
// //
// // Reading pBar Patterns ...
// XPatternAnalysis pBarAnalysis;
// poiDetector.AnalyseBarPatterns(
// pBar,
// pBarAnalysis,
// structureConfig.barsAnalysisConfig //
// );
// //
// // Bullish ...
// bool isPBarHasBullishPatterns =
// (bar.close > pBar.low ||
// bar.open > pBar.low) &&
// (
// //
// pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
// //
// );
// //
// // Bearish ...
// bool isPBarHasBearishPatterns =
// (bar.close < pBar.high ||
// bar.open < pBar.high) &&
// (
// //
// pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
// //
// );
// //
// isBullish =
// isBullish &&
// isPBarHasBullishPatterns &&
// !isPBarHasBearishPatterns;
// //
// isBearish =
// isBearish &&
// isPBarHasBearishPatterns &&
// !isPBarHasBullishPatterns;
// //
// // Summarize Result ...
// result = isBullish ||
// isBearish;
// }
// //
// // Checking PullBack ...
// bool validateByPullback = false;
// if (validateByPullback)
// {
// //
// XBoxZone pullback;
// ENUM_X_DIRECTION pullbackDir;
// bool isPullBack = result &&
// poiDetector.IsPullbackPattern(
// pBar,
// pullback,
// pullbackDir,
// 2,
// false // Force Break ...
// );
// bool isPullbackBullish = isPullBack &&
// IsXBullish(pullbackDir);
// bool isPullbackBearish = isPullBack &&
// IsXBearish(pullbackDir);
// //
// isBullish =
// isBullish &&
// isPullbackBullish;
// //
// isBearish =
// isBearish &&
// isPullbackBearish;
// //
// // Summarize Result ...
// result = isBullish ||
// isBearish;
// }
/**
* Check Bar Has Signal Based on Strategy 4 ...
*
* @param bar: XOHCL, reference to Bar ...
* @param zone: XBoxZone, reference to holds affected zone ...
* @param targets: XTarget, reference to detected Signal's Targets collections ...
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
*
* @return ( bool )
*/
bool Strategy3HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Validation Flags ...
bool validateByBarPatterns = false;
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Do ...
//
// Retrieve pBar Patterns ...
XPatternAnalysis pBarPatterns;
XPatternAnalysis p2BarPatterns;
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
//
poiDetector.AnalyseBarPatterns(
pBar,
pBarPatterns,
patternConfig //
);
poiDetector.AnalyseBarPatterns(
p2Bar,
p2BarPatterns,
patternConfig //
);
//
bool hasSupport = p2BarPatterns.IsValid() &&
p2BarPatterns.IsSupport();
bool hasResistance = p2BarPatterns.IsValid() &&
p2BarPatterns.IsResistance();
//
isBullish =
hasSupport &&
p2BarPatterns.Count(X_DIRECTION_BULLISH) >= 4;
//
isBearish =
hasResistance &&
p2BarPatterns.Count(X_DIRECTION_BEARISH) >= 4;
//
// Summarize Result ...
result = isBullish || isBearish;
//
// Extract Affected Zone ...
if (result)
{
//
XOHCL tmpBar;
XPivot tmpPivot;
XBoxZone tmpZone;
//
if (hasSupport)
{
//
hasSupport = p2BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone);
isBullish =
isBullish &&
hasSupport &&
(IsActed(pBar, tmpZone) ||
IsTested(pBar, tmpZone));
}
//
if (hasResistance)
{
//
hasResistance = p2BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone);
isBearish =
isBearish &&
hasResistance &&
(IsActed(pBar, tmpZone) ||
IsTested(pBar, tmpZone));
}
//
// Cleanup ...
tmpBar.Clean();
tmpZone.Clean();
tmpPivot.Clean();
//
// Summarize Result ...
result = isBullish || isBearish;
}
//
// Validate based on Bars Patterns ...
if (result && validateByBarPatterns)
{
//
// Bullish...
bool isPBarHasBullishPatterns =
pBarPatterns.IsValid() &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
//
);
//
// Bearish ...
bool isPBarHasBearishPatterns =
pBarPatterns.IsValid() &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
isBullish =
isBullish &&
isPBarHasBullishPatterns &&
!isPBarHasBearishPatterns;
//
isBearish =
isBearish &&
isPBarHasBearishPatterns &&
!isPBarHasBullishPatterns;
//
// Summarize Result ...
result = isBullish || isBearish;
}
if (result)
{
//
poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
poiDrawer.DrawPatternAnalysis(p2BarPatterns, structureDrawConfig.barAnalysisDrawConfig);
DebugBreak();
//
result = false;
isBullish = false;
isBearish = false;
}
// //
// bool isConsolidation = poiDetector.DetectXPVZone(zone, p2Bar.Index());
// //
// isBullish =
// isConsolidation &&
// zone.IsBullish();
// //
// isBearish =
// isConsolidation &&
// zone.IsBearish();
// //
// // Summarize Result ...
// result = isBullish || isBearish;
// //
// // Force PBar Has Pattern ...
// if (result && validateByBarPatterns)
// {
// //
// // Analyse Bar Patterns ...
// result = pBarPatterns.IsValid();
// //
// // Bullish ...
// bool isPBarHasBullishPatterns =
// result &&
// (
// //
// pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
// //
// );
// //
// // Bearish ...
// bool isPBarHasBearishPatterns =
// result &&
// (
// //
// pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
// //
// );
// //
// isBullish =
// isBullish &&
// isPBarHasBullishPatterns &&
// !isPBarHasBearishPatterns;
// //
// isBearish =
// isBearish &&
// isPBarHasBearishPatterns &&
// !isPBarHasBullishPatterns;
// //
// // Summarize Result ...
// result = isBullish || isBearish;
// //
// // Reset Flags ...
// if (!result)
// {
// //
// isBullish = false;
// isBearish = false;
// }
// }
// //
// if (result)
// {
// //
// poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
// poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
// DebugBreak();
// //
// result = false;
// isBullish = false;
// isBearish = false;
// }
// //
// // Checking PullBack ...
// bool validateByPullback = false;
// if (validateByPullback)
// {
// //
// XBoxZone pullback;
// ENUM_X_DIRECTION pullbackDir;
// bool isPullBack = result &&
// poiDetector.IsPullbackPattern(
// pBar,
// pullback,
// pullbackDir,
// 2,
// false // Force Break ...
// );
// bool isPullbackBullish = isPullBack &&
// IsXBullish(pullbackDir);
// bool isPullbackBearish = isPullBack &&
// IsXBearish(pullbackDir);
// //
// isBullish =
// isBullish &&
// isPullbackBullish;
// //
// isBearish =
// isBearish &&
// isPullbackBearish;
// //
// // Summarize Result ...
// result = isBullish ||
// isBearish;
// }
//
// Validate ...
result = isBullish ||
isBearish;
//
// Prepare Zone ...
if (result)
{
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
pBarPatterns.Clean();
patternConfig.Clean();
p2BarPatterns.Clean();
//
return result;
}
bool validateByPVChange = false;
bool validateByPVInside = false;
//
// Validate By PV Inside ...
if (result && validateByPVInside)
{
//
double pVale = fimaHelper.GetVale(pBar.Index());
double pPeak = fimaHelper.GetPeak(pBar.Index());
//
bool isValePassed = pVale <= support.upper &&
pVale >= support.upper &&
fimaParser.IsValeSame(pBar.Index());
//
bool isPeakPassed = pPeak <= resistance.upper &&
pPeak >= resistance.upper &&
fimaParser.IsPeakSame(pBar.Index());
//
isBullish =
isBullish &&
isValePassed;
//
isBearish =
isBearish &&
isPeakPassed;
//
// Summarize Result ...
result = isBullish || isBearish;
}
//
// Validate by PV Change ...
if (result && validateByPVChange)
{
//
// bullish => p3, p2 vale under last ...
// bearish => p3, p2 peak over last ...
//
bool isValePassed =
fimaParser.IsValeUnderLast(p2Bar.Index()) ||
fimaParser.IsValeUnderLast(p3Bar.Index());
//
bool isPeakPassed =
fimaParser.IsPeakOverLast(p2Bar.Index()) ||
fimaParser.IsPeakOverLast(p3Bar.Index());
//
isBullish =
isBullish &&
isValePassed;
//
isBearish =
isBearish &&
isPeakPassed;
//
// Summarize Result ...
result = isBullish || isBearish;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+547
View File
@@ -0,0 +1,547 @@
//+------------------------------------------------------------------+
//| XKI_MTF_EA.mq5
//| SaherElm IT Center - Strategy using XKI
//| Author: Hadi Khazaee Asl
//+------------------------------------------------------------------+
#property strict
//
// Imports ...
#include "../Libraries/x-saherelm.common.lib.mq5"
// Inputs
input string InpSymbol = "XAUUSDb";
input ENUM_TIMEFRAMES InpSignalTF = PERIOD_H1; // Signal timeframe (H1)
input int InpKiLength = 26; // KI length (XKI input)
input bool InpShowKI = true; // (XKI input)
input int InpCalcLastBars = 1500; // (XKI input)
input bool InpUseRSI = true; // Use RSI confirmation
input int InpRSIPeriod = 14;
input int InpRSIPrice = PRICE_CLOSE;
input bool InpUseH4Filter = true; // Confirm with H4
input bool InpUseD1Filter = false; // Confirm with D1
input bool InpRequireBothFilters = false; // If true, require BOTH H4 and D1 agreement; else either
input double InpFixedLot = 0.10; // Fixed lot size
input double InpRiskATRMult = 0.0; // Add ATR padding to stop (0=disabled)
input int InpATRPeriod = 14;
input double InpRR = 2.0; // Reward:Risk target
input bool InpTrailByKI = true; // Trail stop to KI
input int InpSlippagePoints = 20; // Max slippage in points
input int InpMaxSpreadPoints = 200; // Max allowed spread in points
input bool InpAvoidAsianSession = true; // Avoid 22:00–06:00 server time
input int InpAsianStartHour = 22;
input int InpAsianEndHour = 6;
input bool InpAvoidNewsWindow = false; // Placeholder flag
input int InpNewsWindowMinutes = 60; // Skip trades within +/- minutes
input int InpBarsLookbackSignal = 2; // Lookback bars for signal (e.g., last closed bar)
// Magic number and comments
input int InpMagic = 260126;
input string InpOrderComment = "XKI_MTF_EA";
// iCustom indicator path (relative to Indicators folder if compiled there)
string g_xkiIndicatorPath = "x-saherelm.x121.xki"; // the compiled name; adjust if different
// Buffers indices as per the indicator
#define KI_BUFFER_INDEX 0
#define KI_COLOR_IDX_BUFFER_INDEX 1
#define KI_STATE_BUFFER_INDEX 2
// States from indicator
#define BULLISH_STATE 1
#define NEUTURAL_STATE 0
#define BEARISH_STATE -1
// Globals
int g_digits;
double g_point;
MqlTick g_tick;
int g_atrHandleH1 = INVALID_HANDLE;
int g_atrHandleH4 = INVALID_HANDLE;
int g_atrHandleD1 = INVALID_HANDLE;
int g_rsiHandleH1 = INVALID_HANDLE;
int g_rsiHandleH4 = INVALID_HANDLE;
int g_rsiHandleD1 = INVALID_HANDLE;
//+------------------------------------------------------------------+
// OnInit
//+------------------------------------------------------------------+
int OnInit()
{
//
g_digits = (int)SymbolInfoInteger(InpSymbol, SYMBOL_DIGITS);
g_point = SymbolInfoDouble(InpSymbol, SYMBOL_POINT);
if (!SymbolInfoTick(InpSymbol, g_tick))
{
Print("Failed to get tick for symbol: ", InpSymbol);
return INIT_FAILED;
}
// Quick validation
if (InpKiLength < 5)
{
Print("Invalid KI length: ", InpKiLength);
return INIT_PARAMETERS_INCORRECT;
}
//
GetOrCreateATRHandle(InpSymbol, InpSignalTF, InpATRPeriod);
if (InpUseH4Filter)
GetOrCreateATRHandle(InpSymbol, PERIOD_H4, InpATRPeriod);
if (InpUseD1Filter)
GetOrCreateATRHandle(InpSymbol, PERIOD_D1, InpATRPeriod);
//
GetOrCreateRSIHandle(InpSymbol, InpSignalTF, InpRSIPeriod, InpRSIPrice);
if (InpUseH4Filter)
GetOrCreateRSIHandle(InpSymbol, PERIOD_H4, InpRSIPeriod, InpRSIPrice);
if (InpUseD1Filter)
GetOrCreateRSIHandle(InpSymbol, PERIOD_D1, InpRSIPeriod, InpRSIPrice);
//
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
// OnDeinit
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//
if (g_atrHandleH1 != INVALID_HANDLE)
{
IndicatorRelease(g_atrHandleH1);
g_atrHandleH1 = INVALID_HANDLE;
}
if (g_atrHandleH4 != INVALID_HANDLE)
{
IndicatorRelease(g_atrHandleH4);
g_atrHandleH4 = INVALID_HANDLE;
}
if (g_atrHandleD1 != INVALID_HANDLE)
{
IndicatorRelease(g_atrHandleD1);
g_atrHandleD1 = INVALID_HANDLE;
}
//
if (g_rsiHandleH1 != INVALID_HANDLE)
{
IndicatorRelease(g_rsiHandleH1);
g_rsiHandleH1 = INVALID_HANDLE;
}
if (g_rsiHandleH4 != INVALID_HANDLE)
{
IndicatorRelease(g_rsiHandleH4);
g_rsiHandleH4 = INVALID_HANDLE;
}
if (g_rsiHandleD1 != INVALID_HANDLE)
{
IndicatorRelease(g_rsiHandleD1);
g_rsiHandleD1 = INVALID_HANDLE;
}
}
//+------------------------------------------------------------------+
// OnTick
//+------------------------------------------------------------------+
void OnTick()
{
if (_Symbol != InpSymbol)
return;
// Basic trading safety
if (!SymbolInfoTick(InpSymbol, g_tick))
return;
double spreadPoints = GetSpread(InpSymbol);
if (spreadPoints > InpMaxSpreadPoints)
return;
if (InpAvoidAsianSession)
{
//
MqlDateTime now = GetCurrentTime();
int hr = now.hour;
if (IsHourInRange(hr, InpAsianStartHour, InpAsianEndHour))
return;
}
if (InpAvoidNewsWindow)
{
// Placeholder: implement your own calendar integration
// Skip trading in a window near news. Here we simply return.
return;
}
// Only process on new bar of signal timeframe
static datetime lastSignalBarTime = 0;
datetime currentSignalBarTime = GetLastClosedBarTime(InpSymbol, InpSignalTF);
if (currentSignalBarTime == 0 || currentSignalBarTime == lastSignalBarTime)
return;
lastSignalBarTime = currentSignalBarTime;
// Get signal state and KI on signal TF (last closed bar)
int signalBarShift = InpBarsLookbackSignal; // 1=last closed, 2=previous
int stateSignal;
double kiSignal, closeSignal;
if (!GetXKIStateAndKI(InpSymbol, InpSignalTF, signalBarShift, stateSignal, kiSignal))
return;
closeSignal = iClose(InpSymbol, InpSignalTF, signalBarShift);
// RSI confirmation
if (InpUseRSI)
{
double rsi = GetRSIValue(InpSymbol, InpSignalTF, InpRSIPeriod, InpRSIPrice, signalBarShift);
if (rsi == EMPTY_VALUE)
return;
if (stateSignal == BULLISH_STATE && rsi <= 50.0)
return;
if (stateSignal == BEARISH_STATE && rsi >= 50.0)
return;
}
// Higher timeframe agreement
bool agreesH4 = true, agreesD1 = true;
if (InpUseH4Filter)
agreesH4 = HigherTFAgrees(InpSymbol, PERIOD_H4, signalBarShift, stateSignal);
if (InpUseD1Filter)
agreesD1 = HigherTFAgrees(InpSymbol, PERIOD_D1, signalBarShift, stateSignal);
bool filterOK = true;
if (InpUseH4Filter || InpUseD1Filter)
{
if (InpRequireBothFilters)
filterOK = (agreesH4 && agreesD1);
else
filterOK = ((InpUseH4Filter && agreesH4) || (InpUseD1Filter && agreesD1));
}
if (!filterOK)
return;
// Neutral or invalid skip
if (stateSignal == NEUTURAL_STATE)
return;
// Ensure no open positions for this symbol/magic
if (HasOpenPosition(InpSymbol, InpMagic))
return;
// Prepare trade params
double atrPad = 0.0;
if (InpRiskATRMult > 0.0)
{
double atr = GetATRValue(InpSymbol, InpSignalTF, InpATRPeriod, signalBarShift);
if (atr != EMPTY_VALUE && atr > 0)
atrPad = atr * InpRiskATRMult;
}
double sl, tp;
bool isBuy = (stateSignal == BULLISH_STATE);
if (isBuy)
{
sl = kiSignal - atrPad;
tp = closeSignal + (closeSignal - sl) * InpRR;
PlaceOrder(InpSymbol, ORDER_TYPE_BUY, InpFixedLot, sl, tp);
}
else if (stateSignal == BEARISH_STATE)
{
sl = kiSignal + atrPad;
tp = closeSignal - (sl - closeSignal) * InpRR;
PlaceOrder(InpSymbol, ORDER_TYPE_SELL, InpFixedLot, sl, tp);
}
// After placement, trailing handled in OnTimer or OnTick below
if (InpTrailByKI)
TrailStopsByKI();
}
//+------------------------------------------------------------------+
// Utilities
//+------------------------------------------------------------------+
//
// Create or reuse an ATR handle for the given TF ...
int GetOrCreateATRHandle(
string symbol,
ENUM_TIMEFRAMES tf,
int period //
)
{
int h = g_atrHandleH1;
if (tf == PERIOD_H4)
h = g_atrHandleH4;
else if (tf == PERIOD_D1)
h = g_atrHandleD1;
if (h == INVALID_HANDLE)
{
h = iATR(symbol, tf, period);
if (h == INVALID_HANDLE)
Print("Failed to create ATR handle: ", symbol, " ", EnumToString(tf), " period=", period);
}
return h;
}
//
// Read ATR value for a specific bar shift (1=last closed bar) ...
double GetATRValue(
string symbol,
ENUM_TIMEFRAMES tf,
int period,
int shift //
)
{
int h = GetOrCreateATRHandle(symbol, tf, period);
if (h == INVALID_HANDLE)
return EMPTY_VALUE;
//
double buff[];
//
// Copy exactly one value at 'shift' ...
int copied = CopyBuffer(h, 0, shift, 1, buff);
if (copied != 1 || !MathIsValidNumber(buff[0]))
return EMPTY_VALUE;
//
return buff[0];
}
//
// Create or reuse an RSI handle for the given TF ...
int GetOrCreateRSIHandle(
string symbol,
ENUM_TIMEFRAMES tf,
int period,
int appliedPrice //
)
{
//
int h = g_rsiHandleH1;
if (tf == PERIOD_H4)
h = g_rsiHandleH4;
else if (tf == PERIOD_D1)
h = g_rsiHandleD1;
if (h == INVALID_HANDLE)
{
h = iRSI(symbol, tf, period, appliedPrice);
if (h == INVALID_HANDLE)
Print("Failed to create RSI handle: ", symbol, " ", EnumToString(tf), " period=", period, " price=", appliedPrice);
}
return h;
}
//
// Read RSI value for a specific bar shift (1=last closed bar) ..
double GetRSIValue(
string symbol,
ENUM_TIMEFRAMES tf,
int period,
int appliedPrice,
int shift //
)
{
int h = GetOrCreateRSIHandle(symbol, tf, period, appliedPrice);
if (h == INVALID_HANDLE)
return EMPTY_VALUE;
double buff[];
int copied = CopyBuffer(h, 0, shift, 1, buff);
if (copied != 1 || !MathIsValidNumber(buff[0]))
return EMPTY_VALUE;
return buff[0];
}
datetime GetLastClosedBarTime(string symbol, ENUM_TIMEFRAMES tf)
{
datetime times[];
if (CopyTime(symbol, tf, 0, 3, times) <= 1)
return 0;
// times[0] is current open bar time; last closed is times[1]
return times[1];
}
bool IsHourInRange(int hr, int startHr, int endHr)
{
// Handles wrap-around (e.g., 22 -> 6)
if (startHr <= endHr)
return (hr >= startHr && hr < endHr);
else
return (hr >= startHr || hr < endHr);
}
bool GetXKIStateAndKI(string symbol, ENUM_TIMEFRAMES tf, int shift, int &stateOut, double &kiOut)
{
// Prepare indicator handle for this TF
static int handleH1 = INVALID_HANDLE;
static int handleH4 = INVALID_HANDLE;
static int handleD1 = INVALID_HANDLE;
int handleRef = handleH1;
if (tf == PERIOD_H4)
handleRef = handleH4;
else if (tf == PERIOD_D1)
handleRef = handleD1;
if (handleRef == INVALID_HANDLE)
{
handleRef = iCustom(symbol, tf, g_xkiIndicatorPath,
InpKiLength, InpShowKI, InpCalcLastBars);
if (handleRef == INVALID_HANDLE)
{
Print("Failed to create XKI handle for TF: ", EnumToString(tf));
return false;
}
}
double kiBuff[];
double stateBuff[];
if (CopyBuffer(handleRef, KI_BUFFER_INDEX, shift, 1, kiBuff) != 1)
return false;
if (CopyBuffer(handleRef, KI_STATE_BUFFER_INDEX, shift, 1, stateBuff) != 1)
return false;
kiOut = kiBuff[0];
stateOut = (int)stateBuff[0];
if (!MathIsValidNumber(kiOut))
return false;
return true;
}
bool HigherTFAgrees(string symbol, ENUM_TIMEFRAMES tf, int shift, int signalState)
{
int stateHTF;
double kiHTF;
if (!GetXKIStateAndKI(symbol, tf, shift, stateHTF, kiHTF))
return false;
if (signalState == BULLISH_STATE)
return (stateHTF == BULLISH_STATE);
if (signalState == BEARISH_STATE)
return (stateHTF == BEARISH_STATE);
return false;
}
bool HasOpenPosition(string symbol, int magic)
{
for (int i = 0; i < PositionsTotal(); i++)
{
ulong ticket = PositionGetTicket(i);
if (ticket == 0)
continue;
if (PositionSelectByTicket(ticket))
{
string sym = PositionGetString(POSITION_SYMBOL);
long mg = (long)PositionGetInteger(POSITION_MAGIC);
if (sym == symbol && mg == magic)
return true;
}
}
return false;
}
void PlaceOrder(string symbol, ENUM_ORDER_TYPE type, double lots, double sl, double tp)
{
MqlTradeRequest req;
MqlTradeResult res;
ZeroMemory(req);
ZeroMemory(res);
double price = 0.0;
if (!SymbolInfoTick(symbol, g_tick))
return;
if (type == ORDER_TYPE_BUY)
price = g_tick.ask;
else if (type == ORDER_TYPE_SELL)
price = g_tick.bid;
// Normalize SL/TP
sl = NormalizeDouble(sl, g_digits);
tp = NormalizeDouble(tp, g_digits);
price = NormalizeDouble(price, g_digits);
req.action = TRADE_ACTION_DEAL;
req.symbol = symbol;
req.volume = lots;
req.type = type;
req.price = price;
req.sl = sl;
req.tp = tp;
req.deviation = InpSlippagePoints;
req.magic = InpMagic;
req.comment = InpOrderComment;
if (!OrderSend(req, res))
Print("OrderSend failed: ", res.retcode);
}
void TrailStopsByKI()
{
// Trail per position using current signal TF KI
for (int i = 0; i < PositionsTotal(); i++)
{
ulong ticket = PositionGetTicket(i);
if (ticket == 0)
continue;
if (!PositionSelectByTicket(ticket))
continue;
string sym = PositionGetString(POSITION_SYMBOL);
long mg = (long)PositionGetInteger(POSITION_MAGIC);
if (sym != InpSymbol || mg != InpMagic)
continue;
ENUM_POSITION_TYPE ptype = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double sl = PositionGetDouble(POSITION_SL);
double priceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
// Use last closed bar KI for stability
int shift = 1;
int state;
double ki;
if (!GetXKIStateAndKI(sym, InpSignalTF, shift, state, ki))
continue;
MqlTradeRequest req;
MqlTradeResult res;
ZeroMemory(req);
ZeroMemory(res);
double newSL = sl;
if (ptype == POSITION_TYPE_BUY)
{
double proposedSL = NormalizeDouble(ki, g_digits);
if (proposedSL > sl)
newSL = proposedSL; // only move up
}
else if (ptype == POSITION_TYPE_SELL)
{
double proposedSL = NormalizeDouble(ki, g_digits);
if (proposedSL < sl || sl == 0.0)
newSL = proposedSL; // only move down (or set if none)
}
if (newSL != sl && newSL != 0.0)
{
req.action = TRADE_ACTION_SLTP;
req.symbol = sym;
req.sl = newSL;
req.tp = PositionGetDouble(POSITION_TP);
req.magic = InpMagic;
if (!OrderSend(req, res))
Print("Trail SLTP failed: ", res.retcode);
}
}
}
//+------------------------------------------------------------------+
Binary file not shown.
@@ -0,0 +1,708 @@
//+------------------------------------------------------------------+
//| TrendPullbackPro.mq5|
//| Trend-following pullback EA with risk & management |
//+------------------------------------------------------------------+
#property copyright "Hadi Strategy"
#property link ""
#property version "1.10"
#property strict
//--- Inputs: risk & money management
input double InpRiskPerTradePercent = 1.0; // Total risk per trade (% of balance)
input int InpMagicNumber = 123456; // Magic number
input double InpStopBufferPoints = 10; // Extra buffer beyond swing high/low (points)
//--- Inputs: indicators
input ENUM_TIMEFRAMES InpTF = PERIOD_CURRENT; // Signal timeframe
input int InpFastEMAPeriod = 20;
input int InpSlowEMAPeriod = 50;
input int InpRSIPeriod = 14;
input double InpRSILowZoneMin = 40; // Uptrend pullback zone min
input double InpRSILowZoneMax = 50; // Uptrend pullback zone max
input double InpRSIHighZoneMin = 50; // Downtrend pullback zone min
input double InpRSIHighZoneMax = 60; // Downtrend pullback zone max
//--- Inputs: partial TP and R multiples
input bool InpUsePartialTP = true;
input double InpPartialCloseAtR = 1.0; // R at which to take partial profit
input double InpPartialClosePercent = 50.0; // % of volume to close at partial TP
input double InpFinalTargetR = 3.0; // Final target R for runner
input bool InpUseBreakEven = true;
input double InpBreakEvenRMultiple = 1.0; // Move SL to BE at this R (runner)
//--- Inputs: trailing stop
input bool InpUseEMATrailing = true;
input double InpTrailStartR = 1.0; // Start trailing after this R
input double InpTrailOffsetPoints = 5; // Extra buffer beyond EMA (points)
//--- Inputs: spread & time filters
input bool InpUseSpreadFilter = true;
input double InpMaxSpreadPoints = 30; // Max allowed spread (in points)
input bool InpUseTimeFilter = false;
input int InpSessionStartHour = 8; // Trading session start (server time)
input int InpSessionEndHour = 22; // Trading session end (server time)
input bool InpAvoidRolloverHour = true;
input int InpRolloverHour = 23; // Avoid new entries at this hour
//--- constants
#define NO_TREND 0
#define UPTREND 1
#define DOWNTREND -1
#define PARTIAL_COMMENT "TrendPullbackEA_Partial"
#define RUNNER_COMMENT "TrendPullbackEA_Runner"
//--- Global indicator handles
int rsi_handle;
int ema_fast_handle;
int ema_slow_handle;
//--- Tick storage
MqlTick last_tick;
//+------------------------------------------------------------------+
//| OnInit |
//+------------------------------------------------------------------+
int OnInit()
{
rsi_handle = iRSI(_Symbol, InpTF, InpRSIPeriod, PRICE_CLOSE);
if(rsi_handle == INVALID_HANDLE)
{
Print("Error creating RSI handle. Error: ", GetLastError());
return(INIT_FAILED);
}
ema_fast_handle = iMA(_Symbol, InpTF, InpFastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
if(ema_fast_handle == INVALID_HANDLE)
{
Print("Error creating fast EMA handle. Error: ", GetLastError());
return(INIT_FAILED);
}
ema_slow_handle = iMA(_Symbol, InpTF, InpSlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
if(ema_slow_handle == INVALID_HANDLE)
{
Print("Error creating slow EMA handle. Error: ", GetLastError());
return(INIT_FAILED);
}
SymbolInfoTick(_Symbol, last_tick);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| OnDeinit |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
IndicatorRelease(rsi_handle);
IndicatorRelease(ema_fast_handle);
IndicatorRelease(ema_slow_handle);
}
//+------------------------------------------------------------------+
//| OnTick |
//+------------------------------------------------------------------+
void OnTick()
{
if(!SymbolInfoTick(_Symbol, last_tick))
return;
// Run main logic once per bar on signal timeframe
static datetime last_bar_time = 0;
datetime cur_bar_time = iTime(_Symbol, InpTF, 0);
if(cur_bar_time == last_bar_time)
return;
last_bar_time = cur_bar_time;
ManageOpenPositions();
// Avoid new entries if no time/spread conditions
if(!CanOpenNewTrades())
return;
CheckOpenSignals();
}
//+------------------------------------------------------------------+
//| Check if we can open new trades (time & spread) |
//+------------------------------------------------------------------+
bool CanOpenNewTrades()
{
// Spread filter
if(InpUseSpreadFilter)
{
double spread_points = (SymbolInfoDouble(_Symbol, SYMBOL_ASK) - SymbolInfoDouble(_Symbol, SYMBOL_BID))
/ SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if(spread_points > InpMaxSpreadPoints)
{
//Print("Spread too high: ", spread_points, " > ", InpMaxSpreadPoints);
return(false);
}
}
// Time filter
if(InpUseTimeFilter)
{
datetime now = TimeCurrent();
MqlDateTime dt;
TimeToStruct(now, dt);
// avoid rollover hour
if(InpAvoidRolloverHour && dt.hour == InpRolloverHour)
return(false);
// session window
bool inSession = (dt.hour >= InpSessionStartHour && dt.hour < InpSessionEndHour);
if(!inSession)
return(false);
}
return(true);
}
//+------------------------------------------------------------------+
//| Check for new entry signals |
//+------------------------------------------------------------------+
void CheckOpenSignals()
{
if(HasOpenPosition())
return;
int trend = GetTrendDirection();
if(trend == NO_TREND)
return;
double rsi_value;
if(!GetRSI(1, rsi_value))
return;
MqlRates rates[];
if(CopyRates(_Symbol, InpTF, 0, 3, rates) < 3)
return;
// rates[0] current, [1] closed 1, [2] closed 2
MqlRates candle = rates[1];
MqlRates prev = rates[2];
bool longSignal = false;
bool shortSignal = false;
if(trend == UPTREND)
{
if(rsi_value >= InpRSILowZoneMin && rsi_value <= InpRSILowZoneMax)
{
if(IsBullishPattern(candle, prev))
longSignal = true;
}
}
else if(trend == DOWNTREND)
{
if(rsi_value >= InpRSIHighZoneMin && rsi_value <= InpRSIHighZoneMax)
{
if(IsBearishPattern(candle, prev))
shortSignal = true;
}
}
if(longSignal)
OpenTrade(ORDER_TYPE_BUY, candle);
else if(shortSignal)
OpenTrade(ORDER_TYPE_SELL, candle);
}
//+------------------------------------------------------------------+
//| Manage open positions (partial TP, BE, trailing) |
//+------------------------------------------------------------------+
void ManageOpenPositions()
{
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
for(int i = PositionsTotal()-1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(!PositionSelectByTicket(ticket))
continue;
if(PositionGetInteger(POSITION_MAGIC) != InpMagicNumber)
continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol)
continue;
long type = PositionGetInteger(POSITION_TYPE);
double volume = PositionGetDouble(POSITION_VOLUME);
double sl = PositionGetDouble(POSITION_SL);
double tp = PositionGetDouble(POSITION_TP);
double price_open = PositionGetDouble(POSITION_PRICE_OPEN);
string comment = PositionGetString(POSITION_COMMENT);
MqlTick tick;
SymbolInfoTick(_Symbol, tick);
double current_price = (type == POSITION_TYPE_BUY ? tick.bid : tick.ask);
double riskPoints;
if(type == POSITION_TYPE_BUY)
riskPoints = (price_open - sl) / point;
else
riskPoints = (sl - price_open) / point;
if(riskPoints <= 0)
continue;
double profitPoints;
if(type == POSITION_TYPE_BUY)
profitPoints = (current_price - price_open) / point;
else
profitPoints = (price_open - current_price) / point;
double rMultiple = profitPoints / riskPoints;
// 1) Partial TP logic for "partial" leg
if(InpUsePartialTP && comment == PARTIAL_COMMENT)
{
if(rMultiple >= InpPartialCloseAtR)
{
// Close this position fully (it's the partial leg)
ClosePosition(ticket);
continue;
}
}
// 2) Break-even & trailing for runner leg
if(comment == RUNNER_COMMENT)
{
// Break-even
if(InpUseBreakEven && rMultiple >= InpBreakEvenRMultiple)
{
if(type == POSITION_TYPE_BUY && sl < price_open)
ModifyPositionSL(ticket, price_open);
else if(type == POSITION_TYPE_SELL && sl > price_open)
ModifyPositionSL(ticket, price_open);
}
// EMA trailing after a certain R
if(InpUseEMATrailing && rMultiple >= InpTrailStartR)
{
double emaFast;
if(!GetEMA(ema_fast_handle, 1, emaFast))
continue;
double newSL;
double offset = InpTrailOffsetPoints * point;
if(type == POSITION_TYPE_BUY)
{
newSL = emaFast - offset;
if(newSL > sl && newSL < current_price) // only tighten SL
ModifyPositionSL(ticket, newSL);
}
else
{
newSL = emaFast + offset;
if(newSL < sl && newSL > current_price)
ModifyPositionSL(ticket, newSL);
}
}
// Optionally: ensure TP aligns with final target R
// If user wants to rely only on trailing, they can disable or adjust final R.
// We keep TP as set at entry.
}
}
}
//+------------------------------------------------------------------+
//| Get trend direction from EMAs |
//+------------------------------------------------------------------+
int GetTrendDirection()
{
double ema_fast[3], ema_slow[3];
if(CopyBuffer(ema_fast_handle, 0, 0, 3, ema_fast) < 3)
return NO_TREND;
if(CopyBuffer(ema_slow_handle, 0, 0, 3, ema_slow) < 3)
return NO_TREND;
double fast = ema_fast[1];
double slow = ema_slow[1];
if(fast > slow)
return UPTREND;
else if(fast < slow)
return DOWNTREND;
return NO_TREND;
}
//+------------------------------------------------------------------+
//| Get RSI value at bar index |
//+------------------------------------------------------------------+
bool GetRSI(int index, double &value)
{
double buffer[1];
int copied = CopyBuffer(rsi_handle, 0, index, 1, buffer);
if(copied != 1)
return false;
value = buffer[0];
return true;
}
//+------------------------------------------------------------------+
//| Get EMA value from handle |
//+------------------------------------------------------------------+
bool GetEMA(int handle, int index, double &value)
{
double buffer[1];
int copied = CopyBuffer(handle, 0, index, 1, buffer);
if(copied != 1)
return false;
value = buffer[0];
return true;
}
//+------------------------------------------------------------------+
//| Bullish pattern: engulfing + pin-bar-ish |
//+------------------------------------------------------------------+
bool IsBullishPattern(const MqlRates &c, const MqlRates &prev)
{
double bodyC = MathAbs(c.close - c.open);
double bodyP = MathAbs(prev.close - prev.open);
double rangeC = c.high - c.low;
if(rangeC <= 0)
return false;
// Basic bullish: close > open
if(c.close <= c.open)
return false;
// Engulfing body: current body >= previous body, and covers its open/close
bool engulfing = (bodyC >= bodyP && c.open <= prev.close && c.close >= prev.open);
// Pin-bar-ish: long lower wick
double lowerWick = MathMin(c.open, c.close) - c.low;
bool longLowerWick = (lowerWick >= rangeC * 0.4); // tweak
if(engulfing || longLowerWick)
return true;
return false;
}
//+------------------------------------------------------------------+
//| Bearish pattern: engulfing + pin-bar-ish |
//+------------------------------------------------------------------+
bool IsBearishPattern(const MqlRates &c, const MqlRates &prev)
{
double bodyC = MathAbs(c.close - c.open);
double bodyP = MathAbs(prev.close - prev.open);
double rangeC = c.high - c.low;
if(rangeC <= 0)
return false;
// Basic bearish: close < open
if(c.close >= c.open)
return false;
// Engulfing body
bool engulfing = (bodyC >= bodyP && c.open >= prev.close && c.close <= prev.open);
// Pin-bar-ish: long upper wick
double upperWick = c.high - MathMax(c.open, c.close);
bool longUpperWick = (upperWick >= rangeC * 0.4); // tweak
if(engulfing || longUpperWick)
return true;
return false;
}
//+------------------------------------------------------------------+
//| Check if there is already an open position |
//+------------------------------------------------------------------+
bool HasOpenPosition()
{
for(int i = PositionsTotal()-1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(!PositionSelectByTicket(ticket))
continue;
if(PositionGetInteger(POSITION_MAGIC) != InpMagicNumber)
continue;
if(PositionGetString(POSITION_SYMBOL) == _Symbol)
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| Calculate lot size based on total risk % |
//+------------------------------------------------------------------+
double CalculateTotalVolume(double stopLossPrice, ENUM_ORDER_TYPE type)
{
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double riskMoney = balance * InpRiskPerTradePercent / 100.0;
double entryPrice = (type == ORDER_TYPE_BUY ? last_tick.ask : last_tick.bid);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
if(tick_size <= 0 || tick_value <= 0)
return(0.0);
double slDistance = (type == ORDER_TYPE_BUY ? entryPrice - stopLossPrice : stopLossPrice - entryPrice);
if(slDistance <= 0)
return(0.0);
double moneyPerPointPerLot = tick_value / tick_size * point;
double stopPoints = slDistance / point;
double volume = riskMoney / (stopPoints * moneyPerPointPerLot);
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double lotStep= SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
volume = MathFloor(volume / lotStep) * lotStep;
if(volume < minLot)
volume = 0.0;
if(volume > maxLot)
volume = maxLot;
return(volume);
}
//+------------------------------------------------------------------+
//| Open trade: split into partial + runner |
//+------------------------------------------------------------------+
void OpenTrade(ENUM_ORDER_TYPE type, const MqlRates &signalCandle)
{
MqlTick tick;
if(!SymbolInfoTick(_Symbol, tick))
return;
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double entryPrice = (type == ORDER_TYPE_BUY ? tick.ask : tick.bid);
double slPrice;
if(type == ORDER_TYPE_BUY)
slPrice = signalCandle.low - InpStopBufferPoints * point;
else
slPrice = signalCandle.high + InpStopBufferPoints * point;
if(slPrice <= 0)
return;
double totalVolume = CalculateTotalVolume(slPrice, type);
if(totalVolume <= 0)
{
Print("Calculated total volume <= 0, skipping trade.");
return;
}
double slDistance = (type == ORDER_TYPE_BUY ? entryPrice - slPrice : slPrice - entryPrice);
// final TP at FinalTargetR
double finalTPDistance = slDistance * InpFinalTargetR;
double runnerTP;
if(type == ORDER_TYPE_BUY)
runnerTP = entryPrice + finalTPDistance;
else
runnerTP = entryPrice - finalTPDistance;
// partial volume
double partialVolume = totalVolume;
double runnerVolume = 0.0;
if(InpUsePartialTP && InpPartialClosePercent > 0 && InpPartialClosePercent < 100)
{
partialVolume = totalVolume * (InpPartialClosePercent / 100.0);
runnerVolume = totalVolume - partialVolume;
}
else
{
// no partial: everything is runner
partialVolume = 0.0;
runnerVolume = totalVolume;
}
// normalized volumes
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
partialVolume = MathFloor(partialVolume / lotStep) * lotStep;
runnerVolume = MathFloor(runnerVolume / lotStep) * lotStep;
if(partialVolume < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))
partialVolume = 0.0;
if(runnerVolume < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))
runnerVolume = 0.0;
// Partial TP price at PartialCloseAtR
double partialTPPrice = 0.0;
if(InpUsePartialTP && partialVolume > 0 && InpPartialCloseAtR > 0)
{
double partialTPDist = slDistance * InpPartialCloseAtR;
if(type == ORDER_TYPE_BUY)
partialTPPrice = entryPrice + partialTPDist;
else
partialTPPrice = entryPrice - partialTPDist;
}
// 1) Open partial leg
if(partialVolume > 0.0)
{
SendOrder(type, partialVolume, slPrice, partialTPPrice, PARTIAL_COMMENT);
}
// 2) Open runner leg
if(runnerVolume > 0.0)
{
SendOrder(type, runnerVolume, slPrice, runnerTP, RUNNER_COMMENT);
}
}
//+------------------------------------------------------------------+
//| Send market order |
//+------------------------------------------------------------------+
bool SendOrder(ENUM_ORDER_TYPE type, double volume, double sl, double tp, string comment)
{
if(volume <= 0.0)
return(false);
MqlTick tick;
if(!SymbolInfoTick(_Symbol, tick))
return(false);
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.magic = InpMagicNumber;
request.symbol = _Symbol;
request.volume = volume;
request.type = type;
request.deviation = 20; // points
request.type_filling= ORDER_FILLING_FOK;
request.price = (type == ORDER_TYPE_BUY ? tick.ask : tick.bid);
request.sl = sl;
request.tp = tp;
request.comment = comment;
if(!OrderSend(request, result))
{
Print("OrderSend failed. Error: ", GetLastError());
return(false);
}
if(result.retcode != TRADE_RETCODE_DONE)
{
Print("OrderSend retcode: ", result.retcode);
return(false);
}
Print("Opened ", (type == ORDER_TYPE_BUY ? "BUY" : "SELL"),
" ticket #", result.order, " vol=", DoubleToString(volume,2),
" SL=", DoubleToString(sl,_Digits)," TP=", DoubleToString(tp,_Digits),
" comment=", comment);
return(true);
}
//+------------------------------------------------------------------+
//| Modify SL for position |
//+------------------------------------------------------------------+
bool ModifyPositionSL(ulong ticket, double newSL)
{
if(!PositionSelectByTicket(ticket))
return(false);
string sym = PositionGetString(POSITION_SYMBOL);
long type = PositionGetInteger(POSITION_TYPE);
double volume = PositionGetDouble(POSITION_VOLUME);
double price = PositionGetDouble(POSITION_PRICE_OPEN);
double tp = PositionGetDouble(POSITION_TP);
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_SLTP;
request.magic = InpMagicNumber;
request.symbol = sym;
request.volume = volume;
request.type = (ENUM_ORDER_TYPE)type;
request.price = price;
request.sl = newSL;
request.tp = tp;
if(!OrderSend(request, result))
{
Print("ModifyPositionSL OrderSend failed. Error: ", GetLastError());
return(false);
}
if(result.retcode != TRADE_RETCODE_DONE)
{
Print("ModifyPositionSL retcode: ", result.retcode);
return(false);
}
Print("Modified SL for ticket #", ticket, " to ", DoubleToString(newSL,_Digits));
return(true);
}
//+------------------------------------------------------------------+
//| Close position |
//+------------------------------------------------------------------+
bool ClosePosition(ulong ticket)
{
if(!PositionSelectByTicket(ticket))
return(false);
string sym = PositionGetString(POSITION_SYMBOL);
long type = PositionGetInteger(POSITION_TYPE);
double volume = PositionGetDouble(POSITION_VOLUME);
double price = 0.0;
MqlTick tick;
if(!SymbolInfoTick(sym, tick))
return(false);
if(type == POSITION_TYPE_BUY)
price = tick.bid;
else
price = tick.ask;
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.magic = InpMagicNumber;
request.symbol = sym;
request.volume = volume;
request.type = (type == POSITION_TYPE_BUY ? ORDER_TYPE_SELL : ORDER_TYPE_BUY);
request.price = price;
request.deviation = 20;
request.type_filling= ORDER_FILLING_FOK;
request.comment = "Close";
if(!OrderSend(request, result))
{
Print("ClosePosition OrderSend failed. Error: ", GetLastError());
return(false);
}
if(result.retcode != TRADE_RETCODE_DONE)
{
Print("ClosePosition retcode: ", result.retcode);
return(false);
}
Print("Closed ticket #", ticket);
return(true);
}
//+------------------------------------------------------------------+
Binary file not shown.
+525
View File
@@ -0,0 +1,525 @@
//+------------------------------------------------------------------+
//| XRR_Pullback.mq5 |
//| Author: Hadi (for XAUUSD,M15) |
//+------------------------------------------------------------------+
#property strict
#property version "0.1"
#property description "M15 pullback EA: Major zone (HH/LL), minor same-direction zone, pullback entry, SL under minor, TP at 2R, 1% risk."
//------------------------------- Inputs -----------------------------
input string Inp_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES Inp_WorkTF = PERIOD_M15;
// Zone detection params
input int Inp_MajorLookbackBars = 400; // bars to scan for HH/LL major zone
input int Inp_MinorWindowBars = 80; // window to find first same-direction minor zone post-major
input int Inp_ZonePadPoints = 50; // padding around zones (points)
// Confirmation / filters
input bool Inp_UseHTFConfluence = true;
input ENUM_TIMEFRAMES Inp_HTF = PERIOD_H1; // confluence timeframe
input int Inp_HTFShiftBars = 3; // HTF confirmation window
input bool Inp_UseEngulfingConfirm = true;
input bool Inp_UseRSIDivergence = false;
input int Inp_RSI_Period = 14;
input bool Inp_UseVolumeSpike = false;
input double Inp_VolSpikeFactor = 1.5; // vs 20-bar average
// Risk management
input double Inp_RiskPercent = 1.0; // 1% per trade
input bool Inp_UseATRforSL = false;
input int Inp_ATR_Period = 14;
input double Inp_ATR_Mult = 1.5;
input double Inp_MinSLPoints = 200; // floor SL (points)
input double Inp_R_MultipleTP = 2.0; // fixed R:R=1:2
// Risk-free (optional)
input bool Inp_MoveToBEatTP1 = true;
input double Inp_TP1_R = 1.0; // move to BE at 1R
input double Inp_BE_OffsetPoints = 10; // lock-in small +offset
// Sessions
input bool Inp_UseSessionFilter = true;
input int Inp_LondonOpenHour = 8; // broker time
input int Inp_LondonCloseHour = 17;
input int Inp_NYOpenHour = 13;
input int Inp_NYCloseHour = 21;
input bool Inp_AllowNYOverlapOnly = false;
// Entry placement
input bool Inp_UseLimitAtZone = true; // limit order at minor zone
input int Inp_MaxSlippagePoints = 100;
input int Inp_MinRetestWickPoints = 30;
// Safety / engine
input int Inp_MinBarsLoaded = 600;
input int Inp_SignalCoolOffBars = 20; // avoid rapid re-entries
input bool Inp_OnePositionOnly = true;
//------------------------------- Structures -------------------------
struct Zone
{
bool isValid;
double priceLow;
double priceHigh;
int barIndex; // starting bar index of zone
bool isSupply; // true: resistance (HH), false: support (LL)
};
struct MinorZone
{
bool isValid;
double priceLow;
double priceHigh;
int barIndex;
bool isSupply; // same direction as major
};
datetime lastSignalTimeBuy = 0;
datetime lastSignalTimeSell = 0;
//
int atrHandler = INVALID_HANDLE;
//------------------------------- Helpers ----------------------------
int DigitsAdjust()
{
return (int)SymbolInfoInteger(Inp_Symbol, SYMBOL_DIGITS);
}
double PointAdjust()
{
return SymbolInfoDouble(Inp_Symbol, SYMBOL_POINT);
}
double TickValue()
{
double v;
SymbolInfoDouble(Inp_Symbol, SYMBOL_TRADE_TICK_VALUE, v);
return v;
}
double TickSize()
{
double s;
SymbolInfoDouble(Inp_Symbol, SYMBOL_TRADE_TICK_SIZE, s);
return s;
}
bool IsSessionAllowed()
{
if (!Inp_UseSessionFilter)
return true;
MqlDateTime t;
TimeToStruct(TimeCurrent(), t);
int hour = t.hour;
bool london = (hour >= Inp_LondonOpenHour && hour < Inp_LondonCloseHour);
bool ny = (hour >= Inp_NYOpenHour && hour < Inp_NYCloseHour);
if (Inp_AllowNYOverlapOnly)
return (london && ny);
return (london || ny);
}
bool EngulfingBearish(int shift)
{
double o0 = iOpen(Inp_Symbol, Inp_WorkTF, shift), c0 = iClose(Inp_Symbol, Inp_WorkTF, shift);
double o1 = iOpen(Inp_Symbol, Inp_WorkTF, shift + 1), c1 = iClose(Inp_Symbol, Inp_WorkTF, shift + 1);
return (c0 < o0 && c1 > o1 && o0 < c1 && c0 < o1 && (o0 - o1) > 0 && (c1 - c0) > 0 && (o1 < c0)); // rough engulfing
}
bool EngulfingBullish(int shift)
{
double o0 = iOpen(Inp_Symbol, Inp_WorkTF, shift), c0 = iClose(Inp_Symbol, Inp_WorkTF, shift);
double o1 = iOpen(Inp_Symbol, Inp_WorkTF, shift + 1), c1 = iClose(Inp_Symbol, Inp_WorkTF, shift + 1);
return (c0 > o0 && c1 < o1 && o0 > c1 && c0 > o1 && (o0 - o1) > 0 && (c0 - c1) > 0 && (o1 > c0)); // rough engulfing inverse
}
bool VolumeSpike(int shift)
{
if (!Inp_UseVolumeSpike)
return true;
double avg = 0;
int n = 20;
for (int i = shift + 1; i < shift + 1 + n; i++)
avg += (double)iVolume(Inp_Symbol, Inp_WorkTF, i);
avg /= n;
double v0 = (double)iVolume(Inp_Symbol, Inp_WorkTF, shift);
return (v0 >= avg * Inp_VolSpikeFactor);
}
bool HTFConfluence(bool wantSupply)
{
if (!Inp_UseHTFConfluence)
return true;
// Simple HTF direction: last HTF candle close vs open
double o = iOpen(Inp_Symbol, Inp_HTF, Inp_HTFShiftBars), c = iClose(Inp_Symbol, Inp_HTF, Inp_HTFShiftBars);
bool htfDown = (c < o), htfUp = (c > o);
return wantSupply ? htfDown : htfUp;
}
//------------------------------- Zone detection ---------------------
Zone FindMajorZone()
{
Zone z;
z.isValid = false;
z.isSupply = false;
z.priceLow = 0;
z.priceHigh = 0;
z.barIndex = -1;
int bars = iBars(Inp_Symbol, Inp_WorkTF);
if (bars < Inp_MinBarsLoaded)
return z;
// Highest high / lowest low over lookback
double hh = -DBL_MAX, ll = DBL_MAX;
int hhBar = -1, llBar = -1;
for (int i = 1; i <= Inp_MajorLookbackBars; i++)
{
double h = iHigh(Inp_Symbol, Inp_WorkTF, i), l = iLow(Inp_Symbol, Inp_WorkTF, i);
if (h > hh)
{
hh = h;
hhBar = i;
}
if (l < ll)
{
ll = l;
llBar = i;
}
}
// Decide which one is closest to current action: use most recent extreme
if (hhBar < llBar)
{
z.isSupply = true;
z.isValid = true;
z.barIndex = hhBar;
z.priceLow = hh - Inp_ZonePadPoints * PointAdjust();
z.priceHigh = hh + Inp_ZonePadPoints * PointAdjust();
}
else
{
z.isSupply = false;
z.isValid = true;
z.barIndex = llBar;
z.priceLow = ll - Inp_ZonePadPoints * PointAdjust();
z.priceHigh = ll + Inp_ZonePadPoints * PointAdjust();
}
return z;
}
MinorZone FindFirstMinorSameDirection(const Zone &major)
{
MinorZone mz;
mz.isValid = false;
mz.isSupply = major.isSupply;
mz.priceLow = 0;
mz.priceHigh = 0;
mz.barIndex = -1;
if (!major.isValid)
return mz;
// Scan forward from major's bar toward current for first reaction zone aligned with major
int start = major.barIndex - 1;
int end = MathMax(1, start - Inp_MinorWindowBars);
// Heuristic: supply minor = bearish impulse followed by base; demand minor = bullish impulse followed by base
for (int i = start; i >= end; i--)
{
double o = iOpen(Inp_Symbol, Inp_WorkTF, i), c = iClose(Inp_Symbol, Inp_WorkTF, i);
double h = iHigh(Inp_Symbol, Inp_WorkTF, i), l = iLow(Inp_Symbol, Inp_WorkTF, i);
bool bearImpulse = (c < o && (o - c) > (h - l) * 0.5);
bool bullImpulse = (c > o && (c - o) > (h - l) * 0.5);
if (major.isSupply && bearImpulse)
{
// Base zone from next candle tight range
double h1 = iHigh(Inp_Symbol, Inp_WorkTF, i - 1), l1 = iLow(Inp_Symbol, Inp_WorkTF, i - 1);
mz.isValid = true;
mz.barIndex = i - 1;
mz.priceLow = l1 - Inp_ZonePadPoints * PointAdjust();
mz.priceHigh = h1 + Inp_ZonePadPoints * PointAdjust();
break;
}
if (!major.isSupply && bullImpulse)
{
double h1 = iHigh(Inp_Symbol, Inp_WorkTF, i - 1), l1 = iLow(Inp_Symbol, Inp_WorkTF, i - 1);
mz.isValid = true;
mz.barIndex = i - 1;
mz.priceLow = l1 - Inp_ZonePadPoints * PointAdjust();
mz.priceHigh = h1 + Inp_ZonePadPoints * PointAdjust();
break;
}
}
return mz;
}
//------------------------------- Signal logic -----------------------
bool PriceRetestedZone(const MinorZone &mz, bool supply, int shift = 0)
{
if (!mz.isValid)
return false;
double high = iHigh(Inp_Symbol, Inp_WorkTF, shift), low = iLow(Inp_Symbol, Inp_WorkTF, shift);
// For supply: retest when high touches zone; for demand: retest when low touches zone
if (supply)
return (high >= mz.priceLow && high <= mz.priceHigh && (high - iClose(Inp_Symbol, Inp_WorkTF, shift)) * 1.0 / PointAdjust() >= Inp_MinRetestWickPoints);
else
return (low <= mz.priceHigh && low >= mz.priceLow && (iClose(Inp_Symbol, Inp_WorkTF, shift) - low) * 1.0 / PointAdjust() >= Inp_MinRetestWickPoints);
}
bool ConfirmAtZone(bool supply)
{
int shift = 0;
if (Inp_UseEngulfingConfirm)
{
if (supply)
{
if (!EngulfingBearish(shift))
return false;
}
else
{
if (!EngulfingBullish(shift))
return false;
}
}
if (!VolumeSpike(shift))
return false;
if (!HTFConfluence(supply))
return false;
// Optional: RSI divergence could be added here if enabled.
return true;
}
//------------------------------- Risk & orders -----------------------
double CalcPositionSize(double sl_points)
{
double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * (Inp_RiskPercent / 100.0);
double tickValue = TickValue();
double tickSize = TickSize();
// Convert SL points to quoted ticks
double ticks = sl_points * PointAdjust() / tickSize;
if (ticks <= 0.0)
return 0.0;
double lots = riskMoney / (ticks * tickValue);
// Normalize to symbol step
double minLot = SymbolInfoDouble(Inp_Symbol, SYMBOL_VOLUME_MIN);
double lotStep = SymbolInfoDouble(Inp_Symbol, SYMBOL_VOLUME_STEP);
double maxLot = SymbolInfoDouble(Inp_Symbol, SYMBOL_VOLUME_MAX);
lots = MathFloor(lots / lotStep) * lotStep;
lots = MathMax(minLot, MathMin(lots, maxLot));
return lots;
}
bool PlaceEntry(const MinorZone &mz, bool supply)
{
double bid = SymbolInfoDouble(Inp_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(Inp_Symbol, SYMBOL_ASK);
double point = PointAdjust();
// SL beneath/above minor zone (or ATR-based)
double sl, entry, tp;
double sl_points;
if (supply)
{
entry = Inp_UseLimitAtZone ? mz.priceLow : bid; // sell near zone top/low
double baseSL = mz.priceHigh + Inp_ZonePadPoints * point;
if (Inp_UseATRforSL)
{
//
double atrs[];
CopyBuffer(atrHandler, MAIN_LINE, 0, 1, atrs);
double atr = atrs[0];
baseSL = MathMax(baseSL, entry + (atr * Inp_ATR_Mult));
}
sl = baseSL;
sl_points = (sl - entry) / point;
sl_points = MathMax(sl_points, Inp_MinSLPoints);
tp = entry - (sl_points * point * Inp_R_MultipleTP);
// Position sizing
double lots = CalcPositionSize(sl_points);
if (lots <= 0)
return false;
MqlTradeRequest req;
MqlTradeResult res;
ZeroMemory(req);
ZeroMemory(res);
req.action = TRADE_ACTION_DEAL;
req.symbol = Inp_Symbol;
req.type = ORDER_TYPE_SELL;
req.volume = lots;
req.price = Inp_UseLimitAtZone ? entry : bid;
req.sl = sl;
req.tp = tp;
req.deviation = Inp_MaxSlippagePoints;
bool ok = OrderSend(req, res);
if (ok)
{
lastSignalTimeSell = TimeCurrent();
}
return ok;
}
else
{
entry = Inp_UseLimitAtZone ? mz.priceHigh : ask; // buy near zone top/high
double baseSL = mz.priceLow - Inp_ZonePadPoints * point;
if (Inp_UseATRforSL)
{
//
double atrs[];
CopyBuffer(atrHandler, MAIN_LINE, 0, 1, atrs);
double atr = atrs[0];
baseSL = MathMin(baseSL, entry - (atr * Inp_ATR_Mult));
}
sl = baseSL;
sl_points = (entry - sl) / point;
sl_points = MathMax(sl_points, Inp_MinSLPoints);
tp = entry + (sl_points * point * Inp_R_MultipleTP);
double lots = CalcPositionSize(sl_points);
if (lots <= 0)
return false;
MqlTradeRequest req;
MqlTradeResult res;
ZeroMemory(req);
ZeroMemory(res);
req.action = TRADE_ACTION_DEAL;
req.symbol = Inp_Symbol;
req.type = ORDER_TYPE_BUY;
req.volume = lots;
req.price = Inp_UseLimitAtZone ? entry : ask;
req.sl = sl;
req.tp = tp;
req.deviation = Inp_MaxSlippagePoints;
bool ok = OrderSend(req, res);
if (ok)
{
lastSignalTimeBuy = TimeCurrent();
}
return ok;
}
}
//------------------------------- Position management ----------------
void ManageOpenPositions()
{
int total = PositionsTotal();
double point = PointAdjust();
for (int i = 0; i < total; i++)
{
string sym = PositionGetSymbol(i);
if (sym != Inp_Symbol)
continue;
if (!PositionSelect(sym))
continue;
long type = (long)PositionGetInteger(POSITION_TYPE);
double price = PositionGetDouble(POSITION_PRICE_OPEN);
double sl = PositionGetDouble(POSITION_SL);
double tp = PositionGetDouble(POSITION_TP);
double current = (type == POSITION_TYPE_BUY) ? SymbolInfoDouble(sym, SYMBOL_BID) : SymbolInfoDouble(sym, SYMBOL_ASK);
// Risk-free move to BE at TP1 (= 1R)
if (Inp_MoveToBEatTP1 && tp > 0 && sl > 0)
{
double rDist = MathAbs(tp - price) / Inp_R_MultipleTP;
bool hitTP1 = (type == POSITION_TYPE_BUY ? (current >= price + rDist) : (current <= price - rDist));
if (hitTP1)
{
double newSL = (type == POSITION_TYPE_BUY ? price + Inp_BE_OffsetPoints * point : price - Inp_BE_OffsetPoints * point);
if ((type == POSITION_TYPE_BUY && newSL > sl) || (type == POSITION_TYPE_SELL && newSL < sl))
{
MqlTradeRequest req;
MqlTradeResult res;
ZeroMemory(req);
ZeroMemory(res);
req.action = TRADE_ACTION_SLTP;
req.symbol = sym;
req.position = (ulong)PositionGetInteger(POSITION_TICKET);
req.sl = newSL;
req.tp = tp;
OrderSend(req, res);
}
}
}
}
}
//------------------------------- Engine ------------------------------
bool CoolOffOk(bool supply)
{
datetime last = supply ? lastSignalTimeSell : lastSignalTimeBuy;
if (last == 0)
return true;
// Convert bars to seconds approximate using last M15 duration
int seconds = Inp_SignalCoolOffBars * 15 * 60;
return (TimeCurrent() - last) >= seconds;
}
void TrySignal()
{
if (!IsSessionAllowed())
return;
Zone major = FindMajorZone();
if (!major.isValid)
return;
MinorZone minor = FindFirstMinorSameDirection(major);
if (!minor.isValid)
return;
// Only act on retest + confirmation
bool retest = PriceRetestedZone(minor, major.isSupply, 0);
if (!retest)
return;
if (!ConfirmAtZone(major.isSupply))
return;
if (Inp_OnePositionOnly && PositionsTotal() > 0)
return;
if (!CoolOffOk(major.isSupply))
return;
PlaceEntry(minor, major.isSupply);
}
//------------------------------- Standard events --------------------
int OnInit()
{
//
if (Symbol() != Inp_Symbol)
{
SymbolSelect(Inp_Symbol, true);
}
//
atrHandler = iATR(Inp_Symbol, Inp_WorkTF, Inp_ATR_Period);
return (INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
void OnTick()
{
static datetime lastBarTime = 0;
MqlRates rates[];
int copied = CopyRates(Inp_Symbol, Inp_WorkTF, 0, Inp_MinBarsLoaded, rates);
if (copied < Inp_MinBarsLoaded)
return;
datetime curBarTime = rates[0].time;
if (curBarTime != lastBarTime)
{
// New bar on M15: evaluate signal
TrySignal();
lastBarTime = curBarTime;
}
// Manage open positions continuously
ManageOpenPositions();
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,288 @@
//+------------------------------------------------------------------+
//| ZigzagColor.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
#property indicator_type1 DRAW_COLOR_ZIGZAG
#property indicator_width1 3
#property indicator_color1 clrAqua, clrMagenta
//--- input parameters
input int InpDepth =12; // Depth
input int InpDeviation=5; // Deviation
input int InpBackstep =3; // Back Step
//--- indicator buffers
double ZigzagPeakBuffer[];
double ZigzagBottomBuffer[];
double HighMapBuffer[];
double LowMapBuffer[];
double ColorBuffer[];
int ExtRecalc=3; // recounting's depth
enum EnSearchMode
{
Extremum=0, // searching for the first extremum
Peak=1, // searching for the next ZigZag peak
Bottom=-1 // searching for the next ZigZag bottom
};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ZigzagPeakBuffer,INDICATOR_DATA);
SetIndexBuffer(1,ZigzagBottomBuffer,INDICATOR_DATA);
SetIndexBuffer(2,ColorBuffer,INDICATOR_COLOR_INDEX);
SetIndexBuffer(3,HighMapBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(4,LowMapBuffer,INDICATOR_CALCULATIONS);
//--- set accuracy
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- name for DataWindow and indicator subwindow label
string short_name=StringFormat("ZigZagColor(%d,%d,%d)",InpDepth,InpDeviation,InpBackstep);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
PlotIndexSetString(0,PLOT_LABEL,short_name);
//--- set an empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
}
//+------------------------------------------------------------------+
//| ZigZag calculation |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total<100)
return(0);
//---
int i,start=0;
int extreme_counter=0,extreme_search=Extremum;
int shift,back=0,last_high_pos=0,last_low_pos=0;
double val=0,res=0;
double cur_low=0,cur_high=0,last_high=0,last_low=0;
//--- initializing
if(prev_calculated==0)
{
ArrayInitialize(ZigzagPeakBuffer,0.0);
ArrayInitialize(ZigzagBottomBuffer,0.0);
ArrayInitialize(HighMapBuffer,0.0);
ArrayInitialize(LowMapBuffer,0.0);
//--- start calculation from bar number InpDepth
start=InpDepth-1;
}
//--- ZigZag was already calculated before
if(prev_calculated>0)
{
i=rates_total-1;
//--- searching for the third extremum from the last uncompleted bar
while(extreme_counter<ExtRecalc && i>rates_total -100)
{
res=(ZigzagPeakBuffer[i]+ZigzagBottomBuffer[i]);
//---
if(res!=0)
extreme_counter++;
i--;
}
i++;
start=i;
//--- what type of exremum we search for
if(LowMapBuffer[i]!=0)
{
cur_low=LowMapBuffer[i];
extreme_search=Peak;
}
else
{
cur_high=HighMapBuffer[i];
extreme_search=Bottom;
}
//--- clear indicator values
for(i=start+1; i<rates_total && !IsStopped(); i++)
{
ZigzagPeakBuffer[i] =0.0;
ZigzagBottomBuffer[i]=0.0;
LowMapBuffer[i] =0.0;
HighMapBuffer[i] =0.0;
}
}
//--- searching for high and low extremes
for(shift=start; shift<rates_total && !IsStopped(); shift++)
{
//--- low
val=Lowest(low,InpDepth,shift);
if(val==last_low)
val=0.0;
else
{
last_low=val;
if((low[shift]-val)>(InpDeviation*_Point))
val=0.0;
else
{
for(back=InpBackstep; back>=1; back--)
{
res=LowMapBuffer[shift-back];
//---
if((res!=0) && (res>val))
LowMapBuffer[shift-back]=0.0;
}
}
}
if(low[shift]==val)
LowMapBuffer[shift]=val;
else
LowMapBuffer[shift]=0.0;
//--- high
val=Highest(high,InpDepth,shift);
if(val==last_high)
val=0.0;
else
{
last_high=val;
if((val-high[shift])>(InpDeviation*_Point))
val=0.0;
else
{
for(back=InpBackstep; back>=1; back--)
{
res=HighMapBuffer[shift-back];
//---
if((res!=0) && (res<val))
HighMapBuffer[shift-back]=0.0;
}
}
}
if(high[shift]==val)
HighMapBuffer[shift]=val;
else
HighMapBuffer[shift]=0.0;
}
//--- set last values
if(extreme_search==0) // undefined values
{
last_low=0;
last_high=0;
}
else
{
last_low=cur_low;
last_high=cur_high;
}
//--- final selection of extreme points for ZigZag
for(shift=start; shift<rates_total && !IsStopped(); shift++)
{
res=0.0;
switch(extreme_search)
{
case Extremum:
if(last_low==0 && last_high==0)
{
if(HighMapBuffer[shift]!=0)
{
last_high=high[shift];
last_high_pos=shift;
extreme_search=-1;
ZigzagPeakBuffer[shift]=last_high;
ColorBuffer[shift]=0;
res=1;
}
if(LowMapBuffer[shift]!=0)
{
last_low=low[shift];
last_low_pos=shift;
extreme_search=1;
ZigzagBottomBuffer[shift]=last_low;
ColorBuffer[shift]=1;
res=1;
}
}
break;
case Peak:
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<last_low &&
HighMapBuffer[shift]==0.0)
{
ZigzagBottomBuffer[last_low_pos]=0.0;
last_low_pos=shift;
last_low=LowMapBuffer[shift];
ZigzagBottomBuffer[shift]=last_low;
ColorBuffer[shift]=1;
res=1;
}
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
{
last_high=HighMapBuffer[shift];
last_high_pos=shift;
ZigzagPeakBuffer[shift]=last_high;
ColorBuffer[shift]=0;
extreme_search=Bottom;
res=1;
}
break;
case Bottom:
if(HighMapBuffer[shift]!=0.0 &&
HighMapBuffer[shift]>last_high &&
LowMapBuffer[shift]==0.0)
{
ZigzagPeakBuffer[last_high_pos]=0.0;
last_high_pos=shift;
last_high=HighMapBuffer[shift];
ZigzagPeakBuffer[shift]=last_high;
ColorBuffer[shift]=0;
}
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
{
last_low=LowMapBuffer[shift];
last_low_pos=shift;
ZigzagBottomBuffer[shift]=last_low;
ColorBuffer[shift]=1;
extreme_search=Peak;
}
break;
default:
return(rates_total);
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Get highest value for range |
//+------------------------------------------------------------------+
double Highest(const double&array[],int count,int start)
{
double res=array[start];
//---
for(int i=start-1; i>start-count && i>=0; i--)
if(res<array[i])
res=array[i];
//---
return(res);
}
//+------------------------------------------------------------------+
//| Get lowest value for range |
//+------------------------------------------------------------------+
double Lowest(const double&array[],int count,int start)
{
double res=array[start];
//---
for(int i=start-1; i>start-count && i>=0; i--)
if(res>array[i])
res=array[i];
//---
return(res);
}
//+------------------------------------------------------------------+
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,383 @@
//+------------------------------------------------------------------+
//| ZigZag Analyzer.mq5|
//| Copyright 2025, MetaQuotes Ltd.|
//| https://www.mql5.com/en/users/lynnchris|
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com/en/users/lynnchris"
#property version "1.0"
#property strict
//
#include "../Libraries/x-saherelm.common.lib.mq5"
// Input parameters
input ENUM_TIMEFRAMES InpTimeFrame = PERIOD_CURRENT; // Timeframe to analyze
input int ZZ_Depth = 12; // ZigZag depth
input int ZZ_Deviation = 5; // ZigZag deviation
input int ZZ_Backstep = 3; // ZigZag backstep
input int LookBackBars = 500; // Bars to search for pivots
input int ExtendFutureBars = 100; // Bars to extend trendlines into the future
// Global indicator handle for ZigZag
int zzHandle;
// Arrays for ZigZag data and pivot storage
double zzBuffer[];
bool pivotIsPeak[];
double pivotPrices[];
datetime pivotTimes[];
// Variable to detect new bars
datetime lastBarTime = 0;
//+------------------------------------------------------------------+
//| Initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//
zzHandle = iCustom(
_Symbol,
InpTimeFrame,
"x-saherelm.xzg",
"",
ZZ_Depth,
ZZ_Deviation,
ZZ_Backstep,
X_PRICE_HIGH,
X_PRICE_LOW,
"",
false,
false,
true,
159,
159 //
);
if (zzHandle == INVALID_HANDLE)
{
Print("Error creating ZigZag handle");
return (INIT_FAILED);
}
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectDelete(0, "Downtrend_HighLine");
ObjectDelete(0, "Downtrend_LowLine");
ObjectDelete(0, "Major_Resistance");
ObjectDelete(0, "Major_Support");
ObjectDelete(0, "Minor_Resistance");
ObjectDelete(0, "Minor_Support");
IndicatorRelease(zzHandle);
}
//+------------------------------------------------------------------+
//| Tick function |
//+------------------------------------------------------------------+
void OnTick()
{
datetime currentBarTime = iTime(_Symbol, InpTimeFrame, 0);
if (currentBarTime == lastBarTime)
return;
lastBarTime = currentBarTime;
// Remove previous objects
ObjectDelete(0, "Downtrend_HighLine");
ObjectDelete(0, "Downtrend_LowLine");
ObjectDelete(0, "Major_Resistance");
ObjectDelete(0, "Major_Support");
ObjectDelete(0, "Minor_Resistance");
ObjectDelete(0, "Minor_Support");
if (CopyBuffer(zzHandle, 0, 0, LookBackBars, zzBuffer) <= 0)
{
Print("Failed to copy ZigZag data");
return;
}
ArraySetAsSeries(zzBuffer, true);
DrawZigZagTrendlines();
DrawSupportResistance();
}
//+------------------------------------------------------------------+
//| Draw ZigZag-based Trendlines |
//+------------------------------------------------------------------+
void DrawZigZagTrendlines()
{
double highPrices[10], lowPrices[10];
datetime highTimes[10], lowTimes[10];
int highCount = 0, lowCount = 0;
// Extract swing points from the ZigZag buffer
for (int i = 0; i < LookBackBars - 1; i++)
{
if (zzBuffer[i] != 0)
{
if (iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && highCount < 10)
{
highPrices[highCount] = zzBuffer[i];
highTimes[highCount] = iTime(_Symbol, InpTimeFrame, i);
highCount++;
}
else if (iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && lowCount < 10)
{
lowPrices[lowCount] = zzBuffer[i];
lowTimes[lowCount] = iTime(_Symbol, InpTimeFrame, i);
lowCount++;
}
}
}
// Exclude the most recent swing if possible
int usedHighCount = (highCount >= 4) ? highCount - 1 : highCount;
int usedLowCount = (lowCount >= 4) ? lowCount - 1 : lowCount;
double mHigh = 0, bHigh = 0, mLow = 0, bLow = 0;
bool validHigh = false, validLow = false;
// Regression for highs
if (usedHighCount >= 3)
{
double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0;
for (int i = 0; i < usedHighCount; i++)
{
double t = (double)highTimes[i];
double p = highPrices[i];
sumT += t;
sumP += p;
sumTP += t * p;
sumT2 += t * t;
}
int N = usedHighCount;
double denominator = N * sumT2 - sumT * sumT;
if (denominator != 0)
{
mHigh = (N * sumTP - sumT * sumP) / denominator;
bHigh = (sumP - mHigh * sumT) / N;
}
else
bHigh = sumP / N;
validHigh = true;
}
// Regression for lows
if (usedLowCount >= 3)
{
double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0;
for (int i = 0; i < usedLowCount; i++)
{
double t = (double)lowTimes[i];
double p = lowPrices[i];
sumT += t;
sumP += p;
sumTP += t * p;
sumT2 += t * t;
}
int N = usedLowCount;
double denominator = N * sumT2 - sumT * sumT;
if (denominator != 0)
{
mLow = (N * sumTP - sumT * sumP) / denominator;
bLow = (sumP - mLow * sumT) / N;
}
else
bLow = sumP / N;
validLow = true;
}
// Define time limits for trendlines
datetime pastTime = iTime(_Symbol, InpTimeFrame, LookBackBars - 1);
datetime futureTime = lastBarTime + ExtendFutureBars * PeriodSeconds();
// Draw trendlines if both regressions are valid
if (validHigh && validLow)
{
// When slopes have the same sign, use average slope
if (mHigh * mLow > 0)
{
double mParallel = (mHigh + mLow) / 2.0;
double bHighParallel = highPrices[0] - mParallel * (double)highTimes[0];
double bLowParallel = lowPrices[0] - mParallel * (double)lowTimes[0];
datetime highStartTime = pastTime;
double highStartPrice = mParallel * (double)highStartTime + bHighParallel;
double highEndPrice = mParallel * (double)futureTime + bHighParallel;
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
Print("Failed to create High Trendline");
else
{
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
}
datetime lowStartTime = pastTime;
double lowStartPrice = mParallel * (double)lowStartTime + bLowParallel;
double lowEndPrice = mParallel * (double)futureTime + bLowParallel;
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
Print("Failed to create Low Trendline");
else
{
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
}
}
else
{
datetime highStartTime = pastTime;
double highStartPrice = mHigh * (double)highStartTime + bHigh;
double highEndPrice = mHigh * (double)futureTime + bHigh;
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
Print("Failed to create High Trendline");
else
{
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
}
datetime lowStartTime = pastTime;
double lowStartPrice = mLow * (double)lowStartTime + bLow;
double lowEndPrice = mLow * (double)futureTime + bLow;
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
Print("Failed to create Low Trendline");
else
{
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
}
}
}
else
{
if (validHigh)
{
datetime highStartTime = pastTime;
double highStartPrice = mHigh * (double)highStartTime + bHigh;
double highEndPrice = mHigh * (double)futureTime + bHigh;
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
Print("Failed to create High Trendline");
else
{
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
}
}
if (validLow)
{
datetime lowStartTime = pastTime;
double lowStartPrice = mLow * (double)lowStartTime + bLow;
double lowEndPrice = mLow * (double)futureTime + bLow;
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
Print("Failed to create Low Trendline");
else
{
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
}
}
}
}
//+------------------------------------------------------------------+
//| Draw Support and Resistance Levels |
//+------------------------------------------------------------------+
void DrawSupportResistance()
{
double confirmedHighs[10], confirmedLows[10];
int confHighCount = 0, confLowCount = 0;
for (int i = 0; i < LookBackBars - 1; i++)
{
if (zzBuffer[i] != 0)
{
if (iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confHighCount < 10)
{
confirmedHighs[confHighCount] = zzBuffer[i];
confHighCount++;
}
else if (iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confLowCount < 10)
{
confirmedLows[confLowCount] = zzBuffer[i];
confLowCount++;
}
}
}
int usedHighCount = (confHighCount >= 4) ? confHighCount - 1 : confHighCount;
int usedLowCount = (confLowCount >= 4) ? confLowCount - 1 : confLowCount;
double majorResistance = -1e9, majorSupport = 1e9;
double minorResistance = -1e9, minorSupport = 1e9;
double tempHigh = -1e9, tempLow = -1e9;
for (int i = 0; i < usedHighCount; i++)
{
if (confirmedHighs[i] > majorResistance)
{
tempHigh = majorResistance;
majorResistance = confirmedHighs[i];
}
else if (confirmedHighs[i] > tempHigh)
{
tempHigh = confirmedHighs[i];
}
}
if (tempHigh > -1e9)
minorResistance = tempHigh;
for (int i = 0; i < usedLowCount; i++)
{
if (confirmedLows[i] < majorSupport)
{
tempLow = majorSupport;
majorSupport = confirmedLows[i];
}
else if (confirmedLows[i] < tempLow)
{
tempLow = confirmedLows[i];
}
}
if (tempLow < 1e9)
minorSupport = tempLow;
if (usedHighCount > 0)
{
if (!ObjectCreate(0, "Major_Resistance", OBJ_HLINE, 0, 0, majorResistance))
Print("Failed to create Major Resistance");
else
ObjectSetInteger(0, "Major_Resistance", OBJPROP_COLOR, clrMagenta);
if (minorResistance > -1e9 && minorResistance < majorResistance)
{
if (!ObjectCreate(0, "Minor_Resistance", OBJ_HLINE, 0, 0, minorResistance))
Print("Failed to create Minor Resistance");
else
ObjectSetInteger(0, "Minor_Resistance", OBJPROP_COLOR, clrFuchsia);
}
}
if (usedLowCount > 0)
{
if (!ObjectCreate(0, "Major_Support", OBJ_HLINE, 0, 0, majorSupport))
Print("Failed to create Major Support");
else
ObjectSetInteger(0, "Major_Support", OBJPROP_COLOR, clrAqua);
if (minorSupport < 1e9 && minorSupport > majorSupport)
{
if (!ObjectCreate(0, "Minor_Support", OBJ_HLINE, 0, 0, minorSupport))
Print("Failed to create Minor Support");
else
ObjectSetInteger(0, "Minor_Support", OBJPROP_COLOR, clrBlue);
}
}
}
//+------------------------------------------------------------------+
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,208 @@
//
// Draw Market Analysis ...
// has = iStructure.pvAnalysis.IsValid();
// if (has)
// {
// //
// XBoxZone iBox;
// XCBoxObject *iBoxObj;
//
// poiDrawer.RemoveDraws();
// //
// has = iStructure.pvAnalysis.HasSupportBox(iBox);
// if (has)
// {
// //
// iBox.to = iBar.time;
// poiDrawer.DrawBox(
// iBox,
// iBoxObj,
// true,
// iBox.type //
// );
// }
// //
// ZeroMemory(iBoxObj);
// has = iStructure.pvAnalysis.HasResistanceBox(iBox);
// if (has)
// {
// //
// iBox.to = iBar.time;
// poiDrawer.DrawBox(
// iBox,
// iBoxObj,
// true,
// iBox.type //
// );
// }
// }
// //
// // Draw Zones ...
// has = HasChild(iStructure.supports);
// if (has) {
// //
// CArrayObj *iSupportObjs;
// poiDrawer.DrawBoxes(
// iStructure.supports,
// iSupportObjs,
// true //
// );
// }
// //
// has = HasChild(iStructure.resistances);
// if (has) {
// //
// CArrayObj *iResistanceObjs;
// poiDrawer.DrawBoxes(
// iStructure.resistances,
// iResistanceObjs,
// true //
// );
// }
//
// Detecte Fibo Section Changes ...
// //
// has = fimaHelper.IsFiboSectionChanged(iDir, iBar.Index());
// has = has &&
// IsXBullish(iDir) &&
// fimaHelper.IsValeOverLast(iBar.Index());
// //
// has = fimaHelper.IsFiboSectionChanged(iDir, iBar.Index());
// has = has &&
// IsXBearish(iDir) &&
// fimaHelper.IsPeakUnderLast(iBar.Index());
// //
// has = fimaHelper.HasFiboPush(iDir, iBar.Index(), 5);
// //
// XBoxZone fimaZones[];
// int fimaZonesCount = fimaHelper.DetectXFIMAZones(
// fimaZones,
// iBar.Index(),
// true, // Only Valid Zones ...
// 50, // Number of Zones ...
// 4, // Shadow Multiplier ...
// 1, // Strength ...
// 7, // Validation Length ...
// 500 // Loopback ..
// );
//
// XPivot fimaPivots[];
// int fimaPivotsCount = fimaHelper.DetecteXFIMAPivots(
// fimaPivots,
// iBar.Index(),
// 50, // Number of Pivots ...
// 7, // Validation Length ...
// 500 // Loopback ...
// );
// //
// has = IsValidSize(fimaZonesCount);
// if (has)
// {
// //
// // Draw Detected Zones ...
// for (int i = 0; i < fimaZonesCount; i++)
// {
// //
// XCBoxObject *iObj;
// has = poiDrawer.DrawBox(
// fimaZones[i],
// iObj,
// true, // Ignore At ...
// fimaZones[i].type // Specified Name ...
// );
// if (has)
// {
// zoneObjects.Add(iObj);
// }
// }
// }
// //
// has = IsValidSize(fimaPivotsCount);
// if (has)
// {
// //
// // Draw Detected Pivots ...
// for (int i = 0; i < fimaPivotsCount; i++)
// {
// //
// XCBarArrowObject *iObj;
// has = poiDrawer.DrawPivot(
// fimaPivots[i],
// iObj);
// if (has)
// {
// pivotObjects.Add(iObj);
// }
// }
// }
//
// Detect DecisionBars ...
// XOHCL decisionBars[];
// int decisionBarsCount = 0;
// ENUM_X_DIRECTION decisionBarDirs[];
// decisionBarsCount = fimaHelper.DetectXFIMAPOIBars(
// decisionBars,
// decisionBarDirs,
// iBar.Index(),
// X_DIRECTION_ALL, // For Dir ...
// 300 // Required Number of Bars ...
// );
// decisionBarsCount = fimaHelper.DetectXFIMAReversalPOIBars(
// decisionBars,
// decisionBarDirs,
// iBar.Index(),
// true, // Force Touch Boundary ...
// X_DIRECTION_ALL, // For Dir ...
// 300 // Required Number of Bars ...
// );
// decisionBarsCount = fimaHelper.DetectXFIMAContinuationalPOIBars(
// decisionBars,
// decisionBarDirs,
// iBar.Index(),
// true,
// X_DIRECTION_ALL, // For Dir ...
// 300 // Required Number of Bars ...
// );
// //
// has = IsValidSize(decisionBarsCount);
// if (has)
// {
// //
// for (int i = 0; i < decisionBarsCount; i++)
// {
// //
// XCBarArrowObject *iObj;
// has = poiDrawer.DrawBarArrow(
// decisionBars[i],
// iObj,
// IsXBullish(decisionBarDirs[i]) ? X_PRICE_LOW : X_PRICE_HIGH,
// 159,
// IsXBullish(decisionBarDirs[i]) ? clrAqua : clrMagenta,
// 5,
// IsXBullish(decisionBarDirs[i]) ? ANCHOR_TOP : ANCHOR_BOTTOM,
// "XOHCL_" + ToXString(TimeToSeconds(decisionBars[i].time)),
// true, // Ignore Bar Tag ...
// 5 // Threshold ...
// );
// if (has)
// {
// barObjects.Add(iObj);
// }
// }
// }
@@ -0,0 +1,76 @@
if (result)
{
//
XOHCL tmpBar;
int tmpIDX = -1;
bool has = false;
double upper = 0;
double lower = 0;
int length = zone.GetAge();
//
// Support ...
tmpIDX = bar.FindLowestIndex(length, MODE_LOW);
if (IsValidIndex(tmpIDX))
{
//
if (tmpBar.Init(symbol, period, tmpIDX))
{
//
lower = iLow(symbol, period, tmpIDX);
upper = bar.FindLowest(length, MODE_CLOSE);
if (upper <= lower)
{
upper = tmpBar.GetDown();
}
//
has = support.Init(
symbol,
period,
upper,
lower,
tmpBar.time,
bar.time,
X_DIRECTION_BULLISH,
ToXString(X_BAR_PATTERN_SUPPORT) //
);
//
tmpBar.Clean();
}
}
//
// Resistance ...
tmpIDX = bar.FindHighestIndex(length, MODE_HIGH);
if (IsValidIndex(tmpIDX))
{
//
if (tmpBar.Init(symbol, period, tmpIDX))
{
//
upper = iHigh(symbol, period, tmpIDX);
lower = bar.FindHighest(length, MODE_CLOSE);
if (upper <= lower)
{
upper = tmpBar.GetUp();
}
//
has = resistance.Init(
symbol,
period,
upper,
lower,
tmpBar.time,
bar.time,
X_DIRECTION_BEARISH,
ToXString(X_BAR_PATTERN_RESISTANCE) //
);
//
tmpBar.Clean();
}
}
}
@@ -0,0 +1,765 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: XFIMAPV
// Description: Integrates All Requirements inside
// this indicator for analyse Markets Based on OM1 ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XFIMA Indicator"
#property icon "../Images/SaherElm_Logo_Color.ico"
#property strict
//
// Definitions ...
//
#define ShortName "XFIMA"
//
// Imports ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Calculation ...
input group "Calculation";
input int pvValidationLength = 7; // Peaks and Vales Validation Length
input int pvValidationCount = 2; // Recent Peak or Vale must under/over latests
input ENUM_X_PRICE peakPriceType = X_PRICE_HIGH; // Peak Calculated Price
input ENUM_X_PRICE valePriceType = X_PRICE_LOW; // Vale Calculated Price
//
// Presentation ...
input group "Presentation";
input bool showPV = true; // Show Peaks and Vales
input bool showHL = true; // Show Highs and Lows
input int startCalculationForLastBars = 1500; // Calculate Last n Bars
input int peakArrowCode = 159; // Peaks Arrow Code
input int highArrowCode = 159; // Highs Arrow Code
input int valeArrowCode = 159; // Vales Arrow Code
input int lowArrowCode = 159; // Lows Arrow Code
//
// Non Inputs ...
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
#define bullishState 1
#define neuturalState 0
#define bearishState -1
//
#define emptyValue 0.0
//
// Buffers ...
//
#property indicator_chart_window
//
#property indicator_buffers 6
#property indicator_plots 4
//
// Plot Buffers ...
//
// PEAKS ...
//
#define peakBufferIndex 0
double peakBuffer[];
//
#define peakBufferPlotIndex 0
#property indicator_label1 "PEAK"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrMagenta
#property indicator_width1 3
//
// VALES ...
//
#define valeBufferIndex 1
double valeBuffer[];
//
#define valeBufferPlotIndex 1
#property indicator_label2 "VALE"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrAqua
#property indicator_width2 3
//
// HIGHS ...
//
#define highBufferIndex 2
double highBuffer[];
//
#define highBufferPlotIndex 2
#property indicator_label3 "HIGH"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrOrangeRed
#property indicator_width3 3
//
// LOWS ...
//
#define lowBufferIndex 3
double lowBuffer[];
//
#define lowBufferPlotIndex 3
#property indicator_label4 "LOW"
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrYellow
#property indicator_width4 3
//
// Data Buffers ...
//
#define mLastBufferIndex 3
//
#define highRawBufferIndex mLastBufferIndex + 1
double highRawBuffer[];
//
#define lowRawBufferIndex mLastBufferIndex + 2
double lowRawBuffer[];
//
// Variables ...
//
int limit;
//
int maxLength;
//
int firstBarIndex;
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
bool has = false;
//
// Validate Inputs ...
has = ValidateInputs();
if (!has)
{
return INIT_PARAMETERS_INCORRECT;
}
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Initial Requirements ...
has = InitRequirements();
if (!has)
{
return INIT_FAILED;
}
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Init Succeed ...
return INIT_SUCCEEDED;
//
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
// De Initialize all Handlers and etc ...
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
// Validate Calculated Bars ...
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Custom Functions ...
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
//
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
result =
//
IsXValid(peakPriceType) &&
IsXValid(valePriceType) &&
NotEmptyZero(pvValidationLength)
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(result, pvValidationLength);
//
return result;
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// Plot Buffers ...
//
// PV ...
//
ENUM_DRAW_TYPE pvDrawType = showPV ? DRAW_ARROW : DRAW_NONE;
//
// PEAK ...
//
ArraySetAsSeries(peakBuffer, true);
SetIndexBuffer(peakBufferIndex, peakBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(peakBufferPlotIndex, PLOT_SHOW_DATA, showPV);
PlotIndexSetInteger(peakBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType);
//
PlotIndexSetDouble(peakBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(peakBufferPlotIndex, PLOT_ARROW, peakArrowCode);
//
// VALE ...
//
ArraySetAsSeries(valeBuffer, true);
SetIndexBuffer(valeBufferIndex, valeBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(valeBufferPlotIndex, PLOT_SHOW_DATA, showPV);
PlotIndexSetInteger(valeBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType);
//
PlotIndexSetDouble(valeBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(valeBufferPlotIndex, PLOT_ARROW, valeArrowCode);
//
// HL ...
//
ENUM_DRAW_TYPE hlDrawType = showHL ? DRAW_ARROW : DRAW_NONE;
//
// HIGH ...
//
ArraySetAsSeries(highBuffer, true);
SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(highBufferPlotIndex, PLOT_SHOW_DATA, showHL);
PlotIndexSetInteger(highBufferPlotIndex, PLOT_DRAW_TYPE, hlDrawType);
//
PlotIndexSetDouble(highBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(highBufferPlotIndex, PLOT_ARROW, highArrowCode);
//
// LOW ...
//
ArraySetAsSeries(lowBuffer, true);
SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(lowBufferPlotIndex, PLOT_SHOW_DATA, showHL);
PlotIndexSetInteger(lowBufferPlotIndex, PLOT_DRAW_TYPE, hlDrawType);
//
PlotIndexSetDouble(lowBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(lowBufferPlotIndex, PLOT_ARROW, lowArrowCode);
//
// Data Buffers ...
//
ArraySetAsSeries(lowRawBuffer, true);
SetIndexBuffer(lowRawBufferIndex, lowRawBuffer, INDICATOR_CALCULATIONS);
//
ArraySetAsSeries(highRawBuffer, true);
SetIndexBuffer(highRawBufferIndex, highRawBuffer, INDICATOR_CALCULATIONS);
}
/**
* Initial all Indicator Requirements ...
*
* @return ( false )
*
*/
bool InitRequirements()
{
//
bool result = true;
//
// Handlers ...
//
return result;
}
/**
* Calculate Custom Buffers ...
*
* @param barIndex: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int barIndex,
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Calculate Bars Limit and First Bar Index ...
int barsLimit = startCalculationForLastBars > 0
? startCalculationForLastBars
: 0;
if (barsLimit == 0)
{
//
barsLimit = ratesTotal;
firstBarIndex = barsLimit - 1;
}
else
{
firstBarIndex = startCalculationForLastBars;
}
//
// bool canCalculate = true;
bool canCalculate =
barIndex <= barsLimit;
if (canCalculate)
{
//
// Calculate Values ...
CalculateValues(
barIndex,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
}
else
{
FillBuffersZero(barIndex);
}
}
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
// TODO: Fill Buffers as Empty ...
lowBuffer[barIndex] = emptyValue;
highBuffer[barIndex] = emptyValue;
peakBuffer[barIndex] = emptyValue;
valeBuffer[barIndex] = emptyValue;
highRawBuffer[barIndex] = emptyValue;
lowRawBuffer[barIndex] = emptyValue;
}
/**
* Calculate Values ...
*
* @param barIndex: int, Specified Bar Index ...
* @param prevCalculated: int, Provides Previous Calculated Bars ...
* @param ratesTotal: int, Provides All Availabled Bars ...
* @param open: double Collection, Provides Open Prices Time Series ...
* @param high: double Collection, Provides High Prices Time Series ...
* @param close: double Collection, Provides Close Prices Time Series ...
* @param low: double Collection, Provides Low Prices Time Series ...
* @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ...
*/
void CalculateValues(
int barIndex,
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Common Requirements ...
//
FillBuffersZero(barIndex);
//
int lastBarIndex = barIndex + 1;
int maxBarIndex = startCalculationForLastBars > 0
? startCalculationForLastBars
: ratesTotal;
//
bool isFirstBar =
startCalculationForLastBars > 0
? barIndex == startCalculationForLastBars
: barIndex == firstBarIndex;
//
// Calculate Highs and Lows ...
XOHCL iBar;
bool has = iBar.Init(
_Symbol,
_Period,
barIndex //
);
if (!has)
{
return;
}
//
int lowestIDX = -1;
double iRawLow = iBar.FindLowest(
lowestIDX,
pvValidationLength,
valePriceType //
);
//
int highestIDX = -1;
double iRawHigh = iBar.FindHighest(
highestIDX,
pvValidationLength,
peakPriceType //
);
//
lowRawBuffer[barIndex] = iRawLow;
highRawBuffer[barIndex] = iRawHigh;
//
lowBuffer[barIndex] = iRawLow;
highBuffer[barIndex] = iRawHigh;
//
if (barIndex < firstBarIndex - (pvValidationLength + 1))
{
//
double tmp[];
ArrayCopy(
tmp,
lowRawBuffer,
0,
barIndex,
pvValidationLength //
);
double minLow = GetMin(tmp);
bool isLow = iRawLow < minLow;
lowBuffer[barIndex] =
isLow
? iRawLow
: lowBuffer[lastBarIndex];
//
XClean(tmp);
ArrayCopy(
tmp,
highRawBuffer,
0,
barIndex,
pvValidationLength //
);
double maxHigh = GetMax(tmp);
bool isHigh = iRawHigh > maxHigh;
highBuffer[barIndex] =
isHigh
? iRawHigh
: highBuffer[lastBarIndex];
//
// Cleanup Resources ...
XClean(tmp);
}
// //
// double iLow = emptyValue;
// // IsLow(iLow, barIndex);
// double iPLow = isFirstBar
// ? iLow
// : lowRawBuffer[lastBarIndex];
// //
// double iHigh = emptyValue;
// IsHigh(iHigh, barIndex);
// double iPHigh = isFirstBar
// ? iHigh
// : highRawBuffer[lastBarIndex];
// //
// // Clculate Values ...
// //
// lowRawBuffer[barIndex] = iLow;
// highRawBuffer[barIndex] = iHigh;
// //
// lowBuffer[barIndex] = NotEmptyZero(iLow)
// ? iLow
// : iPLow;
// highBuffer[barIndex] = NotEmptyZero(iHigh)
// ? iHigh
// : iPHigh;
// //
// double iP2Low =
// barIndex < maxBarIndex - 2
// ? lowBuffer[barIndex + 2]
// : emptyValue;
// double iP2High =
// barIndex < maxBarIndex - 2
// ? highBuffer[barIndex + 2]
// : emptyValue;
// //
// double mLowValues[];
// double iVale = emptyValue;
// if (NotEmptyZero(iPLow))
// {
// Add(iPLow, mLowValues);
// }
// if (NotEmptyZero(iP2Low))
// {
// Add(iP2Low, mLowValues);
// }
// bool isVale = iLow <= GetMin(mLowValues);
// iVale = isVale
// ? iLow
// : isFirstBar
// ? emptyValue
// : valeBuffer[lastBarIndex];
// valeBuffer[barIndex] = iVale;
// //
// double mHighValues[];
// double iPeak = emptyValue;
// if (NotEmptyZero(iPHigh))
// {
// Add(iPHigh, mHighValues);
// }
// if (NotEmptyZero(iP2High))
// {
// Add(iP2High, mHighValues);
// }
// bool isPeak = iHigh >= GetMax(mHighValues);
// iPeak = isPeak
// ? iHigh
// : isFirstBar
// ? emptyValue
// : peakBuffer[lastBarIndex];
// peakBuffer[barIndex] = iPeak;
// //
// bool has =
// NotEmptyZero(iLow) ||
// NotEmptyZero(iPLow) ||
// NotEmptyZero(iHigh) ||
// NotEmptyZero(iPHigh);
// if (has)
// {
// }
}
//
@@ -0,0 +1,295 @@
// //
// isBullish =
// //
// // Vales Same ...
// sameVales >= 7 &&
// //
// // PBar Patterns ...
// isBarPatternsPassed &&
// isPBarCloseOverFast &&
// //
// // Validate PullBack based on HK Bond ...
// isPullbackBullish &&
// pBar.close > pHKBondLower;
//
// poiDrawer.DrawPatternAnalysis(
// pBarAnalysis,
// structureDrawConfig.barAnalysisDrawConfig //
// );
// //
// if (IsValidSize(zonesCount))
// {
// //
// poiDrawer.DrawZones(
// zones,
// structureDrawConfig.drawConfig //
// );
// }
// //
// if (IsValidSize(affectedZonesCount))
// {
// //
// poiDrawer.DrawZones(
// affectedZones,
// structureDrawConfig.drawConfig //
// );
// }
//
// poiDrawer.DrawZones(
// affectedZonesBullish,
// structureDrawConfig.drawConfig //
// );
// //
// poiDrawer.DrawZones(
// affectedZonesBearish,
// structureDrawConfig.drawConfig //
// );
// //
// // Update POI Zones ...
// ENUM_X_DETECTOR_ZONE_ACTION zoneActions[];
// poiDetector.UpdateZones(
// iBar,
// zoneActions //
// // Validation Length ...
// // Required Zones ...
// // Loopback ...
// );
//
// Retrieve Conditions ...
// conditions.Clean();
// has = fimaHelper.GetConditions(
// conditions,
// barIndex,
// 10 // Loopback ...
// );
// if (!has)
// {
// //
// iBar.Clean();
// conditions.Clean();
// //
// return;
// }
//
// structure.Clean();
// poiDetector.AnalyseMarket(
// structure,
// structureConfig,
// barIndex //
// );
// poiDrawer.drawnObjects.Clear();
// poiDrawer.DrawMarketStructure(
// structure,
// structureDrawConfig //
// );
/**
* Check Bar Has Signal Based on Strategy X ...
*
* @param bar: XOHCL, reference to Bar ...
* @param zone: XBoxZone, reference to holds affected zone ...
* @param targets: XTarget, reference to detected Signal's Targets collections ...
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
*
* @return ( bool )
*/
bool StrategyXHasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
bool isBullish = false;
bool isBearish = false;
XOHCL continuationalBar;
XBoxZone continuationalZones[];
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
//
return result;
}
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Check Continuational Pullback ...
bool isContinuationPullBack = poiDetector.IsContinuationPullbackPattern(
pBar,
zone,
continuationalZones,
dir,
continuationalBar,
3, // Continuational Length ...
true, // Force Continuational Loopback Has Zones ...
true, // Force Continuational Loopback Has Patterns ...
2, // Pullback Length ...
false // Force Pullback Break ...
);
//
// Do ...
//
isBullish =
//
IsXBullish(dir) &&
isContinuationPullBack &&
continuationalBar.GetUp() < pBar.GetDown() &&
true
// isPBarHasBullishPatterns
//
;
//
isBearish =
//
IsXBearish(dir) &&
isContinuationPullBack &&
continuationalBar.GetDown() > pBar.GetUp() &&
true
// isPBarHasBearishPatterns
//
;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
// zone.to = bar.time;
// poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
//
// Draw Continuational Zones ...
UpdateToTime(continuationalZones, bar.time);
poiDrawer.DrawZones(continuationalZones, structureDrawConfig.drawConfig);
//
zone.Clean();
//
int idx = -1;
if (isBullish)
{
idx = GetHighestBelow(bar.GetDown(), continuationalZones);
}
else
{
idx = GetLowestAbove(bar.GetUp(), continuationalZones);
}
result = IsValidIndex(idx);
if (result)
{
zone = continuationalZones[idx];
}
//
if (zone.IsValid())
{
//
XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
iConfig.bullishColor = clrYellow;
iConfig.bearishColor = clrYellow;
poiDrawer.DrawZones(continuationalZones, iConfig);
}
//
// Manage Stops ...
if (result)
{
}
//
result = zone.IsValid();
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
continuationalBar.Clean();
XClean(continuationalZones);
//
return result;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,977 @@
`
//
// an Structure for Holds an Specified Symbols
// Positions Info ...
struct XTradeSymbolInfo
{
//
// Properties ...
//
string symbol; // Trading Symbol
//
int longs; // All Long Trades
int shorts; // All Short Trades
//
int trades; // All Trades
//
int losses; // All Loosing Trades
int profits; // All Winning Trades
//
datetime managedStart; // Managed Start Time
//
int managedSLs; // Managed SL(s)
int managedTPs; // Managed TP(s)
int managedTrades; // Managed Trades
//
double managedBalance; // Managed Start Balance
double managedProfits; // Managed Profit(s)
//
// Constructor ...
XTradeSymbolInfo()
{
Clean();
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
symbol = NULL;
//
longs = 0;
shorts = 0;
//
trades = 0;
//
losses = 0;
profits = 0;
//
managedStart = NULL;
//
managedSLs = 0;
managedTPs = 0;
managedTrades = 0;
//
managedBalance = 0;
managedProfits = 0;
//
ZeroMemory(this);
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result = IsSpecifiedValid(symbol);
//
return result;
}
//
bool IsSameAs(XTradeSymbolInfo &item)
{
//
bool result = false;
//
result = IsValid() &&
item.IsValid() &&
symbol == item.symbol;
//
return result;
}
//
string GetRestrictionDescription(
ENUM_XTRADE_RESTRICTION_PERIOD period //
)
{
//
string result = NULL;
//
if (!IsValid() ||
!HasRestrictions(period))
{
return result;
}
//
result +=
"-------------------" + "\n" +
"Restrictions: " + "\n" +
"-------------------" + "\n" +
"Symbol: " + ToXString(symbol) + "\n" +
"Period: " + ToXString(period) + "\n" +
"Start: " + ToFormatString(managedStart) + "\n" +
"Balance: " + ToXString(managedBalance) + "\n" +
"-------------------" + "\n" +
"Trades: " + ToXString(managedTrades) + "\n" +
"SL: " + ToXString(managedSLs) + "\n" +
"TP: " + ToXString(managedTPs) + "\n" +
"Profit: " + ToXString(managedProfits) + "\n" +
"";
//
return result;
}
};
//
void SetForceCloseTradesAt(
string _forceCloseAt //
)
{
forceCloseAt = _forceCloseAt;
}
//
void SetTradeSession(
string symbol,
string start,
string end,
string name = NULL //
)
{
//
// Validate Args ...
bool has = IsValid(end) &&
IsValid(start) &&
IsValid(symbol);
if (!has)
{
return;
}
//
// Create Session ...
//
XTradeSession session;
//
session.end = end;
session.name = name;
session.start = start;
//
int sessionIDX = -1;
has = FindSymbolSession(
sessionIDX,
symbol //
);
//
if (!has)
{
//
// Add New Symbol Session ...
//
XSymbolSessions iSymbolSession;
iSymbolSession.symbol = symbol;
//
AddTradingSession(
session,
iSymbolSession //
);
//
AddRef(
iSymbolSession,
sessions //
);
//
iSymbolSession.Clean();
}
else
{
//
// Update Trading Sessions of Exists Symbol Session ...
AddTradingSession(
session,
sessions[sessionIDX] //
);
}
//
// Cleanup Resources ...
session.Clean();
}
//
void SetTradeRestrictions(
ENUM_XTRADE_RESTRICTION_PERIOD _period,
int _maxAllowedTPs,
int _maxAllowedSLs,
int _maxAllowedTrades //
)
{
//
// Normalizing Args ...
_maxAllowedTPs = NormalizeInt(_maxAllowedTPs, 0);
_maxAllowedSLs = NormalizeInt(_maxAllowedSLs, 0);
_maxAllowedTrades = NormalizeInt(_maxAllowedTrades, 0);
//
restrictionsPeriod = _period;
maxAllowedTPs = _maxAllowedTPs;
maxAllowedSLs = _maxAllowedSLs;
maxAllowedTrades = _maxAllowedTrades;
}
//
// Symbol Info ...
//
bool FindSymbolIndex(
int &index,
XTradeSymbolInfo &item //
)
{
//
bool result = false;
//
index = -1;
//
result = item.IsValid();
if (!result)
{
return result;
}
//
result = HasChild(symbols);
if (!result)
{
return result;
}
//
index = FindIndex(
item,
symbols //
);
//
result = IsValidIndex(index);
//
return result;
}
//
bool FindSymbolIndex(
int &index,
string symbol //
)
{
//
bool result = false;
//
index = -1;
//
result = IsValid(symbol) &&
HasChild(symbols);
if (!result)
{
return result;
}
//
int count = ArraySize(symbols);
for (int i = 0; i < count; i++)
{
//
result = symbols[i].symbol == symbol;
if (result)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
//
void AddOrUpdateSymbolInfo(XTradeSymbolInfo &item)
{
//
bool has = item.IsValid();
if (!has)
{
return;
}
//
int index = -1;
bool isExists = FindSymbolIndex(
index,
item //
);
if (!isExists)
{
//
AddRef(
item,
symbols //
);
}
else
{
//
symbols[index].longs += item.longs;
symbols[index].shorts += item.shorts;
symbols[index].trades += item.trades;
symbols[index].losses += item.losses;
symbols[index].profits += item.profits;
symbols[index].managedSLs += item.managedSLs;
symbols[index].managedTPs += item.managedTPs;
symbols[index].managedTrades += item.managedTrades;
symbols[index].managedProfits += item.managedProfits;
//
// Handle Remove on Managed SL based On Managed TP ...
if (item.managedTPs > 0)
{
//
symbols[index].managedSLs -= item.managedTPs;
if (symbols[index].managedSLs < 0)
{
symbols[index].managedSLs = 0;
}
}
//
// Handle Remove on Managed TP based On Managed SL ...
if (item.managedSLs > 0)
{
//
symbols[index].managedTPs -= item.managedSLs;
if (symbols[index].managedTPs < 0)
{
symbols[index].managedTPs = 0;
}
}
}
}
//
void ResetSymbolsRestrictions()
{
//
bool has = HasChild(symbols);
if (has)
{
//
string prefix = "Protector: ";
//
datetime start = TimeCurrent();
double balance = trader.mAccount.GetBalance();
bool hasRestrictions = HasRestrictions(restrictionsPeriod);
if (!hasRestrictions)
{
//
balance = 0;
start = NULL;
}
//
int count = ArraySize(symbols);
for (int i = 0; i < count; i++)
{
//
XTradeSymbolInfo iInfo = symbols[i];
if (reportRestrictions)
{
//
string message = iInfo.GetRestrictionDescription(restrictionsPeriod);
alert.SendAlert(message);
}
SaveRestrictions(iInfo);
//
symbols[i].managedSLs = 0;
symbols[i].managedTPs = 0;
symbols[i].managedTrades = 0;
symbols[i].managedProfits = 0;
symbols[i].managedStart = start;
symbols[i].managedBalance = balance;
//
iInfo.Clean();
}
//
string message = prefix + "Reset Symbols Restrictions";
HandleReportProtector(message);
}
}
//
void HandleRestrictions()
{
//
bool isNewDay = timeTracker.IsNewDay();
bool isNewHour = timeTracker.IsNewHour();
bool isNewWeek = timeTracker.IsNewWeek();
bool isNewMonth = timeTracker.IsNewMonth();
//
// Reset Force Closed Flag on new Day Starts ...
if (isNewDay)
{
isForceCloseAtTime = false;
}
//
bool canResetRestrictions =
(
//
// Hourly ...
(isNewHour &&
restrictionsPeriod == XTRADE_RESTRICATION_HOURLY)
//
||
//
// Daily ...
(isNewDay &&
restrictionsPeriod == XTRADE_RESTRICATION_DAILY)
//
||
//
// Weekly ...
(isNewWeek &&
restrictionsPeriod == XTRADE_RESTRICATION_WEEKLY)
//
||
//
// Monthly ...
(isNewMonth &&
restrictionsPeriod == XTRADE_RESTRICATION_MONTHLY)
//
)
//
;
if (canResetRestrictions)
{
ResetSymbolsRestrictions();
}
}
//
bool SaveRestrictions(XTradeSymbolInfo &info)
{
//
bool result = false;
//
if (!mSaveRestrictions)
{
return result;
}
//
result = info.IsValid();
if (!result)
{
return result;
}
//
string filePath = GetRestrictionsFilePath(info.symbol);
result = IsValid(filePath);
if (!result)
{
return result;
}
//
string content = info.GetRestrictionDescription(restrictionsPeriod);
//
result = collector.Append(
filePath,
content //
);
//
return result;
}
//
// Symbol Session ...
//
bool FindSymbolSession(
int &index,
string symbol //
)
{
//
bool result = false;
//
index = -1;
//
result = IsValid(symbol) &&
HasChild(sessions);
if (!result)
{
return result;
}
//
int count = ArraySize(sessions);
for (int i = 0; i < count; i++)
{
//
result = sessions[i].symbol == symbol;
if (result)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
//
void AddTradingSession(
XTradeSession &session,
XSymbolSessions &symbolSession //
)
{
//
bool has = session.IsValid() &&
symbolSession.IsValid();
if (!has)
{
return;
}
//
// Check Session Exists in Symbol Session ...
bool isExists = false;
if (HasChild(symbolSession.sessions))
{
//
int count = ArraySize(symbolSession.sessions);
for (int i = 0; i < count; i++)
{
//
isExists = symbolSession.sessions[i].end == session.end &&
symbolSession.sessions[i].start == session.start;
if (isExists)
{
break;
}
}
}
//
if (!isExists)
{
//
AddRef(
session,
symbolSession.sessions //
);
}
}
/**
* Check Signal Execution Conditions ...
*
* @param signal: XSignal instance reference ...
* @param executionResult: ENUM_X_SIGNAL_EXECUTION_RESULT member reference ...
*
* @return ( bool )
*/
bool CheckSignal(
XSignal &signal,
ENUM_X_SIGNAL_EXECUTION_RESULT &executionResult //
)
{
//
bool result = false;
//
// Cleanup ...
executionResult = X_SIGNAL_EXECUTION_UNKNOWN;
//
// Validate Signal ...
result = signal.IsValid();
if (!result)
{
return result;
}
//
// Reporting Signal ...
if (reportSignals)
{
//
string message = signal.GetMessage("Provided");
alert.SendAlert(message);
}
//
SaveSignal(signal);
//
// Check Trade Permission ...
if (!allowTrade)
{
//
result = false;
executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED;
//
return result;
}
//
bool isLong = IsLong(signal.type);
bool isShort = IsShort(signal.type);
//
bool isLongAndAllowed =
isLong &&
allowLongs;
//
bool isShortAndAllowed =
isShort &&
allowShorts;
//
result = isLongAndAllowed ||
isShortAndAllowed;
if (!result)
{
//
executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED;
//
return result;
}
//
// Check Symbol Info Exists or not ...
int symbolInfoIDX = -1;
bool isSymbolInfoExists = FindSymbolIndex(
symbolInfoIDX,
signal.symbol //
);
//
// Check Symbol Session Exists or not ...
int symbolSessionIDX = -1;
bool isSymbolSessionExists = FindSymbolSession(
symbolSessionIDX,
signal.symbol //
);
//
// Chack Trade Session Validating ...
if (isSymbolSessionExists)
{
//
result = sessions[symbolSessionIDX].CanTrade();
if (!result)
{
//
executionResult = X_SIGNAL_EXECUTION_FAILED_DELAY_NOT_PASSED;
//
return result;
}
}
//
// Check Trade Permissions Based on SL(s) Count ...
bool hasRestrictions = restrictionsPeriod != XTRADE_RESTRICATION_NONE;
if (hasRestrictions)
{
//
// Only Can Check Restrictions when
// Symbol Info Exists ...
if (isSymbolInfoExists)
{
//
bool isTPAllowed = maxAllowedTPs == 0
? true
: symbols[symbolInfoIDX].managedTPs < maxAllowedTPs;
bool isSLAllowed = maxAllowedSLs == 0
? true
: symbols[symbolInfoIDX].managedSLs < maxAllowedSLs;
bool isTradeAllowed = maxAllowedTrades == 0
? true
: symbols[symbolInfoIDX].managedTrades < maxAllowedTrades;
//
result = isTPAllowed &&
isSLAllowed &&
isTradeAllowed;
}
//
// Report Error ...
if (!result)
{
//
executionResult = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED;
//
return result;
}
}
//
return result;
}
/**
* Execute Specified Signal ...
*
* @param signal: XSignal instance reference ...
* @param conditions: XCATBEAStrategyConditions instance reference ...
*
* @return ( bool )
*/
bool Execute(XSignal &signal)
{
//
bool result = false;
//
result = signal.IsValid();
if (!result)
{
return result;
}
//
int idx = -1;
bool isExists = HasTrade(
idx,
signal //
);
result = !isExists;
if (!result)
{
return result;
}
//
ENUM_X_SIGNAL_EXECUTION_RESULT executionResult;
//
// Checking Signal For Execution ...
result = CheckSignal(
signal,
executionResult //
);
if (result)
{
//
result = trader.ExecuteSignal(
signal,
executionResult //
);
}
//
// Alert Signal Execution ...
if (reportTrades)
{
//
string executionMessage = ToString(executionResult);
//
string message = NULL;
if (result)
{
message = signal.GetMessage("Executed");
}
else
{
message = signal.GetMessage("Failed due (" + executionMessage + ")");
}
//
alert.SendAlert(message);
}
//
if (result)
{
//
// Create Symbol Info Struct ...
XTradeSymbolInfo iSymbolInfo;
//
iSymbolInfo.trades = 1;
iSymbolInfo.managedTrades = 1;
iSymbolInfo.symbol = signal.symbol;
//
bool isLong = IsLong(signal.type);
if (isLong)
{
iSymbolInfo.longs = 1;
}
else
{
iSymbolInfo.shorts = 1;
}
//
// Fill Balance for Restrications ...
bool hasRestrictions = HasRestrictions(restrictionsPeriod);
if (hasRestrictions)
{
//
// Read Balance ...
double balance = trader.mAccount.GetBalance();
iSymbolInfo.managedBalance = balance;
iSymbolInfo.managedStart = TimeCurrent();
}
//
AddOrUpdateSymbolInfo(iSymbolInfo);
//
// Create Trade Struct ...
XTradeInfo iTrade;
//
ulong positionID = trader.GetLastOpenPositionTicket();
double commission = trader.GetPositionCommission(positionID);
//
iTrade.signal = signal;
iTrade.positionID = positionID;
iTrade.commission = commission;
iTrade.signaledAt = signal.time;
iTrade.executedAt = TimeCurrent();
iTrade.conditions = signal.conditions;
//
AddRef(
iTrade,
trades //
);
}
//
return result;
}
/**
* Check Specified Symbol is Active for
* Analysing or Open Trades ...
*/
bool IsActiveSession(string symbol)
{
//
bool result = false;
//
// Validate Args ...
result = IsValid(symbol);
if (!result)
{
return result;
}
//
// TODO: Complete this ...
// //
// // Check Symbol Session Exists or not ...
// int symbolSessionIDX = -1;
// bool isSymbolSessionExists = FindSymbolSession(
// symbolSessionIDX,
// symbol //
// );
// //
// // Chack Trade Session Validating ...
// if (isSymbolSessionExists)
// {
// result = sessions[symbolSessionIDX].CanTrade();
// }
//
return result;
}
//
string forceCloseAt;
bool isForceCloseAtTime;
//
int maxAllowedTPs;
int maxAllowedSLs;
int maxAllowedTrades;
ENUM_XTRADE_RESTRICTION_PERIOD restrictionsPeriod;
XTradeSymbolInfo symbols[];
XSymbolSessions sessions[];
//
forceCloseAt = NULL;
isForceCloseAtTime = false;
//
maxAllowedTPs = 0;
maxAllowedSLs = 0;
maxAllowedTrades = 0;
restrictionsPeriod = XTRADE_RESTRICATION_NONE;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,379 @@
/**
* Create Bar Object ...
*
* @param bar: XOHCL instance Reference ...
* @param object: XCOHCLObject pointer Reference ..
* @param to: Datetime ...
*
* @return ( bool )
*/
bool CreateBar(
XOHCL &bar,
XCOHCLObject *&object,
datetime to = NULL //
)
{
//
bool result = false;
//
object = NULL;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
to = NormalizeTime(to);
//
string prefix = Prefix();
long chartID = ChartIdentification();
int window = SubWindowIdentification();
//
int width = BarWidth();
//
color mBullishColor = BarBullishColor();
color mBearishColor = BarBearishColor();
//
bool fillBody = BarFillBody();
bool fillHighShadow = BarFillHighShadow();
bool fillLowShadow = BarFillLowShadow();
//
ENUM_LINE_STYLE bodyStyle = BarBodyStyle();
ENUM_LINE_STYLE highShadowStyle = BarHighShadowStyle();
ENUM_LINE_STYLE lowShadowStyle = BarLowShadowStyle();
//
object = new XCOHCLObject();
result = object.Create(
chartID,
window,
bar,
to,
prefix //
);
if (result)
{
//
// Apply Styling ...
//
object.BodyWidth(width);
object.LowShadowWidth(width);
object.HighShadowWidth(width);
//
object.BodyStyle(bodyStyle);
object.LowShadowStyle(lowShadowStyle);
object.HighShadowStyle(highShadowStyle);
//
bool isBullish = bar.IsBullish();
if (isBullish)
{
//
object.BodyColor(mBullishColor);
object.LowShadowColor(mBullishColor);
object.HighShadowColor(mBullishColor);
}
else
{
//
object.BodyColor(mBearishColor);
object.LowShadowColor(mBearishColor);
object.HighShadowColor(mBearishColor);
}
//
object.BodyFill(fillBody);
object.HighShadowFill(fillHighShadow);
object.LowShadowFill(fillLowShadow);
}
//
return result;
}
/**
* Create Bar Arrow Object ...
*
* @param bar: XOHCL instance Reference ...
* @param priceType: ENUM_X_PRICE member ...
* @param arrow: int, Arrow Code ...
* @param clr: color, Arro Color ...
* @param width: int, Arrow Width ...
* @param anchor: ENUM_ARROW_ANCHOR, anchor of Arrow ...
* @param name: string, name of Arrow ...
*
* @return ( bool )
*/
bool CreateBarArrow(
XOHCL &bar,
XCBarArrowObject *&object,
ENUM_X_PRICE priceType,
int arrow = 159,
color clr = clrYellow,
int width = 3,
ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM,
string name = NULL //
)
{
//
bool result = false;
//
object = NULL;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
string barTag = bar.GetTag(name);
//
string prefix = Prefix();
long chartID = ChartIdentification();
int window = SubWindowIdentification();
//
color mBullishColor = BarBullishColor();
color mBearishColor = BarBearishColor();
//
prefix =
(IsValid(prefix)
? prefix + "_"
: prefix) +
barTag;
//
object = new XCBarArrowObject();
result = object
.CreateByBar(
chartID,
prefix,
window,
arrow,
bar,
priceType //
);
if (result)
{
//
object.ArrowColor(clr);
object.ArrowWidth(width);
}
//
return result;
}
/**
* Create Specific Box on Chart ...
*
* @param upper: Double ...
* @param lower: Double ...
* @param from: Datetime ...
* @param to: Datetime ...
* @param clr: Color ...
* @param width: Integer ...
* @param fill: Boolean ...
* @param style: ENUM_LINE_STYLE member ...
*
* @return ( bool )
*/
bool CreateBox(
XCBoxObject *&object,
string name,
double upper,
double lower,
datetime from,
datetime to,
datetime at,
color clr = clrYellowGreen,
int width = 1,
bool fill = false,
ENUM_LINE_STYLE style = STYLE_SOLID //
)
{
//
bool result = false;
//
object = NULL;
//
to = NormalizeTime(to);
//
string dateStr = ToFormatString(from) + "|" + ToFormatString(to);
string dateMD5 = ToMD5(dateStr);
if (!IsValid(name))
{
//
name = "XBox_" +
ToXString(upper) + "_" +
ToXString(lower) + "_" +
dateMD5;
}
//
result =
upper > 0 &&
lower > 0 &&
to > from &&
IsValid(to) &&
IsValid(name) &&
IsValid(from) &&
upper > lower;
if (!result)
{
return result;
}
//
string prefix = Prefix();
long chartID = ChartIdentification();
int window = SubWindowIdentification();
//
object = new XCBoxObject();
result = object.Create(
chartID,
window,
name,
upper,
lower,
from,
to,
at,
prefix //
);
//
if (!result)
{
return result;
}
//
object.BoxColor(clr);
object.BoxFill(fill);
object.BoxWidth(width);
object.BoxStyle(style);
//
return result;
}
/**
* Create Specific Box on Chart ...
*
* @param box: XBoxZone instance Reference ...
* @param clr: Color ...
* @param width: Integer ...
* @param fill: Boolean ...
* @param style: ENUM_LINE_STYLE member ...
*
* @return ( bool )
*/
bool CreateBox(
XBoxZone &box,
XCBoxObject *&object,
color clr = clrYellowGreen,
int width = 1,
bool fill = false,
ENUM_LINE_STYLE style = STYLE_SOLID //
)
{
//
bool result = false;
//
object = NULL;
//
result = box.IsValid();
if (!result)
{
return result;
}
//
string name = box.GetTag();
//
result = CreateBox(
object,
name,
box.upper,
box.lower,
box.from,
box.to,
box.at,
clr,
width,
fill,
style //
);
//
return result;
}
//
// Testing Draws ...
//
XFIMAMarketStructure pivots[];
//
XPivot pvPivots[];
XPivot hkPivots[];
XPivot maPivots[];
XPivot zgPivots[];
XPivot sarPivots[];
//
poiDetector.CollectZGPivots(zgPivots);
poiDetector.CollectMAPivots(maPivots);
poiDetector.CollectHKPivots(hkPivots);
poiDetector.CollectPVPivots(pvPivots);
poiDetector.CollectSARPivots(sarPivots);
//
// Merging All Pivots ...
Copy(pvPivots, pivots, false);
Copy(zgPivots, pivots, false);
Copy(maPivots, pivots, false);
Copy(hkPivots, pivots, false);
Copy(sarPivots, pivots, false);
//
if (HasChild(pivots))
{
poiDrawer.DrawPivots(pivots, iDrawConfig);
}
//
// Cleanup ...
XClean(pivots);
XClean(pvPivots);
XClean(hkPivots);
XClean(maPivots);
XClean(zgPivots);
XClean(sarPivots);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,699 @@
/**
* Check Market Conditions for Pattern Detection ...
*/
void DetectPatterns()
{
//
if (!eaIsNewBar)
{
return;
}
//
// Initialize 1 Indexed Bar ...
XOHCL cBar;
bool has = cBar.Init(
_Symbol,
_Period,
1 //
);
if (!has)
{
return;
}
//
// Do Analysis ...
//
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
// Define Detection Flags ...
//
bool detectPinned = false;
bool detectMomentum = false;
bool detectEngulfed = false;
bool detectTrueGaped = false;
//
bool detectStarPattern = false;
bool detectFlagPattern = false;
bool detectRisingPattern = false;
bool detectPiercingPattern = false;
bool detectSignalKeyBarPattern = false;
//
bool detectSwingTrend = false;
bool detectSwingTrendBreakes = false;
//
bool detectSupports = false;
bool detectResistance = false;
//
// XFIMA Patetrns ...
bool detectFIMAPatterns = true;
//
bool detectFIMAPVPatterns = false;
bool detectFIMAMAPatterns = false;
bool detectFIMASARPatterns = false;
bool detectFIMAZigZagPatterns = false;
//
bool analyseFIMAPVPivots = true;
bool analyseFIMAMAPivots = true;
bool analyseFIMASARPivots = true;
bool analyseFIMAZigZagPivots = true;
//
// Required Pivots ...
int numberOfRequiredPivots = 15;
//
// Checking Momentum Bar ...
if (detectMomentum)
{
//
bool isMomentum = fima2Signaller.poiDetector.IsMomentumBar(
cBar,
iDir //
);
bool isBullishMomentum = isMomentum &&
IsSpecifiedBullish(iDir);
bool isBearishMomentum = isMomentum &&
IsSpecifiedBearish(iDir);
if (isMomentum)
{
Print(ToXString(iDir), " Momentum Bar: ", cBar.time);
}
}
//
// Checking Engulfed Bar ...
if (detectEngulfed)
{
//
bool isEngulfed = fima2Signaller.poiDetector.IsEngulfedBar(
cBar,
iDir //
);
bool isBullishEngulfed = isEngulfed &&
IsSpecifiedBullish(iDir);
bool isBearishEngulfed = isEngulfed &&
IsSpecifiedBearish(iDir);
if (isEngulfed)
{
Print(ToXString(iDir), " Engulfed Bar: ", cBar.time);
}
}
//
// Checking TruGaped Bar ...
if (detectTrueGaped)
{
//
bool isTrueGaped = fima2Signaller.poiDetector.IsTrueGapedBar(
cBar,
iDir //
);
bool isBullishTrueGaped = isTrueGaped &&
IsSpecifiedBullish(iDir);
bool isBearishTrueGaped = isTrueGaped &&
IsSpecifiedBearish(iDir);
if (isTrueGaped)
{
Print(ToXString(iDir), " TrueGapped Bar: ", cBar.time);
}
}
//
// Checking Pinned Bar ...
if (detectPinned)
{
bool isPinned = fima2Signaller.poiDetector.IsPinnedBar(
cBar,
iDir //
);
bool isBullishPinned = isPinned &&
IsSpecifiedBullish(iDir);
bool isBearishPinned = isPinned &&
IsSpecifiedBearish(iDir);
if (isPinned)
{
Print(ToXString(iDir), " Pinned Bar: ", cBar.time);
}
}
//
// Checking Star Pattern ...
if (detectStarPattern)
{
bool isStarPattern = fima2Signaller.poiDetector.IsStartPattern(
cBar,
iDir //
);
bool isBullishStarPattern = isStarPattern &&
IsSpecifiedBullish(iDir);
bool isBearishStarPattern = isStarPattern &&
IsSpecifiedBearish(iDir);
if (isStarPattern)
{
Print(ToXString(iDir), " Star Pattern: ", cBar.time);
}
}
//
// Checking Piercing Pattern ...
if (detectPiercingPattern)
{
//
bool isPiercingPattern = fima2Signaller.poiDetector.IsPiercingPattern(
cBar,
iDir //
);
bool isBullishPiercingPattern = isPiercingPattern &&
IsSpecifiedBullish(iDir);
bool isBearishPiercingPattern = isPiercingPattern &&
IsSpecifiedBearish(iDir);
if (isPiercingPattern)
{
Print(ToXString(iDir), " Piercing Pattern: ", cBar.time);
}
}
//
// Checking Rising Pattern ...
if (detectRisingPattern)
{
//
bool isRisingPattern = fima2Signaller.poiDetector.IsRisingPattern(
cBar,
iDir //
);
bool isBullishRisingPattern = isRisingPattern &&
IsSpecifiedBullish(iDir);
bool isBearishRisingPattern = isRisingPattern &&
IsSpecifiedBearish(iDir);
if (isRisingPattern)
{
Print(ToXString(iDir), " Rising Pattern: ", cBar.time);
}
}
//
// Checking Flag Pattern ...
if (detectFlagPattern)
{
//
XOHCL swingBar;
bool isFlagPattern = fima2Signaller.poiDetector.IsFlagPattern(
cBar,
iDir,
swingBar //
);
bool isBullishFlagPattern = isFlagPattern &&
IsSpecifiedBullish(iDir);
bool isBearishFlagPattern = isFlagPattern &&
IsSpecifiedBearish(iDir);
if (isFlagPattern)
{
Print(ToXString(iDir), " Flag Pattern: ", cBar.time, ", Swing: ", swingBar.time);
}
swingBar.Clean();
}
//
// Detect SignalKey Bar Pattern ...
if (detectSignalKeyBarPattern)
{
//
bool isSignalKeyBar = fima2Signaller.poiDetector.IsSignalKeyBarPattern(
cBar,
iDir //
);
bool isBullishSignalKeyBar = isSignalKeyBar &&
IsSpecifiedBullish(iDir);
bool isBearishSignalKeyBar = isSignalKeyBar &&
IsSpecifiedBearish(iDir);
if (isSignalKeyBar)
{
Print(ToXString(iDir), " SignalKey Bar Pattern: ", cBar.time);
}
}
//
// Detect Swing Trend ...
if (detectSwingTrend)
{
//
XOHCL swings[];
bool hasSwingTrend = fima2Signaller.poiDetector.HasSwingTrend(
cBar,
iDir,
swings //
);
bool hasBullishSwingTrend = hasSwingTrend &&
IsSpecifiedBullish(iDir);
bool hasBearishSwingTrend = hasSwingTrend &&
IsSpecifiedBearish(iDir);
if (hasSwingTrend)
{
//
Print(ToXString(iDir), " Swing Trend: ", cBar.time);
//
CChartObjectTrend *iObj;
has = fima2Signaller.poiDrawer.DrawSwingTrend(
swings,
iDir,
iObj,
true // Ray Right ...
);
if (has)
{
eaDraws.Add(iObj);
}
}
SpecifiedClean(swings);
}
//
// Swing Trend Breakes ...
if (detectSwingTrendBreakes)
{
//
XOHCL swings[];
bool hasSwingTrend = fima2Signaller.poiDetector.HasSwingTrend(
cBar,
iDir,
swings //
);
bool hasBullishSwingTrend = hasSwingTrend &&
IsSpecifiedBullish(iDir);
bool hasBearishSwingTrend = hasSwingTrend &&
IsSpecifiedBearish(iDir);
if (hasSwingTrend)
{
//
if (!HasDirection(trendDir))
{
trendDir = iDir;
}
}
//
// Breaked Detection ...
if (trendDir != iDir)
{
//
Print("Trend Dir Breaked to: ", ToXString(iDir));
trendDir = iDir;
}
//
SpecifiedClean(swings);
}
//
// Detect Supports ...
if (detectSupports)
{
//
XOHCL support;
bool hasSupport = fima2Signaller.poiDetector.HasSupport(
cBar,
support //
);
if (hasSupport)
{
//
XBoxZone supportBox;
has = ToSupportBox(support, supportBox);
if (has)
{
//
// Draw Box ...
XCBoxObject *iObj;
has = fima2Signaller.poiDrawer.DrawBox(
supportBox,
iObj //
);
if (has)
{
eaDraws.Add(iObj);
}
//
ZeroMemory(iObj);
}
//
supportBox.Clean();
}
support.Clean();
}
//
// Detect Resistance ...
if (detectResistance)
{
//
XOHCL resistance;
bool hasResistance = fima2Signaller.poiDetector.HasResistance(
cBar,
resistance //
);
if (hasResistance)
{
//
XBoxZone resistanceBox;
has = ToResistanceBox(resistance, resistanceBox);
if (has)
{
//
// Draw Box ...
XCBoxObject *iObj;
has = fima2Signaller.poiDrawer.DrawBox(
resistanceBox,
iObj //
);
if (has)
{
eaDraws.Add(iObj);
}
//
ZeroMemory(iObj);
}
//
resistanceBox.Clean();
}
resistance.Clean();
}
//
// Detecting FIMA Patterns ...
if (detectFIMAPatterns)
{
//
// Check For PV Pivots ...
if (detectFIMAPVPatterns)
{
//
XPivot pivots[];
int pivotsCount = fima2Signaller.poiDetector.ExtractPVPivots(
pivots, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500, // Max Allowed Loopback ...
10 // Validation Length ...
);
has = IsValidSize(pivotsCount);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
pivots,
drawnPivots //
);
has = IsValidSize(drawnPivotsCount);
if (has)
{
//
AddObjects(
drawnPivots,
eaDraws //
);
//
// Print("Pivots Extracted ...");
}
//
ZeroMemory(drawnPivots);
}
}
//
// Check for MA Patterns ...
if (detectFIMAMAPatterns)
{
//
XPivot pivots[];
int pivotsCount = fima2Signaller.poiDetector.ExtractMAPivots(
pivots, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500, // Max Allowed Loopback ...
0 // Validation Length ...
);
has = IsValidSize(pivotsCount);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
pivots,
drawnPivots //
);
has = IsValidSize(drawnPivotsCount);
if (has)
{
//
AddObjects(
drawnPivots,
eaDraws //
);
//
// Print("Pivots Extracted ...");
}
//
ZeroMemory(drawnPivots);
}
}
//
// Check for SAR Pivots ...
if (detectFIMASARPatterns)
{
//
XPivot pivots[];
int pivotsCount = fima2Signaller.poiDetector.ExtractSARPivots(
pivots, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500 // Max Allowed Loopback ...
);
has = IsValidSize(pivotsCount);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
pivots,
drawnPivots //
);
has = IsValidSize(drawnPivotsCount);
if (has)
{
//
AddObjects(
drawnPivots,
eaDraws //
);
//
// Print("Pivots Extracted ...");
}
//
ZeroMemory(drawnPivots);
}
}
//
// Check for ZigZag Pivots ...
if (detectFIMAZigZagPatterns)
{
//
XPivot pivots[];
int pivotsCount = fima2Signaller.poiDetector.ExtractZigZagPivots(
pivots,
cBar.Index(),
numberOfRequiredPivots,
1500 //
);
has = IsValidSize(pivotsCount);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
pivots,
drawnPivots //
);
has = IsValidSize(drawnPivotsCount);
if (has)
{
//
AddObjects(
drawnPivots,
eaDraws //
);
//
// Print("Pivots Extracted ...");
}
//
ZeroMemory(drawnPivots);
}
}
//
// Analysers ...
//
// Analyse Based on PV ...
if (analyseFIMAPVPivots)
{
//
XPivotAnalysis analysis;
has = fima2Signaller.poiDetector.AnalysePVPivots(
analysis, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500, // Max Allowed Loopback ...
10 // Validation Length ...
);
if (has)
{
//
// Draw Analysis ...
DestroyObject(pvAnalysisObject);
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
analysis,
pvAnalysisObject,
true // Draw Pivots ...
);
if (has)
{
//
// eaDraws.Add(iObj);
//
// Print("FIMA PV Pivots Analysed ...");
}
}
}
//
// Analyse Based on MA ...
if (analyseFIMAMAPivots)
{
//
XPivotAnalysis analysis;
has = fima2Signaller.poiDetector.AnalyseMAPivots(
analysis, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500, // Max Allowed Loopback ...
0 // Validation Length ...
);
if (has)
{
//
// Draw Analysis ...
DestroyObject(maAnalysisObject);
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
analysis,
maAnalysisObject,
true // Draw Pivots ...
);
if (has)
{
//
// eaDraws.Add(iObj);
//
// Print("FIMA MA Pivots Analysed ...");
}
}
}
//
// Analyse Based on SAR ...
if (analyseFIMASARPivots)
{
//
XPivotAnalysis analysis;
has = fima2Signaller.poiDetector.AnalyseSARPivots(
analysis, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500 // Max Allowed Loopback ...
);
if (has)
{
//
// Draw Analysis ...
DestroyObject(sarAnalysisObject);
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
analysis,
sarAnalysisObject,
true // Draw Pivots ...
);
if (has)
{
//
// eaDraws.Add(iObj);
//
// Print("FIMA Sar Pivots Analysed ...");
}
}
}
//
// Analyse Based on ZigZag ...
if (analyseFIMAZigZagPivots)
{
//
XPivotAnalysis analysis;
has = fima2Signaller.poiDetector.AnalyseZigZagPivots(
analysis, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500 // Max Allowed Loopback ...
);
if (has)
{
//
// Draw Analysis ...
DestroyObject(zigzagAnalysisObject);
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
analysis,
zigzagAnalysisObject,
true // Draw Pivots ...
);
if (has)
{
//
// eaDraws.Add(iObj);
//
// Print("FIMA ZigZag Pivots Analysed ...");
}
}
}
}
//
cBar.Clean();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,567 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Library
// -------------------------------------------------
// Name: XCXFIMAEALib ...
// Description: XFIMAEA Library ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XFIMAEA Library"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
#include "../Classes/x-saherelm.xfima.parser.class.mq5"
#include "../../Libraries/x-saherelm.x-pivot.analysis.lib.mq5"
//
// Definitions ...
/**
* XFIMA Base Market Structure ...
* AnalyseMarket result ...
**/
struct XFIMAMarketStructure
{
//
XOHCL bar; // Spacified Start Bar for Analysing ...
XPatternAnalysis barAnalysis; // Structure Bar Pattern Analysis ...
//
XPivotAnalysis pvAnalysis; // PV Pivot Analysis Result ...
XPivotAnalysis zgAnalysis; // ZG Pivot Analysis Result ...
//
XPatternAnalysis barsAnalysis[]; // Anaysed Bars ...
//
// Constructor ...
XFIMAMarketStructure()
{
Clean();
}
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
bar.Clean();
barAnalysis.Clean();
//
pvAnalysis.Clean();
zgAnalysis.Clean();
XClean(barsAnalysis);
//
ZeroMemory(this);
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result = bar.IsValid() &&
barAnalysis.IsValid();
//
return result;
}
//
// Collectors ...
/**
* Collect Required Zones from Structure ...
*
* @param dest: XBoxZone, reference collection to holds result ...
* @param forDir: ENUM_X_DIRECTION, Specified Collectiong ones Direction ...
* @param containsOB: bool, Contains OB Zones ...
* @param containsFVG: bool, Contains FVG Zones ...
*
* @return ( int )
*/
int CollectZones(
XBoxZone &dest[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
bool containsOB = false,
bool containsFVG = false //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return result;
}
//
bool canCollectBullish =
IsXBullish(forDir) ||
!HasDirection(forDir);
//
bool canCollectBearish =
IsXBearish(forDir) ||
!HasDirection(forDir);
//
int count = 0;
XBoxZone tmpBox;
//
// Check Analysis ...
//
// XPV ...
has = pvAnalysis.IsValid();
if (has)
{
//
// Support ...
tmpBox.Clean();
has = pvAnalysis.HasSupportBox(tmpBox);
if (has && canCollectBullish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
//
// Resistance ...
tmpBox.Clean();
has = pvAnalysis.HasResistanceBox(tmpBox);
if (has && canCollectBearish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
}
//
// XZG ...
has = zgAnalysis.IsValid();
if (has)
{
//
// Support ...
tmpBox.Clean();
has = zgAnalysis.HasSupportBox(tmpBox);
if (has && canCollectBullish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
//
// Resistance ...
tmpBox.Clean();
has = zgAnalysis.HasResistanceBox(tmpBox);
if (has && canCollectBearish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
}
//
// Bar Patterns ...
has = HasChild(barsAnalysis);
if (has)
{
//
count = ArraySize(barsAnalysis);
for (int i = 0; i < count; i++)
{
//
// Support ...
has = barsAnalysis[i].IsSupport();
if (has && canCollectBullish)
{
//
AddIfNotExists(
barsAnalysis[i].support,
dest //
);
}
//
// Resistance ...
has = barsAnalysis[i].IsResistance();
if (has && canCollectBearish)
{
//
AddIfNotExists(
barsAnalysis[i].resistance,
dest //
);
}
//
// OB ...
if (containsOB)
{
//
has = barsAnalysis[i].IsOB();
if (has)
{
//
has = (canCollectBullish && barsAnalysis[i].ob.IsBullish()) ||
(canCollectBearish && barsAnalysis[i].ob.IsBearish());
if (has)
{
//
AddIfNotExists(
barsAnalysis[i].ob,
dest //
);
}
}
}
//
// FVG ...
if (containsFVG)
{
has = barsAnalysis[i].IsFVG();
if (has)
{
//
has = (canCollectBullish && barsAnalysis[i].fvg.IsBullish()) ||
(canCollectBearish && barsAnalysis[i].fvg.IsBearish());
if (has)
{
//
AddIfNotExists(
barsAnalysis[i].fvg,
dest //
);
}
}
}
}
}
//
result = ArraySize(dest);
has = IsValidSize(result);
if (has)
{
//
// Update To Time ...
// and also we Can Validate Zones Here ...
datetime cTime = TimeCurrent();
for (int i = 0; i < result; i++)
{
dest[i].to = cTime;
}
}
//
// Cleanup ...
tmpBox.Clean();
//
return result;
}
//
};
struct XFIMAMarketStructureConfig
{
//
// Props ...
//
// Detector Flags ...
//
bool analysePVPivots; // Analyse PV Pivots ...
bool analyseZGPivots; // Analyse ZG Pivots ...
//
bool analyseBarPatterns; // Analyse Bar Patterns ...
//
// Detector Configs ...
//
int loopback; // Max Allowed Looping Back Length ...
int requiredPivots; // Required Extracted Pivots for Analysis ...
//
int pvPivotsValidationLength; // PV Pivots Validation Length ...
double maCrossValidationDiffMultiplier; // a Point Distance to Validate MA Crosses ...
//
XPatternAnalysisConfig barsAnalysisConfig; // Bars Analyser Config ...
//
// Constructor ...
XFIMAMarketStructureConfig()
{
Clean();
}
//
// Tools ...
/**
* This function fulfills the will of the developer
*/
void Clean()
{
//
// Detector Flags ...
analysePVPivots = false;
analyseZGPivots = false;
analyseBarPatterns = false;
//
// Configure Detectors ...
loopback = 0;
requiredPivots = 0;
pvPivotsValidationLength = 0;
maCrossValidationDiffMultiplier = 0;
//
barsAnalysisConfig.Clean();
//
ZeroMemory(this);
}
/**
* Default Configurations ...
*/
void Default()
{
//
// Detector Flags ...
analysePVPivots = true;
analyseZGPivots = true;
analyseBarPatterns = true;
//
// Configure Detectors ...
loopback = 200;
requiredPivots = 10;
pvPivotsValidationLength = 5;
maCrossValidationDiffMultiplier = 4;
//
barsAnalysisConfig.Default();
barsAnalysisConfig.FullPattern();
}
/**
* No Draw Abilioty ...
*/
void Off()
{
//
// Detector Flags ...
analysePVPivots = false;
analyseZGPivots = false;
analyseBarPatterns = false;
}
/**
* Full Draw Abilioty ...
*/
void Full()
{
//
// Detector Flags ...
analysePVPivots = true;
analyseZGPivots = true;
analyseBarPatterns = true;
}
//
};
/**
* Configure Market Structure Drawer ...
**/
struct XFIMAMarketStructureDrawerConfig
{
//
// Props ...
//
bool drawPVAnalysis;
bool drawZGAnalysis;
bool drawBarsAnalysis;
//
XPOIDrawConfig drawConfig;
XPivotAnalysisDrawConfig pivotAnalysisDrawConfig;
XPatternAnalysisDrawConfig barAnalysisDrawConfig;
//
// Constructor ...
XFIMAMarketStructureDrawerConfig()
{
Clean();
}
//
// Tools ...
/**
* This function fulfills the will of the developer
*/
void Clean()
{
//
// Drawing Flags ...
//
drawPVAnalysis = false;
drawZGAnalysis = false;
drawBarsAnalysis = false;
//
// Drawing Configs ...
drawConfig.Clean();
barAnalysisDrawConfig.Clean();
pivotAnalysisDrawConfig.Clean();
//
ZeroMemory(this);
}
/**
* Default Configurations ...
*/
void Default()
{
//
// Drawing Flags ...
//
drawPVAnalysis = true;
drawZGAnalysis = true;
drawBarsAnalysis = true;
//
// Drawing Configs ...
drawConfig.Default();
pivotAnalysisDrawConfig.Default();
//
barAnalysisDrawConfig.Default();
barAnalysisDrawConfig.Full();
XClean(barAnalysisDrawConfig.allowedDrawZones);
Add(
X_BAR_PATTERN_SUPPORT,
barAnalysisDrawConfig.allowedDrawZones);
Add(
X_BAR_PATTERN_RESISTANCE,
barAnalysisDrawConfig.allowedDrawZones);
}
/**
* No Draw Abilioty ...
*/
void Off()
{
//
// Drawing Flags ...
//
drawPVAnalysis = false;
drawZGAnalysis = false;
drawBarsAnalysis = false;
//
// Drawing Configs ...
barAnalysisDrawConfig.Off();
pivotAnalysisDrawConfig.Off();
}
/**
* Full Draw Abilioty ...
*/
void Full()
{
//
// Drawing Flags ...
//
drawPVAnalysis = false;
drawZGAnalysis = false;
drawBarsAnalysis = false;
//
// Drawing Configs ...
barAnalysisDrawConfig.Full();
pivotAnalysisDrawConfig.Full();
}
void ApplyDrawConfig()
{
//
barAnalysisDrawConfig.drawConfig = drawConfig;
barAnalysisDrawConfig.ConfigureQuarterDraws();
pivotAnalysisDrawConfig.drawConfig = drawConfig;
}
void ApplyDrawConfig(XPOIDrawConfig &_drawConfig)
{
//
drawConfig = _drawConfig;
ApplyDrawConfig();
}
//
};
//
@@ -0,0 +1,694 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Library
// -------------------------------------------------
// Name: XCXFIMAEALib ...
// Description: XFIMAEA Library ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XFIMAEA Library"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
#include "../../Libraries/x-saherelm.x-pivot.analysis.lib.mq5"
//
// Definitions ...
/**
* Configure Market Structure Detection ...
**/
struct XFIMAPatternDetectorConfig
{
//
// Props ...
//
bool detectSwingTrend;
//
bool detectStarPattern;
bool detectFlagPattern;
bool detectRisingPattern;
bool detectPiercingPattern;
bool detectSignalKeyBarPattern;
//
bool detectPinned;
bool detectMomentum;
bool detectEngulfed;
bool detectTrueGaped;
//
bool analyseFIMAPVPivots;
bool analyseFIMAZigZagPivots;
//
bool detectMACrosses;
double validMACrossDiffMultiplier;
//
bool detectHKSwitches;
bool detectSARSwitches;
//
// Configs ...
//
// Trending ...
int trendingNumberOfSwings;
int trendingSwingShoulders;
//
// Support and Resistance ...
int zonesRequiredNumber;
int zonesValidationLength;
double zonesMinAlloweStrength;
int zonesBreakValidationLength;
double zonesBarShadowMultiplier;
int zonesMaxAllowedLoopbackLength;
//
// TrueGap ...
double truwGapApprovedPointMultiplier;
//
// Flag Pattern ...
int flagPatternMinimumPullbackBars;
//
// Momentum Bar ...
int momentumBarRangeLength;
double momentumBarApprovedMultiplier;
//
// Pinned Bar ...
double pinnedBaarShadowApprovedMultiplier;
double pinnedBarMinimumPinBarRangeMultiplier;
bool pinnedBarForceDirection;
//
// SignalKey Bar ...
double signalKeyBarShadowApprovedMultiplier;
double signalKeyBarMinimumPinBarRangeMultiplier;
bool signalKeyBarForceDirection;
//
// Analyser ...
int pvPivotsValidationLength;
int numberOfRequiredPivotsForAnalysis;
int maxAllowedLoopbackLengthForAnalysis;
//
// Constructor ...
XFIMAPatternDetectorConfig()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
detectSwingTrend = false;
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
analyseFIMAPVPivots = false;
detectPiercingPattern = false;
analyseFIMAZigZagPivots = false;
detectSignalKeyBarPattern = false;
//
detectMACrosses = false;
validMACrossDiffMultiplier = 0;
//
detectHKSwitches = false;
detectSARSwitches = false;
//
zonesRequiredNumber = 0;
zonesValidationLength = 0;
zonesMinAlloweStrength = 0;
zonesBarShadowMultiplier = 0;
zonesBreakValidationLength = 0;
zonesMaxAllowedLoopbackLength = 0;
//
trendingNumberOfSwings = 0;
trendingSwingShoulders = 0;
momentumBarRangeLength = 0;
pvPivotsValidationLength = 0;
pinnedBarForceDirection = false;
momentumBarApprovedMultiplier = 0;
signalKeyBarForceDirection = false;
truwGapApprovedPointMultiplier = 0;
flagPatternMinimumPullbackBars = 0;
numberOfRequiredPivotsForAnalysis = 0;
pinnedBaarShadowApprovedMultiplier = 0;
maxAllowedLoopbackLengthForAnalysis = 0;
signalKeyBarShadowApprovedMultiplier = 0;
pinnedBarMinimumPinBarRangeMultiplier = 0;
signalKeyBarMinimumPinBarRangeMultiplier = 0;
//
ZeroMemory(this);
}
/**
* Default Model ...
*/
void Default()
{
//
// Patterns ...
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
detectPiercingPattern = false;
detectSignalKeyBarPattern = false;
//
// Bars ...
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
//
// Analysers ...
analyseFIMAPVPivots = false;
analyseFIMAZigZagPivots = false;
//
detectMACrosses = true;
validMACrossDiffMultiplier = 1;
//
detectHKSwitches = true;
detectSARSwitches = true;
//
// Trending ...
trendingNumberOfSwings = 3;
trendingSwingShoulders = 11;
//
// Support and Resistance ...
zonesRequiredNumber = 25;
zonesValidationLength = 21;
zonesMinAlloweStrength = 2;
zonesBarShadowMultiplier = 4;
zonesBreakValidationLength = 3;
zonesMaxAllowedLoopbackLength = 200;
//
// TrueGap ...
truwGapApprovedPointMultiplier = 1;
//
// Flag Pattern ...
flagPatternMinimumPullbackBars = 3;
//
// Momentum Bar ...
momentumBarRangeLength = 3;
momentumBarApprovedMultiplier = 2;
//
// Pinned Bar ...
pinnedBaarShadowApprovedMultiplier = 3;
pinnedBarMinimumPinBarRangeMultiplier = 4;
pinnedBarForceDirection = false;
//
// SignalKey Bar ...
signalKeyBarShadowApprovedMultiplier = 3;
signalKeyBarMinimumPinBarRangeMultiplier = 4;
signalKeyBarForceDirection = false;
//
// Length ...
pvPivotsValidationLength = 10;
numberOfRequiredPivotsForAnalysis = 50;
maxAllowedLoopbackLengthForAnalysis = 1500;
}
/**
* Full Detection Model ...
*/
void FullDetect()
{
//
// Patterns ...
detectStarPattern = true;
detectFlagPattern = true;
detectRisingPattern = true;
detectPiercingPattern = true;
detectSignalKeyBarPattern = true;
//
// Bars ...
detectPinned = true;
detectMomentum = true;
detectEngulfed = true;
detectTrueGaped = true;
//
// Analysers ...
analyseFIMAPVPivots = true;
analyseFIMAZigZagPivots = true;
//
detectMACrosses = true;
detectHKSwitches = true;
detectSARSwitches = true;
}
/**
* Default Config, by turn off all detecting flags ...
*/
void OffDetectors()
{
//
// Patterns ...
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
detectPiercingPattern = false;
detectSignalKeyBarPattern = false;
//
// Bars ...
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
//
// Analysers ...
analyseFIMAPVPivots = false;
analyseFIMAZigZagPivots = false;
//
detectMACrosses = false;
detectHKSwitches = false;
detectSARSwitches = false;
}
//
};
/**
* XFIMA Base Market Structure ...
* AnalyseMarket result ...
**/
struct XFIMAMarketStructure
{
//
XOHCL bar;
//
XBoxZone obs[];
XBoxZone fvgs[];
XBoxZone supports[];
XBoxZone resistances[];
//
XPivot pinBars[];
XPivot engulfBars[];
XPivot trueGapBars[];
XPivot momentumBars[];
//
XBoxZone flagPatterns[];
XBoxZone starPatterns[];
XBoxZone risingPatterns[];
XBoxZone piercingPatterns[];
XBoxZone signalKeyBarPatterns[];
//
// Analysis ...
XPivotAnalysis pvAnalysis;
XPivotAnalysis zigzagAnalysis;
//
ENUM_X_DIRECTION pinnedDir;
ENUM_X_DIRECTION momentumDir;
ENUM_X_DIRECTION engulfedDir;
ENUM_X_DIRECTION trueGapedDir;
//
XOHCL flagSwing;
ENUM_X_DIRECTION flagPatternDir;
//
XOHCL trendSwings[];
ENUM_X_DIRECTION trendDir;
//
ENUM_X_DIRECTION starPatternDir;
ENUM_X_DIRECTION risingPatternDir;
ENUM_X_DIRECTION piercingPatternDir;
ENUM_X_DIRECTION signalKeyBarPatternDir;
//
ENUM_X_DIRECTION maCrossDir;
XPivot maCrosses[];
//
ENUM_X_DIRECTION hkSwitchDir;
XPivot hkSwitches[];
//
ENUM_X_DIRECTION sarSwitchDir;
XPivot sarSwitches[];
//
// Constructor ...
XFIMAMarketStructure()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
bar.Clean();
flagSwing.Clean();
//
pvAnalysis.Clean();
zigzagAnalysis.Clean();
//
trendDir = X_DIRECTION_NONE;
pinnedDir = X_DIRECTION_NONE;
momentumDir = X_DIRECTION_NONE;
engulfedDir = X_DIRECTION_NONE;
trueGapedDir = X_DIRECTION_NONE;
flagPatternDir = X_DIRECTION_NONE;
starPatternDir = X_DIRECTION_NONE;
risingPatternDir = X_DIRECTION_NONE;
piercingPatternDir = X_DIRECTION_NONE;
signalKeyBarPatternDir = X_DIRECTION_NONE;
//
maCrossDir = X_DIRECTION_NONE;
SpecifiedClean(maCrosses);
//
hkSwitchDir = X_DIRECTION_NONE;
SpecifiedClean(hkSwitches);
//
sarSwitchDir = X_DIRECTION_NONE;
SpecifiedClean(sarSwitches);
//
SpecifiedClean(obs);
SpecifiedClean(fvgs);
SpecifiedClean(pinBars);
SpecifiedClean(supports);
SpecifiedClean(engulfBars);
SpecifiedClean(resistances);
SpecifiedClean(trueGapBars);
SpecifiedClean(momentumBars);
SpecifiedClean(flagPatterns);
SpecifiedClean(starPatterns);
SpecifiedClean(risingPatterns);
SpecifiedClean(piercingPatterns);
SpecifiedClean(signalKeyBarPatterns);
//
SpecifiedClean(trendSwings);
//
ZeroMemory(this);
}
//
// Checker Functions ...
//
};
/**
* Configure Market Structure Drawer ...
**/
struct XFIMAMarketStructureDrawerConfig
{
//
// Props ...
//
bool drawOB; // Current Order Block ...
bool drawFVG; // Current Fair Value Gap ...
//
bool drawSupport; // Detected Supports ...
bool drawResistance; // Detected Resistances ...
//
bool drawSwingTrend; // Swing Trend ...
bool swingTrendRayLeft; // Ray Left Swing Trend ...
bool swingTrendRayRight; // Ray Right Swing Trend ...
//
// Draw Current Detected Patterns ...
//
bool drawPinned;
bool drawMomentum;
bool drawEngulfed;
bool drawTrueGaped;
//
bool drawStarPattern;
bool drawFlagPattern;
bool drawRisingPattern;
bool drawPiercingPattern;
bool drawSignalKeyBarPattern;
//
// Draw Recently Zones ...
bool drawRecentPatterns;
bool drawFakeBreakedZone;
bool drawRecentlyTestedZones;
bool drawRecentlyBreakedZones;
//
// Draw Analysis Pivots ...
//
// XPV ...
bool drawFIMAPVPivotsAnalysis;
bool drawFIMAPVPivotsAnalysisZones;
bool drawFIMAPVPivotsAnalysisTrends;
bool drawFIMAPVPivotsAnalysisPivots;
//
// XSAR ...
bool drawFIMASARPivotsAnalysis;
bool drawFIMASARPivotsAnalysisZones;
bool drawFIMASARPivotsAnalysisTrends;
bool drawFIMASARPivotsAnalysisPivots;
//
// XZIGZAG ...
bool drawFIMAZigZagPivotsAnalysis;
bool drawFIMAZigZagPivotsAnalysisZones;
bool drawFIMAZigZagPivotsAnalysisTrends;
bool drawFIMAZigZagPivotsAnalysisPivots;
//
// Constructor ...
XFIMAMarketStructureDrawerConfig()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
drawOB = false;
drawFVG = false;
drawPinned = false;
drawMomentum = false;
drawSupport = false;
drawEngulfed = false;
drawTrueGaped = false;
drawResistance = false;
drawSwingTrend = false;
drawStarPattern = false;
drawFlagPattern = false;
swingTrendRayLeft = false;
drawRisingPattern = false;
swingTrendRayRight = false;
drawPiercingPattern = false;
drawSignalKeyBarPattern = false;
//
drawRecentPatterns = false;
drawFakeBreakedZone = false;
drawRecentlyTestedZones = false;
drawRecentlyBreakedZones = false;
//
drawFIMAPVPivotsAnalysis = false;
drawFIMAPVPivotsAnalysisZones = false;
drawFIMAPVPivotsAnalysisTrends = false;
drawFIMAPVPivotsAnalysisPivots = false;
//
drawFIMASARPivotsAnalysis = false;
drawFIMASARPivotsAnalysisZones = false;
drawFIMASARPivotsAnalysisTrends = false;
drawFIMASARPivotsAnalysisPivots = false;
//
drawFIMAZigZagPivotsAnalysis = false;
drawFIMAZigZagPivotsAnalysisZones = false;
drawFIMAZigZagPivotsAnalysisTrends = false;
drawFIMAZigZagPivotsAnalysisPivots = false;
//
ZeroMemory(this);
}
/**
* Default Model ...
*/
void Default()
{
drawOB = true;
drawFVG = true;
drawPinned = true;
drawMomentum = true;
drawSupport = true;
drawEngulfed = true;
drawTrueGaped = true;
drawResistance = true;
drawSwingTrend = true;
drawStarPattern = true;
drawFlagPattern = true;
drawRisingPattern = true;
drawPiercingPattern = true;
swingTrendRayLeft = false;
swingTrendRayRight = true;
drawSignalKeyBarPattern = true;
//
drawRecentPatterns = true;
drawFakeBreakedZone = true;
drawRecentlyTestedZones = true;
drawRecentlyBreakedZones = true;
//
drawFIMAPVPivotsAnalysis = true;
drawFIMAPVPivotsAnalysisZones = true;
drawFIMAPVPivotsAnalysisTrends = true;
drawFIMAPVPivotsAnalysisPivots = true;
//
drawFIMASARPivotsAnalysis = true;
drawFIMASARPivotsAnalysisZones = true;
drawFIMASARPivotsAnalysisTrends = true;
drawFIMASARPivotsAnalysisPivots = true;
//
drawFIMAZigZagPivotsAnalysis = true;
drawFIMAZigZagPivotsAnalysisZones = true;
drawFIMAZigZagPivotsAnalysisTrends = true;
drawFIMAZigZagPivotsAnalysisPivots = true;
}
/**
* Configure for Full Drawing ...
*/
void FullDraw()
{
//
Default();
//
drawOB = true;
drawFVG = true;
drawPinned = true;
drawMomentum = true;
drawSupport = true;
drawEngulfed = true;
drawTrueGaped = true;
drawResistance = true;
drawSwingTrend = true;
drawStarPattern = true;
drawFlagPattern = true;
drawRisingPattern = true;
swingTrendRayLeft = true;
swingTrendRayRight = true;
drawPiercingPattern = true;
drawSignalKeyBarPattern = true;
//
drawRecentPatterns = true;
drawFakeBreakedZone = true;
drawRecentlyTestedZones = true;
drawRecentlyBreakedZones = true;
//
drawFIMAPVPivotsAnalysis = true;
drawFIMAPVPivotsAnalysisZones = true;
drawFIMAPVPivotsAnalysisTrends = true;
drawFIMAPVPivotsAnalysisPivots = true;
//
drawFIMASARPivotsAnalysis = true;
drawFIMASARPivotsAnalysisZones = true;
drawFIMASARPivotsAnalysisTrends = true;
drawFIMASARPivotsAnalysisPivots = true;
//
drawFIMAZigZagPivotsAnalysis = true;
drawFIMAZigZagPivotsAnalysisZones = true;
drawFIMAZigZagPivotsAnalysisTrends = true;
drawFIMAZigZagPivotsAnalysisPivots = true;
}
//
};
Binary file not shown.
@@ -0,0 +1,792 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Library
// -------------------------------------------------
// Name: XCXFIMAEALib ...
// Description: XFIMAEA Library ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XFIMAEA Library"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
#include "../../Libraries/x-saherelm.x-pivot.analysis.lib.mq5"
//
// Definitions ...
/**
* Configure Market Structure Detection ...
**/
struct XFIMAPatternDetectorConfig
{
//
// Props ...
//
// Flags ...
//
bool detectSupport;
bool detectResistance;
//
bool detectSwingTrend;
//
bool detectOB;
bool detectFVG;
//
bool detectStarPattern;
bool detectFlagPattern;
bool detectRisingPattern;
bool detectPiercingPattern;
bool detectSignalKeyBarPattern;
//
bool detectPinned;
bool detectMomentum;
bool detectEngulfed;
bool detectTrueGaped;
//
bool analyseFIMAPVPivots;
bool analyseFIMASARPivots;
bool analyseFIMAZigZagPivots;
//
bool detectMACrosses;
double validMACrossDiffMultiplier;
//
bool detectHKSwitches;
bool detectSARSwitches;
//
// Configs ...
//
// OB / FVG ...
int obLoopback;
int fvgLoopback;
//
// Trending ...
int trendingNumberOfSwings;
int trendingSwingShoulders;
//
int recentlyPatternsMaxLookupLength;
int recentlyPatternsMaxAllowedCollecting;
//
// Support and Resistance ...
int recentlyZonesMaxLookupLength;
int supportAndResistanceValidationLength;
int minAllowdSupportAndResistanceStrength;
int supportAndResistanceMaxAllowedLoopback;
int supportAndResistanceBreakeValidationLength;
//
// TrueGap ...
double truwGapApprovedPointMultiplier;
//
// Flag Pattern ...
int flagPatternMinimumPullbackBars;
//
// Momentum Bar ...
int momentumBarRangeLength;
double momentumBarApprovedMultiplier;
//
// Pinned Bar ...
double pinnedBaarShadowApprovedMultiplier;
double pinnedBarMinimumPinBarRangeMultiplier;
bool pinnedBarForceDirection;
//
// SignalKey Bar ...
double signalKeyBarShadowApprovedMultiplier;
double signalKeyBarMinimumPinBarRangeMultiplier;
bool signalKeyBarForceDirection;
//
// Analyser ...
int pvPivotsValidationLength;
int numberOfRequiredPivotsForAnalysis;
int maxAllowedLoopbackLengthForAnalysis;
//
// Constructor ...
XFIMAPatternDetectorConfig()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
detectOB = false;
detectFVG = false;
detectSupport = false;
detectResistance = false;
detectSwingTrend = false;
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
detectPiercingPattern = false;
detectSignalKeyBarPattern = false;
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
analyseFIMAPVPivots = false;
analyseFIMASARPivots = false;
analyseFIMAZigZagPivots = false;
//
detectMACrosses = false;
validMACrossDiffMultiplier = 0;
//
detectHKSwitches = false;
detectSARSwitches = false;
//
obLoopback = 0;
fvgLoopback = 0;
trendingNumberOfSwings = 0;
trendingSwingShoulders = 0;
recentlyZonesMaxLookupLength = 0;
recentlyPatternsMaxLookupLength = 0;
recentlyPatternsMaxAllowedCollecting = 0;
supportAndResistanceValidationLength = 0;
minAllowdSupportAndResistanceStrength = 0;
supportAndResistanceMaxAllowedLoopback = 0;
supportAndResistanceBreakeValidationLength = 0;
truwGapApprovedPointMultiplier = 0;
flagPatternMinimumPullbackBars = 0;
momentumBarRangeLength = 0;
momentumBarApprovedMultiplier = 0;
pinnedBaarShadowApprovedMultiplier = 0;
pinnedBarMinimumPinBarRangeMultiplier = 0;
pinnedBarForceDirection = false;
signalKeyBarShadowApprovedMultiplier = 0;
signalKeyBarMinimumPinBarRangeMultiplier = 0;
signalKeyBarForceDirection = false;
pvPivotsValidationLength = 0;
numberOfRequiredPivotsForAnalysis = 0;
maxAllowedLoopbackLengthForAnalysis = 0;
//
ZeroMemory(this);
}
/**
* Default Model ...
*/
void Default()
{
//
// OB / FVG ...
detectOB = false;
detectFVG = false;
//
// Support and Resistances ...
detectSupport = false;
detectResistance = false;
detectSwingTrend = false;
//
// Patterns ...
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
detectPiercingPattern = false;
detectSignalKeyBarPattern = false;
//
// Bars ...
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
//
// Analysers ...
analyseFIMAPVPivots = false;
analyseFIMASARPivots = false;
analyseFIMAZigZagPivots = false;
//
detectMACrosses = true;
validMACrossDiffMultiplier = 1;
//
detectHKSwitches = true;
detectSARSwitches = true;
//
// OB / FVg ...
obLoopback = 5;
fvgLoopback = 5;
//
// Trending ...
trendingNumberOfSwings = 3;
trendingSwingShoulders = 11;
//
// Support and Resistance ...
recentlyZonesMaxLookupLength = 100;
recentlyPatternsMaxLookupLength = 50;
recentlyPatternsMaxAllowedCollecting = 20;
supportAndResistanceValidationLength = 100;
minAllowdSupportAndResistanceStrength = 1;
supportAndResistanceMaxAllowedLoopback = 1500;
supportAndResistanceBreakeValidationLength = 4;
//
// TrueGap ...
truwGapApprovedPointMultiplier = 1;
//
// Flag Pattern ...
flagPatternMinimumPullbackBars = 3;
//
// Momentum Bar ...
momentumBarRangeLength = 3;
momentumBarApprovedMultiplier = 2;
//
// Pinned Bar ...
pinnedBaarShadowApprovedMultiplier = 3;
pinnedBarMinimumPinBarRangeMultiplier = 4;
pinnedBarForceDirection = false;
//
// SignalKey Bar ...
signalKeyBarShadowApprovedMultiplier = 3;
signalKeyBarMinimumPinBarRangeMultiplier = 4;
signalKeyBarForceDirection = false;
//
// Length ...
pvPivotsValidationLength = 10;
numberOfRequiredPivotsForAnalysis = 50;
maxAllowedLoopbackLengthForAnalysis = 1500;
}
/**
* Full Detection Model ...
*/
void FullDetect()
{
//
// OB / FVG ...
detectOB = true;
detectFVG = true;
//
// Support and Resistances ...
detectSupport = true;
detectResistance = true;
detectSwingTrend = true;
//
// Patterns ...
detectStarPattern = true;
detectFlagPattern = true;
detectRisingPattern = true;
detectPiercingPattern = true;
detectSignalKeyBarPattern = true;
//
// Bars ...
detectPinned = true;
detectMomentum = true;
detectEngulfed = true;
detectTrueGaped = true;
//
// Analysers ...
analyseFIMAPVPivots = true;
analyseFIMASARPivots = true;
analyseFIMAZigZagPivots = true;
//
detectMACrosses = true;
detectHKSwitches = true;
detectSARSwitches = true;
}
/**
* Default Config, by turn off all detecting flags ...
*/
void OffDetectors()
{
//
// OB / FVG ...
detectOB = false;
detectFVG = false;
//
// Support and Resistances ...
detectSupport = false;
detectResistance = false;
detectSwingTrend = false;
//
// Patterns ...
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
detectPiercingPattern = false;
detectSignalKeyBarPattern = false;
//
// Bars ...
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
//
// Analysers ...
analyseFIMAPVPivots = false;
analyseFIMASARPivots = false;
analyseFIMAZigZagPivots = false;
//
detectMACrosses = false;
detectHKSwitches = false;
detectSARSwitches = false;
}
//
};
/**
* XFIMA Base Market Structure ...
* AnalyseMarket result ...
**/
struct XFIMAMarketStructure
{
//
XOHCL bar;
//
XBoxZone ob;
XBoxZone fvg;
XBoxZone support;
XBoxZone resistance;
//
XBoxZone obs[];
XBoxZone fvgs[];
XBoxZone supports[];
XBoxZone resistances[];
//
XPivot pinBars[];
XPivot engulfBars[];
XPivot trueGapBars[];
XPivot momentumBars[];
//
XBoxZone flagPatterns[];
XBoxZone starPatterns[];
XBoxZone risingPatterns[];
XBoxZone piercingPatterns[];
XBoxZone signalKeyBarPatterns[];
//
// Previous Support or Resistance based on current ...
//
// Current Support is Touched => Prev Support;
// Current Resistance is Touched => Prev Resistance;
XBoxZone fakeBreakedZone;
//
XBoxZone recentlyTestedZones[];
XBoxZone recentlyBreakedZones[];
//
// Analysis ...
XPivotAnalysis pvAnalysis;
XPivotAnalysis sarAnalysis;
XPivotAnalysis zigzagAnalysis;
//
ENUM_X_DIRECTION pinnedDir;
ENUM_X_DIRECTION momentumDir;
ENUM_X_DIRECTION engulfedDir;
ENUM_X_DIRECTION trueGapedDir;
//
XOHCL flagSwing;
ENUM_X_DIRECTION flagPatternDir;
//
XOHCL trendSwings[];
ENUM_X_DIRECTION trendDir;
//
ENUM_X_DIRECTION starPatternDir;
ENUM_X_DIRECTION risingPatternDir;
ENUM_X_DIRECTION piercingPatternDir;
ENUM_X_DIRECTION signalKeyBarPatternDir;
//
ENUM_X_DIRECTION maCrossDir;
XPivot maCrosses[];
//
ENUM_X_DIRECTION hkSwitchDir;
XPivot hkSwitches[];
//
ENUM_X_DIRECTION sarSwitchDir;
XPivot sarSwitches[];
//
// Constructor ...
XFIMAMarketStructure()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
ob.Clean();
fvg.Clean();
support.Clean();
resistance.Clean();
//
fakeBreakedZone.Clean();
//
bar.Clean();
flagSwing.Clean();
//
pvAnalysis.Clean();
sarAnalysis.Clean();
zigzagAnalysis.Clean();
//
trendDir = X_DIRECTION_NONE;
pinnedDir = X_DIRECTION_NONE;
momentumDir = X_DIRECTION_NONE;
engulfedDir = X_DIRECTION_NONE;
trueGapedDir = X_DIRECTION_NONE;
flagPatternDir = X_DIRECTION_NONE;
starPatternDir = X_DIRECTION_NONE;
risingPatternDir = X_DIRECTION_NONE;
piercingPatternDir = X_DIRECTION_NONE;
signalKeyBarPatternDir = X_DIRECTION_NONE;
//
maCrossDir = X_DIRECTION_NONE;
SpecifiedClean(maCrosses);
//
hkSwitchDir = X_DIRECTION_NONE;
SpecifiedClean(hkSwitches);
//
sarSwitchDir = X_DIRECTION_NONE;
SpecifiedClean(sarSwitches);
//
SpecifiedClean(obs);
SpecifiedClean(fvgs);
SpecifiedClean(pinBars);
SpecifiedClean(supports);
SpecifiedClean(engulfBars);
SpecifiedClean(resistances);
SpecifiedClean(trueGapBars);
SpecifiedClean(momentumBars);
SpecifiedClean(flagPatterns);
SpecifiedClean(starPatterns);
SpecifiedClean(risingPatterns);
SpecifiedClean(piercingPatterns);
SpecifiedClean(signalKeyBarPatterns);
//
SpecifiedClean(trendSwings);
SpecifiedClean(recentlyTestedZones);
SpecifiedClean(recentlyBreakedZones);
//
ZeroMemory(this);
}
//
// Checker Functions ...
//
};
/**
* Configure Market Structure Drawer ...
**/
struct XFIMAMarketStructureDrawerConfig
{
//
// Props ...
//
bool drawOB; // Current Order Block ...
bool drawFVG; // Current Fair Value Gap ...
//
bool drawSupport; // Detected Supports ...
bool drawResistance; // Detected Resistances ...
//
bool drawSwingTrend; // Swing Trend ...
bool swingTrendRayLeft; // Ray Left Swing Trend ...
bool swingTrendRayRight; // Ray Right Swing Trend ...
//
// Draw Current Detected Patterns ...
//
bool drawPinned;
bool drawMomentum;
bool drawEngulfed;
bool drawTrueGaped;
//
bool drawStarPattern;
bool drawFlagPattern;
bool drawRisingPattern;
bool drawPiercingPattern;
bool drawSignalKeyBarPattern;
//
// Draw Recently Zones ...
bool drawRecentPatterns;
bool drawFakeBreakedZone;
bool drawRecentlyTestedZones;
bool drawRecentlyBreakedZones;
//
// Draw Analysis Pivots ...
//
// XPV ...
bool drawFIMAPVPivotsAnalysis;
bool drawFIMAPVPivotsAnalysisZones;
bool drawFIMAPVPivotsAnalysisTrends;
bool drawFIMAPVPivotsAnalysisPivots;
//
// XSAR ...
bool drawFIMASARPivotsAnalysis;
bool drawFIMASARPivotsAnalysisZones;
bool drawFIMASARPivotsAnalysisTrends;
bool drawFIMASARPivotsAnalysisPivots;
//
// XZIGZAG ...
bool drawFIMAZigZagPivotsAnalysis;
bool drawFIMAZigZagPivotsAnalysisZones;
bool drawFIMAZigZagPivotsAnalysisTrends;
bool drawFIMAZigZagPivotsAnalysisPivots;
//
// Constructor ...
XFIMAMarketStructureDrawerConfig()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
drawOB = false;
drawFVG = false;
drawPinned = false;
drawMomentum = false;
drawSupport = false;
drawEngulfed = false;
drawTrueGaped = false;
drawResistance = false;
drawSwingTrend = false;
drawStarPattern = false;
drawFlagPattern = false;
swingTrendRayLeft = false;
drawRisingPattern = false;
swingTrendRayRight = false;
drawPiercingPattern = false;
drawSignalKeyBarPattern = false;
//
drawRecentPatterns = false;
drawFakeBreakedZone = false;
drawRecentlyTestedZones = false;
drawRecentlyBreakedZones = false;
//
drawFIMAPVPivotsAnalysis = false;
drawFIMAPVPivotsAnalysisZones = false;
drawFIMAPVPivotsAnalysisTrends = false;
drawFIMAPVPivotsAnalysisPivots = false;
//
drawFIMASARPivotsAnalysis = false;
drawFIMASARPivotsAnalysisZones = false;
drawFIMASARPivotsAnalysisTrends = false;
drawFIMASARPivotsAnalysisPivots = false;
//
drawFIMAZigZagPivotsAnalysis = false;
drawFIMAZigZagPivotsAnalysisZones = false;
drawFIMAZigZagPivotsAnalysisTrends = false;
drawFIMAZigZagPivotsAnalysisPivots = false;
//
ZeroMemory(this);
}
/**
* Default Model ...
*/
void Default()
{
drawOB = true;
drawFVG = true;
drawPinned = true;
drawMomentum = true;
drawSupport = true;
drawEngulfed = true;
drawTrueGaped = true;
drawResistance = true;
drawSwingTrend = true;
drawStarPattern = true;
drawFlagPattern = true;
drawRisingPattern = true;
drawPiercingPattern = true;
swingTrendRayLeft = false;
swingTrendRayRight = true;
drawSignalKeyBarPattern = true;
//
drawRecentPatterns = true;
drawFakeBreakedZone = true;
drawRecentlyTestedZones = true;
drawRecentlyBreakedZones = true;
//
drawFIMAPVPivotsAnalysis = true;
drawFIMAPVPivotsAnalysisZones = true;
drawFIMAPVPivotsAnalysisTrends = true;
drawFIMAPVPivotsAnalysisPivots = true;
//
drawFIMASARPivotsAnalysis = true;
drawFIMASARPivotsAnalysisZones = true;
drawFIMASARPivotsAnalysisTrends = true;
drawFIMASARPivotsAnalysisPivots = true;
//
drawFIMAZigZagPivotsAnalysis = true;
drawFIMAZigZagPivotsAnalysisZones = true;
drawFIMAZigZagPivotsAnalysisTrends = true;
drawFIMAZigZagPivotsAnalysisPivots = true;
}
/**
* Configure for Full Drawing ...
*/
void FullDraw()
{
//
Default();
//
drawOB = true;
drawFVG = true;
drawPinned = true;
drawMomentum = true;
drawSupport = true;
drawEngulfed = true;
drawTrueGaped = true;
drawResistance = true;
drawSwingTrend = true;
drawStarPattern = true;
drawFlagPattern = true;
drawRisingPattern = true;
swingTrendRayLeft = true;
swingTrendRayRight = true;
drawPiercingPattern = true;
drawSignalKeyBarPattern = true;
//
drawRecentPatterns = true;
drawFakeBreakedZone = true;
drawRecentlyTestedZones = true;
drawRecentlyBreakedZones = true;
//
drawFIMAPVPivotsAnalysis = true;
drawFIMAPVPivotsAnalysisZones = true;
drawFIMAPVPivotsAnalysisTrends = true;
drawFIMAPVPivotsAnalysisPivots = true;
//
drawFIMASARPivotsAnalysis = true;
drawFIMASARPivotsAnalysisZones = true;
drawFIMASARPivotsAnalysisTrends = true;
drawFIMASARPivotsAnalysisPivots = true;
//
drawFIMAZigZagPivotsAnalysis = true;
drawFIMAZigZagPivotsAnalysisZones = true;
drawFIMAZigZagPivotsAnalysisTrends = true;
drawFIMAZigZagPivotsAnalysisPivots = true;
}
//
};
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,495 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class
// -------------------------------------------------
// Name: XCXFIMAPoiDetector ...
// Description: XFIMA POI Detector Class ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XFIMA POI Detector Class"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.base.class.mq5"
#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
#include "../../Classes/x-saherelm.x-market.pattern.class.mq5"
#include "../Libraries/x-saherelm.xfima.lib.mq5"
//
// Implementation ...
class XCXFIMAPOIDetector : public XCMarketPatternDetector
{
//
// Public ...
public:
//
// Props ...
XCBarAnalyser *barAnalyser; // Bar Analyser ...
XCXFIMAHelper *fimaHelper; // XFIMA Helper ...
//
// Constructor ...
XCXFIMAPOIDetector(
XCXFIMAHelper *_fimaHelper //
) : XCMarketPatternDetector()
{
//
barAnalyser = new XCBarAnalyser();
fimaHelper = _fimaHelper;
}
//
// Deconstructor ...
~XCXFIMAPOIDetector()
{
Destroy();
}
//
// Actions and Tools ...
//
// Pivot Analysors ...
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
*
* @return ( bool )
*/
bool AnalysePVPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500,
int validationLength = 0 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractPVPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength, // Max Allowed Loopback ...
validationLength // Validation Length ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XPV",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
*
* @return ( bool )
*/
bool AnalyseMAPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500,
int validationLength = 0 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractMAPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength, // Max Allowed Loopback ...
validationLength // Validation Length ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XMA",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
*
* @return ( bool )
*/
bool AnalyseSARPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractSARPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength // Max Allowed Loopback ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XSAR",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
*
* @return ( bool )
*/
bool AnalyseZigZagPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractZigZagPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength // Max Allowed Loopback ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XZG",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Destroy ...
*/
void Destroy()
{
//
delete barAnalyser;
ZeroMemory(barAnalyser);
}
//
// Testers ...
/**
* Analyse Market based on Specified Bar ...
*
* @param structure: XFIMAMarketStructure, reference to holds result ...
* @param config: XFIMAMarketStructureConfig, reference to Configure Detector ...
* @param barIndex: int, Bar Index ...
*/
void AnalyseMarket(
XFIMAMarketStructure &structure,
XFIMAMarketStructureConfig &config,
int barIndex = 0 //
)
{
//
// Prepare ...
structure.Clean();
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
bool has = false;
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
has = structure.bar.Init(
symbol,
period,
barIndex //
);
if (!has)
{
//
structure.Clean();
return;
}
//
// Reading Bar Patterns ...
XOHCL iBar;
XPatternAnalysis iPatternAnalysis;
for (int i = barIndex; i < barIndex + config.loopback; i++)
{
//
// Cleanup ...
iBar.Clean();
iPatternAnalysis.Clean();
//
// Initialize Indexed Bar ...
//
has = structure.bar.BarAt(i, iBar);
if (!has)
{
break;
}
//
// Analyse Indexed Bar ...
has = AnalyseBarPatterns(iBar, iPatternAnalysis, config.barsAnalysisConfig);
if (has)
{
//
AddRef(
iPatternAnalysis,
structure.barsAnalysis //
);
//
if (i == barIndex)
{
structure.barAnalysis = iPatternAnalysis;
}
}
//
// Check Satisfied ...
has = ArraySize(structure.barsAnalysis) >= config.requiredPivots;
if (has)
{
break;
}
}
//
// Handle Pivot Analysis ...
//
// XPV ...
if (config.analysePVPivots)
{
//
// Reading Pivots ...
has = AnalysePVPivots(
structure.pvAnalysis,
barIndex,
config.requiredPivots,
config.loopback,
config.pvPivotsValidationLength //
);
if (!has)
{
structure.pvAnalysis.Clean();
}
}
//
// XZG ...
if (config.analyseZGPivots)
{
//
// Reading Pivots ...
has = AnalyseZigZagPivots(
structure.zgAnalysis,
barIndex,
config.requiredPivots,
config.loopback //
);
if (!has)
{
structure.zgAnalysis.Clean();
}
}
//
// Cleanup ...
iBar.Clean();
iPatternAnalysis.Clean();
}
//
// Protected ...
protected:
//
// Props ...
//
// Private ...
private:
//
//
};
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,826 @@
/**
* Analyse Market based on Specified Bar ...
*
* @param forBar: XOHCL, reference Specified Bar for Analyse Market ...
* @param structure: XFIMAMarketStructure, reference to holds result ...
* @param config: XFIMAPatternDetectorConfig, reference to Configure Detector ...
*/
void AnalyseMarket(
XOHCL &forBar,
XFIMAMarketStructure &structure,
XFIMAPatternDetectorConfig &config //
)
{
//
// Prepare ...
structure.Clean();
//
// Validate ...
if (!forBar.IsValid())
{
return;
}
//
// Do Analysis ...
//
structure.bar = forBar;
//
int idx = -1;
bool has = false;
int maxAllowedCollecting = 50;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
// Detecting POI Based on Config ...
//
// Order Block ...
if (config.detectOB)
{
//
bool isOB = HasOB(
forBar,
iDir,
structure.ob,
config.obLoopback //
);
bool isBullishOB = isOB &&
IsSpecifiedBullish(iDir);
bool isBearishOB = isOB &&
IsSpecifiedBearish(iDir);
if (!isOB)
{
structure.ob.Clean();
}
//
// Detect Touches ...
if (isOB)
{
//
AddIfNotExists(
structure.ob,
obs,
maxAllowedCollecting //
);
//
XOHCL pBar;
bool has = forBar.GetPreviousBar(pBar);
if (has)
{
//
structure.isOBTouched =
isBullishOB
? pBar.low < structure.ob.upper
: pBar.high > structure.ob.lower;
}
//
pBar.Clean();
}
}
//
// Fair Value Gap ...
if (config.detectFVG)
{
//
bool isFVG = HasFVG(
forBar,
iDir,
structure.fvg,
config.fvgLoopback //
);
bool isBullishFVG = isFVG &&
IsSpecifiedBullish(iDir);
bool isBearishFVG = isFVG &&
IsSpecifiedBearish(iDir);
if (!isFVG)
{
structure.fvg.Clean();
}
//
// Detect Touches ...
if (isFVG)
{
//
AddIfNotExists(
structure.fvg,
fvgs,
maxAllowedCollecting //
);
//
XOHCL pBar;
bool has = forBar.GetPreviousBar(pBar);
if (has)
{
//
structure.isFVGTouched =
isBullishFVG
? pBar.low < structure.fvg.upper
: pBar.high > structure.fvg.lower;
}
//
pBar.Clean();
}
}
//
// Checking Momentum Bar ...
if (config.detectMomentum)
{
//
bool isMomentum = IsMomentumBar(
forBar,
iDir,
config.momentumBarRangeLength,
config.momentumBarApprovedMultiplier //
);
bool isBullishMomentum = isMomentum &&
IsSpecifiedBullish(iDir);
bool isBearishMomentum = isMomentum &&
IsSpecifiedBearish(iDir);
if (isMomentum)
{
structure.momentumDir = iDir;
}
}
//
// Checking Engulfed Bar ...
if (config.detectEngulfed)
{
//
bool isEngulfed = IsEngulfedBar(
forBar,
iDir //
);
bool isBullishEngulfed = isEngulfed &&
IsSpecifiedBullish(iDir);
bool isBearishEngulfed = isEngulfed &&
IsSpecifiedBearish(iDir);
if (isEngulfed)
{
structure.engulfedDir = iDir;
}
}
//
// Checking TruGaped Bar ...
if (config.detectTrueGaped)
{
//
bool isTrueGaped = IsTrueGapedBar(
forBar,
iDir,
config.truwGapApprovedPointMultiplier //
);
bool isBullishTrueGaped = isTrueGaped &&
IsSpecifiedBullish(iDir);
bool isBearishTrueGaped = isTrueGaped &&
IsSpecifiedBearish(iDir);
if (isTrueGaped)
{
structure.trueGapedDir = iDir;
}
}
//
// Checking Pinned Bar ...
if (config.detectPinned)
{
//
bool isPinned = IsPinnedBar(
forBar,
iDir,
config.pinnedBaarShadowApprovedMultiplier,
config.pinnedBarMinimumPinBarRangeMultiplier,
config.pinnedBarForceDirection //
);
bool isBullishPinned = isPinned &&
IsSpecifiedBullish(iDir);
bool isBearishPinned = isPinned &&
IsSpecifiedBearish(iDir);
if (isPinned)
{
structure.pinnedDir = iDir;
}
}
//
// Checking Star Pattern ...
if (config.detectStarPattern)
{
//
bool isStarPattern = IsStartPattern(
forBar,
iDir //
);
bool isBullishStarPattern = isStarPattern &&
IsSpecifiedBullish(iDir);
bool isBearishStarPattern = isStarPattern &&
IsSpecifiedBearish(iDir);
if (isStarPattern)
{
structure.starPatternDir = iDir;
}
}
//
// Checking Piercing Pattern ...
if (config.detectPiercingPattern)
{
//
bool isPiercingPattern = IsPiercingPattern(
forBar,
iDir //
);
bool isBullishPiercingPattern = isPiercingPattern &&
IsSpecifiedBullish(iDir);
bool isBearishPiercingPattern = isPiercingPattern &&
IsSpecifiedBearish(iDir);
if (isPiercingPattern)
{
structure.piercingPatternDir = iDir;
}
}
//
// Checking Rising Pattern ...
if (config.detectRisingPattern)
{
//
bool isRisingPattern = IsRisingPattern(
forBar,
iDir //
);
bool isBullishRisingPattern = isRisingPattern &&
IsSpecifiedBullish(iDir);
bool isBearishRisingPattern = isRisingPattern &&
IsSpecifiedBearish(iDir);
if (isRisingPattern)
{
structure.risingPatternDir = iDir;
}
}
//
// Checking Flag Pattern ...
if (config.detectFlagPattern)
{
//
XOHCL swingBar;
bool isFlagPattern = IsFlagPattern(
forBar,
iDir,
swingBar,
config.flagPatternMinimumPullbackBars //
);
bool isBullishFlagPattern = isFlagPattern &&
IsSpecifiedBullish(iDir);
bool isBearishFlagPattern = isFlagPattern &&
IsSpecifiedBearish(iDir);
if (isFlagPattern)
{
//
structure.flagSwing = swingBar;
structure.flagPatternDir = iDir;
}
swingBar.Clean();
}
//
// Detect SignalKey Bar Pattern ...
if (config.detectSignalKeyBarPattern)
{
//
bool isSignalKeyBar = IsSignalKeyBarPattern(
forBar,
iDir,
config.signalKeyBarShadowApprovedMultiplier,
config.signalKeyBarMinimumPinBarRangeMultiplier,
config.signalKeyBarForceDirection //
);
bool isBullishSignalKeyBar = isSignalKeyBar &&
IsSpecifiedBullish(iDir);
bool isBearishSignalKeyBar = isSignalKeyBar &&
IsSpecifiedBearish(iDir);
if (isSignalKeyBar)
{
structure.signalKeyBarPatternDir = iDir;
}
}
//
// Detect Swing Trend ...
if (config.detectSwingTrend)
{
//
XOHCL swings[];
bool hasSwingTrend = HasSwingTrend(
forBar,
iDir,
swings,
config.trendingNumberOfSwings,
config.trendingSwingShoulders //
);
bool hasBullishSwingTrend = hasSwingTrend &&
IsSpecifiedBullish(iDir);
bool hasBearishSwingTrend = hasSwingTrend &&
IsSpecifiedBearish(iDir);
if (hasSwingTrend)
{
//
Copy(
swings,
structure.trendSwings //
);
structure.trendDir = iDir;
}
SpecifiedClean(swings);
}
//
// Detect Supports ...
if (config.detectSupport)
{
//
XOHCL support;
bool hasSupport = HasSupport(
forBar,
support,
config.supportAndResistanceValidationLength,
config.supportAndResistanceMaxAllowedLoopback //
);
if (hasSupport)
{
//
XBoxZone supportBox;
has = ToSupportBox(support, supportBox);
//
// Validate Zone Strength if Provided ...
if (config.minAllowdSupportAndResistanceStrength > 0)
{
//
has = has &&
ValidateStrength(
supportBox,
config.minAllowdSupportAndResistanceStrength //
);
}
//
if (has)
{
//
AddIfNotExists(
supportBox,
supports,
maxAllowedCollecting //
);
//
structure.support = supportBox;
}
//
// Check for Support Touches ...
XOHCL pBar;
has = has &&
forBar.GetPreviousBar(pBar);
if (has)
{
structure.isSupportTouched = pBar.low < supportBox.upper;
}
//
pBar.Clean();
supportBox.Clean();
}
support.Clean();
}
//
// Detect Resistance ...
if (config.detectResistance)
{
//
XOHCL resistance;
bool hasResistance = HasResistance(
forBar,
resistance,
config.supportAndResistanceValidationLength,
config.supportAndResistanceMaxAllowedLoopback //
);
if (hasResistance)
{
//
XBoxZone resistanceBox;
has = ToResistanceBox(resistance, resistanceBox);
//
// Validate Zone Strength if Provided ...
if (config.minAllowdSupportAndResistanceStrength > 0)
{
//
has = has &&
ValidateStrength(
resistanceBox,
config.minAllowdSupportAndResistanceStrength //
);
}
//
if (has)
{
//
AddIfNotExists(
resistanceBox,
resistances,
maxAllowedCollecting //
);
//
structure.resistance = resistanceBox;
}
//
// Check for Resistance Touches ...
XOHCL pBar;
has = has &&
forBar.GetPreviousBar(pBar);
if (has)
{
structure.isResistanceTouched = pBar.high > resistanceBox.upper;
}
//
pBar.Clean();
resistanceBox.Clean();
}
resistance.Clean();
}
//
// Analysers ...
//
// Analyse Based on PV ...
if (config.analyseFIMAPVPivots)
{
//
XPivotAnalysis analysis;
has = AnalysePVPivots(
analysis, // Result ...
forBar.Index(), // Bar Index ...
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ...
config.pvPivotsValidationLength // Validation Length ...
);
if (has)
{
structure.pvAnalysis = analysis;
}
}
//
// Analyse Based on MA ...
if (config.analyseFIMAMAPivots)
{
//
XPivotAnalysis analysis;
has = AnalyseMAPivots(
analysis, // Result ...
forBar.Index(), // Bar Index ...
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ...
config.pvPivotsValidationLength // Validation Length ...
);
if (has)
{
structure.maAnalysis = analysis;
}
}
//
// Analyse Based on SAR ...
if (config.analyseFIMASARPivots)
{
//
XPivotAnalysis analysis;
has = AnalyseSARPivots(
analysis, // Result ...
forBar.Index(), // Bar Index ...
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ...
);
if (has)
{
structure.sarAnalysis = analysis;
}
}
//
// Analyse Based on ZigZag ...
if (config.analyseFIMAZigZagPivots)
{
//
XPivotAnalysis analysis;
has = AnalyseZigZagPivots(
analysis, // Result ...
forBar.Index(), // Bar Index ...
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ...
);
if (has)
{
structure.zigzagAnalysis = analysis;
}
}
//
// COMPLEX Actions ...
//
// Lockup For Previous Zone ...
has = structure.isSupportTouched ||
structure.isResistanceTouched;
if (has)
{
//
if (structure.isSupportTouched)
{
//
idx = GetYoungestBefore(
structure.support.from,
supports //
);
has = IsValidIndex(idx);
if (has)
{
structure.prevZone = supports[idx];
}
}
else if (structure.isResistanceTouched)
{
//
idx = GetYoungestBefore(
structure.resistance.from,
resistances //
);
has = IsValidIndex(idx);
if (has)
{
structure.prevZone = resistances[idx];
}
}
}
//
// Detect Recently Tested Zones ...
if ((config.detectSupport ||
config.detectResistance) &&
config.recentlyTestedZonesMaxLookup > 0)
{
//
XOHCL iBar;
int idx = -1;
bool has = false;
//
int start = forBar.Index() + 1;
int end = start + config.recentlyTestedZonesMaxLookup;
for (int i = start; i < end; i++)
{
//
// Initialize Indexed Bar ...
has = forBar.BarAt(i, iBar);
if (!has)
{
continue;
}
//
// Selecting Support and Resistances ...
//
// Supports ...
idx = GetYoungestBefore(iBar.time, supports);
has = IsValidIndex(idx);
if (has)
{
//
// Check Testing ...
has = IsTested(iBar, supports[idx]);
if (has)
{
//
AddIfNotExists(
supports[idx],
structure.recentlyTestedZones //
);
}
}
//
// Resistances ...
idx = GetYoungestBefore(iBar.time, resistances);
has = IsValidIndex(idx);
if (has)
{
//
// Check Testing ...
has = IsTested(iBar, resistances[idx]);
if (has)
{
//
AddIfNotExists(
resistances[idx],
structure.recentlyTestedZones //
);
}
}
}
}
//
// Checkup for FakeBreaked Zones ...
if (config.detectSupport ||
config.detectResistance)
{
//
// Retrieve Previous Bar ...
int idx = -1;
XOHCL pForBar;
XOHCL breakerBar;
XBoxZone pSupport;
XOHCL pBreakerBar;
XBoxZone pResistance;
//
// Selecting Previously Touched Support / Resistance ...
has = forBar.GetPreviousBar(pForBar);
if (has)
{
//
// Detecting Nearest Above Lows Support ...
idx = GetYoungestAbove(
pForBar.low,
supports //
);
has = IsValidIndex(idx) &&
IsBreaked(
forBar,
supports[idx] //
);
if (has)
{
pSupport = supports[idx];
}
//
// Detecting Nearest Below Highs Resistance ...
idx = GetYoungestBelow(
pForBar.high,
resistances //
);
has = IsValidIndex(idx) &&
IsBreaked(
forBar,
resistances[idx] //
);
if (has)
{
pResistance = resistances[idx];
}
}
//
// Check at least a zone Exists ...
// Selecting pTestedZone ...
has = pSupport.IsValid() ||
pResistance.IsValid();
if (has)
{
//
// Support ...
has = pSupport.IsValid();
if (has)
{
//
structure.isPTest = true;
structure.pTestedZone = pSupport;
}
//
// Resistance ...
has = pResistance.IsValid();
if (has)
{
//
structure.isPTest = true;
structure.pTestedZone = pResistance;
}
}
//
// Check pTestedZone Existance ...
has = structure.isPTest &&
structure.pTestedZone.IsValid();
if (has)
{
//
// Get Breaker Bars ...
XOHCL breakerBars[];
int breakerBarsCount = GetBreakerBars(
structure.pTestedZone,
breakerBars //
);
has = IsValidSize(breakerBarsCount);
if (has)
{
//
idx = GetYoungestBar(breakerBars);
has = IsValidIndex(idx);
if (has)
{
breakerBar = breakerBars[idx];
}
}
//
SpecifiedClean(breakerBars);
}
//
// Check Zone Breaker Bar Exists ...
// Validate Zone Fake Breake Langth ...
has = breakerBar.IsValid();
if (has)
{
//
// Validate Breake Length ...
has = (breakerBar.Index() - pForBar.Index()) <= config.supportAndResistanceBreakeValidationLength;
}
//
// Cleanup Resources ...
//
if (!has)
{
//
structure.isPTest = false;
structure.pTestedZone.Clean();
}
pForBar.Clean();
pSupport.Clean();
breakerBar.Clean();
pBreakerBar.Clean();
pResistance.Clean();
}
}
//
// Lockup For Previous Zone ...
has = structure.isSupportTouched ||
structure.isResistanceTouched;
if (has)
{
//
if (structure.isSupportTouched)
{
//
idx = GetYoungestBefore(
structure.support.from,
supports //
);
has = IsValidIndex(idx);
if (has)
{
structure.prevZone = supports[idx];
}
}
else if (structure.isResistanceTouched)
{
//
idx = GetYoungestBefore(
structure.resistance.from,
resistances //
);
has = IsValidIndex(idx);
if (has)
{
structure.prevZone = resistances[idx];
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,641 @@
// //
// // Detect At lease Two PEAK and Two Vale ...
// XZigZagPoint tmpPoints[];
// Copy(
// points,
// tmpPoints //
// );
// //
// // Detect Highs ...
// //
// // Highest High ...
// //
// XZigZagPoint iZGPeak1;
// XZigZagPoint iZGPeak2;
// //
// // First ...
// int idx = GetHighest(
// tmpPoints,
// X_ZIGZAG_POINT_TYPE_PEAK //
// );
// result = IsValidIndex(idx);
// if (!result)
// {
// //
// Clean();
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// SpecifiedClean(tmpPoints);
// //
// return result;
// }
// iZGPeak1 = tmpPoints[idx];
// ArrayRemove(
// tmpPoints,
// idx,
// 1 //
// );
// //
// // Second ...
// idx = GetHighest(
// tmpPoints,
// X_ZIGZAG_POINT_TYPE_PEAK //
// );
// result = IsValidIndex(idx);
// if (!result)
// {
// //
// Clean();
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// SpecifiedClean(tmpPoints);
// //
// return result;
// }
// iZGPeak2 = tmpPoints[idx];
// ArrayRemove(
// tmpPoints,
// idx,
// 1 //
// );
// //
// // Detect Lows ...
// //
// XZigZagPoint iZGVale1;
// XZigZagPoint iZGVale2;
// //
// // First ...
// idx = GetLowest(
// tmpPoints,
// X_ZIGZAG_POINT_TYPE_VALE //
// );
// result = IsValidIndex(idx);
// if (!result)
// {
// //
// Clean();
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// iZGVale1.Clean();
// iZGVale2.Clean();
// SpecifiedClean(tmpPoints);
// //
// return result;
// }
// iZGVale1 = tmpPoints[idx];
// ArrayRemove(
// tmpPoints,
// idx,
// 1 //
// );
// //
// // Second ...
// idx = GetLowest(
// tmpPoints,
// X_ZIGZAG_POINT_TYPE_VALE //
// );
// result = IsValidIndex(idx);
// if (!result)
// {
// //
// Clean();
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// iZGVale1.Clean();
// iZGVale2.Clean();
// SpecifiedClean(tmpPoints);
// //
// return result;
// }
// iZGVale2 = tmpPoints[idx];
// ArrayRemove(
// tmpPoints,
// idx,
// 1 //
// );
// //
// // Check Directions ...
// bool isBullish =
// //
// (iZGPeak1.time > iZGPeak2.time &&
// iZGVale1.time < iZGVale2.time)
// //
// ;
// bool isBearish =
// //
// (iZGPeak1.time < iZGPeak2.time &&
// iZGVale1.time > iZGVale2.time)
// //
// ;
// result =
// (isBullish && !isBearish) ||
// (isBearish && !isBullish);
// if (!result)
// {
// //
// Clean();
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// iZGVale1.Clean();
// iZGVale2.Clean();
// SpecifiedClean(tmpPoints);
// //
// return result;
// }
// //
// // Setting Direction ...
// dir =
// isBullish
// ? X_DIRECTION_BULLISH
// : isBearish
// ? X_DIRECTION_BEARISH
// : X_DIRECTION_NONE;
// //
// // Setting Points ...
// Copy(
// points,
// pivots //
// );
//
// Cleanup Resources ...
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// iZGVale1.Clean();
// iZGVale2.Clean();
// SpecifiedClean(tmpPoints);
/**
* Analyse Market Structure ...
*
* @param bar: XOHCL, Specified Bar ...
* @param _pivots: XZigZagPivot, Specified ZigZag Points Collection ...
*
* @return ( bool )
*/
bool Analyse(
XOHCL &bar,
XZigZagPivot &_pivots[] //
)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasChild(_pivots) &&
bar.symbol == _pivots[0].symbol;
if (!result)
{
//
Clean();
return result;
}
//
// AssignSymbol and Period ...
time = bar.time;
symbol = bar.symbol;
period = bar.period;
Copy(_pivots, pivots);
//
// Calculate Peaks and Vales Regressions ...
//
// Peaks Processing ...
double mPeak = 0;
double bPeak = 0;
result = ValidateZigZagPivots(
mPeak,
bPeak,
_pivots,
X_ZIGZAG_PIVOT_TYPE_PEAK //
);
//
// Vales Processing ...
double mVale = 0;
double bVale = 0;
result =
result &&
ValidateZigZagPivots(
mVale,
bVale,
_pivots,
X_ZIGZAG_PIVOT_TYPE_VALE //
);
if (!result)
{
//
Clean();
// SpecifiedClean(recentPeaks);
// SpecifiedClean(recentVales);
//
return result;
}
// //
// // Extracting Pivots ...
// int numberOfPivots = 2;
// //
// // Reading Recent Peaks ...
// XZigZagPivot recentPeaks[];
// int recentPeaksCount = GetRecent(
// _pivots,
// recentPeaks,
// numberOfPivots,
// X_ZIGZAG_PIVOT_TYPE_PEAK //
// );
// //
// // Reading Recent Vales ...
// XZigZagPivot recentVales[];
// int recentValesCount = GetRecent(
// _pivots,
// recentVales,
// numberOfPivots,
// X_ZIGZAG_PIVOT_TYPE_VALE //
// );
// //
// // Validate Pivots ...
// result =
// recentPeaksCount >= numberOfPivots &&
// recentValesCount >= numberOfPivots;
// if (!result)
// {
// //
// Clean();
// SpecifiedClean(recentPeaks);
// SpecifiedClean(recentVales);
// //
// return result;
// }
// //
// // Detect Direction ...
// //
// int zIdx = 0;
// int pIdx = numberOfPivots - 1;
// //
// bool isBullish =
// recentPeaks[zIdx].value > recentPeaks[pIdx].value &&
// recentVales[zIdx].value > recentVales[pIdx].value;
// //
// bool isBearish =
// recentPeaks[zIdx].value < recentPeaks[pIdx].value &&
// recentVales[zIdx].value < recentVales[pIdx].value;
// //
// result = isBullish || isBearish;
// if (!result)
// {
// //
// Clean();
// SpecifiedClean(recentPeaks);
// SpecifiedClean(recentVales);
// //
// return result;
// }
// //
// dir =
// isBullish
// ? X_DIRECTION_BULLISH
// : X_DIRECTION_BEARISH;
//
// Calculate Support and Resistance ...
//
// Validate ...
result = IsValid();
if (!result)
{
Clean();
}
//
// SpecifiedClean(recentPeaks);
// SpecifiedClean(recentVales);
//
return result;
}
bool ValidateZigZagPivots(
double &_pivot,
double &_processed,
XZigZagPivot &_pivots[],
ENUM_X_ZIGZAG_POINT_TYPE _type //
)
{
//
bool result = false;
//
// Prepare ...
_pivot = 0;
_processed = 0;
//
// Validate ...
result = HasChild(_pivots);
if (!result)
{
return result;
}
//
// Define Required Variables for Calculations ...
double sumT = 0;
double sumP = 0;
double sumTP = 0;
double sumT2 = 0;
bool has = false;
int typeCount = 0;
//
// Loop Through Pivots to Calculate Specified
// Type Pivots Summaries ...
int count = ArraySize(_pivots);
for (int i = 0; i < count; i++)
{
//
// Check Type Passed ...
has =
!IsXValid(_type)
? true
: _type == _pivots[i].type;
if (!has)
{
continue;
}
//
typeCount++;
double iP = _pivots[i].value;
double iT = (double)_pivots[i].time;
//
sumT += iT;
sumP += iP;
sumTP += iT * iP;
sumT2 += iT * iP;
}
//
// Calculate Process Values ...
double denominator = typeCount * sumT2 - sumT * sumT;
if (denominator != 0)
{
//
_pivot = (typeCount * sumTP - sumT * sumP) / denominator;
_processed = (sumP - _pivot * sumT) / typeCount;
}
else
{
_processed = sumP / typeCount;
}
//
// Validating Result ...
result = _pivot > 0 &&
_processed > 0;
//
return result;
}
/**
* Analyse Market Structure ...
*
* @param bar: XOHCL, Specified Bar ...
* @param _pivots: XZigZagPivot, Specified ZigZag Points Collection ...
*
* @return ( bool )
*/
bool Analyse(
XOHCL &bar,
XZigZagPivot &_pivots[] //
)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasChild(_pivots) &&
bar.symbol == _pivots[0].symbol;
if (!result)
{
//
Clean();
return result;
}
//
// Assign Requirements ...
//
time = bar.time;
symbol = bar.symbol;
period = bar.period;
Copy(_pivots, pivots);
//
int oldestPeakIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK);
int oldestValeIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE);
int youngestPeakIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK);
int youngestValeIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE);
//
// Calculate Peaks and Vales Regressions ...
//
// Peaks Processing ...
double mPeak = 0;
double bPeak = 0;
bool hasPeak = ValidateZigZagPivots(
mPeak,
bPeak,
pivots,
X_ZIGZAG_PIVOT_TYPE_PEAK //
);
//
// Vales Processing ...
double mVale = 0;
double bVale = 0;
bool hasVale = ValidateZigZagPivots(
mVale,
bVale,
pivots,
X_ZIGZAG_PIVOT_TYPE_VALE //
);
//
// Validate Calculated requirements ...
result =
(hasPeak || hasVale) &&
(IsValidIndex(oldestPeakIdx) &&
IsValidIndex(oldestValeIdx) &&
IsValidIndex(youngestPeakIdx) &&
IsValidIndex(youngestValeIdx));
if (!result)
{
//
Clean();
return result;
}
//
// Calculating Values ...
//
peakToTime = pivots[youngestPeakIdx].time;
peakFromTime = pivots[oldestPeakIdx].time;
//
valeToTime = pivots[youngestValeIdx].time;
valeFromTime = pivots[oldestValeIdx].time;
//
// Check Different Senarios ...
// 1-Valid Peak and Valid Vale Exists ...
if (hasPeak && hasVale)
{
//
// When Slopes Have same Sign, Use Average Slope for Parallel Lines ...
if (mPeak * mVale > 0)
{
//
// Calculating Parallel Slopes ...
double slopeParallel = (mPeak + mVale) / 2;
double bParallelPeak = pivots[youngestPeakIdx].value - slopeParallel * (double)peakToTime;
double bParallelVale = pivots[youngestValeIdx].value - slopeParallel * (double)valeToTime;
//
// Peak ...
peakTo = slopeParallel * (double)peakToTime + bParallelPeak;
peakFrom = slopeParallel * (double)peakFromTime + bParallelPeak;
//
// Vale ...
valeTo = slopeParallel * (double)valeToTime + bParallelVale;
valeFrom = slopeParallel * (double)valeFromTime + bParallelVale;
}
else
//
// separate trendlines if slopes differ ...
{
//
// Peak ...
peakTo = mPeak * (double)peakToTime + bPeak;
peakFrom = mPeak * (double)peakFromTime + bPeak;
//
// Vale ...
valeTo = mVale * (double)valeToTime + bVale;
valeFrom = mVale * (double)valeFromTime + bVale;
}
}
else
//
// Only one of them Exists ...
{
//
// Valid Peak ...
if (hasPeak)
{
//
// Peak ...
peakTo = mPeak * (double)peakToTime + bPeak;
peakFrom = mPeak * (double)peakFromTime + bPeak;
}
//
// Valid Vale ...
if (hasVale)
{
//
// Vale ...
valeTo = mVale * (double)valeToTime + bVale;
valeFrom = mVale * (double)valeFromTime + bVale;
}
}
//
// Detecting Direction ...
//
bool isBullish =
valeTo > valeFrom ||
(valeTo > valeFrom &&
peakTo > peakFrom);
//
bool isBearish =
peakTo < peakFrom ||
(peakTo < peakFrom &&
valeTo < valeFrom);
//
// Validate When Only One Direction Exists ...
result =
(isBullish && !isBearish) ||
(isBearish && !isBullish);
if (!result)
{
//
Clean();
return result;
}
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
// Calculate Support and Resistance ...
//
// Validate ...
result = IsValid();
if (!result)
{
Clean();
}
//
return result;
}
@@ -0,0 +1,511 @@
//
// Testing Bar Zones ...
// XBoxZone barZones[];
// int barCounts = fima2Signaller.fimaHelper.ExtractBarZones(
// barZones,
// 1, // Bar Index ...
// 50, // Number of Zones ...
// 3, // Break Validation Length ...
// true, // Validate Fake Breakes ...
// 5, // Shadow Multiplier ...
// 1, // Strength ...
// 14 // Validation Length ...
// );
// if (IsValidSize(barCounts))
// {
// //
// // XCBoxObject *iObj;
// // for (int i = 0; i < barCounts; i++)
// // {
// // //
// // iObj = NULL;
// // bool isCreated = fima2Signaller.poiDrawer.DrawBox(
// // barZones[i],
// // iObj,
// // true, // Ignore At ...
// // barZones[i].type // Name ...
// // );
// // //
// // ZeroMemory(iObj);
// // }
// // //
// // Print("Bar Zones Detected ...");
// }
//
// Testing HK Zones ...
// XBoxZone hkZones[];
// int hkCounts = fima2Signaller.fimaHelper.ExtractHKZones(
// hkZones,
// 1, // Bar Index ...
// 50, // Number of Zones ...
// 5, // Shadow Multiplier ...
// 1, // Strength ...
// 14 // Validation Length ...
// );
// if (IsValidSize(hkCounts))
// {
// // //
// // XCBoxObject *iObj;
// // for (int i = 0; i < hkCounts; i++)
// // {
// // //
// // iObj = NULL;
// // bool isCreated = fima2Signaller.poiDrawer.DrawBox(
// // hkZones[i],
// // iObj,
// // true, // Ignore At ...
// // hkZones[i].type // Name ...
// // );
// // //
// // ZeroMemory(iObj);
// // }
// // //
// // Print("HK Zones Detected ...");
// }
//
// Testing XFIMA MA Pivots ...
// XPivot maPivots[];
// int maPivotsCount = fimaHelper.ExtractMAPivots(
// maPivots,
// 1, // Bar Index ...
// 50, // Number of Pivots ...
// 1 // Validation Diff ...
// );
// if (IsValidSize(maPivotsCount))
// {
// //
// // CArrayObj *iPivotsObj;
// // maPivotsCount = poiDrawer.DrawPivots(
// // maPivots,
// // iPivotsObj //
// // );
// //
// // Print("MA Pivots Detected ...");
// }
//
// Custom Indicator Direction Shifts ...
bool hasMACross = HasDirection(structure.maCrossDir);
bool hasHKSwitch = HasDirection(structure.hkSwitchDir);
bool hasSARSwitch = HasDirection(structure.sarSwitchDir);
//
// Check Required Pattern Exists ...
bool hasPinnedBar = HasDirection(structure.pinnedDir);
bool hasEngulfedBar = HasDirection(structure.engulfedDir);
bool hasFlagPattern = HasDirection(structure.flagPatternDir);
bool hasStarPattern = HasDirection(structure.starPatternDir);
bool hasRisingPattern = HasDirection(structure.risingPatternDir);
bool hasPiercingPattern = HasDirection(structure.piercingPatternDir);
bool hasSignalKeyBar = HasDirection(structure.signalKeyBarPatternDir);
//
// Check Bar Pattern Exists ...
// and Select Pattern Direction and Price and Price Type ...
has = hasPinnedBar ||
hasEngulfedBar ||
hasFlagPattern ||
hasStarPattern ||
hasSignalKeyBar ||
hasRisingPattern ||
hasPiercingPattern;
if (has)
{
//
if (hasPinnedBar)
{
//
iDir = structure.pinnedDir;
iName = "XPinned_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasEngulfedBar)
{
//
iDir = structure.engulfedDir;
iName = "XEngulfed_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasFlagPattern)
{
//
iDir = structure.flagPatternDir;
iName = "XFlag_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasStarPattern)
{
//
iDir = structure.starPatternDir;
iName = "XStar_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasSignalKeyBar)
{
//
iDir = structure.risingPatternDir;
iName = "XRising_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasRisingPattern)
{
//
iDir = structure.piercingPatternDir;
iName = "XPiercing_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasPiercingPattern)
{
//
iDir = structure.signalKeyBarPatternDir;
iName = "XSignalKey_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
//
isBullish = IsSpecifiedBullish(iDir);
isBearish = IsSpecifiedBearish(iDir);
//
// Retrieve Price Type for Validate ...
iPriceType = isBullish
? X_PRICE_DOWN
: X_PRICE_UP;
iPriceEdgeType = isBullish
? X_PRICE_LOW
: X_PRICE_HIGH;
//
iPrice = bar.GetPrice(iPriceType);
iPriceEdge = bar.GetPrice(iPriceEdgeType);
//
// Validate Calculations ...
has = HasDirection(iDir) &&
(isBullish ||
isBearish) &&
NotEmptyZero(iPrice) &&
NotEmptyZero(iPriceEdge) &&
iPrice != iPriceEdge;
if (!has)
{
//
isBullish = false;
isBearish = false;
iDir = X_DIRECTION_NONE;
}
}
//
// Disable Signallers ...
has = false;
// Strategy 1 ...
// Works on Support or Resistances Areas ...
// has = Strategy1HasSignal(
// bar,
// iZone,
// iName,
// supports,
// resistances,
// iDir,
// structure,
// fimaConditions //
// );
//
// Do all Draws Here ...
bool canDraw = false;
if (canDraw && has)
{
//
int iWidth = 2;
XPOIStyle iStyle;
XCBoxObject *iBoxObj = NULL;
color iClr = isBullish
? clrYellow
: clrDarkOrange;
//
// Supports ...
has = HasChild(supports);
if (has)
{
//
count = ArraySize(supports);
for (int i = 0; i < count; i++)
{
//
has = poiDrawer.DrawBox(
supports[i],
iBoxObj,
true, // Ignore At ...
supports[i].type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
supports[i].dir //
);
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
//
iStyle.Clean();
ZeroMemory(iBoxObj);
}
}
//
// Resistances ...
has = HasChild(resistances);
if (has)
{
//
count = ArraySize(resistances);
for (int i = 0; i < count; i++)
{
//
has = poiDrawer.DrawBox(
resistances[i],
iBoxObj,
true, // Ignore At ...
resistances[i].type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
resistances[i].dir //
);
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
//
iStyle.Clean();
ZeroMemory(iBoxObj);
}
}
//
// Selected Zone ...
has = iZone.IsValid();
if (has)
{
//
has = poiDrawer.DrawBox(
iZone,
iBoxObj,
true, // Ignore At ...
iZone.type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
iZone.dir //
);
//
iStyle.clr = iClr;
iStyle.width = iWidth;
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
}
//
// TrendLines ...
//
// Pivots ...
//
has = HasChild(pvPivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
count = poiDrawer.DrawPivots(
pvPivots,
drawnPivots //
);
}
//
has = HasChild(zgPivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
count = poiDrawer.DrawPivots(
zgPivots,
drawnPivots //
);
}
//
// Patterns Bar ...
has = HasDirection(iDir);
if (has)
{
//
int iCode = 159;
ENUM_ARROW_ANCHOR iAnchor = isBullish
? ANCHOR_TOP
: ANCHOR_BOTTOM;
//
XCBarArrowObject *iPatternObj;
has = poiDrawer.DrawBarArrow(
bar,
iPatternObj,
iPriceEdgeType,
iCode,
iClr,
iWidth,
iAnchor,
iName,
true, // Ignore Bar Tag ...
10 // Threshold ...
);
}
}
/////////////////////////////////////////////////
/**
* Check Pattern Has Signal Based on Strategy 2 ...
*
* @param bar: XOHCL, reference to Pattern Bar ...
* @param iZone: XBoxZone, reference to holds affected zone ...
* @param patternName: string, detected pattern's name ...
* @param supports: XBoxZone, array reference to Provide Exists Supports ...
* @param resistances: XBoxZone, array reference to Provide Exists Resistances ...
* @param patternDir: ENUM_X_DIRECTION, detected pattern's direction ...
* @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
* @param fimaMarketStructure: XFIMAMarketStructure, refrence to Provides Market Structure ...
*
* @return ( bool )
*/
bool Strategy2HasSignal(
XOHCL &bar,
XBoxZone &iZone,
string patternName,
XBoxZone &supports[],
XBoxZone &resistances[],
ENUM_X_DIRECTION patternDir,
XFIMAMarketStructure &structure,
XFIMAConditions &fimaConditions,
XFIMAMarketStructure &fimaMarketStructure //
)
{
//
bool result = false;
//
// Prepare ...
iZone.Clean();
//
// Validate ...
//
// Do Detection ...
//
// Validate result ...
//
// Cleanup Resources ...
//
return result;
}
/**
* Check Pattern Has Signal Based on Strategy 1 ...
*
* @param bar: XOHCL, reference to Pattern Bar ...
* @param iZone: XBoxZone, reference to holds affected zone ...
* @param supports: XBoxZone, array reference to Provide Exists Supports ...
* @param resistances: XBoxZone, array reference to Provide Exists Resistances ...
* @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ...
* @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
*
* @return ( bool )
*/
bool Strategy3HasSignal(
XOHCL &bar,
XBoxZone &iZone,
XBoxZone &supports[],
XBoxZone &resistances[],
XFIMAMarketStructure &structure,
XFIMAConditions &fimaConditions //
)
{
//
bool result = false;
//
// Prepare ...
iZone.Clean();
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Reading XHK ...
//
// Bar 1 ...
double cHKO = fimaConditions.hkOpenBuffer[0];
double cHKH = fimaConditions.hkHighBuffer[0];
double cHKL = fimaConditions.hkLowBuffer[0];
double cHKC = fimaConditions.hkCloseBuffer[0];
//
// Bar 2 ...
double pHKO = fimaConditions.hkOpenBuffer[1];
double pHKH = fimaConditions.hkHighBuffer[1];
double pHKL = fimaConditions.hkLowBuffer[1];
double pHKC = fimaConditions.hkCloseBuffer[1];
//
bool isCHKBullish = cHKO < cHKC;
bool isCHKBearish = cHKO > cHKC;
//
bool isPHKBullish = pHKO < pHKC;
bool isPHKBearish = pHKO > pHKC;
//
bool isCHKSwitchedToBullish = isCHKBullish && !isPHKBullish;
bool isCHKSwitchedToBearish = isCHKBearish && !isPHKBearish;
//
return result;
}
@@ -0,0 +1,916 @@
/**
* Leg Pattern Detection ...
*
* @param bar: XOHCL, reference to Specified Bar ...
* @param zone: XBoxZone, reference to Holds Detection Zone ...
* @param validationLength: int, leg minimum Validation Length ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( bool )
*/
bool IsLegPattern(
XOHCL &bar,
XLeg &leg,
int validationLength = 3,
int loopback = 10 //
)
{
//
bool result = false;
//
// Prepare ...
leg.Clean();
//
// Normalize ...
loopback = NormalizeInt(loopback, 5);
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Prepare Patterns Analysis Config ...
XPatternAnalysisConfig iPatternsConfig;
iPatternsConfig.Default();
iPatternsConfig.CleanPatterns();
iPatternsConfig.AddPattern(X_BAR_PATTERN_LOW);
iPatternsConfig.AddPattern(X_BAR_PATTERN_HIGH);
iPatternsConfig.AddPattern(X_BAR_PATTERN_FLAG);
iPatternsConfig.AddPattern(X_BAR_PATTERN_STAR);
iPatternsConfig.AddPattern(X_BAR_PATTERN_RISING);
iPatternsConfig.AddPattern(X_BAR_PATTERN_PIERCING);
iPatternsConfig.AddPattern(X_BAR_PATTERN_ENGULFED);
iPatternsConfig.AddPattern(X_BAR_PATTERN_MOMENTUM);
iPatternsConfig.AddPattern(X_BAR_PATTERN_SIGNALKEY);
iPatternsConfig.AddPattern(X_BAR_PATTERN_TRUE_GAPED);
//
XOHCL iBar;
XOHCL pBar;
XOHCL iZBar;
XBoxZone zone;
XBoxZone iZone;
XBoxZone jZone;
bool has = false;
XBoxZone supports[];
XOHCL bullishBars[];
XOHCL bearishBars[];
XBoxZone bullishFVGs[];
XBoxZone bearishFVGs[];
bool isBullish = false;
bool isBearish = false;
XBoxZone resistances[];
double bullishPower = 0;
double bearishPower = 0;
int bullishBarsCount = 0;
int bearishBarsCount = 0;
int barIndex = bar.Index();
int start = barIndex + 1;
XPatternAnalysis iPattern;
int end = start + loopback;
XPatternAnalysis patterns[];
int bullishPatternsCount = 0;
int bearishPatternsCount = 0;
int sequentialsBullishBarsCount = 0;
int sequentialsBearishBarsCount = 0;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
for (int i = end; i >= start; i--)
{
//
// Initialize Indexed Bar ...
iBar.Clean();
pBar.Clean();
result = bar.BarAt(i, iBar);
result = result &&
iBar.GetPreviousBar(pBar);
if (!result)
{
break;
}
//
// Fill Bar Direction ...
isBullish = iBar.IsBullish();
isBearish = iBar.IsBearish();
//
// Directional ...
//
if (isBullish)
{
//
bullishBarsCount++;
//
bullishPower += iBar.GetBody();
bullishPower += iBar.GetLowShadow();
bullishPower -= iBar.GetHighShadow();
//
AddIfNotExists(iBar, bullishBars);
}
//
if (isBearish)
{
//
bearishBarsCount++;
//
bearishPower += iBar.GetBody();
bearishPower -= iBar.GetLowShadow();
bearishPower += iBar.GetHighShadow();
//
AddIfNotExists(iBar, bearishBars);
}
//
// Sequentail ....
//
// Bullish ...
if (isBullish)
{
//
if (pBar.IsBullish())
{
sequentialsBullishBarsCount++;
}
else if (pBar.IsBearish())
{
sequentialsBullishBarsCount = 0;
}
}
//
// Bearish ...
if (isBearish)
{
//
if (pBar.IsBearish())
{
sequentialsBearishBarsCount++;
}
else if (pBar.IsBullish())
{
sequentialsBearishBarsCount = 0;
}
}
//
// Detect Patterns ...
iPattern.Clean();
has = AnalyseBarPatterns(iBar, iPattern, iPatternsConfig);
if (has)
{
//
AddRef(iPattern, patterns);
//
bullishPatternsCount += iPattern.Count(X_DIRECTION_BULLISH);
bearishPatternsCount += iPattern.Count(X_DIRECTION_BEARISH);
}
//
// FVG Detection ...
CleanDirection(iDir);
has = HasFVG(iBar, iDir, iZone);
if (has)
{
//
if (iZone.IsBullish())
{
AddIfNotExists(iZone, bullishFVGs);
}
else
{
AddIfNotExists(iZone, bearishFVGs);
}
}
//
// Support / Resistance Detection ...
has = HasSupportResistance(
iBar,
iZone,
jZone,
5 //
);
if (has)
{
//
if (iZone.IsValid())
{
AddIfNotExists(iZone, supports);
}
//
if (jZone.IsValid())
{
AddIfNotExists(jZone, resistances);
}
}
}
//
// Summarizing ...
//
// Detect Direction ...
zone.Clean();
isBullish = false;
isBearish = false;
CleanDirection(iDir);
//
isBullish =
//
bullishPower > 0 &&
bullishBarsCount > 0 &&
bullishPatternsCount > 0 &&
sequentialsBullishBarsCount > 0 &&
//
bullishPower > bearishPower &&
bullishBarsCount > bearishBarsCount &&
bullishPatternsCount > bearishPatternsCount &&
sequentialsBullishBarsCount > sequentialsBearishBarsCount
//
;
//
isBearish =
//
bearishPower > 0 &&
bearishBarsCount > 0 &&
bearishPatternsCount > 0 &&
sequentialsBearishBarsCount > 0 &&
//
bearishPower > bullishPower &&
bearishBarsCount > bullishBarsCount &&
bearishPatternsCount > bullishPatternsCount &&
sequentialsBearishBarsCount > sequentialsBullishBarsCount
//
;
//
// Validate ...
result =
(isBullish && !isBearish) ||
(isBearish && !isBullish);
//
// PRICE Types ...
ENUM_X_PRICE lowerPriceType = X_PRICE_LOW;
ENUM_X_PRICE upperPriceType = X_PRICE_HIGH;
//
// Prepare Zone ...
if (result)
{
//
zone.at = bar.time;
zone.to = bar.time;
zone.period = bar.period;
zone.symbol = bar.symbol;
//
zone.type = ToXString(X_BAR_PATTERN_LEG);
zone.dir = isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
int idx = -1;
if (isBullish)
{
idx = GetOldest(bullishBars);
}
else
{
idx = GetOldest(bearishBars);
}
//
result = IsValidIndex(idx);
if (result)
{
//
iZBar.Clean();
if (isBullish)
{
iZBar = bullishBars[idx];
}
else
{
iZBar = bearishBars[idx];
}
//
zone.from = iZBar.time;
//
iZBar.Clean();
}
//
if (isBullish)
{
//
// Prepare Upper and Lower ...
//
// Upper ...
idx = GetHighestBarPrice(bullishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.upper = bullishBars[idx].GetPrice(upperPriceType);
}
//
// Lower ...
idx = GetLowestBarPrice(bullishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.lower = bullishBars[idx].GetPrice(lowerPriceType);
}
}
else
{
//
// Prepare Upper and Lower ...
//
// Upper ...
idx = GetHighestBarPrice(bearishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.upper = bearishBars[idx].GetPrice(upperPriceType);
}
//
// Lower ...
idx = GetLowestBarPrice(bearishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.lower = bearishBars[idx].GetPrice(lowerPriceType);
}
}
//
result = zone.IsValid();
}
//
// Prepare XLeg ...
if (result)
{
//
leg.dir = zone.dir;
leg.time = zone.from;
leg.upper = zone.upper;
leg.lower = zone.lower;
leg.symbol = zone.symbol;
leg.period = zone.period;
Copy(patterns, leg.patterns);
Copy(supports, leg.supports);
Copy(bullishBars, leg.bullishBars);
Copy(bearishBars, leg.bearishBars);
Copy(resistances, leg.resistances);
Copy(bullishFVGs, leg.bullishFVGs);
Copy(bearishFVGs, leg.bearishFVGs);
leg.sequentialBullishBars = sequentialsBullishBarsCount;
leg.sequentialBearishBars = sequentialsBearishBarsCount;
//
result = leg.IsValid();
}
//
// Cleanup ...
if (!result)
{
zone.Clean();
}
iBar.Clean();
pBar.Clean();
zone.Clean();
iZBar.Clean();
iZone.Clean();
jZone.Clean();
iPattern.Clean();
XClean(supports);
XClean(patterns);
XClean(bullishBars);
XClean(bearishBars);
XClean(bullishFVGs);
XClean(bearishFVGs);
XClean(resistances);
//
return result;
}
bool IsLegPattern1(
XOHCL &bar,
XLeg &leg,
int validationLength = 5,
int loopback = 500 //
)
{
//
bool result = false;
//
// Prepare ...
leg.Clean();
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
validationLength = NormalizeInt(validationLength, 3);
//
// Validate ...
result = bar.IsValid() &&
fimaParser.IsValid();
if (!result)
{
return result;
}
//
int idx = bar.Index();
while (idx < bar.Index() + loopback)
{
//
}
//
return result;
}
//////////////////////////////////////////////////
//
// Leg ...
XLeg leg; // Exists Leg ...
bool drawLeg; // Draw Leg ...
bool manageLegs;
//
bool HasLeg()
{
return leg.IsValid();
}
//
bool ValidateLeg(XOHCL &bar)
{
//
bool result = false;
//
result = HasLeg() &&
bar.IsValid();
if (!result)
{
return result;
}
//
result =
leg.IsBullish()
? bar.low > leg.lower
: leg.IsBearish()
? bar.high < leg.upper
: false;
//
return result;
}
//
void DrawLeg()
{
//
if (!drawLeg)
{
return;
}
//
if (!HasLeg())
{
return;
}
//
// Update to Times ...
leg.UpdateTimes();
//
// Draw Leg Box ...
XBoxZone legZone;
leg.ToBox(legZone);
if (legZone.IsValid())
{
//
legZone.to = TimeCurrent();
poiDrawer.DrawZone(legZone, structureDrawConfig.drawConfig);
}
//
// Draw Legs Other Stufs ...
return;
//
// FVGs ...
poiDrawer.DrawZones(leg.bullishFVGs, structureDrawConfig.drawConfig);
poiDrawer.DrawZones(leg.bearishFVGs, structureDrawConfig.drawConfig);
//
// Support and Resistances ...
poiDrawer.DrawZones(leg.supports, structureDrawConfig.drawConfig);
poiDrawer.DrawZones(leg.resistances, structureDrawConfig.drawConfig);
//
// Patterns ...
poiDrawer.DrawPatternAnalysises(leg.patterns, structureDrawConfig.barAnalysisDrawConfig);
}
//
void ManageLeg(XOHCL &bar)
{
//
// Validate Exists ...
if (HasLeg())
{
//
if (!ValidateLeg(bar))
{
//
// Invalidate XLeg ...
leg.Clean();
}
}
//
// Detect New ...
if (!HasLeg())
{
poiDetector.IsLegPattern(bar, leg);
}
//
// Update Exists ...
if (HasLeg())
{
//
// Update to Times ...
leg.UpdateTimes();
//
DrawLeg();
}
}
//
//
//
ManageLeg(bar);
//
// Checking For Leg Pattern ...
bool hasLeg = poiDetector.IsLegPattern(
pBar,
_leg,
3,
10 //
);
if (hasLeg)
{
hasLeg = _leg.ToBox(legZone);
}
bool hasBullishLeg = hasLeg && _leg.IsBullish();
bool hasBearishLeg = hasLeg && _leg.IsBearish();
//
//
//
int CollectPivots(
XPivot &pivots[],
int barIndex = 0,
int loopback = 500 //
)
{
//
int result = 0;
//
// Prepare ...
XClean(pivots);
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return result;
}
//
has = false;
XOHCL tmpBar;
XPivot tmpPivot;
double tmpValue;
datetime tmpTime;
bool isBullish = false;
bool isBearish = false;
string tmpSymbol = symbol;
ENUM_TIMEFRAMES tmpPeriod = period;
ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
tmpBar.Clean();
tmpPivot.Clean();
//
has = tmpBar.Init(tmpSymbol, tmpPeriod, i);
if (!has)
{
continue;
}
//
// XSAR ...
isBullish = IsSARSwitchedToBullish(i);
isBearish = IsSARSwitchedToBearish(i);
has = isBullish || isBearish;
if (has)
{
}
//
// XMA Fast / Slow ...
//
// States ...
isBullish = IsMASlowSwitchedToBullish(i);
isBearish = IsMASlowSwitchedToBearish(i);
has = isBullish || isBearish;
if (has)
{
}
//
// Crossed Fast Slow ...
isBullish = IsMAFastCrossedOverSlow(i);
isBearish = IsMAFastCrossedUnderSlow(i);
has = isBullish || isBearish;
if (has)
{
}
//
// Crossed Last ...
isBullish = IsMASlowCrossedOverLast(i);
isBearish = IsMASlowCrossedUnderLast(i);
has = isBullish || isBearish;
if (has)
{
}
//
// XHK ...
isBullish = IsHKSwitchedToBullish(i);
isBearish = IsHKSwitchedToBearish(i);
has = isBullish || isBearish;
if (has)
{
}
}
//
result = ArraySize(pivots);
//
return result;
}
//
//
//
/**
* an strucutre to Model Specified Leg Pattern ...
**/
struct XLeg
{
//
// Props ...
//
datetime time;
string symbol;
ENUM_X_DIRECTION dir;
ENUM_TIMEFRAMES period;
//
double upper;
double lower;
//
XOHCL bullishBars[];
XOHCL bearishBars[];
//
XBoxZone supports[];
XBoxZone resistances[];
//
XBoxZone bullishFVGs[];
XBoxZone bearishFVGs[];
//
XPatternAnalysis patterns[];
//
int sequentialBullishBars;
int sequentialBearishBars;
//
// Constructor ...
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
time = NULL;
symbol = NULL;
period = NULL;
dir = X_DIRECTION_NONE;
//
upper = 0;
lower = 0;
sequentialBullishBars = 0;
sequentialBearishBars = 0;
//
XClean(patterns);
XClean(supports);
XClean(bullishBars);
XClean(bearishBars);
XClean(resistances);
XClean(bullishFVGs);
XClean(bearishFVGs);
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
IsXValid(time) &&
IsXValid(symbol) &&
IsXValid(period) &&
HasDirection(dir) &&
NotEmptyZero(upper) &&
NotEmptyZero(lower) &&
upper > lower;
//
return result;
}
/**
* Check is Bullish ...
*
* @return ( bool )
*/
bool IsBullish()
{
return IsValid() &&
IsXBullish(dir);
}
/**
* Check is Bearish ...
*
* @return ( bool )
*/
bool IsBearish()
{
return IsValid() &&
IsXBearish(dir);
}
/**
* Converts a Leg to XBoxZone ...
*
* @param zone: XBoxZone, reference to holds Converted ...
*
* @return ( bool )
*/
bool ToBox(XBoxZone &zone)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
zone.at = time;
zone.dir = dir;
zone.from = time;
zone.upper = upper;
zone.lower = lower;
zone.symbol = symbol;
zone.period = period;
zone.to = TimeCurrent();
zone.type = ToXString(X_BAR_PATTERN_LEG);
//
result = zone.IsValid();
//
// Cleanup ...
if (!result)
{
zone.Clean();
}
//
return result;
}
/**
* Update Times of Collections ...
*
* @param value: datetime, Specified Time ...
*/
void UpdateTimes(datetime value = NULL)
{
//
// Normalize ...
value = NormalizeTime(value);
//
// Validate ...
if (!IsValid())
{
return;
}
//
UpdateToTime(supports, value);
UpdateToTime(resistances, value);
UpdateToTime(bullishFVGs, value);
UpdateToTime(bearishFVGs, value);
}
//
};
@@ -0,0 +1,686 @@
{
"lists": [
{
"id": "d66f2925-aa4e-46e4-8f3e-f2c0ba6c9454",
"title": "Backlog",
"cards": []
},
{
"id": "61ca33e6-05e4-4b44-b88d-3bc8ae5cba86",
"title": "To Do",
"cards": []
},
{
"id": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
"title": "Doing",
"cards": [
{
"id": "a59a73f4-1ab4-477b-893e-b2dfb71fe6ea",
"listId": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
"title": "Add Support for PV in XKI Indicator.",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "f8eb6951-f337-40da-9b98-e468f77709fd",
"listId": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
"title": "implementing Signallers Has Strategy Functions ...",
"description": "Fill Signal Strategies\n",
"labels": [],
"checkboxes": [
{
"id": "832b1c6e-8219-48ed-a897-45251f444cb1",
"title": "Strategy 1",
"checked": false
},
{
"id": "ca4683e7-14f0-4dde-86a2-16ea71e08a48",
"title": "Add more Validations on Entries in Strategy 1;",
"checked": false
},
{
"id": "bd3c09a7-1fbf-45f9-bcf7-ec0f71d1be24",
"title": "adding support Validate by Support and Resistances Zones; on Strategy 1; ",
"checked": false
}
],
"comments": []
},
{
"id": "bad677c0-a119-4f44-be8b-185fc4c996c7",
"listId": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
"title": "add Targets in strategy 1",
"description": "use Guards Instead of Targets.",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "bcb422f9-89db-4816-ba3a-bae95c9c8da4",
"listId": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
"title": "Test all XKI Helper Functions",
"description": "Test all KI Parser Conditional Tools ...\n ",
"labels": [],
"checkboxes": [
{
"id": "987aadc7-1775-4ddb-96a8-c7867b41c5dc",
"title": "IsKIFastBullish",
"checked": true
},
{
"id": "33d30e91-1d65-4cc9-8955-4fcdac1a1a1c",
"title": "IsKIFastBearish",
"checked": true
},
{
"id": "f5efdef3-3dd5-4a67-9335-27ade4a08119",
"title": "IsKIFastSwitchedToBullish",
"checked": true
},
{
"id": "95fd5f87-3076-4a10-9d1d-2190c74e77dc",
"title": "IsKIFastSwitchedToBearish",
"checked": true
},
{
"id": "5848cd3c-7f60-4310-adde-56d0e80896a2",
"title": "IsKIFastOverLast",
"checked": true
},
{
"id": "879b6657-8a36-4329-9edd-2b5243733c37",
"title": "IsKIFastUnderLast",
"checked": true
},
{
"id": "7ebd6627-2bd7-47b1-9b3c-51643a446cb3",
"title": "IsKIFastSameAsLast",
"checked": true
},
{
"id": "4533e930-8c54-45ea-95b8-a95aa9278bd8",
"title": "IsKIFastSwitchedOverLast",
"checked": true
},
{
"id": "1231584a-5181-457b-8f31-02da2962c54a",
"title": "IsKIFastSwitchedUnderLast",
"checked": true
},
{
"id": "67f9ccdb-eff3-4e1e-945b-5232773f16f5",
"title": "IsKISlowBullish",
"checked": true
},
{
"id": "2262f093-f7c9-4a73-983c-055b6098f915",
"title": "IsKISlowBearish",
"checked": true
},
{
"id": "0e6b67fe-0ff5-4783-a4e3-36b3a70007f5",
"title": "IsKISlowSwitchedToBullish",
"checked": true
},
{
"id": "0ec4ea00-63bc-4059-92e2-46afa6793325",
"title": "IsKISlowSwitchedToBearish",
"checked": true
},
{
"id": "cf71aa02-fbf9-4f42-a4f2-791353cc290e",
"title": "IsKISlowOverLast",
"checked": true
},
{
"id": "da046ac2-0ed5-4c45-ba5b-ffd31a1f65a3",
"title": "IsKISlowUnderLast",
"checked": true
},
{
"id": "f57c9dde-9294-4909-b5c8-4a8a9a661072",
"title": "IsKISlowSameAsLast",
"checked": true
},
{
"id": "c52951e5-7a57-4823-a061-9d7a4aa9f0f4",
"title": "IsKISlowSwitchedOverLast",
"checked": true
},
{
"id": "9e523117-d742-4ffa-ae7d-cbd995b6bc61",
"title": "IsKISlowSwitchedUnderLast",
"checked": true
},
{
"id": "3ae34a28-6172-4209-832d-41647e45c072",
"title": "IsKISuperSlowBullish",
"checked": true
},
{
"id": "a7720bdf-2535-430f-9f55-81fa2d281910",
"title": "IsKISuperSlowBearish",
"checked": true
},
{
"id": "b03e521f-d1b4-4e83-9aaa-6a65297420d5",
"title": "IsKISuperSlowSwitchedToBullish",
"checked": true
},
{
"id": "3a59a397-816d-4e41-93cd-cab889ebcc1e",
"title": "IsKISuperSlowSwitchedToBearish",
"checked": true
},
{
"id": "315380e3-702b-41bf-abf5-4b85c0e00ce4",
"title": "IsKISuperSlowOverLast",
"checked": true
},
{
"id": "3a18f5b6-f18e-43d8-b8e6-43fc530ac80d",
"title": "IsKISuperSlowUnderLast",
"checked": true
},
{
"id": "4174d12c-382f-4615-9a65-99c447fa6a2a",
"title": "IsKISuperSlowSameAsLast",
"checked": true
},
{
"id": "03c1fc35-b0c4-477f-ab30-d183a990aff1",
"title": "IsKISuperSlowSwitchedOverLast",
"checked": true
},
{
"id": "82f549d7-6afa-4408-9d3a-d41d4d623bb7",
"title": "IsKISuperSlowSwitchedUnderLast",
"checked": true
},
{
"id": "abd7362a-29ba-4f92-9fe0-0496ccb7e9c6",
"title": "IsKIWaveBullish",
"checked": true
},
{
"id": "440e446f-9aa9-4f74-a950-63a013b42fa5",
"title": "IsKIWaveBearish",
"checked": true
},
{
"id": "2606bddb-aae1-4cca-8a29-b11c9f7015e6",
"title": "IsKIWaveSwitchedToBullish",
"checked": true
},
{
"id": "2036fddf-c4eb-4c5d-a550-d3f84341e78b",
"title": "IsKIWaveSwitchedToBearish",
"checked": true
},
{
"id": "649905b4-d0e9-4009-aeda-08a633861201",
"title": "IsKIWaveOverLast",
"checked": true
},
{
"id": "cc181a1f-298a-438d-afc8-74b0d4200228",
"title": "IsKIWaveUnderLast",
"checked": true
},
{
"id": "66bafec6-7794-4650-8919-d6409b49fbdf",
"title": "IsKIWaveSwitchedOverLast",
"checked": true
},
{
"id": "a5a714cb-ea11-42e3-8e9c-8745405998ae",
"title": "IsKIWaveSwitchedUnderLast",
"checked": true
},
{
"id": "b94e9071-5f85-4a38-828c-7cf8a1e99a63",
"title": "IsPriceOverKIUpper",
"checked": true
},
{
"id": "f534622b-5a7f-4c9c-85ed-c562d907fd89",
"title": "IsPriceSwitchedOverKIUpper",
"checked": true
},
{
"id": "c3a7d88b-c81f-46d4-a3cc-a0d1f5597371",
"title": "IsPriceUnderKIUpper",
"checked": true
},
{
"id": "8e559cb9-f6a9-412e-8882-e622030cf838",
"title": "IsPriceSwitchedUnderKIUpper",
"checked": true
},
{
"id": "1efcb06a-0edd-41d0-8e8b-18cba4f64226",
"title": "IsPriceOverKILower",
"checked": true
},
{
"id": "b16ad1a1-1fb2-4bb6-b2f8-f9310d012f4f",
"title": "IsPriceSwitchedOverKILower",
"checked": true
},
{
"id": "7e95d7e0-a50f-412b-a024-2568bf66c3f1",
"title": "IsPriceUnderKILower",
"checked": true
},
{
"id": "dd0deb1f-a259-4ce9-a471-92e268e10abe",
"title": "IsPriceSwitchedUnderKILower",
"checked": true
},
{
"id": "d747f70e-af68-42f1-a621-efd3ce518b47",
"title": "IsPriceInsideKIBands",
"checked": true
},
{
"id": "ebf997ee-8944-4442-86fb-6d01ea64b8a6",
"title": "IsMAFastBullish",
"checked": true
},
{
"id": "e756a5d0-4477-4277-be7d-5897079add6a",
"title": "IsMAFastSwitchedToBullish",
"checked": true
},
{
"id": "11eb8b4c-004c-4272-921f-4067315aac6a",
"title": "IsMAFastBearish",
"checked": true
},
{
"id": "548819d7-06fa-4ca5-adf2-c4c2d3064d7e",
"title": "IsMAFastSwitchedToBearish",
"checked": true
},
{
"id": "90451b0f-ec2e-48e0-8797-7f48cedf743c",
"title": "IsMAFastOverLast",
"checked": true
},
{
"id": "14210197-c670-4f49-8935-b65926945837",
"title": "IsMAFastSwitchedOverLast",
"checked": true
},
{
"id": "6158296f-fec3-443e-826b-84a481225013",
"title": "IsMAFastUnderLast",
"checked": true
},
{
"id": "e84b372e-fbdc-45da-a604-76a0fc6381c4",
"title": "IsMAFastSwitchedUnderLast",
"checked": true
},
{
"id": "ef0feb55-069c-4e9a-a56e-de05f6b6801f",
"title": "IsMASlowBullish",
"checked": true
},
{
"id": "0568553a-8ad1-4588-834e-26befe2a9bbb",
"title": "IsMASlowSwitchedToBullish",
"checked": true
},
{
"id": "630cd36a-f848-44d6-958b-728c4757df6e",
"title": "IsMASlowBearish",
"checked": true
},
{
"id": "62899e4a-87da-4fc9-8b4b-f1b8b077c177",
"title": "IsMASlowSwitchedToBearish",
"checked": true
},
{
"id": "acca2b2e-27d6-44dc-bd7f-98857e1b7e64",
"title": "IsMASlowOverLast",
"checked": true
},
{
"id": "762fd136-113c-444f-8373-2104bc4db466",
"title": "IsMASlowSwitchedOverLast",
"checked": true
},
{
"id": "49631b5a-8b69-4649-a47d-bef5bda3e137",
"title": "IsMASlowUnderLast",
"checked": true
},
{
"id": "3cd7c2a1-8a8a-4aba-85c2-6279a356c49e",
"title": "IsMASlowSwitchedUnderLast",
"checked": true
},
{
"id": "43bbc4df-7601-4460-b636-61b73b30f10a",
"title": "IsMASuperSlowBullish",
"checked": true
},
{
"id": "a64507e6-c99a-4e6a-a995-c1be671d1083",
"title": "IsMASuperSlowSwitchedToBullish",
"checked": true
},
{
"id": "91c30277-6ea9-40e8-8467-d06beabf486b",
"title": "IsMASuperSlowBearish",
"checked": true
},
{
"id": "65295670-87f7-481c-ab9e-a92c8606923f",
"title": "IsMASuperSlowSwitchedToBearish",
"checked": true
},
{
"id": "0a102b6a-fabe-4aba-938f-d87a22e11b5e",
"title": "IsMASuperSlowOverLast",
"checked": true
},
{
"id": "cc1a7131-227d-4007-82ed-78c8cc9ef33e",
"title": "IsMASuperSlowSwitchedOverLast",
"checked": true
},
{
"id": "97e4a349-77c8-4997-8f1b-875fff8229ab",
"title": "IsMASuperSlowUnderLast",
"checked": true
},
{
"id": "93899467-f06d-420a-ac6e-e645c8c07389",
"title": "IsMASuperSlowSwitchedUnderLast",
"checked": true
},
{
"id": "2cbc64ba-1882-47a6-9206-7b25e8008395",
"title": "IsMACrossoverBullish",
"checked": true
},
{
"id": "d7af351b-1de4-4ca9-958a-388d944d4fa9",
"title": "IsMACrossoverSwitchedToBullish",
"checked": true
},
{
"id": "44b233e6-5a56-4f3a-9c28-60e11aa2059a",
"title": "IsMACrossoverBearish",
"checked": true
},
{
"id": "5af39475-d1f8-477f-b867-5359aaaf94fa",
"title": "IsMACrossoverSwitchedToBearish",
"checked": true
},
{
"id": "d2a8183b-3553-4016-8155-a114c70da5ec",
"title": "IsPeakSameAsLast",
"checked": true
},
{
"id": "7395f77c-7491-417e-8ca8-a41923b46b68",
"title": "IsPeakOverLast",
"checked": true
},
{
"id": "afdae94d-1a14-408d-b1bd-e84c0868a655",
"title": "IsPeakUnderLast",
"checked": true
},
{
"id": "45f52be4-1f08-4e7a-b15b-d8db48752449",
"title": "IsValeSameAsLast",
"checked": true
},
{
"id": "ebc003bc-850d-44e2-a0ed-5ddaba71ae1a",
"title": "IsValeOverLast",
"checked": true
},
{
"id": "c979f0c3-e356-4fa6-bead-596e4a06b962",
"title": "IsValeUnderLast",
"checked": true
},
{
"id": "dd69c2c0-c999-4235-8cb5-74607b27c7ec",
"title": "IsATRBreakoutUp",
"checked": false
},
{
"id": "1a77e8e1-b3e8-48b4-b072-1cda3a69c6f9",
"title": "IsATRBreakoutDown",
"checked": false
},
{
"id": "bfeb3c24-f0ed-4aed-99af-bec8db026a62",
"title": "IsATROverLast",
"checked": false
},
{
"id": "62881e04-9b38-49e4-ae9d-e5161c1b0b5c",
"title": "IsATRUnderLast",
"checked": false
},
{
"id": "33ec5ba0-d31a-4602-ba79-7d3b4d9d7986",
"title": "IsATRSwitchedOverLast",
"checked": false
},
{
"id": "cf0fb674-8dfc-4ed1-b1dd-5a8447d818a4",
"title": "IsATRSwitchedUnderLast",
"checked": false
},
{
"id": "ab07c8e5-454c-4c9b-a69d-fa2e8330a2e0",
"title": "IsVolatilityHigh",
"checked": false
},
{
"id": "031521be-0062-4d07-ade4-ff17782888c7",
"title": "IsVolatilityLow",
"checked": false
},
{
"id": "49376783-45aa-4a57-a304-3547babf0ccd",
"title": "IsVolatilitySwitchdToHigh",
"checked": false
},
{
"id": "5803601b-9143-471d-968f-59622d37b70a",
"title": "IsVolatilitySwitchdToLow",
"checked": false
},
{
"id": "0ab99ddc-75b8-45c7-9140-8cd3dc6921c6",
"title": "IsRSIBullish",
"checked": false
},
{
"id": "ba39f76c-2257-48fe-94ca-addf2148ee23",
"title": "IsRSIBearish",
"checked": false
},
{
"id": "91c098b3-56d8-4728-b411-edf7e42d60b0",
"title": "IsRSIOverbought",
"checked": false
},
{
"id": "7917431d-9bc9-4514-8aea-7fae7c11b0de",
"title": "IsRSIOversold",
"checked": false
},
{
"id": "83d4b28b-fe6c-411c-a209-c57e3c8251d0",
"title": "IsRSISwitchedToOverSold",
"checked": false
},
{
"id": "96493d94-9db6-49de-a7f1-e3990b9469b8",
"title": "IsRSISwitchedFromOverSold",
"checked": false
},
{
"id": "02579268-284f-40f3-93c9-0cb3f70d103a",
"title": "IsRSISwitchedToOverbought",
"checked": false
},
{
"id": "6c473b2e-1b37-44b2-a08c-ce6217d0c00e",
"title": "IsRSISwitchedFromOverbought",
"checked": false
},
{
"id": "30177c7a-47df-4d90-8132-0f467ebc071c",
"title": "IsRSISwitchedToBullish",
"checked": false
},
{
"id": "a3e07f9c-72da-49b4-8101-f742644a2b81",
"title": "IsRSISwitchedToBearish",
"checked": false
}
],
"comments": []
}
]
},
{
"id": "c6b07a7f-d2e7-4f67-a5a9-0d93cd8bf981",
"title": "Test",
"cards": [
{
"id": "128af636-5cd8-4311-a565-e822ba380d59",
"listId": "c6b07a7f-d2e7-4f67-a5a9-0d93cd8bf981",
"title": "Add Support for ATR MA in XKI Indicator ...",
"description": "since we have to Calculate Volatility of ATR for Reversal or Breakouts,\nwe Have to Compare ATR by it's Moving Averages ...\n\nhere in this task we need to add support for atr MA ...",
"labels": [],
"checkboxes": [
{
"id": "f3aabe70-9df5-405d-a737-55e9cc6b2027",
"title": "Add Buffer;",
"checked": true
},
{
"id": "d6d295c4-b3e9-4946-b305-20df0858db59",
"title": "Calculate;",
"checked": true
},
{
"id": "d0e3f5b6-56c9-41a6-95c0-71de279bc70c",
"title": "Implement in Conditions;",
"checked": true
},
{
"id": "4827fc2b-e71d-468c-a069-ec5f17bc6962",
"title": "Implement in Helper;",
"checked": true
},
{
"id": "3fb4bac7-32c5-43be-b6ac-ccf4a15a117b",
"title": "Use in Parser;",
"checked": true
},
{
"id": "b98a8eee-1cbf-455b-9e8f-e4d42ba3f327",
"title": "Remove threshold;",
"checked": true
},
{
"id": "c3636ee3-d577-4728-9b2b-a9237687fd1a",
"title": "Refactor Side Affects;",
"checked": true
}
],
"comments": [
{
"id": "128f3338-1b62-4c2c-8ce4-723ed97fd41c",
"comment": "here we are going to test changes ..."
}
]
},
{
"id": "1b86f94a-a66e-482c-9172-c9dbb338bb63",
"listId": "c6b07a7f-d2e7-4f67-a5a9-0d93cd8bf981",
"title": "Testing POI(s) for Strategies ...",
"description": "we have some POIs in POI Detectors ...\nin this task we have to test them Works ...",
"labels": [],
"checkboxes": [
{
"id": "224b6c66-341f-4dda-aa25-6b45ab034a6e",
"title": "Add Support Testing them;",
"checked": true
},
{
"id": "50caaa08-a3a4-4be5-85d8-4ab41e8dd945",
"title": "Add Support for Safe Entry;",
"checked": true
},
{
"id": "95ee0eba-4e0d-4a6a-be62-93aa562ab767",
"title": "POI",
"checked": true
},
{
"id": "aec8ebe5-0d88-4ea7-bfd3-eb1a26af8a55",
"title": "Breakout POI",
"checked": true
},
{
"id": "6104db5f-95b2-401a-9efd-354b685e7a5f",
"title": "Reversal POI",
"checked": true
},
{
"id": "05aaad69-af4d-4253-89a7-e46a80cae593",
"title": "Continuation POI",
"checked": true
},
{
"id": "a7a75d64-00dd-4004-bab2-5040a47b8441",
"title": "Exhaustion POI",
"checked": true
},
{
"id": "a9c52b07-9a50-4c30-abf9-cd8e3febb6aa",
"title": "TrendExhausted POI",
"checked": true
}
],
"comments": [
{
"id": "cbcb5bf5-898d-4f5a-88bc-55007a11244c",
"comment": "all POI(s) noe well tested ...\nand everythings ready for implementing Strategies ..."
}
]
}
]
},
{
"id": "89823cc9-39a6-4d8b-bd5e-b6a14c03b01d",
"title": "Done",
"cards": []
}
],
"archive": {
"lists": [],
"cards": []
},
"settings": {
"labels": []
}
}
@@ -0,0 +1,46 @@
{
"lists": [
{
"id": "291ee671-37c7-45eb-bd40-24df3cb445ca",
"title": "BackLog",
"cards": []
},
{
"id": "53bb4f6a-34b9-48b8-9391-642c42d222d1",
"title": "ToDO",
"cards": [
{
"id": "b13fa9ba-5a66-42a6-a5eb-50789a59fad3",
"listId": "53bb4f6a-34b9-48b8-9391-642c42d222d1",
"title": "Apply Fix on XRR Tools",
"description": "Try to Recompile XRR Tools and Check it Works Currently or not;",
"labels": [],
"checkboxes": [],
"comments": []
}
]
},
{
"id": "ca095e9c-39f3-44dd-862c-d6c4af1dffff",
"title": "Doing",
"cards": []
},
{
"id": "842e4cfc-aee9-4fa7-9321-cc8ba0d194de",
"title": "Test",
"cards": []
},
{
"id": "b99e6c6c-ec5c-4f7c-b937-5bbba1551004",
"title": "Done",
"cards": []
}
],
"archive": {
"lists": [],
"cards": []
},
"settings": {
"labels": []
}
}
@@ -0,0 +1,279 @@
<mxfile host="65bd71144e">
<diagram id="QReEEfusIJtThQdlE9lK" name="Page-1">
<mxGraphModel dx="1382" dy="987" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="15" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="3">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="420" y="100"/>
<mxPoint x="100" y="100"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="16" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="6">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="420" y="100"/>
<mxPoint x="780" y="100"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="2" value="Position" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="360" y="40" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="17" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="4">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="100" y="340"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="18" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="5">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="100" y="620"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="3" value="States" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="40" y="120" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="27" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="420"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="28" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="500"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="4" value="InDrawdown" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="120" y="320" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="29" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="700"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="30" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="780"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="5" value="InProfit" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="120" y="600" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="19" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="8">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="220"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="20" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="9">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="300"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="21" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="11">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="380"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="22" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="10">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="460"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="6" value="Events" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="720" y="120" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="31" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="260" y="220"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="38" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="220"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="39" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="220"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="43" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="220"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8" value="Bullish Sign" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="200" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="32" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="260" y="300"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="37" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="300"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="40" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="300"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="44" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="300"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9" value="Bearish Sign" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="280" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="34" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="10">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="400" as="targetPoint"/>
<Array as="points">
<mxPoint x="520" y="460"/>
<mxPoint x="520" y="360"/>
<mxPoint x="260" y="360"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="35" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="10" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="460"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="42" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="10">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="680" as="targetPoint"/>
<Array as="points">
<mxPoint x="560" y="460"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="46" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="10" target="24">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="810" as="targetPoint"/>
<Array as="points">
<mxPoint x="560" y="460"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="10" value="Bearish Pushed Tick" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="440" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="33" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="380"/>
<mxPoint x="520" y="360"/>
<mxPoint x="260" y="360"/>
<mxPoint x="260" y="380"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="36" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="380"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="41" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="380"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="45" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="380"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="11" value="Bullish Pushed Tick" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="360" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="23" value="Long" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="680" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="24" value="Short" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="760" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="25" value="Long" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="400" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="26" value="Short" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="480" width="120" height="40" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,259 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Helper Class Library
// ----------------------------------------------
// Name: XSCX121XCCHelper
// Description: provides all Indicator
// Helper requirements ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../Classes/x-saherelm.x-helper.class.mq5"
//
// Definitions ...
//
// Input Models ...
struct X121XCCInputs
{
//
// Props ...
//
// Chart Style ...
ENUM_CHART_MODE mode; // Mode
color upColor; // Up Color
color downColor; // Down Color
color lineColor; // Line mode and Doji candlestick Color
color bearishColor; // Bullish Color
color bullishColor; // Bearish Color
color volumesColor; // Volumes Color
//
// Presentation ...
bool showCandles; // Show Candles
//
// Constructor(s) ...
X121XCCInputs()
{
//
Clean();
}
//
// Tools ...
//
// Clean ...
void Clean()
{
//
mode = CHART_CANDLES;
//
upColor = CLR_NONE;
downColor = CLR_NONE;
lineColor = CLR_NONE;
bearishColor = CLR_NONE;
bullishColor = CLR_NONE;
volumesColor = CLR_NONE;
//
showCandles = false;
//
ZeroMemory(this);
}
//
// Default ...
void Default()
{
//
mode = CHART_CANDLES;
//
upColor = clrLime;
downColor = clrRed;
lineColor = clrLime;
bearishColor = clrRed;
bullishColor = clrLime;
volumesColor = clrGreen;
//
showCandles = true;
}
//
// Hide all Visible Buffers ...
void Hide()
{
showCandles = false;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
true
//
;
//
return result;
}
//
// Retrieve MAx Length ...
int Max()
{
//
int result = 0;
//
result = MathMax(0, 0);
//
return result;
}
};
//
// Class ...
class XCX121XCCHelper : public XCBaseHelper
{
//
// Public ...
public:
//
// Props ...
//
// Constructors ...
XCX121XCCHelper()
: XCBaseHelper(_Symbol, _Period)
{
}
//
// Deconstructor ...
~XCX121XCCHelper()
{
mInputs.Clean();
}
//
// Tools ...
bool Init(
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period, // Trading Period
X121XCCInputs &inputs // Inputs
)
{
//
bool result = false;
//
mSymbol = symbol;
mPeriod = period;
//
result = inputs.IsValid();
if (!result)
{
return result;
}
//
mInputs = inputs;
//
mHandler = iCustom(
mSymbol,
mPeriod,
"x-saherelm.x121.xcc",
//
// Inputs ...
//
// Chart Style ...
"",
mInputs.mode, // Mode
mInputs.upColor, // Up Color
mInputs.downColor, // Down Color
mInputs.lineColor, // Line mode and Doji candlestick Color
mInputs.bullishColor, // Bearish Color
mInputs.bearishColor, // Bullish Color
mInputs.volumesColor, // Volumes Color
//
// Presentation ...
"",
mInputs.showCandles // Show Candles
//
);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
return result;
}
//
// Inputs ...
//
X121XCCInputs GetInputs()
{
return mInputs;
}
//
bool SetInputs(
X121XCCInputs &inputs // Configs
)
{
//
return Init(
mSymbol,
mPeriod,
inputs
//
);
}
//
// Protected ...
protected:
//
// Private ...
private:
//
// Props ...
X121XCCInputs mInputs; // Inputs ...
};
//
// Tools ...
@@ -0,0 +1,241 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Helper Class Library
// ----------------------------------------------
// Name: XSCX121XCTHelper
// Description: provides all Indicator
// Helper requirements ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../Classes/x-saherelm.x-helper.class.mq5"
//
// Definitions ...
//
// Input Models ...
struct X121XCTInputs
{
//
// Props ...
//
string font; // Font
int fontSize; // Font Size;
color clr; // Text Color
ENUM_BASE_CORNER corner; // Text Position
//
// Presentation ...
bool showCandleTime; // Show Candle Time
//
// Constructor(s) ...
X121XCTInputs()
{
Clean();
}
//
// Tools ...
//
// Clean ...
void Clean()
{
//
font = NULL;
fontSize = 15;
clr = CLR_NONE;
corner = CORNER_RIGHT_LOWER;
//
// Presentation ...
showCandleTime = false;
//
ZeroMemory(this);
}
//
// Default ...
void Default()
{
//
font = "Arial";
fontSize = 15;
clr = clrYellow;
corner = CORNER_RIGHT_LOWER;
//
// Presentation ...
showCandleTime = true;
}
//
// Hide all Visible Buffers ...
void Hide()
{
showCandleTime = false;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
true
//
;
//
return result;
}
//
// Retrieve MAx Length ...
int Max()
{
//
int result = 0;
//
result = MathMax(0, 0);
//
return result;
}
};
//
// Class ...
class XCX121XCTHelper : public XCBaseHelper
{
//
// Public ...
public:
//
// Props ...
//
// Constructors ...
XCX121XCTHelper()
: XCBaseHelper(_Symbol, _Period)
{
}
//
// Deconstructor ...
~XCX121XCTHelper()
{
mInputs.Clean();
}
//
// Tools ...
bool Init(
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period, // Trading Period
X121XCTInputs &inputs // Inputs
)
{
//
bool result = false;
//
mSymbol = symbol;
mPeriod = period;
//
result = inputs.IsValid();
if (!result)
{
return result;
}
//
mInputs = inputs;
//
mHandler = iCustom(
mSymbol,
mPeriod,
"x-saherelm.x121.xct",
//
// Inputs ...
mInputs.fontSize, // Font Size ...
mInputs.font, // Font ...
mInputs.clr, // Text Color ...
mInputs.corner, // Text Position ...
//
// Presentation ...
"",
mInputs.showCandleTime // Show Candle Time
//
);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
return result;
}
//
// Inputs ...
//
X121XCTInputs GetInputs()
{
return mInputs;
}
//
bool SetInputs(
X121XCTInputs &inputs // Configs
)
{
//
return Init(
mSymbol,
mPeriod,
inputs
//
);
}
//
// Protected ...
protected:
//
// Private ...
private:
//
// Props ...
X121XCTInputs mInputs; // Inputs ...
};
//
// Tools ...
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,788 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121 X3MA
// Description: X3MA ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 X3MA Indicator"
#property strict
//
// Definitions ...
//
#define ShortName "X121 X3MA"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Fast ...
input group "Fast";
input int fastLength = 6; // Length
input ENUM_MA_METHOD fastMethod = MODE_SMA; // Method
input ENUM_APPLIED_PRICE fastAppliedTo = PRICE_CLOSE; // Applied To
//
// Medium ...
input group "Medium";
input int mediumLength = 21; // Length
input ENUM_MA_METHOD mediumMethod = MODE_SMA; // Method
input ENUM_APPLIED_PRICE mediumAppliedTo = PRICE_CLOSE; // Applied To
//
// Slow ...
input group "Slow";
input int slowLength = 34; // Length
input ENUM_MA_METHOD slowMethod = MODE_SMA; // Method
input ENUM_APPLIED_PRICE slowAppliedTo = PRICE_CLOSE; // Applied To
//
// Presentation ...
input group "Presentation";
//
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
//
input bool applyColor = false;
//
input bool showFast = true; // Show Fast
input bool showMedium = true; // Show Medium
input bool showSlow = true; // Show Slow
//
// Buffers ...
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
#define bullishState 1
#define neuturalState 0
#define bearishState -1
//
#define emptyValue 0.0
//
#property indicator_chart_window
//
#property indicator_buffers 9
#property indicator_plots 3
//
// Plot Buffers ...
//
// FAST ...
//
#define fastBufferIndex 0
double fastBuffer[];
//
#define fastColorBufferIndex 1
double fastColorBuffer[];
//
#property indicator_label1 "X121 X3MA Fast"
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_color1 CLR_NONE, clrYellow, clrChocolate, clrGray
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//
// MEDIUM ...
//
#define mediumBufferIndex 2
double mediumBuffer[];
//
#define mediumColorBufferIndex 3
double mediumColorBuffer[];
//
#property indicator_label2 "X121 X3MA Medium"
#property indicator_type2 DRAW_COLOR_LINE
#property indicator_color2 CLR_NONE, clrAqua, clrMagenta, clrGray
#property indicator_style2 STYLE_DASHDOTDOT
#property indicator_width2 2
//
// SLOW ...
//
#define slowBufferIndex 4
double slowBuffer[];
//
#define slowColorBufferIndex 5
double slowColorBuffer[];
//
#property indicator_label3 "X121 X3MA Slow"
#property indicator_type3 DRAW_COLOR_LINE
#property indicator_color3 CLR_NONE, clrLime, clrRed, clrGray
#property indicator_style3 STYLE_DASH
#property indicator_width3 2
//
// Data Buffers ...
#define mLastBufferIndex 5
//
#define fastStateBufferIndex mLastBufferIndex + 1
double fastStateBuffer[];
//
#define mediumStateBufferIndex mLastBufferIndex + 2
double mediumStateBuffer[];
//
#define slowStateBufferIndex mLastBufferIndex + 3
double slowStateBuffer[];
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
int fastHandler = INVALID_HANDLE;
int mediumHandler = INVALID_HANDLE;
int slowHandler = INVALID_HANDLE;
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Indicator Handlers ...
//
// FAST ...
fastHandler = iMA(
_Symbol,
_Period,
fastLength,
0,
fastMethod,
fastAppliedTo //
);
bool isInited = fastHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// MEDIUM ...
mediumHandler = iMA(
_Symbol,
_Period,
mediumLength,
0,
mediumMethod,
mediumAppliedTo //
);
isInited = mediumHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// SLOW ...
slowHandler = iMA(
_Symbol,
_Period,
slowLength,
0,
slowMethod,
slowAppliedTo //
);
isInited = slowHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
IndicatorRelease(fastHandler);
IndicatorRelease(mediumHandler);
IndicatorRelease(slowHandler);
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
// Validate Calculated Bars ...
//
// FAST ...
int fastCalculatedBars = BarsCalculated(fastHandler);
//
// MEDIUM ...
int mediumCalculatedBars = BarsCalculated(mediumHandler);
//
// SLOW ...
int slowCalculatedBars = BarsCalculated(slowHandler);
//
bool isPassedRequiredCalculatedBars =
//
// FAST ...
fastCalculatedBars >= maxLength &&
//
// MEDIUM ...
mediumCalculatedBars >= maxLength &&
//
// SLOW ...
slowCalculatedBars >= maxLength
//
;
if (!isPassedRequiredCalculatedBars)
{
return prev_calculated;
}
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
//
// FAST ...
int copiedFasts = CopyBuffer(fastHandler, 0, 0, limit, fastBuffer);
//
// MEDIUM ...
int copiedMediumss = CopyBuffer(mediumHandler, 0, 0, limit, mediumBuffer);
//
// SLOW ...
int copiedSlows = CopyBuffer(slowHandler, 0, 0, limit, slowBuffer);
//
// Validate Copied Items ...
bool isPassedRequiredCopiedItems =
//
// FAST ...
copiedFasts >= limit &&
//
// MEDIUM ...
copiedMediumss >= limit &&
//
// SLOW ...
copiedSlows >= limit
//
;
if (!isPassedRequiredCopiedItems)
{
return prev_calculated;
}
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
result =
//
fastLength > 2 &&
mediumLength > 2 &&
slowLength > 2 &&
mediumLength > fastLength &&
mediumLength < slowLength
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(fastLength, mediumLength);
result = MathMax(result, slowLength);
//
return result;
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// Plot Buffers ...
//
// FAST ...
//
ArraySetAsSeries(fastBuffer, true);
SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(fastBufferIndex, PLOT_SHOW_DATA, showFast);
//
PlotIndexSetDouble(fastBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
//
ArraySetAsSeries(fastColorBuffer, true);
SetIndexBuffer(fastColorBufferIndex, fastColorBuffer, INDICATOR_COLOR_INDEX);
//
// MEDIUM ...
//
ArraySetAsSeries(mediumBuffer, true);
SetIndexBuffer(mediumBufferIndex, mediumBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(mediumBufferIndex, PLOT_SHOW_DATA, showMedium);
//
PlotIndexSetDouble(mediumBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
//
ArraySetAsSeries(mediumColorBuffer, true);
SetIndexBuffer(mediumColorBufferIndex, mediumColorBuffer, INDICATOR_COLOR_INDEX);
//
// SLOW ...
//
ArraySetAsSeries(slowBuffer, true);
SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(slowBufferIndex, PLOT_SHOW_DATA, showSlow);
//
PlotIndexSetDouble(slowBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
//
ArraySetAsSeries(slowColorBuffer, true);
SetIndexBuffer(slowColorBufferIndex, slowColorBuffer, INDICATOR_COLOR_INDEX);
//
// Data Buffers ...
//
// FAST State ...
ArraySetAsSeries(fastStateBuffer, true);
SetIndexBuffer(fastStateBufferIndex, fastStateBuffer, INDICATOR_CALCULATIONS);
//
// MEDIUM State ...
ArraySetAsSeries(mediumStateBuffer, true);
SetIndexBuffer(mediumStateBufferIndex, mediumStateBuffer, INDICATOR_CALCULATIONS);
//
// SLOW State ...
ArraySetAsSeries(slowStateBuffer, true);
SetIndexBuffer(slowStateBufferIndex, slowStateBuffer, INDICATOR_CALCULATIONS);
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
//
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Calculate Custom Buffers ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
int barsLimit = startCalculationForLastBars > 0
? startCalculationForLastBars
: 0;
//
// bool canCalculate = true;
bool canCalculate =
barsLimit == 0 ||
bar_index <= barsLimit;
if (canCalculate)
{
//
// Calculate Values ...
CalculateValues(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
}
else
{
FillBuffersZero(bar_index);
}
}
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
// FAST ...
fastBuffer[barIndex] = emptyValue;
fastColorBuffer[barIndex] = hideColorIDX;
fastStateBuffer[barIndex] = neuturalState;
//
// MEDIUM ...
mediumBuffer[barIndex] = emptyValue;
mediumColorBuffer[barIndex] = hideColorIDX;
mediumStateBuffer[barIndex] = neuturalState;
//
// SLOW ...
slowBuffer[barIndex] = emptyValue;
slowColorBuffer[barIndex] = hideColorIDX;
slowStateBuffer[barIndex] = neuturalState;
}
/**
* Calculate Values ...
*
* @param bar_index: int, Specified Bar Index ...
* @param prevCalculated: int, Provides Previous Calculated Bars ...
* @param ratesTotal: int, Provides All Availabled Bars ...
* @param open: double Collection, Provides Open Prices Time Series ...
* @param high: double Collection, Provides High Prices Time Series ...
* @param close: double Collection, Provides Close Prices Time Series ...
* @param low: double Collection, Provides Low Prices Time Series ...
* @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ...
*/
void CalculateValues(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Check Prev Bar ...
//
int lastBarIndex = bar_index + 1;
bool isFirstBar =
startCalculationForLastBars > 0
? bar_index == startCalculationForLastBars
: bar_index == ratesTotal;
//
double iLow = low[bar_index];
double iHigh = high[bar_index];
double iClose = close[bar_index];
//
// FAST ...
//
double iFast = fastBuffer[bar_index];
//
double iFastState =
iLow > iFast
? bullishState
: iHigh < iFast
? bearishState
: neuturalState;
double iFastColor = hideColorIDX;
if (showFast)
{
//
if (applyColor)
{
//
iFastColor =
iFastState == bullishState
? bullishColorIDX
: iFastState == bearishState
? bearishColorIDX
: neuturalColorIDX;
}
else
{
iFastColor = bullishColorIDX;
}
}
fastColorBuffer[bar_index] = iFastColor;
fastStateBuffer[bar_index] = iFastState;
//
// MEDIUM ...
//
double iMedium = mediumBuffer[bar_index];
//
double iMediumState =
iLow > iMedium
? bullishState
: iHigh < iMedium
? bearishState
: neuturalState;
double iMediumColor = hideColorIDX;
if (showMedium)
{
//
if (applyColor)
{
//
iMediumColor =
iMediumState == bullishState
? bullishColorIDX
: iMediumState == bearishState
? bearishColorIDX
: neuturalColorIDX;
}
else
{
iMediumColor = bullishColorIDX;
}
}
mediumColorBuffer[bar_index] = iMediumColor;
mediumStateBuffer[bar_index] = iMediumState;
//
// SLOW ...
//
double iSlow = slowBuffer[bar_index];
//
double iSlowState =
iLow > iSlow
? bullishState
: iHigh < iSlow
? bearishState
: neuturalState;
double iSlowColor = hideColorIDX;
if (showSlow)
{
//
if (applyColor)
{
//
iSlowColor =
iSlowState == bullishState
? bullishColorIDX
: iSlowState == bearishState
? bearishColorIDX
: neuturalColorIDX;
}
else
{
iSlowColor = bullishColorIDX;
}
}
slowColorBuffer[bar_index] = iSlowColor;
slowStateBuffer[bar_index] = iSlowState;
}
//
@@ -0,0 +1,882 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121 XATR
// Description: XATR ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XATR Indicator"
#property strict
//
// Definitions ...
//
#define ShortName "X121 XATR"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
//
input group "RSI Detection";
input int rsiLength = 14; // Length
input ENUM_X_PRICE rsiPriceType = X_PRICE_CLOSE; // Applied To
input ENUM_X_MA_METHOD rsiSmoothingMethod = X_MA_MODE_SMA; // Smoothing Method;
//
input group "ATR Detection";
input int atrLength = 14; // Length
input double atrMultiplier = 1; // Multiplier
input ENUM_X_PRICE atrUpperPriceType = X_PRICE_HIGH; // Upper Zone Applied To
input ENUM_X_PRICE atrLowerPriceType = X_PRICE_LOW; // Lower Zone Applied To
input ENUM_X_MA_METHOD atrSmoothingMethod = X_MA_MODE_SMA; // Smoothing Method
//
input group "Price Change";
input int priceChangeSmoothingLength = 14; // Length
input ENUM_X_PRICE priceChangeType = X_PRICE_CLOSE; // Price Type
input ENUM_X_MA_METHOD priceChangeSmoothingMethod = X_MA_MODE_SMA; // Moving Average Moethod
//
input group "Presentation";
//
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
//
input bool showAtrUpper = true; // Show Upper Zone
input bool showAtrLower = true; // Show Lower Zone
input bool showSmoothedAtrUpper = true; // Show Smoothed Upper Zone
input bool showSmoothedAtrLower = true; // Show Smoothed Lower Zone
input bool showRSIChange = true; // Show RSI Change
input bool showSmoothedRSIChange = true; // ShowSmoothed RSI Change
input bool showPriceChange = true; // Show Price Change
input bool showSmoothedPriceChange = true; // ShowSmoothed Price Change
//
// Buffers ...
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
#property indicator_chart_window
//
#property indicator_buffers 10
#property indicator_plots 8
//
// ATR ...
//
// Upper ...
//
#define atrUpperBufferIndex 0
double atrUpperBuffer[];
#property indicator_label1 "X121 ATRU"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrYellow
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//
// Lower ...
//
#define atrLowerBufferIndex 1
double atrLowerBuffer[];
#property indicator_label2 "X121 ATRL"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrYellow
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//
// ATR Smoothed ...
//
// Upper ...
//
#define atrSmoothedUpperBufferIndex 2
double atrSmoothedUpperBuffer[];
#property indicator_label3 "X121 ATRUSM"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrYellow
#property indicator_style3 STYLE_DASH
#property indicator_width3 1
//
// Lower ...
//
#define atrSmoothedLowerBufferIndex 3
double atrSmoothedLowerBuffer[];
#property indicator_label4 "X121 ATRLSM"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrYellow
#property indicator_style4 STYLE_DASH
#property indicator_width4 1
//
// Price Change ...
//
#define priceChangeBufferIndex 4
double priceChangeBuffer[];
#property indicator_label5 "X121 PCH"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrOrchid
#property indicator_style5 STYLE_SOLID
#property indicator_width5 1
//
// Price Change Smoothed ...
//
#define priceChangeSmoothedBufferIndex 5
double priceChangeSmoothedBuffer[];
#property indicator_label6 "X121 PCHSM"
#property indicator_type6 DRAW_LINE
#property indicator_color6 clrOrchid
#property indicator_style6 STYLE_SOLID
#property indicator_width6 1
//
// RSI Change ...
//
#define rsiChangeBufferIndex 6
double rsiChangeBuffer[];
#property indicator_label7 "X121 RSICH"
#property indicator_type7 DRAW_LINE
#property indicator_color7 clrCornflowerBlue
#property indicator_style7 STYLE_SOLID
#property indicator_width7 1
//
// RSI Change Smoothed ...
//
#define rsiChangeSmoothedBufferIndex 7
double rsiChangeSmoothedBuffer[];
#property indicator_label8 "X121 RSICHSM"
#property indicator_type8 DRAW_LINE
#property indicator_color8 clrCornflowerBlue
#property indicator_style8 STYLE_SOLID
#property indicator_width8 1
//
// Data Buffers ...
//
int mLastBufferIndex = 7;
//
// ATR ...
#define atrBufferIndex mLastBufferIndex + 1
double atrBuffer[];
//
// RSI ...
#define rsiBufferIndex mLastBufferIndex + 2
double rsiBuffer[];
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
// RSI Handler ...
int rsiHandler = INVALID_HANDLE;
//
// ATR Handler ...
int atrHandler = INVALID_HANDLE;
//
ENUM_APPLIED_PRICE rsiAppliedTo = ToAppliedPrice(rsiPriceType);
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Indicator Handlers ...
//
// RSI ...
rsiHandler = iRSI(
_Symbol,
_Period,
rsiLength,
rsiAppliedTo //
);
bool isInited = rsiHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// ATR ...
atrHandler = iATR(
_Symbol,
_Period,
atrLength //
);
isInited = atrHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
IndicatorRelease(rsiHandler);
IndicatorRelease(atrHandler);
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
// Fill All Buffers by Zero ...
if (prev_calculated == 0)
{
}
//
// Validate Calculated Bars ...
//
// RSI ...
int rsiCalculatedBars = BarsCalculated(rsiHandler);
//
// ATR ...
int atrCalculatedBars = BarsCalculated(atrHandler);
//
bool isPassedRequiredCalculatedBars =
//
// RSI ...
rsiCalculatedBars >= maxLength &&
//
// ATR ...
atrCalculatedBars >= maxLength
//
;
if (!isPassedRequiredCalculatedBars)
{
return prev_calculated;
}
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
//
// RSI ...
int copiedRsis = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer);
//
// ATR ...
int copiedAtrs = CopyBuffer(atrHandler, 0, 0, limit, atrBuffer);
//
// Validate Copied Items ...
bool isPassedRequiredCopiedItems =
//
//
// RSI ...
copiedRsis > 0 &&
//
// ATR ...
copiedAtrs > 0
//
;
if (!isPassedRequiredCopiedItems)
{
return prev_calculated;
}
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result =
//
// RSI ...
rsiLength > 0 &&
//
// ATR ...
atrLength > 0 &&
atrMultiplier > 0 &&
//
priceChangeSmoothingLength > 0 &&
//
IsValid(rsiPriceType) &&
IsValid(priceChangeType) &&
IsValid(atrUpperPriceType) &&
IsValid(atrLowerPriceType)
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(rsiLength, atrLength);
result = MathMax(result, priceChangeSmoothingLength);
//
return result;
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// ATR ...
//
// UPPER ...
ENUM_DRAW_TYPE atrUpperDrawType = showAtrUpper ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(atrUpperBuffer, true);
SetIndexBuffer(atrUpperBufferIndex, atrUpperBuffer, INDICATOR_DATA);
PlotIndexSetDouble(atrUpperBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(atrUpperBufferIndex, PLOT_SHOW_DATA, showAtrUpper);
PlotIndexSetInteger(atrUpperBufferIndex, PLOT_DRAW_TYPE, atrUpperDrawType);
//
// LOWER ...
ENUM_DRAW_TYPE atrLowerDrawType = showAtrLower ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(atrLowerBuffer, true);
SetIndexBuffer(atrLowerBufferIndex, atrLowerBuffer, INDICATOR_DATA);
PlotIndexSetDouble(atrLowerBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(atrLowerBufferIndex, PLOT_SHOW_DATA, showAtrLower);
PlotIndexSetInteger(atrLowerBufferIndex, PLOT_DRAW_TYPE, atrLowerDrawType);
//
// ATR Smoothed ...
//
// UPPER ...
ENUM_DRAW_TYPE atrSmoothedUpperDrawType = showSmoothedAtrUpper ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(atrSmoothedUpperBuffer, true);
SetIndexBuffer(atrSmoothedUpperBufferIndex, atrSmoothedUpperBuffer, INDICATOR_DATA);
PlotIndexSetDouble(atrSmoothedUpperBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(atrSmoothedUpperBufferIndex, PLOT_SHOW_DATA, showSmoothedAtrUpper);
PlotIndexSetInteger(atrSmoothedUpperBufferIndex, PLOT_DRAW_TYPE, atrSmoothedUpperDrawType);
//
// LOWER ...
ENUM_DRAW_TYPE atrSmoothedLowerDrawType = showSmoothedAtrLower ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(atrSmoothedLowerBuffer, true);
SetIndexBuffer(atrSmoothedLowerBufferIndex, atrSmoothedLowerBuffer, INDICATOR_DATA);
PlotIndexSetDouble(atrSmoothedLowerBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(atrSmoothedLowerBufferIndex, PLOT_SHOW_DATA, showSmoothedAtrLower);
PlotIndexSetInteger(atrSmoothedLowerBufferIndex, PLOT_DRAW_TYPE, atrSmoothedLowerDrawType);
//
// PriceChange ...
ENUM_DRAW_TYPE priceChangeDrawType = showPriceChange ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(priceChangeBuffer, true);
SetIndexBuffer(priceChangeBufferIndex, priceChangeBuffer, INDICATOR_DATA);
PlotIndexSetDouble(priceChangeBufferIndex, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetInteger(priceChangeBufferIndex, PLOT_SHOW_DATA, showPriceChange);
PlotIndexSetInteger(priceChangeBufferIndex, PLOT_DRAW_TYPE, priceChangeDrawType);
//
// PriceChange Smoothed ...
ENUM_DRAW_TYPE priceChangeSmoothedaDrawType = showSmoothedPriceChange ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(priceChangeSmoothedBuffer, true);
SetIndexBuffer(priceChangeSmoothedBufferIndex, priceChangeSmoothedBuffer, INDICATOR_DATA);
PlotIndexSetDouble(priceChangeSmoothedBufferIndex, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetInteger(priceChangeSmoothedBufferIndex, PLOT_SHOW_DATA, showSmoothedPriceChange);
PlotIndexSetInteger(priceChangeSmoothedBufferIndex, PLOT_DRAW_TYPE, priceChangeSmoothedaDrawType);
//
// RSIChange ...
ENUM_DRAW_TYPE rsiChangeDrawType = showRSIChange ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(rsiChangeBuffer, true);
SetIndexBuffer(rsiChangeBufferIndex, rsiChangeBuffer, INDICATOR_DATA);
PlotIndexSetDouble(rsiChangeBufferIndex, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetInteger(rsiChangeBufferIndex, PLOT_SHOW_DATA, showRSIChange);
PlotIndexSetInteger(rsiChangeBufferIndex, PLOT_DRAW_TYPE, rsiChangeDrawType);
//
// RSIChangeMa ...
ENUM_DRAW_TYPE rsiChangeMaDrawType = showSmoothedRSIChange ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(rsiChangeSmoothedBuffer, true);
SetIndexBuffer(rsiChangeSmoothedBufferIndex, rsiChangeSmoothedBuffer, INDICATOR_DATA);
PlotIndexSetDouble(rsiChangeSmoothedBufferIndex, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetInteger(rsiChangeSmoothedBufferIndex, PLOT_SHOW_DATA, showSmoothedRSIChange);
PlotIndexSetInteger(rsiChangeSmoothedBufferIndex, PLOT_DRAW_TYPE, rsiChangeMaDrawType);
//
// Data Buffers ...
//
// ATR ...
ArraySetAsSeries(atrBuffer, true);
SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS);
//
// RSI ...
ArraySetAsSeries(rsiBuffer, true);
SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS);
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
//
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
IndicatorSetInteger(INDICATOR_DIGITS, 2);
}
/**
* Calculate Custom Buffers ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
int barsLimit = startCalculationForLastBars > 0
? startCalculationForLastBars
: 0;
//
// bool canCalculate = true;
bool canCalculate =
barsLimit == 0 ||
bar_index <= barsLimit;
if (canCalculate)
{
//
CalculateAtrZones(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low //
);
}
else
{
FillBuffersZero(bar_index);
}
}
//
// Custom ...
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
rsiBuffer[barIndex] = 0;
atrBuffer[barIndex] = 0;
atrUpperBuffer[barIndex] = 0;
atrLowerBuffer[barIndex] = 0;
rsiChangeBuffer[barIndex] = 0;
priceChangeBuffer[barIndex] = 0;
atrSmoothedUpperBuffer[barIndex] = 0;
atrSmoothedLowerBuffer[barIndex] = 0;
rsiChangeSmoothedBuffer[barIndex] = 0;
priceChangeSmoothedBuffer[barIndex] = 0;
}
/**
* Calculate ATR Zones ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
*/
void CalculateAtrZones(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[] //
)
{
//
double points = GetPoints(_Symbol);
//
// ATR Calculations ...
double iAtr = atrBuffer[bar_index];
double iMultiPliedAtr = iAtr * atrMultiplier;
//
// Select Upper Price ...
double iUpperPrice = GetAppliedPrice(
atrUpperPriceType,
open,
high,
low,
close,
bar_index //
);
//
// Select Lower Price ...
double iLowerPrice = GetAppliedPrice(
atrLowerPriceType,
open,
high,
low,
close,
bar_index //
);
//
// Calculate Atrs ...
//
double iAtrUpper = iUpperPrice + iMultiPliedAtr;
double iAtrLower = iLowerPrice - iMultiPliedAtr;
//
atrUpperBuffer[bar_index] = iAtrUpper;
atrLowerBuffer[bar_index] = iAtrLower;
//
bool canSmoothAtr = atrSmoothingMethod != X_MA_MODE_NONE;
if (canSmoothAtr)
{
//
// Upper ...
iMAOnBuffer(
ratesTotal,
prevCalculated,
bar_index,
atrLength,
atrUpperBuffer,
atrSmoothedUpperBuffer,
atrSmoothingMethod //
);
//
// Lower ...
iMAOnBuffer(
ratesTotal,
prevCalculated,
bar_index,
atrLength,
atrLowerBuffer,
atrSmoothedLowerBuffer,
atrSmoothingMethod //
);
}
else
{
//
atrSmoothedUpperBuffer[bar_index] = iAtrUpper;
atrSmoothedLowerBuffer[bar_index] = iAtrLower;
}
//
// RSI Change Calculations ...
//
double iRsi = rsiBuffer[bar_index];
double iRsiP = rsiBuffer[bar_index + 1];
double iRsiPrice = GetAppliedPrice(
rsiPriceType,
open,
high,
low,
close,
bar_index //
);
//
double iRsiChanged = iRsi - iRsiP;
double iRsiPointsChanged = iRsiChanged / points;
//
double iRChange = iRsiPrice + (iRsiChanged * points);
rsiChangeBuffer[bar_index] = iRChange;
//
bool canSmoothRsi = rsiSmoothingMethod != X_MA_MODE_NONE;
if (canSmoothRsi)
{
//
// Upper ...
iMAOnBuffer(
ratesTotal,
prevCalculated,
bar_index,
atrLength,
rsiChangeBuffer,
rsiChangeSmoothedBuffer,
rsiSmoothingMethod //
);
}
else
{
rsiChangeSmoothedBuffer[bar_index] = iRChange;
}
//
// PRICE Change Calculation ...
//
double iPChangePrice = GetAppliedPrice(
priceChangeType,
open,
high,
low,
close,
bar_index //
);
double iPPChangePrice = GetAppliedPrice(
priceChangeType,
open,
high,
low,
close,
bar_index + 1 //
);
//
double iPriceChange = iPChangePrice - iPPChangePrice;
double iPricePointsChanged = iPriceChange / points;
double iVolatilityChange = iPriceChange / iAtr;
//
double iPChange = iPChangePrice + (iPricePointsChanged * points);
priceChangeBuffer[bar_index] = iPChange;
//
bool canSmoothPriceChange = priceChangeSmoothingMethod != X_MA_MODE_NONE;
if (canSmoothPriceChange)
{
//
// Upper ...
iMAOnBuffer(
ratesTotal,
prevCalculated,
bar_index,
atrLength,
priceChangeBuffer,
priceChangeSmoothedBuffer,
priceChangeSmoothingMethod //
);
}
else
{
priceChangeSmoothedBuffer[bar_index] = iPChange;
}
}
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,437 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Candle Styles
// ---------------------------------------------------
// Name: X121 XCC
// Description: Candle Styles ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XCC Indicator"
#property strict
//
// START Constants ...
//
//
// Indicator Short Name ...
#define ShortName "X121 XCC"
//
// Holds an SnapShot of Charts Configuration ...
struct XChartStyle
{
//
// chart's ID ...
long chartId;
//
// chart's mode ...
ENUM_CHART_MODE mode;
//
// show bid line ...
bool showBidLine;
//
// show ask line ...
bool showAskLine;
//
// show grids on chart ...
bool showGrid;
//
// show volumes ...
bool showVolumes;
//
// Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) ...
bool showTradeLevels;
//
// chart autoscroll ...
bool autoScroll;
//
// chart quick navigation state ...
bool quickNavigation;
//
// chart's foreground color ...
color foreGroundColor;
//
// chart's background color ...
color backGroundColor;
//
// Up Color ...
color upColor;
//
// Down Color ...
color downColor;
//
// Bullish color ...
color bullishColor;
//
// Bearish color ...
color bearishColor;
//
// grid color ...
color gridColor;
//
// bid line color ...
color bidLineColor;
//
// ask line color ...
color askLineColor;
//
// line mode and doji candlestick color ...
color lineColor;
//
// Color of stop order levels (Stop Loss and Take Profit) ...
color stopColor;
//
// volumes color ...
color volumesColor;
};
//
// END Constants ...
//
//
// START Inputs ...
//
//
input group "Chart Style";
input ENUM_CHART_MODE mode = CHART_CANDLES; // Mode
input color upColor = clrGreen; // Up Color
input color downColor = clrRed; // Down Color
input color lineColor = clrGreen; // Line mode and Doji candlestick Color
input color bullishColor = clrGreen; // Bullish Color
input color bearishColor = clrRed; // Bearish Color
input color volumesColor = clrGreen; // Volumes Color
//
input group "Presentation";
input bool showCandles = true; // Show Candles
//
// END Inputs ...
//
//
// START Includes and Imports ...
//
//
// Includes Draw Library ...
#include "../Libraries/x-saherelm.draw.lib.mq5"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Includes and Imports ...
//
//
// START Buffers ...
//
//
#property indicator_chart_window
//
#property indicator_buffers 0
#property indicator_plots 0
//
// END Buffers ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
int maxLength;
//
XChartStyle chartStyle;
XChartStyle clearStyle;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Event Handlers ...
//
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
drawPrefix = ShortName;
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Apply Chart Style ...
ApplyCustomChartStyle();
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
}
//
// Calculating what we want ...
int OnCalculate(
const int rates_total, // Total Bars on Chart ...
const int prev_calculated, // Total Calculated Bars on Charts ...
const datetime &time[], // History of Open Time ...
const double &open[], // History of Open Price ...
const double &high[], // History of High Price ...
const double &low[], // History of Low Price ...
const double &close[], // History of Close Price ...
const long &tick_volume[], // History of Tick Volumes on Bar ...
const long &volume[], // History of Trade Volumes ...
const int &spread[] // History of Spread Price ...
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
// this counts Available Bars ...
int limit;
//
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
CalculateBuffers(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result = true;
//
return result;
}
//
// Retrieve all Exists Input Max Length ...
// use for Start Of Drawing ...
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
return result;
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
//
// Calculate Buffers ...
void CalculateBuffers(
int bar_index // Selected Bar Index
)
{
}
//
// Apply Custom Chart Style ...
void ApplyCustomChartStyle()
{
//
// Read Current Chart Config and Store it ...
ReadChartStyle();
//
// After Reading Current Chart Style ...
// we have to Save Configs and Change Styles ...
clearStyle = chartStyle;
//
clearStyle.upColor = CLR_NONE;
clearStyle.downColor = CLR_NONE;
clearStyle.lineColor = CLR_NONE;
clearStyle.bullishColor = CLR_NONE;
clearStyle.bearishColor = CLR_NONE;
//
// Decide to Show or not Candles based on User Input ...
if (showCandles)
{
SetChartStyle(chartStyle);
}
else
{
SetChartStyle(clearStyle);
}
}
//
// Read Previous Chart Style ...
void ReadChartStyle()
{
//
// Retrieve Current Chart ID ...
long chartId = ChartID();
chartStyle.chartId = chartId;
//
// Retrieve Chart Mode ...
chartStyle.mode = (ENUM_CHART_MODE)ChartGetInteger(chartId, CHART_MODE);
//
chartStyle.showBidLine = (bool)ChartGetInteger(chartId, CHART_SHOW_BID_LINE);
chartStyle.showAskLine = (bool)ChartGetInteger(chartId, CHART_SHOW_ASK_LINE);
chartStyle.showGrid = (bool)ChartGetInteger(chartId, CHART_SHOW_GRID);
chartStyle.showVolumes = (bool)ChartGetInteger(chartId, CHART_SHOW_VOLUMES);
chartStyle.showTradeLevels = (bool)ChartGetInteger(chartId, CHART_SHOW_TRADE_LEVELS);
chartStyle.autoScroll = (bool)ChartGetInteger(chartId, CHART_AUTOSCROLL);
chartStyle.quickNavigation = (bool)ChartGetInteger(chartId, CHART_QUICK_NAVIGATION);
//
chartStyle.foreGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_FOREGROUND);
chartStyle.backGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_BACKGROUND);
chartStyle.upColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_UP);
chartStyle.downColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_DOWN);
chartStyle.bullishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BULL);
chartStyle.bearishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BEAR);
chartStyle.gridColor = (color)ChartGetInteger(chartId, CHART_COLOR_GRID);
chartStyle.bidLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_BID);
chartStyle.askLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_ASK);
chartStyle.stopColor = (color)ChartGetInteger(chartId, CHART_COLOR_STOP_LEVEL);
chartStyle.lineColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_LINE);
chartStyle.volumesColor = (color)ChartGetInteger(chartId, CHART_COLOR_VOLUME);
//
chartStyle.mode = mode;
chartStyle.upColor = upColor;
chartStyle.downColor = downColor;
chartStyle.lineColor = lineColor;
chartStyle.bearishColor = bearishColor;
chartStyle.bullishColor = bullishColor;
chartStyle.volumesColor = volumesColor;
}
//
// Set Chart Style ...
void SetChartStyle(
XChartStyle &mChartStyle // Chart Style to Apply
)
{
//
ApplyChartStyle(
mChartStyle.chartId,
mChartStyle.mode,
mChartStyle.showBidLine,
mChartStyle.showAskLine,
mChartStyle.showGrid,
mChartStyle.showVolumes,
mChartStyle.showTradeLevels,
mChartStyle.autoScroll,
mChartStyle.quickNavigation,
mChartStyle.foreGroundColor,
mChartStyle.backGroundColor,
mChartStyle.upColor,
mChartStyle.downColor,
mChartStyle.bullishColor,
mChartStyle.bearishColor,
mChartStyle.gridColor,
mChartStyle.bidLineColor,
mChartStyle.askLineColor,
mChartStyle.lineColor,
mChartStyle.stopColor,
mChartStyle.volumesColor);
}
//
// END Functions ...
//
@@ -0,0 +1,624 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121 XCHE
// Description: XCHE ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XCHE Indicator"
#property strict
//
// Definitions ...
//
#define ShortName "X121 XCHE"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
input int cheLength = 35; // Length
input int cheLoopback = 26; // Loopback
input double cheMultiplier1 = 3.0; // 1st Multiplier
input double cheMultiplier2 = 3.5; // 2nd Multiplier
input ENUM_APPLIED_PRICE cheUpperAppliedTo = PRICE_HIGH; // Upper Zone Applied to
input ENUM_APPLIED_PRICE cheLowerAppliedTo = PRICE_LOW; // Lower Zone Applied to
//
input group "Presentation";
//
input int cheArrowCode = 159; // CHE Arrow Code
//
input bool showLE1 = true; // Show 1st Long Exit
input bool showSE1 = true; // Show 1st Short Exit
input bool showLE2 = true; // Show 2st Long Exit
input bool showSE2 = true; // Show 2st Short Exit
//
// Buffers ...
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
#property indicator_chart_window
//
#property indicator_buffers 8
#property indicator_plots 8
//
// Exit 1 ...
//
// LONG ...
//
#define le1BufferIndex 0
double le1Buffer[];
#property indicator_label1 "X121 LE1"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrAqua
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//
// SHORT ...
//
#define se1BufferIndex 1
double se1Buffer[];
#property indicator_label2 "X121 SE1"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrMagenta
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
// Exit 2 ...
//
// LONG ...
//
#define le2BufferIndex 2
double le2Buffer[];
#property indicator_label3 "X121 LE2"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrAqua
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//
// SHORT ...
//
#define se2BufferIndex 3
double se2Buffer[];
#property indicator_label4 "X121 SE2"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrMagenta
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
//
// Start Buffers ...
//
#define le1StartBufferIndex 4
double le1StartBuffer[];
//
#property indicator_label5 "X121 LE1 S"
#property indicator_type5 DRAW_ARROW
#property indicator_color5 clrLime
//
#define se1StartBufferIndex 5
double se1StartBuffer[];
//
#property indicator_label6 "X121 SE1 S"
#property indicator_type6 DRAW_ARROW
#property indicator_color6 clrRed
//
#define le2StartBufferIndex 6
double le2StartBuffer[];
//
#property indicator_label7 "X121 LE2 S"
#property indicator_type7 DRAW_ARROW
#property indicator_color7 clrLime
//
#define se2StartBufferIndex 7
double se2StartBuffer[];
//
#property indicator_label8 "X121 SE2 S"
#property indicator_type8 DRAW_ARROW
#property indicator_color8 clrRed
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
// Working Array ...
double work[][6];
#define hi1Idx 0
#define lo1Idx 1
#define hi2Idx 2
#define lo2Idx 3
#define trend1Idx 4
#define trend2Idx 5
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input cheLength, here we get max Input cheLength
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
if (Bars(_Symbol, _Period) < rates_total)
{
return (prev_calculated);
}
//
if (ArrayRange(work, 0) != rates_total)
{
ArrayResize(work, rates_total);
}
//
// this counts Available Bars ...
//
limit = prev_calculated - 1;
if (limit < 0)
{
limit = 0;
}
//
// Main Loop ...
for (int i = limit; i < rates_total && !IsStopped(); i++)
{
CalculateBuffers(
i,
prev_calculated,
rates_total,
//
open,
high,
low,
close);
}
//
return rates_total;
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = true;
//
result =
cheLength >= 9 &&
cheLoopback >= 0;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(cheLength, cheLoopback);
//
return result;
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// LEVEL 1 ...
//
// Long Exit 1 ...
//
// Draw Type ...
ENUM_DRAW_TYPE le1DrawType = showLE1 ? DRAW_LINE : DRAW_NONE;
ENUM_DRAW_TYPE le1StartDrawType = showLE1 ? DRAW_ARROW : DRAW_NONE;
//
// Buffer ...
SetIndexBuffer(le1BufferIndex, le1Buffer, INDICATOR_DATA);
PlotIndexSetInteger(le1BufferIndex, PLOT_SHOW_DATA, showLE1);
PlotIndexSetInteger(le1BufferIndex, PLOT_DRAW_TYPE, le1DrawType);
//
// Start Buffer ...
SetIndexBuffer(le1StartBufferIndex, le1StartBuffer, INDICATOR_DATA);
PlotIndexSetInteger(le1StartBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(le1StartBufferIndex, PLOT_DRAW_TYPE, le1StartDrawType);
PlotIndexSetInteger(le1StartBufferIndex, PLOT_ARROW, cheArrowCode);
//
// Short Exit 1 ...
//
// Draw Type ...
ENUM_DRAW_TYPE se1DrawType = showSE1 ? DRAW_LINE : DRAW_NONE;
ENUM_DRAW_TYPE se1StartDrawType = showSE1 ? DRAW_ARROW : DRAW_NONE;
//
// Buffer ...
SetIndexBuffer(se1BufferIndex, se1Buffer, INDICATOR_DATA);
PlotIndexSetInteger(se1BufferIndex, PLOT_SHOW_DATA, showSE1);
PlotIndexSetInteger(se1BufferIndex, PLOT_DRAW_TYPE, se1DrawType);
//
// Start Buffer ...
SetIndexBuffer(se1StartBufferIndex, se1StartBuffer, INDICATOR_DATA);
PlotIndexSetInteger(se1StartBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(se1StartBufferIndex, PLOT_DRAW_TYPE, se1StartDrawType);
PlotIndexSetInteger(se1StartBufferIndex, PLOT_ARROW, cheArrowCode);
//
// LEVEL 2 ...
//
// Long Exit 2 ...
//
// Draw Type ...
ENUM_DRAW_TYPE le2DrawType = showLE2 ? DRAW_LINE : DRAW_NONE;
ENUM_DRAW_TYPE le2StartDrawType = showLE2 ? DRAW_ARROW : DRAW_NONE;
//
// Buffer ...
SetIndexBuffer(le2BufferIndex, le2Buffer, INDICATOR_DATA);
PlotIndexSetInteger(le2BufferIndex, PLOT_SHOW_DATA, showLE2);
PlotIndexSetInteger(le2BufferIndex, PLOT_DRAW_TYPE, le2DrawType);
//
// Start Buffer ...
SetIndexBuffer(le2StartBufferIndex, le2StartBuffer, INDICATOR_DATA);
PlotIndexSetInteger(le2StartBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(le2StartBufferIndex, PLOT_DRAW_TYPE, le2StartDrawType);
PlotIndexSetInteger(le2StartBufferIndex, PLOT_ARROW, cheArrowCode);
//
// Short Exit 2 ...
//
// Draw Type ...
ENUM_DRAW_TYPE se2DrawType = showSE2 ? DRAW_LINE : DRAW_NONE;
ENUM_DRAW_TYPE se2StartDrawType = showSE2 ? DRAW_ARROW : DRAW_NONE;
//
// Buffer ...
SetIndexBuffer(se2BufferIndex, se2Buffer, INDICATOR_DATA);
PlotIndexSetInteger(se2BufferIndex, PLOT_SHOW_DATA, showSE2);
PlotIndexSetInteger(se2BufferIndex, PLOT_DRAW_TYPE, se2DrawType);
//
// Start Buffer ...
SetIndexBuffer(se2StartBufferIndex, se2StartBuffer, INDICATOR_DATA);
PlotIndexSetInteger(se2StartBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(se2StartBufferIndex, PLOT_DRAW_TYPE, se2StartDrawType);
PlotIndexSetInteger(se2StartBufferIndex, PLOT_ARROW, cheArrowCode);
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Calculate Buffers ...
*/
void CalculateBuffers(
int bar_index, // Selected Bar Index
int prevCalculated, // Previous Calculated
int ratesTotal, // Total Rates
const double &open[], // Rates Open ...
const double &high[], // Rates High ...
const double &low[], // Rates Low ...
const double &close[] // Rates Close ...
)
{
//
// Cleanup Buffers ...
le1Buffer[bar_index] = le1StartBuffer[bar_index] = se1Buffer[bar_index] = se1StartBuffer[bar_index] = EMPTY_VALUE;
le2Buffer[bar_index] = le2StartBuffer[bar_index] = se2Buffer[bar_index] = se2StartBuffer[bar_index] = EMPTY_VALUE;
//
int start = MathMax(bar_index - cheLoopback, 0);
//
// Calculate ATR Value ...
double atrValue = 0;
for (int k = 1; k <= cheLength && (bar_index - k - 1) >= 0; k++)
{
//
atrValue += MathMax(high[bar_index - k], close[MathMax(bar_index - k - 1, 0)]) -
MathMin(low[bar_index - k], close[MathMax(bar_index - k - 1, 0)]);
}
atrValue /= (double)cheLength;
//
// Retrieve Highest High and Lowest Lows ...
double cheLoopbackMax = high[ArrayMaximum(high, start, cheLoopback)];
double cheLoopbackMin = low[ArrayMinimum(low, start, cheLoopback)];
//
// Fill Multi Dimesional Working Array ...
work[bar_index][hi1Idx] = cheLoopbackMax - cheMultiplier1 * atrValue;
work[bar_index][lo1Idx] = cheLoopbackMin + cheMultiplier1 * atrValue;
work[bar_index][hi2Idx] = cheLoopbackMax - cheMultiplier2 * atrValue;
work[bar_index][lo2Idx] = cheLoopbackMin + cheMultiplier2 * atrValue;
work[bar_index][trend1Idx] = (bar_index > 0) ? work[bar_index - 1][trend1Idx] : 0;
work[bar_index][trend2Idx] = (bar_index > 0) ? work[bar_index - 1][trend2Idx] : 0;
//
if (bar_index > 0)
{
//
// Calculate Trends ...
if (close[bar_index] > work[bar_index - 1][lo1Idx])
{
work[bar_index][trend1Idx] = 1;
}
//
if (close[bar_index] < work[bar_index - 1][hi1Idx])
{
work[bar_index][trend1Idx] = -1;
}
//
if (close[bar_index] > work[bar_index - 1][lo2Idx])
{
work[bar_index][trend2Idx] = 1;
}
//
if (close[bar_index] < work[bar_index - 1][hi2Idx])
{
work[bar_index][trend2Idx] = -1;
}
//
// Calculate Exit Values ...
//
// Exit 1 ...
//
// Long ...
if (cheMultiplier1 > 0 && work[bar_index][trend1Idx] == 1)
{
//
if (work[bar_index][hi1Idx] < work[bar_index - 1][hi1Idx])
{
work[bar_index][hi1Idx] = work[bar_index - 1][hi1Idx];
}
//
le1Buffer[bar_index] = work[bar_index][hi1Idx];
//
if (le1Buffer[bar_index - 1] == EMPTY_VALUE)
{
le1StartBuffer[bar_index] = le1Buffer[bar_index];
}
}
//
// Short ...
if (cheMultiplier1 > 0 && work[bar_index][trend1Idx] == -1)
{
//
if (work[bar_index][lo1Idx] > work[bar_index - 1][lo1Idx])
{
work[bar_index][lo1Idx] = work[bar_index - 1][lo1Idx];
}
//
se1Buffer[bar_index] = work[bar_index][lo1Idx];
//
if (se1Buffer[bar_index - 1] == EMPTY_VALUE)
{
se1StartBuffer[bar_index] = se1Buffer[bar_index];
}
}
//
// Exit 2 ...
//
// Long ...
if (cheMultiplier2 > 0 && work[bar_index][trend2Idx] == 1)
{
if (work[bar_index][hi2Idx] < work[bar_index - 1][hi2Idx])
{
work[bar_index][hi2Idx] = work[bar_index - 1][hi2Idx];
}
//
le2Buffer[bar_index] = work[bar_index][hi2Idx];
//
if (le2Buffer[bar_index - 1] == EMPTY_VALUE)
{
le2StartBuffer[bar_index] = le2Buffer[bar_index];
}
}
//
// Short ...
if (cheMultiplier2 > 0 && work[bar_index][trend2Idx] == -1)
{
//
if (work[bar_index][lo2Idx] > work[bar_index - 1][lo2Idx])
{
work[bar_index][lo2Idx] = work[bar_index - 1][lo2Idx];
}
//
se2Buffer[bar_index] = work[bar_index][lo2Idx];
//
if (se2Buffer[bar_index - 1] == EMPTY_VALUE)
{
se2StartBuffer[bar_index] = se2Buffer[bar_index];
}
}
}
}
//
@@ -0,0 +1,262 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// ---------------------------------------------
// Name: X121 XCT
// Description: Trend Magic Indicator ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XCT Indicator"
#property strict
//
// START Constants ...
//
//
#define ShortName "X121 XCT"
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Constants ...
//
//
// START Inputs ...
//
//
input int fontSize = 15; // Font Size
input string font = "Arial"; // Font
input color clr = clrYellow; // Text Color
input ENUM_BASE_CORNER corner = CORNER_RIGHT_LOWER; // Text Position
//
input group "Presentation";
input bool showTimer = true; // Show Candle Time
//
// END Inputs ...
//
//
// START Buffers ...
//
//
#property indicator_chart_window
//
#property indicator_buffers 0
#property indicator_plots 0
//
// END Buffers ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
bool isCreatedObject;
string tag;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Event Handlers ...
//
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs ...
//
tag = ShortName + _Symbol + ToString(_Period);
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
// Delete Object ...
ObjectDelete(0, tag);
//
Comment("");
}
//
// Calculating what we want ...
int OnCalculate(
const int rates_total, // Total Bars on Chart ...
const int prev_calculated, // Total Calculated Bars on Charts ...
const datetime &time[], // History of Open Time ...
const double &open[], // History of Open Price ...
const double &high[], // History of High Price ...
const double &low[], // History of Low Price ...
const double &close[], // History of Close Price ...
const long &tick_volume[], // History of Tick Volumes on Bar ...
const long &volume[], // History of Trade Volumes ...
const int &spread[] // History of Spread Price ...
)
{
//
if (!showTimer)
{
return rates_total;
}
//
XBarRemainsTime barRemains;
barRemains.Init(
_Symbol,
_Period
//
);
//
string msg = barRemains
.ToString(
"",
"",
"",
"",
"",
":",
true
//
);
//
long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD);
//
string _sp = "";
if (mSpread < 10)
_sp = "..";
else if (mSpread < 100)
_sp = ".";
//
string objText = "Spread: " + IntegerToString(mSpread) + _sp + ", Next Bar in: " + msg;
//
if (IsValid(tag) && !isCreatedObject)
{
CreateIndicatorObject();
}
//
if (isCreatedObject)
{
ObjectSetString(0, tag, OBJPROP_TEXT, objText);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
//
void CreateIndicatorObject()
{
//
if (!showTimer ||
!IsValid(tag))
{
return;
}
//
isCreatedObject = ObjectCreate(0, tag, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, tag, OBJPROP_CORNER, corner);
ObjectSetInteger(0, tag, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, tag, OBJPROP_YDISTANCE, 2);
//
ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER;
switch (corner)
{
case CORNER_LEFT_UPPER:
Anchor = ANCHOR_LEFT_UPPER;
break;
case CORNER_RIGHT_UPPER:
Anchor = ANCHOR_RIGHT_UPPER;
break;
case CORNER_LEFT_LOWER:
Anchor = ANCHOR_LEFT_LOWER;
break;
case CORNER_RIGHT_LOWER:
Anchor = ANCHOR_RIGHT_LOWER;
break;
}
//
int mFontSize = fontSize > 0
? fontSize
: 10;
//
string mFont = IsValid(font)
? font
: "Arial";
//
ObjectSetString(0, tag, OBJPROP_FONT, mFont);
ObjectSetInteger(0, tag, OBJPROP_COLOR, clr);
ObjectSetInteger(0, tag, OBJPROP_ANCHOR, Anchor);
ObjectSetInteger(0, tag, OBJPROP_FONTSIZE, mFontSize);
}
//
// END Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,550 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Ocillator
// -------------------------------------------------
// Name: X121 XDelta
// Description: Detect Comulative Volumes Delta ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XDelta Ocillator"
#property strict
//
// Definitions ...
//
#define ShortName "X121_XDELTA"
//
// Imports ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Makret ...
input group "Market";
input int maLength = 14; // Moving Averge Length
input ENUM_X_MA_METHOD maMethod = X_MA_MODE_EMA; // Moving Averge Method
//
// Presentation ...
input group "Presentation";
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
input bool showDeltaLine = true; // Show Delta Line
input bool showDeltaHistogram = true; // Show Delta Histogram
input bool showDeltaMa = true; // Show Delta Moving Average
//
// Buffers Props ...
//
#property indicator_separate_window
//
#property indicator_buffers 6
#property indicator_plots 3
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
//
// Buffers ...
//
#define deltaLineBufferIndex 0
double deltaLineBuffer[];
#property indicator_label1 "Delta Line"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrYellow
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//
#define deltaHistogramBufferIndex 1
double deltaHistogramBuffer[];
//
#define deltaHistogramColorBufferIndex 2
double deltaHistogramColorBuffer[];
#property indicator_label2 "Delta Histogram"
#property indicator_type2 DRAW_COLOR_HISTOGRAM
#property indicator_color2 CLR_NONE, clrGreen, clrDarkRed
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
#define deltaMaBufferIndex 3
double deltaMaBuffer[];
#property indicator_label3 "Delta MA"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrOrchid
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//
// Data Buffers ...
#define mLastBufferIndex 3
//
#define rawDeltaBufferIndex mLastBufferIndex + 1
double rawDeltaBuffer[];
//
#define deltaStateBufferIndex mLastBufferIndex + 2
double deltaStateBuffer[];
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
int firstBarIndex;
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Indicator Handlers ...
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
IndicatorSetInteger(INDICATOR_DIGITS, 2);
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
//
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
result = maLength > 0 &&
IsValid(maMethod);
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(0, maLength);
//
return result;
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// Plot Buffers ...
//
// Delta Line ...
ENUM_DRAW_TYPE deltaLineDrawType = showDeltaLine ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(deltaLineBuffer, true);
SetIndexBuffer(deltaLineBufferIndex, deltaLineBuffer, INDICATOR_DATA);
PlotIndexSetDouble(deltaLineBufferIndex, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetInteger(deltaLineBufferIndex, PLOT_SHOW_DATA, showDeltaLine);
PlotIndexSetInteger(deltaLineBufferIndex, PLOT_DRAW_TYPE, deltaLineDrawType);
//
// Delta Histogram ...
ENUM_DRAW_TYPE deltaHistogramDrawType = showDeltaHistogram ? DRAW_COLOR_HISTOGRAM : DRAW_NONE;
//
ArraySetAsSeries(deltaHistogramBuffer, true);
SetIndexBuffer(deltaHistogramBufferIndex, deltaHistogramBuffer, INDICATOR_DATA);
PlotIndexSetDouble(deltaHistogramBufferIndex, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetInteger(deltaHistogramBufferIndex, PLOT_SHOW_DATA, showDeltaHistogram);
PlotIndexSetInteger(deltaHistogramBufferIndex, PLOT_DRAW_TYPE, deltaHistogramDrawType);
//
ArraySetAsSeries(deltaHistogramColorBuffer, true);
SetIndexBuffer(deltaHistogramColorBufferIndex, deltaHistogramColorBuffer, INDICATOR_COLOR_INDEX);
//
// Delta Ma ...
ENUM_DRAW_TYPE deltaMaDrawType = showDeltaMa ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(deltaMaBuffer, true);
SetIndexBuffer(deltaMaBufferIndex, deltaMaBuffer, INDICATOR_DATA);
PlotIndexSetDouble(deltaMaBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(deltaMaBufferIndex, PLOT_SHOW_DATA, showDeltaMa);
PlotIndexSetInteger(deltaMaBufferIndex, PLOT_DRAW_TYPE, deltaMaDrawType);
//
// Data Buffers ...
//
ArraySetAsSeries(rawDeltaBuffer, true);
SetIndexBuffer(rawDeltaBufferIndex, rawDeltaBuffer, INDICATOR_CALCULATIONS);
//
ArraySetAsSeries(deltaStateBuffer, true);
SetIndexBuffer(deltaStateBufferIndex, deltaStateBuffer, INDICATOR_CALCULATIONS);
}
/**
* Calculate Custom Buffers ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
int barsLimit = startCalculationForLastBars > 0
? startCalculationForLastBars
: 0;
if (barsLimit == 0)
{
//
barsLimit = ratesTotal;
firstBarIndex = barsLimit - 1;
}
else
{
//
firstBarIndex = startCalculationForLastBars;
}
//
// bool canCalculate = true;
bool canCalculate =
bar_index <= barsLimit;
if (canCalculate)
{
//
CalculateValues(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
}
else
{
FillBuffersZero(bar_index);
}
}
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
rawDeltaBuffer[barIndex] = 0.0;
deltaLineBuffer[barIndex] = 0.0;
deltaStateBuffer[barIndex] = 0.0;
deltaHistogramBuffer[barIndex] = 0.0;
deltaMaBuffer[barIndex] = 0.0;
deltaHistogramColorBuffer[barIndex] = hideColorIDX;
}
/**
* Calculate Vales ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateValues(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Check Prev Bar ...
int lastBarIndex = bar_index + 1;
bool isFirstBar =
startCalculationForLastBars > 0
? bar_index == startCalculationForLastBars
: bar_index == firstBarIndex;
//
XOHCL bar;
bool has = bar.Init(
_Symbol,
_Period,
bar_index //
);
if (!has)
{
return;
}
//
double iDelta = 0.0;
//
// Detecting Delta Volume ...
if (bar.IsBullish())
{
iDelta = (double)bar.volume;
}
else if (bar.IsBearish())
{
iDelta = -(double)bar.volume;
}
//
// Setting iDelta Value ...
if (isFirstBar)
{
//
rawDeltaBuffer[bar_index] = iDelta;
deltaLineBuffer[bar_index] = iDelta;
deltaHistogramBuffer[bar_index] = iDelta;
}
else
{
//
iDelta += deltaLineBuffer[bar_index + 1];
//
rawDeltaBuffer[bar_index] = iDelta;
deltaLineBuffer[bar_index] = iDelta;
deltaHistogramBuffer[bar_index] = iDelta;
}
//
// Setting iDelta State ...
double iState = iDelta > 0
? bullishColorIDX
: iDelta < 0
? bearishColorIDX
: hideColorIDX;
//
// Setting iDelta Color ...
double iDeltaColor = iDelta > 0
? bullishColorIDX
: iDelta < 0
? bearishColorIDX
: hideColorIDX;
//
deltaStateBuffer[bar_index] = iState;
deltaHistogramColorBuffer[bar_index] = iDeltaColor;
//
// Calculate Moving Averages ...
int deltaMAsCount = iMAOnBuffer(
ratesTotal,
prevCalculated,
bar_index,
maLength,
rawDeltaBuffer,
deltaMaBuffer,
maMethod //
);
//
bar.Clean();
}
//
@@ -0,0 +1,692 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121 XDON
// Description: XDON ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XDON Indicator"
#property strict
//
// Definitions ...
//
#define ShortName "X121 XDON"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
input int donchainLength = 40; // Donchain Length
//
// Presentation ...
input group "Presentation";
//
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
//
input bool showUpper = true; // Show Upper Band
input bool showLower = true; // Show Lower Band
//
input bool showOpen = true; // Show Open
input bool showHigh = true; // Show High
input bool showClose = true; // Show Close
input bool showLow = true; // Show Low
//
// Buffers ...
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
#property indicator_chart_window
//
#property indicator_buffers 8
#property indicator_plots 8
//
// Plot Buffers ...
//
// Open ...
//
#define donOpenUpperBufferIndex 0
double donOpenUpperBuffer[];
//
#define donOpenUpperPlotBufferIndex 0
#property indicator_label1 "X121 O U"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrCornflowerBlue
#property indicator_width1 1
//
#define donOpenLowerBufferIndex 1
double donOpenLowerBuffer[];
//
#define donOpenLowerPlotBufferIndex 1
#property indicator_label2 "X121 O L"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrCornflowerBlue
#property indicator_width2 1
//
// High ...
//
#define donHighUpperBufferIndex 2
double donHighUpperBuffer[];
//
#define donHighUpperPlotBufferIndex 2
#property indicator_label3 "X121 H U"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrAquamarine
#property indicator_width3 1
//
#define donHighLowerBufferIndex 3
double donHighLowerBuffer[];
//
#define donHighLowerPlotBufferIndex 3
#property indicator_label4 "X121 H L"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrAquamarine
#property indicator_width4 1
//
// Low ...
//
#define donLowUpperBufferIndex 4
double donLowUpperBuffer[];
//
#define donLowUpperPlotBufferIndex 4
#property indicator_label5 "X121 L U"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrDarkOrchid
#property indicator_width5 1
//
#define donLowLowerBufferIndex 5
double donLowLowerBuffer[];
//
#define donLowLowerPlotBufferIndex 5
#property indicator_label6 "X121 L L"
#property indicator_type6 DRAW_LINE
#property indicator_color6 clrDarkOrchid
#property indicator_width6 1
//
// Close ...
//
#define donCloseUpperBufferIndex 6
double donCloseUpperBuffer[];
//
#define donCloseUpperPlotBufferIndex 6
#property indicator_label7 "X121 C U"
#property indicator_type7 DRAW_LINE
#property indicator_color7 clrCoral
#property indicator_width7 1
//
#define donCloseLowerBufferIndex 7
double donCloseLowerBuffer[];
//
#define donCloseLowerPlotBufferIndex 7
#property indicator_label8 "X121 C L"
#property indicator_type8 DRAW_LINE
#property indicator_color8 clrCoral
#property indicator_width8 1
//
// Data Buffers ...
//
int mLastBufferIndex = 7;
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Indicator Handlers ...
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
// Validate Calculated Bars ...
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
result =
//
donchainLength > 0
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
return result;
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// Plot Buffers ...
//
// Open ...
//
// UPPER ...
bool canShowCOpenUpper = showUpper && showOpen;
ENUM_DRAW_TYPE donOpenUpperDrawType = canShowCOpenUpper ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(donOpenUpperBuffer, true);
SetIndexBuffer(donOpenUpperBufferIndex, donOpenUpperBuffer, INDICATOR_DATA);
PlotIndexSetDouble(donOpenUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(donOpenUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCOpenUpper);
PlotIndexSetInteger(donOpenUpperPlotBufferIndex, PLOT_DRAW_TYPE, donOpenUpperDrawType);
//
// LOWER ...
bool canShowCOpenLower = showLower && showOpen;
ENUM_DRAW_TYPE donOpenLowerDrawType = canShowCOpenLower ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(donOpenLowerBuffer, true);
SetIndexBuffer(donOpenLowerBufferIndex, donOpenLowerBuffer, INDICATOR_DATA);
PlotIndexSetDouble(donOpenLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(donOpenLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCOpenLower);
PlotIndexSetInteger(donOpenLowerPlotBufferIndex, PLOT_DRAW_TYPE, donOpenLowerDrawType);
//
// Close ...
//
// UPPER ...
bool canShowCCloseUpper = showUpper && showClose;
ENUM_DRAW_TYPE donCloseUpperDrawType = canShowCCloseUpper ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(donCloseUpperBuffer, true);
SetIndexBuffer(donCloseUpperBufferIndex, donCloseUpperBuffer, INDICATOR_DATA);
PlotIndexSetDouble(donCloseUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(donCloseUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCCloseUpper);
PlotIndexSetInteger(donCloseUpperPlotBufferIndex, PLOT_DRAW_TYPE, donCloseUpperDrawType);
//
// LOWER ...
bool canShowCCloseLower = showLower && showClose;
ENUM_DRAW_TYPE donCloseLowerDrawType = canShowCCloseLower ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(donCloseLowerBuffer, true);
SetIndexBuffer(donCloseLowerBufferIndex, donCloseLowerBuffer, INDICATOR_DATA);
PlotIndexSetDouble(donCloseLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(donCloseLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCCloseLower);
PlotIndexSetInteger(donCloseLowerPlotBufferIndex, PLOT_DRAW_TYPE, donCloseLowerDrawType);
//
// High ...
//
// UPPER ...
bool canShowCHighUpper = showUpper && showHigh;
ENUM_DRAW_TYPE donHighUpperDrawType = canShowCHighUpper ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(donHighUpperBuffer, true);
SetIndexBuffer(donHighUpperBufferIndex, donHighUpperBuffer, INDICATOR_DATA);
PlotIndexSetDouble(donHighUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(donHighUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCHighUpper);
PlotIndexSetInteger(donHighUpperPlotBufferIndex, PLOT_DRAW_TYPE, donHighUpperDrawType);
//
// LOWER ...
bool canShowCHighLower = showLower && showHigh;
ENUM_DRAW_TYPE donHighLowerDrawType = canShowCHighLower ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(donHighLowerBuffer, true);
SetIndexBuffer(donHighLowerBufferIndex, donHighLowerBuffer, INDICATOR_DATA);
PlotIndexSetDouble(donHighLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(donHighLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCHighLower);
PlotIndexSetInteger(donHighLowerPlotBufferIndex, PLOT_DRAW_TYPE, donHighLowerDrawType);
//
// Low ...
//
// UPPER ...
bool canShowCLowUpper = showUpper && showLow;
ENUM_DRAW_TYPE donLowUpperDrawType = canShowCLowUpper ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(donLowUpperBuffer, true);
SetIndexBuffer(donLowUpperBufferIndex, donLowUpperBuffer, INDICATOR_DATA);
PlotIndexSetDouble(donLowUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(donLowUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCLowUpper);
PlotIndexSetInteger(donLowUpperPlotBufferIndex, PLOT_DRAW_TYPE, donLowUpperDrawType);
//
// LOWER ...
bool canShowCLowLower = showLower && showLow;
ENUM_DRAW_TYPE donLowLowerDrawType = canShowCLowLower ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(donLowLowerBuffer, true);
SetIndexBuffer(donLowLowerBufferIndex, donLowLowerBuffer, INDICATOR_DATA);
PlotIndexSetDouble(donLowLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(donLowLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCLowLower);
PlotIndexSetInteger(donLowLowerPlotBufferIndex, PLOT_DRAW_TYPE, donLowLowerDrawType);
//
// Data Buffers ...
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Calculate Custom Buffers ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
int barsLimit = startCalculationForLastBars > 0
? startCalculationForLastBars
: 0;
//
// bool canCalculate = true;
bool canCalculate =
barsLimit == 0 ||
bar_index <= barsLimit;
if (canCalculate)
{
//
CalculateDonchains(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
}
else
{
FillBuffersZero(bar_index);
}
}
//
// Custom ...
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
donOpenUpperBuffer[barIndex] = EMPTY_VALUE;
donOpenLowerBuffer[barIndex] = EMPTY_VALUE;
donCloseUpperBuffer[barIndex] = EMPTY_VALUE;
donCloseLowerBuffer[barIndex] = EMPTY_VALUE;
donHighUpperBuffer[barIndex] = EMPTY_VALUE;
donHighLowerBuffer[barIndex] = EMPTY_VALUE;
donLowUpperBuffer[barIndex] = EMPTY_VALUE;
donLowLowerBuffer[barIndex] = EMPTY_VALUE;
}
/**
* Calculate Donchain ...
*
* @param bar_index: Integer, Bar Index ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
* @param _length: Integer, Donchain Length ...
* @param _ouBuffer: Double Array Reference ...
* @param _olBuffer: Double Array Reference ...
* @param _huBuffer: Double Array Reference ...
* @param _hlBuffer: Double Array Reference ...
* @param _luBuffer: Double Array Reference ...
* @param _llBuffer: Double Array Reference ...
* @param _cuBuffer: Double Array Reference ...
* @param _clBuffer: Double Array Reference ...
*/
void CalculateDonchain(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
//
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[],
//
int _length,
//
double &_ouBuffer[],
double &_olBuffer[],
double &_huBuffer[],
double &_hlBuffer[],
double &_luBuffer[],
double &_llBuffer[],
double &_cuBuffer[],
double &_clBuffer[] //
)
{
//
double iUpper = 0;
double iLower = 0;
//
// OPEN ...
//
int from = bar_index;
//
iUpper = open[ArrayMaximum(open, from, _length)];
iLower = open[ArrayMinimum(open, from, _length)];
//
_ouBuffer[bar_index] = iUpper;
_olBuffer[bar_index] = iLower;
//
// HIGH ...
//
iUpper = high[ArrayMaximum(high, from, _length)];
iLower = high[ArrayMinimum(high, from, _length)];
//
_huBuffer[bar_index] = iUpper;
_hlBuffer[bar_index] = iLower;
//
// LOW ...
//
iUpper = low[ArrayMaximum(low, from, _length)];
iLower = low[ArrayMinimum(low, from, _length)];
//
_luBuffer[bar_index] = iUpper;
_llBuffer[bar_index] = iLower;
//
// CLOSE ...
//
iUpper = close[ArrayMaximum(close, from, _length)];
iLower = close[ArrayMinimum(close, from, _length)];
//
_cuBuffer[bar_index] = iUpper;
_clBuffer[bar_index] = iLower;
}
/**
* Calculate Different VWaps ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateDonchains(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
CalculateDonchain(
//
bar_index,
prevCalculated,
ratesTotal,
//
open,
high,
close,
low,
tickVolume,
//
donchainLength,
//
donOpenUpperBuffer,
donOpenLowerBuffer,
donHighUpperBuffer,
donHighLowerBuffer,
donLowUpperBuffer,
donLowLowerBuffer,
donCloseUpperBuffer,
donCloseLowerBuffer //
);
}
//
@@ -0,0 +1,636 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121 XHK
// Description: XHK ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XHK Indicator"
#property strict
//
// Definitions ...
//
#define ShortName "X121 XHK"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
input int xhkSmoothingLength = 14; // Length
input ENUM_X_MA_METHOD xhkSmoothingMode = X_MA_MODE_EMA; // Smoothing Method
input bool xhkIgnoreSmoothingShadows = false; // Ignore Smoothed Bar Shadows
//
input group "Presentation";
//
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
//
input bool drawRawXHKCandles = true; // Draw Raw Candle
input bool drawSmoothedXHKCandles = true; // Draw Smoothed Candle
//
// Buffers ...
//
#property indicator_chart_window
//
#property indicator_buffers 10
#property indicator_plots 2
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
// PLOTTED Buffers ...
//
#define openHKBufferIndex 0
double openHKBuffer[];
//
#define highHKBufferIndex 1
double highHKBuffer[];
//
#define lowHKBufferIndex 2
double lowHKBuffer[];
//
#define closeHKBufferIndex 3
double closeHKBuffer[];
//
#define rawHKColorBufferIndex 4
double rawHKColorBuffer[];
//
#define rawHKBufferIndex 0
#property indicator_label1 "X121 XHK Open;X121 XHK High;X121 XHK Low;X121 XHK Close"
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 CLR_NONE, clrDodgerBlue, clrDarkGoldenrod
//
// Open ...
#define openBufferIndex 5
double openBuffer[];
//
// High ...
#define highBufferIndex 6
double highBuffer[];
//
// Low ...
#define lowBufferIndex 7
double lowBuffer[];
//
// Close ...
#define closeBufferIndex 8
double closeBuffer[];
//
// Candle Color ...
#define candleColorBufferIndex 9
double candleColorBuffer[];
//
#define candlesBufferIndex 1
#property indicator_label2 "X121 XHKSM Open;X121 XHKSM High;X121 XHKSM Low;X121 XHKSM Close"
#property indicator_type2 DRAW_COLOR_CANDLES
#property indicator_color2 CLR_NONE, clrAqua, clrMagenta
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
int firstBarIndex;
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Indicator Handlers ...
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
// Fill All Buffers by Zero ...
if (prev_calculated == 0)
{
}
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result =
//
true
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(0, xhkSmoothingLength);
//
return result;
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// RAW ...
//
// Raw Candles Color ...
ArraySetAsSeries(rawHKColorBuffer, true);
SetIndexBuffer(rawHKColorBufferIndex, rawHKColorBuffer, INDICATOR_COLOR_INDEX);
//
// Set EMPTY_VALUE on Candles Buffer ...
PlotIndexSetDouble(rawHKBufferIndex, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetInteger(rawHKBufferIndex, PLOT_SHOW_DATA, false);
//
// Open ...
ArraySetAsSeries(openHKBuffer, true);
SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_DATA);
//
// High ...
ArraySetAsSeries(highHKBuffer, true);
SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_DATA);
//
// Close ...
ArraySetAsSeries(closeHKBuffer, true);
SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_DATA);
//
// Low ...
ArraySetAsSeries(lowHKBuffer, true);
SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_DATA);
//
// SMOOTHED ...
//
// Candles Color ...
ArraySetAsSeries(candleColorBuffer, true);
SetIndexBuffer(candleColorBufferIndex, candleColorBuffer, INDICATOR_COLOR_INDEX);
//
// Set EMPTY_VALUE on Candles Buffer ...
PlotIndexSetDouble(candlesBufferIndex, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetInteger(candlesBufferIndex, PLOT_SHOW_DATA, false);
//
// Open ...
ArraySetAsSeries(openBuffer, true);
SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_DATA);
//
// High ...
ArraySetAsSeries(highBuffer, true);
SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA);
//
// Close ...
ArraySetAsSeries(closeBuffer, true);
SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_DATA);
//
// Low ...
ArraySetAsSeries(lowBuffer, true);
SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA);
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Calculate Custom Buffers ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
int barsLimit = startCalculationForLastBars > 0
? startCalculationForLastBars
: 0;
if (barsLimit == 0)
{
//
barsLimit = ratesTotal;
firstBarIndex = barsLimit - 1;
}
else
{
//
firstBarIndex = startCalculationForLastBars;
}
//
// bool canCalculate = true;
bool canCalculate =
bar_index <= barsLimit;
if (canCalculate)
{
//
CalculateXHK(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low //
);
}
else
{
FillBuffersZero(bar_index);
}
}
//
// Custom ...
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
lowHKBuffer[barIndex] = 0.0;
openHKBuffer[barIndex] = 0.0;
highHKBuffer[barIndex] = 0.0;
closeHKBuffer[barIndex] = 0.0;
rawHKColorBuffer[barIndex] = hideColorIDX;
//
lowBuffer[barIndex] = 0.0;
openBuffer[barIndex] = 0.0;
highBuffer[barIndex] = 0.0;
closeBuffer[barIndex] = 0.0;
candleColorBuffer[barIndex] = hideColorIDX;
}
/**
* Calculate ATR Zones ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
*/
void CalculateXHK(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[] //
)
{
//
int lastBarIndex = bar_index + 1;
bool isFirstBar =
startCalculationForLastBars > 0
? bar_index == startCalculationForLastBars
: bar_index == firstBarIndex;
//
double mPrevHKOpenValue;
double mPrevHKCloseValue;
//
if (ArraySize(open) <= bar_index + 1)
{
//
mPrevHKOpenValue = 0;
mPrevHKCloseValue = 0;
}
else
{
//
mPrevHKOpenValue = openHKBuffer[bar_index + 1];
mPrevHKCloseValue = closeHKBuffer[bar_index + 1];
}
//
double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2;
double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4;
double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue));
double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue));
//
double candleColorValue =
mHKOpenValue < mHKCloseValue ? bullishColorIDX : bearishColorIDX;
//
// Raw HK Buffers ...
openHKBuffer[bar_index] = mHKOpenValue;
highHKBuffer[bar_index] = mHKHighValue;
lowHKBuffer[bar_index] = mHKLowValue;
closeHKBuffer[bar_index] = mHKCloseValue;
rawHKColorBuffer[bar_index] = drawRawXHKCandles ? candleColorValue : hideColorIDX;
//
// Apply Smoothing ...
bool canSmooth = xhkSmoothingLength > 0 &&
xhkSmoothingMode != X_MA_MODE_NONE;
if (!canSmooth)
{
//
double min = MathMin(mHKOpenValue, mHKCloseValue);
double max = MathMax(mHKOpenValue, mHKCloseValue);
//
openBuffer[bar_index] = mHKOpenValue;
highBuffer[bar_index] = xhkIgnoreSmoothingShadows ? max : mHKHighValue;
lowBuffer[bar_index] = xhkIgnoreSmoothingShadows ? min : mHKLowValue;
closeBuffer[bar_index] = mHKCloseValue;
candleColorBuffer[bar_index] = drawSmoothedXHKCandles ? candleColorValue : hideColorIDX;
}
else
{
//
// Open ...
iMAOnBuffer(
ratesTotal,
prevCalculated,
bar_index,
xhkSmoothingLength,
openHKBuffer,
openBuffer,
xhkSmoothingMode //
);
//
// Close ...
iMAOnBuffer(
ratesTotal,
prevCalculated,
bar_index,
xhkSmoothingLength,
closeHKBuffer,
closeBuffer,
xhkSmoothingMode //
);
//
// Ignoring Shadows ...
if (!xhkIgnoreSmoothingShadows)
{
//
// High ...
iMAOnBuffer(
ratesTotal,
prevCalculated,
bar_index,
xhkSmoothingLength,
highHKBuffer,
highBuffer,
xhkSmoothingMode //
);
//
// Low ...
iMAOnBuffer(
ratesTotal,
prevCalculated,
bar_index,
xhkSmoothingLength,
lowHKBuffer,
lowBuffer,
xhkSmoothingMode //
);
}
else
{
//
double min = MathMin(closeBuffer[bar_index], openBuffer[bar_index]);
double max = MathMin(closeBuffer[bar_index], openBuffer[bar_index]);
//
lowBuffer[bar_index] = min;
highBuffer[bar_index] = max;
}
//
// Calculate Smoothed Color ...
candleColorValue =
openBuffer[bar_index] < closeBuffer[bar_index] ? bullishColorIDX : bearishColorIDX;
candleColorBuffer[bar_index] = drawSmoothedXHKCandles ? candleColorValue : hideColorIDX;
}
}
//
@@ -0,0 +1,625 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121 XWZ
// Description: XWZ ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XWZ Indicator"
#property strict
//
// Definitions ...
//
#define ShortName "X121_XICH"
//
// Imports ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
input ENUM_X_PRICE chikouSpanMode = X_PRICE_CLOSE; // ChikouSpan Mode
input int tenkanSenLength = 9; // TenkanSen Length
input ENUM_X_BOUNDARY_PRICE tenkanSenMode = X_BOUNDARY_PRICE_HIGH_LOW; // TencanSen Mode
input int kijunSenLength = 26; // KijunSen Length
input ENUM_X_BOUNDARY_PRICE kijunSenMode = X_BOUNDARY_PRICE_HIGH_LOW; // KijunSen Mode
input int senkouSpanBLength = 52; // SenkouSpan B Length
input ENUM_X_BOUNDARY_PRICE senkouSpanBMode = X_BOUNDARY_PRICE_HIGH_LOW; // SenkouSpan B Mode
//
// Presentation ...
input group "Presentation";
//
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
input bool shiftKumo = true; // Shift Kumo
input bool showTenkanSen = true; // Show TenkanSen
input bool showKijunSen = true; // Show KijunSen
input bool showChikouSpan = true; // Show ChikouSpan
input bool showSenkouSpanA = true; // Show Senkou Span A
input bool showSenkouSpanB = true; // Show Senkou Span B
input bool showKumo = true; // Show Kumo
//
// Buffers ...
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
#property indicator_chart_window
//
#property indicator_buffers 8
#property indicator_plots 6
//
// Plot Buffers ...
//
#define tenkanSenBufferIndex 0
double tenkanSenBuffer[];
//
#property indicator_label1 "XICH TK"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBrown
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//
#define kijunSenBufferIndex 1
double kijunSenBuffer[];
//
#property indicator_label2 "XICH KJ"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrDodgerBlue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
//
#define chikouSpanBufferIndex 2
double chikouSpanBuffer[];
//
#property indicator_label3 "XICH CS"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrDarkGreen
#property indicator_style3 STYLE_SOLID
#property indicator_width3 2
//
#define senkouSpanABufferIndex 3
double senkouSpanABuffer[];
//
#property indicator_label4 "XICH SSA"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrLightGray
#property indicator_style4 STYLE_DASHDOTDOT
#property indicator_width4 2
//
#define senkouSpanBBufferIndex 4
double senkouSpanBBuffer[];
//
#property indicator_label5 "XICH SSB"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrLightGray
#property indicator_style5 STYLE_DASHDOTDOT
#property indicator_width5 2
//
#define senkouABufferIndex 5
double senkouABuffer[];
//
#define senkouBBufferIndex 6
double senkouBBuffer[];
//
#define kumoBufferIndex 5
//
#property indicator_label6 "XICH Kumo"
#property indicator_type6 DRAW_FILLING
#property indicator_color6 clrAqua, clrMagenta
#property indicator_style6 STYLE_SOLID
#property indicator_width6 2
//
// Data Buffers ...
//
int mLastBufferIndex = 6;
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
IndicatorSetInteger(INDICATOR_DIGITS, 2);
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
//
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
result =
//
kijunSenLength > 0 &&
tenkanSenLength > 0 &&
senkouSpanBLength > 0 &&
IsValid(kijunSenMode) &&
IsValid(tenkanSenMode) &&
IsValid(chikouSpanMode) &&
IsValid(senkouSpanBMode)
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(kijunSenLength, tenkanSenLength);
result = MathMax(result, senkouSpanBLength);
//
return result;
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(tenkanSenBuffer, true);
SetIndexBuffer(tenkanSenBufferIndex, tenkanSenBuffer, INDICATOR_DATA);
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_SHOW_DATA, showTenkanSen);
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_TYPE, tenkanSenDrawType);
//
ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(kijunSenBuffer, true);
SetIndexBuffer(kijunSenBufferIndex, kijunSenBuffer, INDICATOR_DATA);
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_SHOW_DATA, showKijunSen);
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_TYPE, kijunSenDrawType);
//
ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(chikouSpanBuffer, true);
SetIndexBuffer(chikouSpanBufferIndex, chikouSpanBuffer, INDICATOR_DATA);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHIFT, -kijunSenLength);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHOW_DATA, showChikouSpan);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_TYPE, chikouSpanDrawType);
//
int shiftSize = shiftKumo ? kijunSenLength : 0;
//
ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(senkouSpanABuffer, true);
SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_SHIFT, shiftSize);
PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA);
PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType);
//
ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(senkouSpanBBuffer, true);
SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_SHIFT, shiftSize);
PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB);
PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType);
//
ArraySetAsSeries(senkouABuffer, true);
SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_BEGIN, maxLength);
//
ArraySetAsSeries(senkouBBuffer, true);
SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_BEGIN, maxLength);
//
ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE;
//
PlotIndexSetInteger(kumoBufferIndex, PLOT_SHIFT, shiftSize);
PlotIndexSetInteger(kumoBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(kumoBufferIndex, PLOT_DRAW_TYPE, kumoDrawType);
}
/**
* Calculate Custom Buffers ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
int barsLimit = startCalculationForLastBars > 0
? startCalculationForLastBars
: 0;
//
// bool canCalculate = true;
bool canCalculate =
barsLimit == 0 ||
bar_index <= barsLimit;
if (canCalculate)
{
//
CalculateValues(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
}
else
{
FillBuffersZero(bar_index);
}
}
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
senkouABuffer[barIndex] = 0;
senkouBBuffer[barIndex] = 0;
kijunSenBuffer[barIndex] = 0;
tenkanSenBuffer[barIndex] = 0;
chikouSpanBuffer[barIndex] = 0;
senkouSpanABuffer[barIndex] = 0;
senkouSpanBBuffer[barIndex] = 0;
}
/**
* Calculate Vales ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateValues(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
double uppers[];
double lowers[];
//
double uppersMax = 0;
double uppersMin = 0;
//
double lowersMax = 0;
double lowersMin = 0;
//
// Calculate ChikouSpan ...
double iChikouSpan = GetAppliedPrice(
_Symbol,
_Period,
bar_index,
chikouSpanMode //
);
//
// Calculate TenkanSen ...
GetPriceBoundary(
uppers,
lowers,
_Symbol,
_Period,
tenkanSenMode,
tenkanSenLength,
bar_index //
);
//
uppersMax = uppers[ArrayMaximum(uppers)];
uppersMin = uppers[ArrayMinimum(uppers)];
//
lowersMax = lowers[ArrayMaximum(lowers)];
lowersMin = lowers[ArrayMinimum(lowers)];
//
double iTenkanSen = (uppersMax + lowersMin) / 2;
//
// Calculate KijunSen ...
GetPriceBoundary(
uppers,
lowers,
_Symbol,
_Period,
kijunSenMode,
kijunSenLength,
bar_index //
);
//
uppersMax = uppers[ArrayMaximum(uppers)];
uppersMin = uppers[ArrayMinimum(uppers)];
//
lowersMax = lowers[ArrayMaximum(lowers)];
lowersMin = lowers[ArrayMinimum(lowers)];
//
double iKijunSen = (uppersMax + lowersMin) / 2;
//
// Calculate SenkouSpanB ...
GetPriceBoundary(
uppers,
lowers,
_Symbol,
_Period,
senkouSpanBMode,
senkouSpanBLength,
bar_index //
);
//
uppersMax = uppers[ArrayMaximum(uppers)];
uppersMin = uppers[ArrayMinimum(uppers)];
//
lowersMax = lowers[ArrayMaximum(lowers)];
lowersMin = lowers[ArrayMinimum(lowers)];
//
double iSenkouSpanB = (uppersMax + lowersMin) / 2;
//
// Calculate SenkouSpanA ...
double iSenkouSpanA = (iTenkanSen + iKijunSen) / 2;
//
// Setting Buffers ...
kijunSenBuffer[bar_index] = iKijunSen;
senkouABuffer[bar_index] = iSenkouSpanA;
senkouBBuffer[bar_index] = iSenkouSpanB;
tenkanSenBuffer[bar_index] = iTenkanSen;
chikouSpanBuffer[bar_index] = iChikouSpan;
senkouSpanABuffer[bar_index] = iSenkouSpanA;
senkouSpanBBuffer[bar_index] = iSenkouSpanB;
}
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,812 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121 XSTR
// Description: XSTR ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XSTR Indicator"
#property strict
//
// Definitions ...
//
#define ShortName "X121 XSTR"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
input int strLength = 14; // Length
input double strMultiplier = 3; // Multiplier
input int vidyaLength = 14; // Smothing Length
input ENUM_MA_METHOD strBoundaryMode = MODE_SMA; // Boundary Mode
input ENUM_APPLIED_PRICE strAppliedTo = PRICE_MEDIAN; // Applied To
input ENUM_APPLIED_PRICE vidyaAppliedTo = PRICE_CLOSE; // Smoothing Applied To
//
input group "Presentation";
input bool showStr = true; // Show Str
input bool showVidya = true; // Show Vidya
input bool showStrUpper = true; // Show Str Upper
input bool showStrLower = true; // Show Str Lower
input bool showStrLowMa = true; // Show Low Smoothed Buffer
input bool showStrHighMa = true; // Show High Smoothed Buffer
//
// Buffers ...
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
#define emptyValue 0.0
//
#property indicator_chart_window
//
#property indicator_buffers 10
#property indicator_plots 6
//
// STR ...
#define strBufferIndex 0
double strBuffer[];
#define strColorBufferIndex 1
double strColorBuffer[];
//
#define strPlotBufferIndex 0
#property indicator_label1 "X121 STR"
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_color1 CLR_NONE, clrLime, clrRed, clrGray
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//
// Up ...
#define strUpBufferIndex 2
double strUpBuffer[];
//
#define strUpPlotBufferIndex 1
#property indicator_label2 "X121 STR U"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrBlueViolet
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//
// Down ...
#define strDownBufferIndex 3
double strDownBuffer[];
//
#define strDownPlotBufferIndex 2
#property indicator_label3 "X121 STR D"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrBlueViolet
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//
// High MA ...
#define strHighMaBufferIndex 4
double strHighMaBuffer[];
//
#define strHighMaPlotBufferIndex 3
#property indicator_label4 "X121 STR HSM"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrAqua
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
//
// Low Ma ...
#define strLowMaBufferIndex 5
double strLowMaBuffer[];
//
#define strLowMaPlotBufferIndex 4
#property indicator_label5 "X121 STR LSM"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrMagenta
#property indicator_style5 STYLE_SOLID
#property indicator_width5 1
//
// VIDYA ...
#define vidyaBufferIndex 6
double vidyaBuffer[];
//
#define vidyaPlotBufferIndex 5
#property indicator_label6 "X121 VIDYA"
#property indicator_type6 DRAW_LINE
#property indicator_color6 clrYellow
#property indicator_style6 STYLE_SOLID
#property indicator_width6 1
//
// Data Buffers ...
//
int mLastBufferIndex = 6;
//
// STR ...
//
// Atr ...
#define atrBufferIndex mLastBufferIndex + 1
double atrBuffer[];
//
// Price ...
#define strPriceBufferIndex mLastBufferIndex + 2
double strPriceBuffer[];
//
// Trend ...
#define strStateBufferIndex mLastBufferIndex + 3
double strStateBuffer[];
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
// ATR Handler ...
int atrHandler = INVALID_HANDLE;
//
// MA Handler ...
int lowMaHandler = INVALID_HANDLE;
int highMaHandler = INVALID_HANDLE;
int vidyaHandler = INVALID_HANDLE;
//
bool isStrTrendChanged;
bool isStrStartBearishTrend;
bool isStrStartBullishTrend;
//
int changeOfTrend;
int startBearishTrend;
int startBullishTrend;
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Indicator Handlers ...
//
// ATR ...
atrHandler = iATR(
_Symbol,
_Period,
strLength //
);
bool isInited = atrHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// Low Ma ...
lowMaHandler = iMA(
_Symbol,
_Period,
strLength,
0,
strBoundaryMode,
PRICE_LOW //
);
isInited = lowMaHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// High Ma ...
highMaHandler = iMA(
_Symbol,
_Period,
strLength,
0,
strBoundaryMode,
PRICE_HIGH //
);
isInited = highMaHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// Vidya ...
vidyaHandler = iVIDyA(
_Symbol,
_Period,
strLength,
vidyaLength,
0, // Shift ...
vidyaAppliedTo //
);
isInited = vidyaHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
IndicatorRelease(atrHandler);
IndicatorRelease(vidyaHandler);
IndicatorRelease(lowMaHandler);
IndicatorRelease(highMaHandler);
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
// Prepare Buffers ...
//
// Validate Calculated Bars ...
//
// ATR ...
int atrCalculatedBars = BarsCalculated(atrHandler);
//
// VIDYA ...
int vidyaCalculatedBars = BarsCalculated(vidyaHandler);
//
// Low Ma ...
int lowMaCalculatedBars = BarsCalculated(lowMaHandler);
//
// High Ma ...
int highMaCalculatedBars = BarsCalculated(highMaHandler);
//
bool isPassedRequiredCalculatedBars =
//
// ATR ...
atrCalculatedBars >= 0 &&
//
// VIDYA ...
vidyaCalculatedBars >= 0 &&
//
// Low Ma ...
lowMaCalculatedBars >= 0 &&
//
// High Ma ...
highMaCalculatedBars >= 0
//
;
if (!isPassedRequiredCalculatedBars)
{
return prev_calculated;
}
//
//
// checking for the limit start of calculation of an indicator ...
limit =
(prev_calculated > rates_total || prev_calculated <= 0)
? maxLength
: prev_calculated - 1;
//
// Buffers Copy ...
//
// ATR ...
int copiedAtrs = CopyBuffer(atrHandler, 0, 0, rates_total, atrBuffer);
//
// VYDIA ...
int copiedVidyas = CopyBuffer(vidyaHandler, 0, 0, rates_total, vidyaBuffer);
//
// Low Ma ...
int copiedLowMas = CopyBuffer(lowMaHandler, 0, 0, rates_total, strLowMaBuffer);
//
// High Ma ...
int copiedHighMas = CopyBuffer(highMaHandler, 0, 0, rates_total, strHighMaBuffer);
//
// Validate Copied Items ...
bool isPassedRequiredCopiedItems =
//
// ATR ...
copiedAtrs >= 0 &&
//
// VIDYA ...
copiedVidyas >= 0 &&
//
// Low Ma ...
copiedLowMas >= 0 &&
//
// Hig Ma ...
copiedHighMas >= 0
//
;
if (!isPassedRequiredCopiedItems)
{
return prev_calculated;
}
//
// Main Loop ...
for (int i = limit; i < rates_total && !IsStopped(); i++)
{
//
CalculateBuffers(
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result =
//
// STR ...
strLength > 0 &&
strMultiplier > 0
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(1, strLength);
//
return result;
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// STR ...
SetIndexBuffer(strBufferIndex, strBuffer, INDICATOR_DATA);
SetIndexBuffer(strColorBufferIndex, strColorBuffer, INDICATOR_COLOR_INDEX);
//
ENUM_DRAW_TYPE strUpDrawType = showStrUpper ? DRAW_LINE : DRAW_NONE;
SetIndexBuffer(strUpBufferIndex, strUpBuffer, INDICATOR_DATA);
PlotIndexSetDouble(strUpPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
PlotIndexSetInteger(strUpPlotBufferIndex, PLOT_SHOW_DATA, showStrUpper);
PlotIndexSetInteger(strUpPlotBufferIndex, PLOT_DRAW_TYPE, strUpDrawType);
//
ENUM_DRAW_TYPE strDownDrawType = showStrLower ? DRAW_LINE : DRAW_NONE;
SetIndexBuffer(strDownBufferIndex, strDownBuffer, INDICATOR_DATA);
PlotIndexSetDouble(strDownPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
PlotIndexSetInteger(strDownPlotBufferIndex, PLOT_SHOW_DATA, showStrLower);
PlotIndexSetInteger(strDownPlotBufferIndex, PLOT_DRAW_TYPE, strDownDrawType);
//
ENUM_DRAW_TYPE strLowMaDrawType = showStrLowMa ? DRAW_LINE : DRAW_NONE;
SetIndexBuffer(strLowMaBufferIndex, strLowMaBuffer, INDICATOR_DATA);
PlotIndexSetDouble(strLowMaPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
PlotIndexSetInteger(strLowMaPlotBufferIndex, PLOT_SHOW_DATA, showStrLowMa);
PlotIndexSetInteger(strLowMaPlotBufferIndex, PLOT_DRAW_TYPE, strLowMaDrawType);
//
ENUM_DRAW_TYPE strHighMaDrawType = showStrHighMa ? DRAW_LINE : DRAW_NONE;
SetIndexBuffer(strHighMaBufferIndex, strHighMaBuffer, INDICATOR_DATA);
PlotIndexSetDouble(strHighMaPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
PlotIndexSetInteger(strHighMaPlotBufferIndex, PLOT_SHOW_DATA, showStrHighMa);
PlotIndexSetInteger(strHighMaPlotBufferIndex, PLOT_DRAW_TYPE, strHighMaDrawType);
//
ENUM_DRAW_TYPE vidyaDrawType = showVidya ? DRAW_LINE : DRAW_NONE;
SetIndexBuffer(vidyaBufferIndex, vidyaBuffer, INDICATOR_DATA);
PlotIndexSetDouble(vidyaPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
PlotIndexSetInteger(vidyaPlotBufferIndex, PLOT_SHOW_DATA, showVidya);
PlotIndexSetInteger(vidyaPlotBufferIndex, PLOT_DRAW_TYPE, vidyaDrawType);
//
// Data Buffers ...
//
SetIndexBuffer(strPriceBufferIndex, strPriceBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(strStateBufferIndex, strStateBuffer, INDICATOR_CALCULATIONS);
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Calculate Custom Buffers ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
CalculateStr(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low //
);
}
//
// Custom ...
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
// STR ...
strBuffer[barIndex] = emptyValue;
strUpBuffer[barIndex] = emptyValue;
strDownBuffer[barIndex] = emptyValue;
strPriceBuffer[barIndex] = emptyValue;
strLowMaBuffer[barIndex] = emptyValue;
strHighMaBuffer[barIndex] = emptyValue;
//
strColorBuffer[barIndex] = hideColorIDX;
strStateBuffer[barIndex] = hideColorIDX;
}
/**
* Calculate STR ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
*/
void CalculateStr(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[] //
)
{
//
// Calculated Price ...
ENUM_X_PRICE mPType = ToXPrice(strAppliedTo);
double price = GetAppliedPrice(
mPType,
open,
high,
low,
close,
bar_index //
);
strPriceBuffer[bar_index] = price;
//
double atr = atrBuffer[bar_index];
//
// Up ...
strUpBuffer[bar_index] = price + (strMultiplier * atr);
//
// Down ...
strDownBuffer[bar_index] = price - (strMultiplier * atr);
//
if (close[bar_index] > strUpBuffer[bar_index - 1])
{
//
strStateBuffer[bar_index] = 1;
if (strStateBuffer[bar_index - 1] == -1)
{
changeOfTrend = 1;
}
}
else if (close[bar_index] < strDownBuffer[bar_index - 1])
{
//
strStateBuffer[bar_index] = -1;
if (strStateBuffer[bar_index - 1] == 1)
{
changeOfTrend = 1;
}
}
else if (strStateBuffer[bar_index - 1] == 1)
{
//
strStateBuffer[bar_index] = 1;
changeOfTrend = 0;
}
else if (strStateBuffer[bar_index - 1] == -1)
{
//
strStateBuffer[bar_index] = -1;
changeOfTrend = 0;
}
//
// Down Trend Starting ...
if (strStateBuffer[bar_index] < 0 && strStateBuffer[bar_index - 1] > 0)
{
startBearishTrend = 1;
}
else
{
startBearishTrend = 0;
}
//
// Up Trend Starting ...
if (strStateBuffer[bar_index] > 0 && strStateBuffer[bar_index - 1] < 0)
{
startBullishTrend = 1;
}
else
{
startBullishTrend = 0;
}
//
if (strStateBuffer[bar_index] > 0 && strDownBuffer[bar_index] < strDownBuffer[bar_index - 1])
{
strDownBuffer[bar_index] = strDownBuffer[bar_index - 1];
}
//
if (strStateBuffer[bar_index] < 0 && strUpBuffer[bar_index] > strUpBuffer[bar_index - 1])
{
strUpBuffer[bar_index] = strUpBuffer[bar_index - 1];
}
//
if (startBearishTrend == 1)
{
strUpBuffer[bar_index] = strPriceBuffer[bar_index] + (strMultiplier * atr);
}
//
if (startBullishTrend == 1)
{
strDownBuffer[bar_index] = strPriceBuffer[bar_index] - (strMultiplier * atr);
}
//
// Draw the indicator ...
//
double colorIDX = hideColorIDX;
strColorBuffer[bar_index] = colorIDX;
//
if (strStateBuffer[bar_index] == 1)
{
//
strBuffer[bar_index] = strDownBuffer[bar_index];
if (changeOfTrend == 1)
{
strBuffer[bar_index - 1] = strBuffer[bar_index - 2];
changeOfTrend = 0;
}
//
colorIDX = bullishColorIDX;
}
else if (strStateBuffer[bar_index] == -1)
{
//
strBuffer[bar_index] = strUpBuffer[bar_index];
if (changeOfTrend == 1)
{
//
strBuffer[bar_index - 1] = strBuffer[bar_index - 2];
changeOfTrend = 0;
}
//
colorIDX = bearishColorIDX;
}
//
if (showStr)
{
strColorBuffer[bar_index] = colorIDX;
}
//
// Str Mid ...
//
double iStrMid = strDownBuffer[bar_index] + ((strUpBuffer[bar_index] - strDownBuffer[bar_index]) / 2);
//
}
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,567 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Ocillator
// -------------------------------------------------
// Name: X121 XVolume
// Description: Detect Bullish/Bearish Volumes ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XVolume Ocillator"
#property strict
//
// Definitions ...
//
#define ShortName "X121_XVOLUME"
//
// Imports ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Makret ...
input group "Market";
input int maLength = 14; // Moving Averge Length
input ENUM_X_MA_METHOD maMethod = X_MA_MODE_EMA; // Moving Averge Method
//
// Presentation ...
input group "Presentation";
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
input bool showBullishVolume = true; // Show Bullish Volume
input bool showBullishVolumeMa = true; // Show Bullish Volume Moving Average
input bool showBearishVolume = true; // Show Bearish Volume
input bool showBearishVolumeMa = true; // Show Bearish Volume Moving Average
//
// Buffers Props ...
//
#property indicator_separate_window
//
#property indicator_buffers 6
#property indicator_plots 4
//
// Buffers ...
//
#define bullishVolumeBufferIndex 0
double bullishVolumeBuffer[];
#property indicator_label1 "Bullish Volume"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrLime
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//
#define bullishVolumeMaBufferIndex 1
double bullishVolumeMaBuffer[];
#property indicator_label2 "Bullish Volume MA"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrLime
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//
#define bearishVolumeBufferIndex 2
double bearishVolumeBuffer[];
#property indicator_label3 "Bearish Volume"
#property indicator_type3 DRAW_HISTOGRAM
#property indicator_color3 clrRed
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
#define bearishVolumeMaBufferIndex 3
double bearishVolumeMaBuffer[];
#property indicator_label4 "Bearish Volume MA"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrRed
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
//
// Data Buffers ...
#define mLastBufferIndex 3
//
#define rawBullishVolumeBufferIndex mLastBufferIndex + 1
double rawBullishVolumeBuffer[];
//
#define rawBearishVolumeBufferIndex mLastBufferIndex + 2
double rawBearishVolumeBuffer[];
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
int firstBarIndex;
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Indicator Handlers ...
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
IndicatorSetInteger(INDICATOR_DIGITS, 2);
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
//
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
result = maLength > 0 &&
IsValid(maMethod);
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(0, maLength);
//
return result;
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// Plot Buffers ...
//
// Bullish ...
//
// Volume ...
ENUM_DRAW_TYPE bullishVolumeDrawType = showBullishVolume ? DRAW_HISTOGRAM : DRAW_NONE;
//
ArraySetAsSeries(bullishVolumeBuffer, true);
SetIndexBuffer(bullishVolumeBufferIndex, bullishVolumeBuffer, INDICATOR_DATA);
PlotIndexSetDouble(bullishVolumeBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(bullishVolumeBufferIndex, PLOT_SHOW_DATA, showBullishVolume);
PlotIndexSetInteger(bullishVolumeBufferIndex, PLOT_DRAW_TYPE, bullishVolumeDrawType);
//
// Average ...
ENUM_DRAW_TYPE bullishVolumeMaDrawType = showBullishVolumeMa ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(bullishVolumeMaBuffer, true);
SetIndexBuffer(bullishVolumeMaBufferIndex, bullishVolumeMaBuffer, INDICATOR_DATA);
PlotIndexSetDouble(bullishVolumeMaBufferIndex, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetInteger(bullishVolumeMaBufferIndex, PLOT_SHOW_DATA, showBullishVolumeMa);
PlotIndexSetInteger(bullishVolumeMaBufferIndex, PLOT_DRAW_TYPE, bullishVolumeMaDrawType);
//
// Bearish ...
//
// Volume ...
ENUM_DRAW_TYPE bearishVolumeDrawType = showBearishVolume ? DRAW_HISTOGRAM : DRAW_NONE;
//
ArraySetAsSeries(bearishVolumeBuffer, true);
SetIndexBuffer(bearishVolumeBufferIndex, bearishVolumeBuffer, INDICATOR_DATA);
PlotIndexSetDouble(bearishVolumeBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(bearishVolumeBufferIndex, PLOT_SHOW_DATA, showBearishVolume);
PlotIndexSetInteger(bearishVolumeBufferIndex, PLOT_DRAW_TYPE, bearishVolumeDrawType);
//
// Average ...
ENUM_DRAW_TYPE bearishVolumeMaDrawType = showBearishVolumeMa ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(bearishVolumeMaBuffer, true);
SetIndexBuffer(bearishVolumeMaBufferIndex, bearishVolumeMaBuffer, INDICATOR_DATA);
PlotIndexSetDouble(bearishVolumeMaBufferIndex, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetInteger(bearishVolumeMaBufferIndex, PLOT_SHOW_DATA, showBearishVolumeMa);
PlotIndexSetInteger(bearishVolumeMaBufferIndex, PLOT_DRAW_TYPE, bearishVolumeMaDrawType);
//
// Data Buffers ...
//
ArraySetAsSeries(rawBullishVolumeBuffer, true);
SetIndexBuffer(rawBullishVolumeBufferIndex, rawBullishVolumeBuffer, INDICATOR_CALCULATIONS);
//
ArraySetAsSeries(rawBearishVolumeBuffer, true);
SetIndexBuffer(rawBearishVolumeBufferIndex, rawBearishVolumeBuffer, INDICATOR_CALCULATIONS);
}
/**
* Calculate Custom Buffers ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
int barsLimit = startCalculationForLastBars > 0
? startCalculationForLastBars
: 0;
if (barsLimit == 0)
{
//
barsLimit = ratesTotal;
firstBarIndex = barsLimit - 1;
}
else
{
//
firstBarIndex = startCalculationForLastBars;
}
//
// bool canCalculate = true;
bool canCalculate =
bar_index <= barsLimit;
if (canCalculate)
{
//
CalculateValues(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
}
else
{
FillBuffersZero(bar_index);
}
}
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
bullishVolumeBuffer[barIndex] = EMPTY_VALUE;
bullishVolumeMaBuffer[barIndex] = EMPTY_VALUE;
rawBullishVolumeBuffer[barIndex] = 0;
//
bearishVolumeBuffer[barIndex] = EMPTY_VALUE;
bearishVolumeMaBuffer[barIndex] = EMPTY_VALUE;
rawBearishVolumeBuffer[barIndex] = 0;
}
/**
* Calculate Vales ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateValues(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Check Prev Bar ...
//
int lastBarIndex = bar_index + 1;
bool isFirstBar =
startCalculationForLastBars > 0
? bar_index == startCalculationForLastBars
: bar_index == firstBarIndex;
//
XOHCL bar;
bool has = bar.Init(
_Symbol,
_Period,
bar_index //
);
if (!has)
{
return;
}
//
double iBullishVolume = 0;
double iBearishVolume = 0;
//
if (bar.IsBullish())
{
//
iBullishVolume = (double)bar.volume;
iBearishVolume = 0;
}
else if (bar.IsBearish())
{
//
iBearishVolume = (double)bar.volume;
iBullishVolume = 0;
}
else
{
//
double volume = ((double)bar.volume) / 2.0;
iBullishVolume = volume;
iBearishVolume = volume;
}
//
bullishVolumeBuffer[bar_index] =
iBullishVolume == 0
? EMPTY_VALUE
: iBullishVolume;
rawBullishVolumeBuffer[bar_index] = iBullishVolume;
//
bearishVolumeBuffer[bar_index] =
iBearishVolume == 0
? EMPTY_VALUE
: iBearishVolume;
rawBearishVolumeBuffer[bar_index] = iBearishVolume;
//
// Calculate Moving Averages ...
//
int bullishMAsCount = iMAOnBuffer(
ratesTotal,
prevCalculated,
bar_index,
maLength,
rawBullishVolumeBuffer,
bullishVolumeMaBuffer,
maMethod //
);
//
int bearishMAsCount = iMAOnBuffer(
ratesTotal,
prevCalculated,
bar_index,
maLength,
rawBearishVolumeBuffer,
bearishVolumeMaBuffer,
maMethod //
);
//
bar.Clean();
}
//
@@ -0,0 +1,712 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121 XVWAP
// Description: XVWAP ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XVWAP Indicator"
#property strict
//
// Definitions ...
//
#define ShortName "X121 XVWAP"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
input int vwapFastLength = 20; // Fast Length
input int vwapMidLength = 40; // Mid Length
input int vwapSlowLength = 60; // Slow Length
input ENUM_APPLIED_PRICE vwapAppliedTo = PRICE_CLOSE; // Applied To
//
// Presentation ...
input group "Presentation";
//
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
//
input bool showVWapFast = true; // Show VWap Fast
input bool showVWapMedium = true; // Show VWap Medium
input bool showVWapSlow = true; // Show VWap Slow
//
// Buffers ...
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
#property indicator_chart_window
//
#property indicator_buffers 11
#property indicator_plots 3
//
// Plot Buffers ...
//
// FAST ...
#define vwapFastBufferIndex 0
double vwapFastBuffer[];
#define vwapFastColorBufferIndex 1
double vwapFastColorBuffer[];
//
#define vwapFastPlotBufferIndex 0
#property indicator_label1 "X121 VWF"
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_color1 CLR_NONE, clrAqua, clrMagenta, clrGray
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//
// MID ...
#define vwapMidBufferIndex 2
double vwapMidBuffer[];
#define vwapMidColorBufferIndex 3
double vwapMidColorBuffer[];
//
#define vwapMidPlotBufferIndex 1
#property indicator_label2 "X121 VWM"
#property indicator_type2 DRAW_COLOR_LINE
#property indicator_color2 CLR_NONE, clrGreen, clrRed, clrGray
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
//
// SLOW ...
#define vwapSlowBufferIndex 4
double vwapSlowBuffer[];
#define vwapSlowColorBufferIndex 5
double vwapSlowColorBuffer[];
//
#define vwapSlowPlotBufferIndex 2
#property indicator_label3 "X121 VWS"
#property indicator_type3 DRAW_COLOR_LINE
#property indicator_color3 CLR_NONE, clrSteelBlue, clrDarkRed, clrGray
#property indicator_style3 STYLE_SOLID
#property indicator_width3 2
//
// Data Buffers ...
//
int mLastBufferIndex = 5;
//
// Volume ...
#define vwapVolumeBufferIndex mLastBufferIndex + 1
double vwapVolumeBuffer[];
//
// Price ...
#define vwapPriceBufferIndex mLastBufferIndex + 2
double vwapPriceBuffer[];
//
// Fast State ...
#define vwapFastStateBufferIndex mLastBufferIndex + 3
double vwapFastStateBuffer[];
//
// Mid State ...
#define vwapMidStateBufferIndex mLastBufferIndex + 4
double vwapMidStateBuffer[];
//
// Slow State ...
#define vwapSlowStateBufferIndex mLastBufferIndex + 5
double vwapSlowStateBuffer[];
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Indicator Handlers ...
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
// Validate Calculated Bars ...
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
result =
//
vwapFastLength > 2 &&
vwapMidLength > vwapFastLength &&
vwapSlowLength > vwapMidLength
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
// XVWAP ...
result = MathMax(result, vwapFastLength);
result = MathMax(result, vwapMidLength);
result = MathMax(result, vwapSlowLength);
//
return result;
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// Plot Buffers ...
//
// Fast ...
ArraySetAsSeries(vwapFastBuffer, true);
ArraySetAsSeries(vwapFastColorBuffer, true);
SetIndexBuffer(vwapFastBufferIndex, vwapFastBuffer, INDICATOR_DATA);
SetIndexBuffer(vwapFastColorBufferIndex, vwapFastColorBuffer, INDICATOR_COLOR_INDEX);
//
// Mid ...
ArraySetAsSeries(vwapMidBuffer, true);
ArraySetAsSeries(vwapMidColorBuffer, true);
SetIndexBuffer(vwapMidBufferIndex, vwapMidBuffer, INDICATOR_DATA);
SetIndexBuffer(vwapMidColorBufferIndex, vwapMidColorBuffer, INDICATOR_COLOR_INDEX);
//
// Slow ...
ArraySetAsSeries(vwapSlowBuffer, true);
ArraySetAsSeries(vwapSlowColorBuffer, true);
SetIndexBuffer(vwapSlowBufferIndex, vwapSlowBuffer, INDICATOR_DATA);
SetIndexBuffer(vwapSlowColorBufferIndex, vwapSlowColorBuffer, INDICATOR_COLOR_INDEX);
//
// Data Buffers ...
//
// Volumes ...
ArraySetAsSeries(vwapVolumeBuffer, true);
SetIndexBuffer(vwapVolumeBufferIndex, vwapVolumeBuffer, INDICATOR_CALCULATIONS);
//
// Price ...
ArraySetAsSeries(vwapPriceBuffer, true);
SetIndexBuffer(vwapPriceBufferIndex, vwapPriceBuffer, INDICATOR_CALCULATIONS);
//
// Fast State ...
ArraySetAsSeries(vwapFastStateBuffer, true);
SetIndexBuffer(vwapFastStateBufferIndex, vwapFastStateBuffer, INDICATOR_CALCULATIONS);
//
// Mid State ...
ArraySetAsSeries(vwapMidStateBuffer, true);
SetIndexBuffer(vwapMidStateBufferIndex, vwapMidStateBuffer, INDICATOR_CALCULATIONS);
//
// Slow State ...
ArraySetAsSeries(vwapSlowStateBuffer, true);
SetIndexBuffer(vwapSlowStateBufferIndex, vwapSlowStateBuffer, INDICATOR_CALCULATIONS);
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Calculate Custom Buffers ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
int barsLimit = startCalculationForLastBars > 0
? startCalculationForLastBars
: 0;
//
// bool canCalculate = true;
bool canCalculate =
barsLimit == 0 ||
bar_index <= barsLimit;
if (canCalculate)
{
//
// Calculate Required VWAP Data Buffers ...
if (ratesTotal - bar_index <= maxLength)
{
//
CalculateVWAPDataBuffers(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
//
// Prevent Moving Forward ...
}
else
{
//
CalculateVWAPDataBuffers(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
//
CalculateVWAPS(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
}
}
else
{
FillBuffersZero(bar_index);
}
}
//
// Custom ...
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
vwapFastBuffer[barIndex] = EMPTY_VALUE;
vwapMidBuffer[barIndex] = EMPTY_VALUE;
vwapSlowBuffer[barIndex] = EMPTY_VALUE;
vwapVolumeBuffer[barIndex] = EMPTY_VALUE;
vwapPriceBuffer[barIndex] = EMPTY_VALUE;
//
vwapFastColorBuffer[barIndex] = hideColorIDX;
vwapMidColorBuffer[barIndex] = hideColorIDX;
vwapSlowColorBuffer[barIndex] = hideColorIDX;
vwapFastStateBuffer[barIndex] = hideColorIDX;
vwapMidStateBuffer[barIndex] = hideColorIDX;
vwapSlowStateBuffer[barIndex] = hideColorIDX;
}
/**
* Calculate VWAP Value for Specified Bar ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
* @param _length: Integer, Specified VWAP Length ...
* @param _show: Boolean, Specified Show Buffer or not ...
* @param _buffer: Double Array Reference, Points to Buffer ...
* @param _colorBuffer: Double Array Reference, Points to Color Buffer ...
* @param _stateBuffer: Double Array Reference, Points to State Buffer ...
*/
void CalculateVWAP(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[],
//
int _length, // Calculation Length
bool _show,
double &_buffer[],
double &_colorBuffer[],
double &_stateBuffer[] //
)
{
//
double vSum = 0;
double pSum = 0;
double mSum = 0;
for (int x = 0; x < _length; x++)
{
//
pSum += vwapPriceBuffer[x + bar_index];
vSum += vwapVolumeBuffer[x + bar_index];
mSum += vwapPriceBuffer[x + bar_index] * vwapVolumeBuffer[x + bar_index];
}
//
double iValue = mSum / vSum;
iValue = NormalizeDouble(iValue, _Digits);
//
_buffer[bar_index] = iValue;
//
bool isBullish = low[bar_index] > iValue;
bool isBearish = high[bar_index] < iValue;
//
double iColor =
isBullish
? bullishColorIDX
: isBearish
? bearishColorIDX
: neuturalColorIDX;
//
_colorBuffer[bar_index] = hideColorIDX;
_stateBuffer[bar_index] = iColor;
if (_show)
{
_colorBuffer[bar_index] = iColor;
}
}
/**
* Calculate VWAP Required Data Buffers ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateVWAPDataBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
ENUM_X_PRICE mPType = ToXPrice(vwapAppliedTo);
double price = GetAppliedPrice(
mPType,
open,
high,
low,
close,
bar_index //
);
vwapPriceBuffer[bar_index] = price;
vwapVolumeBuffer[bar_index] = (double)tickVolume[bar_index];
}
/**
* Calculate Different VWaps ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateVWAPS(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Fast ...
CalculateVWAP(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume,
//
vwapFastLength,
showVWapFast,
vwapFastBuffer,
vwapFastColorBuffer,
vwapFastStateBuffer //
);
//
// Mid ...
CalculateVWAP(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume,
//
vwapMidLength,
showVWapMedium,
vwapMidBuffer,
vwapMidColorBuffer,
vwapMidStateBuffer //
);
//
// Fast ...
CalculateVWAP(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume,
//
vwapSlowLength,
showVWapSlow,
vwapSlowBuffer,
vwapSlowColorBuffer,
vwapSlowStateBuffer //
);
}
//

Some files were not shown because too many files have changed in this diff Show More