apply signaller's Policies in EA signal manager before Execute Signals ...
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -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 ...
|
||||||
|
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user