2221 lines
51 KiB
Plaintext
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
|
|
|
|
//
|
|
};
|
|
|
|
// |