add support for hedge functionalities and also apply fix on Multiple Signals issues ...

This commit is contained in:
2024-12-24 20:09:34 +03:30
parent 8d6c48ede5
commit b5021a80d7
3 changed files with 382 additions and 68 deletions
@@ -212,11 +212,12 @@ struct X121SMCTradeData
*
* @return ( bool )
*/
bool IsOwn(
bool IsOwnSignalTime(
string _symbol,
string _provider,
ENUM_TIMEFRAMES _period,
ENUM_X_POSITION_TYPES _type //
ENUM_X_POSITION_TYPES _type,
datetime _time //
)
{
//
@@ -225,6 +226,8 @@ struct X121SMCTradeData
//
result =
//
IsValid(_time) &&
Time() == _time &&
IsValid(_symbol) &&
IsValid(_period) &&
XType() == _type &&
@@ -241,6 +244,49 @@ struct X121SMCTradeData
return result;
}
/**
* Check Specified Conditions is Own to Model or not ...
*
* @param _symbol: String, Specified Symbol ...
* @param _provider: String, Specified Provider ...
* @param _period: ENUM_TIMEFRAMES member, Specified Signal Period ...
* @param _type: ENUM_X_POSITION_TYPES member, Specified Signal Type ...
*
* @return ( bool )
*/
bool IsOwnStartTime(
string _symbol,
string _provider,
ENUM_TIMEFRAMES _period,
ENUM_X_POSITION_TYPES _type,
datetime _time //
)
{
//
bool result = false;
//
result =
//
IsValid(_time) &&
IsValid(_symbol) &&
IsValid(_period) &&
XType() == _type &&
IsValid(startTime) &&
startTime == _time &&
IsValid(_provider) &&
GetPeriod() == _period &&
GetSymbol() == _symbol &&
Provider() == _provider &&
XType() != X_POSITION_TYPE_ALL &&
XType() != X_POSITION_TYPE_NONE
//
;
//
return result;
}
/**
* Check Specified Signal is Own to Model or not ...
*
@@ -258,11 +304,12 @@ struct X121SMCTradeData
//
IsValid() &&
_signal.IsValid() &&
IsOwn(
IsOwnSignalTime(
_signal.symbol,
_signal.provider,
_signal.period,
ToPositionType(_signal.type))
ToPositionType(_signal.type),
_signal.time)
//
;
@@ -287,11 +334,58 @@ struct X121SMCTradeData
//
IsValid() &&
_position.IsValid() &&
IsOwn(
IsOwnStartTime(
_position.symbol,
_position.provider,
_position.period,
ToPositionType(_position.type))
ToPositionType(_position.type),
_position.openAt)
//
;
//
return result;
}
/**
* Check Specified Position is Own to Model or not ...
*
* @param _position: XPosition instance Reference ...
*
* @return ( bool )
*/
bool IsOwnPosition(XPosition &_position)
{
//
bool result = false;
//
double tp = TP();
double sl = SL();
double entry = Entry();
double volume = Volume();
string symbol = GetSymbol();
string provider = Provider();
ENUM_POSITION_TYPE type = Type();
ENUM_TIMEFRAMES period = GetPeriod();
//
double pVolume = _position.volume;
double pSL = NormalizePrice(_position.sl, _position.symbol);
double pEntry = NormalizePrice(_position.entry, _position.symbol);
//
result =
//
IsValid() &&
sl == pSL &&
entry == pEntry &&
pVolume == volume &&
_position.IsValid() &&
type == _position.type &&
symbol == _position.symbol &&
period == _position.period &&
provider == _position.provider
//
;
@@ -395,6 +489,70 @@ struct X121SMCTradeData
return result;
}
/**
* Update Model Data by Providing Specified Position ...
*
* @param _position: XPosition instance Reference ...
*
* @return ( bool )
*/
bool UpdatePosition(XPosition &_position)
{
//
bool result = false;
//
result =
//
IsValid() &&
_position.IsValid() &&
IsOwnPosition(_position)
//
;
if (!result)
{
return result;
}
//
swap = _position.swap;
ticket = _position.ticket;
profit = _position.profit;
message = _position.comment;
startTime = _position.openAt;
//
// Set Once ...
if (commission == 0 &&
_position.commission != 0)
{
commission = _position.commission;
}
//
// Set Once ...
if (ask == 0)
{
ask = GetAsk(_position.symbol);
}
//
// Set Once ...
if (bid == 0)
{
bid = GetBid(_position.symbol);
}
//
if (profit < 0 && profit < maxDrawdown)
{
maxDrawdown = profit;
}
//
return result;
}
//
// Tools Extensions ...
@@ -534,6 +692,16 @@ struct X121SMCTradeData
return signal.mode;
}
/**
* Get Model Signal Time ...
*
* @return ( datetime )
*/
datetime Time()
{
return signal.time;
}
//
// Additional Helpers Extensions ...
@@ -2387,7 +2555,18 @@ class XC121SMCTradeHandler : public XCBaseAlert
//
// Apply Updates on Data Collection ...
Update(position);
int idx = -1;
bool hasItem = HasItemByPosition(
position,
idx //
);
if (!hasItem)
{
return;
}
//
mData[idx].UpdatePosition(position);
}
//
@@ -2973,18 +3152,18 @@ class XC121SMCTradeHandler : public XCBaseAlert
: maxSameTimeTrades;
//
double bepSummary = 0;
double volumeSummary = 0;
double profitSummary = 0;
XPosition positions[];
//
// Loop through Open Positions ...
for (int i = 0; i < count; i++)
{
//
X121SMCTradeData iData = mData[i];
//
// Profit Sum ...
profitSummary += iData.profit;
//
XPosition iPosition;
bool hasPosition = mTrader.GetPosition(
@@ -2995,6 +3174,10 @@ class XC121SMCTradeHandler : public XCBaseAlert
{
continue;
}
AddRef(
iPosition,
positions //
);
//
// Calculate Break Even Point ...
@@ -3019,6 +3202,11 @@ class XC121SMCTradeHandler : public XCBaseAlert
reachedTPPrice //
);
//
bepSummary += bep;
volumeSummary += volume;
profitSummary += iPosition.profit;
//
// All Protections Done for InProfit Positions ...
if (iData.profit > 0)
@@ -3058,6 +3246,82 @@ class XC121SMCTradeHandler : public XCBaseAlert
}
}
}
//
// Check Partial Close ...
bool canPartialClose = iData.CanPartialClose();
if (canPartialClose && reachedTPLevel > 0)
{
//
double mainVolume = iData.Volume();
double currentVolume = iPosition.volume;
double partialCloseOnTP = iData.PartialCloseOnTPLevel();
double partialCloseVolumeMultiplier = iData.PartialCloseMultiplier();
double closeVolume = currentVolume * partialCloseVolumeMultiplier;
closeVolume = NormalizeVolume(closeVolume, iPosition.symbol);
canPartialClose =
currentVolume == mainVolume &&
reachedTPLevel == partialCloseOnTP;
if (canPartialClose)
{
//
string comment = "PC On TP Level: " + ToString(partialCloseOnTP) + " ...";
bool isModified = mTrader.ClosePartial(
iData.ticket,
closeVolume,
comment //
);
if (isModified)
{
//
string message = ToString(iData.Type()) +
" Position: " +
ToString(iData.ticket) +
" PC (" + ToString(closeVolume) + ") On TP Level: " +
ToString(partialCloseOnTP) + " Successfully ...";
Alert(message);
}
}
}
//
// Check for SL Trail ...
bool canTrailSL = iData.CanTrailSL();
if (canTrailSL && reachedTPLevel > 0)
{
//
double startTrailTPLevel = iData.TrailSLStartOnReachTPLevel();
int tSLTPIndex = (int)reachedTPLevel - 1;
double tSLTPPrice = tps[tSLTPIndex];
canTrailSL =
reachedTPLevel >= startTrailTPLevel &&
(isLong
? iPosition.sl < tSLTPPrice
: iPosition.sl > tSLTPPrice);
if (canTrailSL)
{
//
string comment = "Trail SL on Reached TP: " + ToString(reachedTPLevel) + " ...";
double sl = tSLTPPrice;
double tp = iPosition.tp;
bool isModified = mTrader.Modify(
iData.ticket,
sl,
tp,
comment //
);
if (isModified)
{
//
string message = ToString(iData.Type()) +
" Position: " +
ToString(iData.ticket) +
" Trailed SL On Reached TP: " + ToString(reachedTPLevel) +
" Successfully ...";
Alert(message);
}
}
}
}
}
@@ -3078,10 +3342,46 @@ class XC121SMCTradeHandler : public XCBaseAlert
: 0;
//
// TODO: Here Implement Collection Based Protections ...
// Checking Hedge ...
bool allowHedge = AllowHedge();
if (allowHedge)
{
//
double minHedgeVolumeStep = HedgeMinVolumeStep();
int minRequiredPositionsForHedge = MinimumOpenPositionsForHedge();
double minRequiredProfitPerVolumeStepForHedge = HedgeMinProfitPerVolumeStep();
//
Print("Protection");
//
double minRequiredAdditionalProfit =
bepSummary +
((volumeSummary / minHedgeVolumeStep) * minRequiredProfitPerVolumeStepForHedge);
//
bool canHedge = AllowHedge() &&
profitSummary > 0 &&
minHedgeVolumeStep > 0 &&
minRequiredProfitPerVolumeStepForHedge > 0 &&
profitSummary >= minRequiredAdditionalProfit &&
(minRequiredPositionsForHedge <= 0
? true
: count >= minRequiredPositionsForHedge);
if (canHedge)
{
//
string comment = "Hedge (" + ToString(count) + ") Positions By: " + ToString(profitSummary) + "...";
int closedPositionsCount = mTrader.Close(
positions,
comment //
);
if (IsValidSize(closedPositionsCount))
{
//
string message = "Hedge (" + ToString(count) + ") Positions By: " +
ToString(profitSummary) + " Successfully ...";
Alert(message);
}
}
}
}
//
@@ -3181,10 +3481,7 @@ class XC121SMCTradeHandler : public XCBaseAlert
{
//
result = !HasItem(
item.GetSymbol(),
item.Provider(),
item.GetPeriod(),
item.XType(),
item.signal,
index //
);
}
@@ -3250,16 +3547,35 @@ class XC121SMCTradeHandler : public XCBaseAlert
)
{
//
bool result =
bool result = false;
//
index = -1;
//
int count = Count();
result = signal.IsValid() &&
IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
signal.IsValid() &&
HasItem(signal.symbol,
signal.provider,
signal.period,
ToPositionType(signal.type),
index)
//
;
bool isOwn = mData[i].IsOwn(signal);
if (isOwn)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
@@ -3272,28 +3588,43 @@ class XC121SMCTradeHandler : public XCBaseAlert
)
{
//
bool result =
bool result = false;
//
index = -1;
//
int count = Count();
result = position.IsValid() &&
IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
position.IsValid() &&
HasItem(position.symbol,
position.provider,
position.period,
ToPositionType(position.type),
index)
//
;
bool isOwn = mData[i].IsOwn(position);
if (isOwn)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
//
// Find Item Index ...
bool HasItem(
string symbol,
string provider,
ENUM_TIMEFRAMES period,
ENUM_X_POSITION_TYPES type,
bool HasItemByPosition(
XPosition &position,
int &index //
)
{
@@ -3303,25 +3634,10 @@ class XC121SMCTradeHandler : public XCBaseAlert
//
index = -1;
//
// Validate ...
result =
//
IsValid(symbol) &&
IsValid(period) &&
IsValid(provider) &&
type != X_POSITION_TYPE_ALL &&
type != X_POSITION_TYPE_NONE
//
;
if (!result)
{
return result;
}
//
int count = Count();
result = IsValidSize(count);
result = position.IsValid() &&
IsValidSize(count);
if (!result)
{
return result;
@@ -3331,13 +3647,8 @@ class XC121SMCTradeHandler : public XCBaseAlert
for (int i = 0; i < count; i++)
{
//
result = mData[i].IsOwn(
symbol,
provider,
period,
type //
);
if (result)
bool isOwn = mData[i].IsOwnPosition(position);
if (isOwn)
{
//
index = i;
@@ -3345,6 +3656,9 @@ class XC121SMCTradeHandler : public XCBaseAlert
}
}
//
result = IsValidIndex(index);
//
return result;
}
+1 -1
View File
@@ -568,7 +568,7 @@ class XC121SMCExpert : public XCBaseExpert
//
// Configure Hedging ...
mTradeHandler.AllowHedge(false);
mTradeHandler.AllowHedge(true);
mTradeHandler.HedgeMinVolumeStep(0.01);
mTradeHandler.MinimumOpenPositionsForHedge(2);
mTradeHandler.HedgeMinProfitPerVolumeStep(0.2);
@@ -294,7 +294,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
//
signal.trailSL = true;
signal.trailSLStartOnReachTPLevel = 3;
signal.trailSLStartOnReachTPLevel = 4;
}
//