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

364 lines
7.0 KiB
Plaintext

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