Files
MQL4Data/Bkp/Used/14020419/x-saherelm.ea.mq4
T
2024-01-25 04:05:58 +03:30

1444 lines
37 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center XST Strategy Expert Advisor
// ---------------------------------------------
// saherelm implementation of strategy expert advisor ...
// in this EA, we try to combine multiple tools, to ashive best
// results ...
//
// ShortName: XST
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
// +989121694056
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XST Strategy Expert Advisor"
#property strict
//
// START Inputs ...
//
//
// Signal Prefixe ...
input string signalPrefix = "XST"; // Signal Prefix
//
// Signal Draw Specifications ...
input string bullishSignalLabel = "X_BUY"; // Bullish Signal Label
input color bullishSignalColor = clrAqua; // Bullish Signal Color
//
input string bearishSignalLabel = "X_SELL"; // Bearish Signal Label
input color bearishSignalColor = clrFuchsia; // Bearish Signal Color
//
input bool useOSCSignalling = false; // Use XOSC Signalling
input string oscSignalIdentifier = "XOSC"; // XOSC Signal Identifier
//
input bool useXMASignalling = false; // Use XMA Signalling
input string xmaSignalIdentifier = "XMA"; // XMA Signal Identifier
//
input bool useXSHPSignalling = true; // Use XSHP Signalling
input string xshpSignalIdentifier = "XSHP"; // XSHP Signal Identifier
//
input bool useXMNTMSignalling = false; // Use XMNTM Signalling
input string xmntmSignalIdentifier = "XMNTM"; // XMNTM Signal Identifier
//
input bool useXRSISignalling = true; // Use XRSI Signalling
input string xrsiSignalIdentifier = "XRSI"; // XRSI Signal Identifier
//
input color signalEntryColor = clrAquamarine; // Signal Entry Ptice Color
input color signalSLColor = clrRed; // Signal SL Color
input color signalTPColor = clrGreen; // Signal TP Color
//
// Trade ...
input bool allowTrade = true; // Allow Trade Based on given Signals
input bool allowLongTrades = true; // Allow Long Trades
input bool allowShortTrades = false; // Allow Short Trades
//
// Market Specification Inpouts ...
input int marketLength = 7; // Market Length
input double riskToRewardRatio = 2; // Risk to Reward Ratio
//
// Alerts ...
input bool alertEvents = true; // Alert Events
input bool alertPositions = true; // Alert Positions
input bool longPositionAlerts = true; // Alert Long Positions
input bool shortPositionAlerts = true; // Alert Short Positions
//
// Alert Types ...
input bool terminalAlert = false; // Terminal Alert
input bool pushAlert = false; // Push Notification Alerts
//
// Balance and Finanical Specifications ...
input double lotsPerTradePercent = 0.00001; // Lots Per Trade Percent
input int maxOpenTrades = 4; // Maximum Open Trade
input double maxDrawdownPercentPerPTrade = 0.015; // Maximum DrawDown Per Trade
input double minBalancePercent = 0.5; // Minimum Balance for Trading
input double maxEquityPercent = 0.1; // Maximum Trade Equity
input int closeAllOpenTradesAfterCandle = 504; // Close All Open Trades After Passed Candles
input bool closeAllInProfitOpenTradesWhenMaxOpenTradesReached = false; // Close All In Profit Open Trades When Max Open Trades Reached and New Signal Income
//
// OSC Inputs ...
//
// FastOSC ...
// Short Cycle (Fast OSC) ...
input int fastOSCLength = 10; // FastOSC Length
input double fastOSCMultiplier = 1.0; // FastOSC Multiplier
//
// SlowOSC ...
// Medium Cycle (Slow OSC) ...
input int slowOSCLength = 30; // SlowOSC Length
input double slowOSCMultiplier = 3.0; // SlowOSC Multiplier
//
// Power OSC ...
input double minPowerOSC = 0.04; // Minimum Signal Power
//
// Variance OSC ...
input double minVarianceOSC = 0.1; // Minimum Var Power
//
// ZIGZAG Inputs ...
input int zDeviation = 5; // ZigZag Deviation
input int zBackStep = 3; // ZigZag Back Step
//
// XMA Inputs ...
//
input double step = 0.02; // SAR Step
input double maximum = 0.2; // SAR Maximum
input int shortCycleFastMultiplier = 2; // Short Cycle Fast Multiplier
input int shortCycleSlowMultiplier = 4; // Short Cycle Slow Multiplier
input int mediumCycleFastMultiplier = 6; // Medium Cycle Fast Multiplier
input int mediumCycleSlowMultiplier = 12; // Medium Cycle Slow Multiplier
input int longCycleFastMultiplier = 36; // Long Cycle Fast Multiplier
input int longCycleSlowMultiplier = 72; // Long Cycle Slow Multiplier
//
// Show/Hide Inputs ...
input bool showPSar = false; // Show Parabolic Sar
input bool showMarketMiddle = false; // Show Market Middle
input bool showShortCycle = false; // Show Short Cycle
input bool showShortCycleCrossLines = false; // Show Short Cycle Vertical Lines
input bool showMediumCycle = false; // Show Medium Cycle
input bool showMediumCycleCrossLines = false; // Show Medium Cycle Vertical Lines
input bool showLongCycle = false; // Show Long Cycle
input bool showLongCycleCrossLines = false; // Show Long Cycle Vertical Lines
//
// Color Inputs ...
input color pSarColor = clrCornflowerBlue; // Parabolic Sar Color
input color shortCycleFastColor = clrGreen; // Short Cycle Fast Color ...
input color shortCycleSlowColor = clrRed; // Short Cycle Slow Color ...
input color mediumCycleFastColor = clrAqua; // Medium Cycle Fast Color ...
input color mediumCycleSlowColor = clrFuchsia; // Medium Cycle Slow Color ...
input color longCycleFastColor = clrGoldenrod; // Medium Cycle Fast Color ...
input color longCycleSlowColor = clrBrown; // Medium Cycle Slow Color ...
//
// XMKT Inputs ...
//
// Market Specifications ...
input bool showHighestHigh = false; // Show Market Highest High
input bool showHighestLow = false; // Show Market Highest Low
input bool showHighestOpen = false; // Show Market Highest Open
input bool showHighestClose = false; // Show Market Highest Close
input bool showLowestHigh = false; // Show Market Lowest High
input bool showLowestLow = false; // Show Market Lowest Low
input bool showLowestOpen = false; // Show Market Lowest Open
input bool showLowestClose = false; // Show Market Lowest Close
//
input color highestHighColor = clrDeepPink; // Market Highest High Color
input color highestLowColor = clrDarkOrange; // Market Highest Low Color
input color highestOpenColor = clrDodgerBlue; // Market Highest Open Color
input color highestCloseColor = clrOrchid; // Market Highest Close Color
input color lowestHighColor = clrHotPink; // Market Lowest High Color
input color lowestLowColor = clrOrange; // Market Lowest Low Color
input color lowestOpenColor = clrPowderBlue; // Market Lowest Open Color
input color lowestCloseColor = clrMediumOrchid; // Market Lowest Close Color
//
input ENUM_LINE_STYLE highestHighStyle = STYLE_DOT; // Market Highest High Line Style
input ENUM_LINE_STYLE highestLowStyle = STYLE_DOT; // Market Highest Low Line Style
input ENUM_LINE_STYLE highestOpenStyle = STYLE_DOT; // Market Highest Open Line Style
input ENUM_LINE_STYLE highestCloseStyle = STYLE_DOT; // Market Highest Close Line Style
input ENUM_LINE_STYLE lowestHighStyle = STYLE_DOT; // Market Lowest High Line Style
input ENUM_LINE_STYLE lowestLowStyle = STYLE_DOT; // Market Lowest Low Line Style
input ENUM_LINE_STYLE lowestOpenStyle = STYLE_DOT; // Market Lowest Open Line Style
input ENUM_LINE_STYLE lowestCloseStyle = STYLE_DOT; // Market Lowest Close Line Style
//
// SHPD Indicator ...
input double sharpDetectMultiplier = 500; // Sharp Detect Multiplier
// //
// input bool drawSharpDetectedLabels = false; // Draw Labels on Founded Sharps
// //
// input string sharpBullishLabel = "SH_BULL"; // Sharp Bullish Label
// input color sharpBullishColor = clrAqua; // Sharp Bullish color
// //
// input string sharpBearishLabel = "SH_BEAR"; // Sharp Bearish Label
// input color sharpBearishColor = clrFuchsia; // Sharp Bearish color
// //
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
int lastSignalledBar = 0;
//
bool waitForLongSignals = true;
bool closeLongTrades = false;
//
bool waitForShortSignals = true;
bool closeShortTrades = false;
//
bool isMCGoingToClose;
bool isSharpBullishHappens;
bool isSharpBearishHappens;
//
datetime startMarketTime;
//
// Includes our shared library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes our shared library ...
#include "../Libraries/x-saherelm.signal.lib.mq4"
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Validate Inputs ...
bool inputsNotValiid =
//
// MARKET ...
marketLength < 0
|| riskToRewardRatio < 0
//
// EA ...
|| lotsPerTradePercent < 0
|| maxOpenTrades <= 0
|| maxDrawdownPercentPerPTrade < 0
|| minBalancePercent < 0
|| maxEquityPercent < 0
|| marketLength < 0
//
// OSC ...
|| fastOSCLength < 0
|| fastOSCMultiplier < 0
|| slowOSCLength < 0
|| slowOSCMultiplier < 0
|| minPowerOSC < 0
|| minVarianceOSC < 0
|| slowOSCLength <= fastOSCLength
//
// ZIGZAG ...
|| zDeviation < 0
|| zBackStep < 0
|| zBackStep >= marketLength
//
// XMA ...
//
// Validate Short Cycle ...
|| shortCycleFastMultiplier <= 0
|| shortCycleSlowMultiplier <= 0
|| shortCycleFastMultiplier >= shortCycleSlowMultiplier
//
// Validate Medium Cycle ...
|| mediumCycleFastMultiplier <= 0
|| mediumCycleSlowMultiplier <= 0
|| mediumCycleFastMultiplier >= mediumCycleSlowMultiplier
//
// Validate Long Cycle ...
|| longCycleFastMultiplier <= 0
|| longCycleSlowMultiplier <= 0
|| longCycleFastMultiplier >= longCycleSlowMultiplier
//
// Validate Series of Multipliers ...
|| shortCycleFastMultiplier >= mediumCycleFastMultiplier
|| mediumCycleFastMultiplier >= longCycleFastMultiplier
;
if (inputsNotValiid) {
return INIT_PARAMETERS_INCORRECT;
}
//
totalSignals = 0;
totalLongSignals = 0;
totalShortSignals = 0;
//
initialBalance = 0;
//
// START Define Array Series ...
//
//
// END Define Array Series ...
//
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XST";
// //
// // Set Event Timer on One Seccond ...
// bool isEventSet = EventSetTimer(1);
// if (!isEventSet) {
// LogMessage("Error: " + GetLastError());
// return INIT_FAILED;
// }
//
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason) {
//
// Killing Event Timer ...
EventKillTimer();
}
//
// Ticker Event Handler ...
void OnTick() {
//
isNewDay = IsNewDay();
if (isNewDay) {
//
LogMessage(
StringConcatenate(
"New Day: ", TimeCurrent()
)
);
}
//
// Process Signals to Open Positions ...
ProcessSignals();
//
// Checking State for Signal Handling ...
CheckState();
//
// Process Open Positions for Trailing Stop Loss or Close ...
ProcessOpenPositions();
}
//
// Timer Event Handler ...
void OnTimer() {
//
CheckState();
//
ProcessOpenPositions();
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// START Signal Related Functions ...
//
//
// Calculate Signal ...
// in this function we calculate a signal exists in
// specific bar or not ...
XSignalRequest GenerateSignal(
const int bar_index // Bar Index ...
) {
//
// create temp result ...
XSignalRequest result = {};
result.hasSignal = false;
result.type = X_NONE;
//
XSignal signal = {};
//
XOSCState emptyOscState = {};
ArrayFree(oscStates);
ArrayResize(
oscStates,
marketLength
);
for (int i = 0; i < marketLength; i++) {
oscStates[i] = emptyOscState;
}
//
XMAState emptyXmaState = {};
ArrayFree(xmaStates);
ArrayResize(
xmaStates,
shortCycleSlowMultiplier * marketLength
);
for (int i = 0; i < shortCycleSlowMultiplier * marketLength; i++) {
xmaStates[i] = emptyXmaState;
}
//
XMKTState emptyXmktState = {};
ArrayFree(xmktStates);
ArrayResize(
xmktStates,
marketLength
);
for (int i = 0; i < marketLength; i++) {
xmktStates[i] = emptyXmktState;
}
//
// Retrieve Bar Index Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index + 1
);
//
// START Retrieve Statets ...
//
//
// Loop through Market Length ...
int index = 0;
for (int i = bar_index; i < bar_index + marketLength; i++) {
//
// Retrieve Index OSC State ...
XOSCState oscState = GetOSCState(
i, // Bar Index ...
fastOSCLength,
fastOSCMultiplier,
slowOSCLength,
slowOSCMultiplier
);
//
// Retrieve XMarketState ...
XMKTState xmktState = GetMarketState(
//
i,
marketLength,
//
showHighestHigh,
highestHighColor,
highestHighStyle,
//
showHighestLow,
highestLowColor,
highestLowStyle,
//
showHighestOpen,
highestOpenColor,
highestOpenStyle,
//
showHighestClose,
highestCloseColor,
highestCloseStyle,
//
showLowestHigh,
lowestHighColor,
lowestHighStyle,
//
showLowestLow,
lowestLowColor,
lowestLowStyle,
//
showLowestOpen,
lowestOpenColor,
lowestOpenStyle,
//
showLowestClose,
lowestCloseColor,
lowestCloseStyle
);
//
// Set Retrieved Index States ...
oscStates[index] = oscState;
xmktStates[index] = xmktState;
//
index++;
}
index = 0;
for (int i = bar_index; i < bar_index + (shortCycleSlowMultiplier * marketLength); i++) {
//
// Retrieve XMA State ...
XMAState xmaState = GetXMAState(
i, // Bar Index ...
marketLength, // Market Length ...
step, // SAR Step ...
maximum, // SAR Maximum ...
shortCycleFastMultiplier, // Short Cycle Fast Multiplier ...
shortCycleSlowMultiplier, // Short Cycle Slow Multiplier ...
mediumCycleFastMultiplier, // Medium Cycle Fast Multiplier ...
mediumCycleSlowMultiplier, // Medium Cycle Slow Multiplier ...
longCycleFastMultiplier, // Long Cycle Fast Multiplier ...
longCycleSlowMultiplier, // Long Cycle Slow Multiplier ...
showPSar, // Show Parabolic Sar
showMarketMiddle, // Show Market Middle ...
showShortCycle, // Show Short Cycle
showShortCycleCrossLines, // Show Short Cycle Vertical Lines
showMediumCycle, // Show Medium Cycle
showMediumCycleCrossLines, // Show Medium Cycle Vertical Lines
showLongCycle, // Show Long Cycle
showLongCycleCrossLines, // Show Long Cycle Vertical Lines
pSarColor, // Parabolic Sar Color
shortCycleFastColor, // Short Cycle Fast Color ...
shortCycleSlowColor, // Short Cycle Slow Color ...
mediumCycleFastColor, // Medium Cycle Fast Color ...
mediumCycleSlowColor, // Medium Cycle Slow Color ...
longCycleFastColor, // Medium Cycle Fast Color ...
longCycleSlowColor // Medium Cycle Slow Color ...
);
//
xmaStates[index] = xmaState;
//
index++;
}
//
// END Retrieve Statets ...
//
//
// START States Calculations ...
//
//
// START OSC Calculations ...
//
//
// END OSC Calculations ...
//
//
// START XMA Calculations ...
//
//
// END XMA Calculations ...
//
//
// START Momentum Calculations ...
//
//
// END Momentum Calculations ...
//
//
// START RSI Calculations ...
//
//
// END RSI Calculations ...
//
//
// START PRICE Calculations ...
//
RefreshRates();
//
double marketLow[];
double marketOpen[];
double marketHigh[];
double marketClose[];
//
double marketUp[];
double marketDown[];
//
ArrayResize(
marketLow,
marketLength
);
ArrayResize(
marketOpen,
marketLength
);
ArrayResize(
marketHigh,
marketLength
);
ArrayResize(
marketClose,
marketLength
);
//
ArrayResize(
marketUp,
marketLength
);
ArrayResize(
marketDown,
marketLength
);
//
index = 0;
for (int i = bar_index; i < marketLength + bar_index; i++) {
//
marketLow[index] = iLow(
_Symbol,
_Period,
i
);
//
marketOpen[index] = iOpen(
_Symbol,
_Period,
i
);
//
marketHigh[index] = iHigh(
_Symbol,
_Period,
i
);
//
marketClose[index] = iClose(
_Symbol,
_Period,
i
);
//
// marketUp[i] = MathMax(marketOpen[i], marketClose[i]);
marketUp[index] = marketHigh[i];
//
// marketDown[i] = MathMin(marketOpen[i], marketClose[i]);
marketDown[index] = marketLow[i];
//
index++;
}
//
// LONG Prices ...
double longEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double longClosePrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double longPriceGap = longClosePrice - longEntryPrice;
//
// SHORT Prices ...
double shortEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double shortClosePrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double shortPriceGap = shortEntryPrice - shortClosePrice;
//
if (startMarketTime == 0) {
startMarketTime = barTime;
}
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
startMarketTime
);
//
if (startBarIndex > bar_index + marketLength) {
//
startBarIndex = 0;
startMarketTime = 0;
}
//
bool isSharpBullishDetected = false;
bool isShareBearishDetected = false;
double sharpDetectionValue = sharpDetectMultiplier * _Point;
if (startBarIndex > bar_index + 1) {
//
double marketStartHigh = iHigh(
_Symbol,
_Period,
startBarIndex
);
double marketStartLow = iLow(
_Symbol,
_Period,
startBarIndex
);
//
double prevCandleOpen = iOpen(
_Symbol,
_Period,
bar_index + 1
);
//
double prevCandleHigh = iHigh(
_Symbol,
_Period,
bar_index + 1
);
//
double prevCandleClose = iClose(
_Symbol,
_Period,
bar_index + 1
);
//
double candleOpen = iOpen(
_Symbol,
_Period,
bar_index
);
//
double prevCandleComparedPrice = MathMin(prevCandleOpen, prevCandleClose);
isShareBearishDetected =
prevCandleHigh < marketStartHigh
&& prevCandleComparedPrice < marketStartHigh
&& marketStartHigh - prevCandleComparedPrice >= sharpDetectionValue;
// //
// isSharpBullishDetected =
// marketStartHigh - MathMin(prevCandleOpen, prevCandleClose) >= sharpDetectionValue;
}
//
if (
isShareBearishDetected
|| isSharpBullishDetected
) {
startBarIndex = 0;
startMarketTime = 0;
}
//
//
// END PRICE Calculations ...
//
//
// START Capturing Signal ...
//
//
// START LONG Signals ...
//
//
// NOTES:
// when MC Fast is Over MC Slow,
// All Long Trades must be down when Market Middle is above MCSlow ...
// and must be paused when Market Middle is Going Under MCSlow ...
//
// OSC ...
bool oscHasLongSignal = false;
if (useOSCSignalling) {
//
oscHasLongSignal =
true
&& (
oscStates[0].fastOSC < 0
)
;
}
//
// XMA ...
bool xmaHasLongSignal = false;
if (useXMASignalling) {
//
xmaHasLongSignal =
//
// Long Cycle Trend Up ...
xmaStates[0].lcFast > xmaStates[0].lcSlow
// Lowest Low Must be Higher than lcFast ...
&& xmktStates[0].lowestLow > xmaStates[0].lcFast
//
// Medium Cycle in Up Trend ...
&& xmaStates[0].mcFast > xmaStates[0].mcSlow
//
// and the Medium Cycle Distance must be at least 100 Point ...
&& (xmaStates[0].mcFast - xmaStates[0].mcSlow) > (100 * _Point)
//
// then looking for parabolic sar cross down market middleage ...
&& xmaStates[0].parabolicSAR < xmaStates[0].marketMiddleage
&& !(xmaStates[1].parabolicSAR <= xmaStates[1].marketMiddleage)
//
&& xmaStates[0].scFast > xmaStates[0].marketMiddleage
//
// in crossing time Parabolic SAR must be greater than mcFast ...
&& xmaStates[0].parabolicSAR > xmaStates[0].mcFast
//
// in this conditions, entry price must below than highest high, in market ...
&& longEntryPrice < xmktStates[0].highestHigh
;
}
//
bool xshpHasLongSignal = false;
if (useXSHPSignalling) {
//
xshpHasLongSignal =
//
isShareBearishDetected
//
&& xmaStates[0].mcFast > xmaStates[0].mcSlow
&& xmaStates[1].mcFast > xmaStates[1].mcSlow
&& xmaStates[2].mcFast > xmaStates[3].mcSlow
//
&& xmaStates[1].mcFast - xmaStates[1].mcSlow > (100 * _Point)
//
&& xmktStates[1].lowestLow > xmaStates[1].mcSlow
&& xmktStates[1].highestLow > xmktStates[1].lowestHigh
&& MathAbs(xmktStates[0].highestLow - xmktStates[0].lowestHigh) > (50 * _Point)
//
&& longEntryPrice != xmktStates[0].lowestHigh
&& MathAbs(longEntryPrice - xmktStates[0].lowestHigh) > (50 * _Point)
//
&& (xmaStates[0].marketMiddleage > xmaStates[0].mcFast
|| (
xmaStates[0].marketMiddleage > xmaStates[0].mcSlow
&& xmaStates[0].marketMiddleage < xmaStates[0].mcFast
)
) ?
!(longEntryPrice < xmaStates[0].mcSlow)
&& !(
longEntryPrice > xmaStates[0].mcSlow
&& longEntryPrice < xmaStates[0].mcFast
) :
true
;
}
//
bool xmntmHasLongSignal = false;
if (useXMNTMSignalling) {
}
//
bool xrsiHasLongSignal = false;
if (useXRSISignalling) {
}
//
bool hasLongSignal =
//
// OSC Signals ...
oscHasLongSignal
|| xmaHasLongSignal
|| xshpHasLongSignal
|| xmntmHasLongSignal
|| xrsiHasLongSignal
;
//
// END LONG Signals ...
//
//
// START SHORT Signals ...
//
bool hasShortSignal = false;
//
// END SHORT Signals ...
//
//
// Check Signal Exists regardless of Long or Short ...
bool hasSignal = hasLongSignal || hasShortSignal;
// //
// // Check Short Cycle For Double Crossing ...
// int scCrosses = 0;
// int pSarCrosses = 0;
// //
// // SC Crosses ...
// for (int i = bar_index; i < bar_index + (shortCycleSlowMultiplier * marketLength) - 1; i++) {
// //
// bool isPSarCrossUnderMarketMid =
// xmaStates[0].parabolicSAR < xmaStates[0].marketMiddleage
// && !(xmaStates[1].parabolicSAR < xmaStates[1].marketMiddleage);
// //
// bool isPSarCrossOverMarketMid =
// xmaStates[0].parabolicSAR > xmaStates[0].marketMiddleage
// && !(xmaStates[1].parabolicSAR > xmaStates[1].marketMiddleage);
// //
// if (
// isPSarCrossUnderMarketMid
// || isPSarCrossOverMarketMid
// ) {
// pSarCrosses++;
// }
// //
// bool isSCFastCrossOverSlow =
// xmaStates[i].scFast > xmaStates[i].scSlow
// && !(xmaStates[i].scFast > xmaStates[i].scSlow);
// //
// bool isSCFastCrossUnderSlow =
// xmaStates[i].scFast < xmaStates[i].scSlow
// && !(xmaStates[i].scFast < xmaStates[i].scSlow);
// //
// if (
// isSCFastCrossOverSlow
// || isSCFastCrossUnderSlow
// ) {
// scCrosses++;
// }
// }
// //
// // Parabolic SAR ...
// for (int i = bar_index; i < bar_index + (shortCycleFastMultiplier * marketLength) - 1; i++) {
// //
// bool isPSarCrossUnderMarketMid =
// xmaStates[0].parabolicSAR < xmaStates[0].marketMiddleage
// && !(xmaStates[1].parabolicSAR < xmaStates[1].marketMiddleage);
// //
// bool isPSarCrossOverMarketMid =
// xmaStates[0].parabolicSAR > xmaStates[0].marketMiddleage
// && !(xmaStates[1].parabolicSAR > xmaStates[1].marketMiddleage);
// //
// if (
// isPSarCrossUnderMarketMid
// || isPSarCrossOverMarketMid
// ) {
// pSarCrosses++;
// }
// }
// //
// if (
// scCrosses > 1
// || pSarCrosses > 1
// ) {
// LogMessage("Crosses Exceed ...");
// hasSignal = false;
// }
//
// Prevent from Going forward if there is not a Signal ...
if (!hasSignal) {
//
result.signal = signal;
return result;
}
//
totalSignals++;
//
// Define Price Related Variables ...
//
double price = 0;
double priceGap = 0;
double sl = 0;
double risk;
double reward;
double tp = 0;
double r2rRatio = riskToRewardRatio;
//
datetime time = iTime(
_Symbol,
_Period,
bar_index
);
//
// Fill Signal Related Variables ...
if (hasLongSignal) {
//
price = longEntryPrice;
priceGap = longPriceGap;
//
// Setting Up SL Based on Last Market Lowest ...
sl = GetMarketLowestLow(
bar_index,
marketLength
);
//
risk = price - sl;
if (risk > (MathAbs(xmaStates[0].mcFast - xmaStates[0].mcSlow) / 2)) {
risk = risk / 3;
}
reward = risk * r2rRatio;
tp = price + reward;
//
// Check TP based on Spread ...
if (tp < price + priceGap) {
tp = tp + priceGap;
}
//
sl = 0;
//
totalLongSignals++;
} else if (hasShortSignal) {
//
totalShortSignals++;
//
price = shortEntryPrice;
priceGap = shortPriceGap;
//
risk = sl - price;
reward = risk * r2rRatio;
tp = price - reward;
}
//
// Normalize Prices ...
price = NormalizeDouble(price, _Digits);
sl = NormalizeDouble(sl, _Digits);
tp = NormalizeDouble(tp, _Digits);
//
// Generate Signal Structure ...
signal.type = hasLongSignal ?
X_LONG :
X_SHORT;
signal.tp = tp;
signal.sl = sl;
signal.time = time;
signal.symbol = _Symbol;
signal.entryPrice = price;
signal.id = totalLongSignals;
//
// TODO: Fill Signal Comment By Sgnal Provider
signal.comment =
useOSCSignalling && oscHasLongSignal
? oscSignalIdentifier
: useXMASignalling && xmaHasLongSignal
? xmaSignalIdentifier
: useXSHPSignalling && xshpHasLongSignal
? xshpSignalIdentifier
: useXMNTMSignalling && xmntmHasLongSignal
? xmntmSignalIdentifier
: useXRSISignalling && xrsiHasLongSignal
? xrsiSignalIdentifier
: ""
;
//
// END Capturing Signal ...
//
//
// Fill Result ...
result.hasSignal = hasSignal;
result.signal = signal;
result.type = signal.type;
//
// Return Result ...
return result;
}
//
// Check State for Signal Handling ...
void CheckState() {
//
// Here we Must to Check Market State for enable or disable
// Signal Handlers and also make dection to close all long/short
// trades ...
//
// Prevent from Checking, if there is no states available ...
if (ArraySize(xmaStates) == 0) {
return;
}
// //
// closeLongTrades =
// xmaStates[0].parabolicSAR > xmaStates[0].marketMiddleage
// && !(xmaStates[1].parabolicSAR > xmaStates[1].marketMiddleage)
// ;
// //
// closeLongTrades =
// false
// ;
}
//
// Calculate Signals and Process Based on Exists Signals ...
void ProcessSignals() {
//
XSignalRequest request = {};
request.type = X_NONE;
request.hasSignal = false;
//
// Prevent Multiple Calculating on Same Bars ...
isNewBar = IsNewBar();
if (isNewBar) {
//
countedBars++;
}
//
bool allowDoTrade = true;
//
// Check Balance ...
if (initialBalance > 0) {
//
// Retrieve Account Balance ...
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double minimumBalanceForTrade =
balance > initialBalance
?
minBalancePercent * balance
:
minBalancePercent * initialBalance;
//
// Retrieve Account Equity ...
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
double maxAllowedEquity = balance - (balance * maxEquityPercent);
//
// Retrieve Free Marigin ...
double freeMargin = AccountFreeMargin();
double maximumMariginRisk = balance - (balance * maxEquityPercent);
//
if (
//
// Do not Open Positions if equity not passed ...
equity < maxAllowedEquity ||
//
// Do not Open Positions if free margin not passed ...
freeMargin <= maximumMariginRisk ||
//
// Do not open positions if balance less than minimum ...
balance <= minimumBalanceForTrade
) {
//
allowDoTrade = false;
// //
// string message = StringConcatenate(
// "Trading Pause => ",
// "Balance: ", balance,
// ", Equity: ", equity,
// ", FreeMargin: ", freeMargin
// );
// //
// LogMessage(message);
// SendAlert(message);
}
}
//
// Retrieve Signal Exists ...
request = GenerateSignal(0);
//
// Prevent doing anything else, if there is no signals ...
if (
!allowDoTrade ||
!request.hasSignal ||
request.type == X_NONE
) {
return;
}
//
bool hasLongSignal = request.type == X_LONG;
//
// Check For Bot State ...
if (
(hasLongSignal && !waitForLongSignals)
|| (!hasLongSignal && !waitForShortSignals)
) {
return;
}
//
// Check last Signalled Bar with Counted Bars ...
// Prevent Multiple Signalling on Same Bar ...
bool isInLastSignalledBars = false;
for (int i=0; i < marketLength; i++) {
//
isInLastSignalledBars =
isInLastSignalledBars
|| lastSignalledBar == countedBars - i
;
}
if (isInLastSignalledBars) {
//
totalSignals--;
if (hasLongSignal) {
totalLongSignals--;
} else {
totalShortSignals--;
}
return;
}
//
// increase last signalled bar ...
lastSignalledBar = countedBars;
//
// Calculate Can Trade or not ...
allowDoTrade = allowTrade
&& (
hasLongSignal ?
allowLongTrades :
allowShortTrades
);
//
// Chack Maximum Open Positions ...
int openTrades = CountOpenTrades();
if (maxOpenTrades > 0) {
//
if (openTrades >= maxOpenTrades) {
//
allowDoTrade = false;
//
if (closeAllInProfitOpenTradesWhenMaxOpenTradesReached) {
//
// Close All In Profit Trades ...
bool hasClosedInProfitTrade = CloseAllInProfitTrades();
if (hasClosedInProfitTrade) {
//
openTrades = CountOpenTrades();
//
allowDoTrade = !(openTrades >= maxOpenTrades);
}
}
//
if (!allowDoTrade) {
//
string message = StringConcatenate(
"Trading Pause => ",
"Max Open Trades (",
maxOpenTrades,
") reached ..."
);
//
LogMessage(message);
SendAlert(message);
}
}
}
//
// Check Trading is Enable or not ...
// nothing to do if trading is disabled ...
if (!allowDoTrade) {
// //
// string message = StringConcatenate(
// "Trading Not Allowed ..."
// );
// //
// LogMessage(message);
// SendAlert(message);
return;
}
//
bool isPositionOpened = TradeSignal(
request.signal,
signalPrefix,
lotsPerTradePercent,
//
bullishSignalLabel,
bullishSignalColor,
bearishSignalLabel,
bearishSignalColor,
//
// Signal Identifiers ...
oscSignalIdentifier,
xmaSignalIdentifier,
xshpSignalIdentifier,
xmntmSignalIdentifier,
xrsiSignalIdentifier
);
//
if (isPositionOpened) {
//
bool canAlert =
alertPositions
&& (
hasLongSignal ?
longPositionAlerts
:
shortPositionAlerts
);
//
if (canAlert) {
//
// Alert Message ...
string message = StringConcatenate(
"Trade on Signal ID: ", request.signal.id,
", Entry: ", request.signal.entryPrice,
", TP: ", request.signal.tp
);
//
// Terminal Alert ...
if (terminalAlert) {
Alert(message);
}
//
// Push Alert ...
if (pushAlert) {
SendNotification(message);
}
}
}
}
//
// Process All Open Positions ...
void ProcessOpenPositions() {
//
// this comes from check state ...
if (closeLongTrades) {
//
closeLongTrades = false;
//
bool isAllLongTradesClosed = CloseAllLongTrades();
if (isAllLongTradesClosed) {
// waitForLongSignals = false;
}
}
//
// this comes from check state ...
if (closeShortTrades) {
//
closeShortTrades = false;
//
bool isAllShortTradesClosed = CloseAllShortTrades();
if (isAllShortTradesClosed) {
// waitForShortSignals = false;
}
}
//
bool hasClosedLongTimeTrade = CloseAllLongTimeTrades(
closeAllOpenTradesAfterCandle
);
//
// Close Maximum DrawDown Passed Trades ...
bool hasClosedInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades(
maxDrawdownPercentPerPTrade
);
//
if (
hasClosedLongTimeTrade
|| hasClosedInDrawDownLongTrade
) {
//
// waitForLongSignals = false;
// waitForShortSignals = false;
}
}
//
// Send Special Type of Alerts ...
void SendAlert(string message) {
//
if (!alertEvents) {
return;
}
//
// Terminal Alert ...
if (terminalAlert) {
Alert(message);
}
//
// Push Alert ...
if (pushAlert) {
SendNotification(message);
}
}
//
// END Functions ...
//