854 lines
19 KiB
Plaintext
854 lines
19 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class
|
|
// -------------------------------------------------
|
|
// Name: XCXCATBEASignaller ...
|
|
// Description: Class for XCATBEA Signaller ...
|
|
//
|
|
//
|
|
// 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 XCXCATBEASignaller Class"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
|
|
#include "../../Classes/x-saherelm.x-guard.class.mq5"
|
|
#include "../../Helpers/x-saherelm.x121.xcatb.helper.mq5"
|
|
#include "../Classes/xcatbea.x-poi.detector.class.mq5"
|
|
#include "../Classes/xcatbea.x-poi.drawer.class.mq5"
|
|
#include "../Libraries/xcatbea.lib.mq5"
|
|
#include "../Libraries/xcatbea.signaller.lib.mq5"
|
|
#include "../Libraries/xcatbea.x-poi.extensions.lib.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
struct XCATBNonTBEASignallerInputs
|
|
{
|
|
//
|
|
// Pros ...
|
|
string symbol;
|
|
string provider;
|
|
bool allowDraws;
|
|
bool allowGuards;
|
|
int riskToRewardRatio;
|
|
ENUM_TIMEFRAMES period;
|
|
double slATRMultiplier;
|
|
X121XCatbInputs catbInputs;
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
XCATBNonTBEASignallerInputs()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
// Cleanup ...
|
|
void Clean()
|
|
{
|
|
//
|
|
symbol = NULL;
|
|
period = NULL;
|
|
provider = NULL;
|
|
catbInputs.Clean();
|
|
allowDraws = false;
|
|
allowGuards = false;
|
|
slATRMultiplier = 0;
|
|
riskToRewardRatio = 0;
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
IsValid(symbol) &&
|
|
IsValid(period) &&
|
|
IsValid(provider) &&
|
|
catbInputs.IsValid() &&
|
|
riskToRewardRatio > 0;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
class XCXCATBNonTBEASignaller : XCBase
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
bool allowDraws; // Allow Draws or not ...
|
|
bool allowGuards; // Allow Guards or not ...
|
|
int riskToRewardRatio; // Signals R2R ...
|
|
double slATRMultiplier; // SL ATR Multiplier ...
|
|
|
|
//
|
|
XBarTracker barTraker; // Bar Tracker ...
|
|
XCX121XCatbHelper *helper; // XCATB Helper Class instance ...
|
|
XCBarAnalyser *barAnalyser; // Bar Analyser ...
|
|
XCXCATBEAPOIDrawer *drawer; // POI Drawer ...
|
|
XCXCATBEAPOIDetector *detector; // POI Detector ...
|
|
|
|
//
|
|
XBoxZone unavailableZones[]; // Un Available Zones ...
|
|
|
|
//
|
|
XCATBEAStrategyConditions mConditions;
|
|
XCATBEAStrategyConditions mConditionsCollection[];
|
|
|
|
//
|
|
// Constructor ...
|
|
XCXCATBNonTBEASignaller(XCATBNonTBEASignallerInputs &inputs)
|
|
{
|
|
Init(inputs);
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCXCATBNonTBEASignaller()
|
|
{
|
|
DeInit();
|
|
}
|
|
|
|
//
|
|
// Properties ...
|
|
|
|
//
|
|
string GetSymbol()
|
|
{
|
|
return symbol;
|
|
}
|
|
|
|
//
|
|
string GetProvider()
|
|
{
|
|
return provider;
|
|
}
|
|
|
|
//
|
|
ENUM_TIMEFRAMES GetPeriod()
|
|
{
|
|
return period;
|
|
}
|
|
|
|
//
|
|
double GetR2R()
|
|
{
|
|
return riskToRewardRatio;
|
|
}
|
|
|
|
//
|
|
// Tick Analyser ...
|
|
|
|
/**
|
|
* Process Tick ...
|
|
*/
|
|
void ProcessTick(
|
|
XPosition &positions[],
|
|
XGuard &guards[],
|
|
XCATBEAStrategyConditions &conditions,
|
|
bool isActiveSession = true //
|
|
)
|
|
{
|
|
//
|
|
Clean(guards);
|
|
conditions.Clean();
|
|
|
|
//
|
|
XOHCL bar;
|
|
int count = 0;
|
|
bool has = false;
|
|
int barIndex = 0;
|
|
|
|
//
|
|
// Check Guards ...
|
|
has = DetectGuards(
|
|
guards,
|
|
positions,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
// Check Triggered Conditions ...
|
|
has = HasChild(mConditionsCollection);
|
|
if (has)
|
|
{
|
|
//
|
|
int selectedIDX = -1;
|
|
count = ArraySize(mConditionsCollection);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
// Select indexed Conditions ...
|
|
XCATBEAStrategyConditions iConditions = mConditionsCollection[i];
|
|
|
|
//
|
|
// Check Conditions Triggered ...
|
|
has = DetectSignalTrigger(
|
|
iConditions,
|
|
barIndex //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
selectedIDX = i;
|
|
conditions = iConditions;
|
|
iConditions.Clean();
|
|
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
// When Setup Invalidated
|
|
// Signaller Clean Conditions ...
|
|
if (!has &&
|
|
!iConditions.IsValid())
|
|
{
|
|
//
|
|
selectedIDX = i;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iConditions.Clean();
|
|
}
|
|
|
|
//
|
|
// Check Can Trigger ...
|
|
has = IsValidIndex(selectedIDX) &&
|
|
conditions.IsValid() &&
|
|
conditions.IsSetuped() &&
|
|
conditions.CanTrigger();
|
|
if (has)
|
|
{
|
|
//
|
|
ArrayRemove(
|
|
mConditionsCollection,
|
|
selectedIDX,
|
|
1 //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Check Selected Index for Invalid Conditions ...
|
|
if (IsValidIndex(selectedIDX))
|
|
{
|
|
//
|
|
// Remove Invalidated Conditions ...
|
|
ArrayRemove(
|
|
mConditionsCollection,
|
|
selectedIDX,
|
|
1 //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resource ...
|
|
conditions.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Bar Processing ...
|
|
if (!barTraker.CanProcessBar())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Initialize Bar ...
|
|
bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
// Detect POI(s) ...
|
|
detector.Detect(barIndex);
|
|
|
|
//
|
|
// Validate POI(s) ...
|
|
detector.Validate(
|
|
unavailableZones,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
// Draw POI(s) ...
|
|
if (allowDraws)
|
|
{
|
|
drawer.Draw(bar.time);
|
|
}
|
|
|
|
//
|
|
// Here we Check Active Session ...
|
|
// and Prevent Moving forward if there is not
|
|
// Session actives ...
|
|
// for improvement Calculation Speeds ...
|
|
if (isActiveSession)
|
|
{
|
|
//
|
|
// Check Signal Setups ...
|
|
has = DetectSignalSetup(barIndex);
|
|
if (has)
|
|
{
|
|
//
|
|
barTraker.Waits();
|
|
|
|
//
|
|
AddConditionsIfNotExists();
|
|
|
|
//
|
|
mConditions.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
bar.Clean();
|
|
}
|
|
|
|
//
|
|
// Signalling Tools ...
|
|
|
|
/**
|
|
* Detect Setup Conditions based on Signalling ...
|
|
*
|
|
* @param maxAllowedSLDistanceInPoint: int, Max Allowed SL Distance in Points (if Bigger thn Zero Provided) ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectSignalSetup(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
// Update All Required Buffers ...
|
|
helper.Update(barIndex);
|
|
|
|
//
|
|
// Trigger Block Detection ...
|
|
// result = DetectTriggerBlock(
|
|
// helper,
|
|
// barAnalyser,
|
|
// mConditions.triggerBlock,
|
|
// mConditions.conditions,
|
|
// validations,
|
|
// filters,
|
|
// barIndex,
|
|
// 10 // Loopback ...
|
|
// );
|
|
if (result)
|
|
{
|
|
//
|
|
// Prepare Condition ...
|
|
|
|
// //
|
|
// // Prepare Signal ...
|
|
// mConditions.dir =
|
|
// mConditions
|
|
// .triggerBlock
|
|
// .GetDirection();
|
|
// mConditions.symbol = symbol;
|
|
// mConditions.period = period;
|
|
// mConditions.provider = provider;
|
|
// mConditions.reward = riskToRewardRatio;
|
|
// mConditions.time = mConditions.conditions.bars[0].time;
|
|
// mConditions.setupTime = mConditions.conditions.bars[0].time;
|
|
|
|
// //
|
|
// // Prepare Target ...
|
|
// double targets[];
|
|
// for (int i = 1; i <= riskToRewardRatio; i++)
|
|
// {
|
|
// //
|
|
// Add(
|
|
// (double)i,
|
|
// targets //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Calculate SL Additions ...
|
|
// double iATR = 0;
|
|
// if (barIndex > 0 &&
|
|
// barIndex < ArraySize(helper.atrBuffer))
|
|
// {
|
|
// iATR = helper.atrBuffer[barIndex];
|
|
// }
|
|
// double slAdditional = slATRMultiplier * iATR;
|
|
|
|
// //
|
|
// // Preparing Signal ...
|
|
// result = ToSignal(
|
|
// mConditions.triggerBlock.trigger,
|
|
// mConditions.triggerBlock.signal,
|
|
// targets,
|
|
// slAdditional //
|
|
// );
|
|
// if (result)
|
|
// {
|
|
// //
|
|
// mConditions.triggerBlock.signal.provider = provider;
|
|
// mConditions.sl = mConditions.triggerBlock.signal.sl;
|
|
// mConditions.tp = mConditions.triggerBlock.signal.tp;
|
|
// mConditions.pivot = mConditions.triggerBlock.signal.sl;
|
|
// mConditions.entry = mConditions.triggerBlock.signal.entry;
|
|
// mConditions.point = mConditions.triggerBlock.signal.entry;
|
|
// mConditions.type = ToPositionType(mConditions.triggerBlock.signal.type);
|
|
|
|
// //
|
|
// // Draw Trigger Block ...
|
|
// if (allowDraws)
|
|
// {
|
|
// //
|
|
// DrawTriggerBlock(
|
|
// mConditions.triggerBlock,
|
|
// drawer.drawer,
|
|
// mObjects,
|
|
// NULL, // To ...
|
|
// false // Draw Signal ...
|
|
// );
|
|
// }
|
|
// }
|
|
}
|
|
|
|
//
|
|
result = mConditions.IsValid() &&
|
|
mConditions.IsSetuped();
|
|
|
|
//
|
|
// Cleanup Resource ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Trigger Conditions for Specified Signal ...
|
|
*
|
|
* @param conditions: XCATBEAStrategyConditions instance Reference, Specified Signal Conditions ...
|
|
* @param maxAllowedSetupAge: specified Setup Age for Expiration (if bigger than Zero) ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectSignalTrigger(
|
|
XCATBEAStrategyConditions &conditions,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
// Validate Setup ...
|
|
result = conditions.IsSetuped();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = IsBullish(conditions.dir);
|
|
bool isBearish = IsBearish(conditions.dir);
|
|
|
|
//
|
|
// Validate Direction of Setuped Conditions ...
|
|
result =
|
|
result &&
|
|
(isBullish ||
|
|
isBearish);
|
|
|
|
//
|
|
// Do Triggering Senario based on Trigger Block ...
|
|
if (result &&
|
|
conditions.triggerBlock.IsValid())
|
|
{
|
|
//
|
|
// Checking Score ...
|
|
double bullishScore = 0;
|
|
double bearishScore = 0;
|
|
conditions
|
|
.conditions
|
|
.GenerateScore(
|
|
bullishScore,
|
|
bearishScore //
|
|
);
|
|
bool isScorePassed =
|
|
isBullish
|
|
? bullishScore > bearishScore
|
|
: bearishScore > bullishScore;
|
|
|
|
//
|
|
// Complete Conditions Here ...
|
|
if (isScorePassed)
|
|
{
|
|
conditions.triggerTime = TimeCurrent();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Do Other Validation Senarios ...
|
|
|
|
//
|
|
result = conditions.IsValid() &&
|
|
conditions.IsSetuped() &&
|
|
conditions.CanTrigger();
|
|
|
|
//
|
|
// Check Setup Age or Setup Validations here ...
|
|
if (!result)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Guards bsed on Signalling Class ...
|
|
*
|
|
* @param guards: XCAEAGuard instance Collection, Holds Provided Guards ...
|
|
* @param positions: XPosition instance Collection, Provides Signalling Based Positions for Apply Guards on them ...
|
|
* @param provider: X121SMCStrategySignalProviderData instance Reference, Specified Data for Cycles ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectGuards(
|
|
XGuard &guards[],
|
|
const XPosition &positions[],
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
Clean(guards);
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
result = allowGuards &&
|
|
HasChild(positions);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// TODO: Implement this ...
|
|
|
|
//
|
|
result = HasChild(guards);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
Clean(guards);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
|
|
/**
|
|
* Initialize ...
|
|
*/
|
|
void Init(XCATBNonTBEASignallerInputs &inputs)
|
|
{
|
|
//
|
|
bool has = inputs.IsValid();
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
symbol = inputs.symbol;
|
|
period = inputs.period;
|
|
provider = inputs.provider;
|
|
allowDraws = inputs.allowDraws;
|
|
allowGuards = inputs.allowGuards;
|
|
slATRMultiplier = inputs.slATRMultiplier;
|
|
riskToRewardRatio = inputs.riskToRewardRatio;
|
|
|
|
//
|
|
mObjects = new CArrayObj();
|
|
|
|
//
|
|
// Initialize Bar Tracker ...
|
|
has = barTraker.Init(
|
|
symbol,
|
|
period //
|
|
);
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Initialize Bar Analyser ...
|
|
barAnalyser = new XCBarAnalyser();
|
|
|
|
//
|
|
// initialize Helper ...
|
|
helper = new XCX121XCatbHelper();
|
|
has = helper.Init(
|
|
symbol,
|
|
period,
|
|
inputs.catbInputs //
|
|
);
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
mConditions.Clean();
|
|
Clean(mConditionsCollection);
|
|
|
|
//
|
|
InitPOI();
|
|
}
|
|
|
|
/**
|
|
* DeInitialize ...
|
|
*/
|
|
void DeInit()
|
|
{
|
|
//
|
|
mObjects.Clear();
|
|
delete mObjects;
|
|
ZeroMemory(mObjects);
|
|
|
|
//
|
|
drawer.Clear();
|
|
delete drawer;
|
|
ZeroMemory(drawer);
|
|
|
|
//
|
|
detector.CleanPivots();
|
|
delete detector;
|
|
ZeroMemory(detector);
|
|
|
|
//
|
|
delete helper;
|
|
ZeroMemory(helper);
|
|
|
|
//
|
|
delete barAnalyser;
|
|
ZeroMemory(barAnalyser);
|
|
|
|
//
|
|
barTraker.Clean();
|
|
}
|
|
|
|
/**
|
|
* Add Conditions to Conditions Collection if not Exists ...
|
|
*
|
|
* @param maxAllowed: int, Specified Max Allowed Holding Conditions ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int AddConditionsIfNotExists(
|
|
int maxAllowed = 10 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
bool isSetuped = IsValid(mConditions.setupTime) &&
|
|
HasDirection(mConditions.dir);
|
|
if (!isSetuped)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mConditionsCollection);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
// Copy Original Items ...
|
|
XCATBEAStrategyConditions tmpItems[];
|
|
Copy(
|
|
mConditionsCollection,
|
|
tmpItems //
|
|
);
|
|
|
|
//
|
|
// Prese Item Data ...
|
|
bool isBullish = IsBullish(mConditions.dir);
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCATBEAStrategyConditions iItem = tmpItems[i];
|
|
|
|
//
|
|
bool canRemove = mConditions.dir == iItem.dir &&
|
|
mConditions.pivot == iItem.pivot;
|
|
if (canRemove)
|
|
{
|
|
//
|
|
ArrayRemove(
|
|
mConditionsCollection,
|
|
i,
|
|
1 //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
Clean(tmpItems);
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
mConditions,
|
|
mConditionsCollection //
|
|
);
|
|
|
|
//
|
|
// Remove Olds ...
|
|
CleanupArray(
|
|
mConditionsCollection,
|
|
maxAllowed //
|
|
);
|
|
|
|
//
|
|
result = ArraySize(mConditionsCollection);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
string symbol;
|
|
string provider;
|
|
CArrayObj *mObjects;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
// Initialize and Configure POI Detector and Drawer ...
|
|
void InitPOI()
|
|
{
|
|
//
|
|
// Initialize POI Detector ...
|
|
bool has = helper != NULL;
|
|
if (has)
|
|
{
|
|
//
|
|
detector = new XCXCATBEAPOIDetector(helper);
|
|
|
|
//
|
|
// Configure ...
|
|
detector.detectPeakPivots = true;
|
|
detector.detectValePivots = true;
|
|
}
|
|
|
|
//
|
|
// Initialize POI Drawer ...
|
|
has = detector != NULL;
|
|
if (has)
|
|
{
|
|
//
|
|
drawer = new XCXCATBEAPOIDrawer(detector);
|
|
|
|
//
|
|
// Configure ...
|
|
drawer.drawPeakPivots = true;
|
|
drawer.drawValePivots = true;
|
|
|
|
//
|
|
XCATBPivotStyle iStyle;
|
|
|
|
//
|
|
// Styling Peak Pivot ...
|
|
iStyle.width = 1;
|
|
iStyle.clr = clrMagenta;
|
|
iStyle.style = STYLE_SOLID;
|
|
|
|
//
|
|
drawer.peakPivotStyle = iStyle;
|
|
|
|
//
|
|
// Styling Vale Pivot ...
|
|
iStyle.width = 1;
|
|
iStyle.clr = clrAqua;
|
|
iStyle.style = STYLE_SOLID;
|
|
|
|
//
|
|
drawer.valePivotStyle = iStyle;
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
iStyle.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
}; |