Implement Position Protector ...

need to test BE Hedge ...
This commit is contained in:
2024-09-18 21:13:23 +03:30
parent dbdbb3a276
commit 9393c9ecfe
7 changed files with 623 additions and 119 deletions
+426 -96
View File
@@ -54,8 +54,10 @@ struct X121TradeData
string conditions; // Signal Conditions
//
int trailStep; // Trail Step
bool partiallyClosed; // Partially Closed or not
int trailStep; // Trail Step
int protectionStep; // Protection Step
double lastProtectedVolume; // Last Protected Volume
bool partiallyClosed; // Partially Closed or not
//
// Constructor ...
@@ -195,7 +197,9 @@ struct X121TradeData
//
trailStep = 0;
protectionStep = 0;
partiallyClosed = false;
lastProtectedVolume = 0;
//
signal.Clean();
@@ -1107,6 +1111,18 @@ class X121SCTradeHandler : public XSCBaseAlert
mAllowTrailStopInProfits = value;
}
//
bool OnlyTrailUnprotectedPositions()
{
return mOnlyTrailUnprotectedPositions;
}
//
void OnlyTrailUnprotectedPositions(bool value)
{
mOnlyTrailUnprotectedPositions = value;
}
//
double TrailStopStepsInPoint()
{
@@ -1146,13 +1162,13 @@ class X121SCTradeHandler : public XSCBaseAlert
}
//
double PartialCloseOnSpecificPoint()
double PartialCloseOnSpecificPointOfProfit()
{
return mPartialCloseOnSpecificPoint;
return mPartialCloseOnSpecificPointOfProfit;
}
//
void PartialCloseOnSpecificPoint(double value)
void PartialCloseOnSpecificPointOfProfit(double value)
{
//
if (value < 0)
@@ -1161,17 +1177,17 @@ class X121SCTradeHandler : public XSCBaseAlert
}
//
mPartialCloseOnSpecificPoint = value;
mPartialCloseOnSpecificPointOfProfit = value;
}
//
double PartialCloseVolume()
double PartialCloseVolumeInProfit()
{
return mPartialCloseVolume;
return mPartialCloseVolumeInProfit;
}
//
void PartialCloseVolume(double value)
void PartialCloseVolumeInProfit(double value)
{
//
if (value < 0)
@@ -1180,7 +1196,79 @@ class X121SCTradeHandler : public XSCBaseAlert
}
//
mPartialCloseVolume = value;
mPartialCloseVolumeInProfit = value;
}
//
// In Drawdown Positions Protecting ...
//
bool AllowRecoverInDrawdowns()
{
return mAllowRecoverInDrawdowns;
}
//
void AllowRecoverInDrawdowns(bool value)
{
mAllowRecoverInDrawdowns = value;
}
//
double RecoveryMultiplier()
{
return mRecoveryMultiplier;
}
//
void RecoveryMultiplier(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mRecoveryMultiplier = value;
}
//
double PartialCloseOnSpecificPointOfDrawdown()
{
return mPartialCloseOnSpecificPointOfDrawdown;
}
//
void PartialCloseOnSpecificPointOfDrawdown(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mPartialCloseOnSpecificPointOfDrawdown = value;
}
//
double PartialCloseVolumeInDrawdown()
{
return mPartialCloseVolumeInDrawdown;
}
//
void PartialCloseVolumeInDrawdown(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mPartialCloseVolumeInDrawdown = value;
}
//
@@ -1772,20 +1860,6 @@ class X121SCTradeHandler : public XSCBaseAlert
return result;
}
//
// TODO:
// Here we can apply Same type or Opposit Type
// Signals behaviour ...
// also check For Market Open ...
//
// Check Market ...
// TODO: Fix this ...
// result = mSymbolSession.CanTrade(signal.symbol);
// if (!result) {
// return result;
// }
//
return result;
}
@@ -2054,15 +2128,15 @@ class X121SCTradeHandler : public XSCBaseAlert
XPosition iPosition = iProtected.main;
//
double iSymbolPoint = GetPoints(iPosition.symbol);
double iDistance = MathAbs(iPosition.profit) * iSymbolPoint;
//
double iDistance = MathAbs(iPosition.GetProfitInPoint());
bool isDistancePassed = iDistance >= requiredDistance;
if (isDistancePassed)
{
//
bool isProtected = HandlePositionProtecting(iPosition);
bool isProtected = HandlePositionProtecting(
iPosition,
iProtected.supports //
);
if (isProtected)
{
protectedPositions++;
@@ -2200,6 +2274,7 @@ class X121SCTradeHandler : public XSCBaseAlert
//
int minOpenPositions = MinimumOpenPositionsForHEHedge();
double heMinProfitPerVolumeStep = HedgeHEMinProfitPerVolumeStep();
double beMinProfitPerVolumeStep = HedgeBEMinProfitPerVolumeStep();
//
// Check HE Hedge Conditions ...
@@ -2271,21 +2346,58 @@ class X121SCTradeHandler : public XSCBaseAlert
//
// Check BE Hedge Conditions ...
bool allowBEHedge = positionsCount >= 1 &&
supportsCount >= 1;
supportsCount >= 1 &&
beMinProfitPerVolumeStep > 0;
if (allowBEHedge)
{
//
// Implement BE Hedge ...
//
// Check BE Conditions ...
result = supportsCount > 0;
// 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);
}
//
return result;
@@ -2298,7 +2410,10 @@ class X121SCTradeHandler : public XSCBaseAlert
/**
* Handle Protecting Position ...
*/
bool HandlePositionProtecting(XPosition &position)
bool HandlePositionProtecting(
XPosition &position, // Main Position
XPosition &supports[] // Supports
)
{
//
bool result = false;
@@ -2322,6 +2437,9 @@ class X121SCTradeHandler : public XSCBaseAlert
bool isLong = IsLong(position.type);
bool isInProfit = position.profit > 0;
//
int supportsCount = ArraySize(supports);
//
int zIndex = 0;
int cIndex = zIndex + 1;
@@ -2394,6 +2512,15 @@ class X121SCTradeHandler : public XSCBaseAlert
tmpLSW,
false //
);
bool hasBullishTrend =
//
isBullishTrend
//
||
//
isBullishTrend1
//
;
//
// Bearish ...
@@ -2410,6 +2537,15 @@ class X121SCTradeHandler : public XSCBaseAlert
tmpLSW,
false //
);
bool hasBearishTrend =
//
isBearishTrend
//
||
//
isBearishTrend1
//
;
//
// Define Conditions ...
@@ -2426,35 +2562,38 @@ class X121SCTradeHandler : public XSCBaseAlert
// TODO: Check Volume if Required ...
//
bool isTicksBullish =
(
//
ticks[0].last > ticks[1].last &&
ticks[1].last > ticks[2].last &&
ticks[2].last > ticks[3].last &&
ticks[3].last > ticks[4].last
//
);
bool isTicksBullishForLong =
//
GetTickExit(ticks[0], POSITION_TYPE_BUY, position.symbol) > GetTickExit(ticks[1], POSITION_TYPE_BUY, position.symbol) &&
GetTickExit(ticks[1], POSITION_TYPE_BUY, position.symbol) > GetTickExit(ticks[2], POSITION_TYPE_BUY, position.symbol) &&
GetTickExit(ticks[2], POSITION_TYPE_BUY, position.symbol) > GetTickExit(ticks[3], POSITION_TYPE_BUY, position.symbol)
//
;
//
bool isTicksBearish =
(
//
ticks[0].last < ticks[1].last &&
ticks[1].last < ticks[2].last &&
ticks[2].last < ticks[3].last &&
ticks[3].last < ticks[4].last
//
);
bool isTicksBearishForLong =
//
GetTickExit(ticks[0], POSITION_TYPE_BUY, position.symbol) < GetTickExit(ticks[1], POSITION_TYPE_BUY, position.symbol) &&
GetTickExit(ticks[1], POSITION_TYPE_BUY, position.symbol) < GetTickExit(ticks[2], POSITION_TYPE_BUY, position.symbol) &&
GetTickExit(ticks[2], POSITION_TYPE_BUY, position.symbol) < GetTickExit(ticks[3], POSITION_TYPE_BUY, position.symbol)
//
;
//
bool hasBearishDecision =
bool isTicksBullishForShort =
//
cBar.IsBearishDecision()
GetTickExit(ticks[0], POSITION_TYPE_SELL, position.symbol) > GetTickExit(ticks[1], POSITION_TYPE_SELL, position.symbol) &&
GetTickExit(ticks[1], POSITION_TYPE_SELL, position.symbol) > GetTickExit(ticks[2], POSITION_TYPE_SELL, position.symbol) &&
GetTickExit(ticks[2], POSITION_TYPE_SELL, position.symbol) > GetTickExit(ticks[3], POSITION_TYPE_SELL, position.symbol)
//
||
;
//
bool isTicksBearishForShort =
//
pBar.IsBearishDecision()
GetTickExit(ticks[0], POSITION_TYPE_SELL, position.symbol) < GetTickExit(ticks[1], POSITION_TYPE_SELL, position.symbol) &&
GetTickExit(ticks[1], POSITION_TYPE_SELL, position.symbol) < GetTickExit(ticks[2], POSITION_TYPE_SELL, position.symbol) &&
GetTickExit(ticks[2], POSITION_TYPE_SELL, position.symbol) < GetTickExit(ticks[3], POSITION_TYPE_SELL, position.symbol)
//
;
@@ -2463,33 +2602,42 @@ class X121SCTradeHandler : public XSCBaseAlert
//
cBar.IsBullishDecision()
//
||
;
//
bool hasBearishDecision =
//
pBar.IsBullishDecision()
cBar.IsBearishDecision()
//
;
//
bool hasBullishConditions =
//
isTicksBullish &&
(isBullishTrend ||
isBullishTrend1) &&
(hasBullishPower ||
hasBullishPattern ||
hasBullishPressure)
(
//
hasBullishTrend &&
hasBullishDecision &&
(hasBullishPower ||
hasBullishPattern ||
hasBullishPressure)
//
)
//
;
//
bool hasBearishConditions =
//
isTicksBearish &&
(isBearishTrend ||
isBearishTrend1) &&
(hasBearishPower ||
hasBearishPattern ||
hasBearishPressure)
(
//
hasBearishTrend &&
hasBearishDecision &&
(hasBearishPower ||
hasBearishPattern ||
hasBearishPressure)
//
)
//
;
@@ -2504,16 +2652,16 @@ class X121SCTradeHandler : public XSCBaseAlert
//
// Do In Profit Protection Mechanism ...
//
// - [] Partial Close;
// - [] Specified Point of Profits;
//
// Trail Stops ...
// Remove Trailed Positions TP ...
bool allowTrailStop = AllowTrailStopInProfits();
double trailStep = TrailStopStepsInPoint();
if (allowTrailStop && trailStep > 0)
bool allowOnlyUnprotecteds = OnlyTrailUnprotectedPositions();
bool isProtectionTrailPassed = !allowOnlyUnprotecteds
? true
: supportsCount == 0;
if (allowTrailStop && trailStep > 0 && isProtectionTrailPassed)
{
//
// Temp Vaiables ...
@@ -2524,17 +2672,15 @@ class X121SCTradeHandler : public XSCBaseAlert
{
//
// Check Conditions ...
canTrailStop = isTicksBullish &&
(hasBullishDecision ||
hasBullishConditions);
canTrailStop = isTicksBullishForLong &&
hasBullishConditions;
}
else
{
//
// Check Conditions ...
canTrailStop = isTicksBearish &&
(hasBearishDecision ||
hasBearishConditions);
canTrailStop = isTicksBearishForShort &&
hasBearishConditions;
}
//
@@ -2553,7 +2699,7 @@ class X121SCTradeHandler : public XSCBaseAlert
double requiredProfit =
lastTrailedStep == 0
? ProtectorStartDistanceInPoint()
: lastTrailedStep * trailStep;
: ProtectorStartDistanceInPoint() + (lastTrailedStep * trailStep);
//
bool isProfitsPassed = profitInPoint > requiredProfit;
@@ -2621,18 +2767,12 @@ class X121SCTradeHandler : public XSCBaseAlert
}
}
}
//
if (result)
{
return result;
}
}
//
// Check Points of Profit and Do Partial Closing ...
double partialCloseVolume = PartialCloseVolume();
double partialCloseProfitPoint = PartialCloseOnSpecificPoint();
double partialCloseVolume = PartialCloseVolumeInProfit();
double partialCloseProfitPoint = PartialCloseOnSpecificPointOfProfit();
if (partialCloseVolume > 0 && partialCloseProfitPoint > 0)
{
//
@@ -2671,11 +2811,193 @@ class X121SCTradeHandler : public XSCBaseAlert
else
{
//
if (isLong)
bool allowRecover = AllowRecoverInDrawdowns();
double volumeMultiplier = RecoveryMultiplier();
if (allowRecover && volumeMultiplier > 0)
{
//
bool canRecover = false;
//
// 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 = lastStep <= 0
? position.volume * volumeMultiplier
: position.volume * ((lastStep + 1) * volumeMultiplier);
//
// Long Recovery ...
if (isLong)
{
//
// Opposit Direction ...
canRecover =
//
isTicksBearishForShort &&
hasBearishConditions
//
;
if (canRecover)
{
//
sl = position.entry;
tp = position.sl;
type = POSITION_TYPE_SELL;
}
//
// Same Direction ...
if (!canRecover)
{
//
canRecover =
//
isTicksBullishForLong &&
hasBullishConditions
//
;
if (canRecover)
{
//
sl = position.sl;
tp = position.entry;
type = POSITION_TYPE_BUY;
}
}
}
//
// Short Recovery ...
else
{
//
// Opposit Direction ...
canRecover =
//
isTicksBullishForLong &&
hasBullishConditions
//
;
if (canRecover)
{
//
sl = position.entry;
tp = position.sl;
type = POSITION_TYPE_BUY;
}
//
// Same Direction ...
if (!canRecover)
{
//
canRecover =
//
isTicksBearishForShort &&
hasBearishConditions
//
;
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 ...
);
if (result)
{
//
mData[iDX].protectionStep++;
mData[iDX].lastProtectedVolume = volume;
//
string message = "EQM Open " + (IsLong(type) ? "Long" : "Short") + " Recovery Position in Level: " +
ToString(lastStep + 1) +
" for (" + ToString(position.ticket) + ")";
Alert(message);
}
}
}
}
else
//
// Check Points of Drawdown and Do Partial Closing ...
double partialCloseVolume = PartialCloseVolumeInDrawdown();
double partialCloseDrawdownPoint = PartialCloseOnSpecificPointOfDrawdown();
if (partialCloseVolume > 0 && partialCloseDrawdownPoint > 0)
{
//
double profitPoints = position.GetProfitInPoint();
if (profitPoints < 0 && MathAbs(profitPoints) >= partialCloseDrawdownPoint && !mData[iDX].partiallyClosed)
{
//
string comment = "EQM Partial Close ...";
//
// Do Partial Closing ...
result = mTrader.ClosePartial(
position.ticket,
partialCloseVolume,
comment //
);
if (result)
{
//
mData[iDX].partiallyClosed = true;
//
string message = "EQM Partially Closed " + ToString(partialCloseVolume) + " of (" + ToString(position.ticket) + ")";
Alert(message);
}
}
}
}
@@ -2715,11 +3037,19 @@ class X121SCTradeHandler : public XSCBaseAlert
//
// In Profit Positions Protecting ...
bool mAllowTrailStopInProfits; // Allow Trail Stops for In Profit Positions
double mTrailStopStepsInPoint; // Trail Stop Steps in Point
int mRmoveTPOnTrailStep; // Remove Position TP if Trailed specific times
double mPartialCloseOnSpecificPoint; // Partial Close Position on Specific Points of Profit
double mPartialCloseVolume; // Partial Close Volume
bool mAllowTrailStopInProfits; // Allow Trail Stops for In Profit Positions
bool mOnlyTrailUnprotectedPositions; // Only Trail UnProtected Positions
double mTrailStopStepsInPoint; // Trail Stop Steps in Point
int mRmoveTPOnTrailStep; // Remove Position TP if Trailed specific times
double mPartialCloseOnSpecificPointOfProfit; // Partial Close Position on Specific Points of Profit
double mPartialCloseVolumeInProfit; // Partial Close Volume
//
// In Drawdown Positions Protecting ...
bool mAllowRecoverInDrawdowns; // Allow Recovery For In Drawdown Positions
double mRecoveryMultiplier; // Recovery Volume Multiplier
double mPartialCloseOnSpecificPointOfDrawdown; // Partial Close Position on Specific Points of Drawdown
double mPartialCloseVolumeInDrawdown; // Partial Close Volume
//
// Hedging Properties ...