This commit is contained in:
2024-12-28 23:28:14 +03:30
parent c2cd52bf6b
commit 408422dcfc
20 changed files with 12042 additions and 3459 deletions
@@ -33,6 +33,7 @@
enum ENUM_X_CYCLES
{
X_CYCLE_NONE,
X_CYCLE_TRIGGER,
X_CYCLE_DECISION,
X_CYCLE_ANALYSE,
@@ -41,6 +42,18 @@ enum ENUM_X_CYCLES
X_CYCLE_VISION,
};
string ToString(ENUM_X_CYCLES value)
{
//
string result = EnumToString(value);
//
StringReplace(result, "X_CYCLE_", "");
//
return result;
}
enum ENUM_X_CYCLE_EVENTS
{
SAR_CHANGE_DETECTED,
@@ -50,8 +63,10 @@ enum ENUM_X_CYCLE_EVENTS
VWAP_ORDER_CHANGE_ETECTED,
VWAP_STATE_CHANGE_DETCTED,
CONSOLIDATION_BREAKED_DETECTED,
PIVOT_STARTED,
PIVOT_ENDED,
PEAK_PIVOT_STARTED,
PEAK_PIVOT_ENDED,
VALE_PIVOT_STARTED,
VALE_PIVOT_ENDED,
};
class XC121SMCCycleHelper : public XCBase
@@ -144,6 +159,35 @@ class XC121SMCCycleHelper : public XCBase
mConsolidationLoopback = value;
}
/**
* Get Valid Pivot Points Repetition Length ...
* min => 7
*
* @return ( int )
*/
int ValidPivotRepetition()
{
return mValidPivotRepetition;
}
/**
* Set Valid Pivot Points Repetition Length ...
*
* @param value: Integer ...
* min => 7
*/
void ValidPivotRepetition(int value)
{
//
if (value < 7)
{
value = 7;
}
//
mValidPivotRepetition = value;
}
//
// Actions ...
@@ -191,7 +235,7 @@ class XC121SMCCycleHelper : public XCBase
symbol,
period //
);
mPOIDetector.MaxNumberOfRequiredPOIs(0);
mPOIDetector.MaxNumberOfRequiredPOIs(10);
mPOIDetector.Init();
//
@@ -457,6 +501,12 @@ class XC121SMCCycleHelper : public XCBase
//
if (result)
{
//
if (!IsValidSize(ArraySize(mPivots)))
{
Detect(barIndex);
}
//
Calculate(
barIndex,
@@ -572,315 +622,6 @@ class XC121SMCCycleHelper : public XCBase
return result;
}
/**
* Detect XPV Based POI(s) ...
*
* @param barIndex: Start Bar Index ...
* @param minRepetition: minimum Repeate of POI for Validation ...
* @param requiredPivots: Number of Min Requirement POI(s) ...
* @param pivotHelper: XC121SMCCycleHelper instance Pointer ...
* @param orderFlow: XPVPivot instance Array Reference ...
* @param orderFlowDirection: ENUM_X_DIRECTION member Reference which represents OrderFlow Direction ...
* @param maxAllowedLoopbackBars: Integer, Max Allowed Loopback Bars ...
*
* @return ( bool )
*/
bool DetectOrderFlow(
int barIndex,
XPVPivot &orderFlow[], // OrderFlows ...
ENUM_X_DIRECTION &orderFlowDirection, // Order Flow Direction ...
int minRepetition = 0,
int requiredPivots = 0,
int maxAllowedLoopbackBars = 576 //
)
{
//
bool result = false;
//
orderFlowDirection = X_DIRECTION_NONE;
//
if (maxAllowedLoopbackBars <= 0)
{
maxAllowedLoopbackBars = 1000;
}
//
if (minRepetition <= 0)
{
minRepetition = mX121Helper.GetDonChainLength();
}
//
if (requiredPivots <= 0)
{
requiredPivots = 3;
}
//
int start = barIndex;
int end = start + maxAllowedLoopbackBars;
//
Clean(orderFlow);
//
result = minRepetition > 0 &&
requiredPivots > 0;
if (!result)
{
return result;
}
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
double peak = 0;
XPVPivot peaks[];
int peakRepeate = 0;
int peakToBarIndex = 0;
int peakFromBarIndex = 0;
//
double vale = 0;
XPVPivot vales[];
int valeRepeate = 0;
int valeToBarIndex = 0;
int valeFromBarIndex = 0;
//
bool canLookupPeak = true;
bool canLookupVale = true;
bool canLookup = true;
while (canLookup)
{
//
// Check Peak ...
double iPeak = mX121Helper.GetPeak(barIndex);
if (iPeak != peak)
{
//
if (peak != 0 &&
peakRepeate >= minRepetition)
{
//
bool isExists = false;
int count = ArraySize(peaks);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XPVPivot iPivot = peaks[i];
//
if (iPivot.upper == iPeak)
{
//
isExists = true;
break;
}
}
}
if (!isExists)
{
//
XPVPivot iPivot;
//
iPivot.lower = 0;
iPivot.upper = peak;
iPivot.symbol = symbol;
iPivot.period = period;
iPivot.type = XPV_PEAK;
iPivot.repetition = peakRepeate;
iPivot.to = iTime(
symbol,
period,
peakToBarIndex //
);
iPivot.from = iTime(
symbol,
period,
peakFromBarIndex //
);
//
iPivot.lower = iPivot.CalculateLower();
//
bool isValid = iPivot.IsValid();
if (isValid)
{
//
AddRef(
iPivot,
peaks //
);
}
}
}
//
peak = iPeak;
peakRepeate = 0;
peakFromBarIndex = 0;
peakToBarIndex = barIndex;
}
else if (iPeak == peak)
{
//
peakRepeate++;
peakFromBarIndex = barIndex;
}
//
// Check Vale ...
double iVale = mX121Helper.GetVale(barIndex);
if (iVale != vale)
{
//
if (vale != 0 &&
valeRepeate >= minRepetition)
{
//
bool isExists = false;
int count = ArraySize(vales);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XPVPivot iPivot = vales[i];
//
if (iPivot.lower == iVale)
{
//
isExists = true;
break;
}
}
}
if (!isExists)
{
//
XPVPivot iPivot;
//
iPivot.upper = 0;
iPivot.lower = vale;
iPivot.symbol = symbol;
iPivot.period = period;
iPivot.type = XPV_VALE;
iPivot.repetition = valeRepeate;
iPivot.to = iTime(
symbol,
period,
valeToBarIndex //
);
iPivot.from = iTime(
symbol,
period,
valeFromBarIndex //
);
//
iPivot.upper = iPivot.CalculateUpper();
//
bool isValid = iPivot.IsValid();
if (isValid)
{
//
AddRef(
iPivot,
vales //
);
}
}
}
//
vale = iVale;
valeRepeate = 0;
valeFromBarIndex = 0;
valeToBarIndex = barIndex;
}
else if (iVale == vale)
{
//
valeRepeate++;
valeFromBarIndex = barIndex;
}
//
canLookupPeak = ArraySize(peaks) < requiredPivots;
canLookupVale = ArraySize(vales) < requiredPivots;
canLookup = barIndex < end &&
(canLookupPeak ||
canLookupVale);
if (canLookup)
{
barIndex++;
}
}
//
result = IsValidSize(ArraySize(peaks)) ||
IsValidSize(ArraySize(vales));
if (!result)
{
return result;
}
//
// Detect Order Flow ...
Copy(
peaks,
orderFlow,
false //
);
Copy(
vales,
orderFlow,
false //
);
int count = ArraySize(orderFlow);
result = IsValidSize(orderFlow);
if (!result)
{
return result;
}
//
// Sort Pivots ...
SortPivots(orderFlow);
//
// Filter Broken Order Flows ...
FilterBrokenPivots(orderFlow);
//
// Detect Order Flow Direction ...
result = DetectPivotDirection(
orderFlow,
orderFlowDirection //
);
if (!result)
{
return result;
}
//
return result;
}
/**
* Detect Cycle Trend Based On Pivots ...
*
@@ -1616,18 +1357,6 @@ class XC121SMCCycleHelper : public XCBase
return result;
}
/**
* Get Current Active Pivot ...
*
* @param pivot: XPVPivot instance reference ...
*/
void GetActivePivot(XPVPivot &pivot)
{
//
mActivePivot.to = TimeCurrent();
pivot = mActivePivot;
}
/**
* Count Calculated Pivots ...
*
@@ -1666,6 +1395,86 @@ class XC121SMCCycleHelper : public XCBase
return result;
}
/**
* Retrieve Last Pivot ...
*
* @param pivot: XPVPivot instance Reference ...
*
* @return ( bool )
*/
bool GetLastPivot(XPVPivot &pivot)
{
//
bool result = false;
//
pivot.Clean();
//
XPVPivot pivots[];
int count = FillPivots(pivots);
if (IsValidSize(count))
{
pivot = pivots[count - 1];
}
//
result = pivot.IsValid();
//
return result;
}
/**
* Retrieve Active Peak Pivot ...
*
* @param pivot: XPVPivot instance Reference ...
*
* @return ( bool )
*/
bool GetActivePeakPivot(XPVPivot &pivot)
{
//
bool result = false;
//
pivot.Clean();
//
pivot = mActivePeakPivot;
//
result = pivot.IsValid();
//
return result;
}
/**
* Retrieve Active Vale Pivot ...
*
* @param pivot: XPVPivot instance Reference ...
*
* @return ( bool )
*/
bool GetActiveValePivot(XPVPivot &pivot)
{
//
bool result = false;
//
pivot.Clean();
//
pivot = mActiveValePivot;
//
result = pivot.IsValid();
//
return result;
}
//
// Virtuals ...
@@ -1675,6 +1484,7 @@ class XC121SMCCycleHelper : public XCBase
virtual void Default()
{
//
ValidPivotRepetition(21);
ConsolidationLoopback(10);
MaxAllowedSavedChanges(50);
}
@@ -2118,7 +1928,7 @@ class XC121SMCCycleHelper : public XCBase
int repetition = 0;
ENUM_TIMEFRAMES period = GetPeriod();
int periodSeconds = PeriodSeconds(period);
int minRepetition = mX121Helper.GetDonChainLength();
int minRepetition = ValidPivotRepetition();
ENUM_XPV_PIVOTS type = isNewPeak
? XPV_PEAK
: XPV_VALE;
@@ -2180,67 +1990,340 @@ class XC121SMCCycleHelper : public XCBase
}
}
// //
// // Calculate Pivots ...
// if (isNewPeak || isNewVale)
// {
// //
// if (!mActivePivot.IsValid())
// {
// //
// mActivePivot.symbol = symbol;
// mActivePivot.period = period;
//
// Calculate XPVPivot ...
int pvValidation = ValidPivotRepetition();
if (IsValidSize(pvValidation))
{
//
// Peak ...
mActivePeakPivot.symbol = symbol;
mActivePeakPivot.period = period;
mActivePeakPivot.type = XPV_PEAK;
// //
// mActivePivot.upper = peak;
// mActivePivot.lower = vale;
//
if (mActivePeakPivot.upper == 0 && peak > 0)
{
//
mActivePeakPivot.upper = peak;
mActivePeakPivot.lower = vale;
mActivePeakPivot.from = changeBar.time;
// //
// mActivePivot.from = cTime;
// mActivePivot.to = cTime;
//
Add(
PEAK_PIVOT_STARTED,
events //
);
}
else if (mActivePeakPivot.upper > 0 && mActivePeakPivot.upper == peak)
{
//
mActivePeakPivot.repetition++;
mActivePeakPivot.to = changeBar.time;
}
else if (mActivePeakPivot.upper > 0 && mActivePeakPivot.upper != peak)
{
//
if (mActivePeakPivot.repetition >= pvValidation)
{
//
AddRef(
mActivePeakPivot,
mPivots //
);
// //
// mActivePivot.type =
// isNewPeak
// ? XPV_VALE
// : XPV_PEAK;
// mActivePivot.repetition++;
//
Add(
PEAK_PIVOT_ENDED,
events //
);
// //
// Add(
// PIVOT_STARTED,
// events //
// );
// }
// else
// {
// //
// mActivePivot.to = cTime;
//
mActivePeakPivot.Clean();
}
else
{
//
mActivePeakPivot.upper = peak;
mActivePeakPivot.lower = vale;
mActivePeakPivot.repetition = 0;
mActivePeakPivot.from = changeBar.time;
// //
// mActivePivot.repetition++;
//
Add(
PEAK_PIVOT_STARTED,
events //
);
}
}
// //
// if (mActivePivot.to > mActivePivot.from)
// {
// FillPivotState(mActivePivot);
// }
//
// Vale ...
mActiveValePivot.symbol = symbol;
mActiveValePivot.period = period;
mActiveValePivot.type = XPV_VALE;
// //
// // Check Ticks Zone is Valid ...
// bool isTicksZoneValid =
// //
// mActivePivot.state.IsValid() &&
// mActivePivot.state.ticksZone != NULL &&
// mActivePivot.state.ticksZone.IsValid()
// //
// ;
// if (isTicksZoneValid) {
// //
// Print("Has Valid Ticks Zone ...");
// }
// }
// }
//
// Peak ...
if (mActiveValePivot.lower == 0 && vale > 0)
{
//
mActiveValePivot.lower = vale;
mActiveValePivot.upper = peak;
mActiveValePivot.from = changeBar.time;
//
Add(
VALE_PIVOT_STARTED,
events //
);
}
else if (mActiveValePivot.lower > 0 && mActiveValePivot.lower == vale)
{
//
mActiveValePivot.repetition++;
mActiveValePivot.to = changeBar.time;
}
else if (mActiveValePivot.lower > 0 && mActiveValePivot.lower != vale)
{
//
if (mActiveValePivot.repetition >= pvValidation)
{
//
AddRef(
mActiveValePivot,
mPivots //
);
//
Add(
VALE_PIVOT_ENDED,
events //
);
//
mActiveValePivot.Clean();
}
else
{
//
mActiveValePivot.lower = vale;
mActiveValePivot.upper = peak;
mActiveValePivot.repetition = 0;
mActiveValePivot.from = changeBar.time;
//
Add(
VALE_PIVOT_STARTED,
events //
);
}
}
}
}
/**
* Detect Requirements ...
*/
void Detect(int barIndex)
{
//
if (isDetecting)
{
return;
}
//
int start = barIndex;
int max = 576;
int validPivotRepetition = ValidPivotRepetition();
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
// Try To Detect Valid Peaks or Vales ...
double peak = 0;
double vale = 0;
int peakRepetition = 0;
int valeRepetition = 0;
//
int from = start;
int index = from;
int count = start + max;
//
bool canContinue = true;
//
// Loop Throug Peaks and Vales ...
while (canContinue)
{
//
datetime toTime = iTime(
symbol,
period,
index //
);
//
double iPeak = mX121Helper.GetPeak(index);
double iVale = mX121Helper.GetVale(index);
//
// Peak ...
if (peak == 0 && iPeak > 0)
{
//
peak = iPeak;
peakRepetition = 0;
}
else if (peak > 0 && iPeak > 0 && peak == iPeak)
{
peakRepetition++;
}
else if (peak > 0 && iPeak > 0 && peak != iPeak)
{
//
if (peakRepetition >= validPivotRepetition)
{
//
datetime fromTime = iTime(
symbol,
period,
index - peakRepetition //
);
//
// Create XPVPivotPoint ...
XPVPivotPoint pivotPoint;
pivotPoint.value = iPeak;
pivotPoint.time = toTime;
pivotPoint.type = XPV_PEAK;
pivotPoint.repetition = peakRepetition;
if (pivotPoint.IsValid())
{
//
AddRef(
pivotPoint,
mPivotPoints //
);
}
//
// Create XPVPivot ...
XPVPivot pivot;
pivot.symbol = symbol;
pivot.period = period;
pivot.from = fromTime;
pivot.to = toTime;
pivot.repetition = peakRepetition;
pivot.type = XPV_PEAK;
pivot.upper = peak;
pivot.lower = iVale;
FillPivotState(pivot);
//
if (pivot.IsValid())
{
//
AddRef(
pivot,
mPivots //
);
}
}
//
peak = iPeak;
peakRepetition = 0;
}
//
// Vale ...
if (vale == 0 && iVale > 0)
{
//
vale = iVale;
valeRepetition = 0;
}
else if (vale > 0 && iVale > 0 && vale == iVale)
{
valeRepetition++;
}
else if (vale > 0 && iVale > 0 && vale != iVale)
{
//
if (valeRepetition >= validPivotRepetition)
{
//
datetime fromTime = iTime(
symbol,
period,
index - valeRepetition //
);
//
// Create XPVPivotPoint ...
XPVPivotPoint pivotPoint;
pivotPoint.value = iVale;
pivotPoint.time = toTime;
pivotPoint.type = XPV_VALE;
pivotPoint.repetition = valeRepetition;
if (pivotPoint.IsValid())
{
//
AddRef(
pivotPoint,
mPivotPoints //
);
}
//
// Create XPVPivot ...
XPVPivot pivot;
pivot.symbol = symbol;
pivot.period = period;
pivot.from = fromTime;
pivot.to = toTime;
pivot.repetition = valeRepetition;
pivot.type = XPV_VALE;
pivot.upper = iPeak;
pivot.lower = vale;
FillPivotState(pivot);
//
if (pivot.IsValid())
{
//
AddRef(
pivot,
mPivots //
);
}
}
//
vale = iVale;
valeRepetition = 0;
}
//
index++;
canContinue = index < count;
}
//
int pivotsCount = ArraySize(mPivots);
if (IsValidSize(mPivots))
{
ArrayReverse(mPivots);
}
//
isDetecting = false;
}
//
@@ -2263,12 +2346,14 @@ class XC121SMCCycleHelper : public XCBase
XConsolidationZone mActioveConsolidationZone; // Holds Actiove Consolidation Zone ...
//
int mValidPivotRepetition; // Valid Pivot Point's Repetition ...
XPVPivotPoint mPivotPoints[]; // Holds Pivots ...
//
XCXPVPivotObject mActivePivotObject;
XPVPivot mActivePivot;
XPVPivot mPivots[];
bool isDetecting;
XPVPivot mActivePeakPivot; // Active Pivots ...
XPVPivot mActiveValePivot; // Active Pivots ...
XPVPivot mPivots[]; // Holds Active Pivot ...
//
// Actions ...