last ...
This commit is contained in:
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,864 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 XCATBEASignallerInputs
|
||||
{
|
||||
//
|
||||
// Pros ...
|
||||
string symbol;
|
||||
string provider;
|
||||
bool allowDraws;
|
||||
bool allowGuards;
|
||||
int riskToRewardRatio;
|
||||
ENUM_TIMEFRAMES period;
|
||||
double slATRMultiplier;
|
||||
X121XCatbInputs catbInputs;
|
||||
XTriggerBlockFilters filters;
|
||||
XTriggerBlockValidationRules validations;
|
||||
|
||||
//
|
||||
// Constructor(s) ...
|
||||
XCATBEASignallerInputs()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
symbol = NULL;
|
||||
period = NULL;
|
||||
provider = NULL;
|
||||
filters.Clean();
|
||||
catbInputs.Clean();
|
||||
allowDraws = false;
|
||||
validations.Clean();
|
||||
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 XCXCATBEASignaller : 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 ...
|
||||
XTriggerBlockFilters filters; // Trigger Block Filters ...
|
||||
XCXCATBEAPOIDetector *detector; // POI Detector ...
|
||||
XTriggerBlockValidationRules validations; // Trigger Block Validations ...
|
||||
|
||||
//
|
||||
XBoxZone unavailableZones[]; // Un Available Zones ...
|
||||
|
||||
//
|
||||
XCATBEAStrategyConditions mConditions;
|
||||
XCATBEAStrategyConditions mConditionsCollection[];
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XCXCATBEASignaller(XCATBEASignallerInputs &inputs)
|
||||
{
|
||||
Init(inputs);
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
~XCXCATBEASignaller()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
//
|
||||
// Here we Check Active Session ...
|
||||
// and Prevent Moving forward if there is not
|
||||
// Session actives ...
|
||||
// for improvement Calculation Speeds ...
|
||||
if (!isActiveSession)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
//
|
||||
// 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 = DetectTriggerBlock1(
|
||||
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(XCATBEASignallerInputs &inputs)
|
||||
{
|
||||
//
|
||||
bool has = inputs.IsValid();
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
symbol = inputs.symbol;
|
||||
period = inputs.period;
|
||||
filters = inputs.filters;
|
||||
provider = inputs.provider;
|
||||
allowDraws = inputs.allowDraws;
|
||||
allowGuards = inputs.allowGuards;
|
||||
validations = inputs.validations;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
Binary file not shown.
@@ -0,0 +1,209 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Indicator
|
||||
// -------------------------------------------------
|
||||
// Name: XCXCATBEADataCollector ...
|
||||
// Description: Class for XCATBEA Data Collector ...
|
||||
//
|
||||
//
|
||||
// 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 Class for XCATBEA Data Collector"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../../Classes/x-saherelm.base.class.mq5"
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
|
||||
//
|
||||
// Implementation ...
|
||||
class XCXCATBEADataCollector : public XCBase
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Constructors ...
|
||||
XCXCATBEADataCollector()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
~XCXCATBEADataCollector()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Properties ...
|
||||
|
||||
//
|
||||
string Path()
|
||||
{
|
||||
return mPath;
|
||||
}
|
||||
|
||||
//
|
||||
void Path(string value)
|
||||
{
|
||||
//
|
||||
// Normalizing Collector Path ...
|
||||
if (IsValid(value))
|
||||
{
|
||||
mPath = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mPath = "XCXCATBEADataCollector";
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
string GetFilePath(string fileName)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
mPath + "\\" + fileName + ".x121.log"
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int GetFileHandlerForWrite(string filePath)
|
||||
{
|
||||
//
|
||||
int result = INVALID_HANDLE;
|
||||
|
||||
//
|
||||
if (!IsValid(filePath))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = FileOpen(
|
||||
filePath,
|
||||
FILE_READ | FILE_WRITE | FILE_TXT //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Specified Content into Specified File Name ...
|
||||
*
|
||||
* @param fileName: string, file name ...
|
||||
* @param content: string, content ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Save(
|
||||
string fileName,
|
||||
string content //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = IsValid(content);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
int mHandler = GetFileHandlerForWrite(fileName);
|
||||
result = mHandler != INVALID_HANDLE;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
FileWrite(mHandler, content);
|
||||
FileFlush(mHandler);
|
||||
FileClose(mHandler);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append Specified Content into Specified File Name ...
|
||||
*
|
||||
* @param fileName: string, file name ...
|
||||
* @param content: string, content ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Append(
|
||||
string fileName,
|
||||
string content //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = IsValid(content);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
int mHandler = GetFileHandlerForWrite(fileName);
|
||||
result = mHandler != INVALID_HANDLE;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
FileSeek(mHandler, 0, SEEK_END);
|
||||
FileWrite(mHandler, content);
|
||||
FileFlush(mHandler);
|
||||
FileClose(mHandler);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
string mPath; // Base Collector Path ...
|
||||
};
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,604 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class
|
||||
// -------------------------------------------------
|
||||
// Name: XCXCATBEAPOIDrawer ...
|
||||
// Description: XCATBEA POI Drawer 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 XCATBEA POI Drawer Class"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5"
|
||||
#include "../Classes/xcatbea.x-poi.detector.class.mq5"
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
struct XCATBPivotStyle
|
||||
{
|
||||
//
|
||||
// Properties ...
|
||||
int width;
|
||||
color clr;
|
||||
ENUM_LINE_STYLE style;
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XCATBPivotStyle()
|
||||
{
|
||||
Default();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Cleanup Model ...
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
width = 1;
|
||||
clr = CLR_NONE;
|
||||
style = STYLE_SOLID;
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
//
|
||||
// Default Props ...
|
||||
void Default()
|
||||
{
|
||||
//
|
||||
width = 1;
|
||||
clr = CLR_NONE;
|
||||
style = STYLE_SOLID;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Implementations ...
|
||||
class XCXCATBEAPOIDrawer : public XCBase
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Props ...
|
||||
XCPOIDrawer *drawer;
|
||||
|
||||
//
|
||||
// Drawers ...
|
||||
bool drawPeakPivots;
|
||||
bool drawValePivots;
|
||||
|
||||
//
|
||||
// Styling ...
|
||||
|
||||
//
|
||||
XCATBPivotStyle defaultBullishStyle;
|
||||
XCATBPivotStyle defaultBearishStyle;
|
||||
|
||||
//
|
||||
XCATBPivotStyle peakPivotStyle;
|
||||
XCATBPivotStyle valePivotStyle;
|
||||
|
||||
//
|
||||
// Constructors ...
|
||||
XCXCATBEAPOIDrawer(
|
||||
XCXCATBEAPOIDetector *_detector //
|
||||
)
|
||||
{
|
||||
//
|
||||
detector = _detector;
|
||||
drawer = new XCPOIDrawer();
|
||||
|
||||
//
|
||||
Default();
|
||||
}
|
||||
|
||||
//
|
||||
// De Constructors ...
|
||||
~XCXCATBEAPOIDrawer()
|
||||
{
|
||||
//
|
||||
Clear();
|
||||
|
||||
//
|
||||
delete drawer;
|
||||
ZeroMemory(drawer);
|
||||
|
||||
//
|
||||
ZeroMemory(detector);
|
||||
}
|
||||
|
||||
//
|
||||
// Properties ...
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
virtual void Default()
|
||||
{
|
||||
//
|
||||
// Drawing ...
|
||||
drawPeakPivots = false;
|
||||
drawValePivots = false;
|
||||
|
||||
//
|
||||
// Styling ...
|
||||
|
||||
//
|
||||
// Bullish ...
|
||||
defaultBullishStyle.width = 1;
|
||||
defaultBullishStyle.clr = clrLime;
|
||||
defaultBullishStyle.style = STYLE_SOLID;
|
||||
|
||||
//
|
||||
// Bearish ...
|
||||
defaultBearishStyle.width = 1;
|
||||
defaultBearishStyle.clr = clrRed;
|
||||
defaultBearishStyle.style = STYLE_SOLID;
|
||||
|
||||
//
|
||||
// Pivots ...
|
||||
|
||||
//
|
||||
// PV ...
|
||||
peakPivotStyle = defaultBearishStyle;
|
||||
valePivotStyle = defaultBullishStyle;
|
||||
}
|
||||
|
||||
//
|
||||
void Draw(datetime to = NULL)
|
||||
{
|
||||
//
|
||||
// PV ...
|
||||
DrawPeakPivots(to);
|
||||
DrawValePivots(to);
|
||||
}
|
||||
|
||||
//
|
||||
void DrawPivot(
|
||||
XBoxZone &pivot,
|
||||
datetime to = NULL //
|
||||
)
|
||||
{
|
||||
//
|
||||
DrawBox(
|
||||
pivot,
|
||||
to,
|
||||
false,
|
||||
false //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
void DrawBox(
|
||||
XBoxZone &box,
|
||||
datetime to = NULL,
|
||||
bool drawMiddle = false,
|
||||
bool ignoreType = false //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool has = box.IsValid();
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
bool canUpdateTo = IsValid(to);
|
||||
if (canUpdateTo)
|
||||
{
|
||||
box.to = to;
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Box as POI ...
|
||||
if (!ignoreType)
|
||||
{
|
||||
//
|
||||
// Detect Pivot Type ...
|
||||
ENUM_XCATB_PIVOTS iType = GetPivotType(box);
|
||||
has = IsValid(iType);
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
switch (iType)
|
||||
{
|
||||
//
|
||||
case XCA_PEAK:
|
||||
//
|
||||
DrawPeakPivot(
|
||||
box,
|
||||
to //
|
||||
);
|
||||
break;
|
||||
|
||||
//
|
||||
case XCA_VALE:
|
||||
//
|
||||
DrawValePivot(
|
||||
box,
|
||||
to //
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Draw Regular Box ...
|
||||
else
|
||||
{
|
||||
//
|
||||
// Select Styling Config ...
|
||||
XCATBPivotStyle style;
|
||||
|
||||
//
|
||||
if (box.IsBullish())
|
||||
{
|
||||
style = defaultBullishStyle;
|
||||
}
|
||||
else
|
||||
{
|
||||
style = defaultBearishStyle;
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Box itself ...
|
||||
XCBoxObject *iBoxObj;
|
||||
has = drawer.DrawBox(
|
||||
box,
|
||||
iBoxObj //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Style Object ...
|
||||
ApplyPivotStyle(
|
||||
iBoxObj,
|
||||
style //
|
||||
);
|
||||
|
||||
//
|
||||
// Store Object ...
|
||||
mObjects.Add(iBoxObj);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Box Middle Range ...
|
||||
if (drawMiddle)
|
||||
{
|
||||
//
|
||||
double middle = box.GetMid();
|
||||
string middleName = box.GetMiddleTag();
|
||||
|
||||
//
|
||||
CChartObjectTrend *iMidObj;
|
||||
iMidObj = new CChartObjectTrend();
|
||||
has = iMidObj.Create(
|
||||
drawer.ChartIdentification(),
|
||||
middleName,
|
||||
drawer.SubWindowIdentification(),
|
||||
box.from,
|
||||
middle,
|
||||
box.to,
|
||||
middle //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Styling Object ...
|
||||
iMidObj.Color(style.clr);
|
||||
iMidObj.Width(style.width);
|
||||
iMidObj.Style(style.style);
|
||||
|
||||
//
|
||||
// Store Object ...
|
||||
mObjects.Add(iMidObj);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
style.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void DrawBoxes(
|
||||
XBoxZone &boxes[],
|
||||
datetime to = NULL,
|
||||
bool drawMiddle = false,
|
||||
bool ignoreType = false //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool has = HasChild(boxes);
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
int count = ArraySize(boxes);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XBoxZone iBox = boxes[i];
|
||||
|
||||
//
|
||||
// Detect Pivot Type ...
|
||||
DrawBox(
|
||||
iBox,
|
||||
to,
|
||||
drawMiddle,
|
||||
ignoreType //
|
||||
);
|
||||
|
||||
//
|
||||
iBox.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void Clear()
|
||||
{
|
||||
//
|
||||
// Cleanup Models ...
|
||||
defaultBullishStyle.Clean();
|
||||
defaultBearishStyle.Clean();
|
||||
|
||||
//
|
||||
// Cleanup Styles ...
|
||||
peakPivotStyle.Clean();
|
||||
valePivotStyle.Clean();
|
||||
|
||||
//
|
||||
// Cleanup Pivot Objects Holder ...
|
||||
mObjects.Clear();
|
||||
mPeakPivotObjects.Clear();
|
||||
mValePivotObjects.Clear();
|
||||
}
|
||||
|
||||
//
|
||||
// Collection Drawers ...
|
||||
|
||||
//
|
||||
void DrawPeakPivots(datetime to = NULL)
|
||||
{
|
||||
//
|
||||
bool has = drawPeakPivots;
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
has = detector.HasPeakPivots();
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
int count = detector.CountPeakPivots();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XBoxZone iBox = detector.peakPivots[i];
|
||||
|
||||
//
|
||||
DrawPeakPivot(
|
||||
iBox,
|
||||
to //
|
||||
);
|
||||
|
||||
//
|
||||
iBox.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void DrawValePivots(datetime to = NULL)
|
||||
{
|
||||
//
|
||||
bool has = drawValePivots;
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
has = detector.HasValePivots();
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
int count = detector.CountValePivots();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XBoxZone iBox = detector.valePivots[i];
|
||||
|
||||
//
|
||||
DrawValePivot(
|
||||
iBox,
|
||||
to //
|
||||
);
|
||||
|
||||
//
|
||||
iBox.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// One Item Drawers ...
|
||||
|
||||
//
|
||||
void DrawPeakPivot(
|
||||
XBoxZone &item,
|
||||
datetime to = NULL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool has = drawPeakPivots;
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
has = item.IsValid() &&
|
||||
item.type == GetBoxType(XCA_PEAK) &&
|
||||
item.dir == GetDirection(XCA_PEAK);
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
bool canUpdateTo = IsValid(to);
|
||||
if (canUpdateTo)
|
||||
{
|
||||
item.to = to;
|
||||
}
|
||||
|
||||
//
|
||||
XCBoxObject *iObj;
|
||||
has = drawer.DrawBox(
|
||||
item,
|
||||
iObj //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Style Object ...
|
||||
ApplyPivotStyle(
|
||||
iObj,
|
||||
peakPivotStyle //
|
||||
);
|
||||
|
||||
//
|
||||
// Store Object ...
|
||||
mPeakPivotObjects.Add(iObj);
|
||||
}
|
||||
|
||||
//
|
||||
ZeroMemory(iObj);
|
||||
}
|
||||
|
||||
//
|
||||
void DrawValePivot(
|
||||
XBoxZone &item,
|
||||
datetime to = NULL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool has = drawValePivots;
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
has = item.IsValid() &&
|
||||
item.type == GetBoxType(XCA_VALE) &&
|
||||
item.dir == GetDirection(XCA_VALE);
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
bool canUpdateTo = IsValid(to);
|
||||
if (canUpdateTo)
|
||||
{
|
||||
item.to = to;
|
||||
}
|
||||
|
||||
//
|
||||
XCBoxObject *iObj;
|
||||
has = drawer.DrawBox(
|
||||
item,
|
||||
iObj //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Style Object ...
|
||||
ApplyPivotStyle(
|
||||
iObj,
|
||||
valePivotStyle //
|
||||
);
|
||||
|
||||
//
|
||||
// Store Object ...
|
||||
mValePivotObjects.Add(iObj);
|
||||
}
|
||||
|
||||
//
|
||||
ZeroMemory(iObj);
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
void ApplyPivotStyle(
|
||||
XCBoxObject *&object,
|
||||
XCATBPivotStyle &style //
|
||||
)
|
||||
{
|
||||
//
|
||||
if (object == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
object.BoxColor(style.clr);
|
||||
object.BoxWidth(style.width);
|
||||
object.BoxStyle(style.style);
|
||||
}
|
||||
|
||||
//
|
||||
// Prrivate ...
|
||||
private:
|
||||
//
|
||||
// Props ...
|
||||
XCXCATBEAPOIDetector *detector;
|
||||
|
||||
//
|
||||
CArrayObj mObjects;
|
||||
|
||||
//
|
||||
CArrayObj mPeakPivotObjects;
|
||||
CArrayObj mValePivotObjects;
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user