2434 lines
56 KiB
Plaintext
2434 lines
56 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// --------------------------------------
|
|
// Name: XC121SMCCycleHelper
|
|
// Description: provides all based classes for use ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
|
|
#include "../../Classes/x-saherelm.x-poi.class.mq5"
|
|
#include "../Libraries/x-121.smc.lib.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// Implementations ...
|
|
|
|
enum ENUM_X_CYCLES
|
|
{
|
|
X_CYCLE_TRIGGER,
|
|
X_CYCLE_DECISION,
|
|
X_CYCLE_ANALYSE,
|
|
X_CYCLE_VERIFICATION,
|
|
X_CYCLE_CONSOLIDATION,
|
|
X_CYCLE_VISION,
|
|
};
|
|
|
|
enum ENUM_X_CYCLE_EVENTS
|
|
{
|
|
SAR_CHANGE_DETECTED,
|
|
NEW_PEAK_DETECTED,
|
|
NEW_VALE_DETECTED,
|
|
PIVOT_POINT_DETECTED,
|
|
VWAP_ORDER_CHANGE_ETECTED,
|
|
VWAP_STATE_CHANGE_DETCTED,
|
|
CONSOLIDATION_BREAKED_DETECTED,
|
|
PIVOT_STARTED,
|
|
PIVOT_ENDED,
|
|
};
|
|
|
|
class XC121SMCCycleHelper : public XCBase
|
|
{
|
|
//
|
|
public:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// X121 ...
|
|
XCX121Helper *mX121Helper;
|
|
|
|
//
|
|
// POI Detector ...
|
|
XCPOIDetector *mPOIDetector;
|
|
|
|
//
|
|
// Bar Analyser
|
|
XCBarAnalyser *mBarAnalyser;
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
XC121SMCCycleHelper()
|
|
{
|
|
Default();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XC121SMCCycleHelper()
|
|
{
|
|
DeInit();
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
/**
|
|
* Get Consolidation Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ConsolidationLoopback()
|
|
{
|
|
return mConsolidationLoopback;
|
|
}
|
|
|
|
/**
|
|
* Set Consolidation Loopback Length ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void ConsolidationLoopback(int value)
|
|
{
|
|
//
|
|
if (value < 7)
|
|
{
|
|
value = 7;
|
|
}
|
|
|
|
//
|
|
mConsolidationLoopback = value;
|
|
}
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Initialize ...
|
|
*
|
|
* @param symbol: String ...
|
|
* @param period: ENUM_TIMEFRAMES member ...
|
|
* @param x121Inputs: X121Inputs instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Init(
|
|
string symbol,
|
|
ENUM_TIMEFRAMES period,
|
|
X121Inputs &x121Inputs //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid(symbol) &&
|
|
IsValid(period);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// X121 ...
|
|
mX121Helper = new XCX121Helper();
|
|
result = mX121Helper.Init(
|
|
symbol,
|
|
period,
|
|
x121Inputs //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mPOIDetector = new XCPOIDetector(
|
|
symbol,
|
|
period //
|
|
);
|
|
mPOIDetector.MaxNumberOfRequiredPOIs(0);
|
|
mPOIDetector.Init();
|
|
|
|
//
|
|
// Initialize Bar Analyser Class Instance ...
|
|
mBarAnalyser = new XCBarAnalyser();
|
|
|
|
//
|
|
// Set Chart Style ...
|
|
ApplyChartStyle();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Symbol ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GetSymbol()
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
result = mX121Helper.GetSymbol();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve TimeFrame (Period) ...
|
|
*
|
|
* @return ( ENUM_TIMEFRAMES )
|
|
*/
|
|
ENUM_TIMEFRAMES GetPeriod()
|
|
{
|
|
//
|
|
ENUM_TIMEFRAMES result = NULL;
|
|
|
|
//
|
|
result = mX121Helper.GetPeriod();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get Specified Bar ...
|
|
*
|
|
* @param source: XOHCL instance, Source Bar ...
|
|
* @param bar: XOHCL instance, Dest Bar ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetBar(
|
|
XOHCL &source,
|
|
XOHCL &bar //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
result =
|
|
IsValid(symbol) &&
|
|
IsValid(period) &&
|
|
source.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int index = iBarShift(
|
|
symbol,
|
|
period,
|
|
source.time //
|
|
);
|
|
result = bar.Init(
|
|
symbol,
|
|
period,
|
|
index //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Specified Bar ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
* @param index: Integer ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetBar(
|
|
XOHCL &bar,
|
|
int index = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
if (index < 0)
|
|
{
|
|
index = 0;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
result = bar.Init(
|
|
symbol,
|
|
period,
|
|
index //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Specified Bar ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
* @param time: Datetime ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetBar(
|
|
XOHCL &bar,
|
|
datetime time = NULL //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int index = GetBarIndex(time);
|
|
result = GetBar(bar,
|
|
index //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Specified Time Bar Index ...
|
|
*
|
|
* @param time: DateTime ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int GetBarIndex(datetime time = NULL)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
time = NormalizeTime(time);
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
result = iBarShift(
|
|
symbol,
|
|
period,
|
|
time //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Cycle Conditions ...
|
|
*
|
|
* @param events: ENUM_X_CYCLE_EVENTS member, Array ...
|
|
* @param conditions: X121SMCCycleConditions instance ...
|
|
* @param barIndex: Integer ...
|
|
* @param loopback: Integer ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetConditions(
|
|
ENUM_X_CYCLE_EVENTS &events[],
|
|
ENUM_XPOI_EVENTS &poiEvents[],
|
|
X121SMCCycleConditions &conditions,
|
|
int barIndex = 0,
|
|
int loopback = 7 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
if (loopback < 5)
|
|
{
|
|
loopback = 5;
|
|
}
|
|
|
|
//
|
|
Clean(events);
|
|
Clean(poiEvents);
|
|
conditions.Clean();
|
|
|
|
//
|
|
result = mX121Helper.GetConditions(
|
|
conditions.x121Conditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
conditions.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mPOIDetector.Update(poiEvents);
|
|
mPOIDetector.GetState(conditions.state);
|
|
|
|
//
|
|
conditions.symbol = conditions.x121Conditions.symbol;
|
|
conditions.period = conditions.x121Conditions.period;
|
|
conditions.time = TimeCurrent();
|
|
|
|
//
|
|
result = conditions.IsValid();
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
Calculate(
|
|
barIndex,
|
|
events,
|
|
conditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Get POI State of Specified Pivot ...
|
|
*
|
|
* @param pivot: XPVPivot instance Reference ...
|
|
* @param lookupSwingHighs: Boolean ...
|
|
* @param lookupSwingLows: Boolean ...
|
|
* @param lookupSupportZones: Boolean ...
|
|
* @param lookupResistanceZones: Boolean ...
|
|
* @param lookupSupplyZones: Boolean ...
|
|
* @param lookupDemandZones: Boolean ...
|
|
* @param lookupBullishOrderBlocks: Boolean ...
|
|
* @param lookupBearishOrderBlocks: Boolean ...
|
|
* @param lookupBullishFairValueGaps: Boolean ...
|
|
* @param lookupBearishFairValueGaps: Boolean ...
|
|
* @param lookupBullishRejectionBars: Boolean ...
|
|
* @param lookupBearishRejectionBars: Boolean ...
|
|
* @param lookupBullishMomentumBars: Boolean ...
|
|
* @param lookupBearishMomentumBars: Boolean ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FillPivotState(
|
|
XPVPivot &pivot,
|
|
bool lookupSwingHighs = true,
|
|
bool lookupSwingLows = true,
|
|
bool lookupSupportZones = true,
|
|
bool lookupResistanceZones = true,
|
|
bool lookupSupplyZones = true,
|
|
bool lookupDemandZones = true,
|
|
bool lookupBullishOrderBlocks = true,
|
|
bool lookupBearishOrderBlocks = true,
|
|
bool lookupBullishFairValueGaps = true,
|
|
bool lookupBearishFairValueGaps = true,
|
|
bool lookupBullishRejectionBars = true,
|
|
bool lookupBearishRejectionBars = true,
|
|
bool lookupBullishMomentumBars = true,
|
|
bool lookupBearishMomentumBars = true //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
XPOIState state;
|
|
state.Clean();
|
|
|
|
//
|
|
result = pivot.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XPOIState _state;
|
|
mPOIDetector.GetState(_state);
|
|
result = _state.IsValid() &&
|
|
_state.HasChild();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectPivotPOIs(
|
|
pivot,
|
|
_state,
|
|
state,
|
|
lookupSwingHighs,
|
|
lookupSwingLows,
|
|
lookupSupportZones,
|
|
lookupResistanceZones,
|
|
lookupSupplyZones,
|
|
lookupDemandZones,
|
|
lookupBullishOrderBlocks,
|
|
lookupBearishOrderBlocks,
|
|
lookupBullishFairValueGaps,
|
|
lookupBearishFairValueGaps,
|
|
lookupBullishRejectionBars,
|
|
lookupBearishRejectionBars,
|
|
lookupBullishMomentumBars,
|
|
lookupBearishMomentumBars //
|
|
);
|
|
|
|
//
|
|
result = state.IsValid() &&
|
|
state.HasChild();
|
|
if (result)
|
|
{
|
|
//
|
|
pivot.state = state;
|
|
|
|
//
|
|
CalculatePivotTickZone(pivot);
|
|
}
|
|
|
|
//
|
|
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;
|
|
}
|
|
|
|
//
|
|
// Change Values Actions ...
|
|
|
|
/**
|
|
* Count Saved Parabolic Sar Changes ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountSarChanges()
|
|
{
|
|
return ArraySize(mSarChanges);
|
|
}
|
|
|
|
/**
|
|
* Fill Saved Sar Changes ...
|
|
*
|
|
* @param changes: XValueChange instance Array Reference ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FillSarChanges(
|
|
XValueChange &changes[] //
|
|
)
|
|
{
|
|
//
|
|
Clean(changes);
|
|
|
|
//
|
|
Copy(
|
|
mSarChanges,
|
|
changes //
|
|
);
|
|
|
|
//
|
|
int result = ArraySize(changes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Last Sar Changes ...
|
|
*
|
|
* @param change: XValueChange instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetLastSarChange(XValueChange &change)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = GetLastItem(
|
|
change,
|
|
mSarChanges //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Saved Peaks Changes ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountPeaksChanges()
|
|
{
|
|
return ArraySize(mPeaksChanges);
|
|
}
|
|
|
|
/**
|
|
* Fill Saved Peaks Changes ...
|
|
*
|
|
* @param changes: XValueChange instance Array Reference ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FillPeaksChanges(
|
|
XValueChange &changes[] //
|
|
)
|
|
{
|
|
//
|
|
Clean(changes);
|
|
|
|
//
|
|
Copy(
|
|
mPeaksChanges,
|
|
changes //
|
|
);
|
|
|
|
//
|
|
int result = ArraySize(changes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Last Peak Changes ...
|
|
*
|
|
* @param change: XValueChange instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetLastPeakChange(XValueChange &change)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = GetLastItem(
|
|
change,
|
|
mPeaksChanges //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Saved Vales Changes ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountValesChanges()
|
|
{
|
|
return ArraySize(mValesChanges);
|
|
}
|
|
|
|
/**
|
|
* Fill Saved Vales Changes ...
|
|
*
|
|
* @param changes: XValueChange instance Array Reference ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FillValesChanges(
|
|
XValueChange &changes[] //
|
|
)
|
|
{
|
|
//
|
|
Clean(changes);
|
|
|
|
//
|
|
Copy(
|
|
mValesChanges,
|
|
changes //
|
|
);
|
|
|
|
//
|
|
int result = ArraySize(changes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Last Vale Changes ...
|
|
*
|
|
* @param change: XValueChange instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetLastValeChange(XValueChange &change)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = GetLastItem(
|
|
change,
|
|
mValesChanges //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Saved VWap Order Changes ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountVWapOrderChanges()
|
|
{
|
|
return ArraySize(mVWapOrderChanges);
|
|
}
|
|
|
|
/**
|
|
* Fill Saved VWap Order Changes ...
|
|
*
|
|
* @param changes: XValueChange instance Array Reference ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FillVWapOrderChanges(
|
|
XValueChange &changes[] //
|
|
)
|
|
{
|
|
//
|
|
Clean(changes);
|
|
|
|
//
|
|
Copy(
|
|
mVWapOrderChanges,
|
|
changes //
|
|
);
|
|
|
|
//
|
|
int result = ArraySize(changes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Last VWap Order Changes ...
|
|
*
|
|
* @param change: XValueChange instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetLastVWapOrderChange(XValueChange &change)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = GetLastItem(
|
|
change,
|
|
mVWapOrderChanges //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Saved VWap State Changes ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountVWapStateChanges()
|
|
{
|
|
return ArraySize(mVWapStateChanges);
|
|
}
|
|
|
|
/**
|
|
* Fill Saved VWap State Changes ...
|
|
*
|
|
* @param changes: XValueChange instance Array Reference ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FillVWapStateChanges(
|
|
XValueChange &changes[] //
|
|
)
|
|
{
|
|
//
|
|
Clean(changes);
|
|
|
|
//
|
|
Copy(
|
|
mVWapStateChanges,
|
|
changes //
|
|
);
|
|
|
|
//
|
|
int result = ArraySize(changes);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Last VWap State Changes ...
|
|
*
|
|
* @param change: XValueChange instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetLastVWapStateChange(XValueChange &change)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = GetLastItem(
|
|
change,
|
|
mVWapStateChanges //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Founded Consolidation Zones ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountConsolidationZones()
|
|
{
|
|
return ArraySize(mConsolidationZones);
|
|
}
|
|
|
|
/**
|
|
* Fill Broken Consolidations ...
|
|
*
|
|
* @param consolidations: XConsolidationZone instance Array Reference ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FillConsolidationZones(
|
|
XConsolidationZone &consolidations[] //
|
|
)
|
|
{
|
|
//
|
|
Clean(consolidations);
|
|
|
|
//
|
|
Copy(
|
|
mConsolidationZones,
|
|
consolidations //
|
|
);
|
|
|
|
//
|
|
int result = ArraySize(consolidations);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Last Consolidation Breaks ...
|
|
*
|
|
* @param change: XValueChange instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetLastConsolidationZone(XConsolidationZone &zone)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = GetLastItem(
|
|
zone,
|
|
mConsolidationZones //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Pivot Points Change ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountPivotPoints()
|
|
{
|
|
return ArraySize(mPivotPoints);
|
|
}
|
|
|
|
/**
|
|
* Retrieve All Pivot Point Changes as a Collection ...
|
|
*
|
|
* @param pivots: XPVPivotPoint instance Reference ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FillPivotPointss(XPVPivotPoint &pivots[])
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
Clean(pivots);
|
|
|
|
//
|
|
int count = CountPivotPoints();
|
|
if (!IsValidSize(pivots))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
Copy(
|
|
mPivotPoints,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
result = ArraySize(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve All Peak Pivot Point Changes as a Collection ...
|
|
*
|
|
* @param pivots: XPVPivotPoint instance Reference ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FillPeakPivotPoints(XPVPivotPoint &pivots[])
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
Clean(pivots);
|
|
|
|
//
|
|
int count = CountPivotPoints();
|
|
if (!IsValidSize(count))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XPVPivotPoint iPivot = mPivotPoints[i];
|
|
|
|
//
|
|
bool isValid = iPivot.IsPeak();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddRef(
|
|
iPivot,
|
|
pivots //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve All Vale Pivot Point Changes as a Collection ...
|
|
*
|
|
* @param pivots: XPVPivotPoint instance Reference ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FillValePivotPoints(XPVPivotPoint &pivots[])
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
Clean(pivots);
|
|
|
|
//
|
|
int count = CountPivotPoints();
|
|
if (!IsValidSize(count))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XPVPivotPoint iPivot = mPivotPoints[i];
|
|
|
|
//
|
|
bool isValid = iPivot.IsVale();
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddRef(
|
|
iPivot,
|
|
pivots //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get Current Active Pivot ...
|
|
*
|
|
* @param pivot: XPVPivot instance reference ...
|
|
*/
|
|
void GetActivePivot(XPVPivot &pivot)
|
|
{
|
|
//
|
|
mActivePivot.to = TimeCurrent();
|
|
pivot = mActivePivot;
|
|
}
|
|
|
|
/**
|
|
* Count Calculated Pivots ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountPivots()
|
|
{
|
|
return ArraySize(mPivots);
|
|
}
|
|
|
|
/**
|
|
* Fill Pivots ...
|
|
*
|
|
* @param pivots: XPVPivot instance Reference Array ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FillPivots(XPVPivot &pivots[])
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
Clean(pivots);
|
|
|
|
//
|
|
Copy(
|
|
mPivots,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
result = ArraySize(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Virtuals ...
|
|
|
|
/**
|
|
* Set Default Properties Values ...
|
|
*/
|
|
virtual void Default()
|
|
{
|
|
//
|
|
ConsolidationLoopback(10);
|
|
MaxAllowedSavedChanges(50);
|
|
}
|
|
|
|
//
|
|
protected:
|
|
//
|
|
|
|
/**
|
|
* Calculate Requirements ...
|
|
*
|
|
* @param barIndex: Integer, Bar Index ...
|
|
* @param events: ENUM_X_CYCLE_EVENTS member, Array ...
|
|
* @param conditions: X121SMCCycleConditions instance ...
|
|
*/
|
|
void Calculate(
|
|
int barIndex,
|
|
ENUM_X_CYCLE_EVENTS &events[],
|
|
X121SMCCycleConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
Clean(events);
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
datetime cTime = TimeCurrent();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL changeBar;
|
|
int index =
|
|
barIndex <= 0
|
|
? 1
|
|
: barIndex;
|
|
bool isInited = GetBar(
|
|
changeBar,
|
|
index //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Detect Sar Change ...
|
|
bool isSarSwitchedToBullish = conditions.x121Conditions.isSarSwitchedToBullish;
|
|
bool isSarSwitchedToBearish = conditions.x121Conditions.isSarSwitchedToBearish;
|
|
bool isSarChanged = isSarSwitchedToBullish ||
|
|
isSarSwitchedToBearish;
|
|
|
|
//
|
|
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);
|
|
|
|
//
|
|
Add(
|
|
SAR_CHANGE_DETECTED,
|
|
events //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Peaks Changes ...
|
|
|
|
//
|
|
bool isNewPeak = conditions.x121Conditions.isNewPeak;
|
|
double peak = conditions.x121Conditions.peaksBuffer[0];
|
|
bool isNewPeakOverLast = conditions.x121Conditions.isNewPeakOverLast;
|
|
bool isNewPeakUnderLast = conditions.x121Conditions.isNewPeakUnderLast;
|
|
|
|
//
|
|
if (isNewPeak)
|
|
{
|
|
//
|
|
XValueChange peaksChanged;
|
|
|
|
//
|
|
datetime time = changeBar.time;
|
|
double after = conditions.x121Conditions.peaksBuffer[1];
|
|
double before = conditions.x121Conditions.peaksBuffer[2];
|
|
ENUM_X_DIRECTION dir =
|
|
isNewPeakOverLast
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
// Initialize Model ...
|
|
isInited = peaksChanged.Init(
|
|
before,
|
|
after,
|
|
dir,
|
|
time //
|
|
);
|
|
if (isInited)
|
|
{
|
|
//
|
|
isInited = AddPeaksChange(peaksChanged);
|
|
|
|
//
|
|
Add(
|
|
NEW_PEAK_DETECTED,
|
|
events //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Vales Changes ...
|
|
|
|
//
|
|
bool isNewVale = conditions.x121Conditions.isNewVale;
|
|
double vale = conditions.x121Conditions.valesBuffer[0];
|
|
bool isNewValeOverLast = conditions.x121Conditions.isNewValeOverLast;
|
|
bool isNewValeUnderLast = conditions.x121Conditions.isNewValeUnderLast;
|
|
|
|
//
|
|
if (isNewVale)
|
|
{
|
|
//
|
|
XValueChange valesChanged;
|
|
|
|
//
|
|
datetime time = changeBar.time;
|
|
double after = conditions.x121Conditions.valesBuffer[1];
|
|
double before = conditions.x121Conditions.valesBuffer[2];
|
|
ENUM_X_DIRECTION dir =
|
|
isNewValeUnderLast
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
// Initialize Model ...
|
|
isInited = valesChanged.Init(
|
|
before,
|
|
after,
|
|
dir,
|
|
time //
|
|
);
|
|
if (isInited)
|
|
{
|
|
//
|
|
isInited = AddValesChange(valesChanged);
|
|
|
|
//
|
|
Add(
|
|
NEW_VALE_DETECTED,
|
|
events //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// VWap Direction Change ...
|
|
|
|
//
|
|
// Ordered Change ...
|
|
bool isVWapSwitchedToBullishOrdered =
|
|
conditions.x121Conditions.isVWapSwitchedToBullishOrdered;
|
|
bool isVWapSwitchedToBearishOrdered =
|
|
conditions.x121Conditions.isVWapSwitchedToBearishOrdered;
|
|
bool isVWAPOrderedChanged = isVWapSwitchedToBullishOrdered ||
|
|
isVWapSwitchedToBearishOrdered;
|
|
//
|
|
if (isVWAPOrderedChanged)
|
|
{
|
|
//
|
|
XValueChange vwapOrderChanged;
|
|
|
|
//
|
|
datetime time = changeBar.time;
|
|
ENUM_X_DIRECTION dir =
|
|
isVWapSwitchedToBullishOrdered
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
double after = 0;
|
|
double before = 0;
|
|
if (isVWapSwitchedToBullishOrdered)
|
|
{
|
|
//
|
|
// After Max ...
|
|
after = MathMax(
|
|
conditions.x121Conditions.vwapFastBuffer[1],
|
|
conditions.x121Conditions.vwapMidBuffer[1] //
|
|
);
|
|
after = MathMax(
|
|
after,
|
|
conditions.x121Conditions.vwapSlowBuffer[1] //
|
|
);
|
|
|
|
//
|
|
// Before Min ...
|
|
before = MathMin(
|
|
conditions.x121Conditions.vwapFastBuffer[1],
|
|
conditions.x121Conditions.vwapMidBuffer[1] //
|
|
);
|
|
before = MathMin(
|
|
before,
|
|
conditions.x121Conditions.vwapSlowBuffer[1] //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// After Min ...
|
|
after = MathMin(
|
|
conditions.x121Conditions.vwapFastBuffer[1],
|
|
conditions.x121Conditions.vwapMidBuffer[1] //
|
|
);
|
|
after = MathMin(
|
|
after,
|
|
conditions.x121Conditions.vwapSlowBuffer[1] //
|
|
);
|
|
|
|
//
|
|
// Before Max ...
|
|
before = MathMax(
|
|
conditions.x121Conditions.vwapFastBuffer[1],
|
|
conditions.x121Conditions.vwapMidBuffer[1] //
|
|
);
|
|
before = MathMax(
|
|
before,
|
|
conditions.x121Conditions.vwapSlowBuffer[1] //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Initialize Model ...
|
|
isInited = vwapOrderChanged.Init(
|
|
before,
|
|
after,
|
|
dir,
|
|
time //
|
|
);
|
|
if (isInited)
|
|
{
|
|
//
|
|
isInited = AddVWapOrderChange(vwapOrderChanged);
|
|
|
|
//
|
|
Add(
|
|
VWAP_ORDER_CHANGE_ETECTED,
|
|
events //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// States Changed ...
|
|
bool isVWapSwitchedToBullishState =
|
|
conditions.x121Conditions.isVWapSwitchedToBullishState;
|
|
bool isVWapSwitchedToBearishState =
|
|
conditions.x121Conditions.isVWapSwitchedToBearishState;
|
|
bool isVWapStatesChanged = isVWapSwitchedToBullishState ||
|
|
isVWapSwitchedToBearishState;
|
|
|
|
//
|
|
if (isVWapStatesChanged)
|
|
{
|
|
//
|
|
XValueChange vwapStateChanged;
|
|
|
|
//
|
|
datetime time = changeBar.time;
|
|
ENUM_X_DIRECTION dir =
|
|
isVWapSwitchedToBullishState
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
double after = 0;
|
|
double before = 0;
|
|
if (isVWapSwitchedToBullishState)
|
|
{
|
|
//
|
|
// After Max ...
|
|
after = MathMax(
|
|
conditions.x121Conditions.vwapFastBuffer[1],
|
|
conditions.x121Conditions.vwapMidBuffer[1] //
|
|
);
|
|
after = MathMax(
|
|
after,
|
|
conditions.x121Conditions.vwapSlowBuffer[1] //
|
|
);
|
|
|
|
//
|
|
// Before Min ...
|
|
before = MathMin(
|
|
conditions.x121Conditions.vwapFastBuffer[1],
|
|
conditions.x121Conditions.vwapMidBuffer[1] //
|
|
);
|
|
before = MathMin(
|
|
before,
|
|
conditions.x121Conditions.vwapSlowBuffer[1] //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// After Min ...
|
|
after = MathMin(
|
|
conditions.x121Conditions.vwapFastBuffer[1],
|
|
conditions.x121Conditions.vwapMidBuffer[1] //
|
|
);
|
|
after = MathMin(
|
|
after,
|
|
conditions.x121Conditions.vwapSlowBuffer[1] //
|
|
);
|
|
|
|
//
|
|
// Before Max ...
|
|
before = MathMax(
|
|
conditions.x121Conditions.vwapFastBuffer[1],
|
|
conditions.x121Conditions.vwapMidBuffer[1] //
|
|
);
|
|
before = MathMax(
|
|
before,
|
|
conditions.x121Conditions.vwapSlowBuffer[1] //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Initialize Model ...
|
|
isInited = vwapStateChanged.Init(
|
|
before,
|
|
after,
|
|
dir,
|
|
time //
|
|
);
|
|
if (isInited)
|
|
{
|
|
//
|
|
isInited = AddVWapStateChange(vwapStateChanged);
|
|
|
|
//
|
|
Add(
|
|
VWAP_STATE_CHANGE_DETCTED,
|
|
events //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Consolidations ...
|
|
|
|
//
|
|
int consolidationLoopback = ConsolidationLoopback();
|
|
if (IsValidSize(consolidationLoopback))
|
|
{
|
|
//
|
|
double upper = 0;
|
|
double lower = 0;
|
|
bool hasConsolidation =
|
|
mBarAnalyser.IsConsolidate(
|
|
changeBar,
|
|
upper,
|
|
lower,
|
|
consolidationLoopback //
|
|
);
|
|
|
|
//
|
|
if (hasConsolidation &&
|
|
!mActioveConsolidationZone.IsValid())
|
|
{
|
|
//
|
|
// Initialize Consolidation Zone ...
|
|
bool isInited = mActioveConsolidationZone.Init(
|
|
changeBar.symbol,
|
|
changeBar.period,
|
|
upper,
|
|
lower,
|
|
consolidationLoopback //
|
|
);
|
|
}
|
|
|
|
//
|
|
if (!hasConsolidation &&
|
|
mActioveConsolidationZone.IsValid())
|
|
{
|
|
//
|
|
mActioveConsolidationZone.Update();
|
|
bool isBreaked = mActioveConsolidationZone.IsBreaked();
|
|
|
|
//
|
|
if (isBreaked)
|
|
{
|
|
//
|
|
// Add Active to List ...
|
|
AddRef(
|
|
mActioveConsolidationZone,
|
|
mConsolidationZones //
|
|
);
|
|
|
|
//
|
|
// Clean Active Zone ...
|
|
mActioveConsolidationZone.Clean();
|
|
|
|
//
|
|
Add(
|
|
CONSOLIDATION_BREAKED_DETECTED,
|
|
events //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Valid Peaks and Vales ...
|
|
if (isNewPeak || isNewVale)
|
|
{
|
|
//
|
|
int count = 0;
|
|
double value = 0;
|
|
int repetition = 0;
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
int periodSeconds = PeriodSeconds(period);
|
|
int minRepetition = mX121Helper.GetDonChainLength();
|
|
ENUM_XPV_PIVOTS type = isNewPeak
|
|
? XPV_PEAK
|
|
: XPV_VALE;
|
|
|
|
//
|
|
XValueChange lastChange;
|
|
XValueChange prevChange;
|
|
|
|
//
|
|
count = CountPeaksChanges();
|
|
if (isNewPeak && count >= 2)
|
|
{
|
|
//
|
|
lastChange = mPeaksChanges[count - 1];
|
|
prevChange = mPeaksChanges[count - 2];
|
|
}
|
|
|
|
//
|
|
count = CountValesChanges();
|
|
if (isNewVale && count >= 2)
|
|
{
|
|
//
|
|
lastChange = mValesChanges[count - 1];
|
|
prevChange = mValesChanges[count - 2];
|
|
}
|
|
|
|
//
|
|
if (lastChange.IsValid() &&
|
|
prevChange.IsValid())
|
|
{
|
|
//
|
|
value = prevChange.after;
|
|
int delayTime = ((int)lastChange.time - (int)prevChange.time);
|
|
repetition = delayTime / periodSeconds;
|
|
|
|
//
|
|
bool isValidPivot = repetition >= minRepetition;
|
|
if (isValidPivot)
|
|
{
|
|
//
|
|
XPVPivotPoint pivotPoint;
|
|
pivotPoint.type = type;
|
|
pivotPoint.value = value;
|
|
pivotPoint.time = prevChange.time;
|
|
pivotPoint.repetition = repetition;
|
|
|
|
//
|
|
AddRef(
|
|
pivotPoint,
|
|
mPivotPoints //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
PIVOT_POINT_DETECTED,
|
|
events //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// //
|
|
// // Calculate Pivots ...
|
|
// if (isNewPeak || isNewVale)
|
|
// {
|
|
// //
|
|
// if (!mActivePivot.IsValid())
|
|
// {
|
|
// //
|
|
// mActivePivot.symbol = symbol;
|
|
// mActivePivot.period = period;
|
|
|
|
// //
|
|
// mActivePivot.upper = peak;
|
|
// mActivePivot.lower = vale;
|
|
|
|
// //
|
|
// mActivePivot.from = cTime;
|
|
// mActivePivot.to = cTime;
|
|
|
|
// //
|
|
// mActivePivot.type =
|
|
// isNewPeak
|
|
// ? XPV_VALE
|
|
// : XPV_PEAK;
|
|
// mActivePivot.repetition++;
|
|
|
|
// //
|
|
// Add(
|
|
// PIVOT_STARTED,
|
|
// events //
|
|
// );
|
|
// }
|
|
// else
|
|
// {
|
|
// //
|
|
// mActivePivot.to = cTime;
|
|
|
|
// //
|
|
// mActivePivot.repetition++;
|
|
|
|
// //
|
|
// if (mActivePivot.to > mActivePivot.from)
|
|
// {
|
|
// FillPivotState(mActivePivot);
|
|
// }
|
|
|
|
// //
|
|
// // 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 ...");
|
|
// }
|
|
// }
|
|
// }
|
|
}
|
|
|
|
//
|
|
private:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Change Holders ...
|
|
int mMaxAllowedSavedChanges; // Max llowed Changes to Save ...
|
|
XValueChange mSarChanges[]; // Holds Parabolic Sar Direction Changes ...
|
|
XValueChange mPeaksChanges[]; // Holds Peaks Changes ...
|
|
XValueChange mValesChanges[]; // Holds Vales Changes ...
|
|
XValueChange mVWapOrderChanges[]; // Holds Vales Changes ...
|
|
XValueChange mVWapStateChanges[]; // Holds Vales Changes ...
|
|
|
|
//
|
|
int mConsolidationLoopback; // Consolidation Loopback Length ...
|
|
XConsolidationZone mConsolidationZones[]; // Holds Consolidation Zones ...
|
|
XConsolidationZone mActioveConsolidationZone; // Holds Actiove Consolidation Zone ...
|
|
|
|
//
|
|
XPVPivotPoint mPivotPoints[]; // Holds Pivots ...
|
|
|
|
//
|
|
XCXPVPivotObject mActivePivotObject;
|
|
XPVPivot mActivePivot;
|
|
XPVPivot mPivots[];
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Release All Resources ...
|
|
*/
|
|
void DeInit()
|
|
{
|
|
//
|
|
delete mX121Helper;
|
|
|
|
//
|
|
delete mBarAnalyser;
|
|
}
|
|
|
|
/**
|
|
* Apply Chart Style ...
|
|
*/
|
|
void ApplyChartStyle()
|
|
{
|
|
//
|
|
// Retrieve Current Chart ID ...
|
|
long chartId = ChartID();
|
|
|
|
//
|
|
ENUM_CHART_MODE mMode = CHART_CANDLES; // chart's mMode
|
|
bool mShowBidLine = true; // show bid line
|
|
bool mShowAskLine = true; // show ask line
|
|
bool mShowGrid = false; // show grids on chart
|
|
bool mShowVolumes = false; // show volumes
|
|
bool mShowTradeLevels = true; // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders)
|
|
bool mAutoScroll = true; // chart autoscroll
|
|
bool mQuickNavigation = true; // chart quick navigation state
|
|
color mForeGroundColor = clrWhite; // chart's foreground color
|
|
color mBackGroundColor = clrBlack; // chart's background color
|
|
color mUpColor = clrGreen; // Up Color
|
|
color mDownColor = clrRed; // Down Color
|
|
color mBullishColor = clrGreen; // Bullish color
|
|
color mBearishColor = clrRed; // Bearish color
|
|
color mGridColor = clrGray; // grid color
|
|
color mBidLineColor = clrGray; // bid line color
|
|
color mAskLineColor = clrRed; // ask line color
|
|
color mLineColor = clrLime; // line mMode and doji candlestick color
|
|
color mStopColor = clrGold; // Color of stop order levels (Stop Loss and Take Profit)
|
|
color mVolumesColor = clrGreen; // volumes color
|
|
|
|
//
|
|
ChartSetInteger(chartId, CHART_MODE, mMode);
|
|
ChartSetInteger(chartId, CHART_SHOW_BID_LINE, mShowBidLine);
|
|
ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, mShowAskLine);
|
|
ChartSetInteger(chartId, CHART_SHOW_GRID, mShowGrid);
|
|
ChartSetInteger(chartId, CHART_SHOW_VOLUMES, mShowVolumes);
|
|
ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels);
|
|
ChartSetInteger(chartId, CHART_AUTOSCROLL, mAutoScroll);
|
|
ChartSetInteger(chartId, CHART_QUICK_NAVIGATION, mQuickNavigation);
|
|
ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, mForeGroundColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, mBackGroundColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CHART_UP, mUpColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, mDownColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, mBullishColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, mBearishColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_GRID, mGridColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_BID, mBidLineColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_ASK, mAskLineColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_STOP_LEVEL, mStopColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CHART_LINE, mLineColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_VOLUME, mVolumesColor);
|
|
}
|
|
|
|
/**
|
|
* Fill Pivot Tick Zone ...
|
|
*
|
|
* @param pivot: XPVPivot instance Reference ...
|
|
*/
|
|
void CalculatePivotTickZone(
|
|
XPVPivot &pivot //
|
|
)
|
|
{
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
bool isInited = false;
|
|
|
|
//
|
|
datetime from = pivot.from;
|
|
XOHCL iFromBar;
|
|
int iFromBarIndex = iBarShift(
|
|
symbol,
|
|
period,
|
|
from //
|
|
);
|
|
isInited = iFromBar.Init(
|
|
symbol,
|
|
period,
|
|
iFromBarIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
datetime to = pivot.to;
|
|
XOHCL iToBar;
|
|
int iToBarIndex = iBarShift(
|
|
symbol,
|
|
period,
|
|
to //
|
|
);
|
|
isInited = iToBar.Init(
|
|
symbol,
|
|
period,
|
|
iToBarIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
if (iFromBarIndex <= iToBarIndex)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
XCTicksZone *iZone;
|
|
iZone = new XCTicksZone();
|
|
|
|
//
|
|
int ticksLevels = mPOIDetector.TicksRangeZoneLevel();
|
|
int ticksRange = mPOIDetector.TicksRangeZoneRange();
|
|
isInited = ticksLevels > 0 &&
|
|
ticksRange > 0;
|
|
if (!isInited)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
isInited = iZone.Init(
|
|
iFromBar,
|
|
iToBar //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
pivot.state.ticksZone = iZone;
|
|
}
|
|
|
|
//
|
|
// Change Values Actions ...
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* Add Specified Peaks Changed Item ...
|
|
*
|
|
* @param value: XValueChange instance Reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AddPeaksChange(XValueChange &value)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = value.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int beforeCount = CountSarChanges();
|
|
|
|
//
|
|
AddIfNotExists(
|
|
value,
|
|
mPeaksChanges //
|
|
);
|
|
|
|
//
|
|
int afterCount = CountSarChanges();
|
|
|
|
//
|
|
result = afterCount == beforeCount + 1;
|
|
if (result)
|
|
{
|
|
//
|
|
// Cleaning Up Unused Items ...
|
|
int maxAllowed = MaxAllowedSavedChanges();
|
|
CleanupArray(
|
|
mPeaksChanges,
|
|
maxAllowed //
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Add Specified Vales Changed Item ...
|
|
*
|
|
* @param value: XValueChange instance Reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AddValesChange(XValueChange &value)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = value.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int beforeCount = CountSarChanges();
|
|
|
|
//
|
|
AddIfNotExists(
|
|
value,
|
|
mValesChanges //
|
|
);
|
|
|
|
//
|
|
int afterCount = CountSarChanges();
|
|
|
|
//
|
|
result = afterCount == beforeCount + 1;
|
|
if (result)
|
|
{
|
|
//
|
|
// Cleaning Up Unused Items ...
|
|
int maxAllowed = MaxAllowedSavedChanges();
|
|
CleanupArray(
|
|
mValesChanges,
|
|
maxAllowed //
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Add Specified VWap Order Changed Item ...
|
|
*
|
|
* @param value: XValueChange instance Reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AddVWapOrderChange(XValueChange &value)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = value.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int beforeCount = CountSarChanges();
|
|
|
|
//
|
|
AddIfNotExists(
|
|
value,
|
|
mVWapOrderChanges //
|
|
);
|
|
|
|
//
|
|
int afterCount = CountSarChanges();
|
|
|
|
//
|
|
result = afterCount == beforeCount + 1;
|
|
if (result)
|
|
{
|
|
//
|
|
// Cleaning Up Unused Items ...
|
|
int maxAllowed = MaxAllowedSavedChanges();
|
|
CleanupArray(
|
|
mVWapOrderChanges,
|
|
maxAllowed //
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Add Specified VWap State Changed Item ...
|
|
*
|
|
* @param value: XValueChange instance Reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AddVWapStateChange(XValueChange &value)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = value.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int beforeCount = CountSarChanges();
|
|
|
|
//
|
|
AddIfNotExists(
|
|
value,
|
|
mVWapStateChanges //
|
|
);
|
|
|
|
//
|
|
int afterCount = CountSarChanges();
|
|
|
|
//
|
|
result = afterCount == beforeCount + 1;
|
|
if (result)
|
|
{
|
|
//
|
|
// Cleaning Up Unused Items ...
|
|
int maxAllowed = MaxAllowedSavedChanges();
|
|
CleanupArray(
|
|
mVWapStateChanges,
|
|
maxAllowed //
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|