Last ...
This commit is contained in:
@@ -38,13 +38,13 @@ input string eaLogSuffix = ""; // Log Suffix
|
||||
//
|
||||
// Symbols ...
|
||||
input group "Symbols";
|
||||
input bool eaMultiSymbol = false; // Use Multi Symbol
|
||||
input string eaSymbols = "EURUSDb,GBPUSDb,USDJPYb,USDCHFb,DowJones30,XAUUSDb"; // Trading Symbols
|
||||
input bool eaMultiSymbol = false; // Use Multi Symbol
|
||||
input string eaSymbols = "EURUSDb,GBPUSDb,USDJPYb,USDCHFb"; // Trading Symbols
|
||||
|
||||
//
|
||||
// Volume ...
|
||||
input group "Volume";
|
||||
input double eaR2R = 2; // Risk to Reward Ratio
|
||||
input double eaR2R = 3; // Risk to Reward Ratio
|
||||
input bool eaUseDynamicVolume = false; // Use Dynamic Volume
|
||||
input double eaDynamicVolumeStep = 0.01; // Increase Volume Step
|
||||
input double eaDynamicVolumeBalanceFactor = 200; // Balance Factor for Generate Dynamic Volume
|
||||
|
||||
@@ -1235,6 +1235,15 @@ class XCX121Helper : public XCBaseHelper
|
||||
//
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve DON Chain Length ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int GetDonChainLength() {
|
||||
return mInputs.donchainLength;
|
||||
}
|
||||
|
||||
//
|
||||
// Implement Value Getters ...
|
||||
|
||||
@@ -3340,6 +3340,29 @@ struct XSymbolPositions
|
||||
//
|
||||
};
|
||||
|
||||
//
|
||||
struct XSymbolLastPosition {
|
||||
//
|
||||
string symbol;
|
||||
string provider;
|
||||
datetime time;
|
||||
|
||||
//
|
||||
XSymbolLastPosition() {
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
void Clean() {
|
||||
//
|
||||
time = NULL;
|
||||
symbol = NULL;
|
||||
provider = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// an Structure for Holding Positions Data ...
|
||||
struct XTradeData
|
||||
|
||||
@@ -743,6 +743,315 @@ class XC121SMCCycleHelper : public XCBase
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect XPV Based POI(s) ...
|
||||
*
|
||||
* @param barIndex: Start Bar Index ...
|
||||
* @param minRepetition: minimum Repeate of POI for Validation ...
|
||||
* @param requiredPivots: Number of Min Requirement POI(s) ...
|
||||
* @param pivotHelper: XC121SMCCycleHelper instance Pointer ...
|
||||
* @param orderFlow: XPVPivot instance Array Reference ...
|
||||
* @param orderFlowDirection: ENUM_X_DIRECTION member Reference which represents OrderFlow Direction ...
|
||||
* @param maxAllowedLoopbackBars: Integer, Max Allowed Loopback Bars ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool DetectOrderFlow(
|
||||
int barIndex,
|
||||
XPVPivot &orderFlow[], // OrderFlows ...
|
||||
ENUM_X_DIRECTION &orderFlowDirection, // Order Flow Direction ...
|
||||
int minRepetition = 0,
|
||||
int requiredPivots = 0,
|
||||
int maxAllowedLoopbackBars = 576 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
orderFlowDirection = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
if (maxAllowedLoopbackBars <= 0)
|
||||
{
|
||||
maxAllowedLoopbackBars = 1000;
|
||||
}
|
||||
|
||||
//
|
||||
if (minRepetition <= 0)
|
||||
{
|
||||
minRepetition = mX121Helper.GetDonChainLength();
|
||||
}
|
||||
|
||||
//
|
||||
if (requiredPivots <= 0)
|
||||
{
|
||||
requiredPivots = 3;
|
||||
}
|
||||
|
||||
//
|
||||
int start = barIndex;
|
||||
int end = start + maxAllowedLoopbackBars;
|
||||
|
||||
//
|
||||
Clean(orderFlow);
|
||||
|
||||
//
|
||||
result = minRepetition > 0 &&
|
||||
requiredPivots > 0;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string symbol = GetSymbol();
|
||||
ENUM_TIMEFRAMES period = GetPeriod();
|
||||
|
||||
//
|
||||
double peak = 0;
|
||||
XPVPivot peaks[];
|
||||
int peakRepeate = 0;
|
||||
int peakToBarIndex = 0;
|
||||
int peakFromBarIndex = 0;
|
||||
|
||||
//
|
||||
double vale = 0;
|
||||
XPVPivot vales[];
|
||||
int valeRepeate = 0;
|
||||
int valeToBarIndex = 0;
|
||||
int valeFromBarIndex = 0;
|
||||
|
||||
//
|
||||
bool canLookupPeak = true;
|
||||
bool canLookupVale = true;
|
||||
bool canLookup = true;
|
||||
while (canLookup)
|
||||
{
|
||||
//
|
||||
// Check Peak ...
|
||||
double iPeak = mX121Helper.GetPeak(barIndex);
|
||||
if (iPeak != peak)
|
||||
{
|
||||
//
|
||||
if (peak != 0 &&
|
||||
peakRepeate >= minRepetition)
|
||||
{
|
||||
//
|
||||
bool isExists = false;
|
||||
int count = ArraySize(peaks);
|
||||
if (IsValidSize(count))
|
||||
{
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XPVPivot iPivot = peaks[i];
|
||||
|
||||
//
|
||||
if (iPivot.upper == iPeak)
|
||||
{
|
||||
//
|
||||
isExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isExists)
|
||||
{
|
||||
//
|
||||
XPVPivot iPivot;
|
||||
|
||||
//
|
||||
iPivot.lower = 0;
|
||||
iPivot.upper = peak;
|
||||
iPivot.symbol = symbol;
|
||||
iPivot.period = period;
|
||||
iPivot.type = XPV_PEAK;
|
||||
iPivot.repetition = peakRepeate;
|
||||
iPivot.to = iTime(
|
||||
symbol,
|
||||
period,
|
||||
peakToBarIndex //
|
||||
);
|
||||
iPivot.from = iTime(
|
||||
symbol,
|
||||
period,
|
||||
peakFromBarIndex //
|
||||
);
|
||||
|
||||
//
|
||||
iPivot.lower = iPivot.CalculateLower();
|
||||
|
||||
//
|
||||
bool isValid = iPivot.IsValid();
|
||||
if (isValid)
|
||||
{
|
||||
//
|
||||
AddRef(
|
||||
iPivot,
|
||||
peaks //
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
peak = iPeak;
|
||||
peakRepeate = 0;
|
||||
peakFromBarIndex = 0;
|
||||
peakToBarIndex = barIndex;
|
||||
}
|
||||
else if (iPeak == peak)
|
||||
{
|
||||
//
|
||||
peakRepeate++;
|
||||
peakFromBarIndex = barIndex;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Vale ...
|
||||
double iVale = mX121Helper.GetVale(barIndex);
|
||||
if (iVale != vale)
|
||||
{
|
||||
//
|
||||
if (vale != 0 &&
|
||||
valeRepeate >= minRepetition)
|
||||
{
|
||||
//
|
||||
bool isExists = false;
|
||||
int count = ArraySize(vales);
|
||||
if (IsValidSize(count))
|
||||
{
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XPVPivot iPivot = vales[i];
|
||||
|
||||
//
|
||||
if (iPivot.lower == iVale)
|
||||
{
|
||||
//
|
||||
isExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isExists)
|
||||
{
|
||||
//
|
||||
XPVPivot iPivot;
|
||||
|
||||
//
|
||||
iPivot.upper = 0;
|
||||
iPivot.lower = vale;
|
||||
iPivot.symbol = symbol;
|
||||
iPivot.period = period;
|
||||
iPivot.type = XPV_VALE;
|
||||
iPivot.repetition = valeRepeate;
|
||||
iPivot.to = iTime(
|
||||
symbol,
|
||||
period,
|
||||
valeToBarIndex //
|
||||
);
|
||||
iPivot.from = iTime(
|
||||
symbol,
|
||||
period,
|
||||
valeFromBarIndex //
|
||||
);
|
||||
|
||||
//
|
||||
iPivot.upper = iPivot.CalculateUpper();
|
||||
|
||||
//
|
||||
bool isValid = iPivot.IsValid();
|
||||
if (isValid)
|
||||
{
|
||||
//
|
||||
AddRef(
|
||||
iPivot,
|
||||
vales //
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
vale = iVale;
|
||||
valeRepeate = 0;
|
||||
valeFromBarIndex = 0;
|
||||
valeToBarIndex = barIndex;
|
||||
}
|
||||
else if (iVale == vale)
|
||||
{
|
||||
//
|
||||
valeRepeate++;
|
||||
valeFromBarIndex = barIndex;
|
||||
}
|
||||
|
||||
//
|
||||
canLookupPeak = ArraySize(peaks) < requiredPivots;
|
||||
canLookupVale = ArraySize(vales) < requiredPivots;
|
||||
canLookup = barIndex < end &&
|
||||
(canLookupPeak ||
|
||||
canLookupVale);
|
||||
if (canLookup)
|
||||
{
|
||||
barIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = IsValidSize(ArraySize(peaks)) ||
|
||||
IsValidSize(ArraySize(vales));
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Order Flow ...
|
||||
Copy(
|
||||
peaks,
|
||||
orderFlow,
|
||||
false //
|
||||
);
|
||||
Copy(
|
||||
vales,
|
||||
orderFlow,
|
||||
false //
|
||||
);
|
||||
int count = ArraySize(orderFlow);
|
||||
result = IsValidSize(orderFlow);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Sort Pivots ...
|
||||
SortPivots(orderFlow);
|
||||
|
||||
//
|
||||
// Filter Broken Order Flows ...
|
||||
FilterBrokenPivots(orderFlow);
|
||||
|
||||
//
|
||||
// Detect Order Flow Direction ...
|
||||
result = DetectPivotDirection(
|
||||
orderFlow,
|
||||
orderFlowDirection //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Change Values Actions ...
|
||||
|
||||
|
||||
@@ -2666,6 +2666,29 @@ class XC121SMCTradeHandler : public XCBaseAlert
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (!youngestPosition.IsValid())
|
||||
{
|
||||
//
|
||||
int symbolIDX = FindLastExecutedSignalItem(signal);
|
||||
if (IsValidIndex(symbolIDX))
|
||||
{
|
||||
//
|
||||
datetime cTime = TimeCurrent();
|
||||
int signalPeriodSeconds = PeriodSeconds(signal.period);
|
||||
datetime lastExecutedTime = mLastExecutedSignals[symbolIDX].time;
|
||||
datetime passedTime = ((datetime)lastExecutedTime +
|
||||
((mDelayBarBetweenTwoSignal * signalPeriodSeconds)));
|
||||
|
||||
//
|
||||
result = cTime >= passedTime;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -2712,6 +2735,9 @@ class XC121SMCTradeHandler : public XCBaseAlert
|
||||
forceTrail //
|
||||
);
|
||||
|
||||
//
|
||||
HandleSignalExecuted(signal);
|
||||
|
||||
//
|
||||
string msg = (signal.type == POSITION_TYPE_BUY ? "Long" : "Short") +
|
||||
" Signal Provided by: " + signal.provider +
|
||||
@@ -3789,7 +3815,8 @@ class XC121SMCTradeHandler : public XCBaseAlert
|
||||
private:
|
||||
//
|
||||
// Props ...
|
||||
double mAdditionalVolume; // Volume Additional
|
||||
double mAdditionalVolume; // Volume Additional
|
||||
XSymbolLastPosition mLastExecutedSignals[]; // Last Executed Signals
|
||||
|
||||
//
|
||||
// Read Only ...
|
||||
@@ -4131,6 +4158,78 @@ class XC121SMCTradeHandler : public XCBaseAlert
|
||||
mCollector.SaveSignal(item);
|
||||
}
|
||||
|
||||
//
|
||||
int FindLastExecutedSignalItem(XSignal &signal)
|
||||
{
|
||||
//
|
||||
int result = -1;
|
||||
|
||||
//
|
||||
if (!signal.IsValid())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int count = ArraySize(mLastExecutedSignals);
|
||||
if (!IsValidSize(count))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XSymbolLastPosition iLast = mLastExecutedSignals[i];
|
||||
if (iLast.symbol == signal.symbol &&
|
||||
iLast.provider == signal.provider)
|
||||
{
|
||||
//
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
void HandleSignalExecuted(XSignal &signal)
|
||||
{
|
||||
//
|
||||
if (!signal.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
datetime cTime = TimeCurrent();
|
||||
int symbolIDX = FindLastExecutedSignalItem(signal);
|
||||
bool hasItem = IsValidIndex(symbolIDX);
|
||||
if (hasItem)
|
||||
{
|
||||
mLastExecutedSignals[symbolIDX].time = cTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
XSymbolLastPosition item;
|
||||
|
||||
//
|
||||
item.time = cTime;
|
||||
item.symbol = signal.symbol;
|
||||
item.provider = signal.provider;
|
||||
|
||||
//
|
||||
AddRef(
|
||||
item,
|
||||
mLastExecutedSignals //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
|
||||
@@ -563,7 +563,7 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
|
||||
//
|
||||
mTradeHandler.MaxAllowedSLToPause(0);
|
||||
mTradeHandler.DelayBarBetweenTwoSignal(240);
|
||||
mTradeHandler.DelayBarBetweenTwoSignal(60);
|
||||
mTradeHandler.MaxAllowedSLReachedPauseDelay(HoursToSeconds(24));
|
||||
|
||||
//
|
||||
|
||||
@@ -35,6 +35,7 @@ const string X121SMCStrategyToken = "X121SMC";
|
||||
|
||||
//
|
||||
const string X121SMCSMPVToken = "X121SMCSMPV";
|
||||
const string X121SMCRJBPVToken = "X121SMCRJBPV";
|
||||
const string X121SMCVWAPCToken = "X121SMCVWAPC";
|
||||
|
||||
//
|
||||
@@ -44,6 +45,7 @@ enum ENUM_X_121_SMC_PROVIDERS
|
||||
//
|
||||
X_121_SMC_PROVIDER_NONE,
|
||||
X_121_SMC_PROVIDER_SMPV,
|
||||
X_121_SMC_PROVIDER_RJBPV,
|
||||
X_121_SMC_PROVIDER_VWAPC,
|
||||
};
|
||||
|
||||
@@ -1856,6 +1858,11 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value)
|
||||
result = X121SMCSMPVToken;
|
||||
break;
|
||||
|
||||
//
|
||||
case X_121_SMC_PROVIDER_RJBPV:
|
||||
result = X121SMCRJBPVToken;
|
||||
break;
|
||||
|
||||
//
|
||||
case X_121_SMC_PROVIDER_VWAPC:
|
||||
result = X121SMCVWAPCToken;
|
||||
@@ -1889,6 +1896,10 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value)
|
||||
{
|
||||
result = X_121_SMC_PROVIDER_SMPV;
|
||||
}
|
||||
else if (Contains(X121SMCRJBPVToken, value))
|
||||
{
|
||||
result = X_121_SMC_PROVIDER_RJBPV;
|
||||
}
|
||||
else if (Contains(X121SMCVWAPCToken, value))
|
||||
{
|
||||
result = X_121_SMC_PROVIDER_VWAPC;
|
||||
@@ -1898,4 +1909,7 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value)
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Providers Conditions ...
|
||||
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user