Files
MQL4Data/Bkp/Used/14020425/Libraries/x-saherelm.cci.signal.lib.mq4
T
2024-01-25 04:05:58 +03:30

473 lines
9.6 KiB
Plaintext

///////////////////////////////////////////////////////
//
// 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 ...
//