This commit is contained in:
2025-01-23 20:52:45 +03:30
parent aa3630bc82
commit 330c70088c
10 changed files with 3085 additions and 774 deletions
+5 -1
View File
@@ -66,7 +66,9 @@ input string eaCloseAllTradesAt = ""; // Enable Close All Trades on Signals on T
// Risk Management ...
input group "Risk Management";
input double eaR2R = 2; // Signallers Risk to Reward Ratio
input double eaVolume = 0.05; // Static Volume
input double eaVolume = 0; // Static Volume
input double eaStaticBalance = 1000; // Static Balance
input double eaBalancePerTrade = 10; // Balance Used in Each Trade
input double eaRiskPercentPerBalance = 0; // Risk Percent Per Balance in Each Trade
input bool eaDynamicRiskManagement = false; // Dynamic Risk Management
input bool eaUseDynamicVolume = false; // Use Dynamic Volume
@@ -180,6 +182,8 @@ int OnInit()
// Risk Management ...
eaExpert.R2R(eaR2R);
eaExpert.Volume(eaVolume);
eaExpert.StaticBalance(eaStaticBalance);
eaExpert.BalancePerTrade(eaBalancePerTrade);
eaExpert.RiskPercentPerBalance(eaRiskPercentPerBalance);
eaExpert.DynamicRiskManagement(eaDynamicRiskManagement);
eaExpert.UseDynamicVolume(eaUseDynamicVolume);
+33 -11
View File
@@ -230,12 +230,12 @@ struct X121Conditions
bool isVwapSlowSlopeBearish;
//
bool isRsiOverSold;
bool isRsiOverBought;
bool isRsiCrossedOverOverSold;
bool isRsiCrossedUnderOverSold;
bool isRsiCrossedOverOverBought;
bool isRsiCrossedUnderOverBought;
bool isRsiOverSold;
bool isRsiCrossedUnderOverSold;
bool isRsiCrossedOverOverSold;
//
bool isClosedOverAtrUpper;
@@ -252,11 +252,11 @@ struct X121Conditions
bool isRejectDownAtrLower;
//
bool isBreakUpAtrUpper;
bool isBreakedUpAtrUpper;
bool isBreakDownAtrUpper;
//
bool isBreakUpAtrLower;
bool isBreakedUpAtrLower;
bool isBreakDownAtrLower;
//
@@ -373,6 +373,12 @@ struct X121Conditions
bool isBreakedDownPrevCheSE1;
bool isBreakedDownPrevCheSE2;
//
bool isClosedOverCheMin;
bool isClosedOverCheMax;
bool isClosedUnderCheMin;
bool isClosedUnderCheMax;
//
bool isSarIncreased;
bool isSarDecreased;
@@ -702,11 +708,11 @@ struct X121Conditions
isRejectDownAtrLower = false;
//
isBreakUpAtrUpper = false;
isBreakedUpAtrUpper = false;
isBreakDownAtrUpper = false;
//
isBreakUpAtrLower = false;
isBreakedUpAtrLower = false;
isBreakDownAtrLower = false;
//
@@ -846,6 +852,14 @@ struct X121Conditions
isCheSwitchedToBullish = false;
isCheSwitchedToBearish = false;
//
isClosedOverCheMin = false;
isClosedOverCheMax = false;
//
isClosedUnderCheMin = false;
isClosedUnderCheMax = false;
//
// Complex Conditions ...
@@ -1114,9 +1128,9 @@ struct X121Conditions
ToString("isRejectDownAtrUpper", isRejectDownAtrUpper, ignoreFalseConditions, separator) +
ToString("isRejectUpAtrLower", isRejectUpAtrLower, ignoreFalseConditions, separator) +
ToString("isRejectDownAtrLower", isRejectDownAtrLower, ignoreFalseConditions, separator) +
ToString("isBreakUpAtrUpper", isBreakUpAtrUpper, ignoreFalseConditions, separator) +
ToString("isBreakedUpAtrUpper", isBreakedUpAtrUpper, ignoreFalseConditions, separator) +
ToString("isBreakDownAtrUpper", isBreakDownAtrUpper, ignoreFalseConditions, separator) +
ToString("isBreakUpAtrLower", isBreakUpAtrLower, ignoreFalseConditions, separator) +
ToString("isBreakedUpAtrLower", isBreakedUpAtrLower, ignoreFalseConditions, separator) +
//
"-----------------------" + separator +
"DON ..." + separator +
@@ -1181,6 +1195,10 @@ struct X121Conditions
ToString("isCheBearish", isCheBearish, ignoreFalseConditions, separator) +
ToString("isCheSwitchedToBullish", isCheSwitchedToBullish, ignoreFalseConditions, separator) +
ToString("isCheSwitchedToBearish", isCheSwitchedToBearish, ignoreFalseConditions, separator) +
ToString("isClosedOverCheMin", isClosedOverCheMin, ignoreFalseConditions, separator) +
ToString("isClosedOverCheMax", isClosedOverCheMax, ignoreFalseConditions, separator) +
ToString("isClosedUnderCheMin", isClosedUnderCheMin, ignoreFalseConditions, separator) +
ToString("isClosedUnderCheMax", isClosedUnderCheMax, ignoreFalseConditions, separator) +
//
"-----------------------" + separator +
"Slopes ..." + separator +
@@ -1979,8 +1997,8 @@ class XCX121Helper : public XCBase
//
conditions.isRsiOverSold = xatrConditions.isRsiOverSold;
conditions.isRsiOverBought = xatrConditions.isRsiOverBought;
conditions.isBreakUpAtrUpper = xatrConditions.isBreakUpAtrUpper;
conditions.isBreakUpAtrLower = xatrConditions.isBreakUpAtrLower;
conditions.isBreakedUpAtrUpper = xatrConditions.isBreakedUpAtrUpper;
conditions.isBreakedUpAtrLower = xatrConditions.isBreakedUpAtrLower;
conditions.isClosedOverAtrUpper = xatrConditions.isClosedOverAtrUpper;
conditions.isRejectUpAtrUpper = xatrConditions.isRejectUpAtrUpper;
conditions.isRejectUpAtrLower = xatrConditions.isRejectUpAtrLower;
@@ -2104,6 +2122,10 @@ class XCX121Helper : public XCBase
conditions.isChe1Bearish = xcheConditions.isChe1Bearish;
conditions.isChe2Bullish = xcheConditions.isChe2Bullish;
conditions.isChe2Bearish = xcheConditions.isChe2Bearish;
conditions.isClosedOverCheMin = xcheConditions.isClosedOverCheMin;
conditions.isClosedOverCheMax = xcheConditions.isClosedOverCheMax;
conditions.isClosedUnderCheMin = xcheConditions.isClosedUnderCheMin;
conditions.isClosedUnderCheMax = xcheConditions.isClosedUnderCheMax;
conditions.isCheSwitchedToBullish = xcheConditions.isCheSwitchedToBullish;
conditions.isCheSwitchedToBearish = xcheConditions.isCheSwitchedToBearish;
conditions.isChe1SwitchedToBullish = xcheConditions.isChe1SwitchedToBullish;
+11 -11
View File
@@ -226,11 +226,11 @@ struct X121XATRConditions
bool isRejectDownAtrLower;
//
bool isBreakUpAtrUpper;
bool isBreakedUpAtrUpper;
bool isBreakDownAtrUpper;
//
bool isBreakUpAtrLower;
bool isBreakedUpAtrLower;
bool isBreakDownAtrLower;
//
@@ -312,11 +312,11 @@ struct X121XATRConditions
isRejectDownAtrLower = false;
//
isBreakUpAtrUpper = false;
isBreakedUpAtrUpper = false;
isBreakDownAtrUpper = false;
//
isBreakUpAtrLower = false;
isBreakedUpAtrLower = false;
isBreakDownAtrLower = false;
//
@@ -410,9 +410,9 @@ struct X121XATRConditions
ToString("isRejectDownAtrUpper", isRejectDownAtrUpper, ignoreFalseConditions, separator) +
ToString("isRejectUpAtrLower", isRejectUpAtrLower, ignoreFalseConditions, separator) +
ToString("isRejectDownAtrLower", isRejectDownAtrLower, ignoreFalseConditions, separator) +
ToString("isBreakUpAtrUpper", isBreakUpAtrUpper, ignoreFalseConditions, separator) +
ToString("isBreakedUpAtrUpper", isBreakedUpAtrUpper, ignoreFalseConditions, separator) +
ToString("isBreakDownAtrUpper", isBreakDownAtrUpper, ignoreFalseConditions, separator) +
ToString("isBreakUpAtrLower", isBreakUpAtrLower, ignoreFalseConditions, separator) +
ToString("isBreakedUpAtrLower", isBreakedUpAtrLower, ignoreFalseConditions, separator) +
ToString("isBreakDownAtrLower", isBreakDownAtrLower, ignoreFalseConditions, separator) +
//
""
@@ -1066,7 +1066,7 @@ class XCX121XATRHelper : public XCBaseHelper
;
//
bool isBreakUpAtrUpper = IsBarBreak(
bool isBreakedUpAtrUpper = IsBarBreak(
atrUpperBuffer[cIDX],
X_DIRECTION_BULLISH,
cBar //
@@ -1078,7 +1078,7 @@ class XCX121XATRHelper : public XCBaseHelper
);
//
bool isBreakUpAtrLower = IsBarBreak(
bool isBreakedUpAtrLower = IsBarBreak(
atrLowerBuffer[cIDX],
X_DIRECTION_BULLISH,
cBar //
@@ -1094,8 +1094,8 @@ class XCX121XATRHelper : public XCBaseHelper
conditions.isRsiOverBought = isRsiOverBought;
conditions.isRejectUpAtrUpper = isRejectUpAtrUpper;
conditions.isRejectUpAtrLower = isRejectUpAtrLower;
conditions.isBreakUpAtrUpper = isBreakUpAtrUpper;
conditions.isBreakUpAtrLower = isBreakUpAtrLower;
conditions.isBreakedUpAtrUpper = isBreakedUpAtrUpper;
conditions.isBreakedUpAtrLower = isBreakedUpAtrLower;
conditions.isRejectDownAtrUpper = isRejectDownAtrUpper;
conditions.isRejectDownAtrLower = isRejectDownAtrLower;
conditions.isClosedOverAtrUpper = isClosedOverAtrUpper;
@@ -1108,7 +1108,7 @@ class XCX121XATRHelper : public XCBaseHelper
conditions.isRsiCrossedUnderOverSold = isRsiCrossedUnderOverSold;
conditions.isRsiCrossedOverOverBought = isRsiCrossedOverOverBought;
conditions.isRsiCrossedUnderOverBought = isRsiCrossedUnderOverBought;
//
return result;
}
+69 -2
View File
@@ -200,7 +200,12 @@ struct X121XCHEConditions
bool isCheSwitchedToBearish;
//
// bool isCloseLower
bool isClosedOverCheMin;
bool isClosedOverCheMax;
//
bool isClosedUnderCheMin;
bool isClosedUnderCheMax;
//
// Constructor ...
@@ -274,7 +279,12 @@ struct X121XCHEConditions
isCheSwitchedToBearish = false;
//
// XDON ...
isClosedOverCheMin = false;
isClosedOverCheMax = false;
//
isClosedUnderCheMin = false;
isClosedUnderCheMax = false;
}
/**
@@ -359,6 +369,10 @@ struct X121XCHEConditions
ToString("isCheBearish", isCheBearish, ignoreFalseConditions, separator) +
ToString("isCheSwitchedToBullish", isCheSwitchedToBullish, ignoreFalseConditions, separator) +
ToString("isCheSwitchedToBearish", isCheSwitchedToBearish, ignoreFalseConditions, separator) +
ToString("isClosedOverCheMin", isClosedOverCheMin, ignoreFalseConditions, separator) +
ToString("isClosedOverCheMax", isClosedOverCheMax, ignoreFalseConditions, separator) +
ToString("isClosedUnderCheMin", isClosedUnderCheMin, ignoreFalseConditions, separator) +
ToString("isClosedUnderCheMax", isClosedUnderCheMax, ignoreFalseConditions, separator) +
//
""
//
@@ -1108,6 +1122,55 @@ class XCX121XCHEHelper : public XCBaseHelper
!isCheBullishPrev;
bool isCheSwitchedToBearish = isCheBearish &&
!isCheBearishPrev;
//
double ches[];
double prevCheLE1 = le1Buffer[pIDX];
double prevCheLE2 = le2Buffer[pIDX];
double prevCheSE1 = se1Buffer[pIDX];
double prevCheSE2 = se2Buffer[pIDX];
if (prevCheLE1 != EMPTY_VALUE)
{
//
Add(
prevCheLE1,
ches //
);
}
if (prevCheLE2 != EMPTY_VALUE)
{
//
Add(
prevCheLE2,
ches //
);
}
if (prevCheSE1 != EMPTY_VALUE)
{
//
Add(
prevCheSE1,
ches //
);
}
if (prevCheSE2 != EMPTY_VALUE)
{
//
Add(
prevCheSE2,
ches //
);
}
//
double cheMin = GetMin(ches);
double cheMax = GetMax(ches);
//
bool isClosedOverCheMin = cBar.close > cheMin;
bool isClosedOverCheMax = cBar.close > cheMax;
bool isClosedUnderCheMin = cBar.close < cheMin;
bool isClosedUnderCheMax = cBar.close < cheMax;
//
conditions.isChe1Bullish = isChe1Bullish;
@@ -1122,6 +1185,10 @@ class XCX121XCHEHelper : public XCBaseHelper
conditions.isCheBearish = isCheBearish;
conditions.isCheSwitchedToBullish = isCheSwitchedToBullish;
conditions.isCheSwitchedToBearish = isCheSwitchedToBearish;
conditions.isClosedOverCheMin = isClosedOverCheMin;
conditions.isClosedOverCheMax = isClosedOverCheMax;
conditions.isClosedUnderCheMin = isClosedUnderCheMin;
conditions.isClosedUnderCheMax = isClosedUnderCheMax;
//
return result;
+16 -12
View File
@@ -5319,7 +5319,8 @@ enum ENUM_X_WEEK_DAYS
// Retrieve Day of Week ...
ENUM_X_WEEK_DAYS GetDayOfWeek(
datetime time = NULL //
) {
)
{
//
ENUM_X_WEEK_DAYS result = X_WEEK_DAY_NONE;
@@ -5327,15 +5328,16 @@ ENUM_X_WEEK_DAYS GetDayOfWeek(
time = NormalizeTime(time);
MqlDateTime timeStruct;
bool hasDate = TimeToStruct(
time,
time,
timeStruct //
);
if (!hasDate) {
if (!hasDate)
{
return result;
}
//
result = (ENUM_X_WEEK_DAYS) timeStruct.day_of_week;
result = (ENUM_X_WEEK_DAYS)timeStruct.day_of_week;
//
return result;
@@ -6517,15 +6519,17 @@ bool IsBarBreak(
//
result =
isUp
? (bar.GetDown() < value &&
bar.GetUp() > value) ||
(bar.close > value &&
pBar.close < value)
? bar.IsBullish() &&
((bar.GetDown() < value &&
bar.GetUp() > value) ||
(bar.close > value &&
pBar.close < value))
: isDown
? (bar.GetUp() > value &&
bar.GetDown() < value) ||
(bar.close < value &&
pBar.close > value)
? bar.IsBearish() &&
((bar.GetUp() > value &&
bar.GetDown() < value) ||
(bar.close < value &&
pBar.close > value))
: false;
//
+145 -24
View File
@@ -462,6 +462,60 @@ class XC121SMCExpert : public XCBaseExpert
ReConfigure();
}
/**
* Get Static Balance for Calculate Trade Volume ...
*
* @return ( double )
*/
double StaticBalance()
{
return mStaticBalance;
}
/**
* Set Static Balance for Calculate Trade Volume ...
*
* @param value: Argument 1
*/
void StaticBalance(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mStaticBalance = value;
}
/**
* Get Balance Used In Each Trade ...
*
* @return ( double )
*/
double BalancePerTrade()
{
return mBalancePerTrade;
}
/**
* Set Balance Used In Each Trade ...
*
* @param value: Argument 1
*/
void BalancePerTrade(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mBalancePerTrade = value;
}
/**
* Get Risk Percent Per Balance in Each Trade ...
*
@@ -1602,37 +1656,72 @@ class XC121SMCExpert : public XCBaseExpert
void ApplyVolumeOnSignal(XSignal &signal)
{
//
// Prepare Signal Dynamic Volume
// if Provided ...
if (UseDynamicVolume() &&
DynamicVolumeStep() > 0 &&
DynamicVolumeBalanceFactor() > 0)
double staticVolume = Volume();
double fVolume = staticVolume > 0
? staticVolume
: 0.01;
//
double staticBalance = StaticBalance();
double accountBalance = mTrader.mAccount.GetBalance();
double balance = staticBalance > 0
? staticBalance
: accountBalance;
//
bool useDynamicVolume = UseDynamicVolume();
double balancePerTrade = BalancePerTrade();
double dynamicVolumeStep = DynamicVolumeStep();
double riskPercentPerBalance = RiskPercentPerBalance();
bool allowDynamicRiskManagement = DynamicRiskManagement();
double dynamicVolumeBalanceFactor = DynamicVolumeBalanceFactor();
//
// Apply Static Volume ...
bool allowStaticVolume = staticVolume > 0;
//
// Apply Dynamic Volume ...
bool aloowApplyDynamicVolume = useDynamicVolume &&
dynamicVolumeStep &&
dynamicVolumeBalanceFactor;
//
// Apply Risk Per Trade Volume ...
bool allowApplyRiskPerTradeVolume =
!aloowApplyDynamicVolume &&
riskPercentPerBalance > 0;
//
// Apply Balance Per Trade Volume ...
bool allowApplyBalacePerTradeVolume =
!aloowApplyDynamicVolume &&
!allowApplyRiskPerTradeVolume &&
balancePerTrade > 0;
//
// First Check Dynamic Volume ...
if (aloowApplyDynamicVolume)
{
//
// Dynamic Volume ...
double dVolume = mTrader.GetDynamicVolume(
signal.symbol,
DynamicVolumeBalanceFactor(),
DynamicVolumeStep() //
dynamicVolumeBalanceFactor,
dynamicVolumeStep //
);
if (dVolume < fVolume)
{
dVolume = fVolume;
}
//
if (dVolume > 0)
{
signal.volume = dVolume;
}
else
{
signal.volume = Volume();
}
signal.volume = dVolume;
}
else if (RiskPercentPerBalance() > 0)
else if (allowApplyRiskPerTradeVolume)
{
//
double riskPercent = RiskPercentPerBalance();
//
double balance = mTrader.mAccount.GetBalance();
double riskAmountPerBalance = (riskPercent * balance) / 100;
double riskAmountPerBalance = (riskPercentPerBalance * balance) / 100;
//
double risk = signal.GetRisk();
@@ -1645,6 +1734,10 @@ class XC121SMCExpert : public XCBaseExpert
riskAmountPerBalance,
riskInPoints //
);
if (volume <= 0)
{
volume = fVolume;
}
//
// Check Dynamic Risk Management ...
@@ -1664,18 +1757,44 @@ class XC121SMCExpert : public XCBaseExpert
}
//
if (volume > 0)
signal.volume = volume;
}
else if (allowApplyBalacePerTradeVolume)
{
//
double risk = signal.GetRisk();
double points = GetPoints(signal.symbol);
double riskInPoints = risk / points;
//
double volume = mTrader.mAccount.CalculateVolume(
signal.symbol,
balancePerTrade,
riskInPoints //
);
if (volume <= 0)
{
volume = NormalizeVolume(volume, signal.symbol);
volume = fVolume;
}
//
signal.volume = volume;
}
else if (allowStaticVolume)
{
signal.volume = staticVolume;
}
else
{
signal.volume = Volume();
signal.volume = fVolume;
}
//
// Normalize Signal Volume ...
signal.volume = NormalizeVolume(
signal.volume,
signal.symbol //
);
}
/**
@@ -1836,6 +1955,8 @@ class XC121SMCExpert : public XCBaseExpert
// Risk Management Props ...
double mR2R; // Signallers Risk to Reward Ratio ...
double mVolume; // Static Volume ...
double mStaticBalance; // Static Balance for Calculate Trade Volume ...
double mBalancePerTrade; // Balance Used in Each Trade ...
double mRiskPercentPerBalance; // Risk Percent Per Balance in Each Trade ...
bool mDynamicRiskManagement; // Dynamic Risk Management ...
bool mUseDynamicVolume; // Use Dynamic Volume ...
+11
View File
@@ -37,6 +37,7 @@ const string X121SMCStrategyToken = "X121SMC";
//
const string X121SMCXToken = "X121X";
const string X121SMCXPZToken = "X121XPZ";
const string X121SMCXPVTToken = "X121XPVT";
const string X121SMCXRSPVIToken = "X121XRSPVI";
const string X121SMCXSTRPVToken = "X121XSTRPV";
@@ -48,6 +49,7 @@ enum ENUM_X_121_SMC_PROVIDERS
X_121_SMC_PROVIDER_NONE,
X_121_SMC_PROVIDER_X,
X_121_SMC_PROVIDER_XPZ,
X_121_SMC_PROVIDER_XPVT,
X_121_SMC_PROVIDER_XRSPVI,
X_121_SMC_PROVIDER_XSTRPV,
};
@@ -713,6 +715,11 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value)
result = X121SMCXPZToken;
break;
//
case X_121_SMC_PROVIDER_XPVT:
result = X121SMCXPVTToken;
break;
//
case X_121_SMC_PROVIDER_XRSPVI:
result = X121SMCXRSPVIToken;
@@ -755,6 +762,10 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value)
{
result = X_121_SMC_PROVIDER_XPZ;
}
else if (Contains(X121SMCXPVTToken, value))
{
result = X_121_SMC_PROVIDER_XPVT;
}
else if (Contains(X121SMCXRSPVIToken, value))
{
result = X_121_SMC_PROVIDER_XRSPVI;
+35 -706
View File
@@ -330,15 +330,10 @@ bool DetectX121SMCXSiganlSetup(
//
XOHCL zBar;
result = decisionCycleHelper.GetBar(
result = consolidationCycleHelper.GetBar(
zBar,
zIndex //
);
// zBar.Init(
// symbol,
// period,
// zIndex //
// );
if (!result)
{
return result;
@@ -346,15 +341,10 @@ bool DetectX121SMCXSiganlSetup(
//
XOHCL cBar;
result = decisionCycleHelper.GetBar(
result = consolidationCycleHelper.GetBar(
cBar,
cIndex //
);
// cBar.Init(
// symbol,
// period,
// cIndex //
// );
if (!result)
{
return result;
@@ -362,15 +352,10 @@ bool DetectX121SMCXSiganlSetup(
//
XOHCL pBar;
result = decisionCycleHelper.GetBar(
result = consolidationCycleHelper.GetBar(
pBar,
pIndex //
);
// pBar.Init(
// symbol,
// period,
// pIndex //
// );
if (!result)
{
return result;
@@ -795,659 +780,6 @@ bool DetectX121SMCXSiganlSetup(
//
;
//
// Detect Pivot ...
//
double pivotPremiumDiscount = 0;
//
bool isPivotUpperUpBreaked = false;
bool isPivotUpperDownBreaked = false;
bool isPivotUpperDownRejected = false;
//
bool isPivotLowerUpBreaked = false;
bool isPivotLowerUpRejected = false;
bool isPivotLowerDownBreaked = false;
//
bool isPriceInPivotPremium = false;
bool isPriceInPivotDiscount = false;
//
bool isPivotPremiumUpBreaked = false;
bool isPivotPremiumDownBreaked = false;
bool isPivotPremiumUpRejected = false;
bool isPivotPremiumDownRejected = false;
//
bool isPivotDiscountUpBreaked = false;
bool isPivotDiscountDownBreaked = false;
bool isPivotDiscountUpRejected = false;
bool isPivotDiscountDownRejected = false;
//
bool hasPivot = conditions.pivotZone.IsValid();
//
if (!hasPivot)
{
//
bool hasPeak = conditions.HasPeak();
bool hasVale = conditions.HasVale();
//
int higherPeakIDX = -1;
int higherPeakStartIDX = -1;
datetime higherPeakTime = NULL;
double higherPeak = decisionCycleHelper
.mX121Helper
.xpvHelper
.GetHigherPeak(
higherPeakIDX,
decisionXConditions.peaksBuffer[1] //
);
bool hasHigherPeak =
higherPeak > 0 &&
IsValidIndex(higherPeakIDX);
if (hasHigherPeak)
{
//
// Detect Higher Peak Start Index ...
int idx = higherPeakIDX;
bool canContinue = true;
while (canContinue)
{
//
double iPeak = decisionCycleHelper
.mX121Helper
.xpvHelper
.GetPeak(idx);
canContinue = iPeak == higherPeak;
if (!canContinue)
{
break;
}
//
idx++;
}
//
if (idx > higherPeakIDX)
{
higherPeakStartIDX = idx - 1;
}
}
//
int lowerValeIDX = -1;
int lowerValeStartIDX = -1;
datetime lowerValeTime = NULL;
double lowerVale = decisionCycleHelper
.mX121Helper
.xpvHelper
.GetLowerVale(
lowerValeIDX,
decisionXConditions.valesBuffer[1] //
);
bool hasLowerVale =
lowerVale > 0 &&
IsValidIndex(lowerValeIDX);
if (hasLowerVale)
{
//
// Detect Lower Vale Start Index ...
int idx = lowerValeIDX;
bool canContinue = true;
while (canContinue)
{
//
double iVale = decisionCycleHelper
.mX121Helper
.xpvHelper
.GetVale(idx);
canContinue = iVale == lowerVale;
if (!canContinue)
{
break;
}
//
idx++;
}
//
if (idx > lowerValeIDX)
{
lowerValeStartIDX = idx - 1;
}
}
//
// Now we Have to Detect Higher Peak and Lower Vale
// Zones ...
//
if (hasHigherPeak)
{
//
XOHCL higherPeakStartBar;
bool isInited = higherPeakStartBar.Init(
symbol,
period,
higherPeakStartIDX //
);
if (isInited)
{
higherPeakTime = higherPeakStartBar.time;
}
}
//
if (hasLowerVale)
{
//
XOHCL lowerValeStartBar;
bool isInited = lowerValeStartBar.Init(
symbol,
period,
lowerValeStartIDX //
);
if (isInited)
{
lowerValeTime = lowerValeStartBar.time;
}
}
//
bool isNewPeak =
!hasPeak &&
hasLowerVale &&
hasHigherPeak &&
decisionXConditions.isNewPeakUnderLast;
if (isNewPeak)
{
//
conditions.pvType = XPV_PEAK;
//
conditions.peakTime = cTime;
conditions.peak = decisionXConditions.peaksBuffer[1];
//
conditions.higherPeakTime = higherPeakTime;
conditions.higherPeak = higherPeak;
//
conditions.valeTime = cTime;
conditions.vale = decisionXConditions.valesBuffer[1];
//
conditions.lowerValeTime = lowerValeTime;
conditions.lowerVale = lowerVale;
//
hasPeak = conditions.HasPeak();
hasVale = conditions.HasVale();
}
//
bool isNewVale =
!hasVale &&
!isNewPeak &&
hasLowerVale &&
hasHigherPeak &&
decisionXConditions.isNewValeOverLast;
if (isNewVale)
{
//
conditions.pvType = XPV_PEAK;
//
conditions.peakTime = cTime;
conditions.peak = decisionXConditions.peaksBuffer[1];
//
conditions.higherPeakTime = higherPeakTime;
conditions.higherPeak = higherPeak;
//
conditions.valeTime = cTime;
conditions.vale = decisionXConditions.valesBuffer[1];
//
conditions.lowerValeTime = lowerValeTime;
conditions.lowerVale = lowerVale;
//
hasPeak = conditions.HasPeak();
hasVale = conditions.HasVale();
}
//
if (isNewPeak || isNewVale)
{
//
XPVPivot pivot;
//
pivot.symbol = symbol;
pivot.period = period;
//
pivot.repetition = MathMax(
higherPeakIDX,
lowerValeIDX //
);
pivot.type = conditions.pvType;
//
pivot.upper = higherPeak;
pivot.lower = lowerVale;
//
bool isHigherPeakOlder =
conditions.higherPeakTime < conditions.lowerValeTime;
//
pivot.to = cTime;
pivot.from =
isHigherPeakOlder
? conditions.higherPeakTime
: conditions.lowerValeTime;
//
pivot.type =
isHigherPeakOlder
? XPV_PEAK
: XPV_VALE;
//
hasPivot = pivot.IsValid();
if (hasPivot)
{
conditions.pivotZone = pivot;
}
//
}
//
// Has Pivot ...
hasPivot = conditions.pivotZone.IsValid();
}
//
if (hasPivot)
{
//
// Check Pivot Validation ...
//
bool isPivotDied =
//
(cBar.low > conditions.pivotZone.upper &&
cBar.close > conditions.pivotZone.upper)
//
||
//
(cBar.high < conditions.pivotZone.lower &&
cBar.close < conditions.pivotZone.lower)
//
;
if (isPivotDied)
{
conditions.Clean();
}
//
hasPivot = conditions.pivotZone.IsValid();
if (hasPivot)
{
//
// Detect Pivot States ...
//
XPOIState analysePivotState;
DetectPivotPOIs(
conditions.pivotZone,
analyseState,
analysePivotState //
);
//
XPOIState decisionPivotState;
DetectPivotPOIs(
conditions.pivotZone,
decisionState,
decisionPivotState //
);
//
// Combine two State ...
XPOIState combinedPivotState;
XPOIState iStates[];
// AddRef(
// analysePivotState,
// iStates //
// );
AddRef(
decisionPivotState,
iStates //
);
CombineStates(
combinedPivotState,
iStates //
);
combinedPivotState = decisionPivotState;
//
ArrayFree(iStates);
//
combinedPivotState.time = decisionPivotState.time;
combinedPivotState.symbol = decisionPivotState.symbol;
combinedPivotState.period = decisionPivotState.period;
//
// Hold Only Areas Which on Upper or Lower bondary of Pivot Zone ...
FilterPivotState(
conditions.pivotZone,
combinedPivotState //
);
//
conditions.pivotZone.state = combinedPivotState;
//
// Calculate Pivot Ticks Zone ...
//
int ticksLevels = decisionCycleHelper
.mPOIDetector
.TicksRangeZoneLevel();
int ticksRange = decisionCycleHelper
.mPOIDetector
.TicksRangeZoneRange();
//
CalculatePivotTickZone(
conditions.pivotZone,
ticksLevels,
ticksRange //
);
//
// Try to Fill up Pivot Conditions ...
//
XOHCL pivotCBar;
bool isCInited = triggerCycleHelper.GetBar(
pivotCBar,
cIndex //
);
//
XOHCL pivotPBar;
bool isPInited = triggerCycleHelper.GetBar(
pivotPBar,
pIndex //
);
//
double upper = conditions.pivotZone.upper;
double lower = conditions.pivotZone.lower;
pivotPremiumDiscount = conditions.pivotZone.CalculateMid();
//
// Pivot Upper ...
//
isPivotUpperUpBreaked =
isCInited &&
IsBarBreak(
upper,
X_DIRECTION_BULLISH,
pivotCBar //
);
//
isPivotUpperDownBreaked =
isCInited &&
IsBarBreak(
upper,
X_DIRECTION_BEARISH,
pivotCBar //
);
//
isPivotUpperDownRejected =
isCInited &&
IsBarReject(
upper,
X_DIRECTION_BEARISH,
pivotCBar //
);
//
// Pivot Lower ...
//
isPivotLowerUpBreaked =
isCInited &&
IsBarBreak(
lower,
X_DIRECTION_BULLISH,
pivotCBar //
);
//
isPivotLowerUpRejected =
isCInited &&
IsBarReject(
lower,
X_DIRECTION_BULLISH,
pivotCBar //
);
//
isPivotLowerDownBreaked =
isCInited &&
IsBarBreak(
lower,
X_DIRECTION_BEARISH,
pivotCBar //
);
//
// Pivot Premium / Discount ...
//
bool isPriceInPivotPremium =
isCInited &&
ask < upper &&
bid < upper &&
ask > pivotPremiumDiscount &&
bid > pivotPremiumDiscount;
//
bool isPriceInPivotDiscount =
isCInited &&
ask > lower &&
bid > lower &&
ask < pivotPremiumDiscount &&
bid < pivotPremiumDiscount;
//
//
//
//
isPivotPremiumUpBreaked =
isCInited &&
isPInited &&
IsBarBreak(
pivotPremiumDiscount,
X_DIRECTION_BULLISH,
pivotCBar //
) &&
pivotPBar.high > pivotPremiumDiscount;
//
isPivotPremiumDownBreaked =
isCInited &&
isPInited &&
IsBarBreak(
pivotPremiumDiscount,
X_DIRECTION_BEARISH,
pivotCBar //
) &&
pivotPBar.high > pivotPremiumDiscount;
//
isPivotPremiumUpRejected =
isCInited &&
isPInited &&
IsBarReject(
pivotPremiumDiscount,
X_DIRECTION_BULLISH,
pivotCBar //
) &&
pivotPBar.high > pivotPremiumDiscount;
//
isPivotPremiumDownRejected =
isCInited &&
isPInited &&
IsBarReject(
pivotPremiumDiscount,
X_DIRECTION_BEARISH,
pivotCBar //
) &&
pivotPBar.high > pivotPremiumDiscount;
//
//
//
//
isPivotDiscountUpBreaked =
isCInited &&
isPInited &&
IsBarBreak(
pivotPremiumDiscount,
X_DIRECTION_BULLISH,
pivotCBar //
) &&
pivotPBar.low < pivotPremiumDiscount;
//
isPivotDiscountDownBreaked =
isCInited &&
isPInited &&
IsBarBreak(
pivotPremiumDiscount,
X_DIRECTION_BEARISH,
pivotCBar //
) &&
pivotPBar.low < pivotPremiumDiscount;
//
isPivotDiscountUpRejected =
isCInited &&
isPInited &&
IsBarReject(
pivotPremiumDiscount,
X_DIRECTION_BULLISH,
pivotCBar //
) &&
pivotPBar.low < pivotPremiumDiscount;
//
isPivotDiscountDownRejected =
isCInited &&
isPInited &&
IsBarReject(
pivotPremiumDiscount,
X_DIRECTION_BEARISH,
pivotCBar //
) &&
pivotPBar.low < pivotPremiumDiscount;
//
// Detect Bar Patterns ...
//
if (isCBarBullishRejected)
{
//
int count = conditions.pivotZone.state.CountBullishRejectionBars();
isCBarBullishRejected = IsValidSize(count);
if (isCBarBullishRejected)
{
//
bool hasBar = false;
for (int i = 0; i < count; i++)
{
//
XCRejectionBar *iBar = conditions.pivotZone.state.bullishRejectionBars[i];
//
hasBar = iBar.BarTime() == cBar.time;
if (hasBar)
{
break;
}
}
//
isCBarBullishRejected = hasBar;
}
}
//
if (isCBarBearishRejected)
{
//
int count = conditions.pivotZone.state.CountBearishRejectionBars();
isCBarBearishRejected = IsValidSize(count);
if (isCBarBearishRejected)
{
//
bool hasBar = false;
for (int i = 0; i < count; i++)
{
//
XCRejectionBar *iBar = conditions.pivotZone.state.bearishRejectionBars[i];
//
hasBar = iBar.BarTime() == cBar.time;
if (hasBar)
{
break;
}
}
//
isCBarBearishRejected = hasBar;
}
}
//
// Draw Pivot ...
// XCBaseObject *drawnObjects[];
// triggerCycleHelper.mPOIDetector.mDrawer.DrawPivot(
// conditions.pivotZone,
// drawnObjects,
// true, // Draw State ...
// false, // State As Box ...
// true // Tick Zone ...
// );
}
}
//
//
//
@@ -1458,30 +790,30 @@ bool DetectX121SMCXSiganlSetup(
//
bool isCondition1Bullish =
//
hasPivot &&
// decisionXConditions.isRsiSlopeBullish &&
// analyseXConditions.isRsiSlopeBullish &&
// verificationXConditions.isRsiSlopeBullish &&
// consolidationXConditions.isRsiSlopeBullish &&
// visionXConditions.isRsiCrossedOverOverSold
//
(isCBarBullishRejected &&
pBar.open > cBar.close &&
decisionXConditions.isNewValeUnderLast &&
decisionXConditions.valesBuffer[1] > conditions.pivotZone.lower) &&
//
//
true
// cBar.IsBullish() &&
decisionXConditions.isBreakedUpPrevAtrLower // &&
// cBar.open > analyseXConditions.atrLowerBuffer[0]
//
;
//
bool isCondition1Bearish =
//
hasPivot &&
// decisionXConditions.isRsiSlopeBearish &&
// analyseXConditions.isRsiSlopeBearish &&
// verificationXConditions.isRsiSlopeBearish &&
// consolidationXConditions.isRsiSlopeBearish &&
// visionXConditions.isRsiCrossedUnderOverBought
//
(isCBarBearishRejected &&
pBar.open < cBar.close &&
decisionXConditions.isNewPeakOverLast &&
decisionXConditions.peaksBuffer[1] < conditions.pivotZone.upper) &&
//
//
true
// cBar.IsBearish() &&
decisionXConditions.isBreakedDownPrevAtrUpper // &&
// cBar.open < analyseXConditions.atrUpperBuffer[0]
//
;
@@ -1506,21 +838,16 @@ bool DetectX121SMCXSiganlSetup(
// Manipulate Conditions Point ...
//
conditions.point = pivotPremiumDiscount;
conditions.point = point;
//
// Manipulate Conditions Pivot ...
//
conditions.pivot =
isCondition1Bullish
? conditions.pivotZone.upper
: conditions.pivotZone.lower;
//
// conditions.Clean();
// isCondition1Bullish = false;
// isCondition1Bearish = false;
// conditions.pivot =
// isCondition1Bullish
// ? conditions.pivotZone.upper
// : conditions.pivotZone.lower;
}
//
@@ -1532,6 +859,7 @@ bool DetectX121SMCXSiganlSetup(
//
// false
isCondition1Bullish
// isCondition2Bullish
//
;
@@ -1540,6 +868,7 @@ bool DetectX121SMCXSiganlSetup(
//
// false
isCondition1Bearish
// isCondition2Bearish
//
;
@@ -1905,15 +1234,15 @@ bool DetectX121SMCXSiganlTrigger(
//
double point = conditions.point;
bool isPointBreaked =
isBullish
? ask > point && bid > point
: ask < point && bid < point;
// bool isPointBreaked = IsBarBreak(
// point,
// setupDir,
// cBar //
// );
// bool isPointBreaked =
// isBullish
// ? ask > point && bid > point
// : ask < point && bid < point;
bool isPointBreaked = IsBarBreak(
point,
setupDir,
cBar //
);
//
// Summary ...
File diff suppressed because it is too large Load Diff
+276 -7
View File
@@ -29,6 +29,7 @@
//
#include "../Signals/x-121.smc.x.signal.lib.mq5"
#include "../Signals/x-121.smc.xpz.signal.lib.mq5"
#include "../Signals/x-121.smc.xpvt.signal.lib.mq5"
#include "../Signals/x-121.smc.xrspvi.signal.lib.mq5"
#include "../Signals/x-121.smc.xstrpv.signal.lib.mq5"
@@ -46,6 +47,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
// Props ...
bool useXSignal;
bool useXPZSignal;
bool useXPVTSignal;
bool useXRSPVISignal;
bool useXSTRPVSignal;
@@ -199,6 +201,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
//
bool hasXSignal = false;
bool hasXPZSignal = false;
bool hasXPVTSignal = false;
bool hasXRSPVISignal = false;
bool hasXSTRPVSignal = false;
@@ -220,6 +223,15 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
hasSignal = hasXPZSignal;
}
//
// XPVT Signal ...
if (useXPVTSignal && !hasSignal)
{
//
hasXPVTSignal = DetectXPVTSignal(conditions);
hasSignal = hasXPVTSignal;
}
//
// XRSPVI Signal ...
if (useXRSPVISignal && !hasSignal)
@@ -427,6 +439,23 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
);
}
//
// XPVT Guard Detection ...
if (useXPVTSignal)
{
//
bool hasGuard = DetectX121SMCXPVTGuards(
guards,
positions,
mTriggerCycleHelper,
mDecisionCycleHelper,
mAnalyseCycleHelper,
mVerificationCycleHelper,
mConsolidationCycleHelper,
mVisionCycleHelper //
);
}
//
// XSTRPV Guard Detection ...
if (useXSTRPVSignal)
@@ -594,6 +623,23 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
setupDir = mXConditions.dir;
setupTime = mXConditions.setupTime;
// //
// bool hasPivot = mXConditions.pivotZone.IsValid();
// if (hasPivot)
// {
// //
// XCBaseObject *drawnObjects[];
// int drawnCount = DrawX121SMCXConditions(
// mXConditions,
// drawnObjects,
// mPOIDrawer //
// );
// if (IsValidSize(drawnCount))
// {
// AddObjectsIfNotExists(drawnObjects);
// }
// }
//
if (isSetuped)
{
@@ -935,6 +981,224 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
return result;
}
//
// XPVT Signal ...
bool DetectXPVTSignal(
X121SMCStrategyConditions &conditions //
)
{
//
bool result = false;
//
bool isBullish = false;
bool isBearish = false;
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
XOHCL zBar;
result = zBar.Init(
symbol,
period,
zIndex //
);
if (!result)
{
return result;
}
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
cIndex //
);
if (!result)
{
return result;
}
//
XOHCL pBar;
result = pBar.Init(
symbol,
period,
pIndex //
);
if (!result)
{
return result;
}
//
double cLL = cBar.FindLowest(7, MODE_LOW);
double cHH = cBar.FindHighest(7, MODE_HIGH);
//
datetime cTime = TimeCurrent();
//
ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XPVT;
string providerStr = ToString(provider);
//
// Detect Setup Conditions ...
datetime setupTime = mXPVTConditions.setupTime;
bool isSetuped = mXPVTConditions.IsSetuped();
ENUM_X_DIRECTION setupDir = mXPVTConditions.dir;
if (!isSetuped)
{
//
// Detect Signal Setup ...
isSetuped = DetectX121SMCXPVTSiganlSetup(
symbol,
period,
mXPVTConditions,
mTriggerCycleHelper,
mDecisionCycleHelper,
mAnalyseCycleHelper,
mVerificationCycleHelper,
mConsolidationCycleHelper,
mVisionCycleHelper //
);
//
setupDir = mXPVTConditions.dir;
setupTime = mXPVTConditions.setupTime;
//
if (isSetuped)
{
//
int items = AddX121SMCXPVTConditionsIfNotExists(
mXPVTConditions,
mXPVTConditionsCollection //
);
//
mXPVTConditions.Clean();
}
}
//
int conditionsCount = ArraySize(mXPVTConditionsCollection);
result = IsValidSize(conditionsCount);
if (!result)
{
return result;
}
//
// Looking For Conditions ...
int selectedIndex = 0;
X121SMCStrategyXPVTSignalConditions mTmpConditions[];
Copy(
mXPVTConditionsCollection,
mTmpConditions //
);
X121SMCStrategyXPVTSignalConditions mConditions;
for (int i = 0; i < conditionsCount; i++)
{
//
// Check Triggers ...
bool canTrigger = mTmpConditions[i].CanTrigger();
datetime triggerTime = mTmpConditions[i].triggerTime;
if (!canTrigger)
{
//
// Detect Signal Trigger ...
canTrigger = DetectX121SMCXPVTSiganlTrigger(
mTmpConditions[i],
symbol,
period,
mTriggerCycleHelper,
mDecisionCycleHelper,
mAnalyseCycleHelper,
mVerificationCycleHelper,
mConsolidationCycleHelper,
mVisionCycleHelper //
);
//
result = canTrigger;
if (!result)
{
//
bool isISetuped = mTmpConditions[i].IsSetuped();
if (!isISetuped)
{
//
ArrayRemove(
mXPVTConditionsCollection,
i,
1 //
);
}
continue;
}
//
triggerTime = mTmpConditions[i].triggerTime;
}
//
if (canTrigger)
{
//
selectedIndex = i;
mConditions = mTmpConditions[i];
break;
}
}
//
result = IsValid(mConditions.setupTime) &&
HasDirection(mConditions.dir);
if (!result)
{
return result;
}
//
// Remove Selected Index from Main Collection ...
ArrayRemove(
mXPVTConditionsCollection,
selectedIndex,
1 //
);
//
// Check Signal Direction ...
isBullish = IsBullish(mConditions.dir);
isBearish = IsBearish(mConditions.dir);
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
// Issues Signal on Conditions ...
conditions.sl = mConditions.sl;
conditions.provider = providerStr;
conditions.signalDir = mConditions.dir;
conditions.target = mConditions.target;
//
return result;
}
//
// XSTRPV Signal ...
bool DetectXSTRPVSignal(
@@ -1388,6 +1652,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
//
useXSignal = true;
useXPZSignal = false;
useXPVTSignal = false;
useXRSPVISignal = false;
useXSTRPVSignal = false;
@@ -1457,21 +1722,25 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
//
// XATR ...
x121Inputs.xatrInputs.showATRUpper = showAll || false;
x121Inputs.xatrInputs.showATRLower = showAll || false;
x121Inputs.xatrInputs.showATRUpper = showAll || true;
x121Inputs.xatrInputs.showATRLower = showAll || true;
//
x121Inputs.xatrInputs.atrMultiplier = 1.5;
x121Inputs.xatrInputs.atrSmoothingMode = X_MA_MODE_EMA;
//
// XSTR ...
x121Inputs.xstrInputs.showStr = showAll || false;
x121Inputs.xstrInputs.showStr = true || false;
x121Inputs.xstrInputs.showStrUpper = showAll || false;
x121Inputs.xstrInputs.showStrLower = showAll || false;
//
// XCHE ...
x121Inputs.xcheInputs.showLE1 = showAll || false;
x121Inputs.xcheInputs.showLE2 = showAll || false;
x121Inputs.xcheInputs.showSE1 = showAll || false;
x121Inputs.xcheInputs.showSE2 = showAll || false;
x121Inputs.xcheInputs.showLE1 = showAll || true;
x121Inputs.xcheInputs.showLE2 = showAll || true;
x121Inputs.xcheInputs.showSE1 = showAll || true;
x121Inputs.xcheInputs.showSE2 = showAll || true;
//
// XDON ...