1083 lines
23 KiB
Plaintext
1083 lines
23 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center XCZone MQL5 Expert Advisor
|
|
// -------------------------------------------------
|
|
// Name: XCAEA
|
|
// Description: an Exper Advisor which used XCZone
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://saherelm.ir"
|
|
#property version "1.00"
|
|
#property description "EA based on X121 XCZone indicators"
|
|
#property strict
|
|
|
|
//
|
|
// Include Common Library ...
|
|
#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 "../Libraries/x-saherelm.common.lib.mq5"
|
|
#include "../XCAEA/Classes/xcaea.x-trade.manager.class.mq5"
|
|
#include "../XCAEA/Helpers/xcaea.helper.mq5"
|
|
#include "../XCAEA/Libraries/xcaea.trigger.block.lib.mq5"
|
|
|
|
//
|
|
#define ShortName "XCZONEEA"
|
|
|
|
//
|
|
// Inputs ...
|
|
|
|
//
|
|
// Common ...
|
|
input group "Common";
|
|
input long eaMagicNumber = 78692110; // Magic Number
|
|
input int eaSlippage = 10; // Slippgae
|
|
input string eaLogSuffix = ""; // Log Suffix
|
|
|
|
//
|
|
// Detector ...
|
|
input group "Detector";
|
|
|
|
//
|
|
// Ranges ...
|
|
input double eaMaxAllowedRange = 0.0; // Maximum Allowed Range
|
|
input int eaMinAllowedBlockEdgeLength = 7; // Minimum Required Block Edge Length
|
|
|
|
//
|
|
// Validation ...
|
|
input bool eaForceFVGBarType = true; // Force FVG to Has Same Type of Bars
|
|
input bool eaForceHasSwingBar = true; // Force Has Propper Swing
|
|
input bool eaForceOBOppositBar = true; // Force OB to Start by Opposit Bars
|
|
input bool eaForceHasLiquidity = false; // Force Has Following Liquidity Zone
|
|
input bool eaForceGapBarBreakout = true; // Force FVG's Gap Bar to Breakeout OB Edge Side
|
|
input bool eaForceHasReversalLiquidity = true; // Force Has Reversal Liquidity Zone
|
|
|
|
//
|
|
// Filtering ...
|
|
input bool eaFilterBasedOnSar = true; // Filter Trigger Block Based on Sar
|
|
input bool eaFilterBasedOnRSI = true; // Filter Trigger Block Based on RSI
|
|
input bool eaFilterBasedOnADX = true; // Filter Trigger Block Based on ADX
|
|
input bool eaFilterBasedOnTrend = true; // Filter Trigger Block Based on Trend
|
|
input bool eaFilterBasedOnScores = true; // Filter Trigger Block Based on Scores
|
|
input bool eaFilterBasedOnVolumes = true; // Filter Trigger Block Based on Volumes
|
|
|
|
//
|
|
// Signals ...
|
|
input group "Signals";
|
|
input double maxAllowedR2R = 2; // Max Allowed R2R
|
|
input double eaSLAdditionalPoint = 0.0; // Additional SL in Point
|
|
input double eaSLATRMultiplier = 0.0; // Additional SL using ATR Multiplier
|
|
|
|
//
|
|
// 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
|
|
|
|
//
|
|
// Management ...
|
|
input group "Management";
|
|
input bool eaAllowTrade = true; // Allow Trade on Signals
|
|
input bool eaAllowLongs = true; // Allow Long Trades
|
|
input bool eaAllowShorts = true; // Allow Short Trades
|
|
input ENUM_XCAEA_TRADE_RESTRICTION_PERIOD eaRestrictionsPeriod = XCAEA_TRADE_RESTRICATION_NONE; // Trade Restrictions Period
|
|
input int eaMaxAllowedTPs = 0; // Max Allowed TP(s) per Day
|
|
input int eaMaxAllowedSLs = 0; // Max Allowed SL(s) per Day
|
|
input int eaMaxAllowedTrades = 0; // Max Allowed Trades per Day
|
|
input int eaMaxAllowedPositions = 5; // Max Allowed Same Time Trades
|
|
input double eaMaxAllowedSpread = 25; // Max Allowed Spread For Trade
|
|
input double eaMaxAllowedDrawdownFactor = 0.3; // Max Allowed DrawDown for Trade
|
|
input string eaCloseAllOpenTradesAt = ""; // Close All Open Trades per Day At Specified Time
|
|
|
|
//
|
|
// Alert ...
|
|
// Here we Provider All Requirements for
|
|
// Configuring Alert Provider ...
|
|
input group "Alert";
|
|
input bool eaEnableAlerts = true; // Enable Alerts
|
|
input bool eaLogAlerts = true; // Log Alerts
|
|
input bool eaMailAlerts = false; // Mail Alerts
|
|
input bool eaPushAlerts = false; // Push Alerts
|
|
input bool eaTerminalAlerts = false; // Terminal Alerts
|
|
|
|
//
|
|
// Time Report ...
|
|
input group "Reports";
|
|
input bool eaReportNewMonths = false; // Report New Month
|
|
input bool eaReportNewWeeks = false; // Report New Weeks
|
|
input bool eaReportNewDays = true; // Report New Days
|
|
input bool eaReportNewHours = false; // Report New Hours
|
|
input bool eaReportTrades = true; // Report Trades
|
|
input bool eaReportSignals = true; // Report Signals
|
|
input bool eaReportProtector = true; // Report Protector Actions
|
|
input bool eaReportAfterTradesBalance = true; // Report Balance after a Trade Finished
|
|
|
|
//
|
|
// Variables ...
|
|
|
|
//
|
|
XCAlert *eaAlert;
|
|
XCTrade *eaTrade;
|
|
XSignal eaSignal;
|
|
XCVolume *eaVolume;
|
|
XCAEAInputs eaInputs;
|
|
XCXCAEAHelper *eaHelper;
|
|
XBarTracker eaBarTraker;
|
|
XTimeTracker eaTimeTracker;
|
|
XCXCAEATradeManager *eaTradeManager;
|
|
XCAEAStrategyConditions eaConditions;
|
|
|
|
//
|
|
XTriggerBlock eaTB;
|
|
XBoxZone eaUpperRange;
|
|
XBoxZone eaLowerRange;
|
|
XCAEATriggerBlockConfiguration eaTBConfig;
|
|
|
|
//
|
|
CArrayObj *eaObjects;
|
|
|
|
//
|
|
string eaTag = "";
|
|
|
|
//
|
|
// Event Handlers ...
|
|
|
|
//
|
|
// Initialization ...
|
|
int OnInit()
|
|
{
|
|
//
|
|
// Validate Inputs and Required Parameters
|
|
// for EA to Works fine ...
|
|
if (!ValidateInputs())
|
|
{
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
}
|
|
|
|
//
|
|
// Initial Requirements ...
|
|
InitRequirements();
|
|
|
|
//
|
|
// Configure Detector ...
|
|
ConfigureDetector();
|
|
|
|
//
|
|
// Initialize Volume Manger ...
|
|
if (!InitVolume())
|
|
{
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
return (INIT_SUCCEEDED);
|
|
}
|
|
|
|
//
|
|
// DeInitialization ...
|
|
void OnDeinit(const int reason)
|
|
{
|
|
//
|
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
|
// REASON_REMOVE 1 Program removed from a chart
|
|
// REASON_RECOMPILE 2 Program recompiled
|
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
|
// REASON_CHARTCLOSE 4 Chart closed
|
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
|
// REASON_TEMPLATE 7 Another chart template applied
|
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
|
// REASON_CLOSE 9 Terminal closed
|
|
|
|
//
|
|
// eaObjects.Clear();
|
|
|
|
//
|
|
delete eaHelper;
|
|
ZeroMemory(eaHelper);
|
|
|
|
//
|
|
delete eaAlert;
|
|
ZeroMemory(eaAlert);
|
|
|
|
//
|
|
delete eaTrade;
|
|
ZeroMemory(eaTrade);
|
|
|
|
//
|
|
delete eaVolume;
|
|
ZeroMemory(eaVolume);
|
|
|
|
//
|
|
eaSignal.Clean();
|
|
eaTBConfig.Clean();
|
|
eaBarTraker.Clean();
|
|
eaConditions.Clean();
|
|
eaTimeTracker.Clean();
|
|
|
|
//
|
|
DestroyTimer();
|
|
}
|
|
|
|
//
|
|
// On Tick Handler ...
|
|
void OnTick()
|
|
{
|
|
//
|
|
HandleTimeReport();
|
|
|
|
//
|
|
// Handle Position Management / Protections ...
|
|
eaTradeManager.Manage();
|
|
|
|
//
|
|
eaSignal.Clean();
|
|
eaConditions.Clean();
|
|
|
|
//
|
|
// Check Bar Processing ...
|
|
if (!eaBarTraker.CanProcessBar())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
bool has = false;
|
|
|
|
//
|
|
// Retrieve Bars ...
|
|
XOHCL zBar;
|
|
XOHCL cBar;
|
|
has = zBar.Init(
|
|
_Symbol,
|
|
_Period,
|
|
0 //
|
|
);
|
|
has =
|
|
has &&
|
|
zBar.GetPreviousBar(cBar);
|
|
if (!has)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
double bid = GetBid(zBar.symbol);
|
|
|
|
//
|
|
// Detect Range Blocks ...
|
|
double mid = 0;
|
|
double range = 0;
|
|
XBoxZone upperRNGB;
|
|
XBoxZone lowerRNGB;
|
|
bool isIn = false;
|
|
has = eaHelper
|
|
.barAnalyser
|
|
.DetectRangeBlocks(
|
|
zBar,
|
|
upperRNGB,
|
|
lowerRNGB,
|
|
(288 * 5) //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Setting Range Boxes ...
|
|
upperRNGB.to = zBar.time;
|
|
lowerRNGB.to = zBar.time;
|
|
eaUpperRange.to = zBar.time;
|
|
eaLowerRange.to = zBar.time;
|
|
|
|
//
|
|
bool canSet = false;
|
|
|
|
//
|
|
// Set Upper Range ...
|
|
canSet = !eaUpperRange.IsValid()
|
|
? true
|
|
: upperRNGB.upper > eaUpperRange.upper;
|
|
if (canSet)
|
|
{
|
|
eaUpperRange = upperRNGB;
|
|
}
|
|
|
|
//
|
|
// Set Lower Range ...
|
|
canSet = !eaLowerRange.IsValid()
|
|
? true
|
|
: lowerRNGB.lower < eaLowerRange.lower;
|
|
if (canSet)
|
|
{
|
|
eaLowerRange = lowerRNGB;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Calculate Requirements ...
|
|
range = eaUpperRange.lower - eaLowerRange.upper;
|
|
mid = eaUpperRange.lower - (range / 2);
|
|
|
|
//
|
|
double price = zBar.close; // bid;
|
|
|
|
//
|
|
// Check Price in Upper Tange ...
|
|
bool isInUpperRange =
|
|
price >= eaUpperRange.lower &&
|
|
price <= eaUpperRange.upper;
|
|
|
|
//
|
|
// Check Price in Lower Range ...
|
|
bool isInLowerRange =
|
|
price >= eaLowerRange.lower &&
|
|
price <= eaLowerRange.upper;
|
|
|
|
//
|
|
isIn = isInUpperRange ||
|
|
isInLowerRange;
|
|
if (isIn)
|
|
{
|
|
//
|
|
if (isInUpperRange) {
|
|
eaLowerRange = lowerRNGB;
|
|
}
|
|
|
|
//
|
|
if (isInLowerRange) {
|
|
eaUpperRange = upperRNGB;
|
|
}
|
|
|
|
//
|
|
Print("IsIn ...");
|
|
}
|
|
|
|
//
|
|
// Do Detection ...
|
|
has = DetectTriggerBlock(
|
|
eaTB,
|
|
eaHelper,
|
|
eaTBConfig,
|
|
zBar.Index(),
|
|
10,
|
|
eaSLAdditionalPoint,
|
|
eaSLATRMultiplier //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
bool isBullish = eaTB.trigger.IsBullish();
|
|
|
|
//
|
|
has =
|
|
isBullish
|
|
? zBar.close < mid
|
|
: zBar.close > mid;
|
|
if (!has)
|
|
{
|
|
eaTB.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draws ...
|
|
|
|
//
|
|
// Darw Ranges ...
|
|
has = eaUpperRange.IsValid() &&
|
|
eaLowerRange.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
// Draw Ranges ...
|
|
|
|
//
|
|
// Draw Upper Range ...
|
|
XCBoxObject *iUpperObj;
|
|
has = eaHelper.poiDrawer.DrawBox(
|
|
eaUpperRange,
|
|
iUpperObj //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Style Object ...
|
|
|
|
//
|
|
// Store Object ...
|
|
eaObjects.Add(iUpperObj);
|
|
}
|
|
|
|
//
|
|
// Draw Lower Range ...
|
|
XCBoxObject *iLowerObj;
|
|
has = eaHelper.poiDrawer.DrawBox(
|
|
eaLowerRange,
|
|
iLowerObj //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Style Object ...
|
|
|
|
//
|
|
// Store Object ...
|
|
eaObjects.Add(iLowerObj);
|
|
}
|
|
|
|
//
|
|
// Draw Fibonacchi ...
|
|
}
|
|
|
|
//
|
|
// Draw Trigger Block ...
|
|
has = eaTB.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
if (eaTB.signal.IsValid())
|
|
{
|
|
//
|
|
eaSignal = eaTB.signal;
|
|
|
|
//
|
|
eaConditions.symbol = eaTB.signal.symbol;
|
|
eaConditions.period = eaTB.signal.period;
|
|
eaConditions.conditions = eaTB.conditions;
|
|
}
|
|
|
|
//
|
|
CArrayObj *tObjects;
|
|
tObjects = new CArrayObj();
|
|
|
|
//
|
|
has = DrawTriggerBlock(
|
|
eaTB,
|
|
tObjects,
|
|
eaHelper,
|
|
NULL, // zBar.time,
|
|
0 // Prevent Drawing RR Zones ...
|
|
);
|
|
if (has)
|
|
{
|
|
AddObjects(tObjects, eaObjects);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Handle Signals ...
|
|
|
|
//
|
|
// Check Signal Validation ...
|
|
if (eaSignal.IsValid())
|
|
{
|
|
//
|
|
// Do What we Want ...
|
|
// When we Need Waits Until Next Bar ...
|
|
eaBarTraker.Waits();
|
|
|
|
//
|
|
bool isLong = IsLong(eaSignal.type);
|
|
|
|
//
|
|
// Update Entry ...
|
|
eaSignal.entry = GetEntry(
|
|
eaSignal.symbol,
|
|
eaSignal.type //
|
|
);
|
|
|
|
//
|
|
// Try to Check Liquidity ...
|
|
if (eaTB.rLiquidity.IsValid())
|
|
{
|
|
//
|
|
double irLQRange = eaTB.rLiquidity.GetRange();
|
|
eaSignal.sl =
|
|
isLong
|
|
? eaSignal.sl - irLQRange
|
|
: eaSignal.sl + irLQRange;
|
|
}
|
|
|
|
//
|
|
// Apply Signal Targets ...
|
|
ApplySignalTargets(eaSignal);
|
|
|
|
//
|
|
// Handle Volume Management ...
|
|
double iVolume = eaVolume.CalculateVolume(eaSignal);
|
|
if (iVolume > X_MIN_VOLUME &&
|
|
iVolume != eaSignal.volume)
|
|
{
|
|
eaSignal.volume = iVolume;
|
|
}
|
|
|
|
//
|
|
// Execute Signal ...
|
|
has = eaTradeManager.Execute(
|
|
eaSignal,
|
|
eaConditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
eaTB.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
eaSignal.Clean();
|
|
eaConditions.Clean();
|
|
}
|
|
|
|
//
|
|
// Handle On Trade Event ...
|
|
void OnTrade()
|
|
{
|
|
eaTrade.HandleOnTrade();
|
|
}
|
|
|
|
//
|
|
// On Timer ...
|
|
void OnTimer()
|
|
{
|
|
}
|
|
|
|
//
|
|
// Chart Event Handler ...
|
|
void OnChartEvent(
|
|
const int id,
|
|
const long &lparam,
|
|
const double &dparam,
|
|
const string &sparam //
|
|
)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Event Listeners ...
|
|
|
|
/**
|
|
* Handle StopLoss Triggered Positions ...
|
|
*
|
|
* @param deal: XDeal instance ...
|
|
*/
|
|
void OnStopLossTriggered(const XDeal &deal)
|
|
{
|
|
eaTradeManager.HandleSL(deal);
|
|
}
|
|
|
|
/**
|
|
* Handle Take Profit Triggered Positions ...
|
|
*
|
|
* @param deal: XDeal instance ...
|
|
*/
|
|
void OnTakeProfitTriggered(const XDeal &deal)
|
|
{
|
|
eaTradeManager.HandleTP(deal);
|
|
}
|
|
|
|
/**
|
|
* Handle Force Close a Position ...
|
|
*
|
|
* @param ticket: ULONG ...
|
|
* @param position: XPosition instance ...
|
|
* @param comment: string ...
|
|
*/
|
|
void OnPositionForceClosed(
|
|
const ulong ticket,
|
|
const XPosition &position,
|
|
const string comment //
|
|
)
|
|
{
|
|
eaTradeManager.HandleForceClose(position);
|
|
}
|
|
|
|
/**
|
|
* Handle Position Partially Closed Event ...
|
|
*
|
|
* @param ticket: ULONG ...
|
|
* @param profit: double ...
|
|
* @param comment: string ...
|
|
*/
|
|
void OnPositionPartiallyClosed(
|
|
const ulong ticket,
|
|
const double profit,
|
|
const string comment //
|
|
)
|
|
{
|
|
eaTradeManager.HandlePartiallyClosed(
|
|
ticket,
|
|
profit,
|
|
comment //
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Handle Deals Changes ...
|
|
*
|
|
* @param count: Integer, Number of Changes ...
|
|
*/
|
|
void OnDealsChanged(int count)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Handle Orders Changes ...
|
|
*
|
|
* @param count: Integer, Number of Changes ...
|
|
*/
|
|
void OnOrdersChanged(int count)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Handle Positions Changes ...
|
|
*
|
|
* @param count: Integer, Number of Changes ...
|
|
*/
|
|
void OnPositionsChanged(int count)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Custom Functions ...
|
|
|
|
/**
|
|
* Validate all Inputs of Expert Adviser ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool ValidateInputs()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
string errMessage = "";
|
|
|
|
//
|
|
bool isCommonValid = (
|
|
//
|
|
eaSlippage > 0 &&
|
|
eaMagicNumber > 0
|
|
//
|
|
);
|
|
if (!isCommonValid)
|
|
{
|
|
//
|
|
errMessage += "common configurations error;" + "\n";
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
// Common ...
|
|
isCommonValid &&
|
|
//
|
|
// Otere ...
|
|
true
|
|
//
|
|
;
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
//
|
|
// Since here Logger not Initiallized, we Use Raw Print Command ...
|
|
Print(ShortName + " Errors: \n", errMessage);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Initialize Timer ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool InitTimer()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// TODO: Initialize Timer if necessary ...
|
|
// result = EventSetTimer(1);
|
|
// result = EventSetMillisecondTimer(100);
|
|
result = true;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Destroy Timer ...
|
|
*/
|
|
void DestroyTimer()
|
|
{
|
|
//
|
|
// TODO: Use This ...
|
|
// 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 ...
|
|
*/
|
|
void InitRequirements()
|
|
{
|
|
//
|
|
// Preparing Tags ...
|
|
eaTag =
|
|
(IsValid(eaLogSuffix)
|
|
? eaLogSuffix + "_"
|
|
: "") +
|
|
ShortName;
|
|
|
|
//
|
|
// Initial Bar Tracker ...
|
|
eaBarTraker.Init(
|
|
_Symbol,
|
|
_Period //
|
|
);
|
|
|
|
//
|
|
// Objects ...
|
|
eaObjects = new CArrayObj();
|
|
|
|
//
|
|
// Configure XCA ...
|
|
eaInputs.Default();
|
|
|
|
//
|
|
// Hide all Visible Buffers ...
|
|
eaInputs.Hide();
|
|
|
|
//
|
|
// we Can make Show all requirements here ...
|
|
eaInputs.caInputs.showSar = false;
|
|
|
|
//
|
|
eaHelper = new XCXCAEAHelper();
|
|
bool isInited = eaHelper.Init(
|
|
_Symbol,
|
|
_Period,
|
|
eaInputs //
|
|
);
|
|
|
|
//
|
|
// EA Alert ...
|
|
eaAlert = new XCAlert(
|
|
eaTag,
|
|
eaEnableAlerts,
|
|
eaLogAlerts,
|
|
eaTerminalAlerts,
|
|
eaMailAlerts,
|
|
eaPushAlerts //
|
|
);
|
|
|
|
//
|
|
// EA Trade ...
|
|
eaTrade = new XCTrade(
|
|
eaSlippage,
|
|
eaMagicNumber,
|
|
eaMaxAllowedSpread,
|
|
eaMaxAllowedPositions,
|
|
eaMaxAllowedDrawdownFactor //
|
|
);
|
|
eaTrade.AddOnStopLossEventHandler(OnStopLossTriggered);
|
|
eaTrade.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
|
|
eaTrade.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
|
|
eaTrade.AddOnPartialClosePositionEventHandler(OnPositionPartiallyClosed);
|
|
|
|
//
|
|
// EA Trae Manager ...
|
|
eaTradeManager = new XCXCAEATradeManager(
|
|
eaTrade //
|
|
);
|
|
eaTradeManager.SaveTrades(true);
|
|
eaTradeManager.SetAlertEnableAlerts(eaEnableAlerts);
|
|
eaTradeManager.SetAlertPrefix(eaTag);
|
|
eaTradeManager.SetAlertLogAlerts(eaLogAlerts);
|
|
eaTradeManager.SetAlertMailAlerts(eaMailAlerts);
|
|
eaTradeManager.SetAlertPushAlerts(eaPushAlerts);
|
|
eaTradeManager.SetAlertTerminalAlerts(eaTerminalAlerts);
|
|
|
|
//
|
|
// Setting Trade Reports ...
|
|
eaTradeManager
|
|
.SetTradeReports(
|
|
eaReportTrades,
|
|
eaReportSignals,
|
|
eaReportProtector,
|
|
eaReportAfterTradesBalance //
|
|
);
|
|
|
|
//
|
|
// Setting Trade Permissions ...
|
|
eaTradeManager
|
|
.SetTradePermissions(
|
|
eaAllowTrade,
|
|
eaAllowLongs,
|
|
eaAllowShorts //
|
|
);
|
|
|
|
//
|
|
// Setting Trade Restrictions ...
|
|
eaTradeManager
|
|
.SetTradeRestrictions(
|
|
eaRestrictionsPeriod,
|
|
eaMaxAllowedTPs,
|
|
eaMaxAllowedSLs,
|
|
eaMaxAllowedTrades //
|
|
);
|
|
}
|
|
|
|
//
|
|
void ConfigureDetector()
|
|
{
|
|
//
|
|
// Configure Detector ...
|
|
|
|
//
|
|
// Validation ...
|
|
eaTBConfig.maxAllowedRange = eaMaxAllowedRange;
|
|
eaTBConfig.minAllowedBlockEdgeLength = eaMinAllowedBlockEdgeLength;
|
|
|
|
//
|
|
// Validation ...
|
|
eaTBConfig.forceFVGBarType = eaForceFVGBarType;
|
|
eaTBConfig.forceHasSwingBar = eaForceHasSwingBar;
|
|
eaTBConfig.forceOBOppositBar = eaForceOBOppositBar;
|
|
eaTBConfig.forceHasLiquidity = eaForceHasLiquidity;
|
|
eaTBConfig.forceGapBarBreakout = eaForceGapBarBreakout;
|
|
eaTBConfig.forceHasReversalLiquidity = eaForceHasReversalLiquidity;
|
|
|
|
//
|
|
// Filters ...
|
|
eaTBConfig.filterBasedOnSar = eaFilterBasedOnSar;
|
|
eaTBConfig.filterBasedOnADX = eaFilterBasedOnADX;
|
|
eaTBConfig.filterBasedOnRSI = eaFilterBasedOnRSI;
|
|
eaTBConfig.filterBasedOnTrend = eaFilterBasedOnTrend;
|
|
eaTBConfig.filterBasedOnScores = eaFilterBasedOnScores;
|
|
eaTBConfig.filterBasedOnVolumes = eaFilterBasedOnVolumes;
|
|
|
|
//
|
|
// Targets ...
|
|
double targets[] = {
|
|
1,
|
|
2,
|
|
3,
|
|
4,
|
|
5,
|
|
6,
|
|
7,
|
|
8,
|
|
9,
|
|
10,
|
|
11,
|
|
12,
|
|
13,
|
|
14,
|
|
15,
|
|
};
|
|
Copy(
|
|
targets,
|
|
eaTBConfig.targets //
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Handling Time Reporting ...
|
|
*/
|
|
void HandleTimeReport()
|
|
{
|
|
//
|
|
// Monthly Report ....
|
|
if (eaReportNewMonths &&
|
|
eaTimeTracker.IsNewMonth())
|
|
{
|
|
//
|
|
string msg = "New Month ...";
|
|
|
|
//
|
|
eaAlert.SendAlert(msg);
|
|
}
|
|
|
|
//
|
|
// Weekly Report ....
|
|
if (eaReportNewWeeks &&
|
|
eaTimeTracker.IsNewWeek())
|
|
{
|
|
//
|
|
string msg = "New Week ...";
|
|
|
|
//
|
|
eaAlert.SendAlert(msg);
|
|
}
|
|
|
|
//
|
|
// Daily Report ....
|
|
if (eaReportNewDays &&
|
|
eaTimeTracker.IsNewDay())
|
|
{
|
|
//
|
|
string msg = "New Day ...";
|
|
|
|
//
|
|
eaAlert.SendAlert(msg);
|
|
}
|
|
|
|
//
|
|
// Hourly Report ....
|
|
if (eaReportNewHours &&
|
|
eaTimeTracker.IsNewHour())
|
|
{
|
|
//
|
|
string msg = "New Hour ...";
|
|
|
|
//
|
|
eaAlert.SendAlert(msg);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Apply Signal Targets ...
|
|
void ApplySignalTargets(XSignal &signal)
|
|
{
|
|
//
|
|
bool has = signal.IsValid();
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Clean Signal Targets ...
|
|
Clean(signal.targets);
|
|
|
|
//
|
|
// Calculate Requirements ...
|
|
double r2r = maxAllowedR2R > 0
|
|
? maxAllowedR2R
|
|
: 1;
|
|
double risk = signal.GetRisk();
|
|
double reward = risk * r2r;
|
|
|
|
//
|
|
double isLong = IsLong(signal.type);
|
|
|
|
//
|
|
// Handling Signal TP ...
|
|
signal.tp =
|
|
isLong
|
|
? signal.entry + reward
|
|
: signal.entry - reward;
|
|
|
|
//
|
|
// Try to Apply Money Management ...
|
|
|
|
//
|
|
if (r2r <= 1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// XTarget iTarget;
|
|
|
|
// //
|
|
// // Partial Close 0.5 of Position on Reward 1 ...
|
|
// reward = risk * 1;
|
|
// iTarget.target =
|
|
// isLong
|
|
// ? signal.entry + reward
|
|
// : signal.entry - reward;
|
|
// iTarget.volumeMultiplier = 0.5;
|
|
|
|
// //
|
|
// AddRef(iTarget, signal.targets);
|
|
// iTarget.Clean();
|
|
|
|
// //
|
|
// if (r2r <= 2)
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
//
|
|
// Making Loop ...
|
|
// for (int i = 2; i < ((int)r2r - 1); i++)
|
|
// {
|
|
// //
|
|
// iTarget.Clean();
|
|
|
|
// //
|
|
// reward = i * risk;
|
|
// iTarget.target =
|
|
// isLong
|
|
// ? signal.entry + reward
|
|
// : signal.entry - reward;
|
|
// iTarget.volumeMultiplier = 1 / (r2r - 2);
|
|
|
|
// //
|
|
// AddRef(iTarget, signal.targets);
|
|
// }
|
|
|
|
//
|
|
// Sort Targets ...
|
|
ENUM_X_DIRECTION sortingDir =
|
|
isLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
ApplySortOnTargets(
|
|
sortingDir,
|
|
signal.targets //
|
|
);
|
|
}
|