Files
MQL5Data/Documents/BKP/121.smc.strategy.tmp.mq5
T
2024-10-31 13:27:39 +03:30

1132 lines
34 KiB
Plaintext

//
// LONG ...
//
bool isSoImportantLong =
iConditions.demandZone.IsValid() &&
iConditions.bullishFVG.IsValid() &&
iConditions.bullishOrderBlock.IsValid();
//
bool isImportantLong =
iConditions.demandZone.IsValid() &&
(iConditions.bullishFVG.IsValid() ||
iConditions.bullishOrderBlock.IsValid());
//
bool isRiskyLong =
iConditions.demandZone.IsValid() &&
(iConditions.bullishFVG.IsValid() ||
iConditions.bullishOrderBlock.IsValid());
//
bool hasLongConditions = isSoImportantLong ||
isImportantLong ||
isRiskyLong;
//
if (hasLongConditions)
{
//
// Find Trigger for Input Positions ...
// - [] Breakout;
// - [] Engulf;
// - [] Rejection Bar;
// - [] Momentum Bar;
//
type = POSITION_TYPE_BUY;
entry = GetEntry(mSymbol, type);
sl = iConditions.demandZone.lower - (10 * points);
risk = entry - sl;
reward = risk * r2r;
tp = entry + reward;
//
bool isSpreadOK = IsSpreadPass();
//
// Price Must Breakout the Upper of Demand ...
bool isBreakout =
//
cBar.IsBullish() &&
zBar.low > conditions.demandZone.upper &&
cBar.high > conditions.demandZone.upper &&
cBar.close > conditions.demandZone.upper &&
(cBar.open < conditions.demandZone.upper ||
cBar.low < conditions.demandZone.upper)
//
;
//
// Price Must have Bullish Trend and Momentum on Ticks ...
bool isTicksBullishMomentum =
IsTicksBullish() &&
IsTicksHasMomentum();
//
// Detect momentum / Swing Low / Rejection Bars ...
bool hasMomentumBars = false;
int swingLowsCount = ArraySize(_5MState.swingLows);
int momentumBarsCount = ArraySize(_5MState.momentumBars);
int rejectionBarsCount = ArraySize(_5MState.rejectionBars);
if (IsValidSize(swingLowsCount) ||
IsValidSize(momentumBarsCount) ||
IsValidSize(rejectionBarsCount))
{
//
int foundedPOIs = 0;
//
// Check Swing Lows ...
if (IsValidSize(swingLowsCount))
{
//
for (int i = 0; i < swingLowsCount; i++)
{
//
XOHCL iBar = _5MState.swingLows[i];
//
if (iBar.time > iConditions.demandZone.from)
{
//
if (iBar.low < entry)
{
//
foundedPOIs++;
DrawSwingBar(iBar, true);
}
}
}
}
//
// Check Momentum Bars ...
if (IsValidSize(momentumBarsCount))
{
//
for (int i = 0; i < momentumBarsCount; i++)
{
//
XOHCL iBar = _5MState.momentumBars[i];
//
if (iBar.time > iConditions.demandZone.from)
{
//
if (iBar.IsBullish() && iBar.low < entry)
{
//
foundedPOIs++;
DrawMomentumBar(iBar);
}
}
}
}
//
// Check Rejection Bars ...
if (IsValidSize(rejectionBarsCount))
{
//
for (int i = 0; i < rejectionBarsCount; i++)
{
//
XOHCL iBar = _5MState.rejectionBars[i];
//
if (iBar.time > iConditions.demandZone.from)
{
//
if (iBar.low < entry &&
iBar.GetLowShadow() > iBar.GetHighShadow())
{
//
foundedPOIs++;
DrawRejectionBar(iBar);
}
}
}
}
//
pushers = foundedPOIs;
hasMomentumBars = foundedPOIs > 0;
}
//
hasLongConditions =
hasLongConditions &&
//
isSpreadOK &&
//
isBreakout &&
isTicksBullishMomentum &&
//
hasMomentumBars
//
;
//
if (hasLongConditions)
{
//
removeIDX = i;
conditions = iConditions;
result = hasLongConditions;
//
break;
}
}
//
// SHORT ...
//
bool isSoImportantShort =
iConditions.supplyZone.IsValid() &&
iConditions.bearishFVG.IsValid() &&
iConditions.bearishOrderBlock.IsValid();
//
bool isImportantShort =
iConditions.supplyZone.IsValid() &&
(iConditions.bearishFVG.IsValid() ||
iConditions.bearishOrderBlock.IsValid());
//
bool isRiskyShort =
iConditions.supplyZone.IsValid() &&
(!iConditions.bearishFVG.IsValid() &&
!iConditions.bearishOrderBlock.IsValid());
//
bool hasShortConditions = isSoImportantShort ||
isImportantShort ||
isRiskyShort;
//
if (hasShortConditions)
{
//
// Find Trigger for Input Positions ...
// - [] Breakout;
// - [] Engulf;
// - [] Rejection Bar;
// - [] Momentum Bar;
//
//
// removeIDX = i;
// conditions = iConditions;
// // DrawConditions(iConditions);
// Print("hasShortConditions");
break;
}
//////////////////////////////////////////////////////////////////////////////
//
XZone iBearishOrderBlock;
XZone iBearishFVG;
//
bool isPassed = false;
int orderBlocksCount = ArraySize(orderBlocksState.bearishOrderBlocks);
isPassed = IsValidSize(orderBlocksCount);
if (!isPassed)
{
continue;
}
//
// Find Related Order Block ...
isPassed = false;
for (int j = 0; j < orderBlocksCount; j++)
{
//
XZone jOrderBlock = orderBlocksState.bearishOrderBlocks[j];
//
bool isOrderBlockInsideZone = IsSupplyZoneOrderBlock(
iSupplyZone,
jOrderBlock //
);
if (isOrderBlockInsideZone)
{
//
isPassed = true;
iBearishOrderBlock = jOrderBlock;
conditions.bearishOrderBlock = jOrderBlock;
break;
}
}
if (!isPassed)
{
continue;
}
//
isPassed = false;
int fairValueGapsCount = ArraySize(fvgsState.bearishFVGs);
isPassed = IsValidSize(fairValueGapsCount);
if (!isPassed)
{
continue;
}
//
// Find Related Fair Value Gaps ...
isPassed = false;
for (int j = 0; j < fairValueGapsCount; j++)
{
//
XZone jFVG = fvgsState.bearishFVGs[j];
//
bool isBelongs = IsBearishOrderBlockFVG(
iBearishOrderBlock,
jFVG //
);
if (isBelongs)
{
//
iBearishFVG = jFVG;
conditions.bearishFVG = jFVG;
//
isPassed = true;
break;
}
}
// if (!isPassed)
// {
// continue;
// }
// //
// if (isPassed)
// {
// //
// DrawSupplyZone(iSupplyZone);
// DrawBearishOrderBlock(iBearishOrderBlock);
// DrawBearishFVG(iBearishFVG);
// }
//////////////////////////////////////////////
//
XZone iBullishOrderBlock;
XZone iBullishFVG;
//
bool isPassed = false;
int orderBlocksCount = ArraySize(orderBlocksState.bullishOrderBlocks);
isPassed = IsValidSize(orderBlocksCount);
if (!isPassed)
{
continue;
}
//
// Find Related Order Block ...
isPassed = false;
for (int j = 0; j < orderBlocksCount; j++)
{
//
XZone jOrderBlock = orderBlocksState.bullishOrderBlocks[j];
//
bool isOrderBlockInsideZone = IsDemandZoneOrderBlock(
iDemandZone,
jOrderBlock //
);
if (isOrderBlockInsideZone)
{
//
isPassed = true;
iBullishOrderBlock = jOrderBlock;
conditions.bullishOrderBlock = jOrderBlock;
break;
}
}
if (!isPassed)
{
continue;
}
//
isPassed = false;
int fairValueGapsCount = ArraySize(fvgsState.bullishFVGs);
isPassed = IsValidSize(fairValueGapsCount);
if (!isPassed)
{
continue;
}
//
// Find Related Fair Value Gaps ...
isPassed = false;
for (int j = 0; j < fairValueGapsCount; j++)
{
//
XZone jFVG = fvgsState.bullishFVGs[j];
//
bool isBelongs = IsBullishOrderBlockFVG(
iBullishOrderBlock,
jFVG //
);
if (isBelongs)
{
//
iBullishFVG = jFVG;
conditions.bullishFVG = jFVG;
//
isPassed = true;
break;
}
}
// if (!isPassed)
// {
// continue;
// }
// //
// if (isPassed)
// {
// //
// DrawDemandZone(iDemandZone);
// DrawBullishOrderBlock(iBullishOrderBlock);
// DrawBullishFVG(iBullishFVG);
// }
//////////////////////////////////////////////
//
// Tools Functions ...
/**
* Check an Order Block belongs to a Supply Zone ...
*
* @param supply: XZone instance ...
* @param orderBlock: XZone instance ...
*
* @return ( bool )
*/
bool IsSupplyZoneOrderBlock(
XZone &supply,
XZone &orderBlock //
)
{
//
bool result = false;
//
result = supply.IsValid() &&
orderBlock.IsValid();
if (!result)
{
return result;
}
//
result =
orderBlock.upper <= supply.upper;
//
return result;
}
/**
* Check an Order Block belongs to a Demand Zone ...
*
* @param demand: XZone instance ...
* @param orderBlock: XZone instance ...
*
* @return ( bool )
*/
bool IsDemandZoneOrderBlock(
XZone &demand,
XZone &orderBlock //
)
{
//
bool result = false;
//
result = demand.IsValid() &&
orderBlock.IsValid();
if (!result)
{
return result;
}
//
result =
orderBlock.lower >= demand.lower;
//
return result;
}
/**
* Check a Bearish FVG belongs to a Bearish Order Block ...
*
* @param orderBlock: XZone instance ...
* @param fvg: XZone instance ...
*
* @return ( bool )
*/
bool IsBearishOrderBlockFVG(
XZone &orderBlock,
XZone &fvg //
)
{
//
bool result = false;
//
result = fvg.IsValid() &&
orderBlock.IsValid();
if (!result)
{
return result;
}
//
result =
fvg.upper <= orderBlock.upper &&
fvg.upper > orderBlock.lower;
//
return result;
}
/**
* Check a Bullish FVG belongs to a Bullish Order Block ...
*
* @param orderBlock: XZone instance ...
* @param fvg: XZone instance ...
*
* @return ( bool )
*/
bool IsBullishOrderBlockFVG(
XZone &orderBlock,
XZone &fvg //
)
{
//
bool result = false;
//
result = fvg.IsValid() &&
orderBlock.IsValid();
if (!result)
{
return result;
}
//
result =
fvg.lower >= orderBlock.lower &&
fvg.lower < orderBlock.upper;
//
return result;
}
////////////////////////////////////////////////////////////////////////
//
int supplyZonesCount = ArraySize(supplyAndDemandZoneState.supplyZones);
int demandZonesCount = ArraySize(supplyAndDemandZoneState.demandZones);
//
XOHCL swingHighs[];
Copy(
orderBlocksState.swingHighs,
swingHighs //
);
Copy(
fvgsState.swingHighs,
swingHighs,
false //
);
Copy(
triggerState.swingHighs,
swingHighs,
false //
);
//
XOHCL swingLows[];
Copy(
orderBlocksState.swingLows,
swingLows //
);
Copy(
fvgsState.swingLows,
swingLows,
false //
);
Copy(
triggerState.swingLows,
swingLows,
false //
);
//
int swingHighsCount = ArraySize(swingHighs);
int swingLowsCount = ArraySize(swingLows);
if (!IsValidSize(swingLowsCount) ||
!IsValidSize(swingHighsCount) ||
!IsValidSize(supplyZonesCount) ||
!IsValidSize(demandZonesCount))
{
return result;
}
//
XOHCL zBar;
bool isInited = zBar.Init(
Symbol(),
Period(),
0 //
);
if (!isInited)
{
return result;
}
//
// Detect Swing High and Low as Market Structure Boundaries ...
//
// Swing High ...
XOHCL tmpBar;
for (int i = 0; i < swingHighsCount; i++)
{
//
XOHCL iSwing = swingHighs[i];
//
if (!tmpBar.IsValid() ||
tmpBar.high < iSwing.high)
{
tmpBar = iSwing;
}
}
if (tmpBar.IsValid())
{
//
mSwingHigh = tmpBar;
string name = tmpBar.GetTag(ToString(X_POI_SWING_HIGH));
if (mSwingHighObject != NULL)
{
mSwingHighObject.Delete();
}
mSwingHighObject = new CChartObjectHLine();
bool isCreated = mSwingHighObject.Create(
ChartIdentification(),
name,
SubWindowIdentification(),
tmpBar.high //
);
if (isCreated)
{
//
mSwingHighObject.Width(2);
mSwingHighObject.Color(clrRed);
mSwingHighObject.Style(STYLE_DASHDOTDOT);
}
}
//
// Swing Low ...
tmpBar.Clean();
for (int i = 0; i < swingLowsCount; i++)
{
//
XOHCL iSwing = swingLows[i];
//
if (!tmpBar.IsValid() ||
tmpBar.low > iSwing.low)
{
tmpBar = iSwing;
}
}
if (tmpBar.IsValid())
{
//
mSwingLow = tmpBar;
string name = tmpBar.GetTag(ToString(X_POI_SWING_LOW));
if (mSwingLowObject != NULL)
{
mSwingLowObject.Delete();
}
mSwingLowObject = new CChartObjectHLine();
bool isCreated = mSwingLowObject.Create(
ChartIdentification(),
name,
SubWindowIdentification(),
tmpBar.low //
);
if (isCreated)
{
//
mSwingLowObject.Width(2);
mSwingLowObject.Color(clrLime);
mSwingLowObject.Style(STYLE_DASHDOTDOT);
}
}
tmpBar.Clean();
//
// Demand Zone ...
for (int i = 0; i < demandZonesCount; i++)
{
//
// Demand Zone ...
XZone iDemandZone = supplyAndDemandZoneState.demandZones[i];
conditions.demandZone = iDemandZone;
//
// TODO: Remove this ...
// XCDemandZoneObject *iDemandZoneObj;
// bool isCreated = mPOIDrawer.CreateDemandZone(
// iDemandZone,
// iDemandZoneObj //
// );
//
// Order Blocks ...
int orderBlocksCount = ArraySize(orderBlocksState.bullishOrderBlocks);
if (IsValidSize(orderBlocksCount))
{
//
for (int j = 0; j < orderBlocksCount; j++)
{
//
XZone jZone = orderBlocksState.bullishOrderBlocks[j];
//
bool isInside =
(jZone.lower > iDemandZone.lower &&
jZone.lower < iDemandZone.upper) ||
(jZone.lower < iDemandZone.lower);
if (isInside)
{
//
jZone.to = TimeCurrent();
//
// TODO: Remove this ...
// XCBullishOrderBlockObject *iBullOBObj;
// bool isCreated = mPOIDrawer.CreateBullishOrderBlock(
// jZone,
// iBullOBObj //
// );
AddRef(
jZone,
conditions.bullishOrderBlocks //
);
}
}
}
//
// Support Zones ...
int supportsCount = ArraySize(fvgsState.supportZones);
if (IsValidSize(supportsCount))
{
//
for (int j = 0; j < supportsCount; j++)
{
//
XOHCL jBar = fvgsState.supportZones[j];
//
bool isInside =
(jBar.low > iDemandZone.lower &&
jBar.low < iDemandZone.upper) ||
(jBar.low < iDemandZone.lower);
if (isInside)
{
//
// TODO: Remove this ...
// XCSupportZoneObject *iSupportZoneObj;
// bool isCreated = mPOIDrawer.CreateSupportZone(
// jBar,
// iSupportZoneObj,
// TimeCurrent() //
// );
//
AddRef(
jBar,
conditions.supports //
);
}
}
}
//
// Bullish FVGs ...
int fvgsCount = ArraySize(fvgsState.bullishFVGs);
if (IsValidSize(fvgsCount))
{
//
for (int j = 0; j < fvgsCount; j++)
{
//
XZone jFVG = fvgsState.bullishFVGs[j];
//
bool isInside =
jFVG.from > iDemandZone.from &&
jFVG.lower < iDemandZone.upper &&
jFVG.upper > iDemandZone.upper;
if (isInside)
{
//
jFVG.to = TimeCurrent();
//
// TODO: Remove This ...
// XCBullishFVGObject *iObj;
// bool isCreated = mPOIDrawer.CreateBullishFVG(
// jFVG,
// iObj //
// );
//
AddRef(
jFVG,
conditions.bullishFVGs //
);
}
}
}
//
// Swing Lows ...
int swingLowsCount = ArraySize(triggerState.swingLows);
if (IsValidSize(swingLowsCount))
{
//
for (int j = 0; j < swingLowsCount; j++)
{
//
XOHCL jBar = triggerState.swingLows[j];
//
bool isInside =
jBar.time > iDemandZone.from &&
jBar.low > iDemandZone.lower &&
jBar.GetDown() < iDemandZone.upper;
if (isInside)
{
//
// TODO: Remve this ...
// XCSwingLowObject *iObj;
// bool isCreated = mPOIDrawer.CreateSwingLow(
// jBar,
// iObj //
// );
//
AddRef(
jBar,
conditions.swingLows //
);
}
}
}
//
// Bullish Momentum Bars ...
int bullishMomentumBarsCount = ArraySize(triggerState.momentumBars);
if (IsValidSize(bullishMomentumBarsCount))
{
//
for (int j = 0; j < bullishMomentumBarsCount; j++)
{
//
XOHCL jBar = triggerState.momentumBars[j];
//
bool isInside =
jBar.IsBullish() &&
jBar.time > iDemandZone.from &&
jBar.low > iDemandZone.lower &&
jBar.low < iDemandZone.upper;
if (isInside)
{
//
// TODO: Remove this ...
// XCBullishMomentumBarObject *iObj;
// bool isCreated = mPOIDrawer.CreateBullishMomentumBar(
// jBar,
// iObj //
// );
//
AddRef(
jBar,
conditions.bullishMomentumBars //
);
}
}
}
//
// Bullish Rejection Bars ...
int bullishRejectionBarsCount = ArraySize(triggerState.rejectionBars);
if (IsValidSize(bullishRejectionBarsCount))
{
//
for (int j = 0; j < bullishRejectionBarsCount; j++)
{
//
XOHCL jBar = triggerState.rejectionBars[j];
//
bool isInside =
jBar.GetLowShadow() > jBar.GetHighShadow() &&
jBar.time > iDemandZone.from &&
jBar.low > iDemandZone.lower &&
jBar.low < iDemandZone.upper;
if (isInside)
{
//
// TODO: Remove this ...
XCBullishRejectionBarObject *iObj;
bool isCreated = mPOIDrawer.CreateBullishRejectionBar(
jBar,
iObj //
);
//
AddRef(
jBar,
conditions.bullishRejectionBars //
);
}
}
}
}
//
// Supply Zone ...
// for (int i = 0; i < demandZonesCount; i++)
// {
// //
// // Supply Zone ...
// XZone iSupplyZone = supplyAndDemandZoneState.supplyZones[i];
// conditions.supplyZone = iSupplyZone;
// //
// // Order Blocks ...
// int orderBlocksCount = ArraySize(orderBlocksState.bearishOrderBlocks);
// if (IsValidSize(orderBlocksCount))
// {
// //
// for (int j = 0; j < orderBlocksCount; j++)
// {
// //
// XZone jZone = orderBlocksState.bearishOrderBlocks[j];
// //
// bool isInside =
// jZone.from > iSupplyZone.from &&
// jZone.upper > iSupplyZone.lower &&
// jZone.upper < iSupplyZone.upper;
// if (isInside)
// {
// //
// AddRef(
// jZone,
// conditions.bearishOrderBlocks //
// );
// }
// }
// }
// //
// // Resistance Zones ...
// int resistancesCount = ArraySize(fvgsState.resistanceZones);
// if (IsValidSize(resistancesCount))
// {
// //
// for (int j = 0; j < resistancesCount; j++)
// {
// //
// XOHCL jBar = fvgsState.resistanceZones[j];
// //
// bool isInside =
// jBar.time > iSupplyZone.from &&
// jBar.high > iSupplyZone.lower &&
// jBar.high < iSupplyZone.upper;
// if (isInside)
// {
// //
// AddRef(
// jBar,
// conditions.resistances //
// );
// }
// }
// }
// //
// // Bearish FVGs ...
// int fvgsCount = ArraySize(fvgsState.bearishFVGs);
// if (IsValidSize(fvgsCount))
// {
// //
// for (int j = 0; j < fvgsCount; j++)
// {
// //
// XZone jZone = fvgsState.bearishFVGs[j];
// //
// bool isInside =
// jZone.from > iSupplyZone.from &&
// jZone.upper > iSupplyZone.lower &&
// jZone.upper < iSupplyZone.upper;
// if (isInside)
// {
// //
// AddRef(
// jZone,
// conditions.bearishFVGs //
// );
// }
// }
// }
// //
// // Swing Highs ...
// int swingHighsCount = ArraySize(triggerState.swingHighs);
// if (IsValidSize(swingHighsCount))
// {
// //
// for (int j = 0; j < swingHighsCount; j++)
// {
// //
// XOHCL jBar = triggerState.swingHighs[j];
// //
// bool isInside =
// jBar.time > iSupplyZone.from &&
// jBar.high > iSupplyZone.lower &&
// jBar.high < iSupplyZone.upper;
// if (isInside)
// {
// //
// AddRef(
// jBar,
// conditions.swingHighs //
// );
// }
// }
// }
// //
// // Bearish Momentum Bars ...
// int bearishMomentumBarsCount = ArraySize(triggerState.momentumBars);
// if (IsValidSize(bearishMomentumBarsCount))
// {
// //
// for (int j = 0; j < bearishMomentumBarsCount; j++)
// {
// //
// XOHCL jBar = fvgsState.momentumBars[j];
// //
// bool isInside =
// jBar.IsBearish() &&
// jBar.time > iSupplyZone.from &&
// jBar.high > iSupplyZone.lower &&
// jBar.high < iSupplyZone.upper;
// if (isInside)
// {
// //
// AddRef(
// jBar,
// conditions.bearishMomentumBars //
// );
// }
// }
// }
// //
// // Bearish Rejection Bars ...
// int bearishRejectionBarsCount = ArraySize(triggerState.rejectionBars);
// if (IsValidSize(bearishRejectionBarsCount))
// {
// //
// for (int j = 0; j < bearishRejectionBarsCount; j++)
// {
// //
// XOHCL jBar = fvgsState.rejectionBars[j];
// //
// bool isInside =
// jBar.GetHighShadow() > jBar.GetLowShadow() &&
// jBar.time > iSupplyZone.from &&
// jBar.high > iSupplyZone.lower &&
// jBar.high < iSupplyZone.upper;
// if (isInside)
// {
// //
// AddRef(
// jBar,
// conditions.bearishRejectionBars //
// );
// }
// }
// }
// }
//
bool isConditionReadyForDemand =
conditions.demandZone.IsValid() &&
(ArraySize(conditions.supports) > 0 ||
ArraySize(conditions.swingLows) > 0 ||
ArraySize(conditions.bullishFVGs) > 0 ||
ArraySize(conditions.bullishOrderBlocks) > 0 ||
ArraySize(conditions.bullishMomentumBars) > 0 ||
ArraySize(conditions.bullishRejectionBars) > 0);
//
bool isConditionReadyForSupply =
conditions.supplyZone.IsValid() &&
(ArraySize(conditions.swingHighs) > 0 ||
ArraySize(conditions.bearishFVGs) > 0 ||
ArraySize(conditions.resistances) > 0 ||
ArraySize(conditions.bearishOrderBlocks) > 0 ||
ArraySize(conditions.bearishMomentumBars) > 0 ||
ArraySize(conditions.bearishRejectionBars) > 0);
//
result = isConditionReadyForDemand ||
isConditionReadyForSupply;