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_XASCT = 16,
PROVIDER_XVLM = 17, PROVIDER_XVLM = 17,
PROVIDER_XPVF = 18, PROVIDER_XPVF = 18,
PROVIDER_XPVSAR = 19,
}; };
// //
@@ -197,6 +198,10 @@ ENUM_X121_SIGNAL_PROVIDER FromString(string value)
{ {
result = PROVIDER_XPVF; result = PROVIDER_XPVF;
} }
else if (Contains(value, (EnumToString(PROVIDER_XPVSAR))))
{
result = PROVIDER_XPVSAR;
}
// //
return result; return result;
@@ -1422,6 +1427,24 @@ struct X121SignalGenerator
provider = ToString(PROVIDER_XPVF); 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 = result =
// //
@@ -1500,6 +1523,10 @@ struct X121SignalGenerator
// //
long18 long18
// //
||
//
long19
//
) )
// //
; ;
@@ -2068,6 +2095,24 @@ struct X121SignalGenerator
provider = ToString(PROVIDER_XPVF); 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 = result =
// //
@@ -2146,6 +2191,10 @@ struct X121SignalGenerator
// //
short18 short18
// //
||
//
short19
//
) )
// //
; ;
+299 -29
View File
@@ -2825,6 +2825,25 @@ public:
mAllowShort = value; mAllowShort = value;
} }
//
int DelayBetweenTwoSignal()
{
return mDelayBetweenTwoSignal;
}
//
void DelayBetweenTwoSignal(int value)
{
//
if (value < 0)
{
value = 0;
}
//
mDelayBetweenTwoSignal = value;
}
// //
int ReuiredSignalVerifications() int ReuiredSignalVerifications()
{ {
@@ -3318,6 +3337,44 @@ public:
mForceCloseProfit = value; 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() bool ForceState()
{ {
@@ -3349,6 +3406,18 @@ public:
// //
// Tools ... // Tools ...
//
double GetBullishScore()
{
return mBullishScore;
}
//
double GetBearishScore()
{
return mBearishScore;
}
// //
// Check Provider for any Guards ... // Check Provider for any Guards ...
bool CheckForGuard(XGuard &guards[]) override bool CheckForGuard(XGuard &guards[]) override
@@ -4187,10 +4256,18 @@ public:
if (isSignalValid) if (isSignalValid)
{ {
// //
AddRef( // Check Delay Between Two Signals ...
iSignal, bool isDelayPassed = IsSignalDelayPassed(iSignal);
eSignals //
); //
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 ...
private: private:
@@ -4446,7 +4579,10 @@ private:
// - Receive Signals with minimal Verifications; // - Receive Signals with minimal Verifications;
// - Increase Volume Size of in Profit Positions; // - Increase Volume Size of in Profit Positions;
// - etc ... // - 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 XTradeHandler *mTradeHandler; // Handle all Event which related to Signals and Positions
@@ -4641,10 +4777,8 @@ private:
} }
// //
double profit = SpecifiedIsPositionsReadyForHedge( double profit = SpecifiedCalculatePositionsProfit(
positions, positions //
0.15,
0.01 //
); );
result = result =
profit > hedgingProfit; profit > hedgingProfit;
@@ -4761,30 +4895,158 @@ private:
return; return;
} }
//
double profits = SpecifiedCalculatePositionsProfit(positionsCount);
// //
// Checking Force Sate Conditions ... // Checking Force Sate Conditions ...
if (ForceState()) if (ForceState())
{ {
// //
// Check Force State Hedging ... // Check Force State Hedging ...
// bool isHedged = DoEQMForceClose(); bool isHedged = DoEQMForceClose();
// if (isHedged) if (isHedged)
// { {
// // //
// ForceState(false); ForceState(false);
// return; return;
// } }
// // //
// isHedged = DoEQMForceClose(5); // Handle Act Based On Drawdow ...
// if (isHedged) if (mMaxDrawdownForce > 0)
// { {
// // //
// ForceState(false); double drawdown = GetDrawdownPercent();
// return; 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; return;
} }
@@ -4905,10 +5167,18 @@ private:
if (isValid) if (isValid)
{ {
// //
AddRef( // Check Delay Between Two Signals ...
signal, bool isDelayPassed = IsSignalDelayPassed(signal);
signals //
); //
if (isDelayPassed)
{
//
AddRef(
signal,
signals //
);
}
} }
// //
+4 -4
View File
@@ -39,6 +39,10 @@ public:
// //
// Props ... // Props ...
//
// Trade Class Instance ...
XSCTrade *mTrader;
// //
// Constructor ... // Constructor ...
XSCBaseEA( XSCBaseEA(
@@ -580,10 +584,6 @@ protected:
// //
// Props ... // Props ...
//
// Trade Class Instance ...
XSCTrade *mTrader;
// //
// Check in Test Mode or not ... // Check in Test Mode or not ...
bool mIsInTestMode; bool mIsInTestMode;
+164 -23
View File
@@ -46,6 +46,7 @@ input bool x121EAUseAllSymbols = false;
input bool x121EAUseAllWatchListSymbols = false; // Use All WatchList Symbols input bool x121EAUseAllWatchListSymbols = false; // Use All WatchList Symbols
input bool x121EAAllowLong = true; // Allow Long Trades input bool x121EAAllowLong = true; // Allow Long Trades
input bool x121EAAllowShort = true; // Allow Short 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 int x121EAReuiredSignalVerifications = 5; // Required Verifications for Signals
input bool x121EAGetVerificationFromOtherTimeFrames = true; // Get Verifications from Other Time Frames 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 group "Hedging";
input int x121EARestingAfterHedge = 0; // Resting Seconds After Hedge 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 x121EAMinRequiredProfitPerTrade = 0.5; // Minimum Required Profit for Hedging
input double x121EAMinRequiredProfitPerVolumeFactor = 0.01; // Minimum Required Profit for Hedging Per Volume 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 ... // Alert ...
@@ -122,6 +125,7 @@ input bool x121EATerminalAlerts = false; // Terminal Alerts
// Local Variables ... // Local Variables ...
// //
string x121EAUsedSymbols[];
XSCX121SetupEA *x121EA; XSCX121SetupEA *x121EA;
// //
@@ -170,7 +174,11 @@ void OnDeinit(const int reason)
// On Tick Handler ... // On Tick Handler ...
void OnTick() void OnTick()
{ {
//
x121EA.OnTick(); x121EA.OnTick();
//
X121ReportState();
} }
// //
@@ -206,13 +214,13 @@ bool InitialEA()
); );
// //
string symbols[]; Clean(x121EAUsedSymbols);
if (x121EAUseAllSymbols) if (x121EAUseAllSymbols)
{ {
// //
Copy( Copy(
allSymbols, allSymbols,
symbols // x121EAUsedSymbols //
); );
} }
else if (x121EAUseAllWatchListSymbols) else if (x121EAUseAllWatchListSymbols)
@@ -220,7 +228,7 @@ bool InitialEA()
// //
Copy( Copy(
watchListSymbols, watchListSymbols,
symbols // x121EAUsedSymbols //
); );
} }
else if (IsValidSize(inputSymbolsCount)) else if (IsValidSize(inputSymbolsCount))
@@ -228,7 +236,7 @@ bool InitialEA()
// //
Copy( Copy(
inputSymbols, inputSymbols,
symbols // x121EAUsedSymbols //
); );
} }
else else
@@ -236,10 +244,10 @@ bool InitialEA()
// //
Add( Add(
_Symbol, _Symbol,
symbols // x121EAUsedSymbols //
); );
} }
int symbolsCount = ArraySize(symbols); int symbolsCount = ArraySize(x121EAUsedSymbols);
result = IsValidSize(symbolsCount); result = IsValidSize(symbolsCount);
if (!result) if (!result)
{ {
@@ -259,6 +267,7 @@ bool InitialEA()
// Signals ... // Signals ...
x121EA.AllowLong(x121EAAllowLong); x121EA.AllowLong(x121EAAllowLong);
x121EA.AllowShort(x121EAAllowShort); x121EA.AllowShort(x121EAAllowShort);
x121EA.DelayBetweenTwoSignal(x121EADelayBetweenTwoSignal);
x121EA.ReuiredSignalVerifications(x121EAReuiredSignalVerifications); x121EA.ReuiredSignalVerifications(x121EAReuiredSignalVerifications);
x121EA.GetVerificationFromOtherTimeFrames(x121EAGetVerificationFromOtherTimeFrames); x121EA.GetVerificationFromOtherTimeFrames(x121EAGetVerificationFromOtherTimeFrames);
@@ -317,6 +326,8 @@ bool InitialEA()
// Hedging ... // Hedging ...
x121EA.ForceCloseProfit(x121EAForceCloseProfit); x121EA.ForceCloseProfit(x121EAForceCloseProfit);
x121EA.RestingAfterHedge(x121EARestingAfterHedge); x121EA.RestingAfterHedge(x121EARestingAfterHedge);
x121EA.MaxDrawdownForce(x121EAMaxDrawdownForce);
x121EA.MaxPositionsForce(x121EAMaxPositionsForce);
x121EA.MinRequiredProfitPerTrade(x121EAMinRequiredProfitPerTrade); x121EA.MinRequiredProfitPerTrade(x121EAMinRequiredProfitPerTrade);
x121EA.MinRequiredProfitPerVolumeFactor(x121EAMinRequiredProfitPerVolumeFactor); x121EA.MinRequiredProfitPerVolumeFactor(x121EAMinRequiredProfitPerVolumeFactor);
@@ -333,7 +344,7 @@ bool InitialEA()
// Configure Indicators ... // Configure Indicators ...
X121SetupInputs setupInputsDefault; X121SetupInputs setupInputsDefault;
setupInputsDefault.Default(); setupInputsDefault.Default();
PreConfigureStyles(setupInputsDefault); X121PreConfigureStyles(setupInputsDefault);
// //
// Prepare Providers and Add them into mX121EA class ... // Prepare Providers and Add them into mX121EA class ...
@@ -341,7 +352,7 @@ bool InitialEA()
{ {
// //
// Requirements ... // Requirements ...
string iSymbol = symbols[i]; string iSymbol = x121EAUsedSymbols[i];
ENUM_TIMEFRAMES iHostPeriod = _Period; ENUM_TIMEFRAMES iHostPeriod = _Period;
// //
@@ -370,25 +381,25 @@ bool InitialEA()
} }
// //
void PreConfigureStyles(X121SetupInputs &inputs) void X121PreConfigureStyles(X121SetupInputs &inputs)
{ {
// //
// XPV ... // XPV ...
inputs.pvInputs.showPeaksAndVales = true; inputs.pvInputs.showPeaksAndVales = false;
inputs.pvInputs.showLevels = false; inputs.pvInputs.showLevels = false;
inputs.pvInputs.showConsolidations = false; inputs.pvInputs.showConsolidations = false;
inputs.pvInputs.showFibo1Levels = true; inputs.pvInputs.showFibo1Levels = false;
inputs.pvInputs.showFibo2Levels = true; inputs.pvInputs.showFibo2Levels = false;
inputs.pvInputs.showFibo3Levels = true; inputs.pvInputs.showFibo3Levels = false;
inputs.pvInputs.showFibo4Levels = true; inputs.pvInputs.showFibo4Levels = false;
inputs.pvInputs.showFibo5Levels = true; inputs.pvInputs.showFibo5Levels = false;
// //
// XMC ... // XMC ...
inputs.mcInputs.showSar = true; inputs.mcInputs.showSar = false;
inputs.mcInputs.showFastMa = true; inputs.mcInputs.showFastMa = false;
inputs.mcInputs.showSlowMa = true; inputs.mcInputs.showSlowMa = false;
inputs.mcInputs.showVerifierMa = true; inputs.mcInputs.showVerifierMa = false;
// //
// XHK ... // XHK ...
@@ -398,9 +409,9 @@ void PreConfigureStyles(X121SetupInputs &inputs)
// //
// XCHE ... // XCHE ...
inputs.cheInputs.showLongExit1Line = false; inputs.cheInputs.showLongExit1Line = false;
inputs.cheInputs.showShortExit1Line = true; inputs.cheInputs.showShortExit1Line = false;
inputs.cheInputs.showLongExit2Line = false; inputs.cheInputs.showLongExit2Line = false;
inputs.cheInputs.showShortExit2Line = true; inputs.cheInputs.showShortExit2Line = false;
// //
// XICH ... // XICH ...
@@ -415,7 +426,7 @@ void PreConfigureStyles(X121SetupInputs &inputs)
// //
// XSTR ... // XSTR ...
inputs.strInputs.showTrends = true; inputs.strInputs.showTrends = false;
inputs.strInputs.fillTrends = 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; 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( int ExtractInProfitPositions(
XPosition &positions[], // Position Collection XPosition &positions[], // Position Collection
@@ -3324,6 +3364,46 @@ int FindMaxDrawdownIndex(
return result; 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; double min = 0;
for (int i = 0; i < positionsCount; i++) for (int i = 0; i < positionsCount; i++)