Files
MQL5Data/X121XKIEA/Classes/x-saherelm.x121.xki.signaller.class.mq5
T
2026-01-04 16:38:38 +03:30

2221 lines
51 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class
// -------------------------------------------------
// Name: XCX121XKISignaller ...
// Description: X121XKI Signaller 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 X121XKI Signaller Class"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-signaller.class.mq5"
#include "../../Helpers/x-saherelm.x121.xki.helper.mq5"
#include "../Classes/x-saherelm.x121.xki.parser.class.mq5"
#include "../Classes/x-saherelm.x121.xki.x-poi.detector.class.mq5"
#include "../Classes/x-saherelm.x121.xki.x-poi.drawer.class.mq5"
#include "../Libraries/x-saherelm.x121.xki.lib.mq5"
//
// Implementation ...
//
// Base X121XKI base Signaller ...
class XCX121XKIBaseSignaller : public XCBaseSignaller
{
//
// Public ...
public:
//
// Props ...
//
CArrayObj drawnObjects; // Drawing Objects Holder ...
X121XKIInputs kiInputs; // X121XKI Inputs ...
XCX121XKIHelper *kiHelper; // X121XKI Indicator Helper ...
XCX121XKIPOIDrawer *poiDrawer; // X121XKI POI Drawer ...
XCX121XKIPOIDetector *poiDetector; // X121XKI POI Detector ...
XCX121XKIHelperParser *kiParser; // X121XKI Helper Parser ...
//
// Constructor ...
XCX121XKIBaseSignaller(
string _name, // Name ...
string _symbol, // Symbol ...
ENUM_TIMEFRAMES _period, // Period ...
X121XKIInputs &_kiInputs, // X121XKIInputs ...
bool _processAllTicks = false, // Process All Ticks ...
double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ...
double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ...
double _defaultSignalVolume = 0.01 // Default Signal Volume ...
) : XCBaseSignaller(_name,
_symbol,
_period,
_processAllTicks,
_defaultSignalR2R,
_defaultSignalRiskInPoint,
_defaultSignalVolume //
)
{
//
// Instantiating X121XKI Indicator Helper Class ...
if (_kiInputs.IsValid())
{
//
kiHelper = new XCX121XKIHelper();
bool isInited = kiHelper.Init(
_symbol,
_period,
_kiInputs //
);
if (isInited)
{
kiInputs = _kiInputs;
}
else
{
//
delete kiHelper;
ZeroMemory(kiHelper);
}
}
//
// Instantiate X121XKI Helper Parser ...
kiParser = new XCX121XKIHelperParser(kiHelper);
//
poiDrawer = new XCX121XKIPOIDrawer();
poiDetector = new XCX121XKIPOIDetector(kiHelper, kiParser);
}
//
// Deconstructor ...
~XCX121XKIBaseSignaller()
{
Destroy();
}
//
// Overrides ...
//
// Actions ...
/**
* Destroy ...
*/
void Destroy()
{
//
BeforeDestroy();
//
kiInputs.Clean();
//
delete poiDrawer;
ZeroMemory(poiDrawer);
//
delete poiDetector;
ZeroMemory(poiDetector);
//
delete kiHelper;
ZeroMemory(kiHelper);
}
//
// Virtuals ...
/**
* Before Destroy ...
*/
void virtual BeforeDestroy()
{
}
/**
* Processing Tick ...
*
* @param barIndex: int, Specified Bar Index ...
*/
virtual void ProcessTick(int barIndex = 0)
{
}
/**
* Processing New Bar ...
*
* @param barIndex: int, Specified Bar Index ...
*/
virtual void ProcessNewBar(int barIndex = 0)
{
}
/**
* Check Guards Based on MarketConditions ...
*
* @param guards: XGuard, reference collection to holds result ...
* @param positions: XPosition, reference collection to provides positions ...
* @param barIndex: int
*
* @return ( int )
*/
int virtual CheckForGuard(
XGuard &guards[],
XPosition &positions[],
int barIndex = 0 //
)
{
//
int result = 0;
//
SpecifiedClean(guards);
//
result = ArraySize(guards);
//
return result;
}
/**
* Check Additional Validations on Childs Instances ...
*
* @return ( bool virtual )
*/
bool virtual CheckAdditionslSignallerValidations()
{
//
bool result = false;
//
// Validate Fima Helper Requirements ...
result = kiInputs.IsValid() &&
kiHelper != NULL &&
poiDetector != NULL;
if (!result)
{
return result;
}
//
return result;
}
/**
* Normalizing Signal by Signaller Custom Props ...
*
* @param signal: XSignal ...
*/
void virtual NormalizeSignal(XSignal &signal)
{
}
//
// Protected ...
protected:
//
//
// Protected Actions ...
//
// Private ...
private:
//
};
//
// X121XKI Strategy 1 Signaller Class ...
class XCX121XKIStrategy1Signaller : public XCX121XKIBaseSignaller
{
//
// Public ...
public:
//
// Props ...
//
// Constructor ...
XCX121XKIStrategy1Signaller(
string _symbol, // Symbol ...
ENUM_TIMEFRAMES _period, // Period ...
X121XKIInputs &_kiInputs, // X121XKIInputs ...
bool _processAllTicks = false, // Process All Ticks ...
double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ...
double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ...
double _defaultSignalVolume = 0.01 // Default Signal Volume ...
) : XCX121XKIBaseSignaller("X121XKI1",
_symbol,
_period,
_kiInputs,
_processAllTicks,
_defaultSignalR2R,
_defaultSignalRiskInPoint,
_defaultSignalVolume //
)
{
}
//
// Deconstructor ...
~XCX121XKIStrategy1Signaller()
{
//
Destroy();
}
//
// Overrides ...
/**
* Processing Tick ...
*
* @param barIndex: int, Specified Bar Index ...
*/
virtual void ProcessTick(int barIndex = 0)
{
}
/**
* Processing New Bar ...
*
* @param barIndex: int, Specified Bar Index ...
*/
virtual void ProcessNewBar(int barIndex = 0)
{
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
XOHCL iBar;
XBoxZone iZone;
XSignal iSignal;
bool has = false;
XTarget iTargets[];
bool isBullish = false;
bool isBearish = false;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
// Initialize Bar as CBar ...
has = iBar.Init(
symbol,
period,
barIndex //
);
if (!has)
{
//
iBar.Clean();
return;
}
//
// Strategy X ...
has = HasSignal(
iBar,
iZone,
iTargets,
iDir //
);
//
// Handle Resting Signals ...
has = HasDirection(iDir) &&
iZone.IsValid();
//
// Prepare Signal ...
if (has)
{
//
isBullish = IsXBullish(iDir);
isBearish = IsXBearish(iDir);
//
// Provided SL ...
double points = GetPoints(symbol);
double spread = GetSpread(symbol);
double entry = GetEntry(symbol, iDir);
//
// Calculate SL Addition ...
double slAddition =
slAdditionDistance <= 0
? 0
: slAdditionDistance * points;
//
// Calculate SL Price ...
double sl =
isBullish
? iZone.lower - slAddition
: iZone.upper + slAddition;
//
// Prepare Signal ...
has = PrepareSignal(
iSignal,
iDir,
iTargets,
0, // Use Default R2R ...
sl, // Provided Price for SL ...
0 // Specified Risk in Point ....
);
if (has)
{
iSignal.provider += "_" + iZone.type;
}
}
//
// Notify On Signal Event ...
if (has)
{
NotifySignalEventListeners(iSignal);
}
//
// Cleanup ...
iBar.Clean();
iZone.Clean();
iSignal.Clean();
XClean(iTargets);
}
/**
* Check Guards Based on MarketConditions ...
*
* @param guards: XGuard, reference collection to holds result ...
* @param positions: XPosition, reference collection to provides positions ...
* @param barIndex: int
*
* @return ( int )
*/
int virtual CheckForGuard(
XGuard &guards[],
XPosition &positions[],
int barIndex = 0 //
)
{
//
int result = 0;
//
XClean(guards);
return result;
//
int positionsCount = ArraySize(positions);
if (!IsValidSize(positionsCount))
{
return result;
}
//
// Requirements ...
XGuard iGuard;
bool has = false;
int samePeaks = 0;
int sameVales = 0;
double iValue = 0;
double points10 = 0;
double points50 = 0;
double points100 = 0;
string provider = NULL;
int samePVValidation = 5;
bool isPeakOverLast = false;
bool isValeUnderLast = false;
//
for (int i = 0; i < positionsCount; i++)
{
//
points10 = 10 * positions[i].GetPointsValue();
points50 = 50 * positions[i].GetPointsValue();
points100 = 100 * positions[i].GetPointsValue();
//
// Check Provided By Strategy 1 ...
provider = positions[i].provider;
StringReplace(
provider,
name,
"" //
);
has = Contains(ToXString(X121_XKI_STRATEGY_1), positions[i].provider);
if (has)
{
//
// Now we Check Exit ...
// if (positions[i].IsLong())
// {
// has = ExitBullishPOILong();
// }
// else if (positions[i].IsShort())
// {
// has = ExitBearishPOIShort();
// }
// //
// if (has)
// {
// }
}
}
//
result = ArraySize(guards);
//
// Cleanup ...
iGuard.Clean();
//
return result;
}
//
// Protected ...
protected:
//
//
// Private ...
private:
//
// Props ...
//
// Implementing Strategies ...
/**
* 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 HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Configuration Flags ...
//
// Signaller Flags ...
bool useSignaller1 = true;
bool useSignaller2 = false;
bool useSignaller3 = false;
bool useSignaller4 = false;
bool useSignaller5 = false;
bool useSignaller6 = false;
//
XBoxZone tmpZone;
string provider = NULL;
ENUM_X_DIRECTION tmpDir;
//
bool signaller1HasSignal = false;
bool signaller2HasSignal = false;
bool signaller3HasSignal = false;
bool signaller4HasSignal = false;
bool signaller5HasSignal = false;
bool signaller6HasSignal = false;
//
// Validator Flags ...
bool validateByOrderFlow = false;
//
// Target Flags ...
bool hasPartialCloseOnTp1 = false;
//
bool doRFOnEntryOnTP1 = false;
//
// Draw Flags ...
bool draw = true;
//
// Signal Checking ...
//
// Signal Detection Flags ...
//
// Signaller 1 ...
// POI ...
if (useSignaller1)
{
//
signaller1HasSignal = Strategy1HasSignal(
bar,
tmpZone,
targets,
tmpDir //
);
//
if (signaller1HasSignal)
{
//
provider += ToXString(X121_XKI_STRATEGY_1);
//
if (!zone.IsValid())
{
//
dir = tmpDir;
zone = tmpZone;
}
}
//
tmpZone.Clean();
tmpDir = X_DIRECTION_NONE;
}
//
// Signaller 2 ...
// Breakout POI ...
if (useSignaller2)
{
//
signaller2HasSignal = Strategy2HasSignal(
bar,
tmpZone,
targets,
tmpDir //
);
//
if (signaller2HasSignal)
{
//
provider += ToXString(X121_XKI_STRATEGY_2);
//
if (!zone.IsValid())
{
//
dir = tmpDir;
zone = tmpZone;
}
}
//
tmpZone.Clean();
tmpDir = X_DIRECTION_NONE;
}
//
// Signaller 3 ...
// Reversal ...
if (useSignaller3)
{
//
signaller3HasSignal = Strategy3HasSignal(
bar,
tmpZone,
targets,
tmpDir //
);
//
if (signaller3HasSignal)
{
//
provider += ToXString(X121_XKI_STRATEGY_3);
//
if (!zone.IsValid())
{
//
dir = tmpDir;
zone = tmpZone;
}
}
//
tmpZone.Clean();
tmpDir = X_DIRECTION_NONE;
}
//
// Signaller 4 ...
// Continuation ...
if (useSignaller4)
{
//
signaller4HasSignal = Strategy4HasSignal(
bar,
tmpZone,
targets,
tmpDir //
);
//
if (signaller4HasSignal)
{
//
provider += ToXString(X121_XKI_STRATEGY_4);
//
if (!zone.IsValid())
{
//
dir = tmpDir;
zone = tmpZone;
}
}
//
tmpZone.Clean();
tmpDir = X_DIRECTION_NONE;
}
//
// Signaller 5 ...
// Exhaustion ...
if (useSignaller5)
{
//
signaller5HasSignal = Strategy5HasSignal(
bar,
tmpZone,
targets,
tmpDir //
);
//
if (signaller5HasSignal)
{
//
provider += ToXString(X121_XKI_STRATEGY_5);
//
if (!zone.IsValid())
{
//
dir = tmpDir;
zone = tmpZone;
}
}
//
tmpZone.Clean();
tmpDir = X_DIRECTION_NONE;
}
//
// Signaller 6 ...
// Trend Exhaustion ...
if (useSignaller6)
{
//
signaller6HasSignal = Strategy6HasSignal(
bar,
tmpZone,
targets,
tmpDir //
);
//
if (signaller6HasSignal)
{
//
provider += ToXString(X121_XKI_STRATEGY_6);
//
if (!zone.IsValid())
{
//
dir = tmpDir;
zone = tmpZone;
}
}
//
tmpZone.Clean();
tmpDir = X_DIRECTION_NONE;
}
//
// Summarize Signallers Result ...
result = signaller1HasSignal ||
signaller2HasSignal ||
signaller3HasSignal ||
signaller4HasSignal ||
signaller5HasSignal ||
signaller6HasSignal;
//
// Signal Validating ...
//
// Targets, Restrictions and Risk Management ...
if (result)
{
//
// Requirements ...
XTarget iTarget;
//
// Checking Direction of Signal ...
bool isBullish = IsXBullish(dir);
bool isBearish = IsXBearish(dir);
//
// Provided SL ...
double points = GetPoints(symbol);
double spread = GetSpread(symbol);
double entry = GetEntry(symbol, dir);
//
// Calculate SL Addition ...
double slAddition =
slAdditionDistance <= 0
? 0
: slAdditionDistance * points;
//
// Calculate SL Price ...
double sl =
isBullish
? zone.lower - slAddition
: zone.upper + slAddition;
//
// Calculate Risk ...
double risk = MathAbs(entry - sl);
//
// Calculate Reward ...
double reward = defaultSignalR2R * risk;
//
// Calculate TP1 ...
double tp1 = isBullish
? entry + risk
: entry - risk;
double tp2 = isBullish
? entry + (2 * risk)
: entry - (2 * risk);
//
// Calculate TP ...
double tp = isBullish
? entry + reward
: entry - reward;
//
// Check Max Allowed Risk ...
bool hasTooMuchRisk = maxAllowedRiskDistance <= 0
? false
: risk >= (maxAllowedRiskDistance * points);
if (hasTooMuchRisk)
{
//
// Clean Signal if Too much Risk ...
zone.Clean();
dir = X_DIRECTION_NONE;
}
//
// Common Targets ...
//
// Partial Close on TP 1 ...
if (hasPartialCloseOnTp1)
{
//
iTarget.Clean();
iTarget.target = tp1;
iTarget.actingDistance = 5;
iTarget.volumeMultiplier = 0.8;
iTarget.doRFOnEntry = doRFOnEntryOnTP1;
//
AddRef(iTarget, targets);
}
//
// Custom Signaller Targets ...
//
// Restrictions Handling ...
if (risk > 0 && HasRestrictions())
{
//
// Reset Restricitons if necessary ...
ResetRestrictions();
//
// Handle Custom Restrictions Senario ...
}
//
// Ignore Targets ...
if (ignoreTargets)
{
XClean(targets);
}
//
// Summarize Result ...
result = zone.IsValid() &&
HasDirection(dir);
if (result)
{
zone.type = "" + provider;
}
//
// Cleanup ...
iTarget.Clean();
}
//
// Draws ...
if (result && draw)
{
//
// Other Drawing Materials ...
XPOIDrawConfig drawConfig;
drawConfig.Default();
//
poiDrawer.DrawZone(zone, drawConfig);
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
//
// Cleanup ...
tmpZone.Clean();
//
return result;
}
// #region Custom Signal Strategies ...
/**
* Check Bar Has Signal Based on Strategy 1 ...
* POI ...
*
* @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;
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int scoreBullish = 0;
int scoreBearish = 0;
bool isBullish = false;
bool isBearish = false;
int barIndex = bar.Index() + 1;
//
// Initialize Indexed Bar ...
XOHCL iBar;
result = iBar.Init(bar.symbol, bar.period, barIndex);
if (!result)
{
return result;
}
// #region Market Structure ...
XBoxZone supports[];
XBoxZone resistances[];
XBoxZone minorSupport;
XBoxZone majorSupport;
XBoxZone minorResistance;
XBoxZone majorResistance;
poiDetector.GetCurrentStructure(
supports,
resistances,
minorSupport,
majorSupport,
minorResistance,
majorResistance,
barIndex,
bar.symbol,
iBar.period, // Minor ...
PERIOD_H1, // Major ...
50,
14,
21,
0 //
);
//
// Refining Zones ...
int refineLoopback = 500;
double refineBreakThreshold = 10;
ENUM_X_PRICE refineBreakBy = X_PRICE_CLOSE;
poiDetector.RefineStructure(
supports,
resistances,
minorSupport,
majorSupport,
minorResistance,
majorResistance,
refineLoopback,
refineBreakThreshold,
refineBreakBy //
);
// #endregion
// #region Reading Conditions and Scoring ...
//
// ATR ...
bool isATRUp = kiParser.IsVolatilityHigh(barIndex) ||
kiParser.IsVolatilitySwitchdToHigh(barIndex);
// #region KI ...
//
bool isKIBullish = (kiParser.IsKIFastBullish(barIndex) ||
kiParser.IsKIFastSwitchedToBullish(barIndex)) &&
(kiParser.IsKISlowBullish(barIndex) ||
kiParser.IsKISlowSwitchedToBullish(barIndex));
if (isKIBullish)
{
scoreBullish++;
}
//
bool isKIBearish = (kiParser.IsKIFastBearish(barIndex) ||
kiParser.IsKIFastSwitchedToBearish(barIndex)) &&
(kiParser.IsKISlowBearish(barIndex) ||
kiParser.IsKISlowSwitchedToBearish(barIndex));
if (isKIBearish)
{
scoreBearish++;
}
// #endregion
// #region KI Wave ...
//
bool isKIWaveBullish = kiParser.IsKIWaveBullish(barIndex) ||
kiParser.IsKIWaveSwitchedToBullish(barIndex);
if (isKIWaveBullish)
{
scoreBullish++;
}
//
bool isKIWaveBearish = kiParser.IsKIWaveBearish(barIndex) ||
kiParser.IsKIWaveSwitchedToBearish(barIndex);
if (isKIWaveBearish)
{
scoreBearish++;
}
// #endregion
// #region MA ...
//
bool isMaBullish = kiParser.IsMACrossoverBullish(barIndex) ||
kiParser.IsMACrossoverSwitchedToBullish(barIndex);
if (isMaBullish)
{
scoreBullish++;
}
//
bool isMaBearish = kiParser.IsMACrossoverBearish(barIndex) ||
kiParser.IsMACrossoverSwitchedToBearish(barIndex);
if (isMaBearish)
{
scoreBearish++;
}
// #endregion
// #region LowerTF Candlstick ...
//
bool isLowerTFBullish = IsTFBullishPattern(barIndex, PERIOD_M5);
if (isLowerTFBullish)
{
scoreBullish++;
}
//
bool isLowerTFBearish = IsTFBearishPattern(barIndex, PERIOD_M5);
if (isLowerTFBearish)
{
scoreBearish++;
}
// #endregion
// #region Candlestick ...
//
bool isCandlestickBullish = poiDetector.HasCandlestickDirection(
iBar,
X_DIRECTION_BULLISH //
);
if (isCandlestickBullish)
{
scoreBullish++;
}
//
bool isCandlestickBearish = poiDetector.HasCandlestickDirection(
iBar,
X_DIRECTION_BEARISH //
);
if (isCandlestickBearish)
{
scoreBearish++;
}
// #endregion
// #region NearInside Support/Resistance ...
//
int tmpSupportIDX = -1;
bool isNearSupport = poiDetector.HasNearZone(tmpSupportIDX, iBar.close, 5, supports);
if (isNearSupport)
{
scoreBullish++;
}
//
int tmpResistanceIDX = -1;
bool isNearResistance = poiDetector.HasNearZone(tmpResistanceIDX, iBar.close, 5, resistances);
if (isNearResistance)
{
scoreBearish++;
}
// #endregion
// #endregion
// #region Summarize Directional Conditions ...
//
isBullish =
isATRUp &&
scoreBullish >= 4 &&
(isMaBullish ||
isNearSupport ||
isKIWaveBullish ||
isLowerTFBullish ||
isCandlestickBullish);
//
isBearish =
isATRUp &&
scoreBearish >= 4 &&
(isMaBearish ||
isNearResistance ||
isKIWaveBearish ||
isLowerTFBearish ||
isCandlestickBearish);
// #endregion
//
// Validate Conditions ...
result = isBullish || isBearish;
if (!result)
{
//
iBar.Clean();
XClean(supports);
XClean(resistances);
minorSupport.Clean();
majorSupport.Clean();
minorResistance.Clean();
majorResistance.Clean();
//
return result;
}
//
// Select Operational Zone ...
if (isBullish)
{
//
// Nearest Support ...
if (IsValidIndex(tmpSupportIDX))
{
zone = supports[tmpSupportIDX];
}
//
// Make Sure Zone Exists ...
if (!zone.IsValid())
{
//
// Looking Bar Patterns to Detect Zone ...
poiDetector.HasRecentPatternTouched(zone, iBar.close, barIndex, 5, 5, iBar.period, X_DIRECTION_BULLISH);
}
}
else if (isBearish)
{
//
// Nearest Resistance ...
if (IsValidIndex(tmpResistanceIDX))
{
zone = resistances[tmpResistanceIDX];
}
//
// Make Sure Zone Exists ...
if (!zone.IsValid())
{
//
// Looking Bar Patterns to Detect Zone ...
poiDetector.HasRecentPatternTouched(zone, iBar.close, barIndex, 5, 5, iBar.period, X_DIRECTION_BEARISH);
}
}
//
// Refactor Result ...
result = result &&
zone.IsValid();
if (result)
{
//
// Refine Zone ...
poiDetector.RefineZone(zone);
//
// SL Refactoring ...
//
XOHCL toBar;
if (zone.ToBar(toBar))
{
//
int to = zone.ToIndex();
int from = zone.FromIndex();
int length = from - to;
double iValue =
isBullish
? toBar.FindLowest(length, MODE_LOW)
: isBearish
? toBar.FindHighest(length, MODE_HIGH)
: EMPTY_VALUE;
if (NotEmptyZero(iValue))
{
//
if (isBullish)
{
zone.lower = MathMin(zone.lower, iValue);
}
//
if (isBearish)
{
zone.upper = MathMax(zone.upper, iValue);
}
}
}
toBar.Clean();
}
//
// Do Directional Validation ...
if (result)
{
//
// Bullish ...
if (isBullish)
{
//
isBullish =
isBullish &&
isLowerTFBullish &&
isCandlestickBullish;
}
//
// Bearish ...
if (isBearish)
{
//
isBearish =
isBearish &&
isLowerTFBearish &&
isCandlestickBearish;
}
//
result = isBullish || isBearish;
if (!result)
{
//
isBullish = false;
isBearish = false;
}
}
//
// Validate Result ...
if (!result)
{
//
iBar.Clean();
XClean(supports);
XClean(resistances);
minorSupport.Clean();
majorSupport.Clean();
minorResistance.Clean();
majorResistance.Clean();
//
return result;
}
//
// Draws ...
bool draw = true;
if (draw && result)
{
//
int drawn = 0;
//
XPOIDrawConfig config;
config.Default();
//
if (zone.IsValid())
{
//
drawn++;
//
config.zonesWidth = 3;
config.bullishColor = clrYellow;
config.bearishColor = clrOrange;
//
poiDrawer.DrawZone(zone, config);
//
config.Default();
}
//
// Minors ...
if (minorSupport.IsValid())
{
//
drawn++;
poiDrawer.DrawZone(minorSupport, config);
}
if (minorResistance.IsValid())
{
//
drawn++;
poiDrawer.DrawZone(minorResistance, config);
}
//
// Majors ...
config.bullishColor = clrLime;
config.bearishColor = clrRed;
config.zonesWidth = 4;
//
if (majorSupport.IsValid())
{
//
drawn++;
poiDrawer.DrawZone(majorSupport, config);
}
if (majorResistance.IsValid())
{
//
drawn++;
poiDrawer.DrawZone(majorResistance, config);
}
//
config.Clean();
//
if (drawn > 0)
{
DebugBreak();
}
}
//
// Check and Prepare Direction ...
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish ? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
result = result &&
HasDirection(dir);
if (!result)
{
//
iBar.Clean();
XClean(supports);
XClean(resistances);
minorSupport.Clean();
majorSupport.Clean();
minorResistance.Clean();
majorResistance.Clean();
//
return result;
}
//
// Prepare Zone ...
double entry = GetEntry(iBar.symbol, dir);
if (result)
{
//
double upper = isBullish
? entry
: zone.upper;
double lower = isBullish
? zone.lower
: entry;
datetime to = bar.time;
datetime from = isBullish
? zone.from
: zone.from;
result = zone.Init(
iBar.symbol,
iBar.period,
upper,
lower,
from,
to,
dir,
"XS1" //
);
}
//
// Cleanup Resources ...
iBar.Clean();
XClean(supports);
XClean(resistances);
minorSupport.Clean();
majorSupport.Clean();
minorResistance.Clean();
majorResistance.Clean();
//
result =
result &&
zone.IsValid() &&
HasDirection(dir);
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 2 ...
* Breakout POI ...
*
* @return ( bool )
*/
bool Strategy2HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int barIndex = bar.Index() + 1;
//
// Retrieve Base Conditions ...
bool isBullish = false;
bool isBearish = false;
//
// Validate Conditions ...
result = isBullish || isBearish;
if (!result)
{
return result;
}
//
// Do Validation and Filtering Market Structure if required ...
//
// Check and Prepare Direction ...
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish ? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
result = HasDirection(dir);
if (!result)
{
return result;
}
//
// Prepare Zone ...
//
result =
result &&
zone.IsValid() &&
HasDirection(dir);
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 3 ...
* Reversal ...
*
* @return ( bool )
*/
bool Strategy3HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int barIndex = bar.Index() + 1;
//
// Retrieve Base Conditions ...
bool isBullish = false;
bool isBearish = false;
//
// Validate Conditions ...
result = isBullish || isBearish;
if (!result)
{
return result;
}
//
// Do Validation and Filtering Market Structure if required ...
//
// Check and Prepare Direction ...
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish ? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
result = HasDirection(dir);
if (!result)
{
return result;
}
//
// Prepare Zone ...
//
result =
result &&
zone.IsValid() &&
HasDirection(dir);
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 4 ...
* Continuation ...
*
* @return ( bool )
*/
bool Strategy4HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int barIndex = bar.Index() + 1;
//
// Retrieve Base Conditions ...
bool isBullish = false;
bool isBearish = false;
//
// Validate Conditions ...
result = isBullish || isBearish;
if (!result)
{
return result;
}
//
// Do Validation and Filtering Market Structure if required ...
//
// Check and Prepare Direction ...
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish ? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
result = HasDirection(dir);
if (!result)
{
return result;
}
//
// Prepare Zone ...
//
result =
result &&
zone.IsValid() &&
HasDirection(dir);
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 5 ...
* Exhaustion ...
*
* @return ( bool )
*/
bool Strategy5HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int barIndex = bar.Index() + 1;
//
// Retrieve Base Conditions ...
bool isBullish = false;
bool isBearish = false;
//
// Validate Conditions ...
result = isBullish || isBearish;
if (!result)
{
return result;
}
//
// Do Validation and Filtering Market Structure if required ...
//
// Check and Prepare Direction ...
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish ? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
result = HasDirection(dir);
if (!result)
{
return result;
}
//
// Prepare Zone ...
//
result =
result &&
zone.IsValid() &&
HasDirection(dir);
//
return result;
}
/**
* Check Bar Has Signal Based on Strategy 6 ...
* Trend Exhaustion ...
*
* @return ( bool )
*/
bool Strategy6HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int barIndex = bar.Index() + 1;
//
// Retrieve Base Conditions ...
bool isBullish = false;
bool isBearish = false;
//
// Validate Conditions ...
result = isBullish || isBearish;
if (!result)
{
return result;
}
//
// Do Validation and Filtering Market Structure if required ...
//
// Check and Prepare Direction ...
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish ? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
result = HasDirection(dir);
if (!result)
{
return result;
}
//
// Prepare Zone ...
//
result =
result &&
zone.IsValid() &&
HasDirection(dir);
//
return result;
}
// #endregion
// #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
// #region TF Patterns ...
bool IsTFBullishPattern(
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = kiParser.NormalizeBarIndex(barIndex);
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
//
XOHCL bar;
result = bar.Init(symbol, forPeriod, barIndex) &&
poiDetector.HasCandlestickDirection(bar, X_DIRECTION_BULLISH);
bar.Clean();
//
return result;
}
bool IsTFBearishPattern(
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = kiParser.NormalizeBarIndex(barIndex);
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
//
XOHCL bar;
result = bar.Init(symbol, forPeriod, barIndex) &&
poiDetector.HasCandlestickDirection(bar, X_DIRECTION_BEARISH);
bar.Clean();
//
return result;
}
// #endregion
//
};
//