last ...
This commit is contained in:
@@ -4464,6 +4464,8 @@ public:
|
|||||||
//
|
//
|
||||||
item.recoveryTPPoint = mRecoveryTPPoint;
|
item.recoveryTPPoint = mRecoveryTPPoint;
|
||||||
item.recoverySLPoint = mRecoverySLPoint;
|
item.recoverySLPoint = mRecoverySLPoint;
|
||||||
|
item.maxAllowedRecover = mMaxAllowedRecover;
|
||||||
|
item.recoveryVolumeMultiplier = mRecoveryVolumeMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -4685,8 +4687,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Do Force Closing ...
|
// Do Force Closing ...
|
||||||
|
|
||||||
@@ -4699,15 +4699,18 @@ public:
|
|||||||
double profit = mData[i].profit;
|
double profit = mData[i].profit;
|
||||||
double volume = mData[i].volume;
|
double volume = mData[i].volume;
|
||||||
string symbol = mData[i].symbol;
|
string symbol = mData[i].symbol;
|
||||||
|
string provider = mData[i].provider;
|
||||||
bool isLong = IsLong(mData[i].type);
|
bool isLong = IsLong(mData[i].type);
|
||||||
ENUM_TIMEFRAMES period = mData[i].period;
|
ENUM_TIMEFRAMES period = mData[i].period;
|
||||||
double points = GetPoints(mData[i].symbol);
|
double points = GetPoints(mData[i].symbol);
|
||||||
bool ignoreTPOnTrail = mData[i].ignoreTPOnTrail;
|
bool ignoreTPOnTrail = mData[i].ignoreTPOnTrail;
|
||||||
|
double recoveryTPPoint = mData[i].recoveryTPPoint;
|
||||||
|
double recoverySLPoint = mData[i].recoverySLPoint;
|
||||||
|
int maxAllowedRecover = mData[i].maxAllowedRecover;
|
||||||
double trailStepInPoints = mData[i].trailStepInPoint;
|
double trailStepInPoints = mData[i].trailStepInPoint;
|
||||||
double trailStartInPoint = mData[i].trailStartInPoint;
|
double trailStartInPoint = mData[i].trailStartInPoint;
|
||||||
bool trailBasedOnProfit = mData[i].trailBasedOnProfit;
|
bool trailBasedOnProfit = mData[i].trailBasedOnProfit;
|
||||||
double recoveryTPPoint = mData[i].recoveryTPPoint;
|
double recoveryVolumeMultiplier = mData[i].recoveryVolumeMultiplier;
|
||||||
double recoverySLPoint = mData[i].recoverySLPoint;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
XPosition iPosition;
|
XPosition iPosition;
|
||||||
@@ -4731,6 +4734,132 @@ public:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle Recovery Break Event ...
|
||||||
|
if (mData[i].allowRecover)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (mData[i].recoveryLevel <= 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (profit > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double proftiInPoints = profit / volume;
|
||||||
|
bool canClose = proftiInPoints >= recoveryTPPoint;
|
||||||
|
if (canClose)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string comment = "Recovery TP ...";
|
||||||
|
bool isClosed = mTrader.Close(
|
||||||
|
ticket,
|
||||||
|
comment //
|
||||||
|
);
|
||||||
|
if (isClosed)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "Position (" + ToString(ticket) + ") Hit's Recovery TP ...";
|
||||||
|
Alert(msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XPosition positions[];
|
||||||
|
int positionsCount = mTrader.GetPositions(
|
||||||
|
positions,
|
||||||
|
symbol,
|
||||||
|
provider,
|
||||||
|
period //
|
||||||
|
);
|
||||||
|
if (positionsCount > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XPosition recoveries[];
|
||||||
|
int recoveriesCount = ExtractRecoveries(
|
||||||
|
ticket,
|
||||||
|
positions,
|
||||||
|
recoveries //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (recoveriesCount > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XPosition mustClose[];
|
||||||
|
AddRef(
|
||||||
|
iPosition,
|
||||||
|
mustClose //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
double requiredProfitPoints = (mData[i].recoveryLevel + 1) * recoveryTPPoint;
|
||||||
|
|
||||||
|
//
|
||||||
|
double rSwap = mData[i].swap;
|
||||||
|
double rVolume = volume;
|
||||||
|
double rProfit = profit;
|
||||||
|
double rCommission = mData[i].commission;
|
||||||
|
for (int i = 0; i < recoveriesCount; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
rSwap += recoveries[i].swap;
|
||||||
|
rProfit += recoveries[i].profit;
|
||||||
|
rVolume += recoveries[i].volume;
|
||||||
|
rCommission += mTrader.GetPositionCommission(recoveries[i].ticket);
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
recoveries[i],
|
||||||
|
mustClose //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double profitSummary =
|
||||||
|
rProfit + (-1 * rSwap) - MathAbs(rCommission);
|
||||||
|
if (profitSummary > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double rProfitInPoints = profitSummary / volume;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canFinishRecovery = rProfitInPoints >= requiredProfitPoints;
|
||||||
|
if (canFinishRecovery)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Here we Have to close All Recoveries
|
||||||
|
// and Position it Self ...
|
||||||
|
|
||||||
|
//
|
||||||
|
string comment = "Recovery Done ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
int closeds = mTrader.Close(
|
||||||
|
mustClose,
|
||||||
|
comment //
|
||||||
|
);
|
||||||
|
if (closeds > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "EQM Done Recovery (" + ToString(closeds) + ") Positions ...";
|
||||||
|
Alert(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(mustClose);
|
||||||
|
Clean(positions);
|
||||||
|
Clean(recoveries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Retriece CIndex Bar ...
|
// Retriece CIndex Bar ...
|
||||||
XOHCL cBar;
|
XOHCL cBar;
|
||||||
@@ -4762,6 +4891,14 @@ public:
|
|||||||
tmpLSW,
|
tmpLSW,
|
||||||
true //
|
true //
|
||||||
);
|
);
|
||||||
|
bool isBullishSigns =
|
||||||
|
//
|
||||||
|
isBullishTrend &&
|
||||||
|
hasBullishPower &&
|
||||||
|
hasBullishPattern &&
|
||||||
|
hasBullishPressure
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bearish ...
|
// Bearish ...
|
||||||
@@ -4771,8 +4908,16 @@ public:
|
|||||||
bool isBearishTrend = cBar.HasBearishTrend(
|
bool isBearishTrend = cBar.HasBearishTrend(
|
||||||
tmpHSW,
|
tmpHSW,
|
||||||
tmpLSW,
|
tmpLSW,
|
||||||
false //
|
true //
|
||||||
);
|
);
|
||||||
|
bool isBearishSigns =
|
||||||
|
//
|
||||||
|
isBearishTrend &&
|
||||||
|
hasBearishPower &&
|
||||||
|
hasBearishPattern &&
|
||||||
|
hasBearishPressure
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Trail ...
|
// Trail ...
|
||||||
@@ -4954,65 +5099,228 @@ public:
|
|||||||
//
|
//
|
||||||
// Profit Must be Negative ...
|
// Profit Must be Negative ...
|
||||||
if (
|
if (
|
||||||
profit < 0 &&
|
|
||||||
recoveryTPPoint > 0 &&
|
recoveryTPPoint > 0 &&
|
||||||
recoverySLPoint > 0)
|
recoverySLPoint > 0 &&
|
||||||
|
mData[i].recoveryLevel < maxAllowedRecover)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Current Profit ...
|
// Current Profit ...
|
||||||
double drawdownInPoints = (MathAbs(profit) / volume);
|
double distanceInPoints = (MathAbs(profit) / volume);
|
||||||
|
double _volume = volume * ((mData[i].recoveryLevel + 1) * recoveryVolumeMultiplier);
|
||||||
|
string _comment = GenerateRecoveryTag(ticket);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Try to Remove SL of Recovery Signals ...
|
// Try to Remove SL of Recovery Signals ...
|
||||||
if (iPosition.sl > 0)
|
if (iPosition.sl > 0 || iPosition.tp > 0)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
string comment = "EQM Recover Remove SL";
|
string comment = "EQM Recover Remove TP/SL";
|
||||||
bool isSLRemoved = mTrader.Modify(
|
bool isSLRemoved = mTrader.Modify(
|
||||||
ticket,
|
ticket,
|
||||||
0,
|
0,
|
||||||
iPosition.tp,
|
0,
|
||||||
comment //
|
comment //
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
//
|
||||||
|
if (profit < 0)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Check Position TP ...
|
if (mRecoverBasedOnPressures)
|
||||||
double rewardInPoints = iPosition.GetReward() / points;
|
|
||||||
if (rewardInPoints != recoveryTPPoint)
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
double reward = recoveryTPPoint * points;
|
bool canRecover = distanceInPoints >= recoverySLPoint * 0.75;
|
||||||
double tp =
|
if (canRecover)
|
||||||
isLong
|
{
|
||||||
? iPosition.entry + reward
|
//
|
||||||
: iPosition.entry - reward;
|
XSignal rSignal;
|
||||||
string comment = "EQM Recover Fix TP";
|
bool isPrepared = false;
|
||||||
bool isSLRemoved = mTrader.Modify(
|
double longEntry = GetEntry(symbol, POSITION_TYPE_BUY);
|
||||||
ticket,
|
double shortEntry = GetEntry(symbol, POSITION_TYPE_SELL);
|
||||||
iPosition.sl,
|
|
||||||
tp,
|
//
|
||||||
comment //
|
if (isBullishSigns)
|
||||||
);
|
{
|
||||||
|
//
|
||||||
|
rSignal.Clean();
|
||||||
|
isPrepared = rSignal.Prepare(
|
||||||
|
symbol,
|
||||||
|
provider,
|
||||||
|
period,
|
||||||
|
POSITION_TYPE_BUY,
|
||||||
|
X_ORDER_MODE_MARKET,
|
||||||
|
longEntry,
|
||||||
|
_volume,
|
||||||
|
0,
|
||||||
|
0 //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (isBearishSigns)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
rSignal.Clean();
|
||||||
|
isPrepared = rSignal.Prepare(
|
||||||
|
symbol,
|
||||||
|
provider,
|
||||||
|
period,
|
||||||
|
POSITION_TYPE_SELL,
|
||||||
|
X_ORDER_MODE_MARKET,
|
||||||
|
shortEntry,
|
||||||
|
_volume,
|
||||||
|
0,
|
||||||
|
0 //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (isPrepared)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
rSignal.comment = _comment;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isExecuted = ExecuteRecoverySignal(rSignal);
|
||||||
|
if (isExecuted)
|
||||||
|
{
|
||||||
|
mData[i].recoveryLevel++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Check Price Distance For Recovery ...
|
bool canRecover = distanceInPoints >= recoverySLPoint;
|
||||||
bool canLookForPressure =
|
if (canRecover)
|
||||||
//
|
|
||||||
// in 75% ...
|
|
||||||
drawdownInPoints > ((recoverySLPoint / 3) * 2)
|
|
||||||
//
|
|
||||||
;
|
|
||||||
|
|
||||||
//
|
|
||||||
if (canLookForPressure)
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Looking for Signal Direction and
|
ENUM_POSITION_TYPE _type =
|
||||||
// Founding Pressure ...
|
isLong
|
||||||
|
? POSITION_TYPE_SELL
|
||||||
|
: POSITION_TYPE_BUY;
|
||||||
|
double _entry = GetEntry(symbol, _type);
|
||||||
|
|
||||||
|
//
|
||||||
|
XSignal rSignal;
|
||||||
|
bool isPrepared = rSignal.Prepare(
|
||||||
|
symbol,
|
||||||
|
provider,
|
||||||
|
period,
|
||||||
|
_type,
|
||||||
|
X_ORDER_MODE_MARKET,
|
||||||
|
_entry,
|
||||||
|
_volume,
|
||||||
|
0,
|
||||||
|
0 //
|
||||||
|
);
|
||||||
|
if (isPrepared)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
rSignal.comment = _comment;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isExecuted = ExecuteRecoverySignal(rSignal);
|
||||||
|
if (isExecuted)
|
||||||
|
{
|
||||||
|
mData[i].recoveryLevel++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (profit >= 0 && mData[i].recoveryLevel > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (mRecoverBasedOnPressures)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XSignal rSignal;
|
||||||
|
bool isPrepared = false;
|
||||||
|
double longEntry = GetEntry(symbol, POSITION_TYPE_BUY);
|
||||||
|
double shortEntry = GetEntry(symbol, POSITION_TYPE_SELL);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (isBullishSigns)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
rSignal.Clean();
|
||||||
|
isPrepared = rSignal.Prepare(
|
||||||
|
symbol,
|
||||||
|
provider,
|
||||||
|
period,
|
||||||
|
POSITION_TYPE_BUY,
|
||||||
|
X_ORDER_MODE_MARKET,
|
||||||
|
longEntry,
|
||||||
|
_volume,
|
||||||
|
0,
|
||||||
|
0 //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (isBearishSigns)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
rSignal.Clean();
|
||||||
|
isPrepared = rSignal.Prepare(
|
||||||
|
symbol,
|
||||||
|
provider,
|
||||||
|
period,
|
||||||
|
POSITION_TYPE_SELL,
|
||||||
|
X_ORDER_MODE_MARKET,
|
||||||
|
shortEntry,
|
||||||
|
_volume,
|
||||||
|
0,
|
||||||
|
0 //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (isPrepared)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
rSignal.comment = _comment;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isExecuted = ExecuteRecoverySignal(rSignal);
|
||||||
|
if (isExecuted)
|
||||||
|
{
|
||||||
|
mData[i].recoveryLevel++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ENUM_POSITION_TYPE _type =
|
||||||
|
isLong
|
||||||
|
? POSITION_TYPE_BUY
|
||||||
|
: POSITION_TYPE_SELL;
|
||||||
|
double _entry = GetEntry(symbol, _type);
|
||||||
|
|
||||||
|
//
|
||||||
|
XSignal rSignal;
|
||||||
|
bool isPrepared = rSignal.Prepare(
|
||||||
|
symbol,
|
||||||
|
provider,
|
||||||
|
period,
|
||||||
|
_type,
|
||||||
|
X_ORDER_MODE_MARKET,
|
||||||
|
_entry,
|
||||||
|
_volume,
|
||||||
|
0,
|
||||||
|
0 //
|
||||||
|
);
|
||||||
|
if (isPrepared)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
rSignal.comment = _comment;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isExecuted = ExecuteRecoverySignal(rSignal);
|
||||||
|
if (isExecuted)
|
||||||
|
{
|
||||||
|
mData[i].recoveryLevel++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5342,6 +5650,26 @@ private:
|
|||||||
requiredProfitsForHedge -= commissions;
|
requiredProfitsForHedge -= commissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool ExecuteRecoverySignal(XSignal &signal)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_SIGNAL_EXECUTION_RESULT state;
|
||||||
|
result = mTrader.ExecuteSignal(
|
||||||
|
signal,
|
||||||
|
state,
|
||||||
|
ORDER_TIME_GTC,
|
||||||
|
NULL,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ double eaAllowLong = true; // Allow Long Positions
|
|||||||
double eaAllowShort = true; // Allow Short Positions
|
double eaAllowShort = true; // Allow Short Positions
|
||||||
|
|
||||||
//
|
//
|
||||||
int eaMaxAllowedLongs = 0; // Max Allowed Long Positions
|
int eaMaxAllowedLongs = 1; // Max Allowed Long Positions
|
||||||
int eaMaxAllowedShorts = 0; // Max Allowed Short Positions
|
int eaMaxAllowedShorts = 1; // Max Allowed Short Positions
|
||||||
|
|
||||||
//
|
//
|
||||||
double eaTPPoint = 100; // Static TP Point
|
double eaTPPoint = 100; // Static TP Point
|
||||||
@@ -113,8 +113,8 @@ int OnInit()
|
|||||||
drawPrefix = ShortName;
|
drawPrefix = ShortName;
|
||||||
|
|
||||||
//
|
//
|
||||||
EventSetTimer(5);
|
// EventSetTimer(1);
|
||||||
// EventSetMillisecondTimer(100);
|
EventSetMillisecondTimer(100);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Init Succeed ...
|
// Init Succeed ...
|
||||||
|
|||||||
@@ -3507,7 +3507,7 @@ struct XTradeData
|
|||||||
(maxDrawdown == 0 ||
|
(maxDrawdown == 0 ||
|
||||||
MathAbs(profit) > MathAbs(maxDrawdown)))
|
MathAbs(profit) > MathAbs(maxDrawdown)))
|
||||||
{
|
{
|
||||||
profit = maxDrawdown;
|
maxDrawdown = profit;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -3785,18 +3785,22 @@ struct XTradeData
|
|||||||
// Recovery ...
|
// Recovery ...
|
||||||
|
|
||||||
//
|
//
|
||||||
bool allowRecover; // Allow Recover Specified Position
|
bool allowRecover; // Allow Recover Specified Position
|
||||||
double recoveryTPPoint; // Recovery TP Point
|
double recoveryTPPoint; // Recovery TP Point
|
||||||
double recoverySLPoint; // Recovery SL Point
|
double recoverySLPoint; // Recovery SL Point
|
||||||
int maxAllowedRecover; // Max Allowed Recovery
|
int maxAllowedRecover; // Max Allowed Recovery
|
||||||
|
int recoveryLevel; // Number of Recovery Signals
|
||||||
|
double recoveryVolumeMultiplier; // Recovery Volume Multiplier
|
||||||
|
|
||||||
//
|
//
|
||||||
void ResetRecovery()
|
void ResetRecovery()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
allowRecover = false;
|
allowRecover = false;
|
||||||
|
recoveryLevel = 0;
|
||||||
recoveryTPPoint = 0;
|
recoveryTPPoint = 0;
|
||||||
recoverySLPoint = 0;
|
recoverySLPoint = 0;
|
||||||
|
recoveryVolumeMultiplier = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -5418,8 +5422,9 @@ int ExtractRecoveries(
|
|||||||
XPosition iSource = source[i];
|
XPosition iSource = source[i];
|
||||||
|
|
||||||
//
|
//
|
||||||
ulong isRecovery = ExtractRecoveredTicket(iSource.comment) > 0;
|
ulong parentTicket = ExtractRecoveredTicket(iSource.comment);
|
||||||
if (isRecovery && iSource.ticket == ticket)
|
bool isRecovery = parentTicket > 0;
|
||||||
|
if (isRecovery && parentTicket == ticket)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
AddRef(
|
AddRef(
|
||||||
|
|||||||
Reference in New Issue
Block a user