Attach Trade Handler to EA Class ...
This commit is contained in:
@@ -22,8 +22,10 @@
|
||||
//
|
||||
// Imports ...
|
||||
#include "../../Classes/x-saherelm.xexpert.class.mq5"
|
||||
#include "../Classes/x-121.smc.xtradehandler.class.mq5"
|
||||
#include "../Strategy/x-121.smc.ob.strategy.class.mq5"
|
||||
#include "../Strategy/x-121.smc.supdem.strategy.class.mq5"
|
||||
#include "../Strategy/x-121.smc.test.strategy.class.mq5"
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
@@ -38,6 +40,230 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
public:
|
||||
//
|
||||
|
||||
//
|
||||
// Signal Event Listener ...
|
||||
TOnStopLoss OnPositionSLEventListener;
|
||||
TOnTakeProfit OnPositionTPEventListener;
|
||||
TOnPartialClose OnPositionPartialCloseEventListener;
|
||||
TOnModify OnPositionModifiedEventListener;
|
||||
TOnForceClose OnPositionForceCloseEventListener;
|
||||
|
||||
//
|
||||
TOnX121SMCSignal OnSignalEventListener;
|
||||
|
||||
//
|
||||
// Getter(s) / Setter(s) ...
|
||||
|
||||
/**
|
||||
* Get Use Dynamic Volume State ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool UseDynamicVolume()
|
||||
{
|
||||
return mUseDynamicVolume;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Use Dynamic Volume State ...
|
||||
*
|
||||
* @param value: Boolean ...
|
||||
*/
|
||||
void UseDynamicVolume(bool value)
|
||||
{
|
||||
mUseDynamicVolume = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Increase Volume Step ...
|
||||
*
|
||||
* @return ( double )
|
||||
*/
|
||||
double DynamicVolumeStep()
|
||||
{
|
||||
return mDynamicVolumeStep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Increase Volume Step ...
|
||||
*
|
||||
* @param value: Double ...
|
||||
*/
|
||||
void DynamicVolumeStep(double value)
|
||||
{
|
||||
//
|
||||
if (value < 0.01)
|
||||
{
|
||||
value = 0.01;
|
||||
}
|
||||
|
||||
//
|
||||
mDynamicVolumeStep = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Balance Factor for Generate Dynamic Volume ...
|
||||
*
|
||||
* @return ( double )
|
||||
*/
|
||||
double DynamicVolumeBalanceFactor()
|
||||
{
|
||||
return mDynamicVolumeBalanceFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Balance Factor for Generate Dynamic Volume ...
|
||||
*
|
||||
* @param value: Double ...
|
||||
*/
|
||||
void DynamicVolumeBalanceFactor(double value)
|
||||
{
|
||||
//
|
||||
if (value < 0)
|
||||
{
|
||||
value = 0;
|
||||
}
|
||||
|
||||
//
|
||||
mDynamicVolumeBalanceFactor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Static Volume ...
|
||||
*
|
||||
* @return ( double )
|
||||
*/
|
||||
double Volume()
|
||||
{
|
||||
return mVolume;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Static Volume ...
|
||||
*
|
||||
* @param value: Double ...
|
||||
*/
|
||||
void Volume(double value)
|
||||
{
|
||||
//
|
||||
if (value < 0.01)
|
||||
{
|
||||
value = 0.01;
|
||||
}
|
||||
|
||||
//
|
||||
mVolume = value;
|
||||
}
|
||||
|
||||
//
|
||||
// Actions ...
|
||||
|
||||
/**
|
||||
* Handle OnSignalRecieved Event ...
|
||||
*
|
||||
* @param signal: XSignal instance ...
|
||||
* @param conditions: X121SMCStrategyConditions instance ...
|
||||
*/
|
||||
void HandleOnSignalRecieved(
|
||||
XSignal &signal,
|
||||
X121SMCStrategyConditions &conditions //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Check Signal and Conditions Validations ...
|
||||
|
||||
//
|
||||
if (!signal.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (!conditions.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
bool isLong = IsLong(signal.type);
|
||||
|
||||
//
|
||||
// Notify When a Raw (Unfiltered) Signal Recieved
|
||||
// if it's Provided ...
|
||||
bool mAlertRawSignals = false;
|
||||
if (mAlertRawSignals)
|
||||
{
|
||||
//
|
||||
string msg = "Raw " + (IsLong(signal.type) ? "Long" : "Short") + " Signal Recieved: (" + signal.provider + "," + signal.symbol + "," + ToString(signal.period) + ") ...";
|
||||
Alert(msg);
|
||||
}
|
||||
|
||||
//
|
||||
// Apply Volume On Signal ...
|
||||
ApplyVolumeOnSignal(signal);
|
||||
|
||||
//
|
||||
// Chekc Signalling Enable or not ...
|
||||
bool canContinue =
|
||||
isLong
|
||||
? AllowLong()
|
||||
: AllowShort();
|
||||
if (!canContinue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Apply Filtering On Signal ...
|
||||
bool isFiltered = false;
|
||||
if (isFiltered)
|
||||
{
|
||||
//
|
||||
mTradeHandler.RemoveSignal(signal);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Attach Conditions Summary to Signal ...
|
||||
string conditionsSummary = conditions.GenerateSummary(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false //
|
||||
);
|
||||
|
||||
//
|
||||
// TODO: Retrieve Conditions Summary based on Filter ...
|
||||
signal.conditions = conditionsSummary;
|
||||
|
||||
//
|
||||
// TODO: Check Signal Delay ...
|
||||
// datetime currentTime = TimeCurrent();
|
||||
// int delay = mDelayBarBetweenTwoSignal;
|
||||
// bool isDelayPassed = delay <= 0
|
||||
// ? true
|
||||
// : !IsValid(lastSignalOn)
|
||||
// ? true
|
||||
// : MathAbs(TimeToSeconds(currentTime)) - MathAbs(TimeToSeconds(lastSignalOn)) >= ulong(delay * PeriodSeconds(_Period));
|
||||
// if (!isDelayPassed)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// Execute Signal Using Trade Handler ...
|
||||
ENUM_X_SIGNAL_EXECUTION_RESULT state;
|
||||
bool isExecuted = mTradeHandler.ExecuteSignal(
|
||||
signal,
|
||||
state //
|
||||
);
|
||||
|
||||
//
|
||||
if (isExecuted)
|
||||
{
|
||||
// lastSignalOn = currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Override Actions ...
|
||||
|
||||
@@ -62,7 +288,7 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
//
|
||||
// Signalling ...
|
||||
Disabled(false);
|
||||
AllowLomg(true);
|
||||
AllowLong(true);
|
||||
AllowShort(true);
|
||||
|
||||
//
|
||||
@@ -83,6 +309,13 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
ReportNewWeeks(false);
|
||||
ReportNewHours(false);
|
||||
ReportNewMonths(false);
|
||||
|
||||
//
|
||||
// Volume Default Configurations ...
|
||||
Volume(0.01);
|
||||
UseDynamicVolume(false);
|
||||
DynamicVolumeStep(0.01);
|
||||
DynamicVolumeBalanceFactor(200);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,12 +344,36 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
errMessage += "common configurations error;" + "\n";
|
||||
}
|
||||
|
||||
//
|
||||
// Checking Volume ...
|
||||
bool isVolumeValid = true;
|
||||
if (UseDynamicVolume())
|
||||
{
|
||||
//
|
||||
isVolumeValid =
|
||||
DynamicVolumeStep() > 0 &&
|
||||
DynamicVolumeBalanceFactor() > 0;
|
||||
if (!isVolumeValid)
|
||||
{
|
||||
errMessage += "Dynamic Volume configurations error;" + "\n";
|
||||
}
|
||||
}
|
||||
isVolumeValid = isVolumeValid &&
|
||||
Volume() > 0;
|
||||
if (!isVolumeValid)
|
||||
{
|
||||
errMessage += "Static Volume configurations error;" + "\n";
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
// Common ...
|
||||
isCommonValid &&
|
||||
//
|
||||
// Volume Coniguration ...
|
||||
isVolumeValid &&
|
||||
//
|
||||
// Otere ...
|
||||
true
|
||||
//
|
||||
@@ -187,6 +444,89 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
Slippage(),
|
||||
MagicNumber() //
|
||||
);
|
||||
mTrader.AddOnStopLossEventHandler(OnPositionSLEventListener);
|
||||
mTrader.AddOnTakeProfitEventHandler(OnPositionTPEventListener);
|
||||
mTrader.AddOnModifyPositionEventHandler(OnPositionModifiedEventListener);
|
||||
mTrader.AddOnForceClosePositionEventHandler(OnPositionForceCloseEventListener);
|
||||
mTrader.AddOnPartialClosePositionEventHandler(OnPositionPartialCloseEventListener);
|
||||
|
||||
//
|
||||
// Initialize Trade Handler ...
|
||||
mTradeHandler = new XC121SMCTradeHandler(mTrader);
|
||||
mTradeHandler.SaveTrades(true);
|
||||
mTradeHandler.SaveSignals(true);
|
||||
mTradeHandler.SaveConditions(true);
|
||||
|
||||
//
|
||||
// Configure Alerts ...
|
||||
mTradeHandler.SetAlertPrefix(GetTag());
|
||||
mTradeHandler.SetAlertEnableAlerts(GetAlertEnableAlerts());
|
||||
mTradeHandler.SetAlertLogAlerts(GetAlertLogAlerts());
|
||||
mTradeHandler.SetAlertMailAlerts(GetAlertMailAlerts());
|
||||
mTradeHandler.SetAlertPushAlerts(GetAlertPushAlerts());
|
||||
mTradeHandler.SetAlertTerminalAlerts(GetAlertTerminalAlerts());
|
||||
|
||||
//
|
||||
// TODO: Make This Configurable Later ...
|
||||
|
||||
//
|
||||
// Configure Trade Management ...
|
||||
mTradeHandler.AllowLong(AllowLong());
|
||||
mTradeHandler.AllowShort(AllowShort());
|
||||
mTradeHandler.MaxAllowedLongs(0);
|
||||
mTradeHandler.MaxAllowedShorts(0);
|
||||
mTradeHandler.UseMaxAllowedTradesPerSymbol(true);
|
||||
mTradeHandler.MaxDrawdownPercentForOpenTrades(5);
|
||||
|
||||
//
|
||||
// Configure Position Protector ...
|
||||
|
||||
//
|
||||
mTradeHandler.UseForceMomentumsInProtection(true);
|
||||
mTradeHandler.DelayBarBetweenTwoSignal(2);
|
||||
|
||||
//
|
||||
// Configure Hedging ...
|
||||
mTradeHandler.AllowHedge(false);
|
||||
mTradeHandler.HedgeMinVolumeStep(0.01);
|
||||
mTradeHandler.MinimumOpenPositionsForHEHedge(2);
|
||||
mTradeHandler.HedgeHEMinProfitPerVolumeStep(0.2);
|
||||
mTradeHandler.HedgeBEMinProfitPerVolumeStep(0.06);
|
||||
|
||||
//
|
||||
// In Profit Position Protecting ...
|
||||
|
||||
//
|
||||
// Trail ...
|
||||
mTradeHandler.AllowTrail(false);
|
||||
mTradeHandler.TrailStep(15);
|
||||
mTradeHandler.TrailStartDistance(30);
|
||||
mTradeHandler.OnlyTrailUnprotected(true);
|
||||
mTradeHandler.RemoveTPAfterTrailedLevel(4);
|
||||
|
||||
//
|
||||
// Partial Close (In Profit) ...
|
||||
mTradeHandler.PartialCloseInProfitDistance(0);
|
||||
mTradeHandler.PartialCloseInProfitVolume(0);
|
||||
|
||||
//
|
||||
// In Drawdown Positions Protecting ...
|
||||
|
||||
//
|
||||
// Protect ...
|
||||
mTradeHandler.AllowProtect(false);
|
||||
mTradeHandler.ProtectionDelay(20);
|
||||
mTradeHandler.MaxAllowedProtection(0);
|
||||
mTradeHandler.UseEntryAsProtectionSL(true);
|
||||
mTradeHandler.ProtectOnConditions(true);
|
||||
mTradeHandler.AllowDirectionProtct(false);
|
||||
mTradeHandler.ProtectionStartDistance(50);
|
||||
mTradeHandler.ProtectionVolumeMultiplier(2);
|
||||
|
||||
//
|
||||
// Partial Close (In Profit) ...
|
||||
mTradeHandler.PartialCloseInDrawdownDistance(0);
|
||||
mTradeHandler.PartialCloseInDrawdownVolume(0);
|
||||
|
||||
//
|
||||
// Parsers ...
|
||||
@@ -202,13 +542,13 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
//
|
||||
// Create Class Instance ...
|
||||
XCX121SMCBaseStrategy *iX121SMCStrategy;
|
||||
iX121SMCStrategy = new XCX121SMCOBStrategy(
|
||||
iX121SMCStrategy = new XCX121SMCTestStrategy(
|
||||
_Symbol,
|
||||
_Period //
|
||||
);
|
||||
|
||||
//
|
||||
iX121SMCStrategy.AddXSignalEventHandler(OnSignalRecieved);
|
||||
iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener);
|
||||
|
||||
//
|
||||
ConfigureStrategy(iX121SMCStrategy);
|
||||
@@ -223,7 +563,7 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
string symbols[];
|
||||
int symbolsCount = SplitContent(
|
||||
symbols,
|
||||
eaSymbols //
|
||||
Symbols() //
|
||||
);
|
||||
result = IsValidSize(symbolsCount);
|
||||
if (!result)
|
||||
@@ -267,13 +607,13 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
//
|
||||
// Create Class Instance ...
|
||||
XCX121SMCBaseStrategy *iX121SMCStrategy;
|
||||
iX121SMCStrategy = new XCX121SMCOBStrategy(
|
||||
iX121SMCStrategy = new XCX121SMCTestStrategy(
|
||||
iSymbol,
|
||||
_Period //
|
||||
);
|
||||
|
||||
//
|
||||
iX121SMCStrategy.AddXSignalEventHandler(OnSignalRecieved);
|
||||
iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener);
|
||||
|
||||
//
|
||||
// Register Strategy ...
|
||||
@@ -287,6 +627,99 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy all Initialized EA Requirements ...
|
||||
*/
|
||||
void DestroyEA() override
|
||||
{
|
||||
//
|
||||
delete mCTHelper;
|
||||
delete mCCHelper;
|
||||
delete mTradeHandler;
|
||||
|
||||
//
|
||||
Clean(mStrategies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call all Registered Strategies On Tick ...
|
||||
*/
|
||||
void HandleStrategiesOnTick() override
|
||||
{
|
||||
//
|
||||
int count = ArraySize(mStrategies);
|
||||
if (!IsValidSize(count))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
// Call Tick Handler Function ...
|
||||
mStrategies[i].HandleTick();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Event Handlers ...
|
||||
|
||||
/**
|
||||
* Calls When a Position's SL Triggered ...
|
||||
*
|
||||
* @param deal: XDeal instance ...
|
||||
*/
|
||||
void HandleOnStopLossTriggered(const XDeal &deal) override
|
||||
{
|
||||
//
|
||||
// Finish ...
|
||||
mTradeHandler.Finish(deal);
|
||||
|
||||
//
|
||||
HandleReportBalance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls When a Position's TP Triggered ...
|
||||
*
|
||||
* @param deal: XDeal instance ...
|
||||
*/
|
||||
void HandleOnTakeProfitTriggered(const XDeal &deal) override
|
||||
{
|
||||
//
|
||||
// Finish ...
|
||||
mTradeHandler.Finish(deal);
|
||||
|
||||
//
|
||||
HandleReportBalance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Force Close a Position ...
|
||||
*
|
||||
* @param ticket: Position Ticket ...
|
||||
* @param position: XPosition ...
|
||||
* @param comment: Closing Comment ...
|
||||
*/
|
||||
void HandleOnPositionForceClosed(
|
||||
const ulong ticket,
|
||||
const XPosition &position,
|
||||
const string comment //
|
||||
) override
|
||||
{
|
||||
//
|
||||
// Finish ...
|
||||
mTradeHandler.Finish(
|
||||
ticket,
|
||||
position,
|
||||
comment //
|
||||
);
|
||||
|
||||
//
|
||||
HandleReportBalance();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
/**
|
||||
@@ -324,11 +757,54 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
XC121SMCTradeHandler *mTradeHandler; // Trade Handler ...
|
||||
XCX121SMCBaseStrategy *mStrategies[]; // Registere Strategies in EA ...
|
||||
|
||||
//
|
||||
// Actions ...
|
||||
|
||||
/**
|
||||
* Apply Volume Based On Configurations on Signal ...
|
||||
*
|
||||
* @param signal: XSignal instance
|
||||
*/
|
||||
void ApplyVolumeOnSignal(XSignal &signal)
|
||||
{
|
||||
//
|
||||
// Prepare Signal Dynamic Volume
|
||||
// if Provided ...
|
||||
if (UseDynamicVolume() &&
|
||||
DynamicVolumeStep() > 0 &&
|
||||
DynamicVolumeBalanceFactor() > 0)
|
||||
{
|
||||
//
|
||||
double dVolume = mTrader.GetDynamicVolume(
|
||||
signal.symbol,
|
||||
DynamicVolumeBalanceFactor(),
|
||||
DynamicVolumeStep() //
|
||||
);
|
||||
|
||||
//
|
||||
if (dVolume > 0)
|
||||
{
|
||||
signal.volume = dVolume;
|
||||
}
|
||||
else
|
||||
{
|
||||
signal.volume = Volume();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
signal.volume = Volume();
|
||||
}
|
||||
|
||||
//
|
||||
mTradeHandler.UpdateSignal(signal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure Startegy ...
|
||||
*/
|
||||
@@ -353,7 +829,7 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
// Confiugre Signalling ...
|
||||
|
||||
//
|
||||
strategy.AllowLong(AllowLomg());
|
||||
strategy.AllowLong(AllowLong());
|
||||
strategy.AllowShort(AllowShort());
|
||||
|
||||
//
|
||||
@@ -398,7 +874,7 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
void ReConfigureAllStrategies()
|
||||
{
|
||||
//
|
||||
int count = ArraySize(eaStrategies);
|
||||
int count = ArraySize(mStrategies);
|
||||
if (!IsValidSize(count))
|
||||
{
|
||||
return;
|
||||
@@ -408,7 +884,7 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
ConfigureStrategy(eaStrategies[i]);
|
||||
ConfigureStrategy(mStrategies[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,6 +892,16 @@ class XC121SMCExpert : public XCBaseExpert
|
||||
private:
|
||||
//
|
||||
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
// Volume Management ...
|
||||
bool mUseDynamicVolume; // Use Dynamic Volume ...
|
||||
double mDynamicVolumeStep; // Increase Volume Step ...
|
||||
double mDynamicVolumeBalanceFactor; // Balance Factor for Generate Dynamic Volume ...
|
||||
double mVolume; // Static Volume ...
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user