1252 lines
25 KiB
Plaintext
1252 lines
25 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// 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 bool enableXTPWLong = true; // XTPW Signalling Enable Long
|
|
input bool enableXTPWShort = false; // XTPW Signalling Enable Short
|
|
|
|
//
|
|
input double xTPWShortR2R = 2; // XTPW Short Risk To Reward Ratio
|
|
input double xTPWShortLotsPerTradePercent = 0.0002; // XTPW Lots Percent per Short Trades
|
|
input double xTPWShortMaxDrawdownPerTradePercent = 0.3; // XTPW Max Allowed DrawDown Percent per Short Trade
|
|
|
|
//
|
|
input double xTPWLongR2R = 3; // XTPW Long Risk To Reward Ratio
|
|
input double xTPWLongLotsPerTradePercent = 0.00001; // XTPW Lots Percent per Short Trades
|
|
input double xTPWLongMaxDrawdownPerTradePercent = 0.03; // XTPW Max Allowed DrawDown Percent per Long Trade
|
|
|
|
//
|
|
input int xTPWMaximumCandlesPerTrade = 144; // 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 ...
|
|
//
|
|
|
|
//
|
|
input double xTPWSharpDetectionFactor = 650; // XTPW Sharp Detection Factor
|
|
|
|
//
|
|
// START Global Requirement Functions ...
|
|
//
|
|
//
|
|
// XTPW Based Signal Conditions ...
|
|
struct XTPWSignalConditions {
|
|
datetime startTime;
|
|
datetime signalTime;
|
|
datetime entryTime;
|
|
};
|
|
|
|
//
|
|
struct XTPWMarketState {
|
|
//
|
|
double psar;
|
|
|
|
//
|
|
double scFast;
|
|
double scSlow;
|
|
double scWeight;
|
|
|
|
//
|
|
double mcFast;
|
|
double mcSlow;
|
|
double mcWeight;
|
|
|
|
//
|
|
double lcFast;
|
|
double lcSlow;
|
|
double lcWeight;
|
|
};
|
|
|
|
//
|
|
struct XLHS {
|
|
//
|
|
double scHH;
|
|
double scLL;
|
|
|
|
//
|
|
double mcHH;
|
|
double mcLL;
|
|
|
|
//
|
|
double lcHH;
|
|
double lcLL;
|
|
};
|
|
|
|
//
|
|
static XTPWSignalConditions xTPWLongConds;
|
|
static bool xTPWCloseLongTrades = false;
|
|
static bool xTPWWaitForLongSignals = true;
|
|
|
|
//
|
|
static XTPWSignalConditions xTPWShortConds;
|
|
static bool xTPWCloseShortTrades = false;
|
|
static bool xTPWWaitForShortSignals = true;
|
|
|
|
//
|
|
// Count Number of Closed Maximum DrawDown Trades ...
|
|
static int xTPWFailedSignals = 0;
|
|
|
|
//
|
|
double tPowerVerifier = 20;
|
|
double tPowerMaxVerifier = 55;
|
|
|
|
//
|
|
int scFastLength = 0;
|
|
int scSlowLength = 0;
|
|
|
|
//
|
|
int mcFastLength = 0;
|
|
int mcSlowLength = 0;
|
|
|
|
//
|
|
int lcFastLength = 0;
|
|
int lcSlowLength = 0;
|
|
|
|
//
|
|
datetime lastTurnOffLongTradesTime;
|
|
datetime lastTurnOffShortTradesTime;
|
|
//
|
|
// 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
|
|
|| !(enableXTPWLong || enableXTPWShort)
|
|
) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
datetime barTime = iTime(
|
|
_Symbol,
|
|
_Period,
|
|
bar_index
|
|
);
|
|
|
|
//
|
|
XOHCL candle0 = GetCandleModel(bar_index);
|
|
XOHCL candle1 = GetCandleModel(bar_index + 1);
|
|
XOHCL candle2 = GetCandleModel(bar_index + 1);
|
|
|
|
//
|
|
XTPOWState tPow0 = GetXTPowState(
|
|
bar_index,
|
|
xTPWSwingLength
|
|
);
|
|
XTPOWState tPow1 = GetXTPowState(
|
|
bar_index + 1,
|
|
xTPWSwingLength
|
|
);
|
|
XTPOWState tPow2 = GetXTPowState(
|
|
bar_index + 2,
|
|
xTPWSwingLength
|
|
);
|
|
|
|
//
|
|
XTPWMarketState state0 = GetXTPWMarketState(
|
|
bar_index
|
|
);
|
|
XTPWMarketState state1 = GetXTPWMarketState(
|
|
bar_index + 1
|
|
);
|
|
XTPWMarketState state2 = GetXTPWMarketState(
|
|
bar_index + 2
|
|
);
|
|
|
|
// //
|
|
// // Disable Long Conditions ...
|
|
// if (
|
|
// xTPWWaitForLongSignals
|
|
// &&
|
|
// (
|
|
// isRangeCrossOverRangeWeight
|
|
// ||
|
|
// isRangeCrossUnderRangeWeight
|
|
// ||
|
|
// isTPowUpperAboveMaxVerifier
|
|
// )
|
|
// ) {
|
|
// //
|
|
// xTPWWaitForLongSignals = false;
|
|
// lastTurnOffLongTradesTime = barTime;
|
|
// }
|
|
|
|
// //
|
|
// // Enable Long Conditions ...
|
|
// if (
|
|
// !xTPWWaitForLongSignals
|
|
// && lastTurnOffLongTradesTime > 0
|
|
// && (
|
|
// // isFastCrossOverSlow
|
|
// // ||
|
|
// // isFastCrossUnderSlow
|
|
// isRangeCrossOverRangeWeight
|
|
// ||
|
|
// isRangeCrossUnderRangeWeight
|
|
// ||
|
|
// isTPowUpperBelowMaxVerifier
|
|
// )
|
|
// ) {
|
|
// //
|
|
// // Find Last Turn Off Bar Index ...
|
|
// int lastTurnOffLongTradesBarIndex = iBarShift(
|
|
// _Symbol,
|
|
// _Period,
|
|
// lastTurnOffLongTradesTime
|
|
// );
|
|
|
|
// //
|
|
// // the Distance must be bigger than market length ...
|
|
// if (MathAbs(lastTurnOffLongTradesBarIndex - bar_index) > xTPWSwingLength) {
|
|
// //
|
|
// xTPWWaitForLongSignals = true;
|
|
// lastTurnOffLongTradesTime = 0;
|
|
// }
|
|
// }
|
|
}
|
|
|
|
//
|
|
// Check and Fill Long Signal Conditions ...
|
|
void CheckXTPWLongSignalConditions(
|
|
const int bar_index
|
|
) {
|
|
//
|
|
if (
|
|
!enableXTPWLong
|
|
|| !enableXTPWSignalling
|
|
|| !xTPWWaitForLongSignals
|
|
) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
datetime barTime = iTime(
|
|
_Symbol,
|
|
_Period,
|
|
bar_index
|
|
);
|
|
|
|
//
|
|
// Retrieve TPow States ...
|
|
XTPOWState tPow0 = GetXTPowState(
|
|
bar_index,
|
|
xTPWSwingLength
|
|
);
|
|
XTPOWState tPow1 = GetXTPowState(
|
|
bar_index + 1,
|
|
xTPWSwingLength
|
|
);
|
|
XTPOWState tPow2 = GetXTPowState(
|
|
bar_index + 2,
|
|
xTPWSwingLength
|
|
);
|
|
|
|
//
|
|
// Retrieve TPowMarket State ...
|
|
XTPWMarketState state0 = GetXTPWMarketState(
|
|
bar_index
|
|
);
|
|
XTPWMarketState state1 = GetXTPWMarketState(
|
|
bar_index + 1
|
|
);
|
|
XTPWMarketState state2 = GetXTPWMarketState(
|
|
bar_index + 2
|
|
);
|
|
|
|
//
|
|
// Retrieve XPrice Model ...
|
|
XPrice prices = GetPrice();
|
|
|
|
//
|
|
// Retrieve Candles ...
|
|
XOHCL candle0 = GetCandleModel(bar_index);
|
|
XOHCL candle1 = GetCandleModel(bar_index + 1);
|
|
XOHCL candle2 = GetCandleModel(bar_index + 2);
|
|
|
|
//
|
|
XLHS lhs = GetXTPWLHS(bar_index);
|
|
|
|
//
|
|
bool isHHSame =
|
|
lhs.scHH == lhs.mcHH
|
|
&& lhs.mcHH == lhs.lcHH
|
|
;
|
|
|
|
//
|
|
bool isLLSame =
|
|
lhs.scLL == lhs.mcLL
|
|
&& lhs.mcLL == lhs.lcLL
|
|
;
|
|
|
|
//
|
|
bool startCondition = false;
|
|
bool signalCondition = false;
|
|
bool entryCondition = false;
|
|
|
|
//
|
|
bool longCondition1 =
|
|
//
|
|
true
|
|
//
|
|
&& tPow2.powerDown > tPow2.powerUp
|
|
&& tPow1.powerUp > tPow1.powerDown
|
|
&& tPow1.powerUp > tPowerVerifier
|
|
&& tPow1.powerUp < tPowerMaxVerifier
|
|
;
|
|
|
|
//
|
|
// Start Conditions ...
|
|
startCondition = (
|
|
longCondition1
|
|
)
|
|
;
|
|
|
|
//
|
|
if (
|
|
startCondition
|
|
&& xTPWLongConds.startTime == 0
|
|
&& xTPWLongConds.signalTime == 0
|
|
&& xTPWLongConds.entryTime == 0
|
|
) {
|
|
//
|
|
xTPWLongConds.startTime = barTime;
|
|
xTPWLongConds.signalTime = barTime;
|
|
xTPWLongConds.entryTime = barTime;
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check and Fill Short Signal Conditions ...
|
|
void CheckXTPWShortSignalConditions(
|
|
const int bar_index
|
|
) {
|
|
//
|
|
if (
|
|
!enableXTPWShort
|
|
|| !enableXTPWSignalling
|
|
|| !xTPWWaitForShortSignals
|
|
) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
datetime barTime = iTime(
|
|
_Symbol,
|
|
_Period,
|
|
bar_index
|
|
);
|
|
|
|
//
|
|
// Retrieve TPower State ...
|
|
XTPOWState tPow0 = GetXTPowState(
|
|
bar_index,
|
|
xTPWSwingLength
|
|
);
|
|
XTPOWState tPow1 = GetXTPowState(
|
|
bar_index + 1,
|
|
xTPWSwingLength
|
|
);
|
|
XTPOWState tPow2 = GetXTPowState(
|
|
bar_index + 2,
|
|
xTPWSwingLength
|
|
);
|
|
|
|
//
|
|
// Retrieve TPWMarket State ...
|
|
XTPWMarketState state0 = GetXTPWMarketState(
|
|
bar_index
|
|
);
|
|
XTPWMarketState state1 = GetXTPWMarketState(
|
|
bar_index + 1
|
|
);
|
|
XTPWMarketState state2 = GetXTPWMarketState(
|
|
bar_index + 2
|
|
);
|
|
|
|
//
|
|
// Retrieve Candles ...
|
|
XOHCL candle0 = GetCandleModel(bar_index);
|
|
XOHCL candle1 = GetCandleModel(bar_index + 1);
|
|
XOHCL candle2 = GetCandleModel(bar_index + 2);
|
|
|
|
//
|
|
XPrice prices = GetPrice();
|
|
XLHS lhs = GetXTPWLHS(bar_index);
|
|
|
|
//
|
|
double sharpDetectionValue =
|
|
xTPWSharpDetectionFactor * _Point;
|
|
|
|
//
|
|
bool isHHSame =
|
|
lhs.scHH == lhs.mcHH
|
|
&& lhs.mcHH == lhs.lcHH
|
|
;
|
|
|
|
//
|
|
bool isLLSame =
|
|
lhs.scLL == lhs.mcLL
|
|
&& lhs.mcLL == lhs.lcLL
|
|
;
|
|
|
|
//
|
|
bool startCondition = false;
|
|
bool signalCondition = false;
|
|
bool entryCondition = false;
|
|
|
|
//
|
|
bool shortCondition1 =
|
|
//
|
|
true
|
|
//
|
|
&& tPow1.powerDown > tPowerMaxVerifier
|
|
&& tPow2.powerDown < tPowerMaxVerifier
|
|
;
|
|
|
|
//
|
|
startCondition = (
|
|
shortCondition1
|
|
)
|
|
;
|
|
|
|
//
|
|
if (
|
|
startCondition
|
|
&& xTPWShortConds.startTime == 0
|
|
&& xTPWShortConds.signalTime == 0
|
|
&& xTPWShortConds.entryTime == 0
|
|
) {
|
|
//
|
|
xTPWShortConds.startTime = barTime;
|
|
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
|
|
|| !(enableXTPWLong || enableXTPWShort)
|
|
) {
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool requestLong = type == X_SIGNAL_LONG;
|
|
|
|
//
|
|
// Check Condition Validations ...
|
|
if (requestLong) {
|
|
//
|
|
// Check Long Condtion is Valid, if Long Requested ...
|
|
if (
|
|
!ValidateXTPWLongConditions()
|
|
) {
|
|
return result;
|
|
}
|
|
} else {
|
|
//
|
|
// Check Short Condtion is Valid, if Short Requested ...
|
|
if (
|
|
!ValidateXTPWShortConditions()
|
|
) {
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
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
|
|
);
|
|
|
|
//
|
|
// Price Calculations ...
|
|
XPrice prices = GetPrice();
|
|
|
|
//
|
|
// Read State ...
|
|
XTPWMarketState state0 = GetXTPWMarketState(bar_index);
|
|
|
|
//
|
|
XOHCL candle0 = GetCandleModel(bar_index);
|
|
XOHCL candle1 = GetCandleModel(bar_index + 1);
|
|
XOHCL candle2 = GetCandleModel(bar_index + 2);
|
|
XOHCL candle3 = GetCandleModel(bar_index + 2);
|
|
|
|
//
|
|
double risk = requestLong ?
|
|
//
|
|
MathMin(openPrice, closePrice) - ll :
|
|
hh - MathMax(openPrice, closePrice)
|
|
;
|
|
|
|
//
|
|
double longR2R = xTPWLongR2R;
|
|
double shortR2R = xTPWShortR2R;
|
|
|
|
//
|
|
double sharpDetectorValue = xTPWSharpDetectionFactor * _Point;
|
|
|
|
//
|
|
if (
|
|
risk > 0
|
|
&& requestLong
|
|
) {
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Define Entry Price ...
|
|
double entryPrice = requestLong
|
|
?
|
|
prices.longEntry
|
|
:
|
|
prices.shortEntry
|
|
;
|
|
|
|
//
|
|
// Fix TP Detects for Short Signals ...
|
|
if (!requestLong) {
|
|
risk = 0;
|
|
}
|
|
|
|
//
|
|
double reward = requestLong ?
|
|
risk * longR2R :
|
|
risk * shortR2R
|
|
;
|
|
|
|
//
|
|
if (risk == 0) {
|
|
//
|
|
// Calculate Reward ...
|
|
reward = requestLong
|
|
?
|
|
MathAbs(hh - entryPrice)
|
|
:
|
|
MathAbs(hh - entryPrice)
|
|
;
|
|
|
|
//
|
|
// Detect Sharp Change Occured or not ...
|
|
bool isSharpOccured = reward > sharpDetectorValue
|
|
|| MathAbs(reward - sharpDetectorValue) < (50 * _Point);
|
|
|
|
//
|
|
// Change Rewards on Special Conditions ...
|
|
if (
|
|
(
|
|
requestLong
|
|
&& isSharpOccured
|
|
&& (
|
|
state0.lcFast < state0.lcSlow
|
|
|| (
|
|
state0.mcFast > state0.mcSlow
|
|
&& state0.mcWeight < state0.mcSlow
|
|
)
|
|
)
|
|
)
|
|
) {
|
|
reward = reward / 2;
|
|
}
|
|
|
|
//
|
|
if (reward < 50 * _Point) {
|
|
reward = (50 * _Point) + prices.priceGap;
|
|
}
|
|
|
|
// //
|
|
// if (!requestLong) {
|
|
// reward = reward * shortR2R;
|
|
// }
|
|
}
|
|
|
|
//
|
|
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_XTPW_PROVIDER;
|
|
|
|
//
|
|
result.hasSignal = true;
|
|
result.type = type;
|
|
result.provider = X_XTPW_PROVIDER;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Validate Signal Conditions ...
|
|
bool ValidateXTPWLongConditions() {
|
|
//
|
|
if (
|
|
!enableXTPWLong
|
|
|| !enableXTPWSignalling
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
bool isConditionsFilled =
|
|
xTPWLongConds.startTime > 0
|
|
&& xTPWLongConds.signalTime > 0
|
|
&& xTPWLongConds.entryTime > 0
|
|
;
|
|
|
|
//
|
|
bool isBLFilled = false;
|
|
if (isConditionsFilled) {
|
|
//
|
|
isBLFilled =
|
|
//
|
|
// Starter ...
|
|
true
|
|
//
|
|
&& 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 (
|
|
!enableXTPWShort
|
|
|| !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 =
|
|
//
|
|
// Starter ...
|
|
true
|
|
//
|
|
&& 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
|
|
|| !(enableXTPWLong || enableXTPWShort)
|
|
) {
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int signalBarIndex = iBarShift(
|
|
_Symbol,
|
|
_Period,
|
|
signal.time
|
|
);
|
|
|
|
//
|
|
// XOHCL candle = GetCandleModel(0);
|
|
XOHCL candle0 = GetCandleModel(signalBarIndex);
|
|
XOHCL candle1 = GetCandleModel(signalBarIndex + 1);
|
|
|
|
//
|
|
// Retrieve TPow State ...
|
|
XTPOWState tPow0 = GetXTPowState(
|
|
signalBarIndex,
|
|
xTPWSwingLength
|
|
);
|
|
XTPOWState tPow1 = GetXTPowState(
|
|
signalBarIndex + 1,
|
|
xTPWSwingLength
|
|
);
|
|
|
|
//
|
|
// Retrive XMarket States ...
|
|
XTPWMarketState state0 = GetXTPWMarketState(signalBarIndex);
|
|
XTPWMarketState state1 = GetXTPWMarketState(signalBarIndex + 1);
|
|
XTPWMarketState state2 = GetXTPWMarketState(signalBarIndex + 2);
|
|
|
|
//
|
|
bool isPSarVerified = false;
|
|
bool isTPowVerified = false;
|
|
bool isStateVerified = false;
|
|
bool isPriceVerified = false;
|
|
|
|
//
|
|
// Calculate Sharp Detection Value ...
|
|
double sharpDetectionValue =
|
|
xTPWSharpDetectionFactor * _Point;
|
|
|
|
//
|
|
// Find State0 Min ...
|
|
double state0Min = MathMin(state0.scFast, state0.scSlow);
|
|
state0Min = MathMin(state0Min, state0.mcFast);
|
|
state0Min = MathMin(state0Min, state0.mcSlow);
|
|
state0Min = MathMin(state0Min, state0.lcFast);
|
|
state0Min = MathMin(state0Min, state0.lcSlow);
|
|
|
|
//
|
|
// Find State0 Min ...
|
|
double state0Max = MathMax(state0.scFast, state0.scSlow);
|
|
state0Max = MathMax(state0Max, state0.mcFast);
|
|
state0Max = MathMax(state0Max, state0.mcSlow);
|
|
state0Max = MathMax(state0Max, state0.lcFast);
|
|
state0Max = MathMax(state0Max, state0.lcSlow);
|
|
|
|
//
|
|
// Find Distance Between State0 Min and Max ...
|
|
double state0MinMaxDistance = MathAbs(state0Max - state0Min);
|
|
|
|
//
|
|
// 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
|
|
//
|
|
&& state0.lcSlow > 0
|
|
&& state0.lcFast > state0.lcSlow
|
|
;
|
|
|
|
//
|
|
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 ...
|
|
//
|
|
//
|
|
// Retrieve Market State ...
|
|
XTPWMarketState GetXTPWMarketState(
|
|
const int bar_index
|
|
) {
|
|
//
|
|
XTPWMarketState result = {};
|
|
|
|
//
|
|
int dayCount = GetDailyCandleCount();
|
|
int halfDayCount = (int)(dayCount / 2);
|
|
|
|
//
|
|
if (scFastLength == 0) {
|
|
scFastLength = xTPWSwingLength;
|
|
}
|
|
|
|
//
|
|
if (scSlowLength == 0) {
|
|
scSlowLength = xTPWSwingLength * 2;
|
|
}
|
|
|
|
//
|
|
if (mcFastLength == 0) {
|
|
mcFastLength = halfDayCount;
|
|
}
|
|
|
|
//
|
|
if (mcSlowLength == 0) {
|
|
mcSlowLength = dayCount;
|
|
}
|
|
|
|
//
|
|
if (lcFastLength == 0) {
|
|
lcFastLength = halfDayCount * 3;
|
|
}
|
|
|
|
//
|
|
if (lcSlowLength == 0) {
|
|
lcSlowLength = dayCount * 3;
|
|
}
|
|
|
|
//
|
|
double scFast = GetMA(
|
|
bar_index,
|
|
scFastLength,
|
|
0,
|
|
MODE_SMA,
|
|
PRICE_CLOSE
|
|
);
|
|
|
|
//
|
|
double scSlow = GetMA(
|
|
bar_index,
|
|
scSlowLength,
|
|
0,
|
|
MODE_SMA,
|
|
PRICE_CLOSE
|
|
);
|
|
|
|
//
|
|
double scWeight = GetMA(
|
|
bar_index,
|
|
scSlowLength,
|
|
0,
|
|
MODE_EMA,
|
|
PRICE_MEDIAN
|
|
);
|
|
|
|
//
|
|
double mcFast = GetMA(
|
|
bar_index,
|
|
mcFastLength,
|
|
0,
|
|
MODE_SMA,
|
|
PRICE_CLOSE
|
|
);
|
|
|
|
//
|
|
double mcSlow = GetMA(
|
|
bar_index,
|
|
mcSlowLength,
|
|
0,
|
|
MODE_SMA,
|
|
PRICE_CLOSE
|
|
);
|
|
|
|
//
|
|
double mcWeight = GetMA(
|
|
bar_index,
|
|
mcSlowLength,
|
|
0,
|
|
MODE_EMA,
|
|
PRICE_MEDIAN
|
|
);
|
|
|
|
//
|
|
double lcFast = GetMA(
|
|
bar_index,
|
|
lcFastLength,
|
|
0,
|
|
MODE_SMA,
|
|
PRICE_CLOSE
|
|
);
|
|
|
|
//
|
|
double lcSlow = GetMA(
|
|
bar_index,
|
|
lcSlowLength,
|
|
0,
|
|
MODE_SMA,
|
|
PRICE_CLOSE
|
|
);
|
|
|
|
//
|
|
double lcWeight = GetMA(
|
|
bar_index,
|
|
lcSlowLength,
|
|
0,
|
|
MODE_EMA,
|
|
PRICE_MEDIAN
|
|
);
|
|
|
|
//
|
|
double psar = iSAR(
|
|
_Symbol,
|
|
_Period,
|
|
xTPWPSarStep,
|
|
xTPWPSarMaximum,
|
|
bar_index
|
|
);
|
|
|
|
//
|
|
result.psar = psar;
|
|
result.scFast = scFast;
|
|
result.scSlow = scSlow;
|
|
result.mcFast = mcFast;
|
|
result.mcSlow = mcSlow;
|
|
result.lcFast = lcFast;
|
|
result.lcSlow = lcSlow;
|
|
result.scWeight = scWeight;
|
|
result.mcWeight = mcWeight;
|
|
result.lcWeight = lcWeight;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Highest Highs and Lowest Lows in Cycles ...
|
|
XLHS GetXTPWLHS(
|
|
const int bar_index
|
|
) {
|
|
//
|
|
XLHS result = {};
|
|
|
|
//
|
|
// Retrieve LL and HH (s) ...
|
|
|
|
//
|
|
// SC HH ...
|
|
double scHH = GetMarketHighestHigh(
|
|
bar_index,
|
|
scFastLength
|
|
);
|
|
|
|
//
|
|
// SC LL ...
|
|
double scLL = GetMarketHighestHigh(
|
|
bar_index,
|
|
scFastLength
|
|
);
|
|
|
|
//
|
|
// MC HH ...
|
|
double mcHH = GetMarketHighestHigh(
|
|
bar_index,
|
|
mcFastLength
|
|
);
|
|
|
|
//
|
|
// MC LL ...
|
|
double mcLL = GetMarketHighestHigh(
|
|
bar_index,
|
|
mcFastLength
|
|
);
|
|
|
|
//
|
|
// LC HH ...
|
|
double lcHH = GetMarketHighestHigh(
|
|
bar_index,
|
|
lcFastLength
|
|
);
|
|
|
|
//
|
|
// LC LL ...
|
|
double lcLL = GetMarketHighestHigh(
|
|
bar_index,
|
|
lcFastLength
|
|
);
|
|
|
|
//
|
|
result.scHH = scHH;
|
|
result.scLL = scLL;
|
|
result.mcHH = mcHH;
|
|
result.mcLL = mcLL;
|
|
result.lcHH = lcHH;
|
|
result.lcLL = lcLL;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
//
|
|
// END Data Provider ...
|
|
//
|