add supports for zone recovery ...
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -1122,7 +1122,7 @@ protected:
|
||||
string comment = XEQMSupportToken + " Hedge ...";
|
||||
|
||||
//
|
||||
int closed = mTrader.Close(
|
||||
int closed = Close(
|
||||
positions,
|
||||
comment //
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user