Fix Spread Passing for Signalling and Conditions Processing ...

This commit is contained in:
2024-12-09 23:04:42 +03:30
parent 317e8b8ba3
commit 812e468151
7 changed files with 475 additions and 282 deletions
+153
View File
@@ -0,0 +1,153 @@
/**
* Check Ticks is Bullish or not ...
*
* @return ( bool )
*/
bool IsTicksBullish()
{
//
bool result = false;
//
int start = -1;
int end = -1;
int requiredBullishTicks = 5;
CalculateTicksParams(
start,
end,
requiredBullishTicks //
);
result = IsValidIndex(start) &&
IsValidIndex(end);
if (!result)
{
return result;
}
//
result = true;
for (int i = start + 1; i < end; i++)
{
//
XTick iTick = mTicks[i];
XTick prevTick = mTicks[i - 1];
//
bool isBullish = iTick.bid >= prevTick.bid;
result = result && isBullish;
if (!result)
{
break;
}
}
//
return result;
}
/**
* Check Ticks is Bearish or not ...
*
* @return ( bool )
*/
bool IsTicksBearish()
{
//
bool result = false;
//
int start = -1;
int end = -1;
int requiredBearishTicks = 5;
CalculateTicksParams(
start,
end,
requiredBearishTicks //
);
result = IsValidIndex(start) &&
IsValidIndex(end);
if (!result)
{
return result;
}
//
result = true;
for (int i = start + 1; i < end; i++)
{
//
XTick iTick = mTicks[i];
XTick prevTick = mTicks[i - 1];
//
bool isBearish = iTick.bid <= prevTick.bid;
result = result && isBearish;
if (!result)
{
break;
}
}
//
return result;
}
/**
* Check Ticks Has Momentum or not ...
*
* @return ( bool )
*/
bool IsTicksHasMomentum()
{
//
bool result = false;
//
int start = -1;
int end = -1;
int requiredTicksForMomentum = 5;
CalculateTicksParams(
start,
end,
requiredTicksForMomentum //
);
result = IsValidIndex(start) &&
IsValidIndex(end);
if (!result)
{
return result;
}
//
result = true;
int lastDiff = 0;
for (int i = start + 1; i < end; i++)
{
//
XTick iTick = mTicks[i];
XTick prevTick = mTicks[i - 1];
//
int timeDiff = MathAbs((int)iTick.time - (int)prevTick.bid);
if (lastDiff <= 0)
{
lastDiff = timeDiff;
}
result = result && timeDiff >= lastDiff;
if (!result)
{
break;
}
//
lastDiff = timeDiff;
}
//
return result;
}
///////////////////////////////////////////////////////////////////////
+12 -12
View File
@@ -527,8 +527,8 @@ struct X121Conditions
bool isSarBearish; bool isSarBearish;
// //
bool isSarSwitchedBullish; bool isSarSwitchedToBullish;
bool isSarSwitchedBearish; bool isSarSwitchedToBearish;
// //
// XPV ... // XPV ...
@@ -735,8 +735,8 @@ struct X121Conditions
isSarBearish = false; isSarBearish = false;
// //
isSarSwitchedBullish = false; isSarSwitchedToBullish = false;
isSarSwitchedBearish = false; isSarSwitchedToBearish = false;
// //
// XPV ... // XPV ...
@@ -904,8 +904,8 @@ struct X121Conditions
// XSAR ... // XSAR ...
ToString("isSarBullish", isSarBullish, ignoreFalseConditions, separator) + ToString("isSarBullish", isSarBullish, ignoreFalseConditions, separator) +
ToString("isSarBearish", isSarBearish, ignoreFalseConditions, separator) + ToString("isSarBearish", isSarBearish, ignoreFalseConditions, separator) +
ToString("isSarSwitchedBullish", isSarSwitchedBullish, ignoreFalseConditions, separator) + ToString("isSarSwitchedToBullish", isSarSwitchedToBullish, ignoreFalseConditions, separator) +
ToString("isSarSwitchedBearish", isSarSwitchedBearish, ignoreFalseConditions, separator) + ToString("isSarSwitchedToBearish", isSarSwitchedToBearish, ignoreFalseConditions, separator) +
// //
// XPV ... // XPV ...
ToString("isNewPeak", isNewPeak, ignoreFalseConditions, separator) + ToString("isNewPeak", isNewPeak, ignoreFalseConditions, separator) +
@@ -3543,10 +3543,10 @@ class XCX121Helper : public XCBaseHelper
bool isSarBearishPrev = conditions.sarBuffer[pIndex] > pBar.high; bool isSarBearishPrev = conditions.sarBuffer[pIndex] > pBar.high;
// //
bool isSarSwitchedBullish = isSarBullish && bool isSarSwitchedToBullish = isSarBullish &&
!isSarBullishPrev; !isSarBullishPrev;
bool isSarSwitchedBearish = isSarBearish && bool isSarSwitchedToBearish = isSarBearish &&
!isSarBearishPrev; !isSarBearishPrev;
// //
// XPV ... // XPV ...
@@ -3710,8 +3710,8 @@ class XCX121Helper : public XCBaseHelper
// Set ... // Set ...
conditions.isSarBullish = isSarBullish; conditions.isSarBullish = isSarBullish;
conditions.isSarBearish = isSarBearish; conditions.isSarBearish = isSarBearish;
conditions.isSarSwitchedBullish = isSarSwitchedBullish; conditions.isSarSwitchedToBullish = isSarSwitchedToBullish;
conditions.isSarSwitchedBearish = isSarSwitchedBearish; conditions.isSarSwitchedToBearish = isSarSwitchedToBearish;
conditions.isNewPeak = isNewPeak; conditions.isNewPeak = isNewPeak;
conditions.isNewPeakOverLast = isNewPeakOverLast; conditions.isNewPeakOverLast = isNewPeakOverLast;
conditions.isNewPeakUnderLast = isNewPeakUnderLast; conditions.isNewPeakUnderLast = isNewPeakUnderLast;
+10 -29
View File
@@ -215,6 +215,7 @@ struct XTick
double bid; // Bid ... double bid; // Bid ...
double ask; // Ask ... double ask; // Ask ...
double spread; // Spread ... double spread; // Spread ...
long volume; // Volume ...
// //
// Constructor ... // Constructor ...
@@ -233,13 +234,15 @@ struct XTick
* @param _time: Time ... * @param _time: Time ...
* @param _bid: Bid Price ... * @param _bid: Bid Price ...
* @param _ask: Ask Price ... * @param _ask: Ask Price ...
* @param _volume: Tick Volume ...
*/ */
bool Init( bool Init(
string _symbol, string _symbol,
datetime _time, datetime _time,
double _bid, double _bid,
double _ask, double _ask,
double _spread // double _spread,
long _volume //
) )
{ {
// //
@@ -293,6 +296,7 @@ struct XTick
double _bid = GetBid(_symbol); double _bid = GetBid(_symbol);
double _ask = GetAsk(_symbol); double _ask = GetAsk(_symbol);
double _spread = GetSpread(_symbol); double _spread = GetSpread(_symbol);
long _volume = iTickVolume(_symbol, PERIOD_M1, 0);
// //
result = Init( result = Init(
@@ -300,39 +304,14 @@ struct XTick
_time, _time,
_bid, _bid,
_ask, _ask,
_spread // _spread,
_volume //
); );
// //
return result; return result;
} }
/**
* Init XTick for Specified Time ...
*
* @param _symbol: String, Symbol Representation ...
* @param _time: Datetime, Specified Time ...
*
* @return ( bool )
*/
bool Init(
string _symbol,
datetime _time //
)
{
//
bool result = false;
//
// TODO: Complete this ...
//
result = IsValid();
//
return result;
}
/** /**
* Cleanup ... * Cleanup ...
*/ */
@@ -341,6 +320,7 @@ struct XTick
// //
bid = 0; bid = 0;
ask = 0; ask = 0;
volume = 0;
time = NULL; time = NULL;
symbol = NULL; symbol = NULL;
} }
@@ -359,7 +339,8 @@ struct XTick
result = IsValid(symbol) && result = IsValid(symbol) &&
IsValid(time) && IsValid(time) &&
bid > 0 && bid > 0 &&
ask > 0; ask > 0 &&
volume >= 0;
// //
return result; return result;
@@ -235,6 +235,60 @@ class XCX121SMCBaseStrategy : public XCBaseAlert
mMaxAllowedSpread = value; mMaxAllowedSpread = value;
} }
/**
* Get Min Required Ticks Verification for Spread Pass ...
*
* @return ( int )
*/
int MinRequiredTicksForSpreadPass()
{
return mMinRequiredTicksForSpreadPass;
}
/**
* Set Min Required Ticks Verification for Spread Pass ...
*
* @param value: Integer ...
*/
void MinRequiredTicksForSpreadPass(int value)
{
//
if (value < 100)
{
value = 100;
}
//
mMinRequiredTicksForSpreadPass = value;
}
/**
* Get Max Allowed Save Ticks ...
*
* @return ( int )
*/
int MaxAllowedSaveTicks()
{
return mMaxAllowedSaveTicks;
}
/**
* Set Max Allowed Save Ticks ...
*
* @param value: Integer ...
*/
void MaxAllowedSaveTicks(int value)
{
//
if (value < 150)
{
value = 150;
}
//
mMaxAllowedSaveTicks = value;
}
/** /**
* Get Long Signalling State ... * Get Long Signalling State ...
* *
@@ -534,9 +588,9 @@ class XCX121SMCBaseStrategy : public XCBaseAlert
bool result = false; bool result = false;
// //
int length = 5;
double pointValue = GetPoints(mSymbol); double pointValue = GetPoints(mSymbol);
double maxAllowedSpread = MaxAllowedSpread(); double maxAllowedSpread = MaxAllowedSpread();
int minRequiredTicksVerification = MinRequiredTicksForSpreadPass();
if (maxAllowedSpread > 0) if (maxAllowedSpread > 0)
{ {
maxAllowedSpread *= pointValue; maxAllowedSpread *= pointValue;
@@ -546,193 +600,51 @@ class XCX121SMCBaseStrategy : public XCBaseAlert
maxAllowedSpread = 0; maxAllowedSpread = 0;
} }
//
result = maxAllowedSpread <= 0
? true
: minRequiredTicksVerification > 0;
if (!result)
{
return result;
}
// //
int ticksCount = ArraySize(mTicks); int ticksCount = ArraySize(mTicks);
if (ticksCount <= length) result = ticksCount >= minRequiredTicksVerification;
{
return result;
}
//
int start = -1;
int end = -1;
CalculateTicksParams(
start,
end,
length + 1 //
);
result = IsValidIndex(start) &&
IsValidIndex(end);
if (!result) if (!result)
{ {
return result; return result;
} }
// //
end -= 1; if (maxAllowedSpread > 0)
double spreadAVG = 0;
for (int i = start; i < end; i++)
{
spreadAVG += mTicks[i].spread;
}
spreadAVG /= length;
//
double lastSpread = mTicks[ticksCount - 1].spread;
//
result = lastSpread <= spreadAVG &&
(maxAllowedSpread <= 0
? true
: lastSpread <= maxAllowedSpread);
//
return result;
}
/**
* Check Ticks is Bullish or not ...
*
* @return ( bool )
*/
bool IsTicksBullish()
{
//
bool result = false;
//
int start = -1;
int end = -1;
int requiredBullishTicks = 5;
CalculateTicksParams(
start,
end,
requiredBullishTicks //
);
result = IsValidIndex(start) &&
IsValidIndex(end);
if (!result)
{
return result;
}
//
result = true;
for (int i = start + 1; i < end; i++)
{ {
// //
XTick iTick = mTicks[i]; int end = -1;
XTick prevTick = mTicks[i - 1]; int start = -1;
result = CalculateTicksParams(
// start,
bool isBullish = iTick.bid >= prevTick.bid; end,
result = result && isBullish; minRequiredTicksVerification //
if (!result) );
{ if (!result) {
break; return result;
}
}
//
return result;
}
/**
* Check Ticks is Bearish or not ...
*
* @return ( bool )
*/
bool IsTicksBearish()
{
//
bool result = false;
//
int start = -1;
int end = -1;
int requiredBearishTicks = 5;
CalculateTicksParams(
start,
end,
requiredBearishTicks //
);
result = IsValidIndex(start) &&
IsValidIndex(end);
if (!result)
{
return result;
}
//
result = true;
for (int i = start + 1; i < end; i++)
{
//
XTick iTick = mTicks[i];
XTick prevTick = mTicks[i - 1];
//
bool isBearish = iTick.bid <= prevTick.bid;
result = result && isBearish;
if (!result)
{
break;
}
}
//
return result;
}
/**
* Check Ticks Has Momentum or not ...
*
* @return ( bool )
*/
bool IsTicksHasMomentum()
{
//
bool result = false;
//
int start = -1;
int end = -1;
int requiredTicksForMomentum = 5;
CalculateTicksParams(
start,
end,
requiredTicksForMomentum //
);
result = IsValidIndex(start) &&
IsValidIndex(end);
if (!result)
{
return result;
}
//
result = true;
int lastDiff = 0;
for (int i = start + 1; i < end; i++)
{
//
XTick iTick = mTicks[i];
XTick prevTick = mTicks[i - 1];
//
int timeDiff = MathAbs((int)iTick.time - (int)prevTick.bid);
if (lastDiff <= 0)
{
lastDiff = timeDiff;
}
result = result && timeDiff >= lastDiff;
if (!result)
{
break;
} }
// //
lastDiff = timeDiff; for (int i = start; i < end; i++)
{
//
XTick iTick = mTicks[i];
//
result = iTick.spread <= maxAllowedSpread;
if (!result)
{
break;
}
}
} }
// //
@@ -1475,14 +1387,18 @@ class XCX121SMCBaseStrategy : public XCBaseAlert
// Props ... // Props ...
// //
string mSymbol; // Trading Symbol ... string mSymbol; // Trading Symbol ...
ENUM_TIMEFRAMES mPeriod; // Trading TimeFrame ... ENUM_TIMEFRAMES mPeriod; // Trading TimeFrame ...
bool mForceDisabled; // Force Disabled ... bool mForceDisabled; // Force Disabled ...
bool mAllowLong; // Allow Long Signals bool mAllowLong; // Allow Long Signals
bool mAllowShort; // Allow Short Signals bool mAllowShort; // Allow Short Signals
double mR2R; // Risk/Rewar Ratio ... double mR2R; // Risk/Rewar Ratio ...
double mVolume; // Static Volume Per Trades ... double mVolume; // Static Volume Per Trades ...
double mMaxAllowedSpread; // Max Allowed Spread ...
//
double mMaxAllowedSpread; // Max Allowed Spread ...
int mMinRequiredTicksForSpreadPass; // Min Required Ticks Verification for Spread Pass ...
int mMaxAllowedSaveTicks; // Max Allowed Save Ticks ...
// //
long mChartID; // Chart ID ... long mChartID; // Chart ID ...
@@ -1506,6 +1422,8 @@ class XCX121SMCBaseStrategy : public XCBaseAlert
// //
R2R(1); R2R(1);
Volume(0.01); Volume(0.01);
MaxAllowedSaveTicks(150);
MinRequiredTicksForSpreadPass(100);
// //
ChartIdentification(0); ChartIdentification(0);
@@ -1598,7 +1516,6 @@ class XCX121SMCBaseStrategy : public XCBaseAlert
mVisionDetector.MaxNumberOfRequiredPOIs(poiRequired); mVisionDetector.MaxNumberOfRequiredPOIs(poiRequired);
mVisionDetector.Init(); mVisionDetector.Init();
// //
} }
@@ -1636,7 +1553,7 @@ class XCX121SMCBaseStrategy : public XCBaseAlert
void CleanupTicks() void CleanupTicks()
{ {
// //
int maxRequiredTicks = 50; int maxRequiredTicks = MaxAllowedSaveTicks();
int ticksCount = ArraySize(mTicks); int ticksCount = ArraySize(mTicks);
if (!IsValidSize(ticksCount) || if (!IsValidSize(ticksCount) ||
ticksCount <= maxRequiredTicks) ticksCount <= maxRequiredTicks)
@@ -1686,12 +1603,15 @@ class XCX121SMCBaseStrategy : public XCBaseAlert
* @param end: Integer Reference to End ... * @param end: Integer Reference to End ...
* @param numOfLastTicks: Integer Max Number of Required N Last Ticks ... * @param numOfLastTicks: Integer Max Number of Required N Last Ticks ...
*/ */
void CalculateTicksParams( bool CalculateTicksParams(
int &start, int &start,
int &end, int &end,
int numOfLastTicks = 5 // int numOfLastTicks = 5 //
) )
{ {
//
bool result = 0;
// //
start = -1; start = -1;
end = -1; end = -1;
@@ -1712,6 +1632,13 @@ class XCX121SMCBaseStrategy : public XCBaseAlert
{ {
end = count; end = count;
} }
//
result = IsValidIndex(start) &&
IsValidIndex(end);
//
return result;
} }
// //
@@ -326,6 +326,16 @@ class XC121SMCCycleHelper : public XCBase
// //
result = conditions.IsValid(); result = conditions.IsValid();
//
if (result)
{
//
Calculate(
barIndex,
conditions //
);
}
// //
return result; return result;
} }
@@ -361,6 +371,7 @@ class XC121SMCCycleHelper : public XCBase
// //
double bid = GetBid(bar.symbol); double bid = GetBid(bar.symbol);
double ask = GetAsk(bar.symbol);
// //
// Retrieve X121 Cnditions ... // Retrieve X121 Cnditions ...
@@ -407,7 +418,9 @@ class XC121SMCCycleHelper : public XCBase
// //
// Check Zone is Valid For Bar ... // Check Zone is Valid For Bar ...
bool isValid = bar.high < iZone.Lower(); bool isValid = bar.high < iZone.Lower() &&
ask < iZone.Lower() &&
bid < iZone.Lower();
if (isValid) if (isValid)
{ {
// //
@@ -511,7 +524,9 @@ class XC121SMCCycleHelper : public XCBase
// //
// Check Zone is Valid For Bar ... // Check Zone is Valid For Bar ...
bool isValid = bar.low > iZone.Upper(); bool isValid = bar.low > iZone.Upper() &&
ask > iZone.Upper() &&
bid > iZone.Upper();
if (isValid) if (isValid)
{ {
// //
@@ -616,6 +631,121 @@ class XC121SMCCycleHelper : public XCBase
protected: protected:
// //
/**
* Calculate Requirements ...
*
* @param barIndex: Integer, Bar Index ...
* @param conditions: X121SMCCycleConditions instance ...
*/
void Calculate(
int barIndex,
X121SMCCycleConditions &conditions //
)
{
//
int index =
barIndex <= 0
? 1
: barIndex;
bool isInited = false;
string symbol = GetSymbol();
//
// Retrieve Bar ...
XOHCL bar;
isInited = GetBar(bar, index);
if (!isInited)
{
return;
}
//
// Retrieve Previous Bar ...
XOHCL pBar;
int pIndex = index + 1;
isInited = GetBar(pBar, pIndex);
if (!isInited)
{
return;
}
//
XTick xTick;
isInited = xTick.Init(symbol);
if (!isInited)
{
return;
}
//
bool isSarAttached =
bar.close > conditions.x121Conditions.sarBuffer[0];
if (isSarAttached)
{
Print("Sar Attached ...");
}
// //
// bool isSarBullish =
// conditions.x121Conditions.sarBuffer[index] < bar.low;
// bool isSarBullishPrev =
// conditions.x121Conditions.sarBuffer[pIndex] < pBar.low;
// //
// bool isSarBearish =
// conditions.x121Conditions.sarBuffer[index] > bar.high;
// bool isSarBearishPrev =
// conditions.x121Conditions.sarBuffer[pIndex] > pBar.high;
// //
// bool isSarSwitchedToBullish =
// isSarBullish &&
// !isSarBullishPrev &&
// isSarBearishPrev;
// //
// bool isSarSwitchedToBearish =
// isSarBearish &&
// !isSarBearishPrev &&
// isSarBullishPrev;
// //
// if (isSarSwitchedToBullish ||
// isSarSwitchedToBearish)
// {
// Print("Sar Switched ...");
// }
// //
// bool isSarBullish =
// conditions.x121Conditions.sarBuffer[1] < xTick.ask &&
// conditions.x121Conditions.sarBuffer[1] < xTick.bid &&
// conditions.x121Conditions.isSarBullish;
// //
// bool isSarBearish =
// conditions.x121Conditions.sarBuffer[1] > xTick.ask &&
// conditions.x121Conditions.sarBuffer[1] > xTick.bid &&
// conditions.x121Conditions.isSarBearish;
//
// Detect Sar Changes ...
// bool isSarChanged = (isSarBullish &&
// !isSarBearish) ||
// (isSarBearish &&
// !isSarBullish);
// if (isSarChanged)
// {
// Print("SarChaned");
// }
//
// Detect Peak Changes ...
//
// Detect Vale Changes ...
}
// //
private: private:
// //
@@ -1000,6 +1000,8 @@ class XC121SMCExpert : public XCBaseExpert
strategy.AllowLong(AllowLong()); strategy.AllowLong(AllowLong());
strategy.AllowShort(AllowShort()); strategy.AllowShort(AllowShort());
strategy.MaxAllowedSpread(20); strategy.MaxAllowedSpread(20);
strategy.MaxAllowedSaveTicks(150);
strategy.MinRequiredTicksForSpreadPass(100);
// //
if (Disabled()) if (Disabled())
@@ -123,15 +123,6 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
double pip = GetPipPrice(symbol); double pip = GetPipPrice(symbol);
double pip2 = 2 * pip; double pip2 = 2 * pip;
//
// Detect Conditions ...
result = DetectConditions(conditions);
if (!result)
{
conditions.Clean();
return result;
}
// //
// Check Spread ... // Check Spread ...
bool isSpreadPassed = IsSpreadPass(); bool isSpreadPassed = IsSpreadPass();
@@ -146,6 +137,15 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
return result; return result;
} }
//
// Detect Conditions ...
result = DetectConditions(conditions);
if (!result)
{
conditions.Clean();
return result;
}
// //
// Combine all Signals Conditions ... // Combine all Signals Conditions ...
selectedSL = conditions.sl; selectedSL = conditions.sl;
@@ -425,53 +425,53 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
} }
conditions.visionConditions.state = mVisionState; conditions.visionConditions.state = mVisionState;
// // //
// Detect Valid Supply and Demand Zones ... // // Detect Valid Supply and Demand Zones ...
XCSupplyZone *supplyZone; // XCSupplyZone *supplyZone;
XCDemandZone *demandZone; // XCDemandZone *demandZone;
result = mTriggerCycleHelper // result = mTriggerCycleHelper
.DetectValisSupplyZone( // .DetectValisSupplyZone(
cBar, // cBar,
supplyZone, // supplyZone,
demandZone // // demandZone //
); // );
if (!result) // if (!result)
{ // {
// // //
conditions.Clean(); // conditions.Clean();
return result; // return result;
} // }
// // //
supplyZone.To(cTime); // supplyZone.To(cTime);
XCSupplyZoneObject *iSupplyZoneObj; // XCSupplyZoneObject *iSupplyZoneObj;
result = mPOIDrawer.CreateSupplyZone( // result = mPOIDrawer.CreateSupplyZone(
supplyZone, // supplyZone,
iSupplyZoneObj // // iSupplyZoneObj //
); // );
if (!result) // if (!result)
{ // {
// // //
conditions.Clean(); // conditions.Clean();
return result; // return result;
} // }
// // //
demandZone.To(cTime); // demandZone.To(cTime);
XCDemandZoneObject *iDemandZoneObj; // XCDemandZoneObject *iDemandZoneObj;
result = mPOIDrawer.CreateDemandZone( // result = mPOIDrawer.CreateDemandZone(
demandZone, // demandZone,
iDemandZoneObj // // iDemandZoneObj //
); // );
if (!result) // if (!result)
{ // {
// // //
conditions.Clean(); // conditions.Clean();
return result; // return result;
} // }
// // //
Print("Supply and Demand Zone Created ..."); // Print("Supply and Demand Zone Created ...");
// //
if (!result) if (!result)