last works ...

This commit is contained in:
2024-06-09 04:20:08 +03:30
parent 52e4d1316d
commit a868160ba2
4 changed files with 487 additions and 65 deletions
+170 -15
View File
@@ -401,10 +401,14 @@ struct XProtectedPosition
//
// Volume ...
// For Volume Calculating we have to use Recovery Level ...
// double mVolume =
// lastVolume == 0
// ? volume * 1
// : lastVolume * 1;
double mVolume =
lastVolume == 0
? volume * 3
: lastVolume * 3;
canSameDirectionRecover
? volume
: volume * 2;
//
result = signal.Prepare(
@@ -538,10 +542,9 @@ public:
//
// Initial Class ...
bool
Init(
bool Init(
XSCTrade *trader,
double mMinRequiredProfitPerTrade = 0.35,
double mMinRequiredProfitPerTrade = 0.5,
double mMinRequiredProfitPerTradeVolumeFactor = 0.01 //
)
{
@@ -645,11 +648,8 @@ public:
{
//
int protectedsCount = ArraySize(protecteds);
if (!IsValidSize(protectedsCount))
if (IsValidSize(protectedsCount))
{
return;
}
//
// Loop through Exists ...
for (int i = 0; i < protectedsCount; i++)
@@ -658,20 +658,38 @@ public:
// Do Protection ...
HandlePositionsProtecting(protecteds[i]);
}
}
//
string comment = XEQMSupportToken + " Hege ...";
//
// Handle Hedging All Positions ...
bool allowHedge = AllowHedge();
if (!allowHedge)
if (allowHedge)
{
return;
}
//
XPosition positions[];
int positionsCount = mTrader.GetPositions(positions);
if (!IsValidSize(positions) || positionsCount <= 1)
{
//
// Here We Can Close if Still Positions is EQM Support ...
bool canClosePosition =
//
positionsCount == 1 &&
positions[0].provider == XEQMSupportToken &&
positions[0].profit > (-1 * positions[0].swap) + (minRequiredProfitPerTrade * (positions[0].volume / minRequiredProfitPerTradeVolumeFactor))
//
;
if (canClosePosition)
{
//
bool isClosed = mTrader.Close(
positions[0].ticket,
comment //
);
}
return;
}
@@ -689,11 +707,12 @@ public:
);
if (!canHedge)
{
//
ProtectMargin();
return;
}
//
string comment = XEQMSupportToken + " Hege ...";
ENUM_X_SIGNAL_EXECUTION_RESULT states[];
int closed = mTrader.Close(
positions,
@@ -704,6 +723,7 @@ public:
Clean(protecteds);
}
}
}
//
// Sync Positions ...
@@ -916,6 +936,11 @@ protected:
string comment = GenerateEQMSupportTag(item.ticket);
signal.comment = comment;
//
// Remove Support Signal TP and SL ...
signal.tp = 0;
signal.sl = 0;
//
ENUM_X_SIGNAL_EXECUTION_RESULT state;
bool isExecuted = mTrader.ExecuteSignal(
@@ -968,6 +993,136 @@ protected:
return result;
}
//
// Protecting Margin by Free Coveraged Positions ...
void ProtectMargin()
{
//
double freeMargin = mTrader.mAccount.GetFreeMargin();
//
double balance = mTrader.mAccount.GetBalance();
double equity = mTrader.mAccount.GetEquity();
//
double selectedBalance = MathMin(balance, equity);
//
// Retrieve All Positions ...
XPosition positions[];
int positionsCount = mTrader.GetPositions(positions);
if (!IsValidSize(positionsCount))
{
return;
}
//
bool canForceHedging =
positionsCount >= 25 ||
freeMargin <= selectedBalance / 2;
if (!canForceHedging)
{
return;
}
//
// First Check Hedging By Half of Required Profit ...
double profit = SpecifiedCalculatePositionsProfit(positions);
double requiredProfit = SpecifiedCalculateRequiredProfitForHedge(
positions,
minRequiredProfitPerTrade,
minRequiredProfitPerTradeVolumeFactor //
);
bool canHedge =
//
profit > requiredProfit / 2
//
;
if (canHedge)
{
//
string comment = XEQMSupportToken + " Hege ...";
int closed = mTrader.Close(
positions,
comment //
);
//
return;
}
//
// TODO: Enable this if we want ...
return;
//
// Retrieve In Drawdown Positions ...
XPosition inDPositions[];
int inDPositionsCount = ExtractInDrawdownPositions(
positions,
inDPositions ///
);
if (!IsValidSize(inDPositionsCount))
{
return;
}
//
// Retrieve In Profit Positions ...
XPosition inPPositions[];
int inPPositionsCount = ExtractInProfitPositions(
positions,
inPPositions //
);
if (!IsValidSize(inPPositionsCount))
{
return;
}
//
// if we can't Hedge all Positions ...
// now we are looking to pair Positions for hedge ...
// - Select Max In Drawdown Position;
// - Looking for Coverage it inside In Profit Positions;
// - Clease All of them ...
int maxInDIDX = FindMaxDrawdownIndex(inDPositions);
if (maxInDIDX < 0)
{
return;
}
//
string comment = XEQMSupportToken + " Force Hege ...";
//
XPosition maxInDCoverages[];
int maxInDCoveragesCount = FindCoverageDrawdownPosition(
inDPositions[maxInDIDX],
inPPositions,
maxInDCoverages,
minRequiredProfitPerTrade,
minRequiredProfitPerTradeVolumeFactor //
);
if (!IsValidSize(maxInDCoveragesCount))
{
return;
}
//
bool isClosedMaxInD = mTrader.Close(
inDPositions[maxInDIDX].ticket,
comment //
);
if (isClosedMaxInD)
{
//
int closed = mTrader.Close(
maxInDCoverages,
comment //
);
}
}
//
// Protected Collection Management ...
+1 -1
View File
@@ -523,6 +523,7 @@ class XSCTrade : public XSCBase
public:
//
// Props ...
XSCAccount *mAccount; // Account Info Provider
//
// Constructors ...
@@ -3501,7 +3502,6 @@ private:
double mMaxAllowedDrawdownFactor; // Max Allowed Drawdown Factor
//
XSCAccount *mAccount; // Account Info Provider
XSCTradeBase *mTrader; // Base CTrade Manipulated Instance ...
//
+7 -7
View File
@@ -325,17 +325,17 @@ bool InitialEA()
//
int idx = 0;
ArrayResize(iDescriptor.signallers, 1);
ArrayResize(iDescriptor.signallers, 4);
//
iDescriptor.signallers[idx] = x786Signaller;
idx++;
// iDescriptor.signallers[idx] = x121Signaller;
// idx++;
// iDescriptor.signallers[idx] = x110Signaller;
// idx++;
// iDescriptor.signallers[idx] = x92Signaller;
// idx++;
iDescriptor.signallers[idx] = x121Signaller;
idx++;
iDescriptor.signallers[idx] = x110Signaller;
idx++;
iDescriptor.signallers[idx] = x92Signaller;
idx++;
// iDescriptor.signallers[idx] = x128Signaller;
// idx++;
// iDescriptor.signallers[idx] = xSPSignaller;
+267
View File
@@ -3482,6 +3482,172 @@ int GetYoungest(
return result;
}
//
int FindMaxProfitIndex(
XPosition &positions[] // Position Collection
)
{
//
int result = -1;
//
int positionsCount = ArraySize(positions);
if (!IsValidSize(positionsCount))
{
return result;
}
//
double max = 0;
for (int i = 0; i < positionsCount; i++)
{
//
XPosition iPosition = positions[i];
if (iPosition.profit <= 0)
{
continue;
}
//
if (max == 0 ||
max < iPosition.profit)
{
//
result = i;
max = iPosition.profit;
}
}
//
return result;
}
//
int ExtractInProfitPositions(
XPosition &positions[], // Position Collection
XPosition &inProfits[] // Result
)
{
//
int result = 0;
//
Clean(inProfits);
//
int positionsCount = ArraySize(positions);
if (!IsValidSize(positionsCount))
{
return result;
}
//
for (int i = 0; i < positionsCount; i++)
{
//
XPosition iPosition = positions[i];
//
if (iPosition.profit > 0)
{
//
AddRef(
iPosition,
inProfits //
);
}
}
//
result = ArraySize(inProfits);
//
return result;
}
//
int FindMaxDrawdownIndex(
XPosition &positions[] // Position Collection
)
{
//
int result = -1;
//
int positionsCount = ArraySize(positions);
if (!IsValidSize(positionsCount))
{
return result;
}
//
double min = 0;
for (int i = 0; i < positionsCount; i++)
{
//
XPosition iPosition = positions[i];
if (iPosition.profit >= 0)
{
continue;
}
//
if (min == 0 ||
min > iPosition.profit)
{
//
result = i;
min = iPosition.profit;
}
}
//
return result;
}
//
int ExtractInDrawdownPositions(
XPosition &positions[], // Position Collection
XPosition &inDradowns[] // Result
)
{
//
int result = 0;
//
Clean(inDradowns);
//
int positionsCount = ArraySize(positions);
if (!IsValidSize(positionsCount))
{
return result;
}
//
for (int i = 0; i < positionsCount; i++)
{
//
XPosition iPosition = positions[i];
//
if (iPosition.profit < 0)
{
//
AddRef(
iPosition,
inDradowns //
);
}
}
//
result = ArraySize(inDradowns);
//
return result;
}
//
// Check Filters ...
@@ -3819,6 +3985,107 @@ bool SpecifiedIsPositionsReadyForHedge(
return result;
}
//
int FindCoverageDrawdownPosition(
XPosition &position, // In Drawdown Position
XPosition &inProfits[], // In Profit Positions
XPosition &coverage[], // Coverage Positons
double mMinProfitPerTrade,
double mMinProfitPerVolumeFactor //
)
{
//
int result = 0;
//
Clean(coverage);
//
if (!position.IsValid() || position.profit >= 0)
{
return result;
}
//
int inProfitsCount = ArraySize(inProfits);
if (!IsValidSize(inProfitsCount))
{
return result;
}
//
// Copy in Profits to TMP ...
XPosition tmp[];
Copy(
inProfits,
tmp //
);
//
bool isCoverPassed = false;
while (!isCoverPassed || ArraySize(tmp) > 0)
{
//
XPosition max;
int idx = FindMaxProfitIndex(tmp);
if (idx >= 0)
{
//
if (tmp[idx].profit > 0)
{
AddRef(
tmp[idx],
coverage //
);
//
ArrayRemove(
tmp,
idx,
1 //
);
}
}
//
// Check Cover Passed ...
XPosition tmpPositions[];
Copy(
coverage,
tmpPositions //
);
AddRef(
position,
tmpPositions //
);
//
double profits = SpecifiedCalculatePositionsProfit(tmpPositions);
double requiredProfit = SpecifiedCalculateRequiredProfitForHedge(
tmpPositions,
mMinProfitPerTrade,
mMinProfitPerVolumeFactor //
);
isCoverPassed = profits >= requiredProfit;
if (isCoverPassed)
{
break;
}
//
if (!isCoverPassed && ArraySize(tmp) == 0)
{
break;
}
}
//
result = ArraySize(coverage);
//
return result;
}
//
// Extract a Collection of Positions SL ...
int ExtractSLs(