Initial Commit ...
This commit is contained in:
@@ -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,941 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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;
|
||||
|
||||
//
|
||||
// Parabolic SAR ...
|
||||
double parabolicSAR = GetXMAPSAR(
|
||||
bar_index,
|
||||
stp,
|
||||
mxm
|
||||
);
|
||||
result.parabolicSAR = parabolicSAR;
|
||||
|
||||
//
|
||||
// Market Middleage ...
|
||||
double marketMiddleage = GetXMAMM(
|
||||
bar_index,
|
||||
marketLen,
|
||||
1.5
|
||||
);
|
||||
result.marketMiddleage = marketMiddleage;
|
||||
|
||||
// //
|
||||
// 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;
|
||||
|
||||
//
|
||||
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,222 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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;
|
||||
};
|
||||
|
||||
//
|
||||
// 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,592 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 xWaitForLongSignals = true;
|
||||
static bool xCloseLongTrades = false;
|
||||
|
||||
//
|
||||
static bool xWaitForShortSignals = true;
|
||||
static bool xCloseShortTrades = false;
|
||||
|
||||
//
|
||||
bool isLastTrendUp = 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 isCrossUnder =
|
||||
isTrendingDown
|
||||
&& !isTrendingUp
|
||||
;
|
||||
|
||||
//
|
||||
bool isCrossOver =
|
||||
isTrendingUp
|
||||
&& !isTrendingDown
|
||||
;
|
||||
|
||||
// //
|
||||
// if (isTrendingUp && !isTrendingDown) {
|
||||
// isLastTrendUp = true;
|
||||
// } else if (isTrendingDown && !isTrendingUp) {
|
||||
// isLastTrendUp = false;
|
||||
// }
|
||||
|
||||
//
|
||||
// if (isLastTrendUp) {
|
||||
//
|
||||
// LogMessage(
|
||||
// StringConcatenate(
|
||||
// "isLastTrendUp: ", isLastTrendUp
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
|
||||
//
|
||||
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 =
|
||||
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;
|
||||
|
||||
// //
|
||||
// if (isTrendingUp && !isTrendingDown) {
|
||||
// isLastTrendUp = true;
|
||||
// } else if (isTrendingDown && !isTrendingUp) {
|
||||
// isLastTrendUp = false;
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (isLastTrendUp) {
|
||||
// //
|
||||
// LogMessage(
|
||||
// StringConcatenate(
|
||||
// "isLastTrendUp: ", isLastTrendUp
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
|
||||
//
|
||||
// XOHCL pCandle = GetCandleModel(1);
|
||||
|
||||
//
|
||||
if (signal.type == X_SIGNAL_LONG) {
|
||||
//
|
||||
result =
|
||||
//
|
||||
true
|
||||
//
|
||||
&& isSCTrendUp
|
||||
&& isMCTrendUp
|
||||
&& isLCTrendUp
|
||||
//
|
||||
&& (
|
||||
(
|
||||
states[1].mc.slow < states[1].bnd.low
|
||||
&& states[1].mc.fast < MathMin(states[1].bnd.open, states[1].bnd.close)
|
||||
) || (
|
||||
states[1].lc.fast > states[1].bnd.low
|
||||
&& states[1].lc.fast > states[1].mc.fast
|
||||
)
|
||||
)
|
||||
&& MathAbs(states[1].mc.fast - states[1].bnd.low) > 50 * _Point
|
||||
;
|
||||
} else 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 ...
|
||||
//
|
||||
Reference in New Issue
Block a user