Add Support for Sar Changes Detection ...

This commit is contained in:
2024-12-10 01:38:29 +03:30
parent 812e468151
commit b5cec1f52a
4 changed files with 453 additions and 119 deletions
+38 -2
View File
@@ -215,7 +215,7 @@ struct XTick
double bid; // Bid ... double bid; // Bid ...
double ask; // Ask ... double ask; // Ask ...
double spread; // Spread ... double spread; // Spread ...
long volume; // Volume ... long volume; // Volume ...
// //
// Constructor ... // Constructor ...
@@ -10398,6 +10398,41 @@ bool RemoveLastItem(
return result; return result;
} }
template <typename T>
void CleanupArray(
T &buffer[], // Buffer to Cleanup ...
int maxAllowed = 0 // Max Allowed Number of items ...
)
{
//
if (maxAllowed <= 0)
{
return;
}
//
int count = ArraySize(buffer);
if (!IsValidSize(count) ||
count <= maxAllowed)
{
return;
}
//
int mustRemove = count - maxAllowed;
if (!IsValidSize(mustRemove))
{
return;
}
//
ArrayRemove(
buffer,
0,
mustRemove //
);
}
// //
// Search Array For Specific Item ... // Search Array For Specific Item ...
template <typename T> template <typename T>
@@ -10851,7 +10886,8 @@ void FindSames(
void AddIfNotExists( void AddIfNotExists(
double value, double value,
double &values[], double &values[],
double smoothingPoint = 3) double smoothingPoint = 3 //
)
{ {
// //
double smoothingValue = smoothingPoint * GetPoints(_Symbol); double smoothingValue = smoothingPoint * GetPoints(_Symbol);
@@ -25,6 +25,9 @@
#include "../../Classes/x-saherelm.x-poi.class.mq5" #include "../../Classes/x-saherelm.x-poi.class.mq5"
#include "../Libraries/x-121.smc.lib.mq5" #include "../Libraries/x-121.smc.lib.mq5"
//
// Definitions ...
// //
// Implementations ... // Implementations ...
@@ -47,6 +50,7 @@ class XC121SMCCycleHelper : public XCBase
// Constructor(s) ... // Constructor(s) ...
XC121SMCCycleHelper() XC121SMCCycleHelper()
{ {
Default();
} }
// //
@@ -59,6 +63,33 @@ class XC121SMCCycleHelper : public XCBase
// //
// Getter/Setter(s) ... // Getter/Setter(s) ...
/**
* Get Max llowed Changes to Save ...
*
* @return ( int )
*/
int MaxAllowedSavedChanges()
{
return mMaxAllowedSavedChanges;
}
/**
* Set Max llowed Changes to Save ...
*
* @param value: Integer ...
*/
void MaxAllowedSavedChanges(int value)
{
//
if (value < 10)
{
value = 10;
}
//
mMaxAllowedSavedChanges = value;
}
// //
// Actions ... // Actions ...
@@ -627,6 +658,15 @@ class XC121SMCCycleHelper : public XCBase
// //
// Virtuals ... // Virtuals ...
/**
* Set Default Properties Values ...
*/
virtual void Default()
{
//
MaxAllowedSavedChanges(50);
}
// //
protected: protected:
// //
@@ -643,102 +683,69 @@ class XC121SMCCycleHelper : public XCBase
) )
{ {
// //
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
XOHCL changeBar;
int index = int index =
barIndex <= 0 barIndex <= 0
? 1 ? 1
: barIndex; : barIndex;
bool isInited = false; bool isInited = GetBar(
string symbol = GetSymbol(); changeBar,
index //
// );
// Retrieve Bar ...
XOHCL bar;
isInited = GetBar(bar, index);
if (!isInited) if (!isInited)
{ {
return; return;
} }
// //
// Retrieve Previous Bar ... // Detect Sar Change ...
XOHCL pBar; bool isSarSwitchedToBullish = conditions.x121Conditions.isSarSwitchedToBullish;
int pIndex = index + 1; bool isSarSwitchedToBearish = conditions.x121Conditions.isSarSwitchedToBearish;
isInited = GetBar(pBar, pIndex); bool isSarChanged = isSarSwitchedToBullish ||
if (!isInited) isSarSwitchedToBearish;
{
return;
}
// //
XTick xTick; if (period == PERIOD_M1)
isInited = xTick.Init(symbol);
if (!isInited)
{ {
return; //
if (isSarChanged)
{
//
XValueChange sarChanged;
//
datetime time = changeBar.time;
double after = conditions.x121Conditions.sarBuffer[1];
double before = conditions.x121Conditions.sarBuffer[2];
ENUM_X_DIRECTION dir =
isSarSwitchedToBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
// Initialize Model ...
isInited = sarChanged.Init(
before,
after,
dir,
time //
);
if (isInited)
{
//
isInited = AddSarChange(sarChanged);
if (isInited)
{
Print("Sar Switched ...");
}
}
}
} }
//
bool isSarAttached =
bar.close > conditions.x121Conditions.sarBuffer[0];
if (isSarAttached)
{
Print("Sar Attached ...");
}
// //
// bool isSarBullish =
// conditions.x121Conditions.sarBuffer[index] < bar.low;
// bool isSarBullishPrev =
// conditions.x121Conditions.sarBuffer[pIndex] < pBar.low;
// //
// bool isSarBearish =
// conditions.x121Conditions.sarBuffer[index] > bar.high;
// bool isSarBearishPrev =
// conditions.x121Conditions.sarBuffer[pIndex] > pBar.high;
// //
// bool isSarSwitchedToBullish =
// isSarBullish &&
// !isSarBullishPrev &&
// isSarBearishPrev;
// //
// bool isSarSwitchedToBearish =
// isSarBearish &&
// !isSarBearishPrev &&
// isSarBullishPrev;
// //
// if (isSarSwitchedToBullish ||
// isSarSwitchedToBearish)
// {
// Print("Sar Switched ...");
// }
// //
// bool isSarBullish =
// conditions.x121Conditions.sarBuffer[1] < xTick.ask &&
// conditions.x121Conditions.sarBuffer[1] < xTick.bid &&
// conditions.x121Conditions.isSarBullish;
// //
// bool isSarBearish =
// conditions.x121Conditions.sarBuffer[1] > xTick.ask &&
// conditions.x121Conditions.sarBuffer[1] > xTick.bid &&
// conditions.x121Conditions.isSarBearish;
//
// Detect Sar Changes ...
// bool isSarChanged = (isSarBullish &&
// !isSarBearish) ||
// (isSarBearish &&
// !isSarBullish);
// if (isSarChanged)
// {
// Print("SarChaned");
// }
// //
// Detect Peak Changes ... // Detect Peak Changes ...
@@ -752,6 +759,11 @@ class XC121SMCCycleHelper : public XCBase
// Props ... // Props ...
XCBarAnalyser *mBarAnalyser; XCBarAnalyser *mBarAnalyser;
//
// Change Holders ...
int mMaxAllowedSavedChanges; // Max llowed Changes to Save ...
XValueChange mSarChanges[]; // Holds Parabolic Sar Direction Changes ...
// //
// Actions ... // Actions ...
@@ -854,4 +866,67 @@ class XC121SMCCycleHelper : public XCBase
// //
return result; return result;
} }
//
// Change Values Actions ...
/**
* Count Saved Parabolic Sar Changes ...
*
* @return ( int )
*/
int CountSarChanges()
{
return ArraySize(mSarChanges);
}
/**
* Add Specified Parabolic Sar Changed Item ...
*
* @param value: XValueChange instance Reference ...
*
* @return ( bool )
*/
bool AddSarChange(XValueChange &value)
{
//
bool result = false;
//
result = value.IsValid();
if (!result)
{
return result;
}
//
int beforeCount = CountSarChanges();
//
AddIfNotExists(
value,
mSarChanges //
);
//
int afterCount = CountSarChanges();
//
result = afterCount == beforeCount + 1;
if (result)
{
//
// Cleaning Up Unused Items ...
int maxAllowed = MaxAllowedSavedChanges();
CleanupArray(
mSarChanges,
maxAllowed //
);
}
//
return result;
}
//
}; };
+182
View File
@@ -1840,3 +1840,185 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value)
} }
// //
// Model Value Changed ...
struct XValueChange
{
//
// Props ...
double before; // Before Change Value ...
double after; // After Change Value ...
datetime time; // Change Time ...
ENUM_X_DIRECTION dir; // Change Direction ...
//
// Constructor ...
XValueChange()
{
Clean();
}
//
// Tools ...
/**
* Initialize ...
*
* @param _before: Double, Value Before Change ...
* @param _after: Double, Value After Change ...
* @param _time: Datetime, Change Time ...
* @param _dir: ENUM_X_DIRECTION member, Specified Changed Direction ...
*
* @return ( bool )
*/
bool Init(
double _before, // Before Change Value ...
double _after, // After Change Value ...
ENUM_X_DIRECTION _dir, // Change Direction ...
datetime _time = NULL // Change Time ...
)
{
//
bool result = false;
//
_time = NormalizeTime(_time);
//
// Validate Inputs ...
result =
//
_after > 0 &&
_before > 0 &&
IsValid(_time) &&
_after != _before &&
HasDirection(_dir)
//
;
if (!result)
{
return result;
}
//
// Set Validated Values ...
dir = _dir;
time = _time;
after = _after;
before = _before;
//
result = IsValid();
//
return result;
}
/**
* Cleaning Up ...
*/
void Clean()
{
//
after = 0;
before = 0;
time = NULL;
dir = X_DIRECTION_NONE;
}
/**
* Validate Model ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
//
after > 0 &&
before > 0 &&
IsValid(time) &&
after != before &&
HasDirection(dir)
//
;
//
return result;
}
//
};
/**
* Add Value Change instance to Exists Collection if it's not Exists ...
*
* @param item: XValueChange instance Reference ...
* @param items: XValueChange instance Array Reference ...
*
* @return ( int )
*/
int AddIfNotExists(
XValueChange &item,
XValueChange &items[] //
)
{
//
int result = 0;
//
result = item.IsValid();
if (!result)
{
return result;
}
//
bool canAdd = false;
int count = ArraySize(items);
if (!IsValidSize(count))
{
canAdd = true;
}
else
{
//
XValueChange last;
bool hasItem = GetLastItem(
last,
items //
);
if (!hasItem)
{
canAdd = true;
}
else
{
//
// Compare Last Item with Current ...
canAdd = item.time > last.time;
}
}
//
// Add Item if Allowed ...
if (canAdd)
{
//
AddRef(
item,
items //
);
}
//
result = ArraySize(items);
//
return result;
}
//
@@ -124,24 +124,32 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
double pip2 = 2 * pip; double pip2 = 2 * pip;
// //
// Check Spread ... // Retrieve and Fill Cycle Conditions ...
result = GetCyclesConditions(conditions);
if (!result)
{
//
conditions.Clean();
return result;
}
//
// Check Spread for Signalling Conditions ...
bool isSpreadPassed = IsSpreadPass(); bool isSpreadPassed = IsSpreadPass();
result = isSpreadPassed; result = isSpreadPassed;
if (!result) if (!result)
{ {
// //
// string message = "Spread is not Passed for Analysing ..."; conditions.Clean();
// LogAlert(message);
//
return result; return result;
} }
// //
// Detect Conditions ... // Detect Signal Conditions ...
result = DetectConditions(conditions); result = DetectConditions(conditions);
if (!result) if (!result)
{ {
//
conditions.Clean(); conditions.Clean();
return result; return result;
} }
@@ -272,11 +280,13 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
// Actions ... // Actions ...
/** /**
* Detect and Parse Market Conditions ... * Retrieve Cycles Conditions ...
*
* @param conditions: X121SMCStrategyConditions instance Reference ...
* *
* @return ( bool ) * @return ( bool )
*/ */
bool DetectConditions( bool GetCyclesConditions(
X121SMCStrategyConditions &conditions // X121SMCStrategyConditions &conditions //
) )
{ {
@@ -294,34 +304,6 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
int ppIndex = pIndex + 1; int ppIndex = pIndex + 1;
// //
XOHCL zBar;
result = zBar.Init(
symbol,
period,
zIndex //
);
if (!result)
{
return result;
}
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
cIndex //
);
if (!result)
{
return result;
}
//
string msg = NULL;
//
double bid = GetBid(symbol);
datetime cTime = TimeCurrent(); datetime cTime = TimeCurrent();
// //
@@ -425,6 +407,65 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
} }
conditions.visionConditions.state = mVisionState; conditions.visionConditions.state = mVisionState;
//
return result;
}
/**
* Detect and Parse Market Conditions ...
*
* @param conditions: X121SMCStrategyConditions instance Reference ...
*
* @return ( bool )
*/
bool DetectConditions(
X121SMCStrategyConditions &conditions //
)
{
//
bool result = false;
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
XOHCL zBar;
result = zBar.Init(
symbol,
period,
zIndex //
);
if (!result)
{
return result;
}
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
cIndex //
);
if (!result)
{
return result;
}
//
string msg = NULL;
//
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
// // // //
// // Detect Valid Supply and Demand Zones ... // // Detect Valid Supply and Demand Zones ...
// XCSupplyZone *supplyZone; // XCSupplyZone *supplyZone;