last works on Position Protector ...

This commit is contained in:
2024-09-17 16:49:45 +03:30
parent f6c4b46da3
commit a1c0a364af
4 changed files with 619 additions and 22 deletions
@@ -53,6 +53,10 @@ struct X121TradeData
int pushers; // Signal Pushers
string conditions; // Signal Conditions
//
int trailStep; // Trail Step
bool partiallyClosed; // Partially Closed or not
//
// Constructor ...
void XTradeInfo()
@@ -189,6 +193,10 @@ struct X121TradeData
commission = 0;
maxDrawdown = 0;
//
trailStep = 0;
partiallyClosed = false;
//
signal.Clean();
}
@@ -1049,7 +1057,7 @@ class X121SCTradeHandler : public XSCBaseAlert
//
double ProtectorStartDistanceInPoint()
{
return mProtectorStartDistanceInPointl
return mProtectorStartDistanceInPoint;
}
//
@@ -1065,6 +1073,116 @@ class X121SCTradeHandler : public XSCBaseAlert
mProtectorStartDistanceInPoint = value;
}
//
int DelayBarBetweenTwoSameSignal()
{
return mDelayBarBetweenTwoSameSignal;
}
//
void DelayBarBetweenTwoSameSignal(int value)
{
//
if (value < 0)
{
value = 0;
}
//
mDelayBarBetweenTwoSameSignal = value;
}
//
// In Profit Position Protecting ...
//
bool AllowTrailStopInProfits()
{
return mAllowTrailStopInProfits;
}
//
void AllowTrailStopInProfits(bool value)
{
mAllowTrailStopInProfits = value;
}
//
double TrailStopStepsInPoint()
{
return mTrailStopStepsInPoint;
}
//
void TrailStopStepsInPoint(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mTrailStopStepsInPoint = value;
}
//
int RmoveTPOnTrailStep()
{
return mRmoveTPOnTrailStep;
}
//
void RmoveTPOnTrailStep(int value)
{
//
if (value < 0)
{
value = 0;
}
//
mRmoveTPOnTrailStep = value;
}
//
double PartialCloseOnSpecificPoint()
{
return mPartialCloseOnSpecificPoint;
}
//
void PartialCloseOnSpecificPoint(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mPartialCloseOnSpecificPoint = value;
}
//
double PartialCloseVolume()
{
return mPartialCloseVolume;
}
//
void PartialCloseVolume(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mPartialCloseVolume = value;
}
//
// Hedge Props ...
@@ -1776,6 +1894,50 @@ class X121SCTradeHandler : public XSCBaseAlert
state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED;
return result;
}
//
// Check Position Delays ...
if (result && mDelayBarBetweenTwoSameSignal > 0)
{
//
int youngestAge = 0;
XPosition youngestPosition;
//
// Long Positions when there are Longs ...
if (isLong && longsCount > 0)
{
//
youngestAge = GetYoungest(
youngestPosition,
longs //
);
}
//
// Short Positions when there are Shorts ...
else if (!isLong && shortsCount > 0)
{
//
youngestAge = GetYoungest(
youngestPosition,
shorts //
);
}
//
// Only Check when there is must to check and conditions happens ...
if (youngestAge > 0 && youngestPosition.IsValid())
{
//
result = youngestAge >= mDelayBarBetweenTwoSameSignal;
if (!result)
{
//
state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED;
return result;
}
}
}
}
//
@@ -1886,7 +2048,7 @@ class X121SCTradeHandler : public XSCBaseAlert
{
//
// Check Position is Protectable or not ...
XPosition iProtected = pPositions[i];
XProtectedPosition iProtected = pPositions[i];
//
XPosition iPosition = iProtected.main;
@@ -2138,7 +2300,380 @@ class X121SCTradeHandler : public XSCBaseAlert
bool result = false;
//
// Here we Make Sure this Position has ...
// Find Position's Item Data ...
int iDX = -1;
result = HasItem(
position.ticket,
iDX //
);
if (!result)
{
return result;
}
//
// Here we Make Sure this Position has reached Proper distance ...
//
bool isLong = IsLong(position.type);
bool isInProfit = position.profit > 0;
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
// Last Bar ...
XOHCL cBar;
result = cBar.Init(
position.symbol,
position.period,
cIndex //
);
if (!result)
{
return result;
}
//
// Previous Bar of Last Bar ...
XOHCL pBar;
result = cBar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Last Swing Low Bar ...
XOHCL lastSwingLow;
result = cBar.FindLastSwingLow(lastSwingLow);
if (!result)
{
return result;
}
//
// Last Swing High Bar ...
XOHCL lastSwingHigh;
result = cBar.FindLastSwingHigh(lastSwingHigh);
if (!result)
{
return result;
}
//
// Common Conditions For Bullish and Bearish Powers ...
//
// For Trend ...
XOHCL tmpHSW[];
XOHCL tmpLSW[];
//
// Detect Bullish/Bearish Patterns and Trends ...
//
// Bullish ...
bool hasBullishPower = cBar.HasBullishPower();
bool hasBullishPattern = HasBullishPattern(cBar);
bool hasBullishPressure = cBar.HasBullishPressure();
bool isBullishTrend = cBar.HasBullishTrend(
tmpHSW,
tmpLSW,
true //
);
bool isBullishTrend1 = cBar.HasBullishTrend(
tmpHSW,
tmpLSW,
false //
);
//
// Bearish ...
bool hasBearishPower = cBar.HasBearishPower();
bool hasBearishPattern = HasBearishPattern(cBar);
bool hasBearishPressure = cBar.HasBearishPressure();
bool isBearishTrend = cBar.HasBearishTrend(
tmpHSW,
tmpLSW,
true //
);
bool isBearishTrend1 = cBar.HasBearishTrend(
tmpHSW,
tmpLSW,
false //
);
//
// Define Conditions ...
MqlTick ticks[];
int ticksCount = CopyTicks(
position.symbol,
ticks,
COPY_TICKS_ALL,
0,
5 //
);
//
// 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 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 hasBearishDecision =
//
cBar.IsBearishDecision()
//
||
//
pBar.IsBearishDecision()
//
;
//
bool hasBullishDecision =
//
cBar.IsBullishDecision()
//
||
//
pBar.IsBullishDecision()
//
;
//
bool hasBullishConditions =
//
isTicksBullish &&
(isBullishTrend ||
isBullishTrend1) &&
(hasBullishPower ||
hasBullishPattern ||
hasBullishPressure)
//
;
//
bool hasBearishConditions =
//
isTicksBearish &&
(isBearishTrend ||
isBearishTrend1) &&
(hasBearishPower ||
hasBearishPattern ||
hasBearishPressure)
//
;
//
// In Profit ...
// When a Position running in Profit, we have to look pressures by Same Direction
// of Main Position. for eaxmple if it is long, we look for Bullish Pressures and
// if it is short we look for Bearish Pressures.
// when pressure happens we must Trail position Stop ...
if (isInProfit)
{
//
// 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)
{
//
// Temp Vaiables ...
bool canTrailStop = false;
//
if (isLong)
{
//
// Check Conditions ...
canTrailStop = isTicksBullish &&
(hasBullishDecision ||
hasBullishConditions);
}
else
{
//
// Check Conditions ...
canTrailStop = isTicksBearish &&
(hasBearishDecision ||
hasBearishConditions);
}
//
// Do Stop Trailling ...
if (canTrailStop)
{
//
int lastTrailedStep = mData[iDX].trailStep;
//
double entry = position.entry;
double pointValue = position.GetPointsValue();
double profitInPoint = position.GetProfitInPoint();
//
double requiredProfit =
lastTrailedStep == 0
? ProtectorStartDistanceInPoint()
: lastTrailedStep * trailStep;
//
bool isProfitsPassed = profitInPoint > requiredProfit;
if (isProfitsPassed)
{
//
double delta = (requiredProfit * pointValue);
//
double sl =
isLong
? entry + delta
: entry - delta;
//
string comment = "EQM Trail Stop ...";
//
// Try to Modify Position ...
result = mTrader.Modify(
position.ticket,
sl,
position.tp,
comment //
);
if (result)
{
//
mData[iDX].trailStep++;
//
string message = "EQM Trail (" + ToString(position.ticket) + ") Stop ...";
Alert(message);
//
XPosition trailedPosition;
bool hasPosition = mTrader.GetPosition(
position.ticket,
trailedPosition //
);
//
// Check Remove Trailed Positions TP Conditions ...
int removeTPOnTrailStep = RmoveTPOnTrailStep();
if (removeTPOnTrailStep > 0 && mData[iDX].trailStep == removeTPOnTrailStep && trailedPosition.tp != 0)
{
//
string comment = "EQM Removes TP ...";
//
// Remove Position's TP ...
result = mTrader.Modify(
trailedPosition.ticket,
trailedPosition.sl,
0,
comment //
);
if (result)
{
//
string message = "EQM Removes (" + ToString(trailedPosition.ticket) + ") TP ...";
Alert(message);
}
}
}
}
}
//
if (result)
{
return result;
}
}
//
// Check Points of Profit and Do Partial Closing ...
double partialCloseVolume = PartialCloseVolume();
double partialCloseProfitPoint = PartialCloseOnSpecificPoint();
if (partialCloseVolume > 0 && partialCloseProfitPoint > 0)
{
//
double profitPoints = position.GetProfitInPoint();
if (profitPoints >= partialCloseProfitPoint && !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);
}
}
}
}
//
// In Drawdown ...
// When a Position running in Drawdown, we have to look for pressures by Indirection
// of Main Position. for example if it is long, we Look For Bearish Pressures and if
// it is short we Look for Bullish Pressure.
// when indirectional pressure found we must Open a Recovery Position.
// also if Same Direction Pressure Found we try to Recover Same Direction using Grid ...
else
{
//
if (isLong)
{
}
else
{
}
}
//
return result;
@@ -2171,8 +2706,17 @@ class X121SCTradeHandler : public XSCBaseAlert
double mMaxDrawdownPercentForOpenTrades; // Max Drawdown Percent for Open Trades
//
int mDelayBarBetweenTwoSameSignal; // Delay Bars Between Two Same Type Signal
double mProtectorStartDistanceInPoint; // Protector Start Distance in Point
//
// 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
//
// Hedging Properties ...
bool mAllowHedge; // Allow Protector to Hedge Positions