This commit is contained in:
2025-04-13 22:16:17 +03:30
parent 1d91d3be1b
commit ab6ddf0b43
6 changed files with 1768 additions and 55 deletions
@@ -0,0 +1,693 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCXSTRCCITradeManager
// Description: provides all Requirements for Managing Trades ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-alert.class.mq5"
#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5"
#include "../../Classes/x-saherelm.x-trade.class.mq5"
#include "../Libraries/xstrcci.signaller.lib.mq5"
//
// Definitions ...
//
enum ENUM_XSTRCCI_TRADE_FINALIZATION
{
XSTRCCI_TRADE_FINAL_NONE,
XSTRCCI_TRADE_FINAL_TP,
XSTRCCI_TRADE_FINAL_SL,
XSTRCCI_TRADE_FINAL_CLOSE_IN_PROFIT,
XSTRCCI_TRADE_FINAL_CLOSE_IN_LOSE,
};
//
struct XSTRCCITrade
{
//
// Props ...
double swap;
double profit;
XSignal signal;
ulong positionID;
double commission;
XSTRCCIStrategyConditions conditions;
ENUM_XSTRCCI_TRADE_FINALIZATION finalize;
//
// Constructor ...
XSTRCCITrade()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
swap = 0;
profit = 0;
signal.Clean();
commission = 0;
positionID = 0;
conditions.Clean();
finalize = XSTRCCI_TRADE_FINAL_NONE;
//
ZeroMemory(this);
}
/**
* Check Has Signal ...
*
* @return ( bool )
*/
bool HasSignal()
{
//
bool result = false;
//
result = signal.IsValid();
//
return result;
}
/**
* Check Signal Executed or Not ...
*
* @return ( bool )
*/
bool IsExecuted()
{
//
bool result = false;
//
result = positionID > 0;
//
return result;
}
/**
* Check a Trade is Finalized or not ...
*
* @return ( bool )
*/
bool IsFinalized()
{
//
bool result = false;
//
result = HasSignal() &&
IsExecuted() &&
finalize != XSTRCCI_TRADE_FINAL_NONE;
//
return result;
}
};
//
// Implementations ...
class XCXSTRCCITradeManager : public XCBaseAlert
{
//
// Public ...
public:
//
// Props ...
XCTrade *trader;
bool drawSignal;
XCPOIDrawer *drawer;
//
// Constructors ...
XCXSTRCCITradeManager(XCTrade *&_trader)
{
//
trader = _trader;
drawSignal = true;
drawer = new XCPOIDrawer();
}
//
// De Constructors ...
~XCXSTRCCITradeManager()
{
//
ZeroMemory(trader);
ZeroMemory(drawer);
}
//
// Tools ...
/**
* Do All Position Managing Senaros ...
*/
void Manage()
{
//
bool has = HasChild(trades);
if (!has)
{
return;
}
//
int count = ArraySize(trades);
for (int i = 0; i < count; i++)
{
//
has = trades[i].IsExecuted() &&
!trades[i].IsFinalized();
if (!has)
{
continue;
}
//
XPosition iPosition;
has = trader.GetPosition(
trades[i].positionID,
iPosition //
);
if (!has)
{
continue;
}
//
// Update Trade Data ...
trades[i].swap = iPosition.swap;
trades[i].profit = iPosition.profit;
}
//
// After Update All Trades we can Do Protection ...
Protect();
}
/**
* Do All Position Protection Here ...
*/
void Protect()
{
//
bool has = HasChild(trades);
if (!has)
{
return;
}
//
XPosition ownPosition[];
XPosition ownLongPosition[];
XPosition ownShortPosition[];
//
int count = ArraySize(trades);
for (int i = 0; i < count; i++)
{
//
has =
trades[i].IsExecuted() &&
!trades[i].IsFinalized();
if (!has)
{
continue;
}
//
XPosition iPosition;
has = trader.GetPosition(
trades[i].positionID,
iPosition //
);
if (!has)
{
continue;
}
//
AddRef(
iPosition,
ownPosition //
);
//
if (IsLong(iPosition.type))
{
//
AddRef(
iPosition,
ownLongPosition //
);
}
else
{
//
AddRef(
iPosition,
ownShortPosition //
);
}
}
//
has = HasChild(ownPosition);
if (!has)
{
//
Clean(ownPosition);
Clean(ownLongPosition);
Clean(ownShortPosition);
//
return;
}
//
double swapSum = 0;
double profitSum = 0;
double commissionSum = 0;
//
// Calculate Required Data On Collection ...
count = ArraySize(ownPosition);
for (int i = 0; i < count; i++)
{
//
XPosition iPosition = ownPosition[i];
//
swapSum += iPosition.swap;
profitSum += iPosition.profit;
commissionSum += iPosition.commission;
}
//
// Do Collection Protectiong ...
// TODO: Implement this ...
//
// Do Signle Protections ...
for (int i = 0; i < count; i++)
{
//
// Select Position ...
XPosition iPosition = ownPosition[i];
//
// Handle RF ...
}
}
/**
* Execute Specified Signal ...
*
* @param signal: XSignal instance reference ...
* @param conditions: XSTRCCIStrategyConditions instance reference ...
*
* @return ( bool )
*/
bool Execute(
XSignal &signal,
XSTRCCIStrategyConditions &conditions //
)
{
//
bool result = false;
//
result = signal.IsValid();
if (!result)
{
return result;
}
//
int idx = -1;
bool isExists = HasTrade(
idx,
signal //
);
result = !isExists;
if (!result)
{
return result;
}
//
ENUM_X_SIGNAL_EXECUTION_RESULT executionResult;
result = trader.ExecuteSignal(
signal,
executionResult //
);
//
// Alert Signal Execution ...
string executionMessage = ToString(executionResult);
Alert(executionMessage);
//
if (result)
{
//
if (drawSignal)
{
//
XCSignalObject *iObj;
isExists = drawer.DrawSignal(
signal,
iObj //
);
//
if (isExists)
{
//
mObjects.Add(iObj);
ZeroMemory(iObj);
}
}
//
XSTRCCITrade iTrade;
//
ulong positionID = trader.GetLastOpenPositionTicket();
double commission = trader.GetPositionCommission(positionID);
//
iTrade.signal = signal;
iTrade.conditions = conditions;
iTrade.positionID = positionID;
iTrade.commission = commission;
//
AddRef(
iTrade,
trades //
);
}
//
return result;
}
/**
* Handle Position Take Profit ...
*
* @param deal: XDeal instance reference ...
*/
void HandleTP(const XDeal &deal)
{
//
// Check Ticket Exists or not ...
int idx = -1;
bool isExists = HasTrade(
idx,
deal.positionId //
);
if (!isExists)
{
return;
}
//
// Apply Required Data ...
trades[idx].swap = deal.swap;
trades[idx].profit = deal.profit;
trades[idx].commission = deal.commission;
trades[idx].finalize = XSTRCCI_TRADE_FINAL_TP;
//
tpCount++;
managedTPCount++;
//
}
/**
* Handle Position Stop Loss ...
*
* @param deal: XDeal instance reference ...
*/
void HandleSL(const XDeal &deal)
{
//
// Check Ticket Exists or not ...
int idx = -1;
bool isExists = HasTrade(
idx,
deal.positionId //
);
if (!isExists)
{
return;
}
//
// Apply Required Data ...
trades[idx].swap = deal.swap;
trades[idx].profit = deal.profit;
trades[idx].commission = deal.commission;
trades[idx].finalize = XSTRCCI_TRADE_FINAL_SL;
//
slCount++;
managedSLCount++;
//
}
/**
* Handle Position Force Close ...
*
* @param deal: XDeal instance reference ...
*/
void HandleForceClose(const XPosition &position)
{
//
// Check Ticket Exists or not ...
int idx = -1;
bool isExists = HasTrade(
idx,
position.ticket //
);
if (!isExists)
{
return;
}
//
bool isInProfit = position.profit > 0;
//
// Apply Required Data ...
trades[idx].swap = position.swap;
trades[idx].profit = position.profit;
trades[idx].commission = position.commission;
trades[idx].finalize = isInProfit
? XSTRCCI_TRADE_FINAL_CLOSE_IN_PROFIT
: XSTRCCI_TRADE_FINAL_CLOSE_IN_LOSE;
//
if (isInProfit)
{
//
tpCount++;
managedTPCount++;
}
else
{
//
slCount++;
managedSLCount++;
}
//
}
//
// TODO: Complete this ...
void HandleGuard()
{
}
/**
* Find Executed Trade by Providing Position Ticket ...
*
* @param index: int reference, holding founded item index ...
* @param ticket: ulong, Specified Position Ticket ...
*
* @return ( bool )
*/
bool HasTrade(
int &index,
ulong ticket //
)
{
//
bool result = false;
//
index = -1;
//
result =
ticket > 0 &&
HasChild(trades);
if (!result)
{
return result;
}
//
int count = ArraySize(trades);
for (int i = 0; i < count; i++)
{
//
XSTRCCITrade iTrade = trades[i];
//
result =
iTrade.HasSignal() &&
iTrade.IsExecuted() &&
iTrade.positionID == ticket;
if (result)
{
//
index = i;
//
iTrade.Clean();
break;
}
//
iTrade.Clean();
}
//
result = IsValidIndex(index);
//
return result;
}
/**
* Find Trade Item By Signal ...
*
* @param index: int reference, holding founded item index ...
*
* @return ( bool )
*/
bool HasTrade(
int &index,
XSignal &signal //
)
{
//
bool result = false;
//
index = -1;
//
result =
signal.IsValid() &&
HasChild(trades);
if (!result)
{
return result;
}
//
int count = ArraySize(trades);
for (int i = 0; i < count; i++)
{
//
XSTRCCITrade iTrade = trades[i];
//
result =
iTrade.HasSignal() &&
iTrade.signal.IsSameAs(signal);
if (result)
{
//
index = i;
//
iTrade.Clean();
break;
}
//
iTrade.Clean();
}
//
result = IsValidIndex(index);
//
return result;
}
//
// Protected ...
protected:
//
// Tools ...
//
// Private ...
private:
//
// Props ...
//
int slCount;
int tpCount;
//
int managedSLCount;
int managedTPCount;
//
CArrayObj mObjects;
//
XSTRCCITrade trades[];
};
//
+20 -23
View File
@@ -66,7 +66,6 @@ struct XSTRCCIStrategyConditions
double tp;
double pivot;
double point;
double sls[];
string provider;
double targets[];
@@ -79,7 +78,7 @@ struct XSTRCCIStrategyConditions
XBoxZone signalBox;
ENUM_X_DIRECTION dir;
ENUM_X_POSITION_TYPES type;
ENUM_X_DIRECTION signalDir;
XSTRCCIConditions conditions;
//
// Constructor ...
@@ -113,16 +112,15 @@ struct XSTRCCIStrategyConditions
triggerTime = NULL;
//
Clean(sls);
Clean(targets);
//
signalBox.Clean();
conditions.Clean();
//
dir = X_DIRECTION_NONE;
type = X_POSITION_TYPE_NONE;
signalDir = X_DIRECTION_NONE;
//
}
@@ -164,7 +162,7 @@ struct XSTRCCIStrategyConditions
(sl > 0 ||
tp > 0) &&
IsValid() &&
HasDirection(signalDir);
HasDirection(dir);
if (!result)
{
return result;
@@ -172,7 +170,7 @@ struct XSTRCCIStrategyConditions
//
result =
IsBullish(signalDir);
IsBullish(dir);
//
return result;
@@ -193,7 +191,7 @@ struct XSTRCCIStrategyConditions
(sl > 0 ||
tp > 0) &&
IsValid() &&
HasDirection(signalDir);
HasDirection(dir);
if (!result)
{
return result;
@@ -201,7 +199,7 @@ struct XSTRCCIStrategyConditions
//
result =
IsBearish(signalDir);
IsBearish(dir);
//
return result;
@@ -421,6 +419,7 @@ int AddGuard(
//
bool DetectXSTRCCIConditions(
XSTRCCIConditions &conditions,
XBoxZone &box,
ENUM_X_DIRECTION &dir,
XCXSTRCCIHelper *helper,
@@ -433,6 +432,7 @@ bool DetectXSTRCCIConditions(
//
box.Clean();
conditions.Clean();
dir = X_DIRECTION_NONE;
//
@@ -447,7 +447,6 @@ bool DetectXSTRCCIConditions(
ENUM_TIMEFRAMES period = helper.GetPeriod();
//
XSTRCCIConditions conditions;
result = helper.GetConditions(
conditions,
barIndex,
@@ -505,6 +504,10 @@ bool DetectXSTRCCIConditions(
p3Bar.Clean();
p4Bar.Clean();
//
box.Clean();
conditions.Clean();
//
return result;
}
@@ -750,17 +753,6 @@ bool DetectXSTRCCIConditions(
//
box.type = ToString(dir) + "_Signal_" + conditions.symbol + "_" + ToString(conditions.period);
//
XCBoxObject *iObj;
bool isCreated = helper.poiDrawer.DrawBox(
box,
iObj //
);
if (isCreated)
{
Print("Signal Box ...");
}
}
//
@@ -770,6 +762,14 @@ bool DetectXSTRCCIConditions(
//
// Cleanup Resources ...
//
if (!result)
{
//
box.Clean();
conditions.Clean();
}
//
zBar.Clean();
cBar.Clean();
@@ -778,9 +778,6 @@ bool DetectXSTRCCIConditions(
p3Bar.Clean();
p4Bar.Clean();
//
conditions.Clean();
//
return result;
}
+103 -13
View File
@@ -37,8 +37,6 @@ class XCXSTRCCISignaller : XCBase
//
// Props ...
bool useGuards;
double rfReward;
bool isPassedBoxes;
XSTRCCIInputs inputs;
XBarTracker barTraker;
XCXSTRCCIHelper *helper;
@@ -123,10 +121,6 @@ class XCXSTRCCISignaller : XCBase
datetime cTime = TimeCurrent();
double points = GetPoints(symbol);
//
mConditions.symbol = symbol;
mConditions.period = period;
//
XOHCL zBar;
XOHCL cBar;
@@ -160,11 +154,6 @@ class XCXSTRCCISignaller : XCBase
//
// Setup Conditions ...
double sls[];
double sl = 0;
double pivot = 0;
double point = 0;
double targets[];
XBoxZone signalBox;
bool hasSignalBox = false;
ENUM_X_DIRECTION signalBoxDir = X_DIRECTION_NONE;
@@ -173,7 +162,9 @@ class XCXSTRCCISignaller : XCBase
// Checking Conditions ...
//
XSTRCCIConditions conditions;
hasSignalBox = DetectXSTRCCIConditions(
conditions,
signalBox,
signalBoxDir,
helper,
@@ -197,6 +188,103 @@ class XCXSTRCCISignaller : XCBase
//
// Do What we Want ...
barTraker.Waits();
//
// Draw Signal Box ...
XCBoxObject *iObj;
bool isCreated = helper.poiDrawer.DrawBox(
signalBox,
iObj //
);
if (isCreated)
{
//
mObjects.Add(iObj);
ZeroMemory(iObj);
//
Print("Signal Box ...");
}
//
// Prepare Conditions ...
mConditions.symbol = symbol;
mConditions.period = period;
//
double spread = GetSpread(symbol);
//
double entry =
isBullish
? signalBox.upper
: signalBox.lower;
//
double sl =
isBullish
? signalBox.lower
: signalBox.upper;
//
double risk =
isBullish
? entry - sl
: sl - entry;
risk += spread;
//
double rewardTP = risk * tpReward;
//
double tp =
isBullish
? entry + rewardTP
: entry - rewardTP;
//
// Filling ...
mConditions.sl = sl;
mConditions.tp = tp;
mConditions.pivot =
isBullish
? sl
: entry;
mConditions.point =
isBullish
? entry
: sl;
mConditions.dir = signalBoxDir;
mConditions.provider = "XSTRCCI";
mConditions.signalBox = signalBox;
mConditions.setupTime = zBar.time;
mConditions.conditions = conditions;
//
// Select RF Rewards ...
if (continuesRFTillTarget)
{
//
double rfReward = 1;
while (rfReward < tpReward)
{
//
double rewardRF = risk * rfReward;
double rfTP =
isBullish
? entry + rewardRF
: entry - rewardRF;
//
Add(
rfTP,
mConditions.targets //
);
//
rfReward++;
}
}
}
//
@@ -208,6 +296,10 @@ class XCXSTRCCISignaller : XCBase
pBar.Clean();
pPBar.Clean();
//
signalBox.Clean();
conditions.Clean();
//
return result;
}
@@ -410,9 +502,7 @@ class XCXSTRCCISignaller : XCBase
void Init()
{
//
rfReward = 2;
useGuards = false;
isPassedBoxes = false;
continuesRFTillTarget = true;
//