580 lines
14 KiB
Plaintext
580 lines
14 KiB
Plaintext
|
|
//
|
|
bool DetectNearestTenKijCross(
|
|
XOHCL &bar,
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0,
|
|
int maxAllowedBars = 20 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bar.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
maxAllowedBars = NormalizeInt(maxAllowedBars, 20);
|
|
|
|
//
|
|
// Looping Through LoopBack Period ...
|
|
// for Detecting Result ...
|
|
for (int i = barIndex; i < barIndex + maxAllowedBars; i++)
|
|
{
|
|
//
|
|
XOHCL iBar;
|
|
result = iBar.Init(
|
|
GetSymbol(),
|
|
GetPeriod(),
|
|
i //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
double iTSen = mX121Helper.xichHelper.GetTenkanSen(i);
|
|
double iTSenP = mX121Helper.xichHelper.GetTenkanSen(i + 1);
|
|
|
|
//
|
|
double iKSen = mX121Helper.xichHelper.GetKijunSen(i);
|
|
double iKSenP = mX121Helper.xichHelper.GetKijunSen(i + 1);
|
|
|
|
//
|
|
bool isTSenOverKSen = iTSen > iKSen;
|
|
bool isTSenOverKSenP = iTSenP > iKSenP;
|
|
|
|
//
|
|
bool isTSenUnderKSen = iTSen < iKSen;
|
|
bool isTSenUnderKSenP = iTSenP < iKSenP;
|
|
|
|
//
|
|
|
|
//
|
|
bool isTSenCrossedOverKSen = isTSenOverKSen &&
|
|
!isTSenOverKSenP;
|
|
|
|
//
|
|
bool isTSenCrossedUnderKSen = isTSenUnderKSen &&
|
|
!isTSenUnderKSenP;
|
|
|
|
//
|
|
result = isTSenCrossedOverKSen ||
|
|
isTSenCrossedUnderKSen;
|
|
if (result)
|
|
{
|
|
//
|
|
bar = iBar;
|
|
|
|
//
|
|
dir = isTSenCrossedOverKSen
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
iBar.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool DetectNearestVolumeSwitched(
|
|
XOHCL &bar,
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0,
|
|
int maxAllowedBars = 20 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bar.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
maxAllowedBars = NormalizeInt(maxAllowedBars, 20);
|
|
|
|
//
|
|
// Looping Through LoopBack Period ...
|
|
// for Detecting Result ...
|
|
for (int i = barIndex; i < barIndex + maxAllowedBars; i++)
|
|
{
|
|
//
|
|
XOHCL iBar;
|
|
result = iBar.Init(
|
|
GetSymbol(),
|
|
GetPeriod(),
|
|
i //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
double iBullVMa = mX121Helper.xvolumeHelper.GetBullishVolumeMa(i);
|
|
double iBullVMaP = mX121Helper.xvolumeHelper.GetBullishVolumeMa(i + 1);
|
|
|
|
//
|
|
double iBearVMa = mX121Helper.xvolumeHelper.GetBearishVolumeMa(i);
|
|
double iBearVMaP = mX121Helper.xvolumeHelper.GetBearishVolumeMa(i + 1);
|
|
|
|
//
|
|
bool isBullVMaOverBearVMa = iBullVMa > iBearVMa;
|
|
bool isBullVMaOverBearVMaP = iBullVMaP > iBearVMaP;
|
|
bool isCrossOver = isBullVMaOverBearVMa &&
|
|
!isBullVMaOverBearVMaP;
|
|
|
|
//
|
|
bool isBullVMaUnderBearVMa = iBullVMa < iBearVMa;
|
|
bool isBullVMaUnderBearVMaP = iBullVMaP < iBearVMaP;
|
|
bool isCrossUnder = isBullVMaUnderBearVMa &&
|
|
!isBullVMaUnderBearVMaP;
|
|
|
|
//
|
|
result = isCrossOver ||
|
|
isCrossUnder;
|
|
if (result)
|
|
{
|
|
//
|
|
bar = iBar;
|
|
|
|
//
|
|
dir = isCrossOver
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
iBar.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool DetectNearestDeltaSwitched(
|
|
XOHCL &bar,
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0,
|
|
int maxAllowedBars = 20 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bar.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
maxAllowedBars = NormalizeInt(maxAllowedBars, 20);
|
|
|
|
//
|
|
// Looping Through LoopBack Period ...
|
|
// for Detecting Result ...
|
|
for (int i = barIndex; i < barIndex + maxAllowedBars; i++)
|
|
{
|
|
//
|
|
XOHCL iBar;
|
|
result = iBar.Init(
|
|
GetSymbol(),
|
|
GetPeriod(),
|
|
i //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
double iDelta = mX121Helper.xdeltaHelper.GetDelta(i);
|
|
double iDeltaP = mX121Helper.xdeltaHelper.GetDelta(i + 1);
|
|
|
|
//
|
|
double iDeltaMa = mX121Helper.xdeltaHelper.GetDeltaMa(i);
|
|
double iDeltaMaP = mX121Helper.xdeltaHelper.GetDeltaMa(i + 1);
|
|
|
|
//
|
|
bool isDeltaOverMa = iDelta > iDeltaMa;
|
|
bool isDeltaOverMaP = iDeltaP > iDeltaMaP;
|
|
|
|
//
|
|
bool isDeltaUnderMa = iDelta < iDeltaMa;
|
|
bool isDeltaUnderMaP = iDeltaP < iDeltaMaP;
|
|
|
|
//
|
|
bool isCrossOver = isDeltaOverMa &&
|
|
!isDeltaOverMaP;
|
|
|
|
//
|
|
bool isCrossUnder = isDeltaUnderMa &&
|
|
!isDeltaUnderMaP;
|
|
|
|
//
|
|
result = isCrossOver ||
|
|
isCrossUnder;
|
|
if (result)
|
|
{
|
|
//
|
|
bar = iBar;
|
|
|
|
//
|
|
dir = isCrossOver
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
iBar.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//
|
|
// Activated Boxes ...
|
|
bool HasActivatedBoxConditions(
|
|
ENUM_X_CYCLES cycle,
|
|
XSignalBox &box,
|
|
ENUM_X_DIRECTION &dir,
|
|
XSignalBox &waitingBoxes[],
|
|
X121SMCStrategySignalProviderData &provider,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
box.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Checking Waiting Baoxes Exists ...
|
|
result = HasChild(waitingBoxes);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
Parse(cXConditions);
|
|
|
|
//
|
|
// 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;
|
|
|
|
//
|
|
// Initial Bars ...
|
|
result = zBar.Init(
|
|
cState.symbol,
|
|
cState.period,
|
|
barIndex //
|
|
);
|
|
result =
|
|
result &&
|
|
zBar.GetPreviousBar(cBar);
|
|
result =
|
|
result &&
|
|
cBar.GetPreviousBar(pBar);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
cState.Clean();
|
|
ZeroMemory(cHelper);
|
|
cConditions.Clean();
|
|
cXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Checking Bar Based on Positions State ...
|
|
ENUM_X_DIRECTION iBarPosDir;
|
|
bool isBarValidForDir = cHelper
|
|
.mBarAnalyser
|
|
.IsValidForPosition(
|
|
cBar,
|
|
iBarPosDir //
|
|
);
|
|
bool isBarValidForBullish =
|
|
isBarValidForDir &&
|
|
IsBullish(iBarPosDir);
|
|
bool isBarValidForBearish =
|
|
isBarValidForDir &&
|
|
IsBearish(iBarPosDir);
|
|
|
|
//
|
|
// Extract Selected Boxes ...
|
|
XBoxZone selectedBox;
|
|
XSignalBox iSignalBox;
|
|
count = ArraySize(waitingBoxes);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XSignalBox iBox = waitingBoxes[i];
|
|
|
|
//
|
|
bool isBullish = iBox.ob.IsBullish();
|
|
|
|
//
|
|
has = cBar.low < iBox.sharp.upper &&
|
|
cBar.low > iBox.sharp.lower &&
|
|
cBar.high > iBox.sharp.lower &&
|
|
cBar.high < iBox.sharp.upper;
|
|
|
|
//
|
|
// Force Using OB ...
|
|
if (has)
|
|
{
|
|
//
|
|
iSignalBox = iBox;
|
|
if (!selectedBox.IsValid())
|
|
{
|
|
selectedBox = iBox.ob;
|
|
}
|
|
iBox.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
}
|
|
result =
|
|
iSignalBox.IsValid() &&
|
|
selectedBox.IsValid();
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
cState.Clean();
|
|
iSignalBox.Clean();
|
|
selectedBox.Clean();
|
|
ZeroMemory(cHelper);
|
|
cConditions.Clean();
|
|
cXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool hasSignalBox = iSignalBox.IsValid();
|
|
bool isSignalBoxBullish = IsBullish(iSignalBox.ob.dir);
|
|
|
|
//
|
|
// Checking Other Conditions ...
|
|
|
|
//
|
|
// XVWAP ...
|
|
|
|
//
|
|
bool isVWapSlopeBullish =
|
|
cXConditions.isVwapFastSlopeBullish &&
|
|
cXConditions.isVwapMidSlopeBullish &&
|
|
cXConditions.isVwapSlowSlopeBullish;
|
|
|
|
//
|
|
bool isVWapSlopeBearish =
|
|
cXConditions.isVwapFastSlopeBearish &&
|
|
cXConditions.isVwapMidSlopeBearish &&
|
|
cXConditions.isVwapSlowSlopeBearish;
|
|
|
|
//
|
|
bool isVWapBullishCondition =
|
|
(cXConditions.isVWapBullishOrdered &&
|
|
cXConditions.isVWapSwitchedToBullishState) ||
|
|
(cXConditions.isVWapBullishState &&
|
|
cXConditions.isVWapSwitchedToBullishOrdered);
|
|
|
|
//
|
|
bool isVWapBearishCondition =
|
|
(cXConditions.isVWapBearishOrdered &&
|
|
cXConditions.isVWapSwitchedToBearishState) ||
|
|
(cXConditions.isVWapBearishState &&
|
|
cXConditions.isVWapSwitchedToBearishOrdered);
|
|
|
|
//
|
|
// Bullish Conditions ...
|
|
isBullish =
|
|
//
|
|
// Base Condition ...
|
|
(
|
|
//
|
|
hasSignalBox &&
|
|
isSignalBoxBullish &&
|
|
isVWapSlopeBullish &&
|
|
isBarValidForBullish &&
|
|
isVWapBullishCondition
|
|
//
|
|
)
|
|
//
|
|
;
|
|
|
|
//
|
|
// Bearish Conditions ...
|
|
isBearish =
|
|
//
|
|
// Base Condition ...
|
|
(
|
|
//
|
|
hasSignalBox &&
|
|
isVWapSlopeBearish &&
|
|
!isSignalBoxBullish &&
|
|
isBarValidForBearish &&
|
|
isVWapBearishCondition
|
|
//
|
|
)
|
|
//
|
|
;
|
|
|
|
//
|
|
// Filling Requirements ...
|
|
result =
|
|
isBullish ||
|
|
isBearish;
|
|
if (result)
|
|
{
|
|
//
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
box = iSignalBox;
|
|
box.UpdateTo(TimeCurrent());
|
|
|
|
//
|
|
// Provide TP/SL ...
|
|
|
|
//
|
|
box.sl = isBullish
|
|
? cXConditions.vwapMin
|
|
: cXConditions.vwapMax;
|
|
|
|
//
|
|
box.tp = isBullish
|
|
? box.sharp.upper
|
|
: box.sharp.lower;
|
|
}
|
|
|
|
//
|
|
// Check All Conditions ...
|
|
result =
|
|
box.IsValid() &&
|
|
HasDirection(dir) &&
|
|
(isBullish ||
|
|
isBearish);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
cState.Clean();
|
|
iSignalBox.Clean();
|
|
selectedBox.Clean();
|
|
ZeroMemory(cHelper);
|
|
cConditions.Clean();
|
|
cStateEvents.Clean();
|
|
cXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|