This commit is contained in:
2024-06-26 18:04:28 +03:30
parent 2e365b2bc2
commit f048bd3d37
4 changed files with 814 additions and 165 deletions
+303 -135
View File
@@ -298,7 +298,29 @@ struct XTradeInfo
}
//
string ToString()
string GetSignalFileName()
{
//
string result = NULL;
//
result =
//
symbol + "\\" +
ToString(type) + "\\" +
provider + "_" +
ToFormatString(time)
//
;
//
return result;
}
//
string ToString(
bool onlySignals = false //
)
{
//
string result = NULL;
@@ -346,7 +368,9 @@ struct XTradeInfo
//
result =
//
ToString("Ticket", ticket) +
(onlySignals
? ""
: ToString("Ticket", ticket)) +
ToString("Symbol", symbol) +
ToString("Period", period) +
ToString("Entry", entry) +
@@ -354,14 +378,16 @@ struct XTradeInfo
ToString("Type", ToString(type)) +
ToString("Time", time) +
ToString("Pushers", pushers) +
"-------------" + "\n" +
ToString("Volume", volume) +
ToString("Profit", profit) +
ToString("Commission", commission) +
ToString("Swap", swap) +
ToString("End Time", endTime) +
ToString("Age", age) +
ToString("Message", message) +
(onlySignals
? ""
: "-------------" + "\n" +
ToString("Volume", volume) +
ToString("Profit", profit) +
ToString("Commission", commission) +
ToString("Swap", swap) +
ToString("End Time", endTime) +
ToString("Age", age) +
ToString("Message", message)) +
"-------------" + "\n" +
"Conditions" + "\n" +
"-------------" + "\n" +
@@ -932,6 +958,37 @@ public:
return result;
}
//
bool SaveSignal(XTradeInfo &item)
{
//
bool result = false;
//
string content = item.ToString();
result = IsValid(content);
if (!result)
{
return result;
}
//
int mHandler = GetSignalFileHandlerForWrite(item);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
FileWrite(mHandler, content);
FileFlush(mHandler);
FileClose(mHandler);
//
return result;
}
//
// Protected ...
protected:
@@ -964,7 +1021,32 @@ private:
//
result =
//
mPath + "\\" + fileName + ".x121.log"
mPath + "\\" + "Trades" + "\\" + fileName + ".x121.log"
//
;
//
return result;
}
//
string GetSignalFilePath(XTradeInfo &item)
{
//
string fileName = item.GetSignalFileName();
//
return GetSignalFilePath(fileName);
}
string GetSignalFilePath(string fileName)
{
//
string result = "";
//
result =
//
mPath + "\\" + "Signals" + "\\" + fileName + ".x121.log"
//
;
@@ -1015,6 +1097,50 @@ private:
//
return result;
}
//
int GetSignalFileHandlerForRead(XTradeInfo &item)
{
//
int result = INVALID_HANDLE;
//
string filePath = GetSignalFilePath(item);
if (!IsValid(filePath))
{
return result;
}
//
result = FileOpen(
filePath,
FILE_READ | FILE_TXT //
);
//
return result;
}
int GetSignalFileHandlerForWrite(XTradeInfo &item)
{
//
int result = INVALID_HANDLE;
//
string filePath = GetSignalFilePath(item);
if (!IsValid(filePath))
{
return result;
}
//
result = FileOpen(
filePath,
FILE_READ | FILE_WRITE | FILE_TXT //
);
//
return result;
}
};
//
@@ -1063,6 +1189,65 @@ public:
mSave = value;
}
//
bool GetSaveSignalsOnly()
{
return mSaveSignalsOnly;
}
//
void SetSaveSignalsOnly(bool value)
{
mSaveSignalsOnly = value;
}
//
// Hedging ...
//
double MinProfitPerTrade()
{
return mMinProfitPerTrade;
}
//
void MinProfitPerTrade(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mMinProfitPerTrade = value;
}
//
double MinProfitPerVolumeFactor()
{
return mMinProfitPerVolumeFactor;
}
//
void MinProfitPerVolumeFactor(double value)
{
//
if (value < 0)
{
value = 0;
}
//
if (value > 0 && value < 0.01)
{
value = 0.01;
}
//
mMinProfitPerVolumeFactor = value;
}
//
// Trailling Stop ...
@@ -1684,6 +1869,12 @@ public:
info,
data //
);
//
if (GetSaveSignalsOnly())
{
collector.SaveSignal(info);
}
}
//
@@ -2162,7 +2353,13 @@ protected:
XTradeInfoCollector *collector;
//
bool mSave; // Save Results ...
bool mSave; // Save Results ...
bool mSaveSignalsOnly; // Save Only Signals and COnditions
//
// Hedging ...
double mMinProfitPerTrade; // Minimum Required Profit for Hedging
double mMinProfitPerVolumeFactor; // Minimum Required Profit for Hedging Per Volume
//
// Trailling ...
@@ -3497,6 +3694,18 @@ public:
mTradeHandler.SetSave(value);
}
//
bool SaveSignalsOnly()
{
return mTradeHandler.GetSaveSignalsOnly();
}
//
void SaveSignalsOnly(bool value)
{
mTradeHandler.SetSaveSignalsOnly(value);
}
//
double MinFreeMargingForOpenTrades()
{
@@ -3516,6 +3725,37 @@ public:
mMinFreeMargingForOpenTrades = value;
}
//
// Hedging ...
//
double MinProfitPerTrade()
{
return mTradeHandler.MinProfitPerTrade();
}
//
void MinProfitPerTrade(double value)
{
//
MinRequiredProfitPerTrade(value);
mTradeHandler.MinProfitPerTrade(value);
}
//
double MinProfitPerVolumeFactor()
{
return mTradeHandler.MinProfitPerVolumeFactor();
}
//
void MinProfitPerVolumeFactor(double value)
{
//
MinRequiredProfitPerVolumeFactor(value);
mTradeHandler.MinProfitPerVolumeFactor(value);
}
//
// Overrides ...
@@ -4384,7 +4624,7 @@ public:
bool HandleStateManagement(XSignal &signals[]) override
{
//
const bool result = false;
bool result = false;
//
// Do all State Management here ...
@@ -4395,7 +4635,11 @@ public:
// Youngest Age of Positions longest as enough
// Make State of Signalling to Force State for Recieving
// Signal and Clear their Tp and SL for allowing hedges ...
EQMHandleForceState();
EQMHandleForceState(signals);
if (mForce)
{
result = true;
}
//
DoHedge();
@@ -4582,6 +4826,9 @@ protected:
//
Alert(message);
//
EQMHandleForceState(signals);
//
return;
}
@@ -4843,6 +5090,7 @@ private:
//
SaveResults(false);
SaveSignalsOnly(true);
}
//
@@ -4990,7 +5238,8 @@ private:
XSignal supports[];
int supportsCount = mTradeHandler.DoProtect(
supports,
mSetups);
mSetups //
);
//
if (IsValidSize(supportsCount))
@@ -5038,146 +5287,65 @@ private:
//
// Handle Force State Management ...
void EQMHandleForceState()
bool mForce;
void EQMHandleForceState(XSignal &forceSignals[])
{
//
// Validate Force Marigin ...
double marigin = mTrader.mAccount.GetMargin();
double minFreeMarigin = MinFreeMargingForOpenTrades();
double forceMargin = 3 * minFreeMarigin; // TODO: Make It Configurable
//
// Retrieving Positions ...
XPosition positions[];
int positionsCount = mTrader.GetPositions(positions);
if (!IsValidSize(positionsCount) || positionsCount <= 4)
if (!IsValidSize(positionsCount))
{
return;
}
//
double minRequiredProfitPerTrade = MinRequiredProfitPerTrade();
double minRequiredProfitPerVolumeFactor = MinRequiredProfitPerVolumeFactor();
XPosition oldest;
int oldestAge = GetOldest(
oldest,
positions //
);
//
mForce = marigin >= forceMargin && oldestAge >= 288;
if (!mForce)
{
return;
}
//
double minProfitPerTrade = MinProfitPerTrade();
double minProfitPerVolumeFactor = MinProfitPerVolumeFactor();
//
double profit = SpecifiedCalculatePositionsProfit(positions);
double requiredProfit = SpecifiedCalculateRequiredProfitForHedge(
positions,
minRequiredProfitPerTrade,
minRequiredProfitPerVolumeFactor //
minProfitPerTrade,
minProfitPerVolumeFactor //
);
//
bool canClose =
profit > 0 &&
(profit == requiredProfit ||
profit >= requiredProfit / 2);
if (canClose) {
DoEQMForceClose();
XSymbolPositions symbolPositions[];
int symbolPositionsCount = ExtractSymbolPositions(
positions,
symbolPositions,
minProfitPerTrade,
minProfitPerVolumeFactor //
);
if (!IsValidSize(symbolPositionsCount))
{
return;
}
return;
// //
// XPosition positions[];
// int positionsCount = mTrader.GetPositions(positions);
// if (!IsValidSize(positionsCount))
// {
// //
// EQMClearAllForceStates();
// //
// return;
// }
// //
// // Search For Force State Per Each Setup ...
// //
// int forceCount = 0;
// int setupsCount = CountSetups();
// if (IsValidSize(setupsCount))
// {
// //
// int maxAllowed = MaxAllowedTrades();
// bool perDirection = UseMaxAllowedPerDirection();
// //
// for (int i = 0; i < setupsCount; i++)
// {
// //
// string iSymbol = mSetups[i].GetSymbol();
// ENUM_TIMEFRAMES iPeriod = mSetups[i].GetPeriod();
// //
// XPosition iPositions[];
// int iPositionsCount = mTrader.GetPositions(
// iPositions,
// iSymbol,
// NULL, // All Providers ...
// NULL, // All Periods ...
// NULL, // All Types ...
// true // Filter By Magic ...
// );
// if (!IsValidSize(iPositionsCount))
// {
// continue;
// }
// //
// // Counting Positions ...
// int longs;
// double longProfits;
// double longVolumes;
// //
// int shorts;
// double shortProfits;
// double shortVolumes;
// //
// CountPositions(
// iPositions,
// //
// longs,
// longProfits,
// longVolumes,
// //
// shorts,
// shortProfits,
// shortVolumes //
// );
// //
// bool isMaxReached =
// maxAllowed <= 0
// ? false
// : !perDirection
// ? longs + shorts >= maxAllowed
// : longs >= maxAllowed && shorts >= maxAllowed;
// double volumeSummary = longVolumes + shortVolumes;
// double profitsSummary = longProfits + shortProfits;
// //
// bool isIInForce =
// //
// maxAllowed <= 0
// ? profitsSummary < 0 &&
// longVolumes == shortVolumes
// : isMaxReached &&
// profitsSummary < 0 &&
// longVolumes == shortVolumes
// //
// ;
// if (isIInForce)
// {
// //
// forceCount++;
// mSetups[i].ForceState(true);
// }
// }
// }
// //
// bool isForce = forceCount >= 1;
// if (!isForce)
// {
// return;
// }
//
Log("symbolPositionsCount: " + ToString(symbolPositionsCount));
}
//
+206
View File
@@ -4866,3 +4866,209 @@ int pivotsCount = ArraySize(pivots);
}
}
}
////////////////////////////////////////////////////////////////////////////////////
void EQMHandleForceState()
{
//
XPosition positions[];
int positionsCount = mTrader.GetPositions(positions);
if (!IsValidSize(positionsCount) || positionsCount <= 4)
{
return;
}
//
double minRequiredProfitPerTrade = MinRequiredProfitPerTrade();
double minRequiredProfitPerVolumeFactor = MinRequiredProfitPerVolumeFactor();
//
double profit = SpecifiedCalculatePositionsProfit(positions);
double requiredProfit = SpecifiedCalculateRequiredProfitForHedge(
positions,
minRequiredProfitPerTrade,
minRequiredProfitPerVolumeFactor //
);
//
bool canClose =
profit > 0 &&
(profit == requiredProfit ||
profit >= requiredProfit / 2);
if (canClose)
{
DoEQMForceClose();
}
return;
// //
// XPosition positions[];
// int positionsCount = mTrader.GetPositions(positions);
// if (!IsValidSize(positionsCount))
// {
// //
// EQMClearAllForceStates();
// //
// return;
// }
// //
// // Search For Force State Per Each Setup ...
// //
// int forceCount = 0;
// int setupsCount = CountSetups();
// if (IsValidSize(setupsCount))
// {
// //
// int maxAllowed = MaxAllowedTrades();
// bool perDirection = UseMaxAllowedPerDirection();
// //
// for (int i = 0; i < setupsCount; i++)
// {
// //
// string iSymbol = mSetups[i].GetSymbol();
// ENUM_TIMEFRAMES iPeriod = mSetups[i].GetPeriod();
// //
// XPosition iPositions[];
// int iPositionsCount = mTrader.GetPositions(
// iPositions,
// iSymbol,
// NULL, // All Providers ...
// NULL, // All Periods ...
// NULL, // All Types ...
// true // Filter By Magic ...
// );
// if (!IsValidSize(iPositionsCount))
// {
// continue;
// }
// //
// // Counting Positions ...
// int longs;
// double longProfits;
// double longVolumes;
// //
// int shorts;
// double shortProfits;
// double shortVolumes;
// //
// CountPositions(
// iPositions,
// //
// longs,
// longProfits,
// longVolumes,
// //
// shorts,
// shortProfits,
// shortVolumes //
// );
// //
// bool isMaxReached =
// maxAllowed <= 0
// ? false
// : !perDirection
// ? longs + shorts >= maxAllowed
// : longs >= maxAllowed && shorts >= maxAllowed;
// double volumeSummary = longVolumes + shortVolumes;
// double profitsSummary = longProfits + shortProfits;
// //
// bool isIInForce =
// //
// maxAllowed <= 0
// ? profitsSummary < 0 &&
// longVolumes == shortVolumes
// : isMaxReached &&
// profitsSummary < 0 &&
// longVolumes == shortVolumes
// //
// ;
// if (isIInForce)
// {
// //
// forceCount++;
// mSetups[i].ForceState(true);
// }
// }
// }
// //
// bool isForce = forceCount >= 1;
// if (!isForce)
// {
// return;
// }
//
}
//
void EQMHandleForceSignals(
XSignal &signals[] //
)
{
//
// Validate Signals Count ...
int signalsCount = ArraySize(signals);
if (!IsValidSize(signalsCount))
{
return;
}
//
// Validate Force Marigin ...
double marigin = mTrader.mAccount.GetMargin();
double forceMargin = 100; // TODO: Make It Configurable
bool isInForceMarigin = marigin >= forceMargin;
if (!isInForceMarigin)
{
return;
}
//
// Now we are Sure we in Force State Margin amd we Have Signals ...
//
// here we Must Symbol Categorized Positions ...
int setupsCount = CountSetups();
if (!IsValidSize(setupsCount))
{
return;
}
//
// Retrieving Positions ...
XPosition positions[];
int positionsCount = mTrader.GetPositions(positions);
if (!IsValidSize(positionsCount))
{
return;
}
//
XSymbolPositions symbolPositions[];
int symbolPositionsCount = ExtractSymbolPositions(
positions,
symbolPositions //
);
if (!IsValidSize(symbolPositionsCount))
{
return;
}
//
Log("symbolPositionsCount: " + ToString(symbolPositionsCount));
//
}
+14 -14
View File
@@ -44,15 +44,15 @@ input group "Signals";
//,USDCHFb,EURCHFb,USDJPYb,EURJPYb,GBPUSDb
// EURUSDb,USDCHFb,EURCHFb,USDJPYb,EURJPYb,GBPUSDb
// EURUSDb,USDCHFb,EURCHFb,USDJPYb,EURJPYb,GBPUSDb,XAUUSDb,NZDUSDb,AUDUSDb,USDCADb,BTCUSD,ETHUSD
input string x121EASymbols = "USDCHFb,EURCHFb,USDJPYb,EURJPYb,GBPUSDb"; // Symbols
input bool x121EAUseAllSymbols = false; // Use All Available Symbols
input bool x121EAUseAllWatchListSymbols = false; // Use All WatchList Symbols
input bool x121EAAllowLong = true; // Allow Long Trades
input bool x121EAAllowShort = true; // Allow Short Trades
input bool x121EAExecuteSignalsOnBreakout = false; // Execute Signals On Breakouts
input int x121EADelayBetweenTwoSignal = 10; // Delay Between two Same Signals
input int x121EAReuiredSignalVerifications = 3; // Required Verifications for Signals
input bool x121EAGetVerificationFromOtherTimeFrames = true; // Get Verifications from Other Time Frames
input string x121EASymbols = "EURUSDb,USDCHFb,EURCHFb,USDJPYb,EURJPYb,GBPUSDb"; // Symbols
input bool x121EAUseAllSymbols = false; // Use All Available Symbols
input bool x121EAUseAllWatchListSymbols = false; // Use All WatchList Symbols
input bool x121EAAllowLong = true; // Allow Long Trades
input bool x121EAAllowShort = true; // Allow Short Trades
input bool x121EAExecuteSignalsOnBreakout = false; // Execute Signals On Breakouts
input int x121EADelayBetweenTwoSignal = 10; // Delay Between two Same Signals
input int x121EAReuiredSignalVerifications = 3; // Required Verifications for Signals
input bool x121EAGetVerificationFromOtherTimeFrames = true; // Get Verifications from Other Time Frames
//
// Risk Management ...
@@ -60,8 +60,8 @@ input group "Risk Management";
input double x121EAVolume = 0.01; // Static Volume
input double x121EATPPoint = 1000; // TP Point
input double x121EASLPoint = 1000; // SL Point
input int x121EAMaxAllowedTrades = 2; // Max Allowed Positions Per Symbol
input int x121EAMinFreeMargingForOpenTrades = 500; // Min Margin For Opening Trades
input int x121EAMaxAllowedTrades = 0; // Max Allowed Positions Per Symbol
input int x121EAMinFreeMargingForOpenTrades = 50; // Min Margin For Opening Trades
input bool x121EAUseMaxAllowedPerDirection = true; // Use Max Allowed Positions Per Direction
input bool x121EAIgnoreSL = true; // Ignore Calculated SL
input bool x121EAIgnoreTP = true; // Ignore Calculated TP
@@ -377,8 +377,8 @@ bool InitialEA()
//
// Hedging ...
x121EA.RestingAfterHedge(x121EARestingAfterHedge);
x121EA.MinRequiredProfitPerTrade(x121EAMinRequiredProfitPerTrade);
x121EA.MinRequiredProfitPerVolumeFactor(x121EAMinRequiredProfitPerVolumeFactor);
x121EA.MinProfitPerTrade(x121EAMinRequiredProfitPerTrade);
x121EA.MinProfitPerVolumeFactor(x121EAMinRequiredProfitPerVolumeFactor);
//
// Alert ...
@@ -438,7 +438,7 @@ void X121PreConfigureStyles(X121SetupInputs &inputs)
//
// XATSL ...
inputs.atslInputs.show = true;
inputs.atslInputs.show = false;
//
// XSLN ...
+291 -16
View File
@@ -637,12 +637,12 @@ struct XPosition
//
// Check Items Passed Specific Filters or not ...
bool IsFiltersPassed(
string mSymbol = NULL, // Trading Symbol
string mProvider = NULL, // Signal Provider
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe
string mSymbol = NULL, // Trading Symbol
string mProvider = NULL, // Signal Provider
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe
ENUM_X_POSITION_TYPES mType = NULL, // Long (Buy), Short (Sell)
ulong mMagic = NULL, // Magic Number
bool mFilterByMagic = true // Get Only Self Open Positions
ulong mMagic = NULL, // Magic Number
bool mFilterByMagic = true // Get Only Self Open Positions
)
{
//
@@ -1922,13 +1922,13 @@ struct XOrder
//
// Check Items Passed Specific Filters or not ...
bool IsFiltersPassed(
string mSymbol = NULL, // Trading Symbol
string mProvider = NULL, // Signal Provider
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe
string mSymbol = NULL, // Trading Symbol
string mProvider = NULL, // Signal Provider
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe
ENUM_X_POSITION_TYPES mType = NULL, // Long (Buy), Short (Sell)
ENUM_ORDER_STATE mState = NULL, // Order State
ulong mMagic = NULL, // Magic Number
bool mFilterByMagic = true // Get Only Self Open Positions
ENUM_ORDER_STATE mState = NULL, // Order State
ulong mMagic = NULL, // Magic Number
bool mFilterByMagic = true // Get Only Self Open Positions
)
{
//
@@ -2476,7 +2476,7 @@ struct XGuard
string symbol; // Trading Symbol ...
string provider; // Signal Provider ...
ENUM_TIMEFRAMES period; // Trading Timeframe ...
ENUM_X_POSITION_TYPES type; // Position Type ...
ENUM_X_POSITION_TYPES type; // Position Type ...
ENUM_X_GUARD_ACTIONS action; // Which Action to Do ...
//
@@ -2496,11 +2496,11 @@ struct XGuard
//
// Global Initializer ...
bool Init(
string mSymbol, // Trading Symbol ...
ENUM_TIMEFRAMES mPeriod, // Trading Timeframe ...
ENUM_X_GUARD_ACTIONS mAction, // Which Action to Do ...
string mSymbol, // Trading Symbol ...
ENUM_TIMEFRAMES mPeriod, // Trading Timeframe ...
ENUM_X_GUARD_ACTIONS mAction, // Which Action to Do ...
ENUM_X_POSITION_TYPES mType = NULL, // Position Type ...
string mProvider = NULL, // Signal Provider ...
string mProvider = NULL, // Signal Provider ...
double mDblPayLoad = NULL,
string mStrPayload = NULL //
)
@@ -2773,6 +2773,161 @@ struct XTrail
}
};
//
struct XSymbolPositions
{
//
string symbol;
//
double profit;
double longsProfit;
double shortsProfit;
//
double volume;
double longsVolume;
double shortsVolume;
//
double requiredProfitForHedge;
//
XPosition longs[];
XPosition shorts[];
XPosition positions[];
//
XSymbolPositions()
{
Clean();
}
//
bool Update(
double mMinProfitPerTrade,
double mMinProfitPerVolumeFactor //
)
{
//
bool result = false;
//
bool hasChild = HasChild();
if (!hasChild)
{
return result;
}
//
// Extract Types ...
ExtractPositions(
positions,
longs,
shorts //
);
//
int numOfLongs = 0;
int numOfShorts = 0;
CountPositions(
positions,
numOfLongs,
longsProfit,
longsVolume,
numOfShorts,
shortsProfit,
shortsVolume //
);
//
profit = longsProfit + shortsProfit;
volume = longsVolume + shortsVolume;
requiredProfitForHedge = SpecifiedCalculateRequiredProfitForHedge(
positions,
mMinProfitPerTrade,
mMinProfitPerVolumeFactor //
);
//
return result;
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
symbol = NULL;
//
profit = 0;
longsProfit = 0;
shortsProfit = 0;
//
volume = 0;
longsVolume = 0;
shortsVolume = 0;
//
requiredProfitForHedge = 0;
//
Clean(longs);
Clean(shorts);
Clean(positions);
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result = IsValid(symbol);
//
return result;
}
//
// Has Child ...
bool HasChild()
{
//
bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
int count = Count();
result = IsValidSize(count);
//
return result;
}
//
// Count ...
int Count()
{
return ArraySize(positions);
}
//
};
//
// TypeDefs ...
@@ -4646,6 +4801,126 @@ void ExtractPositions(
}
}
//
int FindSymbolIndex(
string mSymbol,
XSymbolPositions &mItems[] //
)
{
//
int result = -1;
//
if (!IsValid(mSymbol))
{
return result;
}
//
int count = ArraySize(mItems);
if (!IsValidSize(count))
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
XSymbolPositions iItem = mItems[i];
//
if (iItem.symbol == mSymbol)
{
//
result = i;
break;
}
}
//
return result;
}
//
int ExtractSymbolPositions(
XPosition &positions[],
XSymbolPositions &items[], // Holds Result
double mMinProfitPerTrade,
double mMinProfitPerVolumeFactor //
)
{
//
int result = 0;
//
int positionsCount = ArraySize(positions);
if (!IsValidSize(positionsCount))
{
return result;
}
//
Clean(items);
//
for (int i = 0; i < positionsCount; i++)
{
//
XPosition iPosition = positions[i];
//
if (!iPosition.IsValid())
{
continue;
}
//
int itemIDX = FindSymbolIndex(
iPosition.symbol,
items //
);
if (!IsValidIndex(itemIDX))
{
//
// Add New One ...
XSymbolPositions item;
item.symbol = iPosition.symbol;
//
AddRef(
item,
items //
);
itemIDX = FindSymbolIndex(iPosition.symbol, items);
}
//
AddRef(
iPosition,
items[itemIDX].positions //
);
}
//
result = ArraySize(items);
if (IsValidSize(result))
{
//
for (int i = 0; i < result; i++)
{
//
items[i].Update(
mMinProfitPerTrade,
mMinProfitPerVolumeFactor //
);
}
}
//
return result;
}
//
// Custom Drawings ...
bool DrawTrendState(