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
+792
View File
@@ -0,0 +1,792 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCVolume
// Description: provides all Requirements for Volume Managing ...
//
//
// 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
//
// Template Variables of Inputs for Using ...
// input group "Volume";
// input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_STATIC; // Volume Applying Type
// input double eaStaticVoluem = X_MIN_VOLUME; // Static Volume
// input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume
// input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing
// input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade
// input double eaConstantPercent = 0.0; // Constant Percent of Balance Per Trade
// input double eaConstantBalance = 0.0; // Constant Balance for Calculations
// XCVolume *eaVolume;
// eaVolume = new XCVolume();
// bool result = eaVolume.Init(
// eaVolumeSelect,
// eaStaticVoluem,
// eaDynamicVolumeStepBalance,
// eaDynamicVolumeStepVolume,
// eaConstantRiskBalance,
// eaConstantPercent,
// eaConstantBalance //
// );
// if (!result) {
// return INIT_FAILED;
// }
//
// Imports ...
#include "../Classes/x-saherelm.x-account.class.mq5"
#include "../Libraries/x-saherelm.x-trade.lib.mq5"
//
// Definitions ...
#define X_MIN_VOLUME 0.01
//
enum ENUM_X_VOLUME_SELECT_TYPE
{
X_VOLUME_NONE, // None
X_VOLUME_STATIC, // Static Volume
X_VOLUME_CURRENT, // Current Balance
X_VOLUME_EQUITY, // Current Equity
X_VOLUME_CONSTANT // Constant Value
};
//
bool IsValid(ENUM_X_VOLUME_SELECT_TYPE value)
{
//
bool result = false;
//
result = value != X_VOLUME_NONE;
//
return result;
}
//
string ToString(ENUM_X_VOLUME_SELECT_TYPE value)
{
//
string result = NULL;
//
result = EnumToString(value);
//
return result;
}
//
// Implementation ...
class XCVolume : public XCBase
{
//
// Public ...
public:
//
// Props ...
XCAccount *account;
//
// Constructor ...
XCVolume()
{
//
account = new XCAccount();
//
Default();
}
//
// Deconstructor ...
~XCVolume()
{
//
ZeroMemory(account);
}
//
bool Init(
ENUM_X_VOLUME_SELECT_TYPE _SelectType,
double _StaticVolume,
double _DynamicVolumeStepBalance,
double _DynamicVolumeStepVolume,
double _ConstantRiskBalance,
double _ConstantPercent,
double _ConstantBalance //
)
{
//
bool result = false;
//
mVolumeType = _SelectType;
mStaticVolume = _StaticVolume;
mConstantPercent = _ConstantPercent;
mConstantBalance = _ConstantBalance;
mConstantRiskBalance = _ConstantRiskBalance;
mDynamicVolumeStepVolume = _DynamicVolumeStepVolume;
mDynamicVolumeStepBalance = _DynamicVolumeStepBalance;
//
result =
//
CanUseStaticVolume() ||
CanUseDynamicVolume() ||
CanUseConstantRiskBalance() ||
CanUseConstantBalancePercent()
//
;
//
return result;
}
//
// Prperties ...
/**
* Get Volume Calculating Method ...
*
* @return (ENUM_X_VOLUME_SELECT_TYPE)
*/
ENUM_X_VOLUME_SELECT_TYPE VolumeType()
{
return mVolumeType;
}
/**
* Set Volume Calculating Method ...
*
* @param value: ENUM_X_VOLUME_SELECT_TYPE member ...
*/
void VolumeType(ENUM_X_VOLUME_SELECT_TYPE value)
{
mVolumeType = value;
}
/**
* Get Static Volume ...
*
* @return ( double )
*/
double StaticVolume()
{
return mStaticVolume;
}
/**
* Set Static Volume ...
*
* @param value: double
*/
void StaticVolume(double value)
{
//
value = NormalizeDouble(value, 0.01, 1);
//
mStaticVolume = value;
}
/**
* Get Dynamic Volume Step Balance ...
* used to Calculate Final Lottage ...
*
* @return ( double )
*/
double DynamicVolumeStepBalance()
{
return mDynamicVolumeStepBalance;
}
/**
* Set Dynamic Volume Step Balance ...
* used to Calculate Final Lottage ...
*
* @param value: Argument 1
*/
void DynamicVolumeStepBalance(double value)
{
//
value = NormalizeDouble(value, 0);
//
mDynamicVolumeStepBalance = value;
}
/**
* Get Dynamic Volume Step Volume ...
* used to Calculate Final Lottage ...
* how much increase Final Volume based oBalance Step ...
*
* @return ( double )
*/
double DynamicVolumeStepVolume()
{
return mDynamicVolumeStepVolume;
}
/**
* Get Dynamic Volume Step Volume ...
* used to Calculate Final Lottage ...
* how much increase Final Volume based oBalance Step ...
*
* @param value: double
*/
void DynamicVolumeStepVolume(double value)
{
//
value = NormalizeDouble(value, 0.01, 0.1);
//
mDynamicVolumeStepVolume = value;
}
/**
* Get Constant Balance Use for Dyamic Volume Calculation ...
*
* @return ( double )
*/
double ConstantBalance()
{
return mConstantBalance;
}
/**
* Set Constant Balance Use for Dyamic Volume Calculation ...
*
* @param value: Argument 1
*/
void ConstantBalance(double value)
{
//
value = NormalizeDouble(value, 0);
//
mConstantBalance = value;
}
/**
* Get Constant Risk Value Based on Account Currency ...
*
* @return ( double )
*/
double ConstantRiskBalance()
{
return mConstantRiskBalance;
}
/**
* Get Constant Risk Value Based on Account Currency ...
*
* @param value: double
*/
void ConstantRiskBalance(double value)
{
//
value = NormalizeDouble(value, 0);
//
mConstantRiskBalance = value;
}
/**
* Get Constant Percent Based On Selected Balance ...
*
* @return ( double )
*/
double ConstantPercent()
{
return mConstantPercent;
}
/**
* Set Constant Percent Based On Selected Balance ...
*
* @param value: double ...
*/
void ConstantPercent(double value)
{
//
value = NormalizeDouble(value, 0, 100);
//
mConstantPercent = value;
}
//
// Tools ...
/**
* Retrieve Balance based on Provided Volume Type ...
*
* @return ( double )
*/
double GetBalance()
{
//
double result = 0;
//
if (!IsValid(mVolumeType))
{
return result;
}
//
if (mConstantBalance > 0 &&
mVolumeType == X_VOLUME_CONSTANT)
{
result = mConstantBalance;
}
else if (mVolumeType == X_VOLUME_CURRENT)
{
result = account.GetBalance();
}
else if (mVolumeType == X_VOLUME_EQUITY)
{
result = account.GetEquity();
}
//
return result;
}
/**
* Retrieve Balance based on Provided Volume Type ...
*
* @return ( double )
*/
double GetBalance(ENUM_X_VOLUME_SELECT_TYPE type)
{
//
double result = 0;
//
if (!IsValid(type))
{
return result;
}
//
if (mConstantBalance > 0 &&
type == X_VOLUME_CONSTANT)
{
result = mConstantBalance;
}
else if (type == X_VOLUME_CURRENT)
{
result = account.GetBalance();
}
else if (type == X_VOLUME_EQUITY)
{
result = account.GetEquity();
}
//
return result;
}
/**
* Calculate Volume Based On Given Configuration ...
*
* @param symbol: string, Trading Symbol ...
* @param entry: double, Entry Price ...
* @param sl: double, Stop Loss Price ...
*
* @return ( double )
*/
double CalculateVolume(
string symbol,
double entry,
double sl //
)
{
//
double result = X_MIN_VOLUME;
//
bool has = false;
//
// Validate Args ...
has =
sl > 0 &&
entry > 0 &&
IsValid(symbol);
if (!has)
{
return result;
}
//
// Retrieve Balance Type ...
double balance = GetBalance();
double points = GetPoints(symbol);
double riskPrice = MathAbs(entry - sl);
double riskInPoints = riskPrice / points;
//
has = CanUseStaticVolume();
if (has)
{
result = mStaticVolume;
}
//
has = CanUseDynamicVolume();
if (has)
{
//
double multiplier = balance / mDynamicVolumeStepBalance;
if (multiplier < 0)
{
multiplier = 1;
}
//
result = multiplier * mDynamicVolumeStepVolume;
}
//
has = CanUseConstantRiskBalance();
if (has)
{
//
result = account.CalculateVolume(
symbol,
mConstantRiskBalance,
riskInPoints //
);
}
//
has = CanUseConstantBalancePercent();
if (has)
{
//
double riskAmountPerBalance = (mConstantPercent * balance) / 100;
//
result = account.CalculateVolume(
symbol,
riskAmountPerBalance,
riskInPoints //
);
}
//
if (result < X_MIN_VOLUME)
{
result = X_MIN_VOLUME;
}
//
// Normalize Volume ...
result = NormalizeVolume(result, symbol);
//
return result;
}
/**
* Calculate Volume Based On Given Configuration ...
*
* @param signal: XSignal instance reference, provided required Data ...
*
* @return ( double )
*/
double CalculateVolume(XSignal &signal)
{
//
double result = X_MIN_VOLUME;
//
if (!signal.IsValid())
{
return result;
}
//
result = CalculateVolume(
signal.symbol,
signal.entry,
signal.sl //
);
//
return result;
}
/**
* Calculate Specified Percent of Selected Balance for Volume ...
*
* @param percent: double, percent of Balance Risking ...
* @param symbol: string, Trading Symbol ...
* @param entry: double, Entry Price ...
* @param sl: double Stop Loss Price ...
*
* @return ( double )
*/
double CalculateVolume(
ENUM_X_VOLUME_SELECT_TYPE selectType,
double percent,
string symbol,
double entry,
double sl //
)
{
//
double result = X_MIN_VOLUME;
//
bool has = false;
//
// Validate Args ...
has =
sl > 0 &&
entry > 0 &&
percent > 0 &&
IsValid(symbol) &&
IsValid(selectType) &&
(selectType == X_VOLUME_EQUITY ||
selectType == X_VOLUME_CURRENT);
if (!has)
{
return result;
}
//
// Retrieve Balance Type ...
double points = GetPoints(symbol);
double riskPrice = MathAbs(entry - sl);
double balance = GetBalance(selectType);
double riskInPoints = riskPrice / points;
//
double riskAmountPerBalance = (percent * balance) / 100;
//
result = account.CalculateVolume(
symbol,
riskAmountPerBalance,
riskInPoints //
);
//
return result;
}
//
// Protected ...
protected:
//
// Tools ...
/**
* Set Default Props ...
*/
void Default()
{
//
VolumeType(X_VOLUME_STATIC);
StaticVolume(0.01);
//
ConstantBalance(0);
ConstantPercent(0);
ConstantRiskBalance(0);
//
DynamicVolumeStepBalance(0);
DynamicVolumeStepVolume(0.01);
}
/**
* Check Configuration is Valid For Static Volume ...
*
* @return ( bool )
*/
bool CanUseStaticVolume()
{
//
bool result = false;
//
result = IsValid(mVolumeType);
if (!result)
{
return result;
}
//
// Static Volume ...
result =
//
mVolumeType == X_VOLUME_STATIC &&
mStaticVolume > 0 &&
//
mDynamicVolumeStepBalance == 0 &&
//
mConstantBalance == 0 &&
mConstantPercent == 0 &&
mConstantRiskBalance == 0
//
;
//
return result;
}
/**
* Check Configuration is Valid For Dynamic Volume ...
*
* @return ( bool )
*/
bool CanUseDynamicVolume()
{
//
bool result = false;
//
result = IsValid(mVolumeType);
if (!result)
{
return result;
}
//
result =
//
(mVolumeType == X_VOLUME_CURRENT ||
mVolumeType == X_VOLUME_EQUITY ||
(mVolumeType == X_VOLUME_CONSTANT &&
mConstantBalance > 0)) &&
//
mDynamicVolumeStepBalance > 0 &&
mDynamicVolumeStepVolume > 0 &&
//
mStaticVolume == 0 &&
mConstantPercent == 0 &&
mConstantRiskBalance == 0
//
;
//
return result;
}
/**
* Check Configuration is Valid For Constant Risk Balance ...
*
* @return ( bool )
*/
bool CanUseConstantRiskBalance()
{
//
bool result = false;
//
result = IsValid(mVolumeType);
if (!result)
{
return result;
}
//
result =
//
(mVolumeType == X_VOLUME_CURRENT ||
mVolumeType == X_VOLUME_EQUITY ||
(mVolumeType == X_VOLUME_CONSTANT &&
mConstantBalance > 0)) &&
//
mConstantRiskBalance > 0 &&
//
mStaticVolume == 0 &&
mConstantPercent == 0 &&
mDynamicVolumeStepBalance == 0
//
;
//
return result;
}
/**
* Check Configuration is Valid For Constant Risk Percent ...
*
* @return ( bool )
*/
bool CanUseConstantBalancePercent()
{
//
bool result = false;
//
result = IsValid(mVolumeType);
if (!result)
{
return result;
}
//
result =
//
(mVolumeType == X_VOLUME_CURRENT ||
mVolumeType == X_VOLUME_EQUITY ||
(mVolumeType == X_VOLUME_CONSTANT &&
mConstantBalance > 0)) &&
//
mConstantPercent > 0 &&
//
mStaticVolume == 0 &&
mConstantRiskBalance == 0 &&
mDynamicVolumeStepBalance == 0
//
;
//
return result;
}
//
// Private ...
private:
//
// Props ...
//
ENUM_X_VOLUME_SELECT_TYPE mVolumeType; // Balance Type ...
//
// Static Volume ...
double mStaticVolume; // Static Volume ...
//
double mDynamicVolumeStepBalance; // Step of Balance ...
double mDynamicVolumeStepVolume; // Step of Volume ...
//
double mConstantBalance; // Constant Balance ....
double mConstantRiskBalance; // Constant Risk Balance ...
double mConstantPercent; // Constant Percent of Balance ...
};
//
+133 -19
View File
@@ -22,6 +22,8 @@
// Imports ...
#include "../Classes/x-saherelm.x-alert.class.mq5"
#include "../Classes/x-saherelm.x-trade.class.mq5"
#include "../Classes/x-saherelm.x-volume.class.mq5"
#include "../XSTRCCI/Classes/xstrcci.x-trade.manager.class.mq5"
#include "../XSTRCCI/Signals/xstrcci.signaller.class.mq5"
//
@@ -37,6 +39,17 @@ input long eaMagicNumber = 78692110; // Magic Number
input int eaSlippage = 10; // Slippgae
input string eaLogSuffix = ""; // Log Suffix
//
// Volume ...
input group "Volume";
input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_EQUITY; // Volume Applying Type
input double eaStaticVoluem = 0.0; // Static Volume
input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume
input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing
input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade
input double eaConstantPercent = 0.5; // Constant Percent of Balance Per Trade
input double eaConstantBalance = 0.0; // Constant Balance for Calculations
//
// Alert ...
// Here we Provider All Requirements for
@@ -60,6 +73,8 @@ input bool eaReportNewHours = false; // Report New Hours
// Variables, Instances ...
XCAlert *eaAlert;
XCTrade *eaTrade;
XCVolume *eaVolume;
XCXSTRCCITradeManager *eaTradeManager;
//
XSignal eaSignal;
@@ -100,6 +115,13 @@ int OnInit()
// Initial Requirements ...
InitRequirements();
//
// Initialize Volume Manger ...
if (!InitVolume())
{
return INIT_FAILED;
}
//
// Init Succeed ...
return INIT_SUCCEEDED;
@@ -122,7 +144,17 @@ void OnDeinit(const int reason)
// REASON_CLOSE 9 Terminal closed
//
// Destroy Timer ...
ZeroMemory(eaAlert);
ZeroMemory(eaTrade);
ZeroMemory(eaVolume);
ZeroMemory(eaSignaller);
//
eaSignal.Clean();
eaConditions.Clean();
//
DestroyTimer();
}
//
@@ -134,18 +166,16 @@ void OnTick()
int count = 0;
bool has = false;
//
// Handle Position Management / Protections ...
eaTradeManager.Manage();
//
eaSignal.Clean();
eaConditions.Clean();
//
double sl = 0;
double tp = 0;
double r2r = 5;
double risk = 0;
double entry = 0;
double reward = 0;
double volume = 0.01;
string provider = "XSTRCCI";
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
@@ -154,9 +184,6 @@ void OnTick()
bool hasLong = false;
bool hasShort = false;
//
double selectedSL = 0;
//
// Start Calculations ...
@@ -239,6 +266,23 @@ void OnTick()
return;
}
//
// Setting Time to Conditions ...
eaConditions.time = cTime;
has = ToPositionType(
type,
eaConditions.type //
);
if (!has)
{
//
eaSignal.Clean();
eaConditions.Clean();
//
return;
}
//
// Checking Trigger Direction ...
hasLong = eaConditions.HasBullishSignal();
@@ -248,23 +292,29 @@ void OnTick()
if (!has)
{
//
eaSignal.Clean();
eaConditions.Clean();
//
return;
}
//
// Preparing Signal ...
//
eaSignal.sl = sl;
eaSignal.tp = tp;
eaSignal.type = type;
eaSignal.mode = mode;
eaSignal.entry = entry;
eaSignal.volume = volume;
eaSignal.symbol = symbol;
eaSignal.period = period;
eaSignal.type = type;
eaSignal.entry = GetEntry(
eaConditions.symbol,
eaConditions.dir //
);
eaSignal.provider = provider;
eaSignal.time = TimeCurrent();
eaSignal.sl = eaConditions.sl;
eaSignal.tp = eaConditions.tp;
eaSignal.volume = X_MIN_VOLUME;
eaSignal.time = eaConditions.time;
eaSignal.symbol = eaConditions.symbol;
eaSignal.period = eaConditions.period;
//
Copy(
@@ -282,6 +332,15 @@ void OnTick()
return;
}
//
// Handle Volume Management ...
double iVolume = eaVolume.CalculateVolume(eaSignal);
if (iVolume > X_MIN_VOLUME &&
iVolume != eaSignal.volume)
{
eaSignal.volume = iVolume;
}
//
// Draw Signal ...
@@ -289,7 +348,16 @@ void OnTick()
// Execute Signal ...
//
Print("Execute Signal ...");
has =eaTradeManager.Execute(
eaSignal,
eaConditions //
);
if (has)
{
//
// Do What we Want on Successfully Execution Signal ...
Print("Signal Executed ...");
}
//
eaSignal.Clean();
@@ -329,6 +397,7 @@ void OnChartEvent(
*/
void OnStopLossTriggered(const XDeal &deal)
{
eaTradeManager.HandleSL(deal);
}
/**
@@ -338,6 +407,7 @@ void OnStopLossTriggered(const XDeal &deal)
*/
void OnTakeProfitTriggered(const XDeal &deal)
{
eaTradeManager.HandleTP(deal);
}
/**
@@ -353,6 +423,7 @@ void OnPositionForceClosed(
const string comment //
)
{
eaTradeManager.HandleForceClose(position);
}
/**
@@ -464,6 +535,34 @@ void DestroyTimer()
// EventKillTimer();
}
/**
* Initial Volume Manager Class Based on Given Configuration ...
*
* @return ( bool )
*/
bool InitVolume()
{
//
bool result = false;
//
eaVolume = new XCVolume();
//
result = eaVolume.Init(
eaVolumeSelect,
eaStaticVoluem,
eaDynamicVolumeStepBalance,
eaDynamicVolumeStepVolume,
eaConstantRiskBalance,
eaConstantPercent,
eaConstantBalance //
);
//
return result;
}
/**
* Initial Requirements of EA ...
*
@@ -498,6 +597,21 @@ void InitRequirements()
eaMaxAllowedPositions,
eaMaxAllowedDrawdownFactor //
);
eaTrade.AddOnStopLossEventHandler(OnStopLossTriggered);
eaTrade.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
eaTrade.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
//
// EA Trae Manager ...
eaTradeManager = new XCXSTRCCITradeManager(
eaTrade //
);
eaTradeManager.SetAlertEnableAlerts(eaEnableAlerts);
eaTradeManager.SetAlertPrefix(eaTag);
eaTradeManager.SetAlertLogAlerts(eaLogAlerts);
eaTradeManager.SetAlertMailAlerts(eaMailAlerts);
eaTradeManager.SetAlertPushAlerts(eaPushAlerts);
eaTradeManager.SetAlertTerminalAlerts(eaTerminalAlerts);
//
// EA Signaller ...
+27
View File
@@ -1980,6 +1980,33 @@ struct XSignal
//
return result;
}
//
bool IsSameAs(XSignal &item) {
//
bool result = false;
//
result =
//
IsValid() &&
item.IsValid() &&
//
tp == item.tp &&
sl == item.sl &&
mode == item.mode &&
time == item.time &&
type == item.type &&
entry == item.entry &&
symbol == item.symbol &&
period == item.period &&
provider == item.provider
//
;
//
return result;
}
};
//
@@ -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;
//