460 lines
10 KiB
Plaintext
460 lines
10 KiB
Plaintext
//
|
|
// EQUITYMANAGEMENT ...
|
|
//
|
|
|
|
//
|
|
// All available Equity Actions Implemented here ...
|
|
void HandleEquityManagement()
|
|
{
|
|
//
|
|
// TODO: Complete this ...
|
|
|
|
//
|
|
// Here we Must first Check Number of Trades ...
|
|
XPosition positions[];
|
|
int positionsCount = GetPositions(positions);
|
|
if (positionsCount <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
double profit = CalculatePositionsProfit(positions);
|
|
double requiredProfit = CalculatePositionsProfit(positions);
|
|
|
|
//
|
|
if (profit > 0 &&
|
|
positionsCount >= mMaxAllowedPositions)
|
|
{
|
|
//
|
|
// TODO:
|
|
// Wait for Max Profit for Closing all Open Positions ...
|
|
// Also Support Orders ...
|
|
|
|
//
|
|
// here we have to Multiply requirement profit for hedging ...
|
|
bool canHedge = profit >= (requiredProfit * 1.5);
|
|
string comment = "EQM Hedge ...";
|
|
int closed = mTrader.ClosePositions(
|
|
positions,
|
|
comment);
|
|
if (closed > 0)
|
|
{
|
|
//
|
|
// Cancel All Placed Support Orders ...
|
|
CancelAllEQMOrders();
|
|
|
|
//
|
|
string message = "EQM Closed (" + ToString(positionsCount) + ") due Hedge by: " + ToString(profit);
|
|
|
|
//
|
|
LogMessage(message);
|
|
}
|
|
|
|
//
|
|
return;
|
|
}
|
|
else if (profit > 0 && positionsCount > 1)
|
|
{
|
|
//
|
|
// Here we can Hedge Positions in regular Senario ...
|
|
bool canHedge = profit >= requiredProfit;
|
|
string comment = "EQM Hedge ...";
|
|
int closed = mTrader.ClosePositions(
|
|
positions,
|
|
comment);
|
|
if (closed > 0)
|
|
{
|
|
//
|
|
// Cancel All Placed Support Orders ...
|
|
CancelAllEQMOrders();
|
|
|
|
//
|
|
string message = "EQM Closed (" + ToString(positionsCount) + ") due Hedge by: " + ToString(profit);
|
|
|
|
//
|
|
LogMessage(message);
|
|
}
|
|
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
// TODO: Add Longest Age in Props ...
|
|
int longDetectionAgeForInDrawDownPositions = 26;
|
|
int longDetectionAgeForUntriggeredSupports = 26;
|
|
|
|
//
|
|
// Here we have to Place Support Signals if there is no Equity ...
|
|
bool hasEquity = CheckEquityForTrade();
|
|
if (profit < 0 && !hasEquity)
|
|
{
|
|
//
|
|
// Retrieve and Placed EQM Support Orders ...
|
|
HandleEQMSupportPlacement();
|
|
}
|
|
else if (profit < 0 && hasEquity)
|
|
{
|
|
//
|
|
// Here there are some Open Positions and we have eQuity but
|
|
// there isn't new Signals and exists positions in DrawDown ...
|
|
|
|
//
|
|
// here we have to Generate EQM Support Signal ...
|
|
|
|
//
|
|
// First try to Find Max In Draw down Position ...
|
|
XPosition inDPositions[];
|
|
int inDPositionsCount = GetInDrawdownPositions(
|
|
inDPositions,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
X_POSITION_SELECT_MAX);
|
|
if (inDPositionsCount <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
XPosition maxInDPosition = inDPositions[0];
|
|
int maxInDPositionAge = GetAge(maxInDPosition);
|
|
|
|
//
|
|
bool isSupportable = maxInDPositionAge >= longDetectionAgeForInDrawDownPositions;
|
|
if (!isSupportable)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// now we are sure Max In DrawDown Position is Supportable ...
|
|
HandleEQMSupportPlacement();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Retrieve All EQM Placed Support Orders ...
|
|
int GetEQMOrders(
|
|
XOrder &orders[] // Hold Result
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
XOrder allOrders[];
|
|
int allOrdersCount = GetOrders(allOrders);
|
|
if (allOrdersCount <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract EQM Orders ...
|
|
result = GetEQMSupportOrders(
|
|
orders,
|
|
allOrders);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve All EQM Support Positions ...
|
|
int GetEQMPositions(
|
|
XPosition &positions[] // Hold Result
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
XPosition allPositions[];
|
|
int allPositionsCount = GetPositions(allPositions);
|
|
if (allPositionsCount <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract EQM Positions ...
|
|
result = GetEQMSupportPositions(
|
|
positions,
|
|
allPositions);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Cancel all EQM Placed Support Orders ...
|
|
bool CancelAllEQMOrders()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
XOrder eqmOrders[];
|
|
int eqmOrdersCount = GetEQMOrders(eqmOrders);
|
|
if (eqmOrdersCount <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = mTrader.CancelOrders(eqmOrders);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Generate EQM Support Signals ...
|
|
int GenerateEQMSupports(
|
|
XSignal &supports[], // Holds Supports
|
|
bool placeSL = true, // Place SL For EQM Supports
|
|
bool placeTP = true // Place TP For EQM Supports
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Clean result Array ...
|
|
Clean(supports);
|
|
|
|
//
|
|
// Since we Generate Support Signals based on Max In Drawdown Positions ...
|
|
// we hae to Find it and then find it's Related Provider ...
|
|
// then recieve Market Conditions based on it's Signaller's Provider ...
|
|
// then try to Generate Supports ...
|
|
XPosition inDrawdownPositions[];
|
|
int inDrawdownPositionsCount = GetInDrawdownPositions(
|
|
inDrawdownPositions,
|
|
NULL, // All Symbols ...
|
|
NULL, // All TYpe Of Positions ...
|
|
NULL, // All Periods ...
|
|
NULL, // All Providers ...
|
|
X_POSITION_SELECT_MAX // we need Max InDrawdown ...
|
|
);
|
|
if (inDrawdownPositionsCount <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Since We Select Max here ...
|
|
// and also check count ...
|
|
// just Recieve Max In DD Position ...
|
|
XPosition maxInDDPosition = inDrawdownPositions[0];
|
|
|
|
//
|
|
// Here we can Select Provider based on InDD Position ...
|
|
int providerIDX = GetProviderIndex(
|
|
maxInDDPosition.symbol,
|
|
maxInDDPosition.period);
|
|
|
|
//
|
|
// Validate Index ...
|
|
if (providerIDX <= -1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double entry = GetEntry(
|
|
maxInDDPosition.symbol,
|
|
maxInDDPosition.type);
|
|
|
|
//
|
|
// Retrieve Market Conditions Based on Specific Provider ...
|
|
X121MarketConditions conditions = mProviders[providerIDX]
|
|
.provider
|
|
.GetMarketConditions(0);
|
|
|
|
//
|
|
// Retrieve Support and Resistance ...
|
|
XOHCLSupRes supRes = mProviders[providerIDX]
|
|
.provider
|
|
.GenerateSupportAndResistance(
|
|
entry,
|
|
36 //
|
|
);
|
|
|
|
//
|
|
double volume = GetEQMSupportVolume();
|
|
|
|
//
|
|
// Try to Find above peak and below vale Pivots ...
|
|
double pivots[];
|
|
mProviders[providerIDX]
|
|
.provider
|
|
.FillPivotPoints(pivots);
|
|
|
|
// //
|
|
// GenerateFiboEQMSupports(
|
|
// conditions,
|
|
// maxInDDPosition,
|
|
// supports,
|
|
// pivots,
|
|
// volume,
|
|
// placeSL,
|
|
// placeTP);
|
|
|
|
//
|
|
// GenerateSupportAndResistanceEQMSupports(
|
|
// conditions,
|
|
// maxInDDPosition,
|
|
// supRes,
|
|
// supports,
|
|
// volume,
|
|
// placeSL,
|
|
// placeTP);
|
|
|
|
//
|
|
result = ArraySize(supports);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Count all open Positions Volume for supports ...
|
|
double GetEQMSupportVolume(
|
|
bool ignoreEQM = true // Ignore EQM Positions
|
|
)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
// TODO:
|
|
// add to Props ...
|
|
double maxEQMSupportVolume = 0.3;
|
|
|
|
//
|
|
// Retrieve Positions ...
|
|
XPosition positions[];
|
|
int positionsCount = GetPositions(positions);
|
|
if (positionsCount <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve EQM Positions and Check ...
|
|
// if it's count bigger than 0 means there are an Open
|
|
// EQM Support Position and we do not have to do anything ...
|
|
XPosition eqmPositions[];
|
|
int eqmPositionsCount = GetEQMPositions(eqmPositions);
|
|
if (!ignoreEQM && eqmPositionsCount > 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < positionsCount; i++)
|
|
{
|
|
//
|
|
XPosition iPosition = positions[i];
|
|
|
|
//
|
|
result += iPosition.volume;
|
|
}
|
|
|
|
//
|
|
// Multiply Volume Summary ...
|
|
// TODO: Make it Configurable ...
|
|
result *= 1;
|
|
if (result > maxEQMSupportVolume)
|
|
{
|
|
result = maxEQMSupportVolume;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void HandleEQMSupportPlacement()
|
|
{
|
|
//
|
|
// TODO: Add Longest Age in Props ...
|
|
int longDetectionAgeForInDrawDownPositions = 26;
|
|
int longDetectionAgeForUntriggeredSupports = 26;
|
|
|
|
//
|
|
// Here we have to Place EQM Support Orders ...
|
|
|
|
//
|
|
// First Check Exists Supports ...
|
|
XOrder orders[];
|
|
int ordersCount = GetEQMOrders(orders);
|
|
if (ordersCount > 0)
|
|
{
|
|
//
|
|
// When there are Exists Untriggered EQM Support Orders ...
|
|
// first we have to check their Age ...
|
|
// if it's longest as enough for replacing, cance all EQM Orders and regenerate new Ones ...
|
|
// otherwise wait until they triggered or be long as enough ...
|
|
|
|
//
|
|
int minEQMSupportAge = 0;
|
|
for (int i = 0; i < ordersCount; i++)
|
|
{
|
|
//
|
|
XOrder iOrder = orders[i];
|
|
|
|
//
|
|
int iAge = GetAge(iOrder);
|
|
minEQMSupportAge = minEQMSupportAge == 0 ||
|
|
minEQMSupportAge > iAge
|
|
? iAge
|
|
: minEQMSupportAge;
|
|
}
|
|
|
|
//
|
|
// we have min support order's age ...
|
|
// check it is long enough for cancelling or not ...
|
|
bool isTooOld = minEQMSupportAge >= longDetectionAgeForUntriggeredSupports;
|
|
if (!isTooOld)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// we are sre exists EQM Supports are To old ...
|
|
bool isCancelled = CancelAllEQMOrders();
|
|
if (!isCancelled)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
XSignal signals[];
|
|
int signalsCount = GenerateEQMSupports(signals);
|
|
if (signalsCount <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
string comment = GenerateXEQMSupportComment();
|
|
int executed = mTrader.ExecuteSignals(
|
|
signals,
|
|
comment //
|
|
);
|
|
if (executed > 0)
|
|
{
|
|
//
|
|
string message = "Execute (" + ToString(executed) + ") EQM Supports ...";
|
|
|
|
//
|
|
LogMessage(message);
|
|
}
|
|
}
|