1087 lines
57 KiB
Plaintext
1087 lines
57 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.xchvwap.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();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
void ~XCX121SMCTestStrategy()
|
|
{
|
|
//
|
|
delete pvHelper;
|
|
delete chvwapHelper;
|
|
}
|
|
|
|
//
|
|
// Overrides Actions ...
|
|
|
|
//
|
|
// 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;
|
|
|
|
//
|
|
bool isAllowLong = AllowLong();
|
|
bool isAllowShort = AllowShort();
|
|
result = isAllowLong || isAllowShort;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
;
|
|
}
|
|
|
|
//
|
|
// Start Calculations ...
|
|
|
|
//
|
|
string _symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES _period = GetPeriod();
|
|
|
|
//
|
|
double points = GetPoints(_symbol);
|
|
double pip = GetPipPrice(_symbol);
|
|
double pip2 = 2 * pip;
|
|
double pip3 = 3 * pip;
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
int loopback = 7;
|
|
string symbol = _symbol;
|
|
int dest = cIndex + loopback;
|
|
datetime cTime = TimeCurrent();
|
|
ENUM_TIMEFRAMES period = _period;
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//
|
|
bool isSpreadPassed = IsSpreadPass();
|
|
result = isSpreadPassed;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Indicator's Conditions ...
|
|
XCHVWAPConditions chvwapConditions;
|
|
chvwapHelper.GetConditions(
|
|
chvwapConditions,
|
|
cIndex,
|
|
loopback //
|
|
);
|
|
|
|
//
|
|
double pvPOIss[];
|
|
DetectPVPOIs(
|
|
pvPOIss //
|
|
);
|
|
|
|
//
|
|
XZone supplyZone;
|
|
int supplyZonesCount = ArraySize(_5MState.supplyZones);
|
|
bool hasSupplyZoneOverCBar = IsValidSize(supplyZonesCount);
|
|
if (hasSupplyZoneOverCBar)
|
|
{
|
|
//
|
|
hasSupplyZoneOverCBar = false;
|
|
for (int i = 0; i < supplyZonesCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = _5MState.supplyZones[i];
|
|
|
|
//
|
|
if (!hasSupplyZoneOverCBar &&
|
|
iZone.lower > cBar.high)
|
|
{
|
|
//
|
|
iZone.to = cTime;
|
|
supplyZone = iZone;
|
|
hasSupplyZoneOverCBar = true;
|
|
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
XZone demandZone;
|
|
int demandZonesCount = ArraySize(_5MState.demandZones);
|
|
bool hasDemandZoneUnderCBar = IsValidSize(demandZonesCount);
|
|
if (hasDemandZoneUnderCBar)
|
|
{
|
|
//
|
|
hasDemandZoneUnderCBar = false;
|
|
for (int i = 0; i < demandZonesCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = _5MState.demandZones[i];
|
|
|
|
//
|
|
if (!hasDemandZoneUnderCBar &&
|
|
iZone.upper < cBar.low)
|
|
{
|
|
//
|
|
iZone.to = cTime;
|
|
demandZone = iZone;
|
|
hasDemandZoneUnderCBar = true;
|
|
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
XOHCL swingHigh;
|
|
int swingHighsCount = ArraySize(_5MState.swingHighs);
|
|
bool hasSwingHighOverCBar = IsValidSize(swingHighsCount);
|
|
if (hasSwingHighOverCBar)
|
|
{
|
|
//
|
|
hasSwingHighOverCBar = false;
|
|
for (int i = 0; i < swingHighsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = _5MState.swingHighs[i];
|
|
|
|
//
|
|
if (!hasSwingHighOverCBar &&
|
|
iBar.high > cBar.high)
|
|
{
|
|
//
|
|
swingHigh = iBar;
|
|
hasSwingHighOverCBar = true;
|
|
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
XOHCL swingLow;
|
|
int swingLowsCount = ArraySize(_5MState.swingLows);
|
|
bool hasSwingLowUnderCBar = IsValidSize(swingLowsCount);
|
|
if (hasSwingLowUnderCBar)
|
|
{
|
|
//
|
|
hasSwingLowUnderCBar = false;
|
|
for (int i = 0; i < swingLowsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = _5MState.swingLows[i];
|
|
|
|
//
|
|
if (!hasSwingLowUnderCBar &&
|
|
iBar.low < cBar.low)
|
|
{
|
|
//
|
|
swingLow = iBar;
|
|
hasSwingLowUnderCBar = true;
|
|
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
XOHCL bullishRejectionBar;
|
|
XOHCL bearishRejectionBar;
|
|
bool hasBullishRejectionBarUnderCBar = false;
|
|
bool hasBearishRejectionBarOverCBar = false;
|
|
int rejectionBarsCount = ArraySize(_5MState.rejectionBars);
|
|
if (IsValidSize(rejectionBarsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < rejectionBarsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = _5MState.rejectionBars[i];
|
|
|
|
//
|
|
bool isBullish = iBar.GetLowShadow() > iBar.GetHighShadow();
|
|
bool isBearish = iBar.GetHighShadow() > iBar.GetLowShadow();
|
|
|
|
//
|
|
if (isBullish &&
|
|
!hasBullishRejectionBarUnderCBar &&
|
|
iBar.high < cBar.low)
|
|
{
|
|
//
|
|
bullishRejectionBar = iBar;
|
|
hasBullishRejectionBarUnderCBar = true;
|
|
}
|
|
|
|
//
|
|
if (isBearish &&
|
|
!hasBearishRejectionBarOverCBar &&
|
|
iBar.low > cBar.high)
|
|
{
|
|
//
|
|
bearishRejectionBar = iBar;
|
|
hasBearishRejectionBarOverCBar = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
bool isBullish =
|
|
//
|
|
(
|
|
//
|
|
(
|
|
//
|
|
// Common Conditions ...
|
|
//
|
|
// Check Has Swing Low Under CBar ...
|
|
hasSwingLowUnderCBar &&
|
|
//
|
|
// Check has a Demand Zone Under CBar ...
|
|
hasDemandZoneUnderCBar &&
|
|
//
|
|
// Check Candle is Strong ...
|
|
cBar.IsBullishDecision() &&
|
|
//
|
|
// Check Has a Bullish Rejection Bar Under CBar ...
|
|
hasBullishRejectionBarUnderCBar &&
|
|
//
|
|
(
|
|
//
|
|
// First ...
|
|
(
|
|
//
|
|
cBar.open < chvwapConditions.s[0] &&
|
|
cBar.open < chvwapConditions.m[0] &&
|
|
cBar.open < chvwapConditions.l[0] &&
|
|
cBar.open < chvwapConditions.h[0] &&
|
|
//
|
|
cBar.close > chvwapConditions.s[0] &&
|
|
cBar.close > chvwapConditions.m[0] &&
|
|
cBar.close > chvwapConditions.l[0] &&
|
|
cBar.close > chvwapConditions.h[0]
|
|
//
|
|
)
|
|
//
|
|
||
|
|
//
|
|
// Seccend ...
|
|
(
|
|
//
|
|
chvwapConditions.s[0] > chvwapConditions.m[0] &&
|
|
chvwapConditions.m[0] > chvwapConditions.l[0] &&
|
|
chvwapConditions.l[0] > chvwapConditions.h[0] &&
|
|
//
|
|
cBar.close > chvwapConditions.s[0]
|
|
//
|
|
)
|
|
//
|
|
)
|
|
//
|
|
)
|
|
//
|
|
);
|
|
|
|
//
|
|
bool isBearish =
|
|
//
|
|
(
|
|
//
|
|
(
|
|
//
|
|
// Common Conditions ...
|
|
//
|
|
// Check Has Swing High Over CBar ...
|
|
hasSwingHighOverCBar &&
|
|
//
|
|
// Check Has Supply Zone Over CBar ...
|
|
hasSupplyZoneOverCBar &&
|
|
//
|
|
// Check Candle is Strong ...
|
|
cBar.IsBearishDecision() &&
|
|
//
|
|
// Check Has a Bearish Rejection Bar Over CBar ...
|
|
hasBearishRejectionBarOverCBar &&
|
|
//
|
|
(
|
|
//
|
|
// First ...
|
|
(
|
|
//
|
|
cBar.open > chvwapConditions.s[0] &&
|
|
cBar.open > chvwapConditions.m[0] &&
|
|
cBar.open > chvwapConditions.l[0] &&
|
|
cBar.open > chvwapConditions.h[0] &&
|
|
//
|
|
cBar.close < chvwapConditions.s[0] &&
|
|
cBar.close < chvwapConditions.m[0] &&
|
|
cBar.close < chvwapConditions.l[0] &&
|
|
cBar.close < chvwapConditions.h[0]
|
|
//
|
|
)
|
|
//
|
|
||
|
|
//
|
|
// Second ...
|
|
(
|
|
//
|
|
chvwapConditions.s[0] < chvwapConditions.m[0] &&
|
|
chvwapConditions.m[0] < chvwapConditions.l[0] &&
|
|
chvwapConditions.l[0] < chvwapConditions.h[0] &&
|
|
//
|
|
cBar.close < chvwapConditions.s[0]
|
|
//
|
|
)
|
|
//
|
|
)
|
|
//
|
|
)
|
|
//
|
|
);
|
|
|
|
//
|
|
if (isBullish || isBearish)
|
|
{
|
|
//
|
|
// Draw supply if Exists ...
|
|
if (hasSupplyZoneOverCBar)
|
|
{
|
|
//
|
|
XCSupplyZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateSupplyZone(
|
|
supplyZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draw Demand if Exists ...
|
|
if (hasDemandZoneUnderCBar)
|
|
{
|
|
//
|
|
XCDemandZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateDemandZone(
|
|
demandZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draw Swing High ...
|
|
if (hasSwingHighOverCBar)
|
|
{
|
|
//
|
|
XCSwingHighObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateSwingHigh(
|
|
swingHigh,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draw Swing Low ...
|
|
if (hasSwingLowUnderCBar)
|
|
{
|
|
//
|
|
XCSwingLowObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateSwingLow(
|
|
swingLow,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draw Bullish Rejection Bar ...
|
|
if (hasBullishRejectionBarUnderCBar)
|
|
{
|
|
//
|
|
XCBullishRejectionBarObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBullishRejectionBar(
|
|
bullishRejectionBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draw Bearish Rejection Bar ...
|
|
if (hasBearishRejectionBarOverCBar)
|
|
{
|
|
//
|
|
XCBearishRejectionBarObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBearishRejectionBar(
|
|
bearishRejectionBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
Print("");
|
|
// hasLong = isBullish;
|
|
// hasShort = isBearish;
|
|
}
|
|
|
|
//
|
|
result = hasLong ||
|
|
hasShort;
|
|
if (!result)
|
|
{
|
|
conditions.Clean();
|
|
}
|
|
|
|
//
|
|
// 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 slCandidates[];
|
|
|
|
//
|
|
double selectedSL =
|
|
hasLong
|
|
? GetMin(slCandidates)
|
|
: GetMax(slCandidates);
|
|
sl =
|
|
hasLong
|
|
? selectedSL - pip3
|
|
: selectedSL + pip3;
|
|
|
|
//
|
|
// RISK Reward ...
|
|
risk =
|
|
hasLong
|
|
? entry - sl
|
|
: sl - entry;
|
|
reward = risk * r2r;
|
|
tp =
|
|
hasLong
|
|
? entry + reward
|
|
: entry - reward;
|
|
|
|
//
|
|
signal.sl = sl;
|
|
signal.tp = tp;
|
|
signal.type = type;
|
|
signal.mode = mode;
|
|
signal.entry = entry;
|
|
signal.volume = volume;
|
|
signal.symbol = _symbol;
|
|
signal.pushers = pushers;
|
|
signal.provider = GetTag();
|
|
signal.time = TimeCurrent();
|
|
signal.period = _5MState.period;
|
|
|
|
//
|
|
result = PrepareSignal(signal);
|
|
|
|
//
|
|
hasLong = false;
|
|
hasShort = false;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Customize Strategy Identifier ...
|
|
string GetTag() override
|
|
{
|
|
return X121SMCSUPDEMStrategyToken;
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// XPV ...
|
|
XPVInputs pvInputs;
|
|
XSCXPVHelper *pvHelper;
|
|
|
|
//
|
|
// XCHVWAP ...
|
|
XCHVWAPInputs chvwapInputs;
|
|
XSCXCHVWAPHelper *chvwapHelper;
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
|
|
/**
|
|
* Initial Required Indicators Helper ...
|
|
*/
|
|
void InitialHelpers()
|
|
{
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
// Short ...
|
|
ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_MANUALLY; // How to Find Period
|
|
ENUM_TIMEFRAMES scPeriod = PERIOD_M15; // Time Period
|
|
|
|
//
|
|
// Medium ...
|
|
ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_MANUALLY; // How to Find Period
|
|
ENUM_TIMEFRAMES mcPeriod = PERIOD_H1; // Time Period
|
|
|
|
//
|
|
// Long ...
|
|
ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_MANUALLY; // How to Find Period
|
|
ENUM_TIMEFRAMES lcPeriod = PERIOD_H4; // Time Period
|
|
|
|
//
|
|
// Hind ...
|
|
ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_MANUALLY; // How to Find Period
|
|
ENUM_TIMEFRAMES hcPeriod = PERIOD_D1; // Time Period
|
|
|
|
//
|
|
// XPV ...
|
|
|
|
//
|
|
pvInputs.Default();
|
|
|
|
//
|
|
pvInputs.scMethod = scMethod;
|
|
pvInputs.scPeriod = scPeriod;
|
|
pvInputs.mcMethod = mcMethod;
|
|
pvInputs.mcPeriod = mcPeriod;
|
|
pvInputs.lcMethod = lcMethod;
|
|
pvInputs.lcPeriod = lcPeriod;
|
|
pvInputs.hcMethod = hcMethod;
|
|
pvInputs.hcPeriod = hcPeriod;
|
|
|
|
//
|
|
pvInputs.showPeaksAndVales = true;
|
|
pvInputs.showLevels = false;
|
|
pvInputs.showConsolidations = false;
|
|
pvInputs.showFibo1Levels = false;
|
|
pvInputs.showFibo2Levels = false;
|
|
pvInputs.showFibo3Levels = true;
|
|
pvInputs.showFibo4Levels = false;
|
|
pvInputs.showFibo5Levels = false;
|
|
|
|
//
|
|
pvHelper = new XSCXPVHelper();
|
|
pvHelper.Init(
|
|
symbol,
|
|
period,
|
|
pvInputs //
|
|
);
|
|
|
|
//
|
|
// XCHVWAP ...
|
|
|
|
//
|
|
chvwapInputs.Default();
|
|
|
|
//
|
|
chvwapInputs.scMethod = scMethod;
|
|
chvwapInputs.scPeriod = scPeriod;
|
|
chvwapInputs.mcMethod = mcMethod;
|
|
chvwapInputs.mcPeriod = mcPeriod;
|
|
chvwapInputs.lcMethod = lcMethod;
|
|
chvwapInputs.lcPeriod = lcPeriod;
|
|
chvwapInputs.hcMethod = hcMethod;
|
|
chvwapInputs.hcPeriod = hcPeriod;
|
|
|
|
//
|
|
chvwapInputs.showShort = true;
|
|
chvwapInputs.showMedium = true;
|
|
chvwapInputs.showLong = true;
|
|
chvwapInputs.showHind = true;
|
|
|
|
//
|
|
chvwapHelper = new XSCXCHVWAPHelper();
|
|
chvwapHelper.Init(
|
|
symbol,
|
|
period,
|
|
chvwapInputs //
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Detect Direction of VWAP ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
ENUM_X_DIRECTION DetectVWAPDirection()
|
|
{
|
|
//
|
|
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
|
|
//
|
|
int loopback = 7;
|
|
int dest = cIndex + loopback;
|
|
string symbol = GetSymbol();
|
|
datetime cTime = TimeCurrent();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
// Reading Indicator's Conditions ...
|
|
XCHVWAPConditions chvwapConditions;
|
|
chvwapHelper.GetConditions(
|
|
chvwapConditions,
|
|
cIndex,
|
|
loopback //
|
|
);
|
|
|
|
//
|
|
bool isBullishOrdered =
|
|
//
|
|
chvwapConditions.m[0] > chvwapConditions.l[0] &&
|
|
chvwapConditions.l[0] > chvwapConditions.h[0]
|
|
//
|
|
;
|
|
bool isBullishState =
|
|
//
|
|
chvwapHelper.IsBullish(chvwapConditions.mState[0]) &&
|
|
chvwapHelper.IsBullish(chvwapConditions.lState[0]) &&
|
|
chvwapHelper.IsBullish(chvwapConditions.hState[0])
|
|
//
|
|
;
|
|
bool isBullishDirection =
|
|
isBullishState &&
|
|
isBullishOrdered;
|
|
|
|
//
|
|
bool isBearishOrdered =
|
|
//
|
|
chvwapConditions.m[0] < chvwapConditions.l[0] &&
|
|
chvwapConditions.l[0] < chvwapConditions.h[0]
|
|
//
|
|
;
|
|
bool isBearishState =
|
|
//
|
|
chvwapHelper.IsBearish(chvwapConditions.mState[0]) &&
|
|
chvwapHelper.IsBearish(chvwapConditions.lState[0]) &&
|
|
chvwapHelper.IsBearish(chvwapConditions.hState[0])
|
|
//
|
|
;
|
|
bool isBearishDirection =
|
|
isBearishState &&
|
|
isBearishOrdered;
|
|
|
|
//
|
|
if (isBullishDirection &&
|
|
!isBearishDirection)
|
|
{
|
|
result = X_DIRECTION_BULLISH;
|
|
}
|
|
else if (
|
|
isBearishDirection &&
|
|
!isBullishDirection)
|
|
{
|
|
result = X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect XPV POIs ...
|
|
*
|
|
* @param hhs: Double array ...
|
|
* @param lls: Double array ...
|
|
*/
|
|
void DetectPVPOIs(
|
|
double &values[] //
|
|
)
|
|
{
|
|
//
|
|
Clean(values);
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
|
|
//
|
|
int requiredCount = 10;
|
|
|
|
//
|
|
int loopback = 150;
|
|
int dest = cIndex + loopback;
|
|
string symbol = GetSymbol();
|
|
datetime cTime = TimeCurrent();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XPVConditions pvConditions;
|
|
pvHelper.GetConditions(
|
|
pvConditions,
|
|
cIndex,
|
|
loopback //
|
|
);
|
|
|
|
//
|
|
// Find POI ...
|
|
for (int i = 0; i < loopback; i++)
|
|
{
|
|
//
|
|
int iCount = 0;
|
|
double iValue = pvConditions.sCHHs[i];
|
|
|
|
//
|
|
// Peaks ...
|
|
for (int j = 0; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.peaks[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Values ...
|
|
for (int j = 0; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.vales[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
for (int j = 0; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.resistances[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Support ...
|
|
for (int j = 0; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.supports[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Short Cycle Highest Highs ...
|
|
for (int j = i + 1; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.sCHHs[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Short Cycle Lowest Low ...
|
|
for (int j = 0; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.sCLLs[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Medium Cycle Highest Highs ...
|
|
for (int j = 0; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.mCHHs[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Medium Cycle Lowest Low ...
|
|
for (int j = 0; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.mCLLs[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Long Cycle Highest Highs ...
|
|
for (int j = 0; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.lCHHs[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Long Cycle Lowest Low ...
|
|
for (int j = 0; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.lCLLs[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Hind Cycle Highest Highs ...
|
|
for (int j = 0; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.hCHHs[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Hind Cycle Lowest Low ...
|
|
for (int j = 0; j < loopback; j++)
|
|
{
|
|
//
|
|
double jValue = pvConditions.hCLLs[j];
|
|
|
|
//
|
|
if (jValue == iValue)
|
|
{
|
|
iCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (iCount >= requiredCount)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iValue,
|
|
values //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
Print("");
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
// |