add support for hedge functionalities and also apply fix on Multiple Signals issues ...
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user