425 lines
8.2 KiB
Plaintext
425 lines
8.2 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// ----------------------------------------------
|
|
// Name: X92Signaller
|
|
// Description: Signalling using X121 rules ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../Libraries/x-saherelm.xtrade.lib.mq5"
|
|
#include "../Classes/x-saherelm.x121.xmcycle.class.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// Class ...
|
|
class X92Signaller : public XSignallerDescriptor
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
void X92Signaller()
|
|
{
|
|
//
|
|
name = X92;
|
|
Default();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
void ~X92Signaller() {}
|
|
|
|
//
|
|
void SetSymbol(string value)
|
|
{
|
|
this.symbol = value;
|
|
}
|
|
|
|
//
|
|
void SetPeriod(ENUM_TIMEFRAMES value)
|
|
{
|
|
this.period = value;
|
|
}
|
|
|
|
//
|
|
// Override(s) ...
|
|
|
|
//
|
|
bool HasLongConditions(
|
|
X121MCycleConditions &conditions, // Market Conditions
|
|
double &sl, // Hold SL ...
|
|
double &tp // Hold TP ...
|
|
) override
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
sl = 0;
|
|
tp = 0;
|
|
|
|
//
|
|
result = allowLong;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (IsLookingForBoundary())
|
|
{
|
|
//
|
|
FindBoundary(conditions);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double bullishScore = 0;
|
|
double bearishScore = 0;
|
|
conditions.GenerateScore(
|
|
bullishScore,
|
|
bearishScore //
|
|
);
|
|
|
|
//
|
|
bool isRejected =
|
|
//
|
|
(conditions.bars[1].low > lastLower &&
|
|
conditions.bars[2].low > lastLower &&
|
|
conditions.bars[3].low > lastLower &&
|
|
conditions.bars[4].low > lastLower &&
|
|
conditions.bars[5].low > lastLower)
|
|
//
|
|
||
|
|
//
|
|
conditions.bars[1].IsSupportRejected(lastLower)
|
|
//
|
|
;
|
|
bool isBreaked =
|
|
//
|
|
(conditions.bars[1].low > lastUpper &&
|
|
conditions.bars[2].low > lastUpper &&
|
|
conditions.bars[3].low > lastUpper &&
|
|
conditions.bars[4].low > lastUpper &&
|
|
conditions.bars[5].low > lastUpper)
|
|
//
|
|
||
|
|
//
|
|
conditions.bars[1].IsResistanceBreaked(lastUpper)
|
|
//
|
|
;
|
|
|
|
//
|
|
result =
|
|
//
|
|
isBreaked
|
|
//
|
|
||
|
|
//
|
|
isRejected
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isOSCVerified =
|
|
//
|
|
(conditions.oscCcis[0] > 0 &&
|
|
conditions.oscCcis[1] > 0)
|
|
//
|
|
||
|
|
//
|
|
(conditions.oscMacdMains[0] > 0 &&
|
|
conditions.oscMacdMains[1] > 0)
|
|
//
|
|
;
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
result =
|
|
isOSCVerified &&
|
|
bullishScore > bearishScore * 1.5;
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
sl = isBreaked
|
|
? lastUpper
|
|
: lastLower;
|
|
}
|
|
|
|
//
|
|
HandleResetBundary();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasShortConditions(
|
|
X121MCycleConditions &conditions, // Market Conditions
|
|
double &sl, // Hold SL ...
|
|
double &tp // Hold TP ...
|
|
) override
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
sl = 0;
|
|
tp = 0;
|
|
|
|
//
|
|
result = allowLong;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (IsLookingForBoundary())
|
|
{
|
|
//
|
|
FindBoundary(conditions);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double bullishScore = 0;
|
|
double bearishScore = 0;
|
|
conditions.GenerateScore(
|
|
bullishScore,
|
|
bearishScore //
|
|
);
|
|
|
|
//
|
|
bool isRejected =
|
|
//
|
|
(conditions.bars[1].high < lastUpper &&
|
|
conditions.bars[2].high < lastUpper &&
|
|
conditions.bars[3].high < lastUpper &&
|
|
conditions.bars[4].high < lastUpper &&
|
|
conditions.bars[5].high < lastUpper)
|
|
//
|
|
||
|
|
//
|
|
conditions.bars[1].IsResistanceRejected(lastUpper)
|
|
//
|
|
;
|
|
bool isBreaked =
|
|
//
|
|
(conditions.bars[1].high < lastLower &&
|
|
conditions.bars[2].high < lastLower &&
|
|
conditions.bars[3].high < lastLower &&
|
|
conditions.bars[4].high < lastLower &&
|
|
conditions.bars[5].high < lastLower)
|
|
//
|
|
||
|
|
//
|
|
conditions.bars[1].IsSupportBreaked(lastLower)
|
|
//
|
|
;
|
|
|
|
//
|
|
result =
|
|
//
|
|
isBreaked
|
|
//
|
|
||
|
|
//
|
|
isRejected
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isOSCVerified =
|
|
//
|
|
(conditions.oscCcis[0] < 0 &&
|
|
conditions.oscCcis[1] < 0)
|
|
//
|
|
||
|
|
//
|
|
(conditions.oscMacdMains[0] < 0 &&
|
|
conditions.oscMacdMains[1] < 0)
|
|
//
|
|
;
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
result =
|
|
isOSCVerified &&
|
|
bearishScore > bullishScore * 1.5;
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
sl = isBreaked
|
|
? lastLower
|
|
: lastUpper;
|
|
}
|
|
|
|
//
|
|
HandleResetBundary();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
// Props ...
|
|
double lastUpper;
|
|
double lastLower;
|
|
datetime lastTime;
|
|
|
|
//
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
bool IsLookingForBoundary()
|
|
{
|
|
//
|
|
bool result = lastUpper == 0 && lastLower == 0;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void FindBoundary(const X121MCycleConditions &conditions)
|
|
{
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = 1;
|
|
int pIndex = 2;
|
|
int ppIndex = 3;
|
|
|
|
//
|
|
// Detect Inside Bar ...
|
|
if (conditions.bars[cIndex].IsInsideBar())
|
|
{
|
|
//
|
|
lastUpper = conditions.bars[pIndex].high;
|
|
lastLower = conditions.bars[pIndex].low;
|
|
|
|
//
|
|
lastTime = TimeCurrent();
|
|
|
|
//
|
|
DrawPivot(lastUpper, clrOrangeRed);
|
|
DrawPivot(lastLower, clrLimeGreen);
|
|
}
|
|
}
|
|
|
|
//
|
|
void HandleResetBundary()
|
|
{
|
|
//
|
|
if (!IsSpecifiedValid(lastTime))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int age = iBarShift(
|
|
symbol,
|
|
period,
|
|
lastTime,
|
|
false //
|
|
);
|
|
|
|
//
|
|
if (age < 7)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
RemoveDraws("X92_");
|
|
|
|
//
|
|
lastLower = 0;
|
|
lastUpper = 0;
|
|
lastTime = NULL;
|
|
}
|
|
|
|
//
|
|
void DrawPivot(
|
|
double price,
|
|
color clr //
|
|
)
|
|
{
|
|
//
|
|
long chartID = ChartID();
|
|
datetime time1 = iTime(
|
|
symbol,
|
|
period,
|
|
2 //
|
|
);
|
|
datetime time = iTime(
|
|
symbol,
|
|
period,
|
|
0 //
|
|
);
|
|
|
|
//
|
|
string pPrefix = "X92_P_" +
|
|
ToString(price);
|
|
|
|
//
|
|
if (IsDrawExists(pPrefix))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
DrawTrendLine(
|
|
chartID,
|
|
pPrefix,
|
|
0,
|
|
time1,
|
|
price,
|
|
time,
|
|
price,
|
|
clr,
|
|
STYLE_SOLID,
|
|
2,
|
|
false,
|
|
false,
|
|
true //
|
|
);
|
|
}
|
|
|
|
//
|
|
}; |