Files
MQL5Data/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5
T
2024-11-21 17:48:22 +03:30

1997 lines
51 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCX121SMCTestStrategy
// 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 "../../Helpers/x-saherelm.x3ma.helper.mq5"
#include "../../Helpers/x-saherelm.x3vwap.helper.mq5"
#include "../../Helpers/x-saherelm.xchsar.helper.mq5"
#include "../../Helpers/x-saherelm.xpv.helper.mq5"
#include "../Classes/x-121.smc.base.strategy.class.mq5"
//
// Helper(s) ...
//
// XStrategy Class Implementation(s) ...
class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
{
//
// Public ...
public:
//
//
// Constructor(s) ...
void XCX121SMCTestStrategy(
//
// Base ...
string _symbol, // Trading Symbol
ENUM_TIMEFRAMES _period // Trading TimeFrame
)
: XCX121SMCBaseStrategy(_symbol, _period)
{
InitialHelpers();
}
//
// Deconstructur ...
void ~XCX121SMCTestStrategy()
{
}
//
// Overrides Actions ...
/**
* Destroy All Class Implementations ...
*/
void Destroy() override
{
//
delete xpvHelper;
delete x3maHelper;
delete xchsarHelper;
delete x3vwapHelper;
}
/**
* Check Conditions For Signal ...
*/
bool HasSignal(
XSignal &signal,
X121SMCStrategyConditions &conditions //
) override
{
//
bool result = false;
//
signal.Clean();
conditions.Clean();
//
int pushers = 0;
//
double sl = 0;
double tp = 0;
double risk = 0;
double entry = 0;
double reward = 0;
double r2r = R2R();
double volume = Volume();
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
//
bool hasLong = false;
bool hasShort = false;
//
double selectedSL = 0;
//
// Start Calculations ...
//
string _symbol = GetSymbol();
ENUM_TIMEFRAMES _period = GetPeriod();
//
double points = GetPoints(_symbol);
double pip = GetPipPrice(_symbol);
double pip2 = 2 * pip;
//
datetime cTime = TimeCurrent();
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
// Retrieve Bars ...
//
// Zero Bar ...
XOHCL zBar;
result = zBar.Init(
_symbol,
_period,
zIndex //
);
if (!result)
{
return result;
}
//
// Last Bar ...
XOHCL cBar;
result = cBar.Init(
_symbol,
_period,
cIndex //
);
if (!result)
{
return result;
}
//
// Previous Bar ...
XOHCL pBar;
result = pBar.Init(
_symbol,
_period,
pIndex //
);
if (!result)
{
return result;
}
//
// Prepare Areas ...
double bid = GetBid(_symbol);
//
// Check Momentum Bar ...
ENUM_X_DIRECTION momentumBarDir;
bool isCMomentumBar = mBarAnalyser.IsMomentumBar(
cBar,
momentumBarDir //
);
bool isCBullishMomentumBar =
isCMomentumBar &&
IsBullish(momentumBarDir);
bool isCBearishMomentumBar =
isCMomentumBar &&
IsBearish(momentumBarDir);
//
// Check Rejection Bar ...
ENUM_X_DIRECTION rejectionBarDir;
bool isCRejectionBar = mBarAnalyser.IsRejectionBar(
cBar,
rejectionBarDir //
);
bool isCBullishRejectionBar =
isCRejectionBar &&
IsBullish(rejectionBarDir);
bool isCBearishRejectionBar =
isCRejectionBar &&
IsBearish(rejectionBarDir);
//
bool isSpreadPassed = IsSpreadPass();
result = isSpreadPassed;
if (!result)
{
return result;
}
//
// Try to Implement SMC Based Conditions ...
result = DetectConditions(conditions);
if (!result)
{
return result;
}
//
// Validate Order Flow ...
bool isValidOrderFlow = HasValidOrderFlow();
result = isValidOrderFlow;
if (!result)
{
return result;
}
//
XPVPivot lastPivot;
result = GetLastItem(
lastPivot,
mOrderFlow //
);
if (!result)
{
return result;
}
//
bool isOrderFlowBullish = IsBullish(mOrderFlowDir);
//
// Check BOS or CHOCH Happens ...
bool hasBOS =
isOrderFlowBullish
?
//
// Price Close Over Pivot's High ...
cBar.IsBullish() &&
cBar.close > lastPivot.upper
//
:
//
// Price Must Close Under Pivots Low ...
cBar.IsBearish() &&
cBar.close < lastPivot.lower
//
;
bool hasCHOCH =
isOrderFlowBullish
?
//
// Price Close Under Pivot's Low ...
cBar.IsBearish() &&
cBar.close < lastPivot.lower
//
:
//
// Price Must Close Over Pivots High ...
cBar.IsBullish() &&
cBar.close > lastPivot.upper
//
;
//
if (hasBOS || hasCHOCH)
{
//
RedrawOrderFlow();
//
string mTitle =
hasBOS ? "BOS"
: "CHOCH";
//
Print(mTitle);
//
// Here We Have to Decide How to Act Based On
// Conditions for Updating Order Flow ...
if (hasCHOCH)
{
//
hasLong =
//
!isOrderFlowBullish &&
cBar.IsBullish() &&
(isCBullishMomentumBar ||
isCBullishRejectionBar) &&
conditions.xchsarConditions.cSars[0] < cBar.low
//
;
if (hasLong) {
//
// selectedSL = conditions.xpvConditions.peaks[1];
selectedSL = conditions.xchsarConditions.cSars[1];
}
//
hasShort =
//
isOrderFlowBullish &&
cBar.IsBearish() &&
(isCBearishMomentumBar ||
isCBearishRejectionBar) &&
conditions.xchsarConditions.cSars[0] > cBar.high
//
;
if (hasLong) {
//
// selectedSL = conditions.xpvConditions.vales[1];
selectedSL = conditions.xchsarConditions.cSars[1];
}
}
}
//
// Check Parabolic Sar is in Order of Order Flow ...
bool isPSarInDirectionOfOrderFlow =
isOrderFlowBullish
? conditions.xchsarConditions.cSars[0] < cBar.low &&
conditions.xchsarConditions.cSars[1] >= pBar.low
: conditions.xchsarConditions.cSars[0] > cBar.high &&
conditions.xchsarConditions.cSars[1] <= pBar.high;
//
if (isPSarInDirectionOfOrderFlow)
{
RedrawOrderFlow();
Print("");
}
else
{
ClearDraws();
}
//
bool long1 =
//
false
//
;
if (long1)
{
//
CustomStateDrawing(mTriggerPOIState);
selectedSL = conditions.xpvConditions.vales[cIndex];
}
//
// Works by WVAP and PSar ...
bool short1 =
//
false
//
;
if (short1)
{
//
CustomStateDrawing(mTriggerPOIState);
selectedSL = conditions.xpvConditions.peaks[cIndex];
}
// //
// hasLong =
// //
// long1
// //
// ;
// //
// hasShort =
// //
// short1
// //
// ;
//
result = hasLong ||
hasShort;
//
// Rmove Signal Condition ...
if (result)
{
//
// TYPE ...
type =
hasLong
? POSITION_TYPE_BUY
: POSITION_TYPE_SELL;
ENUM_X_POSITION_TYPES xType =
hasLong
? X_POSITION_TYPE_LONG
: X_POSITION_TYPE_SHORT;
//
entry = GetEntry(
conditions.symbol,
type //
);
//
// double candidates[];
// DetectSLCandidates(
// candidates,
// entry,
// conditions,
// xType //
// );
// double selectedSL =
// hasLong
// ? GetMax(candidates)
// : GetMin(candidates);
sl =
hasLong
? selectedSL - pip2
: selectedSL + pip2;
//
// RISK Reward ...
risk =
hasLong
? entry - sl
: sl - entry;
reward = risk * r2r;
tp =
hasLong
? entry + reward
: entry - reward;
//
ClearDraws();
//
signal.sl = sl;
signal.tp = tp;
signal.type = type;
signal.mode = mode;
signal.entry = entry;
signal.volume = volume;
signal.symbol = _symbol;
signal.period = _period;
signal.pushers = pushers;
signal.provider = GetTag();
signal.time = TimeCurrent();
//
result = PrepareSignal(signal);
//
hasLong = false;
hasShort = false;
}
//
return result;
}
/**
* Detect SL Candidates based on Strategy and Conditions ...
*
* @param result: Double array reference ...
* @param entry: Double, Position Entry Price ...
* @param conditions: X121SMCStrategyConditions instance, Provides Configurations ...
* @param type: ENUM_X_POSITION_TYPES member, Specified Position Type ...
*/
void DetectSLCandidates(
double &result[],
double entry,
X121SMCStrategyConditions &conditions,
ENUM_X_POSITION_TYPES type //
) override
{
//
Clean(result);
//
int cIndex = 1;
//
if (entry <= 0 ||
!conditions.IsValid() ||
type == X_POSITION_TYPE_ALL ||
type == X_POSITION_TYPE_NONE)
{
return;
}
//
Add(
conditions.x3vwapConditions.fasts[cIndex],
result //
);
//
Add(
conditions.x3vwapConditions.mids[cIndex],
result //
);
//
Add(
conditions.x3vwapConditions.slows[cIndex],
result //
);
//
Add(
conditions.x3maConditions.fasts[cIndex],
result //
);
//
Add(
conditions.xpvConditions.vales[cIndex],
result //
);
//
Add(
conditions.xpvConditions.peaks[cIndex],
result //
);
//
}
/**
* Customize Strategy Identifier ...
*/
string GetTag() override
{
return X121SMCStrategyToken;
}
//
// Protected ...
protected:
//
//
// Props ...
//
// XPV ...
XPVInputs xpvInputs;
XCXPVHelper *xpvHelper;
//
// X3MA ...
X3MAInputs x3maInputs;
XCX3MAHelper *x3maHelper;
//
// X3VWAP ...
X3VWAPInputs x3vwapInputs;
XCX3VWAPHelper *x3vwapHelper;
//
// XCHSAR ...
XCHSARInputs xchsarInputs;
XCXCHSARHelper *xchsarHelper;
//
XPVPivot mOrderFlow[];
ENUM_X_DIRECTION mOrderFlowDir;
//
// Actions ...
/**
* Detect and Parse Market Conditions ...
*
* @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;
//
conditions.symbol = symbol;
conditions.period = period;
conditions.time = TimeCurrent();
//
int conditionsLoopback = 7;
//
// XPV ...
result = xpvHelper.GetConditions(
conditions.xpvConditions,
cIndex,
conditionsLoopback //
);
if (!result)
{
return result;
}
//
// X3MA ...
result = x3maHelper.GetConditions(
conditions.x3maConditions,
cIndex,
conditionsLoopback //
);
if (!result)
{
return result;
}
//
// X3VWAP ...
result = x3vwapHelper.GetConditions(
conditions.x3vwapConditions,
cIndex,
conditionsLoopback //
);
if (!result)
{
return result;
}
//
// XCHSAR ...
result = xchsarHelper.GetConditions(
conditions.xchsarConditions,
cIndex,
conditionsLoopback //
);
if (!result)
{
return result;
}
//
// Only Detect Order Flow when there isn't ...
if (ArraySize(mOrderFlow) == 0 ||
mOrderFlowDir == X_DIRECTION_NONE)
{
//
int samePivots = 40;
int requiredPivots = 10;
//
DetectOrderFlow(
cIndex,
samePivots,
requiredPivots,
mOrderFlow,
mOrderFlowDir //
);
//
result = IsValidSize(ArraySize(mOrderFlow));
if (!result)
{
return result;
}
}
//
if (result)
{
//
int lastPivotIDX = ArraySize(mOrderFlow) - 1;
if (IsValidSize(lastPivotIDX))
{
FillPivotSate(lastPivotIDX);
}
}
//
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 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,
int minRepetition,
int requiredPivots,
XPVPivot &orderFlow[], // OrderFlows ...
ENUM_X_DIRECTION &orderFlowDirection, // Order Flow Direction ...
int maxAllowedLoopbackBars = 576 //
)
{
//
bool result = false;
//
orderFlowDirection = X_DIRECTION_NONE;
//
if (maxAllowedLoopbackBars <= 0)
{
maxAllowedLoopbackBars = 1000;
}
//
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 = xpvHelper.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 = xpvHelper.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;
}
//
// Find State Inside Pivots and Attached Them to Pivot ...
int orderFlowCount = ArraySize(mOrderFlow);
if (IsValidSize(orderFlowCount))
{
//
// Loop Through Order Flow ...
for (int i = 0; i < orderFlowCount; i++)
{
FillPivotSate(i);
}
}
//
return result;
}
/**
* Filling Specified Orer Flow Index ...
*
* @param pivotIDX: Integer ...
* @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 ...
*/
void FillPivotSate(
int pivotIDX, //
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 //
)
{
//
CalculatePivotTickZone(pivotIDX);
//
// Trigger ...
XPOIState mTriggerState;
if (mTriggerPOIState.HasChild())
{
//
DetectPivotPOIs(
mOrderFlow[pivotIDX],
mTriggerPOIState,
mTriggerState,
lookupSwingHighs,
lookupSwingLows,
lookupSupportZones,
lookupResistanceZones,
lookupSupplyZones,
lookupDemandZones,
lookupBullishOrderBlocks,
lookupBearishOrderBlocks,
lookupBullishFairValueGaps,
lookupBearishFairValueGaps,
lookupBullishRejectionBars,
lookupBearishRejectionBars,
lookupBullishMomentumBars,
lookupBearishMomentumBars //
);
//
if (mTriggerState.HasChild())
{
mTriggerState.Fill(mOrderFlow[pivotIDX].state);
}
}
//
// Analyse ...
XPOIState mAnalyseState;
if (mAnalysePOIState.HasChild())
{
//
DetectPivotPOIs(
mOrderFlow[pivotIDX],
mTriggerPOIState,
mAnalyseState,
lookupSwingHighs,
lookupSwingLows,
lookupSupportZones,
lookupResistanceZones,
lookupSupplyZones,
lookupDemandZones,
lookupBullishOrderBlocks,
lookupBearishOrderBlocks,
lookupBullishFairValueGaps,
lookupBearishFairValueGaps,
lookupBullishRejectionBars,
lookupBearishRejectionBars,
lookupBullishMomentumBars,
lookupBearishMomentumBars //
);
//
if (mAnalyseState.HasChild())
{
mAnalyseState.Fill(mOrderFlow[pivotIDX].state);
}
}
//
// Vision ...
XPOIState mVisionState;
if (mVisionPOIState.HasChild())
{
//
DetectPivotPOIs(
mOrderFlow[pivotIDX],
mTriggerPOIState,
mVisionState,
lookupSwingHighs,
lookupSwingLows,
lookupSupportZones,
lookupResistanceZones,
lookupSupplyZones,
lookupDemandZones,
lookupBullishOrderBlocks,
lookupBearishOrderBlocks,
lookupBullishFairValueGaps,
lookupBearishFairValueGaps,
lookupBullishRejectionBars,
lookupBearishRejectionBars,
lookupBullishMomentumBars,
lookupBearishMomentumBars //
);
//
if (mVisionState.HasChild())
{
mVisionState.Fill(mOrderFlow[pivotIDX].state);
}
}
}
/**
* Fill Pivot Tick Zone ...
*
* @param pivotIDX: Integer ...
*/
void CalculatePivotTickZone(int pivotIDX)
{
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
bool isInited = false;
//
datetime from = mOrderFlow[pivotIDX].from;
XOHCL iFromBar;
int iFromBarIndex = iBarShift(
symbol,
period,
from //
);
isInited = iFromBar.Init(
symbol,
period,
iFromBarIndex //
);
if (!isInited)
{
return;
}
//
datetime to = mOrderFlow[pivotIDX].to;
XOHCL iToBar;
int iToBarIndex = iBarShift(
symbol,
period,
to //
);
isInited = iToBar.Init(
symbol,
period,
iToBarIndex //
);
if (!isInited)
{
return;
}
//
XCTicksZone *iZone;
iZone = new XCTicksZone();
//
int ticksLevels = mTriggerPOIDetector.TicksRangeZoneLevel();
int ticksRange = mTriggerPOIDetector.TicksRangeZoneRange();
isInited = ticksLevels > 0 &&
ticksRange > 0;
if (!isInited)
{
return;
}
//
isInited = iZone.Init(
iFromBar,
iToBar //
);
if (!isInited)
{
return;
}
//
mOrderFlow[pivotIDX].state.ticksZone = iZone;
}
/**
* Validate Order Flow ...
*
* @return ( bool )
*/
bool HasValidOrderFlow()
{
//
bool result = false;
//
int orderFlowCount = ArraySize(mOrderFlow);
result =
IsValidSize(orderFlowCount) &&
mOrderFlowDir != X_DIRECTION_ALL &&
mOrderFlowDir != X_DIRECTION_NONE;
//
return result;
}
/**
* Reset Order Flow ...
*/
void ResetOrderFlow()
{
//
Clean(mOrderFlow);
mOrderFlowDir = X_DIRECTION_NONE;
//
ClearDraws();
}
/**
* Draw Order Flow ...
*/
void RedrawOrderFlow(
bool forceClearDraws = true,
bool forceDrawSamePeriod = true,
bool drawOrderFlow = true,
bool drawOrderFlowState = true,
bool drawOnlyLastOrderFlow = false,
bool drawOnlyLastOrderFlowState = true //
)
{
//
if (forceClearDraws)
{
ClearDraws();
}
//
if (!drawOrderFlow ||
!HasValidOrderFlow())
{
return;
}
//
int orderFlowCount = ArraySize(mOrderFlow);
for (int i = 0; i < orderFlowCount; i++)
{
//
bool isLast = i == orderFlowCount - 1;
bool canDraw =
!drawOnlyLastOrderFlow ||
(isLast &&
drawOnlyLastOrderFlow);
if (!canDraw)
{
continue;
}
//
XPVPivot iPivot = mOrderFlow[i];
//
XCXPVPivotObject *iObj;
iObj = new XCXPVPivotObject();
bool isCreated = iObj.Create(
mPOIDrawer.ChartIdentification(),
mPOIDrawer.SubWindowIdentification(),
iPivot //
);
if (isCreated)
{
//
bool canDrawState =
drawOrderFlowState &&
(!drawOnlyLastOrderFlowState ||
(isLast &&
drawOnlyLastOrderFlowState));
if (canDrawState)
{
//
CustomStateDrawing(
iPivot.state,
forceDrawSamePeriod //
);
}
//
if (iPivot.IsPeak())
{
//
iObj.PivotWidth(1);
iObj.PivotFill(false);
iObj.PivotColor(clrAqua);
iObj.PivotStyle(STYLE_SOLID);
}
//
if (iPivot.IsVale())
{
//
iObj.PivotWidth(1);
iObj.PivotFill(false);
iObj.PivotStyle(STYLE_SOLID);
iObj.PivotColor(clrMagenta);
}
//
AddObjectIfNotExists(iObj);
}
}
}
/**
* Custom Drawing State ...
*
* @param state: XPOIState instance reference, Specified Which state to Draw ...
* @param forceDrawSamePeriod: Boolean ...
*/
void CustomStateDrawing(
XPOIState &state,
bool forceDrawSamePeriod = false //
)
{
//
XPOIState tmpState = state;
if (forceDrawSamePeriod)
{
//
int count = 0;
ENUM_TIMEFRAMES period = GetPeriod();
//
count = state.CountSwingHighs();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCSwing iSwing = state.swingHighs[i];
//
XOHCL iBar;
bool isFilled = iSwing.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.swingHighs,
i,
1 //
);
}
}
}
//
count = state.CountSwingLows();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCSwing iSwing = state.swingLows[i];
//
XOHCL iBar;
bool isFilled = iSwing.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.swingLows,
i,
1 //
);
}
}
}
//
count = state.CountBullishMomentumBars();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCMomentumBar iMomentum = state.bullishMomentumBars[i];
//
XOHCL iBar;
bool isFilled = iMomentum.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.bullishMomentumBars,
i,
1 //
);
}
}
}
//
count = state.CountBearishMomentumBars();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCMomentumBar iMomentum = state.bearishMomentumBars[i];
//
XOHCL iBar;
bool isFilled = iMomentum.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.bearishMomentumBars,
i,
1 //
);
}
}
}
//
count = state.CountBullishRejectionBars();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCRejectionBar iRejection = state.bullishRejectionBars[i];
//
XOHCL iBar;
bool isFilled = iRejection.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.bullishRejectionBars,
i,
1 //
);
}
}
}
//
count = state.CountBearishRejectionBars();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCRejectionBar iRejection = state.bearishRejectionBars[i];
//
XOHCL iBar;
bool isFilled = iRejection.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.bearishRejectionBars,
i,
1 //
);
}
}
}
//
count = state.CountSupportZones();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCSupportZone iZone = state.supportZones[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.supportZones,
i,
1 //
);
}
}
}
//
count = state.CountResistanceZones();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCResistanceZone iZone = state.resistanceZones[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.resistanceZones,
i,
1 //
);
}
}
}
//
count = state.CountSupplyZones();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCSupplyZone iZone = state.supplyZones[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.supplyZones,
i,
1 //
);
}
}
}
//
count = state.CountDemandZones();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCDemandZone iZone = state.demandZones[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.demandZones,
i,
1 //
);
}
}
}
//
count = state.CountBullishOrderBlocks();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCOrderBlock iZone = state.bullishOrderBlocks[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.bullishOrderBlocks,
i,
1 //
);
}
}
}
//
count = state.CountBearishOrderBlocks();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCOrderBlock iZone = state.bearishOrderBlocks[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.bearishOrderBlocks,
i,
1 //
);
}
}
}
//
count = state.CountBullishFairValueGaps();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCFVG iZone = state.bullishFairValueGaps[i];
//
XOHCL iBar;
bool isFilled = iZone.FillStartBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.bullishFairValueGaps,
i,
1 //
);
}
}
}
//
count = state.CountBearishFairValueGaps();
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCFVG iZone = state.bearishFairValueGaps[i];
//
XOHCL iBar;
bool isFilled = iZone.FillStartBar(iBar);
if (!isFilled)
{
continue;
}
//
bool isSamePeriod = iBar.period == period;
if (!isSamePeriod)
{
//
ArrayRemove(
tmpState.bearishFairValueGaps,
i,
1 //
);
}
}
}
//
}
//
DrawState(
tmpState, // State ...
true, // Update To of all Drawings Till now ...
true, // Draw SwingHighs ..
true, // Draw SwingLows ..
false, // Draw SupportZones ..
false, // Draw ResistanceZones ..
false, // Draw SupplyZones ..
false, // Draw DemandZones ..
false, // Draw BullishOrderBlocks ..
false, // Draw BearishOrderBlocks ..
false, // Draw BullishFairValueGaps ..
false, // Draw BearishFairValueGaps ..
true, // Draw BullishRejectionBars ..
true, // Draw BearishRejectionBars ..
true, // Draw BullishMomentumBars ..
true, // Draw BearishMomentumBars ..
true // Draw Ticks Zone ...
);
}
//
// Private ...
private:
//
// Props ...
/**
* Initial Required Indicators Helper ...
*/
void InitialHelpers()
{
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
// Short ...
ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period
ENUM_TIMEFRAMES scPeriod = NULL; // Time Period
//
// Medium ...
ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period
ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period
//
// Long ...
ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period
ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period
//
// Hind ...
ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period
ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period
//
// XPV ...
//
xpvInputs.Default();
//
xpvInputs.scMethod = scMethod;
xpvInputs.scPeriod = scPeriod;
xpvInputs.mcMethod = mcMethod;
xpvInputs.mcPeriod = mcPeriod;
xpvInputs.lcMethod = lcMethod;
xpvInputs.lcPeriod = lcPeriod;
xpvInputs.hcMethod = hcMethod;
xpvInputs.hcPeriod = hcPeriod;
//
xpvInputs.showPeaksAndVales = true;
xpvInputs.showLevels = false;
xpvInputs.showConsolidations = false;
xpvInputs.showFibo1Levels = false;
xpvInputs.showFibo2Levels = false;
xpvInputs.showFibo3Levels = false;
xpvInputs.showFibo4Levels = false;
xpvInputs.showFibo5Levels = false;
//
xpvHelper = new XCXPVHelper();
xpvHelper.Init(
symbol,
period,
xpvInputs //
);
//
// X3MA ...
//
x3maInputs.Default();
//
x3maInputs.showFast = true;
x3maInputs.showMid = false;
x3maInputs.showSlow = false;
//
x3maHelper = new XCX3MAHelper();
x3maHelper.Init(
symbol,
period,
x3maInputs //
);
//
// X3VWAP ...
//
x3vwapInputs.Default();
//
x3vwapInputs.showFast = true;
x3vwapInputs.showMid = true;
x3vwapInputs.showSlow = true;
//
x3vwapHelper = new XCX3VWAPHelper();
x3vwapHelper.Init(
symbol,
period,
x3vwapInputs //
);
//
// XCHCHSAR ...
//
xchsarInputs.Default();
//
xchsarInputs.scMethod = scMethod;
xchsarInputs.scPeriod = scPeriod;
xchsarInputs.mcMethod = mcMethod;
xchsarInputs.mcPeriod = mcPeriod;
xchsarInputs.lcMethod = lcMethod;
xchsarInputs.lcPeriod = lcPeriod;
xchsarInputs.hcMethod = hcMethod;
xchsarInputs.hcPeriod = hcPeriod;
//
xchsarInputs.showCurrent = true;
xchsarInputs.showShort = false;
xchsarInputs.showMedium = false;
xchsarInputs.showLong = false;
xchsarInputs.showHind = false;
//
xchsarHelper = new XCXCHSARHelper();
xchsarHelper.Init(
symbol,
period,
xchsarInputs //
);
}
//
};
//