remove backups ...
This commit is contained in:
@@ -1,344 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestRegresser.mq5 |
|
||||
//| SaherElm IT Center |
|
||||
//| https://www.saherelm.ir |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
#include <ChartObjects/ChartObjectsLines.mqh>
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
input int mLoopbackLength = 200;
|
||||
input ENUM_X_PRICE mPriceType = X_PRICE_HIGH;
|
||||
|
||||
//
|
||||
// Calculation ...
|
||||
input group "Calculation";
|
||||
input int zigzagDepth = 12; // Depth
|
||||
input int zigzagDeviation = 5; // Deviation
|
||||
input int zigzagBackStep = 3; // Back Step
|
||||
|
||||
//
|
||||
// Variables ...
|
||||
|
||||
//
|
||||
int mZigZagHandler = INVALID_HANDLE;
|
||||
|
||||
//
|
||||
// double mSumX = 0;
|
||||
// double mSumY = 0;
|
||||
// double mSumXY = 0;
|
||||
// double mSumX2 = 0;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
double xData[];
|
||||
double yData[];
|
||||
int xDataCount = CollectData(
|
||||
xData,
|
||||
yData //
|
||||
);
|
||||
|
||||
//
|
||||
// Initialize ZigZag Handler ...
|
||||
mZigZagHandler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
"ZigZagColor",
|
||||
zigzagDepth,
|
||||
zigzagDeviation,
|
||||
zigzagBackStep //
|
||||
);
|
||||
if (mZigZagHandler == INVALID_HANDLE)
|
||||
{
|
||||
Print("Error creating ZigZag handle");
|
||||
return (INIT_FAILED);
|
||||
}
|
||||
|
||||
// //
|
||||
// for (int i = 0; i < mLoopbackLength; i++)
|
||||
// {
|
||||
// //
|
||||
// double iY = yData[i];
|
||||
// double iX = xData[i];
|
||||
|
||||
// //
|
||||
// mSumX += iX;
|
||||
// mSumY += iY;
|
||||
// mSumXY += (iX * iY);
|
||||
// mSumX2 += (iX * iX);
|
||||
// }
|
||||
|
||||
// //
|
||||
// for (int i = 0; i < mLoopbackLength; i++)
|
||||
// {
|
||||
// //
|
||||
// double iY = GetAppliedPrice(
|
||||
// _Symbol,
|
||||
// _Period,
|
||||
// i,
|
||||
// mPriceType //
|
||||
// );
|
||||
// double iX = i + 1;
|
||||
|
||||
// //
|
||||
// mSumX += iX;
|
||||
// mSumY += iY;
|
||||
// mSumXY += (iX * iY);
|
||||
// mSumX2 += (iX * iX);
|
||||
// }
|
||||
|
||||
//
|
||||
// int n = mLoopbackLength;
|
||||
// double slope = (n * mSumXY - mSumX * mSumY) / (n * mSumX2 - mSumX * mSumX);
|
||||
// double intercept = (mSumY - slope * mSumX) / n;
|
||||
|
||||
// //
|
||||
// double xData[];
|
||||
// double yData[];
|
||||
// int xDataCount = CollectData(
|
||||
// xData,
|
||||
// yData //
|
||||
// );
|
||||
double _cSlope;
|
||||
double _cIntercept;
|
||||
int calculatedCount = CalculateSlopeandIntercept(
|
||||
_cSlope,
|
||||
_cIntercept,
|
||||
xData,
|
||||
yData //
|
||||
);
|
||||
|
||||
//
|
||||
datetime time1 = iTime(_Symbol, _Period, mLoopbackLength);
|
||||
datetime time2 = iTime(_Symbol, _Period, 0);
|
||||
|
||||
// //
|
||||
// double price1 = (intercept + slope * mLoopbackLength);
|
||||
// double price2 = (intercept + slope);
|
||||
|
||||
//
|
||||
double cPrice1 = PredictValue(
|
||||
_cSlope,
|
||||
_cIntercept,
|
||||
time1 //
|
||||
);
|
||||
double cPrice2 = PredictValue(
|
||||
_cSlope,
|
||||
_cIntercept,
|
||||
time2 //
|
||||
);
|
||||
|
||||
//
|
||||
string name = "TrendLine";
|
||||
string cName = "cTrendLine";
|
||||
|
||||
//
|
||||
// CChartObjectTrend *iTrend = new CChartObjectTrend();
|
||||
// bool isCreated = iTrend.Create(
|
||||
// ChartID(),
|
||||
// name,
|
||||
// 0,
|
||||
// time1,
|
||||
// price1,
|
||||
// time2,
|
||||
// price2 //
|
||||
// );
|
||||
// if (isCreated)
|
||||
// {
|
||||
// //
|
||||
// // Styling Trend Line ...
|
||||
// }
|
||||
|
||||
//
|
||||
CChartObjectTrend *iCTrend = new CChartObjectTrend();
|
||||
bool isCreated = iCTrend.Create(
|
||||
ChartID(),
|
||||
cName,
|
||||
0,
|
||||
time1,
|
||||
cPrice1,
|
||||
time2,
|
||||
cPrice2 //
|
||||
);
|
||||
if (isCreated)
|
||||
{
|
||||
//
|
||||
// Styling Trend Line ...
|
||||
}
|
||||
|
||||
//
|
||||
return (INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//---
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert tick function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
//---
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//
|
||||
int CollectData(
|
||||
double &xData[],
|
||||
double &yData[],
|
||||
int barIndex = 0 //
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = false;
|
||||
|
||||
//
|
||||
SpecifiedClean(xData);
|
||||
SpecifiedClean(yData);
|
||||
|
||||
//
|
||||
barIndex = NormalizeInt(barIndex, 0);
|
||||
|
||||
//
|
||||
int start = barIndex;
|
||||
int end = start + mLoopbackLength;
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
//
|
||||
double iY = GetAppliedPrice(
|
||||
_Symbol,
|
||||
_Period,
|
||||
i //
|
||||
);
|
||||
|
||||
//
|
||||
datetime iTime = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
i //
|
||||
);
|
||||
double iX = i + 1; // (double)TimeToSeconds(iTime);
|
||||
|
||||
//
|
||||
Add(
|
||||
iX,
|
||||
xData //
|
||||
);
|
||||
|
||||
//
|
||||
Add(
|
||||
iY,
|
||||
yData //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
result = ArraySize(xData);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int CalculateSlopeandIntercept(
|
||||
double &_slope,
|
||||
double &_intercept,
|
||||
double &xData[],
|
||||
double &yData[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
bool has = false;
|
||||
|
||||
//
|
||||
_slope = 0;
|
||||
_intercept = 0;
|
||||
|
||||
//
|
||||
if (!HasChild(xData) ||
|
||||
!HasChild(yData))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double sumX = 0;
|
||||
double sumY = 0;
|
||||
double sumXY = 0;
|
||||
double sumX2 = 0;
|
||||
|
||||
//
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
int end = MathMin(ArraySize(xData), ArraySize(yData));
|
||||
for (int i = 0; i < end; i++)
|
||||
{
|
||||
//
|
||||
double x = xData[i];
|
||||
double y = yData[i];
|
||||
|
||||
//
|
||||
sumX += x;
|
||||
sumY += y;
|
||||
sumXY += x * y;
|
||||
sumX2 += x * x;
|
||||
}
|
||||
|
||||
//
|
||||
int n = end;
|
||||
_slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
|
||||
_intercept = (sumY - _slope * sumX) / n;
|
||||
|
||||
//
|
||||
result = n;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double PredictValue(
|
||||
double &_slope,
|
||||
double &_intercept,
|
||||
datetime forTime //
|
||||
)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
if (!IsSpecifiedValid(forTime))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double forX = iBarShift(
|
||||
_Symbol,
|
||||
_Period,
|
||||
forTime //
|
||||
); // (double)TimeToSeconds(forTime);
|
||||
result = (_intercept + _slope * forX);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,843 +0,0 @@
|
||||
|
||||
//
|
||||
// Order Flow ...
|
||||
|
||||
//
|
||||
bool drawOrderFlow;
|
||||
XBoxZone orderFlow[];
|
||||
bool manageOrderFlow;
|
||||
ENUM_X_DIRECTION orderFlowDir;
|
||||
|
||||
//
|
||||
bool HasOrderFlow()
|
||||
{
|
||||
//
|
||||
return HasChild(orderFlow) &&
|
||||
HasDirection(orderFlowDir);
|
||||
}
|
||||
|
||||
//
|
||||
bool HasBullishOrderFlow()
|
||||
{
|
||||
return HasOrderFlow() &&
|
||||
IsXBullish(orderFlowDir);
|
||||
}
|
||||
|
||||
//
|
||||
bool HasBearishOrderFlow()
|
||||
{
|
||||
return HasOrderFlow() &&
|
||||
IsXBearish(orderFlowDir);
|
||||
}
|
||||
|
||||
//
|
||||
bool GetOrderFlowBoundary(
|
||||
double &upper,
|
||||
double &lower //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
upper = EMPTY_VALUE;
|
||||
lower = EMPTY_VALUE;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = HasOrderFlow();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int idx = -1;
|
||||
|
||||
//
|
||||
// Upper ...
|
||||
idx = GetHighest(orderFlow);
|
||||
if (IsValidIndex(idx))
|
||||
{
|
||||
upper = orderFlow[idx].upper;
|
||||
}
|
||||
|
||||
//
|
||||
// Lower ...
|
||||
idx = GetLowest(orderFlow);
|
||||
if (IsValidIndex(idx))
|
||||
{
|
||||
lower = orderFlow[idx].lower;
|
||||
}
|
||||
|
||||
//
|
||||
result = NotEmptyZero(upper) &&
|
||||
NotEmptyZero(lower) &&
|
||||
upper > lower;
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
upper = EMPTY_VALUE;
|
||||
lower = EMPTY_VALUE;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool ValidateOrderFlow(XOHCL &bar)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid() &&
|
||||
HasOrderFlow();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double upper = EMPTY_VALUE;
|
||||
double lower = EMPTY_VALUE;
|
||||
result = GetOrderFlowBoundary(upper, lower);
|
||||
result = result &&
|
||||
HasBullishOrderFlow()
|
||||
? bar.low > lower
|
||||
: bar.high < upper;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
void DrawOrderFlow()
|
||||
{
|
||||
//
|
||||
if (!drawOrderFlow || !HasOrderFlow())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
poiDrawer.DrawZones(orderFlow, structureDrawConfig.drawConfig);
|
||||
}
|
||||
|
||||
//
|
||||
void ManageOrderFlow(XOHCL &bar)
|
||||
{
|
||||
//
|
||||
// Validate Exists ...
|
||||
if (HasOrderFlow())
|
||||
{
|
||||
//
|
||||
if (!ValidateOrderFlow(bar))
|
||||
{
|
||||
//
|
||||
// Invalidate OrderFlow ...
|
||||
XClean(orderFlow);
|
||||
orderFlowDir = X_DIRECTION_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Detect New ...
|
||||
if (!HasOrderFlow())
|
||||
{
|
||||
//
|
||||
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
|
||||
// patternConfig.Default();
|
||||
// patternConfig.supportAndResistanceLoopbackLength = 21;
|
||||
// patternConfig.supportAndResistanceValidationLength = 7;
|
||||
|
||||
//
|
||||
poiDetector.HasOrderFlow(
|
||||
bar,
|
||||
orderFlowDir,
|
||||
orderFlow,
|
||||
structureConfig.orderFlowValidation,
|
||||
structureConfig.orderFlowUseOB,
|
||||
structureConfig.orderFlowUseFVG,
|
||||
structureConfig.orderFlowUseSupportAndResistance,
|
||||
patternConfig.supportAndResistanceLoopbackLength,
|
||||
patternConfig.supportAndResistanceValidationLength,
|
||||
structureConfig.loopback //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Update Exists ...
|
||||
if (HasOrderFlow())
|
||||
{
|
||||
//
|
||||
// Update to Times ...
|
||||
UpdateToTime(orderFlow, TimeCurrent());
|
||||
|
||||
//
|
||||
DrawOrderFlow();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Zone ...
|
||||
|
||||
//
|
||||
XBoxZone support;
|
||||
XBoxZone resistance;
|
||||
bool drawZones;
|
||||
bool drawSupport;
|
||||
bool manageZones;
|
||||
bool drawResistance;
|
||||
|
||||
//
|
||||
bool HasZones()
|
||||
{
|
||||
return HasSupport() ||
|
||||
HasResistance();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasSupport()
|
||||
{
|
||||
return support.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasResistance()
|
||||
{
|
||||
return resistance.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
bool ValidateZones(XOHCL &bar)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid() &&
|
||||
HasZones();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Support ...
|
||||
bool hasSupport = HasSupport();
|
||||
if (hasSupport)
|
||||
{
|
||||
//
|
||||
result = bar.close > support.lower &&
|
||||
!IsBreaked(support, X_PRICE_CLOSE);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
iResistance = support;
|
||||
iResistance.breakAt = NULL;
|
||||
iResistance.dir = X_DIRECTION_BEARISH;
|
||||
iResistance.to = bar.time + (PeriodSeconds(bar.period));
|
||||
iResistance.from = bar.time - (PeriodSeconds(bar.period));
|
||||
|
||||
//
|
||||
support.breakAt = bar.time;
|
||||
support.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Resistance ...
|
||||
bool hasResistance = HasResistance();
|
||||
if (hasResistance)
|
||||
{
|
||||
//
|
||||
result = bar.close < resistance.upper &&
|
||||
!IsBreaked(resistance, X_PRICE_CLOSE);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
iSupport = resistance;
|
||||
iSupport.breakAt = NULL;
|
||||
iSupport.dir = X_DIRECTION_BULLISH;
|
||||
iSupport.to = bar.time + (PeriodSeconds(bar.period));
|
||||
iSupport.from = bar.time - (PeriodSeconds(bar.period));
|
||||
|
||||
//
|
||||
resistance.breakAt = bar.time;
|
||||
resistance.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
(hasSupport && !HasSupport()) ||
|
||||
(hasResistance && !HasResistance());
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
void DrawZones()
|
||||
{
|
||||
//
|
||||
if (!drawZones || !HasZones())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (drawSupport && HasSupport())
|
||||
{
|
||||
poiDrawer.DrawZone(support, structureDrawConfig.drawConfig);
|
||||
}
|
||||
|
||||
//
|
||||
if (drawResistance && HasResistance())
|
||||
{
|
||||
poiDrawer.DrawZone(resistance, structureDrawConfig.drawConfig);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void ManageZones(XOHCL &bar)
|
||||
{
|
||||
//
|
||||
// Validate Exists ...
|
||||
if (HasZones())
|
||||
{
|
||||
//
|
||||
if (!ValidateZones(bar))
|
||||
{
|
||||
//
|
||||
// Invalidate Zones ...
|
||||
|
||||
//
|
||||
// Support ...
|
||||
if (IsXValid(support.breakAt))
|
||||
{
|
||||
//
|
||||
iResistance = support;
|
||||
iResistance.breakAt = NULL;
|
||||
iResistance.dir = X_DIRECTION_BEARISH;
|
||||
iResistance.to = bar.time + (PeriodSeconds(bar.period));
|
||||
iResistance.from = bar.time - (PeriodSeconds(bar.period));
|
||||
|
||||
//
|
||||
support.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Resistance ...
|
||||
if (IsXValid(resistance.breakAt))
|
||||
{
|
||||
//
|
||||
iSupport = resistance;
|
||||
iSupport.breakAt = NULL;
|
||||
iSupport.dir = X_DIRECTION_BULLISH;
|
||||
iSupport.to = bar.time + (PeriodSeconds(bar.period));
|
||||
iSupport.from = bar.time - (PeriodSeconds(bar.period));
|
||||
|
||||
//
|
||||
resistance.Clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Detect New ...
|
||||
XOHCL tmpBar;
|
||||
bool has = false;
|
||||
|
||||
//
|
||||
// Detect Support ...
|
||||
if (!HasSupport())
|
||||
{
|
||||
//
|
||||
has = poiDetector.HasSupport(
|
||||
bar,
|
||||
tmpBar,
|
||||
structureConfig.barsAnalysisConfig.supportAndResistanceValidationLength,
|
||||
structureConfig.barsAnalysisConfig.supportAndResistanceLoopbackLength //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
has = ToSupportBox(tmpBar, support, bar.time);
|
||||
has =
|
||||
has &&
|
||||
!IsBreaked(support, X_PRICE_CLOSE);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
if (support.IsValid())
|
||||
{
|
||||
//
|
||||
iResistance = support;
|
||||
iResistance.breakAt = NULL;
|
||||
iResistance.dir = X_DIRECTION_BEARISH;
|
||||
iResistance.to = bar.time + (PeriodSeconds(bar.period));
|
||||
iResistance.from = bar.time - (PeriodSeconds(bar.period));
|
||||
}
|
||||
|
||||
//
|
||||
support.Clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Resistance ...
|
||||
if (!HasResistance())
|
||||
{
|
||||
//
|
||||
has = poiDetector.HasResistance(
|
||||
bar,
|
||||
tmpBar,
|
||||
structureConfig.barsAnalysisConfig.supportAndResistanceValidationLength,
|
||||
structureConfig.barsAnalysisConfig.supportAndResistanceLoopbackLength //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
has = ToResistanceBox(tmpBar, resistance, bar.time);
|
||||
has =
|
||||
has &&
|
||||
!IsBreaked(resistance, X_PRICE_CLOSE);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
if (resistance.IsValid())
|
||||
{
|
||||
//
|
||||
iSupport = resistance;
|
||||
iSupport.breakAt = NULL;
|
||||
iSupport.dir = X_DIRECTION_BULLISH;
|
||||
iSupport.to = bar.time + (PeriodSeconds(bar.period));
|
||||
iSupport.from = bar.time - (PeriodSeconds(bar.period));
|
||||
}
|
||||
|
||||
//
|
||||
resistance.Clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update Exists ...
|
||||
if (HasZones())
|
||||
{
|
||||
//
|
||||
if (HasSupport())
|
||||
{
|
||||
//
|
||||
support.to = bar.time;
|
||||
support.type = "XFIMASup";
|
||||
}
|
||||
|
||||
//
|
||||
if (HasResistance())
|
||||
{
|
||||
//
|
||||
resistance.to = bar.time;
|
||||
resistance.type = "XFIMARes";
|
||||
}
|
||||
|
||||
//
|
||||
DrawZones();
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
tmpBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
XBoxZone iSupport;
|
||||
XBoxZone iResistance;
|
||||
bool drawIZones;
|
||||
bool drawISupport;
|
||||
bool manageIZones;
|
||||
bool drawIResistance;
|
||||
|
||||
//
|
||||
bool HasIZones()
|
||||
{
|
||||
//
|
||||
return HasISupport() ||
|
||||
HasIResistance();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasISupport()
|
||||
{
|
||||
return iSupport.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasIResistance()
|
||||
{
|
||||
return iResistance.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
void DrawIZones()
|
||||
{
|
||||
//
|
||||
if (!drawIZones || !HasIZones())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (drawISupport && HasISupport())
|
||||
{
|
||||
poiDrawer.DrawZone(iSupport, structureDrawConfig.drawConfig);
|
||||
}
|
||||
|
||||
//
|
||||
if (drawIResistance && HasIResistance())
|
||||
{
|
||||
poiDrawer.DrawZone(iResistance, structureDrawConfig.drawConfig);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
bool ValidateIZones(XOHCL &bar)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid() &&
|
||||
HasIZones();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
// Support ...
|
||||
bool hasSupport = HasISupport();
|
||||
if (hasSupport)
|
||||
{
|
||||
//
|
||||
result = bar.close > iSupport.lower &&
|
||||
!IsBreaked(iSupport, X_PRICE_CLOSE);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
iSupport.breakAt = bar.time;
|
||||
iSupport.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Resistance ...
|
||||
bool hasResistance = HasIResistance();
|
||||
if (hasResistance)
|
||||
{
|
||||
//
|
||||
result = bar.close < iResistance.upper &&
|
||||
!IsBreaked(iResistance, X_PRICE_CLOSE);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
iResistance.breakAt = bar.time;
|
||||
iResistance.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
(hasSupport && !HasISupport()) ||
|
||||
(hasResistance && !HasIResistance());
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
void ManageIZones(XOHCL &bar)
|
||||
{
|
||||
//
|
||||
// Validate Exists ...
|
||||
if (HasIZones())
|
||||
{
|
||||
//
|
||||
if (!ValidateIZones(bar))
|
||||
{
|
||||
//
|
||||
// Invalidate Zones ...
|
||||
|
||||
//
|
||||
// Support ...
|
||||
if (IsXValid(iSupport.breakAt))
|
||||
{
|
||||
iSupport.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Resistance ...
|
||||
if (IsXValid(iResistance.breakAt))
|
||||
{
|
||||
iResistance.Clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update Exists ...
|
||||
if (HasIZones())
|
||||
{
|
||||
//
|
||||
if (HasISupport())
|
||||
{
|
||||
//
|
||||
iSupport.to = bar.time;
|
||||
iSupport.type = "XFIMAISup";
|
||||
}
|
||||
|
||||
//
|
||||
if (HasIResistance())
|
||||
{
|
||||
//
|
||||
iResistance.to = bar.time;
|
||||
iResistance.type = "XFIMAIRes";
|
||||
}
|
||||
|
||||
//
|
||||
DrawIZones();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Trends ...
|
||||
|
||||
//
|
||||
XTrend scTrend;
|
||||
XTrend mcTrend;
|
||||
XTrend lcTrend;
|
||||
XTrend hcTrend;
|
||||
|
||||
//
|
||||
bool drawTrends;
|
||||
bool drawSCTrend;
|
||||
bool drawMCTrend;
|
||||
bool drawLCTrend;
|
||||
bool drawHCTrend;
|
||||
bool manageTrends;
|
||||
|
||||
//
|
||||
bool HasTrend()
|
||||
{
|
||||
//
|
||||
bool result =
|
||||
HasSCTrend() ||
|
||||
HasMCTrend() ||
|
||||
HasLCTrend() ||
|
||||
HasHCTrend();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool HasSCTrend()
|
||||
{
|
||||
return scTrend.IsValid() &&
|
||||
scTrend.HasTrend();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasMCTrend()
|
||||
{
|
||||
return mcTrend.IsValid() &&
|
||||
mcTrend.HasTrend();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasLCTrend()
|
||||
{
|
||||
return lcTrend.IsValid() &&
|
||||
lcTrend.HasTrend();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasHCTrend()
|
||||
{
|
||||
return hcTrend.IsValid() &&
|
||||
hcTrend.HasTrend();
|
||||
}
|
||||
|
||||
//
|
||||
void DrawTrends()
|
||||
{
|
||||
//
|
||||
if (!drawTrends || !HasTrend())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// SC ...
|
||||
if (drawSCTrend && HasSCTrend())
|
||||
{
|
||||
poiDrawer.DrawTrendLine(scTrend, structureDrawConfig.drawConfig);
|
||||
}
|
||||
|
||||
//
|
||||
// MC ...
|
||||
if (drawMCTrend && HasMCTrend())
|
||||
{
|
||||
poiDrawer.DrawTrendLine(mcTrend, structureDrawConfig.drawConfig);
|
||||
}
|
||||
|
||||
//
|
||||
// LC ...
|
||||
if (drawLCTrend && HasLCTrend())
|
||||
{
|
||||
poiDrawer.DrawTrendLine(lcTrend, structureDrawConfig.drawConfig);
|
||||
}
|
||||
|
||||
//
|
||||
// HC ...
|
||||
if (drawHCTrend && HasHCTrend())
|
||||
{
|
||||
poiDrawer.DrawTrendLine(hcTrend, structureDrawConfig.drawConfig);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void ManageTrends(XOHCL &bar)
|
||||
{
|
||||
//
|
||||
// Validate ...
|
||||
bool has = bar.IsValid();
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
XTrend tmpTrend;
|
||||
|
||||
//
|
||||
// SC ...
|
||||
tmpTrend.Clean();
|
||||
has = fimaParser.HasSCTrend(tmpTrend, bar.Index());
|
||||
if (has)
|
||||
{
|
||||
scTrend = tmpTrend;
|
||||
}
|
||||
|
||||
//
|
||||
// MC ...
|
||||
tmpTrend.Clean();
|
||||
has = fimaParser.HasMCTrend(tmpTrend, bar.Index());
|
||||
if (has)
|
||||
{
|
||||
mcTrend = tmpTrend;
|
||||
}
|
||||
|
||||
//
|
||||
// LC ...
|
||||
tmpTrend.Clean();
|
||||
has = fimaParser.HasLCTrend(tmpTrend, bar.Index());
|
||||
if (has)
|
||||
{
|
||||
lcTrend = tmpTrend;
|
||||
}
|
||||
|
||||
//
|
||||
// HC ...
|
||||
tmpTrend.Clean();
|
||||
has = fimaParser.HasHCTrend(tmpTrend, bar.Index());
|
||||
if (has)
|
||||
{
|
||||
hcTrend = tmpTrend;
|
||||
}
|
||||
|
||||
//
|
||||
DrawTrends();
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
tmpTrend.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
void Manage(XOHCL &bar)
|
||||
{
|
||||
//
|
||||
bool has = bar.IsValid();
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
XOHCL p2Bar;
|
||||
XOHCL p3Bar;
|
||||
has = bar.GetPreviousBar(pBar);
|
||||
has = has &&
|
||||
pBar.GetPreviousBar(p2Bar);
|
||||
has = has &&
|
||||
p2Bar.GetPreviousBar(p3Bar);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
pBar.Clean();
|
||||
p2Bar.Clean();
|
||||
p3Bar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
ManageTrends(bar);
|
||||
ManageZones(p2Bar);
|
||||
ManageIZones(p2Bar);
|
||||
ManageOrderFlow(p3Bar);
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
pBar.Clean();
|
||||
p2Bar.Clean();
|
||||
p3Bar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Configure ...
|
||||
drawZones = false;
|
||||
drawIZones = false;
|
||||
drawTrends = false;
|
||||
drawSCTrend = false;
|
||||
drawMCTrend = false;
|
||||
drawLCTrend = false;
|
||||
drawHCTrend = false;
|
||||
drawSupport = false;
|
||||
drawISupport = false;
|
||||
drawOrderFlow = false;
|
||||
drawResistance = false;
|
||||
drawIResistance = false;
|
||||
|
||||
//
|
||||
manageZones = true;
|
||||
manageIZones = true;
|
||||
manageTrends = false;
|
||||
manageOrderFlow = true;
|
||||
|
||||
//
|
||||
// Manage ...
|
||||
Manage(iBar);
|
||||
@@ -1,496 +0,0 @@
|
||||
|
||||
/**
|
||||
* Check Bar Has Signal Based on Strategy 3 ...
|
||||
*
|
||||
* @param bar: XOHCL, reference to Bar ...
|
||||
* @param zone: XBoxZone, reference to holds affected zone ...
|
||||
* @param targets: XTarget, reference to detected Signal's Targets collections ...
|
||||
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Strategy1HasSignal(
|
||||
XOHCL &bar,
|
||||
XBoxZone &zone,
|
||||
XTarget &targets[],
|
||||
ENUM_X_DIRECTION &dir //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
zone.Clean();
|
||||
XClean(targets);
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Validator Flags ...
|
||||
bool validateByZones = true;
|
||||
bool validateByPinBar = true;
|
||||
bool validateByBarPatterns = true;
|
||||
bool validateByCyclesTrend = true;
|
||||
bool validateByMaFastSlowGrows = true;
|
||||
|
||||
//
|
||||
// Define Requirements ...
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
XOHCL p2Bar;
|
||||
XOHCL p3Bar;
|
||||
bool isBullish = false;
|
||||
bool isBearish = false;
|
||||
XPatternAnalysis pBarPatterns;
|
||||
XPatternAnalysis p2BarPatterns;
|
||||
XPatternAnalysis p3BarPatterns;
|
||||
XPatternAnalysisConfig iPatternsConfig;
|
||||
|
||||
//
|
||||
// Reading Bars ...
|
||||
result = bar.GetPreviousBar(pBar);
|
||||
result = result &&
|
||||
pBar.GetPreviousBar(p2Bar);
|
||||
result = result &&
|
||||
p2Bar.GetPreviousBar(p3Bar);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
pBar.Clean();
|
||||
p2Bar.Clean();
|
||||
p3Bar.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Bar Patterns ...
|
||||
iPatternsConfig.Default();
|
||||
iPatternsConfig.FullPattern();
|
||||
result =
|
||||
result &&
|
||||
poiDetector.AnalyseBarPatterns(
|
||||
pBar,
|
||||
pBarPatterns,
|
||||
iPatternsConfig //
|
||||
);
|
||||
result =
|
||||
result &&
|
||||
poiDetector.AnalyseBarPatterns(
|
||||
p2Bar,
|
||||
p2BarPatterns,
|
||||
iPatternsConfig //
|
||||
);
|
||||
result =
|
||||
result &&
|
||||
poiDetector.AnalyseBarPatterns(
|
||||
p3Bar,
|
||||
p3BarPatterns,
|
||||
iPatternsConfig //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
pBar.Clean();
|
||||
p2Bar.Clean();
|
||||
p3Bar.Clean();
|
||||
pBarPatterns.Clean();
|
||||
p2BarPatterns.Clean();
|
||||
p3BarPatterns.Clean();
|
||||
iPatternsConfig.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect a Cross of MAs ...
|
||||
bool isFastCrossedOverSlow = fimaParser.IsMAFastCrossedOverSlow(p2Bar.Index());
|
||||
bool isFastCrossedUnderSlow = fimaParser.IsMAFastCrossedUnderSlow(p2Bar.Index());
|
||||
|
||||
//
|
||||
isBullish = isFastCrossedOverSlow;
|
||||
isBearish = isFastCrossedUnderSlow;
|
||||
|
||||
//
|
||||
result = isBullish || isBearish;
|
||||
|
||||
//
|
||||
// Validate Cross By Over/Under Last ...
|
||||
if (result && validateByMaFastSlowGrows)
|
||||
{
|
||||
//
|
||||
// Bullish ...
|
||||
bool isFastOverLast = fimaParser.IsMAFastOverLast(pBar.Index());
|
||||
bool isSlowOverLast = fimaParser.IsMASlowOverLast(pBar.Index());
|
||||
bool isOverLast = isFastOverLast && isSlowOverLast;
|
||||
|
||||
//
|
||||
// Bearish ...
|
||||
bool isFastUnderLast = fimaParser.IsMAFastUnderLast(pBar.Index());
|
||||
bool isSlowUnderLast = fimaParser.IsMASlowUnderLast(pBar.Index());
|
||||
bool isUnderLast = isFastUnderLast && isSlowUnderLast;
|
||||
|
||||
//
|
||||
isBullish =
|
||||
isBullish &&
|
||||
isOverLast;
|
||||
|
||||
//
|
||||
isBearish =
|
||||
isBearish &&
|
||||
isUnderLast;
|
||||
|
||||
//
|
||||
result = isBullish || isBearish;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate By Cycles Trend ...
|
||||
if (result && validateByCyclesTrend)
|
||||
{
|
||||
//
|
||||
// Reading Cycles Trend ...
|
||||
|
||||
//
|
||||
// Bullish ...
|
||||
|
||||
//
|
||||
bool isLCMABullish = fimaParser.IsLCMABullish(pBar.Index());
|
||||
bool isHCMABullish = fimaParser.IsHCMABullish(pBar.Index());
|
||||
|
||||
//
|
||||
bool isLCMAOverLast = fimaParser.IsLCMAOverLast(pBar.Index());
|
||||
bool isHCMAOverLast = fimaParser.IsHCMAOverLast(pBar.Index());
|
||||
|
||||
//
|
||||
bool isCyclesMABullish = isLCMABullish && isHCMABullish && isLCMAOverLast && isHCMAOverLast;
|
||||
|
||||
//
|
||||
// Bearish ...
|
||||
|
||||
//
|
||||
bool isLCMABearish = fimaParser.IsLCMABearish(pBar.Index());
|
||||
bool isHCMABearish = fimaParser.IsHCMABearish(pBar.Index());
|
||||
|
||||
//
|
||||
bool isLCMAUnderLast = fimaParser.IsLCMAUnderLast(pBar.Index());
|
||||
bool isHCMAUnderLast = fimaParser.IsHCMAUnderLast(pBar.Index());
|
||||
|
||||
//
|
||||
bool isCyclesMABearish = isLCMABearish && isHCMABearish && isLCMAUnderLast && isHCMAUnderLast;
|
||||
|
||||
//
|
||||
isBullish =
|
||||
isBullish &&
|
||||
isCyclesMABullish;
|
||||
|
||||
//
|
||||
isBearish =
|
||||
isBearish &&
|
||||
isCyclesMABearish;
|
||||
|
||||
//
|
||||
result = isBullish || isBearish;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Has a PinBar ...
|
||||
if (result && validateByPinBar)
|
||||
{
|
||||
//
|
||||
bool isPBarIsPinBar = poiDetector.IsPinnedBar(pBar, dir);
|
||||
bool isPBarIsPinBarBullish = isPBarIsPinBar && IsXBullish(dir);
|
||||
bool isPBarIsPinBarBearish = isPBarIsPinBar && IsXBearish(dir);
|
||||
|
||||
//
|
||||
bool isP2BarIsPinBar = poiDetector.IsPinnedBar(p2Bar, dir);
|
||||
bool isP2BarIsPinBarBullish = isP2BarIsPinBar && IsXBullish(dir);
|
||||
bool isP2BarIsPinBarBearish = isP2BarIsPinBar && IsXBearish(dir);
|
||||
|
||||
//
|
||||
bool isBullishPin = isPBarIsPinBarBullish || isP2BarIsPinBarBullish;
|
||||
bool isBearishPin = isPBarIsPinBarBearish || isP2BarIsPinBarBearish;
|
||||
|
||||
//
|
||||
isBullish =
|
||||
isBullish &&
|
||||
isBullishPin;
|
||||
|
||||
//
|
||||
isBearish =
|
||||
isBearish &&
|
||||
isBearishPin;
|
||||
|
||||
//
|
||||
result = isBullish || isBearish;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate By Bar Patterns ...
|
||||
if (result && validateByBarPatterns)
|
||||
{
|
||||
//
|
||||
int count = 0;
|
||||
int bullishCount = 0;
|
||||
int bearishCount = 0;
|
||||
|
||||
//
|
||||
count = pBarPatterns.Count(X_DIRECTION_BULLISH);
|
||||
bullishCount += count;
|
||||
|
||||
//
|
||||
count = p2BarPatterns.Count(X_DIRECTION_BULLISH);
|
||||
bullishCount += count;
|
||||
|
||||
//
|
||||
count = pBarPatterns.Count(X_DIRECTION_BEARISH);
|
||||
bearishCount += count;
|
||||
|
||||
//
|
||||
count = p2BarPatterns.Count(X_DIRECTION_BEARISH);
|
||||
bearishCount += count;
|
||||
|
||||
//
|
||||
bool hasBullishScore = IsValidSize(bullishCount) &&
|
||||
bullishCount > bearishCount;
|
||||
|
||||
//
|
||||
bool hasBearishScore = IsValidSize(bearishCount) &&
|
||||
bearishCount > bullishCount;
|
||||
|
||||
//
|
||||
// Reading Bar Patterns ...
|
||||
|
||||
//
|
||||
// Bullish ...
|
||||
bool isPBarHasBullishPatterns =
|
||||
(pBarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BULLISH));
|
||||
bool isP2BarHasBullishPatterns =
|
||||
(p2BarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BULLISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BULLISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BULLISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BULLISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BULLISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BULLISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BULLISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BULLISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BULLISH));
|
||||
bool hasBullishPatterns = isPBarHasBullishPatterns || isP2BarHasBullishPatterns;
|
||||
|
||||
//
|
||||
// Bearish ...
|
||||
bool isPBarHasBearishPatterns =
|
||||
(pBarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BEARISH));
|
||||
bool isP2BarHasBearishPatterns =
|
||||
(p2BarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BEARISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BEARISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BEARISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BEARISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BEARISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BEARISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BEARISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BEARISH) ||
|
||||
p2BarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BEARISH));
|
||||
bool hasBearishPatterns = isPBarHasBearishPatterns || isP2BarHasBearishPatterns;
|
||||
|
||||
//
|
||||
isBullish =
|
||||
isBullish &&
|
||||
hasBullishScore &&
|
||||
hasBullishPatterns;
|
||||
|
||||
//
|
||||
isBearish =
|
||||
isBearish &&
|
||||
hasBearishScore &&
|
||||
hasBearishPatterns;
|
||||
|
||||
//
|
||||
result = isBullish || isBearish;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate By Zones ...
|
||||
if (result && validateByZones)
|
||||
{
|
||||
//
|
||||
XBoxZone zones[];
|
||||
int count = poiDetector.DetectZones(
|
||||
pBar,
|
||||
zones,
|
||||
true, // Validate Zones ...
|
||||
false, // OB ...
|
||||
true, // FVG ...
|
||||
true, // Supports ...
|
||||
true, // Resistances ...
|
||||
X_DIRECTION_NONE, // All Directions ...
|
||||
X_SORT_BY_DATE, // Sort By ...
|
||||
X_DIRECTION_BEARISH, // Sort Direction ...
|
||||
5, // Zones Loopback ...
|
||||
5, // Zones Validation ...
|
||||
100 // Loopback ...
|
||||
);
|
||||
|
||||
//
|
||||
bool has = IsValidSize(count);
|
||||
if (has)
|
||||
{
|
||||
poiDrawer.DrawZones(zones, structureDrawConfig.drawConfig);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
DebugBreak();
|
||||
|
||||
//
|
||||
result = false;
|
||||
isBullish = false;
|
||||
isBearish = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Detecting Direction ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
dir =
|
||||
isBullish
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
result = HasDirection(dir);
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Zone ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Since Zone Prepared in Above Steps ...
|
||||
// here we only Validate it ...
|
||||
result = zone.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
// Draws ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
|
||||
XPatternAnalysisDrawConfig iPatternsConfig = structureDrawConfig.barAnalysisDrawConfig;
|
||||
iConfig.trendRayLeft = false;
|
||||
iConfig.trendRayRight = false;
|
||||
|
||||
//
|
||||
// Draw Zone ...
|
||||
if (zone.IsValid())
|
||||
{
|
||||
//
|
||||
iConfig.zonesStyle = STYLE_DASHDOT;
|
||||
iConfig.bullishColor = clrYellow;
|
||||
iConfig.bearishColor = clrDarkOrange;
|
||||
|
||||
//
|
||||
poiDrawer.DrawZone(zone, iConfig);
|
||||
}
|
||||
|
||||
//
|
||||
// poiDrawer.DrawZone(mcPVZone, iConfig);
|
||||
// poiDrawer.DrawZone(lcPVZone, iConfig);
|
||||
// poiDrawer.DrawZone(hcPVZone, iConfig);
|
||||
|
||||
//
|
||||
// poiDrawer.DrawZone(pinBarZone, iConfig);
|
||||
// poiDrawer.DrawZone(pullbackZone, iConfig);
|
||||
// poiDrawer.DrawTrendLine(pinBarZoneTrend, iConfig);
|
||||
|
||||
//
|
||||
poiDrawer.DrawPatternAnalysis(pBarPatterns, iPatternsConfig);
|
||||
poiDrawer.DrawPatternAnalysis(p2BarPatterns, iPatternsConfig);
|
||||
poiDrawer.DrawPatternAnalysis(p3BarPatterns, iPatternsConfig);
|
||||
|
||||
//
|
||||
// if (hasATRBox)
|
||||
// {
|
||||
// poiDrawer.DrawZone(atrBox, iConfig);
|
||||
// }
|
||||
|
||||
//
|
||||
// if (hasDoublePatterns)
|
||||
// {
|
||||
// //
|
||||
// poiDrawer.DrawPatternAnalysis(iPatterns, iPatternsConfig);
|
||||
// poiDrawer.DrawPatternAnalysis(iPPatterns, iPatternsConfig);
|
||||
// }
|
||||
|
||||
//
|
||||
iConfig.Clean();
|
||||
iPatternsConfig.Clean();
|
||||
|
||||
//
|
||||
DebugBreak();
|
||||
|
||||
// //
|
||||
// result = false;
|
||||
// isBullish = false;
|
||||
// isBearish = false;
|
||||
// zone.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Targets ...
|
||||
if (result)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
zone.Clean();
|
||||
XClean(targets);
|
||||
dir = X_DIRECTION_NONE;
|
||||
}
|
||||
pBar.Clean();
|
||||
p2Bar.Clean();
|
||||
p3Bar.Clean();
|
||||
pBarPatterns.Clean();
|
||||
p2BarPatterns.Clean();
|
||||
p3BarPatterns.Clean();
|
||||
iPatternsConfig.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -1,949 +0,0 @@
|
||||
|
||||
/**
|
||||
* Check Bar Has Signal Based on Strategy 4 ...
|
||||
*
|
||||
* @param bar: XOHCL, reference to Bar ...
|
||||
* @param zone: XBoxZone, reference to holds affected zone ...
|
||||
* @param targets: XTarget, reference to detected Signal's Targets collections ...
|
||||
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Strategy3HasSignal(
|
||||
XOHCL &bar,
|
||||
XBoxZone &zone,
|
||||
XTarget &targets[],
|
||||
ENUM_X_DIRECTION &dir //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
zone.Clean();
|
||||
XClean(targets);
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Validation Flags ...
|
||||
bool validateByBarPatterns = true;
|
||||
|
||||
//
|
||||
// Define Requirements ...
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
XOHCL p2Bar;
|
||||
XOHCL p3Bar;
|
||||
bool isBullish = false;
|
||||
bool isBearish = false;
|
||||
|
||||
//
|
||||
// Read PBar ...
|
||||
result = bar.GetPreviousBar(pBar);
|
||||
result = result &&
|
||||
pBar.GetPreviousBar(p2Bar);
|
||||
result = result &&
|
||||
p2Bar.GetPreviousBar(p3Bar);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
pBar.Clean();
|
||||
p2Bar.Clean();
|
||||
p3Bar.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Do ...
|
||||
|
||||
//
|
||||
// Retrieve pBar Patterns ...
|
||||
XPatternAnalysis pBarPatterns;
|
||||
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
|
||||
|
||||
//
|
||||
poiDetector.AnalyseBarPatterns(
|
||||
pBar,
|
||||
pBarPatterns,
|
||||
patternConfig //
|
||||
);
|
||||
|
||||
//
|
||||
bool isConsolidation = poiDetector.DetectXPVZone(zone, p2Bar.Index());
|
||||
|
||||
//
|
||||
isBullish =
|
||||
isConsolidation &&
|
||||
zone.IsBullish();
|
||||
|
||||
//
|
||||
isBearish =
|
||||
isConsolidation &&
|
||||
zone.IsBearish();
|
||||
|
||||
//
|
||||
// Summarize Result ...
|
||||
result = isBullish || isBearish;
|
||||
|
||||
//
|
||||
// Force PBar Has Pattern ...
|
||||
if (result && validateByBarPatterns)
|
||||
{
|
||||
//
|
||||
// Analyse Bar Patterns ...
|
||||
result = pBarPatterns.IsValid();
|
||||
|
||||
//
|
||||
// Bullish ...
|
||||
bool isPBarHasBullishPatterns =
|
||||
result &&
|
||||
(
|
||||
//
|
||||
pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
|
||||
//
|
||||
);
|
||||
|
||||
//
|
||||
// Bearish ...
|
||||
bool isPBarHasBearishPatterns =
|
||||
result &&
|
||||
(
|
||||
//
|
||||
pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
|
||||
//
|
||||
);
|
||||
|
||||
//
|
||||
isBullish =
|
||||
isBullish &&
|
||||
isPBarHasBullishPatterns &&
|
||||
!isPBarHasBearishPatterns;
|
||||
|
||||
//
|
||||
isBearish =
|
||||
isBearish &&
|
||||
isPBarHasBearishPatterns &&
|
||||
!isPBarHasBullishPatterns;
|
||||
|
||||
//
|
||||
// Summarize Result ...
|
||||
result = isBullish || isBearish;
|
||||
|
||||
//
|
||||
// Reset Flags ...
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
isBullish = false;
|
||||
isBearish = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
|
||||
poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
|
||||
DebugBreak();
|
||||
|
||||
//
|
||||
result = false;
|
||||
isBullish = false;
|
||||
isBearish = false;
|
||||
}
|
||||
|
||||
// //
|
||||
// // Validate based on Bars Patterns ...
|
||||
// bool validateByBarPatterns = true;
|
||||
// if (validateByBarPatterns)
|
||||
// {
|
||||
// //
|
||||
// // Reading pBar Patterns ...
|
||||
// XPatternAnalysis pBarAnalysis;
|
||||
// poiDetector.AnalyseBarPatterns(
|
||||
// pBar,
|
||||
// pBarAnalysis,
|
||||
// structureConfig.barsAnalysisConfig //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Bullish ...
|
||||
// bool isPBarHasBullishPatterns =
|
||||
// (bar.close > pBar.low ||
|
||||
// bar.open > pBar.low) &&
|
||||
// (
|
||||
// //
|
||||
// pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
|
||||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
|
||||
// pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
|
||||
// pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
|
||||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
|
||||
// //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Bearish ...
|
||||
// bool isPBarHasBearishPatterns =
|
||||
// (bar.close < pBar.high ||
|
||||
// bar.open < pBar.high) &&
|
||||
// (
|
||||
// //
|
||||
// pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
|
||||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
|
||||
// pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
|
||||
// pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
|
||||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
|
||||
// //
|
||||
// );
|
||||
|
||||
// //
|
||||
// isBullish =
|
||||
// isBullish &&
|
||||
// isPBarHasBullishPatterns &&
|
||||
// !isPBarHasBearishPatterns;
|
||||
|
||||
// //
|
||||
// isBearish =
|
||||
// isBearish &&
|
||||
// isPBarHasBearishPatterns &&
|
||||
// !isPBarHasBullishPatterns;
|
||||
|
||||
// //
|
||||
// // Summarize Result ...
|
||||
// result = isBullish ||
|
||||
// isBearish;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Checking PullBack ...
|
||||
// bool validateByPullback = false;
|
||||
// if (validateByPullback)
|
||||
// {
|
||||
// //
|
||||
// XBoxZone pullback;
|
||||
// ENUM_X_DIRECTION pullbackDir;
|
||||
// bool isPullBack = result &&
|
||||
// poiDetector.IsPullbackPattern(
|
||||
// pBar,
|
||||
// pullback,
|
||||
// pullbackDir,
|
||||
// 2,
|
||||
// false // Force Break ...
|
||||
// );
|
||||
// bool isPullbackBullish = isPullBack &&
|
||||
// IsXBullish(pullbackDir);
|
||||
// bool isPullbackBearish = isPullBack &&
|
||||
// IsXBearish(pullbackDir);
|
||||
|
||||
// //
|
||||
// isBullish =
|
||||
// isBullish &&
|
||||
// isPullbackBullish;
|
||||
|
||||
// //
|
||||
// isBearish =
|
||||
// isBearish &&
|
||||
// isPullbackBearish;
|
||||
|
||||
// //
|
||||
// // Summarize Result ...
|
||||
// result = isBullish ||
|
||||
// isBearish;
|
||||
// }
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = isBullish ||
|
||||
isBearish;
|
||||
|
||||
//
|
||||
// Prepare Zone ...
|
||||
if (result)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Targets ...
|
||||
if (result)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
zone.Clean();
|
||||
XClean(targets);
|
||||
dir = X_DIRECTION_NONE;
|
||||
}
|
||||
pBar.Clean();
|
||||
p2Bar.Clean();
|
||||
p3Bar.Clean();
|
||||
pBarPatterns.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
// //
|
||||
// bool isConsolidation = poiDetector.DetectXPVZone(zone, p2Bar.Index());
|
||||
|
||||
// //
|
||||
// isBullish =
|
||||
// isConsolidation &&
|
||||
// zone.IsBullish();
|
||||
|
||||
// //
|
||||
// isBearish =
|
||||
// isConsolidation &&
|
||||
// zone.IsBearish();
|
||||
|
||||
// //
|
||||
// // Summarize Result ...
|
||||
// result = isBullish || isBearish;
|
||||
|
||||
// //
|
||||
// // Force PBar Has Pattern ...
|
||||
// if (result && validateByBarPatterns)
|
||||
// {
|
||||
// //
|
||||
// // Analyse Bar Patterns ...
|
||||
// result = pBarPatterns.IsValid();
|
||||
|
||||
// //
|
||||
// // Bullish ...
|
||||
// bool isPBarHasBullishPatterns =
|
||||
// result &&
|
||||
// (
|
||||
// //
|
||||
// pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
|
||||
// pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
|
||||
// pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
|
||||
// pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
|
||||
// pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
|
||||
// //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Bearish ...
|
||||
// bool isPBarHasBearishPatterns =
|
||||
// result &&
|
||||
// (
|
||||
// //
|
||||
// pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
|
||||
// pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
|
||||
// pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
|
||||
// pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
|
||||
// pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
|
||||
// //
|
||||
// );
|
||||
|
||||
// //
|
||||
// isBullish =
|
||||
// isBullish &&
|
||||
// isPBarHasBullishPatterns &&
|
||||
// !isPBarHasBearishPatterns;
|
||||
|
||||
// //
|
||||
// isBearish =
|
||||
// isBearish &&
|
||||
// isPBarHasBearishPatterns &&
|
||||
// !isPBarHasBullishPatterns;
|
||||
|
||||
// //
|
||||
// // Summarize Result ...
|
||||
// result = isBullish || isBearish;
|
||||
|
||||
// //
|
||||
// // Reset Flags ...
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// isBullish = false;
|
||||
// isBearish = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (result)
|
||||
// {
|
||||
// //
|
||||
// poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
|
||||
// poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
|
||||
// DebugBreak();
|
||||
|
||||
// //
|
||||
// result = false;
|
||||
// isBullish = false;
|
||||
// isBearish = false;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Validate based on Bars Patterns ...
|
||||
// bool validateByBarPatterns = true;
|
||||
// if (validateByBarPatterns)
|
||||
// {
|
||||
// //
|
||||
// // Reading pBar Patterns ...
|
||||
// XPatternAnalysis pBarAnalysis;
|
||||
// poiDetector.AnalyseBarPatterns(
|
||||
// pBar,
|
||||
// pBarAnalysis,
|
||||
// structureConfig.barsAnalysisConfig //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Bullish ...
|
||||
// bool isPBarHasBullishPatterns =
|
||||
// (bar.close > pBar.low ||
|
||||
// bar.open > pBar.low) &&
|
||||
// (
|
||||
// //
|
||||
// pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
|
||||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
|
||||
// pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
|
||||
// pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
|
||||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
|
||||
// //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Bearish ...
|
||||
// bool isPBarHasBearishPatterns =
|
||||
// (bar.close < pBar.high ||
|
||||
// bar.open < pBar.high) &&
|
||||
// (
|
||||
// //
|
||||
// pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
|
||||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
|
||||
// pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
|
||||
// pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
|
||||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
|
||||
// //
|
||||
// );
|
||||
|
||||
// //
|
||||
// isBullish =
|
||||
// isBullish &&
|
||||
// isPBarHasBullishPatterns &&
|
||||
// !isPBarHasBearishPatterns;
|
||||
|
||||
// //
|
||||
// isBearish =
|
||||
// isBearish &&
|
||||
// isPBarHasBearishPatterns &&
|
||||
// !isPBarHasBullishPatterns;
|
||||
|
||||
// //
|
||||
// // Summarize Result ...
|
||||
// result = isBullish ||
|
||||
// isBearish;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Checking PullBack ...
|
||||
// bool validateByPullback = false;
|
||||
// if (validateByPullback)
|
||||
// {
|
||||
// //
|
||||
// XBoxZone pullback;
|
||||
// ENUM_X_DIRECTION pullbackDir;
|
||||
// bool isPullBack = result &&
|
||||
// poiDetector.IsPullbackPattern(
|
||||
// pBar,
|
||||
// pullback,
|
||||
// pullbackDir,
|
||||
// 2,
|
||||
// false // Force Break ...
|
||||
// );
|
||||
// bool isPullbackBullish = isPullBack &&
|
||||
// IsXBullish(pullbackDir);
|
||||
// bool isPullbackBearish = isPullBack &&
|
||||
// IsXBearish(pullbackDir);
|
||||
|
||||
// //
|
||||
// isBullish =
|
||||
// isBullish &&
|
||||
// isPullbackBullish;
|
||||
|
||||
// //
|
||||
// isBearish =
|
||||
// isBearish &&
|
||||
// isPullbackBearish;
|
||||
|
||||
// //
|
||||
// // Summarize Result ...
|
||||
// result = isBullish ||
|
||||
// isBearish;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Check Bar Has Signal Based on Strategy 4 ...
|
||||
*
|
||||
* @param bar: XOHCL, reference to Bar ...
|
||||
* @param zone: XBoxZone, reference to holds affected zone ...
|
||||
* @param targets: XTarget, reference to detected Signal's Targets collections ...
|
||||
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Strategy3HasSignal(
|
||||
XOHCL &bar,
|
||||
XBoxZone &zone,
|
||||
XTarget &targets[],
|
||||
ENUM_X_DIRECTION &dir //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
zone.Clean();
|
||||
XClean(targets);
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Validation Flags ...
|
||||
bool validateByBarPatterns = false;
|
||||
|
||||
//
|
||||
// Define Requirements ...
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
XOHCL p2Bar;
|
||||
XOHCL p3Bar;
|
||||
bool isBullish = false;
|
||||
bool isBearish = false;
|
||||
|
||||
//
|
||||
// Read PBar ...
|
||||
result = bar.GetPreviousBar(pBar);
|
||||
result = result &&
|
||||
pBar.GetPreviousBar(p2Bar);
|
||||
result = result &&
|
||||
p2Bar.GetPreviousBar(p3Bar);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
pBar.Clean();
|
||||
p2Bar.Clean();
|
||||
p3Bar.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Do ...
|
||||
|
||||
//
|
||||
// Retrieve pBar Patterns ...
|
||||
XPatternAnalysis pBarPatterns;
|
||||
XPatternAnalysis p2BarPatterns;
|
||||
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
|
||||
|
||||
//
|
||||
poiDetector.AnalyseBarPatterns(
|
||||
pBar,
|
||||
pBarPatterns,
|
||||
patternConfig //
|
||||
);
|
||||
poiDetector.AnalyseBarPatterns(
|
||||
p2Bar,
|
||||
p2BarPatterns,
|
||||
patternConfig //
|
||||
);
|
||||
|
||||
//
|
||||
bool hasSupport = p2BarPatterns.IsValid() &&
|
||||
p2BarPatterns.IsSupport();
|
||||
bool hasResistance = p2BarPatterns.IsValid() &&
|
||||
p2BarPatterns.IsResistance();
|
||||
|
||||
//
|
||||
isBullish =
|
||||
hasSupport &&
|
||||
p2BarPatterns.Count(X_DIRECTION_BULLISH) >= 4;
|
||||
|
||||
//
|
||||
isBearish =
|
||||
hasResistance &&
|
||||
p2BarPatterns.Count(X_DIRECTION_BEARISH) >= 4;
|
||||
|
||||
//
|
||||
// Summarize Result ...
|
||||
result = isBullish || isBearish;
|
||||
|
||||
//
|
||||
// Extract Affected Zone ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
XOHCL tmpBar;
|
||||
XPivot tmpPivot;
|
||||
XBoxZone tmpZone;
|
||||
|
||||
//
|
||||
if (hasSupport)
|
||||
{
|
||||
//
|
||||
hasSupport = p2BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone);
|
||||
isBullish =
|
||||
isBullish &&
|
||||
hasSupport &&
|
||||
(IsActed(pBar, tmpZone) ||
|
||||
IsTested(pBar, tmpZone));
|
||||
}
|
||||
|
||||
//
|
||||
if (hasResistance)
|
||||
{
|
||||
//
|
||||
hasResistance = p2BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone);
|
||||
isBearish =
|
||||
isBearish &&
|
||||
hasResistance &&
|
||||
(IsActed(pBar, tmpZone) ||
|
||||
IsTested(pBar, tmpZone));
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
tmpBar.Clean();
|
||||
tmpZone.Clean();
|
||||
tmpPivot.Clean();
|
||||
|
||||
//
|
||||
// Summarize Result ...
|
||||
result = isBullish || isBearish;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate based on Bars Patterns ...
|
||||
if (result && validateByBarPatterns)
|
||||
{
|
||||
//
|
||||
// Bullish...
|
||||
bool isPBarHasBullishPatterns =
|
||||
pBarPatterns.IsValid() &&
|
||||
(
|
||||
//
|
||||
pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
|
||||
pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
|
||||
//
|
||||
);
|
||||
|
||||
//
|
||||
// Bearish ...
|
||||
bool isPBarHasBearishPatterns =
|
||||
pBarPatterns.IsValid() &&
|
||||
(
|
||||
//
|
||||
pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
|
||||
pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
|
||||
//
|
||||
);
|
||||
|
||||
//
|
||||
isBullish =
|
||||
isBullish &&
|
||||
isPBarHasBullishPatterns &&
|
||||
!isPBarHasBearishPatterns;
|
||||
|
||||
//
|
||||
isBearish =
|
||||
isBearish &&
|
||||
isPBarHasBearishPatterns &&
|
||||
!isPBarHasBullishPatterns;
|
||||
|
||||
//
|
||||
// Summarize Result ...
|
||||
result = isBullish || isBearish;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
|
||||
poiDrawer.DrawPatternAnalysis(p2BarPatterns, structureDrawConfig.barAnalysisDrawConfig);
|
||||
DebugBreak();
|
||||
|
||||
//
|
||||
result = false;
|
||||
isBullish = false;
|
||||
isBearish = false;
|
||||
}
|
||||
|
||||
// //
|
||||
// bool isConsolidation = poiDetector.DetectXPVZone(zone, p2Bar.Index());
|
||||
|
||||
// //
|
||||
// isBullish =
|
||||
// isConsolidation &&
|
||||
// zone.IsBullish();
|
||||
|
||||
// //
|
||||
// isBearish =
|
||||
// isConsolidation &&
|
||||
// zone.IsBearish();
|
||||
|
||||
// //
|
||||
// // Summarize Result ...
|
||||
// result = isBullish || isBearish;
|
||||
|
||||
// //
|
||||
// // Force PBar Has Pattern ...
|
||||
// if (result && validateByBarPatterns)
|
||||
// {
|
||||
// //
|
||||
// // Analyse Bar Patterns ...
|
||||
// result = pBarPatterns.IsValid();
|
||||
|
||||
// //
|
||||
// // Bullish ...
|
||||
// bool isPBarHasBullishPatterns =
|
||||
// result &&
|
||||
// (
|
||||
// //
|
||||
// pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
|
||||
// pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
|
||||
// pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
|
||||
// pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
|
||||
// pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
|
||||
// //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Bearish ...
|
||||
// bool isPBarHasBearishPatterns =
|
||||
// result &&
|
||||
// (
|
||||
// //
|
||||
// pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
|
||||
// pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
|
||||
// pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
|
||||
// pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
|
||||
// pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
|
||||
// //
|
||||
// );
|
||||
|
||||
// //
|
||||
// isBullish =
|
||||
// isBullish &&
|
||||
// isPBarHasBullishPatterns &&
|
||||
// !isPBarHasBearishPatterns;
|
||||
|
||||
// //
|
||||
// isBearish =
|
||||
// isBearish &&
|
||||
// isPBarHasBearishPatterns &&
|
||||
// !isPBarHasBullishPatterns;
|
||||
|
||||
// //
|
||||
// // Summarize Result ...
|
||||
// result = isBullish || isBearish;
|
||||
|
||||
// //
|
||||
// // Reset Flags ...
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// isBullish = false;
|
||||
// isBearish = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (result)
|
||||
// {
|
||||
// //
|
||||
// poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
|
||||
// poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
|
||||
// DebugBreak();
|
||||
|
||||
// //
|
||||
// result = false;
|
||||
// isBullish = false;
|
||||
// isBearish = false;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Checking PullBack ...
|
||||
// bool validateByPullback = false;
|
||||
// if (validateByPullback)
|
||||
// {
|
||||
// //
|
||||
// XBoxZone pullback;
|
||||
// ENUM_X_DIRECTION pullbackDir;
|
||||
// bool isPullBack = result &&
|
||||
// poiDetector.IsPullbackPattern(
|
||||
// pBar,
|
||||
// pullback,
|
||||
// pullbackDir,
|
||||
// 2,
|
||||
// false // Force Break ...
|
||||
// );
|
||||
// bool isPullbackBullish = isPullBack &&
|
||||
// IsXBullish(pullbackDir);
|
||||
// bool isPullbackBearish = isPullBack &&
|
||||
// IsXBearish(pullbackDir);
|
||||
|
||||
// //
|
||||
// isBullish =
|
||||
// isBullish &&
|
||||
// isPullbackBullish;
|
||||
|
||||
// //
|
||||
// isBearish =
|
||||
// isBearish &&
|
||||
// isPullbackBearish;
|
||||
|
||||
// //
|
||||
// // Summarize Result ...
|
||||
// result = isBullish ||
|
||||
// isBearish;
|
||||
// }
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = isBullish ||
|
||||
isBearish;
|
||||
|
||||
//
|
||||
// Prepare Zone ...
|
||||
if (result)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Targets ...
|
||||
if (result)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
zone.Clean();
|
||||
XClean(targets);
|
||||
dir = X_DIRECTION_NONE;
|
||||
}
|
||||
pBar.Clean();
|
||||
p2Bar.Clean();
|
||||
p3Bar.Clean();
|
||||
pBarPatterns.Clean();
|
||||
patternConfig.Clean();
|
||||
p2BarPatterns.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
bool validateByPVChange = false;
|
||||
bool validateByPVInside = false;
|
||||
|
||||
//
|
||||
// Validate By PV Inside ...
|
||||
if (result && validateByPVInside)
|
||||
{
|
||||
//
|
||||
double pVale = fimaHelper.GetVale(pBar.Index());
|
||||
double pPeak = fimaHelper.GetPeak(pBar.Index());
|
||||
|
||||
//
|
||||
bool isValePassed = pVale <= support.upper &&
|
||||
pVale >= support.upper &&
|
||||
fimaParser.IsValeSame(pBar.Index());
|
||||
|
||||
//
|
||||
bool isPeakPassed = pPeak <= resistance.upper &&
|
||||
pPeak >= resistance.upper &&
|
||||
fimaParser.IsPeakSame(pBar.Index());
|
||||
|
||||
//
|
||||
isBullish =
|
||||
isBullish &&
|
||||
isValePassed;
|
||||
|
||||
//
|
||||
isBearish =
|
||||
isBearish &&
|
||||
isPeakPassed;
|
||||
|
||||
//
|
||||
// Summarize Result ...
|
||||
result = isBullish || isBearish;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate by PV Change ...
|
||||
if (result && validateByPVChange)
|
||||
{
|
||||
//
|
||||
// bullish => p3, p2 vale under last ...
|
||||
// bearish => p3, p2 peak over last ...
|
||||
|
||||
//
|
||||
bool isValePassed =
|
||||
fimaParser.IsValeUnderLast(p2Bar.Index()) ||
|
||||
fimaParser.IsValeUnderLast(p3Bar.Index());
|
||||
|
||||
//
|
||||
bool isPeakPassed =
|
||||
fimaParser.IsPeakOverLast(p2Bar.Index()) ||
|
||||
fimaParser.IsPeakOverLast(p3Bar.Index());
|
||||
|
||||
//
|
||||
isBullish =
|
||||
isBullish &&
|
||||
isValePassed;
|
||||
|
||||
//
|
||||
isBearish =
|
||||
isBearish &&
|
||||
isPeakPassed;
|
||||
|
||||
//
|
||||
// Summarize Result ...
|
||||
result = isBullish || isBearish;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,547 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| XKI_MTF_EA.mq5
|
||||
//| SaherElm IT Center - Strategy using XKI
|
||||
//| Author: Hadi Khazaee Asl
|
||||
//+------------------------------------------------------------------+
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
// Inputs
|
||||
input string InpSymbol = "XAUUSDb";
|
||||
input ENUM_TIMEFRAMES InpSignalTF = PERIOD_H1; // Signal timeframe (H1)
|
||||
input int InpKiLength = 26; // KI length (XKI input)
|
||||
input bool InpShowKI = true; // (XKI input)
|
||||
input int InpCalcLastBars = 1500; // (XKI input)
|
||||
|
||||
input bool InpUseRSI = true; // Use RSI confirmation
|
||||
input int InpRSIPeriod = 14;
|
||||
input int InpRSIPrice = PRICE_CLOSE;
|
||||
|
||||
input bool InpUseH4Filter = true; // Confirm with H4
|
||||
input bool InpUseD1Filter = false; // Confirm with D1
|
||||
input bool InpRequireBothFilters = false; // If true, require BOTH H4 and D1 agreement; else either
|
||||
|
||||
input double InpFixedLot = 0.10; // Fixed lot size
|
||||
input double InpRiskATRMult = 0.0; // Add ATR padding to stop (0=disabled)
|
||||
input int InpATRPeriod = 14;
|
||||
|
||||
input double InpRR = 2.0; // Reward:Risk target
|
||||
input bool InpTrailByKI = true; // Trail stop to KI
|
||||
input int InpSlippagePoints = 20; // Max slippage in points
|
||||
input int InpMaxSpreadPoints = 200; // Max allowed spread in points
|
||||
|
||||
input bool InpAvoidAsianSession = true; // Avoid 22:00–06:00 server time
|
||||
input int InpAsianStartHour = 22;
|
||||
input int InpAsianEndHour = 6;
|
||||
|
||||
input bool InpAvoidNewsWindow = false; // Placeholder flag
|
||||
input int InpNewsWindowMinutes = 60; // Skip trades within +/- minutes
|
||||
|
||||
input int InpBarsLookbackSignal = 2; // Lookback bars for signal (e.g., last closed bar)
|
||||
|
||||
// Magic number and comments
|
||||
input int InpMagic = 260126;
|
||||
input string InpOrderComment = "XKI_MTF_EA";
|
||||
|
||||
// iCustom indicator path (relative to Indicators folder if compiled there)
|
||||
string g_xkiIndicatorPath = "x-saherelm.x121.xki"; // the compiled name; adjust if different
|
||||
|
||||
// Buffers indices as per the indicator
|
||||
#define KI_BUFFER_INDEX 0
|
||||
#define KI_COLOR_IDX_BUFFER_INDEX 1
|
||||
#define KI_STATE_BUFFER_INDEX 2
|
||||
|
||||
// States from indicator
|
||||
#define BULLISH_STATE 1
|
||||
#define NEUTURAL_STATE 0
|
||||
#define BEARISH_STATE -1
|
||||
|
||||
// Globals
|
||||
int g_digits;
|
||||
double g_point;
|
||||
MqlTick g_tick;
|
||||
int g_atrHandleH1 = INVALID_HANDLE;
|
||||
int g_atrHandleH4 = INVALID_HANDLE;
|
||||
int g_atrHandleD1 = INVALID_HANDLE;
|
||||
int g_rsiHandleH1 = INVALID_HANDLE;
|
||||
int g_rsiHandleH4 = INVALID_HANDLE;
|
||||
int g_rsiHandleD1 = INVALID_HANDLE;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// OnInit
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
g_digits = (int)SymbolInfoInteger(InpSymbol, SYMBOL_DIGITS);
|
||||
g_point = SymbolInfoDouble(InpSymbol, SYMBOL_POINT);
|
||||
|
||||
if (!SymbolInfoTick(InpSymbol, g_tick))
|
||||
{
|
||||
Print("Failed to get tick for symbol: ", InpSymbol);
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
// Quick validation
|
||||
if (InpKiLength < 5)
|
||||
{
|
||||
Print("Invalid KI length: ", InpKiLength);
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
GetOrCreateATRHandle(InpSymbol, InpSignalTF, InpATRPeriod);
|
||||
if (InpUseH4Filter)
|
||||
GetOrCreateATRHandle(InpSymbol, PERIOD_H4, InpATRPeriod);
|
||||
if (InpUseD1Filter)
|
||||
GetOrCreateATRHandle(InpSymbol, PERIOD_D1, InpATRPeriod);
|
||||
|
||||
//
|
||||
GetOrCreateRSIHandle(InpSymbol, InpSignalTF, InpRSIPeriod, InpRSIPrice);
|
||||
if (InpUseH4Filter)
|
||||
GetOrCreateRSIHandle(InpSymbol, PERIOD_H4, InpRSIPeriod, InpRSIPrice);
|
||||
if (InpUseD1Filter)
|
||||
GetOrCreateRSIHandle(InpSymbol, PERIOD_D1, InpRSIPeriod, InpRSIPrice);
|
||||
|
||||
//
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// OnDeinit
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
if (g_atrHandleH1 != INVALID_HANDLE)
|
||||
{
|
||||
IndicatorRelease(g_atrHandleH1);
|
||||
g_atrHandleH1 = INVALID_HANDLE;
|
||||
}
|
||||
if (g_atrHandleH4 != INVALID_HANDLE)
|
||||
{
|
||||
IndicatorRelease(g_atrHandleH4);
|
||||
g_atrHandleH4 = INVALID_HANDLE;
|
||||
}
|
||||
if (g_atrHandleD1 != INVALID_HANDLE)
|
||||
{
|
||||
IndicatorRelease(g_atrHandleD1);
|
||||
g_atrHandleD1 = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
//
|
||||
if (g_rsiHandleH1 != INVALID_HANDLE)
|
||||
{
|
||||
IndicatorRelease(g_rsiHandleH1);
|
||||
g_rsiHandleH1 = INVALID_HANDLE;
|
||||
}
|
||||
if (g_rsiHandleH4 != INVALID_HANDLE)
|
||||
{
|
||||
IndicatorRelease(g_rsiHandleH4);
|
||||
g_rsiHandleH4 = INVALID_HANDLE;
|
||||
}
|
||||
if (g_rsiHandleD1 != INVALID_HANDLE)
|
||||
{
|
||||
IndicatorRelease(g_rsiHandleD1);
|
||||
g_rsiHandleD1 = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// OnTick
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
if (_Symbol != InpSymbol)
|
||||
return;
|
||||
|
||||
// Basic trading safety
|
||||
if (!SymbolInfoTick(InpSymbol, g_tick))
|
||||
return;
|
||||
double spreadPoints = GetSpread(InpSymbol);
|
||||
if (spreadPoints > InpMaxSpreadPoints)
|
||||
return;
|
||||
|
||||
if (InpAvoidAsianSession)
|
||||
{
|
||||
//
|
||||
MqlDateTime now = GetCurrentTime();
|
||||
int hr = now.hour;
|
||||
if (IsHourInRange(hr, InpAsianStartHour, InpAsianEndHour))
|
||||
return;
|
||||
}
|
||||
|
||||
if (InpAvoidNewsWindow)
|
||||
{
|
||||
// Placeholder: implement your own calendar integration
|
||||
// Skip trading in a window near news. Here we simply return.
|
||||
return;
|
||||
}
|
||||
|
||||
// Only process on new bar of signal timeframe
|
||||
static datetime lastSignalBarTime = 0;
|
||||
datetime currentSignalBarTime = GetLastClosedBarTime(InpSymbol, InpSignalTF);
|
||||
if (currentSignalBarTime == 0 || currentSignalBarTime == lastSignalBarTime)
|
||||
return;
|
||||
lastSignalBarTime = currentSignalBarTime;
|
||||
|
||||
// Get signal state and KI on signal TF (last closed bar)
|
||||
int signalBarShift = InpBarsLookbackSignal; // 1=last closed, 2=previous
|
||||
int stateSignal;
|
||||
double kiSignal, closeSignal;
|
||||
if (!GetXKIStateAndKI(InpSymbol, InpSignalTF, signalBarShift, stateSignal, kiSignal))
|
||||
return;
|
||||
closeSignal = iClose(InpSymbol, InpSignalTF, signalBarShift);
|
||||
|
||||
// RSI confirmation
|
||||
if (InpUseRSI)
|
||||
{
|
||||
double rsi = GetRSIValue(InpSymbol, InpSignalTF, InpRSIPeriod, InpRSIPrice, signalBarShift);
|
||||
if (rsi == EMPTY_VALUE)
|
||||
return;
|
||||
if (stateSignal == BULLISH_STATE && rsi <= 50.0)
|
||||
return;
|
||||
if (stateSignal == BEARISH_STATE && rsi >= 50.0)
|
||||
return;
|
||||
}
|
||||
|
||||
// Higher timeframe agreement
|
||||
bool agreesH4 = true, agreesD1 = true;
|
||||
if (InpUseH4Filter)
|
||||
agreesH4 = HigherTFAgrees(InpSymbol, PERIOD_H4, signalBarShift, stateSignal);
|
||||
if (InpUseD1Filter)
|
||||
agreesD1 = HigherTFAgrees(InpSymbol, PERIOD_D1, signalBarShift, stateSignal);
|
||||
|
||||
bool filterOK = true;
|
||||
if (InpUseH4Filter || InpUseD1Filter)
|
||||
{
|
||||
if (InpRequireBothFilters)
|
||||
filterOK = (agreesH4 && agreesD1);
|
||||
else
|
||||
filterOK = ((InpUseH4Filter && agreesH4) || (InpUseD1Filter && agreesD1));
|
||||
}
|
||||
if (!filterOK)
|
||||
return;
|
||||
|
||||
// Neutral or invalid skip
|
||||
if (stateSignal == NEUTURAL_STATE)
|
||||
return;
|
||||
|
||||
// Ensure no open positions for this symbol/magic
|
||||
if (HasOpenPosition(InpSymbol, InpMagic))
|
||||
return;
|
||||
|
||||
// Prepare trade params
|
||||
double atrPad = 0.0;
|
||||
if (InpRiskATRMult > 0.0)
|
||||
{
|
||||
double atr = GetATRValue(InpSymbol, InpSignalTF, InpATRPeriod, signalBarShift);
|
||||
if (atr != EMPTY_VALUE && atr > 0)
|
||||
atrPad = atr * InpRiskATRMult;
|
||||
}
|
||||
|
||||
double sl, tp;
|
||||
bool isBuy = (stateSignal == BULLISH_STATE);
|
||||
if (isBuy)
|
||||
{
|
||||
sl = kiSignal - atrPad;
|
||||
tp = closeSignal + (closeSignal - sl) * InpRR;
|
||||
PlaceOrder(InpSymbol, ORDER_TYPE_BUY, InpFixedLot, sl, tp);
|
||||
}
|
||||
else if (stateSignal == BEARISH_STATE)
|
||||
{
|
||||
sl = kiSignal + atrPad;
|
||||
tp = closeSignal - (sl - closeSignal) * InpRR;
|
||||
PlaceOrder(InpSymbol, ORDER_TYPE_SELL, InpFixedLot, sl, tp);
|
||||
}
|
||||
|
||||
// After placement, trailing handled in OnTimer or OnTick below
|
||||
if (InpTrailByKI)
|
||||
TrailStopsByKI();
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// Utilities
|
||||
//+------------------------------------------------------------------+
|
||||
//
|
||||
// Create or reuse an ATR handle for the given TF ...
|
||||
int GetOrCreateATRHandle(
|
||||
string symbol,
|
||||
ENUM_TIMEFRAMES tf,
|
||||
int period //
|
||||
)
|
||||
{
|
||||
int h = g_atrHandleH1;
|
||||
if (tf == PERIOD_H4)
|
||||
h = g_atrHandleH4;
|
||||
else if (tf == PERIOD_D1)
|
||||
h = g_atrHandleD1;
|
||||
if (h == INVALID_HANDLE)
|
||||
{
|
||||
h = iATR(symbol, tf, period);
|
||||
if (h == INVALID_HANDLE)
|
||||
Print("Failed to create ATR handle: ", symbol, " ", EnumToString(tf), " period=", period);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
//
|
||||
// Read ATR value for a specific bar shift (1=last closed bar) ...
|
||||
double GetATRValue(
|
||||
string symbol,
|
||||
ENUM_TIMEFRAMES tf,
|
||||
int period,
|
||||
int shift //
|
||||
)
|
||||
{
|
||||
int h = GetOrCreateATRHandle(symbol, tf, period);
|
||||
if (h == INVALID_HANDLE)
|
||||
return EMPTY_VALUE;
|
||||
|
||||
//
|
||||
double buff[];
|
||||
|
||||
//
|
||||
// Copy exactly one value at 'shift' ...
|
||||
int copied = CopyBuffer(h, 0, shift, 1, buff);
|
||||
if (copied != 1 || !MathIsValidNumber(buff[0]))
|
||||
return EMPTY_VALUE;
|
||||
|
||||
//
|
||||
return buff[0];
|
||||
}
|
||||
|
||||
//
|
||||
// Create or reuse an RSI handle for the given TF ...
|
||||
int GetOrCreateRSIHandle(
|
||||
string symbol,
|
||||
ENUM_TIMEFRAMES tf,
|
||||
int period,
|
||||
int appliedPrice //
|
||||
)
|
||||
{
|
||||
//
|
||||
int h = g_rsiHandleH1;
|
||||
if (tf == PERIOD_H4)
|
||||
h = g_rsiHandleH4;
|
||||
else if (tf == PERIOD_D1)
|
||||
h = g_rsiHandleD1;
|
||||
if (h == INVALID_HANDLE)
|
||||
{
|
||||
h = iRSI(symbol, tf, period, appliedPrice);
|
||||
if (h == INVALID_HANDLE)
|
||||
Print("Failed to create RSI handle: ", symbol, " ", EnumToString(tf), " period=", period, " price=", appliedPrice);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
//
|
||||
// Read RSI value for a specific bar shift (1=last closed bar) ..
|
||||
double GetRSIValue(
|
||||
string symbol,
|
||||
ENUM_TIMEFRAMES tf,
|
||||
int period,
|
||||
int appliedPrice,
|
||||
int shift //
|
||||
)
|
||||
{
|
||||
int h = GetOrCreateRSIHandle(symbol, tf, period, appliedPrice);
|
||||
if (h == INVALID_HANDLE)
|
||||
return EMPTY_VALUE;
|
||||
double buff[];
|
||||
int copied = CopyBuffer(h, 0, shift, 1, buff);
|
||||
if (copied != 1 || !MathIsValidNumber(buff[0]))
|
||||
return EMPTY_VALUE;
|
||||
return buff[0];
|
||||
}
|
||||
|
||||
datetime GetLastClosedBarTime(string symbol, ENUM_TIMEFRAMES tf)
|
||||
{
|
||||
datetime times[];
|
||||
if (CopyTime(symbol, tf, 0, 3, times) <= 1)
|
||||
return 0;
|
||||
// times[0] is current open bar time; last closed is times[1]
|
||||
return times[1];
|
||||
}
|
||||
|
||||
bool IsHourInRange(int hr, int startHr, int endHr)
|
||||
{
|
||||
// Handles wrap-around (e.g., 22 -> 6)
|
||||
if (startHr <= endHr)
|
||||
return (hr >= startHr && hr < endHr);
|
||||
else
|
||||
return (hr >= startHr || hr < endHr);
|
||||
}
|
||||
|
||||
bool GetXKIStateAndKI(string symbol, ENUM_TIMEFRAMES tf, int shift, int &stateOut, double &kiOut)
|
||||
{
|
||||
// Prepare indicator handle for this TF
|
||||
static int handleH1 = INVALID_HANDLE;
|
||||
static int handleH4 = INVALID_HANDLE;
|
||||
static int handleD1 = INVALID_HANDLE;
|
||||
|
||||
int handleRef = handleH1;
|
||||
if (tf == PERIOD_H4)
|
||||
handleRef = handleH4;
|
||||
else if (tf == PERIOD_D1)
|
||||
handleRef = handleD1;
|
||||
|
||||
if (handleRef == INVALID_HANDLE)
|
||||
{
|
||||
handleRef = iCustom(symbol, tf, g_xkiIndicatorPath,
|
||||
InpKiLength, InpShowKI, InpCalcLastBars);
|
||||
if (handleRef == INVALID_HANDLE)
|
||||
{
|
||||
Print("Failed to create XKI handle for TF: ", EnumToString(tf));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
double kiBuff[];
|
||||
double stateBuff[];
|
||||
|
||||
if (CopyBuffer(handleRef, KI_BUFFER_INDEX, shift, 1, kiBuff) != 1)
|
||||
return false;
|
||||
if (CopyBuffer(handleRef, KI_STATE_BUFFER_INDEX, shift, 1, stateBuff) != 1)
|
||||
return false;
|
||||
|
||||
kiOut = kiBuff[0];
|
||||
stateOut = (int)stateBuff[0];
|
||||
|
||||
if (!MathIsValidNumber(kiOut))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HigherTFAgrees(string symbol, ENUM_TIMEFRAMES tf, int shift, int signalState)
|
||||
{
|
||||
int stateHTF;
|
||||
double kiHTF;
|
||||
if (!GetXKIStateAndKI(symbol, tf, shift, stateHTF, kiHTF))
|
||||
return false;
|
||||
if (signalState == BULLISH_STATE)
|
||||
return (stateHTF == BULLISH_STATE);
|
||||
if (signalState == BEARISH_STATE)
|
||||
return (stateHTF == BEARISH_STATE);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasOpenPosition(string symbol, int magic)
|
||||
{
|
||||
for (int i = 0; i < PositionsTotal(); i++)
|
||||
{
|
||||
ulong ticket = PositionGetTicket(i);
|
||||
if (ticket == 0)
|
||||
continue;
|
||||
if (PositionSelectByTicket(ticket))
|
||||
{
|
||||
string sym = PositionGetString(POSITION_SYMBOL);
|
||||
long mg = (long)PositionGetInteger(POSITION_MAGIC);
|
||||
if (sym == symbol && mg == magic)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PlaceOrder(string symbol, ENUM_ORDER_TYPE type, double lots, double sl, double tp)
|
||||
{
|
||||
MqlTradeRequest req;
|
||||
MqlTradeResult res;
|
||||
ZeroMemory(req);
|
||||
ZeroMemory(res);
|
||||
|
||||
double price = 0.0;
|
||||
if (!SymbolInfoTick(symbol, g_tick))
|
||||
return;
|
||||
|
||||
if (type == ORDER_TYPE_BUY)
|
||||
price = g_tick.ask;
|
||||
else if (type == ORDER_TYPE_SELL)
|
||||
price = g_tick.bid;
|
||||
|
||||
// Normalize SL/TP
|
||||
sl = NormalizeDouble(sl, g_digits);
|
||||
tp = NormalizeDouble(tp, g_digits);
|
||||
price = NormalizeDouble(price, g_digits);
|
||||
|
||||
req.action = TRADE_ACTION_DEAL;
|
||||
req.symbol = symbol;
|
||||
req.volume = lots;
|
||||
req.type = type;
|
||||
req.price = price;
|
||||
req.sl = sl;
|
||||
req.tp = tp;
|
||||
req.deviation = InpSlippagePoints;
|
||||
req.magic = InpMagic;
|
||||
req.comment = InpOrderComment;
|
||||
|
||||
if (!OrderSend(req, res))
|
||||
Print("OrderSend failed: ", res.retcode);
|
||||
}
|
||||
|
||||
void TrailStopsByKI()
|
||||
{
|
||||
// Trail per position using current signal TF KI
|
||||
for (int i = 0; i < PositionsTotal(); i++)
|
||||
{
|
||||
ulong ticket = PositionGetTicket(i);
|
||||
if (ticket == 0)
|
||||
continue;
|
||||
if (!PositionSelectByTicket(ticket))
|
||||
continue;
|
||||
|
||||
string sym = PositionGetString(POSITION_SYMBOL);
|
||||
long mg = (long)PositionGetInteger(POSITION_MAGIC);
|
||||
if (sym != InpSymbol || mg != InpMagic)
|
||||
continue;
|
||||
|
||||
ENUM_POSITION_TYPE ptype = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
||||
double sl = PositionGetDouble(POSITION_SL);
|
||||
double priceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
|
||||
|
||||
// Use last closed bar KI for stability
|
||||
int shift = 1;
|
||||
int state;
|
||||
double ki;
|
||||
if (!GetXKIStateAndKI(sym, InpSignalTF, shift, state, ki))
|
||||
continue;
|
||||
|
||||
MqlTradeRequest req;
|
||||
MqlTradeResult res;
|
||||
ZeroMemory(req);
|
||||
ZeroMemory(res);
|
||||
|
||||
double newSL = sl;
|
||||
|
||||
if (ptype == POSITION_TYPE_BUY)
|
||||
{
|
||||
double proposedSL = NormalizeDouble(ki, g_digits);
|
||||
if (proposedSL > sl)
|
||||
newSL = proposedSL; // only move up
|
||||
}
|
||||
else if (ptype == POSITION_TYPE_SELL)
|
||||
{
|
||||
double proposedSL = NormalizeDouble(ki, g_digits);
|
||||
if (proposedSL < sl || sl == 0.0)
|
||||
newSL = proposedSL; // only move down (or set if none)
|
||||
}
|
||||
|
||||
if (newSL != sl && newSL != 0.0)
|
||||
{
|
||||
req.action = TRADE_ACTION_SLTP;
|
||||
req.symbol = sym;
|
||||
req.sl = newSL;
|
||||
req.tp = PositionGetDouble(POSITION_TP);
|
||||
req.magic = InpMagic;
|
||||
|
||||
if (!OrderSend(req, res))
|
||||
Print("Trail SLTP failed: ", res.retcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,708 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TrendPullbackPro.mq5|
|
||||
//| Trend-following pullback EA with risk & management |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Hadi Strategy"
|
||||
#property link ""
|
||||
#property version "1.10"
|
||||
#property strict
|
||||
|
||||
//--- Inputs: risk & money management
|
||||
input double InpRiskPerTradePercent = 1.0; // Total risk per trade (% of balance)
|
||||
input int InpMagicNumber = 123456; // Magic number
|
||||
input double InpStopBufferPoints = 10; // Extra buffer beyond swing high/low (points)
|
||||
|
||||
//--- Inputs: indicators
|
||||
input ENUM_TIMEFRAMES InpTF = PERIOD_CURRENT; // Signal timeframe
|
||||
input int InpFastEMAPeriod = 20;
|
||||
input int InpSlowEMAPeriod = 50;
|
||||
input int InpRSIPeriod = 14;
|
||||
input double InpRSILowZoneMin = 40; // Uptrend pullback zone min
|
||||
input double InpRSILowZoneMax = 50; // Uptrend pullback zone max
|
||||
input double InpRSIHighZoneMin = 50; // Downtrend pullback zone min
|
||||
input double InpRSIHighZoneMax = 60; // Downtrend pullback zone max
|
||||
|
||||
//--- Inputs: partial TP and R multiples
|
||||
input bool InpUsePartialTP = true;
|
||||
input double InpPartialCloseAtR = 1.0; // R at which to take partial profit
|
||||
input double InpPartialClosePercent = 50.0; // % of volume to close at partial TP
|
||||
input double InpFinalTargetR = 3.0; // Final target R for runner
|
||||
input bool InpUseBreakEven = true;
|
||||
input double InpBreakEvenRMultiple = 1.0; // Move SL to BE at this R (runner)
|
||||
|
||||
//--- Inputs: trailing stop
|
||||
input bool InpUseEMATrailing = true;
|
||||
input double InpTrailStartR = 1.0; // Start trailing after this R
|
||||
input double InpTrailOffsetPoints = 5; // Extra buffer beyond EMA (points)
|
||||
|
||||
//--- Inputs: spread & time filters
|
||||
input bool InpUseSpreadFilter = true;
|
||||
input double InpMaxSpreadPoints = 30; // Max allowed spread (in points)
|
||||
|
||||
input bool InpUseTimeFilter = false;
|
||||
input int InpSessionStartHour = 8; // Trading session start (server time)
|
||||
input int InpSessionEndHour = 22; // Trading session end (server time)
|
||||
input bool InpAvoidRolloverHour = true;
|
||||
input int InpRolloverHour = 23; // Avoid new entries at this hour
|
||||
|
||||
//--- constants
|
||||
#define NO_TREND 0
|
||||
#define UPTREND 1
|
||||
#define DOWNTREND -1
|
||||
|
||||
#define PARTIAL_COMMENT "TrendPullbackEA_Partial"
|
||||
#define RUNNER_COMMENT "TrendPullbackEA_Runner"
|
||||
|
||||
//--- Global indicator handles
|
||||
int rsi_handle;
|
||||
int ema_fast_handle;
|
||||
int ema_slow_handle;
|
||||
|
||||
//--- Tick storage
|
||||
MqlTick last_tick;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnInit |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
rsi_handle = iRSI(_Symbol, InpTF, InpRSIPeriod, PRICE_CLOSE);
|
||||
if(rsi_handle == INVALID_HANDLE)
|
||||
{
|
||||
Print("Error creating RSI handle. Error: ", GetLastError());
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
ema_fast_handle = iMA(_Symbol, InpTF, InpFastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
|
||||
if(ema_fast_handle == INVALID_HANDLE)
|
||||
{
|
||||
Print("Error creating fast EMA handle. Error: ", GetLastError());
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
ema_slow_handle = iMA(_Symbol, InpTF, InpSlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
|
||||
if(ema_slow_handle == INVALID_HANDLE)
|
||||
{
|
||||
Print("Error creating slow EMA handle. Error: ", GetLastError());
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
SymbolInfoTick(_Symbol, last_tick);
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnDeinit |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
IndicatorRelease(rsi_handle);
|
||||
IndicatorRelease(ema_fast_handle);
|
||||
IndicatorRelease(ema_slow_handle);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnTick |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
if(!SymbolInfoTick(_Symbol, last_tick))
|
||||
return;
|
||||
|
||||
// Run main logic once per bar on signal timeframe
|
||||
static datetime last_bar_time = 0;
|
||||
datetime cur_bar_time = iTime(_Symbol, InpTF, 0);
|
||||
if(cur_bar_time == last_bar_time)
|
||||
return;
|
||||
last_bar_time = cur_bar_time;
|
||||
|
||||
ManageOpenPositions();
|
||||
|
||||
// Avoid new entries if no time/spread conditions
|
||||
if(!CanOpenNewTrades())
|
||||
return;
|
||||
|
||||
CheckOpenSignals();
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check if we can open new trades (time & spread) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CanOpenNewTrades()
|
||||
{
|
||||
// Spread filter
|
||||
if(InpUseSpreadFilter)
|
||||
{
|
||||
double spread_points = (SymbolInfoDouble(_Symbol, SYMBOL_ASK) - SymbolInfoDouble(_Symbol, SYMBOL_BID))
|
||||
/ SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
||||
if(spread_points > InpMaxSpreadPoints)
|
||||
{
|
||||
//Print("Spread too high: ", spread_points, " > ", InpMaxSpreadPoints);
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Time filter
|
||||
if(InpUseTimeFilter)
|
||||
{
|
||||
datetime now = TimeCurrent();
|
||||
MqlDateTime dt;
|
||||
TimeToStruct(now, dt);
|
||||
|
||||
// avoid rollover hour
|
||||
if(InpAvoidRolloverHour && dt.hour == InpRolloverHour)
|
||||
return(false);
|
||||
|
||||
// session window
|
||||
bool inSession = (dt.hour >= InpSessionStartHour && dt.hour < InpSessionEndHour);
|
||||
if(!inSession)
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check for new entry signals |
|
||||
//+------------------------------------------------------------------+
|
||||
void CheckOpenSignals()
|
||||
{
|
||||
if(HasOpenPosition())
|
||||
return;
|
||||
|
||||
int trend = GetTrendDirection();
|
||||
if(trend == NO_TREND)
|
||||
return;
|
||||
|
||||
double rsi_value;
|
||||
if(!GetRSI(1, rsi_value))
|
||||
return;
|
||||
|
||||
MqlRates rates[];
|
||||
if(CopyRates(_Symbol, InpTF, 0, 3, rates) < 3)
|
||||
return;
|
||||
// rates[0] current, [1] closed 1, [2] closed 2
|
||||
MqlRates candle = rates[1];
|
||||
MqlRates prev = rates[2];
|
||||
|
||||
bool longSignal = false;
|
||||
bool shortSignal = false;
|
||||
|
||||
if(trend == UPTREND)
|
||||
{
|
||||
if(rsi_value >= InpRSILowZoneMin && rsi_value <= InpRSILowZoneMax)
|
||||
{
|
||||
if(IsBullishPattern(candle, prev))
|
||||
longSignal = true;
|
||||
}
|
||||
}
|
||||
else if(trend == DOWNTREND)
|
||||
{
|
||||
if(rsi_value >= InpRSIHighZoneMin && rsi_value <= InpRSIHighZoneMax)
|
||||
{
|
||||
if(IsBearishPattern(candle, prev))
|
||||
shortSignal = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(longSignal)
|
||||
OpenTrade(ORDER_TYPE_BUY, candle);
|
||||
else if(shortSignal)
|
||||
OpenTrade(ORDER_TYPE_SELL, candle);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Manage open positions (partial TP, BE, trailing) |
|
||||
//+------------------------------------------------------------------+
|
||||
void ManageOpenPositions()
|
||||
{
|
||||
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
||||
|
||||
for(int i = PositionsTotal()-1; i >= 0; i--)
|
||||
{
|
||||
ulong ticket = PositionGetTicket(i);
|
||||
if(!PositionSelectByTicket(ticket))
|
||||
continue;
|
||||
|
||||
if(PositionGetInteger(POSITION_MAGIC) != InpMagicNumber)
|
||||
continue;
|
||||
if(PositionGetString(POSITION_SYMBOL) != _Symbol)
|
||||
continue;
|
||||
|
||||
long type = PositionGetInteger(POSITION_TYPE);
|
||||
double volume = PositionGetDouble(POSITION_VOLUME);
|
||||
double sl = PositionGetDouble(POSITION_SL);
|
||||
double tp = PositionGetDouble(POSITION_TP);
|
||||
double price_open = PositionGetDouble(POSITION_PRICE_OPEN);
|
||||
string comment = PositionGetString(POSITION_COMMENT);
|
||||
|
||||
MqlTick tick;
|
||||
SymbolInfoTick(_Symbol, tick);
|
||||
double current_price = (type == POSITION_TYPE_BUY ? tick.bid : tick.ask);
|
||||
|
||||
double riskPoints;
|
||||
if(type == POSITION_TYPE_BUY)
|
||||
riskPoints = (price_open - sl) / point;
|
||||
else
|
||||
riskPoints = (sl - price_open) / point;
|
||||
|
||||
if(riskPoints <= 0)
|
||||
continue;
|
||||
|
||||
double profitPoints;
|
||||
if(type == POSITION_TYPE_BUY)
|
||||
profitPoints = (current_price - price_open) / point;
|
||||
else
|
||||
profitPoints = (price_open - current_price) / point;
|
||||
|
||||
double rMultiple = profitPoints / riskPoints;
|
||||
|
||||
// 1) Partial TP logic for "partial" leg
|
||||
if(InpUsePartialTP && comment == PARTIAL_COMMENT)
|
||||
{
|
||||
if(rMultiple >= InpPartialCloseAtR)
|
||||
{
|
||||
// Close this position fully (it's the partial leg)
|
||||
ClosePosition(ticket);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 2) Break-even & trailing for runner leg
|
||||
if(comment == RUNNER_COMMENT)
|
||||
{
|
||||
// Break-even
|
||||
if(InpUseBreakEven && rMultiple >= InpBreakEvenRMultiple)
|
||||
{
|
||||
if(type == POSITION_TYPE_BUY && sl < price_open)
|
||||
ModifyPositionSL(ticket, price_open);
|
||||
else if(type == POSITION_TYPE_SELL && sl > price_open)
|
||||
ModifyPositionSL(ticket, price_open);
|
||||
}
|
||||
|
||||
// EMA trailing after a certain R
|
||||
if(InpUseEMATrailing && rMultiple >= InpTrailStartR)
|
||||
{
|
||||
double emaFast;
|
||||
if(!GetEMA(ema_fast_handle, 1, emaFast))
|
||||
continue;
|
||||
|
||||
double newSL;
|
||||
double offset = InpTrailOffsetPoints * point;
|
||||
if(type == POSITION_TYPE_BUY)
|
||||
{
|
||||
newSL = emaFast - offset;
|
||||
if(newSL > sl && newSL < current_price) // only tighten SL
|
||||
ModifyPositionSL(ticket, newSL);
|
||||
}
|
||||
else
|
||||
{
|
||||
newSL = emaFast + offset;
|
||||
if(newSL < sl && newSL > current_price)
|
||||
ModifyPositionSL(ticket, newSL);
|
||||
}
|
||||
}
|
||||
|
||||
// Optionally: ensure TP aligns with final target R
|
||||
// If user wants to rely only on trailing, they can disable or adjust final R.
|
||||
// We keep TP as set at entry.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get trend direction from EMAs |
|
||||
//+------------------------------------------------------------------+
|
||||
int GetTrendDirection()
|
||||
{
|
||||
double ema_fast[3], ema_slow[3];
|
||||
if(CopyBuffer(ema_fast_handle, 0, 0, 3, ema_fast) < 3)
|
||||
return NO_TREND;
|
||||
if(CopyBuffer(ema_slow_handle, 0, 0, 3, ema_slow) < 3)
|
||||
return NO_TREND;
|
||||
|
||||
double fast = ema_fast[1];
|
||||
double slow = ema_slow[1];
|
||||
|
||||
if(fast > slow)
|
||||
return UPTREND;
|
||||
else if(fast < slow)
|
||||
return DOWNTREND;
|
||||
return NO_TREND;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get RSI value at bar index |
|
||||
//+------------------------------------------------------------------+
|
||||
bool GetRSI(int index, double &value)
|
||||
{
|
||||
double buffer[1];
|
||||
int copied = CopyBuffer(rsi_handle, 0, index, 1, buffer);
|
||||
if(copied != 1)
|
||||
return false;
|
||||
|
||||
value = buffer[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get EMA value from handle |
|
||||
//+------------------------------------------------------------------+
|
||||
bool GetEMA(int handle, int index, double &value)
|
||||
{
|
||||
double buffer[1];
|
||||
int copied = CopyBuffer(handle, 0, index, 1, buffer);
|
||||
if(copied != 1)
|
||||
return false;
|
||||
value = buffer[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Bullish pattern: engulfing + pin-bar-ish |
|
||||
//+------------------------------------------------------------------+
|
||||
bool IsBullishPattern(const MqlRates &c, const MqlRates &prev)
|
||||
{
|
||||
double bodyC = MathAbs(c.close - c.open);
|
||||
double bodyP = MathAbs(prev.close - prev.open);
|
||||
double rangeC = c.high - c.low;
|
||||
|
||||
if(rangeC <= 0)
|
||||
return false;
|
||||
|
||||
// Basic bullish: close > open
|
||||
if(c.close <= c.open)
|
||||
return false;
|
||||
|
||||
// Engulfing body: current body >= previous body, and covers its open/close
|
||||
bool engulfing = (bodyC >= bodyP && c.open <= prev.close && c.close >= prev.open);
|
||||
|
||||
// Pin-bar-ish: long lower wick
|
||||
double lowerWick = MathMin(c.open, c.close) - c.low;
|
||||
bool longLowerWick = (lowerWick >= rangeC * 0.4); // tweak
|
||||
|
||||
if(engulfing || longLowerWick)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Bearish pattern: engulfing + pin-bar-ish |
|
||||
//+------------------------------------------------------------------+
|
||||
bool IsBearishPattern(const MqlRates &c, const MqlRates &prev)
|
||||
{
|
||||
double bodyC = MathAbs(c.close - c.open);
|
||||
double bodyP = MathAbs(prev.close - prev.open);
|
||||
double rangeC = c.high - c.low;
|
||||
|
||||
if(rangeC <= 0)
|
||||
return false;
|
||||
|
||||
// Basic bearish: close < open
|
||||
if(c.close >= c.open)
|
||||
return false;
|
||||
|
||||
// Engulfing body
|
||||
bool engulfing = (bodyC >= bodyP && c.open >= prev.close && c.close <= prev.open);
|
||||
|
||||
// Pin-bar-ish: long upper wick
|
||||
double upperWick = c.high - MathMax(c.open, c.close);
|
||||
bool longUpperWick = (upperWick >= rangeC * 0.4); // tweak
|
||||
|
||||
if(engulfing || longUpperWick)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check if there is already an open position |
|
||||
//+------------------------------------------------------------------+
|
||||
bool HasOpenPosition()
|
||||
{
|
||||
for(int i = PositionsTotal()-1; i >= 0; i--)
|
||||
{
|
||||
ulong ticket = PositionGetTicket(i);
|
||||
if(!PositionSelectByTicket(ticket))
|
||||
continue;
|
||||
|
||||
if(PositionGetInteger(POSITION_MAGIC) != InpMagicNumber)
|
||||
continue;
|
||||
|
||||
if(PositionGetString(POSITION_SYMBOL) == _Symbol)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate lot size based on total risk % |
|
||||
//+------------------------------------------------------------------+
|
||||
double CalculateTotalVolume(double stopLossPrice, ENUM_ORDER_TYPE type)
|
||||
{
|
||||
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
||||
double riskMoney = balance * InpRiskPerTradePercent / 100.0;
|
||||
|
||||
double entryPrice = (type == ORDER_TYPE_BUY ? last_tick.ask : last_tick.bid);
|
||||
|
||||
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
||||
double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
||||
double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
|
||||
|
||||
if(tick_size <= 0 || tick_value <= 0)
|
||||
return(0.0);
|
||||
|
||||
double slDistance = (type == ORDER_TYPE_BUY ? entryPrice - stopLossPrice : stopLossPrice - entryPrice);
|
||||
if(slDistance <= 0)
|
||||
return(0.0);
|
||||
|
||||
double moneyPerPointPerLot = tick_value / tick_size * point;
|
||||
double stopPoints = slDistance / point;
|
||||
|
||||
double volume = riskMoney / (stopPoints * moneyPerPointPerLot);
|
||||
|
||||
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double lotStep= SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
||||
|
||||
volume = MathFloor(volume / lotStep) * lotStep;
|
||||
|
||||
if(volume < minLot)
|
||||
volume = 0.0;
|
||||
if(volume > maxLot)
|
||||
volume = maxLot;
|
||||
|
||||
return(volume);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Open trade: split into partial + runner |
|
||||
//+------------------------------------------------------------------+
|
||||
void OpenTrade(ENUM_ORDER_TYPE type, const MqlRates &signalCandle)
|
||||
{
|
||||
MqlTick tick;
|
||||
if(!SymbolInfoTick(_Symbol, tick))
|
||||
return;
|
||||
|
||||
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
||||
double entryPrice = (type == ORDER_TYPE_BUY ? tick.ask : tick.bid);
|
||||
|
||||
double slPrice;
|
||||
if(type == ORDER_TYPE_BUY)
|
||||
slPrice = signalCandle.low - InpStopBufferPoints * point;
|
||||
else
|
||||
slPrice = signalCandle.high + InpStopBufferPoints * point;
|
||||
|
||||
if(slPrice <= 0)
|
||||
return;
|
||||
|
||||
double totalVolume = CalculateTotalVolume(slPrice, type);
|
||||
if(totalVolume <= 0)
|
||||
{
|
||||
Print("Calculated total volume <= 0, skipping trade.");
|
||||
return;
|
||||
}
|
||||
|
||||
double slDistance = (type == ORDER_TYPE_BUY ? entryPrice - slPrice : slPrice - entryPrice);
|
||||
|
||||
// final TP at FinalTargetR
|
||||
double finalTPDistance = slDistance * InpFinalTargetR;
|
||||
double runnerTP;
|
||||
if(type == ORDER_TYPE_BUY)
|
||||
runnerTP = entryPrice + finalTPDistance;
|
||||
else
|
||||
runnerTP = entryPrice - finalTPDistance;
|
||||
|
||||
// partial volume
|
||||
double partialVolume = totalVolume;
|
||||
double runnerVolume = 0.0;
|
||||
|
||||
if(InpUsePartialTP && InpPartialClosePercent > 0 && InpPartialClosePercent < 100)
|
||||
{
|
||||
partialVolume = totalVolume * (InpPartialClosePercent / 100.0);
|
||||
runnerVolume = totalVolume - partialVolume;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no partial: everything is runner
|
||||
partialVolume = 0.0;
|
||||
runnerVolume = totalVolume;
|
||||
}
|
||||
|
||||
// normalized volumes
|
||||
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
||||
partialVolume = MathFloor(partialVolume / lotStep) * lotStep;
|
||||
runnerVolume = MathFloor(runnerVolume / lotStep) * lotStep;
|
||||
|
||||
if(partialVolume < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))
|
||||
partialVolume = 0.0;
|
||||
if(runnerVolume < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))
|
||||
runnerVolume = 0.0;
|
||||
|
||||
// Partial TP price at PartialCloseAtR
|
||||
double partialTPPrice = 0.0;
|
||||
if(InpUsePartialTP && partialVolume > 0 && InpPartialCloseAtR > 0)
|
||||
{
|
||||
double partialTPDist = slDistance * InpPartialCloseAtR;
|
||||
if(type == ORDER_TYPE_BUY)
|
||||
partialTPPrice = entryPrice + partialTPDist;
|
||||
else
|
||||
partialTPPrice = entryPrice - partialTPDist;
|
||||
}
|
||||
|
||||
// 1) Open partial leg
|
||||
if(partialVolume > 0.0)
|
||||
{
|
||||
SendOrder(type, partialVolume, slPrice, partialTPPrice, PARTIAL_COMMENT);
|
||||
}
|
||||
|
||||
// 2) Open runner leg
|
||||
if(runnerVolume > 0.0)
|
||||
{
|
||||
SendOrder(type, runnerVolume, slPrice, runnerTP, RUNNER_COMMENT);
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Send market order |
|
||||
//+------------------------------------------------------------------+
|
||||
bool SendOrder(ENUM_ORDER_TYPE type, double volume, double sl, double tp, string comment)
|
||||
{
|
||||
if(volume <= 0.0)
|
||||
return(false);
|
||||
|
||||
MqlTick tick;
|
||||
if(!SymbolInfoTick(_Symbol, tick))
|
||||
return(false);
|
||||
|
||||
MqlTradeRequest request;
|
||||
MqlTradeResult result;
|
||||
ZeroMemory(request);
|
||||
ZeroMemory(result);
|
||||
|
||||
request.action = TRADE_ACTION_DEAL;
|
||||
request.magic = InpMagicNumber;
|
||||
request.symbol = _Symbol;
|
||||
request.volume = volume;
|
||||
request.type = type;
|
||||
request.deviation = 20; // points
|
||||
request.type_filling= ORDER_FILLING_FOK;
|
||||
request.price = (type == ORDER_TYPE_BUY ? tick.ask : tick.bid);
|
||||
request.sl = sl;
|
||||
request.tp = tp;
|
||||
request.comment = comment;
|
||||
|
||||
if(!OrderSend(request, result))
|
||||
{
|
||||
Print("OrderSend failed. Error: ", GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(result.retcode != TRADE_RETCODE_DONE)
|
||||
{
|
||||
Print("OrderSend retcode: ", result.retcode);
|
||||
return(false);
|
||||
}
|
||||
|
||||
Print("Opened ", (type == ORDER_TYPE_BUY ? "BUY" : "SELL"),
|
||||
" ticket #", result.order, " vol=", DoubleToString(volume,2),
|
||||
" SL=", DoubleToString(sl,_Digits)," TP=", DoubleToString(tp,_Digits),
|
||||
" comment=", comment);
|
||||
return(true);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Modify SL for position |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ModifyPositionSL(ulong ticket, double newSL)
|
||||
{
|
||||
if(!PositionSelectByTicket(ticket))
|
||||
return(false);
|
||||
|
||||
string sym = PositionGetString(POSITION_SYMBOL);
|
||||
long type = PositionGetInteger(POSITION_TYPE);
|
||||
double volume = PositionGetDouble(POSITION_VOLUME);
|
||||
double price = PositionGetDouble(POSITION_PRICE_OPEN);
|
||||
double tp = PositionGetDouble(POSITION_TP);
|
||||
|
||||
MqlTradeRequest request;
|
||||
MqlTradeResult result;
|
||||
ZeroMemory(request);
|
||||
ZeroMemory(result);
|
||||
|
||||
request.action = TRADE_ACTION_SLTP;
|
||||
request.magic = InpMagicNumber;
|
||||
request.symbol = sym;
|
||||
request.volume = volume;
|
||||
request.type = (ENUM_ORDER_TYPE)type;
|
||||
request.price = price;
|
||||
request.sl = newSL;
|
||||
request.tp = tp;
|
||||
|
||||
if(!OrderSend(request, result))
|
||||
{
|
||||
Print("ModifyPositionSL OrderSend failed. Error: ", GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(result.retcode != TRADE_RETCODE_DONE)
|
||||
{
|
||||
Print("ModifyPositionSL retcode: ", result.retcode);
|
||||
return(false);
|
||||
}
|
||||
|
||||
Print("Modified SL for ticket #", ticket, " to ", DoubleToString(newSL,_Digits));
|
||||
return(true);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Close position |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ClosePosition(ulong ticket)
|
||||
{
|
||||
if(!PositionSelectByTicket(ticket))
|
||||
return(false);
|
||||
|
||||
string sym = PositionGetString(POSITION_SYMBOL);
|
||||
long type = PositionGetInteger(POSITION_TYPE);
|
||||
double volume = PositionGetDouble(POSITION_VOLUME);
|
||||
double price = 0.0;
|
||||
|
||||
MqlTick tick;
|
||||
if(!SymbolInfoTick(sym, tick))
|
||||
return(false);
|
||||
|
||||
if(type == POSITION_TYPE_BUY)
|
||||
price = tick.bid;
|
||||
else
|
||||
price = tick.ask;
|
||||
|
||||
MqlTradeRequest request;
|
||||
MqlTradeResult result;
|
||||
ZeroMemory(request);
|
||||
ZeroMemory(result);
|
||||
|
||||
request.action = TRADE_ACTION_DEAL;
|
||||
request.magic = InpMagicNumber;
|
||||
request.symbol = sym;
|
||||
request.volume = volume;
|
||||
request.type = (type == POSITION_TYPE_BUY ? ORDER_TYPE_SELL : ORDER_TYPE_BUY);
|
||||
request.price = price;
|
||||
request.deviation = 20;
|
||||
request.type_filling= ORDER_FILLING_FOK;
|
||||
request.comment = "Close";
|
||||
|
||||
if(!OrderSend(request, result))
|
||||
{
|
||||
Print("ClosePosition OrderSend failed. Error: ", GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(result.retcode != TRADE_RETCODE_DONE)
|
||||
{
|
||||
Print("ClosePosition retcode: ", result.retcode);
|
||||
return(false);
|
||||
}
|
||||
|
||||
Print("Closed ticket #", ticket);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,525 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| XRR_Pullback.mq5 |
|
||||
//| Author: Hadi (for XAUUSD,M15) |
|
||||
//+------------------------------------------------------------------+
|
||||
#property strict
|
||||
#property version "0.1"
|
||||
#property description "M15 pullback EA: Major zone (HH/LL), minor same-direction zone, pullback entry, SL under minor, TP at 2R, 1% risk."
|
||||
|
||||
//------------------------------- Inputs -----------------------------
|
||||
|
||||
input string Inp_Symbol = "XAUUSD";
|
||||
input ENUM_TIMEFRAMES Inp_WorkTF = PERIOD_M15;
|
||||
|
||||
// Zone detection params
|
||||
input int Inp_MajorLookbackBars = 400; // bars to scan for HH/LL major zone
|
||||
input int Inp_MinorWindowBars = 80; // window to find first same-direction minor zone post-major
|
||||
input int Inp_ZonePadPoints = 50; // padding around zones (points)
|
||||
|
||||
// Confirmation / filters
|
||||
input bool Inp_UseHTFConfluence = true;
|
||||
input ENUM_TIMEFRAMES Inp_HTF = PERIOD_H1; // confluence timeframe
|
||||
input int Inp_HTFShiftBars = 3; // HTF confirmation window
|
||||
input bool Inp_UseEngulfingConfirm = true;
|
||||
input bool Inp_UseRSIDivergence = false;
|
||||
input int Inp_RSI_Period = 14;
|
||||
input bool Inp_UseVolumeSpike = false;
|
||||
input double Inp_VolSpikeFactor = 1.5; // vs 20-bar average
|
||||
|
||||
// Risk management
|
||||
input double Inp_RiskPercent = 1.0; // 1% per trade
|
||||
input bool Inp_UseATRforSL = false;
|
||||
input int Inp_ATR_Period = 14;
|
||||
input double Inp_ATR_Mult = 1.5;
|
||||
input double Inp_MinSLPoints = 200; // floor SL (points)
|
||||
input double Inp_R_MultipleTP = 2.0; // fixed R:R=1:2
|
||||
|
||||
// Risk-free (optional)
|
||||
input bool Inp_MoveToBEatTP1 = true;
|
||||
input double Inp_TP1_R = 1.0; // move to BE at 1R
|
||||
input double Inp_BE_OffsetPoints = 10; // lock-in small +offset
|
||||
|
||||
// Sessions
|
||||
input bool Inp_UseSessionFilter = true;
|
||||
input int Inp_LondonOpenHour = 8; // broker time
|
||||
input int Inp_LondonCloseHour = 17;
|
||||
input int Inp_NYOpenHour = 13;
|
||||
input int Inp_NYCloseHour = 21;
|
||||
input bool Inp_AllowNYOverlapOnly = false;
|
||||
|
||||
// Entry placement
|
||||
input bool Inp_UseLimitAtZone = true; // limit order at minor zone
|
||||
input int Inp_MaxSlippagePoints = 100;
|
||||
input int Inp_MinRetestWickPoints = 30;
|
||||
|
||||
// Safety / engine
|
||||
input int Inp_MinBarsLoaded = 600;
|
||||
input int Inp_SignalCoolOffBars = 20; // avoid rapid re-entries
|
||||
input bool Inp_OnePositionOnly = true;
|
||||
|
||||
//------------------------------- Structures -------------------------
|
||||
struct Zone
|
||||
{
|
||||
bool isValid;
|
||||
double priceLow;
|
||||
double priceHigh;
|
||||
int barIndex; // starting bar index of zone
|
||||
bool isSupply; // true: resistance (HH), false: support (LL)
|
||||
};
|
||||
|
||||
struct MinorZone
|
||||
{
|
||||
bool isValid;
|
||||
double priceLow;
|
||||
double priceHigh;
|
||||
int barIndex;
|
||||
bool isSupply; // same direction as major
|
||||
};
|
||||
|
||||
datetime lastSignalTimeBuy = 0;
|
||||
datetime lastSignalTimeSell = 0;
|
||||
|
||||
//
|
||||
int atrHandler = INVALID_HANDLE;
|
||||
|
||||
//------------------------------- Helpers ----------------------------
|
||||
int DigitsAdjust()
|
||||
{
|
||||
return (int)SymbolInfoInteger(Inp_Symbol, SYMBOL_DIGITS);
|
||||
}
|
||||
double PointAdjust()
|
||||
{
|
||||
return SymbolInfoDouble(Inp_Symbol, SYMBOL_POINT);
|
||||
}
|
||||
double TickValue()
|
||||
{
|
||||
double v;
|
||||
SymbolInfoDouble(Inp_Symbol, SYMBOL_TRADE_TICK_VALUE, v);
|
||||
return v;
|
||||
}
|
||||
double TickSize()
|
||||
{
|
||||
double s;
|
||||
SymbolInfoDouble(Inp_Symbol, SYMBOL_TRADE_TICK_SIZE, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
bool IsSessionAllowed()
|
||||
{
|
||||
if (!Inp_UseSessionFilter)
|
||||
return true;
|
||||
MqlDateTime t;
|
||||
TimeToStruct(TimeCurrent(), t);
|
||||
int hour = t.hour;
|
||||
bool london = (hour >= Inp_LondonOpenHour && hour < Inp_LondonCloseHour);
|
||||
bool ny = (hour >= Inp_NYOpenHour && hour < Inp_NYCloseHour);
|
||||
if (Inp_AllowNYOverlapOnly)
|
||||
return (london && ny);
|
||||
return (london || ny);
|
||||
}
|
||||
|
||||
bool EngulfingBearish(int shift)
|
||||
{
|
||||
double o0 = iOpen(Inp_Symbol, Inp_WorkTF, shift), c0 = iClose(Inp_Symbol, Inp_WorkTF, shift);
|
||||
double o1 = iOpen(Inp_Symbol, Inp_WorkTF, shift + 1), c1 = iClose(Inp_Symbol, Inp_WorkTF, shift + 1);
|
||||
return (c0 < o0 && c1 > o1 && o0 < c1 && c0 < o1 && (o0 - o1) > 0 && (c1 - c0) > 0 && (o1 < c0)); // rough engulfing
|
||||
}
|
||||
bool EngulfingBullish(int shift)
|
||||
{
|
||||
double o0 = iOpen(Inp_Symbol, Inp_WorkTF, shift), c0 = iClose(Inp_Symbol, Inp_WorkTF, shift);
|
||||
double o1 = iOpen(Inp_Symbol, Inp_WorkTF, shift + 1), c1 = iClose(Inp_Symbol, Inp_WorkTF, shift + 1);
|
||||
return (c0 > o0 && c1 < o1 && o0 > c1 && c0 > o1 && (o0 - o1) > 0 && (c0 - c1) > 0 && (o1 > c0)); // rough engulfing inverse
|
||||
}
|
||||
|
||||
bool VolumeSpike(int shift)
|
||||
{
|
||||
if (!Inp_UseVolumeSpike)
|
||||
return true;
|
||||
double avg = 0;
|
||||
int n = 20;
|
||||
for (int i = shift + 1; i < shift + 1 + n; i++)
|
||||
avg += (double)iVolume(Inp_Symbol, Inp_WorkTF, i);
|
||||
avg /= n;
|
||||
double v0 = (double)iVolume(Inp_Symbol, Inp_WorkTF, shift);
|
||||
return (v0 >= avg * Inp_VolSpikeFactor);
|
||||
}
|
||||
|
||||
bool HTFConfluence(bool wantSupply)
|
||||
{
|
||||
if (!Inp_UseHTFConfluence)
|
||||
return true;
|
||||
// Simple HTF direction: last HTF candle close vs open
|
||||
double o = iOpen(Inp_Symbol, Inp_HTF, Inp_HTFShiftBars), c = iClose(Inp_Symbol, Inp_HTF, Inp_HTFShiftBars);
|
||||
bool htfDown = (c < o), htfUp = (c > o);
|
||||
return wantSupply ? htfDown : htfUp;
|
||||
}
|
||||
|
||||
//------------------------------- Zone detection ---------------------
|
||||
Zone FindMajorZone()
|
||||
{
|
||||
Zone z;
|
||||
z.isValid = false;
|
||||
z.isSupply = false;
|
||||
z.priceLow = 0;
|
||||
z.priceHigh = 0;
|
||||
z.barIndex = -1;
|
||||
int bars = iBars(Inp_Symbol, Inp_WorkTF);
|
||||
if (bars < Inp_MinBarsLoaded)
|
||||
return z;
|
||||
|
||||
// Highest high / lowest low over lookback
|
||||
double hh = -DBL_MAX, ll = DBL_MAX;
|
||||
int hhBar = -1, llBar = -1;
|
||||
for (int i = 1; i <= Inp_MajorLookbackBars; i++)
|
||||
{
|
||||
double h = iHigh(Inp_Symbol, Inp_WorkTF, i), l = iLow(Inp_Symbol, Inp_WorkTF, i);
|
||||
if (h > hh)
|
||||
{
|
||||
hh = h;
|
||||
hhBar = i;
|
||||
}
|
||||
if (l < ll)
|
||||
{
|
||||
ll = l;
|
||||
llBar = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Decide which one is closest to current action: use most recent extreme
|
||||
if (hhBar < llBar)
|
||||
{
|
||||
z.isSupply = true;
|
||||
z.isValid = true;
|
||||
z.barIndex = hhBar;
|
||||
z.priceLow = hh - Inp_ZonePadPoints * PointAdjust();
|
||||
z.priceHigh = hh + Inp_ZonePadPoints * PointAdjust();
|
||||
}
|
||||
else
|
||||
{
|
||||
z.isSupply = false;
|
||||
z.isValid = true;
|
||||
z.barIndex = llBar;
|
||||
z.priceLow = ll - Inp_ZonePadPoints * PointAdjust();
|
||||
z.priceHigh = ll + Inp_ZonePadPoints * PointAdjust();
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
MinorZone FindFirstMinorSameDirection(const Zone &major)
|
||||
{
|
||||
MinorZone mz;
|
||||
mz.isValid = false;
|
||||
mz.isSupply = major.isSupply;
|
||||
mz.priceLow = 0;
|
||||
mz.priceHigh = 0;
|
||||
mz.barIndex = -1;
|
||||
if (!major.isValid)
|
||||
return mz;
|
||||
|
||||
// Scan forward from major's bar toward current for first reaction zone aligned with major
|
||||
int start = major.barIndex - 1;
|
||||
int end = MathMax(1, start - Inp_MinorWindowBars);
|
||||
|
||||
// Heuristic: supply minor = bearish impulse followed by base; demand minor = bullish impulse followed by base
|
||||
for (int i = start; i >= end; i--)
|
||||
{
|
||||
double o = iOpen(Inp_Symbol, Inp_WorkTF, i), c = iClose(Inp_Symbol, Inp_WorkTF, i);
|
||||
double h = iHigh(Inp_Symbol, Inp_WorkTF, i), l = iLow(Inp_Symbol, Inp_WorkTF, i);
|
||||
|
||||
bool bearImpulse = (c < o && (o - c) > (h - l) * 0.5);
|
||||
bool bullImpulse = (c > o && (c - o) > (h - l) * 0.5);
|
||||
|
||||
if (major.isSupply && bearImpulse)
|
||||
{
|
||||
// Base zone from next candle tight range
|
||||
double h1 = iHigh(Inp_Symbol, Inp_WorkTF, i - 1), l1 = iLow(Inp_Symbol, Inp_WorkTF, i - 1);
|
||||
mz.isValid = true;
|
||||
mz.barIndex = i - 1;
|
||||
mz.priceLow = l1 - Inp_ZonePadPoints * PointAdjust();
|
||||
mz.priceHigh = h1 + Inp_ZonePadPoints * PointAdjust();
|
||||
break;
|
||||
}
|
||||
if (!major.isSupply && bullImpulse)
|
||||
{
|
||||
double h1 = iHigh(Inp_Symbol, Inp_WorkTF, i - 1), l1 = iLow(Inp_Symbol, Inp_WorkTF, i - 1);
|
||||
mz.isValid = true;
|
||||
mz.barIndex = i - 1;
|
||||
mz.priceLow = l1 - Inp_ZonePadPoints * PointAdjust();
|
||||
mz.priceHigh = h1 + Inp_ZonePadPoints * PointAdjust();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return mz;
|
||||
}
|
||||
|
||||
//------------------------------- Signal logic -----------------------
|
||||
bool PriceRetestedZone(const MinorZone &mz, bool supply, int shift = 0)
|
||||
{
|
||||
if (!mz.isValid)
|
||||
return false;
|
||||
double high = iHigh(Inp_Symbol, Inp_WorkTF, shift), low = iLow(Inp_Symbol, Inp_WorkTF, shift);
|
||||
// For supply: retest when high touches zone; for demand: retest when low touches zone
|
||||
if (supply)
|
||||
return (high >= mz.priceLow && high <= mz.priceHigh && (high - iClose(Inp_Symbol, Inp_WorkTF, shift)) * 1.0 / PointAdjust() >= Inp_MinRetestWickPoints);
|
||||
else
|
||||
return (low <= mz.priceHigh && low >= mz.priceLow && (iClose(Inp_Symbol, Inp_WorkTF, shift) - low) * 1.0 / PointAdjust() >= Inp_MinRetestWickPoints);
|
||||
}
|
||||
|
||||
bool ConfirmAtZone(bool supply)
|
||||
{
|
||||
int shift = 0;
|
||||
if (Inp_UseEngulfingConfirm)
|
||||
{
|
||||
if (supply)
|
||||
{
|
||||
if (!EngulfingBearish(shift))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!EngulfingBullish(shift))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!VolumeSpike(shift))
|
||||
return false;
|
||||
if (!HTFConfluence(supply))
|
||||
return false;
|
||||
// Optional: RSI divergence could be added here if enabled.
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------- Risk & orders -----------------------
|
||||
double CalcPositionSize(double sl_points)
|
||||
{
|
||||
double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * (Inp_RiskPercent / 100.0);
|
||||
double tickValue = TickValue();
|
||||
double tickSize = TickSize();
|
||||
// Convert SL points to quoted ticks
|
||||
double ticks = sl_points * PointAdjust() / tickSize;
|
||||
if (ticks <= 0.0)
|
||||
return 0.0;
|
||||
double lots = riskMoney / (ticks * tickValue);
|
||||
// Normalize to symbol step
|
||||
double minLot = SymbolInfoDouble(Inp_Symbol, SYMBOL_VOLUME_MIN);
|
||||
double lotStep = SymbolInfoDouble(Inp_Symbol, SYMBOL_VOLUME_STEP);
|
||||
double maxLot = SymbolInfoDouble(Inp_Symbol, SYMBOL_VOLUME_MAX);
|
||||
lots = MathFloor(lots / lotStep) * lotStep;
|
||||
lots = MathMax(minLot, MathMin(lots, maxLot));
|
||||
return lots;
|
||||
}
|
||||
|
||||
bool PlaceEntry(const MinorZone &mz, bool supply)
|
||||
{
|
||||
double bid = SymbolInfoDouble(Inp_Symbol, SYMBOL_BID);
|
||||
double ask = SymbolInfoDouble(Inp_Symbol, SYMBOL_ASK);
|
||||
double point = PointAdjust();
|
||||
|
||||
// SL beneath/above minor zone (or ATR-based)
|
||||
double sl, entry, tp;
|
||||
double sl_points;
|
||||
|
||||
if (supply)
|
||||
{
|
||||
entry = Inp_UseLimitAtZone ? mz.priceLow : bid; // sell near zone top/low
|
||||
double baseSL = mz.priceHigh + Inp_ZonePadPoints * point;
|
||||
if (Inp_UseATRforSL)
|
||||
{
|
||||
//
|
||||
double atrs[];
|
||||
CopyBuffer(atrHandler, MAIN_LINE, 0, 1, atrs);
|
||||
double atr = atrs[0];
|
||||
baseSL = MathMax(baseSL, entry + (atr * Inp_ATR_Mult));
|
||||
}
|
||||
sl = baseSL;
|
||||
sl_points = (sl - entry) / point;
|
||||
sl_points = MathMax(sl_points, Inp_MinSLPoints);
|
||||
tp = entry - (sl_points * point * Inp_R_MultipleTP);
|
||||
// Position sizing
|
||||
double lots = CalcPositionSize(sl_points);
|
||||
if (lots <= 0)
|
||||
return false;
|
||||
|
||||
MqlTradeRequest req;
|
||||
MqlTradeResult res;
|
||||
ZeroMemory(req);
|
||||
ZeroMemory(res);
|
||||
req.action = TRADE_ACTION_DEAL;
|
||||
req.symbol = Inp_Symbol;
|
||||
req.type = ORDER_TYPE_SELL;
|
||||
req.volume = lots;
|
||||
req.price = Inp_UseLimitAtZone ? entry : bid;
|
||||
req.sl = sl;
|
||||
req.tp = tp;
|
||||
req.deviation = Inp_MaxSlippagePoints;
|
||||
bool ok = OrderSend(req, res);
|
||||
if (ok)
|
||||
{
|
||||
lastSignalTimeSell = TimeCurrent();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = Inp_UseLimitAtZone ? mz.priceHigh : ask; // buy near zone top/high
|
||||
double baseSL = mz.priceLow - Inp_ZonePadPoints * point;
|
||||
if (Inp_UseATRforSL)
|
||||
{
|
||||
//
|
||||
double atrs[];
|
||||
CopyBuffer(atrHandler, MAIN_LINE, 0, 1, atrs);
|
||||
double atr = atrs[0];
|
||||
baseSL = MathMin(baseSL, entry - (atr * Inp_ATR_Mult));
|
||||
}
|
||||
sl = baseSL;
|
||||
sl_points = (entry - sl) / point;
|
||||
sl_points = MathMax(sl_points, Inp_MinSLPoints);
|
||||
tp = entry + (sl_points * point * Inp_R_MultipleTP);
|
||||
double lots = CalcPositionSize(sl_points);
|
||||
if (lots <= 0)
|
||||
return false;
|
||||
|
||||
MqlTradeRequest req;
|
||||
MqlTradeResult res;
|
||||
ZeroMemory(req);
|
||||
ZeroMemory(res);
|
||||
req.action = TRADE_ACTION_DEAL;
|
||||
req.symbol = Inp_Symbol;
|
||||
req.type = ORDER_TYPE_BUY;
|
||||
req.volume = lots;
|
||||
req.price = Inp_UseLimitAtZone ? entry : ask;
|
||||
req.sl = sl;
|
||||
req.tp = tp;
|
||||
req.deviation = Inp_MaxSlippagePoints;
|
||||
bool ok = OrderSend(req, res);
|
||||
if (ok)
|
||||
{
|
||||
lastSignalTimeBuy = TimeCurrent();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------- Position management ----------------
|
||||
void ManageOpenPositions()
|
||||
{
|
||||
int total = PositionsTotal();
|
||||
double point = PointAdjust();
|
||||
|
||||
for (int i = 0; i < total; i++)
|
||||
{
|
||||
string sym = PositionGetSymbol(i);
|
||||
if (sym != Inp_Symbol)
|
||||
continue;
|
||||
if (!PositionSelect(sym))
|
||||
continue;
|
||||
|
||||
long type = (long)PositionGetInteger(POSITION_TYPE);
|
||||
double price = PositionGetDouble(POSITION_PRICE_OPEN);
|
||||
double sl = PositionGetDouble(POSITION_SL);
|
||||
double tp = PositionGetDouble(POSITION_TP);
|
||||
double current = (type == POSITION_TYPE_BUY) ? SymbolInfoDouble(sym, SYMBOL_BID) : SymbolInfoDouble(sym, SYMBOL_ASK);
|
||||
|
||||
// Risk-free move to BE at TP1 (= 1R)
|
||||
if (Inp_MoveToBEatTP1 && tp > 0 && sl > 0)
|
||||
{
|
||||
double rDist = MathAbs(tp - price) / Inp_R_MultipleTP;
|
||||
bool hitTP1 = (type == POSITION_TYPE_BUY ? (current >= price + rDist) : (current <= price - rDist));
|
||||
|
||||
if (hitTP1)
|
||||
{
|
||||
double newSL = (type == POSITION_TYPE_BUY ? price + Inp_BE_OffsetPoints * point : price - Inp_BE_OffsetPoints * point);
|
||||
if ((type == POSITION_TYPE_BUY && newSL > sl) || (type == POSITION_TYPE_SELL && newSL < sl))
|
||||
{
|
||||
MqlTradeRequest req;
|
||||
MqlTradeResult res;
|
||||
ZeroMemory(req);
|
||||
ZeroMemory(res);
|
||||
req.action = TRADE_ACTION_SLTP;
|
||||
req.symbol = sym;
|
||||
req.position = (ulong)PositionGetInteger(POSITION_TICKET);
|
||||
req.sl = newSL;
|
||||
req.tp = tp;
|
||||
OrderSend(req, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------- Engine ------------------------------
|
||||
bool CoolOffOk(bool supply)
|
||||
{
|
||||
datetime last = supply ? lastSignalTimeSell : lastSignalTimeBuy;
|
||||
if (last == 0)
|
||||
return true;
|
||||
// Convert bars to seconds approximate using last M15 duration
|
||||
int seconds = Inp_SignalCoolOffBars * 15 * 60;
|
||||
return (TimeCurrent() - last) >= seconds;
|
||||
}
|
||||
|
||||
void TrySignal()
|
||||
{
|
||||
if (!IsSessionAllowed())
|
||||
return;
|
||||
|
||||
Zone major = FindMajorZone();
|
||||
if (!major.isValid)
|
||||
return;
|
||||
|
||||
MinorZone minor = FindFirstMinorSameDirection(major);
|
||||
if (!minor.isValid)
|
||||
return;
|
||||
|
||||
// Only act on retest + confirmation
|
||||
bool retest = PriceRetestedZone(minor, major.isSupply, 0);
|
||||
if (!retest)
|
||||
return;
|
||||
if (!ConfirmAtZone(major.isSupply))
|
||||
return;
|
||||
if (Inp_OnePositionOnly && PositionsTotal() > 0)
|
||||
return;
|
||||
|
||||
if (!CoolOffOk(major.isSupply))
|
||||
return;
|
||||
|
||||
PlaceEntry(minor, major.isSupply);
|
||||
}
|
||||
|
||||
//------------------------------- Standard events --------------------
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
if (Symbol() != Inp_Symbol)
|
||||
{
|
||||
SymbolSelect(Inp_Symbol, true);
|
||||
}
|
||||
|
||||
//
|
||||
atrHandler = iATR(Inp_Symbol, Inp_WorkTF, Inp_ATR_Period);
|
||||
return (INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
}
|
||||
|
||||
void OnTick()
|
||||
{
|
||||
static datetime lastBarTime = 0;
|
||||
MqlRates rates[];
|
||||
int copied = CopyRates(Inp_Symbol, Inp_WorkTF, 0, Inp_MinBarsLoaded, rates);
|
||||
if (copied < Inp_MinBarsLoaded)
|
||||
return;
|
||||
|
||||
datetime curBarTime = rates[0].time;
|
||||
if (curBarTime != lastBarTime)
|
||||
{
|
||||
// New bar on M15: evaluate signal
|
||||
TrySignal();
|
||||
lastBarTime = curBarTime;
|
||||
}
|
||||
|
||||
// Manage open positions continuously
|
||||
ManageOpenPositions();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,288 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ZigzagColor.mq5 |
|
||||
//| Copyright 2000-2025, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
|
||||
#property link "https://www.mql5.com"
|
||||
//--- indicator settings
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 1
|
||||
#property indicator_type1 DRAW_COLOR_ZIGZAG
|
||||
#property indicator_width1 3
|
||||
#property indicator_color1 clrAqua, clrMagenta
|
||||
//--- input parameters
|
||||
input int InpDepth =12; // Depth
|
||||
input int InpDeviation=5; // Deviation
|
||||
input int InpBackstep =3; // Back Step
|
||||
//--- indicator buffers
|
||||
double ZigzagPeakBuffer[];
|
||||
double ZigzagBottomBuffer[];
|
||||
double HighMapBuffer[];
|
||||
double LowMapBuffer[];
|
||||
double ColorBuffer[];
|
||||
|
||||
int ExtRecalc=3; // recounting's depth
|
||||
|
||||
enum EnSearchMode
|
||||
{
|
||||
Extremum=0, // searching for the first extremum
|
||||
Peak=1, // searching for the next ZigZag peak
|
||||
Bottom=-1 // searching for the next ZigZag bottom
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,ZigzagPeakBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,ZigzagBottomBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(2,ColorBuffer,INDICATOR_COLOR_INDEX);
|
||||
SetIndexBuffer(3,HighMapBuffer,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(4,LowMapBuffer,INDICATOR_CALCULATIONS);
|
||||
//--- set accuracy
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||
//--- name for DataWindow and indicator subwindow label
|
||||
string short_name=StringFormat("ZigZagColor(%d,%d,%d)",InpDepth,InpDeviation,InpBackstep);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
||||
PlotIndexSetString(0,PLOT_LABEL,short_name);
|
||||
//--- set an empty value
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| ZigZag calculation |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
if(rates_total<100)
|
||||
return(0);
|
||||
//---
|
||||
int i,start=0;
|
||||
int extreme_counter=0,extreme_search=Extremum;
|
||||
int shift,back=0,last_high_pos=0,last_low_pos=0;
|
||||
double val=0,res=0;
|
||||
double cur_low=0,cur_high=0,last_high=0,last_low=0;
|
||||
//--- initializing
|
||||
if(prev_calculated==0)
|
||||
{
|
||||
ArrayInitialize(ZigzagPeakBuffer,0.0);
|
||||
ArrayInitialize(ZigzagBottomBuffer,0.0);
|
||||
ArrayInitialize(HighMapBuffer,0.0);
|
||||
ArrayInitialize(LowMapBuffer,0.0);
|
||||
//--- start calculation from bar number InpDepth
|
||||
start=InpDepth-1;
|
||||
}
|
||||
//--- ZigZag was already calculated before
|
||||
if(prev_calculated>0)
|
||||
{
|
||||
i=rates_total-1;
|
||||
//--- searching for the third extremum from the last uncompleted bar
|
||||
while(extreme_counter<ExtRecalc && i>rates_total -100)
|
||||
{
|
||||
res=(ZigzagPeakBuffer[i]+ZigzagBottomBuffer[i]);
|
||||
//---
|
||||
if(res!=0)
|
||||
extreme_counter++;
|
||||
i--;
|
||||
}
|
||||
i++;
|
||||
start=i;
|
||||
//--- what type of exremum we search for
|
||||
if(LowMapBuffer[i]!=0)
|
||||
{
|
||||
cur_low=LowMapBuffer[i];
|
||||
extreme_search=Peak;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_high=HighMapBuffer[i];
|
||||
extreme_search=Bottom;
|
||||
}
|
||||
//--- clear indicator values
|
||||
for(i=start+1; i<rates_total && !IsStopped(); i++)
|
||||
{
|
||||
ZigzagPeakBuffer[i] =0.0;
|
||||
ZigzagBottomBuffer[i]=0.0;
|
||||
LowMapBuffer[i] =0.0;
|
||||
HighMapBuffer[i] =0.0;
|
||||
}
|
||||
}
|
||||
//--- searching for high and low extremes
|
||||
for(shift=start; shift<rates_total && !IsStopped(); shift++)
|
||||
{
|
||||
//--- low
|
||||
val=Lowest(low,InpDepth,shift);
|
||||
if(val==last_low)
|
||||
val=0.0;
|
||||
else
|
||||
{
|
||||
last_low=val;
|
||||
if((low[shift]-val)>(InpDeviation*_Point))
|
||||
val=0.0;
|
||||
else
|
||||
{
|
||||
for(back=InpBackstep; back>=1; back--)
|
||||
{
|
||||
res=LowMapBuffer[shift-back];
|
||||
//---
|
||||
if((res!=0) && (res>val))
|
||||
LowMapBuffer[shift-back]=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(low[shift]==val)
|
||||
LowMapBuffer[shift]=val;
|
||||
else
|
||||
LowMapBuffer[shift]=0.0;
|
||||
//--- high
|
||||
val=Highest(high,InpDepth,shift);
|
||||
if(val==last_high)
|
||||
val=0.0;
|
||||
else
|
||||
{
|
||||
last_high=val;
|
||||
if((val-high[shift])>(InpDeviation*_Point))
|
||||
val=0.0;
|
||||
else
|
||||
{
|
||||
for(back=InpBackstep; back>=1; back--)
|
||||
{
|
||||
res=HighMapBuffer[shift-back];
|
||||
//---
|
||||
if((res!=0) && (res<val))
|
||||
HighMapBuffer[shift-back]=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(high[shift]==val)
|
||||
HighMapBuffer[shift]=val;
|
||||
else
|
||||
HighMapBuffer[shift]=0.0;
|
||||
}
|
||||
//--- set last values
|
||||
if(extreme_search==0) // undefined values
|
||||
{
|
||||
last_low=0;
|
||||
last_high=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_low=cur_low;
|
||||
last_high=cur_high;
|
||||
}
|
||||
//--- final selection of extreme points for ZigZag
|
||||
for(shift=start; shift<rates_total && !IsStopped(); shift++)
|
||||
{
|
||||
res=0.0;
|
||||
switch(extreme_search)
|
||||
{
|
||||
case Extremum:
|
||||
if(last_low==0 && last_high==0)
|
||||
{
|
||||
if(HighMapBuffer[shift]!=0)
|
||||
{
|
||||
last_high=high[shift];
|
||||
last_high_pos=shift;
|
||||
extreme_search=-1;
|
||||
ZigzagPeakBuffer[shift]=last_high;
|
||||
ColorBuffer[shift]=0;
|
||||
res=1;
|
||||
}
|
||||
if(LowMapBuffer[shift]!=0)
|
||||
{
|
||||
last_low=low[shift];
|
||||
last_low_pos=shift;
|
||||
extreme_search=1;
|
||||
ZigzagBottomBuffer[shift]=last_low;
|
||||
ColorBuffer[shift]=1;
|
||||
res=1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Peak:
|
||||
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<last_low &&
|
||||
HighMapBuffer[shift]==0.0)
|
||||
{
|
||||
ZigzagBottomBuffer[last_low_pos]=0.0;
|
||||
last_low_pos=shift;
|
||||
last_low=LowMapBuffer[shift];
|
||||
ZigzagBottomBuffer[shift]=last_low;
|
||||
ColorBuffer[shift]=1;
|
||||
res=1;
|
||||
}
|
||||
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
|
||||
{
|
||||
last_high=HighMapBuffer[shift];
|
||||
last_high_pos=shift;
|
||||
ZigzagPeakBuffer[shift]=last_high;
|
||||
ColorBuffer[shift]=0;
|
||||
extreme_search=Bottom;
|
||||
res=1;
|
||||
}
|
||||
break;
|
||||
case Bottom:
|
||||
if(HighMapBuffer[shift]!=0.0 &&
|
||||
HighMapBuffer[shift]>last_high &&
|
||||
LowMapBuffer[shift]==0.0)
|
||||
{
|
||||
ZigzagPeakBuffer[last_high_pos]=0.0;
|
||||
last_high_pos=shift;
|
||||
last_high=HighMapBuffer[shift];
|
||||
ZigzagPeakBuffer[shift]=last_high;
|
||||
ColorBuffer[shift]=0;
|
||||
}
|
||||
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
|
||||
{
|
||||
last_low=LowMapBuffer[shift];
|
||||
last_low_pos=shift;
|
||||
ZigzagBottomBuffer[shift]=last_low;
|
||||
ColorBuffer[shift]=1;
|
||||
extreme_search=Peak;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return(rates_total);
|
||||
}
|
||||
}
|
||||
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get highest value for range |
|
||||
//+------------------------------------------------------------------+
|
||||
double Highest(const double&array[],int count,int start)
|
||||
{
|
||||
double res=array[start];
|
||||
//---
|
||||
for(int i=start-1; i>start-count && i>=0; i--)
|
||||
if(res<array[i])
|
||||
res=array[i];
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get lowest value for range |
|
||||
//+------------------------------------------------------------------+
|
||||
double Lowest(const double&array[],int count,int start)
|
||||
{
|
||||
double res=array[start];
|
||||
//---
|
||||
for(int i=start-1; i>start-count && i>=0; i--)
|
||||
if(res>array[i])
|
||||
res=array[i];
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,383 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ZigZag Analyzer.mq5|
|
||||
//| Copyright 2025, MetaQuotes Ltd.|
|
||||
//| https://www.mql5.com/en/users/lynnchris|
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, MetaQuotes Ltd."
|
||||
#property link "https://www.mql5.com/en/users/lynnchris"
|
||||
#property version "1.0"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
// Input parameters
|
||||
input ENUM_TIMEFRAMES InpTimeFrame = PERIOD_CURRENT; // Timeframe to analyze
|
||||
input int ZZ_Depth = 12; // ZigZag depth
|
||||
input int ZZ_Deviation = 5; // ZigZag deviation
|
||||
input int ZZ_Backstep = 3; // ZigZag backstep
|
||||
input int LookBackBars = 500; // Bars to search for pivots
|
||||
input int ExtendFutureBars = 100; // Bars to extend trendlines into the future
|
||||
|
||||
// Global indicator handle for ZigZag
|
||||
int zzHandle;
|
||||
|
||||
// Arrays for ZigZag data and pivot storage
|
||||
double zzBuffer[];
|
||||
bool pivotIsPeak[];
|
||||
double pivotPrices[];
|
||||
datetime pivotTimes[];
|
||||
|
||||
// Variable to detect new bars
|
||||
datetime lastBarTime = 0;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
zzHandle = iCustom(
|
||||
_Symbol,
|
||||
InpTimeFrame,
|
||||
"x-saherelm.xzg",
|
||||
"",
|
||||
ZZ_Depth,
|
||||
ZZ_Deviation,
|
||||
ZZ_Backstep,
|
||||
X_PRICE_HIGH,
|
||||
X_PRICE_LOW,
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
159,
|
||||
159 //
|
||||
);
|
||||
if (zzHandle == INVALID_HANDLE)
|
||||
{
|
||||
Print("Error creating ZigZag handle");
|
||||
return (INIT_FAILED);
|
||||
}
|
||||
return (INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
ObjectDelete(0, "Downtrend_HighLine");
|
||||
ObjectDelete(0, "Downtrend_LowLine");
|
||||
ObjectDelete(0, "Major_Resistance");
|
||||
ObjectDelete(0, "Major_Support");
|
||||
ObjectDelete(0, "Minor_Resistance");
|
||||
ObjectDelete(0, "Minor_Support");
|
||||
IndicatorRelease(zzHandle);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Tick function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
datetime currentBarTime = iTime(_Symbol, InpTimeFrame, 0);
|
||||
if (currentBarTime == lastBarTime)
|
||||
return;
|
||||
lastBarTime = currentBarTime;
|
||||
|
||||
// Remove previous objects
|
||||
ObjectDelete(0, "Downtrend_HighLine");
|
||||
ObjectDelete(0, "Downtrend_LowLine");
|
||||
ObjectDelete(0, "Major_Resistance");
|
||||
ObjectDelete(0, "Major_Support");
|
||||
ObjectDelete(0, "Minor_Resistance");
|
||||
ObjectDelete(0, "Minor_Support");
|
||||
|
||||
if (CopyBuffer(zzHandle, 0, 0, LookBackBars, zzBuffer) <= 0)
|
||||
{
|
||||
Print("Failed to copy ZigZag data");
|
||||
return;
|
||||
}
|
||||
ArraySetAsSeries(zzBuffer, true);
|
||||
|
||||
DrawZigZagTrendlines();
|
||||
DrawSupportResistance();
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Draw ZigZag-based Trendlines |
|
||||
//+------------------------------------------------------------------+
|
||||
void DrawZigZagTrendlines()
|
||||
{
|
||||
double highPrices[10], lowPrices[10];
|
||||
datetime highTimes[10], lowTimes[10];
|
||||
int highCount = 0, lowCount = 0;
|
||||
|
||||
// Extract swing points from the ZigZag buffer
|
||||
for (int i = 0; i < LookBackBars - 1; i++)
|
||||
{
|
||||
if (zzBuffer[i] != 0)
|
||||
{
|
||||
if (iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && highCount < 10)
|
||||
{
|
||||
highPrices[highCount] = zzBuffer[i];
|
||||
highTimes[highCount] = iTime(_Symbol, InpTimeFrame, i);
|
||||
highCount++;
|
||||
}
|
||||
else if (iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && lowCount < 10)
|
||||
{
|
||||
lowPrices[lowCount] = zzBuffer[i];
|
||||
lowTimes[lowCount] = iTime(_Symbol, InpTimeFrame, i);
|
||||
lowCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude the most recent swing if possible
|
||||
int usedHighCount = (highCount >= 4) ? highCount - 1 : highCount;
|
||||
int usedLowCount = (lowCount >= 4) ? lowCount - 1 : lowCount;
|
||||
|
||||
double mHigh = 0, bHigh = 0, mLow = 0, bLow = 0;
|
||||
bool validHigh = false, validLow = false;
|
||||
|
||||
// Regression for highs
|
||||
if (usedHighCount >= 3)
|
||||
{
|
||||
double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0;
|
||||
for (int i = 0; i < usedHighCount; i++)
|
||||
{
|
||||
double t = (double)highTimes[i];
|
||||
double p = highPrices[i];
|
||||
sumT += t;
|
||||
sumP += p;
|
||||
sumTP += t * p;
|
||||
sumT2 += t * t;
|
||||
}
|
||||
int N = usedHighCount;
|
||||
double denominator = N * sumT2 - sumT * sumT;
|
||||
if (denominator != 0)
|
||||
{
|
||||
mHigh = (N * sumTP - sumT * sumP) / denominator;
|
||||
bHigh = (sumP - mHigh * sumT) / N;
|
||||
}
|
||||
else
|
||||
bHigh = sumP / N;
|
||||
validHigh = true;
|
||||
}
|
||||
|
||||
// Regression for lows
|
||||
if (usedLowCount >= 3)
|
||||
{
|
||||
double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0;
|
||||
for (int i = 0; i < usedLowCount; i++)
|
||||
{
|
||||
double t = (double)lowTimes[i];
|
||||
double p = lowPrices[i];
|
||||
sumT += t;
|
||||
sumP += p;
|
||||
sumTP += t * p;
|
||||
sumT2 += t * t;
|
||||
}
|
||||
int N = usedLowCount;
|
||||
double denominator = N * sumT2 - sumT * sumT;
|
||||
if (denominator != 0)
|
||||
{
|
||||
mLow = (N * sumTP - sumT * sumP) / denominator;
|
||||
bLow = (sumP - mLow * sumT) / N;
|
||||
}
|
||||
else
|
||||
bLow = sumP / N;
|
||||
validLow = true;
|
||||
}
|
||||
|
||||
// Define time limits for trendlines
|
||||
datetime pastTime = iTime(_Symbol, InpTimeFrame, LookBackBars - 1);
|
||||
datetime futureTime = lastBarTime + ExtendFutureBars * PeriodSeconds();
|
||||
|
||||
// Draw trendlines if both regressions are valid
|
||||
if (validHigh && validLow)
|
||||
{
|
||||
// When slopes have the same sign, use average slope
|
||||
if (mHigh * mLow > 0)
|
||||
{
|
||||
double mParallel = (mHigh + mLow) / 2.0;
|
||||
double bHighParallel = highPrices[0] - mParallel * (double)highTimes[0];
|
||||
double bLowParallel = lowPrices[0] - mParallel * (double)lowTimes[0];
|
||||
|
||||
datetime highStartTime = pastTime;
|
||||
double highStartPrice = mParallel * (double)highStartTime + bHighParallel;
|
||||
double highEndPrice = mParallel * (double)futureTime + bHighParallel;
|
||||
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
|
||||
Print("Failed to create High Trendline");
|
||||
else
|
||||
{
|
||||
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
|
||||
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
|
||||
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
|
||||
}
|
||||
|
||||
datetime lowStartTime = pastTime;
|
||||
double lowStartPrice = mParallel * (double)lowStartTime + bLowParallel;
|
||||
double lowEndPrice = mParallel * (double)futureTime + bLowParallel;
|
||||
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
|
||||
Print("Failed to create Low Trendline");
|
||||
else
|
||||
{
|
||||
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
|
||||
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
|
||||
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
datetime highStartTime = pastTime;
|
||||
double highStartPrice = mHigh * (double)highStartTime + bHigh;
|
||||
double highEndPrice = mHigh * (double)futureTime + bHigh;
|
||||
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
|
||||
Print("Failed to create High Trendline");
|
||||
else
|
||||
{
|
||||
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
|
||||
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
|
||||
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
|
||||
}
|
||||
|
||||
datetime lowStartTime = pastTime;
|
||||
double lowStartPrice = mLow * (double)lowStartTime + bLow;
|
||||
double lowEndPrice = mLow * (double)futureTime + bLow;
|
||||
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
|
||||
Print("Failed to create Low Trendline");
|
||||
else
|
||||
{
|
||||
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
|
||||
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
|
||||
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (validHigh)
|
||||
{
|
||||
datetime highStartTime = pastTime;
|
||||
double highStartPrice = mHigh * (double)highStartTime + bHigh;
|
||||
double highEndPrice = mHigh * (double)futureTime + bHigh;
|
||||
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
|
||||
Print("Failed to create High Trendline");
|
||||
else
|
||||
{
|
||||
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
|
||||
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
|
||||
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
|
||||
}
|
||||
}
|
||||
if (validLow)
|
||||
{
|
||||
datetime lowStartTime = pastTime;
|
||||
double lowStartPrice = mLow * (double)lowStartTime + bLow;
|
||||
double lowEndPrice = mLow * (double)futureTime + bLow;
|
||||
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
|
||||
Print("Failed to create Low Trendline");
|
||||
else
|
||||
{
|
||||
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
|
||||
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
|
||||
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Draw Support and Resistance Levels |
|
||||
//+------------------------------------------------------------------+
|
||||
void DrawSupportResistance()
|
||||
{
|
||||
double confirmedHighs[10], confirmedLows[10];
|
||||
int confHighCount = 0, confLowCount = 0;
|
||||
|
||||
for (int i = 0; i < LookBackBars - 1; i++)
|
||||
{
|
||||
if (zzBuffer[i] != 0)
|
||||
{
|
||||
if (iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confHighCount < 10)
|
||||
{
|
||||
confirmedHighs[confHighCount] = zzBuffer[i];
|
||||
confHighCount++;
|
||||
}
|
||||
else if (iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confLowCount < 10)
|
||||
{
|
||||
confirmedLows[confLowCount] = zzBuffer[i];
|
||||
confLowCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int usedHighCount = (confHighCount >= 4) ? confHighCount - 1 : confHighCount;
|
||||
int usedLowCount = (confLowCount >= 4) ? confLowCount - 1 : confLowCount;
|
||||
|
||||
double majorResistance = -1e9, majorSupport = 1e9;
|
||||
double minorResistance = -1e9, minorSupport = 1e9;
|
||||
double tempHigh = -1e9, tempLow = -1e9;
|
||||
for (int i = 0; i < usedHighCount; i++)
|
||||
{
|
||||
if (confirmedHighs[i] > majorResistance)
|
||||
{
|
||||
tempHigh = majorResistance;
|
||||
majorResistance = confirmedHighs[i];
|
||||
}
|
||||
else if (confirmedHighs[i] > tempHigh)
|
||||
{
|
||||
tempHigh = confirmedHighs[i];
|
||||
}
|
||||
}
|
||||
if (tempHigh > -1e9)
|
||||
minorResistance = tempHigh;
|
||||
for (int i = 0; i < usedLowCount; i++)
|
||||
{
|
||||
if (confirmedLows[i] < majorSupport)
|
||||
{
|
||||
tempLow = majorSupport;
|
||||
majorSupport = confirmedLows[i];
|
||||
}
|
||||
else if (confirmedLows[i] < tempLow)
|
||||
{
|
||||
tempLow = confirmedLows[i];
|
||||
}
|
||||
}
|
||||
if (tempLow < 1e9)
|
||||
minorSupport = tempLow;
|
||||
|
||||
if (usedHighCount > 0)
|
||||
{
|
||||
if (!ObjectCreate(0, "Major_Resistance", OBJ_HLINE, 0, 0, majorResistance))
|
||||
Print("Failed to create Major Resistance");
|
||||
else
|
||||
ObjectSetInteger(0, "Major_Resistance", OBJPROP_COLOR, clrMagenta);
|
||||
|
||||
if (minorResistance > -1e9 && minorResistance < majorResistance)
|
||||
{
|
||||
if (!ObjectCreate(0, "Minor_Resistance", OBJ_HLINE, 0, 0, minorResistance))
|
||||
Print("Failed to create Minor Resistance");
|
||||
else
|
||||
ObjectSetInteger(0, "Minor_Resistance", OBJPROP_COLOR, clrFuchsia);
|
||||
}
|
||||
}
|
||||
if (usedLowCount > 0)
|
||||
{
|
||||
if (!ObjectCreate(0, "Major_Support", OBJ_HLINE, 0, 0, majorSupport))
|
||||
Print("Failed to create Major Support");
|
||||
else
|
||||
ObjectSetInteger(0, "Major_Support", OBJPROP_COLOR, clrAqua);
|
||||
|
||||
if (minorSupport < 1e9 && minorSupport > majorSupport)
|
||||
{
|
||||
if (!ObjectCreate(0, "Minor_Support", OBJ_HLINE, 0, 0, minorSupport))
|
||||
Print("Failed to create Minor Support");
|
||||
else
|
||||
ObjectSetInteger(0, "Minor_Support", OBJPROP_COLOR, clrBlue);
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,208 +0,0 @@
|
||||
|
||||
//
|
||||
// Draw Market Analysis ...
|
||||
// has = iStructure.pvAnalysis.IsValid();
|
||||
// if (has)
|
||||
// {
|
||||
// //
|
||||
// XBoxZone iBox;
|
||||
// XCBoxObject *iBoxObj;
|
||||
|
||||
//
|
||||
// poiDrawer.RemoveDraws();
|
||||
|
||||
// //
|
||||
// has = iStructure.pvAnalysis.HasSupportBox(iBox);
|
||||
// if (has)
|
||||
// {
|
||||
// //
|
||||
// iBox.to = iBar.time;
|
||||
// poiDrawer.DrawBox(
|
||||
// iBox,
|
||||
// iBoxObj,
|
||||
// true,
|
||||
// iBox.type //
|
||||
// );
|
||||
// }
|
||||
|
||||
// //
|
||||
// ZeroMemory(iBoxObj);
|
||||
// has = iStructure.pvAnalysis.HasResistanceBox(iBox);
|
||||
// if (has)
|
||||
// {
|
||||
// //
|
||||
// iBox.to = iBar.time;
|
||||
// poiDrawer.DrawBox(
|
||||
// iBox,
|
||||
// iBoxObj,
|
||||
// true,
|
||||
// iBox.type //
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Draw Zones ...
|
||||
// has = HasChild(iStructure.supports);
|
||||
// if (has) {
|
||||
// //
|
||||
// CArrayObj *iSupportObjs;
|
||||
// poiDrawer.DrawBoxes(
|
||||
// iStructure.supports,
|
||||
// iSupportObjs,
|
||||
// true //
|
||||
// );
|
||||
// }
|
||||
|
||||
// //
|
||||
// has = HasChild(iStructure.resistances);
|
||||
// if (has) {
|
||||
// //
|
||||
// CArrayObj *iResistanceObjs;
|
||||
// poiDrawer.DrawBoxes(
|
||||
// iStructure.resistances,
|
||||
// iResistanceObjs,
|
||||
// true //
|
||||
// );
|
||||
// }
|
||||
|
||||
//
|
||||
// Detecte Fibo Section Changes ...
|
||||
|
||||
// //
|
||||
// has = fimaHelper.IsFiboSectionChanged(iDir, iBar.Index());
|
||||
// has = has &&
|
||||
// IsXBullish(iDir) &&
|
||||
// fimaHelper.IsValeOverLast(iBar.Index());
|
||||
|
||||
// //
|
||||
// has = fimaHelper.IsFiboSectionChanged(iDir, iBar.Index());
|
||||
// has = has &&
|
||||
// IsXBearish(iDir) &&
|
||||
// fimaHelper.IsPeakUnderLast(iBar.Index());
|
||||
|
||||
// //
|
||||
// has = fimaHelper.HasFiboPush(iDir, iBar.Index(), 5);
|
||||
|
||||
// //
|
||||
// XBoxZone fimaZones[];
|
||||
// int fimaZonesCount = fimaHelper.DetectXFIMAZones(
|
||||
// fimaZones,
|
||||
// iBar.Index(),
|
||||
// true, // Only Valid Zones ...
|
||||
// 50, // Number of Zones ...
|
||||
// 4, // Shadow Multiplier ...
|
||||
// 1, // Strength ...
|
||||
// 7, // Validation Length ...
|
||||
// 500 // Loopback ..
|
||||
// );
|
||||
|
||||
//
|
||||
// XPivot fimaPivots[];
|
||||
// int fimaPivotsCount = fimaHelper.DetecteXFIMAPivots(
|
||||
// fimaPivots,
|
||||
// iBar.Index(),
|
||||
// 50, // Number of Pivots ...
|
||||
// 7, // Validation Length ...
|
||||
// 500 // Loopback ...
|
||||
// );
|
||||
|
||||
// //
|
||||
// has = IsValidSize(fimaZonesCount);
|
||||
// if (has)
|
||||
// {
|
||||
// //
|
||||
// // Draw Detected Zones ...
|
||||
// for (int i = 0; i < fimaZonesCount; i++)
|
||||
// {
|
||||
// //
|
||||
// XCBoxObject *iObj;
|
||||
// has = poiDrawer.DrawBox(
|
||||
// fimaZones[i],
|
||||
// iObj,
|
||||
// true, // Ignore At ...
|
||||
// fimaZones[i].type // Specified Name ...
|
||||
// );
|
||||
// if (has)
|
||||
// {
|
||||
// zoneObjects.Add(iObj);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// has = IsValidSize(fimaPivotsCount);
|
||||
// if (has)
|
||||
// {
|
||||
// //
|
||||
// // Draw Detected Pivots ...
|
||||
// for (int i = 0; i < fimaPivotsCount; i++)
|
||||
// {
|
||||
// //
|
||||
// XCBarArrowObject *iObj;
|
||||
// has = poiDrawer.DrawPivot(
|
||||
// fimaPivots[i],
|
||||
// iObj);
|
||||
// if (has)
|
||||
// {
|
||||
// pivotObjects.Add(iObj);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
//
|
||||
// Detect DecisionBars ...
|
||||
// XOHCL decisionBars[];
|
||||
// int decisionBarsCount = 0;
|
||||
// ENUM_X_DIRECTION decisionBarDirs[];
|
||||
// decisionBarsCount = fimaHelper.DetectXFIMAPOIBars(
|
||||
// decisionBars,
|
||||
// decisionBarDirs,
|
||||
// iBar.Index(),
|
||||
// X_DIRECTION_ALL, // For Dir ...
|
||||
// 300 // Required Number of Bars ...
|
||||
// );
|
||||
// decisionBarsCount = fimaHelper.DetectXFIMAReversalPOIBars(
|
||||
// decisionBars,
|
||||
// decisionBarDirs,
|
||||
// iBar.Index(),
|
||||
// true, // Force Touch Boundary ...
|
||||
// X_DIRECTION_ALL, // For Dir ...
|
||||
// 300 // Required Number of Bars ...
|
||||
// );
|
||||
// decisionBarsCount = fimaHelper.DetectXFIMAContinuationalPOIBars(
|
||||
// decisionBars,
|
||||
// decisionBarDirs,
|
||||
// iBar.Index(),
|
||||
// true,
|
||||
// X_DIRECTION_ALL, // For Dir ...
|
||||
// 300 // Required Number of Bars ...
|
||||
// );
|
||||
|
||||
// //
|
||||
// has = IsValidSize(decisionBarsCount);
|
||||
// if (has)
|
||||
// {
|
||||
// //
|
||||
// for (int i = 0; i < decisionBarsCount; i++)
|
||||
// {
|
||||
// //
|
||||
// XCBarArrowObject *iObj;
|
||||
// has = poiDrawer.DrawBarArrow(
|
||||
// decisionBars[i],
|
||||
// iObj,
|
||||
// IsXBullish(decisionBarDirs[i]) ? X_PRICE_LOW : X_PRICE_HIGH,
|
||||
// 159,
|
||||
// IsXBullish(decisionBarDirs[i]) ? clrAqua : clrMagenta,
|
||||
// 5,
|
||||
// IsXBullish(decisionBarDirs[i]) ? ANCHOR_TOP : ANCHOR_BOTTOM,
|
||||
// "XOHCL_" + ToXString(TimeToSeconds(decisionBars[i].time)),
|
||||
// true, // Ignore Bar Tag ...
|
||||
// 5 // Threshold ...
|
||||
// );
|
||||
// if (has)
|
||||
// {
|
||||
// barObjects.Add(iObj);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -1,76 +0,0 @@
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
XOHCL tmpBar;
|
||||
int tmpIDX = -1;
|
||||
bool has = false;
|
||||
double upper = 0;
|
||||
double lower = 0;
|
||||
int length = zone.GetAge();
|
||||
|
||||
//
|
||||
// Support ...
|
||||
tmpIDX = bar.FindLowestIndex(length, MODE_LOW);
|
||||
if (IsValidIndex(tmpIDX))
|
||||
{
|
||||
//
|
||||
if (tmpBar.Init(symbol, period, tmpIDX))
|
||||
{
|
||||
//
|
||||
lower = iLow(symbol, period, tmpIDX);
|
||||
upper = bar.FindLowest(length, MODE_CLOSE);
|
||||
if (upper <= lower)
|
||||
{
|
||||
upper = tmpBar.GetDown();
|
||||
}
|
||||
|
||||
//
|
||||
has = support.Init(
|
||||
symbol,
|
||||
period,
|
||||
upper,
|
||||
lower,
|
||||
tmpBar.time,
|
||||
bar.time,
|
||||
X_DIRECTION_BULLISH,
|
||||
ToXString(X_BAR_PATTERN_SUPPORT) //
|
||||
);
|
||||
|
||||
//
|
||||
tmpBar.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Resistance ...
|
||||
tmpIDX = bar.FindHighestIndex(length, MODE_HIGH);
|
||||
if (IsValidIndex(tmpIDX))
|
||||
{
|
||||
//
|
||||
if (tmpBar.Init(symbol, period, tmpIDX))
|
||||
{
|
||||
//
|
||||
upper = iHigh(symbol, period, tmpIDX);
|
||||
lower = bar.FindHighest(length, MODE_CLOSE);
|
||||
if (upper <= lower)
|
||||
{
|
||||
upper = tmpBar.GetUp();
|
||||
}
|
||||
|
||||
//
|
||||
has = resistance.Init(
|
||||
symbol,
|
||||
period,
|
||||
upper,
|
||||
lower,
|
||||
tmpBar.time,
|
||||
bar.time,
|
||||
X_DIRECTION_BEARISH,
|
||||
ToXString(X_BAR_PATTERN_RESISTANCE) //
|
||||
);
|
||||
|
||||
//
|
||||
tmpBar.Clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,765 +0,0 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Indicator
|
||||
// -------------------------------------------------
|
||||
// Name: XFIMAPV
|
||||
// Description: Integrates All Requirements inside
|
||||
// this indicator for analyse Markets Based on OM1 ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XFIMA Indicator"
|
||||
#property icon "../Images/SaherElm_Logo_Color.ico"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
|
||||
//
|
||||
#define ShortName "XFIMA"
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
|
||||
//
|
||||
// Calculation ...
|
||||
input group "Calculation";
|
||||
input int pvValidationLength = 7; // Peaks and Vales Validation Length
|
||||
input int pvValidationCount = 2; // Recent Peak or Vale must under/over latests
|
||||
input ENUM_X_PRICE peakPriceType = X_PRICE_HIGH; // Peak Calculated Price
|
||||
input ENUM_X_PRICE valePriceType = X_PRICE_LOW; // Vale Calculated Price
|
||||
|
||||
//
|
||||
// Presentation ...
|
||||
input group "Presentation";
|
||||
input bool showPV = true; // Show Peaks and Vales
|
||||
input bool showHL = true; // Show Highs and Lows
|
||||
input int startCalculationForLastBars = 1500; // Calculate Last n Bars
|
||||
input int peakArrowCode = 159; // Peaks Arrow Code
|
||||
input int highArrowCode = 159; // Highs Arrow Code
|
||||
input int valeArrowCode = 159; // Vales Arrow Code
|
||||
input int lowArrowCode = 159; // Lows Arrow Code
|
||||
|
||||
//
|
||||
// Non Inputs ...
|
||||
|
||||
//
|
||||
#define hideColorIDX 0
|
||||
#define bullishColorIDX 1
|
||||
#define bearishColorIDX 2
|
||||
#define neuturalColorIDX 3
|
||||
|
||||
//
|
||||
#define bullishState 1
|
||||
#define neuturalState 0
|
||||
#define bearishState -1
|
||||
|
||||
//
|
||||
#define emptyValue 0.0
|
||||
|
||||
//
|
||||
// Buffers ...
|
||||
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 6
|
||||
#property indicator_plots 4
|
||||
|
||||
//
|
||||
// Plot Buffers ...
|
||||
|
||||
//
|
||||
// PEAKS ...
|
||||
|
||||
//
|
||||
#define peakBufferIndex 0
|
||||
double peakBuffer[];
|
||||
|
||||
//
|
||||
#define peakBufferPlotIndex 0
|
||||
#property indicator_label1 "PEAK"
|
||||
#property indicator_type1 DRAW_ARROW
|
||||
#property indicator_color1 clrMagenta
|
||||
#property indicator_width1 3
|
||||
|
||||
//
|
||||
// VALES ...
|
||||
|
||||
//
|
||||
#define valeBufferIndex 1
|
||||
double valeBuffer[];
|
||||
|
||||
//
|
||||
#define valeBufferPlotIndex 1
|
||||
#property indicator_label2 "VALE"
|
||||
#property indicator_type2 DRAW_ARROW
|
||||
#property indicator_color2 clrAqua
|
||||
#property indicator_width2 3
|
||||
|
||||
//
|
||||
// HIGHS ...
|
||||
|
||||
//
|
||||
#define highBufferIndex 2
|
||||
double highBuffer[];
|
||||
|
||||
//
|
||||
#define highBufferPlotIndex 2
|
||||
#property indicator_label3 "HIGH"
|
||||
#property indicator_type3 DRAW_ARROW
|
||||
#property indicator_color3 clrOrangeRed
|
||||
#property indicator_width3 3
|
||||
|
||||
//
|
||||
// LOWS ...
|
||||
|
||||
//
|
||||
#define lowBufferIndex 3
|
||||
double lowBuffer[];
|
||||
|
||||
//
|
||||
#define lowBufferPlotIndex 3
|
||||
#property indicator_label4 "LOW"
|
||||
#property indicator_type4 DRAW_ARROW
|
||||
#property indicator_color4 clrYellow
|
||||
#property indicator_width4 3
|
||||
|
||||
//
|
||||
// Data Buffers ...
|
||||
|
||||
//
|
||||
#define mLastBufferIndex 3
|
||||
|
||||
//
|
||||
#define highRawBufferIndex mLastBufferIndex + 1
|
||||
double highRawBuffer[];
|
||||
|
||||
//
|
||||
#define lowRawBufferIndex mLastBufferIndex + 2
|
||||
double lowRawBuffer[];
|
||||
|
||||
//
|
||||
// Variables ...
|
||||
|
||||
//
|
||||
int limit;
|
||||
|
||||
//
|
||||
int maxLength;
|
||||
|
||||
//
|
||||
int firstBarIndex;
|
||||
|
||||
//
|
||||
// Event Handlers ...
|
||||
|
||||
/**
|
||||
* Initialize Indicator ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
bool has = false;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
has = ValidateInputs();
|
||||
if (!has)
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// because in some cases we may have more than one input for
|
||||
// calculation and we must prevent any calculation
|
||||
// untill we pass the biggest input length, here we get max Input length
|
||||
// and then wait until pass it ...
|
||||
maxLength = ExtractMaxLengthOfInputs();
|
||||
|
||||
//
|
||||
// Initial Requirements ...
|
||||
has = InitRequirements();
|
||||
if (!has)
|
||||
{
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* De Initialize Indicator ...
|
||||
*
|
||||
* @param reason: Integer, De Initialization Reason ...
|
||||
*/
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// De Initialize all Handlers and etc ...
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Bars ...
|
||||
*
|
||||
* @param rates_total: Integer, Total Bars on Chart ...
|
||||
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
|
||||
* @param time: DateTime Array, History of Open Time ...
|
||||
* @param open: Double Array, History of Open Prices ...
|
||||
* @param high: Double Array, History of High Prices ...
|
||||
* @param low: Double Array, History of Low Prices ...
|
||||
* @param close: Double Array, History of Close Prices ...
|
||||
* @param tick_volume: Long, History of Tick Volumes on Bar ...
|
||||
* @param volume: Long, History of Trade Volumes ...
|
||||
* @param spread: Double, History of Spread Price ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int OnCalculate(
|
||||
const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// Validate Calculated Bars ...
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||
? rates_total
|
||||
: (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// Buffers Copy ...
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(
|
||||
i,
|
||||
prev_calculated,
|
||||
rates_total,
|
||||
//
|
||||
open,
|
||||
high,
|
||||
close,
|
||||
low,
|
||||
tick_volume //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Functions ...
|
||||
|
||||
/**
|
||||
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
*/
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Input Args for Initialization ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
IsXValid(peakPriceType) &&
|
||||
IsXValid(valePriceType) &&
|
||||
NotEmptyZero(pvValidationLength)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract Max Length of Inputs ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int ExtractMaxLengthOfInputs()
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
result = MathMax(result, pvValidationLength);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define Required Buffers ...
|
||||
*/
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// Plot Buffers ...
|
||||
|
||||
//
|
||||
// PV ...
|
||||
|
||||
//
|
||||
ENUM_DRAW_TYPE pvDrawType = showPV ? DRAW_ARROW : DRAW_NONE;
|
||||
|
||||
//
|
||||
// PEAK ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(peakBuffer, true);
|
||||
SetIndexBuffer(peakBufferIndex, peakBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(peakBufferPlotIndex, PLOT_SHOW_DATA, showPV);
|
||||
PlotIndexSetInteger(peakBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType);
|
||||
|
||||
//
|
||||
PlotIndexSetDouble(peakBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
PlotIndexSetInteger(peakBufferPlotIndex, PLOT_ARROW, peakArrowCode);
|
||||
|
||||
//
|
||||
// VALE ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(valeBuffer, true);
|
||||
SetIndexBuffer(valeBufferIndex, valeBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(valeBufferPlotIndex, PLOT_SHOW_DATA, showPV);
|
||||
PlotIndexSetInteger(valeBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType);
|
||||
|
||||
//
|
||||
PlotIndexSetDouble(valeBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
PlotIndexSetInteger(valeBufferPlotIndex, PLOT_ARROW, valeArrowCode);
|
||||
|
||||
//
|
||||
// HL ...
|
||||
|
||||
//
|
||||
ENUM_DRAW_TYPE hlDrawType = showHL ? DRAW_ARROW : DRAW_NONE;
|
||||
|
||||
//
|
||||
// HIGH ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(highBuffer, true);
|
||||
SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(highBufferPlotIndex, PLOT_SHOW_DATA, showHL);
|
||||
PlotIndexSetInteger(highBufferPlotIndex, PLOT_DRAW_TYPE, hlDrawType);
|
||||
|
||||
//
|
||||
PlotIndexSetDouble(highBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
PlotIndexSetInteger(highBufferPlotIndex, PLOT_ARROW, highArrowCode);
|
||||
|
||||
//
|
||||
// LOW ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(lowBuffer, true);
|
||||
SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(lowBufferPlotIndex, PLOT_SHOW_DATA, showHL);
|
||||
PlotIndexSetInteger(lowBufferPlotIndex, PLOT_DRAW_TYPE, hlDrawType);
|
||||
|
||||
//
|
||||
PlotIndexSetDouble(lowBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
PlotIndexSetInteger(lowBufferPlotIndex, PLOT_ARROW, lowArrowCode);
|
||||
|
||||
//
|
||||
// Data Buffers ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(lowRawBuffer, true);
|
||||
SetIndexBuffer(lowRawBufferIndex, lowRawBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(highRawBuffer, true);
|
||||
SetIndexBuffer(highRawBufferIndex, highRawBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial all Indicator Requirements ...
|
||||
*
|
||||
* @return ( false )
|
||||
*
|
||||
*/
|
||||
bool InitRequirements()
|
||||
{
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
//
|
||||
// Handlers ...
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Custom Buffers ...
|
||||
*
|
||||
* @param barIndex: Integer, Represent Current Bar ...
|
||||
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
|
||||
* @param ratesTotal: Integer, Represents All Available Bars ...
|
||||
* @param open: Double Array, History of Open Prices ...
|
||||
* @param high: Double Array, History of High Prices ...
|
||||
* @param close: Double Array, History of Close Prices ...
|
||||
* @param low: Double Array, History of Low Prices ...
|
||||
* @param tickVolume: Long, History of Tick Volumes on Bar ...
|
||||
*/
|
||||
void CalculateBuffers(
|
||||
int barIndex,
|
||||
const int prevCalculated,
|
||||
const int ratesTotal,
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &close[],
|
||||
const double &low[],
|
||||
const long &tickVolume[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Calculate Bars Limit and First Bar Index ...
|
||||
int barsLimit = startCalculationForLastBars > 0
|
||||
? startCalculationForLastBars
|
||||
: 0;
|
||||
if (barsLimit == 0)
|
||||
{
|
||||
//
|
||||
barsLimit = ratesTotal;
|
||||
firstBarIndex = barsLimit - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
firstBarIndex = startCalculationForLastBars;
|
||||
}
|
||||
|
||||
//
|
||||
// bool canCalculate = true;
|
||||
bool canCalculate =
|
||||
barIndex <= barsLimit;
|
||||
if (canCalculate)
|
||||
{
|
||||
//
|
||||
// Calculate Values ...
|
||||
CalculateValues(
|
||||
barIndex,
|
||||
prevCalculated,
|
||||
ratesTotal,
|
||||
open,
|
||||
high,
|
||||
close,
|
||||
low,
|
||||
tickVolume //
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
FillBuffersZero(barIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
|
||||
*
|
||||
* @param barIndex: Integer ...
|
||||
*/
|
||||
void FillBuffersZero(int barIndex)
|
||||
{
|
||||
//
|
||||
// TODO: Fill Buffers as Empty ...
|
||||
lowBuffer[barIndex] = emptyValue;
|
||||
highBuffer[barIndex] = emptyValue;
|
||||
peakBuffer[barIndex] = emptyValue;
|
||||
valeBuffer[barIndex] = emptyValue;
|
||||
highRawBuffer[barIndex] = emptyValue;
|
||||
lowRawBuffer[barIndex] = emptyValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Values ...
|
||||
*
|
||||
* @param barIndex: int, Specified Bar Index ...
|
||||
* @param prevCalculated: int, Provides Previous Calculated Bars ...
|
||||
* @param ratesTotal: int, Provides All Availabled Bars ...
|
||||
* @param open: double Collection, Provides Open Prices Time Series ...
|
||||
* @param high: double Collection, Provides High Prices Time Series ...
|
||||
* @param close: double Collection, Provides Close Prices Time Series ...
|
||||
* @param low: double Collection, Provides Low Prices Time Series ...
|
||||
* @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ...
|
||||
*/
|
||||
void CalculateValues(
|
||||
int barIndex,
|
||||
const int prevCalculated,
|
||||
const int ratesTotal,
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &close[],
|
||||
const double &low[],
|
||||
const long &tickVolume[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Common Requirements ...
|
||||
|
||||
//
|
||||
FillBuffersZero(barIndex);
|
||||
|
||||
//
|
||||
int lastBarIndex = barIndex + 1;
|
||||
int maxBarIndex = startCalculationForLastBars > 0
|
||||
? startCalculationForLastBars
|
||||
: ratesTotal;
|
||||
|
||||
//
|
||||
bool isFirstBar =
|
||||
startCalculationForLastBars > 0
|
||||
? barIndex == startCalculationForLastBars
|
||||
: barIndex == firstBarIndex;
|
||||
|
||||
//
|
||||
// Calculate Highs and Lows ...
|
||||
XOHCL iBar;
|
||||
bool has = iBar.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
barIndex //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
int lowestIDX = -1;
|
||||
double iRawLow = iBar.FindLowest(
|
||||
lowestIDX,
|
||||
pvValidationLength,
|
||||
valePriceType //
|
||||
);
|
||||
|
||||
//
|
||||
int highestIDX = -1;
|
||||
double iRawHigh = iBar.FindHighest(
|
||||
highestIDX,
|
||||
pvValidationLength,
|
||||
peakPriceType //
|
||||
);
|
||||
|
||||
//
|
||||
lowRawBuffer[barIndex] = iRawLow;
|
||||
highRawBuffer[barIndex] = iRawHigh;
|
||||
|
||||
//
|
||||
lowBuffer[barIndex] = iRawLow;
|
||||
highBuffer[barIndex] = iRawHigh;
|
||||
|
||||
//
|
||||
if (barIndex < firstBarIndex - (pvValidationLength + 1))
|
||||
{
|
||||
//
|
||||
double tmp[];
|
||||
ArrayCopy(
|
||||
tmp,
|
||||
lowRawBuffer,
|
||||
0,
|
||||
barIndex,
|
||||
pvValidationLength //
|
||||
);
|
||||
double minLow = GetMin(tmp);
|
||||
bool isLow = iRawLow < minLow;
|
||||
lowBuffer[barIndex] =
|
||||
isLow
|
||||
? iRawLow
|
||||
: lowBuffer[lastBarIndex];
|
||||
|
||||
//
|
||||
XClean(tmp);
|
||||
ArrayCopy(
|
||||
tmp,
|
||||
highRawBuffer,
|
||||
0,
|
||||
barIndex,
|
||||
pvValidationLength //
|
||||
);
|
||||
double maxHigh = GetMax(tmp);
|
||||
bool isHigh = iRawHigh > maxHigh;
|
||||
highBuffer[barIndex] =
|
||||
isHigh
|
||||
? iRawHigh
|
||||
: highBuffer[lastBarIndex];
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
XClean(tmp);
|
||||
}
|
||||
|
||||
// //
|
||||
// double iLow = emptyValue;
|
||||
// // IsLow(iLow, barIndex);
|
||||
// double iPLow = isFirstBar
|
||||
// ? iLow
|
||||
// : lowRawBuffer[lastBarIndex];
|
||||
|
||||
// //
|
||||
// double iHigh = emptyValue;
|
||||
// IsHigh(iHigh, barIndex);
|
||||
// double iPHigh = isFirstBar
|
||||
// ? iHigh
|
||||
// : highRawBuffer[lastBarIndex];
|
||||
|
||||
// //
|
||||
// // Clculate Values ...
|
||||
|
||||
// //
|
||||
// lowRawBuffer[barIndex] = iLow;
|
||||
// highRawBuffer[barIndex] = iHigh;
|
||||
|
||||
// //
|
||||
// lowBuffer[barIndex] = NotEmptyZero(iLow)
|
||||
// ? iLow
|
||||
// : iPLow;
|
||||
// highBuffer[barIndex] = NotEmptyZero(iHigh)
|
||||
// ? iHigh
|
||||
// : iPHigh;
|
||||
|
||||
// //
|
||||
// double iP2Low =
|
||||
// barIndex < maxBarIndex - 2
|
||||
// ? lowBuffer[barIndex + 2]
|
||||
// : emptyValue;
|
||||
// double iP2High =
|
||||
// barIndex < maxBarIndex - 2
|
||||
// ? highBuffer[barIndex + 2]
|
||||
// : emptyValue;
|
||||
|
||||
// //
|
||||
// double mLowValues[];
|
||||
// double iVale = emptyValue;
|
||||
// if (NotEmptyZero(iPLow))
|
||||
// {
|
||||
// Add(iPLow, mLowValues);
|
||||
// }
|
||||
// if (NotEmptyZero(iP2Low))
|
||||
// {
|
||||
// Add(iP2Low, mLowValues);
|
||||
// }
|
||||
// bool isVale = iLow <= GetMin(mLowValues);
|
||||
// iVale = isVale
|
||||
// ? iLow
|
||||
// : isFirstBar
|
||||
// ? emptyValue
|
||||
// : valeBuffer[lastBarIndex];
|
||||
// valeBuffer[barIndex] = iVale;
|
||||
|
||||
// //
|
||||
// double mHighValues[];
|
||||
// double iPeak = emptyValue;
|
||||
// if (NotEmptyZero(iPHigh))
|
||||
// {
|
||||
// Add(iPHigh, mHighValues);
|
||||
// }
|
||||
// if (NotEmptyZero(iP2High))
|
||||
// {
|
||||
// Add(iP2High, mHighValues);
|
||||
// }
|
||||
// bool isPeak = iHigh >= GetMax(mHighValues);
|
||||
// iPeak = isPeak
|
||||
// ? iHigh
|
||||
// : isFirstBar
|
||||
// ? emptyValue
|
||||
// : peakBuffer[lastBarIndex];
|
||||
// peakBuffer[barIndex] = iPeak;
|
||||
|
||||
// //
|
||||
// bool has =
|
||||
// NotEmptyZero(iLow) ||
|
||||
// NotEmptyZero(iPLow) ||
|
||||
// NotEmptyZero(iHigh) ||
|
||||
// NotEmptyZero(iPHigh);
|
||||
// if (has)
|
||||
// {
|
||||
// }
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1,295 +0,0 @@
|
||||
|
||||
// //
|
||||
// isBullish =
|
||||
// //
|
||||
// // Vales Same ...
|
||||
// sameVales >= 7 &&
|
||||
// //
|
||||
// // PBar Patterns ...
|
||||
// isBarPatternsPassed &&
|
||||
// isPBarCloseOverFast &&
|
||||
// //
|
||||
// // Validate PullBack based on HK Bond ...
|
||||
// isPullbackBullish &&
|
||||
// pBar.close > pHKBondLower;
|
||||
|
||||
//
|
||||
// poiDrawer.DrawPatternAnalysis(
|
||||
// pBarAnalysis,
|
||||
// structureDrawConfig.barAnalysisDrawConfig //
|
||||
// );
|
||||
|
||||
// //
|
||||
// if (IsValidSize(zonesCount))
|
||||
// {
|
||||
// //
|
||||
// poiDrawer.DrawZones(
|
||||
// zones,
|
||||
// structureDrawConfig.drawConfig //
|
||||
// );
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (IsValidSize(affectedZonesCount))
|
||||
// {
|
||||
// //
|
||||
// poiDrawer.DrawZones(
|
||||
// affectedZones,
|
||||
// structureDrawConfig.drawConfig //
|
||||
// );
|
||||
// }
|
||||
|
||||
//
|
||||
// poiDrawer.DrawZones(
|
||||
// affectedZonesBullish,
|
||||
// structureDrawConfig.drawConfig //
|
||||
// );
|
||||
|
||||
// //
|
||||
// poiDrawer.DrawZones(
|
||||
// affectedZonesBearish,
|
||||
// structureDrawConfig.drawConfig //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Update POI Zones ...
|
||||
// ENUM_X_DETECTOR_ZONE_ACTION zoneActions[];
|
||||
// poiDetector.UpdateZones(
|
||||
// iBar,
|
||||
// zoneActions //
|
||||
// // Validation Length ...
|
||||
// // Required Zones ...
|
||||
// // Loopback ...
|
||||
// );
|
||||
|
||||
//
|
||||
// Retrieve Conditions ...
|
||||
// conditions.Clean();
|
||||
// has = fimaHelper.GetConditions(
|
||||
// conditions,
|
||||
// barIndex,
|
||||
// 10 // Loopback ...
|
||||
// );
|
||||
// if (!has)
|
||||
// {
|
||||
// //
|
||||
// iBar.Clean();
|
||||
// conditions.Clean();
|
||||
|
||||
// //
|
||||
// return;
|
||||
// }
|
||||
|
||||
//
|
||||
// structure.Clean();
|
||||
// poiDetector.AnalyseMarket(
|
||||
// structure,
|
||||
// structureConfig,
|
||||
// barIndex //
|
||||
// );
|
||||
// poiDrawer.drawnObjects.Clear();
|
||||
// poiDrawer.DrawMarketStructure(
|
||||
// structure,
|
||||
// structureDrawConfig //
|
||||
// );
|
||||
|
||||
/**
|
||||
* Check Bar Has Signal Based on Strategy X ...
|
||||
*
|
||||
* @param bar: XOHCL, reference to Bar ...
|
||||
* @param zone: XBoxZone, reference to holds affected zone ...
|
||||
* @param targets: XTarget, reference to detected Signal's Targets collections ...
|
||||
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool StrategyXHasSignal(
|
||||
XOHCL &bar,
|
||||
XBoxZone &zone,
|
||||
XTarget &targets[],
|
||||
ENUM_X_DIRECTION &dir //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
zone.Clean();
|
||||
XClean(targets);
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Requirements ...
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
XOHCL p2Bar;
|
||||
bool isBullish = false;
|
||||
bool isBearish = false;
|
||||
XOHCL continuationalBar;
|
||||
XBoxZone continuationalZones[];
|
||||
|
||||
//
|
||||
// Read PBar ...
|
||||
result = bar.GetPreviousBar(pBar);
|
||||
result = result &&
|
||||
pBar.GetPreviousBar(p2Bar);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
pBar.Clean();
|
||||
p2Bar.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading pBar Patterns ...
|
||||
XPatternAnalysis pBarAnalysis;
|
||||
poiDetector.AnalyseBarPatterns(
|
||||
pBar,
|
||||
pBarAnalysis,
|
||||
structureConfig.barsAnalysisConfig //
|
||||
);
|
||||
|
||||
//
|
||||
// Check Continuational Pullback ...
|
||||
bool isContinuationPullBack = poiDetector.IsContinuationPullbackPattern(
|
||||
pBar,
|
||||
zone,
|
||||
continuationalZones,
|
||||
dir,
|
||||
continuationalBar,
|
||||
3, // Continuational Length ...
|
||||
true, // Force Continuational Loopback Has Zones ...
|
||||
true, // Force Continuational Loopback Has Patterns ...
|
||||
2, // Pullback Length ...
|
||||
false // Force Pullback Break ...
|
||||
);
|
||||
|
||||
//
|
||||
// Do ...
|
||||
|
||||
//
|
||||
isBullish =
|
||||
//
|
||||
IsXBullish(dir) &&
|
||||
isContinuationPullBack &&
|
||||
continuationalBar.GetUp() < pBar.GetDown() &&
|
||||
true
|
||||
// isPBarHasBullishPatterns
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
isBearish =
|
||||
//
|
||||
IsXBearish(dir) &&
|
||||
isContinuationPullBack &&
|
||||
continuationalBar.GetDown() > pBar.GetUp() &&
|
||||
true
|
||||
// isPBarHasBearishPatterns
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = isBullish ||
|
||||
isBearish;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
dir =
|
||||
isBullish
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
result = HasDirection(dir);
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Zone ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// zone.to = bar.time;
|
||||
// poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
|
||||
|
||||
//
|
||||
// Draw Continuational Zones ...
|
||||
UpdateToTime(continuationalZones, bar.time);
|
||||
poiDrawer.DrawZones(continuationalZones, structureDrawConfig.drawConfig);
|
||||
|
||||
//
|
||||
zone.Clean();
|
||||
|
||||
//
|
||||
int idx = -1;
|
||||
if (isBullish)
|
||||
{
|
||||
idx = GetHighestBelow(bar.GetDown(), continuationalZones);
|
||||
}
|
||||
else
|
||||
{
|
||||
idx = GetLowestAbove(bar.GetUp(), continuationalZones);
|
||||
}
|
||||
result = IsValidIndex(idx);
|
||||
if (result)
|
||||
{
|
||||
zone = continuationalZones[idx];
|
||||
}
|
||||
|
||||
//
|
||||
if (zone.IsValid())
|
||||
{
|
||||
//
|
||||
XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
|
||||
iConfig.bullishColor = clrYellow;
|
||||
iConfig.bearishColor = clrYellow;
|
||||
poiDrawer.DrawZones(continuationalZones, iConfig);
|
||||
}
|
||||
|
||||
//
|
||||
// Manage Stops ...
|
||||
if (result)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
result = zone.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Targets ...
|
||||
if (result)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
zone.Clean();
|
||||
XClean(targets);
|
||||
dir = X_DIRECTION_NONE;
|
||||
}
|
||||
pBar.Clean();
|
||||
p2Bar.Clean();
|
||||
continuationalBar.Clean();
|
||||
XClean(continuationalZones);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,977 +0,0 @@
|
||||
`
|
||||
//
|
||||
// an Structure for Holds an Specified Symbols
|
||||
// Positions Info ...
|
||||
struct XTradeSymbolInfo
|
||||
{
|
||||
//
|
||||
// Properties ...
|
||||
|
||||
//
|
||||
string symbol; // Trading Symbol
|
||||
|
||||
//
|
||||
int longs; // All Long Trades
|
||||
int shorts; // All Short Trades
|
||||
|
||||
//
|
||||
int trades; // All Trades
|
||||
|
||||
//
|
||||
int losses; // All Loosing Trades
|
||||
int profits; // All Winning Trades
|
||||
|
||||
//
|
||||
datetime managedStart; // Managed Start Time
|
||||
|
||||
//
|
||||
int managedSLs; // Managed SL(s)
|
||||
int managedTPs; // Managed TP(s)
|
||||
int managedTrades; // Managed Trades
|
||||
|
||||
//
|
||||
double managedBalance; // Managed Start Balance
|
||||
double managedProfits; // Managed Profit(s)
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XTradeSymbolInfo()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
symbol = NULL;
|
||||
|
||||
//
|
||||
longs = 0;
|
||||
shorts = 0;
|
||||
|
||||
//
|
||||
trades = 0;
|
||||
|
||||
//
|
||||
losses = 0;
|
||||
profits = 0;
|
||||
|
||||
//
|
||||
managedStart = NULL;
|
||||
|
||||
//
|
||||
managedSLs = 0;
|
||||
managedTPs = 0;
|
||||
managedTrades = 0;
|
||||
|
||||
//
|
||||
managedBalance = 0;
|
||||
managedProfits = 0;
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = IsSpecifiedValid(symbol);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool IsSameAs(XTradeSymbolInfo &item)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = IsValid() &&
|
||||
item.IsValid() &&
|
||||
symbol == item.symbol;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string GetRestrictionDescription(
|
||||
ENUM_XTRADE_RESTRICTION_PERIOD period //
|
||||
)
|
||||
{
|
||||
//
|
||||
string result = NULL;
|
||||
|
||||
//
|
||||
if (!IsValid() ||
|
||||
!HasRestrictions(period))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result +=
|
||||
"-------------------" + "\n" +
|
||||
"Restrictions: " + "\n" +
|
||||
"-------------------" + "\n" +
|
||||
"Symbol: " + ToXString(symbol) + "\n" +
|
||||
"Period: " + ToXString(period) + "\n" +
|
||||
"Start: " + ToFormatString(managedStart) + "\n" +
|
||||
"Balance: " + ToXString(managedBalance) + "\n" +
|
||||
"-------------------" + "\n" +
|
||||
"Trades: " + ToXString(managedTrades) + "\n" +
|
||||
"SL: " + ToXString(managedSLs) + "\n" +
|
||||
"TP: " + ToXString(managedTPs) + "\n" +
|
||||
"Profit: " + ToXString(managedProfits) + "\n" +
|
||||
"";
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
void SetForceCloseTradesAt(
|
||||
string _forceCloseAt //
|
||||
)
|
||||
{
|
||||
forceCloseAt = _forceCloseAt;
|
||||
}
|
||||
|
||||
//
|
||||
void SetTradeSession(
|
||||
string symbol,
|
||||
string start,
|
||||
string end,
|
||||
string name = NULL //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Validate Args ...
|
||||
bool has = IsValid(end) &&
|
||||
IsValid(start) &&
|
||||
IsValid(symbol);
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Create Session ...
|
||||
|
||||
//
|
||||
XTradeSession session;
|
||||
|
||||
//
|
||||
session.end = end;
|
||||
session.name = name;
|
||||
session.start = start;
|
||||
|
||||
//
|
||||
int sessionIDX = -1;
|
||||
has = FindSymbolSession(
|
||||
sessionIDX,
|
||||
symbol //
|
||||
);
|
||||
|
||||
//
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
// Add New Symbol Session ...
|
||||
|
||||
//
|
||||
XSymbolSessions iSymbolSession;
|
||||
iSymbolSession.symbol = symbol;
|
||||
|
||||
//
|
||||
AddTradingSession(
|
||||
session,
|
||||
iSymbolSession //
|
||||
);
|
||||
|
||||
//
|
||||
AddRef(
|
||||
iSymbolSession,
|
||||
sessions //
|
||||
);
|
||||
|
||||
//
|
||||
iSymbolSession.Clean();
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Update Trading Sessions of Exists Symbol Session ...
|
||||
AddTradingSession(
|
||||
session,
|
||||
sessions[sessionIDX] //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
session.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
void SetTradeRestrictions(
|
||||
ENUM_XTRADE_RESTRICTION_PERIOD _period,
|
||||
int _maxAllowedTPs,
|
||||
int _maxAllowedSLs,
|
||||
int _maxAllowedTrades //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Normalizing Args ...
|
||||
_maxAllowedTPs = NormalizeInt(_maxAllowedTPs, 0);
|
||||
_maxAllowedSLs = NormalizeInt(_maxAllowedSLs, 0);
|
||||
_maxAllowedTrades = NormalizeInt(_maxAllowedTrades, 0);
|
||||
|
||||
//
|
||||
restrictionsPeriod = _period;
|
||||
maxAllowedTPs = _maxAllowedTPs;
|
||||
maxAllowedSLs = _maxAllowedSLs;
|
||||
maxAllowedTrades = _maxAllowedTrades;
|
||||
}
|
||||
//
|
||||
// Symbol Info ...
|
||||
|
||||
//
|
||||
bool FindSymbolIndex(
|
||||
int &index,
|
||||
XTradeSymbolInfo &item //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
index = -1;
|
||||
|
||||
//
|
||||
result = item.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = HasChild(symbols);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
index = FindIndex(
|
||||
item,
|
||||
symbols //
|
||||
);
|
||||
|
||||
//
|
||||
result = IsValidIndex(index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool FindSymbolIndex(
|
||||
int &index,
|
||||
string symbol //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
index = -1;
|
||||
|
||||
//
|
||||
result = IsValid(symbol) &&
|
||||
HasChild(symbols);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int count = ArraySize(symbols);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
result = symbols[i].symbol == symbol;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = IsValidIndex(index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
void AddOrUpdateSymbolInfo(XTradeSymbolInfo &item)
|
||||
{
|
||||
//
|
||||
bool has = item.IsValid();
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
int index = -1;
|
||||
bool isExists = FindSymbolIndex(
|
||||
index,
|
||||
item //
|
||||
);
|
||||
if (!isExists)
|
||||
{
|
||||
//
|
||||
AddRef(
|
||||
item,
|
||||
symbols //
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
symbols[index].longs += item.longs;
|
||||
symbols[index].shorts += item.shorts;
|
||||
symbols[index].trades += item.trades;
|
||||
symbols[index].losses += item.losses;
|
||||
symbols[index].profits += item.profits;
|
||||
symbols[index].managedSLs += item.managedSLs;
|
||||
symbols[index].managedTPs += item.managedTPs;
|
||||
symbols[index].managedTrades += item.managedTrades;
|
||||
symbols[index].managedProfits += item.managedProfits;
|
||||
|
||||
//
|
||||
// Handle Remove on Managed SL based On Managed TP ...
|
||||
if (item.managedTPs > 0)
|
||||
{
|
||||
//
|
||||
symbols[index].managedSLs -= item.managedTPs;
|
||||
if (symbols[index].managedSLs < 0)
|
||||
{
|
||||
symbols[index].managedSLs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Remove on Managed TP based On Managed SL ...
|
||||
if (item.managedSLs > 0)
|
||||
{
|
||||
//
|
||||
symbols[index].managedTPs -= item.managedSLs;
|
||||
if (symbols[index].managedTPs < 0)
|
||||
{
|
||||
symbols[index].managedTPs = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void ResetSymbolsRestrictions()
|
||||
{
|
||||
//
|
||||
bool has = HasChild(symbols);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
string prefix = "Protector: ";
|
||||
|
||||
//
|
||||
datetime start = TimeCurrent();
|
||||
double balance = trader.mAccount.GetBalance();
|
||||
bool hasRestrictions = HasRestrictions(restrictionsPeriod);
|
||||
if (!hasRestrictions)
|
||||
{
|
||||
//
|
||||
balance = 0;
|
||||
start = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
int count = ArraySize(symbols);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XTradeSymbolInfo iInfo = symbols[i];
|
||||
if (reportRestrictions)
|
||||
{
|
||||
//
|
||||
string message = iInfo.GetRestrictionDescription(restrictionsPeriod);
|
||||
alert.SendAlert(message);
|
||||
}
|
||||
SaveRestrictions(iInfo);
|
||||
|
||||
//
|
||||
symbols[i].managedSLs = 0;
|
||||
symbols[i].managedTPs = 0;
|
||||
symbols[i].managedTrades = 0;
|
||||
symbols[i].managedProfits = 0;
|
||||
symbols[i].managedStart = start;
|
||||
symbols[i].managedBalance = balance;
|
||||
|
||||
//
|
||||
iInfo.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
string message = prefix + "Reset Symbols Restrictions";
|
||||
HandleReportProtector(message);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void HandleRestrictions()
|
||||
{
|
||||
//
|
||||
bool isNewDay = timeTracker.IsNewDay();
|
||||
bool isNewHour = timeTracker.IsNewHour();
|
||||
bool isNewWeek = timeTracker.IsNewWeek();
|
||||
bool isNewMonth = timeTracker.IsNewMonth();
|
||||
|
||||
//
|
||||
// Reset Force Closed Flag on new Day Starts ...
|
||||
if (isNewDay)
|
||||
{
|
||||
isForceCloseAtTime = false;
|
||||
}
|
||||
|
||||
//
|
||||
bool canResetRestrictions =
|
||||
(
|
||||
//
|
||||
// Hourly ...
|
||||
(isNewHour &&
|
||||
restrictionsPeriod == XTRADE_RESTRICATION_HOURLY)
|
||||
//
|
||||
||
|
||||
//
|
||||
// Daily ...
|
||||
(isNewDay &&
|
||||
restrictionsPeriod == XTRADE_RESTRICATION_DAILY)
|
||||
//
|
||||
||
|
||||
//
|
||||
// Weekly ...
|
||||
(isNewWeek &&
|
||||
restrictionsPeriod == XTRADE_RESTRICATION_WEEKLY)
|
||||
//
|
||||
||
|
||||
//
|
||||
// Monthly ...
|
||||
(isNewMonth &&
|
||||
restrictionsPeriod == XTRADE_RESTRICATION_MONTHLY)
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
if (canResetRestrictions)
|
||||
{
|
||||
ResetSymbolsRestrictions();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
bool SaveRestrictions(XTradeSymbolInfo &info)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (!mSaveRestrictions)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = info.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string filePath = GetRestrictionsFilePath(info.symbol);
|
||||
result = IsValid(filePath);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string content = info.GetRestrictionDescription(restrictionsPeriod);
|
||||
|
||||
//
|
||||
result = collector.Append(
|
||||
filePath,
|
||||
content //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Symbol Session ...
|
||||
|
||||
//
|
||||
bool FindSymbolSession(
|
||||
int &index,
|
||||
string symbol //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
index = -1;
|
||||
|
||||
//
|
||||
result = IsValid(symbol) &&
|
||||
HasChild(sessions);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int count = ArraySize(sessions);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
result = sessions[i].symbol == symbol;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = IsValidIndex(index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
void AddTradingSession(
|
||||
XTradeSession &session,
|
||||
XSymbolSessions &symbolSession //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool has = session.IsValid() &&
|
||||
symbolSession.IsValid();
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Session Exists in Symbol Session ...
|
||||
bool isExists = false;
|
||||
if (HasChild(symbolSession.sessions))
|
||||
{
|
||||
//
|
||||
int count = ArraySize(symbolSession.sessions);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
isExists = symbolSession.sessions[i].end == session.end &&
|
||||
symbolSession.sessions[i].start == session.start;
|
||||
if (isExists)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (!isExists)
|
||||
{
|
||||
//
|
||||
AddRef(
|
||||
session,
|
||||
symbolSession.sessions //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Signal Execution Conditions ...
|
||||
*
|
||||
* @param signal: XSignal instance reference ...
|
||||
* @param executionResult: ENUM_X_SIGNAL_EXECUTION_RESULT member reference ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool CheckSignal(
|
||||
XSignal &signal,
|
||||
ENUM_X_SIGNAL_EXECUTION_RESULT &executionResult //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
executionResult = X_SIGNAL_EXECUTION_UNKNOWN;
|
||||
|
||||
//
|
||||
// Validate Signal ...
|
||||
result = signal.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Reporting Signal ...
|
||||
if (reportSignals)
|
||||
{
|
||||
//
|
||||
string message = signal.GetMessage("Provided");
|
||||
alert.SendAlert(message);
|
||||
}
|
||||
|
||||
//
|
||||
SaveSignal(signal);
|
||||
|
||||
//
|
||||
// Check Trade Permission ...
|
||||
if (!allowTrade)
|
||||
{
|
||||
//
|
||||
result = false;
|
||||
executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isLong = IsLong(signal.type);
|
||||
bool isShort = IsShort(signal.type);
|
||||
|
||||
//
|
||||
bool isLongAndAllowed =
|
||||
isLong &&
|
||||
allowLongs;
|
||||
|
||||
//
|
||||
bool isShortAndAllowed =
|
||||
isShort &&
|
||||
allowShorts;
|
||||
|
||||
//
|
||||
result = isLongAndAllowed ||
|
||||
isShortAndAllowed;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Symbol Info Exists or not ...
|
||||
int symbolInfoIDX = -1;
|
||||
bool isSymbolInfoExists = FindSymbolIndex(
|
||||
symbolInfoIDX,
|
||||
signal.symbol //
|
||||
);
|
||||
|
||||
//
|
||||
// Check Symbol Session Exists or not ...
|
||||
int symbolSessionIDX = -1;
|
||||
bool isSymbolSessionExists = FindSymbolSession(
|
||||
symbolSessionIDX,
|
||||
signal.symbol //
|
||||
);
|
||||
|
||||
//
|
||||
// Chack Trade Session Validating ...
|
||||
if (isSymbolSessionExists)
|
||||
{
|
||||
//
|
||||
result = sessions[symbolSessionIDX].CanTrade();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
executionResult = X_SIGNAL_EXECUTION_FAILED_DELAY_NOT_PASSED;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Trade Permissions Based on SL(s) Count ...
|
||||
bool hasRestrictions = restrictionsPeriod != XTRADE_RESTRICATION_NONE;
|
||||
if (hasRestrictions)
|
||||
{
|
||||
//
|
||||
// Only Can Check Restrictions when
|
||||
// Symbol Info Exists ...
|
||||
if (isSymbolInfoExists)
|
||||
{
|
||||
//
|
||||
bool isTPAllowed = maxAllowedTPs == 0
|
||||
? true
|
||||
: symbols[symbolInfoIDX].managedTPs < maxAllowedTPs;
|
||||
bool isSLAllowed = maxAllowedSLs == 0
|
||||
? true
|
||||
: symbols[symbolInfoIDX].managedSLs < maxAllowedSLs;
|
||||
bool isTradeAllowed = maxAllowedTrades == 0
|
||||
? true
|
||||
: symbols[symbolInfoIDX].managedTrades < maxAllowedTrades;
|
||||
|
||||
//
|
||||
result = isTPAllowed &&
|
||||
isSLAllowed &&
|
||||
isTradeAllowed;
|
||||
}
|
||||
|
||||
//
|
||||
// Report Error ...
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
executionResult = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute Specified Signal ...
|
||||
*
|
||||
* @param signal: XSignal instance reference ...
|
||||
* @param conditions: XCATBEAStrategyConditions instance reference ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Execute(XSignal &signal)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = signal.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int idx = -1;
|
||||
bool isExists = HasTrade(
|
||||
idx,
|
||||
signal //
|
||||
);
|
||||
result = !isExists;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
ENUM_X_SIGNAL_EXECUTION_RESULT executionResult;
|
||||
|
||||
//
|
||||
// Checking Signal For Execution ...
|
||||
result = CheckSignal(
|
||||
signal,
|
||||
executionResult //
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
result = trader.ExecuteSignal(
|
||||
signal,
|
||||
executionResult //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Alert Signal Execution ...
|
||||
if (reportTrades)
|
||||
{
|
||||
//
|
||||
string executionMessage = ToString(executionResult);
|
||||
|
||||
//
|
||||
string message = NULL;
|
||||
if (result)
|
||||
{
|
||||
message = signal.GetMessage("Executed");
|
||||
}
|
||||
else
|
||||
{
|
||||
message = signal.GetMessage("Failed due (" + executionMessage + ")");
|
||||
}
|
||||
|
||||
//
|
||||
alert.SendAlert(message);
|
||||
}
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Create Symbol Info Struct ...
|
||||
XTradeSymbolInfo iSymbolInfo;
|
||||
|
||||
//
|
||||
iSymbolInfo.trades = 1;
|
||||
iSymbolInfo.managedTrades = 1;
|
||||
iSymbolInfo.symbol = signal.symbol;
|
||||
|
||||
//
|
||||
bool isLong = IsLong(signal.type);
|
||||
if (isLong)
|
||||
{
|
||||
iSymbolInfo.longs = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
iSymbolInfo.shorts = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Fill Balance for Restrications ...
|
||||
bool hasRestrictions = HasRestrictions(restrictionsPeriod);
|
||||
if (hasRestrictions)
|
||||
{
|
||||
//
|
||||
// Read Balance ...
|
||||
double balance = trader.mAccount.GetBalance();
|
||||
iSymbolInfo.managedBalance = balance;
|
||||
iSymbolInfo.managedStart = TimeCurrent();
|
||||
}
|
||||
|
||||
//
|
||||
AddOrUpdateSymbolInfo(iSymbolInfo);
|
||||
|
||||
//
|
||||
// Create Trade Struct ...
|
||||
XTradeInfo iTrade;
|
||||
|
||||
//
|
||||
ulong positionID = trader.GetLastOpenPositionTicket();
|
||||
double commission = trader.GetPositionCommission(positionID);
|
||||
|
||||
//
|
||||
iTrade.signal = signal;
|
||||
iTrade.positionID = positionID;
|
||||
iTrade.commission = commission;
|
||||
iTrade.signaledAt = signal.time;
|
||||
iTrade.executedAt = TimeCurrent();
|
||||
iTrade.conditions = signal.conditions;
|
||||
|
||||
//
|
||||
AddRef(
|
||||
iTrade,
|
||||
trades //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Specified Symbol is Active for
|
||||
* Analysing or Open Trades ...
|
||||
*/
|
||||
bool IsActiveSession(string symbol)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
result = IsValid(symbol);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Complete this ...
|
||||
|
||||
// //
|
||||
// // Check Symbol Session Exists or not ...
|
||||
// int symbolSessionIDX = -1;
|
||||
// bool isSymbolSessionExists = FindSymbolSession(
|
||||
// symbolSessionIDX,
|
||||
// symbol //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Chack Trade Session Validating ...
|
||||
// if (isSymbolSessionExists)
|
||||
// {
|
||||
// result = sessions[symbolSessionIDX].CanTrade();
|
||||
// }
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string forceCloseAt;
|
||||
bool isForceCloseAtTime;
|
||||
|
||||
//
|
||||
int maxAllowedTPs;
|
||||
int maxAllowedSLs;
|
||||
int maxAllowedTrades;
|
||||
ENUM_XTRADE_RESTRICTION_PERIOD restrictionsPeriod;
|
||||
|
||||
XTradeSymbolInfo symbols[];
|
||||
XSymbolSessions sessions[];
|
||||
|
||||
//
|
||||
forceCloseAt = NULL;
|
||||
isForceCloseAtTime = false;
|
||||
|
||||
//
|
||||
maxAllowedTPs = 0;
|
||||
maxAllowedSLs = 0;
|
||||
maxAllowedTrades = 0;
|
||||
restrictionsPeriod = XTRADE_RESTRICATION_NONE;
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,379 +0,0 @@
|
||||
|
||||
/**
|
||||
* Create Bar Object ...
|
||||
*
|
||||
* @param bar: XOHCL instance Reference ...
|
||||
* @param object: XCOHCLObject pointer Reference ..
|
||||
* @param to: Datetime ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool CreateBar(
|
||||
XOHCL &bar,
|
||||
XCOHCLObject *&object,
|
||||
datetime to = NULL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
object = NULL;
|
||||
|
||||
//
|
||||
result = bar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
to = NormalizeTime(to);
|
||||
|
||||
//
|
||||
string prefix = Prefix();
|
||||
long chartID = ChartIdentification();
|
||||
int window = SubWindowIdentification();
|
||||
|
||||
//
|
||||
int width = BarWidth();
|
||||
|
||||
//
|
||||
color mBullishColor = BarBullishColor();
|
||||
color mBearishColor = BarBearishColor();
|
||||
|
||||
//
|
||||
bool fillBody = BarFillBody();
|
||||
bool fillHighShadow = BarFillHighShadow();
|
||||
bool fillLowShadow = BarFillLowShadow();
|
||||
|
||||
//
|
||||
ENUM_LINE_STYLE bodyStyle = BarBodyStyle();
|
||||
ENUM_LINE_STYLE highShadowStyle = BarHighShadowStyle();
|
||||
ENUM_LINE_STYLE lowShadowStyle = BarLowShadowStyle();
|
||||
|
||||
//
|
||||
object = new XCOHCLObject();
|
||||
result = object.Create(
|
||||
chartID,
|
||||
window,
|
||||
bar,
|
||||
to,
|
||||
prefix //
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Apply Styling ...
|
||||
|
||||
//
|
||||
object.BodyWidth(width);
|
||||
object.LowShadowWidth(width);
|
||||
object.HighShadowWidth(width);
|
||||
|
||||
//
|
||||
object.BodyStyle(bodyStyle);
|
||||
object.LowShadowStyle(lowShadowStyle);
|
||||
object.HighShadowStyle(highShadowStyle);
|
||||
|
||||
//
|
||||
bool isBullish = bar.IsBullish();
|
||||
if (isBullish)
|
||||
{
|
||||
//
|
||||
object.BodyColor(mBullishColor);
|
||||
object.LowShadowColor(mBullishColor);
|
||||
object.HighShadowColor(mBullishColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
object.BodyColor(mBearishColor);
|
||||
object.LowShadowColor(mBearishColor);
|
||||
object.HighShadowColor(mBearishColor);
|
||||
}
|
||||
|
||||
//
|
||||
object.BodyFill(fillBody);
|
||||
object.HighShadowFill(fillHighShadow);
|
||||
object.LowShadowFill(fillLowShadow);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Bar Arrow Object ...
|
||||
*
|
||||
* @param bar: XOHCL instance Reference ...
|
||||
* @param priceType: ENUM_X_PRICE member ...
|
||||
* @param arrow: int, Arrow Code ...
|
||||
* @param clr: color, Arro Color ...
|
||||
* @param width: int, Arrow Width ...
|
||||
* @param anchor: ENUM_ARROW_ANCHOR, anchor of Arrow ...
|
||||
* @param name: string, name of Arrow ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool CreateBarArrow(
|
||||
XOHCL &bar,
|
||||
XCBarArrowObject *&object,
|
||||
ENUM_X_PRICE priceType,
|
||||
int arrow = 159,
|
||||
color clr = clrYellow,
|
||||
int width = 3,
|
||||
ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM,
|
||||
string name = NULL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
object = NULL;
|
||||
|
||||
//
|
||||
result = bar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string barTag = bar.GetTag(name);
|
||||
|
||||
//
|
||||
string prefix = Prefix();
|
||||
long chartID = ChartIdentification();
|
||||
int window = SubWindowIdentification();
|
||||
|
||||
//
|
||||
color mBullishColor = BarBullishColor();
|
||||
color mBearishColor = BarBearishColor();
|
||||
|
||||
//
|
||||
prefix =
|
||||
(IsValid(prefix)
|
||||
? prefix + "_"
|
||||
: prefix) +
|
||||
barTag;
|
||||
|
||||
//
|
||||
object = new XCBarArrowObject();
|
||||
result = object
|
||||
.CreateByBar(
|
||||
chartID,
|
||||
prefix,
|
||||
window,
|
||||
arrow,
|
||||
bar,
|
||||
priceType //
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
object.ArrowColor(clr);
|
||||
object.ArrowWidth(width);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Specific Box on Chart ...
|
||||
*
|
||||
* @param upper: Double ...
|
||||
* @param lower: Double ...
|
||||
* @param from: Datetime ...
|
||||
* @param to: Datetime ...
|
||||
* @param clr: Color ...
|
||||
* @param width: Integer ...
|
||||
* @param fill: Boolean ...
|
||||
* @param style: ENUM_LINE_STYLE member ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool CreateBox(
|
||||
XCBoxObject *&object,
|
||||
string name,
|
||||
double upper,
|
||||
double lower,
|
||||
datetime from,
|
||||
datetime to,
|
||||
datetime at,
|
||||
color clr = clrYellowGreen,
|
||||
int width = 1,
|
||||
bool fill = false,
|
||||
ENUM_LINE_STYLE style = STYLE_SOLID //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
object = NULL;
|
||||
|
||||
//
|
||||
to = NormalizeTime(to);
|
||||
|
||||
//
|
||||
string dateStr = ToFormatString(from) + "|" + ToFormatString(to);
|
||||
string dateMD5 = ToMD5(dateStr);
|
||||
if (!IsValid(name))
|
||||
{
|
||||
//
|
||||
name = "XBox_" +
|
||||
ToXString(upper) + "_" +
|
||||
ToXString(lower) + "_" +
|
||||
dateMD5;
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
upper > 0 &&
|
||||
lower > 0 &&
|
||||
to > from &&
|
||||
IsValid(to) &&
|
||||
IsValid(name) &&
|
||||
IsValid(from) &&
|
||||
upper > lower;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string prefix = Prefix();
|
||||
long chartID = ChartIdentification();
|
||||
int window = SubWindowIdentification();
|
||||
|
||||
//
|
||||
object = new XCBoxObject();
|
||||
result = object.Create(
|
||||
chartID,
|
||||
window,
|
||||
name,
|
||||
upper,
|
||||
lower,
|
||||
from,
|
||||
to,
|
||||
at,
|
||||
prefix //
|
||||
);
|
||||
|
||||
//
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
object.BoxColor(clr);
|
||||
object.BoxFill(fill);
|
||||
object.BoxWidth(width);
|
||||
object.BoxStyle(style);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create Specific Box on Chart ...
|
||||
*
|
||||
* @param box: XBoxZone instance Reference ...
|
||||
* @param clr: Color ...
|
||||
* @param width: Integer ...
|
||||
* @param fill: Boolean ...
|
||||
* @param style: ENUM_LINE_STYLE member ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool CreateBox(
|
||||
XBoxZone &box,
|
||||
XCBoxObject *&object,
|
||||
color clr = clrYellowGreen,
|
||||
int width = 1,
|
||||
bool fill = false,
|
||||
ENUM_LINE_STYLE style = STYLE_SOLID //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
object = NULL;
|
||||
|
||||
//
|
||||
result = box.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string name = box.GetTag();
|
||||
|
||||
//
|
||||
result = CreateBox(
|
||||
object,
|
||||
name,
|
||||
box.upper,
|
||||
box.lower,
|
||||
box.from,
|
||||
box.to,
|
||||
box.at,
|
||||
clr,
|
||||
width,
|
||||
fill,
|
||||
style //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Testing Draws ...
|
||||
|
||||
//
|
||||
XFIMAMarketStructure pivots[];
|
||||
|
||||
//
|
||||
XPivot pvPivots[];
|
||||
XPivot hkPivots[];
|
||||
XPivot maPivots[];
|
||||
XPivot zgPivots[];
|
||||
XPivot sarPivots[];
|
||||
|
||||
//
|
||||
poiDetector.CollectZGPivots(zgPivots);
|
||||
poiDetector.CollectMAPivots(maPivots);
|
||||
poiDetector.CollectHKPivots(hkPivots);
|
||||
poiDetector.CollectPVPivots(pvPivots);
|
||||
poiDetector.CollectSARPivots(sarPivots);
|
||||
|
||||
//
|
||||
// Merging All Pivots ...
|
||||
Copy(pvPivots, pivots, false);
|
||||
Copy(zgPivots, pivots, false);
|
||||
Copy(maPivots, pivots, false);
|
||||
Copy(hkPivots, pivots, false);
|
||||
Copy(sarPivots, pivots, false);
|
||||
|
||||
//
|
||||
if (HasChild(pivots))
|
||||
{
|
||||
poiDrawer.DrawPivots(pivots, iDrawConfig);
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
XClean(pivots);
|
||||
XClean(pvPivots);
|
||||
XClean(hkPivots);
|
||||
XClean(maPivots);
|
||||
XClean(zgPivots);
|
||||
XClean(sarPivots);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,699 +0,0 @@
|
||||
|
||||
/**
|
||||
* Check Market Conditions for Pattern Detection ...
|
||||
*/
|
||||
void DetectPatterns()
|
||||
{
|
||||
//
|
||||
if (!eaIsNewBar)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize 1 Indexed Bar ...
|
||||
XOHCL cBar;
|
||||
bool has = cBar.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
1 //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Do Analysis ...
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
// Define Detection Flags ...
|
||||
|
||||
//
|
||||
bool detectPinned = false;
|
||||
bool detectMomentum = false;
|
||||
bool detectEngulfed = false;
|
||||
bool detectTrueGaped = false;
|
||||
|
||||
//
|
||||
bool detectStarPattern = false;
|
||||
bool detectFlagPattern = false;
|
||||
bool detectRisingPattern = false;
|
||||
bool detectPiercingPattern = false;
|
||||
bool detectSignalKeyBarPattern = false;
|
||||
|
||||
//
|
||||
bool detectSwingTrend = false;
|
||||
bool detectSwingTrendBreakes = false;
|
||||
|
||||
//
|
||||
bool detectSupports = false;
|
||||
bool detectResistance = false;
|
||||
|
||||
//
|
||||
// XFIMA Patetrns ...
|
||||
bool detectFIMAPatterns = true;
|
||||
//
|
||||
bool detectFIMAPVPatterns = false;
|
||||
bool detectFIMAMAPatterns = false;
|
||||
bool detectFIMASARPatterns = false;
|
||||
bool detectFIMAZigZagPatterns = false;
|
||||
//
|
||||
bool analyseFIMAPVPivots = true;
|
||||
bool analyseFIMAMAPivots = true;
|
||||
bool analyseFIMASARPivots = true;
|
||||
bool analyseFIMAZigZagPivots = true;
|
||||
|
||||
//
|
||||
// Required Pivots ...
|
||||
int numberOfRequiredPivots = 15;
|
||||
|
||||
//
|
||||
// Checking Momentum Bar ...
|
||||
if (detectMomentum)
|
||||
{
|
||||
//
|
||||
bool isMomentum = fima2Signaller.poiDetector.IsMomentumBar(
|
||||
cBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishMomentum = isMomentum &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishMomentum = isMomentum &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isMomentum)
|
||||
{
|
||||
Print(ToXString(iDir), " Momentum Bar: ", cBar.time);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Engulfed Bar ...
|
||||
if (detectEngulfed)
|
||||
{
|
||||
//
|
||||
bool isEngulfed = fima2Signaller.poiDetector.IsEngulfedBar(
|
||||
cBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishEngulfed = isEngulfed &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishEngulfed = isEngulfed &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isEngulfed)
|
||||
{
|
||||
Print(ToXString(iDir), " Engulfed Bar: ", cBar.time);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking TruGaped Bar ...
|
||||
if (detectTrueGaped)
|
||||
{
|
||||
//
|
||||
bool isTrueGaped = fima2Signaller.poiDetector.IsTrueGapedBar(
|
||||
cBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishTrueGaped = isTrueGaped &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishTrueGaped = isTrueGaped &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isTrueGaped)
|
||||
{
|
||||
Print(ToXString(iDir), " TrueGapped Bar: ", cBar.time);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Pinned Bar ...
|
||||
if (detectPinned)
|
||||
{
|
||||
bool isPinned = fima2Signaller.poiDetector.IsPinnedBar(
|
||||
cBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishPinned = isPinned &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishPinned = isPinned &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isPinned)
|
||||
{
|
||||
Print(ToXString(iDir), " Pinned Bar: ", cBar.time);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Star Pattern ...
|
||||
if (detectStarPattern)
|
||||
{
|
||||
bool isStarPattern = fima2Signaller.poiDetector.IsStartPattern(
|
||||
cBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishStarPattern = isStarPattern &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishStarPattern = isStarPattern &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isStarPattern)
|
||||
{
|
||||
Print(ToXString(iDir), " Star Pattern: ", cBar.time);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Piercing Pattern ...
|
||||
if (detectPiercingPattern)
|
||||
{
|
||||
//
|
||||
bool isPiercingPattern = fima2Signaller.poiDetector.IsPiercingPattern(
|
||||
cBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishPiercingPattern = isPiercingPattern &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishPiercingPattern = isPiercingPattern &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isPiercingPattern)
|
||||
{
|
||||
Print(ToXString(iDir), " Piercing Pattern: ", cBar.time);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Rising Pattern ...
|
||||
if (detectRisingPattern)
|
||||
{
|
||||
//
|
||||
bool isRisingPattern = fima2Signaller.poiDetector.IsRisingPattern(
|
||||
cBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishRisingPattern = isRisingPattern &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishRisingPattern = isRisingPattern &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isRisingPattern)
|
||||
{
|
||||
Print(ToXString(iDir), " Rising Pattern: ", cBar.time);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Flag Pattern ...
|
||||
if (detectFlagPattern)
|
||||
{
|
||||
//
|
||||
XOHCL swingBar;
|
||||
bool isFlagPattern = fima2Signaller.poiDetector.IsFlagPattern(
|
||||
cBar,
|
||||
iDir,
|
||||
swingBar //
|
||||
);
|
||||
bool isBullishFlagPattern = isFlagPattern &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishFlagPattern = isFlagPattern &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isFlagPattern)
|
||||
{
|
||||
Print(ToXString(iDir), " Flag Pattern: ", cBar.time, ", Swing: ", swingBar.time);
|
||||
}
|
||||
swingBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Detect SignalKey Bar Pattern ...
|
||||
if (detectSignalKeyBarPattern)
|
||||
{
|
||||
//
|
||||
bool isSignalKeyBar = fima2Signaller.poiDetector.IsSignalKeyBarPattern(
|
||||
cBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishSignalKeyBar = isSignalKeyBar &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishSignalKeyBar = isSignalKeyBar &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isSignalKeyBar)
|
||||
{
|
||||
Print(ToXString(iDir), " SignalKey Bar Pattern: ", cBar.time);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Swing Trend ...
|
||||
if (detectSwingTrend)
|
||||
{
|
||||
//
|
||||
XOHCL swings[];
|
||||
bool hasSwingTrend = fima2Signaller.poiDetector.HasSwingTrend(
|
||||
cBar,
|
||||
iDir,
|
||||
swings //
|
||||
);
|
||||
bool hasBullishSwingTrend = hasSwingTrend &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool hasBearishSwingTrend = hasSwingTrend &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (hasSwingTrend)
|
||||
{
|
||||
//
|
||||
Print(ToXString(iDir), " Swing Trend: ", cBar.time);
|
||||
|
||||
//
|
||||
CChartObjectTrend *iObj;
|
||||
has = fima2Signaller.poiDrawer.DrawSwingTrend(
|
||||
swings,
|
||||
iDir,
|
||||
iObj,
|
||||
true // Ray Right ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
eaDraws.Add(iObj);
|
||||
}
|
||||
}
|
||||
SpecifiedClean(swings);
|
||||
}
|
||||
|
||||
//
|
||||
// Swing Trend Breakes ...
|
||||
if (detectSwingTrendBreakes)
|
||||
{
|
||||
//
|
||||
XOHCL swings[];
|
||||
bool hasSwingTrend = fima2Signaller.poiDetector.HasSwingTrend(
|
||||
cBar,
|
||||
iDir,
|
||||
swings //
|
||||
);
|
||||
bool hasBullishSwingTrend = hasSwingTrend &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool hasBearishSwingTrend = hasSwingTrend &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (hasSwingTrend)
|
||||
{
|
||||
//
|
||||
if (!HasDirection(trendDir))
|
||||
{
|
||||
trendDir = iDir;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Breaked Detection ...
|
||||
if (trendDir != iDir)
|
||||
{
|
||||
//
|
||||
Print("Trend Dir Breaked to: ", ToXString(iDir));
|
||||
trendDir = iDir;
|
||||
}
|
||||
|
||||
//
|
||||
SpecifiedClean(swings);
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Supports ...
|
||||
if (detectSupports)
|
||||
{
|
||||
//
|
||||
XOHCL support;
|
||||
bool hasSupport = fima2Signaller.poiDetector.HasSupport(
|
||||
cBar,
|
||||
support //
|
||||
);
|
||||
if (hasSupport)
|
||||
{
|
||||
//
|
||||
XBoxZone supportBox;
|
||||
has = ToSupportBox(support, supportBox);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Draw Box ...
|
||||
XCBoxObject *iObj;
|
||||
has = fima2Signaller.poiDrawer.DrawBox(
|
||||
supportBox,
|
||||
iObj //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
eaDraws.Add(iObj);
|
||||
}
|
||||
|
||||
//
|
||||
ZeroMemory(iObj);
|
||||
}
|
||||
|
||||
//
|
||||
supportBox.Clean();
|
||||
}
|
||||
support.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Resistance ...
|
||||
if (detectResistance)
|
||||
{
|
||||
//
|
||||
XOHCL resistance;
|
||||
bool hasResistance = fima2Signaller.poiDetector.HasResistance(
|
||||
cBar,
|
||||
resistance //
|
||||
);
|
||||
if (hasResistance)
|
||||
{
|
||||
//
|
||||
XBoxZone resistanceBox;
|
||||
has = ToResistanceBox(resistance, resistanceBox);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Draw Box ...
|
||||
XCBoxObject *iObj;
|
||||
has = fima2Signaller.poiDrawer.DrawBox(
|
||||
resistanceBox,
|
||||
iObj //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
eaDraws.Add(iObj);
|
||||
}
|
||||
|
||||
//
|
||||
ZeroMemory(iObj);
|
||||
}
|
||||
|
||||
//
|
||||
resistanceBox.Clean();
|
||||
}
|
||||
resistance.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Detecting FIMA Patterns ...
|
||||
if (detectFIMAPatterns)
|
||||
{
|
||||
//
|
||||
// Check For PV Pivots ...
|
||||
if (detectFIMAPVPatterns)
|
||||
{
|
||||
//
|
||||
XPivot pivots[];
|
||||
int pivotsCount = fima2Signaller.poiDetector.ExtractPVPivots(
|
||||
pivots, // Result ...
|
||||
cBar.Index(), // Bar Index ...
|
||||
numberOfRequiredPivots, // Required Number of Pivots ...
|
||||
1500, // Max Allowed Loopback ...
|
||||
10 // Validation Length ...
|
||||
);
|
||||
has = IsValidSize(pivotsCount);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
CArrayObj *drawnPivots = new CArrayObj();
|
||||
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
|
||||
pivots,
|
||||
drawnPivots //
|
||||
);
|
||||
has = IsValidSize(drawnPivotsCount);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddObjects(
|
||||
drawnPivots,
|
||||
eaDraws //
|
||||
);
|
||||
|
||||
//
|
||||
// Print("Pivots Extracted ...");
|
||||
}
|
||||
|
||||
//
|
||||
ZeroMemory(drawnPivots);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check for MA Patterns ...
|
||||
if (detectFIMAMAPatterns)
|
||||
{
|
||||
//
|
||||
XPivot pivots[];
|
||||
int pivotsCount = fima2Signaller.poiDetector.ExtractMAPivots(
|
||||
pivots, // Result ...
|
||||
cBar.Index(), // Bar Index ...
|
||||
numberOfRequiredPivots, // Required Number of Pivots ...
|
||||
1500, // Max Allowed Loopback ...
|
||||
0 // Validation Length ...
|
||||
);
|
||||
has = IsValidSize(pivotsCount);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
CArrayObj *drawnPivots = new CArrayObj();
|
||||
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
|
||||
pivots,
|
||||
drawnPivots //
|
||||
);
|
||||
has = IsValidSize(drawnPivotsCount);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddObjects(
|
||||
drawnPivots,
|
||||
eaDraws //
|
||||
);
|
||||
|
||||
//
|
||||
// Print("Pivots Extracted ...");
|
||||
}
|
||||
|
||||
//
|
||||
ZeroMemory(drawnPivots);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check for SAR Pivots ...
|
||||
if (detectFIMASARPatterns)
|
||||
{
|
||||
//
|
||||
XPivot pivots[];
|
||||
int pivotsCount = fima2Signaller.poiDetector.ExtractSARPivots(
|
||||
pivots, // Result ...
|
||||
cBar.Index(), // Bar Index ...
|
||||
numberOfRequiredPivots, // Required Number of Pivots ...
|
||||
1500 // Max Allowed Loopback ...
|
||||
);
|
||||
has = IsValidSize(pivotsCount);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
CArrayObj *drawnPivots = new CArrayObj();
|
||||
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
|
||||
pivots,
|
||||
drawnPivots //
|
||||
);
|
||||
has = IsValidSize(drawnPivotsCount);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddObjects(
|
||||
drawnPivots,
|
||||
eaDraws //
|
||||
);
|
||||
|
||||
//
|
||||
// Print("Pivots Extracted ...");
|
||||
}
|
||||
|
||||
//
|
||||
ZeroMemory(drawnPivots);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check for ZigZag Pivots ...
|
||||
if (detectFIMAZigZagPatterns)
|
||||
{
|
||||
//
|
||||
XPivot pivots[];
|
||||
int pivotsCount = fima2Signaller.poiDetector.ExtractZigZagPivots(
|
||||
pivots,
|
||||
cBar.Index(),
|
||||
numberOfRequiredPivots,
|
||||
1500 //
|
||||
);
|
||||
has = IsValidSize(pivotsCount);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
CArrayObj *drawnPivots = new CArrayObj();
|
||||
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
|
||||
pivots,
|
||||
drawnPivots //
|
||||
);
|
||||
has = IsValidSize(drawnPivotsCount);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddObjects(
|
||||
drawnPivots,
|
||||
eaDraws //
|
||||
);
|
||||
|
||||
//
|
||||
// Print("Pivots Extracted ...");
|
||||
}
|
||||
|
||||
//
|
||||
ZeroMemory(drawnPivots);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Analysers ...
|
||||
|
||||
//
|
||||
// Analyse Based on PV ...
|
||||
if (analyseFIMAPVPivots)
|
||||
{
|
||||
//
|
||||
XPivotAnalysis analysis;
|
||||
has = fima2Signaller.poiDetector.AnalysePVPivots(
|
||||
analysis, // Result ...
|
||||
cBar.Index(), // Bar Index ...
|
||||
numberOfRequiredPivots, // Required Number of Pivots ...
|
||||
1500, // Max Allowed Loopback ...
|
||||
10 // Validation Length ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Draw Analysis ...
|
||||
DestroyObject(pvAnalysisObject);
|
||||
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
|
||||
analysis,
|
||||
pvAnalysisObject,
|
||||
true // Draw Pivots ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// eaDraws.Add(iObj);
|
||||
|
||||
//
|
||||
// Print("FIMA PV Pivots Analysed ...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Analyse Based on MA ...
|
||||
if (analyseFIMAMAPivots)
|
||||
{
|
||||
//
|
||||
XPivotAnalysis analysis;
|
||||
has = fima2Signaller.poiDetector.AnalyseMAPivots(
|
||||
analysis, // Result ...
|
||||
cBar.Index(), // Bar Index ...
|
||||
numberOfRequiredPivots, // Required Number of Pivots ...
|
||||
1500, // Max Allowed Loopback ...
|
||||
0 // Validation Length ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Draw Analysis ...
|
||||
DestroyObject(maAnalysisObject);
|
||||
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
|
||||
analysis,
|
||||
maAnalysisObject,
|
||||
true // Draw Pivots ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// eaDraws.Add(iObj);
|
||||
|
||||
//
|
||||
// Print("FIMA MA Pivots Analysed ...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Analyse Based on SAR ...
|
||||
if (analyseFIMASARPivots)
|
||||
{
|
||||
//
|
||||
XPivotAnalysis analysis;
|
||||
has = fima2Signaller.poiDetector.AnalyseSARPivots(
|
||||
analysis, // Result ...
|
||||
cBar.Index(), // Bar Index ...
|
||||
numberOfRequiredPivots, // Required Number of Pivots ...
|
||||
1500 // Max Allowed Loopback ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Draw Analysis ...
|
||||
DestroyObject(sarAnalysisObject);
|
||||
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
|
||||
analysis,
|
||||
sarAnalysisObject,
|
||||
true // Draw Pivots ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// eaDraws.Add(iObj);
|
||||
|
||||
//
|
||||
// Print("FIMA Sar Pivots Analysed ...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Analyse Based on ZigZag ...
|
||||
if (analyseFIMAZigZagPivots)
|
||||
{
|
||||
//
|
||||
XPivotAnalysis analysis;
|
||||
has = fima2Signaller.poiDetector.AnalyseZigZagPivots(
|
||||
analysis, // Result ...
|
||||
cBar.Index(), // Bar Index ...
|
||||
numberOfRequiredPivots, // Required Number of Pivots ...
|
||||
1500 // Max Allowed Loopback ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Draw Analysis ...
|
||||
DestroyObject(zigzagAnalysisObject);
|
||||
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
|
||||
analysis,
|
||||
zigzagAnalysisObject,
|
||||
true // Draw Pivots ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// eaDraws.Add(iObj);
|
||||
|
||||
//
|
||||
// Print("FIMA ZigZag Pivots Analysed ...");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
cBar.Clean();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,567 +0,0 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Library
|
||||
// -------------------------------------------------
|
||||
// Name: XCXFIMAEALib ...
|
||||
// Description: XFIMAEA Library ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XFIMAEA Library"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
|
||||
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
|
||||
#include "../Classes/x-saherelm.xfima.parser.class.mq5"
|
||||
#include "../../Libraries/x-saherelm.x-pivot.analysis.lib.mq5"
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
|
||||
/**
|
||||
* XFIMA Base Market Structure ...
|
||||
* AnalyseMarket result ...
|
||||
**/
|
||||
struct XFIMAMarketStructure
|
||||
{
|
||||
//
|
||||
XOHCL bar; // Spacified Start Bar for Analysing ...
|
||||
XPatternAnalysis barAnalysis; // Structure Bar Pattern Analysis ...
|
||||
|
||||
//
|
||||
XPivotAnalysis pvAnalysis; // PV Pivot Analysis Result ...
|
||||
XPivotAnalysis zgAnalysis; // ZG Pivot Analysis Result ...
|
||||
|
||||
//
|
||||
XPatternAnalysis barsAnalysis[]; // Anaysed Bars ...
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XFIMAMarketStructure()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* Cleanup ...
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
bar.Clean();
|
||||
barAnalysis.Clean();
|
||||
|
||||
//
|
||||
pvAnalysis.Clean();
|
||||
zgAnalysis.Clean();
|
||||
XClean(barsAnalysis);
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = bar.IsValid() &&
|
||||
barAnalysis.IsValid();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Collectors ...
|
||||
|
||||
/**
|
||||
* Collect Required Zones from Structure ...
|
||||
*
|
||||
* @param dest: XBoxZone, reference collection to holds result ...
|
||||
* @param forDir: ENUM_X_DIRECTION, Specified Collectiong ones Direction ...
|
||||
* @param containsOB: bool, Contains OB Zones ...
|
||||
* @param containsFVG: bool, Contains FVG Zones ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int CollectZones(
|
||||
XBoxZone &dest[],
|
||||
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
|
||||
bool containsOB = false,
|
||||
bool containsFVG = false //
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
XClean(dest);
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
bool has = IsValid();
|
||||
if (!has)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool canCollectBullish =
|
||||
IsXBullish(forDir) ||
|
||||
!HasDirection(forDir);
|
||||
|
||||
//
|
||||
bool canCollectBearish =
|
||||
IsXBearish(forDir) ||
|
||||
!HasDirection(forDir);
|
||||
|
||||
//
|
||||
int count = 0;
|
||||
XBoxZone tmpBox;
|
||||
|
||||
//
|
||||
// Check Analysis ...
|
||||
|
||||
//
|
||||
// XPV ...
|
||||
has = pvAnalysis.IsValid();
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Support ...
|
||||
tmpBox.Clean();
|
||||
has = pvAnalysis.HasSupportBox(tmpBox);
|
||||
if (has && canCollectBullish)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
tmpBox,
|
||||
dest //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Resistance ...
|
||||
tmpBox.Clean();
|
||||
has = pvAnalysis.HasResistanceBox(tmpBox);
|
||||
if (has && canCollectBearish)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
tmpBox,
|
||||
dest //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// XZG ...
|
||||
has = zgAnalysis.IsValid();
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Support ...
|
||||
tmpBox.Clean();
|
||||
has = zgAnalysis.HasSupportBox(tmpBox);
|
||||
if (has && canCollectBullish)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
tmpBox,
|
||||
dest //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Resistance ...
|
||||
tmpBox.Clean();
|
||||
has = zgAnalysis.HasResistanceBox(tmpBox);
|
||||
if (has && canCollectBearish)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
tmpBox,
|
||||
dest //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Bar Patterns ...
|
||||
has = HasChild(barsAnalysis);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
count = ArraySize(barsAnalysis);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
// Support ...
|
||||
has = barsAnalysis[i].IsSupport();
|
||||
if (has && canCollectBullish)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
barsAnalysis[i].support,
|
||||
dest //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Resistance ...
|
||||
has = barsAnalysis[i].IsResistance();
|
||||
if (has && canCollectBearish)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
barsAnalysis[i].resistance,
|
||||
dest //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// OB ...
|
||||
if (containsOB)
|
||||
{
|
||||
//
|
||||
has = barsAnalysis[i].IsOB();
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
has = (canCollectBullish && barsAnalysis[i].ob.IsBullish()) ||
|
||||
(canCollectBearish && barsAnalysis[i].ob.IsBearish());
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
barsAnalysis[i].ob,
|
||||
dest //
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FVG ...
|
||||
if (containsFVG)
|
||||
{
|
||||
has = barsAnalysis[i].IsFVG();
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
has = (canCollectBullish && barsAnalysis[i].fvg.IsBullish()) ||
|
||||
(canCollectBearish && barsAnalysis[i].fvg.IsBearish());
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
barsAnalysis[i].fvg,
|
||||
dest //
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = ArraySize(dest);
|
||||
has = IsValidSize(result);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Update To Time ...
|
||||
// and also we Can Validate Zones Here ...
|
||||
datetime cTime = TimeCurrent();
|
||||
for (int i = 0; i < result; i++)
|
||||
{
|
||||
dest[i].to = cTime;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
tmpBox.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
struct XFIMAMarketStructureConfig
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
// Detector Flags ...
|
||||
|
||||
//
|
||||
bool analysePVPivots; // Analyse PV Pivots ...
|
||||
bool analyseZGPivots; // Analyse ZG Pivots ...
|
||||
|
||||
//
|
||||
bool analyseBarPatterns; // Analyse Bar Patterns ...
|
||||
|
||||
//
|
||||
// Detector Configs ...
|
||||
|
||||
//
|
||||
int loopback; // Max Allowed Looping Back Length ...
|
||||
int requiredPivots; // Required Extracted Pivots for Analysis ...
|
||||
|
||||
//
|
||||
int pvPivotsValidationLength; // PV Pivots Validation Length ...
|
||||
double maCrossValidationDiffMultiplier; // a Point Distance to Validate MA Crosses ...
|
||||
|
||||
//
|
||||
XPatternAnalysisConfig barsAnalysisConfig; // Bars Analyser Config ...
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XFIMAMarketStructureConfig()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* This function fulfills the will of the developer
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
// Detector Flags ...
|
||||
analysePVPivots = false;
|
||||
analyseZGPivots = false;
|
||||
analyseBarPatterns = false;
|
||||
|
||||
//
|
||||
// Configure Detectors ...
|
||||
loopback = 0;
|
||||
requiredPivots = 0;
|
||||
pvPivotsValidationLength = 0;
|
||||
maCrossValidationDiffMultiplier = 0;
|
||||
|
||||
//
|
||||
barsAnalysisConfig.Clean();
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Configurations ...
|
||||
*/
|
||||
void Default()
|
||||
{
|
||||
//
|
||||
// Detector Flags ...
|
||||
analysePVPivots = true;
|
||||
analyseZGPivots = true;
|
||||
analyseBarPatterns = true;
|
||||
|
||||
//
|
||||
// Configure Detectors ...
|
||||
loopback = 200;
|
||||
requiredPivots = 10;
|
||||
pvPivotsValidationLength = 5;
|
||||
maCrossValidationDiffMultiplier = 4;
|
||||
|
||||
//
|
||||
barsAnalysisConfig.Default();
|
||||
barsAnalysisConfig.FullPattern();
|
||||
}
|
||||
|
||||
/**
|
||||
* No Draw Abilioty ...
|
||||
*/
|
||||
void Off()
|
||||
{
|
||||
//
|
||||
// Detector Flags ...
|
||||
analysePVPivots = false;
|
||||
analyseZGPivots = false;
|
||||
analyseBarPatterns = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full Draw Abilioty ...
|
||||
*/
|
||||
void Full()
|
||||
{
|
||||
//
|
||||
// Detector Flags ...
|
||||
analysePVPivots = true;
|
||||
analyseZGPivots = true;
|
||||
analyseBarPatterns = true;
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
/**
|
||||
* Configure Market Structure Drawer ...
|
||||
**/
|
||||
struct XFIMAMarketStructureDrawerConfig
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
bool drawPVAnalysis;
|
||||
bool drawZGAnalysis;
|
||||
bool drawBarsAnalysis;
|
||||
|
||||
//
|
||||
XPOIDrawConfig drawConfig;
|
||||
XPivotAnalysisDrawConfig pivotAnalysisDrawConfig;
|
||||
XPatternAnalysisDrawConfig barAnalysisDrawConfig;
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XFIMAMarketStructureDrawerConfig()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* This function fulfills the will of the developer
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
// Drawing Flags ...
|
||||
|
||||
//
|
||||
drawPVAnalysis = false;
|
||||
drawZGAnalysis = false;
|
||||
drawBarsAnalysis = false;
|
||||
|
||||
//
|
||||
// Drawing Configs ...
|
||||
drawConfig.Clean();
|
||||
barAnalysisDrawConfig.Clean();
|
||||
pivotAnalysisDrawConfig.Clean();
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Configurations ...
|
||||
*/
|
||||
void Default()
|
||||
{
|
||||
//
|
||||
// Drawing Flags ...
|
||||
|
||||
//
|
||||
drawPVAnalysis = true;
|
||||
drawZGAnalysis = true;
|
||||
drawBarsAnalysis = true;
|
||||
|
||||
//
|
||||
// Drawing Configs ...
|
||||
drawConfig.Default();
|
||||
pivotAnalysisDrawConfig.Default();
|
||||
|
||||
//
|
||||
barAnalysisDrawConfig.Default();
|
||||
barAnalysisDrawConfig.Full();
|
||||
XClean(barAnalysisDrawConfig.allowedDrawZones);
|
||||
Add(
|
||||
X_BAR_PATTERN_SUPPORT,
|
||||
barAnalysisDrawConfig.allowedDrawZones);
|
||||
Add(
|
||||
X_BAR_PATTERN_RESISTANCE,
|
||||
barAnalysisDrawConfig.allowedDrawZones);
|
||||
}
|
||||
|
||||
/**
|
||||
* No Draw Abilioty ...
|
||||
*/
|
||||
void Off()
|
||||
{
|
||||
//
|
||||
// Drawing Flags ...
|
||||
|
||||
//
|
||||
drawPVAnalysis = false;
|
||||
drawZGAnalysis = false;
|
||||
drawBarsAnalysis = false;
|
||||
|
||||
//
|
||||
// Drawing Configs ...
|
||||
barAnalysisDrawConfig.Off();
|
||||
pivotAnalysisDrawConfig.Off();
|
||||
}
|
||||
|
||||
/**
|
||||
* Full Draw Abilioty ...
|
||||
*/
|
||||
void Full()
|
||||
{
|
||||
//
|
||||
// Drawing Flags ...
|
||||
|
||||
//
|
||||
drawPVAnalysis = false;
|
||||
drawZGAnalysis = false;
|
||||
drawBarsAnalysis = false;
|
||||
|
||||
//
|
||||
// Drawing Configs ...
|
||||
barAnalysisDrawConfig.Full();
|
||||
pivotAnalysisDrawConfig.Full();
|
||||
}
|
||||
|
||||
void ApplyDrawConfig()
|
||||
{
|
||||
//
|
||||
barAnalysisDrawConfig.drawConfig = drawConfig;
|
||||
barAnalysisDrawConfig.ConfigureQuarterDraws();
|
||||
pivotAnalysisDrawConfig.drawConfig = drawConfig;
|
||||
}
|
||||
|
||||
void ApplyDrawConfig(XPOIDrawConfig &_drawConfig)
|
||||
{
|
||||
//
|
||||
drawConfig = _drawConfig;
|
||||
ApplyDrawConfig();
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
//
|
||||
@@ -1,694 +0,0 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Library
|
||||
// -------------------------------------------------
|
||||
// Name: XCXFIMAEALib ...
|
||||
// Description: XFIMAEA Library ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XFIMAEA Library"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
|
||||
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
|
||||
#include "../../Libraries/x-saherelm.x-pivot.analysis.lib.mq5"
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
|
||||
/**
|
||||
* Configure Market Structure Detection ...
|
||||
**/
|
||||
struct XFIMAPatternDetectorConfig
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
bool detectSwingTrend;
|
||||
|
||||
//
|
||||
bool detectStarPattern;
|
||||
bool detectFlagPattern;
|
||||
bool detectRisingPattern;
|
||||
bool detectPiercingPattern;
|
||||
bool detectSignalKeyBarPattern;
|
||||
|
||||
//
|
||||
bool detectPinned;
|
||||
bool detectMomentum;
|
||||
bool detectEngulfed;
|
||||
bool detectTrueGaped;
|
||||
|
||||
//
|
||||
bool analyseFIMAPVPivots;
|
||||
bool analyseFIMAZigZagPivots;
|
||||
|
||||
//
|
||||
bool detectMACrosses;
|
||||
double validMACrossDiffMultiplier;
|
||||
|
||||
//
|
||||
bool detectHKSwitches;
|
||||
bool detectSARSwitches;
|
||||
|
||||
//
|
||||
// Configs ...
|
||||
|
||||
//
|
||||
// Trending ...
|
||||
int trendingNumberOfSwings;
|
||||
int trendingSwingShoulders;
|
||||
|
||||
//
|
||||
// Support and Resistance ...
|
||||
int zonesRequiredNumber;
|
||||
int zonesValidationLength;
|
||||
double zonesMinAlloweStrength;
|
||||
int zonesBreakValidationLength;
|
||||
double zonesBarShadowMultiplier;
|
||||
int zonesMaxAllowedLoopbackLength;
|
||||
|
||||
//
|
||||
// TrueGap ...
|
||||
double truwGapApprovedPointMultiplier;
|
||||
|
||||
//
|
||||
// Flag Pattern ...
|
||||
int flagPatternMinimumPullbackBars;
|
||||
|
||||
//
|
||||
// Momentum Bar ...
|
||||
int momentumBarRangeLength;
|
||||
double momentumBarApprovedMultiplier;
|
||||
|
||||
//
|
||||
// Pinned Bar ...
|
||||
double pinnedBaarShadowApprovedMultiplier;
|
||||
double pinnedBarMinimumPinBarRangeMultiplier;
|
||||
bool pinnedBarForceDirection;
|
||||
|
||||
//
|
||||
// SignalKey Bar ...
|
||||
double signalKeyBarShadowApprovedMultiplier;
|
||||
double signalKeyBarMinimumPinBarRangeMultiplier;
|
||||
bool signalKeyBarForceDirection;
|
||||
|
||||
//
|
||||
// Analyser ...
|
||||
int pvPivotsValidationLength;
|
||||
int numberOfRequiredPivotsForAnalysis;
|
||||
int maxAllowedLoopbackLengthForAnalysis;
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XFIMAPatternDetectorConfig()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* Cleanup Model ...
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
detectPinned = false;
|
||||
detectMomentum = false;
|
||||
detectEngulfed = false;
|
||||
detectTrueGaped = false;
|
||||
detectSwingTrend = false;
|
||||
detectStarPattern = false;
|
||||
detectFlagPattern = false;
|
||||
detectRisingPattern = false;
|
||||
analyseFIMAPVPivots = false;
|
||||
detectPiercingPattern = false;
|
||||
analyseFIMAZigZagPivots = false;
|
||||
detectSignalKeyBarPattern = false;
|
||||
|
||||
//
|
||||
detectMACrosses = false;
|
||||
validMACrossDiffMultiplier = 0;
|
||||
|
||||
//
|
||||
detectHKSwitches = false;
|
||||
detectSARSwitches = false;
|
||||
|
||||
//
|
||||
zonesRequiredNumber = 0;
|
||||
zonesValidationLength = 0;
|
||||
zonesMinAlloweStrength = 0;
|
||||
zonesBarShadowMultiplier = 0;
|
||||
zonesBreakValidationLength = 0;
|
||||
zonesMaxAllowedLoopbackLength = 0;
|
||||
|
||||
//
|
||||
trendingNumberOfSwings = 0;
|
||||
trendingSwingShoulders = 0;
|
||||
momentumBarRangeLength = 0;
|
||||
pvPivotsValidationLength = 0;
|
||||
pinnedBarForceDirection = false;
|
||||
momentumBarApprovedMultiplier = 0;
|
||||
signalKeyBarForceDirection = false;
|
||||
truwGapApprovedPointMultiplier = 0;
|
||||
flagPatternMinimumPullbackBars = 0;
|
||||
numberOfRequiredPivotsForAnalysis = 0;
|
||||
pinnedBaarShadowApprovedMultiplier = 0;
|
||||
maxAllowedLoopbackLengthForAnalysis = 0;
|
||||
signalKeyBarShadowApprovedMultiplier = 0;
|
||||
pinnedBarMinimumPinBarRangeMultiplier = 0;
|
||||
signalKeyBarMinimumPinBarRangeMultiplier = 0;
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Model ...
|
||||
*/
|
||||
void Default()
|
||||
{
|
||||
//
|
||||
// Patterns ...
|
||||
detectStarPattern = false;
|
||||
detectFlagPattern = false;
|
||||
detectRisingPattern = false;
|
||||
detectPiercingPattern = false;
|
||||
detectSignalKeyBarPattern = false;
|
||||
|
||||
//
|
||||
// Bars ...
|
||||
detectPinned = false;
|
||||
detectMomentum = false;
|
||||
detectEngulfed = false;
|
||||
detectTrueGaped = false;
|
||||
|
||||
//
|
||||
// Analysers ...
|
||||
analyseFIMAPVPivots = false;
|
||||
analyseFIMAZigZagPivots = false;
|
||||
|
||||
//
|
||||
detectMACrosses = true;
|
||||
validMACrossDiffMultiplier = 1;
|
||||
|
||||
//
|
||||
detectHKSwitches = true;
|
||||
detectSARSwitches = true;
|
||||
|
||||
//
|
||||
// Trending ...
|
||||
trendingNumberOfSwings = 3;
|
||||
trendingSwingShoulders = 11;
|
||||
|
||||
//
|
||||
// Support and Resistance ...
|
||||
zonesRequiredNumber = 25;
|
||||
zonesValidationLength = 21;
|
||||
zonesMinAlloweStrength = 2;
|
||||
zonesBarShadowMultiplier = 4;
|
||||
zonesBreakValidationLength = 3;
|
||||
zonesMaxAllowedLoopbackLength = 200;
|
||||
|
||||
//
|
||||
// TrueGap ...
|
||||
truwGapApprovedPointMultiplier = 1;
|
||||
|
||||
//
|
||||
// Flag Pattern ...
|
||||
flagPatternMinimumPullbackBars = 3;
|
||||
|
||||
//
|
||||
// Momentum Bar ...
|
||||
momentumBarRangeLength = 3;
|
||||
momentumBarApprovedMultiplier = 2;
|
||||
|
||||
//
|
||||
// Pinned Bar ...
|
||||
pinnedBaarShadowApprovedMultiplier = 3;
|
||||
pinnedBarMinimumPinBarRangeMultiplier = 4;
|
||||
pinnedBarForceDirection = false;
|
||||
|
||||
//
|
||||
// SignalKey Bar ...
|
||||
signalKeyBarShadowApprovedMultiplier = 3;
|
||||
signalKeyBarMinimumPinBarRangeMultiplier = 4;
|
||||
signalKeyBarForceDirection = false;
|
||||
|
||||
//
|
||||
// Length ...
|
||||
pvPivotsValidationLength = 10;
|
||||
numberOfRequiredPivotsForAnalysis = 50;
|
||||
maxAllowedLoopbackLengthForAnalysis = 1500;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full Detection Model ...
|
||||
*/
|
||||
void FullDetect()
|
||||
{
|
||||
//
|
||||
// Patterns ...
|
||||
detectStarPattern = true;
|
||||
detectFlagPattern = true;
|
||||
detectRisingPattern = true;
|
||||
detectPiercingPattern = true;
|
||||
detectSignalKeyBarPattern = true;
|
||||
|
||||
//
|
||||
// Bars ...
|
||||
detectPinned = true;
|
||||
detectMomentum = true;
|
||||
detectEngulfed = true;
|
||||
detectTrueGaped = true;
|
||||
|
||||
//
|
||||
// Analysers ...
|
||||
analyseFIMAPVPivots = true;
|
||||
analyseFIMAZigZagPivots = true;
|
||||
|
||||
//
|
||||
detectMACrosses = true;
|
||||
detectHKSwitches = true;
|
||||
detectSARSwitches = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Config, by turn off all detecting flags ...
|
||||
*/
|
||||
void OffDetectors()
|
||||
{
|
||||
//
|
||||
// Patterns ...
|
||||
detectStarPattern = false;
|
||||
detectFlagPattern = false;
|
||||
detectRisingPattern = false;
|
||||
detectPiercingPattern = false;
|
||||
detectSignalKeyBarPattern = false;
|
||||
|
||||
//
|
||||
// Bars ...
|
||||
detectPinned = false;
|
||||
detectMomentum = false;
|
||||
detectEngulfed = false;
|
||||
detectTrueGaped = false;
|
||||
|
||||
//
|
||||
// Analysers ...
|
||||
analyseFIMAPVPivots = false;
|
||||
analyseFIMAZigZagPivots = false;
|
||||
|
||||
//
|
||||
detectMACrosses = false;
|
||||
detectHKSwitches = false;
|
||||
detectSARSwitches = false;
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
/**
|
||||
* XFIMA Base Market Structure ...
|
||||
* AnalyseMarket result ...
|
||||
**/
|
||||
struct XFIMAMarketStructure
|
||||
{
|
||||
//
|
||||
XOHCL bar;
|
||||
|
||||
//
|
||||
XBoxZone obs[];
|
||||
XBoxZone fvgs[];
|
||||
XBoxZone supports[];
|
||||
XBoxZone resistances[];
|
||||
|
||||
//
|
||||
XPivot pinBars[];
|
||||
XPivot engulfBars[];
|
||||
XPivot trueGapBars[];
|
||||
XPivot momentumBars[];
|
||||
|
||||
//
|
||||
XBoxZone flagPatterns[];
|
||||
XBoxZone starPatterns[];
|
||||
XBoxZone risingPatterns[];
|
||||
XBoxZone piercingPatterns[];
|
||||
XBoxZone signalKeyBarPatterns[];
|
||||
|
||||
//
|
||||
// Analysis ...
|
||||
XPivotAnalysis pvAnalysis;
|
||||
XPivotAnalysis zigzagAnalysis;
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION pinnedDir;
|
||||
ENUM_X_DIRECTION momentumDir;
|
||||
ENUM_X_DIRECTION engulfedDir;
|
||||
ENUM_X_DIRECTION trueGapedDir;
|
||||
|
||||
//
|
||||
XOHCL flagSwing;
|
||||
ENUM_X_DIRECTION flagPatternDir;
|
||||
|
||||
//
|
||||
XOHCL trendSwings[];
|
||||
ENUM_X_DIRECTION trendDir;
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION starPatternDir;
|
||||
ENUM_X_DIRECTION risingPatternDir;
|
||||
ENUM_X_DIRECTION piercingPatternDir;
|
||||
ENUM_X_DIRECTION signalKeyBarPatternDir;
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION maCrossDir;
|
||||
XPivot maCrosses[];
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION hkSwitchDir;
|
||||
XPivot hkSwitches[];
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION sarSwitchDir;
|
||||
XPivot sarSwitches[];
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XFIMAMarketStructure()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* Cleanup Model ...
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
bar.Clean();
|
||||
flagSwing.Clean();
|
||||
|
||||
//
|
||||
pvAnalysis.Clean();
|
||||
zigzagAnalysis.Clean();
|
||||
|
||||
//
|
||||
trendDir = X_DIRECTION_NONE;
|
||||
pinnedDir = X_DIRECTION_NONE;
|
||||
momentumDir = X_DIRECTION_NONE;
|
||||
engulfedDir = X_DIRECTION_NONE;
|
||||
trueGapedDir = X_DIRECTION_NONE;
|
||||
flagPatternDir = X_DIRECTION_NONE;
|
||||
starPatternDir = X_DIRECTION_NONE;
|
||||
risingPatternDir = X_DIRECTION_NONE;
|
||||
piercingPatternDir = X_DIRECTION_NONE;
|
||||
signalKeyBarPatternDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
maCrossDir = X_DIRECTION_NONE;
|
||||
SpecifiedClean(maCrosses);
|
||||
|
||||
//
|
||||
hkSwitchDir = X_DIRECTION_NONE;
|
||||
SpecifiedClean(hkSwitches);
|
||||
|
||||
//
|
||||
sarSwitchDir = X_DIRECTION_NONE;
|
||||
SpecifiedClean(sarSwitches);
|
||||
|
||||
//
|
||||
SpecifiedClean(obs);
|
||||
SpecifiedClean(fvgs);
|
||||
SpecifiedClean(pinBars);
|
||||
SpecifiedClean(supports);
|
||||
SpecifiedClean(engulfBars);
|
||||
SpecifiedClean(resistances);
|
||||
SpecifiedClean(trueGapBars);
|
||||
SpecifiedClean(momentumBars);
|
||||
SpecifiedClean(flagPatterns);
|
||||
SpecifiedClean(starPatterns);
|
||||
SpecifiedClean(risingPatterns);
|
||||
SpecifiedClean(piercingPatterns);
|
||||
SpecifiedClean(signalKeyBarPatterns);
|
||||
|
||||
//
|
||||
SpecifiedClean(trendSwings);
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
//
|
||||
// Checker Functions ...
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
/**
|
||||
* Configure Market Structure Drawer ...
|
||||
**/
|
||||
struct XFIMAMarketStructureDrawerConfig
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
bool drawOB; // Current Order Block ...
|
||||
bool drawFVG; // Current Fair Value Gap ...
|
||||
|
||||
//
|
||||
bool drawSupport; // Detected Supports ...
|
||||
bool drawResistance; // Detected Resistances ...
|
||||
|
||||
//
|
||||
bool drawSwingTrend; // Swing Trend ...
|
||||
bool swingTrendRayLeft; // Ray Left Swing Trend ...
|
||||
bool swingTrendRayRight; // Ray Right Swing Trend ...
|
||||
|
||||
//
|
||||
// Draw Current Detected Patterns ...
|
||||
|
||||
//
|
||||
bool drawPinned;
|
||||
bool drawMomentum;
|
||||
bool drawEngulfed;
|
||||
bool drawTrueGaped;
|
||||
|
||||
//
|
||||
bool drawStarPattern;
|
||||
bool drawFlagPattern;
|
||||
bool drawRisingPattern;
|
||||
bool drawPiercingPattern;
|
||||
bool drawSignalKeyBarPattern;
|
||||
|
||||
//
|
||||
// Draw Recently Zones ...
|
||||
bool drawRecentPatterns;
|
||||
bool drawFakeBreakedZone;
|
||||
bool drawRecentlyTestedZones;
|
||||
bool drawRecentlyBreakedZones;
|
||||
|
||||
//
|
||||
// Draw Analysis Pivots ...
|
||||
|
||||
//
|
||||
// XPV ...
|
||||
bool drawFIMAPVPivotsAnalysis;
|
||||
bool drawFIMAPVPivotsAnalysisZones;
|
||||
bool drawFIMAPVPivotsAnalysisTrends;
|
||||
bool drawFIMAPVPivotsAnalysisPivots;
|
||||
|
||||
//
|
||||
// XSAR ...
|
||||
bool drawFIMASARPivotsAnalysis;
|
||||
bool drawFIMASARPivotsAnalysisZones;
|
||||
bool drawFIMASARPivotsAnalysisTrends;
|
||||
bool drawFIMASARPivotsAnalysisPivots;
|
||||
|
||||
//
|
||||
// XZIGZAG ...
|
||||
bool drawFIMAZigZagPivotsAnalysis;
|
||||
bool drawFIMAZigZagPivotsAnalysisZones;
|
||||
bool drawFIMAZigZagPivotsAnalysisTrends;
|
||||
bool drawFIMAZigZagPivotsAnalysisPivots;
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XFIMAMarketStructureDrawerConfig()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* Cleanup Model ...
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
drawOB = false;
|
||||
drawFVG = false;
|
||||
drawPinned = false;
|
||||
drawMomentum = false;
|
||||
drawSupport = false;
|
||||
drawEngulfed = false;
|
||||
drawTrueGaped = false;
|
||||
drawResistance = false;
|
||||
drawSwingTrend = false;
|
||||
drawStarPattern = false;
|
||||
drawFlagPattern = false;
|
||||
swingTrendRayLeft = false;
|
||||
drawRisingPattern = false;
|
||||
swingTrendRayRight = false;
|
||||
drawPiercingPattern = false;
|
||||
drawSignalKeyBarPattern = false;
|
||||
|
||||
//
|
||||
drawRecentPatterns = false;
|
||||
drawFakeBreakedZone = false;
|
||||
drawRecentlyTestedZones = false;
|
||||
drawRecentlyBreakedZones = false;
|
||||
|
||||
//
|
||||
drawFIMAPVPivotsAnalysis = false;
|
||||
drawFIMAPVPivotsAnalysisZones = false;
|
||||
drawFIMAPVPivotsAnalysisTrends = false;
|
||||
drawFIMAPVPivotsAnalysisPivots = false;
|
||||
|
||||
//
|
||||
drawFIMASARPivotsAnalysis = false;
|
||||
drawFIMASARPivotsAnalysisZones = false;
|
||||
drawFIMASARPivotsAnalysisTrends = false;
|
||||
drawFIMASARPivotsAnalysisPivots = false;
|
||||
|
||||
//
|
||||
drawFIMAZigZagPivotsAnalysis = false;
|
||||
drawFIMAZigZagPivotsAnalysisZones = false;
|
||||
drawFIMAZigZagPivotsAnalysisTrends = false;
|
||||
drawFIMAZigZagPivotsAnalysisPivots = false;
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Model ...
|
||||
*/
|
||||
void Default()
|
||||
{
|
||||
drawOB = true;
|
||||
drawFVG = true;
|
||||
drawPinned = true;
|
||||
drawMomentum = true;
|
||||
drawSupport = true;
|
||||
drawEngulfed = true;
|
||||
drawTrueGaped = true;
|
||||
drawResistance = true;
|
||||
drawSwingTrend = true;
|
||||
drawStarPattern = true;
|
||||
drawFlagPattern = true;
|
||||
drawRisingPattern = true;
|
||||
drawPiercingPattern = true;
|
||||
swingTrendRayLeft = false;
|
||||
swingTrendRayRight = true;
|
||||
drawSignalKeyBarPattern = true;
|
||||
|
||||
//
|
||||
drawRecentPatterns = true;
|
||||
drawFakeBreakedZone = true;
|
||||
drawRecentlyTestedZones = true;
|
||||
drawRecentlyBreakedZones = true;
|
||||
|
||||
//
|
||||
drawFIMAPVPivotsAnalysis = true;
|
||||
drawFIMAPVPivotsAnalysisZones = true;
|
||||
drawFIMAPVPivotsAnalysisTrends = true;
|
||||
drawFIMAPVPivotsAnalysisPivots = true;
|
||||
|
||||
//
|
||||
drawFIMASARPivotsAnalysis = true;
|
||||
drawFIMASARPivotsAnalysisZones = true;
|
||||
drawFIMASARPivotsAnalysisTrends = true;
|
||||
drawFIMASARPivotsAnalysisPivots = true;
|
||||
|
||||
//
|
||||
drawFIMAZigZagPivotsAnalysis = true;
|
||||
drawFIMAZigZagPivotsAnalysisZones = true;
|
||||
drawFIMAZigZagPivotsAnalysisTrends = true;
|
||||
drawFIMAZigZagPivotsAnalysisPivots = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure for Full Drawing ...
|
||||
*/
|
||||
void FullDraw()
|
||||
{
|
||||
//
|
||||
Default();
|
||||
|
||||
//
|
||||
drawOB = true;
|
||||
drawFVG = true;
|
||||
drawPinned = true;
|
||||
drawMomentum = true;
|
||||
drawSupport = true;
|
||||
drawEngulfed = true;
|
||||
drawTrueGaped = true;
|
||||
drawResistance = true;
|
||||
drawSwingTrend = true;
|
||||
drawStarPattern = true;
|
||||
drawFlagPattern = true;
|
||||
drawRisingPattern = true;
|
||||
swingTrendRayLeft = true;
|
||||
swingTrendRayRight = true;
|
||||
drawPiercingPattern = true;
|
||||
drawSignalKeyBarPattern = true;
|
||||
|
||||
//
|
||||
drawRecentPatterns = true;
|
||||
drawFakeBreakedZone = true;
|
||||
drawRecentlyTestedZones = true;
|
||||
drawRecentlyBreakedZones = true;
|
||||
|
||||
//
|
||||
drawFIMAPVPivotsAnalysis = true;
|
||||
drawFIMAPVPivotsAnalysisZones = true;
|
||||
drawFIMAPVPivotsAnalysisTrends = true;
|
||||
drawFIMAPVPivotsAnalysisPivots = true;
|
||||
|
||||
//
|
||||
drawFIMASARPivotsAnalysis = true;
|
||||
drawFIMASARPivotsAnalysisZones = true;
|
||||
drawFIMASARPivotsAnalysisTrends = true;
|
||||
drawFIMASARPivotsAnalysisPivots = true;
|
||||
|
||||
//
|
||||
drawFIMAZigZagPivotsAnalysis = true;
|
||||
drawFIMAZigZagPivotsAnalysisZones = true;
|
||||
drawFIMAZigZagPivotsAnalysisTrends = true;
|
||||
drawFIMAZigZagPivotsAnalysisPivots = true;
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
@@ -1,792 +0,0 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Library
|
||||
// -------------------------------------------------
|
||||
// Name: XCXFIMAEALib ...
|
||||
// Description: XFIMAEA Library ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XFIMAEA Library"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
|
||||
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
|
||||
#include "../../Libraries/x-saherelm.x-pivot.analysis.lib.mq5"
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
|
||||
/**
|
||||
* Configure Market Structure Detection ...
|
||||
**/
|
||||
struct XFIMAPatternDetectorConfig
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
// Flags ...
|
||||
|
||||
//
|
||||
bool detectSupport;
|
||||
bool detectResistance;
|
||||
|
||||
//
|
||||
bool detectSwingTrend;
|
||||
|
||||
//
|
||||
bool detectOB;
|
||||
bool detectFVG;
|
||||
|
||||
//
|
||||
bool detectStarPattern;
|
||||
bool detectFlagPattern;
|
||||
bool detectRisingPattern;
|
||||
bool detectPiercingPattern;
|
||||
bool detectSignalKeyBarPattern;
|
||||
|
||||
//
|
||||
bool detectPinned;
|
||||
bool detectMomentum;
|
||||
bool detectEngulfed;
|
||||
bool detectTrueGaped;
|
||||
|
||||
//
|
||||
bool analyseFIMAPVPivots;
|
||||
bool analyseFIMASARPivots;
|
||||
bool analyseFIMAZigZagPivots;
|
||||
|
||||
//
|
||||
bool detectMACrosses;
|
||||
double validMACrossDiffMultiplier;
|
||||
|
||||
//
|
||||
bool detectHKSwitches;
|
||||
bool detectSARSwitches;
|
||||
|
||||
//
|
||||
// Configs ...
|
||||
|
||||
//
|
||||
// OB / FVG ...
|
||||
int obLoopback;
|
||||
int fvgLoopback;
|
||||
|
||||
//
|
||||
// Trending ...
|
||||
int trendingNumberOfSwings;
|
||||
int trendingSwingShoulders;
|
||||
|
||||
//
|
||||
int recentlyPatternsMaxLookupLength;
|
||||
int recentlyPatternsMaxAllowedCollecting;
|
||||
|
||||
//
|
||||
// Support and Resistance ...
|
||||
int recentlyZonesMaxLookupLength;
|
||||
int supportAndResistanceValidationLength;
|
||||
int minAllowdSupportAndResistanceStrength;
|
||||
int supportAndResistanceMaxAllowedLoopback;
|
||||
int supportAndResistanceBreakeValidationLength;
|
||||
|
||||
//
|
||||
// TrueGap ...
|
||||
double truwGapApprovedPointMultiplier;
|
||||
|
||||
//
|
||||
// Flag Pattern ...
|
||||
int flagPatternMinimumPullbackBars;
|
||||
|
||||
//
|
||||
// Momentum Bar ...
|
||||
int momentumBarRangeLength;
|
||||
double momentumBarApprovedMultiplier;
|
||||
|
||||
//
|
||||
// Pinned Bar ...
|
||||
double pinnedBaarShadowApprovedMultiplier;
|
||||
double pinnedBarMinimumPinBarRangeMultiplier;
|
||||
bool pinnedBarForceDirection;
|
||||
|
||||
//
|
||||
// SignalKey Bar ...
|
||||
double signalKeyBarShadowApprovedMultiplier;
|
||||
double signalKeyBarMinimumPinBarRangeMultiplier;
|
||||
bool signalKeyBarForceDirection;
|
||||
|
||||
//
|
||||
// Analyser ...
|
||||
int pvPivotsValidationLength;
|
||||
int numberOfRequiredPivotsForAnalysis;
|
||||
int maxAllowedLoopbackLengthForAnalysis;
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XFIMAPatternDetectorConfig()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* Cleanup Model ...
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
detectOB = false;
|
||||
detectFVG = false;
|
||||
detectSupport = false;
|
||||
detectResistance = false;
|
||||
detectSwingTrend = false;
|
||||
detectStarPattern = false;
|
||||
detectFlagPattern = false;
|
||||
detectRisingPattern = false;
|
||||
detectPiercingPattern = false;
|
||||
detectSignalKeyBarPattern = false;
|
||||
detectPinned = false;
|
||||
detectMomentum = false;
|
||||
detectEngulfed = false;
|
||||
detectTrueGaped = false;
|
||||
analyseFIMAPVPivots = false;
|
||||
analyseFIMASARPivots = false;
|
||||
analyseFIMAZigZagPivots = false;
|
||||
|
||||
//
|
||||
detectMACrosses = false;
|
||||
validMACrossDiffMultiplier = 0;
|
||||
|
||||
//
|
||||
detectHKSwitches = false;
|
||||
detectSARSwitches = false;
|
||||
|
||||
//
|
||||
obLoopback = 0;
|
||||
fvgLoopback = 0;
|
||||
trendingNumberOfSwings = 0;
|
||||
trendingSwingShoulders = 0;
|
||||
recentlyZonesMaxLookupLength = 0;
|
||||
recentlyPatternsMaxLookupLength = 0;
|
||||
recentlyPatternsMaxAllowedCollecting = 0;
|
||||
supportAndResistanceValidationLength = 0;
|
||||
minAllowdSupportAndResistanceStrength = 0;
|
||||
supportAndResistanceMaxAllowedLoopback = 0;
|
||||
supportAndResistanceBreakeValidationLength = 0;
|
||||
truwGapApprovedPointMultiplier = 0;
|
||||
flagPatternMinimumPullbackBars = 0;
|
||||
momentumBarRangeLength = 0;
|
||||
momentumBarApprovedMultiplier = 0;
|
||||
pinnedBaarShadowApprovedMultiplier = 0;
|
||||
pinnedBarMinimumPinBarRangeMultiplier = 0;
|
||||
pinnedBarForceDirection = false;
|
||||
signalKeyBarShadowApprovedMultiplier = 0;
|
||||
signalKeyBarMinimumPinBarRangeMultiplier = 0;
|
||||
signalKeyBarForceDirection = false;
|
||||
pvPivotsValidationLength = 0;
|
||||
numberOfRequiredPivotsForAnalysis = 0;
|
||||
maxAllowedLoopbackLengthForAnalysis = 0;
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Model ...
|
||||
*/
|
||||
void Default()
|
||||
{
|
||||
//
|
||||
// OB / FVG ...
|
||||
detectOB = false;
|
||||
detectFVG = false;
|
||||
|
||||
//
|
||||
// Support and Resistances ...
|
||||
detectSupport = false;
|
||||
detectResistance = false;
|
||||
detectSwingTrend = false;
|
||||
|
||||
//
|
||||
// Patterns ...
|
||||
detectStarPattern = false;
|
||||
detectFlagPattern = false;
|
||||
detectRisingPattern = false;
|
||||
detectPiercingPattern = false;
|
||||
detectSignalKeyBarPattern = false;
|
||||
|
||||
//
|
||||
// Bars ...
|
||||
detectPinned = false;
|
||||
detectMomentum = false;
|
||||
detectEngulfed = false;
|
||||
detectTrueGaped = false;
|
||||
|
||||
//
|
||||
// Analysers ...
|
||||
analyseFIMAPVPivots = false;
|
||||
analyseFIMASARPivots = false;
|
||||
analyseFIMAZigZagPivots = false;
|
||||
|
||||
//
|
||||
detectMACrosses = true;
|
||||
validMACrossDiffMultiplier = 1;
|
||||
|
||||
//
|
||||
detectHKSwitches = true;
|
||||
detectSARSwitches = true;
|
||||
|
||||
//
|
||||
// OB / FVg ...
|
||||
obLoopback = 5;
|
||||
fvgLoopback = 5;
|
||||
|
||||
//
|
||||
// Trending ...
|
||||
trendingNumberOfSwings = 3;
|
||||
trendingSwingShoulders = 11;
|
||||
|
||||
//
|
||||
// Support and Resistance ...
|
||||
recentlyZonesMaxLookupLength = 100;
|
||||
recentlyPatternsMaxLookupLength = 50;
|
||||
recentlyPatternsMaxAllowedCollecting = 20;
|
||||
supportAndResistanceValidationLength = 100;
|
||||
minAllowdSupportAndResistanceStrength = 1;
|
||||
supportAndResistanceMaxAllowedLoopback = 1500;
|
||||
supportAndResistanceBreakeValidationLength = 4;
|
||||
|
||||
//
|
||||
// TrueGap ...
|
||||
truwGapApprovedPointMultiplier = 1;
|
||||
|
||||
//
|
||||
// Flag Pattern ...
|
||||
flagPatternMinimumPullbackBars = 3;
|
||||
|
||||
//
|
||||
// Momentum Bar ...
|
||||
momentumBarRangeLength = 3;
|
||||
momentumBarApprovedMultiplier = 2;
|
||||
|
||||
//
|
||||
// Pinned Bar ...
|
||||
pinnedBaarShadowApprovedMultiplier = 3;
|
||||
pinnedBarMinimumPinBarRangeMultiplier = 4;
|
||||
pinnedBarForceDirection = false;
|
||||
|
||||
//
|
||||
// SignalKey Bar ...
|
||||
signalKeyBarShadowApprovedMultiplier = 3;
|
||||
signalKeyBarMinimumPinBarRangeMultiplier = 4;
|
||||
signalKeyBarForceDirection = false;
|
||||
|
||||
//
|
||||
// Length ...
|
||||
pvPivotsValidationLength = 10;
|
||||
numberOfRequiredPivotsForAnalysis = 50;
|
||||
maxAllowedLoopbackLengthForAnalysis = 1500;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full Detection Model ...
|
||||
*/
|
||||
void FullDetect()
|
||||
{
|
||||
//
|
||||
// OB / FVG ...
|
||||
detectOB = true;
|
||||
detectFVG = true;
|
||||
|
||||
//
|
||||
// Support and Resistances ...
|
||||
detectSupport = true;
|
||||
detectResistance = true;
|
||||
detectSwingTrend = true;
|
||||
|
||||
//
|
||||
// Patterns ...
|
||||
detectStarPattern = true;
|
||||
detectFlagPattern = true;
|
||||
detectRisingPattern = true;
|
||||
detectPiercingPattern = true;
|
||||
detectSignalKeyBarPattern = true;
|
||||
|
||||
//
|
||||
// Bars ...
|
||||
detectPinned = true;
|
||||
detectMomentum = true;
|
||||
detectEngulfed = true;
|
||||
detectTrueGaped = true;
|
||||
|
||||
//
|
||||
// Analysers ...
|
||||
analyseFIMAPVPivots = true;
|
||||
analyseFIMASARPivots = true;
|
||||
analyseFIMAZigZagPivots = true;
|
||||
|
||||
//
|
||||
detectMACrosses = true;
|
||||
detectHKSwitches = true;
|
||||
detectSARSwitches = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Config, by turn off all detecting flags ...
|
||||
*/
|
||||
void OffDetectors()
|
||||
{
|
||||
//
|
||||
// OB / FVG ...
|
||||
detectOB = false;
|
||||
detectFVG = false;
|
||||
|
||||
//
|
||||
// Support and Resistances ...
|
||||
detectSupport = false;
|
||||
detectResistance = false;
|
||||
detectSwingTrend = false;
|
||||
|
||||
//
|
||||
// Patterns ...
|
||||
detectStarPattern = false;
|
||||
detectFlagPattern = false;
|
||||
detectRisingPattern = false;
|
||||
detectPiercingPattern = false;
|
||||
detectSignalKeyBarPattern = false;
|
||||
|
||||
//
|
||||
// Bars ...
|
||||
detectPinned = false;
|
||||
detectMomentum = false;
|
||||
detectEngulfed = false;
|
||||
detectTrueGaped = false;
|
||||
|
||||
//
|
||||
// Analysers ...
|
||||
analyseFIMAPVPivots = false;
|
||||
analyseFIMASARPivots = false;
|
||||
analyseFIMAZigZagPivots = false;
|
||||
|
||||
//
|
||||
detectMACrosses = false;
|
||||
detectHKSwitches = false;
|
||||
detectSARSwitches = false;
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
/**
|
||||
* XFIMA Base Market Structure ...
|
||||
* AnalyseMarket result ...
|
||||
**/
|
||||
struct XFIMAMarketStructure
|
||||
{
|
||||
//
|
||||
XOHCL bar;
|
||||
|
||||
//
|
||||
XBoxZone ob;
|
||||
XBoxZone fvg;
|
||||
XBoxZone support;
|
||||
XBoxZone resistance;
|
||||
|
||||
//
|
||||
XBoxZone obs[];
|
||||
XBoxZone fvgs[];
|
||||
XBoxZone supports[];
|
||||
XBoxZone resistances[];
|
||||
|
||||
//
|
||||
XPivot pinBars[];
|
||||
XPivot engulfBars[];
|
||||
XPivot trueGapBars[];
|
||||
XPivot momentumBars[];
|
||||
|
||||
//
|
||||
XBoxZone flagPatterns[];
|
||||
XBoxZone starPatterns[];
|
||||
XBoxZone risingPatterns[];
|
||||
XBoxZone piercingPatterns[];
|
||||
XBoxZone signalKeyBarPatterns[];
|
||||
|
||||
//
|
||||
// Previous Support or Resistance based on current ...
|
||||
//
|
||||
// Current Support is Touched => Prev Support;
|
||||
// Current Resistance is Touched => Prev Resistance;
|
||||
XBoxZone fakeBreakedZone;
|
||||
|
||||
//
|
||||
XBoxZone recentlyTestedZones[];
|
||||
XBoxZone recentlyBreakedZones[];
|
||||
|
||||
//
|
||||
// Analysis ...
|
||||
XPivotAnalysis pvAnalysis;
|
||||
XPivotAnalysis sarAnalysis;
|
||||
XPivotAnalysis zigzagAnalysis;
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION pinnedDir;
|
||||
ENUM_X_DIRECTION momentumDir;
|
||||
ENUM_X_DIRECTION engulfedDir;
|
||||
ENUM_X_DIRECTION trueGapedDir;
|
||||
|
||||
//
|
||||
XOHCL flagSwing;
|
||||
ENUM_X_DIRECTION flagPatternDir;
|
||||
|
||||
//
|
||||
XOHCL trendSwings[];
|
||||
ENUM_X_DIRECTION trendDir;
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION starPatternDir;
|
||||
ENUM_X_DIRECTION risingPatternDir;
|
||||
ENUM_X_DIRECTION piercingPatternDir;
|
||||
ENUM_X_DIRECTION signalKeyBarPatternDir;
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION maCrossDir;
|
||||
XPivot maCrosses[];
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION hkSwitchDir;
|
||||
XPivot hkSwitches[];
|
||||
|
||||
//
|
||||
ENUM_X_DIRECTION sarSwitchDir;
|
||||
XPivot sarSwitches[];
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XFIMAMarketStructure()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* Cleanup Model ...
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
support.Clean();
|
||||
resistance.Clean();
|
||||
|
||||
//
|
||||
fakeBreakedZone.Clean();
|
||||
|
||||
//
|
||||
bar.Clean();
|
||||
flagSwing.Clean();
|
||||
|
||||
//
|
||||
pvAnalysis.Clean();
|
||||
sarAnalysis.Clean();
|
||||
zigzagAnalysis.Clean();
|
||||
|
||||
//
|
||||
trendDir = X_DIRECTION_NONE;
|
||||
pinnedDir = X_DIRECTION_NONE;
|
||||
momentumDir = X_DIRECTION_NONE;
|
||||
engulfedDir = X_DIRECTION_NONE;
|
||||
trueGapedDir = X_DIRECTION_NONE;
|
||||
flagPatternDir = X_DIRECTION_NONE;
|
||||
starPatternDir = X_DIRECTION_NONE;
|
||||
risingPatternDir = X_DIRECTION_NONE;
|
||||
piercingPatternDir = X_DIRECTION_NONE;
|
||||
signalKeyBarPatternDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
maCrossDir = X_DIRECTION_NONE;
|
||||
SpecifiedClean(maCrosses);
|
||||
|
||||
//
|
||||
hkSwitchDir = X_DIRECTION_NONE;
|
||||
SpecifiedClean(hkSwitches);
|
||||
|
||||
//
|
||||
sarSwitchDir = X_DIRECTION_NONE;
|
||||
SpecifiedClean(sarSwitches);
|
||||
|
||||
//
|
||||
SpecifiedClean(obs);
|
||||
SpecifiedClean(fvgs);
|
||||
SpecifiedClean(pinBars);
|
||||
SpecifiedClean(supports);
|
||||
SpecifiedClean(engulfBars);
|
||||
SpecifiedClean(resistances);
|
||||
SpecifiedClean(trueGapBars);
|
||||
SpecifiedClean(momentumBars);
|
||||
SpecifiedClean(flagPatterns);
|
||||
SpecifiedClean(starPatterns);
|
||||
SpecifiedClean(risingPatterns);
|
||||
SpecifiedClean(piercingPatterns);
|
||||
SpecifiedClean(signalKeyBarPatterns);
|
||||
|
||||
//
|
||||
SpecifiedClean(trendSwings);
|
||||
SpecifiedClean(recentlyTestedZones);
|
||||
SpecifiedClean(recentlyBreakedZones);
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
//
|
||||
// Checker Functions ...
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
/**
|
||||
* Configure Market Structure Drawer ...
|
||||
**/
|
||||
struct XFIMAMarketStructureDrawerConfig
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
bool drawOB; // Current Order Block ...
|
||||
bool drawFVG; // Current Fair Value Gap ...
|
||||
|
||||
//
|
||||
bool drawSupport; // Detected Supports ...
|
||||
bool drawResistance; // Detected Resistances ...
|
||||
|
||||
//
|
||||
bool drawSwingTrend; // Swing Trend ...
|
||||
bool swingTrendRayLeft; // Ray Left Swing Trend ...
|
||||
bool swingTrendRayRight; // Ray Right Swing Trend ...
|
||||
|
||||
//
|
||||
// Draw Current Detected Patterns ...
|
||||
|
||||
//
|
||||
bool drawPinned;
|
||||
bool drawMomentum;
|
||||
bool drawEngulfed;
|
||||
bool drawTrueGaped;
|
||||
|
||||
//
|
||||
bool drawStarPattern;
|
||||
bool drawFlagPattern;
|
||||
bool drawRisingPattern;
|
||||
bool drawPiercingPattern;
|
||||
bool drawSignalKeyBarPattern;
|
||||
|
||||
//
|
||||
// Draw Recently Zones ...
|
||||
bool drawRecentPatterns;
|
||||
bool drawFakeBreakedZone;
|
||||
bool drawRecentlyTestedZones;
|
||||
bool drawRecentlyBreakedZones;
|
||||
|
||||
//
|
||||
// Draw Analysis Pivots ...
|
||||
|
||||
//
|
||||
// XPV ...
|
||||
bool drawFIMAPVPivotsAnalysis;
|
||||
bool drawFIMAPVPivotsAnalysisZones;
|
||||
bool drawFIMAPVPivotsAnalysisTrends;
|
||||
bool drawFIMAPVPivotsAnalysisPivots;
|
||||
|
||||
//
|
||||
// XSAR ...
|
||||
bool drawFIMASARPivotsAnalysis;
|
||||
bool drawFIMASARPivotsAnalysisZones;
|
||||
bool drawFIMASARPivotsAnalysisTrends;
|
||||
bool drawFIMASARPivotsAnalysisPivots;
|
||||
|
||||
//
|
||||
// XZIGZAG ...
|
||||
bool drawFIMAZigZagPivotsAnalysis;
|
||||
bool drawFIMAZigZagPivotsAnalysisZones;
|
||||
bool drawFIMAZigZagPivotsAnalysisTrends;
|
||||
bool drawFIMAZigZagPivotsAnalysisPivots;
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XFIMAMarketStructureDrawerConfig()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* Cleanup Model ...
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
drawOB = false;
|
||||
drawFVG = false;
|
||||
drawPinned = false;
|
||||
drawMomentum = false;
|
||||
drawSupport = false;
|
||||
drawEngulfed = false;
|
||||
drawTrueGaped = false;
|
||||
drawResistance = false;
|
||||
drawSwingTrend = false;
|
||||
drawStarPattern = false;
|
||||
drawFlagPattern = false;
|
||||
swingTrendRayLeft = false;
|
||||
drawRisingPattern = false;
|
||||
swingTrendRayRight = false;
|
||||
drawPiercingPattern = false;
|
||||
drawSignalKeyBarPattern = false;
|
||||
|
||||
//
|
||||
drawRecentPatterns = false;
|
||||
drawFakeBreakedZone = false;
|
||||
drawRecentlyTestedZones = false;
|
||||
drawRecentlyBreakedZones = false;
|
||||
|
||||
//
|
||||
drawFIMAPVPivotsAnalysis = false;
|
||||
drawFIMAPVPivotsAnalysisZones = false;
|
||||
drawFIMAPVPivotsAnalysisTrends = false;
|
||||
drawFIMAPVPivotsAnalysisPivots = false;
|
||||
|
||||
//
|
||||
drawFIMASARPivotsAnalysis = false;
|
||||
drawFIMASARPivotsAnalysisZones = false;
|
||||
drawFIMASARPivotsAnalysisTrends = false;
|
||||
drawFIMASARPivotsAnalysisPivots = false;
|
||||
|
||||
//
|
||||
drawFIMAZigZagPivotsAnalysis = false;
|
||||
drawFIMAZigZagPivotsAnalysisZones = false;
|
||||
drawFIMAZigZagPivotsAnalysisTrends = false;
|
||||
drawFIMAZigZagPivotsAnalysisPivots = false;
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Model ...
|
||||
*/
|
||||
void Default()
|
||||
{
|
||||
drawOB = true;
|
||||
drawFVG = true;
|
||||
drawPinned = true;
|
||||
drawMomentum = true;
|
||||
drawSupport = true;
|
||||
drawEngulfed = true;
|
||||
drawTrueGaped = true;
|
||||
drawResistance = true;
|
||||
drawSwingTrend = true;
|
||||
drawStarPattern = true;
|
||||
drawFlagPattern = true;
|
||||
drawRisingPattern = true;
|
||||
drawPiercingPattern = true;
|
||||
swingTrendRayLeft = false;
|
||||
swingTrendRayRight = true;
|
||||
drawSignalKeyBarPattern = true;
|
||||
|
||||
//
|
||||
drawRecentPatterns = true;
|
||||
drawFakeBreakedZone = true;
|
||||
drawRecentlyTestedZones = true;
|
||||
drawRecentlyBreakedZones = true;
|
||||
|
||||
//
|
||||
drawFIMAPVPivotsAnalysis = true;
|
||||
drawFIMAPVPivotsAnalysisZones = true;
|
||||
drawFIMAPVPivotsAnalysisTrends = true;
|
||||
drawFIMAPVPivotsAnalysisPivots = true;
|
||||
|
||||
//
|
||||
drawFIMASARPivotsAnalysis = true;
|
||||
drawFIMASARPivotsAnalysisZones = true;
|
||||
drawFIMASARPivotsAnalysisTrends = true;
|
||||
drawFIMASARPivotsAnalysisPivots = true;
|
||||
|
||||
//
|
||||
drawFIMAZigZagPivotsAnalysis = true;
|
||||
drawFIMAZigZagPivotsAnalysisZones = true;
|
||||
drawFIMAZigZagPivotsAnalysisTrends = true;
|
||||
drawFIMAZigZagPivotsAnalysisPivots = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure for Full Drawing ...
|
||||
*/
|
||||
void FullDraw()
|
||||
{
|
||||
//
|
||||
Default();
|
||||
|
||||
//
|
||||
drawOB = true;
|
||||
drawFVG = true;
|
||||
drawPinned = true;
|
||||
drawMomentum = true;
|
||||
drawSupport = true;
|
||||
drawEngulfed = true;
|
||||
drawTrueGaped = true;
|
||||
drawResistance = true;
|
||||
drawSwingTrend = true;
|
||||
drawStarPattern = true;
|
||||
drawFlagPattern = true;
|
||||
drawRisingPattern = true;
|
||||
swingTrendRayLeft = true;
|
||||
swingTrendRayRight = true;
|
||||
drawPiercingPattern = true;
|
||||
drawSignalKeyBarPattern = true;
|
||||
|
||||
//
|
||||
drawRecentPatterns = true;
|
||||
drawFakeBreakedZone = true;
|
||||
drawRecentlyTestedZones = true;
|
||||
drawRecentlyBreakedZones = true;
|
||||
|
||||
//
|
||||
drawFIMAPVPivotsAnalysis = true;
|
||||
drawFIMAPVPivotsAnalysisZones = true;
|
||||
drawFIMAPVPivotsAnalysisTrends = true;
|
||||
drawFIMAPVPivotsAnalysisPivots = true;
|
||||
|
||||
//
|
||||
drawFIMASARPivotsAnalysis = true;
|
||||
drawFIMASARPivotsAnalysisZones = true;
|
||||
drawFIMASARPivotsAnalysisTrends = true;
|
||||
drawFIMASARPivotsAnalysisPivots = true;
|
||||
|
||||
//
|
||||
drawFIMAZigZagPivotsAnalysis = true;
|
||||
drawFIMAZigZagPivotsAnalysisZones = true;
|
||||
drawFIMAZigZagPivotsAnalysisTrends = true;
|
||||
drawFIMAZigZagPivotsAnalysisPivots = true;
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,495 +0,0 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class
|
||||
// -------------------------------------------------
|
||||
// Name: XCXFIMAPoiDetector ...
|
||||
// Description: XFIMA POI Detector Class ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XFIMA POI Detector Class"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../../Classes/x-saherelm.base.class.mq5"
|
||||
#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
|
||||
#include "../../Classes/x-saherelm.x-market.pattern.class.mq5"
|
||||
#include "../Libraries/x-saherelm.xfima.lib.mq5"
|
||||
|
||||
//
|
||||
// Implementation ...
|
||||
class XCXFIMAPOIDetector : public XCMarketPatternDetector
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Props ...
|
||||
XCBarAnalyser *barAnalyser; // Bar Analyser ...
|
||||
XCXFIMAHelper *fimaHelper; // XFIMA Helper ...
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XCXFIMAPOIDetector(
|
||||
XCXFIMAHelper *_fimaHelper //
|
||||
) : XCMarketPatternDetector()
|
||||
{
|
||||
//
|
||||
barAnalyser = new XCBarAnalyser();
|
||||
fimaHelper = _fimaHelper;
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
~XCXFIMAPOIDetector()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Actions and Tools ...
|
||||
|
||||
//
|
||||
// Pivot Analysors ...
|
||||
|
||||
/**
|
||||
* Analyse Market based on Specified Kind of Pivots ...
|
||||
*
|
||||
* @param analysis: XPivotAnalysis, reference to hold result ...
|
||||
* @param barIndex: int, Bar Index ...
|
||||
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
||||
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
||||
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool AnalysePVPivots(
|
||||
XPivotAnalysis &analysis,
|
||||
int barIndex = 0,
|
||||
int requiredNumberOFPivots = 50,
|
||||
int maxAllowedLoopbackLength = 1500,
|
||||
int validationLength = 0 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
analysis.Clean();
|
||||
|
||||
//
|
||||
// Reading Pivots ...
|
||||
XPivot pivots[];
|
||||
int count = fimaHelper.ExtractPVPivots(
|
||||
pivots, // Result ...
|
||||
barIndex, // Bar Index ...
|
||||
requiredNumberOFPivots, // Required Number of Pivots ...
|
||||
maxAllowedLoopbackLength, // Max Allowed Loopback ...
|
||||
validationLength // Validation Length ...
|
||||
);
|
||||
result = IsValidSize(count);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
SpecifiedClean(pivots);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string symbol = fimaHelper.GetSymbol();
|
||||
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
|
||||
|
||||
//
|
||||
// Initialize Analysis ...
|
||||
result = analysis.Init(
|
||||
"XFIMA_XPV",
|
||||
symbol,
|
||||
period,
|
||||
pivots //
|
||||
);
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
if (!result)
|
||||
{
|
||||
analysis.Clean();
|
||||
}
|
||||
SpecifiedClean(pivots);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyse Market based on Specified Kind of Pivots ...
|
||||
*
|
||||
* @param analysis: XPivotAnalysis, reference to hold result ...
|
||||
* @param barIndex: int, Bar Index ...
|
||||
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
||||
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
||||
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool AnalyseMAPivots(
|
||||
XPivotAnalysis &analysis,
|
||||
int barIndex = 0,
|
||||
int requiredNumberOFPivots = 50,
|
||||
int maxAllowedLoopbackLength = 1500,
|
||||
int validationLength = 0 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
analysis.Clean();
|
||||
|
||||
//
|
||||
// Reading Pivots ...
|
||||
XPivot pivots[];
|
||||
int count = fimaHelper.ExtractMAPivots(
|
||||
pivots, // Result ...
|
||||
barIndex, // Bar Index ...
|
||||
requiredNumberOFPivots, // Required Number of Pivots ...
|
||||
maxAllowedLoopbackLength, // Max Allowed Loopback ...
|
||||
validationLength // Validation Length ...
|
||||
);
|
||||
result = IsValidSize(count);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
SpecifiedClean(pivots);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string symbol = fimaHelper.GetSymbol();
|
||||
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
|
||||
|
||||
//
|
||||
// Initialize Analysis ...
|
||||
result = analysis.Init(
|
||||
"XFIMA_XMA",
|
||||
symbol,
|
||||
period,
|
||||
pivots //
|
||||
);
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
if (!result)
|
||||
{
|
||||
analysis.Clean();
|
||||
}
|
||||
SpecifiedClean(pivots);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyse Market based on Specified Kind of Pivots ...
|
||||
*
|
||||
* @param analysis: XPivotAnalysis, reference to hold result ...
|
||||
* @param barIndex: int, Bar Index ...
|
||||
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
||||
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool AnalyseSARPivots(
|
||||
XPivotAnalysis &analysis,
|
||||
int barIndex = 0,
|
||||
int requiredNumberOFPivots = 50,
|
||||
int maxAllowedLoopbackLength = 1500 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
analysis.Clean();
|
||||
|
||||
//
|
||||
// Reading Pivots ...
|
||||
XPivot pivots[];
|
||||
int count = fimaHelper.ExtractSARPivots(
|
||||
pivots, // Result ...
|
||||
barIndex, // Bar Index ...
|
||||
requiredNumberOFPivots, // Required Number of Pivots ...
|
||||
maxAllowedLoopbackLength // Max Allowed Loopback ...
|
||||
);
|
||||
result = IsValidSize(count);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
SpecifiedClean(pivots);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string symbol = fimaHelper.GetSymbol();
|
||||
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
|
||||
|
||||
//
|
||||
// Initialize Analysis ...
|
||||
result = analysis.Init(
|
||||
"XFIMA_XSAR",
|
||||
symbol,
|
||||
period,
|
||||
pivots //
|
||||
);
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
if (!result)
|
||||
{
|
||||
analysis.Clean();
|
||||
}
|
||||
SpecifiedClean(pivots);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyse Market based on Specified Kind of Pivots ...
|
||||
*
|
||||
* @param analysis: XPivotAnalysis, reference to hold result ...
|
||||
* @param barIndex: int, Bar Index ...
|
||||
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
||||
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool AnalyseZigZagPivots(
|
||||
XPivotAnalysis &analysis,
|
||||
int barIndex = 0,
|
||||
int requiredNumberOFPivots = 50,
|
||||
int maxAllowedLoopbackLength = 1500 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
analysis.Clean();
|
||||
|
||||
//
|
||||
// Reading Pivots ...
|
||||
XPivot pivots[];
|
||||
int count = fimaHelper.ExtractZigZagPivots(
|
||||
pivots, // Result ...
|
||||
barIndex, // Bar Index ...
|
||||
requiredNumberOFPivots, // Required Number of Pivots ...
|
||||
maxAllowedLoopbackLength // Max Allowed Loopback ...
|
||||
);
|
||||
result = IsValidSize(count);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
SpecifiedClean(pivots);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string symbol = fimaHelper.GetSymbol();
|
||||
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
|
||||
|
||||
//
|
||||
// Initialize Analysis ...
|
||||
result = analysis.Init(
|
||||
"XFIMA_XZG",
|
||||
symbol,
|
||||
period,
|
||||
pivots //
|
||||
);
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
if (!result)
|
||||
{
|
||||
analysis.Clean();
|
||||
}
|
||||
SpecifiedClean(pivots);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy ...
|
||||
*/
|
||||
void Destroy()
|
||||
{
|
||||
//
|
||||
delete barAnalyser;
|
||||
ZeroMemory(barAnalyser);
|
||||
}
|
||||
|
||||
//
|
||||
// Testers ...
|
||||
|
||||
/**
|
||||
* Analyse Market based on Specified Bar ...
|
||||
*
|
||||
* @param structure: XFIMAMarketStructure, reference to holds result ...
|
||||
* @param config: XFIMAMarketStructureConfig, reference to Configure Detector ...
|
||||
* @param barIndex: int, Bar Index ...
|
||||
*/
|
||||
void AnalyseMarket(
|
||||
XFIMAMarketStructure &structure,
|
||||
XFIMAMarketStructureConfig &config,
|
||||
int barIndex = 0 //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Prepare ...
|
||||
structure.Clean();
|
||||
|
||||
//
|
||||
// Normalize ...
|
||||
barIndex = NormalizeInt(barIndex, 0);
|
||||
|
||||
//
|
||||
bool has = false;
|
||||
|
||||
//
|
||||
string symbol = fimaHelper.GetSymbol();
|
||||
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
|
||||
has = structure.bar.Init(
|
||||
symbol,
|
||||
period,
|
||||
barIndex //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
structure.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Bar Patterns ...
|
||||
XOHCL iBar;
|
||||
XPatternAnalysis iPatternAnalysis;
|
||||
for (int i = barIndex; i < barIndex + config.loopback; i++)
|
||||
{
|
||||
//
|
||||
// Cleanup ...
|
||||
iBar.Clean();
|
||||
iPatternAnalysis.Clean();
|
||||
|
||||
//
|
||||
// Initialize Indexed Bar ...
|
||||
//
|
||||
has = structure.bar.BarAt(i, iBar);
|
||||
if (!has)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Analyse Indexed Bar ...
|
||||
has = AnalyseBarPatterns(iBar, iPatternAnalysis, config.barsAnalysisConfig);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddRef(
|
||||
iPatternAnalysis,
|
||||
structure.barsAnalysis //
|
||||
);
|
||||
|
||||
//
|
||||
if (i == barIndex)
|
||||
{
|
||||
structure.barAnalysis = iPatternAnalysis;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Satisfied ...
|
||||
has = ArraySize(structure.barsAnalysis) >= config.requiredPivots;
|
||||
if (has)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Pivot Analysis ...
|
||||
|
||||
//
|
||||
// XPV ...
|
||||
if (config.analysePVPivots)
|
||||
{
|
||||
//
|
||||
// Reading Pivots ...
|
||||
has = AnalysePVPivots(
|
||||
structure.pvAnalysis,
|
||||
barIndex,
|
||||
config.requiredPivots,
|
||||
config.loopback,
|
||||
config.pvPivotsValidationLength //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
structure.pvAnalysis.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// XZG ...
|
||||
if (config.analyseZGPivots)
|
||||
{
|
||||
//
|
||||
// Reading Pivots ...
|
||||
has = AnalyseZigZagPivots(
|
||||
structure.zgAnalysis,
|
||||
barIndex,
|
||||
config.requiredPivots,
|
||||
config.loopback //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
structure.zgAnalysis.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
iBar.Clean();
|
||||
iPatternAnalysis.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,826 +0,0 @@
|
||||
|
||||
/**
|
||||
* Analyse Market based on Specified Bar ...
|
||||
*
|
||||
* @param forBar: XOHCL, reference Specified Bar for Analyse Market ...
|
||||
* @param structure: XFIMAMarketStructure, reference to holds result ...
|
||||
* @param config: XFIMAPatternDetectorConfig, reference to Configure Detector ...
|
||||
*/
|
||||
void AnalyseMarket(
|
||||
XOHCL &forBar,
|
||||
XFIMAMarketStructure &structure,
|
||||
XFIMAPatternDetectorConfig &config //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Prepare ...
|
||||
structure.Clean();
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
if (!forBar.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Do Analysis ...
|
||||
|
||||
//
|
||||
structure.bar = forBar;
|
||||
|
||||
//
|
||||
int idx = -1;
|
||||
bool has = false;
|
||||
int maxAllowedCollecting = 50;
|
||||
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
// Detecting POI Based on Config ...
|
||||
|
||||
//
|
||||
// Order Block ...
|
||||
if (config.detectOB)
|
||||
{
|
||||
//
|
||||
bool isOB = HasOB(
|
||||
forBar,
|
||||
iDir,
|
||||
structure.ob,
|
||||
config.obLoopback //
|
||||
);
|
||||
bool isBullishOB = isOB &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishOB = isOB &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (!isOB)
|
||||
{
|
||||
structure.ob.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Touches ...
|
||||
if (isOB)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
structure.ob,
|
||||
obs,
|
||||
maxAllowedCollecting //
|
||||
);
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
bool has = forBar.GetPreviousBar(pBar);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
structure.isOBTouched =
|
||||
isBullishOB
|
||||
? pBar.low < structure.ob.upper
|
||||
: pBar.high > structure.ob.lower;
|
||||
}
|
||||
|
||||
//
|
||||
pBar.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Fair Value Gap ...
|
||||
if (config.detectFVG)
|
||||
{
|
||||
//
|
||||
bool isFVG = HasFVG(
|
||||
forBar,
|
||||
iDir,
|
||||
structure.fvg,
|
||||
config.fvgLoopback //
|
||||
);
|
||||
bool isBullishFVG = isFVG &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishFVG = isFVG &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (!isFVG)
|
||||
{
|
||||
structure.fvg.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Touches ...
|
||||
if (isFVG)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
structure.fvg,
|
||||
fvgs,
|
||||
maxAllowedCollecting //
|
||||
);
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
bool has = forBar.GetPreviousBar(pBar);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
structure.isFVGTouched =
|
||||
isBullishFVG
|
||||
? pBar.low < structure.fvg.upper
|
||||
: pBar.high > structure.fvg.lower;
|
||||
}
|
||||
|
||||
//
|
||||
pBar.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Momentum Bar ...
|
||||
if (config.detectMomentum)
|
||||
{
|
||||
//
|
||||
bool isMomentum = IsMomentumBar(
|
||||
forBar,
|
||||
iDir,
|
||||
config.momentumBarRangeLength,
|
||||
config.momentumBarApprovedMultiplier //
|
||||
);
|
||||
bool isBullishMomentum = isMomentum &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishMomentum = isMomentum &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isMomentum)
|
||||
{
|
||||
structure.momentumDir = iDir;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Engulfed Bar ...
|
||||
if (config.detectEngulfed)
|
||||
{
|
||||
//
|
||||
bool isEngulfed = IsEngulfedBar(
|
||||
forBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishEngulfed = isEngulfed &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishEngulfed = isEngulfed &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isEngulfed)
|
||||
{
|
||||
structure.engulfedDir = iDir;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking TruGaped Bar ...
|
||||
if (config.detectTrueGaped)
|
||||
{
|
||||
//
|
||||
bool isTrueGaped = IsTrueGapedBar(
|
||||
forBar,
|
||||
iDir,
|
||||
config.truwGapApprovedPointMultiplier //
|
||||
);
|
||||
bool isBullishTrueGaped = isTrueGaped &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishTrueGaped = isTrueGaped &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isTrueGaped)
|
||||
{
|
||||
structure.trueGapedDir = iDir;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Pinned Bar ...
|
||||
if (config.detectPinned)
|
||||
{
|
||||
//
|
||||
bool isPinned = IsPinnedBar(
|
||||
forBar,
|
||||
iDir,
|
||||
config.pinnedBaarShadowApprovedMultiplier,
|
||||
config.pinnedBarMinimumPinBarRangeMultiplier,
|
||||
config.pinnedBarForceDirection //
|
||||
);
|
||||
bool isBullishPinned = isPinned &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishPinned = isPinned &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isPinned)
|
||||
{
|
||||
structure.pinnedDir = iDir;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Star Pattern ...
|
||||
if (config.detectStarPattern)
|
||||
{
|
||||
//
|
||||
bool isStarPattern = IsStartPattern(
|
||||
forBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishStarPattern = isStarPattern &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishStarPattern = isStarPattern &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isStarPattern)
|
||||
{
|
||||
structure.starPatternDir = iDir;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Piercing Pattern ...
|
||||
if (config.detectPiercingPattern)
|
||||
{
|
||||
//
|
||||
bool isPiercingPattern = IsPiercingPattern(
|
||||
forBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishPiercingPattern = isPiercingPattern &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishPiercingPattern = isPiercingPattern &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isPiercingPattern)
|
||||
{
|
||||
structure.piercingPatternDir = iDir;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Rising Pattern ...
|
||||
if (config.detectRisingPattern)
|
||||
{
|
||||
//
|
||||
bool isRisingPattern = IsRisingPattern(
|
||||
forBar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishRisingPattern = isRisingPattern &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishRisingPattern = isRisingPattern &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isRisingPattern)
|
||||
{
|
||||
structure.risingPatternDir = iDir;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Flag Pattern ...
|
||||
if (config.detectFlagPattern)
|
||||
{
|
||||
//
|
||||
XOHCL swingBar;
|
||||
bool isFlagPattern = IsFlagPattern(
|
||||
forBar,
|
||||
iDir,
|
||||
swingBar,
|
||||
config.flagPatternMinimumPullbackBars //
|
||||
);
|
||||
bool isBullishFlagPattern = isFlagPattern &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishFlagPattern = isFlagPattern &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isFlagPattern)
|
||||
{
|
||||
//
|
||||
structure.flagSwing = swingBar;
|
||||
structure.flagPatternDir = iDir;
|
||||
}
|
||||
swingBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Detect SignalKey Bar Pattern ...
|
||||
if (config.detectSignalKeyBarPattern)
|
||||
{
|
||||
//
|
||||
bool isSignalKeyBar = IsSignalKeyBarPattern(
|
||||
forBar,
|
||||
iDir,
|
||||
config.signalKeyBarShadowApprovedMultiplier,
|
||||
config.signalKeyBarMinimumPinBarRangeMultiplier,
|
||||
config.signalKeyBarForceDirection //
|
||||
);
|
||||
bool isBullishSignalKeyBar = isSignalKeyBar &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool isBearishSignalKeyBar = isSignalKeyBar &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (isSignalKeyBar)
|
||||
{
|
||||
structure.signalKeyBarPatternDir = iDir;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Swing Trend ...
|
||||
if (config.detectSwingTrend)
|
||||
{
|
||||
//
|
||||
XOHCL swings[];
|
||||
bool hasSwingTrend = HasSwingTrend(
|
||||
forBar,
|
||||
iDir,
|
||||
swings,
|
||||
config.trendingNumberOfSwings,
|
||||
config.trendingSwingShoulders //
|
||||
);
|
||||
bool hasBullishSwingTrend = hasSwingTrend &&
|
||||
IsSpecifiedBullish(iDir);
|
||||
bool hasBearishSwingTrend = hasSwingTrend &&
|
||||
IsSpecifiedBearish(iDir);
|
||||
if (hasSwingTrend)
|
||||
{
|
||||
//
|
||||
Copy(
|
||||
swings,
|
||||
structure.trendSwings //
|
||||
);
|
||||
structure.trendDir = iDir;
|
||||
}
|
||||
SpecifiedClean(swings);
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Supports ...
|
||||
if (config.detectSupport)
|
||||
{
|
||||
//
|
||||
XOHCL support;
|
||||
bool hasSupport = HasSupport(
|
||||
forBar,
|
||||
support,
|
||||
config.supportAndResistanceValidationLength,
|
||||
config.supportAndResistanceMaxAllowedLoopback //
|
||||
);
|
||||
if (hasSupport)
|
||||
{
|
||||
//
|
||||
XBoxZone supportBox;
|
||||
has = ToSupportBox(support, supportBox);
|
||||
|
||||
//
|
||||
// Validate Zone Strength if Provided ...
|
||||
if (config.minAllowdSupportAndResistanceStrength > 0)
|
||||
{
|
||||
//
|
||||
has = has &&
|
||||
ValidateStrength(
|
||||
supportBox,
|
||||
config.minAllowdSupportAndResistanceStrength //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
supportBox,
|
||||
supports,
|
||||
maxAllowedCollecting //
|
||||
);
|
||||
|
||||
//
|
||||
structure.support = supportBox;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for Support Touches ...
|
||||
XOHCL pBar;
|
||||
has = has &&
|
||||
forBar.GetPreviousBar(pBar);
|
||||
if (has)
|
||||
{
|
||||
structure.isSupportTouched = pBar.low < supportBox.upper;
|
||||
}
|
||||
|
||||
//
|
||||
pBar.Clean();
|
||||
supportBox.Clean();
|
||||
}
|
||||
support.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Resistance ...
|
||||
if (config.detectResistance)
|
||||
{
|
||||
//
|
||||
XOHCL resistance;
|
||||
bool hasResistance = HasResistance(
|
||||
forBar,
|
||||
resistance,
|
||||
config.supportAndResistanceValidationLength,
|
||||
config.supportAndResistanceMaxAllowedLoopback //
|
||||
);
|
||||
if (hasResistance)
|
||||
{
|
||||
//
|
||||
XBoxZone resistanceBox;
|
||||
has = ToResistanceBox(resistance, resistanceBox);
|
||||
|
||||
//
|
||||
// Validate Zone Strength if Provided ...
|
||||
if (config.minAllowdSupportAndResistanceStrength > 0)
|
||||
{
|
||||
//
|
||||
has = has &&
|
||||
ValidateStrength(
|
||||
resistanceBox,
|
||||
config.minAllowdSupportAndResistanceStrength //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
resistanceBox,
|
||||
resistances,
|
||||
maxAllowedCollecting //
|
||||
);
|
||||
|
||||
//
|
||||
structure.resistance = resistanceBox;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for Resistance Touches ...
|
||||
XOHCL pBar;
|
||||
has = has &&
|
||||
forBar.GetPreviousBar(pBar);
|
||||
if (has)
|
||||
{
|
||||
structure.isResistanceTouched = pBar.high > resistanceBox.upper;
|
||||
}
|
||||
|
||||
//
|
||||
pBar.Clean();
|
||||
resistanceBox.Clean();
|
||||
}
|
||||
resistance.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Analysers ...
|
||||
|
||||
//
|
||||
// Analyse Based on PV ...
|
||||
if (config.analyseFIMAPVPivots)
|
||||
{
|
||||
//
|
||||
XPivotAnalysis analysis;
|
||||
has = AnalysePVPivots(
|
||||
analysis, // Result ...
|
||||
forBar.Index(), // Bar Index ...
|
||||
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
|
||||
config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ...
|
||||
config.pvPivotsValidationLength // Validation Length ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
structure.pvAnalysis = analysis;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Analyse Based on MA ...
|
||||
if (config.analyseFIMAMAPivots)
|
||||
{
|
||||
//
|
||||
XPivotAnalysis analysis;
|
||||
has = AnalyseMAPivots(
|
||||
analysis, // Result ...
|
||||
forBar.Index(), // Bar Index ...
|
||||
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
|
||||
config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ...
|
||||
config.pvPivotsValidationLength // Validation Length ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
structure.maAnalysis = analysis;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Analyse Based on SAR ...
|
||||
if (config.analyseFIMASARPivots)
|
||||
{
|
||||
//
|
||||
XPivotAnalysis analysis;
|
||||
has = AnalyseSARPivots(
|
||||
analysis, // Result ...
|
||||
forBar.Index(), // Bar Index ...
|
||||
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
|
||||
config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
structure.sarAnalysis = analysis;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Analyse Based on ZigZag ...
|
||||
if (config.analyseFIMAZigZagPivots)
|
||||
{
|
||||
//
|
||||
XPivotAnalysis analysis;
|
||||
has = AnalyseZigZagPivots(
|
||||
analysis, // Result ...
|
||||
forBar.Index(), // Bar Index ...
|
||||
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
|
||||
config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
structure.zigzagAnalysis = analysis;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// COMPLEX Actions ...
|
||||
|
||||
//
|
||||
// Lockup For Previous Zone ...
|
||||
has = structure.isSupportTouched ||
|
||||
structure.isResistanceTouched;
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
if (structure.isSupportTouched)
|
||||
{
|
||||
//
|
||||
idx = GetYoungestBefore(
|
||||
structure.support.from,
|
||||
supports //
|
||||
);
|
||||
has = IsValidIndex(idx);
|
||||
if (has)
|
||||
{
|
||||
structure.prevZone = supports[idx];
|
||||
}
|
||||
}
|
||||
else if (structure.isResistanceTouched)
|
||||
{
|
||||
//
|
||||
idx = GetYoungestBefore(
|
||||
structure.resistance.from,
|
||||
resistances //
|
||||
);
|
||||
has = IsValidIndex(idx);
|
||||
if (has)
|
||||
{
|
||||
structure.prevZone = resistances[idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Recently Tested Zones ...
|
||||
if ((config.detectSupport ||
|
||||
config.detectResistance) &&
|
||||
config.recentlyTestedZonesMaxLookup > 0)
|
||||
{
|
||||
//
|
||||
XOHCL iBar;
|
||||
int idx = -1;
|
||||
bool has = false;
|
||||
|
||||
//
|
||||
int start = forBar.Index() + 1;
|
||||
int end = start + config.recentlyTestedZonesMaxLookup;
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
//
|
||||
// Initialize Indexed Bar ...
|
||||
has = forBar.BarAt(i, iBar);
|
||||
if (!has)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Selecting Support and Resistances ...
|
||||
|
||||
//
|
||||
// Supports ...
|
||||
idx = GetYoungestBefore(iBar.time, supports);
|
||||
has = IsValidIndex(idx);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Check Testing ...
|
||||
has = IsTested(iBar, supports[idx]);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
supports[idx],
|
||||
structure.recentlyTestedZones //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Resistances ...
|
||||
idx = GetYoungestBefore(iBar.time, resistances);
|
||||
has = IsValidIndex(idx);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Check Testing ...
|
||||
has = IsTested(iBar, resistances[idx]);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddIfNotExists(
|
||||
resistances[idx],
|
||||
structure.recentlyTestedZones //
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Checkup for FakeBreaked Zones ...
|
||||
if (config.detectSupport ||
|
||||
config.detectResistance)
|
||||
{
|
||||
//
|
||||
// Retrieve Previous Bar ...
|
||||
int idx = -1;
|
||||
XOHCL pForBar;
|
||||
XOHCL breakerBar;
|
||||
XBoxZone pSupport;
|
||||
XOHCL pBreakerBar;
|
||||
XBoxZone pResistance;
|
||||
|
||||
//
|
||||
// Selecting Previously Touched Support / Resistance ...
|
||||
has = forBar.GetPreviousBar(pForBar);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Detecting Nearest Above Lows Support ...
|
||||
idx = GetYoungestAbove(
|
||||
pForBar.low,
|
||||
supports //
|
||||
);
|
||||
has = IsValidIndex(idx) &&
|
||||
IsBreaked(
|
||||
forBar,
|
||||
supports[idx] //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
pSupport = supports[idx];
|
||||
}
|
||||
|
||||
//
|
||||
// Detecting Nearest Below Highs Resistance ...
|
||||
idx = GetYoungestBelow(
|
||||
pForBar.high,
|
||||
resistances //
|
||||
);
|
||||
has = IsValidIndex(idx) &&
|
||||
IsBreaked(
|
||||
forBar,
|
||||
resistances[idx] //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
pResistance = resistances[idx];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check at least a zone Exists ...
|
||||
// Selecting pTestedZone ...
|
||||
has = pSupport.IsValid() ||
|
||||
pResistance.IsValid();
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Support ...
|
||||
has = pSupport.IsValid();
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
structure.isPTest = true;
|
||||
structure.pTestedZone = pSupport;
|
||||
}
|
||||
|
||||
//
|
||||
// Resistance ...
|
||||
has = pResistance.IsValid();
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
structure.isPTest = true;
|
||||
structure.pTestedZone = pResistance;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check pTestedZone Existance ...
|
||||
has = structure.isPTest &&
|
||||
structure.pTestedZone.IsValid();
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Get Breaker Bars ...
|
||||
XOHCL breakerBars[];
|
||||
int breakerBarsCount = GetBreakerBars(
|
||||
structure.pTestedZone,
|
||||
breakerBars //
|
||||
);
|
||||
has = IsValidSize(breakerBarsCount);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
idx = GetYoungestBar(breakerBars);
|
||||
has = IsValidIndex(idx);
|
||||
if (has)
|
||||
{
|
||||
breakerBar = breakerBars[idx];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
SpecifiedClean(breakerBars);
|
||||
}
|
||||
|
||||
//
|
||||
// Check Zone Breaker Bar Exists ...
|
||||
// Validate Zone Fake Breake Langth ...
|
||||
has = breakerBar.IsValid();
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Validate Breake Length ...
|
||||
has = (breakerBar.Index() - pForBar.Index()) <= config.supportAndResistanceBreakeValidationLength;
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
//
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
structure.isPTest = false;
|
||||
structure.pTestedZone.Clean();
|
||||
}
|
||||
pForBar.Clean();
|
||||
pSupport.Clean();
|
||||
breakerBar.Clean();
|
||||
pBreakerBar.Clean();
|
||||
pResistance.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Lockup For Previous Zone ...
|
||||
has = structure.isSupportTouched ||
|
||||
structure.isResistanceTouched;
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
if (structure.isSupportTouched)
|
||||
{
|
||||
//
|
||||
idx = GetYoungestBefore(
|
||||
structure.support.from,
|
||||
supports //
|
||||
);
|
||||
has = IsValidIndex(idx);
|
||||
if (has)
|
||||
{
|
||||
structure.prevZone = supports[idx];
|
||||
}
|
||||
}
|
||||
else if (structure.isResistanceTouched)
|
||||
{
|
||||
//
|
||||
idx = GetYoungestBefore(
|
||||
structure.resistance.from,
|
||||
resistances //
|
||||
);
|
||||
has = IsValidIndex(idx);
|
||||
if (has)
|
||||
{
|
||||
structure.prevZone = resistances[idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,641 +0,0 @@
|
||||
// //
|
||||
// // Detect At lease Two PEAK and Two Vale ...
|
||||
// XZigZagPoint tmpPoints[];
|
||||
// Copy(
|
||||
// points,
|
||||
// tmpPoints //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Detect Highs ...
|
||||
|
||||
// //
|
||||
// // Highest High ...
|
||||
|
||||
// //
|
||||
// XZigZagPoint iZGPeak1;
|
||||
// XZigZagPoint iZGPeak2;
|
||||
|
||||
// //
|
||||
// // First ...
|
||||
// int idx = GetHighest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_PEAK //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGPeak1 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Second ...
|
||||
// idx = GetHighest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_PEAK //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGPeak2 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Detect Lows ...
|
||||
|
||||
// //
|
||||
// XZigZagPoint iZGVale1;
|
||||
// XZigZagPoint iZGVale2;
|
||||
|
||||
// //
|
||||
// // First ...
|
||||
// idx = GetLowest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_VALE //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGVale1 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Second ...
|
||||
// idx = GetLowest(
|
||||
// tmpPoints,
|
||||
// X_ZIGZAG_POINT_TYPE_VALE //
|
||||
// );
|
||||
// result = IsValidIndex(idx);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
// iZGVale2 = tmpPoints[idx];
|
||||
// ArrayRemove(
|
||||
// tmpPoints,
|
||||
// idx,
|
||||
// 1 //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Check Directions ...
|
||||
// bool isBullish =
|
||||
// //
|
||||
// (iZGPeak1.time > iZGPeak2.time &&
|
||||
// iZGVale1.time < iZGVale2.time)
|
||||
// //
|
||||
// ;
|
||||
// bool isBearish =
|
||||
// //
|
||||
// (iZGPeak1.time < iZGPeak2.time &&
|
||||
// iZGVale1.time > iZGVale2.time)
|
||||
// //
|
||||
// ;
|
||||
// result =
|
||||
// (isBullish && !isBearish) ||
|
||||
// (isBearish && !isBullish);
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Setting Direction ...
|
||||
// dir =
|
||||
// isBullish
|
||||
// ? X_DIRECTION_BULLISH
|
||||
// : isBearish
|
||||
// ? X_DIRECTION_BEARISH
|
||||
// : X_DIRECTION_NONE;
|
||||
|
||||
// //
|
||||
// // Setting Points ...
|
||||
// Copy(
|
||||
// points,
|
||||
// pivots //
|
||||
// );
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
// iZGPeak1.Clean();
|
||||
// iZGPeak2.Clean();
|
||||
// iZGVale1.Clean();
|
||||
// iZGVale2.Clean();
|
||||
// SpecifiedClean(tmpPoints);
|
||||
|
||||
/**
|
||||
* Analyse Market Structure ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param _pivots: XZigZagPivot, Specified ZigZag Points Collection ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Analyse(
|
||||
XOHCL &bar,
|
||||
XZigZagPivot &_pivots[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid() &&
|
||||
HasChild(_pivots) &&
|
||||
bar.symbol == _pivots[0].symbol;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// AssignSymbol and Period ...
|
||||
time = bar.time;
|
||||
symbol = bar.symbol;
|
||||
period = bar.period;
|
||||
Copy(_pivots, pivots);
|
||||
|
||||
//
|
||||
// Calculate Peaks and Vales Regressions ...
|
||||
|
||||
//
|
||||
// Peaks Processing ...
|
||||
double mPeak = 0;
|
||||
double bPeak = 0;
|
||||
result = ValidateZigZagPivots(
|
||||
mPeak,
|
||||
bPeak,
|
||||
_pivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_PEAK //
|
||||
);
|
||||
|
||||
//
|
||||
// Vales Processing ...
|
||||
double mVale = 0;
|
||||
double bVale = 0;
|
||||
result =
|
||||
result &&
|
||||
ValidateZigZagPivots(
|
||||
mVale,
|
||||
bVale,
|
||||
_pivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_VALE //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
// SpecifiedClean(recentPeaks);
|
||||
// SpecifiedClean(recentVales);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
// //
|
||||
// // Extracting Pivots ...
|
||||
// int numberOfPivots = 2;
|
||||
|
||||
// //
|
||||
// // Reading Recent Peaks ...
|
||||
// XZigZagPivot recentPeaks[];
|
||||
// int recentPeaksCount = GetRecent(
|
||||
// _pivots,
|
||||
// recentPeaks,
|
||||
// numberOfPivots,
|
||||
// X_ZIGZAG_PIVOT_TYPE_PEAK //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Reading Recent Vales ...
|
||||
// XZigZagPivot recentVales[];
|
||||
// int recentValesCount = GetRecent(
|
||||
// _pivots,
|
||||
// recentVales,
|
||||
// numberOfPivots,
|
||||
// X_ZIGZAG_PIVOT_TYPE_VALE //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Validate Pivots ...
|
||||
// result =
|
||||
// recentPeaksCount >= numberOfPivots &&
|
||||
// recentValesCount >= numberOfPivots;
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// SpecifiedClean(recentPeaks);
|
||||
// SpecifiedClean(recentVales);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Detect Direction ...
|
||||
|
||||
// //
|
||||
// int zIdx = 0;
|
||||
// int pIdx = numberOfPivots - 1;
|
||||
|
||||
// //
|
||||
// bool isBullish =
|
||||
// recentPeaks[zIdx].value > recentPeaks[pIdx].value &&
|
||||
// recentVales[zIdx].value > recentVales[pIdx].value;
|
||||
|
||||
// //
|
||||
// bool isBearish =
|
||||
// recentPeaks[zIdx].value < recentPeaks[pIdx].value &&
|
||||
// recentVales[zIdx].value < recentVales[pIdx].value;
|
||||
|
||||
// //
|
||||
// result = isBullish || isBearish;
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// Clean();
|
||||
// SpecifiedClean(recentPeaks);
|
||||
// SpecifiedClean(recentVales);
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// //
|
||||
// dir =
|
||||
// isBullish
|
||||
// ? X_DIRECTION_BULLISH
|
||||
// : X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
// Calculate Support and Resistance ...
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = IsValid();
|
||||
if (!result)
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// SpecifiedClean(recentPeaks);
|
||||
// SpecifiedClean(recentVales);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ValidateZigZagPivots(
|
||||
double &_pivot,
|
||||
double &_processed,
|
||||
XZigZagPivot &_pivots[],
|
||||
ENUM_X_ZIGZAG_POINT_TYPE _type //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
_pivot = 0;
|
||||
_processed = 0;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = HasChild(_pivots);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Required Variables for Calculations ...
|
||||
double sumT = 0;
|
||||
double sumP = 0;
|
||||
double sumTP = 0;
|
||||
double sumT2 = 0;
|
||||
bool has = false;
|
||||
int typeCount = 0;
|
||||
|
||||
//
|
||||
// Loop Through Pivots to Calculate Specified
|
||||
// Type Pivots Summaries ...
|
||||
int count = ArraySize(_pivots);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
// Check Type Passed ...
|
||||
has =
|
||||
!IsXValid(_type)
|
||||
? true
|
||||
: _type == _pivots[i].type;
|
||||
if (!has)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
typeCount++;
|
||||
double iP = _pivots[i].value;
|
||||
double iT = (double)_pivots[i].time;
|
||||
|
||||
//
|
||||
sumT += iT;
|
||||
sumP += iP;
|
||||
sumTP += iT * iP;
|
||||
sumT2 += iT * iP;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Process Values ...
|
||||
double denominator = typeCount * sumT2 - sumT * sumT;
|
||||
if (denominator != 0)
|
||||
{
|
||||
//
|
||||
_pivot = (typeCount * sumTP - sumT * sumP) / denominator;
|
||||
_processed = (sumP - _pivot * sumT) / typeCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
_processed = sumP / typeCount;
|
||||
}
|
||||
|
||||
//
|
||||
// Validating Result ...
|
||||
result = _pivot > 0 &&
|
||||
_processed > 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyse Market Structure ...
|
||||
*
|
||||
* @param bar: XOHCL, Specified Bar ...
|
||||
* @param _pivots: XZigZagPivot, Specified ZigZag Points Collection ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Analyse(
|
||||
XOHCL &bar,
|
||||
XZigZagPivot &_pivots[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid() &&
|
||||
HasChild(_pivots) &&
|
||||
bar.symbol == _pivots[0].symbol;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Assign Requirements ...
|
||||
|
||||
//
|
||||
time = bar.time;
|
||||
symbol = bar.symbol;
|
||||
period = bar.period;
|
||||
Copy(_pivots, pivots);
|
||||
|
||||
//
|
||||
int oldestPeakIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK);
|
||||
int oldestValeIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE);
|
||||
int youngestPeakIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK);
|
||||
int youngestValeIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE);
|
||||
|
||||
//
|
||||
// Calculate Peaks and Vales Regressions ...
|
||||
|
||||
//
|
||||
// Peaks Processing ...
|
||||
double mPeak = 0;
|
||||
double bPeak = 0;
|
||||
bool hasPeak = ValidateZigZagPivots(
|
||||
mPeak,
|
||||
bPeak,
|
||||
pivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_PEAK //
|
||||
);
|
||||
|
||||
//
|
||||
// Vales Processing ...
|
||||
double mVale = 0;
|
||||
double bVale = 0;
|
||||
bool hasVale = ValidateZigZagPivots(
|
||||
mVale,
|
||||
bVale,
|
||||
pivots,
|
||||
X_ZIGZAG_PIVOT_TYPE_VALE //
|
||||
);
|
||||
|
||||
//
|
||||
// Validate Calculated requirements ...
|
||||
result =
|
||||
(hasPeak || hasVale) &&
|
||||
(IsValidIndex(oldestPeakIdx) &&
|
||||
IsValidIndex(oldestValeIdx) &&
|
||||
IsValidIndex(youngestPeakIdx) &&
|
||||
IsValidIndex(youngestValeIdx));
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating Values ...
|
||||
|
||||
//
|
||||
peakToTime = pivots[youngestPeakIdx].time;
|
||||
peakFromTime = pivots[oldestPeakIdx].time;
|
||||
|
||||
//
|
||||
valeToTime = pivots[youngestValeIdx].time;
|
||||
valeFromTime = pivots[oldestValeIdx].time;
|
||||
|
||||
//
|
||||
// Check Different Senarios ...
|
||||
// 1-Valid Peak and Valid Vale Exists ...
|
||||
if (hasPeak && hasVale)
|
||||
{
|
||||
//
|
||||
// When Slopes Have same Sign, Use Average Slope for Parallel Lines ...
|
||||
if (mPeak * mVale > 0)
|
||||
{
|
||||
//
|
||||
// Calculating Parallel Slopes ...
|
||||
double slopeParallel = (mPeak + mVale) / 2;
|
||||
double bParallelPeak = pivots[youngestPeakIdx].value - slopeParallel * (double)peakToTime;
|
||||
double bParallelVale = pivots[youngestValeIdx].value - slopeParallel * (double)valeToTime;
|
||||
|
||||
//
|
||||
// Peak ...
|
||||
peakTo = slopeParallel * (double)peakToTime + bParallelPeak;
|
||||
peakFrom = slopeParallel * (double)peakFromTime + bParallelPeak;
|
||||
|
||||
//
|
||||
// Vale ...
|
||||
valeTo = slopeParallel * (double)valeToTime + bParallelVale;
|
||||
valeFrom = slopeParallel * (double)valeFromTime + bParallelVale;
|
||||
}
|
||||
else
|
||||
//
|
||||
// separate trendlines if slopes differ ...
|
||||
{
|
||||
//
|
||||
// Peak ...
|
||||
peakTo = mPeak * (double)peakToTime + bPeak;
|
||||
peakFrom = mPeak * (double)peakFromTime + bPeak;
|
||||
|
||||
//
|
||||
// Vale ...
|
||||
valeTo = mVale * (double)valeToTime + bVale;
|
||||
valeFrom = mVale * (double)valeFromTime + bVale;
|
||||
}
|
||||
}
|
||||
else
|
||||
//
|
||||
// Only one of them Exists ...
|
||||
{
|
||||
//
|
||||
// Valid Peak ...
|
||||
if (hasPeak)
|
||||
{
|
||||
//
|
||||
// Peak ...
|
||||
peakTo = mPeak * (double)peakToTime + bPeak;
|
||||
peakFrom = mPeak * (double)peakFromTime + bPeak;
|
||||
}
|
||||
|
||||
//
|
||||
// Valid Vale ...
|
||||
if (hasVale)
|
||||
{
|
||||
//
|
||||
// Vale ...
|
||||
valeTo = mVale * (double)valeToTime + bVale;
|
||||
valeFrom = mVale * (double)valeFromTime + bVale;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Detecting Direction ...
|
||||
|
||||
//
|
||||
bool isBullish =
|
||||
valeTo > valeFrom ||
|
||||
(valeTo > valeFrom &&
|
||||
peakTo > peakFrom);
|
||||
|
||||
//
|
||||
bool isBearish =
|
||||
peakTo < peakFrom ||
|
||||
(peakTo < peakFrom &&
|
||||
valeTo < valeFrom);
|
||||
|
||||
//
|
||||
// Validate When Only One Direction Exists ...
|
||||
result =
|
||||
(isBullish && !isBearish) ||
|
||||
(isBearish && !isBullish);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
dir =
|
||||
isBullish
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
// Calculate Support and Resistance ...
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = IsValid();
|
||||
if (!result)
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -1,511 +0,0 @@
|
||||
//
|
||||
// Testing Bar Zones ...
|
||||
// XBoxZone barZones[];
|
||||
// int barCounts = fima2Signaller.fimaHelper.ExtractBarZones(
|
||||
// barZones,
|
||||
// 1, // Bar Index ...
|
||||
// 50, // Number of Zones ...
|
||||
// 3, // Break Validation Length ...
|
||||
// true, // Validate Fake Breakes ...
|
||||
// 5, // Shadow Multiplier ...
|
||||
// 1, // Strength ...
|
||||
// 14 // Validation Length ...
|
||||
// );
|
||||
// if (IsValidSize(barCounts))
|
||||
// {
|
||||
// //
|
||||
// // XCBoxObject *iObj;
|
||||
// // for (int i = 0; i < barCounts; i++)
|
||||
// // {
|
||||
// // //
|
||||
// // iObj = NULL;
|
||||
// // bool isCreated = fima2Signaller.poiDrawer.DrawBox(
|
||||
// // barZones[i],
|
||||
// // iObj,
|
||||
// // true, // Ignore At ...
|
||||
// // barZones[i].type // Name ...
|
||||
// // );
|
||||
|
||||
// // //
|
||||
// // ZeroMemory(iObj);
|
||||
// // }
|
||||
|
||||
// // //
|
||||
// // Print("Bar Zones Detected ...");
|
||||
// }
|
||||
|
||||
//
|
||||
// Testing HK Zones ...
|
||||
// XBoxZone hkZones[];
|
||||
// int hkCounts = fima2Signaller.fimaHelper.ExtractHKZones(
|
||||
// hkZones,
|
||||
// 1, // Bar Index ...
|
||||
// 50, // Number of Zones ...
|
||||
// 5, // Shadow Multiplier ...
|
||||
// 1, // Strength ...
|
||||
// 14 // Validation Length ...
|
||||
// );
|
||||
// if (IsValidSize(hkCounts))
|
||||
// {
|
||||
// // //
|
||||
// // XCBoxObject *iObj;
|
||||
// // for (int i = 0; i < hkCounts; i++)
|
||||
// // {
|
||||
// // //
|
||||
// // iObj = NULL;
|
||||
// // bool isCreated = fima2Signaller.poiDrawer.DrawBox(
|
||||
// // hkZones[i],
|
||||
// // iObj,
|
||||
// // true, // Ignore At ...
|
||||
// // hkZones[i].type // Name ...
|
||||
// // );
|
||||
|
||||
// // //
|
||||
// // ZeroMemory(iObj);
|
||||
// // }
|
||||
|
||||
// // //
|
||||
// // Print("HK Zones Detected ...");
|
||||
// }
|
||||
|
||||
//
|
||||
// Testing XFIMA MA Pivots ...
|
||||
// XPivot maPivots[];
|
||||
// int maPivotsCount = fimaHelper.ExtractMAPivots(
|
||||
// maPivots,
|
||||
// 1, // Bar Index ...
|
||||
// 50, // Number of Pivots ...
|
||||
// 1 // Validation Diff ...
|
||||
// );
|
||||
// if (IsValidSize(maPivotsCount))
|
||||
// {
|
||||
// //
|
||||
// // CArrayObj *iPivotsObj;
|
||||
// // maPivotsCount = poiDrawer.DrawPivots(
|
||||
// // maPivots,
|
||||
// // iPivotsObj //
|
||||
// // );
|
||||
|
||||
// //
|
||||
// // Print("MA Pivots Detected ...");
|
||||
// }
|
||||
|
||||
//
|
||||
// Custom Indicator Direction Shifts ...
|
||||
bool hasMACross = HasDirection(structure.maCrossDir);
|
||||
bool hasHKSwitch = HasDirection(structure.hkSwitchDir);
|
||||
bool hasSARSwitch = HasDirection(structure.sarSwitchDir);
|
||||
|
||||
//
|
||||
// Check Required Pattern Exists ...
|
||||
bool hasPinnedBar = HasDirection(structure.pinnedDir);
|
||||
bool hasEngulfedBar = HasDirection(structure.engulfedDir);
|
||||
bool hasFlagPattern = HasDirection(structure.flagPatternDir);
|
||||
bool hasStarPattern = HasDirection(structure.starPatternDir);
|
||||
bool hasRisingPattern = HasDirection(structure.risingPatternDir);
|
||||
bool hasPiercingPattern = HasDirection(structure.piercingPatternDir);
|
||||
bool hasSignalKeyBar = HasDirection(structure.signalKeyBarPatternDir);
|
||||
|
||||
//
|
||||
// Check Bar Pattern Exists ...
|
||||
// and Select Pattern Direction and Price and Price Type ...
|
||||
has = hasPinnedBar ||
|
||||
hasEngulfedBar ||
|
||||
hasFlagPattern ||
|
||||
hasStarPattern ||
|
||||
hasSignalKeyBar ||
|
||||
hasRisingPattern ||
|
||||
hasPiercingPattern;
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
if (hasPinnedBar)
|
||||
{
|
||||
//
|
||||
iDir = structure.pinnedDir;
|
||||
iName = "XPinned_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
||||
}
|
||||
else if (hasEngulfedBar)
|
||||
{
|
||||
//
|
||||
iDir = structure.engulfedDir;
|
||||
iName = "XEngulfed_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
||||
}
|
||||
else if (hasFlagPattern)
|
||||
{
|
||||
//
|
||||
iDir = structure.flagPatternDir;
|
||||
iName = "XFlag_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
||||
}
|
||||
else if (hasStarPattern)
|
||||
{
|
||||
//
|
||||
iDir = structure.starPatternDir;
|
||||
iName = "XStar_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
||||
}
|
||||
else if (hasSignalKeyBar)
|
||||
{
|
||||
//
|
||||
iDir = structure.risingPatternDir;
|
||||
iName = "XRising_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
||||
}
|
||||
else if (hasRisingPattern)
|
||||
{
|
||||
//
|
||||
iDir = structure.piercingPatternDir;
|
||||
iName = "XPiercing_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
||||
}
|
||||
else if (hasPiercingPattern)
|
||||
{
|
||||
//
|
||||
iDir = structure.signalKeyBarPatternDir;
|
||||
iName = "XSignalKey_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
||||
}
|
||||
|
||||
//
|
||||
isBullish = IsSpecifiedBullish(iDir);
|
||||
isBearish = IsSpecifiedBearish(iDir);
|
||||
|
||||
//
|
||||
// Retrieve Price Type for Validate ...
|
||||
iPriceType = isBullish
|
||||
? X_PRICE_DOWN
|
||||
: X_PRICE_UP;
|
||||
iPriceEdgeType = isBullish
|
||||
? X_PRICE_LOW
|
||||
: X_PRICE_HIGH;
|
||||
|
||||
//
|
||||
iPrice = bar.GetPrice(iPriceType);
|
||||
iPriceEdge = bar.GetPrice(iPriceEdgeType);
|
||||
|
||||
//
|
||||
// Validate Calculations ...
|
||||
has = HasDirection(iDir) &&
|
||||
(isBullish ||
|
||||
isBearish) &&
|
||||
NotEmptyZero(iPrice) &&
|
||||
NotEmptyZero(iPriceEdge) &&
|
||||
iPrice != iPriceEdge;
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
isBullish = false;
|
||||
isBearish = false;
|
||||
iDir = X_DIRECTION_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Disable Signallers ...
|
||||
|
||||
has = false;
|
||||
// Strategy 1 ...
|
||||
// Works on Support or Resistances Areas ...
|
||||
// has = Strategy1HasSignal(
|
||||
// bar,
|
||||
// iZone,
|
||||
// iName,
|
||||
// supports,
|
||||
// resistances,
|
||||
// iDir,
|
||||
// structure,
|
||||
// fimaConditions //
|
||||
// );
|
||||
|
||||
//
|
||||
// Do all Draws Here ...
|
||||
bool canDraw = false;
|
||||
if (canDraw && has)
|
||||
{
|
||||
//
|
||||
int iWidth = 2;
|
||||
XPOIStyle iStyle;
|
||||
XCBoxObject *iBoxObj = NULL;
|
||||
color iClr = isBullish
|
||||
? clrYellow
|
||||
: clrDarkOrange;
|
||||
|
||||
//
|
||||
// Supports ...
|
||||
has = HasChild(supports);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
count = ArraySize(supports);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
has = poiDrawer.DrawBox(
|
||||
supports[i],
|
||||
iBoxObj,
|
||||
true, // Ignore At ...
|
||||
supports[i].type // Name ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
poiDrawer.GetBoxStyle(
|
||||
iStyle,
|
||||
supports[i].dir //
|
||||
);
|
||||
|
||||
//
|
||||
poiDrawer.ApplyBoxStyle(
|
||||
iBoxObj,
|
||||
iStyle //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
iStyle.Clean();
|
||||
ZeroMemory(iBoxObj);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Resistances ...
|
||||
has = HasChild(resistances);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
count = ArraySize(resistances);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
has = poiDrawer.DrawBox(
|
||||
resistances[i],
|
||||
iBoxObj,
|
||||
true, // Ignore At ...
|
||||
resistances[i].type // Name ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
poiDrawer.GetBoxStyle(
|
||||
iStyle,
|
||||
resistances[i].dir //
|
||||
);
|
||||
|
||||
//
|
||||
poiDrawer.ApplyBoxStyle(
|
||||
iBoxObj,
|
||||
iStyle //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
iStyle.Clean();
|
||||
ZeroMemory(iBoxObj);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Selected Zone ...
|
||||
has = iZone.IsValid();
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
has = poiDrawer.DrawBox(
|
||||
iZone,
|
||||
iBoxObj,
|
||||
true, // Ignore At ...
|
||||
iZone.type // Name ...
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
poiDrawer.GetBoxStyle(
|
||||
iStyle,
|
||||
iZone.dir //
|
||||
);
|
||||
|
||||
//
|
||||
iStyle.clr = iClr;
|
||||
iStyle.width = iWidth;
|
||||
|
||||
//
|
||||
poiDrawer.ApplyBoxStyle(
|
||||
iBoxObj,
|
||||
iStyle //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TrendLines ...
|
||||
|
||||
//
|
||||
// Pivots ...
|
||||
|
||||
//
|
||||
has = HasChild(pvPivots);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
CArrayObj *drawnPivots = new CArrayObj();
|
||||
count = poiDrawer.DrawPivots(
|
||||
pvPivots,
|
||||
drawnPivots //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
has = HasChild(zgPivots);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
CArrayObj *drawnPivots = new CArrayObj();
|
||||
count = poiDrawer.DrawPivots(
|
||||
zgPivots,
|
||||
drawnPivots //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Patterns Bar ...
|
||||
has = HasDirection(iDir);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
int iCode = 159;
|
||||
ENUM_ARROW_ANCHOR iAnchor = isBullish
|
||||
? ANCHOR_TOP
|
||||
: ANCHOR_BOTTOM;
|
||||
|
||||
//
|
||||
XCBarArrowObject *iPatternObj;
|
||||
has = poiDrawer.DrawBarArrow(
|
||||
bar,
|
||||
iPatternObj,
|
||||
iPriceEdgeType,
|
||||
iCode,
|
||||
iClr,
|
||||
iWidth,
|
||||
iAnchor,
|
||||
iName,
|
||||
true, // Ignore Bar Tag ...
|
||||
10 // Threshold ...
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Check Pattern Has Signal Based on Strategy 2 ...
|
||||
*
|
||||
* @param bar: XOHCL, reference to Pattern Bar ...
|
||||
* @param iZone: XBoxZone, reference to holds affected zone ...
|
||||
* @param patternName: string, detected pattern's name ...
|
||||
* @param supports: XBoxZone, array reference to Provide Exists Supports ...
|
||||
* @param resistances: XBoxZone, array reference to Provide Exists Resistances ...
|
||||
* @param patternDir: ENUM_X_DIRECTION, detected pattern's direction ...
|
||||
* @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
|
||||
* @param fimaMarketStructure: XFIMAMarketStructure, refrence to Provides Market Structure ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Strategy2HasSignal(
|
||||
XOHCL &bar,
|
||||
XBoxZone &iZone,
|
||||
string patternName,
|
||||
XBoxZone &supports[],
|
||||
XBoxZone &resistances[],
|
||||
ENUM_X_DIRECTION patternDir,
|
||||
XFIMAMarketStructure &structure,
|
||||
XFIMAConditions &fimaConditions,
|
||||
XFIMAMarketStructure &fimaMarketStructure //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
iZone.Clean();
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
|
||||
//
|
||||
// Do Detection ...
|
||||
|
||||
//
|
||||
// Validate result ...
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Pattern Has Signal Based on Strategy 1 ...
|
||||
*
|
||||
* @param bar: XOHCL, reference to Pattern Bar ...
|
||||
* @param iZone: XBoxZone, reference to holds affected zone ...
|
||||
* @param supports: XBoxZone, array reference to Provide Exists Supports ...
|
||||
* @param resistances: XBoxZone, array reference to Provide Exists Resistances ...
|
||||
* @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ...
|
||||
* @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Strategy3HasSignal(
|
||||
XOHCL &bar,
|
||||
XBoxZone &iZone,
|
||||
XBoxZone &supports[],
|
||||
XBoxZone &resistances[],
|
||||
XFIMAMarketStructure &structure,
|
||||
XFIMAConditions &fimaConditions //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
iZone.Clean();
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading XHK ...
|
||||
|
||||
//
|
||||
// Bar 1 ...
|
||||
double cHKO = fimaConditions.hkOpenBuffer[0];
|
||||
double cHKH = fimaConditions.hkHighBuffer[0];
|
||||
double cHKL = fimaConditions.hkLowBuffer[0];
|
||||
double cHKC = fimaConditions.hkCloseBuffer[0];
|
||||
|
||||
//
|
||||
// Bar 2 ...
|
||||
double pHKO = fimaConditions.hkOpenBuffer[1];
|
||||
double pHKH = fimaConditions.hkHighBuffer[1];
|
||||
double pHKL = fimaConditions.hkLowBuffer[1];
|
||||
double pHKC = fimaConditions.hkCloseBuffer[1];
|
||||
|
||||
//
|
||||
bool isCHKBullish = cHKO < cHKC;
|
||||
bool isCHKBearish = cHKO > cHKC;
|
||||
|
||||
//
|
||||
bool isPHKBullish = pHKO < pHKC;
|
||||
bool isPHKBearish = pHKO > pHKC;
|
||||
|
||||
//
|
||||
bool isCHKSwitchedToBullish = isCHKBullish && !isPHKBullish;
|
||||
bool isCHKSwitchedToBearish = isCHKBearish && !isPHKBearish;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -1,916 +0,0 @@
|
||||
|
||||
/**
|
||||
* Leg Pattern Detection ...
|
||||
*
|
||||
* @param bar: XOHCL, reference to Specified Bar ...
|
||||
* @param zone: XBoxZone, reference to Holds Detection Zone ...
|
||||
* @param validationLength: int, leg minimum Validation Length ...
|
||||
* @param loopback: int, Max Allowed Loopback Length ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsLegPattern(
|
||||
XOHCL &bar,
|
||||
XLeg &leg,
|
||||
int validationLength = 3,
|
||||
int loopback = 10 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
leg.Clean();
|
||||
|
||||
//
|
||||
// Normalize ...
|
||||
loopback = NormalizeInt(loopback, 5);
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Patterns Analysis Config ...
|
||||
XPatternAnalysisConfig iPatternsConfig;
|
||||
iPatternsConfig.Default();
|
||||
iPatternsConfig.CleanPatterns();
|
||||
iPatternsConfig.AddPattern(X_BAR_PATTERN_LOW);
|
||||
iPatternsConfig.AddPattern(X_BAR_PATTERN_HIGH);
|
||||
iPatternsConfig.AddPattern(X_BAR_PATTERN_FLAG);
|
||||
iPatternsConfig.AddPattern(X_BAR_PATTERN_STAR);
|
||||
iPatternsConfig.AddPattern(X_BAR_PATTERN_RISING);
|
||||
iPatternsConfig.AddPattern(X_BAR_PATTERN_PIERCING);
|
||||
iPatternsConfig.AddPattern(X_BAR_PATTERN_ENGULFED);
|
||||
iPatternsConfig.AddPattern(X_BAR_PATTERN_MOMENTUM);
|
||||
iPatternsConfig.AddPattern(X_BAR_PATTERN_SIGNALKEY);
|
||||
iPatternsConfig.AddPattern(X_BAR_PATTERN_TRUE_GAPED);
|
||||
|
||||
//
|
||||
XOHCL iBar;
|
||||
XOHCL pBar;
|
||||
XOHCL iZBar;
|
||||
XBoxZone zone;
|
||||
XBoxZone iZone;
|
||||
XBoxZone jZone;
|
||||
bool has = false;
|
||||
XBoxZone supports[];
|
||||
XOHCL bullishBars[];
|
||||
XOHCL bearishBars[];
|
||||
XBoxZone bullishFVGs[];
|
||||
XBoxZone bearishFVGs[];
|
||||
bool isBullish = false;
|
||||
bool isBearish = false;
|
||||
XBoxZone resistances[];
|
||||
double bullishPower = 0;
|
||||
double bearishPower = 0;
|
||||
int bullishBarsCount = 0;
|
||||
int bearishBarsCount = 0;
|
||||
int barIndex = bar.Index();
|
||||
int start = barIndex + 1;
|
||||
XPatternAnalysis iPattern;
|
||||
int end = start + loopback;
|
||||
XPatternAnalysis patterns[];
|
||||
int bullishPatternsCount = 0;
|
||||
int bearishPatternsCount = 0;
|
||||
int sequentialsBullishBarsCount = 0;
|
||||
int sequentialsBearishBarsCount = 0;
|
||||
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
for (int i = end; i >= start; i--)
|
||||
{
|
||||
//
|
||||
// Initialize Indexed Bar ...
|
||||
iBar.Clean();
|
||||
pBar.Clean();
|
||||
result = bar.BarAt(i, iBar);
|
||||
result = result &&
|
||||
iBar.GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Fill Bar Direction ...
|
||||
isBullish = iBar.IsBullish();
|
||||
isBearish = iBar.IsBearish();
|
||||
|
||||
//
|
||||
// Directional ...
|
||||
|
||||
//
|
||||
if (isBullish)
|
||||
{
|
||||
//
|
||||
bullishBarsCount++;
|
||||
|
||||
//
|
||||
bullishPower += iBar.GetBody();
|
||||
bullishPower += iBar.GetLowShadow();
|
||||
bullishPower -= iBar.GetHighShadow();
|
||||
|
||||
//
|
||||
AddIfNotExists(iBar, bullishBars);
|
||||
}
|
||||
|
||||
//
|
||||
if (isBearish)
|
||||
{
|
||||
//
|
||||
bearishBarsCount++;
|
||||
|
||||
//
|
||||
bearishPower += iBar.GetBody();
|
||||
bearishPower -= iBar.GetLowShadow();
|
||||
bearishPower += iBar.GetHighShadow();
|
||||
|
||||
//
|
||||
AddIfNotExists(iBar, bearishBars);
|
||||
}
|
||||
|
||||
//
|
||||
// Sequentail ....
|
||||
|
||||
//
|
||||
// Bullish ...
|
||||
if (isBullish)
|
||||
{
|
||||
//
|
||||
if (pBar.IsBullish())
|
||||
{
|
||||
sequentialsBullishBarsCount++;
|
||||
}
|
||||
else if (pBar.IsBearish())
|
||||
{
|
||||
sequentialsBullishBarsCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Bearish ...
|
||||
if (isBearish)
|
||||
{
|
||||
//
|
||||
if (pBar.IsBearish())
|
||||
{
|
||||
sequentialsBearishBarsCount++;
|
||||
}
|
||||
else if (pBar.IsBullish())
|
||||
{
|
||||
sequentialsBearishBarsCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Patterns ...
|
||||
iPattern.Clean();
|
||||
has = AnalyseBarPatterns(iBar, iPattern, iPatternsConfig);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
AddRef(iPattern, patterns);
|
||||
|
||||
//
|
||||
bullishPatternsCount += iPattern.Count(X_DIRECTION_BULLISH);
|
||||
bearishPatternsCount += iPattern.Count(X_DIRECTION_BEARISH);
|
||||
}
|
||||
|
||||
//
|
||||
// FVG Detection ...
|
||||
CleanDirection(iDir);
|
||||
has = HasFVG(iBar, iDir, iZone);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
if (iZone.IsBullish())
|
||||
{
|
||||
AddIfNotExists(iZone, bullishFVGs);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddIfNotExists(iZone, bearishFVGs);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Support / Resistance Detection ...
|
||||
has = HasSupportResistance(
|
||||
iBar,
|
||||
iZone,
|
||||
jZone,
|
||||
5 //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
if (iZone.IsValid())
|
||||
{
|
||||
AddIfNotExists(iZone, supports);
|
||||
}
|
||||
|
||||
//
|
||||
if (jZone.IsValid())
|
||||
{
|
||||
AddIfNotExists(jZone, resistances);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Summarizing ...
|
||||
|
||||
//
|
||||
// Detect Direction ...
|
||||
zone.Clean();
|
||||
isBullish = false;
|
||||
isBearish = false;
|
||||
CleanDirection(iDir);
|
||||
|
||||
//
|
||||
isBullish =
|
||||
//
|
||||
bullishPower > 0 &&
|
||||
bullishBarsCount > 0 &&
|
||||
bullishPatternsCount > 0 &&
|
||||
sequentialsBullishBarsCount > 0 &&
|
||||
//
|
||||
bullishPower > bearishPower &&
|
||||
bullishBarsCount > bearishBarsCount &&
|
||||
bullishPatternsCount > bearishPatternsCount &&
|
||||
sequentialsBullishBarsCount > sequentialsBearishBarsCount
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
isBearish =
|
||||
//
|
||||
bearishPower > 0 &&
|
||||
bearishBarsCount > 0 &&
|
||||
bearishPatternsCount > 0 &&
|
||||
sequentialsBearishBarsCount > 0 &&
|
||||
//
|
||||
bearishPower > bullishPower &&
|
||||
bearishBarsCount > bullishBarsCount &&
|
||||
bearishPatternsCount > bullishPatternsCount &&
|
||||
sequentialsBearishBarsCount > sequentialsBullishBarsCount
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result =
|
||||
(isBullish && !isBearish) ||
|
||||
(isBearish && !isBullish);
|
||||
|
||||
//
|
||||
// PRICE Types ...
|
||||
ENUM_X_PRICE lowerPriceType = X_PRICE_LOW;
|
||||
ENUM_X_PRICE upperPriceType = X_PRICE_HIGH;
|
||||
|
||||
//
|
||||
// Prepare Zone ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
zone.at = bar.time;
|
||||
zone.to = bar.time;
|
||||
zone.period = bar.period;
|
||||
zone.symbol = bar.symbol;
|
||||
|
||||
//
|
||||
zone.type = ToXString(X_BAR_PATTERN_LEG);
|
||||
zone.dir = isBullish
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
int idx = -1;
|
||||
if (isBullish)
|
||||
{
|
||||
idx = GetOldest(bullishBars);
|
||||
}
|
||||
else
|
||||
{
|
||||
idx = GetOldest(bearishBars);
|
||||
}
|
||||
|
||||
//
|
||||
result = IsValidIndex(idx);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
iZBar.Clean();
|
||||
if (isBullish)
|
||||
{
|
||||
iZBar = bullishBars[idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
iZBar = bearishBars[idx];
|
||||
}
|
||||
|
||||
//
|
||||
zone.from = iZBar.time;
|
||||
|
||||
//
|
||||
iZBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
if (isBullish)
|
||||
{
|
||||
//
|
||||
// Prepare Upper and Lower ...
|
||||
|
||||
//
|
||||
// Upper ...
|
||||
idx = GetHighestBarPrice(bullishBars, upperPriceType);
|
||||
if (IsValidIndex(idx))
|
||||
{
|
||||
zone.upper = bullishBars[idx].GetPrice(upperPriceType);
|
||||
}
|
||||
|
||||
//
|
||||
// Lower ...
|
||||
idx = GetLowestBarPrice(bullishBars, upperPriceType);
|
||||
if (IsValidIndex(idx))
|
||||
{
|
||||
zone.lower = bullishBars[idx].GetPrice(lowerPriceType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Prepare Upper and Lower ...
|
||||
|
||||
//
|
||||
// Upper ...
|
||||
idx = GetHighestBarPrice(bearishBars, upperPriceType);
|
||||
if (IsValidIndex(idx))
|
||||
{
|
||||
zone.upper = bearishBars[idx].GetPrice(upperPriceType);
|
||||
}
|
||||
|
||||
//
|
||||
// Lower ...
|
||||
idx = GetLowestBarPrice(bearishBars, upperPriceType);
|
||||
if (IsValidIndex(idx))
|
||||
{
|
||||
zone.lower = bearishBars[idx].GetPrice(lowerPriceType);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = zone.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare XLeg ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
leg.dir = zone.dir;
|
||||
leg.time = zone.from;
|
||||
leg.upper = zone.upper;
|
||||
leg.lower = zone.lower;
|
||||
leg.symbol = zone.symbol;
|
||||
leg.period = zone.period;
|
||||
Copy(patterns, leg.patterns);
|
||||
Copy(supports, leg.supports);
|
||||
Copy(bullishBars, leg.bullishBars);
|
||||
Copy(bearishBars, leg.bearishBars);
|
||||
Copy(resistances, leg.resistances);
|
||||
Copy(bullishFVGs, leg.bullishFVGs);
|
||||
Copy(bearishFVGs, leg.bearishFVGs);
|
||||
leg.sequentialBullishBars = sequentialsBullishBarsCount;
|
||||
leg.sequentialBearishBars = sequentialsBearishBarsCount;
|
||||
|
||||
//
|
||||
result = leg.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
if (!result)
|
||||
{
|
||||
zone.Clean();
|
||||
}
|
||||
iBar.Clean();
|
||||
pBar.Clean();
|
||||
zone.Clean();
|
||||
iZBar.Clean();
|
||||
iZone.Clean();
|
||||
jZone.Clean();
|
||||
iPattern.Clean();
|
||||
XClean(supports);
|
||||
XClean(patterns);
|
||||
XClean(bullishBars);
|
||||
XClean(bearishBars);
|
||||
XClean(bullishFVGs);
|
||||
XClean(bearishFVGs);
|
||||
XClean(resistances);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsLegPattern1(
|
||||
XOHCL &bar,
|
||||
XLeg &leg,
|
||||
int validationLength = 5,
|
||||
int loopback = 500 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
leg.Clean();
|
||||
|
||||
//
|
||||
// Normalize ...
|
||||
loopback = NormalizeInt(loopback, 50);
|
||||
validationLength = NormalizeInt(validationLength, 3);
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = bar.IsValid() &&
|
||||
fimaParser.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int idx = bar.Index();
|
||||
while (idx < bar.Index() + loopback)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Leg ...
|
||||
|
||||
XLeg leg; // Exists Leg ...
|
||||
bool drawLeg; // Draw Leg ...
|
||||
bool manageLegs;
|
||||
|
||||
//
|
||||
bool HasLeg()
|
||||
{
|
||||
return leg.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
bool ValidateLeg(XOHCL &bar)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = HasLeg() &&
|
||||
bar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
leg.IsBullish()
|
||||
? bar.low > leg.lower
|
||||
: leg.IsBearish()
|
||||
? bar.high < leg.upper
|
||||
: false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
void DrawLeg()
|
||||
{
|
||||
//
|
||||
if (!drawLeg)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (!HasLeg())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Update to Times ...
|
||||
leg.UpdateTimes();
|
||||
|
||||
//
|
||||
// Draw Leg Box ...
|
||||
XBoxZone legZone;
|
||||
leg.ToBox(legZone);
|
||||
if (legZone.IsValid())
|
||||
{
|
||||
//
|
||||
legZone.to = TimeCurrent();
|
||||
poiDrawer.DrawZone(legZone, structureDrawConfig.drawConfig);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Legs Other Stufs ...
|
||||
return;
|
||||
|
||||
//
|
||||
// FVGs ...
|
||||
poiDrawer.DrawZones(leg.bullishFVGs, structureDrawConfig.drawConfig);
|
||||
poiDrawer.DrawZones(leg.bearishFVGs, structureDrawConfig.drawConfig);
|
||||
|
||||
//
|
||||
// Support and Resistances ...
|
||||
poiDrawer.DrawZones(leg.supports, structureDrawConfig.drawConfig);
|
||||
poiDrawer.DrawZones(leg.resistances, structureDrawConfig.drawConfig);
|
||||
|
||||
//
|
||||
// Patterns ...
|
||||
poiDrawer.DrawPatternAnalysises(leg.patterns, structureDrawConfig.barAnalysisDrawConfig);
|
||||
}
|
||||
|
||||
//
|
||||
void ManageLeg(XOHCL &bar)
|
||||
{
|
||||
//
|
||||
// Validate Exists ...
|
||||
if (HasLeg())
|
||||
{
|
||||
//
|
||||
if (!ValidateLeg(bar))
|
||||
{
|
||||
//
|
||||
// Invalidate XLeg ...
|
||||
leg.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Detect New ...
|
||||
if (!HasLeg())
|
||||
{
|
||||
poiDetector.IsLegPattern(bar, leg);
|
||||
}
|
||||
|
||||
//
|
||||
// Update Exists ...
|
||||
if (HasLeg())
|
||||
{
|
||||
//
|
||||
// Update to Times ...
|
||||
leg.UpdateTimes();
|
||||
|
||||
//
|
||||
DrawLeg();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
ManageLeg(bar);
|
||||
|
||||
//
|
||||
// Checking For Leg Pattern ...
|
||||
bool hasLeg = poiDetector.IsLegPattern(
|
||||
pBar,
|
||||
_leg,
|
||||
3,
|
||||
10 //
|
||||
);
|
||||
if (hasLeg)
|
||||
{
|
||||
hasLeg = _leg.ToBox(legZone);
|
||||
}
|
||||
bool hasBullishLeg = hasLeg && _leg.IsBullish();
|
||||
bool hasBearishLeg = hasLeg && _leg.IsBearish();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int CollectPivots(
|
||||
XPivot &pivots[],
|
||||
int barIndex = 0,
|
||||
int loopback = 500 //
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
XClean(pivots);
|
||||
|
||||
//
|
||||
// Normalize ...
|
||||
loopback = NormalizeInt(loopback, 50);
|
||||
barIndex = NormalizeBarIndex(barIndex);
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
bool has = IsValid();
|
||||
if (!has)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
has = false;
|
||||
XOHCL tmpBar;
|
||||
XPivot tmpPivot;
|
||||
double tmpValue;
|
||||
datetime tmpTime;
|
||||
bool isBullish = false;
|
||||
bool isBearish = false;
|
||||
string tmpSymbol = symbol;
|
||||
ENUM_TIMEFRAMES tmpPeriod = period;
|
||||
ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE;
|
||||
for (int i = barIndex; i < barIndex + loopback; i++)
|
||||
{
|
||||
//
|
||||
tmpBar.Clean();
|
||||
tmpPivot.Clean();
|
||||
|
||||
//
|
||||
has = tmpBar.Init(tmpSymbol, tmpPeriod, i);
|
||||
if (!has)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// XSAR ...
|
||||
isBullish = IsSARSwitchedToBullish(i);
|
||||
isBearish = IsSARSwitchedToBearish(i);
|
||||
has = isBullish || isBearish;
|
||||
if (has)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// XMA Fast / Slow ...
|
||||
|
||||
//
|
||||
// States ...
|
||||
isBullish = IsMASlowSwitchedToBullish(i);
|
||||
isBearish = IsMASlowSwitchedToBearish(i);
|
||||
has = isBullish || isBearish;
|
||||
if (has)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Crossed Fast Slow ...
|
||||
isBullish = IsMAFastCrossedOverSlow(i);
|
||||
isBearish = IsMAFastCrossedUnderSlow(i);
|
||||
has = isBullish || isBearish;
|
||||
if (has)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Crossed Last ...
|
||||
isBullish = IsMASlowCrossedOverLast(i);
|
||||
isBearish = IsMASlowCrossedUnderLast(i);
|
||||
has = isBullish || isBearish;
|
||||
if (has)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// XHK ...
|
||||
isBullish = IsHKSwitchedToBullish(i);
|
||||
isBearish = IsHKSwitchedToBearish(i);
|
||||
has = isBullish || isBearish;
|
||||
if (has)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = ArraySize(pivots);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* an strucutre to Model Specified Leg Pattern ...
|
||||
**/
|
||||
struct XLeg
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
datetime time;
|
||||
string symbol;
|
||||
ENUM_X_DIRECTION dir;
|
||||
ENUM_TIMEFRAMES period;
|
||||
|
||||
//
|
||||
double upper;
|
||||
double lower;
|
||||
|
||||
//
|
||||
XOHCL bullishBars[];
|
||||
XOHCL bearishBars[];
|
||||
|
||||
//
|
||||
XBoxZone supports[];
|
||||
XBoxZone resistances[];
|
||||
|
||||
//
|
||||
XBoxZone bullishFVGs[];
|
||||
XBoxZone bearishFVGs[];
|
||||
|
||||
//
|
||||
XPatternAnalysis patterns[];
|
||||
|
||||
//
|
||||
int sequentialBullishBars;
|
||||
int sequentialBearishBars;
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* Cleanup ...
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
time = NULL;
|
||||
symbol = NULL;
|
||||
period = NULL;
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
upper = 0;
|
||||
lower = 0;
|
||||
sequentialBullishBars = 0;
|
||||
sequentialBearishBars = 0;
|
||||
|
||||
//
|
||||
XClean(patterns);
|
||||
XClean(supports);
|
||||
XClean(bullishBars);
|
||||
XClean(bearishBars);
|
||||
XClean(resistances);
|
||||
XClean(bullishFVGs);
|
||||
XClean(bearishFVGs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
IsXValid(time) &&
|
||||
IsXValid(symbol) &&
|
||||
IsXValid(period) &&
|
||||
HasDirection(dir) &&
|
||||
NotEmptyZero(upper) &&
|
||||
NotEmptyZero(lower) &&
|
||||
upper > lower;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is Bullish ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsBullish()
|
||||
{
|
||||
return IsValid() &&
|
||||
IsXBullish(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is Bearish ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsBearish()
|
||||
{
|
||||
return IsValid() &&
|
||||
IsXBearish(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Leg to XBoxZone ...
|
||||
*
|
||||
* @param zone: XBoxZone, reference to holds Converted ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool ToBox(XBoxZone &zone)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Prepare ...
|
||||
zone.Clean();
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
result = IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
zone.at = time;
|
||||
zone.dir = dir;
|
||||
zone.from = time;
|
||||
zone.upper = upper;
|
||||
zone.lower = lower;
|
||||
zone.symbol = symbol;
|
||||
zone.period = period;
|
||||
zone.to = TimeCurrent();
|
||||
zone.type = ToXString(X_BAR_PATTERN_LEG);
|
||||
|
||||
//
|
||||
result = zone.IsValid();
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
if (!result)
|
||||
{
|
||||
zone.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Times of Collections ...
|
||||
*
|
||||
* @param value: datetime, Specified Time ...
|
||||
*/
|
||||
void UpdateTimes(datetime value = NULL)
|
||||
{
|
||||
//
|
||||
// Normalize ...
|
||||
value = NormalizeTime(value);
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
if (!IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
UpdateToTime(supports, value);
|
||||
UpdateToTime(resistances, value);
|
||||
UpdateToTime(bullishFVGs, value);
|
||||
UpdateToTime(bearishFVGs, value);
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
Reference in New Issue
Block a user