1735 lines
38 KiB
Plaintext
1735 lines
38 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_XIND,
|
|
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 ...
|
|
|
|
//
|
|
// Validate FVG BOXes ...
|
|
|
|
//
|
|
bool IsFVGBoxValid(
|
|
XBoxZone &box,
|
|
ENUM_X_CYCLES cycle,
|
|
X121SMCStrategySignalProviderData &provider //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = box.IsValid();
|
|
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;
|
|
}
|
|
|
|
//
|
|
bool isBoxBullish = box.IsBullish();
|
|
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
XBoxZone tmpBoxes[];
|
|
count = cState.FairValueGapsAsBox(tmpBoxes);
|
|
has = IsValidSize(count);
|
|
|
|
//
|
|
// Check Must Contains Inner Cycle FVG ...
|
|
XBoxZone selectedBox;
|
|
bool hasSelectedBox = false;
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XBoxZone iBox = tmpBoxes[i];
|
|
|
|
//
|
|
// Regular Validation of Boxes ...
|
|
bool isValid = IsBoxValid(
|
|
iBox,
|
|
0,
|
|
iBox.period //
|
|
);
|
|
bool isTypePassed = iBox.dir == box.dir;
|
|
bool isFromPssed = iBox.from >= box.from;
|
|
bool isPlacePassed =
|
|
IsBoxInsideOr(
|
|
iBox,
|
|
box //
|
|
) &&
|
|
(isBoxBullish
|
|
? iBox.lower >= box.lower
|
|
: iBox.upper <= box.upper);
|
|
has =
|
|
isValid &&
|
|
isFromPssed &&
|
|
isTypePassed &&
|
|
isPlacePassed;
|
|
if (!has)
|
|
{
|
|
//
|
|
iBox.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
has =
|
|
!hasSelectedBox
|
|
? true
|
|
: isBoxBullish
|
|
? selectedBox.upper > iBox.upper
|
|
: selectedBox.lower < iBox.lower;
|
|
if (has)
|
|
{
|
|
//
|
|
selectedBox = iBox;
|
|
hasSelectedBox = selectedBox.IsValid();
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
result = hasSelectedBox;
|
|
|
|
//
|
|
cState.Clean();
|
|
Clean(tmpBoxes);
|
|
selectedBox.Clean();
|
|
ZeroMemory(cHelper);
|
|
cConditions.Clean();
|
|
cXConditions.Clean();
|
|
cStateEvents.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool CheckConsolidationPassedBox(
|
|
XBoxZone &consolidationBox,
|
|
XBoxZone &box,
|
|
XPOIState &state //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = box.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
XBoxZone selectedBox;
|
|
has = state.HasConsolidationZones();
|
|
if (has)
|
|
{
|
|
//
|
|
count = state.CountConsolidationZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XConsolidationZone iZone = state.consolidationZones[i];
|
|
has = ToBox(
|
|
selectedBox,
|
|
iZone //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iZone.Clean();
|
|
selectedBox.Clean();
|
|
continue;
|
|
};
|
|
|
|
//
|
|
// Check Selected Box is Related to BOX or not ...
|
|
bool isValid =
|
|
//
|
|
// Direction Passed ...
|
|
selectedBox.dir == box.dir &&
|
|
//
|
|
// Time Passe ...
|
|
selectedBox.to > box.from &&
|
|
selectedBox.from < box.from &&
|
|
//
|
|
// Place Passed ...
|
|
(
|
|
//
|
|
// Upper Inside ...
|
|
(selectedBox.upper >= box.lower &&
|
|
selectedBox.upper <= box.upper)
|
|
//
|
|
||
|
|
//
|
|
// Lower Inside ...
|
|
(selectedBox.lower <= box.upper &&
|
|
selectedBox.lower >= box.lower)
|
|
//
|
|
||
|
|
//
|
|
// Fully Inside ...
|
|
(selectedBox.upper <= box.upper &&
|
|
selectedBox.lower >= box.lower)
|
|
//
|
|
);
|
|
if (isValid)
|
|
{
|
|
//
|
|
iZone.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
iZone.Clean();
|
|
selectedBox.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
result = selectedBox.IsValid();
|
|
if (result)
|
|
{
|
|
consolidationBox = selectedBox;
|
|
}
|
|
selectedBox.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Signalling Conditions Parsers ...
|
|
|
|
//
|
|
// Detect Signals Based On XPV Indicator Golden Zones ...
|
|
bool HasXINDConditions(
|
|
XBoxZone &waitingBoxes[],
|
|
XBoxZone &activatedBoxes[],
|
|
XBoxZone &breakedBoxes[],
|
|
ENUM_X_CYCLES cycle,
|
|
XBoxZone &box,
|
|
XBoxZone &zone,
|
|
ENUM_X_DIRECTION &dir,
|
|
X121SMCStrategySignalProviderData &provider,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
box.Clean();
|
|
zone.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Checking Required Zone Boxes for Signalling ...
|
|
int waitingBoxesCount = ArraySize(waitingBoxes);
|
|
int breakedBoxesCount = ArraySize(breakedBoxes);
|
|
int activatedBoxesCount = ArraySize(activatedBoxes);
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//
|
|
XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer;
|
|
|
|
//
|
|
// Select Waiting Box ...
|
|
XBoxZone selectedBox;
|
|
bool hasSelectedBox = false;
|
|
bool useWaitingBoxes = true;
|
|
bool useActivtedBoxes = true;
|
|
bool useBreakedBoxes = false;
|
|
XBoxZone selectedConsolidationBox;
|
|
bool hasSelectedConsolidationBox = false;
|
|
if (useWaitingBoxes && IsValidSize(waitingBoxesCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < waitingBoxesCount; i++)
|
|
{
|
|
//
|
|
XBoxZone iBox = waitingBoxes[i];
|
|
|
|
//
|
|
// Check PV Passed Box ...
|
|
has = IsBoxPVPassed(
|
|
iBox,
|
|
cXConditions //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
selectedBox = iBox;
|
|
iBox.Clean();
|
|
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Check Consolidation Passed Box ...
|
|
has = CheckConsolidationPassedBox(
|
|
selectedConsolidationBox,
|
|
iBox,
|
|
cState //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
selectedBox = iBox;
|
|
iBox.Clean();
|
|
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
hasSelectedBox = selectedBox.IsValid();
|
|
if (!hasSelectedBox)
|
|
{
|
|
selectedBox.Clean();
|
|
}
|
|
|
|
//
|
|
hasSelectedConsolidationBox = selectedConsolidationBox.IsValid();
|
|
if (!hasSelectedConsolidationBox)
|
|
{
|
|
selectedConsolidationBox.Clean();
|
|
}
|
|
}
|
|
if (useActivtedBoxes && !hasSelectedBox && IsValidSize(activatedBoxesCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < activatedBoxesCount; i++)
|
|
{
|
|
//
|
|
XBoxZone iBox = activatedBoxes[i];
|
|
|
|
//
|
|
// Check PV Passed Box ...
|
|
has = IsBoxPVPassed(
|
|
iBox,
|
|
cXConditions //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
selectedBox = iBox;
|
|
iBox.Clean();
|
|
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Check Consolidation Passed Box ...
|
|
has = CheckConsolidationPassedBox(
|
|
selectedConsolidationBox,
|
|
iBox,
|
|
cState //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
selectedBox = iBox;
|
|
iBox.Clean();
|
|
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
hasSelectedBox = selectedBox.IsValid();
|
|
if (!hasSelectedBox)
|
|
{
|
|
selectedBox.Clean();
|
|
}
|
|
|
|
//
|
|
hasSelectedConsolidationBox = selectedConsolidationBox.IsValid();
|
|
if (!hasSelectedConsolidationBox)
|
|
{
|
|
selectedConsolidationBox.Clean();
|
|
}
|
|
}
|
|
if (useBreakedBoxes && !hasSelectedBox && IsValidSize(breakedBoxesCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < breakedBoxesCount; i++)
|
|
{
|
|
//
|
|
XBoxZone iBox = breakedBoxes[i];
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
hasSelectedBox = selectedBox.IsValid();
|
|
if (!hasSelectedBox)
|
|
{
|
|
selectedBox.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
double selectedBoxMid = 0;
|
|
double selectedBoxStr = 0;
|
|
if (hasSelectedBox)
|
|
{
|
|
//
|
|
selectedBoxMid = (selectedBox.lower + ((selectedBox.upper - selectedBox.lower) / 2));
|
|
|
|
//
|
|
selectedBox.to = zBar.time;
|
|
CheckBoxStr(
|
|
cHelper,
|
|
selectedBox,
|
|
selectedBoxStr //
|
|
);
|
|
|
|
//
|
|
if (selectedBoxStr != 0)
|
|
{
|
|
//
|
|
long chartId = drawer.ChartIdentification();
|
|
int subWindow = drawer.SubWindowIdentification();
|
|
string name = selectedBox.GetTag() + "_SUPRES";
|
|
|
|
//
|
|
CChartObjectTrend *iObj;
|
|
iObj = new CChartObjectTrend();
|
|
has = iObj.Create(
|
|
chartId,
|
|
name,
|
|
subWindow,
|
|
selectedBox.from,
|
|
selectedBoxStr,
|
|
selectedBox.to,
|
|
selectedBoxStr //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
color lineColor =
|
|
selectedBox.IsBullish()
|
|
? clrLime
|
|
: clrRed;
|
|
iObj.Color(lineColor);
|
|
iObj.Width(2);
|
|
}
|
|
}
|
|
|
|
//
|
|
XCBoxObject *iObj;
|
|
has = drawer.DrawBox(
|
|
selectedBox,
|
|
iObj //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
iObj.BoxColor(clrCornflowerBlue);
|
|
iObj.BoxStyle(STYLE_SOLID);
|
|
iObj.BoxWidth(2);
|
|
|
|
//
|
|
Print("Selected Box ...");
|
|
}
|
|
}
|
|
|
|
//
|
|
if (hasSelectedConsolidationBox)
|
|
{
|
|
//
|
|
XCBoxObject *iObj;
|
|
has = drawer.DrawBox(
|
|
selectedConsolidationBox,
|
|
iObj //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
iObj.BoxWidth(2);
|
|
iObj.BoxStyle(STYLE_SOLID);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Bullish and Bearish Consolidation Zones ...
|
|
XBoxZone consolidationBox;
|
|
bool hasConsolidationBox = false;
|
|
if (!hasConsolidationBox)
|
|
{
|
|
//
|
|
hasConsolidationBox = cStateEvents.hasNewConsolidationZone;
|
|
if (hasConsolidationBox)
|
|
{
|
|
//
|
|
idx = GetYoungest(cState.consolidationZones);
|
|
has = IsValidIndex(idx);
|
|
if (has)
|
|
{
|
|
//
|
|
XConsolidationZone cZone = cState.consolidationZones[idx];
|
|
|
|
//
|
|
ToBox(
|
|
consolidationBox,
|
|
cZone //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
hasConsolidationBox = consolidationBox.IsValid();
|
|
// if (hasConsolidationBox)
|
|
// {
|
|
// //
|
|
// XCBoxObject *iObj;
|
|
// has = drawer.DrawBox(
|
|
// consolidationBox,
|
|
// iObj //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// color crlBox = consolidationBox.IsBullish()
|
|
// ? clrBlue
|
|
// : clrDarkRed;
|
|
|
|
// //
|
|
// iObj.BoxWidth(2);
|
|
// iObj.BoxColor(crlBox);
|
|
// iObj.BoxStyle(STYLE_SOLID);
|
|
// }
|
|
// }
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
// Reading Resources ...
|
|
|
|
//
|
|
double sarZ = cXConditions.sarBuffer[zIDX];
|
|
double sarC = cXConditions.sarBuffer[cIDX];
|
|
double sarP = cXConditions.sarBuffer[pIDX];
|
|
double sarPP = cXConditions.sarBuffer[ppIDX];
|
|
|
|
//
|
|
double peakZ = cXConditions.peaksBuffer[zIDX];
|
|
double peakC = cXConditions.peaksBuffer[cIDX];
|
|
double peakP = cXConditions.peaksBuffer[pIDX];
|
|
double peakPP = cXConditions.peaksBuffer[ppIDX];
|
|
|
|
//
|
|
double valeZ = cXConditions.valesBuffer[zIDX];
|
|
double valeC = cXConditions.valesBuffer[cIDX];
|
|
double valeP = cXConditions.valesBuffer[pIDX];
|
|
double valePP = cXConditions.valesBuffer[ppIDX];
|
|
|
|
//
|
|
double strZ = cXConditions.strBuffer[zIDX];
|
|
double strC = cXConditions.strBuffer[cIDX];
|
|
double strP = cXConditions.strBuffer[pIDX];
|
|
double strPP = cXConditions.strBuffer[ppIDX];
|
|
|
|
//
|
|
double priceChangeZ = cXConditions.priceChangeBuffer[zIDX];
|
|
double priceChangeC = cXConditions.priceChangeBuffer[cIDX];
|
|
double priceChangeP = cXConditions.priceChangeBuffer[pIDX];
|
|
double priceChangePP = cXConditions.priceChangeBuffer[ppIDX];
|
|
|
|
//
|
|
double peaksGoldenZ = cXConditions.peaksGoldenBuffer[zIDX];
|
|
double peaksGoldenC = cXConditions.peaksGoldenBuffer[cIDX];
|
|
double peaksGoldenP = cXConditions.peaksGoldenBuffer[pIDX];
|
|
double peaksGoldenPP = cXConditions.peaksGoldenBuffer[ppIDX];
|
|
|
|
//
|
|
double valesGoldenZ = cXConditions.valesGoldenBuffer[zIDX];
|
|
double valesGoldenC = cXConditions.valesGoldenBuffer[cIDX];
|
|
double valesGoldenP = cXConditions.valesGoldenBuffer[pIDX];
|
|
double valesGoldenPP = cXConditions.valesGoldenBuffer[ppIDX];
|
|
|
|
//
|
|
// Generate Conditions ...
|
|
|
|
//
|
|
bool isPBarBullishPriceChangeVPattern =
|
|
priceChangeP > priceChangePP &&
|
|
priceChangeP > priceChangeC;
|
|
|
|
//
|
|
bool isPBarBearishPriceChangeVPattern =
|
|
priceChangeP < priceChangePP &&
|
|
priceChangeP < priceChangeC;
|
|
|
|
//
|
|
bool isCBarBullishPriceChangeVPattern =
|
|
priceChangeC > priceChangeP &&
|
|
priceChangeC > priceChangeZ;
|
|
|
|
//
|
|
bool isCBarBearishPriceChangeVPattern =
|
|
priceChangeC < priceChangeP &&
|
|
priceChangeC < priceChangeZ;
|
|
|
|
//
|
|
bool isCPriceChangeUnderSelectedBoxMid =
|
|
selectedBoxMid > 0 &&
|
|
priceChangeC < selectedBoxMid;
|
|
|
|
//
|
|
bool isCPriceChangeOverSelectedBoxMid =
|
|
selectedBoxMid > 0 &&
|
|
priceChangeC > selectedBoxMid;
|
|
|
|
//
|
|
bool isPPriceChangeUnderSelectedBoxMid =
|
|
selectedBoxMid > 0 &&
|
|
priceChangeP < selectedBoxMid;
|
|
|
|
//
|
|
bool isPPriceChangeOverSelectedBoxMid =
|
|
selectedBoxMid > 0 &&
|
|
priceChangeP > selectedBoxMid;
|
|
|
|
//
|
|
bool isPriceChangeUnderSelectedBoxMid =
|
|
isCPriceChangeUnderSelectedBoxMid ||
|
|
isPPriceChangeUnderSelectedBoxMid;
|
|
|
|
//
|
|
bool isPriceChangeOverSelectedBoxMid =
|
|
isCPriceChangeOverSelectedBoxMid ||
|
|
isPPriceChangeOverSelectedBoxMid;
|
|
|
|
//
|
|
bool isBarBullishPriceChangeVPattern =
|
|
isPBarBullishPriceChangeVPattern ||
|
|
isCBarBullishPriceChangeVPattern;
|
|
|
|
//
|
|
bool isBarBearishPriceChangeVPattern =
|
|
isPBarBearishPriceChangeVPattern ||
|
|
isCBarBearishPriceChangeVPattern;
|
|
|
|
//
|
|
bool isPriceChangeBullishRejectedStr =
|
|
//
|
|
cXConditions.strStateBuffer[zIDX] > 0 &&
|
|
cXConditions.strStateBuffer[cIDX] > 0 &&
|
|
cXConditions.strStateBuffer[pIDX] > 0 &&
|
|
//
|
|
cXConditions.strBuffer[zIDX] == cXConditions.strBuffer[cIDX] &&
|
|
cXConditions.strBuffer[zIDX] == cXConditions.strBuffer[pIDX] &&
|
|
//
|
|
((priceChangeP < strC &&
|
|
priceChangeC > strC) ||
|
|
(priceChangeC < strC &&
|
|
priceChangeZ > strC))
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isPriceChangeBearishRejectedStr =
|
|
//
|
|
cXConditions.strStateBuffer[zIDX] < 0 &&
|
|
cXConditions.strStateBuffer[cIDX] < 0 &&
|
|
cXConditions.strStateBuffer[pIDX] < 0 &&
|
|
//
|
|
cXConditions.strBuffer[zIDX] == cXConditions.strBuffer[cIDX] &&
|
|
cXConditions.strBuffer[zIDX] == cXConditions.strBuffer[pIDX] &&
|
|
//
|
|
((priceChangeP > strC &&
|
|
priceChangeC < strC) ||
|
|
(priceChangeC > strC &&
|
|
priceChangeZ > strC))
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCBarBullishRejectedStr =
|
|
cBar.low < strC &&
|
|
cBar.GetDown() > strC;
|
|
|
|
//
|
|
bool isPBarBullishRejectedStr =
|
|
pBar.low < strP &&
|
|
pBar.GetDown() > strP;
|
|
|
|
//
|
|
bool isBarBullishRejectedStr =
|
|
isCBarBullishRejectedStr ||
|
|
isPBarBullishRejectedStr;
|
|
|
|
//
|
|
bool isCBarBearishRejectedStr =
|
|
cBar.high > strC &&
|
|
cBar.GetUp() < strC;
|
|
|
|
//
|
|
bool isPBarBearishRejectedStr =
|
|
pBar.high > strP &&
|
|
pBar.GetUp() < strP;
|
|
|
|
//
|
|
bool isBarBearishRejectedStr =
|
|
isCBarBearishRejectedStr ||
|
|
isPBarBearishRejectedStr;
|
|
|
|
//
|
|
bool isCPVsPeakSame =
|
|
provider.decisionXConditions.peaksBuffer[cIDX] == provider.analyseXConditions.peaksBuffer[cIDX] &&
|
|
provider.analyseXConditions.peaksBuffer[cIDX] == provider.consolidationXConditions.peaksBuffer[cIDX];
|
|
|
|
bool isPPVsPeakSame =
|
|
provider.decisionXConditions.peaksBuffer[pIDX] == provider.analyseXConditions.peaksBuffer[pIDX] &&
|
|
provider.analyseXConditions.peaksBuffer[pIDX] == provider.consolidationXConditions.peaksBuffer[pIDX];
|
|
|
|
//
|
|
bool isCPVsValeSame =
|
|
provider.decisionXConditions.valesBuffer[cIDX] == provider.analyseXConditions.valesBuffer[cIDX] &&
|
|
provider.analyseXConditions.valesBuffer[cIDX] == provider.consolidationXConditions.valesBuffer[cIDX];
|
|
|
|
bool isPPVsValeSame =
|
|
provider.decisionXConditions.valesBuffer[pIDX] == provider.analyseXConditions.valesBuffer[pIDX] &&
|
|
provider.analyseXConditions.valesBuffer[pIDX] == provider.consolidationXConditions.valesBuffer[pIDX];
|
|
|
|
//
|
|
bool isPeaksSame = isCPVsPeakSame && isPPVsPeakSame;
|
|
bool isValesSame = isCPVsValeSame && isPPVsValeSame;
|
|
|
|
//
|
|
// Bars Conditions ...
|
|
|
|
//
|
|
ENUM_X_DIRECTION cBarDir;
|
|
|
|
//
|
|
// Hammer ...
|
|
bool isCBarHammer = cHelper
|
|
.mBarAnalyser
|
|
.IsHammer(
|
|
cBar,
|
|
cBarDir //
|
|
);
|
|
bool isCBarBullishHammer =
|
|
isCBarHammer &&
|
|
IsBullish(cBarDir);
|
|
bool isCBarBearishHammer =
|
|
isCBarHammer &&
|
|
IsBearish(cBarDir);
|
|
|
|
//
|
|
// Rejected ...
|
|
bool isCBarRejected = cHelper
|
|
.mBarAnalyser
|
|
.IsRejected(
|
|
cBar,
|
|
cBarDir,
|
|
false, // Force Type ...
|
|
true // Force Fibo Pressure ...
|
|
);
|
|
bool isCBarBullishRejected =
|
|
isCBarRejected &&
|
|
IsBullish(cBarDir);
|
|
bool isCBarBearishRejected =
|
|
isCBarRejected &&
|
|
IsBearish(cBarDir);
|
|
|
|
//
|
|
// Engulfed ...
|
|
bool isCBarEngulfed = cHelper
|
|
.mBarAnalyser
|
|
.IsEngulfed(
|
|
cBar,
|
|
cBarDir //
|
|
);
|
|
bool isCBarBullishEngulfed =
|
|
isCBarEngulfed &&
|
|
IsBullish(cBarDir);
|
|
bool isCBarBearishEngulfed =
|
|
isCBarEngulfed &&
|
|
IsBearish(cBarDir);
|
|
|
|
//
|
|
// Momentum ...
|
|
bool isCBarMomentum = cHelper
|
|
.mBarAnalyser
|
|
.IsMomentum(
|
|
cBar,
|
|
cBarDir,
|
|
1 //
|
|
);
|
|
bool isCBarBullishMomentum =
|
|
isCBarMomentum &&
|
|
IsBullish(cBarDir);
|
|
bool isCBarBearishMomentum =
|
|
isCBarMomentum &&
|
|
IsBearish(cBarDir);
|
|
|
|
//
|
|
// Bar Sumarise ...
|
|
|
|
//
|
|
bool isCBarValidForBullish =
|
|
(isCBarBullishHammer ||
|
|
isCBarBullishRejected ||
|
|
isCBarBullishMomentum ||
|
|
isCBarBullishEngulfed);
|
|
|
|
//
|
|
bool isCBarValidForBearish =
|
|
(isCBarBearishHammer ||
|
|
isCBarBearishRejected ||
|
|
isCBarBearishMomentum ||
|
|
isCBarBearishEngulfed);
|
|
|
|
//
|
|
bool isCBarBreakUpLastPeak =
|
|
cBar.IsBullish() &&
|
|
cBar.GetUp() > peakP &&
|
|
cBar.GetDown() < peakP;
|
|
|
|
//
|
|
bool isCBarBreakDownLastPeak =
|
|
cBar.IsBearish() &&
|
|
cBar.GetUp() > peakP &&
|
|
cBar.GetDown() < peakP;
|
|
|
|
//
|
|
bool isCBarBreakUpLastVale =
|
|
cBar.IsBullish() &&
|
|
cBar.GetUp() > valeP &&
|
|
cBar.GetDown() < valeP;
|
|
|
|
//
|
|
bool isCBarBreakDownLastVale =
|
|
cBar.IsBearish() &&
|
|
cBar.GetUp() > valeP &&
|
|
cBar.GetDown() < valeP;
|
|
|
|
//
|
|
bool isCBarBreakUpPeakGolden =
|
|
cBar.IsBullish() &&
|
|
cBar.GetUp() > peaksGoldenC &&
|
|
cBar.GetDown() < peaksGoldenC;
|
|
|
|
//
|
|
bool isCBarBreakDownPeakGolden =
|
|
cBar.IsBearish() &&
|
|
cBar.GetUp() > peaksGoldenC &&
|
|
cBar.GetDown() < peaksGoldenC;
|
|
|
|
//
|
|
bool isCBarBreakUpValeGolden =
|
|
cBar.IsBullish() &&
|
|
cBar.GetUp() > valesGoldenC &&
|
|
cBar.GetDown() < valesGoldenC;
|
|
|
|
//
|
|
bool isCBarBreakDownValeGolden =
|
|
cBar.IsBearish() &&
|
|
cBar.GetUp() > valesGoldenC &&
|
|
cBar.GetDown() < valesGoldenC;
|
|
|
|
//
|
|
// Summarize Conditions ...
|
|
|
|
//
|
|
bool isBoxSignalBullish =
|
|
//
|
|
hasSelectedBox &&
|
|
selectedBox.IsBullish()
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isBoxSignalBearish =
|
|
//
|
|
hasSelectedBox &&
|
|
selectedBox.IsBearish()
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isConsolidationBoxSignalBullish =
|
|
isBoxSignalBullish &&
|
|
hasSelectedConsolidationBox &&
|
|
selectedConsolidationBox.IsBullish();
|
|
|
|
//
|
|
bool isConsolidationBoxSignalBearish =
|
|
isBoxSignalBearish &&
|
|
hasSelectedConsolidationBox &&
|
|
selectedConsolidationBox.IsBearish();
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
bool isCond1Bullish =
|
|
//
|
|
isBoxSignalBullish &&
|
|
selectedBoxStr > 0 &&
|
|
isCBarValidForBullish &&
|
|
(cXConditions.isStrBullish
|
|
? isBarBullishRejectedStr
|
|
: true) &&
|
|
!hasSelectedConsolidationBox &&
|
|
isBarBullishPriceChangeVPattern
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond1Bearish =
|
|
//
|
|
isBoxSignalBearish &&
|
|
selectedBoxStr > 0 &&
|
|
isCBarValidForBearish &&
|
|
(cXConditions.isStrBearish
|
|
? isBarBearishRejectedStr
|
|
: true) &&
|
|
!hasSelectedConsolidationBox &&
|
|
isBarBearishPriceChangeVPattern
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond2Bullish =
|
|
//
|
|
isCBarValidForBullish &&
|
|
isBarBullishPriceChangeVPattern &&
|
|
isConsolidationBoxSignalBullish &&
|
|
(isPriceChangeBullishRejectedStr ||
|
|
isPriceChangeUnderSelectedBoxMid)
|
|
//
|
|
;
|
|
|
|
bool isCond2Bearish =
|
|
//
|
|
isCBarValidForBearish &&
|
|
isBarBearishPriceChangeVPattern &&
|
|
isConsolidationBoxSignalBearish &&
|
|
(isPriceChangeBearishRejectedStr ||
|
|
isPriceChangeOverSelectedBoxMid)
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isCond3Bullish =
|
|
//
|
|
false
|
|
//
|
|
;
|
|
|
|
bool isCond3Bearish =
|
|
//
|
|
false
|
|
//
|
|
;
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
isBullish =
|
|
//
|
|
isCond1Bullish ||
|
|
isCond2Bullish ||
|
|
isCond3Bullish
|
|
//
|
|
;
|
|
|
|
//
|
|
isBearish =
|
|
//
|
|
isCond1Bearish ||
|
|
isCond2Bearish ||
|
|
isCond3Bearish
|
|
//
|
|
;
|
|
|
|
// //
|
|
// if (isBoxSignalBullish || isBoxSignalBearish)
|
|
// {
|
|
// Print("Box Has Signal ...");
|
|
// }
|
|
|
|
//
|
|
// if (isPeaksSame ||
|
|
// isValesSame)
|
|
// {
|
|
// //
|
|
// long chartId = drawer.ChartIdentification();
|
|
// int subWindow = drawer.SubWindowIdentification();
|
|
|
|
// //
|
|
// string name1 = "decision_";
|
|
// string name2 = "analyse_";
|
|
// string name3 = "consolidation_";
|
|
|
|
// //
|
|
// CChartObjectTrend *t1Obj;
|
|
// t1Obj = new CChartObjectTrend();
|
|
|
|
// //
|
|
// CChartObjectTrend *t2Obj;
|
|
// t2Obj = new CChartObjectTrend();
|
|
|
|
// //
|
|
// CChartObjectTrend *t3Obj;
|
|
// t3Obj = new CChartObjectTrend();
|
|
|
|
// //
|
|
// color tValeColor = clrAqua;
|
|
// color tPeakColor = clrMagenta;
|
|
|
|
// //
|
|
// datetime from = pBar.time;
|
|
// datetime to = zBar.time;
|
|
|
|
// //
|
|
// if (isPeaksSame)
|
|
// {
|
|
// //
|
|
// // Prepare Names ...
|
|
// name1 = name1 + "_Vale";
|
|
// name2 = name2 + "_Vale";
|
|
// name3 = name3 + "_Vale";
|
|
|
|
// //
|
|
// // T1 ...
|
|
// has = t1Obj.Create(
|
|
// chartId,
|
|
// name1,
|
|
// subWindow,
|
|
// from,
|
|
// provider.decisionXConditions.valesBuffer[cIDX],
|
|
// to,
|
|
// provider.decisionXConditions.valesBuffer[cIDX] //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// t1Obj.Color(tValeColor);
|
|
// }
|
|
|
|
// //
|
|
// // T2 ...
|
|
// has = t2Obj.Create(
|
|
// chartId,
|
|
// name2,
|
|
// subWindow,
|
|
// from,
|
|
// provider.analyseXConditions.valesBuffer[cIDX],
|
|
// to,
|
|
// provider.analyseXConditions.valesBuffer[cIDX] //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// t2Obj.Color(tValeColor);
|
|
// }
|
|
|
|
// //
|
|
// // T3 ...
|
|
// has = t3Obj.Create(
|
|
// chartId,
|
|
// name1,
|
|
// subWindow,
|
|
// from,
|
|
// provider.consolidationXConditions.valesBuffer[cIDX],
|
|
// to,
|
|
// provider.consolidationXConditions.valesBuffer[cIDX] //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// t3Obj.Color(tValeColor);
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// if (isValesSame)
|
|
// {
|
|
// //
|
|
// // Prepare Names ...
|
|
// name1 = name1 + "_Peak";
|
|
// name2 = name2 + "_Peak";
|
|
// name3 = name3 + "_Peak";
|
|
|
|
// //
|
|
// // T1 ...
|
|
// has = t1Obj.Create(
|
|
// chartId,
|
|
// name1,
|
|
// subWindow,
|
|
// from,
|
|
// provider.decisionXConditions.peaksBuffer[cIDX],
|
|
// to,
|
|
// provider.decisionXConditions.peaksBuffer[cIDX] //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// t1Obj.Color(tPeakColor);
|
|
// }
|
|
|
|
// //
|
|
// // T2 ...
|
|
// has = t2Obj.Create(
|
|
// chartId,
|
|
// name2,
|
|
// subWindow,
|
|
// from,
|
|
// provider.analyseXConditions.peaksBuffer[cIDX],
|
|
// to,
|
|
// provider.analyseXConditions.peaksBuffer[cIDX] //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// t2Obj.Color(tPeakColor);
|
|
// }
|
|
|
|
// //
|
|
// // T3 ...
|
|
// has = t3Obj.Create(
|
|
// chartId,
|
|
// name1,
|
|
// subWindow,
|
|
// from,
|
|
// provider.consolidationXConditions.peaksBuffer[cIDX],
|
|
// to,
|
|
// provider.consolidationXConditions.peaksBuffer[cIDX] //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// t3Obj.Color(tPeakColor);
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// Print("PVS Same ...");
|
|
// }
|
|
|
|
//
|
|
if (isConsolidationBoxSignalBullish ||
|
|
isConsolidationBoxSignalBearish)
|
|
{
|
|
Print("Has Consolidation Selected Box ...");
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
if (isBullish)
|
|
{
|
|
//
|
|
if (isCond1Bullish)
|
|
{
|
|
pivot = selectedBoxStr;
|
|
}
|
|
else if (isCond2Bullish)
|
|
{
|
|
pivot = selectedBoxMid;
|
|
}
|
|
else if (hasSelectedBox)
|
|
{
|
|
//
|
|
// Default Box SL ...
|
|
pivot = selectedBox.lower;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Default Non Box SL ...
|
|
pivot = cBar.low;
|
|
}
|
|
}
|
|
else if (isBearish)
|
|
{
|
|
//
|
|
if (isCond1Bearish)
|
|
{
|
|
pivot = selectedBoxStr;
|
|
}
|
|
else if (isCond2Bearish)
|
|
{
|
|
pivot = selectedBoxMid;
|
|
}
|
|
else if (hasSelectedBox)
|
|
{
|
|
//
|
|
// Default Box SL ...
|
|
pivot = selectedBox.upper;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Default Non Box SL ...
|
|
pivot = cBar.high;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Usually is Current Price or Entry Price ...
|
|
double point = GetEntry(
|
|
cBar.symbol,
|
|
dir //
|
|
);
|
|
|
|
//
|
|
box.upper =
|
|
isBullish
|
|
? point
|
|
: pivot;
|
|
|
|
//
|
|
box.lower =
|
|
isBullish
|
|
? pivot
|
|
: point;
|
|
|
|
//
|
|
zone = selectedBox;
|
|
}
|
|
|
|
//
|
|
// 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);
|
|
selectedBox.Clean();
|
|
cStateEvents.Clean();
|
|
cXConditions.Clean();
|
|
|
|
//
|
|
ZeroMemory(drawer);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
bool IsBoxPVPassed(
|
|
XBoxZone &box,
|
|
X121Conditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = box.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// double boxValue = box.lower + ((box.upper - box.lower) / 2);
|
|
|
|
//
|
|
bool isBullishPassed =
|
|
box.IsBullish() &&
|
|
conditions.valesBuffer[0] < box.upper &&
|
|
conditions.valesBuffer[0] > box.lower;
|
|
|
|
//
|
|
bool isBearishPassed =
|
|
box.IsBearish() &&
|
|
conditions.peaksBuffer[0] > box.lower &&
|
|
conditions.peaksBuffer[0] < box.upper;
|
|
|
|
//
|
|
result = isBullishPassed ||
|
|
isBearishPassed;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void CheckBoxStr(
|
|
XC121SMCCycleHelper *helper,
|
|
XBoxZone &box,
|
|
double &value //
|
|
)
|
|
{
|
|
//
|
|
value = 0;
|
|
|
|
//
|
|
if (!box.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
ENUM_TIMEFRAMES _period = helper.GetPeriod();
|
|
|
|
//
|
|
int toIDX = box.ToIndex(_period);
|
|
int fromIDX = box.FromIndex(_period);
|
|
if (!IsValidIndex(toIDX) ||
|
|
!IsValidIndex(fromIDX))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
bool isBullish = box.IsBullish();
|
|
XCX121XSTRHelper *strHelper = helper.mX121Helper.xstrHelper;
|
|
for (int i = fromIDX; i >= toIDX; i--)
|
|
{
|
|
//
|
|
double iStr = strHelper.GetSTR(i);
|
|
double iPStr = strHelper.GetSTR(i);
|
|
double iStrState = strHelper.GetSTRState(i);
|
|
|
|
//
|
|
bool isSame = iStr == iPStr;
|
|
bool isStrBullish = iStrState > 0;
|
|
bool isStrBearish = iStrState < 0;
|
|
bool isStrInBox =
|
|
iStr <= box.upper &&
|
|
iStr >= box.lower;
|
|
|
|
//
|
|
if (isSame && isStrInBox)
|
|
{
|
|
//
|
|
if (isBullish && isStrBullish)
|
|
{
|
|
//
|
|
// Min Bullish Str as Support ...
|
|
value =
|
|
value <= 0
|
|
? iStr
|
|
: value > iStr
|
|
? iStr
|
|
: value;
|
|
}
|
|
else if (!isBullish && isStrBearish)
|
|
{
|
|
//
|
|
// Max Bearish Str as Resistance ...
|
|
value =
|
|
value <= 0
|
|
? iStr
|
|
: value < iStr
|
|
? iStr
|
|
: value;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
ZeroMemory(strHelper);
|
|
|
|
//
|
|
}
|
|
|
|
// |