This commit is contained in:
2024-06-22 08:33:18 +03:30
parent 532be35f74
commit 6063d3be61
5 changed files with 597 additions and 57 deletions
+49
View File
@@ -69,6 +69,7 @@ enum ENUM_X121_SIGNAL_PROVIDER
PROVIDER_XASCT = 16,
PROVIDER_XVLM = 17,
PROVIDER_XPVF = 18,
PROVIDER_XPVSAR = 19,
};
//
@@ -197,6 +198,10 @@ ENUM_X121_SIGNAL_PROVIDER FromString(string value)
{
result = PROVIDER_XPVF;
}
else if (Contains(value, (EnumToString(PROVIDER_XPVSAR))))
{
result = PROVIDER_XPVSAR;
}
//
return result;
@@ -1422,6 +1427,24 @@ struct X121SignalGenerator
provider = ToString(PROVIDER_XPVF);
}
//
// XPVSAR ...
bool long19 =
//
// Starting Conditions ...
conditions.mcConditions.isSARSwitchedToBullish &&
conditions.pvConditions.vales[zIndex] == conditions.mcConditions.psar[zIndex] &&
conditions.strConditions.isTrendBullish &&
conditions.cheConditions.isStrongBullish
//
;
if (long19)
{
//
pusher += 2;
provider = ToString(PROVIDER_XPVSAR);
}
//
result =
//
@@ -1500,6 +1523,10 @@ struct X121SignalGenerator
//
long18
//
||
//
long19
//
)
//
;
@@ -2068,6 +2095,24 @@ struct X121SignalGenerator
provider = ToString(PROVIDER_XPVF);
}
//
// XPVSAR ...
bool short19 =
//
// Starting Conditions ...
conditions.mcConditions.isSARSwitchedToBearish &&
conditions.pvConditions.peaks[zIndex] == conditions.mcConditions.psar[zIndex] &&
conditions.strConditions.isTrendBearish &&
conditions.cheConditions.isStrongBearish
//
;
if (short19)
{
//
pusher += 2;
provider = ToString(PROVIDER_XPVSAR);
}
//
result =
//
@@ -2146,6 +2191,10 @@ struct X121SignalGenerator
//
short18
//
||
//
short19
//
)
//
;
+299 -29
View File
@@ -2825,6 +2825,25 @@ public:
mAllowShort = value;
}
//
int DelayBetweenTwoSignal()
{
return mDelayBetweenTwoSignal;
}
//
void DelayBetweenTwoSignal(int value)
{
//
if (value < 0)
{
value = 0;
}
//
mDelayBetweenTwoSignal = value;
}
//
int ReuiredSignalVerifications()
{
@@ -3318,6 +3337,44 @@ public:
mForceCloseProfit = value;
}
//
double MaxDrawdownForce()
{
return mMaxDrawdownForce;
}
//
void MaxDrawdownForce(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mMaxDrawdownForce = value;
}
//
int MaxPositionsForce()
{
return mMaxPositionsForce;
}
//
void MaxPositionsForce(int value)
{
//
if (value < 0)
{
value = 0;
}
//
mMaxPositionsForce = value;
}
//
bool ForceState()
{
@@ -3349,6 +3406,18 @@ public:
//
// Tools ...
//
double GetBullishScore()
{
return mBullishScore;
}
//
double GetBearishScore()
{
return mBearishScore;
}
//
// Check Provider for any Guards ...
bool CheckForGuard(XGuard &guards[]) override
@@ -4187,10 +4256,18 @@ public:
if (isSignalValid)
{
//
AddRef(
iSignal,
eSignals //
);
// Check Delay Between Two Signals ...
bool isDelayPassed = IsSignalDelayPassed(iSignal);
//
if (isDelayPassed)
{
//
AddRef(
iSignal,
eSignals //
);
}
}
}
@@ -4409,6 +4486,62 @@ protected:
);
}
//
// Check Delay Between Two Signals ...
bool IsSignalDelayPassed(
XSignal &signal //
)
{
//
bool result = false;
//
// Check Signal Validation ...
result = signal.IsValid();
if (!result)
{
return result;
}
//
// Check Delay Signals Allowed ...
int delay = DelayBetweenTwoSignal();
result = delay <= 0;
if (result)
{
return result;
}
//
// Retrieve Positions ...
// Based On Provider and Symbol and TimeFrame ...
XPosition positions[];
int positionsCount = mTrader.GetPositions(
positions,
signal.symbol,
signal.provider,
signal.period,
ToPositionType(signal.type),
true // Filter By Magic ...
);
result = !IsValidSize(positionsCount);
if (result)
{
return result;
}
//
XPosition youngest;
int youngestAge = GetYoungest(
youngest,
positions //
);
result = youngestAge >= delay;
//
return result;
}
//
// Private ...
private:
@@ -4446,7 +4579,10 @@ private:
// - Receive Signals with minimal Verifications;
// - Increase Volume Size of in Profit Positions;
// - etc ...
bool mForceState; // Determine in Force State or not
bool mForceState; // Determine in Force State or not
int mDelayBetweenTwoSignal; // Delay between two same signal
int mMaxPositionsForce; // Max Number of Positions For Guard Handling
double mMaxDrawdownForce; // Force Handling State on Drawdown for Guard
//
XTradeHandler *mTradeHandler; // Handle all Event which related to Signals and Positions
@@ -4641,10 +4777,8 @@ private:
}
//
double profit = SpecifiedIsPositionsReadyForHedge(
positions,
0.15,
0.01 //
double profit = SpecifiedCalculatePositionsProfit(
positions //
);
result =
profit > hedgingProfit;
@@ -4761,30 +4895,158 @@ private:
return;
}
//
double profits = SpecifiedCalculatePositionsProfit(positionsCount);
//
// Checking Force Sate Conditions ...
if (ForceState())
{
//
// Check Force State Hedging ...
// bool isHedged = DoEQMForceClose();
// if (isHedged)
// {
// //
// ForceState(false);
// return;
// }
bool isHedged = DoEQMForceClose();
if (isHedged)
{
//
ForceState(false);
return;
}
// //
// isHedged = DoEQMForceClose(5);
// if (isHedged)
// {
// //
// ForceState(false);
// return;
// }
//
// Handle Act Based On Drawdow ...
if (mMaxDrawdownForce > 0)
{
//
double drawdown = GetDrawdownPercent();
if (drawdown > 5)
{
//
// Try to Hedge ...
if (profits > 0)
{
//
bool isHedged = DoEQMForceClose(profits);
if (isHedged)
{
//
ForceState(false);
return;
}
}
// //
//
// Close Max In Drawdown Position ...
int maxInDIDX = FindMaxDrawdownIndex(positions);
if (isValidIndex(maxInDIDX))
{
//
string comment = XEQMSupportToken + " Max In D ...";
//
bool isClosed = mTrader.Close(
positions[maxInDIDX].ticket,
comment //
);
if (isClosed)
{
//
string message = XEQMSupportToken + "Close " + ToString(positions[maxInDIDX].ticket) + " Due Max In Drawdown ...";
//
Alert(message);
}
//
return;
}
//
return;
}
}
//
// Handle Act Based on Positions Count ...
if (mMaxPositionsForce > 0 && positionsCount > mMaxPositionsForce)
{
//
double requiredProfit = SpecifiedCalculateRequiredProfitForHedge(
positions,
mMinRequiredProfitPerTrade,
mMinRequiredProfitPerVolumeFactor //
);
//
double halfProfit = requiredProfit / 2;
if (halfProfit > 0 && profit > halfProfit)
{
//
bool isHedged = DoEQMForceClose(halfProfit);
if (isHedged)
{
//
ForceState(false);
return;
}
}
//
// Close Min In Profit Position ...
int minInPIDX = FindMinProfitIndex(positions);
if (IsValidIndex(minInPIDX))
{
//
string comment = XEQMSupportToken + " Min In P ...";
//
bool isClosed = mTrader.Close(
positions[minInPIDX].ticket,
comment //
);
if (isClosed)
{
//
string message = XEQMSupportToken + "Close " + ToString(positions[maxInDIDX].ticket) + " Due Min In Profit ...";
//
Alert(message);
//
return;
}
}
//
// Close Max In Drawdown Position ...
int maxInDIDX = FindMaxDrawdownIndex(positions);
if (isValidIndex(maxInDIDX))
{
//
string comment = XEQMSupportToken + " Max In D ...";
//
bool isClosed = mTrader.Close(
positions[maxInDIDX].ticket,
comment //
);
if (isClosed)
{
//
string message = XEQMSupportToken + "Close " + ToString(positions[maxInDIDX].ticket) + " Due Max In Drawdown ...";
//
Alert(message);
}
//
return;
}
//
return;
}
//
return;
}
@@ -4905,10 +5167,18 @@ private:
if (isValid)
{
//
AddRef(
signal,
signals //
);
// Check Delay Between Two Signals ...
bool isDelayPassed = IsSignalDelayPassed(signal);
//
if (isDelayPassed)
{
//
AddRef(
signal,
signals //
);
}
}
//
+4 -4
View File
@@ -39,6 +39,10 @@ public:
//
// Props ...
//
// Trade Class Instance ...
XSCTrade *mTrader;
//
// Constructor ...
XSCBaseEA(
@@ -580,10 +584,6 @@ protected:
//
// Props ...
//
// Trade Class Instance ...
XSCTrade *mTrader;
//
// Check in Test Mode or not ...
bool mIsInTestMode;
+164 -23
View File
@@ -46,6 +46,7 @@ input bool x121EAUseAllSymbols = false;
input bool x121EAUseAllWatchListSymbols = false; // Use All WatchList Symbols
input bool x121EAAllowLong = true; // Allow Long Trades
input bool x121EAAllowShort = true; // Allow Short Trades
input int x121EADelayBetweenTwoSignal = 10; // Delay Between two Same Signals
input int x121EAReuiredSignalVerifications = 5; // Required Verifications for Signals
input bool x121EAGetVerificationFromOtherTimeFrames = true; // Get Verifications from Other Time Frames
@@ -102,9 +103,11 @@ input double x121EAMaxAllowedRecoveryVolume = 0.08; // Max Allowed Recovery Sign
//
input group "Hedging";
input int x121EARestingAfterHedge = 0; // Resting Seconds After Hedge
input double x121EAForceCloseProfit = 15; // Close All Positions Regardless of Policies when Profit Reached
input double x121EAMaxDrawdownForce = 5; // Max Drawdown Force State for Handling Guards
input int x121EAMaxPositionsForce = 15; // Max Number of Positions Force State for Handling Guards
input double x121EAMinRequiredProfitPerTrade = 0.5; // Minimum Required Profit for Hedging
input double x121EAMinRequiredProfitPerVolumeFactor = 0.01; // Minimum Required Profit for Hedging Per Volume
input double x121EAForceCloseProfit = 20; // Close All Positions Regardless of Policies when Profit Reached
//
// Alert ...
@@ -122,6 +125,7 @@ input bool x121EATerminalAlerts = false; // Terminal Alerts
// Local Variables ...
//
string x121EAUsedSymbols[];
XSCX121SetupEA *x121EA;
//
@@ -170,7 +174,11 @@ void OnDeinit(const int reason)
// On Tick Handler ...
void OnTick()
{
//
x121EA.OnTick();
//
X121ReportState();
}
//
@@ -206,13 +214,13 @@ bool InitialEA()
);
//
string symbols[];
Clean(x121EAUsedSymbols);
if (x121EAUseAllSymbols)
{
//
Copy(
allSymbols,
symbols //
x121EAUsedSymbols //
);
}
else if (x121EAUseAllWatchListSymbols)
@@ -220,7 +228,7 @@ bool InitialEA()
//
Copy(
watchListSymbols,
symbols //
x121EAUsedSymbols //
);
}
else if (IsValidSize(inputSymbolsCount))
@@ -228,7 +236,7 @@ bool InitialEA()
//
Copy(
inputSymbols,
symbols //
x121EAUsedSymbols //
);
}
else
@@ -236,10 +244,10 @@ bool InitialEA()
//
Add(
_Symbol,
symbols //
x121EAUsedSymbols //
);
}
int symbolsCount = ArraySize(symbols);
int symbolsCount = ArraySize(x121EAUsedSymbols);
result = IsValidSize(symbolsCount);
if (!result)
{
@@ -259,6 +267,7 @@ bool InitialEA()
// Signals ...
x121EA.AllowLong(x121EAAllowLong);
x121EA.AllowShort(x121EAAllowShort);
x121EA.DelayBetweenTwoSignal(x121EADelayBetweenTwoSignal);
x121EA.ReuiredSignalVerifications(x121EAReuiredSignalVerifications);
x121EA.GetVerificationFromOtherTimeFrames(x121EAGetVerificationFromOtherTimeFrames);
@@ -317,6 +326,8 @@ bool InitialEA()
// Hedging ...
x121EA.ForceCloseProfit(x121EAForceCloseProfit);
x121EA.RestingAfterHedge(x121EARestingAfterHedge);
x121EA.MaxDrawdownForce(x121EAMaxDrawdownForce);
x121EA.MaxPositionsForce(x121EAMaxPositionsForce);
x121EA.MinRequiredProfitPerTrade(x121EAMinRequiredProfitPerTrade);
x121EA.MinRequiredProfitPerVolumeFactor(x121EAMinRequiredProfitPerVolumeFactor);
@@ -333,7 +344,7 @@ bool InitialEA()
// Configure Indicators ...
X121SetupInputs setupInputsDefault;
setupInputsDefault.Default();
PreConfigureStyles(setupInputsDefault);
X121PreConfigureStyles(setupInputsDefault);
//
// Prepare Providers and Add them into mX121EA class ...
@@ -341,7 +352,7 @@ bool InitialEA()
{
//
// Requirements ...
string iSymbol = symbols[i];
string iSymbol = x121EAUsedSymbols[i];
ENUM_TIMEFRAMES iHostPeriod = _Period;
//
@@ -370,25 +381,25 @@ bool InitialEA()
}
//
void PreConfigureStyles(X121SetupInputs &inputs)
void X121PreConfigureStyles(X121SetupInputs &inputs)
{
//
// XPV ...
inputs.pvInputs.showPeaksAndVales = true;
inputs.pvInputs.showPeaksAndVales = false;
inputs.pvInputs.showLevels = false;
inputs.pvInputs.showConsolidations = false;
inputs.pvInputs.showFibo1Levels = true;
inputs.pvInputs.showFibo2Levels = true;
inputs.pvInputs.showFibo3Levels = true;
inputs.pvInputs.showFibo4Levels = true;
inputs.pvInputs.showFibo5Levels = true;
inputs.pvInputs.showFibo1Levels = false;
inputs.pvInputs.showFibo2Levels = false;
inputs.pvInputs.showFibo3Levels = false;
inputs.pvInputs.showFibo4Levels = false;
inputs.pvInputs.showFibo5Levels = false;
//
// XMC ...
inputs.mcInputs.showSar = true;
inputs.mcInputs.showFastMa = true;
inputs.mcInputs.showSlowMa = true;
inputs.mcInputs.showVerifierMa = true;
inputs.mcInputs.showSar = false;
inputs.mcInputs.showFastMa = false;
inputs.mcInputs.showSlowMa = false;
inputs.mcInputs.showVerifierMa = false;
//
// XHK ...
@@ -398,9 +409,9 @@ void PreConfigureStyles(X121SetupInputs &inputs)
//
// XCHE ...
inputs.cheInputs.showLongExit1Line = false;
inputs.cheInputs.showShortExit1Line = true;
inputs.cheInputs.showShortExit1Line = false;
inputs.cheInputs.showLongExit2Line = false;
inputs.cheInputs.showShortExit2Line = true;
inputs.cheInputs.showShortExit2Line = false;
//
// XICH ...
@@ -415,7 +426,7 @@ void PreConfigureStyles(X121SetupInputs &inputs)
//
// XSTR ...
inputs.strInputs.showTrends = true;
inputs.strInputs.showTrends = false;
inputs.strInputs.fillTrends = false;
//
@@ -441,3 +452,133 @@ void PreConfigureStyles(X121SetupInputs &inputs)
}
//
void X121ReportState()
{
//
string comment = NULL;
//
comment =
ShortName + "\n" +
"------------" + "\n" +
"Trading Symbols: " + ToString(ArraySize(x121EAUsedSymbols)) + "\n" + "\n";
//
// Detect What we Want to Show as Comment ...
bool isInForceState = x121EA.ForceState();
double bullishScore = 0; // x121EA.GetBullishScore();
double bearishScore = 0; // x121EA.GetBearishScore();
double drawDownPercent = x121EA.GetDrawdownPercent();
//
comment +=
//
(bullishScore > 0 || bearishScore > 0
? "Scores:" + "\n" +
"------------" + "\n" +
"Bullish: " + ToString(bullishScore) + "\n" +
"Bearish: " + ToString(bearishScore) + "\n" +
"------------" + "\n"
: "") +
"Drawdown: " + ToString(drawDownPercent) + "%" + "\n" +
"------------" + "\n" +
"Force State: " + ToString(isInForceState) + "\n" +
//
""
//
;
//
XPosition positions[];
int positionsCount = x121EA.mTrader.GetPositions(
positions //
);
if (IsValidSize(positionsCount))
{
//
int longs = 0;
double longVolumes = 0;
double longProfits = 0;
//
int shorts = 0;
double shortVolumes = 0;
double shortProfits = 0;
//
// Retrieve Required Informations of Positions ...
CountPositions(
positions,
longs,
longProfits,
longVolumes,
shorts,
shortProfits,
shortVolumes //
);
//
comment +=
//
"------------" + "\n" +
"Positions: " + "\n" +
"------------" + "\n" +
(longs <= 0
? ""
: "\n" + "Longs:" + "\n" +
"------------" + "\n" +
"Count: " + ToString(longs) + "\n" +
"Profits: " + ToString(longProfits) + "\n" +
""
//
) +
//
(shorts <= 0
? ""
: "\n" + "Shorts:" + "\n" +
"------------" + "\n" +
"Count: " + ToString(shorts) + "\n" +
"Profits: " + ToString(shortProfits) + "\n" +
""
//
) +
//
""
//
;
}
//
if (positionsCount > 1 && x121EAMinRequiredProfitPerTrade > 0 && x121EAMinRequiredProfitPerVolumeFactor > 0)
{
//
double profit = SpecifiedCalculatePositionsProfit(
positions //
);
double requiredProfitForHedge = SpecifiedCalculateRequiredProfitForHedge(
positions,
x121EAMinRequiredProfitPerTrade,
x121EAMinRequiredProfitPerVolumeFactor //
);
//
comment +=
//
"\n" + "Hedging: " + "\n" +
"------------" + "\n" +
"Profits: " + ToString(profit) + "\n" +
"RequiredProft: " + ToString(requiredProfitForHedge) + "\n" +
//
""
//
;
}
//
if (IsValid(comment))
{
Comment(comment);
}
}
//
+80
View File
@@ -3266,6 +3266,46 @@ int FindMaxProfitIndex(
return result;
}
//
int FindMinProfitIndex(
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 ExtractInProfitPositions(
XPosition &positions[], // Position Collection
@@ -3324,6 +3364,46 @@ int FindMaxDrawdownIndex(
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 FindMinDrawdownIndex(
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++)