This commit is contained in:
2025-05-07 23:53:37 +03:30
parent 32f895407f
commit 2ba019e1f0
5 changed files with 746 additions and 49 deletions
+45
View File
@@ -50,6 +50,17 @@ input double eaConstantRiskBalance = 0.0; // Constant Ri
input double eaConstantPercent = 0.5; // Constant Percent of Balance Per Trade
input double eaConstantBalance = 0.0; // Constant Balance for Calculations
//
// Management ...
input group "Management";
input bool eaAllowTrade = true; // Allow Trade on Signals
input bool eaAllowLongs = true; // Allow Long Trades
input bool eaAllowShorts = true; // Allow Short Trades
input int eaMaxAllowedTradesPerDay = 3; // Max Allowed Trades per Day
input int eaMaxAllowedSLsPerDay = 2; // Max Allowed SL(s) per Day
input string eaSessionStartTime = ""; // Trade Start Time
input string eaSessionEndTime = ""; // Trade End Time
//
// Alert ...
// Here we Provider All Requirements for
@@ -68,6 +79,10 @@ input bool eaReportNewMonths = false; // Report New Month
input bool eaReportNewWeeks = false; // Report New Weeks
input bool eaReportNewDays = true; // Report New Days
input bool eaReportNewHours = false; // Report New Hours
input bool eaReportTrades = true; // Report Trades
input bool eaReportSignals = true; // Report Signals
input bool eaReportProtector = true; // Report Protector Actions
input bool eaReportAfterTradesBalance = true; // Report Balance after a Trade Finished
//
// Variables, Instances ...
@@ -327,6 +342,8 @@ void OnTick()
eaSignal.time = eaConditions.time;
eaSignal.symbol = eaConditions.symbol;
eaSignal.period = eaConditions.period;
eaSignal.partialCloseOnTPLevel = eaConditions.partialCloseOnTPLevel;
eaSignal.partialCloseMultiplier = eaConditions.partialCloseMultiplier;
//
Copy(
@@ -627,6 +644,34 @@ void InitRequirements()
eaTradeManager.SetAlertPushAlerts(eaPushAlerts);
eaTradeManager.SetAlertTerminalAlerts(eaTerminalAlerts);
//
// Setting Trade Reports ...
eaTradeManager
.SetTradeReports(
eaReportTrades,
eaReportSignals,
eaReportProtector,
eaReportAfterTradesBalance //
);
//
// Setting Trade Permissions ...
eaTradeManager
.SetTradePermissions(
eaAllowTrade,
eaAllowLongs,
eaAllowShorts //
);
//
//
//
//
// eaMaxAllowedTradesPerDay
// eaMaxAllowedSLsPerDay
// eaSessionStartTime
// eaSessionEndTime
//
// EA Signaller ...
eaSignaller = new XCXCAEASignaller(
+55 -3
View File
@@ -952,6 +952,32 @@ struct XPosition
}
}
//
// Calculate Touched Reward ...
double CalculateTouchedReward()
{
//
double result = 0.0;
//
bool has = IsValid() &&
profit > 0;
if (!has)
{
return result;
}
//
double risk = MathAbs(entry - sl);
double currentReward = MathAbs(price - entry);
//
result = currentReward / risk;
//
return result;
}
//
// Calculate Age ...
int GetAge(
@@ -1111,6 +1137,7 @@ struct XSignal
//
// TP ...
double fullTPLevel; // Full TP ...
bool isPartiallyClosed; // Check Partially Closed Before or not ...
double partialCloseMultiplier; // Amount of Partial Close ...
double partialCloseOnTPLevel; // Do Partial Close on TP Level ...
@@ -1697,6 +1724,7 @@ struct XSignal
fullTPLevel = 0;
tpLevelForBreakEven = 0;
partialCloseOnTPLevel = 0;
isPartiallyClosed = false;
partialCloseMultiplier = 0;
trailSLStartOnReachTPLevel = 0;
@@ -1709,7 +1737,8 @@ struct XSignal
//
// Default Values ...
void Default() {
void Default()
{
//
entry = 0;
volume = 0;
@@ -1739,6 +1768,7 @@ struct XSignal
//
fullTPLevel = 0;
tpLevelForBreakEven = 0;
isPartiallyClosed = false;
partialCloseOnTPLevel = 0;
partialCloseMultiplier = 0;
trailSLStartOnReachTPLevel = 0;
@@ -2029,7 +2059,8 @@ struct XSignal
}
//
bool IsSameAs(XSignal &item) {
bool IsSameAs(XSignal &item)
{
//
bool result = false;
@@ -2054,6 +2085,28 @@ struct XSignal
//
return result;
}
//
string GetMessage()
{
//
string result = NULL;
//
if (!IsValid())
{
return result;
}
//
result = ToString(type) +
" Signal Provided by: " + provider +
" on (" + symbol + ")" +
" in: " + ToString(period);
//
return result;
}
};
//
@@ -5239,7 +5292,6 @@ bool IsStateFilterPassed(
//
//
//
// Calculate Positions Profit Summary ...
+277 -3
View File
@@ -319,6 +319,17 @@ class XCXCAEATradeManager : public XCBaseAlert
drawSignal = true;
drawer = new XCPOIDrawer();
//
allowTrade = true;
allowLongs = true;
allowShorts = true;
//
reportTrades = true;
reportSignals = true;
reportProtector = true;
reportAfterTradesBalance = true;
//
SaveTrades(false);
@@ -362,6 +373,52 @@ class XCXCAEATradeManager : public XCBaseAlert
mSaveTrades = value;
}
//
// TODO: Implement this ...
void SetTradeSession(
string start,
string end //
)
{
//
bool has = IsValid(start) ||
IsValid(end);
if (!has)
{
return;
}
//
}
//
void SetTradeReports(
bool _reportTrades,
bool _reportSignals,
bool _reportProtector,
bool _reportAfterTradesBalance //
)
{
//
reportTrades = _reportTrades;
reportSignals = _reportSignals;
reportProtector = _reportProtector;
reportAfterTradesBalance = _reportAfterTradesBalance;
}
//
void SetTradePermissions(
bool _allowTrade,
bool _allowLongs,
bool _allowShorts //
)
{
//
allowTrade = _allowTrade;
allowLongs = _allowLongs;
allowShorts = _allowShorts;
}
//
// Tools ...
@@ -543,6 +600,7 @@ class XCXCAEATradeManager : public XCBaseAlert
if (iPosition.profit > 0)
{
//
// Handle Risk Free On Targets ...
double targets[];
Copy(
trades[idx].signal.targets,
@@ -624,13 +682,148 @@ class XCXCAEATradeManager : public XCBaseAlert
ToString(iPosition.ticket) +
" RF On Traget: " + ToString(jTarget) +
" Successfully ...";
HandleReportProtector(message);
}
}
}
}
//
// Handle Partial Close on Specified Targets ...
has = !trades[idx].signal.isPartiallyClosed &&
trades[idx].signal.partialCloseOnTPLevel > 0 &&
trades[idx].signal.partialCloseMultiplier > 0;
if (has)
{
//
// Check Reward Touched ...
double iCurrReward = iPosition.CalculateTouchedReward();
has = iCurrReward >= trades[idx].signal.partialCloseOnTPLevel;
if (has)
{
//
// Check Volume Multiplier ...
double volumeMultiplier = trades[idx].signal.partialCloseMultiplier;
has = volumeMultiplier > 0 &&
volumeMultiplier <= 1;
if (has)
{
//
// Do Partial Closing ...
double volume = iPosition.volume * volumeMultiplier;
string comment = "PC On Target ...";
has = trader.ClosePartial(
iPosition.ticket,
volume,
comment //
);
if (has)
{
//
// Update Model ...
trades[idx].signal.isPartiallyClosed = true;
//
string message = prefix +
ToString(iPosition.type) +
" Position: " +
ToString(iPosition.ticket) +
" PC (" + ToString(volume) + ") On Traget: " + ToString(iCurrReward) +
" Successfully ...";
HandleReportProtector(message);
}
}
}
}
}
}
}
/**
* Check Signal Execution Conditions ...
*
* @param signal: XSignal instance reference ...
* @param executionResult: ENUM_X_SIGNAL_EXECUTION_RESULT member reference ...
*
* @return ( bool )
*/
bool CheckSignal(
XSignal &signal,
ENUM_X_SIGNAL_EXECUTION_RESULT &executionResult //
)
{
//
bool result = false;
//
// Cleanup ...
executionResult = X_SIGNAL_EXECUTION_UNKNOWN;
//
// Validate Signal ...
result = signal.IsValid();
if (!result)
{
return result;
}
//
// Reporting Signal ...
if (reportSignals)
{
//
string message = signal.GetMessage();
Alert(message);
}
//
// Check Trade Permission ...
if (!allowTrade)
{
//
result = false;
executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED;
//
return result;
}
//
bool isLong = IsLong(signal.type);
bool isShort = IsShort(signal.type);
//
bool isLongAndAllowed =
isLong &&
allowLongs;
//
bool isShortAndAllowed =
isShort &&
allowShorts;
//
result = isLongAndAllowed ||
isShortAndAllowed;
if (!result)
{
//
executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED;
//
return result;
}
}
}
}
//
// TODO: Complete this ...
// Implementing Trade Session Validating ...
//
// TODO: Complete this ...
// Implementing Trade Permissions Based on SL(s) Count ...
//
return result;
}
/**
@@ -670,15 +863,30 @@ class XCXCAEATradeManager : public XCBaseAlert
//
ENUM_X_SIGNAL_EXECUTION_RESULT executionResult;
//
// Checking Signal For Execution ...
result = CheckSignal(
signal,
executionResult //
);
if (result)
{
//
result = trader.ExecuteSignal(
signal,
executionResult //
);
}
//
// Alert Signal Execution ...
if (reportTrades)
{
//
string executionMessage = ToString(executionResult);
Alert(executionMessage);
}
//
if (result)
@@ -762,6 +970,11 @@ class XCXCAEATradeManager : public XCBaseAlert
// Save Trade ...
Save(trades[idx]);
//
// Handle Balance Reporting ...
string prefix = "TP: " + ToString(trades[idx].profit);
HandleReportBalance(prefix);
//
RemoveTrade(idx);
}
@@ -800,6 +1013,11 @@ class XCXCAEATradeManager : public XCBaseAlert
// Save Trade ...
Save(trades[idx]);
//
// Handle Balance Reporting ...
string prefix = "SL: " + ToString(trades[idx].profit);
HandleReportBalance(prefix);
//
RemoveTrade(idx);
}
@@ -854,6 +1072,16 @@ class XCXCAEATradeManager : public XCBaseAlert
// Save Trade ...
Save(trades[idx]);
//
// Handle Balance Reporting ...
string prefix = "Force Close " +
(isInProfit
? "Profit"
: "Loss") +
": " +
ToString(trades[idx].profit);
HandleReportBalance(prefix);
//
RemoveTrade(idx);
}
@@ -1045,6 +1273,41 @@ class XCXCAEATradeManager : public XCBaseAlert
return result;
}
//
void HandleReportBalance(string prefix = NULL)
{
//
if (!reportAfterTradesBalance)
{
return;
}
//
double balance = trader.mAccount.GetBalance();
string currency = trader.mAccount.GetCurrency();
//
string message =
(IsValid(prefix)
? prefix + "\n"
: "") +
"Account Balance: " + ToString(balance) + currency;
Alert(message);
}
//
void HandleReportProtector(string message = NULL)
{
//
if (!reportProtector)
{
return;
}
//
Alert(message);
}
//
bool Save(
XCAEATrade &trade,
@@ -1093,6 +1356,11 @@ class XCXCAEATradeManager : public XCBaseAlert
//
// Props ...
//
bool allowTrade;
bool allowLongs;
bool allowShorts;
//
bool mSaveTrades;
@@ -1104,6 +1372,12 @@ class XCXCAEATradeManager : public XCBaseAlert
int managedSLCount;
int managedTPCount;
//
bool reportTrades;
bool reportSignals;
bool reportProtector;
bool reportAfterTradesBalance;
//
CArrayObj mObjects;
+310 -15
View File
@@ -79,6 +79,10 @@ struct XCAEAStrategyConditions
datetime setupTime;
datetime triggerTime;
//
double partialCloseOnTPLevel;
double partialCloseMultiplier;
//
ENUM_X_DIRECTION dir;
XBoxZone decisionZone;
@@ -118,6 +122,10 @@ struct XCAEAStrategyConditions
setupTime = NULL;
triggerTime = NULL;
//
partialCloseOnTPLevel = 0;
partialCloseMultiplier = 0;
//
Clean(targets);
@@ -711,6 +719,14 @@ bool DetectDecisionZone(
double p2FastState = conditions.fastStateBuffer[p2IDX];
double p3FastState = conditions.fastStateBuffer[p3IDX];
//
// RSI ...
double zRSI = conditions.rsiBuffer[zIDX];
double cRSI = conditions.rsiBuffer[cIDX];
double pRSI = conditions.rsiBuffer[pIDX];
double p2RSI = conditions.rsiBuffer[p2IDX];
double p3RSI = conditions.rsiBuffer[p3IDX];
//
// Create Custom Conditions ...
@@ -912,7 +928,19 @@ bool DetectDecisionZone(
bool isSarSwitchedToBearish =
cFastState < 0 &&
isSarSwitchedInFiboStrongBearish;
;
//
// RSI Conditions ...
//
bool isRSICrossedOverOS =
p3RSI < conditions.rsiOSLevel &&
cRSI > conditions.rsiOSLevel;
//
bool isRSICrossedUnderOB =
p3RSI > conditions.rsiOBLevel &&
cRSI < conditions.rsiOBLevel;
//
// Testing Conditions ...
@@ -1047,12 +1075,14 @@ bool DetectDecisionZone(
//
bool isCond1Bullish =
isCIsValePivot &&
isRSICrossedOverOS &&
!isFiboSectionChanged &&
isSarSwitchedToBullish;
//
bool isCond1Bearish =
isCIsPeakPivot &&
isRSICrossedUnderOB &&
!isFiboSectionChanged &&
isSarSwitchedToBearish;
@@ -1167,18 +1197,12 @@ bool DetectDecisionZone(
}
//
bool isCond2 =
(cPeak == pPeak &&
cPeak == cSWH &&
cPeak == cResistance) &&
(cVale == pVale &&
cVale == cSWL &&
cVale == cSupport);
if (isCond2)
{
//
Print("Decision Zone Full Cond1");
}
// bool isCond2 = isFiboSectionChanged;
// if (isCond2)
// {
// //
// Print("Decision Zone Full Cond1");
// }
//
// Summarise Result ...
@@ -1232,6 +1256,275 @@ bool DetectDecisionZone(
//
// Trigger Conditions ...
//
// Detect Trigger Based On Decision Zone's
// Volume and Score ...
bool CanTriggerCond0(
XCXCAEAHelper *helper,
XBoxZone &box,
ENUM_X_DIRECTION &dir,
double &sl,
double &tp,
int barIndex = 0,
int loopback = 5,
double scorePassMultiplier = 1 //
)
{
//
bool result = false;
//
// Normalize Args ...
sl = 0;
tp = 0;
dir = X_DIRECTION_NONE;
loopback = NormalizeInt(loopback, 5);
barIndex = NormalizeInt(barIndex, 0);
//
// Validate Decision Box ...
result = box.IsValid() &&
helper != NULL;
if (!result)
{
return result;
}
//
// Define Requirements ...
//
bool isBullish = box.IsBullish();
bool isBearish = box.IsBearish();
//
// Scores ...
double bullScores[];
double bearScores[];
//
// Volumes ...
double bullVolumes[];
double bearVolumes[];
//
// Create a Loop through Loopack ...
XOHCL iBar;
bool has = false;
int start = barIndex;
XCAEAConditions iConditions;
int end = barIndex + loopback;
for (int i = end; i >= start; i--)
{
//
// Retrieve Bar ...
has = iBar.Init(
box.symbol,
box.period,
i //
);
if (!has)
{
//
iBar.Clean();
iConditions.Clean();
//
continue;
}
//
// Retrieve Conditions ...
has = helper.GetConditions(
iConditions,
i //
);
if (!has)
{
//
iBar.Clean();
iConditions.Clean();
//
continue;
}
//
// Retrieve Scores ...
double iBullScore = 0;
double iBearScore = 0;
iConditions
.GenerateScore(
iBullScore,
iBearScore //
);
Add(
iBullScore,
bullScores //
);
Add(
iBearScore,
bearScores //
);
//
// Retrieve Volumes ...
double iBullVolume = 0;
double iBearVolume = 0;
helper
.barAnalyser
.CalculateRangeVolume(
iBar,
iBullVolume,
iBearVolume,
2 // Loopback ...
);
Add(
iBullVolume,
bullVolumes //
);
Add(
iBearVolume,
bearVolumes //
);
//
iBar.Clean();
iConditions.Clean();
}
//
// Calculating Requirements ...
//
// Scores ...
//
// Bullish ...
double bullScore = GetSum(bullScores);
double bullScoreMax = GetMax(bullScores);
double bullScoreMin = GetMin(bullScores);
//
// Bearish ...
double bearScore = GetSum(bearScores);
double bearScoreMax = GetMax(bearScores);
double bearScoreMin = GetMin(bearScores);
//
// Volumes ...
//
// Bullish ...
double bullVolume = GetSum(bullVolumes);
double bullVolumeMax = GetMax(bullVolumes);
double bullVolumeMin = GetMin(bullVolumes);
//
// Bearish ...
double bearVolume = GetSum(bearVolumes);
double bearVolumeMax = GetMax(bearVolumes);
double bearVolumeMin = GetMin(bearVolumes);
//
// Creating Result Conditions ...
//
bool isBullishPassed =
isBullish &&
bullScore >= (scorePassMultiplier * bearScore) &&
bullVolume >= (scorePassMultiplier * bearVolume);
//
bool isBearishPassed =
isBearish &&
bearScore >= (scorePassMultiplier * bullScore) &&
bearVolume >= (scorePassMultiplier * bullVolume);
//
result = isBullishPassed ||
isBearishPassed;
if (!result)
{
//
iBar.Clean();
Clean(bullScores);
Clean(bearScores);
Clean(bullVolumes);
Clean(bearVolumes);
iConditions.Clean();
//
return result;
}
//
// Validating Box to Find a Rejection ...
//
// Validating Box to Has a Gap ...
//
// Validating Box to Has a Block ...
//
bool isPassed =
isBullishPassed ||
isBearishPassed;
if (isPassed)
{
//
// Preparing TP and SL ...
//
sl = isBullishPassed
? box.lower
: box.upper;
//
tp = 0;
}
//
// Summarizing ...
//
bool canTriggerLong =
isBullishPassed;
//
bool canTriggerShort =
isBearishPassed;
//
result = canTriggerLong ||
canTriggerShort;
if (result)
{
//
dir = canTriggerLong
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
Print("Triggered ...");
}
//
// Cleanup Resources ...
//
iBar.Clean();
Clean(bullScores);
Clean(bearScores);
Clean(bullVolumes);
Clean(bearVolumes);
iConditions.Clean();
//
return result;
}
//
// Detect Trigger Based On Decision Zone's
// Fake Breaked out ...
@@ -1258,7 +1551,8 @@ bool CanTriggerCond1(
//
// Validate Decision Box ...
result = box.IsValid();
result = box.IsValid() &&
helper != NULL;
if (!result)
{
return result;
@@ -1373,7 +1667,8 @@ bool CanTriggerCond2(
//
// Validate Decision Box ...
result = box.IsValid();
result = box.IsValid() &&
helper != NULL;
if (!result)
{
return result;
+51 -20
View File
@@ -139,8 +139,8 @@ class XCXCAEASignaller : XCBase
inputs.caInputs.showPeaksAndVales = true;
//
inputs.caInputs.showKI = false;
inputs.caInputs.showTKI = false;
inputs.caInputs.showKI = true;
inputs.caInputs.showTKI = true;
inputs.caInputs.showVidya = true;
inputs.caInputs.showTrend = true;
inputs.caInputs.showPeakAndValeGolden = false;
@@ -159,7 +159,7 @@ class XCXCAEASignaller : XCBase
//
// Oscillators Views ...
inputs.showRSI = false;
inputs.showRSI = true;
inputs.showCCI = false;
inputs.showMFI = false;
inputs.showRVI = false;
@@ -602,29 +602,42 @@ class XCXCAEASignaller : XCBase
// Checking Trigger Conditions ...
double sl = 0;
double tp = 0;
ENUM_X_DIRECTION triggerDir;
ENUM_X_DIRECTION triggerDir = X_DIRECTION_NONE;
//
// Checking Trigger Cond 0 ...
bool canTriggerCond0 = CanTriggerCond0(
helper,
conditions.decisionZone,
triggerDir,
sl,
tp,
barIndex //
);
//
// Checking Trigger Cond 1 ...
bool canTriggerCond1 = CanTriggerCond1(
helper,
conditions.decisionZone,
triggerDir,
sl,
tp,
barIndex //
);
bool canTriggerCond1 = false;
// CanTriggerCond1(
// helper,
// conditions.decisionZone,
// triggerDir,
// sl,
// tp,
// barIndex //
// );
//
// Checking Trigger Cond 2 ...
bool canTriggerCond2 = CanTriggerCond2(
helper,
conditions.decisionZone,
triggerDir,
sl,
tp,
barIndex //
);
bool canTriggerCond2 = false;
// CanTriggerCond2(
// helper,
// conditions.decisionZone,
// triggerDir,
// sl,
// tp,
// barIndex //
// );
//
// Update Signal Box To ...
@@ -645,6 +658,7 @@ class XCXCAEASignaller : XCBase
//
// Summarizing Result ...
result =
canTriggerCond0 ||
canTriggerCond1 ||
canTriggerCond2;
@@ -655,6 +669,7 @@ class XCXCAEASignaller : XCBase
IsBearish(triggerDir);
//
// Configure Conditions for Preparing Signal ...
if (result)
{
//
@@ -697,6 +712,22 @@ class XCXCAEASignaller : XCBase
conditions.targets //
);
//
rfReward = risk * 2.85;
rfPrice =
isBullish
? entry + rfReward
: entry - rfReward;
Add(
rfPrice,
conditions.targets //
);
//
// Handling Partial Close ...
conditions.partialCloseOnTPLevel = 1;
conditions.partialCloseMultiplier = 0.5;
//
conditions.sl = sl;
conditions.tp = tp;