This commit is contained in:
2024-09-19 14:49:24 +03:30
parent f3398901ef
commit 46f8009ca5
5 changed files with 478 additions and 248 deletions
+357 -239
View File
@@ -54,10 +54,12 @@ struct X121TradeData
string conditions; // Signal Conditions
//
int trailStep; // Trail Step
int protectionStep; // Protection Step
double lastProtectedVolume; // Last Protected Volume
bool partiallyClosed; // Partially Closed or not
int trailStep; // Trail Step
int protectionStep; // Protection Step
datetime lastProtectedOn; // Last Protection Date
double lastProtectedInProfit; // Last Protection In Profit
double lastProtectedInDrawdown; // Last Protection In Drawdown
bool partiallyClosed; // Partially Closed or not
//
// Constructor ...
@@ -199,7 +201,9 @@ struct X121TradeData
trailStep = 0;
protectionStep = 0;
partiallyClosed = false;
lastProtectedVolume = 0;
lastProtectedOn = NULL;
lastProtectedInProfit = 0;
lastProtectedInDrawdown = 0;
//
signal.Clean();
@@ -1233,6 +1237,44 @@ class X121SCTradeHandler : public XSCBaseAlert
mRecoveryMultiplier = value;
}
//
int RecoveryDelayInMinute()
{
return mRecoveryDelayInMinute;
}
//
void RecoveryDelayInMinute(int value)
{
//
if (value < 0)
{
value = 0;
}
//
mRecoveryDelayInMinute = value;
}
//
double RecoveryDistanceInPoint()
{
return mRecoveryDistanceInPoint;
}
//
void RecoveryDistanceInPoint(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mRecoveryDistanceInPoint = value;
}
//
double PartialCloseOnSpecificPointOfDrawdown()
{
@@ -2288,59 +2330,51 @@ class X121SCTradeHandler : public XSCBaseAlert
// Check Main Positions Count and also not Support Positions ...
result = supportsCount == 0 &&
positionsCount >= minOpenPositions;
if (!result)
{
return result;
}
//
// Check Profits ...
result = profits > 0;
if (!result)
{
return result;
}
//
// Calculate Required Profit ...
double volumeSteps = volumes / minVolumeStep;
double minRequiredProfit = (volumeSteps * heMinProfitPerVolumeStep) +
commissions + (-1 * swaps);
//
// Check Profits Satisfied Required Profit's For Hedge or not ...
result = profits >= minRequiredProfit;
if (!result)
{
return result;
}
//
int flatPositionsCount = ArraySize(flatPositions);
result = IsValidSize(flatPositionsCount);
if (!result)
{
return result;
}
//
string comment = "EQM HE Hedge ...";
int closed = mTrader.Close(
flatPositions,
comment //
);
//
result = closed > 0;
if (result)
{
//
string message = "EQM HE Hedge Close (" + ToString(flatPositionsCount) + ") Positions by: " + ToString(profits);
Alert(message);
}
// Check Profits ...
result = profits > 0;
if (result)
{
//
// Calculate Required Profit ...
double volumeSteps = volumes / minVolumeStep;
double minRequiredProfit = (volumeSteps * heMinProfitPerVolumeStep) +
commissions + (-1 * swaps);
//
return result;
//
// Check Profits Satisfied Required Profit's For Hedge or not ...
result = profits >= minRequiredProfit;
if (result)
{
//
int flatPositionsCount = ArraySize(flatPositions);
result = IsValidSize(flatPositionsCount);
if (result)
{
//
string comment = "EQM HE Hedge ...";
int closed = mTrader.Close(
flatPositions,
comment //
);
//
result = closed > 0;
if (result)
{
//
string message = "EQM HE Hedge Close (" + ToString(flatPositionsCount) + ") Positions by: " + ToString(profits);
Alert(message);
//
return result;
}
}
}
}
}
}
//
@@ -2356,47 +2390,44 @@ class X121SCTradeHandler : public XSCBaseAlert
//
// Check Profits ...
result = profits > 0;
if (!result)
{
return result;
}
//
// Calculate Required Profit ...
double volumeSteps = volumes / minVolumeStep;
double minRequiredProfit = (volumeSteps * beMinProfitPerVolumeStep) +
commissions + (-1 * swaps);
//
// Check Profits Satisfied Required Profit's For Hedge or not ...
result = profits >= minRequiredProfit;
if (!result)
{
return result;
}
//
int flatPositionsCount = ArraySize(flatPositions);
result = IsValidSize(flatPositionsCount);
if (!result)
{
return result;
}
//
string comment = "EQM BE Hedge ...";
int closed = mTrader.Close(
flatPositions,
comment //
);
//
result = closed > 0;
if (result)
{
//
string message = "EQM BE Hedge Close (" + ToString(flatPositionsCount) + ") Positions by: " + ToString(profits);
Alert(message);
// Calculate Required Profit ...
double volumeSteps = volumes / minVolumeStep;
double minRequiredProfit = (volumeSteps * beMinProfitPerVolumeStep) +
commissions + (-1 * swaps);
//
// Check Profits Satisfied Required Profit's For Hedge or not ...
result = profits >= minRequiredProfit;
if (result)
{
//
int flatPositionsCount = ArraySize(flatPositions);
result = IsValidSize(flatPositionsCount);
if (result)
{
//
string comment = "EQM BE Hedge ...";
int closed = mTrader.Close(
flatPositions,
comment //
);
//
result = closed > 0;
if (result)
{
//
string message = "EQM BE Hedge Close (" + ToString(flatPositionsCount) + ") Positions by: " + ToString(profits);
Alert(message);
//
return result;
}
}
}
}
//
@@ -2769,6 +2800,140 @@ class X121SCTradeHandler : public XSCBaseAlert
}
}
//
bool allowRecover = AllowRecoverInDrawdowns();
double volumeMultiplier = RecoveryMultiplier();
if (allowRecover && volumeMultiplier > 0 && supportsCount > 0)
{
//
bool canRecover = false;
int delayMinutes = RecoveryDelayInMinute();
double recoveryDistancePoint = RecoveryDistanceInPoint();
//
// Temparory Requirement for Recover Signal ...
double sl = 0;
double tp = 0;
double entry = 0;
ENUM_POSITION_TYPE type = NULL;
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
double lastStep = mData[iDX].protectionStep;
double volume = position.volume * volumeMultiplier;
// supportsCount <= 0
// ? position.volume * volumeMultiplier
// : position.volume * ((supportsCount + 1) * volumeMultiplier);
//
datetime currentTime = TimeCurrent();
double currentProfit = position.GetProfitInPoint();
datetime lastProtectedOn = mData[iDX].lastProtectedOn;
double lastProtectedProfit = mData[iDX].lastProtectedInProfit;
bool isRecoveryConditionsPassed =
//
// Check Regular Conditions ...
delayMinutes > 0 &&
recoveryDistancePoint > 0 &&
IsValid(lastProtectedOn) &&
//
// Check Time Delay Passed ...
(TimeToSeconds(currentTime) - TimeToSeconds(lastProtectedOn)) >= ulong(delayMinutes * 60) &&
//
// Check Recovery Distance Passed ...
MathAbs(currentProfit) - MathAbs(lastProtectedProfit) >= recoveryDistancePoint;
//
if (isRecoveryConditionsPassed)
{
//
// Long Recovery ...
if (isLong)
{
//
// Same Direction ...
canRecover = true;
if (canRecover)
{
//
sl = position.sl;
tp = position.tp;
type = POSITION_TYPE_BUY;
}
}
//
// Short Recovery ...
else
{
//
// Same Direction ...
canRecover = true;
if (canRecover)
{
//
sl = position.sl;
tp = position.tp;
type = POSITION_TYPE_SELL;
}
}
//
if (canRecover)
{
//
XSignal signal;
entry = GetEntry(
position.symbol,
type //
);
//
// Prepare Signal ...
result = signal.Prepare(
position.symbol,
position.provider,
position.period,
type,
mode,
entry,
volume,
sl,
tp //
);
//
if (result)
{
//
// Generate Comment for Recover and Support ...
string comment = GenerateSupportTag(position.ticket);
//
signal.comment = comment;
//
ENUM_X_SIGNAL_EXECUTION_RESULT state;
result = ExecuteSignal(
signal,
state,
true // Support Signal need to Ignore Policies ...
);
if (result)
{
//
mData[iDX].protectionStep++;
mData[iDX].lastProtectedOn = currentTime;
mData[iDX].lastProtectedInProfit = currentProfit;
//
string message = "EQM Open " + (IsLong(type) ? "Long" : "Short") + " Recovery Position in Level: " +
ToString(lastStep + 1) +
" for (" + ToString(position.ticket) + ")";
Alert(message);
}
}
}
}
}
//
// Check Points of Profit and Do Partial Closing ...
double partialCloseVolume = PartialCloseVolumeInProfit();
@@ -2817,6 +2982,8 @@ class X121SCTradeHandler : public XSCBaseAlert
{
//
bool canRecover = false;
int delayMinutes = RecoveryDelayInMinute();
double recoveryDistancePoint = RecoveryDistanceInPoint();
//
// Temparory Requirement for Recover Signal ...
@@ -2826,171 +2993,120 @@ class X121SCTradeHandler : public XSCBaseAlert
ENUM_POSITION_TYPE type = NULL;
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
double lastStep = mData[iDX].protectionStep;
double volume = supportsCount <= 0
? position.volume * volumeMultiplier
: position.volume * ((supportsCount + 1) * volumeMultiplier);
double volume = position.volume * volumeMultiplier;
// supportsCount <= 0
// ? position.volume * volumeMultiplier
// : position.volume * ((supportsCount + 1) * volumeMultiplier);
//
// Long Recovery ...
if (isLong)
datetime currentTime = TimeCurrent();
double currentDrawdown = position.GetProfitInPoint();
datetime lastProtectedOn = mData[iDX].lastProtectedOn;
double lastProtectedDrawdown = mData[iDX].lastProtectedInDrawdown;
bool isRecoveryConditionsPassed = supportsCount <= 0
? true
:
//
// Check Regular Conditions ...
delayMinutes > 0 &&
recoveryDistancePoint > 0 &&
IsValid(lastProtectedOn) &&
lastProtectedDrawdown < 0 &&
//
// Check Time Delay Passed ...
(TimeToSeconds(currentTime) - TimeToSeconds(lastProtectedOn)) >= ulong(delayMinutes * 60) &&
//
// Check Recovery Distance Passed ...
MathAbs(currentDrawdown) - MathAbs(lastProtectedDrawdown) >= recoveryDistancePoint;
//
if (isRecoveryConditionsPassed)
{
//
// Opposit Direction ...
canRecover =
//
isTicksBearishForShort &&
(
//
hasBearishTrend &&
(hasBearishPower ||
hasBearishPattern ||
hasBearishPressure)
//
)
//
;
if (canRecover)
// Long Recovery ...
if (isLong)
{
//
sl = position.tp;
tp = position.sl;
type = POSITION_TYPE_SELL;
// Opposit Direction ...
canRecover = true;
if (canRecover)
{
//
sl = position.tp;
tp = position.sl;
type = POSITION_TYPE_SELL;
}
}
//
// Short Recovery ...
else
{
//
// Opposit Direction ...
canRecover = true;
if (canRecover)
{
//
sl = position.tp;
tp = position.sl;
type = POSITION_TYPE_BUY;
}
}
//
// Same Direction ...
// if (!canRecover)
// {
// //
// canRecover =
// //
// isTicksBullishForLong &&
// (
// //
// hasBullishTrend &&
// (hasBullishPower ||
// hasBullishPattern ||
// hasBullishPressure)
// //
// )
// //
// ;
// if (canRecover)
// {
// //
// sl = position.sl;
// tp = position.entry;
// type = POSITION_TYPE_BUY;
// }
// }
}
//
// Short Recovery ...
else
{
//
// Opposit Direction ...
canRecover =
//
isTicksBullishForLong &&
(
//
hasBullishTrend &&
(hasBullishPower ||
hasBullishPattern ||
hasBullishPressure)
//
)
//
;
if (canRecover)
{
//
sl = position.tp;
tp = position.sl;
type = POSITION_TYPE_BUY;
}
//
// Same Direction ...
// if (!canRecover)
// {
// //
// canRecover =
// //
// isTicksBearishForShort &&
// (
// //
// hasBearishTrend &&
// (hasBearishPower ||
// hasBearishPattern ||
// hasBearishPressure)
// //
// )
// //
// ;
// if (canRecover)
// {
// //
// sl = position.sl;
// tp = position.entry;
// type = POSITION_TYPE_SELL;
// }
// }
}
//
if (canRecover)
{
//
XSignal signal;
entry = GetEntry(
position.symbol,
type //
);
//
// Prepare Signal ...
result = signal.Prepare(
position.symbol,
position.provider,
position.period,
type,
mode,
entry,
volume,
sl,
tp //
);
//
if (result)
{
//
// Generate Comment for Recover and Support ...
string comment = GenerateSupportTag(position.ticket);
//
signal.comment = comment;
//
ENUM_X_SIGNAL_EXECUTION_RESULT state;
result = ExecuteSignal(
signal,
state,
true // Support Signal need to Ignore Policies ...
XSignal signal;
entry = GetEntry(
position.symbol,
type //
);
//
// Prepare Signal ...
result = signal.Prepare(
position.symbol,
position.provider,
position.period,
type,
mode,
entry,
volume,
sl,
tp //
);
//
if (result)
{
//
mData[iDX].protectionStep++;
mData[iDX].lastProtectedVolume = volume;
// Generate Comment for Recover and Support ...
string comment = GenerateSupportTag(position.ticket);
//
string message = "EQM Open " + (IsLong(type) ? "Long" : "Short") + " Recovery Position in Level: " +
ToString(lastStep + 1) +
" for (" + ToString(position.ticket) + ")";
Alert(message);
signal.comment = comment;
//
ENUM_X_SIGNAL_EXECUTION_RESULT state;
result = ExecuteSignal(
signal,
state,
true // Support Signal need to Ignore Policies ...
);
if (result)
{
//
mData[iDX].protectionStep++;
mData[iDX].lastProtectedOn = currentTime;
mData[iDX].lastProtectedInDrawdown = currentDrawdown;
//
string message = "EQM Open " + (IsLong(type) ? "Long" : "Short") + " Recovery Position in Level: " +
ToString(lastStep + 1) +
" for (" + ToString(position.ticket) + ")";
Alert(message);
}
}
}
}
@@ -3076,6 +3192,8 @@ class X121SCTradeHandler : public XSCBaseAlert
// In Drawdown Positions Protecting ...
bool mAllowRecoverInDrawdowns; // Allow Recovery For In Drawdown Positions
double mRecoveryMultiplier; // Recovery Volume Multiplier
int mRecoveryDelayInMinute; // Delay Between Two Recovery in Minutes
double mRecoveryDistanceInPoint; // Distance Between Two Recovery in Point
double mPartialCloseOnSpecificPointOfDrawdown; // Partial Close Position on Specific Points of Drawdown
double mPartialCloseVolumeInDrawdown; // Partial Close Volume
+108
View File
@@ -0,0 +1,108 @@
//
// Long Recovery ...
if (isLong)
{
//
// Opposit Direction ...
// canRecover =
// //
// isTicksBearishForShort &&
// (
// //
// hasBearishTrend &&
// (hasBearishPower ||
// hasBearishPattern ||
// hasBearishPressure)
// //
// )
// //
// ;
// if (canRecover)
// {
// //
// sl = position.tp;
// tp = position.sl;
// type = POSITION_TYPE_SELL;
// }
//
// Same Direction ...
// if (!canRecover)
// {
// //
// canRecover =
// //
// isTicksBullishForLong &&
// (
// //
// hasBullishTrend &&
// (hasBullishPower ||
// hasBullishPattern ||
// hasBullishPressure)
// //
// )
// //
// ;
// if (canRecover)
// {
// //
// sl = position.sl;
// tp = position.entry;
// type = POSITION_TYPE_BUY;
// }
// }
}
//
// Short Recovery ...
else
{
//
// Opposit Direction ...
// canRecover =
// //
// isTicksBullishForLong &&
// (
// //
// hasBullishTrend &&
// (hasBullishPower ||
// hasBullishPattern ||
// hasBullishPressure)
// //
// )
// //
// ;
// if (canRecover)
// {
// //
// sl = position.tp;
// tp = position.sl;
// type = POSITION_TYPE_BUY;
// }
//
// Same Direction ...
// if (!canRecover)
// {
// //
// canRecover =
// //
// isTicksBearishForShort &&
// (
// //
// hasBearishTrend &&
// (hasBearishPower ||
// hasBearishPattern ||
// hasBearishPressure)
// //
// )
// //
// ;
// if (canRecover)
// {
// //
// sl = position.sl;
// tp = position.entry;
// type = POSITION_TYPE_SELL;
// }
// }
}
+11 -7
View File
@@ -91,11 +91,11 @@ input double eaProtectorStartDistanceInPoint = 35; // Protector Start Distance i
//
// Protector > Hedging Properties ...
input group "Hedging";
input bool eaAllowHedge = false; // Allow Protector to Hedge Positions
input double eaHedgeMinVolumeStep = 0.01; // Minimum Volume Step For Hedge
input int eaMinimumOpenPositionsForHEHedge = 2; // Minimum Open Positions For HE Hedge
input double eaHedgeHEMinProfitPerVolumeStep = 0.2; // Minimum Required Profit For HE Hedge Per Volume Step
input double eaHedgeBEMinProfitPerVolumeStep = 0.05; // Minimum Required Profit For BE Hedge Per Volume Step
input bool eaAllowHedge = false; // Allow Protector to Hedge Positions
input double eaHedgeMinVolumeStep = 0.01; // Minimum Volume Step For Hedge
input int eaMinimumOpenPositionsForHEHedge = 2; // Minimum Open Positions For HE Hedge
input double eaHedgeHEMinProfitPerVolumeStep = 1; // Minimum Required Profit For HE Hedge Per Volume Step
input double eaHedgeBEMinProfitPerVolumeStep = 0.1; // Minimum Required Profit For BE Hedge Per Volume Step
//
// Protector > In Profit Positions Protecting ...
@@ -103,7 +103,7 @@ input group "In Profit Positions Protecting";
input bool eaAllowTrailStopInProfits = true; // Allow Trail Stops for In Profit Positions
input bool eaOnlyTrailUnprotectedPositions = true; // Only Trail UnProtected Positions
input double eaTrailStopStepsInPoint = 10; // Trail Stop Steps in Point
input int eaRmoveTPOnTrailStep = 0; // Remove Position TP if Trailed specific times
input int eaRmoveTPOnTrailStep = 5; // Remove Position TP if Trailed specific times
input double eaPartialCloseOnSpecificPointOfProfit = 0; // Partial Close Position on Specific Points of Profit
input double eaPartialCloseVolumeInProfit = 0; // Partial Close Volume
@@ -111,7 +111,9 @@ input double eaPartialCloseVolumeInProfit = 0; // Partial Close Volume
// Protector > In Drawdown Positions Protecting ...
input group "In Drawdown Positions Protecting";
input bool eaAllowRecoverInDrawdowns = true; // Allow Recovery For In Drawdown Positions
input double eaRecoveryMultiplier = 2; // Recovery Volume Multiplier
input double eaRecoveryMultiplier = 1; // Recovery Volume Multiplier
input int eaRecoveryDelayInMinute = 1; // Delay Between Two Recovery in Minutes
input double eaRecoveryDistanceInPoint = 30; // Distance Between Two Recovery in Point
input double eaPartialCloseOnSpecificPointOfDrawdown = 0; // Partial Close Position on Specific Points of Drawdown
input double eaPartialCloseVolumeInDrawdown = 0; // Partial Close Volume
@@ -499,6 +501,8 @@ bool InitialEA()
// Protector > In Drawdown Positions Protecting ...
eaTradeHandler.AllowRecoverInDrawdowns(eaAllowRecoverInDrawdowns);
eaTradeHandler.RecoveryMultiplier(eaRecoveryMultiplier);
eaTradeHandler.RecoveryDelayInMinute(eaRecoveryDelayInMinute);
eaTradeHandler.RecoveryDistanceInPoint(eaRecoveryDistanceInPoint);
eaTradeHandler.PartialCloseOnSpecificPointOfDrawdown(eaPartialCloseOnSpecificPointOfDrawdown);
eaTradeHandler.PartialCloseVolumeInDrawdown(eaPartialCloseVolumeInDrawdown);
+1 -1
View File
@@ -16,7 +16,7 @@ async function handlePack() {
//
var year = date.getFullYear();
var month = date.getMonth();
var month = date.getMonth() + 1;
var day = date.getDate();
var hour = date.getHours();
var min = date.getMinutes();
+1 -1
View File
@@ -25,7 +25,7 @@
"rmClassesEx": "shx --silent rm -r ./Classes/*.ex5 || npm run true",
"rmIndicatorsEx": "shx --silent rm -r ./Indicators/*.ex5 || npm run true",
"prepareWorkspace": "npm run cleanupEx && npm run compileEA",
"generatePack": "npm run prepareWorkspace && npm run pack"
"generatePack": "npm run prepareWorkspace && npm run pack && npm run cleanupEx && npm run compileIndicators"
},
"repository": {
"type": "git",