Files
xMQL4/Packed/XAUUSD-15M/MQL4/Libraries/x-saherelm.xr.signal.lib.mq4
T
2024-01-25 04:03:36 +03:30

1142 lines
23 KiB
Plaintext

///////////////////////////////////////////////////////
//
// 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 Inputs ...
//
//
input string xRStarter = "- XR Signal Provider -"; // --> XR Signal Provider <--
//
input bool enableXRSignalling = true; // XR Signalling Enable
//
input bool enableXRLong = true; // XR Signalling Enable Long
input bool enableXRShort = true; // XR Signalling Enable Short
//
input double xRShortR2R = 1.5; // XR Short Risk To Reward Ratio
input double xRShortLotsPerTradePercent = 0.0002; // XR Lots Percent per Short Trades
input double xRShortMaxDrawdownPerTradePercent = 0.15; // XR Max Allowed DrawDown Percent per Short Trade
//
input double xRLongR2R = 1.5; // XR Long Risk To Reward Ratio
input double xRLongLotsPerTradePercent = 0.0002; // XR Lots Percent per Short Trades
input double xRLongMaxDrawdownPerTradePercent = 0.15; // XR Max Allowed DrawDown Percent per Long Trade
//
input int xRMaximumCandlesPerTrade = 96; // XR Maximum Candles which a Trade can open
//
input int xRSwingLength = 48; // XR Swing Length
//
// END Inputs ...
//
//
input double xRSharpDetectionFactor = 1350; // XR Sharp Detection Factor
//
// START Global Requirement Functions ...
//
//
// XR Market State ...
struct XRMarketState {
//
double fast;
double slow;
double open;
//
double range;
double rangeFast;
double rangeSlow;
double rangeOpen;
//
double verifier;
};
//
// XR Based Signal Conditions ...
struct XRSignalConditions {
datetime startTime;
datetime signalTime;
datetime entryTime;
};
//
static XRSignalConditions xRLongConds;
static bool xRCloseLongTrades = false;
static bool xRWaitForLongSignals = true;
//
static XRSignalConditions xRShortConds;
static bool xRCloseShortTrades = false;
static bool xRWaitForShortSignals = true;
//
// Count Number of Closed Maximum DrawDown Trades ...
static int xRFailedSignals = 0;
//
double xRMaximumDrawDown = 0;
//
int fastLength = 0;
int slowLength = 0;
//
int verifierLength = 0;
//
int rangeFastLength = 0;
int rangeSlowLength = 0;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill Long and Short Signal Handlers ...
void CheckXRSignalHandler(
const int bar_index
) {
//
// Check Market For Enable/Disable Signal Handlers ...
// Checking Market for Long Signals ...
//
if (
!enableXRSignalling
|| !(enableXRLong || enableXRShort)
) {
return;
}
}
//
// Check and Fill Long Signal Conditions ...
void CheckXRLongSignalConditions(
const int bar_index
) {
//
if (
!enableXRLong
|| !enableXRSignalling
) {
return;
}
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// Read Prices ...
XPrice prices = GetPrice();
//
// Read XPVTState ...
XPvtState pvt0 = GetPVTState(
bar_index,
xRSwingLength
);
//
// Double Length Pivots ...
XPvtState dblPvt0 = GetPVTState(
bar_index,
(xRSwingLength * 2)
);
//
// Reading Required Candles ...
XOHCL candle0 = GetCandleModel(bar_index);
XOHCL candle1 = GetCandleModel(bar_index + 1);
XOHCL candle2 = GetCandleModel(bar_index + 2);
XOHCL candle3 = GetCandleModel(bar_index + 3);
//
// Reding Required XRMarketStates ...
XRMarketState state0 = GetXRMarketState(bar_index);
XRMarketState state1 = GetXRMarketState(bar_index + 1);
XRMarketState state2 = GetXRMarketState(bar_index + 2);
XRMarketState state3 = GetXRMarketState(bar_index + 3);
//
// Reading required XRangeStates ...
XRState range0 = ReadXRange(
bar_index + xRSwingLength,
xRSwingLength
);
XRState range1 = ReadXRange(
bar_index + xRSwingLength + 1,
xRSwingLength
);
XRState range2 = ReadXRange(
bar_index + xRSwingLength + 2,
xRSwingLength
);
//
XRState cRange0 = ReadXRange(
bar_index,
xRSwingLength
);
//
// Validate Farest Range Values ...
if (
range2.hh == 0
||
range2.ll == 0
||
range2.mid == 0
) {
return;
}
//
// Reading Required XTPowStates ...
XTPOWState tPow0 = GetXTPowState(
bar_index,
xRSwingLength
);
XTPOWState tPow1 = GetXTPowState(
bar_index + 1,
xRSwingLength
);
XTPOWState tPow2 = GetXTPowState(
bar_index + 2,
xRSwingLength
);
//
// if state verifier below range middle
// this means market is bullish ...
//
// if state verifier above range middle
// this means market is bearish ...
//
//
bool isMarketBullish =
state0.verifier < range0.mid
&& state1.verifier < range1.mid;
bool isMarketBearish =
state0.verifier > range0.mid
&& state1.verifier > range1.mid;
bool isMarketGoingBullish =
state0.verifier > range0.mid
&& !(state1.verifier > range1.mid);
bool isMarketGoingBearish =
state0.verifier < range0.mid
&& !(state1.verifier < range1.mid);
//
// Check Highest High Conditions ...
bool isHHVerified =
!(
pvt0.hh == dblPvt0.hh
)
;
//
int sharpDetectionLength = 7;
double sharpDetectionValue = xRSharpDetectionFactor * _Point;
//
int sharpHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
sharpDetectionLength,
bar_index
);
double sharpHH = iHigh(
_Symbol,
_Period,
sharpHHIdx
);
//
int sharpLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
sharpDetectionLength,
bar_index
);
double sharpLL = iLow(
_Symbol,
_Period,
sharpLLIdx
);
//
double sharpDiff = sharpHH - sharpLL;
bool isSharpOccered =
sharpDiff > sharpDetectionValue;
//
XRMarketState lastState = GetXRMarketState(
bar_index + sharpDetectionLength
);
//
double stateFSDiff = (state0.fast - state0.slow) - (lastState.fast - lastState.slow);
//
// Start Calculating Long Conditions ...
bool longCondition1 =
//
// Starter ...
true
//
&& isMarketBullish
//
&&
(
candle2.high < range2.mid
|| (
candle2.high > range2.mid
&& candle2.low < range2.mid
)
)
&& candle1.low > range1.mid
;
//
if (
//
(
longCondition1
)
//
&& xRLongConds.startTime == 0
&& xRLongConds.entryTime == 0
&& xRLongConds.signalTime == 0
) {
//
xRLongConds.startTime = barTime;
xRLongConds.entryTime = barTime;
xRLongConds.signalTime = barTime;
//
return;
}
}
//
// Check and Fill Short Signal Conditions ...
void CheckXRShortSignalConditions(
const int bar_index
) {
//
if (
!enableXRShort
|| !enableXRSignalling
) {
return;
}
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// Read Prices ...
XPrice prices = GetPrice();
//
// Read XPVTState ...
XPvtState pvt0 = GetPVTState(
bar_index,
xRSwingLength
);
//
// Double Length Pivots ...
XPvtState dblPvt0 = GetPVTState(
bar_index,
(xRSwingLength * 2)
);
//
// Reading Required Candles ...
XOHCL candle0 = GetCandleModel(bar_index);
XOHCL candle1 = GetCandleModel(bar_index + 1);
XOHCL candle2 = GetCandleModel(bar_index + 2);
XOHCL candle3 = GetCandleModel(bar_index + 3);
//
// Reding Required XRMarketStates ...
XRMarketState state0 = GetXRMarketState(bar_index);
XRMarketState state1 = GetXRMarketState(bar_index + 1);
XRMarketState state2 = GetXRMarketState(bar_index + 2);
XRMarketState state3 = GetXRMarketState(bar_index + 3);
//
// Reading required XRangeStates ...
XRState range0 = ReadXRange(
bar_index + xRSwingLength,
xRSwingLength
);
XRState range1 = ReadXRange(
bar_index + xRSwingLength + 1,
xRSwingLength
);
XRState range2 = ReadXRange(
bar_index + xRSwingLength + 2,
xRSwingLength
);
//
XRState cRange0 = ReadXRange(
bar_index,
xRSwingLength
);
//
// Validate Farest Range Values ...
if (
range2.hh == 0
||
range2.ll == 0
||
range2.mid == 0
) {
return;
}
//
// Reading Required XTPowStates ...
XTPOWState tPow0 = GetXTPowState(
bar_index,
xRSwingLength
);
XTPOWState tPow1 = GetXTPowState(
bar_index + 1,
xRSwingLength
);
XTPOWState tPow2 = GetXTPowState(
bar_index + 2,
xRSwingLength
);
//
// if state verifier below range middle
// this means market is bullish ...
//
// if state verifier above range middle
// this means market is bearish ...
//
//
bool isMarketBullish =
state0.verifier < range0.mid
&& state1.verifier < range1.mid;
bool isMarketBearish =
state0.verifier > range0.mid
&& state1.verifier > range1.mid;
bool isMarketGoingBullish =
state0.verifier > range0.mid
&& !(state1.verifier > range1.mid);
bool isMarketGoingBearish =
state0.verifier < range0.mid
&& !(state1.verifier < range1.mid);
//
// Check Highest High Conditions ...
bool isHHVerified =
!(
pvt0.hh == dblPvt0.hh
)
;
//
int sharpDetectionLength = 7;
double sharpDetectionValue = xRSharpDetectionFactor * _Point;
//
int sharpHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
sharpDetectionLength,
bar_index
);
double sharpHH = iHigh(
_Symbol,
_Period,
sharpHHIdx
);
//
int sharpLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
sharpDetectionLength,
bar_index
);
double sharpLL = iLow(
_Symbol,
_Period,
sharpLLIdx
);
//
double sharpDiff = sharpHH - sharpLL;
bool isSharpOccered =
sharpDiff > sharpDetectionValue;
//
XRMarketState lastState = GetXRMarketState(
bar_index + sharpDetectionLength
);
//
double stateFSDiff = (state0.fast - state0.slow) - (lastState.fast - lastState.slow);
//
// Start Calculating Long Conditions ...
bool shortCondition1 =
//
// Starter ...
true
//
&& isMarketBearish
//
&&
(
candle2.low > range2.mid
|| (
candle2.high > range2.mid
&& candle2.low < range2.mid
)
)
&& candle1.high < range1.mid
;
//
if (
//
(
shortCondition1
)
//
&& xRShortConds.startTime == 0
&& xRShortConds.entryTime == 0
&& xRShortConds.signalTime == 0
) {
//
xRShortConds.startTime = barTime;
xRShortConds.entryTime = barTime;
xRShortConds.signalTime = barTime;
//
return;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateXRSignal(
const ENUM_X_SIGNAL_TYPE type, // Signal Type ...
const string signalTag , // Signal Tag ...
const int bar_index
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (
!enableXRSignalling
|| !(enableXRLong || enableXRShort)
) {
return result;
}
//
bool requestLong = type == X_SIGNAL_LONG;
//
if (requestLong) {
//
if (
!ValidateXRLongConditions()
) {
return result;
}
} else {
//
if (
!ValidateXRShortConditions()
) {
return result;
}
}
//
// Price Calculations ...
XPvtState pvts = GetPVTState(
bar_index,
xRSwingLength
);
XPrice prices = GetPrice();
//
double entryPrice = requestLong ?
prices.longEntry :
prices.shortEntry
;
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = requestLong ?
MathMin(openPrice, closePrice) - pvts.ll :
pvts.hh - MathMax(openPrice, closePrice);
if (risk <= 0) {
//
risk = requestLong ?
MathAbs(pvts.hh - entryPrice) :
MathAbs(pvts.ll - entryPrice)
;
}
//
double reward =
requestLong ?
risk * xRLongR2R :
risk * xRShortR2R
;
//
double sl = requestLong ?
0 :
0;
//
double tp = requestLong ?
entryPrice + reward :
entryPrice - reward
;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.type = type;
result.signal.time = barTime;
result.signal.tag = signalTag;
result.signal.symbol = _Symbol;
result.signal.entry = entryPrice;
result.signal.id = totalSignals + 1;
result.signal.provider = X_XR_PROVIDER;
//
result.hasSignal = true;
result.type = type;
result.provider = X_XR_PROVIDER;
//
return result;
}
//
// Validate Long Signal Conditions ...
bool ValidateXRLongConditions() {
//
if (
!enableXRLong
|| !enableXRSignalling
) {
return false;
}
//
bool isConditionsFilled =
xRLongConds.startTime > 0
&& xRLongConds.signalTime > 0
&& xRLongConds.entryTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
isBLFilled =
//
xRLongConds.signalTime >= xRLongConds.startTime
&& xRLongConds.entryTime >= xRLongConds.signalTime
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
&& xRWaitForLongSignals
;
//
// 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
) {
ClearXRLongSignalConditions();
}
//
return result;
}
//
// Validate Short Signal Conditions ...
bool ValidateXRShortConditions() {
//
if (
!enableXRShort
|| !enableXRSignalling
) {
return false;
}
//
bool isConditionsFilled =
xRShortConds.startTime > 0
&& xRShortConds.signalTime > 0
&& xRShortConds.entryTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
isBLFilled =
//
xRShortConds.signalTime >= xRShortConds.startTime
&& xRShortConds.entryTime >= xRShortConds.signalTime
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
&& xRWaitForShortSignals
;
//
// 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
) {
ClearXRShortSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXRLongSignalConditions() {
//
xRLongConds.startTime = 0;
xRLongConds.signalTime = 0;
xRLongConds.entryTime = 0;
}
//
// Clear Short Signal Conditions for New One ...
void ClearXRShortSignalConditions() {
//
xRShortConds.startTime = 0;
xRShortConds.signalTime = 0;
xRShortConds.entryTime = 0;
}
//
// Check State for Long Signals ...
bool IsReadyForXRSignals(
const XSignal &signal
) {
//
bool result = false;
//
if (
!enableXRSignalling
|| !(enableXRLong || enableXRShort)
) {
return result;
}
//
// Find Signal Bar Index ...
int signalBarIndex = iBarShift(
_Symbol,
_Period,
signal.time
);
//
// Read Prices ...
XPrice prices = GetPrice();
//
// Read XPVTState ...
XPvtState pvt0 = GetPVTState(
signalBarIndex,
xRSwingLength
);
//
// Reading Required Candles ...
XOHCL candle0 = GetCandleModel(signalBarIndex);
XOHCL candle1 = GetCandleModel(signalBarIndex + 1);
XOHCL candle2 = GetCandleModel(signalBarIndex + 2);
XOHCL candle3 = GetCandleModel(signalBarIndex + 3);
//
// Reding Required XRMarketStates ...
XRMarketState state0 = GetXRMarketState(signalBarIndex);
XRMarketState state1 = GetXRMarketState(signalBarIndex + 1);
XRMarketState state2 = GetXRMarketState(signalBarIndex + 2);
XRMarketState state3 = GetXRMarketState(signalBarIndex + 3);
//
// Reading required XRangeStates ...
XRState range0 = ReadXRange(
signalBarIndex + xRSwingLength,
xRSwingLength
);
XRState range1 = ReadXRange(
signalBarIndex + xRSwingLength + 1,
xRSwingLength
);
XRState range2 = ReadXRange(
signalBarIndex + xRSwingLength + 2,
xRSwingLength
);
//
// Reading Required XTPowStates ...
XTPOWState tPow0 = GetXTPowState(
signalBarIndex,
xRSwingLength
);
XTPOWState tPow1 = GetXTPowState(
signalBarIndex + 1,
xRSwingLength
);
XTPOWState tPow2 = GetXTPowState(
signalBarIndex + 2,
xRSwingLength
);
//
double hhllDiff = MathAbs(pvt0.hh - pvt0.ll);
double sharpDetectionValue = xRSharpDetectionFactor * _Point;
bool isSharpOccured = hhllDiff > sharpDetectionValue;
//
// Calculate State Min Max Diff ...
//
double state0Min = MathMin(state0.fast, state0.slow);
state0Min = MathMin(state0Min, state0.open);
state0Min = MathMin(state0Min, state0.rangeFast);
state0Min = MathMin(state0Min, state0.rangeSlow);
state0Min = MathMin(state0Min, state0.rangeOpen);
state0Min = MathMin(state0Min, state0.verifier);
//
double state0Max = MathMax(state0.fast, state0.slow);
state0Max = MathMax(state0Max, state0.open);
state0Max = MathMax(state0Max, state0.rangeFast);
state0Max = MathMax(state0Max, state0.rangeSlow);
state0Max = MathMax(state0Max, state0.rangeOpen);
state0Max = MathMax(state0Max, state0.verifier);
//
double state0MinMaxDiff = (state0Max - state0Min);
//
bool isTPowValid = false;
bool isStateValid = false;
bool isRangeValid = false;
//
// Verify Long Signals ...
if (signal.type == X_SIGNAL_LONG) {
//
// Retrieve TPow Verifications ...
isTPowValid =
//
// Starter ...
true
;
//
// Retrieve XMarket Verifications ...
isStateValid =
//
// Starter ...
true
//
// && !(state0MinMaxDiff > sharpDetectionValue)
;
//
// Retrieve XRange Verifications ...
isRangeValid =
//
// Starter ...
true
;
//
result =
//
// Starter ...
true
//
&& isTPowValid
&& isStateValid
&& isRangeValid
;
} else
//
// Verify Short Signals ...
if (signal.type == X_SIGNAL_SHORT) {
//
// Retrieve TPow Verifications ...
isTPowValid =
//
// Starter ...
true
;
//
// Retrieve XMarket Verifications ...
isStateValid =
//
// Starter ...
true
;
//
// Retrieve XRange Verifications ...
isRangeValid =
//
// Starter ...
true
;
//
result =
//
// Starter ...
true
//
&& isTPowValid
&& isStateValid
&& isRangeValid
;
}
//
return result;
}
//
// END Functions ...
//
//
// START Data Providers ...
//
//
XRMarketState GetXRMarketState(
const int bar_index
) {
//
XRMarketState result = {};
//
// Calculate Market Lengths ...
//
if (fastLength == 0) {
fastLength = xRSwingLength;
}
//
if (slowLength == 0) {
slowLength = xRSwingLength * 2;
}
//
if (verifierLength == 0) {
verifierLength = (GetDailyCandleCount() * 2);
}
//
if (rangeFastLength == 0) {
rangeFastLength = (int)(verifierLength / 2);
}
//
if (rangeSlowLength == 0) {
rangeSlowLength = verifierLength;
}
//
// Reading Values ...
//
double fast = GetMA(
bar_index,
fastLength,
0,
MODE_SMA,
PRICE_CLOSE
);
//
double slow = GetMA(
bar_index,
slowLength,
0,
MODE_SMA,
PRICE_CLOSE
);
//
double open = GetMA(
bar_index,
fastLength,
0,
MODE_SMA,
PRICE_OPEN
);
//
double rangeFast = GetMA(
bar_index,
rangeFastLength,
0,
MODE_SMA,
PRICE_CLOSE
);
//
double rangeSlow = GetMA(
bar_index,
rangeSlowLength,
0,
MODE_SMA,
PRICE_CLOSE
);
//
double rangeOpen = GetMA(
bar_index,
rangeFastLength,
0,
MODE_SMA,
PRICE_OPEN
);
//
double verifier = GetMA(
bar_index,
verifierLength,
0,
MODE_EMA,
PRICE_MEDIAN
);
//
// Filling Result ...
result.fast = fast;
result.slow = slow;
result.open = open;
result.verifier = verifier;
result.rangeFast = rangeFast;
result.rangeSlow = rangeSlow;
result.rangeOpen = rangeOpen;
//
return result;
}
//
// END Data Providers ...
//