last ...
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user