1189 lines
24 KiB
Plaintext
1189 lines
24 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 X121 SMC Signal Class
|
|
// -------------------------------------------------
|
|
// Name: XICH
|
|
// Description: provide all Signalling functions ...
|
|
//
|
|
//
|
|
// 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 "../../Libraries/x-trade.lib"
|
|
#include "../Classes/x-121.smc.market.cycle.helper.class.mq5"
|
|
#include "../Libraries/x-121.smc.guard.lib.mq5"
|
|
#include "../Libraries/x-121.smc.lib.mq5"
|
|
|
|
//
|
|
// Provided Signals Enumeration ...
|
|
enum ENUM_X121SMC_XIND_PROVIDERS
|
|
{
|
|
X121SMC_XIND_PROVIDER_NONE,
|
|
X121SMC_XIND_PROVIDER_XSTR,
|
|
X121SMC_XIND_PROVIDER_XTKKUMO,
|
|
};
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// XIND Signal Conditions ...
|
|
struct X121SMCStrategyXINDSignalConditions
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
double sl;
|
|
ENUM_X_DIRECTION dir;
|
|
ENUM_X_POSITION_TYPES type;
|
|
|
|
//
|
|
// Setup Props ...
|
|
|
|
//
|
|
datetime setupTime;
|
|
datetime triggerTime;
|
|
|
|
//
|
|
double pivot;
|
|
double point;
|
|
double sls[];
|
|
double targets[];
|
|
|
|
//
|
|
XBoxZone signalBox;
|
|
|
|
//
|
|
ENUM_X121SMC_XIND_PROVIDERS provider;
|
|
|
|
//
|
|
// Constructor ...
|
|
X121SMCStrategyXINDSignalConditions()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleaning Up ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
sl = 0;
|
|
|
|
//
|
|
dir = X_DIRECTION_NONE;
|
|
type = X_POSITION_TYPE_NONE;
|
|
|
|
//
|
|
symbol = NULL;
|
|
period = NULL;
|
|
setupTime = NULL;
|
|
triggerTime = NULL;
|
|
|
|
//
|
|
ExtensionClean();
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
/**
|
|
* Check Condition is Setting Up ...
|
|
*
|
|
* @param dir: ENUM_X_DIRECTION member, Setting Up Direction ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSetuped()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid(setupTime) &&
|
|
HasDirection(dir);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Calculate Setup Age ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int GetSetupAge()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsSetuped())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect How we Can Trigger Signal ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool CanTrigger()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
sl > 0 &&
|
|
IsValid(symbol) &&
|
|
IsValid(period) &&
|
|
IsValid(triggerTime) &&
|
|
type != X_POSITION_TYPE_ALL &&
|
|
type != X_POSITION_TYPE_NONE
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extensions ...
|
|
|
|
/**
|
|
* Clean Additional Properties ...
|
|
*/
|
|
void ExtensionClean()
|
|
{
|
|
//
|
|
pivot = 0;
|
|
point = 0;
|
|
|
|
//
|
|
Clean(sls);
|
|
Clean(targets);
|
|
signalBox.Clean();
|
|
|
|
//
|
|
provider = X121SMC_XIND_PROVIDER_NONE;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
void UpdateTo(datetime value = NULL)
|
|
{
|
|
//
|
|
value = NormalizeTime(value);
|
|
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// Extension Functions ...
|
|
|
|
//
|
|
// Signalling Conditions Parsers ...
|
|
|
|
//
|
|
// Detect Signals Based On XPV Indicator Golden Zones ...
|
|
//
|
|
bool HasXPVConditions(
|
|
ENUM_X_CYCLES cycle,
|
|
XBoxZone &box,
|
|
ENUM_X_DIRECTION &dir,
|
|
X121SMCStrategySignalProviderData &provider,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
box.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Fil Selected Data ...
|
|
XPOIState cState;
|
|
X121Conditions cXConditions;
|
|
XPOIStateEvents cStateEvents;
|
|
XC121SMCCycleHelper *cHelper;
|
|
X121SMCCycleConditions cConditions;
|
|
result = provider.SelectCycle(
|
|
cycle,
|
|
cState,
|
|
cStateEvents,
|
|
cXConditions,
|
|
cHelper,
|
|
cConditions //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
cState.Clean();
|
|
ZeroMemory(cHelper);
|
|
cConditions.Clean();
|
|
cXConditions.Clean();
|
|
cStateEvents.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Normalize Args ...
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
int zIDX = barIndex;
|
|
int cIDX = zIDX + 1;
|
|
int pIDX = cIDX + 1;
|
|
int ppIDX = pIDX + 1;
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
XOHCL zBar;
|
|
XOHCL cBar;
|
|
XOHCL pBar;
|
|
XOHCL pPBar;
|
|
|
|
//
|
|
// Initial Bars ...
|
|
result = zBar.Init(
|
|
cState.symbol,
|
|
cState.period,
|
|
barIndex //
|
|
);
|
|
result =
|
|
result &&
|
|
zBar.GetPreviousBar(cBar);
|
|
result =
|
|
result &&
|
|
cBar.GetPreviousBar(pBar);
|
|
result =
|
|
result &&
|
|
pBar.GetPreviousBar(pPBar);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
cState.Clean();
|
|
ZeroMemory(cHelper);
|
|
cConditions.Clean();
|
|
cXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Checking Conditions ...
|
|
|
|
//
|
|
// Retrieve Some Values ...
|
|
|
|
//
|
|
double peak = cXConditions.peaksBuffer[cIDX];
|
|
double peakZ = cXConditions.peaksBuffer[zIDX];
|
|
double peakP = cXConditions.peaksBuffer[pIDX];
|
|
double peakPP = cXConditions.peaksBuffer[ppIDX];
|
|
|
|
//
|
|
double vale = cXConditions.valesBuffer[cIDX];
|
|
double valeZ = cXConditions.valesBuffer[zIDX];
|
|
double valeP = cXConditions.valesBuffer[pIDX];
|
|
double valePP = cXConditions.valesBuffer[ppIDX];
|
|
|
|
//
|
|
double atrUpperSM = cXConditions.atrUpperSMBuffer[cIDX];
|
|
double atrLowerSM = cXConditions.atrLowerSMBuffer[cIDX];
|
|
|
|
//
|
|
double atrUpperSMZ = cXConditions.atrUpperSMBuffer[zIDX];
|
|
double atrLowerSMZ = cXConditions.atrLowerSMBuffer[zIDX];
|
|
|
|
//
|
|
double atrUpperSMP = cXConditions.atrUpperSMBuffer[pIDX];
|
|
double atrLowerSMP = cXConditions.atrLowerSMBuffer[pIDX];
|
|
|
|
//
|
|
double atrUpperSMPP = cXConditions.atrUpperSMBuffer[ppIDX];
|
|
double atrLowerSMPP = cXConditions.atrLowerSMBuffer[ppIDX];
|
|
|
|
//
|
|
double rsiChange = cXConditions.rsiChangeBuffer[cIDX];
|
|
double rsiChangeZ = cXConditions.rsiChangeBuffer[zIDX];
|
|
double rsiChangeP = cXConditions.rsiChangeBuffer[pIDX];
|
|
double rsiChangePP = cXConditions.rsiChangeBuffer[ppIDX];
|
|
|
|
//
|
|
double rsiChangeSM = cXConditions.rsiChangeSMBuffer[cIDX];
|
|
double rsiChangeSMZ = cXConditions.rsiChangeSMBuffer[zIDX];
|
|
double rsiChangeSMP = cXConditions.rsiChangeSMBuffer[pIDX];
|
|
double rsiChangeSMPP = cXConditions.rsiChangeSMBuffer[ppIDX];
|
|
|
|
//
|
|
double peaksGolden = cXConditions.peaksGoldenBuffer[cIDX];
|
|
double peaksGoldenZ = cXConditions.peaksGoldenBuffer[zIDX];
|
|
double peaksGoldenP = cXConditions.peaksGoldenBuffer[pIDX];
|
|
double peaksGoldenPP = cXConditions.peaksGoldenBuffer[ppIDX];
|
|
|
|
//
|
|
double valesGolden = cXConditions.valesGoldenBuffer[cIDX];
|
|
double valesGoldenZ = cXConditions.valesGoldenBuffer[zIDX];
|
|
double valesGoldenP = cXConditions.valesGoldenBuffer[pIDX];
|
|
double valesGoldenPP = cXConditions.valesGoldenBuffer[ppIDX];
|
|
|
|
//
|
|
double priceChange = cXConditions.priceChangeBuffer[cIDX];
|
|
double priceChangeZ = cXConditions.priceChangeBuffer[zIDX];
|
|
double priceChangeP = cXConditions.priceChangeBuffer[pIDX];
|
|
double priceChangePP = cXConditions.priceChangeBuffer[ppIDX];
|
|
|
|
//
|
|
double priceChangeSM = cXConditions.priceChangeSMBuffer[cIDX];
|
|
double priceChangeSMZ = cXConditions.priceChangeSMBuffer[zIDX];
|
|
double priceChangeSMP = cXConditions.priceChangeSMBuffer[pIDX];
|
|
double priceChangeSMPP = cXConditions.priceChangeSMBuffer[ppIDX];
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
bool isPSwingLow =
|
|
//
|
|
(pBar.low < pPBar.low &&
|
|
pBar.low < cBar.low &&
|
|
zBar.open > cBar.low)
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCSwingLow =
|
|
//
|
|
(pBar.low < pPBar.low &&
|
|
cBar.low < pBar.low &&
|
|
zBar.close > cBar.low)
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isSwingLow =
|
|
//
|
|
isPSwingLow ||
|
|
isCSwingLow
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isPSwingHigh =
|
|
//
|
|
pBar.high >= pPBar.high &&
|
|
pBar.high > cBar.high &&
|
|
zBar.open < cBar.high
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCSwingHigh =
|
|
//
|
|
(pBar.high >= pPBar.high &&
|
|
cBar.high > pBar.high &&
|
|
zBar.close < cBar.high)
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isSwingHigh =
|
|
//
|
|
isPSwingHigh &&
|
|
isCSwingHigh
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isBarsOverPeaksGoldenZone =
|
|
//
|
|
cBar.high > peaksGolden &&
|
|
pBar.high > peaksGoldenP
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isBarsUnderValesGoldenZone =
|
|
//
|
|
cBar.low < valesGolden &&
|
|
pBar.low < valesGoldenP
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isBarsOverAtrUpper =
|
|
//
|
|
cBar.high > atrUpperSM &&
|
|
pBar.high > atrUpperSMP
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isBarsUnderAtrLower =
|
|
//
|
|
cBar.low < atrLowerSM &&
|
|
pBar.low < atrLowerSMP
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isRsiChangeOverAtrUpper =
|
|
rsiChangeP > atrUpperSMP;
|
|
|
|
//
|
|
bool isRsiChangeUnderAtrLower =
|
|
rsiChangeP < atrLowerSMP;
|
|
|
|
//
|
|
bool isRsiChangeOverPeaksGoldenZone =
|
|
rsiChangeP > peaksGoldenP;
|
|
|
|
//
|
|
bool isRsiChangeUnderValesGoldenZone =
|
|
rsiChangeP < valesGoldenP;
|
|
|
|
//
|
|
bool isPriceChangeOverAtrUpper =
|
|
priceChangeP > atrUpperSMP;
|
|
|
|
//
|
|
bool isPriceChangeUnderAtrLower =
|
|
priceChangeP < atrLowerSMP;
|
|
|
|
//
|
|
bool isPriceChangeOverPeaksGoldenZone =
|
|
priceChangeP > peaksGoldenP;
|
|
|
|
//
|
|
bool isPriceChangeUnderValesGoldenZone =
|
|
priceChangeP < valesGoldenP;
|
|
|
|
//
|
|
// XPV Peaks or Vales ...
|
|
|
|
//
|
|
bool isCBarEqualsToPeak = cBar.high == peak;
|
|
bool isCBarEqualsToVale = cBar.low == vale;
|
|
|
|
//
|
|
bool isPBarEqualsToPeak = pBar.high == peakP;
|
|
bool isPBarEqualsToVale = pBar.low == valeP;
|
|
|
|
//
|
|
bool isPPBarEqualsToPeak = pPBar.high == peakPP;
|
|
bool isPPBarEqualsToVale = pPBar.low == valePP;
|
|
|
|
//
|
|
bool isBarsEqualsToPeak = isCBarEqualsToPeak ||
|
|
isPBarEqualsToPeak ||
|
|
isPPBarEqualsToPeak;
|
|
bool isBarsEqualsToVale = isCBarEqualsToVale ||
|
|
isPBarEqualsToVale ||
|
|
isPPBarEqualsToVale;
|
|
|
|
//
|
|
// Detect VPatterns ...
|
|
|
|
//
|
|
bool isRsiChangeBullishVPattern =
|
|
//
|
|
rsiChangeP < rsiChangePP &&
|
|
rsiChangeP < rsiChange &&
|
|
rsiChangeP < rsiChangeZ
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isRsiChangeBearishVPattern =
|
|
//
|
|
rsiChangeP > rsiChangePP &&
|
|
rsiChangeP > rsiChange &&
|
|
rsiChangeP > rsiChangeZ
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isRsiChangeBullish =
|
|
//
|
|
(isRsiChangeUnderAtrLower &&
|
|
isRsiChangeBullishVPattern &&
|
|
isRsiChangeUnderValesGoldenZone)
|
|
//
|
|
;
|
|
|
|
bool isRsiChangeBearish =
|
|
//
|
|
(isRsiChangeOverAtrUpper &&
|
|
isRsiChangeBearishVPattern &&
|
|
isRsiChangeOverPeaksGoldenZone)
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isPriceChangeBullishVPattern =
|
|
//
|
|
priceChangeP < priceChangePP &&
|
|
priceChangeP < priceChange &&
|
|
priceChangeP < priceChangeZ
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isPriceChangeBearishVPattern =
|
|
//
|
|
priceChangeP > priceChangePP &&
|
|
priceChangeP > priceChange &&
|
|
priceChangeP > priceChangeZ
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isPriceChangeBullish =
|
|
//
|
|
(isPriceChangeUnderAtrLower &&
|
|
isPriceChangeBullishVPattern &&
|
|
isPriceChangeUnderValesGoldenZone)
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isPriceChangeBearish =
|
|
//
|
|
(isPriceChangeOverAtrUpper &&
|
|
isPriceChangeBearishVPattern &&
|
|
isPriceChangeOverPeaksGoldenZone)
|
|
//
|
|
;
|
|
|
|
//
|
|
// XVWAP ...
|
|
|
|
//
|
|
bool isVWapIsBullish =
|
|
//
|
|
(cXConditions.isVWapBullishOrdered &&
|
|
cXConditions.isVWapSwitchedToBullishState)
|
|
//
|
|
||
|
|
//
|
|
(cXConditions.isVWapBullishState &&
|
|
cXConditions.isVWapSwitchedToBullishOrdered)
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isVWapIsBearish =
|
|
//
|
|
(cXConditions.isVWapBearishOrdered &&
|
|
cXConditions.isVWapSwitchedToBearishState)
|
|
//
|
|
||
|
|
//
|
|
(cXConditions.isVWapBearishState &&
|
|
cXConditions.isVWapSwitchedToBearishOrdered)
|
|
//
|
|
;
|
|
|
|
//
|
|
// Checking Bar States ...
|
|
|
|
//
|
|
ENUM_X_DIRECTION cBarPosDir;
|
|
bool isCBarValidForPosition =
|
|
cHelper
|
|
.mBarAnalyser
|
|
.IsValidForPosition(
|
|
cBar,
|
|
cBarPosDir //
|
|
);
|
|
|
|
//
|
|
ENUM_X_DIRECTION pBarPosDir;
|
|
bool isPBarValidForPosition =
|
|
cHelper
|
|
.mBarAnalyser
|
|
.IsValidForPosition(
|
|
pBar,
|
|
pBarPosDir //
|
|
);
|
|
|
|
//
|
|
bool isBarValidForBullish =
|
|
//
|
|
(isCBarValidForPosition &&
|
|
IsBullish(cBarPosDir))
|
|
//
|
|
&&
|
|
//
|
|
(isPBarValidForPosition &&
|
|
IsBullish(pBarPosDir))
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isBarValidForBearish =
|
|
//
|
|
(isCBarValidForPosition &&
|
|
IsBearish(cBarPosDir))
|
|
//
|
|
&&
|
|
//
|
|
(isPBarValidForPosition &&
|
|
IsBearish(pBarPosDir))
|
|
//
|
|
;
|
|
|
|
//
|
|
// Summarize Conditions ...
|
|
|
|
//
|
|
isBullish =
|
|
//
|
|
// isSwingLow &&
|
|
isVWapIsBullish // &&
|
|
// isBarsEqualsToVale &&
|
|
// isRsiChangeBullish &&
|
|
// isBarsUnderAtrLower &&
|
|
// isBarValidForBullish &&
|
|
// isPriceChangeBullish &&
|
|
// isBarsUnderValesGoldenZone
|
|
//
|
|
;
|
|
|
|
//
|
|
isBearish =
|
|
//
|
|
//isSwingHigh &&
|
|
isVWapIsBearish // &&
|
|
//isBarsEqualsToPeak &&
|
|
// isBarsOverAtrUpper &&
|
|
// isRsiChangeBearish &&
|
|
// isBarValidForBearish &&
|
|
// isPriceChangeBearish &&
|
|
// isBarsOverPeaksGoldenZone
|
|
//
|
|
;
|
|
|
|
//
|
|
// Filling Requirements ...
|
|
result =
|
|
isBullish ||
|
|
isBearish;
|
|
if (result)
|
|
{
|
|
//
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
box.dir = dir;
|
|
box.from = pPBar.time;
|
|
box.to = TimeCurrent();
|
|
box.symbol = cBar.symbol;
|
|
box.period = cBar.period;
|
|
|
|
//
|
|
double points = GetPoints(box.symbol);
|
|
|
|
//
|
|
// Usually is Preffered SL ...
|
|
double pivot = 0;
|
|
|
|
//
|
|
// Usually is Current Price or Entry Price ...
|
|
double point = GetEntry(
|
|
cBar.symbol,
|
|
dir //
|
|
);
|
|
|
|
//
|
|
box.upper =
|
|
isBullish
|
|
? point
|
|
: pivot;
|
|
|
|
//
|
|
box.lower =
|
|
isBullish
|
|
? pivot
|
|
: point;
|
|
|
|
//
|
|
XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer;
|
|
bool drawBoxes = true;
|
|
if (drawBoxes)
|
|
{
|
|
//
|
|
if (box.IsValid())
|
|
{
|
|
//
|
|
XCBoxObject *iObj;
|
|
bool isCreated = drawer.DrawBox(
|
|
box,
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
//
|
|
// TODO: ...
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check All Conditions ...
|
|
result =
|
|
box.IsValid() &&
|
|
HasDirection(dir) &&
|
|
(isBullish ||
|
|
isBearish);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
pPBar.Clean();
|
|
cState.Clean();
|
|
cConditions.Clean();
|
|
cConditions.Clean();
|
|
ZeroMemory(cHelper);
|
|
cStateEvents.Clean();
|
|
cXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasXSTRConditions(
|
|
ENUM_X_CYCLES cycle,
|
|
XBoxZone &box,
|
|
ENUM_X_DIRECTION &dir,
|
|
X121SMCStrategySignalProviderData &provider,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
box.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Fil Selected Data ...
|
|
XPOIState cState;
|
|
X121Conditions cXConditions;
|
|
XPOIStateEvents cStateEvents;
|
|
XC121SMCCycleHelper *cHelper;
|
|
X121SMCCycleConditions cConditions;
|
|
result = provider.SelectCycle(
|
|
cycle,
|
|
cState,
|
|
cStateEvents,
|
|
cXConditions,
|
|
cHelper,
|
|
cConditions //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
cState.Clean();
|
|
ZeroMemory(cHelper);
|
|
cConditions.Clean();
|
|
cXConditions.Clean();
|
|
cStateEvents.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Normalize Args ...
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
int zIDX = barIndex;
|
|
int cIDX = zIDX + 1;
|
|
int pIDX = cIDX + 1;
|
|
int ppIDX = pIDX + 1;
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
XOHCL zBar;
|
|
XOHCL cBar;
|
|
XOHCL pBar;
|
|
XOHCL pPBar;
|
|
|
|
//
|
|
// Initial Bars ...
|
|
result = zBar.Init(
|
|
cState.symbol,
|
|
cState.period,
|
|
barIndex //
|
|
);
|
|
result =
|
|
result &&
|
|
zBar.GetPreviousBar(cBar);
|
|
result =
|
|
result &&
|
|
cBar.GetPreviousBar(pBar);
|
|
result =
|
|
result &&
|
|
pBar.GetPreviousBar(pPBar);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
cState.Clean();
|
|
ZeroMemory(cHelper);
|
|
cConditions.Clean();
|
|
cXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Checking Conditions ...
|
|
|
|
//
|
|
// XSTR ...
|
|
bool isStrIsBullish =
|
|
(cXConditions.isStrBullish ||
|
|
cXConditions.isStrSwitchedToBullish);
|
|
bool isStrIsBearish =
|
|
(cXConditions.isStrBearish ||
|
|
cXConditions.isStrSwitchedToBearish);
|
|
|
|
//
|
|
// Detecting Str Box ...
|
|
XBoxZone strBox;
|
|
bool hasStrBox = false;
|
|
if (!hasStrBox)
|
|
{
|
|
//
|
|
hasStrBox =
|
|
cXConditions.isStrBullish ||
|
|
cXConditions.isStrBearish;
|
|
if (hasStrBox)
|
|
{
|
|
//
|
|
ENUM_X_DIRECTION strDir =
|
|
cXConditions.isStrBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
XOHCL lastBar;
|
|
ENUM_X_DIRECTION lastDir;
|
|
bool hasLast =
|
|
cHelper
|
|
.DetectNearestStrSwitched(
|
|
lastBar,
|
|
lastDir,
|
|
zIDX //
|
|
);
|
|
|
|
//
|
|
XOHCL prevBar;
|
|
ENUM_X_DIRECTION prevDir;
|
|
bool hasPrev =
|
|
hasLast &&
|
|
cHelper
|
|
.DetectNearestStrSwitched(
|
|
prevBar,
|
|
prevDir,
|
|
lastBar.Index() + 1 //
|
|
);
|
|
|
|
//
|
|
hasStrBox =
|
|
hasLast &&
|
|
hasPrev;
|
|
if (hasStrBox)
|
|
{
|
|
//
|
|
int fromIDX = MathMax(
|
|
lastBar.Index(),
|
|
prevBar.Index() //
|
|
);
|
|
|
|
//
|
|
string symbol = cBar.symbol;
|
|
ENUM_TIMEFRAMES period = cBar.period;
|
|
|
|
//
|
|
datetime from = GetBarTime(
|
|
symbol,
|
|
period,
|
|
fromIDX //
|
|
);
|
|
|
|
//
|
|
int length = fromIDX - barIndex;
|
|
|
|
//
|
|
double upper = zBar.FindHighest(
|
|
length,
|
|
MODE_HIGH //
|
|
);
|
|
|
|
//
|
|
double lower = zBar.FindLowest(
|
|
length,
|
|
MODE_LOW //
|
|
);
|
|
|
|
//
|
|
strBox.from = from;
|
|
strBox.dir = strDir;
|
|
strBox.lower = lower;
|
|
strBox.upper = upper;
|
|
strBox.symbol = symbol;
|
|
strBox.period = period;
|
|
strBox.type = "XSTRBox";
|
|
strBox.to = TimeCurrent();
|
|
|
|
//
|
|
hasStrBox = strBox.IsValid();
|
|
}
|
|
|
|
//
|
|
lastBar.Clean();
|
|
prevBar.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// XFastMa ...
|
|
|
|
//
|
|
bool isFastMaOverStr =
|
|
(cXConditions.x3maFastBuffer[cIDX] > cXConditions.strBuffer[cIDX]);
|
|
|
|
//
|
|
bool isFastMaUnderStr =
|
|
(cXConditions.x3maFastBuffer[cIDX] < cXConditions.strBuffer[cIDX]);
|
|
|
|
//
|
|
bool isFastMaBullishReject =
|
|
cBar.low < pBar.low &&
|
|
cBar.low > cXConditions.strBuffer[cIDX] &&
|
|
cBar.low < cXConditions.x3maFastBuffer[cIDX] &&
|
|
cBar.GetDown() > cXConditions.x3maFastBuffer[cIDX];
|
|
|
|
//
|
|
bool isFastMaBearishReject =
|
|
cBar.high > pBar.high &&
|
|
cBar.high < cXConditions.strBuffer[cIDX] &&
|
|
cBar.high > cXConditions.x3maFastBuffer[cIDX] &&
|
|
cBar.GetUp() < cXConditions.x3maFastBuffer[cIDX];
|
|
|
|
//
|
|
// Summarize Conditions ...
|
|
|
|
//
|
|
isBullish =
|
|
//
|
|
// false
|
|
hasStrBox &&
|
|
isStrIsBullish &&
|
|
isFastMaOverStr &&
|
|
isFastMaBullishReject
|
|
//
|
|
//
|
|
;
|
|
|
|
//
|
|
isBearish =
|
|
//
|
|
// false
|
|
hasStrBox &&
|
|
isStrIsBearish &&
|
|
isFastMaUnderStr &&
|
|
isFastMaBearishReject
|
|
//
|
|
;
|
|
|
|
//
|
|
// Filling Requirements ...
|
|
result =
|
|
isBullish ||
|
|
isBearish;
|
|
if (result)
|
|
{
|
|
//
|
|
XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer;
|
|
XCBoxObject *iObj;
|
|
bool isCreated = drawer.DrawBox(
|
|
strBox,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
Print("STRBox");
|
|
}
|
|
|
|
//
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
box.dir = dir;
|
|
box.from = pPBar.time;
|
|
box.to = TimeCurrent();
|
|
box.symbol = cBar.symbol;
|
|
box.period = cBar.period;
|
|
|
|
//
|
|
double points = GetPoints(box.symbol);
|
|
|
|
//
|
|
double pivot = cXConditions.strBuffer[cIDX];
|
|
// isBullish
|
|
// ? cBar.low - (points * 5)
|
|
// : cBar.high + (points * 5);
|
|
|
|
//
|
|
double point = GetEntry(
|
|
cBar.symbol,
|
|
dir //
|
|
);
|
|
|
|
//
|
|
box.upper =
|
|
isBullish
|
|
? point
|
|
: pivot;
|
|
|
|
//
|
|
box.lower =
|
|
isBullish
|
|
? pivot
|
|
: point;
|
|
|
|
//
|
|
bool drawBoxes = true;
|
|
if (drawBoxes)
|
|
{
|
|
//
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check All Conditions ...
|
|
result =
|
|
box.IsValid() &&
|
|
HasDirection(dir) &&
|
|
(isBullish ||
|
|
isBearish);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
pPBar.Clean();
|
|
cState.Clean();
|
|
strBox.Clean();
|
|
cConditions.Clean();
|
|
cConditions.Clean();
|
|
ZeroMemory(cHelper);
|
|
cStateEvents.Clean();
|
|
cXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
// |