1827 lines
36 KiB
Plaintext
1827 lines
36 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// --------------------------------------
|
|
// Name: XPOI
|
|
// Description: Provides Point of Interests ...
|
|
// - Swing Highs;
|
|
// - Swing Lows;
|
|
//
|
|
// 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.xalert.class.mq5"
|
|
#include <Arrays/ArrayObj.mqh>
|
|
#include <ChartObjects/ChartObject.mqh>
|
|
#include <ChartObjects/ChartObjectsArrows.mqh>
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// All Available POI(s) ...
|
|
enum ENUM_XPOIS
|
|
{
|
|
//
|
|
// Momentum Bar ...
|
|
X_POI_MOMENTUM_BAR, // Momentum Bar ...
|
|
//
|
|
// Rejection Bar ...
|
|
X_POI_REJECTION_BAR, // Rejection Bar ...
|
|
//
|
|
// Swings ...
|
|
X_POI_SWING_HIGH, // Simple Swing High ...
|
|
X_POI_SWING_LOW, // Simple Swing Low ...
|
|
//
|
|
// Support nad Resistance ...
|
|
X_POI_SUPPORT, // Support Zone ...
|
|
X_POI_RESISTANCE, // Resistance Zone ...
|
|
};
|
|
|
|
//
|
|
// Event Types ...
|
|
enum ENUM_XPOI_EVENTS
|
|
{
|
|
//
|
|
// Momentum Bar ...
|
|
X_MOMENTUM_BAR_DETECTED, // Momentum Bar ...
|
|
//
|
|
// Rejection Bar ...
|
|
X_REJECTION_BAR_DETECTED, // Rejection Bar ...
|
|
//
|
|
// Swings ...
|
|
X_SWING_HIGH_DETECTED,
|
|
X_SWING_LOW_DETECTED,
|
|
//
|
|
// Support nad Resistance ...
|
|
X_SUPPORT_DETECTED,
|
|
X_RESISTANCE_DETECTED,
|
|
};
|
|
|
|
//
|
|
// XOHCL Event Handler ...
|
|
typedef void (*TXOHCLEventHandler)(
|
|
XOHCL &bar //
|
|
);
|
|
|
|
//
|
|
// Extensions ...
|
|
|
|
/**
|
|
* Converts ENUM_XPOI value to String Representation ...
|
|
*
|
|
* @param value: ENUM_XPOI member ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string ToString(ENUM_XPOIS value)
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
switch (value)
|
|
{
|
|
//
|
|
case X_POI_MOMENTUM_BAR:
|
|
result = "XMNTMB";
|
|
break;
|
|
|
|
//
|
|
case X_POI_REJECTION_BAR:
|
|
result = "XRJCTB";
|
|
break;
|
|
|
|
//
|
|
case X_POI_SWING_HIGH:
|
|
result = "XSPH";
|
|
break;
|
|
|
|
//
|
|
case X_POI_SWING_LOW:
|
|
result = "XSPL";
|
|
break;
|
|
|
|
//
|
|
case X_POI_SUPPORT:
|
|
result = "XSUP";
|
|
break;
|
|
|
|
//
|
|
case X_POI_RESISTANCE:
|
|
result = "XRES";
|
|
break;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Implementation ...
|
|
|
|
//
|
|
class XCPOI : public XSCBaseAlert
|
|
{
|
|
//
|
|
public:
|
|
//
|
|
|
|
//
|
|
// Constructors ...
|
|
/**
|
|
* Create an Instance ...
|
|
*
|
|
* @param symbol: String ...
|
|
* @param period: ENUM_TIMEFRAMES member ...
|
|
*/
|
|
void XCPOI(
|
|
string symbol,
|
|
ENUM_TIMEFRAMES period //
|
|
)
|
|
{
|
|
//
|
|
// Attach Required Properties ...
|
|
mSymbol = symbol;
|
|
mPeriod = period;
|
|
|
|
//
|
|
// Initialize Bar Tracker ...
|
|
mBarTracker.Init(
|
|
mSymbol,
|
|
mPeriod //
|
|
);
|
|
|
|
//
|
|
// Apply Default Configurations ...
|
|
ApplyDefaultConfig();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
void ~XCPOI()
|
|
{
|
|
//
|
|
DestroyPOIs();
|
|
DestroyObjects();
|
|
}
|
|
|
|
//
|
|
// Getter(s) / Setter(s) ...
|
|
|
|
/**
|
|
* Get Chart ID ...
|
|
*
|
|
* @return ( long )
|
|
*/
|
|
long ChartID()
|
|
{
|
|
return mChartID;
|
|
}
|
|
|
|
/**
|
|
* Set Chart ID ...
|
|
*
|
|
* @param value: Long
|
|
*/
|
|
void ChartID(long value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mChartID = value;
|
|
}
|
|
|
|
/**
|
|
* Get Sub Window Number ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int Window()
|
|
{
|
|
return mWindow;
|
|
}
|
|
|
|
/**
|
|
* Get Sub Window Number ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void Window(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mWindow = value;
|
|
}
|
|
|
|
/**
|
|
* Get Max Number of POIs which holds ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int MaxNumberOfPOIs()
|
|
{
|
|
return mMaxNumberOfPOIs;
|
|
}
|
|
|
|
/**
|
|
* Set Max Number of POIs which holds ...
|
|
* 0 => Infinity ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void MaxNumberOfPOIs(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mMaxNumberOfPOIs = value;
|
|
}
|
|
|
|
/**
|
|
* Get Number of POI(s) which must Find at Initializations ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int MaxNumberOfRequiredPOIs()
|
|
{
|
|
return mMaxNumberOfRequiredPOIs;
|
|
}
|
|
|
|
/**
|
|
* Set Number of POI(s) which must Find at Initializations ...
|
|
* 2 is Default ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void MaxNumberOfRequiredPOIs(int value)
|
|
{
|
|
//
|
|
if (value < 2)
|
|
{
|
|
value = 2;
|
|
}
|
|
|
|
//
|
|
mMaxNumberOfRequiredPOIs = value;
|
|
}
|
|
|
|
/**
|
|
* Check Is Locked or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLocked()
|
|
{
|
|
return mLock;
|
|
}
|
|
|
|
//
|
|
// POI(s) Configs ...
|
|
|
|
//
|
|
// Swing High ...
|
|
|
|
/**
|
|
* Get Draw Swing Highs State ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AllowDrawSwingHighs()
|
|
{
|
|
return mAllowDrawSwingHighs;
|
|
}
|
|
|
|
/**
|
|
* Set Draw Swing Highs State ...
|
|
*
|
|
* @param value: Boolean
|
|
*/
|
|
void AllowDrawSwingHighs(bool value)
|
|
{
|
|
mAllowDrawSwingHighs = value;
|
|
}
|
|
|
|
/**
|
|
* Get Threshold Required for Swing High Detection ...
|
|
*
|
|
* @return ( double )
|
|
*/
|
|
double SwingHighThreshold()
|
|
{
|
|
return mSwingHighThreshold;
|
|
}
|
|
|
|
/**
|
|
* Set Threshold Required for Swing High Detection ...
|
|
*
|
|
* @param value: Double ...
|
|
*/
|
|
void SwingHighThreshold(double value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mSwingHighThreshold = value;
|
|
}
|
|
|
|
/**
|
|
* Get Swing High Arrow Code ...
|
|
*
|
|
* @return ( char )
|
|
*/
|
|
char SwingHighArrowCode()
|
|
{
|
|
return mSwingHighArrowCode;
|
|
}
|
|
|
|
/**
|
|
* Set Swing High Arrow Code ...
|
|
*
|
|
* @param value: Char ...
|
|
*/
|
|
void SwingHighArrowCode(char value)
|
|
{
|
|
mSwingHighArrowCode = value;
|
|
}
|
|
|
|
/**
|
|
* Get Swing High Color ...
|
|
*
|
|
* @return ( color )
|
|
*/
|
|
color SwingHighColor()
|
|
{
|
|
return mSwingHighColor;
|
|
}
|
|
|
|
/**
|
|
* Get Swing High Color ...
|
|
*
|
|
* @param value: Color
|
|
*/
|
|
void SwingHighColor(color value)
|
|
{
|
|
mSwingHighColor = value;
|
|
}
|
|
|
|
/**
|
|
* Get Swing High Width ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int SwingHighWidth()
|
|
{
|
|
return mSwingHighWidth;
|
|
}
|
|
|
|
/**
|
|
* Set Swing High Width ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void SwingHighWidth(int value)
|
|
{
|
|
//
|
|
if (value < 1)
|
|
{
|
|
value = 1;
|
|
}
|
|
|
|
//
|
|
mSwingHighWidth = value;
|
|
}
|
|
|
|
//
|
|
// Swing Low ...
|
|
|
|
/**
|
|
* Get Draw Swing Lows State ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AllowDrawSwingLows()
|
|
{
|
|
return mAllowDrawSwingLows;
|
|
}
|
|
|
|
/**
|
|
* Set Draw Swing Lows State ...
|
|
*
|
|
* @param value: Boolean
|
|
*/
|
|
void AllowDrawSwingLows(bool value)
|
|
{
|
|
mAllowDrawSwingLows = value;
|
|
}
|
|
|
|
/**
|
|
* Get Threshold Required for Swing Low Detection ...
|
|
*
|
|
* @return ( double )
|
|
*/
|
|
double SwingLowThreshold()
|
|
{
|
|
return mSwingLowThreshold;
|
|
}
|
|
|
|
/**
|
|
* Set Threshold Required for Swing Low Detection ...
|
|
*
|
|
* @param value: Double ...
|
|
*/
|
|
void SwingLowThreshold(double value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mSwingLowThreshold = value;
|
|
}
|
|
|
|
/**
|
|
* Get Swing Low Arrow Code ...
|
|
*
|
|
* @return ( char )
|
|
*/
|
|
char SwingLowArrowCode()
|
|
{
|
|
return mSwingLowArrowCode;
|
|
}
|
|
|
|
/**
|
|
* Set Swing Low Arrow Code ...
|
|
*
|
|
* @param value: Char ...
|
|
*/
|
|
void SwingLowArrowCode(char value)
|
|
{
|
|
mSwingLowArrowCode = value;
|
|
}
|
|
|
|
/**
|
|
* Get Swing Low Color ...
|
|
*
|
|
* @return ( color )
|
|
*/
|
|
color SwingLowColor()
|
|
{
|
|
return mSwingLowColor;
|
|
}
|
|
|
|
/**
|
|
* Get Swing Low Color ...
|
|
*
|
|
* @param value: Color
|
|
*/
|
|
void SwingLowColor(color value)
|
|
{
|
|
mSwingLowColor = value;
|
|
}
|
|
|
|
/**
|
|
* Get Swing Low Width ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int SwingLowWidth()
|
|
{
|
|
return mSwingLowWidth;
|
|
}
|
|
|
|
/**
|
|
* Set Swing Low Width ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void SwingLowWidth(int value)
|
|
{
|
|
//
|
|
if (value < 1)
|
|
{
|
|
value = 1;
|
|
}
|
|
|
|
//
|
|
mSwingLowWidth = value;
|
|
}
|
|
|
|
//
|
|
// Momentum Bars ...
|
|
|
|
/**
|
|
* Get Draw Momentum Bars State ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AllowDrawMomentumBars()
|
|
{
|
|
return mAllowDrawMomentumBars;
|
|
}
|
|
|
|
/**
|
|
* Set Draw Momentum Bars State ...
|
|
*
|
|
* @param value: Boolean
|
|
*/
|
|
void AllowDrawMomentumBars(bool value)
|
|
{
|
|
mAllowDrawMomentumBars = value;
|
|
}
|
|
|
|
/**
|
|
* Get Momentum Bar Percent ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int MomentumBarPercent()
|
|
{
|
|
return mMomentumBarPercent;
|
|
}
|
|
|
|
/**
|
|
* Set Momentum Bar Percent ...
|
|
*
|
|
* @param value: Integer
|
|
*/
|
|
void MomentumBarPercent(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mMomentumBarPercent = value;
|
|
}
|
|
|
|
/**
|
|
* Get Momentum Bar Sharp Ratio ...
|
|
*
|
|
* @return ( double )
|
|
*/
|
|
double MomentumBarSharpRatio()
|
|
{
|
|
return mMomentumBarSharpRatio;
|
|
}
|
|
|
|
/**
|
|
* Set Momentum Bar Sharp Ratio ...
|
|
*
|
|
* @param value: Double ...
|
|
*/
|
|
void MomentumBarSharpRatio(double value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mMomentumBarSharpRatio = value;
|
|
}
|
|
|
|
/**
|
|
* Get Momentum Bar Loopback ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int MomentumBarLoopBack()
|
|
{
|
|
return mMomentumBarLoopBack;
|
|
}
|
|
|
|
/**
|
|
* Set Momentum Bar Loopback ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void MomentumBarLoopBack(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mMomentumBarLoopBack = value;
|
|
}
|
|
|
|
/**
|
|
* Get Momentum Bar Width ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int MomentumBarWidth()
|
|
{
|
|
return mMomentumBarWidth;
|
|
}
|
|
|
|
/**
|
|
* Set Momentum Bar Width ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void MomentumBarWidth(int value)
|
|
{
|
|
mMomentumBarWidth = value;
|
|
}
|
|
|
|
/**
|
|
* Get Bullish Momentum Bar Arrow Code ...
|
|
*
|
|
* @return ( char )
|
|
*/
|
|
char MomentumBarBullishArrowCode()
|
|
{
|
|
return mMomentumBarBullishArrowCode;
|
|
}
|
|
|
|
/**
|
|
* Set Bullish Momentum Bar Arrow Code ...
|
|
*
|
|
* @param value: Char ...
|
|
*/
|
|
void MomentumBarBullishArrowCode(char value)
|
|
{
|
|
mMomentumBarBullishArrowCode = value;
|
|
}
|
|
|
|
/**
|
|
* Get Bullish Momentum Bar Color ...
|
|
*
|
|
* @return ( char )
|
|
*/
|
|
char MomentumBarBearishArrowCode()
|
|
{
|
|
return mMomentumBarBearishArrowCode;
|
|
}
|
|
|
|
/**
|
|
* Set Bullish Momentum Bar Color ...
|
|
*
|
|
* @param value: Color ...
|
|
*/
|
|
void MomentumBarBearishArrowCode(char value)
|
|
{
|
|
mMomentumBarBearishArrowCode = value;
|
|
}
|
|
|
|
/**
|
|
* Get Bearish Momentum Bar Arrow Code ...
|
|
*
|
|
* @return ( color )
|
|
*/
|
|
color MomentumBarBullishColor()
|
|
{
|
|
return mMomentumBarBullishColor;
|
|
}
|
|
|
|
/**
|
|
* Set Bearish Momentum Bar Arrow Code ...
|
|
*
|
|
* @param value: Color ...
|
|
*/
|
|
void MomentumBarBullishColor(color value)
|
|
{
|
|
mMomentumBarBullishColor = value;
|
|
}
|
|
|
|
/**
|
|
* Get Bearish Momentum Bar Color ...
|
|
*
|
|
* @return ( color )
|
|
*/
|
|
color MomentumBarBearishColor()
|
|
{
|
|
return mMomentumBarBearishColor;
|
|
}
|
|
|
|
/**
|
|
* Set Bearish Momentum Bar Color ...
|
|
*
|
|
* @param value: Color ...
|
|
*/
|
|
void MomentumBarBearishColor(color value)
|
|
{
|
|
mMomentumBarBearishColor = value;
|
|
}
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Initialize POI Detector ...
|
|
*/
|
|
void Init()
|
|
{
|
|
//
|
|
// Detect Previous POI(s) ...
|
|
DetectRequiredPOIs();
|
|
}
|
|
|
|
/**
|
|
* Update POI(s) ...
|
|
*
|
|
* @param state: an Array Refrence of ENUM_XPOI_EVENTS members ...
|
|
*/
|
|
int Update(
|
|
ENUM_XPOI_EVENTS &state[] //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
Clean(state);
|
|
|
|
//
|
|
// Check Bar Tracker if Waits ...
|
|
if (!mBarTracker.IsNewBar())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int cIndex = 1;
|
|
int pIndex = cIndex + 1;
|
|
|
|
//
|
|
XOHCL cBar;
|
|
bool isInited = cBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
cIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL pBar;
|
|
isInited = pBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
pIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Swing High ...
|
|
int swingHighsCount = ArraySize(mSwingHighs);
|
|
bool isSingHigh = pBar.IsSimpleSwingHigh(SwingHighThreshold());
|
|
if (isSingHigh)
|
|
{
|
|
//
|
|
AddRef(
|
|
pBar,
|
|
mSwingHighs //
|
|
);
|
|
swingHighsCount = ArraySize(mSwingHighs);
|
|
|
|
//
|
|
DrawSwingHighs();
|
|
|
|
//
|
|
Add(
|
|
X_SWING_HIGH_DETECTED,
|
|
state //
|
|
);
|
|
OnSwingHighDetected(pBar);
|
|
NotifySwingHighEventListeners(pBar);
|
|
}
|
|
|
|
//
|
|
// Detect Swing Low ...
|
|
int swingLowsCount = ArraySize(mSwingLows);
|
|
bool isSingLow = pBar.IsSimpleSwingLow(SwingLowThreshold());
|
|
if (isSingLow)
|
|
{
|
|
//
|
|
AddRef(
|
|
pBar,
|
|
mSwingLows //
|
|
);
|
|
swingLowsCount = ArraySize(mSwingLows);
|
|
|
|
//
|
|
DrawSwingLows();
|
|
|
|
//
|
|
Add(
|
|
X_SWING_LOW_DETECTED,
|
|
state //
|
|
);
|
|
OnSwingLowDetected(pBar);
|
|
NotifySwingLowEventListeners(pBar);
|
|
}
|
|
|
|
//
|
|
// Detect Momentum Bar ...
|
|
int momentumBarsCount = ArraySize(mMomentumBars);
|
|
bool isStrongBar = cBar.IsStrong(MomentumBarPercent());
|
|
bool isSharpBullish = cBar.IsSharpBullish(
|
|
MomentumBarLoopBack(),
|
|
MomentumBarSharpRatio() //
|
|
);
|
|
bool isSharpBearish = cBar.IsSharpBearish(
|
|
MomentumBarLoopBack(),
|
|
MomentumBarSharpRatio() //
|
|
);
|
|
bool isMomentumBar =
|
|
isStrongBar &&
|
|
(isSharpBearish ||
|
|
isSharpBullish);
|
|
if (isMomentumBar)
|
|
{
|
|
//
|
|
AddRef(
|
|
cBar,
|
|
mMomentumBars //
|
|
);
|
|
momentumBarsCount = ArraySize(mMomentumBars);
|
|
|
|
//
|
|
DrawMomentumBars();
|
|
|
|
//
|
|
Add(
|
|
X_MOMENTUM_BAR_DETECTED,
|
|
state //
|
|
);
|
|
OnMomentumBarDetected(pBar);
|
|
NotifyMomentumBarEventListeners(pBar);
|
|
}
|
|
|
|
//
|
|
mBarTracker.Waits();
|
|
|
|
//
|
|
result = ArraySize(state);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Enable Draw All POI(s) ...
|
|
*/
|
|
void EnableDrawPOIs()
|
|
{
|
|
//
|
|
bool state = true;
|
|
|
|
//
|
|
AllowDrawSwingHighs(state);
|
|
AllowDrawSwingLows(state);
|
|
AllowDrawMomentumBars(state);
|
|
}
|
|
|
|
/**
|
|
* Disable Draw All POI(s) ...
|
|
*/
|
|
void DisableDrawPOIs()
|
|
{
|
|
//
|
|
bool state = false;
|
|
|
|
//
|
|
AllowDrawSwingHighs(state);
|
|
AllowDrawSwingLows(state);
|
|
AllowDrawMomentumBars(state);
|
|
}
|
|
|
|
//
|
|
// Virtual Actions ...
|
|
|
|
/**
|
|
* Apply Default Configurations ...
|
|
*/
|
|
virtual void ApplyDefaultConfig()
|
|
{
|
|
//
|
|
ChartID(0);
|
|
Window(0);
|
|
|
|
//
|
|
MaxNumberOfPOIs(10);
|
|
MaxNumberOfRequiredPOIs(2);
|
|
|
|
//
|
|
SwingHighWidth(5);
|
|
SwingHighThreshold(3);
|
|
SwingHighArrowCode(108);
|
|
SwingHighColor(clrMagenta);
|
|
|
|
//
|
|
SwingLowWidth(5);
|
|
SwingLowThreshold(3);
|
|
SwingLowArrowCode(108);
|
|
SwingLowColor(clrAqua);
|
|
|
|
//
|
|
MomentumBarPercent(55);
|
|
MomentumBarLoopBack(3);
|
|
MomentumBarSharpRatio(1.2);
|
|
MomentumBarWidth(5);
|
|
MomentumBarBullishArrowCode((char)225);
|
|
MomentumBarBearishArrowCode((char)226);
|
|
MomentumBarBullishColor(clrAqua);
|
|
MomentumBarBearishColor(clrMagenta);
|
|
}
|
|
|
|
//
|
|
// Event Listeners ...
|
|
|
|
/**
|
|
* Calls When new Swing High Detected ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*/
|
|
virtual void OnSwingHighDetected(XOHCL &bar)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Register an Event Listener for New Swing High Detected ...
|
|
*
|
|
* @param listener: TXOHCLEventHandler instance ...
|
|
*/
|
|
void AddSwingHighEventListener(TXOHCLEventHandler listener)
|
|
{
|
|
//
|
|
Add(
|
|
listener,
|
|
mSwingHighEventListeners //
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Calls When new Swing Low Detected ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*/
|
|
virtual void OnSwingLowDetected(XOHCL &bar)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Register an Event Listener for New Swing Low Detected ...
|
|
*
|
|
* @param listener: TXOHCLEventHandler instance ...
|
|
*/
|
|
void AddSwingLowEventListener(TXOHCLEventHandler listener)
|
|
{
|
|
//
|
|
Add(
|
|
listener,
|
|
mSwingLowEventListeners //
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Calls When new Momentum Bar Detected ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*/
|
|
virtual void OnMomentumBarDetected(XOHCL &bar)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Register an Event Listener for New Momentum Bar Detected ...
|
|
*
|
|
* @param listener: TXOHCLEventHandler instance ...
|
|
*/
|
|
void AddMomentumBarEventListener(TXOHCLEventHandler listener)
|
|
{
|
|
//
|
|
Add(
|
|
listener,
|
|
mMomentumBarEventListeners //
|
|
);
|
|
}
|
|
|
|
//
|
|
protected:
|
|
//
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Lock ...
|
|
*/
|
|
void Lock()
|
|
{
|
|
mLock = true;
|
|
}
|
|
|
|
/**
|
|
* Unlock ...
|
|
*/
|
|
void Unlock()
|
|
{
|
|
mLock = false;
|
|
}
|
|
|
|
/**
|
|
* Detect Required POI(s) ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*/
|
|
void DetectRequiredPOIs(int barIndex = 0)
|
|
{
|
|
//
|
|
// Validate Reuired POI(s) ...
|
|
int requiredPOIs = MaxNumberOfRequiredPOIs();
|
|
if (requiredPOIs <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Lock();
|
|
|
|
//
|
|
// Normalize Bar Index ...
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
// Define Index of Bars ...
|
|
int zIndex = barIndex;
|
|
int cIndex = zIndex + 1;
|
|
|
|
//
|
|
XOHCL cBar;
|
|
bool isRetrieved = mBarTracker.GetBar(cBar, cIndex);
|
|
if (!isRetrieved)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Detect POI(s) based On Current Bar ...
|
|
|
|
//
|
|
// Swing Highs ...
|
|
int swingHighsCount = ArraySize(mSwingHighs);
|
|
if (swingHighsCount < requiredPOIs)
|
|
{
|
|
//
|
|
bool isSwingHigh = cBar.IsSimpleSwingHigh(SwingHighThreshold());
|
|
if (isSwingHigh)
|
|
{
|
|
//
|
|
AddRef(
|
|
cBar,
|
|
mSwingHighs //
|
|
);
|
|
|
|
//
|
|
swingHighsCount = ArraySize(mSwingHighs);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Swing Low ...
|
|
int swingLowsCount = ArraySize(mSwingLows);
|
|
if (swingLowsCount < requiredPOIs)
|
|
{
|
|
//
|
|
bool isSwingLow = cBar.IsSimpleSwingLow(SwingLowThreshold());
|
|
if (isSwingLow)
|
|
{
|
|
//
|
|
AddRef(
|
|
cBar,
|
|
mSwingLows //
|
|
);
|
|
|
|
//
|
|
swingLowsCount = ArraySize(mSwingLows);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Momentum Bars ...
|
|
int momentumBarsCount = ArraySize(mMomentumBars);
|
|
if (momentumBarsCount < requiredPOIs)
|
|
{
|
|
//
|
|
bool isStrongBar = cBar.IsStrong(MomentumBarPercent());
|
|
|
|
//
|
|
// Bullish ...
|
|
bool isSharpBullish = cBar.IsSharpBullish(
|
|
MomentumBarLoopBack(),
|
|
MomentumBarSharpRatio() //
|
|
);
|
|
|
|
//
|
|
// Bearish ...
|
|
bool isSharpBearish = cBar.IsSharpBearish(
|
|
MomentumBarLoopBack(),
|
|
MomentumBarSharpRatio() //
|
|
);
|
|
|
|
//
|
|
bool isMomentumBar =
|
|
isStrongBar &&
|
|
(isSharpBearish ||
|
|
isSharpBullish);
|
|
if (isMomentumBar)
|
|
{
|
|
//
|
|
AddRef(
|
|
cBar,
|
|
mMomentumBars //
|
|
);
|
|
|
|
//
|
|
momentumBarsCount = ArraySize(mMomentumBars);
|
|
}
|
|
}
|
|
|
|
//
|
|
bool canContinue =
|
|
//
|
|
swingHighsCount < requiredPOIs ||
|
|
swingLowsCount < requiredPOIs ||
|
|
momentumBarsCount < requiredPOIs
|
|
//
|
|
;
|
|
if (canContinue)
|
|
{
|
|
DetectRequiredPOIs(barIndex + 1);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Complete Calculations ...
|
|
|
|
//
|
|
XOHCL tmpBars[];
|
|
|
|
//
|
|
// Reverse Swing Highs ...
|
|
Copy(
|
|
mSwingHighs,
|
|
tmpBars //
|
|
);
|
|
Clean(mSwingHighs);
|
|
ArrayReverse(tmpBars);
|
|
Copy(
|
|
tmpBars,
|
|
mSwingHighs //
|
|
);
|
|
Clean(tmpBars);
|
|
|
|
//
|
|
// Reverse Swing Lows ...
|
|
Copy(
|
|
mSwingLows,
|
|
tmpBars //
|
|
);
|
|
Clean(mSwingLows);
|
|
ArrayReverse(tmpBars);
|
|
Copy(
|
|
tmpBars,
|
|
mSwingLows //
|
|
);
|
|
Clean(tmpBars);
|
|
|
|
//
|
|
// Reverse Momentum Bars ...
|
|
Copy(
|
|
mMomentumBars,
|
|
tmpBars //
|
|
);
|
|
Clean(mMomentumBars);
|
|
ArrayReverse(tmpBars);
|
|
Copy(
|
|
tmpBars,
|
|
mMomentumBars //
|
|
);
|
|
Clean(tmpBars);
|
|
|
|
//
|
|
Unlock();
|
|
DrawPOIs();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Destroy POIs ...
|
|
|
|
/**
|
|
* Destroy All POI(s) ...
|
|
*/
|
|
void DestroyPOIs()
|
|
{
|
|
//
|
|
DestroySwingHighs();
|
|
DestroySwingLows();
|
|
|
|
//
|
|
DestroyMomentumBars();
|
|
}
|
|
|
|
/**
|
|
* Destroy Swing Highs ...
|
|
*/
|
|
void DestroySwingHighs()
|
|
{
|
|
Clean(mSwingHighs);
|
|
}
|
|
|
|
/**
|
|
* Destroy Swing Lows ...
|
|
*/
|
|
void DestroySwingLows()
|
|
{
|
|
Clean(mSwingLows);
|
|
}
|
|
|
|
/**
|
|
* Destroy Momentum Bars ...
|
|
*/
|
|
void DestroyMomentumBars()
|
|
{
|
|
Clean(mMomentumBars);
|
|
}
|
|
|
|
//
|
|
// Draw Actions ...
|
|
|
|
/**
|
|
* Draw All POI(s) ...
|
|
*/
|
|
void DrawPOIs()
|
|
{
|
|
//
|
|
DrawSwingHighs();
|
|
DrawSwingLows();
|
|
|
|
//
|
|
DrawMomentumBars();
|
|
}
|
|
|
|
/**
|
|
* Draw Swing Highs ...
|
|
*/
|
|
void DrawSwingHighs()
|
|
{
|
|
//
|
|
bool allow = AllowDrawSwingHighs();
|
|
if (!allow)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mSwingHighs);
|
|
if (!IsValidSize(count))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOHCL iSwing = mSwingHighs[i];
|
|
|
|
//
|
|
string iName = iSwing.GetTag(ToString(X_POI_SWING_HIGH));
|
|
int iIDX = HasObject(
|
|
iName,
|
|
mSwingHighObjects //
|
|
);
|
|
if (IsValidIndex(iIDX))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
CreateSwingHighObject(iSwing, iName);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draw Swing Lows ...
|
|
*/
|
|
void DrawSwingLows()
|
|
{
|
|
//
|
|
bool allow = AllowDrawSwingLows();
|
|
if (!allow)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mSwingLows);
|
|
if (!IsValidSize(count))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOHCL iSwing = mSwingLows[i];
|
|
|
|
//
|
|
string iName = iSwing.GetTag(ToString(X_POI_SWING_LOW));
|
|
int iIDX = HasObject(
|
|
iName,
|
|
mSwingLowObjects //
|
|
);
|
|
if (IsValidIndex(iIDX))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
CreateSwingLowObject(iSwing, iName);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draw Momentum Bars ...
|
|
*/
|
|
void DrawMomentumBars()
|
|
{
|
|
//
|
|
bool allow = AllowDrawMomentumBars();
|
|
if (!allow)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mMomentumBars);
|
|
if (!IsValidSize(count))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = mMomentumBars[i];
|
|
|
|
//
|
|
string iName = iBar.GetTag(ToString(X_POI_MOMENTUM_BAR));
|
|
int iIDX = HasObject(
|
|
iName,
|
|
mMomentumBarObjects //
|
|
);
|
|
if (IsValidIndex(iIDX))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
CreateMomentumBarObject(iBar, iName);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clean All Drawn Objects ...
|
|
*/
|
|
void DestroyObjects()
|
|
{
|
|
//
|
|
DestroySwingHighObjects();
|
|
DestroySwingLowObjects();
|
|
DestroyMomentumBarObjects();
|
|
}
|
|
|
|
/**
|
|
* Clean Swing Highs Drawn Objects ...
|
|
*/
|
|
void DestroySwingHighObjects()
|
|
{
|
|
mSwingHighObjects.Clear();
|
|
}
|
|
|
|
/**
|
|
* Clean Swing Lows Drawn Objects ...
|
|
*/
|
|
void DestroySwingLowObjects()
|
|
{
|
|
mSwingLowObjects.Clear();
|
|
}
|
|
|
|
/**
|
|
* Clean Momentum Bars Drawn Objects ...
|
|
*/
|
|
void DestroyMomentumBarObjects()
|
|
{
|
|
mMomentumBarObjects.Clear();
|
|
}
|
|
|
|
/**
|
|
* Detect an Object Exists in Array or not ...
|
|
*
|
|
* @param name: String ...
|
|
* @param array: CArrayObj instance ...
|
|
*
|
|
* @return ( int ): index of Object ...
|
|
*/
|
|
int HasObject(
|
|
string name,
|
|
CArrayObj &array //
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
if (!IsValid(name))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = array.Total();
|
|
if (!IsValidSize(count))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
CChartObject iObj = array.At(i);
|
|
|
|
//
|
|
if (iObj.Name() == name)
|
|
{
|
|
//
|
|
result = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Event Handler Notifiers ...
|
|
|
|
/**
|
|
* Notify New Swing High Point Event Handlers ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*/
|
|
void NotifySwingHighEventListeners(XOHCL &bar)
|
|
{
|
|
//
|
|
if (!bar.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mSwingHighEventListeners);
|
|
if (!IsValidSize(count))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
TXOHCLEventHandler iListener = mSwingHighEventListeners[i];
|
|
iListener(bar);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notify New Swing Low Point Event Handlers ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*/
|
|
void NotifySwingLowEventListeners(XOHCL &bar)
|
|
{
|
|
//
|
|
if (!bar.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mSwingLowEventListeners);
|
|
if (!IsValidSize(count))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
TXOHCLEventHandler iListener = mSwingLowEventListeners[i];
|
|
iListener(bar);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notify New Momentum Bar Event Handlers ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*/
|
|
void NotifyMomentumBarEventListeners(XOHCL &bar)
|
|
{
|
|
//
|
|
if (!bar.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mMomentumBarEventListeners);
|
|
if (!IsValidSize(count))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
TXOHCLEventHandler iListener = mMomentumBarEventListeners[i];
|
|
iListener(bar);
|
|
}
|
|
}
|
|
|
|
//
|
|
private:
|
|
//
|
|
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
bool mLock; // Lock State ...
|
|
string mSymbol; // Market Symbol ...
|
|
ENUM_TIMEFRAMES mPeriod; // Market Period ...
|
|
long mChartID; // Chart ID ...
|
|
int mWindow; // Window ID ...
|
|
int mMaxNumberOfPOIs; // Max Allowed Number of POI(s) which Can Holds ...
|
|
int mMaxNumberOfRequiredPOIs; // Max Allowed Number of POI(s) which Must Find at Initializion Time ...
|
|
|
|
//
|
|
XBarTracker mBarTracker; // Market Bar Tracker ...
|
|
|
|
//
|
|
// POI Holders ...
|
|
|
|
//
|
|
// Swing Highs ...
|
|
|
|
bool mAllowDrawSwingHighs; // Draw Swing Highs ...
|
|
char mSwingHighArrowCode; // Swing High Arrow Code ...
|
|
color mSwingHighColor; // Swing High Color ...
|
|
int mSwingHighWidth; // Swing High Width ...
|
|
double mSwingHighThreshold; // Threshold Required for Swing High Detection ...
|
|
XOHCL mSwingHighs[]; // Swing Highs ...
|
|
CArrayObj mSwingHighObjects; // Swing High Chart Objects ...
|
|
TXOHCLEventHandler mSwingHighEventListeners[]; // Swing High Event Listeners ...
|
|
|
|
/**
|
|
* Create an Object to Represent Swing High on Chart ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
* @param name: String ...
|
|
*/
|
|
void CreateSwingHighObject(
|
|
XOHCL &bar,
|
|
string name //
|
|
)
|
|
{
|
|
//
|
|
if (!bar.IsValid() ||
|
|
!IsValid(name))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
CChartObjectArrow *iObj;
|
|
iObj = new CChartObjectArrow();
|
|
bool isCreated = iObj.Create(
|
|
ChartID(),
|
|
name,
|
|
Window(),
|
|
bar.time,
|
|
bar.high,
|
|
SwingHighArrowCode() //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Configure Object ...
|
|
iObj.Width(SwingHighWidth());
|
|
iObj.Color(SwingHighColor());
|
|
iObj.Anchor(ANCHOR_BOTTOM);
|
|
|
|
//
|
|
mSwingHighObjects.Add(iObj);
|
|
}
|
|
|
|
//
|
|
// Swing Lows ...
|
|
|
|
bool mAllowDrawSwingLows; // Draw Swing Lows ...
|
|
char mSwingLowArrowCode; // Swing Low Arrow Code ...
|
|
color mSwingLowColor; // Swing Low Color ...
|
|
int mSwingLowWidth; // Swing Low Width ...
|
|
double mSwingLowThreshold; // Threshold Required for Swing Low Detection ...
|
|
XOHCL mSwingLows[]; // Swing Lows ...
|
|
CArrayObj mSwingLowObjects; // Swing Low Chart Objects ...
|
|
TXOHCLEventHandler mSwingLowEventListeners[]; // Swing Low Event Listeners ...
|
|
|
|
/**
|
|
* Create an Object to Represent Swing Low on Chart ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
* @param name: String ...
|
|
*/
|
|
void CreateSwingLowObject(
|
|
XOHCL &bar,
|
|
string name //
|
|
)
|
|
{
|
|
//
|
|
if (!bar.IsValid() ||
|
|
!IsValid(name))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
CChartObjectArrow *iObj;
|
|
iObj = new CChartObjectArrow();
|
|
bool isCreated = iObj.Create(
|
|
ChartID(),
|
|
name,
|
|
Window(),
|
|
bar.time,
|
|
bar.low,
|
|
SwingLowArrowCode() //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Configure Object ...
|
|
iObj.Width(SwingLowWidth());
|
|
iObj.Color(SwingLowColor());
|
|
iObj.Anchor(ANCHOR_TOP);
|
|
|
|
//
|
|
mSwingLowObjects.Add(iObj);
|
|
}
|
|
|
|
//
|
|
// Momentum Bar ...
|
|
|
|
bool mAllowDrawMomentumBars; // Draw Momentum Bars ...
|
|
int mMomentumBarPercent; // Momentum Bar Percent ...
|
|
double mMomentumBarSharpRatio; // Momentum Bar Sharp Ratio ...
|
|
int mMomentumBarLoopBack; // Momentum Bar Loopback ...
|
|
int mMomentumBarWidth; // Momentum Bar Width ...
|
|
char mMomentumBarBullishArrowCode; // Bullish Momentum Bar Arrow Code ...
|
|
char mMomentumBarBearishArrowCode; // Bullish Momentum Bar Color ...
|
|
color mMomentumBarBullishColor; // Bearish Momentum Bar Arrow Code ...
|
|
color mMomentumBarBearishColor; // Bearish Momentum Bar Color ...
|
|
XOHCL mMomentumBars[]; // Momentum Bars ...
|
|
CArrayObj mMomentumBarObjects; // Momentm Bar Chart Objects ...
|
|
TXOHCLEventHandler mMomentumBarEventListeners[]; // Momentum Bars Event Listeners ...
|
|
|
|
/**
|
|
* Create an Object to Represent Momentum Bar on Chart ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
* @param name: String ...
|
|
*/
|
|
void CreateMomentumBarObject(
|
|
XOHCL &bar,
|
|
string name //
|
|
)
|
|
{
|
|
//
|
|
if (!bar.IsValid() ||
|
|
!IsValid(name))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
bool isBullish = bar.IsBullish();
|
|
double price =
|
|
isBullish
|
|
? bar.low
|
|
: bar.high;
|
|
char arrowCode =
|
|
isBullish
|
|
? MomentumBarBullishArrowCode()
|
|
: MomentumBarBearishArrowCode();
|
|
color clr =
|
|
isBullish
|
|
? MomentumBarBullishColor()
|
|
: MomentumBarBearishColor();
|
|
ENUM_ARROW_ANCHOR anchor =
|
|
isBullish
|
|
? ANCHOR_TOP
|
|
: ANCHOR_BOTTOM;
|
|
|
|
//
|
|
CChartObjectArrow *iObj;
|
|
iObj = new CChartObjectArrow();
|
|
bool isCreated = iObj.Create(
|
|
ChartID(),
|
|
name,
|
|
Window(),
|
|
bar.time,
|
|
price,
|
|
arrowCode //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Configure Object ...
|
|
iObj.Width(MomentumBarWidth());
|
|
iObj.Color(clr);
|
|
iObj.Anchor(anchor);
|
|
|
|
//
|
|
mMomentumBarObjects.Add(iObj);
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
// |