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
+211 -56
View File
@@ -401,10 +401,14 @@ struct XProtectedPosition
// //
// Volume ... // Volume ...
// For Volume Calculating we have to use Recovery Level ... // For Volume Calculating we have to use Recovery Level ...
// double mVolume =
// lastVolume == 0
// ? volume * 1
// : lastVolume * 1;
double mVolume = double mVolume =
lastVolume == 0 canSameDirectionRecover
? volume * 3 ? volume
: lastVolume * 3; : volume * 2;
// //
result = signal.Prepare( result = signal.Prepare(
@@ -538,10 +542,9 @@ public:
// //
// Initial Class ... // Initial Class ...
bool bool Init(
Init(
XSCTrade *trader, XSCTrade *trader,
double mMinRequiredProfitPerTrade = 0.35, double mMinRequiredProfitPerTrade = 0.5,
double mMinRequiredProfitPerTradeVolumeFactor = 0.01 // double mMinRequiredProfitPerTradeVolumeFactor = 0.01 //
) )
{ {
@@ -645,63 +648,80 @@ public:
{ {
// //
int protectedsCount = ArraySize(protecteds); int protectedsCount = ArraySize(protecteds);
if (!IsValidSize(protectedsCount)) if (IsValidSize(protectedsCount))
{
return;
}
//
// Loop through Exists ...
for (int i = 0; i < protectedsCount; i++)
{ {
// //
// Do Protection ... // Loop through Exists ...
HandlePositionsProtecting(protecteds[i]); for (int i = 0; i < protectedsCount; i++)
} {
//
// // Do Protection ...
// Handle Hedging All Positions ... HandlePositionsProtecting(protecteds[i]);
bool allowHedge = AllowHedge(); }
if (!allowHedge)
{
return;
}
//
XPosition positions[];
int positionsCount = mTrader.GetPositions(positions);
if (!IsValidSize(positions) || positionsCount <= 1)
{
return;
}
//
double profit = SpecifiedCalculatePositionsProfit(positions);
double requiredProfit = SpecifiedCalculateRequiredProfitForHedge(
positions,
minRequiredProfitPerTrade,
minRequiredProfitPerTradeVolumeFactor //
);
bool canHedge = SpecifiedIsPositionsReadyForHedge(
positions,
minRequiredProfitPerTrade,
minRequiredProfitPerTradeVolumeFactor //
);
if (!canHedge)
{
return;
} }
// //
string comment = XEQMSupportToken + " Hege ..."; string comment = XEQMSupportToken + " Hege ...";
ENUM_X_SIGNAL_EXECUTION_RESULT states[];
int closed = mTrader.Close( //
positions, // Handle Hedging All Positions ...
comment // bool allowHedge = AllowHedge();
); if (allowHedge)
if (IsValidSize(closed))
{ {
Clean(protecteds); //
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;
}
//
double profit = SpecifiedCalculatePositionsProfit(positions);
double requiredProfit = SpecifiedCalculateRequiredProfitForHedge(
positions,
minRequiredProfitPerTrade,
minRequiredProfitPerTradeVolumeFactor //
);
bool canHedge = SpecifiedIsPositionsReadyForHedge(
positions,
minRequiredProfitPerTrade,
minRequiredProfitPerTradeVolumeFactor //
);
if (!canHedge)
{
//
ProtectMargin();
return;
}
//
ENUM_X_SIGNAL_EXECUTION_RESULT states[];
int closed = mTrader.Close(
positions,
comment //
);
if (IsValidSize(closed))
{
Clean(protecteds);
}
} }
} }
@@ -916,6 +936,11 @@ protected:
string comment = GenerateEQMSupportTag(item.ticket); string comment = GenerateEQMSupportTag(item.ticket);
signal.comment = comment; signal.comment = comment;
//
// Remove Support Signal TP and SL ...
signal.tp = 0;
signal.sl = 0;
// //
ENUM_X_SIGNAL_EXECUTION_RESULT state; ENUM_X_SIGNAL_EXECUTION_RESULT state;
bool isExecuted = mTrader.ExecuteSignal( bool isExecuted = mTrader.ExecuteSignal(
@@ -968,6 +993,136 @@ protected:
return result; 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 ... // Protected Collection Management ...
+2 -2
View File
@@ -523,6 +523,7 @@ class XSCTrade : public XSCBase
public: public:
// //
// Props ... // Props ...
XSCAccount *mAccount; // Account Info Provider
// //
// Constructors ... // Constructors ...
@@ -3182,7 +3183,7 @@ public:
// //
// Tools ... // Tools ...
// //
// Retrieve Last Open Position Ticket ... // Retrieve Last Open Position Ticket ...
ulong GetLastOpenPositionTicket() ulong GetLastOpenPositionTicket()
@@ -3501,7 +3502,6 @@ private:
double mMaxAllowedDrawdownFactor; // Max Allowed Drawdown Factor double mMaxAllowedDrawdownFactor; // Max Allowed Drawdown Factor
// //
XSCAccount *mAccount; // Account Info Provider
XSCTradeBase *mTrader; // Base CTrade Manipulated Instance ... XSCTradeBase *mTrader; // Base CTrade Manipulated Instance ...
// //
+7 -7
View File
@@ -325,17 +325,17 @@ bool InitialEA()
// //
int idx = 0; int idx = 0;
ArrayResize(iDescriptor.signallers, 1); ArrayResize(iDescriptor.signallers, 4);
// //
iDescriptor.signallers[idx] = x786Signaller; iDescriptor.signallers[idx] = x786Signaller;
idx++; idx++;
// iDescriptor.signallers[idx] = x121Signaller; iDescriptor.signallers[idx] = x121Signaller;
// idx++; idx++;
// iDescriptor.signallers[idx] = x110Signaller; iDescriptor.signallers[idx] = x110Signaller;
// idx++; idx++;
// iDescriptor.signallers[idx] = x92Signaller; iDescriptor.signallers[idx] = x92Signaller;
// idx++; idx++;
// iDescriptor.signallers[idx] = x128Signaller; // iDescriptor.signallers[idx] = x128Signaller;
// idx++; // idx++;
// iDescriptor.signallers[idx] = xSPSignaller; // iDescriptor.signallers[idx] = xSPSignaller;
+267
View File
@@ -3482,6 +3482,172 @@ int GetYoungest(
return result; 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 ... // Check Filters ...
@@ -3819,6 +3985,107 @@ bool SpecifiedIsPositionsReadyForHedge(
return result; 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 ... // Extract a Collection of Positions SL ...
int ExtractSLs( int ExtractSLs(