1917 lines
40 KiB
Plaintext
1917 lines
40 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// --------------------------------------
|
|
// Name: XSCX121Strategy
|
|
// Description: provides all based classes for use ...
|
|
//
|
|
//
|
|
// 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 "../../Classes/x-saherelm.x-poi.class.mq5"
|
|
#include "../../Classes/x-saherelm.xalert.class.mq5"
|
|
#include "../../Classes/x-saherelm.xtrade.class.mq5"
|
|
#include "../Libraries/x-121.smc.lib.mq5"
|
|
|
|
//
|
|
// Helper(s) ...
|
|
|
|
//
|
|
// XStrategy Class Implementation(s) ...
|
|
class XCX121SMCStrategy : public XSCBaseAlert
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
void XCX121SMCStrategy(
|
|
//
|
|
// Base ...
|
|
string _symbol, // Trading Symbol
|
|
ENUM_TIMEFRAMES _period // Trading TimeFrame
|
|
)
|
|
{
|
|
//
|
|
mSymbol = _symbol;
|
|
mPeriod = _period;
|
|
|
|
//
|
|
Init();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
void ~XCX121SMCStrategy()
|
|
{
|
|
DeInit();
|
|
}
|
|
|
|
//
|
|
// Getter / Setter (s) ...
|
|
|
|
/**
|
|
* Retrieve Symbol ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string Symbol()
|
|
{
|
|
return mSymbol;
|
|
}
|
|
|
|
/**
|
|
* Retrieve TimeFrame ...
|
|
*
|
|
* @return ( ENUM_TIMEFRAMES )
|
|
*/
|
|
ENUM_TIMEFRAMES Period()
|
|
{
|
|
return mPeriod;
|
|
}
|
|
|
|
/**
|
|
* Check Strategy is Disabled or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsDisabled()
|
|
{
|
|
return mForceDisabled;
|
|
}
|
|
|
|
/**
|
|
* Get Signal Volume ...
|
|
*
|
|
* @return ( double )
|
|
*/
|
|
double Volume()
|
|
{
|
|
return mVolume;
|
|
}
|
|
|
|
/**
|
|
* Set Signal Volume ...
|
|
*
|
|
* @param value: Double ...
|
|
*/
|
|
void Volume(double value)
|
|
{
|
|
//
|
|
if (value < 0.01)
|
|
{
|
|
value = 0.01;
|
|
}
|
|
|
|
//
|
|
mVolume = value;
|
|
}
|
|
|
|
/**
|
|
* Get Risk/Reward Ratio ...
|
|
*
|
|
* @return ( double )
|
|
*/
|
|
double R2R()
|
|
{
|
|
return mR2R;
|
|
}
|
|
|
|
/**
|
|
* Set Risk/Reward Ratio ...
|
|
*
|
|
* @param value: Double ...
|
|
*/
|
|
void R2R(double value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 1.5;
|
|
}
|
|
|
|
//
|
|
mR2R = value;
|
|
}
|
|
|
|
/**
|
|
* Get Long Signalling State ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AllowLong()
|
|
{
|
|
return mAllowLong;
|
|
}
|
|
|
|
/**
|
|
* Set Long Signalling State ...
|
|
*
|
|
* @param value: Boolean ...
|
|
*/
|
|
void AllowLong(bool value)
|
|
{
|
|
mAllowLong = value;
|
|
}
|
|
|
|
/**
|
|
* Get Short Signalling State ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AllowShort()
|
|
{
|
|
return mAllowShort;
|
|
}
|
|
|
|
/**
|
|
* Set Short Signalling State ...
|
|
*
|
|
* @param value: Argument 1
|
|
*/
|
|
void AllowShort(bool value)
|
|
{
|
|
mAllowShort = value;
|
|
}
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Disable Strategy ...
|
|
*/
|
|
void Disable()
|
|
{
|
|
mForceDisabled = true;
|
|
}
|
|
|
|
/**
|
|
* Enable Strategy ...
|
|
*/
|
|
void Enable()
|
|
{
|
|
mForceDisabled = false;
|
|
}
|
|
|
|
/**
|
|
* Register Signal Event Handler ...
|
|
*
|
|
* @param handler: an Instance of TOnXSignal ...
|
|
*/
|
|
void AddXSignalEventHandler(TOnX121SMCSignal handler)
|
|
{
|
|
//
|
|
Add(
|
|
handler,
|
|
mSignalEventHandlers //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Virtual Actions ...
|
|
|
|
//
|
|
// Check Conditions For Signal and Execute Signal ...
|
|
virtual void HandleTick()
|
|
{
|
|
//
|
|
// Check State ...
|
|
if (IsDisabled())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Check Signalling State ...
|
|
if (!AllowLong() && !AllowShort())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Check Bar Tracker State ...
|
|
if (!mBarTracker.CanProcessBar())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Retrieve Current Tick and Check it's Time
|
|
// by Last Issued Tick ...
|
|
MqlTick cTick;
|
|
bool hasTick = GetTick(
|
|
mSymbol,
|
|
cTick //
|
|
);
|
|
bool isSameAsLast = cTick.time == mLastTick.time;
|
|
if (isSameAsLast)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Update Last Issued Tick ...
|
|
mLastTick = cTick;
|
|
SaveTickData();
|
|
CleanupTicks();
|
|
|
|
//
|
|
// Update POIs ...
|
|
|
|
//
|
|
ENUM_XPOI_EVENTS _4HStates[];
|
|
m4HPOI.Update(_4HStates);
|
|
|
|
//
|
|
ENUM_XPOI_EVENTS _4HSupDemStates[];
|
|
m4HSupDemPOI.Update(_4HSupDemStates);
|
|
|
|
//
|
|
ENUM_XPOI_EVENTS _15MStates[];
|
|
m15MPOI.Update(_15MStates);
|
|
|
|
//
|
|
ENUM_XPOI_EVENTS _5MStates[];
|
|
m5MPOI.Update(_5MStates);
|
|
|
|
//
|
|
// Check Current Processing Tick has Signal or not ...
|
|
XSignal signal;
|
|
X121SMCStrategyConditions conditions;
|
|
bool hasSignal = HasSignal(
|
|
signal,
|
|
conditions //
|
|
);
|
|
if (!hasSignal)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Waits Until Next Candle if Current Tick has Signal ...
|
|
mBarTracker.Waits();
|
|
|
|
//
|
|
// Notify Signal Event Handlers ...
|
|
NotifyOnSignalEventHandlers(
|
|
signal,
|
|
conditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Check Conditions For Signal ...
|
|
virtual bool HasSignal(
|
|
XSignal &signal,
|
|
X121SMCStrategyConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
signal.Clean();
|
|
conditions.Clean();
|
|
|
|
//
|
|
double sl = 0;
|
|
double tp = 0;
|
|
double risk = 0;
|
|
double entry = 0;
|
|
double reward = 0;
|
|
double r2r = R2R();
|
|
double volume = Volume();
|
|
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
|
|
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
|
|
|
//
|
|
bool hasLong = false;
|
|
bool hasShort = false;
|
|
|
|
//
|
|
// Start Calculations ...
|
|
|
|
//
|
|
double points = GetPoints(mSymbol);
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
// Retrieve Bars ...
|
|
|
|
//
|
|
// Zero Bar ...
|
|
XOHCL zBar;
|
|
result = zBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
zIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Last Bar ...
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
cIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Prepare Conditions ...
|
|
|
|
//
|
|
conditions.symbol = mSymbol;
|
|
conditions.period = mPeriod;
|
|
conditions.time = cBar.time;
|
|
|
|
//
|
|
// Reading POI(s) ...
|
|
|
|
//
|
|
XPOIState _4HSupDemState;
|
|
m4HSupDemPOI.GetState(_4HSupDemState);
|
|
|
|
//
|
|
// 4H ...
|
|
XPOIState _4HState;
|
|
m4HPOI.GetState(_4HState);
|
|
|
|
//
|
|
// 15M ...
|
|
XPOIState _15MState;
|
|
m15MPOI.GetState(_15MState);
|
|
|
|
//
|
|
// 5M ...
|
|
XPOIState _5MState;
|
|
m5MPOI.GetState(_5MState);
|
|
|
|
//
|
|
// Try to Implement SMC Based Conditions ...
|
|
|
|
//
|
|
// 1- First Step is Find a Supply and Demand Zone ...
|
|
// - [] this Zone must be Fresh ...
|
|
// - [] contains Engulfing ...
|
|
// - [] has Order Block ...
|
|
// - [] has FVG ...
|
|
DetectImportantPOIs(
|
|
conditions,
|
|
_4HSupDemState,
|
|
_4HState,
|
|
_15MState,
|
|
_5MState //
|
|
);
|
|
if (conditions.supplyZone.IsValid() ||
|
|
conditions.bearishFVG.IsValid() ||
|
|
conditions.bearishOrderBlock.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
conditions,
|
|
mConditions //
|
|
);
|
|
}
|
|
else if (conditions.demandZone.IsValid() ||
|
|
conditions.bullishFVG.IsValid() ||
|
|
conditions.bullishOrderBlock.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
conditions,
|
|
mConditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
conditions.Clean();
|
|
|
|
//
|
|
// Check Conditions for Signal ...
|
|
int conditionsCount = ArraySize(mConditions);
|
|
if (!IsValidSize(conditionsCount))
|
|
{
|
|
//
|
|
result = false;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop through Conditions for Filter Based on POIs ...
|
|
int removeIDX = -1;
|
|
for (int i = 0; i < conditionsCount; i++)
|
|
{
|
|
//
|
|
X121SMCStrategyConditions iConditions = mConditions[i];
|
|
|
|
//
|
|
// LONG ...
|
|
|
|
//
|
|
bool isSoImportantLong =
|
|
conditions.demandZone.IsValid() &&
|
|
conditions.bullishFVG.IsValid() &&
|
|
conditions.bullishOrderBlock.IsValid();
|
|
|
|
//
|
|
bool isImportantLong =
|
|
conditions.demandZone.IsValid() &&
|
|
(conditions.bullishFVG.IsValid() ||
|
|
conditions.bullishOrderBlock.IsValid());
|
|
|
|
//
|
|
bool isRiskyLong =
|
|
conditions.demandZone.IsValid() &&
|
|
(conditions.bullishFVG.IsValid() ||
|
|
conditions.bullishOrderBlock.IsValid());
|
|
|
|
//
|
|
bool hasLongConditions = isSoImportantLong ||
|
|
isImportantLong ||
|
|
isRiskyLong;
|
|
|
|
//
|
|
if (hasLongConditions)
|
|
{
|
|
//
|
|
// Find Trigger for Input Positions ...
|
|
// - [] Breakout;
|
|
// - [] Engulf;
|
|
// - [] Rejection Bar;
|
|
// - [] Momentum Bar;
|
|
|
|
//
|
|
removeIDX = i;
|
|
DrawConditions(conditions);
|
|
Print("hasLongConditions");
|
|
// break;
|
|
}
|
|
|
|
//
|
|
// SHORT ...
|
|
|
|
//
|
|
bool isSoImportantShort =
|
|
conditions.supplyZone.IsValid() &&
|
|
conditions.bearishFVG.IsValid() &&
|
|
conditions.bearishOrderBlock.IsValid();
|
|
|
|
//
|
|
bool isImportantShort =
|
|
conditions.supplyZone.IsValid() &&
|
|
(conditions.bearishFVG.IsValid() ||
|
|
conditions.bearishOrderBlock.IsValid());
|
|
|
|
//
|
|
bool isRiskyShort =
|
|
conditions.supplyZone.IsValid() &&
|
|
(!conditions.bearishFVG.IsValid() &&
|
|
!conditions.bearishOrderBlock.IsValid());
|
|
|
|
//
|
|
bool hasShortConditions = isSoImportantShort ||
|
|
isImportantShort ||
|
|
isRiskyShort;
|
|
|
|
//
|
|
if (hasShortConditions)
|
|
{
|
|
//
|
|
// Find Trigger for Input Positions ...
|
|
// - [] Breakout;
|
|
// - [] Engulf;
|
|
// - [] Rejection Bar;
|
|
// - [] Momentum Bar;
|
|
|
|
//
|
|
removeIDX = i;
|
|
DrawConditions(conditions);
|
|
Print("hasShortConditions");
|
|
// break;
|
|
}
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
// Rmove Signal Condition ...
|
|
if (result &&
|
|
IsValidIndex(removeIDX))
|
|
{
|
|
//
|
|
ArrayRemove(
|
|
mConditions,
|
|
removeIDX,
|
|
1);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Overrides ...
|
|
|
|
//
|
|
// Customize Strategy Identifier ...
|
|
string GetTag() override
|
|
{
|
|
return X121SMCStrategyToken;
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
string mSymbol; // Trading Symbol ...
|
|
ENUM_TIMEFRAMES mPeriod; // Trading TimeFrame ...
|
|
bool mForceDisabled; // Force Disabled ...
|
|
bool mAllowLong; // Allow Long Signals
|
|
bool mAllowShort; // Allow Short Signals
|
|
double mR2R; // Risk/Rewar Ratio ...
|
|
double mVolume; // Static Volume Per Trades ...
|
|
|
|
//
|
|
MqlTick mLastTick; // Last Issued Tick ...
|
|
XTick mTicks[]; // Hold Ticks Data ...
|
|
|
|
/**
|
|
* Cleanup Ticks Size ...
|
|
*/
|
|
void CleanupTicks()
|
|
{
|
|
//
|
|
int maxRequiredTicks = 50;
|
|
int ticksCount = ArraySize(mTicks);
|
|
if (!IsValidSize(ticksCount) ||
|
|
ticksCount <= maxRequiredTicks)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int removeCount = ticksCount - maxRequiredTicks;
|
|
if (!IsValidSize(removeCount))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
ArrayRemove(
|
|
mTicks,
|
|
0,
|
|
removeCount //
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Add new Tick Data to Collection ...
|
|
*/
|
|
void SaveTickData()
|
|
{
|
|
//
|
|
datetime time = TimeCurrent();
|
|
double ask = GetAsk(mSymbol);
|
|
double bid = GetBid(mSymbol);
|
|
|
|
//
|
|
XTick tick;
|
|
bool isInited = tick.Init(
|
|
mSymbol,
|
|
time,
|
|
bid,
|
|
ask //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
tick,
|
|
mTicks //
|
|
);
|
|
}
|
|
|
|
//
|
|
XBarTracker mBarTracker; // Strategy Time Tracker ...
|
|
|
|
//
|
|
// Point Of Interests ...
|
|
XCPOI *m4HPOI;
|
|
XCPOI *m4HSupDemPOI;
|
|
XCPOI *m15MPOI;
|
|
XCPOI *m5MPOI;
|
|
|
|
//
|
|
// Collect all Drawn Objects ...
|
|
CArrayObj mDrawnObjects;
|
|
|
|
/**
|
|
* Remove Specified Drawn Object ...
|
|
*
|
|
* @param name: Object name ...
|
|
*/
|
|
void RemoveObject(string name)
|
|
{
|
|
//
|
|
if (!IsValid(name))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int count = mDrawnObjects.Total();
|
|
if (!IsValidSize(count))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int idx = -1;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
string iName = ((CChartObject *)mDrawnObjects.At(i)).Name();
|
|
string iObjName = ((XCBaseObject *)mDrawnObjects.At(i)).ObjName();
|
|
|
|
//
|
|
if ((IsValid(iName) &&
|
|
iName == name) ||
|
|
(IsValid(iObjName) &&
|
|
iObjName == name))
|
|
{
|
|
//
|
|
idx = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (IsValidIndex(idx))
|
|
{
|
|
mDrawnObjects.Delete(idx);
|
|
}
|
|
}
|
|
|
|
//
|
|
XOHCL mSwingHigh;
|
|
CChartObjectHLine *mSwingHighObject;
|
|
|
|
//
|
|
XOHCL mSwingLow;
|
|
CChartObjectHLine *mSwingLowObject;
|
|
|
|
//
|
|
// Holding Supply and Demand Zones ...
|
|
// XZone mSupplyZones[];
|
|
// XZone mDemandZones[];
|
|
|
|
//
|
|
// XZone mBearishOrderBlocks[];
|
|
// XZone mBullishOrderBlocks[];
|
|
|
|
//
|
|
// XZone mBearishFVGs[];
|
|
// XZone mBullishFVGs[];
|
|
|
|
//
|
|
X121SMCStrategyConditions mConditions[];
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Install all Helpers and Prepare all Configurations for required Indicators ...
|
|
*/
|
|
void Init()
|
|
{
|
|
//
|
|
mForceDisabled = false;
|
|
|
|
//
|
|
string symbol = Symbol();
|
|
ENUM_TIMEFRAMES period = Period();
|
|
|
|
//
|
|
// Initialize Bar Tracker ...
|
|
mBarTracker.Init(
|
|
symbol,
|
|
period //
|
|
);
|
|
|
|
//
|
|
// Initialize POIs ...
|
|
|
|
//
|
|
// this used only for Supply and
|
|
// Demand Zone for H4 Time Frame ..,
|
|
// POI Detector ...
|
|
m4HSupDemPOI = new XCPOI(
|
|
symbol,
|
|
PERIOD_M15 //
|
|
);
|
|
m4HSupDemPOI.Window(0);
|
|
m4HSupDemPOI.DisablePOIs();
|
|
m4HSupDemPOI.DisableDrawPOIs();
|
|
m4HSupDemPOI.ChartID(ChartID());
|
|
m4HSupDemPOI.AllowSupplyZones(true);
|
|
m4HSupDemPOI.AllowDemandZones(true);
|
|
m4HSupDemPOI.SupplyZonePeriod(PERIOD_H4);
|
|
m4HSupDemPOI.DemandZonePeriod(PERIOD_H4);
|
|
|
|
//
|
|
m4HSupDemPOI.Init();
|
|
|
|
//
|
|
// 4H Period ...
|
|
// POI Detector ...
|
|
m4HPOI = new XCPOI(
|
|
symbol,
|
|
PERIOD_H4 //
|
|
);
|
|
|
|
//
|
|
m4HPOI.Window(0);
|
|
m4HPOI.DisableDrawPOIs();
|
|
m4HPOI.ChartID(ChartID());
|
|
m4HPOI.SupplyZonePeriod(PERIOD_H4);
|
|
m4HPOI.DemandZonePeriod(PERIOD_H4);
|
|
|
|
//
|
|
m4HPOI.Init();
|
|
|
|
//
|
|
// 15M Period ...
|
|
// POI Detector ...
|
|
m15MPOI = new XCPOI(
|
|
symbol,
|
|
PERIOD_M15 //
|
|
);
|
|
|
|
//
|
|
m15MPOI.Window(0);
|
|
m15MPOI.DisableDrawPOIs();
|
|
m15MPOI.ChartID(ChartID());
|
|
m15MPOI.MaxNumberOfRequiredPOIs(2);
|
|
m15MPOI.SupplyZonePeriod(PERIOD_M15);
|
|
m15MPOI.DemandZonePeriod(PERIOD_M15);
|
|
|
|
//
|
|
m15MPOI.Init();
|
|
|
|
//
|
|
// Trigger Period ...
|
|
// POI Detector ...
|
|
m5MPOI = new XCPOI(
|
|
symbol,
|
|
PERIOD_M5 //
|
|
);
|
|
|
|
//
|
|
m5MPOI.Window(0);
|
|
m5MPOI.DisableDrawPOIs();
|
|
m5MPOI.ChartID(ChartID());
|
|
m5MPOI.MaxNumberOfRequiredPOIs(2);
|
|
m5MPOI.SupplyZonePeriod(PERIOD_M5);
|
|
m5MPOI.DemandZonePeriod(PERIOD_M5);
|
|
|
|
//
|
|
m5MPOI.Init();
|
|
|
|
//
|
|
}
|
|
|
|
/**
|
|
* De Initialize all Tools ...
|
|
*/
|
|
void DeInit()
|
|
{
|
|
//
|
|
delete m4HPOI;
|
|
delete m5MPOI;
|
|
delete m15MPOI;
|
|
// delete m4HSupDemPOI;
|
|
}
|
|
|
|
/**
|
|
* Reste Bar Tracker ...
|
|
*/
|
|
void ResetBarTracker()
|
|
{
|
|
mBarTracker.Clean();
|
|
}
|
|
|
|
/**
|
|
* Prepare and Normalize Signal for Execution in Strategy ...
|
|
*
|
|
* @param signal: XSignal instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool PrepareSignal(XSignal &signal)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Check Strategy Is Enables ...
|
|
result = !IsDisabled();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Validate Signal ...
|
|
result = signal.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isLong = IsLong(signal.type);
|
|
|
|
//
|
|
// TODO: Implement Signal Preparation Mechanism here ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Update Supply and Demand Zones ...
|
|
*
|
|
* @param state: Argument 1
|
|
*/
|
|
void DetectImportantPOIs(
|
|
X121SMCStrategyConditions &conditions,
|
|
XPOIState &supplyAndDemandZoneState,
|
|
XPOIState &orderBlocksState,
|
|
XPOIState &fvgsState,
|
|
XPOIState &triggerState //
|
|
)
|
|
{
|
|
//
|
|
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;
|
|
}
|
|
|
|
//
|
|
XOHCL zBar;
|
|
bool isInited = zBar.Init(
|
|
Symbol(),
|
|
Period(),
|
|
0 //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
}
|
|
DrawSwingHigh(tmpBar);
|
|
|
|
//
|
|
// Swing Low ...
|
|
tmpBar.Clean();
|
|
for (int i = 0; i < swingLowsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iSwing = swingLows[i];
|
|
|
|
//
|
|
if (!tmpBar.IsValid() ||
|
|
tmpBar.low > iSwing.low)
|
|
{
|
|
tmpBar = iSwing;
|
|
}
|
|
}
|
|
DrawSwingLow(tmpBar);
|
|
tmpBar.Clean();
|
|
|
|
//
|
|
// Supply Zone ...
|
|
for (int i = 0; i < supplyZonesCount; i++)
|
|
{
|
|
//
|
|
XZone iSupplyZone = supplyAndDemandZoneState.supplyZones[i];
|
|
conditions.supplyZone = iSupplyZone;
|
|
|
|
//
|
|
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);
|
|
// }
|
|
}
|
|
|
|
//
|
|
// Demand Zone ...
|
|
for (int i = 0; i < demandZonesCount; i++)
|
|
{
|
|
//
|
|
XZone iDemandZone = supplyAndDemandZoneState.demandZones[i];
|
|
conditions.demandZone = iDemandZone;
|
|
|
|
//
|
|
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);
|
|
// }
|
|
}
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
// On X121 Signal Recieved Event Handler(s) ...
|
|
TOnX121SMCSignal mSignalEventHandlers[];
|
|
|
|
//
|
|
/**
|
|
* Notified Signal Event Handler(s) ...
|
|
*
|
|
* @param signal: XSignal instance ...
|
|
* @param conditions: XStrategyConditions instance ...
|
|
*/
|
|
void NotifyOnSignalEventHandlers(
|
|
XSignal &signal,
|
|
X121SMCStrategyConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
if (!signal.IsValid() || !conditions.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mSignalEventHandlers);
|
|
if (!IsValidSize(count))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
mSignalEventHandlers[i](
|
|
signal,
|
|
conditions //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//
|
|
// Draw Functions ...
|
|
|
|
/**
|
|
* Draw Specific Swing High ...
|
|
*
|
|
* @param swing: XOHCL instance which represents Swing Point ...
|
|
*/
|
|
void DrawSwingHigh(XOHCL &swing)
|
|
{
|
|
//
|
|
if (!swing.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
string name = swing.GetTag(ToString(X_POI_SWING_HIGH));
|
|
|
|
//
|
|
if (mSwingHigh.IsValid())
|
|
{
|
|
//
|
|
mSwingHigh.Clean();
|
|
mSwingHighObject.Delete();
|
|
}
|
|
|
|
//
|
|
mSwingHigh = swing;
|
|
mSwingHighObject = new CChartObjectHLine();
|
|
bool isCreated = mSwingHighObject.Create(
|
|
ChartID(),
|
|
name,
|
|
0,
|
|
swing.high //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
mSwingHighObject.Width(1);
|
|
mSwingHighObject.Color(clrBrown);
|
|
mSwingHighObject.Style(STYLE_SOLID);
|
|
}
|
|
|
|
/**
|
|
* Draw Specific Swing Low ...
|
|
*
|
|
* @param swing: XOHCL instance which represents Swing Point ...
|
|
*/
|
|
void DrawSwingLow(XOHCL &swing)
|
|
{
|
|
//
|
|
if (!swing.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
string name = swing.GetTag(ToString(X_POI_SWING_LOW));
|
|
|
|
//
|
|
if (mSwingLow.IsValid())
|
|
{
|
|
//
|
|
mSwingLow.Clean();
|
|
mSwingLowObject.Delete();
|
|
}
|
|
|
|
//
|
|
mSwingLow = swing;
|
|
mSwingLowObject = new CChartObjectHLine();
|
|
|
|
//
|
|
bool isCreated = mSwingLowObject.Create(
|
|
ChartID(),
|
|
name,
|
|
0,
|
|
swing.low //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
mSwingLowObject.Width(1);
|
|
mSwingLowObject.Color(clrGreen);
|
|
mSwingLowObject.Style(STYLE_SOLID);
|
|
}
|
|
|
|
/**
|
|
* Draw Supply Zone ...
|
|
*
|
|
* @param zone: XZone instance ...
|
|
*/
|
|
void DrawSupplyZone(XZone &zone)
|
|
{
|
|
//
|
|
if (!zone.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
string name = zone.GetTag();
|
|
RemoveObject(name);
|
|
// int idx = FindIndex(zone, mSupplyZones);
|
|
// if (IsValidIndex(idx))
|
|
// {
|
|
// // //
|
|
// // ArrayRemove(
|
|
// // mSupplyZones,
|
|
// // idx,
|
|
// // 1 //
|
|
// // );
|
|
|
|
// //
|
|
// }
|
|
|
|
//
|
|
zone.to = TimeCurrent();
|
|
name = zone.GetTag();
|
|
// AddRef(
|
|
// zone,
|
|
// mSupplyZones //
|
|
// );
|
|
|
|
//
|
|
XCSupplyZoneObject *iObj;
|
|
iObj = new XCSupplyZoneObject();
|
|
bool isCreated = iObj.CreateByZone(
|
|
ChartID(),
|
|
name,
|
|
0,
|
|
zone,
|
|
NULL,
|
|
true //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
iObj.ZoneWidth(1);
|
|
iObj.ZoneStyle(STYLE_DOT);
|
|
iObj.ZoneColor(clrMagenta);
|
|
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
|
|
/**
|
|
* Draw Demand Zone ...
|
|
*
|
|
* @param zone: XZone instance ...
|
|
*/
|
|
void DrawDemandZone(XZone &zone)
|
|
{
|
|
//
|
|
if (!zone.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
string name = zone.GetTag();
|
|
RemoveObject(name);
|
|
// int idx = FindIndex(zone, mDemandZones);
|
|
// if (IsValidIndex(idx))
|
|
// {
|
|
// // //
|
|
// // ArrayRemove(
|
|
// // mDemandZones,
|
|
// // idx,
|
|
// // 1 //
|
|
// // );
|
|
|
|
// //
|
|
// }
|
|
|
|
//
|
|
zone.to = TimeCurrent();
|
|
name = zone.GetTag();
|
|
// AddRef(
|
|
// zone,
|
|
// mDemandZones //
|
|
// );
|
|
|
|
//
|
|
XCDemandZoneObject *iObj;
|
|
iObj = new XCDemandZoneObject();
|
|
bool isCreated = iObj.CreateByZone(
|
|
ChartID(),
|
|
name,
|
|
0,
|
|
zone,
|
|
NULL,
|
|
true //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
iObj.ZoneWidth(1);
|
|
iObj.ZoneStyle(STYLE_DOT);
|
|
iObj.ZoneColor(clrAqua);
|
|
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
|
|
/**
|
|
* Draw Specific Bearish Order Block ...
|
|
*
|
|
* @param zone: XZone instance ...
|
|
*/
|
|
void DrawBearishOrderBlock(XZone &zone)
|
|
{
|
|
//
|
|
if (!zone.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
string name = zone.GetTag();
|
|
RemoveObject(name);
|
|
// int idx = FindIndex(zone, mBearishOrderBlocks);
|
|
// if (IsValidIndex(idx))
|
|
// {
|
|
// // //
|
|
// // ArrayRemove(
|
|
// // mBearishOrderBlocks,
|
|
// // idx,
|
|
// // 1 //
|
|
// // );
|
|
|
|
// //
|
|
// }
|
|
|
|
//
|
|
zone.to = TimeCurrent();
|
|
name = zone.GetTag();
|
|
// AddRef(
|
|
// zone,
|
|
// mBearishOrderBlocks //
|
|
// );
|
|
|
|
//
|
|
XCBearishOrderBlockObject *iObj;
|
|
iObj = new XCBearishOrderBlockObject();
|
|
bool isCreated = iObj.CreateByZone(
|
|
ChartID(),
|
|
name,
|
|
0,
|
|
zone,
|
|
NULL,
|
|
true //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
iObj.ZoneWidth(1);
|
|
iObj.ZoneColor(clrRed);
|
|
iObj.ZoneStyle(STYLE_DASH);
|
|
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
|
|
/**
|
|
* Draw Specific Bullish Order Block ...
|
|
*
|
|
* @param zone: XZone instance ...
|
|
*/
|
|
void DrawBullishOrderBlock(XZone &zone)
|
|
{
|
|
//
|
|
if (!zone.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
string name = zone.GetTag();
|
|
RemoveObject(name);
|
|
// int idx = FindIndex(zone, mBullishOrderBlocks);
|
|
// if (IsValidIndex(idx))
|
|
// {
|
|
// // //
|
|
// // ArrayRemove(
|
|
// // mBullishOrderBlocks,
|
|
// // idx,
|
|
// // 1 //
|
|
// // );
|
|
|
|
// //
|
|
// }
|
|
|
|
//
|
|
zone.to = TimeCurrent();
|
|
name = zone.GetTag();
|
|
// AddRef(
|
|
// zone,
|
|
// mBullishOrderBlocks //
|
|
// );
|
|
|
|
//
|
|
XCBullishOrderBlockObject *iObj;
|
|
iObj = new XCBullishOrderBlockObject();
|
|
bool isCreated = iObj.CreateByZone(
|
|
ChartID(),
|
|
name,
|
|
0,
|
|
zone,
|
|
NULL,
|
|
true //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
iObj.ZoneWidth(1);
|
|
iObj.ZoneColor(clrLime);
|
|
iObj.ZoneStyle(STYLE_DASH);
|
|
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
|
|
/**
|
|
* Draw Specific Bearish FVG ...
|
|
*
|
|
* @param zone: XZone instance ...
|
|
*/
|
|
void DrawBearishFVG(XZone &zone)
|
|
{
|
|
//
|
|
if (!zone.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
string name = zone.GetTag();
|
|
RemoveObject(name);
|
|
// int idx = FindIndex(zone, mBearishFVGs);
|
|
// if (IsValidIndex(idx))
|
|
// {
|
|
// //
|
|
// // ArrayRemove(
|
|
// // mBearishFVGs,
|
|
// // idx,
|
|
// // 1 //
|
|
// // );
|
|
|
|
// //
|
|
// }
|
|
|
|
//
|
|
zone.to = TimeCurrent();
|
|
name = zone.GetTag();
|
|
// AddRef(
|
|
// zone,
|
|
// mBearishFVGs //
|
|
// );
|
|
|
|
//
|
|
XCBearishFVGObject *iObj;
|
|
iObj = new XCBearishFVGObject();
|
|
bool isCreated = iObj.CreateByZone(
|
|
ChartID(),
|
|
name,
|
|
0,
|
|
zone,
|
|
NULL,
|
|
true //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
iObj.ZoneWidth(1);
|
|
iObj.ZoneColor(clrOrange);
|
|
iObj.ZoneStyle(STYLE_DASHDOT);
|
|
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
|
|
/**
|
|
* Draw Specific Bullish FVG ...
|
|
*
|
|
* @param zone: XZone instance ...
|
|
*/
|
|
void DrawBullishFVG(XZone &zone)
|
|
{
|
|
//
|
|
if (!zone.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
string name = zone.GetTag();
|
|
RemoveObject(name);
|
|
// int idx = FindIndex(zone, mBullishFVGs);
|
|
// if (IsValidIndex(idx))
|
|
// {
|
|
// // //
|
|
// // ArrayRemove(
|
|
// // mBullishFVGs,
|
|
// // idx,
|
|
// // 1 //
|
|
// // );
|
|
|
|
// //
|
|
// }
|
|
|
|
//
|
|
zone.to = TimeCurrent();
|
|
name = zone.GetTag();
|
|
// AddRef(
|
|
// zone,
|
|
// mBullishFVGs //
|
|
// );
|
|
|
|
//
|
|
XCBullishFVGObject *iObj;
|
|
iObj = new XCBullishFVGObject();
|
|
bool isCreated = iObj.CreateByZone(
|
|
ChartID(),
|
|
name,
|
|
0,
|
|
zone,
|
|
NULL,
|
|
true //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
iObj.ZoneWidth(1);
|
|
iObj.ZoneColor(clrSteelBlue);
|
|
iObj.ZoneStyle(STYLE_DASHDOT);
|
|
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
|
|
/**
|
|
* Draw Specific Condition ...
|
|
*
|
|
* @param conditions: Argument 1
|
|
*/
|
|
void DrawConditions(X121SMCStrategyConditions &conditions)
|
|
{
|
|
//
|
|
if (conditions.supplyZone.IsValid())
|
|
{
|
|
DrawSupplyZone(conditions.supplyZone);
|
|
}
|
|
|
|
//
|
|
if (conditions.bearishOrderBlock.IsValid())
|
|
{
|
|
DrawBearishOrderBlock(conditions.bearishOrderBlock);
|
|
}
|
|
|
|
//
|
|
if (conditions.bearishFVG.IsValid())
|
|
{
|
|
DrawBearishFVG(conditions.bearishFVG);
|
|
}
|
|
|
|
//
|
|
if (conditions.demandZone.IsValid())
|
|
{
|
|
DrawDemandZone(conditions.demandZone);
|
|
}
|
|
|
|
//
|
|
if (conditions.bullishOrderBlock.IsValid())
|
|
{
|
|
DrawBullishOrderBlock(conditions.bullishOrderBlock);
|
|
}
|
|
|
|
//
|
|
if (conditions.bullishFVG.IsValid())
|
|
{
|
|
DrawBullishFVG(conditions.bullishFVG);
|
|
}
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
// |