2012 lines
40 KiB
Plaintext
2012 lines
40 KiB
Plaintext
//
|
|
bool Prepare(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
ENUM_POSITION_TYPE mType, // Long (Buy) or Short (Sell)
|
|
ENUM_X_ORDER_MODES mMode, // Execution Mode
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
IsValid(mMode) &&
|
|
IsValid(mSymbol) &&
|
|
IsValid(mPeriod) &&
|
|
NotEmpty(mEntry) &&
|
|
NotEmpty(mVolume) &&
|
|
IsValid(mProvider)
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (mTP < 0)
|
|
{
|
|
mTP = 0;
|
|
}
|
|
|
|
//
|
|
if (mSL < 0)
|
|
{
|
|
mSL = 0;
|
|
}
|
|
|
|
//
|
|
type = mType;
|
|
mode = mMode;
|
|
symbol = mSymbol;
|
|
period = mPeriod;
|
|
provider = mProvider;
|
|
|
|
//
|
|
// Normalization Values ...
|
|
sl = NormalizePrice(mSL, mSymbol);
|
|
tp = NormalizePrice(mTP, mSymbol);
|
|
mEntry = NormalizePrice(mEntry, mSymbol);
|
|
mVolume = NormalizeVolume(mVolume, mSymbol);
|
|
|
|
//
|
|
entry = mEntry;
|
|
volume = mVolume;
|
|
|
|
//
|
|
result = Normalize();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool PrepareComplex(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
ENUM_POSITION_TYPE mType, // Long (Buy) or Short (Sell)
|
|
ENUM_X_ORDER_MODES mMode, // Execution Mode
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
//
|
|
// TP ...
|
|
double mFullTPLevel = 0, // Full TP Level
|
|
double mPartialCloseOnTPLevel = 0, // Partial Close On TP Level
|
|
double mPartialCloseMultiplier = 0, // Partial Close Multiplier
|
|
//
|
|
// RF ...
|
|
bool mRiskFreeOnBreakEven = false, // Risk Free Signal On Break Even ...
|
|
double mTpLevelForBreakEven = 0, // TP Level for Break Even ...
|
|
//
|
|
// SL Trail ...
|
|
bool mTrailSL = false, // Trail SL
|
|
double mTrailSLStartOnReachTPLevel = 0 // Trail SL Starts after Reached TP Level
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate Args ...
|
|
result =
|
|
//
|
|
// Common ...
|
|
mSL > 0 &&
|
|
mEntry > 0 &&
|
|
mVolume > 0 &&
|
|
IsValid(mSymbol) &&
|
|
IsValid(mPeriod) &&
|
|
IsValid(mProvider) &&
|
|
mMode != X_ORDER_MODE_NOTHING
|
|
//
|
|
&&
|
|
//
|
|
// TP ...
|
|
mFullTPLevel > 0
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Prepare Regular Signal Values ...
|
|
double _risk = MathAbs(mEntry - mSL);
|
|
double _reward = _risk * mFullTPLevel;
|
|
|
|
//
|
|
bool isLong = IsLong(mType);
|
|
|
|
//
|
|
sl = mSL;
|
|
type = mType;
|
|
mode = mMode;
|
|
entry = mEntry;
|
|
symbol = mSymbol;
|
|
period = mPeriod;
|
|
volume = mVolume;
|
|
provider = mProvider;
|
|
fullTPLevel = mFullTPLevel;
|
|
tp = isLong
|
|
? mEntry + _reward
|
|
: mEntry - _reward;
|
|
|
|
//
|
|
result = Normalize();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Other Conditions ...
|
|
|
|
//
|
|
bool canPartialClose =
|
|
//
|
|
mPartialCloseOnTPLevel > 0 &&
|
|
mPartialCloseMultiplier > 0 &&
|
|
mPartialCloseOnTPLevel < mFullTPLevel
|
|
//
|
|
;
|
|
if (canPartialClose)
|
|
{
|
|
//
|
|
partialCloseOnTPLevel = mPartialCloseOnTPLevel;
|
|
partialCloseMultiplier = mPartialCloseMultiplier;
|
|
}
|
|
|
|
//
|
|
bool canRFOnBEP =
|
|
//
|
|
mRiskFreeOnBreakEven &&
|
|
mTpLevelForBreakEven > 0
|
|
//
|
|
;
|
|
if (canRFOnBEP)
|
|
{
|
|
//
|
|
riskFreeOnBreakEven = mRiskFreeOnBreakEven;
|
|
tpLevelForBreakEven = mTpLevelForBreakEven;
|
|
}
|
|
|
|
//
|
|
bool canTrailSL =
|
|
//
|
|
mTrailSL &&
|
|
mTrailSLStartOnReachTPLevel > 0 &&
|
|
mTrailSLStartOnReachTPLevel < mFullTPLevel
|
|
//
|
|
;
|
|
if (canTrailSL)
|
|
{
|
|
//
|
|
trailSL = mTrailSL;
|
|
trailSLStartOnReachTPLevel = mTrailSLStartOnReachTPLevel;
|
|
}
|
|
|
|
//
|
|
result = IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool PrepareLong(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
ENUM_X_ORDER_MODES mMode, // Execution Mode
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return Prepare(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
POSITION_TYPE_BUY,
|
|
mMode,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
bool PrepareShort(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
ENUM_X_ORDER_MODES mMode, // Execution Mode
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return Prepare(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
POSITION_TYPE_SELL,
|
|
mMode,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
// Market Mode ...
|
|
|
|
//
|
|
bool PrepareMarketLong(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareLong(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_MARKET,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
bool PrepareMarketShort(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareShort(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_MARKET,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
// Stop Mode ...
|
|
|
|
//
|
|
bool PrepareStopLong(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareLong(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_STOP,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
bool PrepareStopShort(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareShort(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_STOP,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
// Limit Mode ...
|
|
|
|
//
|
|
bool PrepareLimitLong(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareLong(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_LIMIT,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
bool PrepareLimitShort(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareShort(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_LIMIT,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
// Generate Opposit Direction ...
|
|
bool GenerateOpposit(
|
|
XSignal &mSignal // Oppsoit Signal
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
ENUM_POSITION_TYPE mType = Opposit(this.type);
|
|
double mEntry = GetExit(this.symbol, mType);
|
|
|
|
//
|
|
bool isLong = IsLong(mType);
|
|
|
|
//
|
|
// Calculate Risk Reward Ratio ...
|
|
double risk = GetRisk();
|
|
double reward = GetReward();
|
|
|
|
//
|
|
double mSL = isLong
|
|
? mEntry - risk
|
|
: mEntry + risk;
|
|
|
|
//
|
|
double mTP = isLong
|
|
? mEntry + reward
|
|
: mEntry - reward;
|
|
|
|
//
|
|
result = mSignal.Prepare(
|
|
this.symbol,
|
|
this.provider,
|
|
this.period,
|
|
mType,
|
|
this.mode,
|
|
mEntry,
|
|
this.volume,
|
|
mSL,
|
|
mTP //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Prepare Opposit Signal based On a Position ...
|
|
bool PrepareOpposit(
|
|
XPosition &source // Source Data
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
ENUM_POSITION_TYPE mType = Opposit(source.type);
|
|
double mEntry = GetEntry(source.symbol, mType);
|
|
|
|
//
|
|
bool isLong = IsLong(mType);
|
|
|
|
//
|
|
double risk = source.GetRisk();
|
|
double reward = source.GetReward();
|
|
|
|
//
|
|
double mSL = isLong
|
|
? mEntry - risk
|
|
: mEntry + risk;
|
|
|
|
//
|
|
double mTP = isLong
|
|
? mEntry + reward
|
|
: mEntry - reward;
|
|
|
|
//
|
|
return Prepare(
|
|
source.symbol,
|
|
source.provider,
|
|
source.period,
|
|
mType,
|
|
X_ORDER_MODE_MARKET,
|
|
mEntry,
|
|
source.volume,
|
|
mSL,
|
|
mTP //
|
|
);
|
|
|
|
//
|
|
result = IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Handle Executing Support Signals ...
|
|
int supportsCount = ArraySize(mSignal.supports);
|
|
if (supportsCount > 0)
|
|
{
|
|
//
|
|
int executed = 0;
|
|
for (int i = 0; i < supportsCount; i++)
|
|
{
|
|
//
|
|
XSignal iSupport = mSignal.supports[i];
|
|
|
|
//
|
|
int supIndex = i + 1;
|
|
string iComment = GenerateSupportTag(ticket);
|
|
iSupport.comment = iComment;
|
|
|
|
//
|
|
bool isExecuted = ExecuteSignal(
|
|
iSupport,
|
|
state,
|
|
lifetime,
|
|
expiration
|
|
//
|
|
);
|
|
if (isExecuted)
|
|
{
|
|
executed++;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = executed == supportsCount;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Handle Partial Close on Specified Targets ...
|
|
has = !trades[idx].signal.isPartiallyClosed &&
|
|
trades[idx].signal.partialCloseOnTPLevel > 0 &&
|
|
trades[idx].signal.partialCloseMultiplier > 0;
|
|
if (has)
|
|
{
|
|
//
|
|
// Check Reward Touched ...
|
|
double iCurrReward = iPosition.CalculateTouchedReward();
|
|
has = iCurrReward >= trades[idx].signal.partialCloseOnTPLevel;
|
|
if (has)
|
|
{
|
|
//
|
|
// Check Volume Multiplier ...
|
|
double volumeMultiplier = trades[idx].signal.partialCloseMultiplier;
|
|
has = volumeMultiplier > 0 &&
|
|
volumeMultiplier <= 1;
|
|
if (has)
|
|
{
|
|
//
|
|
// Do Partial Closing ...
|
|
double volume = iPosition.volume * volumeMultiplier;
|
|
|
|
//
|
|
// Normalizing Volume ...
|
|
volume = NormalizeVolume(
|
|
volume,
|
|
iPosition.symbol //
|
|
);
|
|
|
|
//
|
|
string comment = "PC On Target ...";
|
|
has = trader.ClosePartial(
|
|
iPosition.ticket,
|
|
volume,
|
|
comment //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Update Model ...
|
|
trades[idx].signal.isPartiallyClosed = true;
|
|
|
|
//
|
|
string message = prefix +
|
|
ToString(iPosition.type) +
|
|
" Position: " +
|
|
ToString(iPosition.ticket) +
|
|
" PC (" + ToString(volume) + ") On Traget: " + ToString(iCurrReward) +
|
|
" Successfully ...";
|
|
HandleReportProtector(message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Check Different Trigger Conditions ...
|
|
|
|
//
|
|
// Checking Trigger Cond 0 ...
|
|
bool canTriggerCond0 = false;
|
|
// CanTriggerCond0(
|
|
// helper,
|
|
// conditions.decisionZone,
|
|
// triggerDir,
|
|
// sl,
|
|
// tp,
|
|
// barIndex //
|
|
// );
|
|
|
|
//
|
|
// Checking Trigger Cond 1 ...
|
|
bool canTriggerCond1 = false;
|
|
if (isTooLarge)
|
|
{
|
|
//
|
|
canTriggerCond1 = CanTriggerCond1(
|
|
helper,
|
|
conditions.decisionZone,
|
|
triggerDir,
|
|
sl,
|
|
targets,
|
|
iObjects,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Checking Trigger Cond 2 ...
|
|
bool canTriggerCond2 = false;
|
|
if (!isTooLarge)
|
|
{
|
|
//
|
|
canTriggerCond2 = CanTriggerCond2(
|
|
helper,
|
|
conditions.decisionZone,
|
|
decisionOBs,
|
|
triggerDir,
|
|
sl,
|
|
targets,
|
|
iObjects,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Checking Trigger Cond 3 ...
|
|
bool canTriggerCond3 = false;
|
|
// CanTriggerCond3(
|
|
// helper,
|
|
// conditions.decisionZone,
|
|
// triggerDir,
|
|
// sl,
|
|
// tp,
|
|
// iObjects,
|
|
// barIndex //
|
|
// );
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Detect Trigger Based On Decision Zone's
|
|
bool CanTriggerCond0(
|
|
XCXCAEAHelper *helper,
|
|
XBoxZone &box,
|
|
ENUM_X_DIRECTION &dir,
|
|
double &sl,
|
|
XTarget &targets[],
|
|
CArrayObj *drawns,
|
|
int barIndex = 0,
|
|
int loopback = 5,
|
|
double scorePassMultiplier = 1 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
sl = 0;
|
|
tp = 0;
|
|
dir = X_DIRECTION_NONE;
|
|
loopback = NormalizeInt(loopback, 5);
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
// Validate Decision Box ...
|
|
result = box.IsValid() &&
|
|
helper != NULL;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Define Requirements ...
|
|
|
|
//
|
|
bool isBullish = box.IsBullish();
|
|
bool isBearish = box.IsBearish();
|
|
|
|
//
|
|
// Scores ...
|
|
double bullScores[];
|
|
double bearScores[];
|
|
|
|
//
|
|
// Volumes ...
|
|
double bullVolumes[];
|
|
double bearVolumes[];
|
|
|
|
//
|
|
// Create a Loop through Loopack ...
|
|
XOHCL iBar;
|
|
bool has = false;
|
|
int start = barIndex;
|
|
XCAEAConditions iConditions;
|
|
int end = barIndex + loopback;
|
|
for (int i = end; i >= start; i--)
|
|
{
|
|
//
|
|
// Retrieve Bar ...
|
|
has = iBar.Init(
|
|
box.symbol,
|
|
box.period,
|
|
i //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
iConditions.Clean();
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Retrieve Conditions ...
|
|
has = helper.GetConditions(
|
|
iConditions,
|
|
i //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
iConditions.Clean();
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Retrieve Scores ...
|
|
double iBullScore = 0;
|
|
double iBearScore = 0;
|
|
iConditions
|
|
.GenerateScore(
|
|
iBullScore,
|
|
iBearScore //
|
|
);
|
|
Add(
|
|
iBullScore,
|
|
bullScores //
|
|
);
|
|
Add(
|
|
iBearScore,
|
|
bearScores //
|
|
);
|
|
|
|
//
|
|
// Retrieve Volumes ...
|
|
double iBullVolume = 0;
|
|
double iBearVolume = 0;
|
|
helper
|
|
.barAnalyser
|
|
.CalculateRangeVolume(
|
|
iBar,
|
|
iBullVolume,
|
|
iBearVolume,
|
|
2 // Loopback ...
|
|
);
|
|
Add(
|
|
iBullVolume,
|
|
bullVolumes //
|
|
);
|
|
Add(
|
|
iBearVolume,
|
|
bearVolumes //
|
|
);
|
|
|
|
//
|
|
iBar.Clean();
|
|
iConditions.Clean();
|
|
}
|
|
|
|
//
|
|
// Calculating Requirements ...
|
|
|
|
//
|
|
// Scores ...
|
|
|
|
//
|
|
// Bullish ...
|
|
double bullScore = GetSum(bullScores);
|
|
double bullScoreMax = GetMax(bullScores);
|
|
double bullScoreMin = GetMin(bullScores);
|
|
|
|
//
|
|
// Bearish ...
|
|
double bearScore = GetSum(bearScores);
|
|
double bearScoreMax = GetMax(bearScores);
|
|
double bearScoreMin = GetMin(bearScores);
|
|
|
|
//
|
|
// Volumes ...
|
|
|
|
//
|
|
// Bullish ...
|
|
double bullVolume = GetSum(bullVolumes);
|
|
double bullVolumeMax = GetMax(bullVolumes);
|
|
double bullVolumeMin = GetMin(bullVolumes);
|
|
|
|
//
|
|
// Bearish ...
|
|
double bearVolume = GetSum(bearVolumes);
|
|
double bearVolumeMax = GetMax(bearVolumes);
|
|
double bearVolumeMin = GetMin(bearVolumes);
|
|
|
|
//
|
|
// Creating Result Conditions ...
|
|
|
|
//
|
|
bool isBullishPassed =
|
|
isBullish &&
|
|
bullScore >= (scorePassMultiplier * bearScore) &&
|
|
bullVolume >= (scorePassMultiplier * bearVolume);
|
|
|
|
//
|
|
bool isBearishPassed =
|
|
isBearish &&
|
|
bearScore >= (scorePassMultiplier * bullScore) &&
|
|
bearVolume >= (scorePassMultiplier * bullVolume);
|
|
|
|
//
|
|
result = isBullishPassed ||
|
|
isBearishPassed;
|
|
if (!result)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
Clean(bullScores);
|
|
Clean(bearScores);
|
|
Clean(bullVolumes);
|
|
Clean(bearVolumes);
|
|
iConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Validating Box to Find a Rejection ...
|
|
|
|
//
|
|
// Validating Box to Has a Gap ...
|
|
|
|
//
|
|
// Validating Box to Has a Block ...
|
|
|
|
//
|
|
bool isPassed =
|
|
isBullishPassed ||
|
|
isBearishPassed;
|
|
if (isPassed)
|
|
{
|
|
//
|
|
// Preparing TP and SL ...
|
|
|
|
//
|
|
sl = isBullishPassed
|
|
? box.lower
|
|
: box.upper;
|
|
|
|
//
|
|
tp = 0;
|
|
}
|
|
|
|
//
|
|
// Summarizing ...
|
|
|
|
//
|
|
bool canTriggerLong =
|
|
isBullishPassed;
|
|
|
|
//
|
|
bool canTriggerShort =
|
|
isBearishPassed;
|
|
|
|
//
|
|
result = canTriggerLong ||
|
|
canTriggerShort;
|
|
if (result)
|
|
{
|
|
//
|
|
dir = canTriggerLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
iBar.Clean();
|
|
Clean(bullScores);
|
|
Clean(bearScores);
|
|
Clean(bullVolumes);
|
|
Clean(bearVolumes);
|
|
iConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Based On Decision Zone's
|
|
bool CanTriggerCond1(
|
|
XCXCAEAHelper *helper,
|
|
XBoxZone &box,
|
|
ENUM_X_DIRECTION &dir,
|
|
double &sl,
|
|
XTarget &targets[],
|
|
CArrayObj *drawns,
|
|
int barIndex = 0,
|
|
int loopback = 10 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
sl = 0;
|
|
tp = 0;
|
|
dir = X_DIRECTION_NONE;
|
|
loopback = NormalizeInt(loopback, 5);
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
// Validate Decision Box ...
|
|
result = box.IsValid() &&
|
|
helper != NULL;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Box is Faked Breaked Out ...
|
|
|
|
//
|
|
XBoxZone validatorFVG;
|
|
|
|
//
|
|
bool isBullishFakedBreakedOut = IsBoxFakedBreakout(
|
|
helper,
|
|
box,
|
|
validatorFVG,
|
|
X_DIRECTION_BULLISH,
|
|
barIndex,
|
|
100, // Loopback For FVG ...
|
|
true, // Force FVg Validation ...
|
|
true // Force FVG Bar Type ...
|
|
);
|
|
|
|
//
|
|
bool isBearishFakedBreakedOut = IsBoxFakedBreakout(
|
|
helper,
|
|
box,
|
|
validatorFVG,
|
|
X_DIRECTION_BEARISH,
|
|
barIndex,
|
|
100, // Loopback For FVG ...
|
|
true, // Force FVg Validation ...
|
|
true // Force FVG Bar Type ...
|
|
);
|
|
|
|
//
|
|
bool isFakeBreaked =
|
|
isBullishFakedBreakedOut ||
|
|
isBearishFakedBreakedOut;
|
|
if (isFakeBreaked)
|
|
{
|
|
//
|
|
// Preparing TP and SL ...
|
|
|
|
//
|
|
sl = isBullishFakedBreakedOut
|
|
? validatorFVG.lower
|
|
: validatorFVG.upper;
|
|
|
|
//
|
|
tp = isBullishFakedBreakedOut
|
|
? box.upper
|
|
: box.lower;
|
|
}
|
|
|
|
//
|
|
// Summarizing ...
|
|
|
|
//
|
|
bool canTriggerLong =
|
|
isBullishFakedBreakedOut;
|
|
|
|
//
|
|
bool canTriggerShort =
|
|
isBearishFakedBreakedOut;
|
|
|
|
//
|
|
result = canTriggerLong ||
|
|
canTriggerShort;
|
|
if (result)
|
|
{
|
|
//
|
|
dir = canTriggerLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
validatorFVG.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Based On Decision Zone's
|
|
// Using OB inside Boxes ...
|
|
bool CanTriggerCond2(
|
|
XCXCAEAHelper *helper,
|
|
XBoxZone &decisionZone,
|
|
XBoxZone &decisionPivots[],
|
|
ENUM_X_DIRECTION &dir,
|
|
double &sl,
|
|
XTarget &targets[],
|
|
CArrayObj *drawns,
|
|
int barIndex = 0,
|
|
int loopback = 10 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
sl = 0;
|
|
tp = 0;
|
|
dir = X_DIRECTION_NONE;
|
|
loopback = NormalizeInt(loopback, 5);
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
// Validate Decision Box ...
|
|
result = decisionZone.IsValid() &&
|
|
helper != NULL;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = helper.GetSymbol();
|
|
bool isBullish = decisionZone.IsBullish();
|
|
bool isBearish = decisionZone.IsBearish();
|
|
ENUM_TIMEFRAMES period = helper.GetPeriod();
|
|
|
|
//
|
|
int zIndex = barIndex;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int p2Index = pIndex + 1;
|
|
|
|
//
|
|
// Extract Bars ...
|
|
XOHCL zBar;
|
|
XOHCL cBar;
|
|
result = zBar.Init(
|
|
symbol,
|
|
period,
|
|
cIndex //
|
|
);
|
|
result =
|
|
result &&
|
|
zBar.GetPreviousBar(cBar);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool has = false;
|
|
XBoxZone selectedPivot;
|
|
bool hasPivots = HasChild(decisionPivots);
|
|
int pivotsCount = ArraySize(decisionPivots);
|
|
|
|
//
|
|
// Select Activated Pivot ...
|
|
if (hasPivots)
|
|
{
|
|
//
|
|
for (int i = 0; i < pivotsCount; i++)
|
|
{
|
|
//
|
|
// Check Rejection of Block ...
|
|
has =
|
|
isBullish
|
|
? cBar.IsBullish() &&
|
|
decisionPivots[i].IsBullish() &&
|
|
cBar.low < decisionPivots[i].upper &&
|
|
cBar.low > decisionPivots[i].lower &&
|
|
cBar.close > decisionPivots[i].upper
|
|
: cBar.IsBearish() &&
|
|
decisionPivots[i].IsBearish() &&
|
|
cBar.high > decisionPivots[i].lower &&
|
|
cBar.high < decisionPivots[i].upper &&
|
|
cBar.close < decisionPivots[i].lower;
|
|
if (has)
|
|
{
|
|
selectedPivot = decisionPivots[i];
|
|
}
|
|
|
|
// //
|
|
// // Draw Pivot ...
|
|
// XCBoxObject *iObj;
|
|
|
|
// //
|
|
// has = helper.poiDrawer.DrawBox(
|
|
// decisionPivots[i],
|
|
// iObj //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// drawns.Add(iObj);
|
|
// }
|
|
|
|
// //
|
|
// ZeroMemory(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Selected Pivot is Exists or not ...
|
|
bool hasSelectedPivot = selectedPivot.IsValid();
|
|
|
|
//
|
|
// Detect Liquidity For Selected Pivot ...
|
|
double ssl = 0;
|
|
double bsl = 0;
|
|
bool hasSSL = false;
|
|
bool hasBSL = false;
|
|
if (hasSelectedPivot)
|
|
{
|
|
//
|
|
// Required Info ...
|
|
// int toIDX = selectedPivot.ToIndex();
|
|
// int fromIDX = selectedPivot.FromIndex();
|
|
|
|
// //
|
|
// // SSL ...
|
|
// datetime sslTo = NULL;
|
|
// datetime sslFrom = NULL;
|
|
|
|
// //
|
|
// // BSL ...
|
|
// datetime bslTo = NULL;
|
|
// datetime bslFrom = NULL;
|
|
|
|
// //
|
|
// // Loop ...
|
|
// XOHCL iBar;
|
|
// for (int i = fromIDX; i > toIDX; i--)
|
|
// {
|
|
// //
|
|
// hasSSL =
|
|
// ssl > 0 &&
|
|
// IsValid(sslTo) &&
|
|
// IsValid(sslFrom);
|
|
|
|
// //
|
|
// hasBSL =
|
|
// bsl > 0 &&
|
|
// IsValid(bslTo) &&
|
|
// IsValid(bslFrom);
|
|
|
|
// //
|
|
// iBar.Clean();
|
|
|
|
// //
|
|
// if (hasSSL && hasBSL)
|
|
// {
|
|
// break;
|
|
// }
|
|
// }
|
|
// iBar.Clean();
|
|
}
|
|
|
|
//
|
|
// Draw Selected Pivot ...
|
|
if (hasSelectedPivot)
|
|
{
|
|
//
|
|
// Draw Pivot ...
|
|
XCBoxObject *iObj;
|
|
|
|
//
|
|
has = helper.poiDrawer.DrawBox(
|
|
selectedPivot,
|
|
iObj //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
color iColor =
|
|
isBullish
|
|
? clrAqua
|
|
: clrMagenta;
|
|
|
|
//
|
|
iObj.BoxWidth(2);
|
|
iObj.BoxColor(iColor);
|
|
iObj.BoxStyle(STYLE_SOLID);
|
|
|
|
//
|
|
drawns.Add(iObj);
|
|
}
|
|
|
|
//
|
|
ZeroMemory(iObj);
|
|
}
|
|
|
|
//
|
|
// Summarizing ...
|
|
|
|
//
|
|
bool canTriggerLong =
|
|
isBullish &&
|
|
hasSelectedPivot &&
|
|
selectedPivot.IsBullish();
|
|
|
|
//
|
|
bool canTriggerShort =
|
|
isBearish &&
|
|
hasSelectedPivot &&
|
|
selectedPivot.IsBearish();
|
|
|
|
//
|
|
result = canTriggerLong ||
|
|
canTriggerShort;
|
|
if (result)
|
|
{
|
|
//
|
|
dir = canTriggerLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
//
|
|
// Preparing TP and SL ...
|
|
|
|
//
|
|
sl = canTriggerLong
|
|
? selectedPivot.lower // activatedFVG.lower
|
|
: selectedPivot.upper; // activatedFVG.upper;
|
|
|
|
//
|
|
// Since Here TP Must Calculated
|
|
// Using R2R we Ignore Target ...
|
|
tp = 0;
|
|
// if (isBullish && zBar.close < decisionZone.upper)
|
|
// {
|
|
// tp = decisionZone.upper;
|
|
// }
|
|
// else if (isBearish && zBar.close > decisionZone.lower)
|
|
// {
|
|
// tp = decisionZone.lower;
|
|
// }
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Based On Decision Zone's
|
|
// Block Based Triggering ...
|
|
bool CanTriggerCond3(
|
|
XCXCAEAHelper *helper,
|
|
XBoxZone &box,
|
|
ENUM_X_DIRECTION &dir,
|
|
double &sl,
|
|
XTarget &targets[],
|
|
CArrayObj *drawns,
|
|
int barIndex = 0,
|
|
int loopback = 10 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize Args ...
|
|
sl = 0;
|
|
tp = 0;
|
|
dir = X_DIRECTION_NONE;
|
|
loopback = NormalizeInt(loopback, 5);
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
// Validate Decision Box ...
|
|
result = box.IsValid() &&
|
|
helper != NULL;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = box.IsBullish();
|
|
bool isBearish = box.IsBearish();
|
|
|
|
//
|
|
bool has = false;
|
|
int swingLoopback = 7;
|
|
ENUM_TIMEFRAMES period = helper.GetPeriod();
|
|
string symbol = helper.GetSymbol();
|
|
int toIDX = box.ToIndex(period);
|
|
int fromIDX = box.FromIndex(period);
|
|
datetime cTime = GetBarTime(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
// Initialize iBar ...
|
|
XOHCL iBar;
|
|
result = iBar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Validate Box ...
|
|
// For Box Validating we use 50% of Box Range ...
|
|
// if Price Touched Box 50% rate we Invalidate Box ...
|
|
// r if Prce Touched Leg 2 of Box Size ...
|
|
double boxLeg2 = box.GetLeg(2);
|
|
|
|
//
|
|
// Draw Box Leg2 ...
|
|
string iLeg2Name = box.GetMiddleTag();
|
|
StringReplace(
|
|
iLeg2Name,
|
|
"Mid",
|
|
"Leg2" //
|
|
);
|
|
CChartObjectTrend *iLeg2Obj;
|
|
iLeg2Obj = new CChartObjectTrend();
|
|
has = iLeg2Obj.Create(
|
|
helper.poiDrawer.ChartIdentification(),
|
|
iLeg2Name,
|
|
helper.poiDrawer.SubWindowIdentification(),
|
|
box.from,
|
|
boxLeg2,
|
|
box.to,
|
|
boxLeg2 //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
iLeg2Obj.Color(clrYellow);
|
|
|
|
//
|
|
drawns.Add(iLeg2Obj);
|
|
}
|
|
ZeroMemory(iLeg2Obj);
|
|
|
|
//
|
|
bool isBoxValid =
|
|
isBullish
|
|
? iBar.close < boxLeg2
|
|
: iBar.close > boxLeg2;
|
|
result = isBoxValid;
|
|
if (!result)
|
|
{
|
|
//
|
|
box.Clean();
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
iBar.Clean();
|
|
|
|
//
|
|
// Detect Box FVG ...
|
|
|
|
//
|
|
// we Have to Detect a Broken Liquidity for Box ...
|
|
|
|
//
|
|
XBoxZone fvg;
|
|
XBoxZone fvgs[];
|
|
for (int i = fromIDX + loopback; i > barIndex; i--)
|
|
{
|
|
//
|
|
// Initialize iBar ...
|
|
XOHCL iBar;
|
|
has = iBar.Init(
|
|
symbol,
|
|
period,
|
|
i //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Check iBar Has FVG ...
|
|
XBoxZone iFVG;
|
|
has = helper
|
|
.barAnalyser
|
|
.IsFVG(
|
|
iBar,
|
|
iFVG,
|
|
true //
|
|
);
|
|
has =
|
|
//
|
|
// Check FVG Exists ...
|
|
has &&
|
|
//
|
|
// Check FVG Direction ...
|
|
iFVG.dir == box.dir &&
|
|
//
|
|
// Check FVG not Breaked ...
|
|
!IsBoxBreaked(
|
|
helper,
|
|
iFVG,
|
|
barIndex //
|
|
) &&
|
|
//
|
|
// Check FVG Placement ...
|
|
(iFVG.IsBullish()
|
|
? iFVG.lower < box.upper
|
|
: iFVG.upper > box.lower);
|
|
if (has)
|
|
{
|
|
//
|
|
iFVG.to = cTime;
|
|
|
|
//
|
|
AddRef(
|
|
iFVG,
|
|
fvgs //
|
|
);
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
iFVG.Clean();
|
|
}
|
|
|
|
//
|
|
// Detecting Target FVG ...
|
|
int idx = isBullish
|
|
? GetHighest(fvgs)
|
|
: GetLowest(fvgs);
|
|
has = IsValidIndex(idx);
|
|
if (has)
|
|
{
|
|
//
|
|
fvg = fvgs[idx];
|
|
|
|
//
|
|
fvg.to = cTime;
|
|
}
|
|
|
|
//
|
|
// Ensure FVG must Exists ...
|
|
result = fvg.IsValid();
|
|
if (!result)
|
|
{
|
|
//
|
|
fvg.Clean();
|
|
Clean(fvgs);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check FVg Break ...
|
|
bool isBreaked = IsBoxBreaked(
|
|
helper,
|
|
fvg,
|
|
barIndex //
|
|
);
|
|
result = !isBreaked;
|
|
if (!result)
|
|
{
|
|
//
|
|
fvg.Clean();
|
|
Clean(fvgs);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Draw FVG ...
|
|
XCBoxObject *iObj;
|
|
has = helper.poiDrawer.DrawBox(
|
|
fvg,
|
|
iObj //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
color fvgColor =
|
|
isBullish
|
|
? clrLime
|
|
: clrRed;
|
|
|
|
//
|
|
iObj.BoxWidth(2);
|
|
iObj.BoxColor(fvgColor);
|
|
iObj.Style(STYLE_SOLID);
|
|
|
|
//
|
|
drawns.Add(iObj);
|
|
}
|
|
ZeroMemory(iObj);
|
|
|
|
//
|
|
// Detecting Liquiidties ...
|
|
XCAEALQSweep iLQ;
|
|
XCAEALQSweep lqs[];
|
|
toIDX = fvg.ToIndex();
|
|
fromIDX = fvg.FromIndex();
|
|
XCAEAConditions iConditions;
|
|
double fvgPrice = isBullish
|
|
? fvg.upper
|
|
: fvg.lower;
|
|
double fvgReversePrice = isBullish
|
|
? fvg.lower
|
|
: fvg.upper;
|
|
for (int i = fromIDX; i > toIDX; i--)
|
|
{
|
|
//
|
|
// Initialize iBar ...
|
|
has = iBar.Init(
|
|
symbol,
|
|
period,
|
|
i //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
iConditions.Clean();
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Reading Conditions ...
|
|
has = helper.GetConditions(
|
|
iConditions,
|
|
i,
|
|
5 //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
iConditions.Clean();
|
|
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
double iSweep =
|
|
isBullish
|
|
? iConditions.valeBuffer[1]
|
|
: iConditions.peakBuffer[1];
|
|
double iSweepP =
|
|
isBullish
|
|
? iConditions.valeBuffer[2]
|
|
: iConditions.peakBuffer[2];
|
|
double iSweepP2 =
|
|
isBullish
|
|
? iConditions.valeBuffer[3]
|
|
: iConditions.peakBuffer[3];
|
|
double iReverse =
|
|
isBullish
|
|
? iConditions.peakBuffer[1]
|
|
: iConditions.valeBuffer[1];
|
|
|
|
//
|
|
bool isSweepContinue =
|
|
iSweepP == iSweep &&
|
|
(isBullish
|
|
? iSweep > fvgPrice
|
|
: iSweep < fvgPrice);
|
|
|
|
//
|
|
bool isSweepContinueP =
|
|
iSweepP2 == iSweepP &&
|
|
(isBullish
|
|
? iSweepP > fvgPrice
|
|
: iSweepP < fvgPrice);
|
|
|
|
//
|
|
bool isSweepStart =
|
|
isSweepContinue &&
|
|
!isSweepContinueP;
|
|
|
|
//
|
|
bool isSweepFinished =
|
|
!isSweepContinue &&
|
|
isSweepContinueP;
|
|
|
|
//
|
|
if (isSweepStart)
|
|
{
|
|
//
|
|
iLQ.Clean();
|
|
|
|
//
|
|
iLQ.symbol = iBar.symbol;
|
|
iLQ.period = iBar.period;
|
|
iLQ.type = isBullish
|
|
? XCAEA_LQ_TYPE_VALE
|
|
: XCAEA_LQ_TYPE_PEAK;
|
|
iLQ.to = iBar.time;
|
|
iLQ.from = iBar.time;
|
|
|
|
//
|
|
iLQ.length = 1;
|
|
iLQ.sweeped = iSweep;
|
|
iLQ.reverse = iReverse;
|
|
}
|
|
|
|
//
|
|
if (isSweepContinue)
|
|
{
|
|
//
|
|
iLQ.length++;
|
|
iLQ.to = iBar.time;
|
|
iLQ.sweeped = iSweep;
|
|
iLQ.reverse = MathMin(iLQ.reverse, iReverse);
|
|
}
|
|
|
|
//
|
|
if (isSweepFinished)
|
|
{
|
|
//
|
|
AddRef(
|
|
iLQ,
|
|
lqs //
|
|
);
|
|
|
|
//
|
|
iLQ.Clean();
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
iConditions.Clean();
|
|
}
|
|
|
|
//
|
|
// Retrieve Bar and Conditions ...
|
|
has = iBar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
has = has &&
|
|
helper.GetConditions(
|
|
iConditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
result = has;
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean(lqs);
|
|
fvg.Clean();
|
|
iLQ.Clean();
|
|
Clean(fvgs);
|
|
iBar.Clean();
|
|
iConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Select Peak/Vale Value Based on Box ...
|
|
double iPV = isBullish
|
|
? iConditions.valeBuffer[1]
|
|
: iConditions.peakBuffer[1];
|
|
double iPVReverse = isBullish
|
|
? iConditions.peakBuffer[1]
|
|
: iConditions.valeBuffer[1];
|
|
|
|
//
|
|
// Validate Liquidities Exists ...
|
|
result = HasChild(lqs);
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean(lqs);
|
|
fvg.Clean();
|
|
iLQ.Clean();
|
|
Clean(fvgs);
|
|
iBar.Clean();
|
|
iConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Draw Liquidities ...
|
|
for (int i = 0; i < ArraySize(lqs); i++)
|
|
{
|
|
//
|
|
iLQ = lqs[i];
|
|
|
|
//
|
|
CChartObjectTrend *iTrend;
|
|
iTrend = new CChartObjectTrend();
|
|
string itName = iLQ.GetTag();
|
|
has = iTrend.Create(
|
|
0,
|
|
itName,
|
|
0,
|
|
iLQ.from,
|
|
iLQ.sweeped,
|
|
iLQ.to,
|
|
iLQ.sweeped //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
color itColor =
|
|
isBullish
|
|
? clrLime
|
|
: clrRed;
|
|
|
|
//
|
|
iTrend.Width(2);
|
|
iTrend.Color(itColor);
|
|
iTrend.Style(STYLE_SOLID);
|
|
|
|
//
|
|
drawns.Add(iTrend);
|
|
}
|
|
|
|
//
|
|
ZeroMemory(iTrend);
|
|
}
|
|
|
|
//
|
|
// PV Must go Inside FVG ...
|
|
has =
|
|
isBullish
|
|
? iPV < fvgPrice
|
|
: iPV > fvgPrice;
|
|
result = has;
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean(lqs);
|
|
fvg.Clean();
|
|
iLQ.Clean();
|
|
Clean(fvgs);
|
|
iBar.Clean();
|
|
iConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect a Traget for SL based on Activated FVG ...
|
|
XBoxZone slTarget;
|
|
double fvgValidatorPrice =
|
|
isBullish
|
|
? fvg.lower
|
|
: fvg.upper;
|
|
for (int i = 0; i < ArraySize(fvgs); i++)
|
|
{
|
|
//
|
|
XBoxZone iFVG = fvgs[i];
|
|
|
|
//
|
|
double iFVGPrice =
|
|
isBullish
|
|
? iFVG.upper
|
|
: iFVG.lower;
|
|
|
|
//
|
|
// Validate Placement ...
|
|
has = iFVGPrice > fvgValidatorPrice;
|
|
if (!has)
|
|
{
|
|
//
|
|
iFVG.Clean();
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Set slTarget ...
|
|
double slTargetPrice = (isBullish
|
|
? slTarget.upper
|
|
: slTarget.lower);
|
|
has =
|
|
!slTarget.IsValid()
|
|
? true
|
|
: (isBullish
|
|
? slTargetPrice < iFVGPrice
|
|
: slTargetPrice > iFVGPrice);
|
|
if (has)
|
|
{
|
|
slTarget = iFVG;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Ensure SL Target Exists ...
|
|
result = slTarget.IsValid();
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean(lqs);
|
|
fvg.Clean();
|
|
iLQ.Clean();
|
|
Clean(fvgs);
|
|
iBar.Clean();
|
|
iConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Darw SL Target Zone ...
|
|
slTarget.to = cTime;
|
|
XCBoxObject *iSLObj;
|
|
has = helper.poiDrawer.DrawBox(
|
|
slTarget,
|
|
iSLObj //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
color slTargetColor =
|
|
isBullish
|
|
? clrAqua
|
|
: clrMagenta;
|
|
|
|
//
|
|
iSLObj.BoxWidth(1);
|
|
iSLObj.BoxColor(slTargetColor);
|
|
|
|
//
|
|
drawns.Add(iSLObj);
|
|
}
|
|
ZeroMemory(iSLObj);
|
|
|
|
//
|
|
// Summarizing ...
|
|
|
|
//
|
|
bool canTriggerLong =
|
|
isBullish &&
|
|
fvg.IsBullish() &&
|
|
slTarget.IsBullish();
|
|
|
|
//
|
|
bool canTriggerShort =
|
|
isBearish &&
|
|
fvg.IsBearish() &&
|
|
slTarget.IsBearish();
|
|
|
|
//
|
|
result = canTriggerLong ||
|
|
canTriggerShort;
|
|
if (result)
|
|
{
|
|
//
|
|
dir = canTriggerLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
// Preparing TP and SL ...
|
|
|
|
//
|
|
sl = isBullish
|
|
? slTarget.lower
|
|
: slTarget.upper;
|
|
|
|
//
|
|
// Since Here TP Must Calculated
|
|
// Using R2R we Ignore Target ...
|
|
tp = 0;
|
|
|
|
//
|
|
// Add Target if price is Inside Analyse Box ...
|
|
double price = iBar.close;
|
|
double target =
|
|
isBullish
|
|
? box.upper
|
|
: box.lower;
|
|
has =
|
|
isBullish
|
|
? price < target
|
|
: price > target;
|
|
if (has)
|
|
{
|
|
tp = target;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
Clean(lqs);
|
|
fvg.Clean();
|
|
iLQ.Clean();
|
|
Clean(fvgs);
|
|
iBar.Clean();
|
|
iConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|