Last Works ...

This commit is contained in:
2024-11-05 04:34:58 +03:30
parent 8928cebb97
commit 6e8768e6eb
12 changed files with 1589 additions and 202 deletions
@@ -437,7 +437,7 @@ struct X121SMCTradeData
struct X121SMCProtectedPosition
{
//
XPosition main; // Main Position ...
XPosition main; // Main Position ...
X121SMCTradeData data; // Trade Handler Data ...
//
@@ -495,6 +495,191 @@ struct X121SMCProtectedPosition
}
};
//
struct X121SMCSymbolPositionInfo
{
//
string symbol;
//
datetime enableAt;
//
int longSLs;
int longTPs;
//
int shortSLs;
int shortTPs;
//
int countedSLs;
//
void X121SMCSymbolPositionInfo()
{
Clean();
}
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
longSLs = 0;
longTPs = 0;
//
shortSLs = 0;
shortTPs = 0;
//
countedSLs = 0;
//
enableAt = NULL;
}
/**
* Check is own Symbol Info ...
*
* @param _symbol: String ...
*
* @return ( bool )
*/
bool IsOwn(string _symbol)
{
//
bool result = false;
//
result =
//
IsValid(symbol) &&
_symbol == symbol
//
;
//
return result;
}
/**
* Check Symbol Trading is Enable or not ...
*
* @param time: DateTime ...
*
* @return ( bool )
*/
bool IsEnable(datetime time = NULL)
{
//
bool result = false;
//
time = NormalizeTime(time);
//
bool isEnableAtValid = IsValid(enableAt);
//
result =
!isEnableAtValid
? true
: time > enableAt;
if (result &&
isEnableAtValid)
{
Reset();
}
//
return result;
}
/**
* Pause Symbol Trading ...
*
* @param seconds: Integer ...
*/
void Pause(int seconds)
{
//
if (seconds <= 0)
{
return;
}
//
datetime _enableAt = ((datetime)((int)TimeCurrent() + seconds));
enableAt = _enableAt;
}
/**
* Handle Stop Loss ...
*
* @param _type: ENUM_POSITION_TYPE member ...
*/
void HandleSL(ENUM_POSITION_TYPE _type)
{
//
bool isLong = IsLong(_type);
if (isLong)
{
longSLs++;
}
else
{
shortSLs++;
}
//
countedSLs++;
}
/**
* Handle Take Profit ...
*
* @param _type: ENUM_POSITION_TYPE member ...
*/
void HandleTP(ENUM_POSITION_TYPE _type)
{
//
bool isLong = IsLong(_type);
if (isLong)
{
longTPs++;
}
else
{
shortTPs++;
}
//
countedSLs--;
if (countedSLs < 0)
{
countedSLs = 0;
}
}
/**
* Reset Counter ...
*/
void Reset()
{
//
countedSLs = 0;
enableAt = NULL;
}
//
};
//
// Implementations ...
@@ -1092,6 +1277,44 @@ class XC121SMCTradeHandler : public XSCBaseAlert
mDelayBarBetweenTwoSignal = value;
}
//
int MaxAllowedSLToPause()
{
return mMaxAllowedSLToPause;
}
//
void MaxAllowedSLToPause(int value)
{
//
if (value < 0)
{
value = 0;
}
//
mMaxAllowedSLToPause = value;
}
//
int MaxAllowedSLReachedPauseDelay()
{
return mMaxAllowedSLReachedPauseDelay;
}
//
void MaxAllowedSLReachedPauseDelay(int value)
{
//
if (value < 0)
{
value = 0;
}
//
mMaxAllowedSLReachedPauseDelay = value;
}
//
double AcceptNextSameTypeSignalWhenLastInProfit()
{
@@ -1779,9 +2002,73 @@ class XC121SMCTradeHandler : public XSCBaseAlert
mData[idx].endTime = deal.time;
mData[idx].profit = deal.profit;
//
bool isTP = deal.reason == DEAL_REASON_TP;
bool isSL = deal.reason == DEAL_REASON_SL;
//
mData[idx].message =
deal.reason == DEAL_REASON_TP ? "TP" : "SL";
isTP
? "TP"
: isSL
? "SL"
: "";
//
if (isTP || isSL)
{
//
int symbolIDX = -1;
bool hasInfo = HasSymbol(
mData[idx].symbol,
symbolIDX //
);
//
X121SMCSymbolPositionInfo info;
if (!hasInfo)
{
//
// Add New One ...
info.symbol = mData[idx].symbol;
}
else
{
//
// Update Exists ...
info = mSymbolInfos[symbolIDX];
//
// Remove Exists ...
ArrayRemove(
mSymbolInfos,
symbolIDX,
1 //
);
}
//
ENUM_POSITION_TYPE xType = IsLong(mData[idx].type)
? POSITION_TYPE_BUY
: POSITION_TYPE_SELL;
if (isTP)
{
info.HandleTP(xType);
}
else if (isSL)
{
info.HandleSL(xType);
}
//
AddRef(
info,
mSymbolInfos //
);
//
HandlePauseSymbol(mData[idx].symbol);
}
//
Save(idx);
@@ -1815,7 +2102,72 @@ class XC121SMCTradeHandler : public XSCBaseAlert
mData[idx].message = comment;
//
Save(idx);
bool handleForceClose = true;
if (handleForceClose)
{
//
bool isTP = position.profit > 0;
bool isSL = position.profit < 0;
//
if (isTP || isSL)
{
//
int symbolIDX = -1;
bool hasInfo = HasSymbol(
mData[idx].symbol,
symbolIDX //
);
//
X121SMCSymbolPositionInfo info;
if (!hasInfo)
{
//
// Add New One ...
info.symbol = mData[idx].symbol;
}
else
{
//
// Update Exists ...
info = mSymbolInfos[symbolIDX];
//
// Remove Exists ...
ArrayRemove(
mSymbolInfos,
symbolIDX,
1 //
);
}
//
ENUM_POSITION_TYPE xType = IsLong(mData[idx].type)
? POSITION_TYPE_BUY
: POSITION_TYPE_SELL;
if (isTP)
{
info.HandleTP(xType);
}
else if (isSL)
{
info.HandleSL(xType);
}
//
AddRef(
info,
mSymbolInfos //
);
//
HandlePauseSymbol(mData[idx].symbol);
}
//
Save(idx);
}
}
//
@@ -1992,7 +2344,24 @@ class XC121SMCTradeHandler : public XSCBaseAlert
{
return result;
}
//
int symbolIDX = -1;
bool hasSymbolInfo = HasSymbol(
signal.symbol,
symbolIDX //
);
//
// Check rading Not Paused ...
result =
!hasSymbolInfo ||
mSymbolInfos[symbolIDX].IsEnable();
if (!result)
{
return result;
}
//
bool isLong = IsLong(signal.type);
@@ -2105,39 +2474,39 @@ class XC121SMCTradeHandler : public XSCBaseAlert
return result;
}
//
XPosition longs[];
XPosition shorts[];
//
// Counting Positions ...
if (mUseMaxAllowedTradesPerSymbol)
{
//
mTrader.GetPositions(
longs,
shorts,
signal.symbol //
);
}
else
{
//
mTrader.GetPositions(
longs,
shorts,
NULL // All Symbols ...
);
}
//
int longsCount = ArraySize(longs);
int shortsCount = ArraySize(shorts);
//
// Check Trades Count ...
if (mMaxAllowedLongs > 0 || mMaxAllowedShorts > 0)
{
//
XPosition longs[];
XPosition shorts[];
//
// Counting Positions ...
if (mUseMaxAllowedTradesPerSymbol)
{
//
mTrader.GetPositions(
longs,
shorts,
signal.symbol //
);
}
else
{
//
mTrader.GetPositions(
longs,
shorts,
NULL // All Symbols ...
);
}
//
int longsCount = ArraySize(longs);
int shortsCount = ArraySize(shorts);
//
result =
//
@@ -2159,48 +2528,48 @@ class XC121SMCTradeHandler : public XSCBaseAlert
state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED;
return result;
}
}
//
// Check Position Delays ...
if (result && mDelayBarBetweenTwoSignal > 0)
{
//
int youngestAge = 0;
XPosition youngestPosition;
//
// Check Position Delays ...
if (result && mDelayBarBetweenTwoSignal > 0)
// Long Positions when there are Longs ...
if (isLong && longsCount > 0)
{
//
int youngestAge = 0;
XPosition youngestPosition;
youngestAge = GetYoungest(
youngestPosition,
longs //
);
}
//
// Short Positions when there are Shorts ...
else if (!isLong && shortsCount > 0)
{
//
youngestAge = GetYoungest(
youngestPosition,
shorts //
);
}
//
// Only Check when there is must to check and conditions happens ...
if (youngestAge > 0 && youngestPosition.IsValid())
{
//
// Long Positions when there are Longs ...
if (isLong && longsCount > 0)
result = youngestAge >= mDelayBarBetweenTwoSignal;
if (!result)
{
//
youngestAge = GetYoungest(
youngestPosition,
longs //
);
}
//
// Short Positions when there are Shorts ...
else if (!isLong && shortsCount > 0)
{
//
youngestAge = GetYoungest(
youngestPosition,
shorts //
);
}
//
// Only Check when there is must to check and conditions happens ...
if (youngestAge > 0 && youngestPosition.IsValid())
{
//
result = youngestAge >= mDelayBarBetweenTwoSignal;
if (!result)
{
//
state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED;
return result;
}
state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED;
return result;
}
}
}
@@ -2346,11 +2715,35 @@ class XC121SMCTradeHandler : public XSCBaseAlert
}
}
/**
* Reset All Paused Symbols ...
*/
void ResumePausedSymbols()
{
//
int count = ArraySize(mSymbolInfos);
if (!IsValidSize(count))
{
return;
}
//
for (int i = 0; i < count; i++)
{
//
mSymbolInfos[i].Reset();
}
//
string message = "Force Resume Paused Symbols ...";
Alert(message);
}
//
// Protected ...
protected:
//
XSCTrade *mTrader; // Instance of Trader Class
XSCTrade *mTrader; // Instance of Trader Class
X121SMCTradeCollector *mCollector; // Instance of Trade Collector Class
//
@@ -2583,8 +2976,8 @@ class XC121SMCTradeHandler : public XSCBaseAlert
* Handle Protecting Position ...
*/
bool HandlePositionProtecting(
XPosition &position, // Main Position
XPosition &supports[], // Supports
XPosition &position, // Main Position
XPosition &supports[], // Supports
X121SMCProtectedPosition &positions[] // All Positions
)
{
@@ -3286,6 +3679,57 @@ class XC121SMCTradeHandler : public XSCBaseAlert
// Trailling ...
}
/**
* Pause Specified Symbol Trading ...
*
* @param symbol: String ...
*/
void HandlePauseSymbol(string symbol)
{
//
if (!IsValid(symbol))
{
return;
}
//
int idx = -1;
bool hasItem = HasSymbol(
symbol,
idx //
);
if (!hasItem)
{
return;
}
//
int maxAllowedSLToPause = MaxAllowedSLToPause();
int pauseDelay = MaxAllowedSLReachedPauseDelay();
if (maxAllowedSLToPause <= 0 || pauseDelay <= 0)
{
return;
}
//
bool canPauseSymbol =
mSymbolInfos[idx].IsEnable() &&
mSymbolInfos[idx].countedSLs >= maxAllowedSLToPause;
if (!canPauseSymbol)
{
return;
}
//
mSymbolInfos[idx].Pause(pauseDelay);
//
string message = "Pause (" + symbol + ") until: (" + ToString(mSymbolInfos[idx].enableAt) + ") ...";
Alert(message);
//
}
//
// Private ...
private:
@@ -3317,8 +3761,10 @@ class XC121SMCTradeHandler : public XSCBaseAlert
// Protector ...
//
bool mUseForceMomentumsInProtection; // Use Force Momentums In Protection;
int mDelayBarBetweenTwoSignal; // Delay Bars Between Two Signal
int mMaxAllowedSLToPause; // Max Allowed SL Per Symbol
int mMaxAllowedSLReachedPauseDelay; // Pause Symbol Trading After Mx Allowed SL Reached
bool mUseForceMomentumsInProtection; // Use Force Momentums In Protection
double mAcceptNextSameTypeSignalWhenLastInProfit; // Accept Next Same Type Signal When Last in Profit in Point
//
@@ -3364,6 +3810,64 @@ class XC121SMCTradeHandler : public XSCBaseAlert
double mHedgeHEMinProfitPerVolumeStep; // Minimum Required Profit For HE Hedge Per Volume Step
double mHedgeBEMinProfitPerVolumeStep; // Minimum Required Profit For BE Hedge Per Volume Step
//
X121SMCSymbolPositionInfo mSymbolInfos[];
/**
* Find Specific Symbo Indo Item index ...
*
* @param symbol: String ...
* @param index: Integer ...
*
* @return ( bool )
*/
bool HasSymbol(
string symbol,
int &index //
)
{
//
bool result = false;
//
index = -1;
//
result = IsValid(symbol);
if (!result)
{
return result;
}
//
int count = ArraySize(mSymbolInfos);
result = IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
bool isOwn = mSymbolInfos[i]
.IsOwn(symbol);
if (isOwn)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
//
// Common Functions ...