Initial Commit ...
This commit is contained in:
@@ -0,0 +1,784 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center XST_OSC Strategy Expert Advisor
|
||||
// ---------------------------------------------
|
||||
// saherelm implementation of strategy expert advisor ...
|
||||
//
|
||||
// ShortName: XST_OSC
|
||||
//
|
||||
// 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 "SaherElm XST_OSC Strategy Expert Advisor"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
// Signal Prefixe ...
|
||||
input string signalPrefix = "XST_OSC"; // 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 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.1; // Maximum DrawDown Per Trade
|
||||
input double minBalancePercent = 0.5; // Minimum Balance for Trading
|
||||
input double maxEquityPercent = 0.1; // Maximum Trade Equity
|
||||
input int closeAllOpenTradesAfterCandle = 864; // Close All Open Trades After Passed Candles
|
||||
|
||||
//
|
||||
// OSC Inputs ...
|
||||
//
|
||||
// FastOSC ...
|
||||
// Short Cycle (Fast OSC) ...
|
||||
input int fastOSCLength = 7; // FastOSC Length
|
||||
input double fastOSCMultiplier = 1.0; // FastOSC Multiplier
|
||||
|
||||
//
|
||||
// SlowOSC ...
|
||||
// Medium Cycle (Slow OSC) ...
|
||||
input int slowOSCLength = 14; // SlowOSC Length
|
||||
input double slowOSCMultiplier = 3.0; // SlowOSC Multiplier
|
||||
|
||||
//
|
||||
// Power OSC ...
|
||||
input double minPowerOSC = 0.055; // Minimum Signal Power
|
||||
|
||||
//
|
||||
// Variance OSC ...
|
||||
input double minVarianceOSC = 0; // Minimum Var Power
|
||||
|
||||
//
|
||||
// ZIGZAG Inputs ...
|
||||
input int zDeviation = 5; // ZigZag Deviation
|
||||
input int zBackStep = 3; // ZigZag Back Step
|
||||
|
||||
//
|
||||
// XMA Inputs ...
|
||||
//
|
||||
input int shortCycleFastMultiplier = 1; // Short Cycle Fast Multiplier
|
||||
input int shortCycleSlowMultiplier = 4; // Short Cycle Slow Multiplier
|
||||
input int mediumCycleFastMultiplier = 7; // Medium Cycle Fast Multiplier
|
||||
input int mediumCycleSlowMultiplier = 14; // Medium Cycle Slow Multiplier
|
||||
input int longCycleFastMultiplier = 70; // Long Cycle Fast Multiplier
|
||||
input int longCycleSlowMultiplier = 140; // Long Cycle Slow Multiplier
|
||||
//
|
||||
// Show/Hide Inputs ...
|
||||
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 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 ...
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
int lastSignalledBar = 0;
|
||||
|
||||
//
|
||||
bool waitForLongSignals = true;
|
||||
bool closeLongTrades = false;
|
||||
|
||||
//
|
||||
bool waitForShortSignals = true;
|
||||
bool closeShortTrades = false;
|
||||
|
||||
//
|
||||
// Includes our shared library ...
|
||||
#include "../Libraries/x-saherelm.lib.mq4"
|
||||
|
||||
//
|
||||
// Includes our shared library ...
|
||||
#include "../Libraries/x-saherelm.osc.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_OSC";
|
||||
|
||||
// //
|
||||
// // 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() {
|
||||
//
|
||||
// Checking State for Signal Handling ...
|
||||
CheckState();
|
||||
|
||||
//
|
||||
// Process Signals to Open Positions ...
|
||||
ProcessSignals();
|
||||
|
||||
//
|
||||
// Process Open Positions for Trailing Stop Loss or Close ...
|
||||
ProcessOpenPositions();
|
||||
}
|
||||
|
||||
//
|
||||
// Timer Event Handler ...
|
||||
void OnTimer() {
|
||||
//
|
||||
CheckState();
|
||||
|
||||
//
|
||||
ProcessOpenPositions();
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Check State for Signal Handling ...
|
||||
void CheckState() {
|
||||
//
|
||||
// Here we Must to Check Market State in Big Picture ...
|
||||
|
||||
//
|
||||
bool isSCFastCrossUnderSlow = xmaState.scFast < xmaState.scSlow
|
||||
&& !(xmaState.scFastPrev < xmaState.scSlowPrev);
|
||||
|
||||
//
|
||||
bool isMCFastCrossUnderSlow = xmaState.mcFast < xmaState.mcSlow
|
||||
&& !(xmaState.mcFastPrev < xmaState.mcSlowPrev);
|
||||
|
||||
//
|
||||
bool isLCFastCrossUnderSlow = xmaState.lcFast < xmaState.lcSlow
|
||||
&& !(xmaState.lcFastPrev < xmaState.lcSlowPrev);
|
||||
|
||||
//
|
||||
closeLongTrades =
|
||||
(
|
||||
isSCFastCrossUnderSlow
|
||||
&& isMCFastCrossUnderSlow
|
||||
)
|
||||
||
|
||||
(
|
||||
isSCFastCrossUnderSlow
|
||||
&& isLCFastCrossUnderSlow
|
||||
)
|
||||
||
|
||||
(
|
||||
isMCFastCrossUnderSlow
|
||||
&& isLCFastCrossUnderSlow
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
waitForLongSignals =
|
||||
waitForLongSignals
|
||||
?
|
||||
true
|
||||
:
|
||||
(
|
||||
(
|
||||
xmaState.lcFast > xmaState.lcSlow
|
||||
&& !(xmaState.lcFastPrev > xmaState.lcSlowPrev)
|
||||
)
|
||||
||
|
||||
(
|
||||
xmaState.mcFast > xmaState.mcSlow
|
||||
&& !(xmaState.mcFastPrev > xmaState.mcSlowPrev)
|
||||
)
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
// 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++;
|
||||
|
||||
// //
|
||||
// LogMessage(
|
||||
// StringConcatenate(
|
||||
// "Check Signals, Bars: ",
|
||||
// countedBars
|
||||
// )
|
||||
// );
|
||||
|
||||
//
|
||||
// Retrieve Signal Exists ...
|
||||
// request = CalculateSignal(
|
||||
// //
|
||||
// // Bar Index ...
|
||||
// 0,
|
||||
// //
|
||||
// // Market Specification Inpouts ...
|
||||
// marketLength, // Market Length ...
|
||||
// //
|
||||
// // Risk To Reward Ratio ...
|
||||
// riskToRewardRatio,
|
||||
// //
|
||||
// // XMA Inputs ...
|
||||
// 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 ...
|
||||
// //
|
||||
// // Show/Hide Inputs ...
|
||||
// showShortCycle,
|
||||
// showShortCycleCrossLines,
|
||||
// showMediumCycle,
|
||||
// showMediumCycleCrossLines,
|
||||
// showLongCycle,
|
||||
// showLongCycleCrossLines,
|
||||
// //
|
||||
// // Color Inputs ...
|
||||
// shortCycleFastColor,
|
||||
// shortCycleSlowColor,
|
||||
// mediumCycleFastColor,
|
||||
// mediumCycleSlowColor,
|
||||
// longCycleFastColor,
|
||||
// longCycleSlowColor,
|
||||
// //
|
||||
// // OSC ...
|
||||
// fastOSCLength, // FastOSC Length ...
|
||||
// fastOSCMultiplier, // FastOSC Multiplier ...
|
||||
// slowOSCLength, // SlowOSC Length ...
|
||||
// slowOSCMultiplier, // SlowOSC Multiplier ...
|
||||
// minPowerOSC, // Minimum Signal Power ...
|
||||
// minVarianceOSC, // Minimum Var Power ...
|
||||
// //
|
||||
// // ZIGZAG Inputs ...
|
||||
// zDeviation, // ZigZag Deviation ...
|
||||
// zBackStep // ZigZag Back Step ...
|
||||
// );
|
||||
}
|
||||
|
||||
//
|
||||
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);
|
||||
|
||||
//
|
||||
// Close In Profit Trades ...
|
||||
// then Recheck Signal ...
|
||||
// bool hasInProfitTradeClosed = CloseAllInProfitTrades();
|
||||
// if (hasInProfitTradeClosed) {
|
||||
// ProcessSignals();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Signal Exists ...
|
||||
request = CalculateSignal(
|
||||
//
|
||||
// Bar Index ...
|
||||
0,
|
||||
//
|
||||
// Market Specification Inpouts ...
|
||||
marketLength, // Market Length ...
|
||||
//
|
||||
// Risk To Reward Ratio ...
|
||||
riskToRewardRatio,
|
||||
//
|
||||
// XMA Inputs ...
|
||||
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 ...
|
||||
//
|
||||
// Show/Hide Inputs ...
|
||||
showShortCycle,
|
||||
showShortCycleCrossLines,
|
||||
showMediumCycle,
|
||||
showMediumCycleCrossLines,
|
||||
showLongCycle,
|
||||
showLongCycleCrossLines,
|
||||
//
|
||||
// Color Inputs ...
|
||||
shortCycleFastColor,
|
||||
shortCycleSlowColor,
|
||||
mediumCycleFastColor,
|
||||
mediumCycleSlowColor,
|
||||
longCycleFastColor,
|
||||
longCycleSlowColor,
|
||||
//
|
||||
// OSC ...
|
||||
fastOSCLength, // FastOSC Length ...
|
||||
fastOSCMultiplier, // FastOSC Multiplier ...
|
||||
slowOSCLength, // SlowOSC Length ...
|
||||
slowOSCMultiplier, // SlowOSC Multiplier ...
|
||||
minPowerOSC, // Minimum Signal Power ...
|
||||
minVarianceOSC, // Minimum Var Power ...
|
||||
//
|
||||
// ZIGZAG Inputs ...
|
||||
zDeviation, // ZigZag Deviation ...
|
||||
zBackStep // ZigZag Back Step ...
|
||||
);
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
if (lastSignalledBar == countedBars) {
|
||||
//
|
||||
totalSignals--;
|
||||
if (hasLongSignal) {
|
||||
totalLongSignals--;
|
||||
} else {
|
||||
totalShortSignals--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Prevent Signals if openTrades on last Market ...
|
||||
// this means for each trades at least we have to wait market length passed from last signal ...
|
||||
// if (lastSignalledBar + (marketLength) > countedBars) {
|
||||
// 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;
|
||||
|
||||
//
|
||||
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
|
||||
);
|
||||
|
||||
//
|
||||
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() {
|
||||
//
|
||||
// TODO:
|
||||
// - Order 5 Long Time;
|
||||
// - Order 8 Long Time;
|
||||
// - Order 13 Long Time;
|
||||
// - lcTrendDown;
|
||||
// - mcTrendUp;
|
||||
// - scTrendDown;
|
||||
// - marketMiddleage < mcSlow;
|
||||
// - longEntryPrice > lcSlow;
|
||||
// - scTrendPowerUp;
|
||||
// - Order 14 All Long Trades;
|
||||
// - lcMarket TrendUp;
|
||||
// - mcMarket TrendUp;
|
||||
// -
|
||||
// - Order 16 Long Time;
|
||||
// - Ordrr 17 Long Time;
|
||||
// - Ordrr 22 Long Time;
|
||||
// - Ordrr 26 Long Time;
|
||||
// - Ordrr 32 All Long Trades;
|
||||
// - Ordrr 40 Long Time;
|
||||
// - Ordrr 41 Long Time;
|
||||
// - Ordrr 52 Long Time;
|
||||
// - Ordrr 66 Long Time;
|
||||
// - Ordrr 73 Long Time;
|
||||
// - Ordrr 74 All Long Trades;
|
||||
// - Ordrr 78 Long Time;
|
||||
// - Ordrr 78 Long Time;
|
||||
// - Ordrr 87 All Long Trades;
|
||||
// - Ordrr 95 Long Time;
|
||||
// - Ordrr 97 Long Time;
|
||||
// - Ordrr 106 Long Time;
|
||||
// - Ordrr 107 All Long Trades;
|
||||
// - Ordrr 109 Long Time;
|
||||
// - Ordrr 111 Long Time;
|
||||
|
||||
//
|
||||
if (closeLongTrades) {
|
||||
//
|
||||
closeLongTrades = false;
|
||||
|
||||
//
|
||||
bool isAllLongTradesClosed = CloseAllLongTrades();
|
||||
if (isAllLongTradesClosed) {
|
||||
waitForLongSignals = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
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 ...
|
||||
//
|
||||
@@ -0,0 +1,220 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center ADX Oscillator
|
||||
// ---------------------------------------------
|
||||
// saherelm implementation of above oscillator ...
|
||||
//
|
||||
// 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 "SaherElm ADX Oscillator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int length = 7; // Averaging Length
|
||||
input ENUM_APPLIED_PRICE appliedPrice = PRICE_WEIGHTED; // Averaging Applied Price
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_minimum 0
|
||||
#property indicator_maximum 100
|
||||
|
||||
//
|
||||
#property indicator_buffers 3
|
||||
|
||||
//
|
||||
#property indicator_level1 0.0
|
||||
#property indicator_level2 50.0
|
||||
#property indicator_level3 70.0
|
||||
#property indicator_level4 100.0
|
||||
#property indicator_levelcolor clrSilver
|
||||
#property indicator_levelstyle STYLE_DOT
|
||||
|
||||
//
|
||||
// ADX ...
|
||||
#property indicator_width1 1
|
||||
#property indicator_color1 clrLightBlue
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
|
||||
//
|
||||
// Positive Direction ...
|
||||
#property indicator_width2 1
|
||||
#property indicator_color2 clrLime
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_style2 STYLE_DOT
|
||||
|
||||
//
|
||||
// Negative Direction ...
|
||||
#property indicator_width3 1
|
||||
#property indicator_color3 clrRed
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_style3 STYLE_DOT
|
||||
|
||||
//
|
||||
// Declare Buffers ...
|
||||
#define adxBufferIndex 0
|
||||
#define positiveBufferIndex 1
|
||||
#define negativeBufferIndex 2
|
||||
|
||||
double adxBuffer[];
|
||||
double positiveBuffer[];
|
||||
double negativeBuffer[];
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// Start Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit() {
|
||||
//
|
||||
// Initialize what we want ...
|
||||
|
||||
//
|
||||
// Validating Input Parameters ...
|
||||
if (length < 0) {
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
IndicatorBuffers(3);
|
||||
|
||||
//
|
||||
SetIndexBuffer(positiveBufferIndex, positiveBuffer);
|
||||
SetIndexLabel(positiveBufferIndex, "DI+");
|
||||
|
||||
//
|
||||
SetIndexBuffer(negativeBufferIndex, negativeBuffer);
|
||||
SetIndexLabel(negativeBufferIndex, "DI-");
|
||||
|
||||
//
|
||||
SetIndexBuffer(adxBufferIndex, adxBuffer);
|
||||
SetIndexLabel(adxBufferIndex, "ADX");
|
||||
|
||||
//
|
||||
// initialization done ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// Do Calculation ...
|
||||
int OnCalculate(
|
||||
const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[]
|
||||
) {
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// because in some cases we may have more than one input for
|
||||
// calculation and we must prevent any calculation
|
||||
// untill we pass the biggest input length, here we get max Input length
|
||||
// and then wait until pass it ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
// input variable, we return 0 means nothing passed ...
|
||||
if (rates_total < maxLength) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// found which candles calculated before ...
|
||||
limit = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1;
|
||||
|
||||
//
|
||||
// this is the main loop of calculations, for each bar index ...
|
||||
for (int i = limit - 1; i >= 0; i--) {
|
||||
//
|
||||
// Start Calculation here ...
|
||||
// i is bar_index ...
|
||||
|
||||
//
|
||||
// Calculate Long TP ...
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
void CalculateBuffers(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
|
||||
//
|
||||
// Retrieves the current ADX value ...
|
||||
double adx = iADX(
|
||||
_Symbol,
|
||||
_Period,
|
||||
length,
|
||||
appliedPrice,
|
||||
MODE_MAIN,
|
||||
bar_index
|
||||
);
|
||||
adxBuffer[bar_index] = adx;
|
||||
|
||||
//
|
||||
// Retrieves the current DI+ value ...
|
||||
double plusDi = iADX(
|
||||
_Symbol,
|
||||
_Period,
|
||||
length,
|
||||
appliedPrice,
|
||||
MODE_PLUSDI,
|
||||
bar_index
|
||||
);
|
||||
positiveBuffer[bar_index] = plusDi;
|
||||
|
||||
//
|
||||
// Retrieves the current DI- value ...
|
||||
double minusDi = iADX(
|
||||
_Symbol,
|
||||
_Period,
|
||||
length,
|
||||
appliedPrice,
|
||||
MODE_MINUSDI,
|
||||
bar_index
|
||||
);
|
||||
negativeBuffer[bar_index] = minusDi;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,173 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MA Indicator
|
||||
// ---------------------------------------------
|
||||
// saherelm implementation of above indicator ...
|
||||
// this indicator uses two ma line:
|
||||
// - fast ma;
|
||||
// - slow ma;
|
||||
//
|
||||
// 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 "SaherElm MA Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
// Fast MA ...
|
||||
input int maLength = 20; // MA Length
|
||||
input int maShift = 0; // MA Shift
|
||||
input ENUM_MA_METHOD maMethod = MODE_EMA; // MA Method
|
||||
input ENUM_APPLIED_PRICE maAppliedPrice = PRICE_CLOSE; // MA Applied Price
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 1
|
||||
|
||||
//
|
||||
#property indicator_plots 1
|
||||
|
||||
//
|
||||
// Start Define Indicator Buffer Styles ...
|
||||
//
|
||||
//
|
||||
// Fast Ma Buffer ...
|
||||
#property indicator_label1 "Ma"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrYellow
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 2
|
||||
|
||||
//
|
||||
// End Define Indicator Buffer Styles ...
|
||||
//
|
||||
|
||||
//
|
||||
// Buffers ...
|
||||
#define maBufferIndex 0
|
||||
|
||||
double maBuffer[];
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// Start Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit() {
|
||||
//
|
||||
// Initialize what we want ...
|
||||
if (maLength <= 0) {
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Start Set Index Buffers ...
|
||||
//
|
||||
//
|
||||
// Ma ...
|
||||
SetIndexBuffer(maBufferIndex, maBuffer);
|
||||
SetIndexDrawBegin(maBufferIndex, maLength + 1);
|
||||
//
|
||||
// End Set Index Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[]
|
||||
) {
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// because in some cases we may have more than one input for
|
||||
// calculation and we must prevent any calculation
|
||||
// untill we pass the biggest input length, here we get max Input length
|
||||
// and then wait until pass it ...
|
||||
int maxLength = MathMax(0, maLength);
|
||||
|
||||
//
|
||||
// input variable, we return 0 means nothing passed ...
|
||||
if (rates_total < maxLength) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// found which candles calculated before ...
|
||||
limit = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1;
|
||||
|
||||
//
|
||||
// this is the main loop of calculations, for each bar index ...
|
||||
for (int i = limit - 1; i >= 0; i--) {
|
||||
//
|
||||
// Start Calculation here ...
|
||||
// i is bar_index ...
|
||||
|
||||
//
|
||||
// Calculate Ma ...
|
||||
CalculateMa(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Calculating Ma ...
|
||||
void CalculateMa(
|
||||
const int &bar_index
|
||||
) {
|
||||
//
|
||||
// Calculating Fast Ma ...
|
||||
double ma = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
maLength,
|
||||
maShift,
|
||||
maMethod,
|
||||
maAppliedPrice,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
maBuffer[bar_index] = ma;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,160 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center Momentum Oscillator
|
||||
// ---------------------------------------------
|
||||
// saherelm implementation of above oscillator ...
|
||||
//
|
||||
// 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 "SaherElm Momentum Oscillator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int length = 7; // Market Length
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 1
|
||||
|
||||
//
|
||||
#property indicator_level1 0.0
|
||||
#property indicator_level2 100.0
|
||||
#property indicator_levelcolor clrSilver
|
||||
#property indicator_levelstyle STYLE_DOT
|
||||
|
||||
//
|
||||
// MOMENTUM ...
|
||||
#property indicator_width1 1
|
||||
#property indicator_color1 clrLightBlue
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
|
||||
//
|
||||
// Declare Buffers ...
|
||||
#define momentumBufferIndex 0
|
||||
|
||||
double momentumBuffer[];
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// Start Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit() {
|
||||
//
|
||||
// Initialize what we want ...
|
||||
|
||||
//
|
||||
// Validating Input Parameters ...
|
||||
if (length < 0) {
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
IndicatorBuffers(1);
|
||||
|
||||
//
|
||||
SetIndexBuffer(momentumBufferIndex, momentumBuffer);
|
||||
SetIndexLabel(momentumBufferIndex, "Momentum");
|
||||
SetIndexDrawBegin(momentumBufferIndex, length);
|
||||
|
||||
//
|
||||
// initialization done ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// Do Calculation ...
|
||||
int OnCalculate(
|
||||
const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[]
|
||||
) {
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// because in some cases we may have more than one input for
|
||||
// calculation and we must prevent any calculation
|
||||
// untill we pass the biggest input length, here we get max Input length
|
||||
// and then wait until pass it ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
// input variable, we return 0 means nothing passed ...
|
||||
if (rates_total < maxLength) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// found which candles calculated before ...
|
||||
limit = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1;
|
||||
|
||||
//
|
||||
// this is the main loop of calculations, for each bar index ...
|
||||
for (int i = limit - 1; i >= 0; i--) {
|
||||
//
|
||||
// Start Calculation here ...
|
||||
// i is bar_index ...
|
||||
|
||||
//
|
||||
// Calculate Long TP ...
|
||||
CalculateBuffers(
|
||||
i,
|
||||
close
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
void CalculateBuffers(
|
||||
const int bar_index,
|
||||
const double &close[]
|
||||
) {
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
double momentum = close[bar_index] * 100 / close[bar_index + length];
|
||||
|
||||
//
|
||||
momentumBuffer[bar_index] = momentum;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,330 @@
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center OSC Indicator
|
||||
// -------------------------------------------------------------
|
||||
// this indicator provides OSC ...
|
||||
//
|
||||
// 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 "SaherElm OSC Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START 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
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// Includes our shared library ...
|
||||
#include "../Libraries/x-saherelm.lib.mq4"
|
||||
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
// we have 2 buffer in this indicator ...
|
||||
#property indicator_buffers 5
|
||||
|
||||
//
|
||||
// also we have 2 line for draw on this indicator ...
|
||||
#property indicator_plots 5
|
||||
|
||||
//
|
||||
// Fast OSC ...
|
||||
#property indicator_width1 1
|
||||
#property indicator_color1 clrAqua
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
|
||||
//
|
||||
// Slow OSC ...
|
||||
#property indicator_width2 1
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrFuchsia
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
|
||||
//
|
||||
// Power OSC ...
|
||||
#property indicator_width3 1
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrYellow
|
||||
#property indicator_style3 STYLE_DASHDOTDOT
|
||||
|
||||
//
|
||||
// Var OSC ...
|
||||
#property indicator_width4 1
|
||||
#property indicator_type4 DRAW_HISTOGRAM
|
||||
#property indicator_color4 clrBlueViolet
|
||||
#property indicator_style4 STYLE_SOLID
|
||||
|
||||
//
|
||||
// Tan Fast/Slow OSC ...
|
||||
#property indicator_width5 0
|
||||
#property indicator_type5 DRAW_NONE
|
||||
#property indicator_color5 clrNONE
|
||||
#property indicator_style5 STYLE_SOLID
|
||||
|
||||
//
|
||||
//#property indicator_minimum 0
|
||||
//#property indicator_maximum 1
|
||||
|
||||
//
|
||||
// set color of horizontal levels ...
|
||||
#property indicator_levelcolor clrGray
|
||||
|
||||
//
|
||||
// set style of horizontal levels ...
|
||||
#property indicator_levelstyle STYLE_DOT
|
||||
|
||||
//
|
||||
// Declare Buffers ...
|
||||
#define fastOSCBufferIndex 0
|
||||
#define slowOSCBufferIndex 1
|
||||
#define powerOSCBufferIndex 2
|
||||
#define varOSCBufferIndex 3
|
||||
#define fastSlowOSCAngleBufferIndex 4
|
||||
|
||||
//
|
||||
double fastOSCBuffer[];
|
||||
double slowOSCBuffer[];
|
||||
double fastSlowOSCAngleBuffer[];
|
||||
double powerOSCBuffer[];
|
||||
double varOSCBuffer[];
|
||||
|
||||
//
|
||||
// Used Indicators List ...
|
||||
string rmaIndicatorName = "x-saherelm.rma";
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// Start Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit() {
|
||||
//
|
||||
// Initialize what we want ...
|
||||
|
||||
//
|
||||
// Validating Input Parameters ...
|
||||
if (
|
||||
fastOSCLength < 0 ||
|
||||
slowOSCLength < 0 ||
|
||||
slowOSCLength <= fastOSCLength
|
||||
) {
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// here we specify logging enabled or not ...
|
||||
enableLogging = true;
|
||||
|
||||
//
|
||||
// this is a Tag which attached to our Logger ...
|
||||
logTag = "XS_OSC";
|
||||
|
||||
//
|
||||
// set descriptions of horizontal levels ...
|
||||
SetLevelValue(0, 0.0);
|
||||
IndicatorSetString(INDICATOR_LEVELTEXT,0,"");
|
||||
|
||||
//
|
||||
// set descriptions of horizontal levels ...
|
||||
SetLevelValue(1, 0.5);
|
||||
IndicatorSetString(INDICATOR_LEVELTEXT,1,"");
|
||||
|
||||
//
|
||||
// set descriptions of horizontal levels ...
|
||||
SetLevelValue(2, 1);
|
||||
IndicatorSetString(INDICATOR_LEVELTEXT,2,"");
|
||||
|
||||
//
|
||||
// Fast OSC Buffer ...
|
||||
SetIndexBuffer(fastOSCBufferIndex, fastOSCBuffer);
|
||||
SetIndexLabel(fastOSCBufferIndex, "Fast OSC");
|
||||
SetIndexDrawBegin(fastOSCBufferIndex, fastOSCLength - 1);
|
||||
|
||||
//
|
||||
// Slow OSC Buffer ...
|
||||
SetIndexBuffer(slowOSCBufferIndex, slowOSCBuffer);
|
||||
SetIndexLabel(slowOSCBufferIndex, "Slow OSC");
|
||||
SetIndexDrawBegin(slowOSCBufferIndex, slowOSCLength - 1);
|
||||
|
||||
//
|
||||
// Power OSC Buffer ...
|
||||
SetIndexBuffer(powerOSCBufferIndex, powerOSCBuffer);
|
||||
SetIndexLabel(powerOSCBufferIndex, "Power OSC");
|
||||
|
||||
//
|
||||
// Var OSC Buffer ...
|
||||
SetIndexBuffer(varOSCBufferIndex, varOSCBuffer);
|
||||
SetIndexLabel(varOSCBufferIndex, "Var OSC");
|
||||
|
||||
//
|
||||
// Tan Fast/Slow OSC Buffer ...
|
||||
SetIndexBuffer(fastSlowOSCAngleBufferIndex, fastSlowOSCAngleBuffer);
|
||||
SetIndexLabel(fastSlowOSCAngleBufferIndex, "F/L OSC Angle");
|
||||
|
||||
//
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//
|
||||
// Do Calculation ...
|
||||
int OnCalculate(
|
||||
const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[]
|
||||
) {
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// because in some cases we may have more than one input for
|
||||
// calculation and we must prevent any calculation
|
||||
// untill we pass the biggest input length, here we get max Input length
|
||||
// and then wait until pass it ...
|
||||
int maxLength = MathMax(fastOSCLength, slowOSCLength);
|
||||
|
||||
//
|
||||
// input variable, we return 0 means nothing passed ...
|
||||
if (rates_total < maxLength) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// found which candles calculated before ...
|
||||
limit = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1;
|
||||
|
||||
//
|
||||
// this is the main loop of calculations, for each bar index ...
|
||||
for (int i = limit - 1; i >= 0; i--) {
|
||||
//
|
||||
// Start Calculation here ...
|
||||
// i is bar_index ...
|
||||
|
||||
//
|
||||
CalculateOscillators(close, i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
|
||||
//
|
||||
// De Initialization ...
|
||||
void OnDeinit(const int reason) {
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
void CalculateOscillators(
|
||||
const double &close[],
|
||||
const int &bar_index
|
||||
) {
|
||||
//
|
||||
// FastOSC ...
|
||||
// Short Cycle Calculations ...
|
||||
int scl = fastOSCLength / 2;
|
||||
int scl2 = scl / 2;
|
||||
double maScl = iCustom(_Symbol, _Period, rmaIndicatorName, scl, 0, bar_index);
|
||||
double scmAtr = iATR(_Symbol, _Period, scl, bar_index);
|
||||
double scmOff = fastOSCMultiplier * scmAtr;
|
||||
double maScl2 = iCustom(_Symbol, _Period, rmaIndicatorName, scl2, 0, bar_index);
|
||||
double sctParam = maScl2 != 0 ? maScl2 : close[bar_index + 1];
|
||||
double sct = sctParam + scmOff;
|
||||
double scb = sctParam - scmOff;
|
||||
|
||||
//
|
||||
// SlowOSC ...
|
||||
// Medium Cycle Calculations ...
|
||||
int mcl = slowOSCLength / 2;
|
||||
int mcl2 = mcl / 2;
|
||||
double maMcl = iCustom(_Symbol, _Period, rmaIndicatorName, mcl, 0, bar_index);
|
||||
double mcmAtr = iATR(_Symbol, _Period, mcl, bar_index);
|
||||
double mcmOff = slowOSCMultiplier * mcmAtr;
|
||||
double maMcl2 = iCustom(_Symbol, _Period, rmaIndicatorName, mcl2, 0, bar_index);
|
||||
double mctParam = maMcl2 != 0 ? maMcl2 : close[bar_index + 1];
|
||||
double mct = mctParam + mcmOff;
|
||||
double mcb = mctParam - mcmOff;
|
||||
|
||||
//
|
||||
double scMM = (sct + scb) / 2;
|
||||
|
||||
//
|
||||
double fastOCS = (close[bar_index] - mcb) / (mct - mcb);
|
||||
fastOSCBuffer[bar_index] = fastOCS;
|
||||
|
||||
//
|
||||
double slowOCS = (scMM - mcb) / (mct - mcb);
|
||||
slowOSCBuffer[bar_index] = slowOCS;
|
||||
|
||||
//
|
||||
// Signal Power ...
|
||||
// Difference Variant between FastOSC and Slow OSC ...
|
||||
double powerOSC = fastOCS - slowOCS;
|
||||
powerOSCBuffer[bar_index] = powerOSC;
|
||||
|
||||
//
|
||||
// Var OSC ...
|
||||
double varOSC = fastOCS - 0.5;
|
||||
varOSCBuffer[bar_index] = varOSC;
|
||||
|
||||
//
|
||||
// Calculate Tan Fast/Slow OSC ...
|
||||
double fastOSCSlope = fastOSCBuffer[bar_index] - fastOSCBuffer[bar_index + 1];
|
||||
double slowOSCSlope = slowOSCBuffer[bar_index] - slowOSCBuffer[bar_index + 1];
|
||||
double tanFastSlowOSC = MathAbs(
|
||||
(fastOSCSlope - slowOSCSlope) / (1 + (fastOSCSlope * slowOSCSlope))
|
||||
);
|
||||
|
||||
//
|
||||
// here we pass Tan of angle ...
|
||||
// fastSlowOSCAngleBuffer[bar_index] = tanFastSlowOSC;
|
||||
|
||||
//
|
||||
// here we pass degree of angle ...
|
||||
fastSlowOSCAngleBuffer[bar_index] = MathArctan(tanFastSlowOSC);
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,141 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center RMA Indicator
|
||||
// ---------------------------------------------
|
||||
// saherelm implementation of above oscillator ...
|
||||
//
|
||||
// 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 "SaherElm RMA Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
// Set the RMA Length ...
|
||||
input int RMALength = 10; // Length
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
// we have 2 buffer in this indicator ...
|
||||
#property indicator_buffers 1
|
||||
|
||||
//
|
||||
// also we have 1 line for draw on this indicator ...
|
||||
#property indicator_plots 1
|
||||
|
||||
//
|
||||
// here we declare plot SlowOCS to system ...
|
||||
#property indicator_label1 "RMA"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrFuchsia
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
// Declare Buffers ...
|
||||
#define RMABufferIndex 0
|
||||
|
||||
//
|
||||
double RMABuffer[];
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// Start Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit() {
|
||||
//
|
||||
// Initialize what we want ...
|
||||
SetIndexBuffer(RMABufferIndex, RMABuffer);
|
||||
|
||||
//
|
||||
// initialization done ...
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//
|
||||
// Do Calculation ...
|
||||
int OnCalculate(
|
||||
const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[]
|
||||
) {
|
||||
//
|
||||
int maxLength = MathMax(0, RMALength);
|
||||
|
||||
//
|
||||
// wait to pass bars until we have rights ...
|
||||
if (rates_total <= maxLength) {
|
||||
//
|
||||
// return not calculated ...
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// find loop count for bars manipulation ...
|
||||
int count = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1;
|
||||
|
||||
//
|
||||
// Print("Count: ", count, ", Bars: ", Bars);
|
||||
|
||||
//
|
||||
// this is the main loop of calculations, for each bar index ...
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
//
|
||||
// Start Calculation with Formula 1 ...
|
||||
//
|
||||
double shortSMA = iMA(_Symbol, _Period, RMALength, 0, MODE_SMA, PRICE_CLOSE, i);
|
||||
double mediumSMA = iMA(_Symbol, _Period, RMALength * 2, 0, MODE_SMA, PRICE_CLOSE, i);
|
||||
double longSMA = iMA(_Symbol, _Period, RMALength * 3, 0, MODE_SMA, PRICE_CLOSE, i);
|
||||
|
||||
//
|
||||
double rma1 = longSMA - mediumSMA + shortSMA;
|
||||
rma1 = NormalizeDouble(rma1, _Digits);
|
||||
//
|
||||
// End Calculation with Formula 1 ...
|
||||
//
|
||||
|
||||
//
|
||||
RMABuffer[i] = rma1;
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,234 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center RSI Oscillator
|
||||
// ---------------------------------------------
|
||||
// saherelm implementation of above oscillator ...
|
||||
//
|
||||
// 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 "SaherElm RSI Oscillator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int rsiPeriod=14; // RSI Period
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_minimum 0
|
||||
#property indicator_maximum 100
|
||||
|
||||
//
|
||||
#property indicator_buffers 1
|
||||
#property indicator_color1 DodgerBlue
|
||||
|
||||
//
|
||||
#property indicator_level1 30.0
|
||||
#property indicator_level2 50.0
|
||||
#property indicator_level3 70.0
|
||||
#property indicator_levelcolor clrSilver
|
||||
#property indicator_levelstyle STYLE_DOT
|
||||
|
||||
//
|
||||
// Declare Buffers ...
|
||||
#define rsiBufferIndex 0
|
||||
#define positiveBufferIndex 1
|
||||
#define negativeBufferIndex 2
|
||||
|
||||
double rsiBuffer[];
|
||||
double positiveBuffer[];
|
||||
double negativeBuffer[];
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// Start Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit() {
|
||||
//
|
||||
// Initialize what we want ...
|
||||
|
||||
//
|
||||
string short_name;
|
||||
|
||||
//
|
||||
IndicatorBuffers(3);
|
||||
|
||||
//
|
||||
SetIndexBuffer(positiveBufferIndex, positiveBuffer);
|
||||
SetIndexBuffer(negativeBufferIndex, negativeBuffer);
|
||||
|
||||
//
|
||||
SetIndexStyle(rsiBufferIndex, DRAW_LINE);
|
||||
SetIndexBuffer(rsiBufferIndex, rsiBuffer);
|
||||
|
||||
//
|
||||
// name for DataWindow and indicator subwindow label
|
||||
short_name="RSI("+string(rsiPeriod)+")";
|
||||
IndicatorShortName(short_name);
|
||||
SetIndexLabel(rsiBufferIndex, short_name);
|
||||
|
||||
//
|
||||
// check for input
|
||||
if (rsiPeriod < 2) {
|
||||
//
|
||||
Print("Incorrect value for input variable InpRSIPeriod = ", rsiPeriod);
|
||||
|
||||
//
|
||||
// Failed Initialization ...
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// set where to start draw ...
|
||||
SetIndexDrawBegin(0, rsiPeriod);
|
||||
|
||||
//
|
||||
// initialization done ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// Do Calculation ...
|
||||
int OnCalculate(
|
||||
const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[]
|
||||
) {
|
||||
//
|
||||
int i,pos;
|
||||
double diff;
|
||||
|
||||
//
|
||||
// Prevent from run calculations if there is no fulfilled conditions ...
|
||||
if (Bars <= rsiPeriod || rsiPeriod < 2) {
|
||||
//
|
||||
// return nothing calculated result ...
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// counting from 0 to rates_total, this is most important ...
|
||||
ArraySetAsSeries(rsiBuffer, false);
|
||||
ArraySetAsSeries(positiveBuffer, false);
|
||||
ArraySetAsSeries(negativeBuffer, false);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(close, false);
|
||||
|
||||
//
|
||||
// preliminary calculations ...
|
||||
pos = prev_calculated - 1;
|
||||
if (pos <= rsiPeriod) {
|
||||
//
|
||||
// first RSIPeriod values of the indicator are not calculated
|
||||
rsiBuffer[0] = 0.0;
|
||||
positiveBuffer[0] = 0.0;
|
||||
negativeBuffer[0] = 0.0;
|
||||
|
||||
//
|
||||
double sump=0.0;
|
||||
double sumn=0.0;
|
||||
for (i = 1; i <= rsiPeriod; i++) {
|
||||
//
|
||||
rsiBuffer[i]=0.0;
|
||||
positiveBuffer[i]=0.0;
|
||||
negativeBuffer[i]=0.0;
|
||||
|
||||
//
|
||||
diff = close[i] - close[i - 1];
|
||||
if(diff > 0) {
|
||||
sump += diff;
|
||||
} else {
|
||||
sumn -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// calculate first visible value ...
|
||||
positiveBuffer[rsiPeriod] = sump / rsiPeriod;
|
||||
negativeBuffer[rsiPeriod] = sumn / rsiPeriod;
|
||||
if (negativeBuffer[rsiPeriod] != 0.0) {
|
||||
//
|
||||
rsiBuffer[rsiPeriod] = 100.0 - (
|
||||
100.0 / (
|
||||
1.0 + positiveBuffer[rsiPeriod] / negativeBuffer[rsiPeriod]
|
||||
)
|
||||
);
|
||||
} else {
|
||||
//
|
||||
if (positiveBuffer[rsiPeriod] != 0.0) {
|
||||
rsiBuffer[rsiPeriod] = 100.0;
|
||||
} else {
|
||||
rsiBuffer[rsiPeriod] = 50.0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// prepare the position value for main calculation ...
|
||||
pos = rsiPeriod + 1;
|
||||
}
|
||||
|
||||
//
|
||||
// the main loop of calculations ...
|
||||
for (i = pos; i < rates_total && !IsStopped(); i++) {
|
||||
//
|
||||
diff = close[i] - close[i-1];
|
||||
|
||||
//
|
||||
positiveBuffer[i] = (positiveBuffer[i-1] * (rsiPeriod - 1) + (diff > 0.0 ? diff : 0.0)) / rsiPeriod;
|
||||
negativeBuffer[i] = (negativeBuffer[i-1] * (rsiPeriod - 1) + (diff < 0.0 ? -diff : 0.0)) / rsiPeriod;
|
||||
|
||||
//
|
||||
if (negativeBuffer[i] != 0.0) {
|
||||
rsiBuffer[i] = 100.0 - 100.0 / (1 + positiveBuffer[i] / negativeBuffer[i]);
|
||||
} else {
|
||||
//
|
||||
if (positiveBuffer[i] != 0.0) {
|
||||
rsiBuffer[i] = 100.0;
|
||||
} else {
|
||||
rsiBuffer[i] = 50.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return(rates_total);
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,643 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center XMA Indicator
|
||||
// ---------------------------------------------
|
||||
// saherelm implementation of above oscillator ...
|
||||
//
|
||||
// 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 "SaherElm XMA Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int marketLength = 7; // Market Length
|
||||
input int shortCycleFastMultiplier = 1; // Short Cycle Fast Multiplier
|
||||
input int shortCycleSlowMultiplier = 4; // Short Cycle Slow Multiplier
|
||||
input int mediumCycleFastMultiplier = 7; // Medium Cycle Fast Multiplier
|
||||
input int mediumCycleSlowMultiplier = 14; // Medium Cycle Slow Multiplier
|
||||
input int longCycleFastMultiplier = 70; // Long Cycle Fast Multiplier
|
||||
input int longCycleSlowMultiplier = 140; // Long Cycle Slow Multiplier
|
||||
//
|
||||
// Show Inputs ...
|
||||
input bool showShortCycle = true; // Show Short Cycle
|
||||
input bool showShortCycleCrossLines = true; // Show Short Cycle Vertical Lines
|
||||
input bool showMediumCycle = true; // Show Medium Cycle
|
||||
input bool showMediumCycleCrossLines = true; // Show Medium Cycle Vertical Lines
|
||||
input bool showLongCycle = true; // Show Long Cycle
|
||||
input bool showLongCycleCrossLines = true; // Show Long Cycle Vertical Lines
|
||||
//
|
||||
// Color Inputs ...
|
||||
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 ...
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
// define indicator buffers ...
|
||||
#property indicator_buffers 7
|
||||
#property indicator_plots 7
|
||||
|
||||
//
|
||||
// Middle ...
|
||||
#property indicator_label7 "Mid"
|
||||
#property indicator_type7 DRAW_LINE
|
||||
#property indicator_color7 clrBisque
|
||||
#property indicator_style7 STYLE_DASHDOTDOT
|
||||
#property indicator_width7 1
|
||||
|
||||
//
|
||||
// Declare Buffers ...
|
||||
#define scFastBufferIndex 0
|
||||
#define scSlowBufferIndex 1
|
||||
#define mcFastBufferIndex 2
|
||||
#define mcSlowBufferIndex 3
|
||||
#define lcFastBufferIndex 4
|
||||
#define lcSlowBufferIndex 5
|
||||
#define midBufferIndex 6
|
||||
|
||||
//
|
||||
double scFastBuffer[];
|
||||
double scSlowBuffer[];
|
||||
double mcFastBuffer[];
|
||||
double mcSlowBuffer[];
|
||||
double lcFastBuffer[];
|
||||
double lcSlowBuffer[];
|
||||
double midBuffer[];
|
||||
|
||||
//
|
||||
int shortCycleFastLength;
|
||||
int shortCycleSlowLength;
|
||||
int mediumCycleFastLength;
|
||||
int mediumCycleSlowLength;
|
||||
int longCycleFastLength;
|
||||
int longCycleSlowLength;
|
||||
|
||||
//
|
||||
// Includes our shared library ...
|
||||
#include "../Libraries/x-saherelm.lib.mq4"
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// Start Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit() {
|
||||
//
|
||||
// Initialize what we want ...
|
||||
|
||||
//
|
||||
// Validating Input Parameters ...
|
||||
if (
|
||||
//
|
||||
// Validate Market Length ...
|
||||
marketLength <= 0
|
||||
//
|
||||
// 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
|
||||
) {
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// here we specify logging enabled or not ...
|
||||
enableLogging = true;
|
||||
|
||||
//
|
||||
// this is a Tag which attached to our Logger ...
|
||||
logTag = "XST_XMA";
|
||||
|
||||
//
|
||||
// Calculate Cycle Length based on given Multipliers ...
|
||||
shortCycleFastLength = marketLength * shortCycleFastMultiplier;
|
||||
shortCycleSlowLength = marketLength * shortCycleSlowMultiplier;
|
||||
mediumCycleFastLength = marketLength * mediumCycleFastMultiplier;
|
||||
mediumCycleSlowLength = marketLength * mediumCycleSlowMultiplier;
|
||||
longCycleFastLength = marketLength * longCycleFastMultiplier;
|
||||
longCycleSlowLength = marketLength * longCycleSlowMultiplier;
|
||||
|
||||
//
|
||||
// Short Cycle Fast ...
|
||||
SetIndexLabel(scFastBufferIndex, "SCFast");
|
||||
SetIndexBuffer(scFastBufferIndex, scFastBuffer);
|
||||
SetIndexDrawBegin(scFastBufferIndex, shortCycleFastLength);
|
||||
SetIndexStyle(
|
||||
scFastBufferIndex,
|
||||
DRAW_LINE,
|
||||
STYLE_DOT,
|
||||
1,
|
||||
showShortCycle ?
|
||||
shortCycleFastColor :
|
||||
clrNONE
|
||||
);
|
||||
|
||||
//
|
||||
// Short Cycle Slow ...
|
||||
SetIndexLabel(scSlowBufferIndex, "SCSLow");
|
||||
SetIndexBuffer(scSlowBufferIndex, scSlowBuffer);
|
||||
SetIndexDrawBegin(scSlowBufferIndex, shortCycleSlowLength);
|
||||
SetIndexStyle(
|
||||
scSlowBufferIndex,
|
||||
DRAW_LINE,
|
||||
STYLE_DOT,
|
||||
1,
|
||||
showShortCycle ?
|
||||
shortCycleSlowColor :
|
||||
clrNONE
|
||||
);
|
||||
|
||||
//
|
||||
// Medium Cycle Fast ...
|
||||
SetIndexLabel(mcFastBufferIndex, "MCFast");
|
||||
SetIndexBuffer(mcFastBufferIndex, mcFastBuffer);
|
||||
SetIndexDrawBegin(mcFastBufferIndex, mediumCycleFastLength);
|
||||
SetIndexStyle(
|
||||
mcFastBufferIndex,
|
||||
DRAW_LINE,
|
||||
STYLE_DOT,
|
||||
1,
|
||||
showMediumCycle ?
|
||||
mediumCycleFastColor :
|
||||
clrNONE
|
||||
);
|
||||
|
||||
//
|
||||
// Medium Cycle Slow ...
|
||||
SetIndexLabel(mcSlowBufferIndex, "MCSlow");
|
||||
SetIndexBuffer(mcSlowBufferIndex, mcSlowBuffer);
|
||||
SetIndexDrawBegin(mcSlowBufferIndex, mediumCycleSlowLength);
|
||||
SetIndexStyle(
|
||||
mcSlowBufferIndex,
|
||||
DRAW_LINE,
|
||||
STYLE_DOT,
|
||||
1,
|
||||
showMediumCycle ?
|
||||
mediumCycleSlowColor :
|
||||
clrNONE
|
||||
);
|
||||
|
||||
//
|
||||
// Long Cycle Fast ...
|
||||
SetIndexLabel(lcFastBufferIndex, "LCFast");
|
||||
SetIndexBuffer(lcFastBufferIndex, lcFastBuffer);
|
||||
SetIndexDrawBegin(lcFastBufferIndex, longCycleFastLength);
|
||||
SetIndexStyle(
|
||||
lcFastBufferIndex,
|
||||
DRAW_LINE,
|
||||
STYLE_DOT,
|
||||
1,
|
||||
showLongCycle ?
|
||||
longCycleFastColor :
|
||||
clrNONE
|
||||
);
|
||||
|
||||
//
|
||||
// Long Cycle Slow ...
|
||||
SetIndexLabel(lcSlowBufferIndex, "LCSlow");
|
||||
SetIndexBuffer(lcSlowBufferIndex, lcSlowBuffer);
|
||||
SetIndexDrawBegin(lcSlowBufferIndex, longCycleSlowLength);
|
||||
SetIndexStyle(
|
||||
lcSlowBufferIndex,
|
||||
DRAW_LINE,
|
||||
STYLE_DOT,
|
||||
1,
|
||||
showLongCycle ?
|
||||
longCycleSlowColor :
|
||||
clrNONE
|
||||
);
|
||||
|
||||
//
|
||||
// Market Middleage ...
|
||||
SetIndexBuffer(midBufferIndex, midBuffer);
|
||||
SetIndexDrawBegin(midBufferIndex, marketLength);
|
||||
|
||||
//
|
||||
// initialization done ...
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason) {
|
||||
//
|
||||
RemoveDraws(logTag);
|
||||
}
|
||||
|
||||
//
|
||||
// Do Calculation ...
|
||||
int OnCalculate(
|
||||
const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[]
|
||||
) {
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// because in some cases we may have more than one input for
|
||||
// calculation and we must prevent any calculation
|
||||
// untill we pass the biggest input length, here we get max Input length
|
||||
// and then wait until pass it ...
|
||||
int maxLength = MathMax(marketLength, longCycleSlowLength);
|
||||
|
||||
//
|
||||
// input variable, we return 0 means nothing passed ...
|
||||
if (rates_total < maxLength) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// found which candles calculated before ...
|
||||
limit = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1;
|
||||
|
||||
//
|
||||
// this is the main loop of calculations, for each bar index ...
|
||||
for (int i = limit - 1; i >= 0; i--) {
|
||||
//
|
||||
// Start Calculation here ...
|
||||
// i is bar_index ...
|
||||
|
||||
//
|
||||
// Calculate Short Cycle ...
|
||||
CalculateShortCycle(i);
|
||||
|
||||
//
|
||||
// Calculate Medium Cycle ...
|
||||
CalculateMediumCycle(i);
|
||||
|
||||
//
|
||||
// Calculate Long Cycle ...
|
||||
CalculateLongCycle(i);
|
||||
|
||||
//
|
||||
// Calculate Market Middleage ...
|
||||
CalculateMarketMiddleage(i);
|
||||
|
||||
//
|
||||
// Calculate Cross Points ...
|
||||
CalculateCrossPoints(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Calculate Short Cycle ...
|
||||
void CalculateShortCycle(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
// Fast ...
|
||||
double shortCycleFast = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
shortCycleFastLength,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_WEIGHTED,
|
||||
bar_index
|
||||
);
|
||||
scFastBuffer[bar_index] = shortCycleFast;
|
||||
|
||||
//
|
||||
// Slow ...
|
||||
double shortCycleSlow = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
shortCycleSlowLength,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_WEIGHTED,
|
||||
bar_index
|
||||
);
|
||||
scSlowBuffer[bar_index] = shortCycleSlow;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Medium Cycle ...
|
||||
void CalculateMediumCycle(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
// Fast ...
|
||||
double mediumCycleFast = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
mediumCycleFastLength,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_MEDIAN,
|
||||
bar_index
|
||||
);
|
||||
mcFastBuffer[bar_index] = mediumCycleFast;
|
||||
|
||||
//
|
||||
// Slow ...
|
||||
double mediumCycleSlow = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
mediumCycleSlowLength,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_MEDIAN,
|
||||
bar_index
|
||||
);
|
||||
mcSlowBuffer[bar_index] = mediumCycleSlow;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Long Cycle ...
|
||||
void CalculateLongCycle(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
// Fast ...
|
||||
double longCycleFast = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
longCycleFastLength,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_CLOSE,
|
||||
bar_index
|
||||
);
|
||||
lcFastBuffer[bar_index] = longCycleFast;
|
||||
|
||||
//
|
||||
// Slow ...
|
||||
double longCycleSlow = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
longCycleSlowLength,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_CLOSE,
|
||||
bar_index
|
||||
);
|
||||
lcSlowBuffer[bar_index] = longCycleSlow;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Market Middleage ...
|
||||
void CalculateMarketMiddleage(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
// Mid ...
|
||||
double marketMiddleage = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
(int)(marketLength * 1.5),
|
||||
0,
|
||||
MODE_EMA,
|
||||
PRICE_MEDIAN,
|
||||
bar_index
|
||||
);
|
||||
midBuffer[bar_index] = marketMiddleage;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Cross Points and Draw Section Line on theme ...
|
||||
void CalculateCrossPoints(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
// START Draw Cross Lines ...
|
||||
//
|
||||
//
|
||||
// Short Cycle ...
|
||||
bool isSCFastCrossOverSlow = scFastBuffer[bar_index] > scSlowBuffer[bar_index]
|
||||
&& !(scFastBuffer[bar_index + 1] > scSlowBuffer[bar_index + 1]);
|
||||
|
||||
//
|
||||
bool isSCFastCrossUnderSlow = scFastBuffer[bar_index] < scSlowBuffer[bar_index]
|
||||
&& !(scFastBuffer[bar_index + 1] < scSlowBuffer[bar_index + 1]);
|
||||
|
||||
//
|
||||
// Medium Cycle ...
|
||||
bool isMCFastCrossOverSlow = mcFastBuffer[bar_index] > mcSlowBuffer[bar_index]
|
||||
&& !(mcFastBuffer[bar_index + 1] > mcSlowBuffer[bar_index + 1]);
|
||||
|
||||
//
|
||||
bool isMCFastCrossUnderSlow = mcFastBuffer[bar_index] < mcSlowBuffer[bar_index]
|
||||
&& !(mcFastBuffer[bar_index + 1] < mcSlowBuffer[bar_index + 1]);
|
||||
|
||||
//
|
||||
// Long Cycle ...
|
||||
bool isLCFastCrossOverSlow = lcFastBuffer[bar_index] > lcSlowBuffer[bar_index]
|
||||
&& !(lcFastBuffer[bar_index + 1] > lcSlowBuffer[bar_index + 1]);
|
||||
|
||||
//
|
||||
bool isLCFastCrossUnderSlow = lcFastBuffer[bar_index] < lcSlowBuffer[bar_index]
|
||||
&& !(lcFastBuffer[bar_index + 1] < lcSlowBuffer[bar_index + 1]);
|
||||
|
||||
//
|
||||
// START Drawing CrossPoints ...
|
||||
//
|
||||
//
|
||||
datetime currentTime = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
if (showShortCycleCrossLines) {
|
||||
//
|
||||
// Draw Line ...
|
||||
if (isSCFastCrossOverSlow) {
|
||||
//
|
||||
string lbl = StringConcatenate(
|
||||
logTag,
|
||||
"_SC_F_OV_S_",
|
||||
currentTime
|
||||
);
|
||||
|
||||
//
|
||||
DrawVerticalLine(
|
||||
0,
|
||||
lbl,
|
||||
0,
|
||||
currentTime,
|
||||
showShortCycleCrossLines ?
|
||||
shortCycleFastColor :
|
||||
clrNONE
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Line ...
|
||||
if (isSCFastCrossUnderSlow) {
|
||||
//
|
||||
string lbl = StringConcatenate(
|
||||
logTag,
|
||||
"_SC_F_UN_S_",
|
||||
currentTime
|
||||
);
|
||||
|
||||
//
|
||||
DrawVerticalLine(
|
||||
0,
|
||||
lbl,
|
||||
0,
|
||||
currentTime,
|
||||
showShortCycleCrossLines ?
|
||||
shortCycleSlowColor :
|
||||
clrNONE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (showMediumCycleCrossLines) {
|
||||
//
|
||||
// Draw Line ...
|
||||
if (isMCFastCrossOverSlow) {
|
||||
//
|
||||
string lbl = StringConcatenate(
|
||||
logTag,
|
||||
"_MC_F_OV_S_",
|
||||
currentTime
|
||||
);
|
||||
|
||||
//
|
||||
DrawVerticalLine(
|
||||
0,
|
||||
lbl,
|
||||
0,
|
||||
currentTime,
|
||||
showMediumCycleCrossLines ?
|
||||
mediumCycleFastColor :
|
||||
clrNONE
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Line ...
|
||||
if (isMCFastCrossUnderSlow) {
|
||||
//
|
||||
string lbl = StringConcatenate(
|
||||
logTag,
|
||||
"_MC_F_UN_S_",
|
||||
currentTime
|
||||
);
|
||||
|
||||
//
|
||||
DrawVerticalLine(
|
||||
0,
|
||||
lbl,
|
||||
0,
|
||||
currentTime,
|
||||
showMediumCycleCrossLines ?
|
||||
mediumCycleSlowColor :
|
||||
clrNONE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (showLongCycleCrossLines) {
|
||||
//
|
||||
// Draw Line ...
|
||||
if (isLCFastCrossOverSlow) {
|
||||
//
|
||||
string lbl = StringConcatenate(
|
||||
logTag,
|
||||
"_LC_F_OV_S_",
|
||||
currentTime
|
||||
);
|
||||
|
||||
//
|
||||
DrawVerticalLine(
|
||||
0,
|
||||
lbl,
|
||||
0,
|
||||
currentTime,
|
||||
showLongCycleCrossLines ?
|
||||
longCycleFastColor :
|
||||
clrNONE
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Line ...
|
||||
if (isLCFastCrossUnderSlow) {
|
||||
//
|
||||
string lbl = StringConcatenate(
|
||||
logTag,
|
||||
"_LC_F_UN_S_",
|
||||
currentTime
|
||||
);
|
||||
|
||||
//
|
||||
DrawVerticalLine(
|
||||
0,
|
||||
lbl,
|
||||
0,
|
||||
currentTime,
|
||||
showLongCycleCrossLines ?
|
||||
longCycleSlowColor :
|
||||
clrNONE
|
||||
);
|
||||
}
|
||||
}
|
||||
//
|
||||
// END Drawing CrossPoints ...
|
||||
//
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,476 @@
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center ZigZag Indicator
|
||||
// -------------------------------------------------------------
|
||||
// this indicator provides signals for Main strategy ...
|
||||
//
|
||||
// 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 "SaherElm ZigZag Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int depth = 12; // Depth
|
||||
input int deviation = 5; // Deviation
|
||||
input int backStep = 3; // BackStep
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// Includes our shared library ...
|
||||
#include "../Libraries/x-saherelm.lib.mq4"
|
||||
|
||||
//
|
||||
// here we specify logging enabled or not ...
|
||||
bool enableLogging = true;
|
||||
|
||||
//
|
||||
// this is a Tag which attached to our Logger ...
|
||||
string logTag = "XS_ZG";
|
||||
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 1
|
||||
|
||||
//
|
||||
#property indicator_width1 1
|
||||
#property indicator_color1 clrAqua
|
||||
// #property indicator_type1 DRAW_SECTION
|
||||
// #property indicator_style1 STYLE_SOLID
|
||||
|
||||
// //
|
||||
// #property indicator_width2 1
|
||||
// #property indicator_color2 clrNONE
|
||||
// #property indicator_type2 DRAW_NONE
|
||||
// #property indicator_style2 STYLE_SOLID
|
||||
|
||||
// //
|
||||
// #property indicator_width3 1
|
||||
// #property indicator_color3 clrNONE
|
||||
// #property indicator_type3 DRAW_NONE
|
||||
// #property indicator_style3 STYLE_SOLID
|
||||
|
||||
//
|
||||
// Buffers ...
|
||||
//
|
||||
#define zigzagBufferIndex 0
|
||||
#define highBufferIndex 1
|
||||
#define lowBufferIndex 2
|
||||
// #define ziggyBufferIndex 3
|
||||
|
||||
//
|
||||
double zigzagBuffer[];
|
||||
double highBuffer[];
|
||||
double lowBuffer[];
|
||||
// double ziggyBuffer[];
|
||||
|
||||
//
|
||||
// recounting's depth of extremums ...
|
||||
int level=3;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// Start Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit() {
|
||||
//
|
||||
// Initialize what we want ...
|
||||
|
||||
//
|
||||
// Validating Input Parameters ...
|
||||
if (
|
||||
depth <= 0 ||
|
||||
backStep < 0 ||
|
||||
deviation < 0 ||
|
||||
backStep >= depth
|
||||
) {
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Set Index Buffers of ZigZag ...
|
||||
IndicatorBuffers(3);
|
||||
|
||||
//
|
||||
// ZigZag Buffer ...
|
||||
SetIndexBuffer(zigzagBufferIndex, zigzagBuffer);
|
||||
SetIndexStyle(zigzagBufferIndex, DRAW_SECTION);
|
||||
SetIndexLabel(zigzagBufferIndex, "ZigZag");
|
||||
|
||||
//
|
||||
// High Buffer ...
|
||||
SetIndexBuffer(highBufferIndex, highBuffer);
|
||||
SetIndexLabel(highBufferIndex, "");
|
||||
|
||||
//
|
||||
// Low Buffer ...
|
||||
SetIndexBuffer(lowBufferIndex, lowBuffer);
|
||||
SetIndexLabel(lowBufferIndex, "");
|
||||
|
||||
//
|
||||
// Ziggy Buffer ...
|
||||
// SetIndexBuffer(ziggyBufferIndex, ziggyBuffer);
|
||||
// SetIndexLabel(ziggyBufferIndex, "");
|
||||
|
||||
//
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//
|
||||
// Do Calculation ...
|
||||
int OnCalculate(
|
||||
const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[]
|
||||
) {
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
int maxLength = MathMax(depth, backStep);
|
||||
|
||||
int i;
|
||||
int counterZ;
|
||||
int back;
|
||||
int pos;
|
||||
|
||||
//
|
||||
int lastlowpos = 0;
|
||||
int lasthighpos = 0;
|
||||
int whatlookfor = 0;
|
||||
|
||||
//
|
||||
double extremum;
|
||||
|
||||
//
|
||||
double curlow = 0.0;
|
||||
double curhigh = 0.0;
|
||||
double lasthigh = 0.0;
|
||||
double lastlow = 0.0;
|
||||
|
||||
//
|
||||
// input variable, we return 0 means nothing passed ...
|
||||
if (rates_total < maxLength) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// first calculations ...
|
||||
if (prev_calculated == 0) {
|
||||
limit = InitializeBuffers();
|
||||
} else {
|
||||
//
|
||||
// find first extremum in the depth ExtLevel or 100 last bars ...
|
||||
i = counterZ = 0;
|
||||
while(counterZ < level && i < 100) {
|
||||
//
|
||||
if(zigzagBuffer[i] != 0.0) {
|
||||
counterZ++;
|
||||
}
|
||||
|
||||
//
|
||||
i++;
|
||||
}
|
||||
|
||||
//
|
||||
// no extremum found - recounting all from begin ...
|
||||
if(counterZ == 0) {
|
||||
limit = InitializeBuffers();
|
||||
} else {
|
||||
//
|
||||
// set start position to found extremum position ...
|
||||
limit = i-1;
|
||||
|
||||
//
|
||||
//--- what kind of extremum?
|
||||
if(lowBuffer[i] != 0.0) {
|
||||
//
|
||||
// low extremum ...
|
||||
curlow = lowBuffer[i];
|
||||
|
||||
//
|
||||
// will look for the next high extremum ...
|
||||
whatlookfor=1;
|
||||
} else {
|
||||
//
|
||||
// high extremum ...
|
||||
curhigh = highBuffer[i];
|
||||
|
||||
//
|
||||
// will look for the next low extremum ...
|
||||
whatlookfor=-1;
|
||||
}
|
||||
|
||||
//
|
||||
// clear the rest data ...
|
||||
for(i = limit - 1; i >= 0; i--) {
|
||||
//
|
||||
lowBuffer[i]=0.0;
|
||||
highBuffer[i]=0.0;
|
||||
zigzagBuffer[i]=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Main Calculation Loop ...
|
||||
for (i = limit; i >= 0; i--) {
|
||||
//
|
||||
// find lowest low in depth of bars ...
|
||||
extremum = low[
|
||||
iLowest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_LOW,
|
||||
depth,
|
||||
i
|
||||
)
|
||||
];
|
||||
|
||||
//
|
||||
// this lowest has been found previously ...
|
||||
if (extremum == lastlow) {
|
||||
extremum = 0.0;
|
||||
} else {
|
||||
//
|
||||
// new last low ...
|
||||
lastlow=extremum;
|
||||
|
||||
//
|
||||
// discard extremum if current low is too high ...
|
||||
if(low[i] - extremum > deviation * _Point) {
|
||||
extremum=0.0;
|
||||
} else {
|
||||
//
|
||||
// clear previous extremums in backstep bars ...
|
||||
for(back = 1; back <= backStep; back++) {
|
||||
//
|
||||
pos = i + back;
|
||||
|
||||
//
|
||||
if(lowBuffer[pos] != 0 && lowBuffer[pos] > extremum) {
|
||||
lowBuffer[pos] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// found extremum is current low ...
|
||||
if (low[i] == extremum) {
|
||||
lowBuffer[i] = extremum;
|
||||
} else {
|
||||
lowBuffer[i] = 0.0;
|
||||
}
|
||||
|
||||
//
|
||||
// find highest high in depth of bars ...
|
||||
extremum = high[
|
||||
iHighest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_HIGH,
|
||||
depth,
|
||||
i
|
||||
)
|
||||
];
|
||||
|
||||
//
|
||||
// this highest has been found previously ...
|
||||
if (extremum == lasthigh) {
|
||||
extremum = 0.0;
|
||||
} else {
|
||||
//
|
||||
// new last high ...
|
||||
lasthigh=extremum;
|
||||
|
||||
//
|
||||
// discard extremum if current high is too low ...
|
||||
if (extremum - high[i] > deviation * Point) {
|
||||
extremum = 0.0;
|
||||
} else {
|
||||
//
|
||||
// clear previous extremums in backstep bars ...
|
||||
for(back = 1; back <= backStep; back++) {
|
||||
//
|
||||
pos = i + back;
|
||||
|
||||
//
|
||||
if (highBuffer[pos] != 0 && highBuffer[pos] < extremum) {
|
||||
highBuffer[pos] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// found extremum is current high ...
|
||||
if (high[i] == extremum) {
|
||||
highBuffer[i] = extremum;
|
||||
} else {
|
||||
highBuffer[i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// final cutting ...
|
||||
if( whatlookfor == 0) {
|
||||
//
|
||||
lastlow = 0.0;
|
||||
lasthigh = 0.0;
|
||||
} else {
|
||||
//
|
||||
lastlow = curlow;
|
||||
lasthigh = curhigh;
|
||||
}
|
||||
|
||||
//
|
||||
for(i = limit; i >= 0; i--) {
|
||||
switch(whatlookfor) {
|
||||
//
|
||||
// look for peak or lawn ...
|
||||
case 0:
|
||||
//
|
||||
if (lastlow == 0.0 && lasthigh == 0.0) {
|
||||
if(highBuffer[i]!=0.0) {
|
||||
//
|
||||
lasthigh = High[i];
|
||||
lasthighpos = i;
|
||||
whatlookfor = -1;
|
||||
|
||||
//
|
||||
zigzagBuffer[i] = lasthigh;
|
||||
}
|
||||
|
||||
//
|
||||
if(lowBuffer[i] != 0.0) {
|
||||
//
|
||||
lastlow = Low[i];
|
||||
lastlowpos = i;
|
||||
whatlookfor = 1;
|
||||
|
||||
//
|
||||
zigzagBuffer[i] = lastlow;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// look for peak ...
|
||||
case 1:
|
||||
//
|
||||
if (
|
||||
lowBuffer[i] != 0.0 &&
|
||||
lowBuffer[i] < lastlow &&
|
||||
highBuffer[i] == 0.0
|
||||
) {
|
||||
//
|
||||
zigzagBuffer[lastlowpos] = 0.0;
|
||||
lastlowpos = i;
|
||||
lastlow = lowBuffer[i];
|
||||
zigzagBuffer[i] = lastlow;
|
||||
}
|
||||
|
||||
//
|
||||
if(highBuffer[i] != 0.0 && lowBuffer[i] == 0.0) {
|
||||
//
|
||||
lasthigh = highBuffer[i];
|
||||
lasthighpos = i;
|
||||
zigzagBuffer[i] = lasthigh;
|
||||
|
||||
//
|
||||
whatlookfor=-1;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// look for lawn ...
|
||||
case -1:
|
||||
//
|
||||
if(
|
||||
highBuffer[i] != 0.0 &&
|
||||
highBuffer[i] > lasthigh &&
|
||||
lowBuffer[i] == 0.0
|
||||
) {
|
||||
//
|
||||
zigzagBuffer[lasthighpos] = 0.0;
|
||||
lasthighpos = i;
|
||||
lasthigh = highBuffer[i];
|
||||
zigzagBuffer[i] = lasthigh;
|
||||
}
|
||||
|
||||
//
|
||||
if(
|
||||
lowBuffer[i] !=0.0 &&
|
||||
highBuffer[i] == 0.0
|
||||
) {
|
||||
//
|
||||
lastlow = lowBuffer[i];
|
||||
lastlowpos = i;
|
||||
zigzagBuffer[i] = lastlow;
|
||||
whatlookfor=1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Done ...
|
||||
return rates_total;
|
||||
}
|
||||
|
||||
//
|
||||
// De Initialization ...
|
||||
void OnDeinit(const int reason) {
|
||||
//
|
||||
// RemoveDraws(signalPrefix);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
int InitializeBuffers() {
|
||||
//
|
||||
ArrayInitialize(lowBuffer,0.0);
|
||||
ArrayInitialize(highBuffer, 0.0);
|
||||
ArrayInitialize(zigzagBuffer, 0.0);
|
||||
|
||||
//
|
||||
//--- first counting position
|
||||
return(Bars - depth);
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,968 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL4 Global Library
|
||||
// ---------------------------------------------
|
||||
// saherelm useful tools and definitions ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Includes Logger library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq4"
|
||||
|
||||
//
|
||||
// Includes Drawing library ...
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq4"
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Determines current working is New Bar or not ...
|
||||
bool IsNewBar() {
|
||||
//
|
||||
static datetime lastbar;
|
||||
datetime curbar = (datetime)SeriesInfoInteger(_Symbol, _Period, SERIES_LASTBAR_DATE);
|
||||
|
||||
//
|
||||
if(lastbar != curbar) {
|
||||
//
|
||||
lastbar = curbar;
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve RMA on Specific Candle ...
|
||||
double GetRMA(
|
||||
int bar_index,
|
||||
int length
|
||||
) {
|
||||
//
|
||||
double shortSMA = iMA(_Symbol, _Period, length, 0, MODE_SMA, PRICE_CLOSE, bar_index);
|
||||
double mediumSMA = iMA(_Symbol, _Period, length * 2, 0, MODE_SMA, PRICE_CLOSE, bar_index);
|
||||
double longSMA = iMA(_Symbol, _Period, length * 3, 0, MODE_SMA, PRICE_CLOSE, bar_index);
|
||||
|
||||
//
|
||||
double result = longSMA - mediumSMA + shortSMA;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// this function check crossing up two Buffers ...
|
||||
bool IsCrossedOver(
|
||||
double &arr1[],
|
||||
double &arr2[],
|
||||
int index1,
|
||||
int index2 = -1
|
||||
) {
|
||||
//
|
||||
// Normalize Index 2 Value ...
|
||||
if (index2 < 0) {
|
||||
index2 = index1 + 1;
|
||||
}
|
||||
|
||||
//
|
||||
bool result = (arr1[index1] > arr2[index1]) && !(arr1[index2] > arr2[index2]);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// this function check crossing down two Buffers ...
|
||||
bool IsCrossedUnder(
|
||||
double &arr1[],
|
||||
double &arr2[],
|
||||
int index1,
|
||||
int index2 = -1
|
||||
) {
|
||||
//
|
||||
// Normalize Index 2 Value ...
|
||||
if (index2 < 0) {
|
||||
index2 = index1 + 1;
|
||||
}
|
||||
|
||||
//
|
||||
bool result = (arr1[index1] < arr2[index1]) && !(arr1[index2] < arr2[index2]);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Convert points to Actual Point ...
|
||||
double PointsToDouble(int points) {
|
||||
//
|
||||
double result = points * _Point;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Converts Pips to Points ...
|
||||
int PipsToPoints(int pips) {
|
||||
//
|
||||
int result = pips * ((_Digits == 3 || _Digits == 5) ? 10 : 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Converts Pips to Double ...
|
||||
double PipsToDouble(int pips) {
|
||||
//
|
||||
double result = PointsToDouble(PipsToPoints(pips));
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Converts Double Value to Pips ...
|
||||
int PriceToPips(double value) {
|
||||
//
|
||||
if (value <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
double pipValue = _Point * MathPow(10, _Digits);
|
||||
int result = (int)(value / pipValue);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Converts Pips to Double ...
|
||||
double PipsToPrice(int pips) {
|
||||
//
|
||||
if (pips <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
double pipValue = _Point * MathPow(10, _Digits);
|
||||
double result = pipValue * pips;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Generate ATR StopLoss Value ...
|
||||
double CalculateATRSL(
|
||||
int period,
|
||||
double multiplier
|
||||
) {
|
||||
//
|
||||
if (period <= 0 || multiplier <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
double atrValue = iATR(
|
||||
_Symbol,
|
||||
_Period,
|
||||
period,
|
||||
0
|
||||
);
|
||||
|
||||
//
|
||||
double result = atrValue * multiplier;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Candle Type ...
|
||||
// Bullish => means close > open ...
|
||||
bool isBullishCandle(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
// Temp Result ...
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (bar_index < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double open = iOpen(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
double close = iClose(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
result = isBullishCandle(
|
||||
open,
|
||||
close
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isBullishCandle(
|
||||
const double open,
|
||||
const double close
|
||||
) {
|
||||
//
|
||||
// Temp Result ...
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = open < close;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Candle Type ...
|
||||
// Bearish => means close < open ...
|
||||
bool isBearishCandle(
|
||||
const int bar_index
|
||||
) {
|
||||
//
|
||||
// Temp Result ...
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (bar_index < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double open = iOpen(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
double close = iClose(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
result = isBearishCandle(
|
||||
open,
|
||||
close
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isBearishCandle(
|
||||
const double open,
|
||||
const double close
|
||||
) {
|
||||
//
|
||||
// Temp Result ...
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = open > close;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Highest High Value based on Given Market ...
|
||||
double GetMarketHighestHigh(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const int marketLen // Market Length ...
|
||||
) {
|
||||
//
|
||||
// Empty Result ...
|
||||
double result = 0.0;
|
||||
|
||||
//
|
||||
// Retrieve Desired Bar Index ...
|
||||
int foundedBarIndex = iHighest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_HIGH,
|
||||
marketLen,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
// Retrieve Price ...
|
||||
result = iHigh(
|
||||
_Symbol,
|
||||
_Period,
|
||||
foundedBarIndex
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Highest High Value based on Given Market ...
|
||||
double GetMarketLowestLow(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const int marketLen // Market Length ...
|
||||
) {
|
||||
//
|
||||
// Empty Result ...
|
||||
double result = 0.0;
|
||||
|
||||
//
|
||||
// Retrieve Desired Bar Index ...
|
||||
int foundedBarIndex = iLowest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_LOW,
|
||||
marketLen,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
// Retrieve Price ...
|
||||
result = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
foundedBarIndex
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Highest High Value based on Given Market ...
|
||||
double GetMarketHighestOpen(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const int marketLen // Market Length ...
|
||||
) {
|
||||
//
|
||||
// Empty Result ...
|
||||
double result = 0.0;
|
||||
|
||||
//
|
||||
// Retrieve Desired Bar Index ...
|
||||
int foundedBarIndex = iHighest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_OPEN,
|
||||
marketLen,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
// Retrieve Price ...
|
||||
result = iOpen(
|
||||
_Symbol,
|
||||
_Period,
|
||||
foundedBarIndex
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Highest High Value based on Given Market ...
|
||||
double GetMarketLowestClose(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const int marketLen // Market Length ...
|
||||
) {
|
||||
//
|
||||
// Empty Result ...
|
||||
double result = 0.0;
|
||||
|
||||
//
|
||||
// Retrieve Desired Bar Index ...
|
||||
int foundedBarIndex = iLowest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_CLOSE,
|
||||
marketLen,
|
||||
bar_index
|
||||
);
|
||||
|
||||
//
|
||||
// Retrieve Price ...
|
||||
result = iClose(
|
||||
_Symbol,
|
||||
_Period,
|
||||
foundedBarIndex
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find last Candle which it's Low Price is
|
||||
// less than given price ...
|
||||
double GetLowLessCandlePrice(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int index = bar_index + 1;
|
||||
double result = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
|
||||
//
|
||||
while (result >= price) {
|
||||
//
|
||||
index++;
|
||||
|
||||
//
|
||||
result = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
int GetLowLessCandleIndex(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int result = bar_index + 1;
|
||||
double cP = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
|
||||
//
|
||||
while (cP >= price) {
|
||||
//
|
||||
result++;
|
||||
|
||||
//
|
||||
cP = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find last Candle which it's Low Price is
|
||||
// great than given price ...
|
||||
double GetLowGreatCandlePrice(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int index = bar_index + 1;
|
||||
double result = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
|
||||
//
|
||||
while (result >= price) {
|
||||
//
|
||||
index++;
|
||||
|
||||
//
|
||||
result = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
int GetLowGreatCandleIndex(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int result = bar_index + 1;
|
||||
double cP = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
|
||||
//
|
||||
while (cP >= price) {
|
||||
//
|
||||
result++;
|
||||
|
||||
//
|
||||
cP = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find last Candle which it's High Price is
|
||||
// less than given price ...
|
||||
double GetHighLessCandlePrice(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int index = bar_index + 1;
|
||||
double result = iHigh(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
|
||||
//
|
||||
while (result >= price) {
|
||||
//
|
||||
index++;
|
||||
|
||||
//
|
||||
result = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
int GetHighLessCandleIndex(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int result = bar_index + 1;
|
||||
double cP = iHigh(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
|
||||
//
|
||||
while (cP >= price) {
|
||||
//
|
||||
result++;
|
||||
|
||||
//
|
||||
cP = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find last Candle which it's High Price is
|
||||
// great than given price ...
|
||||
double GetHighGreatCandlePrice(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int index = bar_index + 1;
|
||||
double result = iHigh(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
|
||||
//
|
||||
while (result <= price) {
|
||||
//
|
||||
index++;
|
||||
|
||||
//
|
||||
result = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
int GetHighGreatCandleIndex(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int result = bar_index + 1;
|
||||
double cP = iHigh(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
|
||||
//
|
||||
while (cP <= price) {
|
||||
//
|
||||
result++;
|
||||
|
||||
//
|
||||
cP = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find last Candle which it's Open Price is
|
||||
// less than given price ...
|
||||
double GetOpenLessCandlePrice(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int index = bar_index + 1;
|
||||
double result = iOpen(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
|
||||
//
|
||||
while (result >= price) {
|
||||
//
|
||||
index++;
|
||||
|
||||
//
|
||||
result = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
int GetOpenLessCandleIndex(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int result = bar_index + 1;
|
||||
double cP = iOpen(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
|
||||
//
|
||||
while (cP >= price) {
|
||||
//
|
||||
result++;
|
||||
|
||||
//
|
||||
cP = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find last Candle which it's Open Price is
|
||||
// less than given price ...
|
||||
double GetOpenGreatCandlePrice(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int index = bar_index + 1;
|
||||
double result = iOpen(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
|
||||
//
|
||||
while (result <= price) {
|
||||
//
|
||||
index++;
|
||||
|
||||
//
|
||||
result = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
int GetOpenGreatCandleIndex(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int result = bar_index + 1;
|
||||
double cP = iOpen(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
|
||||
//
|
||||
while (cP <= price) {
|
||||
//
|
||||
result++;
|
||||
|
||||
//
|
||||
cP = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find last Candle which it's Close Price is
|
||||
// less than given price ...
|
||||
double GetCloseLessCandlePrice(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int index = bar_index + 1;
|
||||
double result = iClose(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
|
||||
//
|
||||
while (result >= price) {
|
||||
//
|
||||
index++;
|
||||
|
||||
//
|
||||
result = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
int GetCloseLessCandleIndex(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int result = bar_index + 1;
|
||||
double cP = iClose(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
|
||||
//
|
||||
while (cP >= price) {
|
||||
//
|
||||
result++;
|
||||
|
||||
//
|
||||
cP = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find last Candle which it's Close Price is
|
||||
// great than given price ...
|
||||
double GetCloseGreatCandlePrice(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int index = bar_index + 1;
|
||||
double result = iClose(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
|
||||
//
|
||||
while (result <= price) {
|
||||
//
|
||||
index++;
|
||||
|
||||
//
|
||||
result = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
int GetCloseGreatCandleIndex(
|
||||
//
|
||||
const int bar_index, // Bar Index ...
|
||||
const double price // Position Open Price ...
|
||||
) {
|
||||
//
|
||||
int result = bar_index + 1;
|
||||
double cP = iClose(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
|
||||
//
|
||||
while (cP <= price) {
|
||||
//
|
||||
result++;
|
||||
|
||||
//
|
||||
cP = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
struct XMinMax {
|
||||
double min;
|
||||
double max;
|
||||
};
|
||||
|
||||
//
|
||||
// Find Min and Max Value of specific Buffer ...
|
||||
XMinMax GetBufferMinMax(const double &buffer[]) {
|
||||
//
|
||||
XMinMax result = {};
|
||||
|
||||
//
|
||||
int bufferSize = ArraySize(buffer);
|
||||
if (bufferSize < 1) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double min = buffer[0];
|
||||
double max = buffer[0];
|
||||
|
||||
//
|
||||
for (int i = 1; i < bufferSize; i++) {
|
||||
//
|
||||
if (buffer[i] < min) {
|
||||
min = buffer[i];
|
||||
} else if (buffer[i] > max) {
|
||||
max = buffer[i];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result.min = min;
|
||||
result.max = max;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,47 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL4 Draw Global Library
|
||||
// ---------------------------------------------
|
||||
// saherelm useful tools and definitions ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Log Tag ...
|
||||
static string logTag = "";
|
||||
|
||||
//
|
||||
// Enable or Disable Logging ...
|
||||
static bool enableLogging = false;
|
||||
|
||||
//
|
||||
// Start Log Messages ...
|
||||
//
|
||||
|
||||
//
|
||||
// Logging a Message, specified for this EA ...
|
||||
// using provided LogTag ...
|
||||
void LogMessage(string message) {
|
||||
//
|
||||
if (!enableLogging) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Print(logTag, " > ", message);
|
||||
}
|
||||
|
||||
//
|
||||
// End Log Messages ...
|
||||
//
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL4 Models Global Library
|
||||
// ---------------------------------------------
|
||||
// saherelm useful tools and definitions ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Start Models ...
|
||||
//
|
||||
|
||||
//
|
||||
// Used Indicators List ...
|
||||
const string xmaIndicatorName = "x-saherelm.xma";
|
||||
const string adxIndicatorName = "x-saherelm.adx";
|
||||
const string oscIndicatorName = "x-saherelm.osc";
|
||||
const string zigZagIndicatorName = "x-saherelm.zigzag";
|
||||
|
||||
//
|
||||
// Direction ...
|
||||
enum X_DIRECTION {
|
||||
X_UP,
|
||||
X_DOWN
|
||||
};
|
||||
|
||||
//
|
||||
// these are different signal types ...
|
||||
enum X_SIGNAL_TYPE {
|
||||
X_NONE,
|
||||
X_LONG,
|
||||
X_SHORT,
|
||||
};
|
||||
|
||||
//
|
||||
// we Model each signals as this type ...
|
||||
struct XSignal {
|
||||
int id;
|
||||
X_SIGNAL_TYPE type;
|
||||
double tp;
|
||||
double sl;
|
||||
string symbol;
|
||||
datetime time;
|
||||
double entryPrice;
|
||||
};
|
||||
|
||||
//
|
||||
// this is Signal Request Response model ...
|
||||
struct XSignalRequest {
|
||||
bool hasSignal;
|
||||
X_SIGNAL_TYPE type;
|
||||
XSignal signal;
|
||||
};
|
||||
|
||||
//
|
||||
// we model OSC Return Data ...
|
||||
struct XOSCState {
|
||||
//
|
||||
double fastOSC;
|
||||
double fastOSCPrev;
|
||||
|
||||
//
|
||||
double slowOSC;
|
||||
double slowOSCPrev;
|
||||
|
||||
//
|
||||
double powerOSC;
|
||||
double powerOSCPrev;
|
||||
|
||||
//
|
||||
double varOSC;
|
||||
double varOSCPrev;
|
||||
|
||||
//
|
||||
double tanFSOSC;
|
||||
|
||||
//
|
||||
bool isOSCCrossOver;
|
||||
bool isOSCCrossUnder;
|
||||
};
|
||||
|
||||
//
|
||||
// Define a Model to Represent Snapshot of XMA Indicator ...
|
||||
struct XMAState {
|
||||
//
|
||||
// Short Cycle ...
|
||||
//
|
||||
// FAST ...
|
||||
double scFast;
|
||||
double scFastPrev;
|
||||
|
||||
//
|
||||
// SLOW ...
|
||||
double scSlow;
|
||||
double scSlowPrev;
|
||||
|
||||
//
|
||||
bool isSCTrendUp;
|
||||
|
||||
//
|
||||
// Medium Cycle ...
|
||||
//
|
||||
// FAST ...
|
||||
double mcFast;
|
||||
double mcFastPrev;
|
||||
|
||||
//
|
||||
// SLOW ...
|
||||
double mcSlow;
|
||||
double mcSlowPrev;
|
||||
|
||||
//
|
||||
// Long Cycle ...
|
||||
//
|
||||
// FAST ...
|
||||
double lcFast;
|
||||
double lcFastPrev;
|
||||
|
||||
//
|
||||
// SLOW ...
|
||||
double lcSlow;
|
||||
double lcSlowPrev;
|
||||
|
||||
//
|
||||
// MIDDLEAGE ...
|
||||
double marketMiddleage;
|
||||
double marketMiddleagePrev;
|
||||
};
|
||||
|
||||
//
|
||||
// Represent ADX State ...
|
||||
struct XADXState {
|
||||
//
|
||||
double trendPower;
|
||||
double trendPowerPrev;
|
||||
|
||||
//
|
||||
double upDirection;
|
||||
double upDirectionPrev;
|
||||
|
||||
//
|
||||
double downDirection;
|
||||
double downDirectionPrev;
|
||||
|
||||
//
|
||||
bool isUpTrend;
|
||||
bool isDownTrend;
|
||||
};
|
||||
|
||||
//
|
||||
// ZigZag State ...
|
||||
struct XZigZagState {
|
||||
//
|
||||
double zigZag;
|
||||
datetime zigZagTime;
|
||||
|
||||
//
|
||||
double zigZagPrev;
|
||||
datetime zigZagPrevTime;
|
||||
|
||||
//
|
||||
double low;
|
||||
int lowBarIndex;
|
||||
datetime lowTime;
|
||||
|
||||
//
|
||||
double high;
|
||||
int highBarIndex;
|
||||
datetime highTime;
|
||||
|
||||
//
|
||||
double delta;
|
||||
|
||||
//
|
||||
bool isWaitForTrendUp;
|
||||
bool isWaitForTrendDown;
|
||||
|
||||
//
|
||||
bool isLowIsLastLow;
|
||||
bool isHighIsLastHigh;
|
||||
};
|
||||
//
|
||||
// End Models ...
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user