1342 lines
31 KiB
Plaintext
1342 lines
31 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"
|
||
|
||
//
|
||
// 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 ....
|
||
);
|
||
}
|
||
|
||
//
|
||
// 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;
|
||
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();
|
||
|
||
//
|
||
// Near to TP Guard ...
|
||
has = positions[i].profit > 0;
|
||
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;
|
||
|
||
//
|
||
XBoxZone tmpZone;
|
||
string provider = NULL;
|
||
ENUM_X_DIRECTION tmpDir;
|
||
|
||
//
|
||
bool signaller1HasSignal = false;
|
||
bool signaller2HasSignal = false;
|
||
bool signaller3HasSignal = false;
|
||
bool signaller4HasSignal = false;
|
||
bool signaller5HasSignal = 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 ...
|
||
if (useSignaller1)
|
||
{
|
||
//
|
||
signaller1HasSignal = Strategy1HasSignal(
|
||
bar,
|
||
tmpZone,
|
||
targets,
|
||
tmpDir //
|
||
);
|
||
|
||
//
|
||
if (signaller1HasSignal)
|
||
{
|
||
//
|
||
provider += "1";
|
||
|
||
//
|
||
if (!zone.IsValid())
|
||
{
|
||
//
|
||
dir = tmpDir;
|
||
zone = tmpZone;
|
||
}
|
||
}
|
||
|
||
//
|
||
tmpZone.Clean();
|
||
tmpDir = X_DIRECTION_NONE;
|
||
}
|
||
|
||
//
|
||
// Signaller 2 ...
|
||
if (useSignaller2)
|
||
{
|
||
//
|
||
signaller2HasSignal = Strategy2HasSignal(
|
||
bar,
|
||
tmpZone,
|
||
targets,
|
||
tmpDir //
|
||
);
|
||
|
||
//
|
||
if (signaller2HasSignal)
|
||
{
|
||
//
|
||
provider += "2";
|
||
|
||
//
|
||
if (!zone.IsValid())
|
||
{
|
||
//
|
||
dir = tmpDir;
|
||
zone = tmpZone;
|
||
}
|
||
}
|
||
|
||
//
|
||
tmpZone.Clean();
|
||
tmpDir = X_DIRECTION_NONE;
|
||
}
|
||
|
||
//
|
||
// Signaller 3 ...
|
||
if (useSignaller3)
|
||
{
|
||
//
|
||
signaller3HasSignal = Strategy3HasSignal(
|
||
bar,
|
||
tmpZone,
|
||
targets,
|
||
tmpDir //
|
||
);
|
||
|
||
//
|
||
if (signaller3HasSignal)
|
||
{
|
||
//
|
||
provider += "3";
|
||
|
||
//
|
||
if (!zone.IsValid())
|
||
{
|
||
//
|
||
dir = tmpDir;
|
||
zone = tmpZone;
|
||
}
|
||
}
|
||
|
||
//
|
||
tmpZone.Clean();
|
||
tmpDir = X_DIRECTION_NONE;
|
||
}
|
||
|
||
//
|
||
// Signaller 4 ...
|
||
if (useSignaller4)
|
||
{
|
||
//
|
||
signaller4HasSignal = Strategy4HasSignal(
|
||
bar,
|
||
tmpZone,
|
||
targets,
|
||
tmpDir //
|
||
);
|
||
|
||
//
|
||
if (signaller4HasSignal)
|
||
{
|
||
//
|
||
provider += "4";
|
||
|
||
//
|
||
if (!zone.IsValid())
|
||
{
|
||
//
|
||
dir = tmpDir;
|
||
zone = tmpZone;
|
||
}
|
||
}
|
||
|
||
//
|
||
tmpZone.Clean();
|
||
tmpDir = X_DIRECTION_NONE;
|
||
}
|
||
|
||
//
|
||
// Signaller 5 ...
|
||
if (useSignaller5)
|
||
{
|
||
//
|
||
signaller5HasSignal = Strategy5HasSignal(
|
||
bar,
|
||
tmpZone,
|
||
targets,
|
||
tmpDir //
|
||
);
|
||
|
||
//
|
||
if (signaller5HasSignal)
|
||
{
|
||
//
|
||
provider += "5";
|
||
|
||
//
|
||
if (!zone.IsValid())
|
||
{
|
||
//
|
||
dir = tmpDir;
|
||
zone = tmpZone;
|
||
}
|
||
}
|
||
|
||
//
|
||
tmpZone.Clean();
|
||
tmpDir = X_DIRECTION_NONE;
|
||
}
|
||
|
||
//
|
||
// Summarize Signallers Result ...
|
||
result = signaller1HasSignal ||
|
||
signaller2HasSignal ||
|
||
signaller3HasSignal ||
|
||
signaller4HasSignal ||
|
||
signaller5HasSignal;
|
||
|
||
//
|
||
// 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);
|
||
|
||
//
|
||
// 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;
|
||
}
|
||
|
||
//
|
||
// Custom Signal Strategies ...
|
||
|
||
/**
|
||
* Check Bar Has Signal Based on Strategy 1 ...
|
||
*
|
||
* Pattern‑based reversal:
|
||
* - Detects Pin Bar or Signal Key Bar.
|
||
* - Confirms with POI detector.
|
||
* - Good for reversals at support/resistance.
|
||
*
|
||
* @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;
|
||
}
|
||
|
||
//
|
||
result = poiDetector.IsKISignal(
|
||
dir,
|
||
bar.Index() //
|
||
);
|
||
bool isBullish = result &&
|
||
IsXBullish(dir);
|
||
bool isBearish = result &&
|
||
IsXBearish(dir);
|
||
result = isBullish ||
|
||
isBearish;
|
||
if (!result)
|
||
{
|
||
return result;
|
||
}
|
||
|
||
//
|
||
// Detect Nearest Directional ...
|
||
int nearestDirectionalSwitchIndex = -1;
|
||
if (isBullish)
|
||
{
|
||
//
|
||
isBullish = poiDetector.NearestKIFastSwitchedToBullish(
|
||
nearestDirectionalSwitchIndex,
|
||
bar.Index() + 2 //
|
||
);
|
||
}
|
||
else
|
||
{
|
||
//
|
||
isBearish = poiDetector.NearestKIFastSwitchedToBearish(
|
||
nearestDirectionalSwitchIndex,
|
||
bar.Index() + 2 //
|
||
);
|
||
}
|
||
result =
|
||
IsValidIndex(nearestDirectionalSwitchIndex) &&
|
||
(isBullish ||
|
||
isBearish);
|
||
if (!result)
|
||
{
|
||
//
|
||
bar.Clean();
|
||
return result;
|
||
}
|
||
|
||
//
|
||
// Preparing Zone ...
|
||
double upper = bar.FindHighest(nearestDirectionalSwitchIndex - bar.Index(), MODE_HIGH);
|
||
double lower = bar.FindLowest(nearestDirectionalSwitchIndex - bar.Index(), MODE_LOW);
|
||
|
||
//
|
||
result = zone.Init(
|
||
symbol,
|
||
period,
|
||
upper,
|
||
lower,
|
||
GetBarTime(symbol, period, nearestDirectionalSwitchIndex),
|
||
bar.time,
|
||
dir,
|
||
"XKI1" //
|
||
);
|
||
|
||
//
|
||
// Support and Resistance ...
|
||
XBoxZone support;
|
||
XBoxZone resistance;
|
||
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,
|
||
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,
|
||
X_BAR_PATTERN_RESISTANCE //
|
||
);
|
||
|
||
//
|
||
tmpBar.Clean();
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// TODO: Rempve ...
|
||
if (result)
|
||
{
|
||
//
|
||
// Other Drawing Materials ...
|
||
XPOIDrawConfig drawConfig;
|
||
drawConfig.Default();
|
||
|
||
//
|
||
poiDrawer.DrawZone(zone, drawConfig);
|
||
|
||
//
|
||
if (support.IsValid())
|
||
{
|
||
poiDrawer.DrawZone(support, drawConfig);
|
||
}
|
||
|
||
//
|
||
if (resistance.IsValid())
|
||
{
|
||
poiDrawer.DrawZone(resistance, drawConfig);
|
||
}
|
||
|
||
//
|
||
drawConfig.Clean();
|
||
|
||
//
|
||
// DebugBreak();
|
||
}
|
||
|
||
//
|
||
result =
|
||
result &&
|
||
zone.IsValid() &&
|
||
HasDirection(dir);
|
||
|
||
//
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Check Bar Has Signal Based on Strategy 2 ...
|
||
*
|
||
* Trend‑following:
|
||
* - Requires KI Fast + KI Slow alignment.
|
||
* - Confirms with MA crossover.
|
||
* - RSI filter to avoid false signals.
|
||
*
|
||
* @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;
|
||
}
|
||
|
||
//
|
||
bool isBullish = kiParser.IsBullishMomentumTrend(bar.Index());
|
||
bool isBearish = kiParser.IsBearishMomentumTrend(bar.Index());
|
||
result = isBullish ||
|
||
isBearish;
|
||
if (!result)
|
||
{
|
||
return result;
|
||
}
|
||
|
||
//
|
||
dir = isBullish
|
||
? X_DIRECTION_BULLISH
|
||
: isBearish
|
||
? X_DIRECTION_BEARISH
|
||
: X_DIRECTION_NONE;
|
||
result = ToBox(bar, zone, dir, X_BAR_PATTERN_MOMENTUM);
|
||
result =
|
||
result &&
|
||
zone.IsValid() &&
|
||
HasDirection(dir);
|
||
|
||
//
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Check Bar Has Signal Based on Strategy 3 ...
|
||
*
|
||
* Breakout:
|
||
* - Detects price breaking KI bands with ATR confirmation.
|
||
* - Confirms with Momentum Bar pattern.
|
||
*
|
||
* @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;
|
||
}
|
||
|
||
//
|
||
bool isBullish = poiDetector.IsBullishBreakoutPOI(bar.Index());
|
||
bool isBearish = poiDetector.IsBearishBreakoutPOI(bar.Index());
|
||
result = isBullish ||
|
||
isBearish;
|
||
if (!result)
|
||
{
|
||
return result;
|
||
}
|
||
|
||
//
|
||
dir = isBullish
|
||
? X_DIRECTION_BULLISH
|
||
: isBearish
|
||
? X_DIRECTION_BEARISH
|
||
: X_DIRECTION_NONE;
|
||
result = ToBox(bar, zone, dir, X_BAR_PATTERN_TRUE_GAPED);
|
||
result =
|
||
result &&
|
||
zone.IsValid() &&
|
||
HasDirection(dir);
|
||
|
||
//
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Check Bar Has Signal Based on Strategy 4 ...
|
||
*
|
||
* Exhaustion:
|
||
* - Strong trend + RSI extreme + volatility low.
|
||
* - Confirms with Piercing/Dark Cloud Cover candlestick.
|
||
*
|
||
* @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;
|
||
}
|
||
|
||
//
|
||
bool isBullish = poiDetector.IsBullishTrendExhaustedPOI(bar.Index());
|
||
bool isBearish = poiDetector.IsBearishTrendExhaustedPOI(bar.Index());
|
||
result = isBullish ||
|
||
isBearish;
|
||
if (!result)
|
||
{
|
||
return result;
|
||
}
|
||
|
||
//
|
||
dir = isBullish
|
||
? X_DIRECTION_BULLISH
|
||
: isBearish
|
||
? X_DIRECTION_BEARISH
|
||
: X_DIRECTION_NONE;
|
||
result = ToBox(bar, zone, dir, X_BAR_PATTERN_PIERCING);
|
||
result =
|
||
result &&
|
||
zone.IsValid() &&
|
||
HasDirection(dir);
|
||
|
||
//
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Check Bar Has Signal Based on Strategy 5 ...
|
||
*
|
||
* Continuation:
|
||
* - Requires strong trend confirmation (KI fast/slow + MA crossover + RSI filter).
|
||
* - Confirms with continuation candlestick patterns (Flag or Rising pattern).
|
||
* - Ensures zone validity for entry.
|
||
*
|
||
* @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;
|
||
}
|
||
|
||
//
|
||
bool isBullish = kiParser.IsTrendStrongBullish(bar.Index());
|
||
bool isBearish = kiParser.IsTrendStrongBearish(bar.Index());
|
||
result = isBullish ||
|
||
isBearish;
|
||
if (!result)
|
||
{
|
||
return result;
|
||
}
|
||
|
||
//
|
||
// Confirm Direction by Candlestick Continuation Patterns ...
|
||
isBullish =
|
||
isBullish &&
|
||
poiDetector.IsBullishContinuationPOI(bar.Index());
|
||
isBearish =
|
||
isBearish &&
|
||
poiDetector.IsBearishContinuationPOI(bar.Index());
|
||
result = isBullish ||
|
||
isBearish;
|
||
if (!result)
|
||
{
|
||
return result;
|
||
}
|
||
|
||
//
|
||
dir = isBullish
|
||
? X_DIRECTION_BULLISH
|
||
: isBearish
|
||
? X_DIRECTION_BEARISH
|
||
: X_DIRECTION_NONE;
|
||
result = ToBox(bar, zone, dir, X_BAR_PATTERN_PIERCING);
|
||
result =
|
||
result &&
|
||
zone.IsValid() &&
|
||
HasDirection(dir);
|
||
|
||
//
|
||
return result;
|
||
}
|
||
|
||
//
|
||
};
|
||
|
||
// |