Initial Commit ...
This commit is contained in:
@@ -0,0 +1,720 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL4 XTPW Signal Global Library
|
||||
// ---------------------------------------------------
|
||||
// XSaherElm EA Signal Provider based on
|
||||
// XTPow Indicator...
|
||||
//
|
||||
//
|
||||
// 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 xTPWStarter = "- XTPW Signal Provider -"; // ---> XTPW Signal Provider <---
|
||||
|
||||
//
|
||||
input bool enableXTPWSignalling = true; // XTPW Signalling Enable
|
||||
|
||||
//
|
||||
input double xTPWR2R = 2.5; // XTPW Risk To Reward Ratio
|
||||
input int xTPWMaximumCandlesPerTrade = 206; // XTPW Maximum Candles which a Trade can open
|
||||
|
||||
//
|
||||
input double xTPWPSarStep = 0.02; // XTPW Parabolic Sar Step
|
||||
input double xTPWPSarMaximum = 0.2; // XTPW Parabolic Sar Maximum
|
||||
|
||||
//
|
||||
input int xTPWSwingLength = 7; // XTPW Signal Swing Length
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Requirement Functions ...
|
||||
//
|
||||
//
|
||||
// XTPW Based Signal Conditions ...
|
||||
struct XTPWSignalConditions {
|
||||
datetime startTime;
|
||||
datetime signalTime;
|
||||
datetime entryTime;
|
||||
};
|
||||
|
||||
//
|
||||
struct XTPWMarketState {
|
||||
double psar;
|
||||
double fast;
|
||||
double slow;
|
||||
double verifier;
|
||||
};
|
||||
|
||||
//
|
||||
static XTPWSignalConditions xTPWLongConds;
|
||||
static bool xTPWCloseLongTrades = false;
|
||||
static bool xTPWWaitForLongSignals = true;
|
||||
|
||||
//
|
||||
static XTPWSignalConditions xTPWShortConds;
|
||||
static bool xTPWCloseShortTrades = false;
|
||||
static bool xTPWWaitForShortSignals = true;
|
||||
//
|
||||
// END Global Requirement Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Check and Fill Long and Short Signal Handlers ...
|
||||
void CheckXTPWSignalHandler(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
// Check Market For Enable/Disable Signal Handlers ...
|
||||
// Checking Market for Long Signals ...
|
||||
|
||||
//
|
||||
if (!enableXTPWSignalling) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
datetime barTime = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
XOHCL candle = GetCandleModel(bar_index);
|
||||
XOHCL pCandle = GetCandleModel(bar_index + 1);
|
||||
}
|
||||
|
||||
//
|
||||
// Check and Fill Long Signal Conditions ...
|
||||
void CheckXTPWLongSignalConditions(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
if (
|
||||
!enableXTPWSignalling
|
||||
|| !xTPWWaitForLongSignals
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
datetime barTime = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
bool startCondition = false;
|
||||
bool signalCondition = false;
|
||||
|
||||
//
|
||||
if (
|
||||
startCondition
|
||||
&& xTPWLongConds.startTime == 0
|
||||
) {
|
||||
//
|
||||
xTPWLongConds.startTime = barTime;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (
|
||||
signalCondition
|
||||
&& xTPWLongConds.startTime > 0
|
||||
&& xTPWLongConds.signalTime == 0
|
||||
) {
|
||||
//
|
||||
xTPWLongConds.signalTime = barTime;
|
||||
xTPWLongConds.entryTime = barTime;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check and Fill Short Signal Conditions ...
|
||||
void CheckXShortSignalConditions(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
if (
|
||||
!enableXTPWSignalling
|
||||
|| !xTPWWaitForShortSignals
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
datetime barTime = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
bool startCondition = false;
|
||||
bool signalCondition = false;
|
||||
|
||||
//
|
||||
if (
|
||||
startCondition
|
||||
&& xTPWShortConds.startTime == 0
|
||||
) {
|
||||
//
|
||||
xTPWShortConds.startTime = barTime;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (
|
||||
signalCondition
|
||||
&& xTPWShortConds.startTime > 0
|
||||
&& xTPWShortConds.signalTime == 0
|
||||
) {
|
||||
//
|
||||
xTPWShortConds.signalTime = barTime;
|
||||
xTPWShortConds.entryTime = barTime;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Convert Long Signal Conditions to XSignal ...
|
||||
XSignalRequest GenerateXTPWSignal(
|
||||
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 (!enableXTPWSignalling) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
bool requestLong = type == X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
if (requestLong) {
|
||||
//
|
||||
if (
|
||||
!ValidateXTPWLongConditions()
|
||||
) {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
if (
|
||||
!ValidateXTPWShortConditions()
|
||||
) {
|
||||
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,
|
||||
xTPWSwingLength
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
double hh =
|
||||
//
|
||||
GetMarketHighestHigh(
|
||||
bar_index,
|
||||
xTPWSwingLength
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
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 * xTPWR2R;
|
||||
|
||||
//
|
||||
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_XXX_PROVIDER;
|
||||
|
||||
//
|
||||
result.hasSignal = true;
|
||||
result.type = type;
|
||||
result.provider = X_XXX_PROVIDER;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Signal Conditions ...
|
||||
bool ValidateXTPWLongConditions() {
|
||||
//
|
||||
if (!enableXTPWSignalling) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
bool isConditionsFilled =
|
||||
xTPWLongConds.startTime > 0
|
||||
&& xTPWLongConds.signalTime > 0
|
||||
&& xTPWLongConds.entryTime > 0
|
||||
;
|
||||
|
||||
//
|
||||
bool isBLFilled = false;
|
||||
if (isConditionsFilled) {
|
||||
//
|
||||
int startBarIndex = iBarShift(
|
||||
_Symbol,
|
||||
_Period,
|
||||
xTPWLongConds.startTime
|
||||
);
|
||||
|
||||
//
|
||||
int signalBarIndex = iBarShift(
|
||||
_Symbol,
|
||||
_Period,
|
||||
xTPWLongConds.signalTime
|
||||
);
|
||||
|
||||
//
|
||||
int entryBarIndex = iBarShift(
|
||||
_Symbol,
|
||||
_Period,
|
||||
xTPWLongConds.entryTime
|
||||
);
|
||||
|
||||
//
|
||||
isBLFilled =
|
||||
//
|
||||
xTPWLongConds.signalTime > xTPWLongConds.startTime
|
||||
&& xTPWLongConds.entryTime >= xTPWLongConds.signalTime
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
bool result =
|
||||
isBLFilled
|
||||
&& isConditionsFilled
|
||||
&& xTPWWaitForLongSignals
|
||||
;
|
||||
|
||||
//
|
||||
// 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
|
||||
) {
|
||||
ClearXTPWLongSignalConditions();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Signal Conditions ...
|
||||
bool ValidateXTPWShortConditions() {
|
||||
//
|
||||
if (!enableXTPWSignalling) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
bool isConditionsFilled =
|
||||
xTPWShortConds.startTime > 0
|
||||
&& xTPWShortConds.signalTime > 0
|
||||
&& xTPWShortConds.entryTime > 0
|
||||
;
|
||||
|
||||
//
|
||||
bool isBLFilled = false;
|
||||
if (isConditionsFilled) {
|
||||
//
|
||||
int startBarIndex = iBarShift(
|
||||
_Symbol,
|
||||
_Period,
|
||||
xTPWShortConds.startTime
|
||||
);
|
||||
|
||||
//
|
||||
int signalBarIndex = iBarShift(
|
||||
_Symbol,
|
||||
_Period,
|
||||
xTPWShortConds.signalTime
|
||||
);
|
||||
|
||||
//
|
||||
int entryBarIndex = iBarShift(
|
||||
_Symbol,
|
||||
_Period,
|
||||
xTPWShortConds.entryTime
|
||||
);
|
||||
|
||||
//
|
||||
isBLFilled =
|
||||
//
|
||||
xTPWShortConds.signalTime > xTPWShortConds.startTime
|
||||
&& xTPWShortConds.entryTime >= xTPWShortConds.signalTime
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
bool result =
|
||||
isBLFilled
|
||||
&& isConditionsFilled
|
||||
&& xTPWWaitForShortSignals
|
||||
;
|
||||
|
||||
//
|
||||
// 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
|
||||
) {
|
||||
ClearXTPWShortSignalConditions();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Clear Long Signal Conditions for New One ...
|
||||
void ClearXTPWLongSignalConditions() {
|
||||
//
|
||||
xTPWLongConds.startTime = 0;
|
||||
xTPWLongConds.entryTime = 0;
|
||||
xTPWLongConds.signalTime = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Clear Short Signal Conditions for New One ...
|
||||
void ClearXTPWShortSignalConditions() {
|
||||
//
|
||||
xTPWShortConds.startTime = 0;
|
||||
xTPWShortConds.entryTime = 0;
|
||||
xTPWShortConds.signalTime = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Check State for Long Signals ...
|
||||
bool IsReadyForXTPWSignals(
|
||||
const XSignal &signal
|
||||
) {
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (!enableXTPWSignalling) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int signalBarIndex = iBarShift(
|
||||
_Symbol,
|
||||
_Period,
|
||||
signal.time
|
||||
);
|
||||
|
||||
//
|
||||
// XOHCL candle = GetCandleModel(0);
|
||||
XOHCL candle = GetCandleModel(signalBarIndex);
|
||||
XOHCL pCandle = GetCandleModel(signalBarIndex + 1);
|
||||
|
||||
//
|
||||
// Retrive XMarket States ...
|
||||
|
||||
//
|
||||
double hh = GetMarketHighestHigh(
|
||||
signalBarIndex,
|
||||
xTPWSwingLength
|
||||
);
|
||||
double ll = GetMarketLowestLow(
|
||||
signalBarIndex,
|
||||
xTPWSwingLength
|
||||
);
|
||||
double diffChange = (hh - ll);
|
||||
bool isBigSharpOccured =
|
||||
diffChange > (600 * _Point)
|
||||
;
|
||||
|
||||
//
|
||||
bool isPSarVerified = false;
|
||||
bool isTPowVerified = false;
|
||||
bool isStateVerified = false;
|
||||
bool isPriceVerified = false;
|
||||
|
||||
//
|
||||
// Verify Long Signals ...
|
||||
if (signal.type == X_SIGNAL_LONG) {
|
||||
//
|
||||
// Get Price Verification for Long ...
|
||||
isPriceVerified =
|
||||
//
|
||||
// Starter ...
|
||||
true
|
||||
;
|
||||
|
||||
//
|
||||
isTPowVerified =
|
||||
//
|
||||
// Starter ...
|
||||
true
|
||||
;
|
||||
|
||||
//
|
||||
isPSarVerified =
|
||||
//
|
||||
// Starter ...
|
||||
true
|
||||
;
|
||||
|
||||
//
|
||||
isStateVerified =
|
||||
//
|
||||
// Start ...
|
||||
true
|
||||
;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
// Starter ...
|
||||
true
|
||||
//
|
||||
&& isPSarVerified
|
||||
//
|
||||
&& isTPowVerified
|
||||
//
|
||||
&& isStateVerified
|
||||
//
|
||||
&& isPriceVerified
|
||||
;
|
||||
} else
|
||||
//
|
||||
// Verify Short Signals ...
|
||||
if (signal.type == X_SIGNAL_SHORT) {
|
||||
//
|
||||
isPSarVerified =
|
||||
//
|
||||
// Starter ...
|
||||
true
|
||||
;
|
||||
|
||||
//
|
||||
// Get Price Verification for Short ...
|
||||
isPriceVerified =
|
||||
//
|
||||
// Starter ...
|
||||
true
|
||||
;
|
||||
|
||||
//
|
||||
isTPowVerified =
|
||||
//
|
||||
// Starter ...
|
||||
true
|
||||
;
|
||||
|
||||
//
|
||||
isStateVerified =
|
||||
//
|
||||
// Start ...
|
||||
true
|
||||
;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
// Starter Condition ...
|
||||
true
|
||||
//
|
||||
&& isPSarVerified
|
||||
//
|
||||
&& isTPowVerified
|
||||
//
|
||||
&& isStateVerified
|
||||
//
|
||||
&& isPriceVerified
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Data Provider ...
|
||||
//
|
||||
XTPWMarketState GetXMTPWarketState(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
XTPWMarketState result = {};
|
||||
|
||||
//
|
||||
double fast = GetMA(
|
||||
bar_index,
|
||||
xTPWSwingLength,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_CLOSE
|
||||
);
|
||||
|
||||
//
|
||||
double slow = GetMA(
|
||||
bar_index,
|
||||
xTPWSwingLength * 2,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_CLOSE
|
||||
);
|
||||
|
||||
//
|
||||
int dailyCount = GetDailyCandleCount();
|
||||
double verifier = GetMA(
|
||||
bar_index,
|
||||
dailyCount,
|
||||
0,
|
||||
MODE_EMA,
|
||||
PRICE_MEDIAN
|
||||
);
|
||||
|
||||
//
|
||||
double psar = iSAR(
|
||||
_Symbol,
|
||||
_Period,
|
||||
xTPWPSarStep,
|
||||
xTPWPSarMaximum,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
result.psar = psar;
|
||||
result.fast = fast;
|
||||
result.slow = slow;
|
||||
result.verifier = verifier;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END Data Provider ...
|
||||
//
|
||||
Reference in New Issue
Block a user