This commit is contained in:
2024-05-25 08:43:32 +03:30
parent da63c4cb71
commit b8515c9d05
5 changed files with 1307 additions and 374 deletions
File diff suppressed because it is too large Load Diff
+207 -109
View File
@@ -288,14 +288,6 @@ public:
//
bool result = false;
//
// TODO:
// Make them Configurable ...
int numberOfPositionsForHege = 4;
int levelsOnClose = 6;
int requiredAgeForSLTrail = 3;
int requiredDistanceForSLTrail = 10;
//
XPosition positions[];
int positionsCount = mTrader.GetPositions(positions);
@@ -304,6 +296,109 @@ public:
return result;
}
//
HandleEQMState();
//
HandleHedging(positions);
//
HandleTrailManagement(positions);
//
// Must false ...
return result;
}
//
void HandleHedging(XPosition &positions[])
{
//
// TODO:
// Make them Configurable ...
int numberOfPositionsForHege = 3;
//
int positionsCount = ArraySize(positions);
if (positionsCount <= 0)
{
return;
}
//
// Hedge ...
if (positionsCount >= numberOfPositionsForHege)
{
//
double profit = CalculatePositionsProfit(positions);
double requiredProfit = CalculateRequiredProfitForHedge(positions);
//
bool isReadyForHedge = profit >= requiredProfit;
if (!isReadyForHedge)
{
return;
}
//
string comment = "EQM Hedge ...";
int closed = mTrader.Close(
positions,
comment
//
);
if (closed > 0)
{
//
string message = "EQM Hedge Positions on Profit: " + ToString(profit);
//
mAlert.Alert(message);
//
for (int i = 0; i < positionsCount; i++)
{
RemoveSLTrail(positions[i].ticket);
}
}
}
}
//
void HandleEQMState()
{
//
bool equityReached = !mTrader.CheckEquityForTrade();
bool maxAllowedReached = !mTrader.CheckPositionsForTrade();
bool enableEQM = equityReached || maxAllowedReached;
if (!enableEQM)
{
//
return;
}
//
Print("EQM Enabled: " + (equityReached ? "Max Equity Reached ..." : maxAllowedReached ? "Max Allowed Positions Reached ..."
: ""));
}
//
void HandleTrailManagement(XPosition &positions[])
{
//
// TODO:
// Make them Configurable ...
int levelsOnClose = 6;
int requiredAgeForSLTrail = 3;
int requiredDistanceForSLTrail = 10;
//
int positionsCount = ArraySize(positions);
if (positionsCount <= 0)
{
return;
}
//
// Trail Positions Stop ...
for (int i = 0; i < positionsCount; i++)
@@ -316,6 +411,7 @@ public:
//
iPosition.provider == ToString(X786) ||
iPosition.provider == ToString(X121) ||
iPosition.provider == ToString(X110) ||
iPosition.provider == ToString(X92)
//
;
@@ -496,48 +592,6 @@ public:
}
}
}
//
// Hedge ...
if (positionsCount >= numberOfPositionsForHege)
{
//
double profit = CalculatePositionsProfit(positions);
double requiredProfit = CalculateRequiredProfitForHedge(positions);
//
bool isReadyForHedge = profit >= requiredProfit;
if (!isReadyForHedge)
{
return result;
}
//
string comment = "EQM Hedge ...";
int closed = mTrader.Close(
positions,
comment
//
);
if (closed > 0)
{
//
string message = "EQM Hedge Positions on Profit: " + ToString(profit);
//
mAlert.Alert(message);
//
for (int i = 0; i < positionsCount; i++)
{
RemoveSLTrail(positions[i].ticket);
}
}
}
//
// Must false ...
return result;
}
//
@@ -598,7 +652,7 @@ public:
NULL, // All Periods ...
iSignal.type //
);
if (positionsCount <= 5)
if (positionsCount < 2)
{
//
// First Signal in a While of Specific Provider ...
@@ -610,71 +664,112 @@ public:
//
continue;
}
else
{
//
// not First Signal ...
// else
// {
// //
// // not First Signal ...
//
// Calculate Provider Specified Open Positions Profit ...
double profits = CalculatePositionsProfit(positions);
if (profits > 0)
{
//
AddRef(
iSignal,
signals //
);
// //
// // Calculate Provider Specified Open Positions Profit ...
// double profits = CalculatePositionsProfit(positions);
// if (profits > 0)
// {
//
continue;
}
else
{
//
// Find Max In Profit of Same Position ...
Clean(positions);
positionsCount = mTrader.GetInProfitPositions(
positions,
iSignal.symbol,
iSignal.provider,
NULL, // All Periods ...
iSignal.type,
X_POSITION_SELECT_MAX // Max In Profit ...
);
if (positionsCount <= 0)
{
continue;
}
// //
// AddRef(
// iSignal,
// signals //
// );
//
string comment = "EQM Close Max Profit ...";
bool isClosed = mTrader.Close(
positions[0].ticket,
comment //
);
if (isClosed)
{
//
RemoveTrail(positions[0].ticket);
// // //
// // // Find Max In Profit of Same Position ...
// // Clean(positions);
// // positionsCount = mTrader.GetInProfitPositions(
// // positions,
// // iSignal.symbol,
// // iSignal.provider,
// // NULL, // All Periods ...
// // iSignal.type,
// // X_POSITION_SELECT_MAX // Max In Profit ...
// // );
// // if (positionsCount <= 0)
// // {
// // continue;
// // }
//
string message = "EQM Close Max In Profit (" + ToString(positions[0].ticket) + ") for new Signal ...";
// // //
// // string comment = "EQM Close Max Profit ...";
// // bool isClosed = mTrader.Close(
// // positions[0].ticket,
// // comment //
// // );
// // if (isClosed)
// // {
// // //
// // RemoveTrail(positions[0].ticket);
//
mAlert.Alert(message);
// // //
// // string message = "EQM Close Max In Profit (" + ToString(positions[0].ticket) + ") for new Signal ...";
//
AddRef(
iSignal,
signals //
);
// // //
// // mAlert.Alert(message);
//
continue;
}
}
}
// // //
// // AddRef(
// // iSignal,
// // signals //
// // );
// // //
// // continue;
// // }
// }
// else
// {
// // //
// // // Find Max In Profit of Same Position ...
// // Clean(positions);
// // positionsCount = mTrader.GetInProfitPositions(
// // positions,
// // iSignal.symbol,
// // iSignal.provider,
// // NULL, // All Periods ...
// // iSignal.type,
// // X_POSITION_SELECT_MAX // Max In Profit ...
// // );
// // if (positionsCount <= 0)
// // {
// // continue;
// // }
// // //
// // string comment = "EQM Close Max Profit ...";
// // bool isClosed = mTrader.Close(
// // positions[0].ticket,
// // comment //
// // );
// // if (isClosed)
// // {
// // //
// // RemoveTrail(positions[0].ticket);
// // //
// // string message = "EQM Close Max In Profit (" + ToString(positions[0].ticket) + ") for new Signal ...";
// // //
// // mAlert.Alert(message);
// // //
// // AddRef(
// // iSignal,
// // signals //
// // );
// // //
// // continue;
// // }
// }
// }
}
//
@@ -705,6 +800,9 @@ public:
return false;
}
//
// Profit Management ...
//
// Tools ...
+534 -4
View File
@@ -30,11 +30,179 @@
typedef void (*TOnSignal)(XSignal &signals[]);
//
// Model Account Profits ...
struct XProfitTracker {
//
int count; // Number of Positions ...
enum ENUM_X_PROFIT_TRACK_FIELDS
{
X_PROFIT_TRACK_PROFIT,
X_PROFIT_TRACK_LONGS_PROFIT,
X_PROFIT_TRACK_SHORTS_PROFIT,
};
//
// Model Account Profits ...
struct XProfitTrack
{
//
int longs; // Number of Long ...
int shorts; // Number of Short ...
//
double profit; // Profit of All ...
double longsProfit; // Profits of Longs ...
double shortsProfit; // Profits of Shorts ...
//
double profitFrom; // Profit of All ...
double longsProfitFrom; // Profits of Longs ...
double shortsProfitFrom; // Profits of Shorts ...
//
double volume; // Volume ...
double longsVolume; // Volume of Longs ...
double shortsVolume; // Volume of Shorts ...
//
datetime time; // Check Time ...
//
XProfitTrack()
{
Clean();
}
//
// Tools ...
//
// Initialization ...
bool Init(XSCTrade *mTrader)
{
//
bool result = false;
//
XPosition positions[];
int positionsCount = mTrader.GetPositions(positions);
result = positionsCount > 0;
if (!result)
{
return result;
}
//
for (int i = 0; i < positionsCount; i++)
{
//
XPosition iPosition = positions[i];
//
bool isLong = IsLong(iPosition.type);
//
if (isLong)
{
//
longs++;
longsVolume += iPosition.volume;
longsProfit += iPosition.profit;
}
else
{
//
shorts++;
shortsVolume += iPosition.volume;
shortsProfit += iPosition.profit;
}
//
profit += iPosition.profit;
volume += iPosition.volume;
}
//
result = IsValid();
if (result)
{
time = TimeCurrent();
}
//
return result;
}
//
double SelectField(ENUM_X_PROFIT_TRACK_FIELDS field)
{
//
double result = profit;
//
switch (field)
{
//
case X_PROFIT_TRACK_LONGS_PROFIT:
result = longsProfit;
break;
//
case X_PROFIT_TRACK_SHORTS_PROFIT:
result = shortsProfit;
break;
//
default:
case X_PROFIT_TRACK_PROFIT:
result = profit;
break;
}
//
return result;
}
//
// Cleanup ...
void Clean()
{
//
longs = 0;
shorts = 0;
profit = 0;
volume = 0;
profitFrom = 0;
longsVolume = 0;
longsProfit = 0;
shortsVolume = 0;
shortsProfit = 0;
longsProfitFrom = 0;
shortsProfitFrom = 0;
//
time = NULL;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
(longs > 0 || shorts > 0)
//
&&
//
volume > 0
//
;
//
return result;
}
//
};
//
@@ -401,6 +569,9 @@ public:
// Check Trade Events ...
OnTrade();
//
HandleProfitManageMent();
//
// First Check For Any Guard Actions ...
// then Handle Guards if Provided ...
@@ -698,6 +869,16 @@ public:
}
}
//
virtual void OnGoingToProfit(XProfitTrack &track) {}
virtual void OnLongsGoingToProfit(XProfitTrack &track) {}
virtual void OnShortsGoingToProfit(XProfitTrack &track) {}
//
virtual void OnGoingToDrawdown(XProfitTrack &track) {}
virtual void OnLongsGoingToDrawdown(XProfitTrack &track) {}
virtual void OnShortsGoingToDrawdown(XProfitTrack &track) {}
//
// Protected ...
protected:
@@ -815,6 +996,355 @@ protected:
return result;
}
//
// Profit Tracker ...
//
XProfitTrack mProfitTracks[];
//
bool GetProfitTrack(
XProfitTrack &track,
int index = 0 //
)
{
//
bool result = false;
//
if (index < 0)
{
index = 0;
}
//
int tracksCount = CountProfitTracks();
result = tracksCount > 0 && index < tracksCount;
if (!result)
{
return result;
}
//
track.Clean();
//
track = mProfitTracks[index];
//
result = track.IsValid();
//
return result;
}
//
int CountProfitTracks()
{
return ArraySize(mProfitTracks);
}
//
void AddProfitTrack()
{
//
XProfitTrack track;
bool isValid = track.Init(mTrader);
if (!isValid)
{
return;
}
//
ArraySetAsSeries(mProfitTracks, false);
//
AddRef(
track,
mProfitTracks //
);
//
ArraySetAsSeries(mProfitTracks, true);
}
//
// Extract Specified Field Vales of XProfit Track Struct ...
int ExtractProfitTrackField(
double &result[],
ENUM_X_PROFIT_TRACK_FIELDS field,
int start = 0,
int count = 10 //
)
{
//
Clean(result);
//
if (start < 0)
{
start = 0;
}
//
int end = start + count;
//
int tracksCount = CountProfitTracks();
if (end > tracksCount)
{
end = tracksCount;
}
//
for (int i = start; i < end; i++)
{
//
XProfitTrack iTrack;
bool isValid = GetProfitTrack(
iTrack,
i //
);
//
if (!isValid)
{
continue;
}
//
double iValue = iTrack.SelectField(field);
Add(
iValue,
result //
);
}
//
int mResult = ArraySize(result);
//
return mResult;
}
//
double AverageProfitTrackField(
ENUM_X_PROFIT_TRACK_FIELDS field,
int start = 0,
int count = 10 //
)
{
//
double result = EMPTY_VALUE;
//
double items[];
int itemsCount = ExtractProfitTrackField(
items,
field,
start,
count //
);
if (itemsCount <= 0)
{
return result;
}
//
result = GetAverage(items);
//
return result;
}
//
bool IsProfitTrackFieldIncreasing(
ENUM_X_PROFIT_TRACK_FIELDS field,
int start = 0,
int count = 10 //
)
{
//
bool result = false;
//
double items[];
int itemsCount = ExtractProfitTrackField(
items,
field,
start,
count //
);
if (itemsCount <= 0)
{
return result;
}
//
int from = itemsCount - 1;
int to = 0;
//
result = IsIncreasing(
from,
to,
items //
);
//
return result;
}
//
bool IsProfitTrackFieldDecreasing(
ENUM_X_PROFIT_TRACK_FIELDS field,
int start = 0,
int count = 10 //
)
{
//
bool result = false;
//
double items[];
int itemsCount = ExtractProfitTrackField(
items,
field,
start,
count //
);
if (itemsCount <= 0)
{
return result;
}
//
int from = itemsCount - 1;
int to = 0;
//
result = IsDecreasing(
from,
to,
items //
);
//
return result;
}
//
void HandleProfitManageMent()
{
//
AddProfitTrack();
//
int profitsCount = CountProfitTracks();
if (profitsCount <= 1)
{
return;
}
//
XProfitTrack cT;
bool isValid = GetProfitTrack(
cT,
0 //
);
if (!isValid)
{
return;
}
//
XProfitTrack pT;
isValid = GetProfitTrack(
pT,
1 //
);
if (!isValid)
{
return;
}
//
cT.profitFrom = pT.profit;
cT.longsProfitFrom = pT.longsProfit;
cT.shortsProfitFrom = pT.shortsProfit;
//
bool isGoningToProfit =
//
cT.profit > 0 &&
pT.profit <= 0
//
;
if (isGoningToProfit)
{
//
OnGoingToProfit(cT);
}
//
bool isLongsGoningToProfit =
//
cT.longsProfit > 0 &&
pT.longsProfit <= 0
//
;
if (isLongsGoningToProfit)
{
OnLongsGoingToProfit(cT);
}
//
bool isShortsGoningToProfit =
//
cT.shortsProfit > 0 &&
pT.shortsProfit <= 0
//
;
if (isShortsGoningToProfit)
{
OnShortsGoingToProfit(cT);
}
//
bool isGoningToDrawdown =
//
cT.profit < 0 &&
pT.profit >= 0
//
;
if (isGoningToDrawdown)
{
OnGoingToDrawdown(cT);
}
bool isLongsGoningToDrawdown =
//
cT.longsProfit < 0 &&
pT.longsProfit >= 0
//
;
if (isLongsGoningToDrawdown)
{
OnLongsGoingToDrawdown(cT);
}
bool isShortsGoningToDrawdown =
//
cT.shortsProfit < 0 &&
pT.shortsProfit >= 0
//
;
if (isShortsGoningToDrawdown)
{
OnShortsGoingToDrawdown(cT);
}
}
//
// Guards ...
+21 -18
View File
@@ -30,18 +30,18 @@
//
// Inputs ...
long x121EAMagicNumber = 78692110; // Magic Number
int x121EASlippage = 10; // Slippgae
string x121EASymbols = "EURUSDb"; // Symbols
long x121EAMagicNumber = 78692110; // Magic Number
int x121EASlippage = 10; // Slippgae
string x121EASymbols = "EURUSDb,USDCHFb,USDJPYb,GBPUSDb,XAUUSDb,AUDUSDb,USDCADb,NZDUSDb"; // Symbols
//
bool x121EAAllowLong = true; // Allow Long Trades
bool x121EAAllowShort = true; // Allow Short Trades
int x121EAManageInterval = 5; // Manager Check Intervals Seconds
int x121EAMaxAllowedPositions = 5; // Max Allowed Positions
int x121EAMaxAllowedPositions = 30; // Max Allowed Positions
double x121EAMaxAllowedSpread = 0; // Max Allowed Spred for Opening Trades
double x121EAMinProfitPerTrade = 0.4; // Min Profit Per Trade based On Volume Factor (Hedge)
double x121EAMinProfitPerTrade = 0.3; // Min Profit Per Trade based On Volume Factor (Hedge)
double x121EAMinProfitPerVolumeFactor = 0.01; // Min Volume Factor for Calculating Profit (Hedge)
double x121EAMaxAllowedDrawdownFactor = 0.015; // Max Allowed Drawdown Factor
double x121EAMaxAllowedDrawdownFactor = 0.05; // Max Allowed Drawdown Factor
//
double x121EAVolume = 0.01;
@@ -190,7 +190,10 @@ bool InitialEA()
//
// Define Signallers ...
ENUM_X121_SIGNAL_PROVIDERS signallers[];
GetAllX121SignalProviders(signallers);
Add(X786, signallers);
Add(X110, signallers);
Add(X121, signallers);
// GetAllX121SignalProviders(signallers);
//
// Instantiate X121EA Class ...
@@ -238,9 +241,9 @@ bool InitialEA()
//
// XMC ...
iDescriptor.inputs.mcInputs.showFastMa = true;
iDescriptor.inputs.mcInputs.showSlowMa = true;
iDescriptor.inputs.mcInputs.showVerifierMa = true;
iDescriptor.inputs.mcInputs.showFastMa = false;
iDescriptor.inputs.mcInputs.showSlowMa = false;
iDescriptor.inputs.mcInputs.showVerifierMa = false;
//
// XICH ...
@@ -255,26 +258,26 @@ bool InitialEA()
//
// XCHE ...
iDescriptor.inputs.cheInputs.showLongExit1Line = true;
iDescriptor.inputs.cheInputs.showShortExit1Line = true;
iDescriptor.inputs.cheInputs.showLongExit2Line = true;
iDescriptor.inputs.cheInputs.showShortExit2Line = true;
iDescriptor.inputs.cheInputs.showLongExit1Line = false;
iDescriptor.inputs.cheInputs.showShortExit1Line = false;
iDescriptor.inputs.cheInputs.showLongExit2Line = false;
iDescriptor.inputs.cheInputs.showShortExit2Line = false;
//
// XPV ...
iDescriptor.inputs.pvInputs.showPeaksAndVales = true;
iDescriptor.inputs.pvInputs.showPeaksAndVales = false;
iDescriptor.inputs.pvInputs.showLevels = false;
iDescriptor.inputs.pvInputs.showConsolidations = false;
iDescriptor.inputs.pvInputs.showFibo1Levels = false;
iDescriptor.inputs.pvInputs.showFibo2Levels = false;
iDescriptor.inputs.pvInputs.showFibo3Levels = true;
iDescriptor.inputs.pvInputs.showFibo3Levels = false;
iDescriptor.inputs.pvInputs.showFibo4Levels = false;
iDescriptor.inputs.pvInputs.showFibo5Levels = false;
//
// XZG ...
iDescriptor.inputs.zgInputs.showZigZag = false;
iDescriptor.inputs.zgInputs.showPeaksAndVales = true;
iDescriptor.inputs.zgInputs.showPeaksAndVales = false;
//
// XDON ...
@@ -285,7 +288,7 @@ bool InitialEA()
//
// XSTR ...
iDescriptor.inputs.strInputs.showTrends = true;
iDescriptor.inputs.strInputs.showTrends = false;
iDescriptor.inputs.strInputs.fillTrends = false;
//
+1 -1
View File
@@ -3784,7 +3784,7 @@ bool IsUnder(
// Check if a Value Increasing in Loopback ...
bool IsIncreasing(
const int from, // Last Time Index
const int to, // Fisr Tima Index
const int to, // Fisrs Tima Index
const double &buffer[] // the Buffer which required to search
)
{