apply some EQM Force State Handling ...

This commit is contained in:
2024-06-23 19:06:19 +03:30
parent 43ea4edc42
commit 03de958361
5 changed files with 4642 additions and 4544 deletions
-564
View File
@@ -978,29 +978,11 @@ struct X121SignalGenerator
{ {
// //
string version; string version;
double hotLevels[];
// //
// Constructor ... // Constructor ...
void X121SignalGenerator() void X121SignalGenerator()
{ {
//
Add(
0.25,
hotLevels //
);
//
Add(
0.20,
hotLevels //
);
//
Add(
0.15,
hotLevels //
);
} }
// //
@@ -3169,552 +3151,6 @@ struct X121SignalGenerator
return result; return result;
} }
//
// Calculate Ticks Zone ...
XSCZones *zones = new XSCZones(
signal.symbol,
signal.period //
);
//
XSCZonesInput zonesInput;
zonesInput.length = 26;
zonesInput.numberOfZones = 10;
//
zonesInput.AddLevelColor(
hotLevels[0],
clrRed //
);
zonesInput.AddLevelColor(
hotLevels[1],
clrOrange //
);
zonesInput.AddLevelColor(
hotLevels[2],
clrLightCoral //
);
//
bool canUseZones = zones.Init(zonesInput);
if (canUseZones)
{
signal.zones = zones;
}
//
// Calculate Trend ...
XSCTrend *trend = new XSCTrend(
signal.symbol,
signal.period //
);
//
XSCTrendInput tInputs;
tInputs.Default();
bool canUseTrend = trend.Init(tInputs);
if (canUseTrend)
{
//
signal.trend = trend;
}
//
XSCCFInput cfInputs;
cfInputs.Default();
XSCCF *cf = new XSCCF(
signal.symbol,
signal.period //
);
bool canUseCF = cf.Init(cfInputs);
if (canUseCF)
{
signal.cf = cf;
}
//
// Generate Support Signals ...
// if (_useSupport)
// {
// //
// GenerateSupportSignals(
// signal //
// );
// }
//
return result;
}
//
void GenerateSupportSignals(
XSignal &signal // Source Signal for Support Generating ...
)
{
//
double pivots[];
int pivotsCount = GenerateSupportPivots(
signal,
pivots //
);
if (!IsValidSize(pivotsCount))
{
return;
}
//
XSignal supports[];
int indirectionalsCount =
PrepareInDirectionalSupportSignals(
supports,
signal,
pivots //
);
if (IsValidSize(indirectionalsCount))
{
//
Copy(
supports,
signal.supports //
);
//
Clean(supports);
}
}
//
int GenerateSupportPivots(
XSignal &signal, // Source Signal for Support Generating ...
double &pivots[] //
)
{
//
int result = 0;
//
// Validate Signal ...
if (!signal.IsValid())
{
return result;
}
//
// Retrieve Signal Direction ...
bool isLong = IsLong(signal.type);
//
bool canUseCF = signal.cf != NULL &&
signal.cf.IsValid();
bool canUseZones = signal.zones != NULL &&
signal.zones.IsValid();
bool canUseTrend = signal.trend != NULL &&
signal.trend.IsValid();
//
datetime prevTime = iTime(
signal.symbol,
signal.period,
1 //
);
//
datetime cTime = TimeCurrent();
//
string entryLineName = "sEntry" + signal.symbol;
DrawTrendLine(
0,
entryLineName,
0,
prevTime,
signal.entry,
cTime,
signal.entry,
clrYellow,
STYLE_SOLID,
2,
false,
false,
true //
);
//
Clean(pivots);
double tmpPivots[];
//
if (canUseCF)
{
//
signal.cf.Draw();
XOHCL cfBULLBar = signal.cf.GetBullishBar();
XOHCL cfBEARBar = signal.cf.GetBearishBar();
//
Add(
cfBULLBar.high,
tmpPivots //
);
Add(
cfBULLBar.low,
tmpPivots //
);
Add(
cfBEARBar.high,
tmpPivots //
);
Add(
cfBEARBar.low,
tmpPivots //
);
//
signal.cf.Remove();
}
//
if (canUseTrend)
{
//
signal.trend.Draw();
//
// Lows ...
Add(
signal.trend.GetLows(),
tmpPivots //
);
//
// Highs ...
Add(
signal.trend.GetHighs(),
tmpPivots //
);
//
// Support ...
Add(
signal.trend.GetSupport(),
tmpPivots //
);
//
// Resistance ...
Add(
signal.trend.GetResistance(),
tmpPivots //
);
//
signal.trend.Remove();
}
//
if (canUseZones)
{
//
signal.zones.Draw();
//
// Find Hot Zones ...
for (int i = 0; i < signal.zones.CountZones(); i++)
{
//
// Retrieve Indexed Zone ...
XSCZone *iZone = signal.zones.GetZone(i);
//
// Check Zone is Hot Zone or not ...
bool isHotZone = false;
for (int j = 0; j < ArraySize(hotLevels); j++)
{
//
isHotZone = (iZone.percent / 100) >= hotLevels[j];
if (isHotZone)
{
break;
}
}
//
// Prevent Moving Forward if there isn't Hot Zone ...
if (!isHotZone)
{
continue;
}
//
// Zone High ...
Add(
iZone.high,
tmpPivots //
);
//
// Zone Low ...
Add(
iZone.low,
tmpPivots //
);
}
//
signal.zones.Remove();
}
//
int tmpPivotsCount = ArraySize(tmpPivots);
if (!IsValidSize(tmpPivotsCount))
{
return result;
}
//
for (int i = 0; i < tmpPivotsCount; i++)
{
//
double iPivot = tmpPivots[i];
//
bool isValidPivot =
isLong
? signal.entry > iPivot
: signal.entry < iPivot;
if (isValidPivot)
{
//
Add(
iPivot,
pivots //
);
}
}
//
ArrayFree(tmpPivots);
//
RemoveDraws(entryLineName);
//
result = ArraySize(pivots);
//
return result;
}
//
bool PrepareDirectionalSupportSignals(
XPosition &support,
XPosition &parent,
XSignal &result //
)
{
//
bool mResult = false;
//
result.Clean();
//
mResult = support.IsValid() && parent.IsValid();
if (!mResult)
{
return mResult;
}
//
mResult = support.provider == XEQMSupportToken + XINDirectionalToken;
if (!mResult)
{
return mResult;
}
//
// Indirectional Supports Updated Using Directional ...
//
double entryPrice = GetEntry(
parent.symbol,
parent.type //
);
//
ENUM_X_ORDER_MODES rMode = X_ORDER_MODE_NOTHING;
bool isParentLong = IsLong(parent.type);
if (isParentLong)
{
//
if (entryPrice < parent.entry)
{
rMode = X_ORDER_MODE_STOP;
}
}
else
{
//
if (entryPrice > parent.entry)
{
rMode = X_ORDER_MODE_STOP;
}
}
//
mResult = rMode != X_ORDER_MODE_NOTHING;
if (!mResult)
{
return mResult;
}
//
mResult = result.Prepare(
parent.symbol,
XEQMSupportToken + XDirectionalToken,
parent.period,
parent.type,
rMode,
parent.entry,
parent.volume,
0,
0 //
);
//
if (mResult)
{
//
string comment = GenerateSupportTag(parent.ticket);
result.comment = comment;
}
else
{
result.Clean();
}
//
return mResult;
}
//
int PrepareInDirectionalSupportSignals(
XSignal &supports[],
XSignal &source,
double &pivots[] //
)
{
//
int result = 0;
//
Clean(supports);
//
int pivotsCount = ArraySize(pivots);
if (!IsValidSize(pivotsCount))
{
return result;
}
//
bool isLong = IsLong(source.type);
//
XSignal rSignal; // Recovery Signal ...
//
double rSL = 0; // Recovery Stop Loss ...
double rTP = 0; // Recovery Take Profit ...
double rEntry = 0; // Recovery Entry Point ...
double rVolume = 0; // Recovery Volume ...
ENUM_POSITION_TYPE rType; // Recovery Signal Type ...
ENUM_X_ORDER_MODES rMode; // Recovery Signal Mode ...
bool isSignalPrepared = false; // Check Signal Preparation Succeed ...
//
bool condition = false;
//
double onePointValue = PointToPrice(1, source.symbol);
//
double directionalVolumeMultiplier = 1;
double inDirectionalVolumeMultiplier = 2;
//
// if Long we are Looking for lower prices than
// entry price and vise verse ...
//
for (int i = 0; i < pivotsCount; i++)
{
//
double iPivot = pivots[i];
//
bool isValidPrice =
isLong
? source.entry > iPivot
: source.entry < iPivot;
if (!isValidPrice)
{
continue;
}
//
// InDirectional ...
if (isLong)
{
//
rType = POSITION_TYPE_SELL;
rMode = X_ORDER_MODE_STOP;
}
else
{
//
rType = POSITION_TYPE_BUY;
rMode = X_ORDER_MODE_STOP;
}
//
rEntry = iPivot;
rVolume = source.volume;
//
isSignalPrepared = rSignal.Prepare(
source.symbol,
XEQMSupportToken + XINDirectionalToken,
source.period,
rType,
rMode,
rEntry,
rVolume,
rSL,
rTP //
);
if (isSignalPrepared)
{
//
AddRef(
rSignal,
supports //
);
//
rSignal.Clean();
//
rSL = 0;
rTP = 0;
rEntry = 0;
isSignalPrepared = false;
}
}
//
result = ArraySize(supports);
// //
return result; return result;
} }
+177 -226
View File
@@ -153,16 +153,6 @@ struct XTradeInfo
lConditions = _lConditions; lConditions = _lConditions;
hConditions = _hConditions; hConditions = _hConditions;
//
X121SignalGenerator generator;
XSignal tSignal = _signal;
generator.GenerateSupportPivots(
tSignal,
pivots //
);
tSignal.Clean();
int pivotsCount = ArraySize(pivots);
// //
allowGrid = _allowGrid; allowGrid = _allowGrid;
allowRecover = _allowRecover; allowRecover = _allowRecover;
@@ -412,14 +402,11 @@ struct XTradeInfo
// Supporting ... // Supporting ...
// //
double pivots[];
bool allowSupport; // Allow Support bool allowSupport; // Allow Support
// //
void ResetSupport() void ResetSupport()
{ {
//
Clean(pivots);
allowSupport = false; allowSupport = false;
} }
@@ -432,158 +419,6 @@ struct XTradeInfo
// //
bool result = false; bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
int pivotsCount = ArraySize(pivots);
result = IsValidSize(pivotsCount);
if (!result)
{
return result;
}
//
support.Clean();
//
ENUM_POSITION_TYPE sType =
type == X_POSITION_TYPE_LONG
? POSITION_TYPE_BUY
: POSITION_TYPE_SELL;
//
bool isLong = IsLong(type);
//
ENUM_POSITION_TYPE cType = GetOpposit(sType);
double cEntry = GetEntry(
symbol,
cType //
);
//
double pivot = 0;
int pivotIndex = -1;
for (int i = 0; i < pivotsCount; i++)
{
//
double iPivot = pivots[i];
if (iPivot <= 0)
{
continue;
}
//
result =
isLong
? cEntry < entry && cEntry <= iPivot
: cEntry > entry && cEntry >= iPivot;
if (result)
{
//
pivot = iPivot;
pivotIndex = i;
break;
}
}
//
if (result)
{
//
result = support.Prepare(
symbol,
XEQMSupportToken + XINDirectionalToken,
period,
cType,
X_ORDER_MODE_MARKET,
cEntry,
volume * 2,
0,
0 //
);
if (result)
{
//
string comment = GenerateSupportTag(ticket);
support.comment = comment;
//
// Prepare Directional Support ...
XSignal mSup;
result = mSup.Prepare(
symbol,
XEQMSupportToken + XDirectionalToken,
period,
sType,
X_ORDER_MODE_STOP,
entry,
volume,
0,
0 //
);
if (result)
{
//
string comment = GenerateSupportTag(ticket);
mSup.comment = comment;
//
AddRef(
mSup,
support.supports //
);
//
result = ArrayRemove(
pivots,
pivotIndex,
1 //
);
}
}
}
//
if (!result)
{
support.Clean();
}
//
return result;
}
//
bool RemovePivot(
double pivot,
int index //
)
{
//
bool result = false;
//
result = IsValid() &&
IsValidIndex(index) &&
ArraySize(pivots) > index;
if (!result)
{
return result;
}
//
result = ArrayRemove(
pivots,
index,
1 //
);
// //
return result; return result;
} }
@@ -4675,24 +4510,12 @@ private:
// EQM Functions ... // EQM Functions ...
// //
bool DoEQMForceClose( // Force Close All Positions Due EQM Hedge ...
double requiredProfit = 0 // Required Profit For EQM Force Hedge ... bool DoEQMForceClose()
)
{ {
// //
bool result = false; bool result = false;
//
double hedgingProfit =
requiredProfit == 0
? mForceCloseProfit
: requiredProfit;
bool canDo = hedgingProfit > 0;
if (!canDo)
{
return result;
}
// //
XPosition positions[]; XPosition positions[];
int positionsCount = mTrader.GetPositions(positions); int positionsCount = mTrader.GetPositions(positions);
@@ -4706,12 +4529,6 @@ private:
double profit = SpecifiedCalculatePositionsProfit( double profit = SpecifiedCalculatePositionsProfit(
positions // positions //
); );
result =
profit > hedgingProfit;
if (!result)
{
return result;
}
// //
string comment = XEQMSupportToken + " Hedge ..."; string comment = XEQMSupportToken + " Hedge ...";
@@ -4722,6 +4539,12 @@ private:
// //
result = IsValidSize(closed); result = IsValidSize(closed);
if (result)
{
//
mTradeHandler.Sync();
EQMClearAllForceStates();
}
// //
// Handle Sleeping ... // Handle Sleeping ...
@@ -4799,24 +4622,7 @@ private:
if (!IsValidSize(positionsCount)) if (!IsValidSize(positionsCount))
{ {
// //
int setupsCount = CountSetups(); EQMClearAllForceStates();
if (IsValidSize(setupsCount))
{
//
for (int i = 0; i < setupsCount; i++)
{
mSetups[i].ForceState(false);
}
}
//
// Disable Force State if there isn't any open Positions
// and it's Enabled ...
// this means Hedged positions ...
// if (ForceState())
// {
// ForceState(false);
// }
// //
return; return;
@@ -4910,30 +4716,156 @@ private:
} }
// //
// bool isForce = forceCount > 1; bool isForce = forceCount >= 1;
// if (!ForceState() && isForce) if (!isForce || !IsValidSize(setupsCount))
// { {
// // return;
// ForceState(isForce); }
// return;
// }
// else if (ForceState() && !isForce)
// {
// //
// ForceState(isForce);
// return;
// }
// //
// // Handle Force State ...
// if (!ForceState())
// {
// return;
// }
// //
// TODO ...
// Here i Can Check what to do In Force State ... // Here i Can Check what to do In Force State ...
//
// Handle Hedging Based On Positions ...
double drawdown = GetDrawdownPercent();
double forceDrawdown = MaxDrawdownForce();
int positionsForce = MaxPositionsForce();
double forceCloseProfit = ForceCloseProfit();
double minRequiredProfitPerTrade = MinRequiredProfitPerTrade();
double minRequiredProfitPerVolumeFactor = MinRequiredProfitPerVolumeFactor();
//
// Try To Force Hedging ...
bool canForceHedge =
(positionsForce <= 0
? true
: positionsCount > positionsForce)
//
||
//
(forceDrawdown > 0 &&
drawdown >= forceDrawdown);
if (canForceHedge)
{
//
// Check Required Profit ...
//
double profit = SpecifiedCalculatePositionsProfit(positions);
//
// Check Force Close Profit ...
if (forceCloseProfit > 0)
{
//
canForceHedge = profit >= forceCloseProfit;
if (canForceHedge)
{
//
bool isHedged = DoEQMForceClose();
if (isHedged)
{
return;
}
}
}
//
// Calculate Required Profit ...
double requiredProfit = SpecifiedCalculateRequiredProfitForHedge(
positions,
minRequiredProfitPerTrade,
minRequiredProfitPerVolumeFactor //
);
//
canForceHedge =
requiredProfit <= 0
? profit > 0
: profit >= (requiredProfit / 2);
if (canForceHedge)
{
//
bool isHedged = DoEQMForceClose();
if (isHedged)
{
return;
}
}
//
// At Least Hedgeing ...
// Minimal Hedge ...
//
// Check Symbol Hedging ...
for (int i = 0; i < setupsCount; i++)
{
//
string iSymbol = mSetups[i].GetSymbol();
//
XPosition iSymbolPositions[];
int iSymbolPositionsCount = mTrader.GetPositions(
iSymbolPositions,
//
iSymbol,
NULL, // All Providers ...
NULL, // All Periods ...
NULL, // All Types ...
true // Filter By Magic ...
);
if (!IsValidSize(iSymbolPositionsCount))
{
continue;
}
//
double profit = SpecifiedCalculatePositionsProfit(iSymbolPositions);
//
double requiredProfit = SpecifiedCalculateRequiredProfitForHedge(
iSymbolPositions,
minRequiredProfitPerTrade,
minRequiredProfitPerVolumeFactor //
);
//
bool canHedge =
requiredProfit <= 0
? profit > 0
: profit >= requiredProfit;
if (canHedge)
{
//
string comment = XEQMSupportToken + " Hedge Symbol ...";
//
int closed = mTrader.Close(
iSymbolPositions,
comment //
);
//
if (closed == iSymbolPositionsCount)
{
//
mSetups[i].ForceState(false);
//
string message = XEQMSupportToken + " Hedge Symbol (" + iSymbol + "): " + ToString(profit);
Alert(message);
}
}
}
return;
}
//
// Implement Other Senarios ...
//
} }
// //
@@ -4954,13 +4886,15 @@ private:
// //
int setupIDX = FindSetupIndex(signal.symbol); int setupIDX = FindSetupIndex(signal.symbol);
if (!IsValidIndex(setupIDX)) { if (!IsValidIndex(setupIDX))
{
return; return;
} }
// //
bool isForce = mSetups[setupIDX].ForceState(); bool isForce = mSetups[setupIDX].ForceState();
if (!isForce) { if (!isForce)
{
return; return;
} }
@@ -5120,6 +5054,23 @@ private:
} }
} }
//
void EQMClearAllForceStates()
{
//
int setupsCount = CountSetups();
if (!IsValidSize(setupsCount))
{
return;
}
//
for (int i = 0; i < setupsCount; i++)
{
mSetups[i].ForceState(false);
}
}
// //
}; };
+4464 -3747
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -112,7 +112,7 @@ input double x121EAMaxAllowedRecoveryVolume = 0.08; // Max Allowed Recovery Sign
input group "Hedging"; input group "Hedging";
input int x121EARestingAfterHedge = 0; // Resting Seconds After Hedge input int x121EARestingAfterHedge = 0; // Resting Seconds After Hedge
input double x121EAForceCloseProfit = 15; // Close All Positions Regardless of Policies when Profit Reached input double x121EAForceCloseProfit = 15; // Close All Positions Regardless of Policies when Profit Reached
input double x121EAMaxDrawdownForce = 10; // Max Drawdown Force State for Handling Guards input double x121EAMaxDrawdownForce = 5; // Max Drawdown Force State for Handling Guards
input int x121EAMaxPositionsForce = 10; // Max Number of Positions Force State for Handling Guards input int x121EAMaxPositionsForce = 10; // Max Number of Positions Force State for Handling Guards
input double x121EAMinRequiredProfitPerTrade = 0.5; // Minimum Required Profit for Hedging input double x121EAMinRequiredProfitPerTrade = 0.5; // Minimum Required Profit for Hedging
input double x121EAMinRequiredProfitPerVolumeFactor = 0.01; // Minimum Required Profit for Hedging Per Volume input double x121EAMinRequiredProfitPerVolumeFactor = 0.01; // Minimum Required Profit for Hedging Per Volume
-6
View File
@@ -734,12 +734,6 @@ struct XSignal
// //
XSignal supports[]; // a Collecion of Support Signals ... XSignal supports[]; // a Collecion of Support Signals ...
//
// TODO: Temp ...
XSCZones *zones;
XSCTrend *trend;
XSCCF *cf;
// //
// Constructor ... // Constructor ...
XSignal() XSignal()