This commit is contained in:
2024-05-27 17:41:32 +03:30
parent 72dc9737f9
commit 54160e7f99
6 changed files with 677 additions and 22 deletions
+16 -15
View File
@@ -1522,7 +1522,8 @@ public:
price, price,
mSupportResistances, mSupportResistances,
count, count,
step); step //
);
// //
return result; return result;
@@ -4194,13 +4195,13 @@ private:
// //
result = result =
// //
isCSMHKLong // isCSMHKLong
// // //
|| // ||
// // //
isSSMHKLong // isSSMHKLong
// // //
|| // ||
// //
isMSMHKLong isMSMHKLong
// //
@@ -4810,13 +4811,13 @@ private:
// //
result = result =
// //
isCSMHKShort // isCSMHKShort
// // //
|| // ||
// // //
isSSMHKShort // isSSMHKShort
// // //
|| // ||
// //
isMSMHKShort isMSMHKShort
// //
+341 -6
View File
@@ -396,6 +396,9 @@ public:
// //
mAlert.Alert(message); mAlert.Alert(message);
//
RemoveEQMOrders();
// //
for (int i = 0; i < positionsCount; i++) for (int i = 0; i < positionsCount; i++)
{ {
@@ -434,19 +437,282 @@ public:
XSCPositionHolder *iHolder = mHolders[i]; XSCPositionHolder *iHolder = mHolders[i];
// //
XPosition iMaxInDP; // We Can Select Multiple Positions for Place EQM Supports ...
bool hasMaxInDP = iHolder.GetMaxInDrawdown(iMaxInDP);
if (!hasMaxInDP) //
// Select Max In Drawdown Position and Protect it ...
XPosition iSelectedPosition;
bool iHasPosition = iHolder.GetMaxInDrawdown(iSelectedPosition);
if (iHasPosition)
{ {
//
// Try to Protect Max In Drawdown Positions Position ...
PlaceEQMOrders(iSelectedPosition);
}
}
//
}
//
// Add Or Update EQM Orders ...
void PlaceEQMOrders(XPosition &position)
{
//
// TODO: Make It Configurable ...
int maxEQMCount = 5;
return;
//
// Position Protection Senarioos ...
if (!position.IsValid())
{
return;
}
//
int descriptorIDX = FindDescriptorIndex(position);
if (descriptorIDX <= -1)
{
return;
}
//
X121ProviderDescriptor descriptor = mDescriptors[descriptorIDX];
//
XOHCLSupRes slSupRes;
bool hasSupRes = descriptor
.provider
.GenerateSupRes(
slSupRes,
position.type,
5 //
);
//
XDrawSpecifications supDrawSpecs;
supDrawSpecs.draw = true;
supDrawSpecs.rayRight = true;
supDrawSpecs.clr = clrLightGreen;
//,
XDrawSpecifications resDrawSpecs;
resDrawSpecs.draw = true;
resDrawSpecs.rayRight = true;
resDrawSpecs.clr = clrLightCoral;
//
// DrawSupRes(
// slSupRes,
// supDrawSpecs,
// resDrawSpecs //
// );
//
XSignal supports[];
int supportsCount = GenerateEQMOrders(
supports,
position,
slSupRes //
);
if (!IsValidSize(supportsCount))
{
return;
}
//
XOrder untriggeredOrders[];
int untriggeredOrdersCount = mTrader.GetOrders(
untriggeredOrders,
position.symbol,
XEQMSupportToken,
position.period,
NULL, // All Types ...
ORDER_STATE_PLACED,
true //
);
//
XPosition triggereSupports[];
int tiggeredSupportsCount = mTrader.GetPositions(
triggereSupports,
position.symbol,
XEQMSupportToken,
position.period,
NULL, // All Types ...
true //
);
//
if (untriggeredOrdersCount +
tiggeredSupportsCount >=
maxEQMCount)
{
return;
}
//
XSignal filteredSignals[];
for (int i = 0; i < supportsCount; i++)
{
//
XSignal iSupport = supports[i];
//
double sl;
iSupport.RegularSL(sl);
//
double tp;
iSupport.RegularTP(tp);
//
if (!IsValidSize(untriggeredOrdersCount) && !IsValidSize(tiggeredSupportsCount))
{
//
AddRef(
iSupport,
filteredSignals //
);
//
continue; continue;
} }
// //
// Try to Protect a Position ... bool isOrdersPassed = true;
ProtectPosition(iMaxInDP); if (!IsValidSize(untriggeredOrdersCount))
{
isOrdersPassed = true;
}
else
{
//
for (int j = 0; j < untriggeredOrdersCount; j++)
{
//
XOrder jOrder = untriggeredOrders[j];
//
bool isSame =
//
jOrder.symbol == iSupport.symbol &&
jOrder.period == iSupport.period &&
jOrder.openPrice == iSupport.entry &&
jOrder.sl == sl &&
jOrder.tp == tp
//
;
if (isSame)
{
//
isOrdersPassed = false;
break;
}
}
}
//
bool isPositionsPassed = true;
if (!IsValidSize(tiggeredSupportsCount))
{
isPositionsPassed = true;
}
else
{
//
for (int j = 0; j < tiggeredSupportsCount; j++)
{
//
XPosition jPosition = triggereSupports[j];
//
bool isSame =
//
jPosition.symbol == iSupport.symbol &&
jPosition.period == iSupport.period &&
jPosition.entry == iSupport.entry &&
jPosition.sl == sl &&
jPosition.tp == tp
//
;
if (isSame)
{
//
isPositionsPassed = false;
break;
}
}
}
//
if (isOrdersPassed &&
isPositionsPassed)
{
//
AddRef(
iSupport,
filteredSignals //
);
}
}
int filteredSignalsCount = ArraySize(filteredSignals);
if (!IsValidSize(filteredSignalsCount))
{
return;
} }
// //
ENUM_X_SIGNAL_EXECUTION_RESULT states[];
int placedOrders = mTrader.ExecuteSignals(
filteredSignals,
states,
ORDER_TIME_GTC,
NULL,
false // Ignore Policies ...
);
if (placedOrders > 0)
{
//
string message = "EQM Placed (" + ToString(placedOrders) + ") Support Orders ...";
//
mAlert.Alert(message);
}
}
//
void RemoveEQMOrders()
{
//
XOrder untriggeredOrders[];
int untriggeredOrdersCount = mTrader.GetOrders(
untriggeredOrders,
NULL,
XEQMSupportToken,
NULL,
NULL, // All Types ...
ORDER_STATE_PLACED,
true //
);
if (!IsValidSize(untriggeredOrdersCount))
{
return;
}
//
int canceleds = mTrader.CancelOrders(
untriggeredOrders //
);
if (canceleds > 0)
{
//
string message = "EQM Cancel Support ...";
//
mAlert.Alert(message);
}
} }
// //
@@ -479,7 +745,7 @@ public:
// //
bool canManageState = bool canManageState =
// //
true iPosition.provider != XEQMSupportToken
// //
; ;
@@ -1024,6 +1290,9 @@ public:
// //
mAlert.Alert(message); mAlert.Alert(message);
//
RemoveEQMOrders();
} }
// //
@@ -1039,6 +1308,9 @@ public:
// //
// Here i Have to Detect In DrawDown Positions ... // Here i Have to Detect In DrawDown Positions ...
//
RemoveEQMOrders();
// //
string mSymbols[]; string mSymbols[];
XSCPositionHolder *mHolders[]; XSCPositionHolder *mHolders[];
@@ -1101,6 +1373,9 @@ protected:
{ {
// //
// Here i Can Protect Position ... // Here i Can Protect Position ...
// This Protect Include One Position in Market Mode ...
// If Provided ...
// the Positions Selection must passed Some conditions ...
// //
string message = "For (" + position.symbol + ") Max In Drawdown Position is: (" + string message = "For (" + position.symbol + ") Max In Drawdown Position is: (" +
@@ -1130,6 +1405,66 @@ private:
return ArraySize(mDescriptors); return ArraySize(mDescriptors);
} }
//
// Find Specifc Descriptor ...
int FindDescriptorIndex(
string symbol,
ENUM_TIMEFRAMES period //
)
{
//
int result = -1;
//
if (!IsValid(symbol) ||
!IsValid(period))
{
return result;
}
//
int descriptorsCount = CountDescriptors();
if (!IsValidSize(descriptorsCount))
{
return result;
}
//
for (int i = 0; i < descriptorsCount; i++)
{
//
X121ProviderDescriptor iDescriptor = mDescriptors[i];
//
bool isPassed =
//
iDescriptor.symbol == symbol &&
iDescriptor.period == period
//
;
if (isPassed)
{
//
result = i;
break;
}
}
//
return result;
}
template <typename T>
int FindDescriptorIndex(
T &item //
)
{
return FindDescriptorIndex(
item.symbol,
item.period //
);
}
// //
// Trails Holding ... // Trails Holding ...
+153
View File
@@ -5290,3 +5290,156 @@ struct X121MarketCycleDescriptor
}; };
// //
// Custom Draws ...
//
// Custom Struct Draws ...
bool DrawSupRes(
XOHCLSupRes &item, // Struct item to Draw ...
XDrawSpecifications &supSpecs, // Supports specs ...
XDrawSpecifications &resSpecs, // Resistances specs ...
long chartID = 0,
int subWindow = 0,
string prefix = "SupRes" //
)
{
//
bool result = false;
//
result = item.IsValid();
if (!result)
{
return result;
}
//
datetime cTime = TimeCurrent();
datetime pTime = TimeCurrent() - PeriodSeconds(PERIOD_M10);
//
// Support ...
int supCount = item.CountSupports();
bool canDrawSups = IsValidSize(supCount) && supSpecs.draw;
if (canDrawSups)
{
//
for (int i = 0; i < supCount; i++)
{
//
double iSup = item.sup[i];
//
string supName = prefix + "_" + "Sup_" + ToString(iSup);
//
DrawTrendLine(
chartID,
supName,
subWindow,
pTime,
iSup,
cTime,
iSup,
supSpecs.clr,
supSpecs.style,
supSpecs.width,
supSpecs.back,
supSpecs.selection,
supSpecs.rayRight,
supSpecs.hidden,
supSpecs.zOrder //
);
//
if (IsValid(supSpecs.label))
{
//
DrawText(
chartID,
supName + "_lbl",
subWindow,
cTime,
iSup,
supSpecs.label,
supSpecs.labelFont,
supSpecs.labelFontSize,
supSpecs.labelColor,
supSpecs.labelAngel,
supSpecs.labelAnchor,
supSpecs.back,
supSpecs.selection,
supSpecs.hidden,
supSpecs.zOrder //
);
}
}
}
//
// Resistance ...
int resCount = item.CountResistances();
bool canDrawRess = IsValidSize(supCount) && supSpecs.draw;
if (canDrawRess)
{
//
for (int i = 0; i < resCount; i++)
{
//
double iRes = item.res[i];
//
string resName = prefix + "_" + "Res_" + ToString(iRes);
//
DrawTrendLine(
chartID,
resName,
subWindow,
pTime,
iRes,
cTime,
iRes,
resSpecs.clr,
resSpecs.style,
resSpecs.width,
resSpecs.back,
resSpecs.selection,
resSpecs.rayRight,
resSpecs.hidden,
resSpecs.zOrder //
);
//
if (IsValid(resSpecs.label))
{
//
DrawText(
chartID,
resName + "_lbl",
subWindow,
cTime,
iRes,
resSpecs.label,
resSpecs.labelFont,
resSpecs.labelFontSize,
resSpecs.labelColor,
resSpecs.labelAngel,
resSpecs.labelAnchor,
resSpecs.back,
resSpecs.selection,
resSpecs.hidden,
resSpecs.zOrder //
);
}
}
}
//
result = canDrawSups || canDrawRess;
//
return result;
}
//
+1
View File
@@ -514,6 +514,7 @@ public:
// //
// Implementation ... // Implementation ...
//
// a Class For Manage Trades and Handle Trading Actions ... // a Class For Manage Trades and Handle Trading Actions ...
class XSCTrade : public XSCBase class XSCTrade : public XSCBase
{ {
+1 -1
View File
@@ -195,7 +195,7 @@ bool InitialEA()
Add(X110, signallers); Add(X110, signallers);
Add(X121, signallers); Add(X121, signallers);
Add(X128, signallers); Add(X128, signallers);
// Add(X92, signallers); Add(X92, signallers);
// GetAllX121SignalProviders(signallers); // GetAllX121SignalProviders(signallers);
// //
+165
View File
@@ -3945,3 +3945,168 @@ string PrepareSLTrailTag(
} }
// //
// EQM Support Orders ...
//
int GenerateEQMOrders(
XSignal &orders[], // Result
XPosition &position, // Supported Position
XOHCLSupRes &supRes, // Data Source
bool longs = true,
bool shorts = true //
)
{
//
int result = 0;
//
Clean(orders);
//
if (!supRes.IsValid() ||
!position.IsValid())
{
return result;
}
//
if (longs)
{
//
double longLevels[];
//
Copy(
supRes.res,
longLevels //
);
//
double minSup = GetMin(
supRes.sup //
);
if (minSup > 0)
{
//
Add(
minSup,
longLevels //
);
}
//
ArraySort(longLevels);
//
if (ArraySize(longLevels) > 2)
{
//
for (int i = 0; i < ArraySize(longLevels) - 2; i++)
{
//
double iSL = longLevels[i];
double iEntry = longLevels[i + 1];
double iTP = longLevels[i + 2];
//
XSignal iSignal;
bool isPrepared = iSignal.PrepareStopLong(
position.symbol,
XEQMSupportToken,
position.period,
iEntry,
position.volume,
X_SIGNAL_USE_NOTHING,
iSL,
iTP //
);
if (isPrepared)
{
//
string comment = GenerateSupportTag(position.ticket);
iSignal.comment = comment;
//
AddRef(
iSignal,
orders //
);
}
}
}
}
//
if (shorts)
{
//
double shortLevels[];
//
Copy(
supRes.sup,
shortLevels //
);
//
double maxRes = GetMax(
supRes.res //
);
if (maxRes > 0)
{
//
Add(
maxRes,
shortLevels //
);
}
//
ArraySort(shortLevels);
ArrayReverse(shortLevels);
//
if (ArraySize(shortLevels) > 2)
{
//
for (int i = 0; i < ArraySize(shortLevels) - 2; i++)
{
//
double iSL = shortLevels[i];
double iEntry = shortLevels[i + 1];
double iTP = shortLevels[i + 2];
//
XSignal iSignal;
bool isPrepared = iSignal.PrepareStopShort(
position.symbol,
XEQMSupportToken,
position.period,
iEntry,
position.volume,
X_SIGNAL_USE_NOTHING,
iSL,
iTP //
);
if (isPrepared)
{
//
string comment = GenerateSupportTag(position.ticket);
iSignal.comment = comment;
//
AddRef(
iSignal,
orders //
);
}
}
}
}
//
result = ArraySize(orders);
//
return result;
}