This commit is contained in:
2025-03-07 11:53:51 +03:30
parent 5534bde7e5
commit f050a00b44
5 changed files with 1119 additions and 68 deletions
+418
View File
@@ -0,0 +1,418 @@
//+------------------------------------------------------------------+
//| SMC_OrderBlock_EA.mq5|
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#include <Trade/AccountInfo.mqh>
#include <Trade/Trade.mqh>
//
// Input parameters
input ENUM_TIMEFRAMES TimeFrame = PERIOD_M15; // Timeframe for analysis
input double RiskPercent = 1.0; // Risk per trade (1-2%)
input int ATR_Period = 14; // ATR period for volatility
input int OrderBlockLength = 20; // Bars for consolidation
input int ConfirmationCandles = 3; // Candles to confirm breakout
input double StopLossMultiplier = 1.5; // Stop loss buffer
input double TakeProfitRatio = 2.0; // Risk:Reward ratio
input int TrailingStopPips = 50; // Trailing stop in pips
//
CTrade trade;
CAccountInfo accountInfo;
//
double Ask = 0;
double Bid = 0;
//
// Order Block structure
struct OrderBlock
{
datetime startTime;
double high;
double low;
};
//
int atrHandler = INVALID_HANDLE;
int maFastHandler = INVALID_HANDLE;
int maSlowHandler = INVALID_HANDLE;
//
double atrs[];
double fastMAs[];
double slowMAs[];
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//
trade.SetExpertMagicNumber(123456); // Unique magic number
//
atrHandler = iATR(_Symbol, TimeFrame, ATR_Period);
maFastHandler = iMA(_Symbol, TimeFrame, 20, 0, MODE_SMA, PRICE_CLOSE);
maSlowHandler = iMA(_Symbol, TimeFrame, 50, 0, MODE_SMA, PRICE_CLOSE);
//
bool isValid =
atrHandler != INVALID_HANDLE &&
maFastHandler != INVALID_HANDLE &&
maSlowHandler != INVALID_HANDLE;
if (!isValid)
{
return (INIT_FAILED);
}
//
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//
// Cleanup code if needed ...
IndicatorRelease(atrHandler);
IndicatorRelease(maFastHandler);
IndicatorRelease(maSlowHandler);
//
ZeroMemory(atrs);
ZeroMemory(fastMAs);
ZeroMemory(slowMAs);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Avoid multiple orders
if (CheckOpenOrders())
return;
//
CopyBuffer(atrHandler, MAIN_LINE, 0, 200, atrs);
//
CopyBuffer(maFastHandler, MAIN_LINE, 0, 2, fastMAs);
CopyBuffer(maSlowHandler, MAIN_LINE, 0, 2, slowMAs);
//
Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits); // Get the Ask Price
Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits); // Get the Bid Price
//
// Check for trend and execute trades
if (IsUptrend())
{
OrderBlock block = FindBullishOrderBlock();
if (block.startTime != 0 && IsPriceInBlock(block))
{
if (ConfirmBullishEntry())
ExecuteTrade(block, ORDER_TYPE_BUY);
}
}
else if (IsDowntrend())
{
OrderBlock block = FindBearishOrderBlock();
if (block.startTime != 0 && IsPriceInBlock(block))
{
if (ConfirmBearishEntry())
ExecuteTrade(block, ORDER_TYPE_SELL);
}
}
// Manage trailing stops
TrailStop();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Check if price is within the order block |
//+------------------------------------------------------------------+
bool IsPriceInBlock(OrderBlock &block)
{
double currentPrice = (Ask + Bid) / 2; // Mid-price
return (currentPrice >= block.low && currentPrice <= block.high);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Detect uptrend using moving averages |
//+------------------------------------------------------------------+
bool IsUptrend()
{
//
double maFast = fastMAs[0];
double maSlow = slowMAs[0];
//
return (maFast > maSlow);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Detect downtrend using moving averages |
//+------------------------------------------------------------------+
bool IsDowntrend()
{
//
double maFast = fastMAs[0];
double maSlow = slowMAs[0];
//
return (maFast < maSlow);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Find bullish order blocks |
//+------------------------------------------------------------------+
OrderBlock FindBullishOrderBlock()
{
//
OrderBlock block;
block.startTime = 0;
//
for (int i = 1; i < 100; i++)
{
double prevHigh = iHigh(NULL, TimeFrame, i);
double prevLow = iLow(NULL, TimeFrame, i);
double prevClose = iClose(NULL, TimeFrame, i);
double prevOpen = iOpen(NULL, TimeFrame, i);
double atr = atrs[i];
if (prevClose - prevOpen > 1.5 * atr)
{ // Strong bullish candle
double consolidationHigh = prevHigh;
double consolidationLow = prevLow;
bool isConsolidation = true;
for (int j = 1; j <= OrderBlockLength; j++)
{
double newHigh = iHigh(NULL, TimeFrame, i - j);
double newLow = iLow(NULL, TimeFrame, i - j);
consolidationHigh = MathMax(consolidationHigh, newHigh);
consolidationLow = MathMin(consolidationLow, newLow);
if ((consolidationHigh - consolidationLow) > 0.5 * atr)
{
isConsolidation = false;
break;
}
}
if (isConsolidation)
{
block.high = consolidationHigh;
block.low = consolidationLow;
block.startTime = iTime(NULL, TimeFrame, i);
return block;
}
}
}
return block;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Find bearish order blocks |
//+------------------------------------------------------------------+
OrderBlock FindBearishOrderBlock()
{
//
OrderBlock block;
block.startTime = 0;
//
for (int i = 1; i < 100; i++)
{
double prevHigh = iHigh(NULL, TimeFrame, i);
double prevLow = iLow(NULL, TimeFrame, i);
double prevClose = iClose(NULL, TimeFrame, i);
double prevOpen = iOpen(NULL, TimeFrame, i);
double atr = atrs[i];
if (prevOpen - prevClose > 1.5 * atr)
{ // Strong bearish candle
double consolidationHigh = prevHigh;
double consolidationLow = prevLow;
bool isConsolidation = true;
for (int j = 1; j <= OrderBlockLength; j++)
{
double newHigh = iHigh(NULL, TimeFrame, i - j);
double newLow = iLow(NULL, TimeFrame, i - j);
consolidationHigh = MathMax(consolidationHigh, newHigh);
consolidationLow = MathMin(consolidationLow, newLow);
if ((consolidationHigh - consolidationLow) > 0.5 * atr)
{
isConsolidation = false;
break;
}
}
if (isConsolidation)
{
block.high = consolidationHigh;
block.low = consolidationLow;
block.startTime = iTime(NULL, TimeFrame, i);
return block;
}
}
}
return block;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Confirm bullish entry with candle pattern |
//+------------------------------------------------------------------+
bool ConfirmBullishEntry()
{
//
int shift = iBarShift(NULL, TimeFrame, TimeCurrent());
double prevLow = iLow(NULL, TimeFrame, shift + 1);
double currentClose = iClose(NULL, TimeFrame, shift);
return (currentClose > prevLow && iOpen(NULL, TimeFrame, shift) < currentClose);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Confirm bearish entry with candle pattern |
//+------------------------------------------------------------------+
bool ConfirmBearishEntry()
{
//
int shift = iBarShift(NULL, TimeFrame, TimeCurrent());
double prevHigh = iHigh(NULL, TimeFrame, shift + 1);
double currentClose = iClose(NULL, TimeFrame, shift);
return (currentClose < prevHigh && iOpen(NULL, TimeFrame, shift) > currentClose);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Execute trade with risk management |
//+------------------------------------------------------------------+
void ExecuteTrade(OrderBlock &block, ENUM_ORDER_TYPE orderType)
{
//
double atr = atrs[0];
double stopLoss, takeProfit, lotSize;
double entryPrice = (orderType == ORDER_TYPE_BUY) ? Ask : Bid;
// Calculate stop loss and take profit
if (orderType == ORDER_TYPE_BUY)
{
stopLoss = block.low - StopLossMultiplier * atr;
takeProfit = entryPrice + (entryPrice - stopLoss) * TakeProfitRatio;
}
else
{
stopLoss = block.high + StopLossMultiplier * atr;
takeProfit = entryPrice - (stopLoss - entryPrice) * TakeProfitRatio;
}
// Calculate lot size based on risk
lotSize = CalculateLotSize(stopLoss, entryPrice, orderType);
if (lotSize <= 0)
return;
// Place order
if (orderType == ORDER_TYPE_BUY)
{
trade.Buy(lotSize, _Symbol, entryPrice, stopLoss, takeProfit, "SMC Bullish Order Block");
}
else
{
trade.Sell(lotSize, _Symbol, entryPrice, stopLoss, takeProfit, "SMC Bearish Order Block");
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Calculate lot size based on risk per trade |
//+------------------------------------------------------------------+
double CalculateLotSize(double stopLoss, double entryPrice, ENUM_ORDER_TYPE orderType)
{
double riskAmount = AccountBalance() * RiskPercent / 100;
double stopLossPips = MathAbs((entryPrice - stopLoss) / SymbolInfoDouble(_Symbol, SYMBOL_POINT));
if (stopLossPips == 0)
return 0;
double pipValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double lotSize = riskAmount / (stopLossPips * pipValue);
lotSize = NormalizeDouble(lotSize, 2); // Adjust to symbol's lot precision
return MathMax(lotSize, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN));
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Check for existing open orders |
//+------------------------------------------------------------------+
bool CheckOpenOrders()
{
for (int i = 0; i < PositionsTotal(); i++)
{
if (PositionGetSymbol(i) == _Symbol)
return true;
}
return false;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Trailing stop logic |
//+------------------------------------------------------------------+
void TrailStop()
{
for (int i = 0; i < PositionsTotal(); i++)
{
if (PositionGetSymbol(i) != _Symbol)
continue;
ulong ticket = PositionGetInteger(POSITION_TICKET);
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double currentPrice = (type == POSITION_TYPE_BUY) ? Bid : Ask;
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double stopLoss = PositionGetDouble(POSITION_SL);
double trailingStopPrice = (type == POSITION_TYPE_BUY)
? currentPrice - TrailingStopPips * SymbolInfoDouble(_Symbol, SYMBOL_POINT)
: currentPrice + TrailingStopPips * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
// Update stop loss if price moves favorably
if ((type == POSITION_TYPE_BUY && trailingStopPrice > stopLoss) ||
(type == POSITION_TYPE_SELL && trailingStopPrice < stopLoss))
{
trade.PositionModify(ticket, trailingStopPrice, PositionGetDouble(POSITION_TP));
}
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Calculate Account Balance |
//+------------------------------------------------------------------+
double AccountBalance()
{
return accountInfo.Balance();
}
//+------------------------------------------------------------------+
+80 -3
View File
@@ -1324,6 +1324,83 @@ bool HasInsideBox(
return result;
}
bool IsValidBox(
XBoxZone &box,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
result = box.IsValid();
if (!result)
{
return result;
}
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (!IsValid(forPeriod))
{
forPeriod = box.period;
}
//
int fromIndex = iBarShift(
box.symbol,
forPeriod,
box.from //
);
result = IsValidIndex(fromIndex);
if (!result)
{
return result;
}
//
XOHCL iBar;
bool isBullish = box.IsBullish();
for (int i = barIndex; i < fromIndex; i++)
{
//
result = iBar.Init(
box.symbol,
forPeriod,
i //
);
if (!result)
{
break;
}
//
result =
isBullish
? iBar.GetDown() > box.lower
: iBar.GetUp() < box.upper;
if (!result)
{
break;
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
/**
* Converts to XBoxZone ...
*
@@ -2899,14 +2976,14 @@ int FilterZones(
/**
* Detect Nearest Price Out of Specified Box ...
*
*
* @param box: XBoxZone instance Reference ...
* @param outSideBar: XOHCL instance Reference which Represents Out Side Bar if Exists ...
* @param forPeriod: ENUM_TIMEFRAMES member which provides time frame of Out Bar, if not Provides used box Period as Default ...
* @param forDir: ENUM_X_DIRECTION member which Specified outSide Direction, use Box Dir as Default ...
* @param forDir: ENUM_X_DIRECTION member which Specified outSide Direction, use Box Dir as Default ...
* @param forceBodyIn: bool value which Specifyed Body Breakes or not, Default is false ...
* @param barIndex: integer value which Specified Start Bar Index, Default is 0 ...
*
*
* @return ( bool )
*/
bool DetectBoxNearestPriceOut(
+8 -2
View File
@@ -488,11 +488,17 @@ struct XOBFVG
continue;
}
//
// bool isBarAbove =
// bar.low > iFVG.Upper();
// bool isBarBelow =
// bar.high < iFVG.Lower();
//
bool isBarAbove =
bar.low > iFVG.Upper();
bar.GetDown() > iFVG.Upper();
bool isBarBelow =
bar.high < iFVG.Lower();
bar.GetUp() < iFVG.Lower();
//
isValidFVG =
@@ -164,12 +164,14 @@ class XCX121SMCXWZSignalDetector : public XCBase
double targets[];
double reward = 0;
XBoxZone signalBox;
int activatedFVGIDX = 0;
int activatedZoneIDX = 0;
double amountPercent = 0;
bool hasPriority = false;
int activatedFVGIDX = -1;
int activatedBoxIDX = -1;
int activatedZoneIDX = -1;
double amountPercent = -1;
bool hasSignalBox = false;
bool hasWaitingZones = false;
bool hasWaitingBoxes = false;
bool hasRewardAmount = false;
bool isSignalBoxReversal = false;
bool hasWorkingZoneOveralDirection = false;
@@ -214,10 +216,14 @@ class XCX121SMCXWZSignalDetector : public XCBase
.DetectOveralDirection(wzOveralDir);
//
// Detect Zones and Boxes ...
hasWaitingZones = workingZone.DetectZone(
provider //
);
//
hasWaitingBoxes = workingZone.HasWaitingBoxes();
//
// Checking Working Zone Destory or not ...
bool isWorkingZoneDestroyed = workingZone.IsDestroyed(
@@ -264,8 +270,7 @@ class XCX121SMCXWZSignalDetector : public XCBase
//
true, // Draw Supply Zone ...
true, // Draw Demand Zone ...
true, // Draw Waiting Zones ...
true // Draw Waiting Zones Box Area ...
true // Draw Waiting Zones ...
//
);
}
@@ -276,7 +281,9 @@ class XCX121SMCXWZSignalDetector : public XCBase
//
// Detect Signal Box ...
hasSignalBox =
//
bool isZoneActivated =
hasWorkingZone &&
hasWaitingZones &&
workingZone.IsZoneActivated(
@@ -285,23 +292,38 @@ class XCX121SMCXWZSignalDetector : public XCBase
provider,
zIndex //
);
//
bool isBoxActivated =
hasWorkingZone &&
hasWaitingBoxes &&
workingZone.IsBoxActivated(
activatedBoxIDX,
provider,
zIndex //
);
//
hasSignalBox =
isBoxActivated ||
isZoneActivated;
if (hasSignalBox)
{
//
signalBox.Clean();
//
XOBFVG iOBFVG = workingZone.waitingZones[activatedZoneIDX];
XCFVG *activatedFVG = iOBFVG.fvgs[activatedFVGIDX];
hasSignalBox = ToBox(
signalBox,
activatedFVG //
);
if (hasSignalBox)
if (isZoneActivated)
{
//
signalBox.to = cTime;
signalBoxDir = signalBox.dir;
XOBFVG iOBFVG = workingZone.waitingZones[activatedZoneIDX];
XCFVG *activatedFVG = iOBFVG.fvgs[activatedFVGIDX];
hasSignalBox = ToBox(
signalBox,
activatedFVG //
);
//
signalProvider = X121SMC_XWZ_PROVIDER_ACTIVATED_ZONE;
//
@@ -326,13 +348,48 @@ class XCX121SMCXWZSignalDetector : public XCBase
1 //
);
}
//
iOBFVG.Clean();
ZeroMemory(activatedFVG);
}
//
iOBFVG.Clean();
ZeroMemory(activatedFVG);
if (isBoxActivated)
{
//
signalBox = workingZone.waitingBoxes[activatedBoxIDX];
//
signalProvider = X121SMC_XWZ_PROVIDER_ACTIVATED_BOX;
//
AddRef(
signalBox,
workingZone.unavailableBoxes //
);
//
ArrayRemove(
workingZone.waitingBoxes,
activatedBoxIDX,
1 //
);
}
//
if (hasSignalBox)
{
//
signalBox.to = cTime;
signalBoxDir = signalBox.dir;
}
}
//
//
//
//
// Remove Invalidate Zones ...
if (hasWaitingZones)
@@ -343,6 +400,16 @@ class XCX121SMCXWZSignalDetector : public XCBase
hasWaitingZones = workingZone.HasWaitingZones();
}
//
// Remove InValidate Boxes ...
if (hasWaitingBoxes)
{
//
// Validate Waiting Boxes ...
workingZone.ValidateWaitingBoxes(zIndex);
hasWaitingBoxes = workingZone.HasWaitingBoxes();
}
//
//
//
@@ -413,6 +480,12 @@ class XCX121SMCXWZSignalDetector : public XCBase
? signalBox.upper
: signalBox.lower;
//
double entry = GetEntry(
signalBox.symbol,
signalBoxDir //
);
//
double iSL = 0;
@@ -432,6 +505,11 @@ class XCX121SMCXWZSignalDetector : public XCBase
// }
//
double iAtr = provider.decisionXConditions.atrBuffer[1];
iAtr *= 1.5;
//
// Default SL ...
iSL = pivot;
//
@@ -443,19 +521,13 @@ class XCX121SMCXWZSignalDetector : public XCBase
//
// Select Condition SL ...
//
double entry = GetEntry(
signalBox.symbol,
signalBoxDir //
);
//
double slsMin = GetMin(sls);
double slsMax = GetMax(sls);
//
double longSL = slsMin;
double shortSL = slsMax;
double longSL = slsMin - iAtr;
double shortSL = slsMax + iAtr;
//
sl = isBullish
+516 -38
View File
@@ -30,10 +30,8 @@
enum ENUM_X121SMC_XWZ_PROVIDERS
{
X121SMC_XWZ_PROVIDER_NONE,
X121SMC_XWZ_PROVIDER_PV_ZONE,
X121SMC_XWZ_PROVIDER_ACTIVATED_BOX,
X121SMC_XWZ_PROVIDER_ACTIVATED_ZONE,
X121SMC_XWZ_PROVIDER_ACTIVATED_CHOCH,
X121SMC_XWZ_PROVIDER_PRICE_INSIDE_ZONE,
};
//
@@ -73,6 +71,10 @@ struct X121SMCStrategyXWZWorkingZone
XOBFVG waitingZones[];
XOBFVG unavailableZones[];
//
XBoxZone waitingBoxes[];
XBoxZone unavailableBoxes[];
//
CArrayObj mDrawnObjects;
CArrayObj mWorkingZoneObjects;
@@ -101,6 +103,11 @@ struct X121SMCStrategyXWZWorkingZone
//
Clean(waitingZones);
Clean(unavailableZones);
//
Clean(waitingBoxes);
Clean(unavailableBoxes);
//
ZeroMemory(supplyZone);
@@ -461,7 +468,8 @@ struct X121SMCStrategyXWZWorkingZone
//
// Detect OB FVG ...
if (hasNewOrderBlock)
if (false &&
hasNewOrderBlock)
{
//
XOHCL obStartedBar;
@@ -596,6 +604,104 @@ struct X121SMCStrategyXWZWorkingZone
obStartedBar.Clean();
}
//
//
//
//
// Check New Order Block Detection Analyse ...
XBoxZone analyseOBBox;
XCOrderBlock *analyseOB = NULL;
bool hasNewAnalyseOrderBlock =
Contains(
X_BULLISH_ORDERBLOCK_DETECTED,
provider
.analysePoiEvents //
) ||
Contains(
X_BEARISH_ORDERBLOCK_DETECTED,
provider
.analysePoiEvents //
);
if (hasNewAnalyseOrderBlock)
{
//
idx = GetYoungest(provider
.analyseState
.orderBlocks //
);
has = IsValidIndex(idx);
if (has)
{
//
analyseOB = provider
.analyseState
.orderBlocks[idx];
has = ToBox(
analyseOBBox,
analyseOB //
);
if (has)
{
//
analyseOB.To(cTime);
analyseOBBox.to = cTime;
hasNewAnalyseOrderBlock = analyseOBBox.IsValid();
}
}
}
//
// Checking Analyse Order Block ...
if (hasNewAnalyseOrderBlock)
{
//
XCBaseObject *iObj;
has = provider
.visionCycleHelper
.mPOIDrawer
.CreateOrderBlock(
analyseOB,
iObj //
);
if (has)
{
//
XOHCL obStartedBar;
bool isOBStartedBodyOut = false;
bool isOBStarted = analyseOB.IsStarted(
analyseOB.GetDirection(),
obStartedBar,
isOBStartedBodyOut //
);
//
has = isOBStarted &&
isOBStartedBodyOut;
if (has)
{
//
has = IsExists(analyseOBBox);
if (!has)
{
//
AddRef(
analyseOBBox,
waitingBoxes //
);
}
}
}
}
//
analyseOBBox.Clean();
ZeroMemory(analyseOB);
//
//
//
//
result = HasWaitingZones();
@@ -694,6 +800,83 @@ struct X121SMCStrategyXWZWorkingZone
return result;
}
//
int ValidateWaitingBoxes(
int barIndex = 0 //
)
{
//
int result = 0;
//
bool has = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (barIndex == 0)
{
barIndex = 1;
}
//
has = IsValid() &&
HasWaitingBoxes();
if (!has)
{
return result;
}
//
int removeIDX[];
result = CountWaitingBoxes();
for (int i = 0; i < result; i++)
{
//
has = IsValidBox(
waitingBoxes[i],
barIndex,
period //
);
if (!has)
{
//
Add(
i,
removeIDX //
);
//
AddRef(
waitingBoxes[i],
unavailableBoxes //
);
}
}
//
has = HasChild(removeIDX);
if (has)
{
//
CleanupArray(
removeIDX,
waitingBoxes //
);
}
Clean(removeIDX);
//
result = CountWaitingBoxes();
//
return result;
}
//
bool IsZoneActivated(
int &zoneIDX,
@@ -848,17 +1031,17 @@ struct X121SMCStrategyXWZWorkingZone
// Activate Zone Using PV ...
bool isPVPassed =
isBullish
? vale < iBox.upper &&
vale > iBox.lower
: peak < iBox.upper &&
peak > iBox.lower;
? vale <= iBox.upper &&
vale >= iBox.lower
: peak <= iBox.upper &&
peak >= iBox.lower;
bool isPV50Passed =
isBullish
? vale < iBox.upper &&
vale < iRange &&
vale <= iRange &&
vale > iBox.lower
: peak < iBox.upper &&
peak < iRange &&
peak >= iRange &&
peak > iBox.lower;
//
@@ -872,7 +1055,8 @@ struct X121SMCStrategyXWZWorkingZone
//
// Combine Result ...
result = isPV50Passed;
result = isPVPassed;
// || isPVPassed
// || isPV50Passed
// || isRejected;
if (result)
@@ -933,6 +1117,194 @@ struct X121SMCStrategyXWZWorkingZone
return result;
}
//
bool IsBoxActivated(
int &boxIDX,
X121SMCStrategySignalProviderData &provider,
int barIndex = 0 //
)
{
//
bool result = false;
//
boxIDX = -1;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
result = IsValid() &&
HasWaitingBoxes();
if (!result)
{
return result;
}
//
XOHCL bar;
XOHCL cBar;
result = bar.Init(
symbol,
period,
barIndex //
);
result =
result &&
bar.GetPreviousBar(cBar);
if (!result)
{
//
bar.Clean();
cBar.Clean();
//
return result;
}
//
// Retrieve Some Required Data ...
//
double peak = provider.decisionXConditions.peaksBuffer[1];
double vale = provider.decisionXConditions.valesBuffer[1];
//
double analysePeak = provider.analyseXConditions.peaksBuffer[1];
double analyseVale = provider.analyseXConditions.valesBuffer[1];
//
double consolidationPeak = provider.consolidationXConditions.peaksBuffer[1];
double consolidationVale = provider.consolidationXConditions.valesBuffer[1];
//
double visionPeak = provider.visionXConditions.peaksBuffer[1];
double visionVale = provider.visionXConditions.valesBuffer[1];
//
bool isPeaksSame =
peak == analysePeak &&
analysePeak == consolidationPeak;
//
bool isValesSame =
vale == analyseVale &&
analyseVale == consolidationVale;
//
// Calculate Scores Conditions ...
//
bool isDecisionScoreBullish =
provider.decisionBullishScore > provider.decisionBearishScore;
//
bool isDecisionScoreBearish =
provider.decisionBearishScore > provider.decisionBullishScore;
//
bool isAnalyseScoreBullish =
provider.analyseBullishScore > provider.analyseBearishScore;
//
bool isAnalyseScoreBearish =
provider.analyseBearishScore > provider.analyseBullishScore;
//
bool isConsolidationScoreBullish =
provider.consolidationBullishScore > provider.consolidationBearishScore;
//
bool isConsolidationScoreBearish =
provider.consolidationBearishScore > provider.consolidationBullishScore;
//
bool isVisionScoreBullish =
provider.visionBullishScore > provider.visionBearishScore;
//
bool isVisionScoreBearish =
provider.visionBearishScore > provider.visionBullishScore;
//
int count = CountWaitingBoxes();
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = waitingBoxes[i];
bool isBullish = iBox.IsBullish();
//
// Checking Rejection ...
//
// Bullish ...
bool isBullishRejected =
isBullish &&
cBar.low <= iBox.upper &&
cBar.GetDown() > iBox.upper;
//
// Bearish ...
bool isBearishRejected =
!isBullish &&
cBar.high >= iBox.lower &&
cBar.GetUp() < iBox.lower;
//
// Rejection ...
bool isRejected = isBullishRejected ||
isBearishRejected;
//
// Checking Breaktion ...
//
// Bullish ...
bool isBullishBreaked =
isBullish &&
cBar.high > iBox.upper &&
cBar.GetUp() > iBox.upper &&
cBar.low >= iBox.lower;
//
// Bearish ...
bool isBearishBreaked =
!isBullish &&
cBar.low < iBox.lower &&
cBar.GetDown() < iBox.lower &&
cBar.high <= iBox.upper;
//
// Breaktion ...
bool isBreaked = isBullishBreaked ||
isBearishBreaked;
//
result = isRejected ||
isBreaked;
//
if (result)
{
//
boxIDX = i;
break;
}
//
}
//
bar.Clean();
cBar.Clean();
//
return result;
}
//
bool IsExists(XOBFVG &zone)
{
@@ -941,8 +1313,9 @@ struct X121SMCStrategyXWZWorkingZone
//
// Check Validation ...
result = HasWaitingZones() ||
HasUnavailableZones();
result = zone.IsValid() &&
(HasWaitingZones() ||
HasUnavailableZones());
if (!result)
{
return result;
@@ -979,6 +1352,53 @@ struct X121SMCStrategyXWZWorkingZone
return result;
}
//
bool IsExists(XBoxZone &box)
{
//
bool result = false;
//
// Check Validation ...
result = box.IsValid() &&
(HasWaitingBoxes() ||
HasUnavailableBoxes());
if (!result)
{
return result;
}
//
int idx = -1;
//
// Check Index in Waiting Zones ...
idx = FindIndex(
box,
waitingBoxes //
);
result = IsValidIndex(idx);
if (result)
{
return result;
}
//
// Check Index in Unavailable Zones ...
idx = FindIndex(
box,
unavailableBoxes //
);
result = IsValidIndex(idx);
if (result)
{
return result;
}
//
return result;
}
//
bool IsDestroyed(
int barIndex = 0,
@@ -1330,6 +1750,18 @@ struct X121SMCStrategyXWZWorkingZone
}
}
//
has = HasWaitingBoxes();
if (has)
{
//
count = CountWaitingBoxes();
for (int i = 0; i < count; i++)
{
waitingBoxes[i].to = value;
}
}
//
}
@@ -1338,9 +1770,7 @@ struct X121SMCStrategyXWZWorkingZone
XCPOIDrawer *drawer,
bool drawSupplyZone = false,
bool drawDemandZone = false,
bool drawWaitingZones = false,
bool drawWaitingZonesBoxArea = false //
)
bool drawWaitingZones = false)
{
//
if (drawer == NULL)
@@ -1605,30 +2035,54 @@ struct X121SMCStrategyXWZWorkingZone
}
//
if (drawWaitingZonesBoxArea)
{
//
XBoxZone iBox;
has = waitingZones[i].ToZone(
iBox //
);
if (has)
{
//
XCBoxObject *iBoxObj;
has = drawer.DrawBox(
iBox,
iBoxObj //
);
if (has)
{
mDrawnObjects.Add(iBoxObj);
}
}
// if (drawWaitingZonesBoxArea)
// {
// //
// XBoxZone iBox;
// has = waitingZones[i].ToZone(
// iBox //
// );
// if (has)
// {
// //
// XCBoxObject *iBoxObj;
// has = drawer.DrawBox(
// iBox,
// iBoxObj //
// );
// if (has)
// {
// mDrawnObjects.Add(iBoxObj);
// }
// }
//
iBox.Clean();
// //
// iBox.Clean();
// }
}
}
//
has = HasWaitingBoxes();
if (has)
{
//
count = CountWaitingBoxes();
for (int i = 0; i < count; i++)
{
//
XCBoxObject *iBoxObj;
has = drawer.DrawBox(
waitingBoxes[i],
iBoxObj //
);
if (has)
{
mDrawnObjects.Add(iBoxObj);
}
//
ZeroMemory(iBoxObj);
}
}
}
@@ -1678,6 +2132,30 @@ struct X121SMCStrategyXWZWorkingZone
return ArraySize(unavailableZones);
}
//
bool HasWaitingBoxes()
{
return HasChild(waitingBoxes);
}
//
int CountWaitingBoxes()
{
return ArraySize(waitingBoxes);
}
//
bool HasUnavailableBoxes()
{
return HasChild(unavailableBoxes);
}
//
int CountUnavailableBoxes()
{
return ArraySize(unavailableBoxes);
}
//
};