apply signaller's Policies in EA signal manager before Execute Signals ...

This commit is contained in:
2024-06-05 06:25:20 +03:30
parent 00631650dc
commit 6b05f48cde
8 changed files with 447 additions and 15 deletions
@@ -1778,6 +1778,57 @@ struct X121ProviderDescriptor
// //
return result; return result;
} }
//
// Find Specific Signaller Index ...
int FindSignallerIndex(ENUM_XSIGNAL_PROVIDERS name)
{
//
int result = -1;
//
// Converts Provided Signaller Name to String ...
string strName = ToString(name);
//
result = FindSignallerIndex(strName);
//
return result;
}
//
// Find Specific Signaller Index ...
int FindSignallerIndex(string name)
{
//
int result = -1;
//
int signallersCount = ArraySize(signallers);
if (!IsValid() ||
!IsValid(name) ||
!IsValidSize(signallersCount) ||
name == ToString(PROVIDER_NONE))
{
return result;
}
//
for (int i = 0; i < signallersCount; i++)
{
//
if (signallers[i].GetName() == name)
{
//
result = i;
break;
}
}
//
return result;
}
}; };
// //
+230
View File
@@ -272,6 +272,236 @@ public:
return false; return false;
} }
//
// Here we Manage Signals for Executing ...
// - Check Policies based on their Signaller ...
// - Check Same Time Open Positions ...
// - Check Signal Age for new Trade ...
// and etc ...
int HandleSignalManagement(XSignal &signals[])
{
//
int result = 0;
//
int signalsCount = ArraySize(signals);
if (!IsValidSize(signalsCount))
{
return result;
}
//
XSignal tmpSignals[];
Copy(
signals,
tmpSignals //
);
//
Clean(signals);
//
for (int i = 0; i < signalsCount; i++)
{
//
XSignal iSignal = tmpSignals[i];
//
// Find Provider Descriptor Which Issued this Signal ...
int iProviderIDX = FindDescriptorIndex(
iSignal.symbol,
iSignal.period);
if (!IsValidIndex(iProviderIDX))
{
//
string message = "Couldn't find Signal Descriptor ...";
Log(message);
//
continue;
}
//
// Now we Have to Find Signaller Which Issued this Signal ...
int iSignallerIDX = mDescriptors[iProviderIDX]
.FindSignallerIndex(iSignal.provider);
if (!IsValidIndex(iSignallerIDX))
{
//
string message = "Couldn't find Signal Provider ...";
Log(message);
//
continue;
}
//
// Check Position Type is Enabled or not ...
bool isLong = IsLong(iSignal.type);
bool isAllowedType = isLong
? mDescriptors[iProviderIDX].signallers[iSignallerIDX].allowLong
: mDescriptors[iProviderIDX].signallers[iSignallerIDX].allowShort;
if (!isAllowedType)
{
//
string message = "ignore Signal due Type Policy ...";
Log(message);
//
continue;
}
//
// Retrieve Long and Short Signals of same Provider ...
XPosition longs[];
XPosition shorts[];
mTrader.GetPositions(
longs,
shorts,
iSignal.symbol,
iSignal.provider,
iSignal.period //
);
int longsCount = ArraySize(longs);
int shortsCount = ArraySize(shorts);
//
// Check Max Number of Positions ...
bool isMaxNumberOfPositionsPassed = isLong
? mDescriptors[iProviderIDX].signallers[iSignallerIDX].maxAllowedLong <= 0
? true
: longsCount < mDescriptors[iProviderIDX].signallers[iSignallerIDX].maxAllowedLong
: mDescriptors[iProviderIDX].signallers[iSignallerIDX].maxAllowedShort <= 0
? true
: shortsCount < mDescriptors[iProviderIDX].signallers[iSignallerIDX].maxAllowedShort;
if (!isMaxNumberOfPositionsPassed)
{
//
string message = "ignore Signal due Max Allowed Positions Reached ...";
Log(message);
//
continue;
}
//
// Check Delay Between Two Same Type Signals ...
// Check Open Next Behaviour ...
if (longsCount > 0 || shortsCount > 0)
{
//
// Check if Signaller Configured for Check Delay between Same type Signals ...
if (mDescriptors[iProviderIDX].signallers[iSignallerIDX].delayBetweenTwoSameTypeSignals > 0)
{
//
bool isDelayPassed = true;
//
if (longsCount > 0)
{
//
XPosition youngestLong;
int youngestLongAge = GetYoungest(
youngestLong,
longs //
);
//
if (isLong)
{
isDelayPassed = youngestLongAge >= mDescriptors[iProviderIDX].signallers[iSignallerIDX].delayBetweenTwoSameTypeSignals;
}
}
//
if (shortsCount > 0)
{
//
XPosition youngestShort;
int youngetsShortAge = GetYoungest(
youngestShort,
shorts //
);
//
if (!isLong)
{
isDelayPassed = youngetsShortAge >= mDescriptors[iProviderIDX].signallers[iSignallerIDX].delayBetweenTwoSameTypeSignals;
}
}
//
if (!isDelayPassed)
{
//
string message = "ignore Signal due Delay Between Same Type Policy ...";
Log(message);
//
continue;
}
}
//
// Check Next Position ...
if (mDescriptors[iProviderIDX].signallers[iSignallerIDX].openNextPositionOnProfit)
{
//
bool isNextPassed = true;
//
if (isLong && longsCount > 0)
{
//
double profit = SpecifiedCalculatePositionsProfit(longs);
isNextPassed = profit > 0;
}
//
if (!isLong && shortsCount > 0)
{
//
double profit = SpecifiedCalculatePositionsProfit(shorts);
isNextPassed = profit > 0;
}
//
// Check Ignore for Opposit Signals ...
if (!isNextPassed &&
((isLong && shortsCount > longsCount) ||
(!isLong && longsCount > shortsCount)))
{
isNextPassed = mDescriptors[iProviderIDX].signallers[iSignallerIDX].ignoreProfitForOppositeSignals;
}
//
if (!isNextPassed)
{
//
string message = "ignore Signal due Next Must be In Profit Policy ...";
Log(message);
//
continue;
}
}
}
//
// Finally Add Filtered Signals into Result ...
AddRef(
iSignal,
signals //
);
}
//
result = ArraySize(signals);
//
return result;
}
// //
// Tools ... // Tools ...
+58 -6
View File
@@ -2537,18 +2537,36 @@ public:
// Props ... // Props ...
// //
ENUM_XSIGNAL_PROVIDERS name; ENUM_XSIGNAL_PROVIDERS name; // Signaller Name
// //
bool allowLong; bool allowLong; // Allow Long Positions
bool allowShort; bool allowShort; // Allow Short Positions
// //
double r2r; double r2r; // Risk To Reward Ratio
//
double staticVolumeLong; // Static Volume for Long
double staticVolumeShort; // Static Volume For Short
//
int maxAllowedLong; // Max Allowed Same Time Long Open Positions
int maxAllowedShort; // Max Allowed Same Time Short Open Positions
//
int delayBetweenTwoSameTypeSignals; // Delay between Two Same Type Signals
int maxAllowedOpenPositionAge; // Close Position if Still Alive bigger than this value
//
double minRequiredProfitPerTrade; // Minimum Required Profit Per Trade for Hedging
double minRequiredProfitPerTradeVolumeFactor; // Calculate Required Profit Based on Volume Factor for Hedging
//
bool openNextPositionOnProfit; // Open Next Signaller Position only When Previous Signals in Profit
bool ignoreProfitForOppositeSignals; // Ignore In Profit Policy when Opposite Signal Comming
// //
double staticVolumeLong;
double staticVolumeShort;
// //
// Constructor ... // Constructor ...
@@ -2576,6 +2594,20 @@ public:
// //
staticVolumeLong = 0; staticVolumeLong = 0;
staticVolumeShort = 0; staticVolumeShort = 0;
//
maxAllowedLong = 0;
maxAllowedShort = 0;
maxAllowedOpenPositionAge = 0;
delayBetweenTwoSameTypeSignals = 0;
//
minRequiredProfitPerTrade = 0;
minRequiredProfitPerTradeVolumeFactor = 0;
//
openNextPositionOnProfit = false;
ignoreProfitForOppositeSignals = false;
} }
// //
@@ -2604,11 +2636,31 @@ public:
} }
// //
// Retrieve Signaller Name as String ...
string GetName() string GetName()
{ {
return ToString(name); return ToString(name);
} }
//
// Check Hedge is Enable or Not ...
bool AllowHedge()
{
//
bool result = false;
//
result =
//
minRequiredProfitPerTrade > 0 &&
minRequiredProfitPerTradeVolumeFactor > 0
//
;
//
return result;
}
// //
// Generate Signal ... // Generate Signal ...
bool GenerateSignal( bool GenerateSignal(
+36
View File
@@ -2131,6 +2131,42 @@ public:
return mResult; return mResult;
} }
//
void GetPositions(
XPosition &longs[], // Hold's Longs Result
XPosition &shorts[], // Hold's Shorts Result
string symbol = NULL, // Trading Symbol
string provider = NULL, // Signal Provider
ENUM_TIMEFRAMES period = NULL, // Trading Period
bool filterByMagic = true, // Get Only Self Open Positions
bool forceClean = true // Clean Result Array
)
{
//
// Retrieve Long Positions ...
GetPositions(
longs,
symbol,
provider,
period,
POSITION_TYPE_BUY,
filterByMagic,
forceClean //
);
//
// Retrieve Short Positions ...
GetPositions(
shorts,
symbol,
provider,
period,
POSITION_TYPE_SELL,
filterByMagic,
forceClean //
);
}
// //
// Select In Profit Positions ... // Select In Profit Positions ...
int GetInProfitPositions( int GetInProfitPositions(
+12 -5
View File
@@ -3850,6 +3850,13 @@ bool IsValidSize(T &buffer[])
return result; return result;
} }
//
// Check a Given Index is Valid or not ...
bool IsValidIndex(int index)
{
return index >= 0;
}
// //
// Normalize Index Based On Specified Buffer ... // Normalize Index Based On Specified Buffer ...
template <typename T> template <typename T>
@@ -5776,12 +5783,12 @@ void Copy(
// Copy Items from a Buffer ... // Copy Items from a Buffer ...
template <typename T> template <typename T>
int Copy( int Copy(
int start, // Start int start, // Start
int count, // Number of Items for read int count, // Number of Items for read
T &source[], // Source Buffer T &source[], // Source Buffer
T &dest[], // Dest Buffer T &dest[], // Dest Buffer
bool forceClean = true, // Force To Clean buffer bool forceClean = true, // Force To Clean buffer
bool forceStart = true // Force To Clean buffer bool forceStart = true // Force To Clean buffer
) )
{ {
// //
@@ -307,8 +307,26 @@ public:
// //
r2r = 1; r2r = 1;
//
maxAllowedLong = 3;
maxAllowedShort = 3;
// //
staticVolumeLong = 0.01; staticVolumeLong = 0.01;
staticVolumeShort = 0.01; staticVolumeShort = 0.01;
//
maxAllowedOpenPositionAge = 576; // Two Days on 5 Min
delayBetweenTwoSameTypeSignals = 12; // 1 Hour on 5 Min
//
// Set 10 $ Per each Trade on 0.01 Volume
// is Enough for Hedging ...
minRequiredProfitPerTrade = 10;
minRequiredProfitPerTradeVolumeFactor = 0.01;
//
openNextPositionOnProfit = true;
ignoreProfitForOppositeSignals = true;
} }
}; };
@@ -181,8 +181,26 @@ public:
// //
r2r = 1; r2r = 1;
//
maxAllowedLong = 3;
maxAllowedShort = 3;
// //
staticVolumeLong = 0.01; staticVolumeLong = 0.01;
staticVolumeShort = 0.01; staticVolumeShort = 0.01;
//
maxAllowedOpenPositionAge = 576; // Two Days on 5 Min
delayBetweenTwoSameTypeSignals = 12; // 1 Hour on 5 Min
//
// Set 10 $ Per each Trade on 0.01 Volume
// is Enough for Hedging ...
minRequiredProfitPerTrade = 10;
minRequiredProfitPerTradeVolumeFactor = 0.01;
//
openNextPositionOnProfit = true;
ignoreProfitForOppositeSignals = true;
} }
}; };
+24 -4
View File
@@ -104,9 +104,10 @@ public:
conditions.isSMHKBullish)) conditions.isSMHKBullish))
// //
; ;
// //
if (result) { if (result)
{
sl = conditions.donLowerHs[1]; sl = conditions.donLowerHs[1];
} }
@@ -165,9 +166,10 @@ public:
conditions.isSMHKBearish)) conditions.isSMHKBearish))
// //
; ;
// //
if (result) { if (result)
{
sl = conditions.donUpperLs[1]; sl = conditions.donUpperLs[1];
} }
@@ -186,8 +188,26 @@ public:
// //
r2r = 1; r2r = 1;
//
maxAllowedLong = 3;
maxAllowedShort = 3;
// //
staticVolumeLong = 0.01; staticVolumeLong = 0.01;
staticVolumeShort = 0.01; staticVolumeShort = 0.01;
//
maxAllowedOpenPositionAge = 576; // Two Days on 5 Min
delayBetweenTwoSameTypeSignals = 12; // 1 Hour on 5 Min
//
// Set 10 $ Per each Trade on 0.01 Volume
// is Enough for Hedging ...
minRequiredProfitPerTrade = 10;
minRequiredProfitPerTradeVolumeFactor = 0.01;
//
openNextPositionOnProfit = true;
ignoreProfitForOppositeSignals = true;
} }
}; };