Initial Commit ...

This commit is contained in:
2024-01-25 04:05:58 +03:30
commit dac3101466
520 changed files with 186332 additions and 0 deletions
@@ -0,0 +1,472 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 CCI Signal Global Library
// ---------------------------------------------------
// saherelm useful tools and definitions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Includes library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// Based Signal Conditions ...
struct XCCILongSignalConditions {
//
datetime start;
//
datetime crossOverMinusHundredTime;
datetime crossUnderMinusHundredTime;
//
double crossOverSlope;
};
//
static XCCILongSignalConditions cciLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill Signal Conditions ...
void CheckCCILongSignalConditions(
const int bar_index,
const int marketLen,
//
const double smoother = 10
) {
//
// Retrieve Bar Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// LONG:
// wait for cci cross under -100
// then wait for cross over -100
// slope of crossing over ??? ...
if (cciLongConds.start == 0) {
// LogMessage("Start");
cciLongConds.start = barTime;
return;
}
//
// Check Start Time ...
if (cciLongConds.start == 0) {
return;
}
//
// Read current, prev, and prevPrev CCI ...
double cci = GetMarketCCI(
bar_index,
marketLen
);
double cci1 = GetMarketCCI(
bar_index + 1,
marketLen
);
double cci2 = GetMarketCCI(
bar_index + 2,
marketLen
);
//
// Find Cross Under -100 ...
bool isCrossUnderMinusHundred =
cci < -105 && !(cci1 < -105)
&& MathAbs(MathAbs(cci) - MathAbs(cci1)) > smoother
;
//
// Find Cross Over -100 ...
bool isCrossOverMinusHundred =
cci > -105 && !(cci1 > -105)
&& MathAbs(cci - cci1) > smoother
;
//
// Fill Conditions ...
if (
isCrossUnderMinusHundred
&& cciLongConds.crossUnderMinusHundredTime == 0
&& cciLongConds.crossOverMinusHundredTime == 0
) {
// LogMessage("Cross Under ...");
cciLongConds.crossUnderMinusHundredTime = barTime;
return;
}
//
// Fill Conditions ...
if (
isCrossOverMinusHundred
&& cciLongConds.crossOverMinusHundredTime == 0
&& cciLongConds.crossUnderMinusHundredTime != 0
) {
//
// LogMessage("Cross Over ...");
cciLongConds.crossOverMinusHundredTime = barTime;
}
//
// Prevent Going forward untill Cross Under Happens ...
if (cciLongConds.crossUnderMinusHundredTime == 0) {
return;
}
//
// Prevent from Going forward untill Cross Over Happens ...
if (cciLongConds.crossOverMinusHundredTime == 0) {
return;
}
//
// Calculate Slope ...
double x1 = 0;
double y1 = cci1;
double x2 = 1;
double y2 = cci;
//
// Calculat Line Slope ...
double tSlope = GetSlope(
x1, y1, x2, y2
);
//
cciLongConds.crossOverSlope = tSlope;
// LogMessage("Slope: " + tSlope);
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateCCILongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateCCILongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
int llIdx = GetLowestLowOFCCILongPeriodIndex();
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
// GetLowestLowOFCCILongPeriod();
//
int hhIdx = GetHighestHighOfCCILongPeriodIndex();
double hh = GetHighestHighOfCCILongPeriod();
// GetMarketHighestHigh(
// bar_index,
// marketLen
// );
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r;
//
double sl = 0; // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_CCI_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_CCI_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateCCILongConditions() {
//
int crossUnderBarIndex =
cciLongConds.crossUnderMinusHundredTime != 0
? iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
)
: -1
;
//
int crossOverBarIndex =
cciLongConds.crossOverMinusHundredTime != 0
? iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
)
: -1
;
//
bool isConditionsFilled =
//
cciLongConds.start != 0
&& cciLongConds.crossUnderMinusHundredTime != 0
&& cciLongConds.crossOverMinusHundredTime != 0
&& cciLongConds.crossUnderMinusHundredTime >= cciLongConds.start
&& cciLongConds.crossOverMinusHundredTime > cciLongConds.crossUnderMinusHundredTime
;
//
bool isLogicPassed =
//
crossOverBarIndex > 0
&& crossUnderBarIndex > 0
&& crossUnderBarIndex > crossOverBarIndex
&& (crossUnderBarIndex - crossOverBarIndex) >= 5
;
//
bool result =
//
isConditionsFilled
&& isLogicPassed
&& cciLongConds.crossOverSlope > 0
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearCCILongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearCCILongSignalConditions() {
//
cciLongConds.start = 0;
cciLongConds.crossOverSlope = 0;
cciLongConds.crossOverMinusHundredTime = 0;
cciLongConds.crossUnderMinusHundredTime = 0;
}
//
int GetHighestHighOfCCILongPeriodIndex() {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
);
//
int result = iHighest(
_Symbol,
_Period,
MODE_HIGH,
crossUnderBarIndex - crossOverBarIndex,
crossOverBarIndex
);
//
return result;
}
//
double GetHighestHighOfCCILongPeriod() {
//
int index = GetHighestHighOfCCILongPeriodIndex();
//
double result = iHigh(
_Symbol,
_Period,
index
);
//
return result;
}
//
int GetLowestLowOFCCILongPeriodIndex() {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
);
//
int result = iLowest(
_Symbol,
_Period,
MODE_LOW,
crossUnderBarIndex - crossOverBarIndex,
crossOverBarIndex
);
//
return result;
}
//
double GetLowestLowOFCCILongPeriod() {
//
int index = GetLowestLowOFCCILongPeriodIndex();
//
double result = iLow(
_Symbol,
_Period,
index
);
//
return result;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForCCILongSignals(
const XState &states[]
) {
//
bool result = false;
//
XStateInfo info = ParseXMAStates(states);
//
result =
//
true
//
// && states[1].mc.fast > states[1].mc.slow
// && MathAbs(states[1].mc.fast - states[1].mc.slow) > 100 * _Point
// && states[1].marketMiddleage > states[1].sc.fast
// && states[1].marketMiddleage > states[1].mc.fast
;
//
return result;
}
//
// END Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,948 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 Indicator Global Library
// ---------------------------------------------------
// saherelm useful tools and definitions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Includes library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
static double zigZags[];
//
// END Global Requirement Functions ...
//
//
// START Indicator Reading Data ...
//
//
// START XMKT Data ...
//
XMKTState GetXMKT(
const int bar_index,
const int marketLen,
//
const bool showHighestHigh = true,
const bool showHighestLow = true,
const bool showHighestOpen = true,
const bool showHighestClose = true,
const bool showLowestHigh = true,
const bool showLowestLow = true,
const bool showLowestOpen = true,
const bool showLowestClose = true,
const color highestHighColor = clrDeepPink,
const color highestLowColor = clrDarkOrange,
const color highestOpenColor = clrDodgerBlue,
const color highestCloseColor = clrOrchid,
const color lowestHighColor = clrHotPink,
const color lowestLowColor = clrOrange,
const color lowestOpenColor = clrPowderBlue,
const color lowestCloseColor = clrMediumOrchid,
const ENUM_LINE_STYLE highestHighStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestLowStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestOpenStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestCloseStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestHighStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestLowStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestOpenStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestCloseStyle = STYLE_DOT
) {
//
XMKTState result = {};
//
string xmktIndName = "x-saherelm.xmarket";
//
int highestHighBufferIndex = 0;
int highestLowBufferIndex = 1;
int highestOpenBufferIndex = 2;
int highestCloseBufferIndex = 3;
int lowestHighBufferIndex = 4;
int lowestLowBufferIndex = 5;
int lowestOpenBufferIndex = 6;
int lowestCloseBufferIndex = 7;
//
// Highest High ...
double highestHigh = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestHighBufferIndex, // Buffer Index ...
bar_index
);
result.highestHigh = highestHigh;
//
// Highest Low ...
double highestLow = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestLowBufferIndex, // Buffer Index ...
bar_index
);
result.highestLow = highestLow;
//
// Highest Open ...
double highestOpen = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestOpenBufferIndex, // Buffer Index ...
bar_index
);
result.highestOpen = highestOpen;
//
// Highest Close ...
double highestClose = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestCloseBufferIndex, // Buffer Index ...
bar_index
);
result.highestClose = highestClose;
//
// Lowest High ...
double lowestHigh = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestHighBufferIndex, // Buffer Index ...
bar_index
);
result.lowestHigh = lowestHigh;
//
// Lowest Low ...
double lowestLow = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestLowBufferIndex, // Buffer Index ...
bar_index
);
result.lowestLow = lowestLow;
//
// Lowest Open ...
double lowestOpen = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestOpenBufferIndex, // Buffer Index ...
bar_index
);
result.lowestOpen = lowestOpen;
//
// Lowest Close ...
double lowestClose = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestCloseBufferIndex, // Buffer Index ...
bar_index
);
result.lowestClose = lowestClose;
//
return result;
}
//
// END XMKT Data ...
//
//
// START XOSC Data ...
//
XCycleState GetXOSC(
const int bar_index,
const int marketLen,
//
const int fastMult,
const int slowMult,
//
const double fastMMul = 1.0,
const double slowMMul = 3.0
) {
//
XCycleState result = {};
//
string oscIndName = "x-saherelm.osc";
//
// Prepare OSC Inputs ...
//
int fastLength = fastMult * marketLen;
int slowLength = slowMult * marketLen;
//
// Fast ...
double fast = iCustom(
_Symbol,
_Period,
oscIndName,
//
// Inputs ...
fastLength,
fastMMul,
slowLength,
slowMMul,
//
0, // Buffer Index ...
bar_index
);
result.fast = fast;
//
// Slow ...
double slow = iCustom(
_Symbol,
_Period,
oscIndName,
//
// Inputs ...
fastLength,
fastMMul,
slowLength,
slowMMul,
//
1, // Buffer Index ...
bar_index
);
result.slow = slow;
//
return result;
}
//
// END XOSC Data ...
//
//
// START XBND Data ...
//
XBndState GetXBND(
const int bar_index,
//
const int marketLen = 10, // Market Length ...
const int shift = 0, // MA Shift ...
const ENUM_MA_METHOD method = MODE_SMA // MA Method ...
) {
//
XBndState result = {};
//
double high = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_HIGH
);
result.high = high;
//
double open = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_OPEN
);
result.open = open;
//
double close = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_CLOSE
);
result.close = close;
//
double low = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_LOW
);
result.low = low;
//
return result;
}
//
// END XBND Data ...
//
//
// START ZigZag Data ...
//
void PrepareZigZagState(
const int bar_index,
//
const int depth = 12,
const int deviation = 5,
const int backStep = 3
) {
//
string zigzagIndName = "x-saherelm.zigzag";
//
ArrayFree(zigZags);
ArrayResize(
zigZags,
3
);
//
double zigZag = 0;
int index = 0;
int i = bar_index;
while (index < 3) {
//
zigZag = iCustom(
_Symbol,
_Period,
zigzagIndName,
//
// Inputs ...
depth,
deviation,
backStep,
//
0, // Buffer Index ...
i
);
//
if (zigZag > 0) {
//
zigZags[index] = zigZag;
index++;
}
//
i++;
}
}
//
// END ZigZag Data ...
//
//
// START XMA Data ...
//
//
// Retrieve Short Cycle ...
XCycleState GetXMASC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow= slow;
//
return result;
}
//
// Retrieve Medium Cycle ...
XCycleState GetXMAMC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow= slow;
//
return result;
}
//
// Retrieve Long Cycle ...
XCycleState GetXMALC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow = slow;
//
return result;
}
//
// Retrieve Long Cycle ...
XCycleState GetXMANN(
const int bar_index,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = 10;
int slowLength = 50;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow = slow;
//
return result;
}
//
// Retrieve Middle ...
double GetXMAMM(
const int bar_index,
const int marketLen,
const double multiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_EMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_MEDIAN
) {
//
double result = 0;
//
int length = (int)(marketLen * multiplier);
//
double middle = iMA(
_Symbol,
_Period,
length,
shift,
method,
appliedPrice,
bar_index
);
result = middle;
//
return result;
}
//
// Retrieve XMA Parabolic SAR ...
double GetXMAPSAR(
const int bar_index,
//
double stp = 0.02,
double mxm = 0.2
) {
//
double result = 0;
//
double pSar = iSAR(
_Symbol,
_Period,
stp,
mxm,
bar_index
);
result = pSar;
//
return result;
}
//
XState GetXState(
const int bar_index,
const int marketLen,
//
const double stp,
const double mxm,
//
const int shortCycleFastMult,
const int shortCycleSlowMult,
const int mediumCycleFastMult,
const int mediumCycleSlowMult,
const int longCycleFastMult,
const int longCycleSlowMult
) {
//
XState result = {};
//
// Short Cycle ...
XCycleState sc = GetXMASC(
bar_index,
marketLen,
shortCycleFastMult,
shortCycleSlowMult
);
result.sc = sc;
//
// Medium Cycle ...
XCycleState mc = GetXMAMC(
bar_index,
marketLen,
mediumCycleFastMult,
mediumCycleSlowMult
);
result.mc = mc;
//
// Long Cycle ...
XCycleState lc = GetXMALC(
bar_index,
marketLen,
longCycleFastMult,
longCycleSlowMult
);
result.lc = lc;
// //
// // OSC ...
// XCycleState osc = GetXOSC(
// //
// bar_index,
// marketLen,
// //
// shortCycleFastMult,
// shortCycleSlowMult
// );
// result.osc = osc;
//
// Market Middleage ...
double marketMiddleage = GetXMAMM(
bar_index,
marketLen,
1.5
);
result.marketMiddleage = marketMiddleage;
//
// Parabolic SAR ...
double parabolicSAR = GetXMAPSAR(
bar_index,
stp,
mxm
);
result.parabolicSAR = parabolicSAR;
// //
// int cciMarketLength = longCycleSlowMult * marketLen;
// double cci = GetMarketCCI(
// bar_index,
// cciMarketLength
// );
// result.cci = cci;
//
XBndState bnd = GetXBND(
bar_index
);
result.bnd = bnd;
//
XMKTState mkt = GetXMKT(
bar_index,
marketLen
);
result.mkt = mkt;
//
double longCycleHighestHigh = GetMarketHighestHigh(
bar_index,
longCycleFastMult * marketLen
);
result.longCycleHighestHigh = longCycleHighestHigh;
//
return result;
}
//
// END XMA Data ...
//
//
// END Indicator Reading Data ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,91 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 Draw Global Library
// ---------------------------------------------
// saherelm useful tools and definitions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Log Tag ...
static string logTag = "";
//
// Enable or Disable Logging ...
static bool enableLogging = false;
//
// Start Log Messages ...
//
//
// Logging a Message, specified for this EA ...
// using provided LogTag ...
void LogMessage(string message) {
//
if (!enableLogging) {
return;
}
//
Print(logTag, " > ", message);
}
//
// this used for logging series ...
void LogSeries(
double &series[], // which series to Log ...
int length = 0, // number of items to Log, 0 means all ...
int skip = 0 // number of items which skip before logging ...
) {
//
string msg = "";
//
int seriesSize = ArraySize(series);
if (
skip < 0
|| length < 0
|| seriesSize == 0
|| skip > seriesSize
|| skip + length > seriesSize
) {
return;
}
//
length = length == 0 ?
seriesSize :
length;
int start = skip > 1 ?
skip - 1 :
skip == 1 ?
1 :
0;
//
// Loop through series items ...
for (int i = start; i < start + length; i++) {
//
msg += StringConcatenate(
"i[", i, "]: ", series[i], ", "
);
}
//
LogMessage(msg);
}
//
// End Log Messages ...
//
@@ -0,0 +1,225 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 Models Global Library
// ---------------------------------------------
// saherelm useful tools and definitions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// START STATIC Variables ...
//
//
static int totalSignals = 0;
static int totalLongSignals = 0;
static int totalShortSignals = 0;
//
static double initialBalance = 0;
//
static int countedBars = 0;
static bool isNewBar = false;
static bool isNewDay = false;
//
// END STATIC Variables ...
//
//
// Start Models ...
//
//
// Signal Providers ...
enum ENUM_X_SIGNAL_PROVIDER {
X_UNKNOWN_PROVIDER,
X_OSC_PROVIDER,
X_CCI_PROVIDER,
X_SHP_PROVIDER,
X_XMA_PROVIDER,
X_RMA_PROVIDER,
X_XXX_PROVIDER
};
//
// these are different signal types ...
enum ENUM_X_SIGNAL_TYPE {
X_SIGNAL_NONE,
X_SIGNAL_LONG,
X_SIGNAL_SHORT,
};
//
// we Model each signals as this type ...
struct XSignal {
//
// Signal Symbol ...
string symbol;
//
// Signal Type ...
ENUM_X_SIGNAL_TYPE type;
//
// Signal ID ...
int id;
//
// Signal Ticket Number, when Opening Trade ...
int ticket;
//
// Signal Provider ...
ENUM_X_SIGNAL_PROVIDER provider;
//
// Target Point ...
double tp;
//
// Stop Loss ...
double sl;
//
// Signal Entry Price ...
double entry;
//
// Signalling Time ...
datetime time;
//
// Signal Comments ...
string comment;
};
//
// this is Signal Request Response model ...
struct XSignalRequest {
bool hasSignal;
XSignal signal;
ENUM_X_SIGNAL_TYPE type;
ENUM_X_SIGNAL_PROVIDER provider;
};
//
struct XBndState {
double high;
double open;
double close;
double low;
};
//
struct XMKTState {
//
double highestHigh;
double highestLow;
double highestOpen;
double highestClose;
//
double lowestHigh;
double lowestLow;
double lowestOpen;
double lowestClose;
};
//
struct XCycleState {
double fast;
double slow;
};
//
// Define a Model to Represent Snapshot of XMA Indicator ...
struct XState {
//
// SC ...
XCycleState sc;
//
// MC ...
XCycleState mc;
//
// LC ...
XCycleState lc;
//
// OSC ...
// XCycleState osc;
//
// MIDDLEAGE ...
double marketMiddleage;
//
// PARABOLIC-SAR ...
double parabolicSAR;
//
double cci;
//
XBndState bnd;
//
XMKTState mkt;
//
double longCycleHighestHigh;
};
//
// Parsed XMA Buffer ...
struct XStateInfo {
//
// Check Market Cross Exists or not ...
//
bool isSCFastCrossOverSlow;
bool isSCFastCrossUnderSlow;
//
double scMin;
double scMax;
//
bool isMCFastCrossOverSlow;
bool isMCFastCrossUnderSlow;
//
double mcMin;
double mcMax;
bool isLCFastCrossOverSlow;
bool isLCFastCrossUnderSlow;
//
double lcMin;
double lcMax;
//
bool isMMCrossOverSCFast;
bool isMMCrossUnderSCFast;
//
bool isMMCrossOverMCFast;
bool isMMCrossUnderMCFast;
//
double mmMin;
double mmMax;
};
//
// End Models ...
//
@@ -0,0 +1,363 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 OSC Signal Global Library
// ---------------------------------------------------
// saherelm useful tools and definitions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Includes library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// SHP Based Signal Conditions ...
struct XOSCLongSignalConditions {
//
datetime crossOverTime;
double slowOnCrossOver;
//
datetime crossUnderTime;
double slowOnCrossUnder;
};
//
static XOSCLongSignalConditions oscLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckOSCLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult,
//
int lcFMult,
int lcSMult,
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
XState states[];
ArrayResize(
states,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < marketLen; i++) {
//
XState state = GetXState(
i,
marketLen,
//
stp,
mxm,
scFMult,
scSMult,
mcFMult,
mcSMult,
lcFMult,
lcSMult
);
//
states[index] = state;
//
index++;
}
//
bool isCrossUnder =
states[0].osc.fast < 0
&& !(states[1].osc.fast < 0)
;
//
bool isCrossOver =
states[0].osc.fast > 0
&& !(states[1].osc.fast > 0)
;
//
int oneTouches = 0;
int halfTouches = 0;
int minusOneTouches = 0;
for (int i = 0; i < marketLen - 1; i++) {
//
// One Touches ...
if (
states[i].osc.fast > 1
&& !(states[i + 1].osc.fast > 1)
) {
oneTouches++;
}
//
// Half Touches ...
if (
states[i].osc.fast > 0.5
&& !(states[i + 1].osc.fast > 0.5)
) {
halfTouches++;
}
//
// Minus One Touches ...
if (
states[i].osc.fast < -1
&& !(states[i + 1].osc.fast < -1)
) {
minusOneTouches++;
}
}
//
if (
isCrossUnder
&& oscLongConds.crossUnderTime == 0
) {
//
oscLongConds.crossUnderTime = barTime;
oscLongConds.slowOnCrossUnder = states[0].osc.slow;
return;
}
//
if (
isCrossOver
&& oscLongConds.crossUnderTime > 0
&& oscLongConds.crossOverTime == 0
) {
//
oscLongConds.crossOverTime = barTime;
oscLongConds.slowOnCrossOver = states[0].osc.slow;
return;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateOSCLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateOSCLongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r; // 300 * _Point;
//
double sl = 0; // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_OSC_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_OSC_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateOSCLongConditions() {
//
bool isConditionsFilled =
oscLongConds.crossOverTime > 0
&& oscLongConds.crossUnderTime > 0
&& oscLongConds.slowOnCrossOver > 0
&& oscLongConds.slowOnCrossUnder > 0
&& oscLongConds.crossOverTime > oscLongConds.crossUnderTime
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
oscLongConds.crossUnderTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
oscLongConds.crossOverTime
);
//
isBLFilled =
crossUnderBarIndex > crossOverBarIndex
// && oscLongConds.slowOnCrossOver > oscLongConds.slowOnCrossUnder
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearOSCLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearOSCLongSignalConditions() {
//
oscLongConds.crossOverTime = 0;;
oscLongConds.crossUnderTime = 0;;
}
//
// Check State for Long Signals ...
bool IsReadyForOSCLongSignals(
const XSignal &signal,
const XState &states[]
) {
//
bool result = false;
//
result =
//
true
;
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,363 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 RMA Signal Global Library
// ---------------------------------------------------
// saherelm useful tools and definitions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Includes library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// RMA Based Signal Conditions ...
struct XRMALongSignalConditions {
//
datetime crossUnderTime;
//
datetime crossOverTime;
};
//
static XRMALongSignalConditions xrmaLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXRMALongSignalConditions(
const int bar_index,
const int marketLen,
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
XCycleState states[];
ArrayResize(
states,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < marketLen; i++) {
//
XCycleState state = GetXMANN(i);
//
states[index] = state;
//
index++;
}
//
bool isCrossUnder =
states[1].fast < states[1].slow
&& !(states[2].fast < states[2].slow)
;
//
bool isCrossOver =
states[1].fast > states[1].slow
&& !(states[2].fast > states[2].slow)
;
//
if (
isCrossUnder
&& xrmaLongConds.crossUnderTime == 0
) {
//
xrmaLongConds.crossUnderTime = barTime;
return;
}
//
if (
isCrossOver
&& xrmaLongConds.crossUnderTime > 0
&& xrmaLongConds.crossOverTime == 0
) {
//
xrmaLongConds.crossOverTime = barTime;
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXRMALongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateXRMALongConditions(marketLen)) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r; // 300 * _Point;
//
double sl = 0; // entryPrice - (300 * _Point); // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_RMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_RMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXRMALongConditions(
const int marketLen
) {
//
bool isConditionsFilled =
true
&& xrmaLongConds.crossOverTime > 0
&& xrmaLongConds.crossUnderTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
xrmaLongConds.crossOverTime
);
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
xrmaLongConds.crossUnderTime
);
//
XCycleState stateOnCrossUnder = GetXMANN(
crossUnderBarIndex
);
//
XCycleState stateOnCrossOver = GetXMANN(
crossOverBarIndex
);
//
double maC = iMA(
_Symbol,
_Period,
14,
0,
MODE_SMA,
PRICE_CLOSE,
crossOverBarIndex
);
// //
// double rmaOnCrossOver = GetRMA(
// crossOverBarIndex,
// 10
// );
// //
// double rmaOnMarketLength = GetRMA(
// crossOverBarIndex + marketLen,
// 10
// );
// //
// double prevCandleHigh = iHigh(
// _Symbol,
// _Period,
// crossOverBarIndex
// );
// //
// PrepareZigZagState(crossOverBarIndex);
// double zigZagDelta = zigZags[1] - zigZags[2];
// bool isZigZagWaitForHigh = zigZagDelta < 0;
//
isBLFilled =
true
//
&& (crossUnderBarIndex - crossOverBarIndex) > 5
//
&& xrmaLongConds.crossOverTime > xrmaLongConds.crossUnderTime
//
&& stateOnCrossOver.slow < stateOnCrossUnder.slow
//
&& MathAbs(stateOnCrossOver.fast - stateOnCrossOver.slow) > (70 * _Point)
//
&& maC >= stateOnCrossOver.slow
// //
// && !(rmaOnCrossOver < stateOnCrossOver.slow)
// //
// && MathAbs(rmaOnCrossOver - rmaOnMarketLength) < (600 * _Point)
// //
// && !isZigZagWaitForHigh
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXRMALongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXRMALongSignalConditions() {
//
xrmaLongConds.crossOverTime = 0;
xrmaLongConds.crossUnderTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXRMALongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
result =
//
true
;
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,391 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 SHP Signal Global Library
// ---------------------------------------------------
// saherelm useful tools and definitions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Includes library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// SHP Based Signal Conditions ...
struct XSHPLongSignalConditions {
//
datetime start;
datetime stop;
};
//
static XSHPLongSignalConditions shpLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckSHPLongSignalConditions(
const int bar_index,
const int marketLen,
const double shpDetectMult,
const double smoother = 30
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
double high = iHigh(
_Symbol,
_Period,
bar_index
);
//
double low = iLow(
_Symbol,
_Period,
bar_index + 1
);
//
double mHH = GetMarketHighestHigh(
bar_index,
marketLen
);
//
double mLL = GetMarketLowestLow(
bar_index,
marketLen
);
double m2LL = GetMarketLowestLow(
bar_index,
marketLen * 2
);
//
int mHLIdx = iHighest(
_Symbol,
_Period,
MODE_LOW,
marketLen,
bar_index
);
datetime mHLTime = iTime(
_Symbol,
_Period,
mHLIdx
);
double mHL = iHigh(
_Symbol,
_Period,
mHLIdx
);
//
double hlDiff = (mHL - mLL);
double sharpDetectValue = shpDetectMult * _Point;
//
bool isSharpDetected =
// (
// low == mLL
// || MathAbs(mLL - low) < (smoother * _Point)
// )
// &&
// !(
// mLL > m2LL
// && MathAbs(m2LL - mLL) > sharpDetectValue / 2
// )
// &&
(
hlDiff > sharpDetectValue
|| hlDiff > sharpDetectValue - (smoother * _Point)
)
;
//
if (isSharpDetected) {
//
shpLongConds.start = mHLTime;
shpLongConds.stop = barTime;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateSHPLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r, // Risk to Reward ratio ...
const double shpDetectMultiplier // Sharp Detect Multiplier ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateSHPLongConditions(shpDetectMultiplier)) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = 300 * _Point; // risk * r2r;
//
double sl = 0; // ll;
//
// this means Market Lowest Low ...
double shpValue = shpDetectMultiplier * _Point;
if (
reward == 0
|| reward < 20 * _Point
) {
reward = shpValue;
}
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_SHP_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_SHP_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateSHPLongConditions(
const double shpDetectMultiplier
) {
//
double shpDetectValue = shpDetectMultiplier * _Point;
//
bool isConditionsFilled =
shpLongConds.stop != 0
&& shpLongConds.start != 0
&& shpLongConds.stop > shpLongConds.start
;
//
bool isBLFilled = true;
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearSHPLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearSHPLongSignalConditions() {
//
shpLongConds.stop = 0;
shpLongConds.start = 0;
}
//
// Check State for Long Signals ...
bool IsReadyForSHPLongSignals(
const XSignal &signal,
const XState &states[]
) {
//
bool result = false;
//
XStateInfo info = ParseXMAStates(states);
//
int xmaMarketLen = ArraySize(states);
double mHH = GetMarketHighestHigh(0, xmaMarketLen);
double m2HH = GetMarketHighestHigh(0, (int) (xmaMarketLen * 1.5));
//
int lcUpDownTouches = 0;
int cciHundredTouches = 0;
for (int i = 0; i < xmaMarketLen; i++) {
//
double high = iHigh(
_Symbol,
_Period,
i
);
//
double low = iLow(
_Symbol,
_Period,
i
);
//
double up = MathMax(states[i].lc.fast, states[i].lc.slow);
double down = MathMax(states[i].lc.fast, states[i].lc.slow);
//
if (high >= up && low <= down) {
lcUpDownTouches++;
}
//
if (
i < xmaMarketLen - 1
&& i < 10
) {
if (
states[i].cci < 100
&& states[i + 1].cci > 100
) {
cciHundredTouches++;
}
}
}
//
result =
//
true
//
&& states[0].mc.fast > states[0].mc.slow
&& states[0].lc.fast > states[0].lc.slow
//
&& states[0].sc.fast < states[0].sc.slow
&& states[1].sc.fast < states[1].sc.slow
//
&& states[0].marketMiddleage < states[0].sc.fast
&& states[1].marketMiddleage < states[1].sc.fast
&& !(
states[1].sc.fast < states[1].mc.fast
&& states[1].sc.slow < states[1].mc.fast
&& states[1].sc.fast > states[1].mc.slow
&& states[1].sc.slow > states[1].mc.slow
)
&& !(
states[0].marketMiddleage < states[0].mc.fast
&& states[0].marketMiddleage > states[0].mc.slow
)
//
&& mHH != m2HH
&& lcUpDownTouches == 0
&& cciHundredTouches == 0
;
//
return result;
}
//
// END Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,678 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 X Signal Global Library
// ---------------------------------------------------
// saherelm useful tools and definitions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Includes library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// X Based Signal Conditions ...
struct XSignalConditions {
datetime startTime;
datetime signalTime;
};
//
static XSignalConditions xLongConds;
static XSignalConditions xShortConds;
//
static bool xCloseLongTrades = false;
static bool xWaitForLongSignals = true;
static datetime xWaitForLongSignalChangeTime;
//
static bool xWaitForShortSignals = true;
static bool xCloseShortTrades = false;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill Long Signal Conditions ...
void CheckXLongSignalConditions(
const int bar_index,
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
// //
// bool isCrossUnder =
// states[1].osc.fast < states[1].osc.slow
// && !(states[2].osc.fast < states[2].osc.slow)
// ;
// //
// bool isCrossOver =
// states[1].osc.fast > states[1].osc.slow
// && !(states[2].osc.fast > states[2].osc.slow)
// ;
//
XOHCL pCandle = GetCandleModel(1);
// //
// bool isTrendingUp =
// pCandle.low > states[0].bnd.high
// && pCandle.high > states[0].bnd.high;
// //
// bool isTrendingDown =
// pCandle.high < states[0].bnd.low
// && pCandle.low < states[0].bnd.low;
//
bool isTrendingUp =
states[1].bnd.open < states[1].bnd.close
&& !(states[2].bnd.open < states[2].bnd.close)
;
//
bool isTrendingDown =
states[1].bnd.open > states[1].bnd.close
&& !(states[2].bnd.open > states[2].bnd.close)
;
//
bool isCrossUnder =
isTrendingDown
&& !isTrendingUp
;
//
bool isCrossOver =
isTrendingUp
&& !isTrendingDown
;
//
// Check Market For Enable/Disable Signal Handlers ...
// Checking Market for Long Signals ...
if (xWaitForLongSignals) {
//
bool isLCFastOnTrendingUpTouchLowestLow =
//
// LC Trending Up ...
states[1].lc.fast > states[1].lc.slow
&& states[2].lc.fast > states[2].lc.slow
//
// LC Fast Touch Market Lowest Low ...
&& states[1].lc.fast > states[1].mkt.lowestLow
&& !(states[2].lc.fast > states[2].mkt.lowestLow)
;
//
bool isMCSlowCrossOverBNDHigh =
states[1].mc.fast > states[1].mc.slow
&& states[1].mc.slow > states[1].bnd.high
&& !(states[2].mc.slow > states[2].bnd.high)
;
//
// Disable Long Trade Handlers ...
if (
isMCSlowCrossOverBNDHigh
|| isLCFastOnTrendingUpTouchLowestLow
) {
//
xWaitForLongSignals = false;
xWaitForLongSignalChangeTime = TimeCurrent();
LogMessage("Disable Long ...");
}
} else {
//
bool isAllTrendingUp =
//
// SC ...
states[1].sc.fast > states[1].sc.slow
//
// MC ...
&& states[1].mc.fast > states[1].mc.slow
&& !(states[2].mc.fast > states[2].mc.slow)
//
// LC ...
&& states[1].lc.fast > states[1].lc.slow
;
//
int lastWaitChangeBarIndex = iBarShift(
_Symbol,
_Period,
xWaitForLongSignalChangeTime
);
//
// Enable Long Trade Handlers ...
if (
isAllTrendingUp
&& lastWaitChangeBarIndex - bar_index >= marketLen
) {
xWaitForLongSignals = true;
LogMessage("Enable Long ...");
}
}
//
if (
isCrossUnder
&& xLongConds.startTime == 0
) {
//
xLongConds.startTime = barTime;
return;
}
//
if (
isCrossOver
&& xLongConds.startTime > 0
&& xLongConds.signalTime == 0
) {
//
xLongConds.signalTime = barTime;
return;
}
}
//
// Check and Fill Short Signal Conditions ...
void CheckXShortSignalConditions(
const int bar_index,
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
bool isCrossUnder =
false;
//
bool isCrossOver =
false;
// //
// bool isCrossUnder =
// states[1].osc.fast < states[1].osc.slow
// && !(states[2].osc.fast < states[2].osc.slow)
// ;
// //
// bool isCrossOver =
// states[1].osc.fast > states[1].osc.slow
// && !(states[2].osc.fast > states[2].osc.slow)
// ;
//
if (
isCrossOver
&& xShortConds.startTime == 0
) {
//
xShortConds.startTime = barTime;
return;
}
//
if (
isCrossUnder
&& xShortConds.startTime > 0
&& xShortConds.signalTime == 0
) {
//
xShortConds.signalTime = barTime;
return;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateXSignal(
const ENUM_X_SIGNAL_TYPE type, // Signal Type ...
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r, // Risk to Reward ratio ...
const XState &states[],
//
const double smoother = 5
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
bool requestLong = type == X_SIGNAL_LONG;
//
if (requestLong) {
//
if (
!ValidateXLongConditions(
marketLen,
states,
smoother
)
) {
return result;
}
} else {
//
if (
!ValidateXShortConditions(
marketLen,
states,
smoother
)
) {
return result;
}
}
//
// Price Calculations ...
//
RefreshRates();
//
double askPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double bidPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double entryPrice = requestLong ?
askPrice :
bidPrice;
//
double exitPrice = requestLong ?
bidPrice :
askPrice;
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double hh =
GetMarketHighestHigh(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = requestLong ?
MathMin(openPrice, closePrice) - ll :
hh - MathMax(openPrice, closePrice);
double reward = risk * r2r; // risk * r2r; // 300 * _Point;
// if (risk > (500 * _Point)) {
// reward = 300 * _Point;
// }
//
double sl = 0; // ll;
double tp = requestLong ?
entryPrice + reward :
entryPrice - reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = type;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XXX_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = type;
result.provider = X_XXX_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateXLongConditions(
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
bool isConditionsFilled =
xLongConds.startTime > 0
&& xLongConds.signalTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
xLongConds.startTime
);
//
int signalBarIndex = iBarShift(
_Symbol,
_Period,
xLongConds.signalTime
);
//
isBLFilled =
//
xLongConds.signalTime > xLongConds.startTime
&& MathAbs(signalBarIndex - startBarIndex) > 2
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
&& xWaitForLongSignals
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXLongSignalConditions();
}
//
return result;
}
bool ValidateXShortConditions(
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
bool isConditionsFilled =
xShortConds.startTime > 0
&& xShortConds.signalTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
xShortConds.startTime
);
//
int signalBarIndex = iBarShift(
_Symbol,
_Period,
xShortConds.signalTime
);
//
isBLFilled =
//
xShortConds.signalTime > xShortConds.startTime
&& MathAbs(signalBarIndex - startBarIndex) > 2
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
&& xWaitForLongSignals
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXShortSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXLongSignalConditions() {
//
xLongConds.startTime = 0;
xLongConds.signalTime = 0;
}
//
// Clear Short Signal Conditions for New One ...
void ClearXShortSignalConditions() {
//
xShortConds.startTime = 0;
xShortConds.signalTime = 0;
}
//
// Check State for Long Signals ...
bool IsReadyForXSignals(
const XSignal &signal,
const XState &states[],
const int marketLen,
//
double smoother = 100
) {
//
bool result = false;
//
bool isSCTrendUp =
states[1].sc.fast > states[1].sc.slow
&& states[2].sc.fast > states[2].sc.slow;
// //
// bool isSCTrendDown =
// states[1].sc.fast < states[1].sc.slow
// && states[2].sc.fast < states[2].sc.slow;
//
bool isMCTrendUp =
states[1].mc.fast > states[1].mc.slow
&& states[2].mc.fast > states[2].mc.slow;
// //
// bool isMCTrendDown =
// states[1].mc.fast < states[1].mc.slow
// && states[2].mc.fast < states[2].mc.slow;
//
bool isLCTrendUp =
states[1].lc.fast > states[1].lc.slow
&& states[2].lc.fast > states[2].lc.slow;
// //
// bool isLCTrendDown =
// states[1].lc.fast < states[1].lc.slow
// && states[2].lc.fast < states[2].lc.slow;
// //
// bool isTrendingUp =
// pCandle.low > states[0].bnd.high
// && pCandle.high > states[0].bnd.high;
// //
// bool isTrendingDown =
// pCandle.high < states[0].bnd.low
// && pCandle.low < states[0].bnd.low;
//
XOHCL candle = GetCandleModel(0);
XOHCL pCandle = GetCandleModel(1);
//
// Verify Long Signals ...
if (signal.type == X_SIGNAL_LONG) {
//
result =
//
// Starter ...
true
//
// Trending State ...
&& isSCTrendUp
&& isMCTrendUp
&& isLCTrendUp
//
// Checking Signal Entry ...
&& (
signal.entry < candle.high
|| signal.entry < states[0].mkt.highestHigh
)
//
// Checking Signal TP ...
&& (
signal.tp < states[1].longCycleHighestHigh
&& MathAbs(states[1].longCycleHighestHigh - signal.tp) > 100 * _Point
)
//
// Checking Market Sharpness ...
&&
(
pCandle.high < states[1].longCycleHighestHigh
&& !(MathAbs(states[1].longCycleHighestHigh - pCandle.high) < 20 * _Point)
)
//
// Checking Special Conditions ...
// Condition 1 ...
&& (
states[1].lc.fast > states[1].mc.fast
&& states[1].lc.slow > states[1].mc.fast
?
states[1].lc.slow < states[1].mkt.lowestLow
:
true
)
//
// Condition 2 ...
&& !(
states[1].lc.fast > states[1].mkt.highestHigh
&& states[1].lc.slow < states[1].mkt.lowestLow
)
//
// Condition 3 ...
&& MathAbs(states[1].sc.fast - states[1].sc.slow) > 20 * _Point
;
} else
//
// Verify Short Signals ...
if (signal.type == X_SIGNAL_SHORT) {
//
result =
false
;
}
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,490 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 XMA Signal Global Library
// ---------------------------------------------------
// saherelm useful tools and definitions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Includes library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// XMA Based Signal Conditions ...
struct XMAMCLongSignalConditions {
//
datetime mcFastCrossUnderSlowTime;
double crossUnderMCFast;
double crossUnderMCSlow;
//
datetime mcFastCrossOverSlowTime;
double crossOverMCFast;
double crossOverMCSlow;
//
datetime mcFastBiggerThanCrossUnderSlowTime;
};
//
static XMAMCLongSignalConditions xmaMCLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXMAMCLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult
) {
//
XCycleState mcs[];
int positionsMarketLen = bar_index + marketLen;
//
// Retrieve Bar Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// Resize Arrays ...
ArrayResize(
mcs,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < positionsMarketLen; i++) {
//
XCycleState mc = GetXMAMC(
i,
marketLen,
mcFMult,
mcSMult
);
mcs[index] = mc;
//
index++;
}
//
bool isMCFastCrossUnderSlow =
mcs[0].fast < mcs[0].slow
&& !(mcs[1].fast <= mcs[1].slow)
;
bool isMCFastCrossOverSlow =
mcs[0].fast > mcs[0].slow
&& !(mcs[1].fast >= mcs[1].slow)
;
//
if (
isMCFastCrossUnderSlow
&& xmaMCLongConds.mcFastCrossUnderSlowTime == 0
) {
//
xmaMCLongConds.crossUnderMCFast = mcs[0].fast;
xmaMCLongConds.crossUnderMCSlow = mcs[0].slow;
xmaMCLongConds.mcFastCrossUnderSlowTime = barTime;
return;
}
//
if (
isMCFastCrossUnderSlow
&& xmaMCLongConds.mcFastCrossUnderSlowTime > 0
) {
//
ClearXMAMCLongSignalConditions();
//
xmaMCLongConds.crossUnderMCFast = mcs[0].fast;
xmaMCLongConds.crossUnderMCSlow = mcs[0].slow;
xmaMCLongConds.mcFastCrossUnderSlowTime = barTime;
return;
}
//
if (
isMCFastCrossOverSlow
&& xmaMCLongConds.mcFastCrossUnderSlowTime > 0
&& xmaMCLongConds.mcFastCrossOverSlowTime == 0
) {
//
xmaMCLongConds.crossOverMCFast = mcs[0].fast;
xmaMCLongConds.crossOverMCSlow = mcs[0].slow;
xmaMCLongConds.mcFastCrossOverSlowTime = barTime;
return;
}
//
if (
xmaMCLongConds.mcFastCrossUnderSlowTime > 0
&& xmaMCLongConds.mcFastCrossOverSlowTime > 0
&& mcs[0].fast > xmaMCLongConds.crossUnderMCSlow
&& xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime == 0
) {
//
xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime = barTime;
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXMAMCLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r, // Risk to Reward ratio ...
const double shpDetectMult,
const double smoother = 50
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (
!ValidateXMAMCLongConditions(
marketLen,
shpDetectMult,
smoother
)
) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
3
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r;
//
double sl = 0;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_XMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXMAMCLongConditions(
const int marketLen,
const double shpDetectMult,
const double smoother = 50
) {
//
bool isConditionsFilled =
xmaMCLongConds.crossOverMCSlow > 0
&& xmaMCLongConds.crossOverMCFast > 0
&& xmaMCLongConds.crossUnderMCFast > 0
&& xmaMCLongConds.crossUnderMCSlow > 0
&& xmaMCLongConds.mcFastCrossOverSlowTime != 0
&& xmaMCLongConds.mcFastCrossUnderSlowTime != 0
&& xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime != 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
xmaMCLongConds.mcFastCrossUnderSlowTime
);
//
int crossOverAndBiggerBarIndex = iBarShift(
_Symbol,
_Period,
xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime
);
//
int cycleMarketLen = MathMin(
MathAbs(crossUnderBarIndex - crossOverAndBiggerBarIndex),
marketLen * 2
);
double hh = GetMarketHighestHigh(
crossOverAndBiggerBarIndex,
cycleMarketLen
);
double ll = GetMarketLowestLow(
crossOverAndBiggerBarIndex,
cycleMarketLen
);
//
double high = iHigh(
_Symbol,
_Period,
crossOverAndBiggerBarIndex
);
double pcHigh = iHigh(
_Symbol,
_Period,
crossOverAndBiggerBarIndex + 1
);
//
double diff = (hh - ll);
double shpValue = shpDetectMult * _Point;
//
bool isPriceRegular =
//
true
//
&&
(
diff < shpValue
|| diff < shpValue - (smoother * _Point)
)
&&
!(
high == hh
|| pcHigh == hh
|| MathAbs(hh - high) < (smoother * _Point)
|| MathAbs(hh - pcHigh) < (smoother * _Point)
)
;
//
// LogMessage("Price Regular: " + isPriceRegular);
//
isBLFilled =
isPriceRegular
&& xmaMCLongConds.mcFastCrossUnderSlowTime < xmaMCLongConds.mcFastCrossOverSlowTime
&& xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime >= xmaMCLongConds.mcFastCrossUnderSlowTime
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXMAMCLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXMAMCLongSignalConditions() {
//
xmaMCLongConds.mcFastCrossUnderSlowTime = 0;
xmaMCLongConds.crossUnderMCFast = 0;
xmaMCLongConds.crossUnderMCSlow = 0;
//
xmaMCLongConds.mcFastCrossOverSlowTime = 0;
xmaMCLongConds.crossOverMCFast = 0;
xmaMCLongConds.crossOverMCSlow = 0;
//
xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXMAMCLongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
int countRangedCandles = 0;
bool isMarketRanging = false;
for (int i = 1; i < marketLen; i++) {
//
double high = iHigh(
_Symbol,
_Period,
i
);
//
double low = iLow(
_Symbol,
_Period,
i
);
//
bool isRanging =
//
high > states[i].mc.fast
&& high > states[i].mc.slow
//
&& low < states[i].mc.fast
&& low < states[i].mc.slow
;
if (isRanging) {
countRangedCandles++;
}
}
//
XStateInfo info = ParseXMAStates(states);
double mmSlope = GetSlope(
1,
states[1].marketMiddleage,
2,
states[0].marketMiddleage
);
double mmSlope1 = GetSlope(
1,
states[2].marketMiddleage,
2,
states[1].marketMiddleage
);
double mmSlopeDiff = mmSlope - mmSlope1;
//
isMarketRanging = countRangedCandles > 0;
//
result =
//
true
//
&& mmSlope > 0
&& mmSlope1 > 0
&& mmSlopeDiff > 0
&& !isMarketRanging
&& states[0].marketMiddleage < info.mmMax
;
// if (result) {
// LogMessage("mmSlope: " + mmSlope + ", mmSlope1: " + mmSlope1 + ", Diff: " + mmSlopeDiff);
// }
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,338 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 XMA Signal Global Library
// ---------------------------------------------------
// saherelm useful tools and definitions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Includes library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// XMA Based Signal Conditions ...
struct XMAMMLongSignalConditions {
//
datetime crossUnderTime;
//
datetime crossOverTime;
};
//
static XMAMMLongSignalConditions xmaMMLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXMAMMLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult,
//
int lcFMult,
int lcSMult,
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
XState states[];
ArrayResize(
states,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < marketLen; i++) {
//
XState state = GetXState(
i,
marketLen,
//
stp,
mxm,
scFMult,
scSMult,
mcFMult,
mcSMult,
lcFMult,
lcSMult
);
//
states[index] = state;
//
index++;
}
//
bool isCrossUnder =
states[1].marketMiddleage < states[1].sc.fast
&& !(states[2].marketMiddleage < states[2].sc.fast)
;
//
bool isCrossOver =
states[1].marketMiddleage > states[1].sc.fast
&& !(states[2].marketMiddleage > states[2].sc.fast)
;
//
if (
isCrossUnder
&& xmaMMLongConds.crossUnderTime == 0
) {
//
xmaMMLongConds.crossUnderTime = barTime;
return;
}
//
if (
isCrossOver
&& xmaMMLongConds.crossUnderTime > 0
&& xmaMMLongConds.crossOverTime == 0
) {
//
xmaMMLongConds.crossOverTime = barTime;
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXMAMMLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateXMAMMLongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = 300 * _Point; // risk * r2r;
//
double sl = 0; // entryPrice - (300 * _Point); // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_XMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXMAMMLongConditions() {
//
bool isConditionsFilled =
true
&& xmaMMLongConds.crossOverTime > 0
&& xmaMMLongConds.crossUnderTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
xmaMMLongConds.crossOverTime
);
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
xmaMMLongConds.crossUnderTime
);
//
isBLFilled =
true
//
&& (crossUnderBarIndex - crossOverBarIndex) > 5
//
&& xmaMMLongConds.crossOverTime > xmaMMLongConds.crossUnderTime
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXMAMMLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXMAMMLongSignalConditions() {
//
xmaMMLongConds.crossOverTime = 0;
xmaMMLongConds.crossUnderTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXMAMMLongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
result =
//
true
//
// && states[0].parabolicSAR < states[0].marketMiddleage
// && !(
// states[0].parabolicSAR < states[0].mc.fast
// && states[0].parabolicSAR < states[0].mc.slow
// )
//
// && states[0].mc.fast > states[0].mc.slow
//
// && MathAbs(states[0].mc.fast - states[0].mc.slow) > (150 * _Point)
;
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,360 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 XMA Signal Global Library
// ---------------------------------------------------
// saherelm useful tools and definitions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Includes library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// XMA Based Signal Conditions ...
struct XMASCLongSignalConditions {
//
datetime scFastCrossUnderSlowTime;
double crossUnderSCFast;
double crossUnderSCSlow;
//
datetime scFastCrossOverSlowTime;
double crossOverSCFast;
double crossOverSCSlow;
//
datetime scFastBiggerThanCrossUnderSlowTime;
};
//
static XMASCLongSignalConditions xmaSCLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXMASCLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult
) {
//
XCycleState scs[];
int positionsMarketLen = bar_index + marketLen;
//
// Retrieve Bar Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// Resize Arrays ...
ArrayResize(
scs,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < positionsMarketLen; i++) {
//
XCycleState sc = GetXMASC(
i,
marketLen,
scFMult,
scSMult
);
scs[index] = sc;
//
index++;
}
//
bool isSCFastCrossUnderSlow =
scs[0].fast < scs[0].slow
&& !(scs[1].fast <= scs[1].slow)
;
bool isSCFastCrossOverSlow =
scs[0].fast > scs[0].slow
&& !(scs[1].fast >= scs[1].slow)
;
//
if (
isSCFastCrossUnderSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime == 0
) {
//
xmaSCLongConds.crossUnderSCFast = scs[0].fast;
xmaSCLongConds.crossUnderSCSlow = scs[0].slow;
xmaSCLongConds.scFastCrossUnderSlowTime = barTime;
return;
}
//
if (
isSCFastCrossOverSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime > 0
&& xmaSCLongConds.scFastCrossOverSlowTime == 0
) {
//
xmaSCLongConds.crossOverSCFast = scs[0].fast;
xmaSCLongConds.crossOverSCSlow = scs[0].slow;
xmaSCLongConds.scFastCrossOverSlowTime = barTime;
return;
}
//
if (
xmaSCLongConds.scFastCrossUnderSlowTime > 0
&& xmaSCLongConds.scFastCrossOverSlowTime > 0
&& scs[0].fast > xmaSCLongConds.crossUnderSCSlow
&& xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime == 0
) {
//
xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime = barTime;
return;
}
//
if (
isSCFastCrossUnderSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime > 0
&& xmaSCLongConds.scFastCrossOverSlowTime > 0
) {
//
ClearXMASCLongSignalConditions();
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXMASCLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
//
// const double shpDetectMultiplier
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateXMASCLongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index + 1
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index + 1
);
// //
// double sharpDetectValue = shpDetectMultiplier * _Point;
// double lowPrice = iLow(
// _Symbol,
// _Period,
// bar_index + 1
// );
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r;
//
double sl = 0;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_XMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXMASCLongConditions() {
//
bool isConditionsFilled =
xmaSCLongConds.crossOverSCSlow > 0
&& xmaSCLongConds.crossOverSCFast > 0
&& xmaSCLongConds.crossUnderSCFast > 0
&& xmaSCLongConds.crossUnderSCSlow > 0
&& xmaSCLongConds.scFastCrossOverSlowTime != 0
&& xmaSCLongConds.scFastCrossUnderSlowTime != 0
&& xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime !=0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
isBLFilled =
xmaSCLongConds.crossOverSCFast > xmaSCLongConds.crossUnderSCSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime < xmaSCLongConds.scFastCrossOverSlowTime
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXMASCLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXMASCLongSignalConditions() {
//
xmaSCLongConds.crossUnderSCFast = 0;
xmaSCLongConds.crossUnderSCSlow = 0;
xmaSCLongConds.scFastCrossUnderSlowTime = 0;
//
xmaSCLongConds.crossOverSCFast = 0;
xmaSCLongConds.crossOverSCSlow = 0;
xmaSCLongConds.scFastCrossOverSlowTime = 0;
//
xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXMASCLongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
result =
//
true
//
&& states[0].sc.fast > states[0].sc.slow
&& states[1].sc.fast > states[1].sc.slow
;
//
return result;
}
//
// END Functions ...
//