This commit is contained in:
2024-05-26 19:53:36 +03:30
parent 4e78f13edf
commit c1aa4fe888
4 changed files with 1288 additions and 214 deletions
+196 -205
View File
@@ -296,22 +296,55 @@ public:
return result; return result;
} }
//
// Synch Position Tracker ...
SyncPositionTracker();
// //
HandleEQMState(signals); HandleEQMState(signals);
// //
HandleHedging(positions); HandleEQMHedge(positions);
// //
HandleTrailManagement(positions); HandleTrailManagement(positions);
//
// Close all Positions on 22 ...
// TODO: Make it Configurable ...
int closeHour = -1;
MqlDateTime cTime = GetCurrentTime();
if (closeHour >= 0 && cTime.hour == closeHour)
{
//
string comment = "EQM Close on Time ...";
//
XPosition positions[];
int positionsCount = mTrader.GetPositions(positions);
if (positionsCount <= 0)
{
return result;
}
//
int closed = mTrader.Close(
positions,
comment //
);
if (closed > 0)
{
mAlert.Alert(comment);
}
}
// //
// Must false ... // Must false ...
return result; return result;
} }
// //
void HandleHedging(XPosition &positions[]) void HandleEQMHedge(XPosition &positions[])
{ {
// //
// TODO: // TODO:
@@ -329,12 +362,20 @@ public:
// Hedge ... // Hedge ...
if (positionsCount >= numberOfPositionsForHege) if (positionsCount >= numberOfPositionsForHege)
{ {
//
int maxAllowedPositions = GetMaxAllowedPositions();
// //
double profit = CalculatePositionsProfit(positions); double profit = CalculatePositionsProfit(positions);
double requiredProfit = CalculateRequiredProfitForHedge(positions); double requiredProfit = CalculateRequiredProfitForHedge(positions);
// //
bool isReadyForHedge = profit >= requiredProfit; bool isReadyForHedge =
positionsCount < maxAllowedPositions
? profit >= requiredProfit
: positionsCount >= maxAllowedPositions && profit >= (requiredProfit * 0.50)
? true
: false;
if (!isReadyForHedge) if (!isReadyForHedge)
{ {
return; return;
@@ -385,66 +426,72 @@ public:
{ {
eqmMessage += "- Max Allowed Positions Reached ..."; eqmMessage += "- Max Allowed Positions Reached ...";
} }
mAlert.Alert(eqmMessage); // mAlert.Alert(eqmMessage);
// //
int descriptorsCount = CountDescriptors(); // Retrieve InDrawdown Positions Count ...
if (descriptorsCount <= 0) // Separate based on Directions and Symbols ...
{ // Accept Only One Signal based on each symbol Indirect ...
return; // for Fittion Positions to HedgeEnable in Long Time Positions ...
}
// // //
XSignal supportSignals[]; // int descriptorsCount = CountDescriptors();
for (int i = 0; i < descriptorsCount; i++) // if (descriptorsCount <= 0)
{ // {
// // return;
X121ProviderDescriptor iDescriptor = mDescriptors[i]; // }
// // //
XSignal iSupportSignals[]; // XSignal supportSignals[];
int iSupportSignalsCount = iDescriptor // for (int i = 0; i < descriptorsCount; i++)
.provider // {
.GenerateEQMSupportSignals( // //
iSupportSignals // // X121ProviderDescriptor iDescriptor = mDescriptors[i];
);
if (iSupportSignalsCount <= 0)
{
continue;
}
// // //
Copy( // XSignal iSupportSignals[];
iSupportSignals, // int iSupportSignalsCount = iDescriptor
supportSignals, // .provider
false // // .GenerateEQMSupportSignals(
); // iSupportSignals //
} // );
// if (iSupportSignalsCount <= 0)
// {
// continue;
// }
// // //
int supportSignalsCount = ArraySize(supportSignals); // Copy(
if (supportSignalsCount <= 0) // iSupportSignals,
{ // supportSignals,
return; // false //
} // );
// }
// // //
ENUM_X_SIGNAL_EXECUTION_RESULT states[]; // int supportSignalsCount = ArraySize(supportSignals);
int executedSupports = mTrader.ExecuteSignals( // if (supportSignalsCount <= 0)
supportSignals, // {
states, // return;
ORDER_TIME_GTC, // }
NULL,
false // Ignore Policies ...
);
if (executedSupports > 0)
{
//
string message = "EQM Execute (" + ToString(executedSupports) + ") Support Signals ...";
// // //
mAlert.Alert(message); // ENUM_X_SIGNAL_EXECUTION_RESULT states[];
} // int executedSupports = mTrader.ExecuteSignals(
// supportSignals,
// states,
// ORDER_TIME_GTC,
// NULL,
// false // Ignore Policies ...
// );
// if (executedSupports > 0)
// {
// //
// string message = "EQM Execute (" + ToString(executedSupports) + ") Support Signals ...";
// //
// mAlert.Alert(message);
// }
} }
// //
@@ -455,7 +502,8 @@ public:
// Make them Configurable ... // Make them Configurable ...
int levelsOnClose = 6; int levelsOnClose = 6;
int requiredAgeForSLTrail = 0; int requiredAgeForSLTrail = 0;
int requiredDistanceForSLTrail = 30; int requiredDistanceForSLTrail = 100;
return;
// //
int positionsCount = ArraySize(positions); int positionsCount = ArraySize(positions);
@@ -474,7 +522,7 @@ public:
// //
bool canManageState = bool canManageState =
// //
false true
// //
; ;
@@ -518,18 +566,19 @@ public:
// //
double slDiff = PointToPrice(priceDistance, iPosition.symbol); double slDiff = PointToPrice(priceDistance, iPosition.symbol);
double appliedSL = slDiff / 2;
//
double sl =
IsLong(iPosition.type)
? iPosition.sl + slDiff
: iPosition.sl - slDiff;
// // // //
// double sl = // double sl =
// IsLong(iPosition.type) // IsLong(iPosition.type)
// ? iPosition.entry + (slDiff / 2) // ? iPosition.sl + slDiff
// : iPosition.entry - (slDiff / 2); // : iPosition.sl - slDiff;
//
double sl =
IsLong(iPosition.type)
? iPosition.entry + appliedSL
: iPosition.entry - appliedSL;
// //
bool isInit = trail.Init( bool isInit = trail.Init(
@@ -608,6 +657,7 @@ public:
// //
double slDiff = PointToPrice(priceDistance, iPosition.symbol); double slDiff = PointToPrice(priceDistance, iPosition.symbol);
double appliedSL = slDiff / 2;
// //
double selectedValue = double selectedValue =
@@ -623,145 +673,8 @@ public:
// //
double sl = double sl =
isLong isLong
? selectedValue + slDiff ? selectedValue + appliedSL
: selectedValue - slDiff; : selectedValue - appliedSL;
//
// Update Trail Values ...
bool isUpdated = trail.Update(
sl,
iPosition.profit //
);
if (!isUpdated)
{
continue;
}
}
//
if (trail.IsValid())
{
//
string comment = trail.GenerateTag();
bool isModified = mTrader.Modify(
trail.ticket,
trail.after,
iPosition.tp,
comment //
);
if (isModified)
{
//
RemoveTrail(trail.ticket);
//
AddSLTrail(trail);
//
string message = "Position (" + ToString(trail.ticket) + ") Trailed SL on Level: " + ToString(trail.level);
mAlert.Alert(message);
}
}
}
else if (iPosition.profit < 0)
{
//
XTrail trail;
bool isTrailedBefore = GetSLTrail(
iPosition.ticket,
trail //
);
//
if (!isTrailedBefore)
{
//
// Add First Time ...
//
// Check Position Age ...
int iPositionAge = iPosition.GetAge(iPosition.period);
if (iPositionAge < requiredAgeForSLTrail)
{
continue;
}
//
// Check Position Profit Distance ...
double priceDistanceInPoint = PriceToPoint(MathAbs(iPosition.profit) / iPosition.volume, iPosition.symbol);
double priceDistance = PointToPrice(priceDistanceInPoint, iPosition.symbol);
if (priceDistance < requiredDistanceForSLTrail)
{
continue;
}
//
double slDiff = PointToPrice(priceDistance, iPosition.symbol);
//
double sl =
IsLong(iPosition.type)
? iPosition.sl + slDiff
: iPosition.sl - slDiff;
//
bool isInit = trail.Init(
iPosition.ticket,
iPosition.type,
iPosition.profit,
iPosition.sl,
sl //
);
if (!isInit)
{
continue;
}
}
else
{
//
// Update Exists ...
//
// Check Profit ...
bool isProfitPassed = iPosition.profit > trail.profit;
if (!isProfitPassed)
{
continue;
}
//
// Check Age Distance from Last ...
int age = iBarShift(
iPosition.symbol,
iPosition.period,
trail.time,
false //
);
if (age < requiredAgeForSLTrail)
{
continue;
}
//
double priceDistanceInPoint = PriceToPoint((MathAbs(iPosition.profit) - MathAbs(trail.profit)) / iPosition.volume, iPosition.symbol);
double priceDistance = PointToPrice(priceDistanceInPoint, iPosition.symbol);
//
double slDiff = PointToPrice(priceDistance, iPosition.symbol);
//
double selectedValue =
//
iPosition.sl
//
;
//
double sl =
IsLong(iPosition.type)
? selectedValue + slDiff
: selectedValue - slDiff;
// //
// Update Trail Values ... // Update Trail Values ...
@@ -926,11 +839,89 @@ public:
} }
// //
// Profit Management ... // Handle Position Changed Event ...
void OnPositionsChangedHandler(int count)
{
//
// Synchronize Tracker ...
SyncPositionTracker();
}
// //
// Tools ... // Tools ...
//
// Position Tracker ...
//
// Synchronize Positions and Position Tracker ...
void SyncPositionTracker()
{
//
static datetime lastSyncPositionTracker = NULL;
datetime cTime = TimeCurrent();
//
int syncInterval = PeriodSeconds(PERIOD_M5);
int lastDiff = (int)cTime - (int)lastSyncPositionTracker;
//
bool canSync =
lastSyncPositionTracker == NULL
? true
: lastDiff >= syncInterval;
if (!canSync)
{
return;
}
//
XPositionTrackerState state;
int synced = mPositionTracker.Sync(
state,
mTrader //
);
if (synced > 0)
{
//
// Check State and Do What we Want ...
int onProfitsCount = ArraySize(state.onProfits);
int onDrawdownCount = ArraySize(state.onDrawdowns);
//
// Do What we want whe a Position Dropped to Prefit ...
if (onProfitsCount > 0)
{
//
for (int i = 0; i < onProfitsCount; i++)
{
//
XPositionTrack iTrack = state.onProfits[i];
//
string message = "Position (" + ToString(iTrack.ticket) + ", " + iTrack.symbol + ") Dropped in Profit ...";
mAlert.Alert(message);
}
}
//
// Do what we want when a Position Dropped to Drawdown ...
if (onDrawdownCount > 0)
{
//
for (int i = 0; i < onDrawdownCount; i++)
{
//
XPositionTrack iTrack = state.onDrawdowns[i];
//
string message = "Position (" + ToString(iTrack.ticket) + ", " + iTrack.symbol + ") Dropped in Drawdown ...";
mAlert.Alert(message);
}
}
}
}
// //
// Protected ... // Protected ...
protected: protected:
File diff suppressed because it is too large Load Diff
+6 -8
View File
@@ -31,16 +31,16 @@
// //
// Inputs ... // Inputs ...
long x121EAMagicNumber = 78692110; // Magic Number long x121EAMagicNumber = 78692110; // Magic Number
int x121EASlippage = 10; // Slippgae int x121EASlippage = 10; // Slippgae
string x121EASymbols = "EURUSDb"; // Symbols string x121EASymbols = "EURUSDb,USDCHFb,USDJPYb,GBPUSDb"; // Symbols
// //
bool x121EAAllowLong = true; // Allow Long Trades bool x121EAAllowLong = true; // Allow Long Trades
bool x121EAAllowShort = true; // Allow Short Trades bool x121EAAllowShort = true; // Allow Short Trades
int x121EAManageInterval = 0; // Manager Check Intervals Seconds int x121EAManageInterval = 0; // Manager Check Intervals Seconds
int x121EAMaxAllowedPositions = 5; // Max Allowed Positions int x121EAMaxAllowedPositions = 10; // Max Allowed Positions
double x121EAMaxAllowedSpread = 0; // Max Allowed Spred for Opening Trades double x121EAMaxAllowedSpread = 0; // Max Allowed Spred for Opening Trades
double x121EAMinProfitPerTrade = 0.5; // Min Profit Per Trade based On Volume Factor (Hedge) double x121EAMinProfitPerTrade = 5; // Min Profit Per Trade based On Volume Factor (Hedge)
double x121EAMinProfitPerVolumeFactor = 0.01; // Min Volume Factor for Calculating Profit (Hedge) double x121EAMinProfitPerVolumeFactor = 0.01; // Min Volume Factor for Calculating Profit (Hedge)
double x121EAMaxAllowedDrawdownFactor = 0.002; // Max Allowed Drawdown Factor double x121EAMaxAllowedDrawdownFactor = 0.002; // Max Allowed Drawdown Factor
// //
@@ -230,9 +230,7 @@ bool InitialEA()
iDescriptor.symbol = iSymbol; iDescriptor.symbol = iSymbol;
iDescriptor.period = iPeriod; iDescriptor.period = iPeriod;
iDescriptor.allowLong = x121EAAllowLong; iDescriptor.allowLong = x121EAAllowLong;
// iDescriptor.allowShort = x121EAAllowShort;
// TODO:
iDescriptor.allowShort = false; // x121EAAllowShort;
Copy( Copy(
signallers, signallers,
iDescriptor.signallers); iDescriptor.signallers);
+12
View File
@@ -4217,6 +4217,18 @@ int Add(
return result; return result;
} }
template <typename T> template <typename T>
int AddSpecific(
T item, // item want to add
T &buffer[] // Destination buffer
)
{
//
return Add(
item,
buffer //
);
}
template <typename T>
int AddRef( int AddRef(
T &item, // item want to add T &item, // item want to add
T &buffer[] // Destination buffer T &buffer[] // Destination buffer