add supports for zone recovery ...

This commit is contained in:
2024-06-15 23:37:33 +03:30
parent f1edb81a7e
commit 69393d6d83
5 changed files with 872 additions and 32 deletions
+559 -8
View File
@@ -116,6 +116,7 @@ struct XTradeInfo
//
ResetGrid();
ResetRecovery();
}
//
@@ -580,6 +581,249 @@ struct XTradeInfo
//
return result;
}
//
// Recovery Zone System ...
//
ENUM_POSITION_TYPE rLastRecoveryType; // Last Executed Recovery Signal's Type
double rLongEntry; // Represent Next Recovery Long Signal's Entry
double rShortEntry; // Represent Next Recovery Short Signal's Entry
double rVolume; // Represent Next Recovery Signal's Volume
double rZoneUpper; // Zone Recovery Upper Bound
double rZoneLower; // Zone Recovery Lower Bound
//
void ResetRecovery()
{
//
rVolume = 0;
rLongEntry = 0;
rZoneUpper = 0;
rZoneLower = 0;
rShortEntry = 0;
}
//
void SetRecovery(
double nextLongEntry,
double nextShortEntry,
double zoneUpper,
double zoneLower,
double nextVolume //
)
{
//
rVolume = nextVolume;
rZoneUpper = zoneUpper;
rZoneLower = zoneLower;
rLongEntry = nextLongEntry;
rShortEntry = nextShortEntry;
}
//
void PrepareNextRecovery(
double distance, // Define Target Based On Zones
double volumeMultiplier, // Volume Multiplier
ENUM_POSITION_TYPE lastType // Last Type
)
{
//
bool isValid =
//
IsValid() &&
entry > 0 &&
volume > 0 &&
distance > 0 &&
volumeMultiplier > 0
//
;
//
bool isLong = IsLong(lastType);
//
double distancePrice = PointToPrice(
distance,
symbol //
);
//
double selectedEntry =
isLong
? rLongEntry <= 0
? entry
: rLongEntry
: rShortEntry <= 0
? entry
: rShortEntry;
double selectedVolume =
rVolume <= 0
? volume
: rVolume;
//
double nextLongEntry =
isLong
? selectedEntry
: selectedEntry + distancePrice;
double nextShortEntry =
isLong
? selectedEntry - distancePrice
: selectedEntry;
//
double nextVolume = selectedVolume * volumeMultiplier;
//
double zoneUpper =
rZoneUpper > 0
? rZoneUpper
: isLong
? entry + distancePrice
: entry + (distancePrice * 2);
double zoneLower =
rZoneLower > 0
? rZoneLower
: isLong
? entry + (distancePrice * 2)
: entry - distancePrice;
//
SetRecovery(
nextLongEntry,
nextShortEntry,
zoneUpper,
zoneLower,
nextVolume //
);
//
rLastRecoveryType = lastType;
}
//
// Check if a Recovery Signal Exists Prepared and
// Provide it ...
bool HasRecovery(
XSignal &signal, // Result Signal ...
double distance,
double volumeMultiplier //
)
{
//
bool result = false;
//
signal.Clean();
//
result =
//
IsValid() &&
entry > 0 &&
volume > 0 &&
distance > 0 &&
volumeMultiplier > 0
//
;
if (!result)
{
return result;
}
//
double distancePrice = PointToPrice(
distance,
symbol //
);
//
bool isLong = IsLong(type);
bool isLastLong = IsLong(rLastRecoveryType);
//
// Check For Long Recovery ...
double cLongEntry = GetEntry(
symbol,
POSITION_TYPE_BUY //
);
bool hasLongRecovery =
!isLastLong &&
rLongEntry > 0 && cLongEntry >= rLongEntry;
//
// Check For Short Recovery ...
double cShortEntry = GetEntry(
symbol,
POSITION_TYPE_SELL //
);
bool hasShortRecovery =
isLastLong &&
rShortEntry > 0 &&
cShortEntry <= rShortEntry;
//
result = hasLongRecovery || hasShortRecovery;
if (!result)
{
return result;
}
//
ENUM_POSITION_TYPE rType =
hasLongRecovery
? POSITION_TYPE_BUY
: POSITION_TYPE_SELL;
//
double rEntry =
hasLongRecovery
? cLongEntry
: cShortEntry;
//
double rTP =
hasLongRecovery
? rZoneUpper
: rZoneLower;
//
double rSL =
hasLongRecovery
? rZoneLower
: rZoneUpper;
//
result = signal.Prepare(
symbol,
provider,
period,
rType,
X_ORDER_MODE_MARKET,
rEntry,
rVolume,
rSL, // SL ...
rTP // TP ...
);
if (result)
{
//
// set Support Token ...
string comment = GenerateSupportTag(ticket);
signal.comment = comment;
//
PrepareNextRecovery(
distance,
volumeMultiplier,
rType //
);
}
//
return result;
}
};
//
@@ -871,6 +1115,79 @@ public:
return result;
}
//
// Recovery System ...
//
bool AllowRecovery()
{
return mAllowRecovery;
}
//
void AllowRecovery(bool value)
{
mAllowRecovery = value;
}
//
double RecoveryDistance()
{
return mRecoveryDistance;
}
//
void RecoveryDistance(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mRecoveryDistance = value;
}
//
double RecoveryVolumeMultiplier()
{
return mRecoveryVolumeMultiplier;
}
//
void RecoveryVolumeMultiplier(double value)
{
//
if (value <= 1)
{
value = 0;
}
//
mRecoveryVolumeMultiplier = value;
}
//
// Check Recovery Properties to Validate it's Enable or not ...
bool EnableRecovery()
{
//
bool result = false;
//
result =
//
AllowRecovery() &&
RecoveryDistance() > 0 &&
RecoveryVolumeMultiplier() > 0
//
;
//
return result;
}
//
// Tools ...
@@ -1081,6 +1398,18 @@ public:
GridVolumeMultiplier() //
);
}
//
// Check if Recovery System Enable or Not ...
if (EnableRecovery())
{
//
data[infoIDX].PrepareNextRecovery(
GridDistance(),
GridVolumeMultiplier(),
signal.type //
);
}
}
//
@@ -1141,7 +1470,6 @@ public:
}
//
// Grid System Tools ...
int RequestForGrid(XSignal &signals[])
{
//
@@ -1192,6 +1520,150 @@ public:
return result;
}
//
int RequestForRecovery(XSignal &signals[])
{
//
int result = 0;
//
Clean(signals);
//
if (!EnableRecovery())
{
return result;
}
//
int count = Count();
if (!IsValidSize(count))
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
XSignal iSignal;
bool hasRecovery = data[i].HasRecovery(
iSignal,
RecoveryDistance(),
RecoveryVolumeMultiplier() //
);
//
if (hasRecovery)
{
//
AddRef(
iSignal,
signals //
);
}
}
//
result = ArraySize(signals);
//
return result;
}
//
int RequestForProtect(XSignal &signals[])
{
//
// Grid ...
XSignal grids[];
int gridsCount = RequestForGrid(grids);
//
// Recovery ...
XSignal recoveries[];
int recoveriesCount = RequestForRecovery(recoveries);
//
Clean(signals);
//
if (IsValidSize(gridsCount))
{
//
Copy(
grids,
signals,
false //
);
}
//
if (IsValidSize(recoveriesCount))
{
//
Copy(
recoveries,
signals,
false //
);
}
//
int result = ArraySize(signals);
//
return result;
}
//
// Sync ...
void Sync()
{
//
int count = Count();
if (!IsValidSize(count))
{
return;
}
//
int mustRemoved[];
for (int i = 0; i < count; i++)
{
//
XTradeInfo iInfo = data[i];
//
if (iInfo.ticket > 0 && !mTrader.IsOpen(iInfo.ticket))
{
//
AddSpecific(
i,
mustRemoved //
);
}
}
//
int mustRemovedCount = ArraySize(mustRemoved);
if (!IsValidSize(mustRemovedCount))
{
return;
}
//
for (int i = 0; i < mustRemovedCount; i++)
{
//
ArrayRemove(
data,
i,
1 //
);
}
}
//
// Protected ...
protected:
@@ -1236,6 +1708,12 @@ protected:
bool mAllowGrid; // Use Grid System to Recovery Positions
double mGridDistance; // Grid System Distance
double mGridVolumeMultiplier; // Grid System Volume Multiplier
//
// Recovery ...
bool mAllowRecovery; // Use Recovery System to Recovery Positions
double mRecoveryDistance; // Recovery System Distance
double mRecoveryVolumeMultiplier; // Recovery System Volume Multiplier
};
//
@@ -1528,6 +2006,9 @@ public:
mUseSupport = value;
}
//
// Grid System ...
//
bool AllowGrid()
{
@@ -1564,6 +2045,45 @@ public:
mTradeInfoHandler.GridVolumeMultiplier(value);
}
//
// Recovery System ...
//
bool AllowRecovery()
{
return mTradeInfoHandler.AllowRecovery();
}
//
void AllowRecovery(bool value)
{
mTradeInfoHandler.AllowRecovery(value);
}
//
double RecoveryDistance()
{
return mTradeInfoHandler.RecoveryDistance();
}
//
void RecoveryDistance(double value)
{
mTradeInfoHandler.RecoveryDistance(value);
}
//
double RecoveryVolumeMultiplier()
{
return mTradeInfoHandler.RecoveryVolumeMultiplier();
}
//
void RecoveryVolumeMultiplier(double value)
{
mTradeInfoHandler.RecoveryVolumeMultiplier(value);
}
//
bool SaveResults()
{
@@ -2356,8 +2876,8 @@ public:
DoEQMCloseOnSpecificTime();
//
// Do EQM Grid if Provided ...
DoEQMGrid();
// Do EQM Protection if Provided ...
DoEQMProtect();
//
// if Returns true, Signal Execution failed ...
@@ -2373,7 +2893,15 @@ public:
//
// Signal Info Manager ...
XSignal tSignal = signal;
mTradeInfoHandler.Update(tSignal);
bool isSupport = ExtractSupportedTicket(signal.comment) > 0;
bool isEQMSupport = ExtractEQMSupportedTicket(signal.comment) > 0;
if (!isSupport && !isEQMSupport)
{
mTradeInfoHandler.Update(tSignal);
}
//
mTradeInfoHandler.Sync();
}
//
@@ -2386,6 +2914,7 @@ public:
// Signal Info Manager ...
XSignal tSignal = signal;
mTradeInfoHandler.Remove(tSignal);
mTradeInfoHandler.Sync();
}
//
@@ -2398,8 +2927,16 @@ public:
// When a Position Closed Manually ...
// Signal Info Manager ...
XPosition tPosition = position;
bool isSupport = ExtractSupportedTicket(position.comment) > 0;
bool isEQMSupport = ExtractEQMSupportedTicket(position.comment) > 0;
tPosition.comment = comment;
mTradeInfoHandler.Update(tPosition);
if (!isSupport && !isEQMSupport)
{
mTradeInfoHandler.Update(tPosition);
}
//
mTradeInfoHandler.Sync();
}
//
@@ -2410,6 +2947,7 @@ public:
// Signal Info Manager ...
XDeal tDeal = deal;
mTradeInfoHandler.Update(tDeal);
mTradeInfoHandler.Sync();
}
//
@@ -2420,6 +2958,7 @@ public:
// Signal Info Manager ...
XDeal tDeal = deal;
mTradeInfoHandler.Update(tDeal);
mTradeInfoHandler.Sync();
}
//
@@ -2557,6 +3096,18 @@ private:
return mTradeInfoHandler.EnableGrid();
}
//
bool EnableRecovery()
{
return mTradeInfoHandler.EnableRecovery();
}
//
bool EnableProtection()
{
return EnableGrid() || EnableRecovery();
}
//
// Remove Untriggered EQM Orders ...
void RemoveEQMOrders()
@@ -2788,10 +3339,10 @@ private:
//
// Do Gridding Mechanism ...
void DoEQMGrid()
void DoEQMProtect()
{
//
if (!EnableGrid())
if (!EnableProtection())
{
return;
}
@@ -2799,7 +3350,7 @@ private:
//
XSignal signals[];
int signalsCount = mTradeInfoHandler
.RequestForGrid(signals);
.RequestForProtect(signals);
if (!IsValidSize(signalsCount))
{
return;