This commit is contained in:
2024-07-28 14:16:13 +03:30
parent 0e3df1a494
commit be741a0ebd
3 changed files with 383 additions and 50 deletions
+367 -39
View File
@@ -4464,6 +4464,8 @@ public:
// //
item.recoveryTPPoint = mRecoveryTPPoint; item.recoveryTPPoint = mRecoveryTPPoint;
item.recoverySLPoint = mRecoverySLPoint; item.recoverySLPoint = mRecoverySLPoint;
item.maxAllowedRecover = mMaxAllowedRecover;
item.recoveryVolumeMultiplier = mRecoveryVolumeMultiplier;
} }
// //
@@ -4685,8 +4687,6 @@ public:
} }
} }
//
// //
// Do Force Closing ... // Do Force Closing ...
@@ -4699,15 +4699,18 @@ public:
double profit = mData[i].profit; double profit = mData[i].profit;
double volume = mData[i].volume; double volume = mData[i].volume;
string symbol = mData[i].symbol; string symbol = mData[i].symbol;
string provider = mData[i].provider;
bool isLong = IsLong(mData[i].type); bool isLong = IsLong(mData[i].type);
ENUM_TIMEFRAMES period = mData[i].period; ENUM_TIMEFRAMES period = mData[i].period;
double points = GetPoints(mData[i].symbol); double points = GetPoints(mData[i].symbol);
bool ignoreTPOnTrail = mData[i].ignoreTPOnTrail; bool ignoreTPOnTrail = mData[i].ignoreTPOnTrail;
double recoveryTPPoint = mData[i].recoveryTPPoint;
double recoverySLPoint = mData[i].recoverySLPoint;
int maxAllowedRecover = mData[i].maxAllowedRecover;
double trailStepInPoints = mData[i].trailStepInPoint; double trailStepInPoints = mData[i].trailStepInPoint;
double trailStartInPoint = mData[i].trailStartInPoint; double trailStartInPoint = mData[i].trailStartInPoint;
bool trailBasedOnProfit = mData[i].trailBasedOnProfit; bool trailBasedOnProfit = mData[i].trailBasedOnProfit;
double recoveryTPPoint = mData[i].recoveryTPPoint; double recoveryVolumeMultiplier = mData[i].recoveryVolumeMultiplier;
double recoverySLPoint = mData[i].recoverySLPoint;
// //
XPosition iPosition; XPosition iPosition;
@@ -4731,6 +4734,132 @@ public:
continue; continue;
} }
//
// Handle Recovery Break Event ...
if (mData[i].allowRecover)
{
//
if (mData[i].recoveryLevel <= 0)
{
//
if (profit > 0)
{
//
double proftiInPoints = profit / volume;
bool canClose = proftiInPoints >= recoveryTPPoint;
if (canClose)
{
//
string comment = "Recovery TP ...";
bool isClosed = mTrader.Close(
ticket,
comment //
);
if (isClosed)
{
//
string msg = "Position (" + ToString(ticket) + ") Hit's Recovery TP ...";
Alert(msg);
break;
}
}
}
}
else
{
//
XPosition positions[];
int positionsCount = mTrader.GetPositions(
positions,
symbol,
provider,
period //
);
if (positionsCount > 0)
{
//
XPosition recoveries[];
int recoveriesCount = ExtractRecoveries(
ticket,
positions,
recoveries //
);
//
if (recoveriesCount > 0)
{
//
XPosition mustClose[];
AddRef(
iPosition,
mustClose //
);
//
double requiredProfitPoints = (mData[i].recoveryLevel + 1) * recoveryTPPoint;
//
double rSwap = mData[i].swap;
double rVolume = volume;
double rProfit = profit;
double rCommission = mData[i].commission;
for (int i = 0; i < recoveriesCount; i++)
{
//
rSwap += recoveries[i].swap;
rProfit += recoveries[i].profit;
rVolume += recoveries[i].volume;
rCommission += mTrader.GetPositionCommission(recoveries[i].ticket);
//
AddRef(
recoveries[i],
mustClose //
);
}
//
double profitSummary =
rProfit + (-1 * rSwap) - MathAbs(rCommission);
if (profitSummary > 0)
{
//
double rProfitInPoints = profitSummary / volume;
//
bool canFinishRecovery = rProfitInPoints >= requiredProfitPoints;
if (canFinishRecovery)
{
//
// Here we Have to close All Recoveries
// and Position it Self ...
//
string comment = "Recovery Done ...";
//
int closeds = mTrader.Close(
mustClose,
comment //
);
if (closeds > 0)
{
//
string msg = "EQM Done Recovery (" + ToString(closeds) + ") Positions ...";
Alert(msg);
}
}
//
Clean(mustClose);
Clean(positions);
Clean(recoveries);
}
}
}
}
}
// //
// Retriece CIndex Bar ... // Retriece CIndex Bar ...
XOHCL cBar; XOHCL cBar;
@@ -4762,6 +4891,14 @@ public:
tmpLSW, tmpLSW,
true // true //
); );
bool isBullishSigns =
//
isBullishTrend &&
hasBullishPower &&
hasBullishPattern &&
hasBullishPressure
//
;
// //
// Bearish ... // Bearish ...
@@ -4771,8 +4908,16 @@ public:
bool isBearishTrend = cBar.HasBearishTrend( bool isBearishTrend = cBar.HasBearishTrend(
tmpHSW, tmpHSW,
tmpLSW, tmpLSW,
false // true //
); );
bool isBearishSigns =
//
isBearishTrend &&
hasBearishPower &&
hasBearishPattern &&
hasBearishPressure
//
;
// //
// Trail ... // Trail ...
@@ -4954,65 +5099,228 @@ public:
// //
// Profit Must be Negative ... // Profit Must be Negative ...
if ( if (
profit < 0 &&
recoveryTPPoint > 0 && recoveryTPPoint > 0 &&
recoverySLPoint > 0) recoverySLPoint > 0 &&
mData[i].recoveryLevel < maxAllowedRecover)
{ {
// //
// Current Profit ... // Current Profit ...
double drawdownInPoints = (MathAbs(profit) / volume); double distanceInPoints = (MathAbs(profit) / volume);
double _volume = volume * ((mData[i].recoveryLevel + 1) * recoveryVolumeMultiplier);
string _comment = GenerateRecoveryTag(ticket);
// //
// Try to Remove SL of Recovery Signals ... // Try to Remove SL of Recovery Signals ...
if (iPosition.sl > 0) if (iPosition.sl > 0 || iPosition.tp > 0)
{ {
// //
string comment = "EQM Recover Remove SL"; string comment = "EQM Recover Remove TP/SL";
bool isSLRemoved = mTrader.Modify( bool isSLRemoved = mTrader.Modify(
ticket, ticket,
0, 0,
iPosition.tp, 0,
comment // comment //
); );
} }
else
//
if (profit < 0)
{ {
// //
// Check Position TP ... if (mRecoverBasedOnPressures)
double rewardInPoints = iPosition.GetReward() / points;
if (rewardInPoints != recoveryTPPoint)
{ {
// //
double reward = recoveryTPPoint * points; bool canRecover = distanceInPoints >= recoverySLPoint * 0.75;
double tp = if (canRecover)
isLong {
? iPosition.entry + reward //
: iPosition.entry - reward; XSignal rSignal;
string comment = "EQM Recover Fix TP"; bool isPrepared = false;
bool isSLRemoved = mTrader.Modify( double longEntry = GetEntry(symbol, POSITION_TYPE_BUY);
ticket, double shortEntry = GetEntry(symbol, POSITION_TYPE_SELL);
iPosition.sl,
tp, //
comment // if (isBullishSigns)
); {
//
rSignal.Clean();
isPrepared = rSignal.Prepare(
symbol,
provider,
period,
POSITION_TYPE_BUY,
X_ORDER_MODE_MARKET,
longEntry,
_volume,
0,
0 //
);
}
else if (isBearishSigns)
{
//
rSignal.Clean();
isPrepared = rSignal.Prepare(
symbol,
provider,
period,
POSITION_TYPE_SELL,
X_ORDER_MODE_MARKET,
shortEntry,
_volume,
0,
0 //
);
}
//
if (isPrepared)
{
//
rSignal.comment = _comment;
//
bool isExecuted = ExecuteRecoverySignal(rSignal);
if (isExecuted)
{
mData[i].recoveryLevel++;
}
}
}
} }
else else
{ {
// //
// Check Price Distance For Recovery ... bool canRecover = distanceInPoints >= recoverySLPoint;
bool canLookForPressure = if (canRecover)
//
// in 75% ...
drawdownInPoints > ((recoverySLPoint / 3) * 2)
//
;
//
if (canLookForPressure)
{ {
// //
// Looking for Signal Direction and ENUM_POSITION_TYPE _type =
// Founding Pressure ... isLong
? POSITION_TYPE_SELL
: POSITION_TYPE_BUY;
double _entry = GetEntry(symbol, _type);
//
XSignal rSignal;
bool isPrepared = rSignal.Prepare(
symbol,
provider,
period,
_type,
X_ORDER_MODE_MARKET,
_entry,
_volume,
0,
0 //
);
if (isPrepared)
{
//
rSignal.comment = _comment;
//
bool isExecuted = ExecuteRecoverySignal(rSignal);
if (isExecuted)
{
mData[i].recoveryLevel++;
}
}
}
}
}
else if (profit >= 0 && mData[i].recoveryLevel > 0)
{
//
if (mRecoverBasedOnPressures)
{
//
XSignal rSignal;
bool isPrepared = false;
double longEntry = GetEntry(symbol, POSITION_TYPE_BUY);
double shortEntry = GetEntry(symbol, POSITION_TYPE_SELL);
//
if (isBullishSigns)
{
//
rSignal.Clean();
isPrepared = rSignal.Prepare(
symbol,
provider,
period,
POSITION_TYPE_BUY,
X_ORDER_MODE_MARKET,
longEntry,
_volume,
0,
0 //
);
}
else if (isBearishSigns)
{
//
rSignal.Clean();
isPrepared = rSignal.Prepare(
symbol,
provider,
period,
POSITION_TYPE_SELL,
X_ORDER_MODE_MARKET,
shortEntry,
_volume,
0,
0 //
);
}
//
if (isPrepared)
{
//
rSignal.comment = _comment;
//
bool isExecuted = ExecuteRecoverySignal(rSignal);
if (isExecuted)
{
mData[i].recoveryLevel++;
}
}
}
else
{
//
ENUM_POSITION_TYPE _type =
isLong
? POSITION_TYPE_BUY
: POSITION_TYPE_SELL;
double _entry = GetEntry(symbol, _type);
//
XSignal rSignal;
bool isPrepared = rSignal.Prepare(
symbol,
provider,
period,
_type,
X_ORDER_MODE_MARKET,
_entry,
_volume,
0,
0 //
);
if (isPrepared)
{
//
rSignal.comment = _comment;
//
bool isExecuted = ExecuteRecoverySignal(rSignal);
if (isExecuted)
{
mData[i].recoveryLevel++;
}
} }
} }
} }
@@ -5342,6 +5650,26 @@ private:
requiredProfitsForHedge -= commissions; requiredProfitsForHedge -= commissions;
} }
//
bool ExecuteRecoverySignal(XSignal &signal)
{
//
bool result = false;
//
ENUM_X_SIGNAL_EXECUTION_RESULT state;
result = mTrader.ExecuteSignal(
signal,
state,
ORDER_TIME_GTC,
NULL,
false //
);
//
return result;
}
// //
}; };
+4 -4
View File
@@ -43,8 +43,8 @@ double eaAllowLong = true; // Allow Long Positions
double eaAllowShort = true; // Allow Short Positions double eaAllowShort = true; // Allow Short Positions
// //
int eaMaxAllowedLongs = 0; // Max Allowed Long Positions int eaMaxAllowedLongs = 1; // Max Allowed Long Positions
int eaMaxAllowedShorts = 0; // Max Allowed Short Positions int eaMaxAllowedShorts = 1; // Max Allowed Short Positions
// //
double eaTPPoint = 100; // Static TP Point double eaTPPoint = 100; // Static TP Point
@@ -113,8 +113,8 @@ int OnInit()
drawPrefix = ShortName; drawPrefix = ShortName;
// //
EventSetTimer(5); // EventSetTimer(1);
// EventSetMillisecondTimer(100); EventSetMillisecondTimer(100);
// //
// Init Succeed ... // Init Succeed ...
+12 -7
View File
@@ -3507,7 +3507,7 @@ struct XTradeData
(maxDrawdown == 0 || (maxDrawdown == 0 ||
MathAbs(profit) > MathAbs(maxDrawdown))) MathAbs(profit) > MathAbs(maxDrawdown)))
{ {
profit = maxDrawdown; maxDrawdown = profit;
} }
// //
@@ -3785,18 +3785,22 @@ struct XTradeData
// Recovery ... // Recovery ...
// //
bool allowRecover; // Allow Recover Specified Position bool allowRecover; // Allow Recover Specified Position
double recoveryTPPoint; // Recovery TP Point double recoveryTPPoint; // Recovery TP Point
double recoverySLPoint; // Recovery SL Point double recoverySLPoint; // Recovery SL Point
int maxAllowedRecover; // Max Allowed Recovery int maxAllowedRecover; // Max Allowed Recovery
int recoveryLevel; // Number of Recovery Signals
double recoveryVolumeMultiplier; // Recovery Volume Multiplier
// //
void ResetRecovery() void ResetRecovery()
{ {
// //
allowRecover = false; allowRecover = false;
recoveryLevel = 0;
recoveryTPPoint = 0; recoveryTPPoint = 0;
recoverySLPoint = 0; recoverySLPoint = 0;
recoveryVolumeMultiplier = 0;
} }
// //
@@ -5418,8 +5422,9 @@ int ExtractRecoveries(
XPosition iSource = source[i]; XPosition iSource = source[i];
// //
ulong isRecovery = ExtractRecoveredTicket(iSource.comment) > 0; ulong parentTicket = ExtractRecoveredTicket(iSource.comment);
if (isRecovery && iSource.ticket == ticket) bool isRecovery = parentTicket > 0;
if (isRecovery && parentTicket == ticket)
{ {
// //
AddRef( AddRef(