Initial Commit ...

This commit is contained in:
2024-01-25 04:05:58 +03:30
commit dac3101466
520 changed files with 186332 additions and 0 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+532
View File
@@ -0,0 +1,532 @@
//+------------------------------------------------------------------+
//| x-saherelm.ea |
//| Copyright 2023, SaherElm IT Center |
//| https://www.saherelm.ir |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Inputs ...
input double riskToReward = 1.5; // Risk To Reward Ratio
//
// Define Models ...
//
// Signal Providers ...
enum ENUM_XSIGNAL_PROVIDER {
X_UNKNOWN_PROVIDER = 0,
X_CCI_PROVIDER = 1
};
//
// Signal Type ...
enum ENUM_XSIGNAL_TYPE {
X_NONE = 0,
X_BUY = 1,
X_SELL = 2
};
//
// Signal ...
struct XSignal {
//
// Signal Type ...
ENUM_XSIGNAL_TYPE type;
//
// Signal ID ...
int id;
//
// Signal Ticket Number, when Opening Trade ...
int ticket;
//
// Signal Provider ...
ENUM_XSIGNAL_PROVIDER provider;
//
// Target Point ...
double tp;
//
// Stop Loss ...
double sl;
//
// Signal Entry Price ...
double price;
//
// Signalling Time ...
datetime time;
};
//
// CCI Based Signal Conditions ...
struct XCCILongSignalConditions {
//
datetime start;
//
datetime crossOverMinusHundredTime;
datetime crossUnderMinusHundredTime;
//
double crossOverSlope;
};
//
bool isNewBar = false;
//
int countedBars = 0;
int totalSignals = 0;
int lastSignalledBar = 0;
//
XCCILongSignalConditions cciLongConds = {};
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//
isNewBar = IsNewBar();
//
if (isNewBar) {
//
countedBars++;
}
//
datetime barTime = iTime(
_Symbol,
_Period,
0
);
//
bool hasSignal = false;
bool hasLongSignal = false;
bool hasShortSignal = false;
//
// Generate Signals Based On iCCI ...
CheckCCILongSignalConditions(0);
//
// Long Signal ...
hasLongSignal =
//
// Check CCI Long Signal is Valid ...
ValidateCCILongConditions();
//
// Signal ...
hasSignal = hasLongSignal || hasShortSignal;
//
// Prevent Going Forward when there is no Signal ...
if (!hasSignal) {
return;
}
//
if (lastSignalledBar == countedBars) {
return;
}
//
totalSignals++;
lastSignalledBar = countedBars;
//
// Get CCI Long Signal ...
XSignal signal = {};
//
if (hasLongSignal) {
signal = GenerateCCILongSignal();
}
//
TradeOnSignal(signal);
//
Print("CCI Long Signal ...");
//
ClearCCILongSignalConditions();
}
//
// Trade Based On Signal ...
void TradeOnSignal(
XSignal &signal
) {
//
if (signal.type == X_NONE) {
return;
}
//
bool isLongSignal = signal.type == X_BUY;
//
// Order Operation ...
int operation = isLongSignal ?
OP_BUY :
OP_SELL;
//
// Detect Trade Color ...
color clr = isLongSignal ?
clrAqua :
clrFuchsia;
//
// Generate Signal Comment ...
string label = isLongSignal ?
"BUY" :
"SELL";
//
// Generate Signal Comment ...
string comment = StringConcatenate(
"XCCI",
"_", signal.id,
"_", label
);
//
// Placing Order ...
int orderTicket = OrderSend(
_Symbol,
operation,
0.01,
signal.price,
3,
signal.sl,
signal.tp,
comment,
signal.id,
0,
clr
);
//
// Draw Signal Shape if Order Opened Successfully ...
if (orderTicket >= 0) {
//
signal.ticket = orderTicket;
Print("Order: ", orderTicket, " ...");
}
}
//
// Convert CCI Long Signal Conditions to XSignal ...
XSignal GenerateCCILongSignal() {
//
XSignal result = {};
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll = GetLowestLow();
double hh = GetHighestHigh();
double pSar = iSAR(
_Symbol,
_Period,
0.002,
0.02,
0
);
//
double sl = ll;
//
double risk = entryPrice - ll;
double reward = risk * riskToReward;
//
double tp = entryPrice + reward;
//
if (tp > hh) {
tp = hh;
}
//
if (tp < entryPrice + priceGap) {
tp = entryPrice + priceGap;
}
//
datetime barTime = iTime(
_Symbol,
_Period,
0
);
//
result.tp = tp;
result.sl = 0; // sl;
result.type = X_BUY;
result.id = totalSignals;
result.price = entryPrice;
result.provider = X_CCI_PROVIDER;
result.time = barTime;
//
return result;
}
//
// Validate CCI Signal Conditions ...
bool ValidateCCILongConditions() {
//
bool result =
cciLongConds.start != 0
&& cciLongConds.crossUnderMinusHundredTime != 0
&& cciLongConds.crossOverMinusHundredTime != 0
&& cciLongConds.crossUnderMinusHundredTime >= cciLongConds.start
&& cciLongConds.crossOverMinusHundredTime > cciLongConds.crossUnderMinusHundredTime
&& cciLongConds.crossOverSlope > 0;
//
return result;
}
//
// Clear CCI Long Signal Conditions for New One ...
void ClearCCILongSignalConditions() {
//
cciLongConds.start = 0;
cciLongConds.crossOverSlope = 0;
cciLongConds.crossOverMinusHundredTime = 0;
cciLongConds.crossUnderMinusHundredTime = 0;
}
//
// Check and Fill CC Signal Conditions ...
void CheckCCILongSignalConditions(
const int bar_index
) {
//
// Retrieve Bar Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// LONG:
// wait for cci cross under -100
// then wait for cross over -100
// slope of crossing over ??? ...
if (cciLongConds.start == 0) {
cciLongConds.start = barTime;
}
//
// Check Start Time ...
if (cciLongConds.start == 0) {
return;
}
//
// Read current, prev, and prevPrev CCI ...
double cci = GetCCI(bar_index);
double cci1 = GetCCI(bar_index + 1);
double cci2 = GetCCI(bar_index + 2);
//
// Find Cross Under -100 ...
bool isCrossUnderMinusHundred =
cci < -100 && !(cci1 < -100);
//
// Fill Conditions ...
if (
isCrossUnderMinusHundred
&& cciLongConds.crossUnderMinusHundredTime == 0
) {
//
cciLongConds.crossUnderMinusHundredTime = barTime;
}
//
// Prevent Going forward untill Cross Under Happens ...
if (cciLongConds.crossUnderMinusHundredTime == 0) {
return;
}
//
// Find Cross Over -100 ...
bool isCrossOverMinusHundred =
cci > -100 && !(cci1 > -100);
//
// Fill Conditions ...
if (
isCrossOverMinusHundred
&& cciLongConds.crossOverMinusHundredTime == 0
) {
//
cciLongConds.crossOverMinusHundredTime = barTime;
}
//
// Prevent from Going forward untill Cross Over Happens ...
if (cciLongConds.crossOverMinusHundredTime == 0) {
return;
}
//
// Calculate Slope ...
double x1 = 0;
double y1 = cci1;
double x2 = 1;
double y2 = cci;
//
// Calculat Line Slope ...
double tSlope = GetSlope(
x1, y1, x2, y2
);
//
cciLongConds.crossOverSlope = tSlope;
}
//
// Retrieve CCI Value ...
double GetCCI(
const int bar_index,
const int marketLength = 504,
const ENUM_APPLIED_PRICE source = PRICE_TYPICAL
) {
//
double result = iCCI(
_Symbol,
_Period,
marketLength,
source,
bar_index
);
//
return result;
}
//
// 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;
}
//
// Get Slope of a Line by it's two Point ...
double GetSlope(
double x1,
double y1,
double x2,
double y2
) {
//
double result = (y2 - y1)/(x2 - x1);
return result;
}
//
// Market Related Functions ...
//
double GetLowestLow() {
//
int index = iLowest(
_Symbol,
_Period,
MODE_LOW,
14,
0
);
//
double result = iLow(
_Symbol,
_Period,
index
);
//
return result;
}
//
double GetHighestHigh() {
//
int index = iHighest(
_Symbol,
_Period,
MODE_HIGH,
14,
0
);
//
double result = iHigh(
_Symbol,
_Period,
index
);
//
return result;
}
File diff suppressed because it is too large Load Diff
+100
View File
@@ -0,0 +1,100 @@
///////////////////////////////////////////////////////
//
// 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 shpdIndicatorName = "x-saherelm.shpd";
const string zigZagIndicatorName = "x-saherelm.zigzag";
const string xmarketIndicatorName = "x-saherelm.xmarket";
const string momentumIndicatorName = "x-saherelm.momentum";
//
// 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;
int ticket;
X_SIGNAL_TYPE type;
double tp;
double sl;
string symbol;
datetime time;
string comment;
double entryPrice;
};
//
// this is Signal Request Response model ...
struct XSignalRequest {
bool hasSignal;
X_SIGNAL_TYPE type;
XSignal signal;
};
//
struct XMACycleState {
double fast;
double slow;
};
//
// Define a Model to Represent Snapshot of XMA Indicator ...
struct XMAState {
//
// SC ...
XMACycleState sc;
//
// MC ...
XMACycleState mc;
//
// LC ...
XMACycleState lc;
//
// MIDDLEAGE ...
double marketMiddleage;
//
// PARABOLIC-SAR ...
double parabolicSAR;
};
//
// End Models ...
//
+330
View File
@@ -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 ...
//
+412
View File
@@ -0,0 +1,412 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center X Indicator
// ---------------------------------------------
// saherelm implementation of above indicator ...
//
// 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 X Indicator"
#property strict
//
// START Inputs ...
//
//
input int marketLength = 7; // Market Length
//
input int shortCycleMultiplier = 2; // Market Short Cycle Multiplier
input int mediumCycleMultiplier = 6; // Market Medium Cycle Multiplier
input int longCycleMultiplier = 36; // Market Medium Cycle Multiplier
//
input ENUM_MA_METHOD maMethod = MODE_SMA; // Ma Method
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
#property indicator_buffers 6
//
#property indicator_plots 6
//
// Start Define Indicator Buffer Styles ...
//
//
// Short Cycle Highest High Buffer ...
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//
// Short Cycle Lowest Low Buffer ...
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
// Medium Cycle Highest High Buffer ...
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrAqua
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
// Medium Cycle Lowest Low Buffer ...
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrFuchsia
#property indicator_style4 STYLE_DOT
#property indicator_width4 1
//
// Long Cycle Highest High Buffer ...
#property indicator_type5 DRAW_LINE
#property indicator_color5 C'62,82,6'
#property indicator_style5 STYLE_DOT
#property indicator_width5 1
//
// Long Cycle Lowest Low Buffer ...
#property indicator_type6 DRAW_LINE
#property indicator_color6 C'255,81,0'
#property indicator_style6 STYLE_DOT
#property indicator_width6 1
//
// End Define Indicator Buffer Styles ...
//
//
// Buffers ...
//
// HH Buffers ...
#define scHHBufferIndex 0
#define scLLBufferIndex 1
#define mcHHBufferIndex 2
#define mcLLBufferIndex 3
#define lcHHBufferIndex 4
#define lcLLBufferIndex 5
double scHHBuffer[];
double scLLBuffer[];
double mcHHBuffer[];
double mcLLBuffer[];
double lcHHBuffer[];
double lcLLBuffer[];
//
// Variables ...
int shortCycleLength;
int mediumCycleLength;
int longCycleLength;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
if (
marketLength <= 0 ||
shortCycleMultiplier <= 0 ||
mediumCycleMultiplier <= 0 ||
shortCycleMultiplier > mediumCycleMultiplier
) {
return INIT_PARAMETERS_INCORRECT;
}
//
// Start Set Index Buffers ...
//
shortCycleLength = shortCycleMultiplier * marketLength;
mediumCycleLength = mediumCycleMultiplier * marketLength;
longCycleLength = longCycleMultiplier * marketLength;
//
// Highest High and Lowest Low Buffers ...
//
// Short Cycle Highest High ...
string scHHLbl = StringConcatenate(
"SC HH(", shortCycleLength, ")"
);
SetIndexBuffer(scHHBufferIndex, scHHBuffer);
SetIndexLabel(scHHBufferIndex, scHHLbl);
//
// Short Cycle Lowest Low ...
string scLLLbl = StringConcatenate(
"SC LL(", shortCycleLength, ")"
);
SetIndexBuffer(scLLBufferIndex, scLLBuffer);
SetIndexLabel(scLLBufferIndex, scLLLbl);
//
// Medium Cycle Highest High ...
string mcHHLbl = StringConcatenate(
"MC HH(", mediumCycleLength, ")"
);
SetIndexBuffer(mcHHBufferIndex, mcHHBuffer);
SetIndexLabel(mcHHBufferIndex, mcHHLbl);
//
// Medium Cycle Lowest Low ...
string mcLLLbl = StringConcatenate(
"MC LL(", mediumCycleLength, ")"
);
SetIndexBuffer(mcLLBufferIndex, mcLLBuffer);
SetIndexLabel(mcLLBufferIndex, mcLLLbl);
//
// Long Cycle Highest High ...
string lcHHLbl = StringConcatenate(
"LC HH(", longCycleLength, ")"
);
SetIndexBuffer(lcHHBufferIndex, lcHHBuffer);
SetIndexLabel(lcHHBufferIndex, lcHHLbl);
//
// Long Cycle Lowest Low ...
string lcLLLbl = StringConcatenate(
"LC LL(", longCycleLength, ")"
);
SetIndexBuffer(lcLLBufferIndex, lcLLBuffer);
SetIndexLabel(lcLLBufferIndex, lcLLLbl);
//
// 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, marketLength);
//
// 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 ...
//
// Calculat Ma's ...
//
CalculateShortCycle(i);
//
CalculateMediumCycle(i);
//
CalculateLongCycle(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculating Short Cycle ...
void CalculateShortCycle(
const int &bar_index
) {
//
// Short Cycle Highest High ...
//
int scHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
shortCycleLength,
bar_index
);
//
double scHH = iHigh(
_Symbol,
_Period,
scHHIdx
);
//
scHHBuffer[bar_index] = scHH;
//
// Short Cycle Lowest Low ...
//
int scLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
shortCycleLength,
bar_index
);
//
double scLL = iLow(
_Symbol,
_Period,
scLLIdx
);
//
scLLBuffer[bar_index] = scLL;
}
//
// Calculating Medium Cycle ...
void CalculateMediumCycle(
const int &bar_index
) {
//
// Medium Cycle Highest High ...
//
int mcHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
mediumCycleLength,
bar_index
);
//
double mcHH = iHigh(
_Symbol,
_Period,
mcHHIdx
);
//
mcHHBuffer[bar_index] = mcHH;
//
// Medium Cycle Lowest Low ...
//
int mcLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
mediumCycleLength,
bar_index
);
//
double mcLL = iLow(
_Symbol,
_Period,
mcLLIdx
);
//
mcLLBuffer[bar_index] = mcLL;
}
//
// Calculating Long Cycle ...
void CalculateLongCycle(
const int &bar_index
) {
//
// Long Cycle Highest High ...
//
int lcHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
longCycleLength,
bar_index
);
//
double lcHH = iHigh(
_Symbol,
_Period,
lcHHIdx
);
//
lcHHBuffer[bar_index] = lcHH;
//
// Long Cycle Lowest Low ...
//
int lcLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
longCycleLength,
bar_index
);
//
double lcLL = iLow(
_Symbol,
_Period,
lcLLIdx
);
//
lcLLBuffer[bar_index] = lcLL;
}
//
// END Functions ...
//
@@ -0,0 +1,265 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center Trend Power 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 ...
//
input int marketLength = 7; // Market Length
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_separate_window
//
#property indicator_plots 3
#property indicator_buffers 3
#property indicator_minimum 0
#property indicator_maximum 100
//
#property indicator_levelcolor clrGray
#property indicator_levelstyle STYLE_DOT
//
// Start Define Indicator Buffer Styles ...
//
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrLime
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//
#property indicator_type2 DRAW_HISTOGRAM
#property indicator_color2 clrRed
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrYellow
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
// End Define Indicator Buffer Styles ...
//
//
// Buffers ...
#define powerUpBufferIndex 0
#define powerDownBufferIndex 1
#define signalBufferIndex 2
#define diBufferIndex 3
double powerUpBuffer[];
double powerDownBuffer[];
double signalBuffer[];
double diBuffer[];
//
#include "../Libraries/x-saherelm.lib.mq4"
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
if (marketLength <= 0) {
return INIT_PARAMETERS_INCORRECT;
}
//
SetLevelValue(0, 0.0);
IndicatorSetString(INDICATOR_LEVELTEXT,0,"");
//
SetLevelValue(1, 50);
IndicatorSetString(INDICATOR_LEVELTEXT,1,"");
//
SetLevelValue(2, 100);
IndicatorSetString(INDICATOR_LEVELTEXT,2,"");
//
string pUpLbl = StringConcatenate(
"P Up (", marketLength, ")"
);
SetIndexLabel(powerUpBufferIndex, pUpLbl);
SetIndexBuffer(powerUpBufferIndex, powerUpBuffer);
SetIndexDrawBegin(powerUpBufferIndex, marketLength + 1);
//
string pDownLbl = StringConcatenate(
"P Down (", marketLength, ")"
);
SetIndexLabel(powerDownBufferIndex, pDownLbl);
SetIndexBuffer(powerDownBufferIndex, powerDownBuffer);
SetIndexDrawBegin(powerDownBufferIndex, marketLength + 1);
//
string pSignalLbl = StringConcatenate(
"P Signal (", marketLength, ")"
);
SetIndexLabel(signalBufferIndex, pSignalLbl);
SetIndexBuffer(signalBufferIndex, signalBuffer);
SetIndexDrawBegin(signalBufferIndex, marketLength + 1);
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "X_TPW_OSC";
//
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, marketLength);
//
// 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 Buffers ...
CalculateBuffers(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculating Ma ...
void CalculateBuffers(
const int &bar_index
) {
//
double powerUp = 0;
double powerDown = 0;
//
int dailyCount = GetDailyCandleCount();
double dailyHH = GetMarketHighestHigh(
bar_index,
dailyCount
);
double dailyLL = GetMarketLowestLow(
bar_index,
dailyCount
);
double dailyDiff = dailyHH - dailyLL;
double rate = dailyDiff / 100;
//
for (int i = bar_index; i < bar_index + marketLength; i++) {
//
XOHCL c = GetCandleModel(i);
//
double cRange =
MathAbs(c.open - c.close)
// MathAbs(c.high - c.low)
;
bool isBullish = c.open < c.close;
//
if (isBullish) {
powerUp += cRange;
} else {
powerDown += cRange;
}
}
//
powerUp = powerUp / rate;
powerDown = powerDown / rate;
//
double ema = GetMA(
bar_index,
marketLength,
0,
MODE_EMA,
PRICE_WEIGHTED
);
//
double signal = (ema / 100) * rate;
double signalAddition = MathMin(powerUp, powerDown);
//
powerUpBuffer[bar_index] = powerUp;
powerDownBuffer[bar_index] = powerDown;
signalBuffer[bar_index] = signal + signalAddition;
}
//
// END Functions ...
//
@@ -0,0 +1,291 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center Trend Power 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 ...
//
input int marketLength = 7; // Market Length
input int shift = 0; // Shift
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_separate_window
//
#property indicator_plots 3
#property indicator_buffers 3
// #property indicator_minimum 0
// #property indicator_maximum 200
//
#property indicator_levelcolor clrGray
#property indicator_levelstyle STYLE_DOT
//
// Start Define Indicator Buffer Styles ...
//
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrLime
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//
#property indicator_type2 DRAW_HISTOGRAM
#property indicator_color2 clrRed
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrYellow
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
// #property indicator_type4 DRAW_LINE
// #property indicator_color4 clrAqua
// #property indicator_style4 STYLE_DASHDOT
// #property indicator_width4 1
//
// End Define Indicator Buffer Styles ...
//
//
// Buffers ...
#define powerUpBufferIndex 0
#define powerDownBufferIndex 1
#define signalBufferIndex 2
// #define diBufferIndex 3
double powerUpBuffer[];
double powerDownBuffer[];
double signalBuffer[];
// double diBuffer[];
//
#include "../Libraries/x-saherelm.lib.mq4"
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
if (marketLength <= 0) {
return INIT_PARAMETERS_INCORRECT;
}
// //
// SetLevelValue(0, 0.0);
// IndicatorSetString(INDICATOR_LEVELTEXT,0,"");
// //
// SetLevelValue(1, 50);
// IndicatorSetString(INDICATOR_LEVELTEXT,1,"");
// //
// SetLevelValue(2, 100);
// IndicatorSetString(INDICATOR_LEVELTEXT,2,"");
//
string pUpLbl = StringConcatenate(
"P Up (", marketLength, ")"
);
SetIndexLabel(powerUpBufferIndex, pUpLbl);
SetIndexBuffer(powerUpBufferIndex, powerUpBuffer);
SetIndexDrawBegin(powerUpBufferIndex, marketLength + 1);
//
string pDownLbl = StringConcatenate(
"P Down (", marketLength, ")"
);
SetIndexLabel(powerDownBufferIndex, pDownLbl);
SetIndexBuffer(powerDownBufferIndex, powerDownBuffer);
SetIndexDrawBegin(powerDownBufferIndex, marketLength + 1);
//
string pSignalLbl = StringConcatenate(
"P Signal (", marketLength, ")"
);
SetIndexLabel(signalBufferIndex, pSignalLbl);
SetIndexBuffer(signalBufferIndex, signalBuffer);
SetIndexDrawBegin(signalBufferIndex, marketLength + 1);
// //
// string pDiLbl = StringConcatenate(
// "P DI (", marketLength, ")"
// );
// SetIndexLabel(diBufferIndex, pDiLbl);
// SetIndexBuffer(diBufferIndex, diBuffer);
// SetIndexDrawBegin(diBufferIndex, marketLength + 1);
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "X_TPW_OSC";
//
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, marketLength);
//
// 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 Buffers ...
CalculateBuffers(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculating Ma ...
void CalculateBuffers(
const int &bar_index
) {
//
double powerUp = 0;
double powerDown = 0;
//
int dailyCount = GetDailyCandleCount();
double dailyHH = GetMarketHighestHigh(
bar_index,
dailyCount
);
double dailyLL = GetMarketLowestLow(
bar_index,
dailyCount
);
double dailyDiff = dailyHH - dailyLL;
double rate = dailyDiff / 100;
//
for (int i = bar_index + shift; i < bar_index + marketLength + shift; i++) {
//
XOHCL c = GetCandleModel(i);
//
double cRange =
MathAbs(c.open - c.close)
// MathAbs(c.high - c.low)
;
bool isBullish = c.open < c.close;
//
if (isBullish) {
powerUp += cRange;
} else {
powerDown += cRange;
}
}
//
powerUp = powerUp / rate;
powerDown = powerDown / rate;
//
double ema = GetMA(
bar_index,
(marketLength * 2),
0,
MODE_EMA,
PRICE_WEIGHTED
);
//
powerUpBuffer[bar_index] = powerUp;
//
powerDownBuffer[bar_index] = -1 * powerDown;
//
double emaRate = MathAbs(powerUp - MathAbs(powerDown)) / 100;
double signal = (ema / 100) * emaRate;
//
bool isPowerUp = powerUp > MathAbs(powerDown);
double signalAddition = isPowerUp ? (-1 * powerDown) : powerUp;
signalBuffer[bar_index] = signal + signalAddition;
//
// double pDiff = powerUpBuffer[bar_index] - powerDownBuffer[bar_index];
// double cDiValue = pDiff + signalBuffer[bar_index];
// diBuffer[bar_index] = cDiValue;
}
//
// END Functions ...
//
+395
View File
@@ -0,0 +1,395 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center X Indicator
// ---------------------------------------------
// saherelm implementation of above indicator ...
//
// 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 X Indicator"
#property strict
//
// START Inputs ...
//
//
input int marketLength = 7; // Market Length
//
input double step = 0.02; // P SAR Step
input double maximum = 0.2; // P SAR Maximum
//
input int shortCycleMultiplier = 2; // Market Short Cycle Multiplier
input int mediumCycleMultiplier = 6; // Market Medium Cycle Multiplier
input int longCycleMultiplier = 36; // Market Medium Cycle Multiplier
//
input ENUM_MA_METHOD maMethod = MODE_SMA; // Ma Method
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
#property indicator_buffers 7
//
#property indicator_plots 7
//
// Start Define Indicator Buffer Styles ...
//
//
// Short Cycle Fast Buffer ...
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//
// Short Cycle Slow Buffer ...
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
// Medium Cycle Fast Buffer ...
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrAqua
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
// Medium Cycle Slow Buffer ...
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrFuchsia
#property indicator_style4 STYLE_DOT
#property indicator_width4 1
//
// Long Cycle Fast Buffer ...
#property indicator_type5 DRAW_LINE
#property indicator_color5 C'62,82,6'
#property indicator_style5 STYLE_DOT
#property indicator_width5 1
//
// Long Cycle Slow Buffer ...
#property indicator_type6 DRAW_LINE
#property indicator_color6 C'255,81,0'
#property indicator_style6 STYLE_DOT
#property indicator_width6 1
//
// Parabolic SAR ...
#property indicator_type7 DRAW_LINE
#property indicator_color7 C'0,174,255'
#property indicator_style7 STYLE_DASHDOT
#property indicator_width7 1
//
// End Define Indicator Buffer Styles ...
//
//
// Buffers ...
//
// Ma Buffers ...
#define scFastBufferIndex 0
#define scSlowBufferIndex 1
#define mcFastBufferIndex 2
#define mcSlowBufferIndex 3
#define lcFastBufferIndex 4
#define lcSlowBufferIndex 5
#define psarBufferIndex 6
double scFastBuffer[];
double scSlowBuffer[];
double mcFastBuffer[];
double mcSlowBuffer[];
double lcFastBuffer[];
double lcSlowBuffer[];
double psarBuffer[];
//
// Variables ...
int shortCycleLength;
int mediumCycleLength;
int longCycleLength;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
if (
marketLength <= 0 ||
shortCycleMultiplier <= 0 ||
mediumCycleMultiplier <= 0 ||
shortCycleMultiplier > mediumCycleMultiplier
) {
return INIT_PARAMETERS_INCORRECT;
}
//
// Start Set Index Buffers ...
//
shortCycleLength = shortCycleMultiplier * marketLength;
mediumCycleLength = mediumCycleMultiplier * marketLength;
longCycleLength = longCycleMultiplier * marketLength;
//
// Ma Buffers ...
//
// Short Cycle ...
string scFLbl = StringConcatenate(
"SC F(", shortCycleLength, ")"
);
SetIndexBuffer(scFastBufferIndex, scFastBuffer);
SetIndexLabel(scFastBufferIndex, scFLbl);
//
string scSLbl = StringConcatenate(
"SC S(", shortCycleLength, ")"
);
SetIndexBuffer(scSlowBufferIndex, scSlowBuffer);
SetIndexLabel(scSlowBufferIndex, scSLbl);
//
// Medium Cycle ...
string mcFLbl = StringConcatenate(
"MC F(", mediumCycleLength, ")"
);
SetIndexBuffer(mcFastBufferIndex, mcFastBuffer);
SetIndexLabel(mcFastBufferIndex, mcFLbl);
//
string mcSLbl = StringConcatenate(
"MC S(", mediumCycleLength, ")"
);
SetIndexBuffer(mcSlowBufferIndex, mcSlowBuffer);
SetIndexLabel(mcSlowBufferIndex, mcSLbl);
//
// Long Cycle ...
string lcFLbl = StringConcatenate(
"LC F(", longCycleLength, ")"
);
SetIndexBuffer(lcFastBufferIndex, lcFastBuffer);
SetIndexLabel(lcFastBufferIndex, lcFLbl);
//
string lcSLbl = StringConcatenate(
"LC S(", longCycleLength, ")"
);
SetIndexBuffer(lcSlowBufferIndex, lcSlowBuffer);
SetIndexLabel(lcSlowBufferIndex, lcSLbl);
//
// End Set Index Buffers ...
//
//
// Parabolic Sar ...
SetIndexBuffer(psarBufferIndex, psarBuffer);
SetIndexLabel(psarBufferIndex, "P Sar");
//
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, marketLength);
//
// 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 ...
//
// Calculat Ma's ...
//
CalculateShortCycle(i);
//
CalculateMediumCycle(i);
//
CalculateLongCycle(i);
//
// Parabolic SAR ...
CalculateParabolicSAR(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculating Short Cycle ...
void CalculateShortCycle(
const int &bar_index
) {
//
double scFast = iMA(
_Symbol,
_Period,
shortCycleLength,
0,
maMethod,
PRICE_OPEN,
bar_index
);
scFastBuffer[bar_index] = scFast;
//
double scSlow = iMA(
_Symbol,
_Period,
shortCycleLength,
0,
maMethod,
PRICE_CLOSE,
bar_index
);
scSlowBuffer[bar_index] = scSlow;
}
//
// Calculating Medium Cycle ...
void CalculateMediumCycle(
const int &bar_index
) {
//
double mcFast = iMA(
_Symbol,
_Period,
mediumCycleLength,
0,
maMethod,
PRICE_OPEN,
bar_index
);
mcFastBuffer[bar_index] = mcFast;
//
double mcSlow = iMA(
_Symbol,
_Period,
mediumCycleLength,
0,
maMethod,
PRICE_CLOSE,
bar_index
);
mcSlowBuffer[bar_index] = mcSlow;
}
//
// Calculating Long Cycle ...
void CalculateLongCycle(
const int &bar_index
) {
//
double lcFast = iMA(
_Symbol,
_Period,
longCycleLength,
0,
maMethod,
PRICE_OPEN,
bar_index
);
lcFastBuffer[bar_index] = lcFast;
//
double lcSlow = iMA(
_Symbol,
_Period,
longCycleLength,
0,
maMethod,
PRICE_CLOSE,
bar_index
);
lcSlowBuffer[bar_index] = lcSlow;
}
//
// Calculate Parabolic SAR ...
void CalculateParabolicSAR(
const int &bar_index
) {
//
double pSar = iSAR(
_Symbol,
_Period,
step,
maximum,
bar_index
);
//
psarBuffer[bar_index] = pSar;
}
//
// END Functions ...
//
@@ -0,0 +1,790 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XST Strategy Expert Advisor
// ---------------------------------------------
// saherelm implementation of strategy expert advisor ...
// in this EA, we try to combine multiple tools, to ashive best
// results ...
//
// ShortName: XST
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
// +989121694056
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XST Strategy Expert Advisor"
#property strict
//
// START Inputs ...
//
//
// Signal Prefixe ...
input string signalPrefix = "XST"; // Signal Prefix
//
// Signal Draw Specifications ...
input string bullishSignalLabel = "X_BUY"; // Bullish Signal Label
input color bullishSignalColor = clrAqua; // Bullish Signal Color
//
input string bearishSignalLabel = "X_SELL"; // Bearish Signal Label
input color bearishSignalColor = clrFuchsia; // Bearish Signal Color
//
input 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 = 1.5; // Risk to Reward Ratio
// input double maxTPMultiplier = 1000; // Max Allowed TP
//
// 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.05; // Maximum DrawDown Per Trade
input double minBalancePercent = 0.5; // Minimum Balance for Trading
input double maxEquityPercent = 0.1; // Maximum Trade Equity
input int closeAllOpenTradesAfterCandle = 408; // Close All Open Trades After Passed Candles
input bool closeAllInProfitOpenTradesWhenMaxOpenTradesReached = false; // Close All In Profit Open Trades When Max Open Trades Reached and New Signal Income
//
// Indicators ...
//
// CCI Inputs ...
input double step = 0.01; // SAR Step
input double maximum = 0.1; // SAR Maximum
//
// XMA Inputs ...
//
input int shortCycleFastMultiplier = 2; // Short Cycle Fast Multiplier
input int shortCycleSlowMultiplier = 4; // Short Cycle Slow Multiplier
input int mediumCycleFastMultiplier = 6; // Medium Cycle Fast Multiplier
input int mediumCycleSlowMultiplier = 12; // Medium Cycle Slow Multiplier
input int longCycleFastMultiplier = 36; // Long Cycle Fast Multiplier
input int longCycleSlowMultiplier = 72; // Long Cycle Slow Multiplier
//
// SHPD Indicator ...
input double sharpDetectMultiplier = 800; // Sharp Detect Multiplier
//
// 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.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
//
// XMA ...
//
// Validate Short Cycle ...
|| shortCycleFastMultiplier <= 0
|| shortCycleSlowMultiplier <= 0
|| shortCycleFastMultiplier >= shortCycleSlowMultiplier
//
// Validate Medium Cycle ...
|| mediumCycleFastMultiplier <= 0
|| mediumCycleSlowMultiplier <= 0
|| mediumCycleFastMultiplier >= mediumCycleSlowMultiplier
//
// Validate Long Cycle ...
|| longCycleFastMultiplier <= 0
|| longCycleSlowMultiplier <= 0
|| longCycleFastMultiplier >= longCycleSlowMultiplier
//
// Validate Series of Multipliers ...
|| shortCycleFastMultiplier >= mediumCycleFastMultiplier
|| mediumCycleFastMultiplier >= longCycleFastMultiplier
;
//
if (inputsNotValiid) {
return INIT_PARAMETERS_INCORRECT;
}
//
totalSignals = 0;
totalLongSignals = 0;
totalShortSignals = 0;
//
initialBalance = 0;
//
// START Define Array Series ...
//
//
// END Define Array Series ...
//
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XST";
// //
// // Set Event Timer on One Seccond ...
// bool isEventSet = EventSetTimer(1);
// if (!isEventSet) {
// LogMessage("Error: " + GetLastError());
// return INIT_FAILED;
// }
//
ClearSignalConditions();
//
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason) {
//
// Killing Event Timer ...
EventKillTimer();
}
//
// Ticker Event Handler ...
void OnTick() {
//
isNewDay = IsNewDay();
if (isNewDay) {
//
LogMessage(
StringConcatenate(
"New Day: ", TimeCurrent()
)
);
}
//
// Process Signals to Open Positions ...
ProcessSignals();
//
// Checking State for Signal Handling ...
CheckState();
//
// Process Open Positions for Trailing Stop Loss or Close ...
ProcessOpenPositions();
}
//
// Timer Event Handler ...
void OnTimer() {
//
CheckState();
//
ProcessOpenPositions();
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Check State for Signal Handling ...
void CheckState() {
//
// Here we Must to Check Market State for enable or disable
// Signal Handlers and also make dection to close all long/short
// trades ...
// //
// closeLongTrades = xCloseLongTrades;
// waitForLongSignals = xWaitForLongSignals;
// //
// closeShortTrades = xCloseShortTrades;
// waitForShortSignals = xWaitForShortSignals;
// //
// xCloseLongTrades = false;
// xCloseShortTrades = false;
}
//
// Calculate Signals and Process Based on Exists Signals ...
void ProcessSignals() {
//
XSignalRequest request = {};
request.type = X_SIGNAL_NONE;
request.hasSignal = false;
//
// Prevent Multiple Calculating on Same Bars ...
isNewBar = IsNewBar();
if (isNewBar) {
countedBars++;
}
//
if (countedBars < longCycleSlowMultiplier * marketLength) {
return;
}
//
bool allowDoTrade = true;
//
// Check Balance ...
if (initialBalance > 0) {
//
// Retrieve Account Balance ...
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double minimumBalanceForTrade =
balance > initialBalance
?
minBalancePercent * balance
:
minBalancePercent * initialBalance;
//
// Retrieve Account Equity ...
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
double maxAllowedEquity = balance - (balance * maxEquityPercent);
//
// Retrieve Free Marigin ...
double freeMargin = AccountFreeMargin();
double maximumMariginRisk = balance - (balance * maxEquityPercent);
//
if (
//
// Do not Open Positions if equity not passed ...
equity < maxAllowedEquity ||
//
// Do not Open Positions if free margin not passed ...
freeMargin <= maximumMariginRisk ||
//
// Do not open positions if balance less than minimum ...
balance <= minimumBalanceForTrade
) {
//
allowDoTrade = false;
// //
// string message = StringConcatenate(
// "Trading Pause => ",
// "Balance: ", balance,
// ", Equity: ", equity,
// ", FreeMargin: ", freeMargin
// );
// //
// LogMessage(message);
// SendAlert(message);
}
}
//
// Retrieve Signal Exists ...
request = GenerateSignal(0);
//
// Prevent doing anything else, if there is no signals ...
if (
!allowDoTrade ||
!request.hasSignal ||
request.type == X_SIGNAL_NONE
) {
return;
}
//
bool hasLongSignal = request.type == X_SIGNAL_LONG;
//
// Check For Bot State ...
if (
(hasLongSignal && !waitForLongSignals)
|| (!hasLongSignal && !waitForShortSignals)
) {
//
// Clear Signal Conditions ...
if (hasLongSignal) {
ClearLongSignalConditions();
} else {
ClearShortSignalConditions();
}
//
return;
}
//
// Check last Signalled Bar with Counted Bars ...
// Prevent Multiple Signalling on Same Bar ...
bool isInLastSignalledBars = false;
for (int i=0; i < marketLength; i++) {
//
isInLastSignalledBars =
isInLastSignalledBars
|| lastSignalledBar == countedBars - i
;
}
if (isInLastSignalledBars) {
//
// Clear Signal Conditions ...
if (hasLongSignal) {
ClearLongSignalConditions();
} else {
ClearShortSignalConditions();
}
//
return;
}
//
// increase last signalled bar ...
lastSignalledBar = countedBars;
//
// Calculate Can Trade or not ...
allowDoTrade = allowTrade
&& (
hasLongSignal ?
allowLongTrades :
allowShortTrades
);
//
// Chack Maximum Open Positions ...
int openTrades = CountOpenTrades();
if (maxOpenTrades > 0) {
//
if (openTrades >= maxOpenTrades) {
//
allowDoTrade = false;
//
if (closeAllInProfitOpenTradesWhenMaxOpenTradesReached) {
//
// Close All In Profit Trades ...
bool hasClosedInProfitTrade = CloseAllInProfitTrades();
if (hasClosedInProfitTrade) {
//
openTrades = CountOpenTrades();
//
allowDoTrade = !(openTrades >= maxOpenTrades);
}
}
//
if (!allowDoTrade) {
//
string message = StringConcatenate(
"Trading Pause => ",
"Max Open Trades (",
maxOpenTrades,
") reached ..."
);
//
LogMessage(message);
SendAlert(message);
}
}
}
//
// Check Trading is Enable or not ...
// nothing to do if trading is disabled ...
if (!allowDoTrade) {
//
// Clear Signal Conditions ...
if (hasLongSignal) {
ClearLongSignalConditions();
} else {
ClearShortSignalConditions();
}
// //
// string message = StringConcatenate(
// "Trading Not Allowed ..."
// );
// //
// LogMessage(message);
// SendAlert(message);
return;
}
//
bool isPositionOpened = TradeSignal(
request.signal,
signalPrefix,
lotsPerTradePercent,
//
bullishSignalLabel,
bullishSignalColor,
bearishSignalLabel,
bearishSignalColor
);
//
totalSignals++;
if (hasLongSignal) {
//
totalLongSignals++;
ClearLongSignalConditions();
} else {
//
totalShortSignals++;
ClearShortSignalConditions();
}
//
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.entry,
", TP: ", request.signal.tp
);
//
// Terminal Alert ...
if (terminalAlert) {
Alert(message);
}
//
// Push Alert ...
if (pushAlert) {
SendNotification(message);
}
}
}
}
//
// Process All Open Positions ...
void ProcessOpenPositions() {
//
// this comes from check state ...
if (closeLongTrades) {
//
closeLongTrades = false;
//
bool isAllLongTradesClosed = CloseAllLongTrades();
if (isAllLongTradesClosed) {
}
}
//
// this comes from check state ...
if (closeShortTrades) {
//
closeShortTrades = false;
//
bool isAllShortTradesClosed = CloseAllShortTrades();
if (isAllShortTradesClosed) {
}
}
//
// Close All XXX Provided Signals on it's Specific Condition ...
if (xCloseLongTrades) {
//
CloseAllProviderLongTrades(X_XXX_PROVIDER);
//
xCloseLongTrades = false;
}
//
bool hasClosedLongTimeTrade = CloseAllLongTimeTrades(
closeAllOpenTradesAfterCandle
);
//
// Close Maximum DrawDown Passed Trades ...
bool hasClosedInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades(
maxDrawdownPercentPerPTrade
);
//
if (
hasClosedLongTimeTrade
|| hasClosedInDrawDownLongTrade
) {
//
// waitForLongSignals = 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 ...
//
//
//
// Calculate Signal ...
// in this function we calculate a signal exists in
// specific bar or not ...
XSignalRequest GenerateSignal(
const int bar_index // Bar Index ...
) {
//
// create temp result ...
XSignalRequest result = {};
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
bool hasSignal = false;
bool hasLongSignal = false;
bool hasShortSignal = false;
//
XSignal signal = {};
//
// Retrieve XMA States ...
// based on medium cycle slow ...
XState states[];
ArrayFree(states);
ArrayResize(
states,
marketLength
);
//
int index = 0;
for (int i = bar_index; i < bar_index + marketLength; i++) {
//
states[index] = GetXState(
i,
marketLength,
//
step,
maximum,
//
shortCycleFastMultiplier,
shortCycleSlowMultiplier,
mediumCycleFastMultiplier,
mediumCycleSlowMultiplier,
longCycleFastMultiplier,
longCycleSlowMultiplier
);
//
index++;
}
//
CheckXLongSignalConditions(
bar_index,
marketLength,
states
);
//
CheckXShortSignalConditions(
bar_index,
marketLength,
states
);
//
XSignalRequest xLongSignalRequest = GenerateXSignal(
X_SIGNAL_LONG,
bar_index,
marketLength,
riskToRewardRatio,
states
);
//
XSignalRequest xShortSignalRequest = GenerateXSignal(
X_SIGNAL_SHORT,
bar_index,
marketLength,
riskToRewardRatio,
states
);
//
if (xLongSignalRequest.hasSignal) {
//
// Here we can Check and Filter Signals Based On State ...
bool isReady = IsReadyForXSignals(
xLongSignalRequest.signal,
states,
marketLength
);
//
if (isReady && xWaitForLongSignals) {
//
hasLongSignal = true;
signal = xLongSignalRequest.signal;
} else {
ClearXLongSignalConditions();
}
} else if (xShortSignalRequest.hasSignal) {
//
// Here we can Check and Filter Signals Based On State ...
bool isReady = IsReadyForXSignals(
xShortSignalRequest.signal,
states,
marketLength
);
//
if (isReady) {
//
hasShortSignal = true;
signal = xShortSignalRequest.signal;
} else {
ClearXShortSignalConditions();
}
}
//
hasSignal = hasLongSignal || hasShortSignal;
//
if (!hasSignal) {
//
signal.type = X_SIGNAL_NONE;
result.type = X_SIGNAL_NONE;
}
//
// Normalize TP, SL and Entry Price ...
signal.tp = NormalizeDouble(signal.tp, _Digits);
signal.sl = NormalizeDouble(signal.sl, _Digits);
signal.entry = NormalizeDouble(signal.entry, _Digits);
//
result.signal = signal;
result.type = signal.type;
result.hasSignal = hasSignal;
result.provider = signal.provider;
//
// Return Result ...
return result;
}
@@ -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,257 @@
/////////////////////////////////////////////////////////////////
//
// 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 2
//
// also we have 2 line for draw on this indicator ...
#property indicator_plots 2
//
// 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
//
// 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
//
double fastOSCBuffer[];
double slowOSCBuffer[];
//
// 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);
//
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;
}
//
// 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,402 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XSHPD 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 XSHPD Indicator"
#property strict
//
// START Inputs ...
//
input int marketLength = 7; // Market Length ...
input double sharpDetectMultiplier = 70; // Sharp Detect Multiplier
//
input bool drawLabels = true; // Draw Labels on Founded Sharps
//
input string sharpBullishLabel = "SH_BULL"; // Sharp Bullish Label
input color sharpBullishColor = clrAqua; // Sharp Bullish color
//
input string sharpBearishLabel = "SH_BEAR"; // Sharp Bearish Label
input color sharpBearishColor = clrFuchsia; // Sharp Bearish color
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 4
//
// Declare Buffers ...
#define marketHighestHighBufferIndex 0
#define marketLowestLowBufferIndex 1
#define sharpBullishBufferIndex 2
#define sharpBearishBufferIndex 3
//
double marketHighestHighBuffer[];
double marketLowestLowBuffer[];
double sharpBullishBuffer[];
double sharpBearishBuffer[];
//
#include "../Libraries/x-saherelm.lib.mq4"
#include "../Libraries/x-saherelm.draw.lib.mq4"
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
if (
marketLength <= 0
) {
return INIT_PARAMETERS_INCORRECT;
}
//
enableLogging = true;
//
logTag = "X_SHPD";
//
// Highest High ...
SetIndexLabel(marketHighestHighBufferIndex, "");
SetIndexBuffer(marketHighestHighBufferIndex, marketHighestHighBuffer);
SetIndexStyle(
marketHighestHighBufferIndex,
DRAW_LINE, // DRAW_NONE,
STYLE_DOT,
1, // 0,
clrAqua // clrNONE
);
//
// Lowest Low ...
SetIndexLabel(marketLowestLowBufferIndex, "");
SetIndexBuffer(marketLowestLowBufferIndex, marketLowestLowBuffer);
SetIndexStyle(
marketLowestLowBufferIndex,
DRAW_NONE,
STYLE_DOT,
0,
clrNONE
);
//
// Sharp Bullish Buffer ...
SetIndexLabel(sharpBullishBufferIndex, "");
SetIndexBuffer(sharpBullishBufferIndex, sharpBullishBuffer);
SetIndexStyle(
sharpBullishBufferIndex,
DRAW_NONE,
STYLE_DOT,
0,
clrNONE
);
//
// Sharp Bearish Buffer ...
SetIndexLabel(sharpBearishBufferIndex, "");
SetIndexBuffer(sharpBearishBufferIndex, sharpBearishBuffer);
SetIndexStyle(
sharpBearishBufferIndex,
DRAW_NONE,
STYLE_DOT,
0,
clrNONE
);
//
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason) {
//
RemoveDraws(logTag);
}
//
// 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, marketLength);
//
// 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 Sharp ...
CalculateSharp(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculating Sharp ...
void CalculateSharp(
const int &bar_index
) {
//
int index = 0;
//
double high = iHigh(
_Symbol,
_Period,
bar_index + 1
);
//
double low = iLow(
_Symbol,
_Period,
bar_index + 1
);
//
double open = iOpen(
_Symbol,
_Period,
bar_index + 1
);
//
double close = iClose(
_Symbol,
_Period,
bar_index + 1
);
//
marketHighestHighBuffer[bar_index] = GetMarketHighestHigh(
bar_index,
marketLength
);
//
marketLowestLowBuffer[bar_index] = GetMarketLowestLow(
bar_index,
marketLength
);
//
double maHHs[];
ArrayResize(
maHHs,
marketLength
);
//
double maLLs[];
ArrayResize(
maLLs,
marketLength
);
//
index = 0;
for (int i = bar_index; i < bar_index + marketLength; i++) {
//
maLLs[index] = marketLowestLowBuffer[i];
maHHs[index] = marketHighestHighBuffer[i];
//
index++;
}
//
int maxHighIdx = ArrayMaximum(maHHs);
double maxHigh = maHHs[maxHighIdx];
//
int minHighIdx = ArrayMinimum(maHHs);
double minHigh = maHHs[minHighIdx];
//
double highDiffRate = (maxHigh - minHigh) / 100;
//
int maxLowIdx = ArrayMaximum(maLLs);
double maxLow = maLLs[maxLowIdx];
//
int minLowIdx = ArrayMinimum(maLLs);
double minLow = maLLs[minLowIdx];
//
double lowDiffRate = (maxLow - minLow) / 100;
//
bool isSharpBullishDetected =
high == maxHigh
&& low > minLow
&& marketHighestHighBuffer[bar_index] == maxHigh
&& maxHigh - minHigh > highDiffRate * sharpDetectMultiplier
;
sharpBullishBuffer[bar_index] = isSharpBullishDetected ? 1 : 0;
//
bool isSharpBearishDetected =
low == minLow
&& high < maxHigh
&& marketLowestLowBuffer[bar_index] == minLow
&& maxLow - minLow > lowDiffRate * sharpDetectMultiplier
;
sharpBearishBuffer[bar_index] = isSharpBearishDetected ? 1 : 0;
//
if (
drawLabels
&& (
isSharpBearishDetected
|| isSharpBullishDetected
)
) {
//
datetime time = iTime(
_Symbol,
_Period,
bar_index
);
//
string lbl = StringConcatenate(
logTag,
isSharpBullishDetected ? "Bullish_" : "Bearish_",
bar_index
);
//
double price =
isSharpBullishDetected
?
marketLowestLowBuffer[bar_index] - (10 * _Point)
:
marketHighestHighBuffer[bar_index] + (10 * _Point)
;
//
uchar arrowCode =
isSharpBullishDetected
?
SYMBOL_ARROWUP
:
SYMBOL_ARROWDOWN
;
//
ENUM_ARROW_ANCHOR anchor =
isSharpBullishDetected
?
ANCHOR_BOTTOM
:
ANCHOR_TOP
;
//
color clr =
isSharpBullishDetected
?
sharpBullishColor
:
sharpBearishColor
;
//
string lblText =
isSharpBullishDetected
?
sharpBullishLabel
:
sharpBearishLabel
;
//
DrawText(
0,
lbl,
0,
time,
price,
lblText,
"Tahoma",
5,
clr
);
}
}
//
// END Functions ...
//
@@ -0,0 +1,250 @@
///////////////////////////////////////////////////////
//
// 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
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
#property indicator_chart_window
//
// #property indicator_buffers 3
//
// Declare Buffers ...
//
datetime startTime;
double lHigh;
double lLow;
//
datetime highTimes[];
//
datetime lowTimes[];
//
// 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;
}
//
// 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 ...
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
startTime
);
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
if (startTime == 0) {
//
startTime = barTime;
return;
}
//
if (
startTime > 0
&& startBarIndex - bar_index == length
) {
//
int hhIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
length,
bar_index
);
datetime hhTime = iTime(
_Symbol,
_Period,
hhIdx
);
double hh = iHigh(
_Symbol,
_Period,
hhIdx
);
//
int hhSize = ArraySize(highTimes);
datetime tempTimes[];
ArrayResize(
tempTimes,
hhSize
);
ArrayCopy(
tempTimes,
highTimes
);
ArrayResize(
highTimes,
hhSize + 1
);
highTimes[0] = hhTime;
ArrayCopy(
highTimes,
tempTimes,
1
);
//
int llIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
length,
bar_index
);
datetime llTime = iTime(
_Symbol,
_Period,
llIdx
);
double ll = iLow(
_Symbol,
_Period,
llIdx
);
//
int llSize = ArraySize(lowTimes);
ArrayFree(tempTimes);
ArrayResize(
tempTimes,
llSize
);
ArrayCopy(
tempTimes,
lowTimes
);
ArrayResize(
lowTimes,
llSize + 1
);
lowTimes[0] = llTime;
ArrayCopy(
lowTimes,
tempTimes,
1
);
//
startTime = 0;
ArrayFree(tempTimes);
}
}
//
// END Functions ...
//
@@ -0,0 +1,425 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XBand Indicator
// ---------------------------------------------
// saherelm implementation of xBand Indicator ...
//
// 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 XBND Indicator"
#property strict
//
#include "../Libraries/x-saherelm.lib.mq4"
#include "../Libraries/x-saherelm.draw.lib.mq4"
//
// START Inputs ...
//
input int marketLength = 5; // Averaging Length
input int ignoreLastCross = 4; // Ignore Last Cross
input int shift = 0; // Averaging Shift
input ENUM_MA_METHOD method = MODE_SMA; // Averaging Mode
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
#property indicator_chart_window
//
#property indicator_buffers 4
//
// Declare Buffers ...
//
// High ...
#property indicator_width1 1
#property indicator_color1 clrAqua
#property indicator_type1 DRAW_LINE
#property indicator_style1 STYLE_DASHDOT
//
// Open ...
#property indicator_width2 1
#property indicator_color2 clrGreen
#property indicator_type2 DRAW_LINE
#property indicator_style2 STYLE_DASH
//
// Close ...
#property indicator_width3 1
#property indicator_color3 clrRed
#property indicator_type3 DRAW_LINE
#property indicator_style3 STYLE_DASH
//
// Low ...
#property indicator_width4 1
#property indicator_color4 clrFuchsia
#property indicator_type4 DRAW_LINE
#property indicator_style4 STYLE_DASHDOT
//
#define highBufferIndex 0
#define openBufferIndex 1
#define closeBufferIndex 2
#define lowBufferIndex 3
//
double highBuffer[];
double openBuffer[];
double closeBuffer[];
double lowBuffer[];
//
datetime lastCrossTime;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
//
// Validating Input Parameters ...
if (
marketLength < 2
|| ignoreLastCross < 0
) {
return INIT_PARAMETERS_INCORRECT;
}
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XBND";
//
// High ...
string highLabel = StringConcatenate(
"High(", marketLength, ")"
);
SetIndexBuffer(highBufferIndex, highBuffer);
SetIndexLabel(highBufferIndex, highLabel);
//
// Open ...
string openLabel = StringConcatenate(
"Open(", marketLength, ")"
);
SetIndexBuffer(openBufferIndex, openBuffer);
SetIndexLabel(openBufferIndex, openLabel);
//
// Close ...
string closeLabel = StringConcatenate(
"Close(", marketLength, ")"
);
SetIndexBuffer(closeBufferIndex, closeBuffer);
SetIndexLabel(closeBufferIndex, closeLabel);
//
// Low ...
string lowLabel = StringConcatenate(
"Low(", marketLength, ")"
);
SetIndexBuffer(lowBufferIndex, lowBuffer);
SetIndexLabel(lowBufferIndex, lowLabel);
//
// 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(0, marketLength);
//
// 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 Buffers ...
CalculateBuffers(i);
//
// Calculate Market Changes ...
CalculateInfo(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
void CalculateBuffers(
const int bar_index
) {
//
// High ...
double high = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_HIGH,
bar_index
);
//
highBuffer[bar_index] = high;
//
// Open ...
double open = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_OPEN,
bar_index
);
//
openBuffer[bar_index] = open;
//
// Close ...
double close = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_CLOSE,
bar_index
);
//
closeBuffer[bar_index] = close;
//
// Low ...
double low = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_LOW,
bar_index
);
//
lowBuffer[bar_index] = low;
}
//
void CalculateInfo(
const int bar_index
) {
//
XOHCL pCandle = GetCandleModel(bar_index);
//
bool isTrendingUp =
pCandle.low > highBuffer[bar_index]
&& pCandle.high > highBuffer[bar_index];
//
bool isTrendingDown =
pCandle.high < lowBuffer[bar_index]
&& pCandle.low < lowBuffer[bar_index];
//
bool isOpenCrossOverClose =
true
// &&
// (
// pCandle.high > highBuffer[bar_index + 1]
// || pCandle.low < lowBuffer[bar_index + 1]
// )
&& openBuffer[bar_index + 1] > closeBuffer[bar_index + 1]
&& !(openBuffer[bar_index + 2] >= closeBuffer[bar_index + 2])
;
//
bool isOpenCrossUnderClose =
true
// &&
// (
// pCandle.high > highBuffer[bar_index + 1]
// || pCandle.low < lowBuffer[bar_index + 1]
// )
&& openBuffer[bar_index + 1] < closeBuffer[bar_index + 1]
&& !(openBuffer[bar_index + 2] <= closeBuffer[bar_index + 2])
;
//
isTrendingUp = isOpenCrossUnderClose;
isTrendingDown = isOpenCrossOverClose;
//
datetime time = iTime(
_Symbol,
_Period,
bar_index
);
//
if (
isTrendingUp
|| isTrendingDown
) {
//
if (lastCrossTime == 0) {
lastCrossTime = time;
} else {
//
int lastCrossBarIndex = iBarShift(
_Symbol,
_Period,
lastCrossTime
);
//
int diff = lastCrossBarIndex - bar_index;
if (diff <= ignoreLastCross) {
return;
} else {
lastCrossTime = time;
}
}
}
//
string lbl = StringConcatenate(
logTag,
"_Arrow_",
isTrendingUp ? "UP" : "Down",
"_", time
);
//
color clr = isTrendingUp ?
clrAqua :
clrFuchsia;
//
ENUM_ARROW_ANCHOR anchor = isTrendingUp ?
ANCHOR_BOTTOM :
ANCHOR_TOP;
//
uchar arrowCode = isTrendingUp ?
SYMBOL_ARROWUP :
SYMBOL_ARROWDOWN;
//
double price = isTrendingUp ?
pCandle.low - 20 * _Point :
pCandle.high + 20 * _Point;
//
if (isTrendingUp) {
//
// this means Market Going Up ...
}
//
if (isTrendingDown) {
//
// this means Market Going Downm ...
}
//
if (
isTrendingUp
|| isTrendingDown
) {
//
bool isDrawn = DrawArrow(
0,
lbl,
0,
time,
price,
arrowCode,
anchor,
clr
);
}
}
//
// END Functions ...
//
@@ -0,0 +1,410 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XHH 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 XHH Indicator"
#property strict
//
// START Inputs ...
//
//
input int marketLength = 7; // Market Length
//
input int shortCycleMultiplier = 4; // Market Short Cycle Multiplier
input int mediumCycleMultiplier = 14; // Market Medium Cycle Multiplier
input int longCycleMultiplier = 27; // Market Medium Cycle Multiplier
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
#property indicator_buffers 6
//
#property indicator_plots 6
//
// Start Define Indicator Buffer Styles ...
//
//
// Short Cycle Highest High Buffer ...
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//
// Short Cycle Lowest Low Buffer ...
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
// Medium Cycle Highest High Buffer ...
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrAqua
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
// Medium Cycle Lowest Low Buffer ...
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrFuchsia
#property indicator_style4 STYLE_DOT
#property indicator_width4 1
//
// Long Cycle Highest High Buffer ...
#property indicator_type5 DRAW_LINE
#property indicator_color5 C'62,82,6'
#property indicator_style5 STYLE_DOT
#property indicator_width5 1
//
// Long Cycle Lowest Low Buffer ...
#property indicator_type6 DRAW_LINE
#property indicator_color6 C'255,81,0'
#property indicator_style6 STYLE_DOT
#property indicator_width6 1
//
// End Define Indicator Buffer Styles ...
//
//
// Buffers ...
#define shortCycleHighestHighBufferIndex 0
#define shortCycleLowestLowBufferIndex 1
#define mediumCycleHighestHighBufferIndex 2
#define mediumCycleLowestLowBufferIndex 3
#define longCycleHighestHighBufferIndex 4
#define longCycleLowestLowBufferIndex 5
double shortCycleHighestHighBuffer[];
double shortCycleLowestLowBuffer[];
double mediumCycleHighestHighBuffer[];
double mediumCycleLowestLowBuffer[];
double longCycleHighestHighBuffer[];
double longCycleLowestLowBuffer[];
//
// Variables ...
int shortCycleLength;
int mediumCycleLength;
int longCycleLength;
//
double highestHighTimes[];
double lowestLowTimes[];
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
if (
marketLength <= 0 ||
shortCycleMultiplier <= 0 ||
mediumCycleMultiplier <= 0 ||
shortCycleMultiplier > mediumCycleMultiplier
) {
return INIT_PARAMETERS_INCORRECT;
}
//
// Start Set Index Buffers ...
//
shortCycleLength = shortCycleMultiplier * marketLength;
mediumCycleLength = mediumCycleMultiplier * marketLength;
longCycleLength = longCycleMultiplier * marketLength;
//
// Short Cycle Highest High ...
string scHHLbl = StringConcatenate(
"SC HH(", shortCycleLength, ")"
);
SetIndexBuffer(shortCycleHighestHighBufferIndex, shortCycleHighestHighBuffer);
SetIndexLabel(shortCycleHighestHighBufferIndex, scHHLbl);
//
// Short Cycle Lowest Low ...
string scLLLbl = StringConcatenate(
"SC LL(", shortCycleLength, ")"
);
SetIndexBuffer(shortCycleLowestLowBufferIndex, shortCycleLowestLowBuffer);
SetIndexLabel(shortCycleLowestLowBufferIndex, scLLLbl);
//
// Medium Cycle Highest High ...
string mcHHLbl = StringConcatenate(
"MC HH(", mediumCycleLength, ")"
);
SetIndexBuffer(mediumCycleHighestHighBufferIndex, mediumCycleHighestHighBuffer);
SetIndexLabel(mediumCycleHighestHighBufferIndex, mcHHLbl);
//
// Medium Cycle Lowest Low ...
string mcLLLbl = StringConcatenate(
"MC LL(", mediumCycleLength, ")"
);
SetIndexBuffer(mediumCycleLowestLowBufferIndex, mediumCycleLowestLowBuffer);
SetIndexLabel(mediumCycleLowestLowBufferIndex, mcLLLbl);
//
// Long Cycle Highest High ...
string lcHHLbl = StringConcatenate(
"LC HH(", longCycleLength, ")"
);
SetIndexBuffer(longCycleHighestHighBufferIndex, longCycleHighestHighBuffer);
SetIndexLabel(longCycleHighestHighBufferIndex, lcHHLbl);
//
// Long Cycle Lowest Low ...
string lcLLLbl = StringConcatenate(
"LC LL(", longCycleLength, ")"
);
SetIndexBuffer(longCycleLowestLowBufferIndex, longCycleLowestLowBuffer);
SetIndexLabel(longCycleLowestLowBufferIndex, lcLLLbl);
//
// 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, marketLength);
//
// 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 ...
//
CalculateShortCycle(i);
//
CalculateMediumCycle(i);
//
CalculateLongCycle(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculating Short Cycle ...
void CalculateShortCycle(
const int &bar_index
) {
//
// Short Cycle Highest High ...
//
int scHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
shortCycleLength,
bar_index
);
//
double scHH = iHigh(
_Symbol,
_Period,
scHHIdx
);
//
shortCycleHighestHighBuffer[bar_index] = scHH;
//
// Short Cycle Lowest Low ...
//
int scLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
shortCycleLength,
bar_index
);
//
double scLL = iLow(
_Symbol,
_Period,
scLLIdx
);
//
shortCycleLowestLowBuffer[bar_index] = scLL;
}
//
// Calculating Medium Cycle ...
void CalculateMediumCycle(
const int &bar_index
) {
//
// Medium Cycle Highest High ...
//
int mcHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
mediumCycleLength,
bar_index
);
//
double mcHH = iHigh(
_Symbol,
_Period,
mcHHIdx
);
//
mediumCycleHighestHighBuffer[bar_index] = mcHH;
//
// Medium Cycle Lowest Low ...
//
int mcLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
mediumCycleLength,
bar_index
);
//
double mcLL = iLow(
_Symbol,
_Period,
mcLLIdx
);
//
mediumCycleLowestLowBuffer[bar_index] = mcLL;
}
//
// Calculating Long Cycle ...
void CalculateLongCycle(
const int &bar_index
) {
//
// Long Cycle Highest High ...
//
int lcHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
longCycleLength,
bar_index
);
//
double lcHH = iHigh(
_Symbol,
_Period,
lcHHIdx
);
//
longCycleHighestHighBuffer[bar_index] = lcHH;
//
// Long Cycle Lowest Low ...
//
int lcLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
longCycleLength,
bar_index
);
//
double lcLL = iLow(
_Symbol,
_Period,
lcLLIdx
);
//
longCycleLowestLowBuffer[bar_index] = lcLL;
}
//
// END Functions ...
//
@@ -0,0 +1,695 @@
///////////////////////////////////////////////////////
//
// 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 ...
//
//
// Market Specifications ...
input int marketLength = 7; // Market Length
input double step = 0.02; // SAR Step
input double maximum = 0.2; // SAR Maximum
//
// Cycle Definitions ...
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 showPSar = true; // Show Parabolic Sar
input bool showMarketMiddle = true; // Show Market Middle
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 pSarColor = clrCornflowerBlue; // Parabolic Sar Color
input color shortCycleFastColor = clrGreen; // Short Cycle Fast Color
input color shortCycleSlowColor = clrRed; // Short Cycle Slow Color
input color mediumCycleFastColor = clrAqua; // Medium Cycle Fast Color
input color mediumCycleSlowColor = clrFuchsia; // Medium Cycle Slow Color
input color longCycleFastColor = clrGoldenrod; // Medium Cycle Fast Color
input color longCycleSlowColor = clrBrown; // Medium Cycle Slow Color
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
// define indicator buffers ...
#property indicator_buffers 8
#property indicator_plots 8
//
// Declare Buffers ...
#define scFastBufferIndex 0
#define scSlowBufferIndex 1
#define mcFastBufferIndex 2
#define mcSlowBufferIndex 3
#define lcFastBufferIndex 4
#define lcSlowBufferIndex 5
#define midBufferIndex 6
#define pSarBufferIndex 7
//
double scFastBuffer[];
double scSlowBuffer[];
double mcFastBuffer[];
double mcSlowBuffer[];
double lcFastBuffer[];
double lcSlowBuffer[];
double midBuffer[];
double pSarBuffer[];
//
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);
SetIndexLabel(midBufferIndex, "Market Mid");
//
// Parabolic Sar ...
SetIndexBuffer(pSarBufferIndex, pSarBuffer);
SetIndexLabel(pSarBufferIndex, "P Sar");
SetIndexStyle(
pSarBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
showPSar ?
pSarColor :
clrNONE
);
//
// Market Middle ...
SetIndexBuffer(midBufferIndex, midBuffer);
SetIndexLabel(midBufferIndex, "Mid");
SetIndexStyle(
midBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
showMarketMiddle ?
clrAntiqueWhite :
clrNONE
);
//
// 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);
//
// Calculate Parabolic Sar ...
CalculateParabolicSar(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 ...
//
}
void CalculateParabolicSar(
const int bar_index
) {
//
double sarValue = iSAR(
NULL,
_Period,
step,
maximum,
bar_index
);
//
pSarBuffer[bar_index] = sarValue;
}
//
// END Functions ...
//
@@ -0,0 +1,394 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XMKT Indicator
// ---------------------------------------------
// retrieve market base info ...
//
// 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 XMKT Indicator"
#property strict
//
// START Inputs ...
//
//
// Market Specifications ...
input int marketLength = 7; // Market Length
//
input bool showHighestHigh = true; // Show Market Highest High
input bool showHighestLow = true; // Show Market Highest Low
input bool showHighestOpen = true; // Show Market Highest Open
input bool showHighestClose = true; // Show Market Highest Close
input bool showLowestHigh = true; // Show Market Lowest High
input bool showLowestLow = true; // Show Market Lowest Low
input bool showLowestOpen = true; // Show Market Lowest Open
input bool showLowestClose = true; // Show Market Lowest Close
//
input color highestHighColor = clrDeepPink; // Market Highest High Color
input color highestLowColor = clrDarkOrange; // Market Highest Low Color
input color highestOpenColor = clrDodgerBlue; // Market Highest Open Color
input color highestCloseColor = clrOrchid; // Market Highest Close Color
input color lowestHighColor = clrHotPink; // Market Lowest High Color
input color lowestLowColor = clrOrange; // Market Lowest Low Color
input color lowestOpenColor = clrPowderBlue; // Market Lowest Open Color
input color lowestCloseColor = clrMediumOrchid; // Market Lowest Close Color
//
input ENUM_LINE_STYLE highestHighStyle = STYLE_DOT; // Market Highest High Line Style
input ENUM_LINE_STYLE highestLowStyle = STYLE_DOT; // Market Highest Low Line Style
input ENUM_LINE_STYLE highestOpenStyle = STYLE_DOT; // Market Highest Open Line Style
input ENUM_LINE_STYLE highestCloseStyle = STYLE_DOT; // Market Highest Close Line Style
input ENUM_LINE_STYLE lowestHighStyle = STYLE_DOT; // Market Lowest High Line Style
input ENUM_LINE_STYLE lowestLowStyle = STYLE_DOT; // Market Lowest Low Line Style
input ENUM_LINE_STYLE lowestOpenStyle = STYLE_DOT; // Market Lowest Open Line Style
input ENUM_LINE_STYLE lowestCloseStyle = STYLE_DOT; // Market Lowest Close Line Style
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
// define indicator buffers ...
#property indicator_buffers 8
#property indicator_plots 8
//
// Declare Buffers ...
#define marketHighestHighBufferIndex 0
#define marketHighestLowBufferIndex 1
#define marketHighestOpenBufferIndex 2
#define marketHighestCloseBufferIndex 3
#define marketLowestHighBufferIndex 4
#define marketLowestLowBufferIndex 5
#define marketLowestOpenBufferIndex 6
#define marketLowestCloseBufferIndex 7
//
double marketHighestHighBuffer[];
double marketHighestLowBuffer[];
double marketHighestOpenBuffer[];
double marketHighestCloseBuffer[];
double marketLowestHighBuffer[];
double marketLowestLowBuffer[];
double marketLowestOpenBuffer[];
double marketLowestCloseBuffer[];
//
// 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 (marketLength <= 0) {
return INIT_PARAMETERS_INCORRECT;
}
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XST_XMKT";
//
// Highest High ...
string highestHighLbl = StringConcatenate("HH(", marketLength,")");
SetIndexLabel(marketHighestHighBufferIndex, highestHighLbl);
SetIndexBuffer(marketHighestHighBufferIndex, marketHighestHighBuffer);
SetIndexStyle(
marketHighestHighBufferIndex,
showHighestHigh ?
DRAW_LINE :
DRAW_NONE,
highestHighStyle,
1,
showHighestHigh ?
highestHighColor :
clrNONE
);
//
// Highest Low ...
string highestLowLbl = StringConcatenate("HL(", marketLength,")");
SetIndexLabel(marketHighestLowBufferIndex, highestLowLbl);
SetIndexBuffer(marketHighestLowBufferIndex, marketHighestLowBuffer);
SetIndexStyle(
marketHighestLowBufferIndex,
showHighestLow ?
DRAW_LINE :
DRAW_NONE,
highestLowStyle,
1,
showHighestLow ?
highestLowColor :
clrNONE
);
//
// Highest Open ...
string highestOpenLbl = StringConcatenate("HO(", marketLength,")");
SetIndexLabel(marketHighestOpenBufferIndex, highestOpenLbl);
SetIndexBuffer(marketHighestOpenBufferIndex, marketHighestOpenBuffer);
SetIndexStyle(
marketHighestOpenBufferIndex,
showHighestOpen ?
DRAW_LINE :
DRAW_NONE,
highestOpenStyle,
1,
showHighestOpen ?
highestOpenColor :
clrNONE
);
//
// Highest Close ...
string highestCloseLbl = StringConcatenate("HC(", marketLength,")");
SetIndexLabel(marketHighestCloseBufferIndex, highestCloseLbl);
SetIndexBuffer(marketHighestCloseBufferIndex, marketHighestCloseBuffer);
SetIndexStyle(
marketHighestCloseBufferIndex,
showHighestClose ?
DRAW_LINE :
DRAW_NONE,
highestCloseStyle,
1,
showHighestClose ?
highestCloseColor :
clrNONE
);
//
// Lowest High ...
string lowestHighLbl = StringConcatenate("LH(", marketLength,")");
SetIndexLabel(marketLowestHighBufferIndex, lowestHighLbl);
SetIndexBuffer(marketLowestHighBufferIndex, marketLowestHighBuffer);
SetIndexStyle(
marketLowestHighBufferIndex,
showLowestHigh ?
DRAW_LINE :
DRAW_NONE,
lowestHighStyle,
1,
showLowestHigh ?
lowestHighColor :
clrNONE
);
//
// Lowest Low ...
string lowestLowLbl = StringConcatenate("LL(", marketLength,")");
SetIndexLabel(marketLowestLowBufferIndex, lowestLowLbl);
SetIndexBuffer(marketLowestLowBufferIndex, marketLowestLowBuffer);
SetIndexStyle(
marketLowestLowBufferIndex,
showLowestLow ?
DRAW_LINE :
DRAW_NONE,
lowestLowStyle,
1,
showLowestLow ?
lowestLowColor :
clrNONE
);
//
// Lowest Open ...
string lowestOpenLbl = StringConcatenate("LO(", marketLength,")");
SetIndexLabel(marketLowestOpenBufferIndex, lowestOpenLbl);
SetIndexBuffer(marketLowestOpenBufferIndex, marketLowestOpenBuffer);
SetIndexStyle(
marketLowestOpenBufferIndex,
showLowestOpen ?
DRAW_LINE :
DRAW_NONE,
lowestOpenStyle,
1,
showLowestOpen ?
lowestOpenColor :
clrNONE
);
//
// Lowest Close ...
string lowestCloseLbl = StringConcatenate("LC(", marketLength,")");
SetIndexLabel(marketLowestCloseBufferIndex, lowestCloseLbl);
SetIndexBuffer(marketLowestCloseBufferIndex, marketLowestCloseBuffer);
SetIndexStyle(
marketLowestCloseBufferIndex,
showLowestClose ?
DRAW_LINE :
DRAW_NONE,
lowestCloseStyle,
1,
showLowestClose ?
lowestCloseColor :
clrNONE
);
//
// 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, 3);
//
// 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 ...
CalculateBuffers(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculate Short Cycle ...
void CalculateBuffers(
const int bar_index
) {
//
// Highest High ...
double highestHighValue = GetMarketHighestHigh(
bar_index,
marketLength
);
marketHighestHighBuffer[bar_index] = highestHighValue;
//
// Highest Low ...
double highestLowValue = GetMarketHighestLow(
bar_index,
marketLength
);
marketHighestLowBuffer[bar_index] = highestLowValue;
//
// Highest Open ...
double highestOpenValue = GetMarketHighestOpen(
bar_index,
marketLength
);
marketHighestOpenBuffer[bar_index] = highestOpenValue;
//
// Highest Close ...
double highestCloseValue = GetMarketHighestClose(
bar_index,
marketLength
);
marketHighestCloseBuffer[bar_index] = highestCloseValue;
//
// Lowest High ...
double lowestHighValue = GetMarketLowestHigh(
bar_index,
marketLength
);
marketLowestHighBuffer[bar_index] = lowestHighValue;
//
// Lowest Low ...
double lowestLowValue = GetMarketLowestLow(
bar_index,
marketLength
);
marketLowestLowBuffer[bar_index] = lowestLowValue;
//
// Lowest Open ...
double lowestOpenValue = GetMarketLowestOpen(
bar_index,
marketLength
);
marketLowestOpenBuffer[bar_index] = lowestOpenValue;
//
// Lowest Close ...
double lowestCloseValue = GetMarketLowestClose(
bar_index,
marketLength
);
marketLowestCloseBuffer[bar_index] = lowestCloseValue;
}
//
// END Functions ...
//
@@ -0,0 +1,221 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XMTR Indicator
// ---------------------------------------------
// retrieve market base info ...
//
// 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 XMKT Indicator"
#property strict
//
// START Inputs ...
//
//
// Market Specifications ...
input int marketLength = 20; // Market Length
input int atrMultiplier = 1; // ATR Multiplier
input int atrLength = 5; // ATR Period
input ENUM_APPLIED_PRICE source = PRICE_CLOSE; // Source
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
// define indicator buffers ...
#property indicator_buffers 3
#property indicator_plots 3
//
// Declare Buffers ...
#define trendBufferIndex 0
#define upTrendBufferIndex 1
#define downTrendBufferIndex 2
//
double trendBuffer[];
double upTrendBuffer[];
double downTrendBuffer[];
//
// 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 (marketLength <= 0) {
return INIT_PARAMETERS_INCORRECT;
}
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XMTR";
//
// TREND ...
SetIndexLabel(trendBufferIndex, "Trend");
SetIndexBuffer(trendBufferIndex, trendBuffer);
SetIndexStyle(
trendBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
clrNONE
);
//
// UP Trend ...
SetIndexLabel(upTrendBufferIndex, "Up Trend");
SetIndexBuffer(upTrendBufferIndex, upTrendBuffer);
SetIndexStyle(
upTrendBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
clrNONE
);
//
// DOWN Trend ...
SetIndexLabel(downTrendBufferIndex, "Down Trend");
SetIndexBuffer(downTrendBufferIndex, downTrendBuffer);
SetIndexStyle(
downTrendBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
clrNONE
);
//
// 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, 3);
//
// 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 ...
CalculateBuffers(
i,
low
);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculate Short Cycle ...
void CalculateBuffers(
const int bar_index,
const double &low[]
) {
//
double atr = GetMarketTRSMA(
bar_index,
atrLength
);
//
double smoothedAtr = (atr * atrMultiplier);
double upTrend = low[bar_index] - smoothedAtr;
double downTrend = low[bar_index] + smoothedAtr;
//
double cciValue = GetMarketCCI(
bar_index,
marketLength,
source
);
//
// TODO: Complete this ...
}
//
// 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 ...
//
@@ -0,0 +1,472 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 CCI Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// Based Signal Conditions ...
struct XCCILongSignalConditions {
//
datetime start;
//
datetime crossOverMinusHundredTime;
datetime crossUnderMinusHundredTime;
//
double crossOverSlope;
};
//
static XCCILongSignalConditions cciLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill Signal Conditions ...
void CheckCCILongSignalConditions(
const int bar_index,
const int marketLen,
//
const double smoother = 10
) {
//
// Retrieve Bar Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// LONG:
// wait for cci cross under -100
// then wait for cross over -100
// slope of crossing over ??? ...
if (cciLongConds.start == 0) {
// LogMessage("Start");
cciLongConds.start = barTime;
return;
}
//
// Check Start Time ...
if (cciLongConds.start == 0) {
return;
}
//
// Read current, prev, and prevPrev CCI ...
double cci = GetMarketCCI(
bar_index,
marketLen
);
double cci1 = GetMarketCCI(
bar_index + 1,
marketLen
);
double cci2 = GetMarketCCI(
bar_index + 2,
marketLen
);
//
// Find Cross Under -100 ...
bool isCrossUnderMinusHundred =
cci < -105 && !(cci1 < -105)
&& MathAbs(MathAbs(cci) - MathAbs(cci1)) > smoother
;
//
// Find Cross Over -100 ...
bool isCrossOverMinusHundred =
cci > -105 && !(cci1 > -105)
&& MathAbs(cci - cci1) > smoother
;
//
// Fill Conditions ...
if (
isCrossUnderMinusHundred
&& cciLongConds.crossUnderMinusHundredTime == 0
&& cciLongConds.crossOverMinusHundredTime == 0
) {
// LogMessage("Cross Under ...");
cciLongConds.crossUnderMinusHundredTime = barTime;
return;
}
//
// Fill Conditions ...
if (
isCrossOverMinusHundred
&& cciLongConds.crossOverMinusHundredTime == 0
&& cciLongConds.crossUnderMinusHundredTime != 0
) {
//
// LogMessage("Cross Over ...");
cciLongConds.crossOverMinusHundredTime = barTime;
}
//
// Prevent Going forward untill Cross Under Happens ...
if (cciLongConds.crossUnderMinusHundredTime == 0) {
return;
}
//
// Prevent from Going forward untill Cross Over Happens ...
if (cciLongConds.crossOverMinusHundredTime == 0) {
return;
}
//
// Calculate Slope ...
double x1 = 0;
double y1 = cci1;
double x2 = 1;
double y2 = cci;
//
// Calculat Line Slope ...
double tSlope = GetSlope(
x1, y1, x2, y2
);
//
cciLongConds.crossOverSlope = tSlope;
// LogMessage("Slope: " + tSlope);
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateCCILongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateCCILongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
int llIdx = GetLowestLowOFCCILongPeriodIndex();
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
// GetLowestLowOFCCILongPeriod();
//
int hhIdx = GetHighestHighOfCCILongPeriodIndex();
double hh = GetHighestHighOfCCILongPeriod();
// GetMarketHighestHigh(
// bar_index,
// marketLen
// );
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r;
//
double sl = 0; // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_CCI_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_CCI_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateCCILongConditions() {
//
int crossUnderBarIndex =
cciLongConds.crossUnderMinusHundredTime != 0
? iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
)
: -1
;
//
int crossOverBarIndex =
cciLongConds.crossOverMinusHundredTime != 0
? iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
)
: -1
;
//
bool isConditionsFilled =
//
cciLongConds.start != 0
&& cciLongConds.crossUnderMinusHundredTime != 0
&& cciLongConds.crossOverMinusHundredTime != 0
&& cciLongConds.crossUnderMinusHundredTime >= cciLongConds.start
&& cciLongConds.crossOverMinusHundredTime > cciLongConds.crossUnderMinusHundredTime
;
//
bool isLogicPassed =
//
crossOverBarIndex > 0
&& crossUnderBarIndex > 0
&& crossUnderBarIndex > crossOverBarIndex
&& (crossUnderBarIndex - crossOverBarIndex) >= 5
;
//
bool result =
//
isConditionsFilled
&& isLogicPassed
&& cciLongConds.crossOverSlope > 0
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearCCILongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearCCILongSignalConditions() {
//
cciLongConds.start = 0;
cciLongConds.crossOverSlope = 0;
cciLongConds.crossOverMinusHundredTime = 0;
cciLongConds.crossUnderMinusHundredTime = 0;
}
//
int GetHighestHighOfCCILongPeriodIndex() {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
);
//
int result = iHighest(
_Symbol,
_Period,
MODE_HIGH,
crossUnderBarIndex - crossOverBarIndex,
crossOverBarIndex
);
//
return result;
}
//
double GetHighestHighOfCCILongPeriod() {
//
int index = GetHighestHighOfCCILongPeriodIndex();
//
double result = iHigh(
_Symbol,
_Period,
index
);
//
return result;
}
//
int GetLowestLowOFCCILongPeriodIndex() {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
);
//
int result = iLowest(
_Symbol,
_Period,
MODE_LOW,
crossUnderBarIndex - crossOverBarIndex,
crossOverBarIndex
);
//
return result;
}
//
double GetLowestLowOFCCILongPeriod() {
//
int index = GetLowestLowOFCCILongPeriodIndex();
//
double result = iLow(
_Symbol,
_Period,
index
);
//
return result;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForCCILongSignals(
const XState &states[]
) {
//
bool result = false;
//
XStateInfo info = ParseXMAStates(states);
//
result =
//
true
//
// && states[1].mc.fast > states[1].mc.slow
// && MathAbs(states[1].mc.fast - states[1].mc.slow) > 100 * _Point
// && states[1].marketMiddleage > states[1].sc.fast
// && states[1].marketMiddleage > states[1].mc.fast
;
//
return result;
}
//
// END Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,948 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 Indicator 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
static double zigZags[];
//
// END Global Requirement Functions ...
//
//
// START Indicator Reading Data ...
//
//
// START XMKT Data ...
//
XMKTState GetXMKT(
const int bar_index,
const int marketLen,
//
const bool showHighestHigh = true,
const bool showHighestLow = true,
const bool showHighestOpen = true,
const bool showHighestClose = true,
const bool showLowestHigh = true,
const bool showLowestLow = true,
const bool showLowestOpen = true,
const bool showLowestClose = true,
const color highestHighColor = clrDeepPink,
const color highestLowColor = clrDarkOrange,
const color highestOpenColor = clrDodgerBlue,
const color highestCloseColor = clrOrchid,
const color lowestHighColor = clrHotPink,
const color lowestLowColor = clrOrange,
const color lowestOpenColor = clrPowderBlue,
const color lowestCloseColor = clrMediumOrchid,
const ENUM_LINE_STYLE highestHighStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestLowStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestOpenStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestCloseStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestHighStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestLowStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestOpenStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestCloseStyle = STYLE_DOT
) {
//
XMKTState result = {};
//
string xmktIndName = "x-saherelm.xmarket";
//
int highestHighBufferIndex = 0;
int highestLowBufferIndex = 1;
int highestOpenBufferIndex = 2;
int highestCloseBufferIndex = 3;
int lowestHighBufferIndex = 4;
int lowestLowBufferIndex = 5;
int lowestOpenBufferIndex = 6;
int lowestCloseBufferIndex = 7;
//
// Highest High ...
double highestHigh = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestHighBufferIndex, // Buffer Index ...
bar_index
);
result.highestHigh = highestHigh;
//
// Highest Low ...
double highestLow = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestLowBufferIndex, // Buffer Index ...
bar_index
);
result.highestLow = highestLow;
//
// Highest Open ...
double highestOpen = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestOpenBufferIndex, // Buffer Index ...
bar_index
);
result.highestOpen = highestOpen;
//
// Highest Close ...
double highestClose = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestCloseBufferIndex, // Buffer Index ...
bar_index
);
result.highestClose = highestClose;
//
// Lowest High ...
double lowestHigh = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestHighBufferIndex, // Buffer Index ...
bar_index
);
result.lowestHigh = lowestHigh;
//
// Lowest Low ...
double lowestLow = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestLowBufferIndex, // Buffer Index ...
bar_index
);
result.lowestLow = lowestLow;
//
// Lowest Open ...
double lowestOpen = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestOpenBufferIndex, // Buffer Index ...
bar_index
);
result.lowestOpen = lowestOpen;
//
// Lowest Close ...
double lowestClose = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestCloseBufferIndex, // Buffer Index ...
bar_index
);
result.lowestClose = lowestClose;
//
return result;
}
//
// END XMKT Data ...
//
//
// START XOSC Data ...
//
XCycleState GetXOSC(
const int bar_index,
const int marketLen,
//
const int fastMult,
const int slowMult,
//
const double fastMMul = 1.0,
const double slowMMul = 3.0
) {
//
XCycleState result = {};
//
string oscIndName = "x-saherelm.osc";
//
// Prepare OSC Inputs ...
//
int fastLength = fastMult * marketLen;
int slowLength = slowMult * marketLen;
//
// Fast ...
double fast = iCustom(
_Symbol,
_Period,
oscIndName,
//
// Inputs ...
fastLength,
fastMMul,
slowLength,
slowMMul,
//
0, // Buffer Index ...
bar_index
);
result.fast = fast;
//
// Slow ...
double slow = iCustom(
_Symbol,
_Period,
oscIndName,
//
// Inputs ...
fastLength,
fastMMul,
slowLength,
slowMMul,
//
1, // Buffer Index ...
bar_index
);
result.slow = slow;
//
return result;
}
//
// END XOSC Data ...
//
//
// START XBND Data ...
//
XBndState GetXBND(
const int bar_index,
//
const int marketLen = 10, // Market Length ...
const int shift = 0, // MA Shift ...
const ENUM_MA_METHOD method = MODE_SMA // MA Method ...
) {
//
XBndState result = {};
//
double high = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_HIGH
);
result.high = high;
//
double open = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_OPEN
);
result.open = open;
//
double close = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_CLOSE
);
result.close = close;
//
double low = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_LOW
);
result.low = low;
//
return result;
}
//
// END XBND Data ...
//
//
// START ZigZag Data ...
//
void PrepareZigZagState(
const int bar_index,
//
const int depth = 12,
const int deviation = 5,
const int backStep = 3
) {
//
string zigzagIndName = "x-saherelm.zigzag";
//
ArrayFree(zigZags);
ArrayResize(
zigZags,
3
);
//
double zigZag = 0;
int index = 0;
int i = bar_index;
while (index < 3) {
//
zigZag = iCustom(
_Symbol,
_Period,
zigzagIndName,
//
// Inputs ...
depth,
deviation,
backStep,
//
0, // Buffer Index ...
i
);
//
if (zigZag > 0) {
//
zigZags[index] = zigZag;
index++;
}
//
i++;
}
}
//
// END ZigZag Data ...
//
//
// START XMA Data ...
//
//
// Retrieve Short Cycle ...
XCycleState GetXMASC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow= slow;
//
return result;
}
//
// Retrieve Medium Cycle ...
XCycleState GetXMAMC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow= slow;
//
return result;
}
//
// Retrieve Long Cycle ...
XCycleState GetXMALC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow = slow;
//
return result;
}
//
// Retrieve Long Cycle ...
XCycleState GetXMANN(
const int bar_index,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = 10;
int slowLength = 50;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow = slow;
//
return result;
}
//
// Retrieve Middle ...
double GetXMAMM(
const int bar_index,
const int marketLen,
const double multiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_EMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_MEDIAN
) {
//
double result = 0;
//
int length = (int)(marketLen * multiplier);
//
double middle = iMA(
_Symbol,
_Period,
length,
shift,
method,
appliedPrice,
bar_index
);
result = middle;
//
return result;
}
//
// Retrieve XMA Parabolic SAR ...
double GetXMAPSAR(
const int bar_index,
//
double stp = 0.02,
double mxm = 0.2
) {
//
double result = 0;
//
double pSar = iSAR(
_Symbol,
_Period,
stp,
mxm,
bar_index
);
result = pSar;
//
return result;
}
//
XState GetXState(
const int bar_index,
const int marketLen,
//
const double stp,
const double mxm,
//
const int shortCycleFastMult,
const int shortCycleSlowMult,
const int mediumCycleFastMult,
const int mediumCycleSlowMult,
const int longCycleFastMult,
const int longCycleSlowMult
) {
//
XState result = {};
//
// Short Cycle ...
XCycleState sc = GetXMASC(
bar_index,
marketLen,
shortCycleFastMult,
shortCycleSlowMult
);
result.sc = sc;
//
// Medium Cycle ...
XCycleState mc = GetXMAMC(
bar_index,
marketLen,
mediumCycleFastMult,
mediumCycleSlowMult
);
result.mc = mc;
//
// Long Cycle ...
XCycleState lc = GetXMALC(
bar_index,
marketLen,
longCycleFastMult,
longCycleSlowMult
);
result.lc = lc;
//
// OSC ...
XCycleState osc = GetXOSC(
//
bar_index,
marketLen,
//
shortCycleFastMult,
shortCycleSlowMult
);
result.osc = osc;
//
// Market Middleage ...
double marketMiddleage = GetXMAMM(
bar_index,
marketLen,
1.5
);
result.marketMiddleage = marketMiddleage;
//
// Parabolic SAR ...
double parabolicSAR = GetXMAPSAR(
bar_index,
stp,
mxm
);
result.parabolicSAR = parabolicSAR;
// //
// int cciMarketLength = longCycleSlowMult * marketLen;
// double cci = GetMarketCCI(
// bar_index,
// cciMarketLength
// );
// result.cci = cci;
//
XBndState bnd = GetXBND(
bar_index
);
result.bnd = bnd;
//
XMKTState mkt = GetXMKT(
bar_index,
marketLen
);
result.mkt = mkt;
//
double longCycleHighestHigh = GetMarketHighestHigh(
bar_index,
longCycleFastMult * marketLen
);
result.longCycleHighestHigh = longCycleHighestHigh;
//
return result;
}
//
// END XMA Data ...
//
//
// END Indicator Reading Data ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,91 @@
///////////////////////////////////////////////////////
//
// 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);
}
//
// this used for logging series ...
void LogSeries(
double &series[], // which series to Log ...
int length = 0, // number of items to Log, 0 means all ...
int skip = 0 // number of items which skip before logging ...
) {
//
string msg = "";
//
int seriesSize = ArraySize(series);
if (
skip < 0
|| length < 0
|| seriesSize == 0
|| skip > seriesSize
|| skip + length > seriesSize
) {
return;
}
//
length = length == 0 ?
seriesSize :
length;
int start = skip > 1 ?
skip - 1 :
skip == 1 ?
1 :
0;
//
// Loop through series items ...
for (int i = start; i < start + length; i++) {
//
msg += StringConcatenate(
"i[", i, "]: ", series[i], ", "
);
}
//
LogMessage(msg);
}
//
// End Log Messages ...
//
@@ -0,0 +1,225 @@
///////////////////////////////////////////////////////
//
// 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 STATIC Variables ...
//
//
static int totalSignals = 0;
static int totalLongSignals = 0;
static int totalShortSignals = 0;
//
static double initialBalance = 0;
//
static int countedBars = 0;
static bool isNewBar = false;
static bool isNewDay = false;
//
// END STATIC Variables ...
//
//
// Start Models ...
//
//
// Signal Providers ...
enum ENUM_X_SIGNAL_PROVIDER {
X_UNKNOWN_PROVIDER,
X_OSC_PROVIDER,
X_CCI_PROVIDER,
X_SHP_PROVIDER,
X_XMA_PROVIDER,
X_RMA_PROVIDER,
X_XXX_PROVIDER
};
//
// these are different signal types ...
enum ENUM_X_SIGNAL_TYPE {
X_SIGNAL_NONE,
X_SIGNAL_LONG,
X_SIGNAL_SHORT,
};
//
// we Model each signals as this type ...
struct XSignal {
//
// Signal Symbol ...
string symbol;
//
// Signal Type ...
ENUM_X_SIGNAL_TYPE type;
//
// Signal ID ...
int id;
//
// Signal Ticket Number, when Opening Trade ...
int ticket;
//
// Signal Provider ...
ENUM_X_SIGNAL_PROVIDER provider;
//
// Target Point ...
double tp;
//
// Stop Loss ...
double sl;
//
// Signal Entry Price ...
double entry;
//
// Signalling Time ...
datetime time;
//
// Signal Comments ...
string comment;
};
//
// this is Signal Request Response model ...
struct XSignalRequest {
bool hasSignal;
XSignal signal;
ENUM_X_SIGNAL_TYPE type;
ENUM_X_SIGNAL_PROVIDER provider;
};
//
struct XBndState {
double high;
double open;
double close;
double low;
};
//
struct XMKTState {
//
double highestHigh;
double highestLow;
double highestOpen;
double highestClose;
//
double lowestHigh;
double lowestLow;
double lowestOpen;
double lowestClose;
};
//
struct XCycleState {
double fast;
double slow;
};
//
// Define a Model to Represent Snapshot of XMA Indicator ...
struct XState {
//
// SC ...
XCycleState sc;
//
// MC ...
XCycleState mc;
//
// LC ...
XCycleState lc;
//
// OSC ...
XCycleState osc;
//
// MIDDLEAGE ...
double marketMiddleage;
//
// PARABOLIC-SAR ...
double parabolicSAR;
//
double cci;
//
XBndState bnd;
//
XMKTState mkt;
//
double longCycleHighestHigh;
};
//
// Parsed XMA Buffer ...
struct XStateInfo {
//
// Check Market Cross Exists or not ...
//
bool isSCFastCrossOverSlow;
bool isSCFastCrossUnderSlow;
//
double scMin;
double scMax;
//
bool isMCFastCrossOverSlow;
bool isMCFastCrossUnderSlow;
//
double mcMin;
double mcMax;
bool isLCFastCrossOverSlow;
bool isLCFastCrossUnderSlow;
//
double lcMin;
double lcMax;
//
bool isMMCrossOverSCFast;
bool isMMCrossUnderSCFast;
//
bool isMMCrossOverMCFast;
bool isMMCrossUnderMCFast;
//
double mmMin;
double mmMax;
};
//
// End Models ...
//
@@ -0,0 +1,363 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 OSC Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// SHP Based Signal Conditions ...
struct XOSCLongSignalConditions {
//
datetime crossOverTime;
double slowOnCrossOver;
//
datetime crossUnderTime;
double slowOnCrossUnder;
};
//
static XOSCLongSignalConditions oscLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckOSCLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult,
//
int lcFMult,
int lcSMult,
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
XState states[];
ArrayResize(
states,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < marketLen; i++) {
//
XState state = GetXState(
i,
marketLen,
//
stp,
mxm,
scFMult,
scSMult,
mcFMult,
mcSMult,
lcFMult,
lcSMult
);
//
states[index] = state;
//
index++;
}
//
bool isCrossUnder =
states[0].osc.fast < 0
&& !(states[1].osc.fast < 0)
;
//
bool isCrossOver =
states[0].osc.fast > 0
&& !(states[1].osc.fast > 0)
;
//
int oneTouches = 0;
int halfTouches = 0;
int minusOneTouches = 0;
for (int i = 0; i < marketLen - 1; i++) {
//
// One Touches ...
if (
states[i].osc.fast > 1
&& !(states[i + 1].osc.fast > 1)
) {
oneTouches++;
}
//
// Half Touches ...
if (
states[i].osc.fast > 0.5
&& !(states[i + 1].osc.fast > 0.5)
) {
halfTouches++;
}
//
// Minus One Touches ...
if (
states[i].osc.fast < -1
&& !(states[i + 1].osc.fast < -1)
) {
minusOneTouches++;
}
}
//
if (
isCrossUnder
&& oscLongConds.crossUnderTime == 0
) {
//
oscLongConds.crossUnderTime = barTime;
oscLongConds.slowOnCrossUnder = states[0].osc.slow;
return;
}
//
if (
isCrossOver
&& oscLongConds.crossUnderTime > 0
&& oscLongConds.crossOverTime == 0
) {
//
oscLongConds.crossOverTime = barTime;
oscLongConds.slowOnCrossOver = states[0].osc.slow;
return;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateOSCLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateOSCLongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r; // 300 * _Point;
//
double sl = 0; // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_OSC_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_OSC_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateOSCLongConditions() {
//
bool isConditionsFilled =
oscLongConds.crossOverTime > 0
&& oscLongConds.crossUnderTime > 0
&& oscLongConds.slowOnCrossOver > 0
&& oscLongConds.slowOnCrossUnder > 0
&& oscLongConds.crossOverTime > oscLongConds.crossUnderTime
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
oscLongConds.crossUnderTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
oscLongConds.crossOverTime
);
//
isBLFilled =
crossUnderBarIndex > crossOverBarIndex
// && oscLongConds.slowOnCrossOver > oscLongConds.slowOnCrossUnder
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearOSCLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearOSCLongSignalConditions() {
//
oscLongConds.crossOverTime = 0;;
oscLongConds.crossUnderTime = 0;;
}
//
// Check State for Long Signals ...
bool IsReadyForOSCLongSignals(
const XSignal &signal,
const XState &states[]
) {
//
bool result = false;
//
result =
//
true
;
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,363 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 RMA Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// RMA Based Signal Conditions ...
struct XRMALongSignalConditions {
//
datetime crossUnderTime;
//
datetime crossOverTime;
};
//
static XRMALongSignalConditions xrmaLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXRMALongSignalConditions(
const int bar_index,
const int marketLen,
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
XCycleState states[];
ArrayResize(
states,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < marketLen; i++) {
//
XCycleState state = GetXMANN(i);
//
states[index] = state;
//
index++;
}
//
bool isCrossUnder =
states[1].fast < states[1].slow
&& !(states[2].fast < states[2].slow)
;
//
bool isCrossOver =
states[1].fast > states[1].slow
&& !(states[2].fast > states[2].slow)
;
//
if (
isCrossUnder
&& xrmaLongConds.crossUnderTime == 0
) {
//
xrmaLongConds.crossUnderTime = barTime;
return;
}
//
if (
isCrossOver
&& xrmaLongConds.crossUnderTime > 0
&& xrmaLongConds.crossOverTime == 0
) {
//
xrmaLongConds.crossOverTime = barTime;
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXRMALongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateXRMALongConditions(marketLen)) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r; // 300 * _Point;
//
double sl = 0; // entryPrice - (300 * _Point); // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_RMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_RMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXRMALongConditions(
const int marketLen
) {
//
bool isConditionsFilled =
true
&& xrmaLongConds.crossOverTime > 0
&& xrmaLongConds.crossUnderTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
xrmaLongConds.crossOverTime
);
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
xrmaLongConds.crossUnderTime
);
//
XCycleState stateOnCrossUnder = GetXMANN(
crossUnderBarIndex
);
//
XCycleState stateOnCrossOver = GetXMANN(
crossOverBarIndex
);
//
double maC = iMA(
_Symbol,
_Period,
14,
0,
MODE_SMA,
PRICE_CLOSE,
crossOverBarIndex
);
// //
// double rmaOnCrossOver = GetRMA(
// crossOverBarIndex,
// 10
// );
// //
// double rmaOnMarketLength = GetRMA(
// crossOverBarIndex + marketLen,
// 10
// );
// //
// double prevCandleHigh = iHigh(
// _Symbol,
// _Period,
// crossOverBarIndex
// );
// //
// PrepareZigZagState(crossOverBarIndex);
// double zigZagDelta = zigZags[1] - zigZags[2];
// bool isZigZagWaitForHigh = zigZagDelta < 0;
//
isBLFilled =
true
//
&& (crossUnderBarIndex - crossOverBarIndex) > 5
//
&& xrmaLongConds.crossOverTime > xrmaLongConds.crossUnderTime
//
&& stateOnCrossOver.slow < stateOnCrossUnder.slow
//
&& MathAbs(stateOnCrossOver.fast - stateOnCrossOver.slow) > (70 * _Point)
//
&& maC >= stateOnCrossOver.slow
// //
// && !(rmaOnCrossOver < stateOnCrossOver.slow)
// //
// && MathAbs(rmaOnCrossOver - rmaOnMarketLength) < (600 * _Point)
// //
// && !isZigZagWaitForHigh
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXRMALongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXRMALongSignalConditions() {
//
xrmaLongConds.crossOverTime = 0;
xrmaLongConds.crossUnderTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXRMALongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
result =
//
true
;
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,391 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 SHP Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// SHP Based Signal Conditions ...
struct XSHPLongSignalConditions {
//
datetime start;
datetime stop;
};
//
static XSHPLongSignalConditions shpLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckSHPLongSignalConditions(
const int bar_index,
const int marketLen,
const double shpDetectMult,
const double smoother = 30
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
double high = iHigh(
_Symbol,
_Period,
bar_index
);
//
double low = iLow(
_Symbol,
_Period,
bar_index + 1
);
//
double mHH = GetMarketHighestHigh(
bar_index,
marketLen
);
//
double mLL = GetMarketLowestLow(
bar_index,
marketLen
);
double m2LL = GetMarketLowestLow(
bar_index,
marketLen * 2
);
//
int mHLIdx = iHighest(
_Symbol,
_Period,
MODE_LOW,
marketLen,
bar_index
);
datetime mHLTime = iTime(
_Symbol,
_Period,
mHLIdx
);
double mHL = iHigh(
_Symbol,
_Period,
mHLIdx
);
//
double hlDiff = (mHL - mLL);
double sharpDetectValue = shpDetectMult * _Point;
//
bool isSharpDetected =
// (
// low == mLL
// || MathAbs(mLL - low) < (smoother * _Point)
// )
// &&
// !(
// mLL > m2LL
// && MathAbs(m2LL - mLL) > sharpDetectValue / 2
// )
// &&
(
hlDiff > sharpDetectValue
|| hlDiff > sharpDetectValue - (smoother * _Point)
)
;
//
if (isSharpDetected) {
//
shpLongConds.start = mHLTime;
shpLongConds.stop = barTime;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateSHPLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r, // Risk to Reward ratio ...
const double shpDetectMultiplier // Sharp Detect Multiplier ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateSHPLongConditions(shpDetectMultiplier)) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = 300 * _Point; // risk * r2r;
//
double sl = 0; // ll;
//
// this means Market Lowest Low ...
double shpValue = shpDetectMultiplier * _Point;
if (
reward == 0
|| reward < 20 * _Point
) {
reward = shpValue;
}
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_SHP_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_SHP_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateSHPLongConditions(
const double shpDetectMultiplier
) {
//
double shpDetectValue = shpDetectMultiplier * _Point;
//
bool isConditionsFilled =
shpLongConds.stop != 0
&& shpLongConds.start != 0
&& shpLongConds.stop > shpLongConds.start
;
//
bool isBLFilled = true;
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearSHPLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearSHPLongSignalConditions() {
//
shpLongConds.stop = 0;
shpLongConds.start = 0;
}
//
// Check State for Long Signals ...
bool IsReadyForSHPLongSignals(
const XSignal &signal,
const XState &states[]
) {
//
bool result = false;
//
XStateInfo info = ParseXMAStates(states);
//
int xmaMarketLen = ArraySize(states);
double mHH = GetMarketHighestHigh(0, xmaMarketLen);
double m2HH = GetMarketHighestHigh(0, (int) (xmaMarketLen * 1.5));
//
int lcUpDownTouches = 0;
int cciHundredTouches = 0;
for (int i = 0; i < xmaMarketLen; i++) {
//
double high = iHigh(
_Symbol,
_Period,
i
);
//
double low = iLow(
_Symbol,
_Period,
i
);
//
double up = MathMax(states[i].lc.fast, states[i].lc.slow);
double down = MathMax(states[i].lc.fast, states[i].lc.slow);
//
if (high >= up && low <= down) {
lcUpDownTouches++;
}
//
if (
i < xmaMarketLen - 1
&& i < 10
) {
if (
states[i].cci < 100
&& states[i + 1].cci > 100
) {
cciHundredTouches++;
}
}
}
//
result =
//
true
//
&& states[0].mc.fast > states[0].mc.slow
&& states[0].lc.fast > states[0].lc.slow
//
&& states[0].sc.fast < states[0].sc.slow
&& states[1].sc.fast < states[1].sc.slow
//
&& states[0].marketMiddleage < states[0].sc.fast
&& states[1].marketMiddleage < states[1].sc.fast
&& !(
states[1].sc.fast < states[1].mc.fast
&& states[1].sc.slow < states[1].mc.fast
&& states[1].sc.fast > states[1].mc.slow
&& states[1].sc.slow > states[1].mc.slow
)
&& !(
states[0].marketMiddleage < states[0].mc.fast
&& states[0].marketMiddleage > states[0].mc.slow
)
//
&& mHH != m2HH
&& lcUpDownTouches == 0
&& cciHundredTouches == 0
;
//
return result;
}
//
// END Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,676 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 X Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// X Based Signal Conditions ...
struct XSignalConditions {
datetime startTime;
datetime signalTime;
};
//
static XSignalConditions xLongConds;
static XSignalConditions xShortConds;
//
static bool xCloseLongTrades = false;
static bool xWaitForLongSignals = true;
static datetime xWaitForLongSignalChangeTime;
//
static bool xWaitForShortSignals = true;
static bool xCloseShortTrades = false;
//
bool isLastTrendUp = false;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill Long Signal Conditions ...
void CheckXLongSignalConditions(
const int bar_index,
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
// //
// bool isCrossUnder =
// states[1].osc.fast < states[1].osc.slow
// && !(states[2].osc.fast < states[2].osc.slow)
// ;
// //
// bool isCrossOver =
// states[1].osc.fast > states[1].osc.slow
// && !(states[2].osc.fast > states[2].osc.slow)
// ;
//
XOHCL pCandle = GetCandleModel(1);
// //
// bool isTrendingUp =
// pCandle.low > states[0].bnd.high
// && pCandle.high > states[0].bnd.high;
// //
// bool isTrendingDown =
// pCandle.high < states[0].bnd.low
// && pCandle.low < states[0].bnd.low;
//
bool isTrendingUp =
states[1].bnd.open < states[1].bnd.close
&& !(states[2].bnd.open < states[2].bnd.close)
;
//
bool isTrendingDown =
states[1].bnd.open > states[1].bnd.close
&& !(states[2].bnd.open > states[2].bnd.close)
;
//
bool isCrossUnder =
isTrendingDown
&& !isTrendingUp
;
//
bool isCrossOver =
isTrendingUp
&& !isTrendingDown
;
//
// Check Market For Enable/Disable Signal Handlers ...
// Checking Market for Long Signals ...
if (xWaitForLongSignals) {
//
bool isLCFastOnTrendingUpTouchLowestLow =
//
// LC Trending Up ...
states[1].lc.fast > states[1].lc.slow
&& states[2].lc.fast > states[2].lc.slow
//
// LC Fast Touch Market Lowest Low ...
&& states[1].lc.fast > states[1].mkt.lowestLow
&& !(states[2].lc.fast > states[2].mkt.lowestLow)
;
//
bool isMCSlowCrossOverBNDHigh =
states[1].mc.fast > states[1].mc.slow
&& states[1].mc.slow > states[1].bnd.high
&& !(states[2].mc.slow > states[2].bnd.high)
;
//
// Disable Long Trade Handlers ...
if (
isMCSlowCrossOverBNDHigh
|| isLCFastOnTrendingUpTouchLowestLow
) {
//
xWaitForLongSignals = false;
xWaitForLongSignalChangeTime = TimeCurrent();
LogMessage("Disable Long: " + TimeCurrent());
}
} else {
//
bool isAllTrendingUp =
//
// SC ...
states[1].sc.fast > states[1].sc.slow
//
// MC ...
&& states[1].mc.fast > states[1].mc.slow
&& !(states[2].mc.fast > states[2].mc.slow)
//
// LC ...
&& states[1].lc.fast > states[1].lc.slow
;
//
int lastWaitChangeBarIndex = iBarShift(
_Symbol,
_Period,
xWaitForLongSignalChangeTime
);
//
// Enable Long Trade Handlers ...
if (
isAllTrendingUp
&& lastWaitChangeBarIndex - bar_index >= marketLen
) {
xWaitForLongSignals = true;
LogMessage("Enable Long: " + TimeCurrent());
}
}
//
if (
isCrossUnder
&& xLongConds.startTime == 0
) {
//
xLongConds.startTime = barTime;
return;
}
//
if (
isCrossOver
&& xLongConds.startTime > 0
&& xLongConds.signalTime == 0
) {
//
xLongConds.signalTime = barTime;
return;
}
}
//
// Check and Fill Short Signal Conditions ...
void CheckXShortSignalConditions(
const int bar_index,
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
bool isCrossUnder =
states[1].osc.fast < states[1].osc.slow
&& !(states[2].osc.fast < states[2].osc.slow)
;
//
bool isCrossOver =
states[1].osc.fast > states[1].osc.slow
&& !(states[2].osc.fast > states[2].osc.slow)
;
//
if (
isCrossOver
&& xShortConds.startTime == 0
) {
//
xShortConds.startTime = barTime;
return;
}
//
if (
isCrossUnder
&& xShortConds.startTime > 0
&& xShortConds.signalTime == 0
) {
//
xShortConds.signalTime = barTime;
return;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateXSignal(
const ENUM_X_SIGNAL_TYPE type, // Signal Type ...
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r, // Risk to Reward ratio ...
const XState &states[],
//
const double smoother = 5
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
bool requestLong = type == X_SIGNAL_LONG;
//
if (requestLong) {
//
if (
!ValidateXLongConditions(
marketLen,
states,
smoother
)
) {
return result;
}
} else {
//
if (
!ValidateXShortConditions(
marketLen,
states,
smoother
)
) {
return result;
}
}
//
// Price Calculations ...
//
RefreshRates();
//
double askPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double bidPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double entryPrice = requestLong ?
askPrice :
bidPrice;
//
double exitPrice = requestLong ?
bidPrice :
askPrice;
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double hh =
GetMarketHighestHigh(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = requestLong ?
MathMin(openPrice, closePrice) - ll :
hh - MathMax(openPrice, closePrice);
double reward = risk * r2r; // risk * r2r; // 300 * _Point;
// if (risk > (500 * _Point)) {
// reward = 300 * _Point;
// }
//
double sl = 0; // ll;
double tp = requestLong ?
entryPrice + reward :
entryPrice - reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = type;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XXX_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = type;
result.provider = X_XXX_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateXLongConditions(
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
bool isConditionsFilled =
xLongConds.startTime > 0
&& xLongConds.signalTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
xLongConds.startTime
);
//
int signalBarIndex = iBarShift(
_Symbol,
_Period,
xLongConds.signalTime
);
//
isBLFilled =
//
xLongConds.signalTime > xLongConds.startTime
&& MathAbs(signalBarIndex - startBarIndex) > 2
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
&& xWaitForLongSignals
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXLongSignalConditions();
}
//
return result;
}
bool ValidateXShortConditions(
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
bool isConditionsFilled =
xShortConds.startTime > 0
&& xShortConds.signalTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
xShortConds.startTime
);
//
int signalBarIndex = iBarShift(
_Symbol,
_Period,
xShortConds.signalTime
);
//
isBLFilled =
//
xShortConds.signalTime > xShortConds.startTime
&& MathAbs(signalBarIndex - startBarIndex) > 2
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
&& xWaitForLongSignals
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXShortSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXLongSignalConditions() {
//
xLongConds.startTime = 0;
xLongConds.signalTime = 0;
}
//
// Clear Short Signal Conditions for New One ...
void ClearXShortSignalConditions() {
//
xShortConds.startTime = 0;
xShortConds.signalTime = 0;
}
//
// Check State for Long Signals ...
bool IsReadyForXSignals(
const XSignal &signal,
const XState &states[],
const int marketLen,
//
double smoother = 100
) {
//
bool result = false;
//
bool isSCTrendUp =
states[1].sc.fast > states[1].sc.slow
&& states[2].sc.fast > states[2].sc.slow;
// //
// bool isSCTrendDown =
// states[1].sc.fast < states[1].sc.slow
// && states[2].sc.fast < states[2].sc.slow;
//
bool isMCTrendUp =
states[1].mc.fast > states[1].mc.slow
&& states[2].mc.fast > states[2].mc.slow;
// //
// bool isMCTrendDown =
// states[1].mc.fast < states[1].mc.slow
// && states[2].mc.fast < states[2].mc.slow;
//
bool isLCTrendUp =
states[1].lc.fast > states[1].lc.slow
&& states[2].lc.fast > states[2].lc.slow;
// //
// bool isLCTrendDown =
// states[1].lc.fast < states[1].lc.slow
// && states[2].lc.fast < states[2].lc.slow;
// //
// bool isTrendingUp =
// pCandle.low > states[0].bnd.high
// && pCandle.high > states[0].bnd.high;
// //
// bool isTrendingDown =
// pCandle.high < states[0].bnd.low
// && pCandle.low < states[0].bnd.low;
// //
// if (isTrendingUp && !isTrendingDown) {
// isLastTrendUp = true;
// } else if (isTrendingDown && !isTrendingUp) {
// isLastTrendUp = false;
// }
// //
// if (isLastTrendUp) {
// //
// LogMessage(
// StringConcatenate(
// "isLastTrendUp: ", isLastTrendUp
// )
// );
// }
//
XOHCL pCandle = GetCandleModel(1);
//
// Verify Long Signals ...
if (signal.type == X_SIGNAL_LONG) {
//
result =
//
true
//
&& isSCTrendUp
&& isMCTrendUp
&& isLCTrendUp
//
&&
(
pCandle.high < states[1].longCycleHighestHigh
&& !(MathAbs(states[1].longCycleHighestHigh - pCandle.high) < 20 * _Point)
)
//
&& (
states[1].lc.fast > states[1].mc.fast
&& states[1].lc.slow > states[1].mc.fast
?
states[1].lc.slow < states[1].mkt.lowestLow
:
true
)
//
// && signal.entry <= states[1].mkt.highestOpen
// //
// && (
// (
// states[1].mc.slow < states[1].bnd.low
// && states[1].mc.fast < MathMin(states[1].bnd.open, states[1].bnd.close)
// ) || (
// states[1].lc.fast > states[1].bnd.low
// && states[1].lc.fast > states[1].mc.fast
// )
// )
// && MathAbs(states[1].mc.fast - states[1].bnd.low) > 50 * _Point
;
} else
//
// Verify Short Signals ...
if (signal.type == X_SIGNAL_SHORT) {
//
result =
false
;
}
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,490 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 XMA Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// XMA Based Signal Conditions ...
struct XMAMCLongSignalConditions {
//
datetime mcFastCrossUnderSlowTime;
double crossUnderMCFast;
double crossUnderMCSlow;
//
datetime mcFastCrossOverSlowTime;
double crossOverMCFast;
double crossOverMCSlow;
//
datetime mcFastBiggerThanCrossUnderSlowTime;
};
//
static XMAMCLongSignalConditions xmaMCLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXMAMCLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult
) {
//
XCycleState mcs[];
int positionsMarketLen = bar_index + marketLen;
//
// Retrieve Bar Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// Resize Arrays ...
ArrayResize(
mcs,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < positionsMarketLen; i++) {
//
XCycleState mc = GetXMAMC(
i,
marketLen,
mcFMult,
mcSMult
);
mcs[index] = mc;
//
index++;
}
//
bool isMCFastCrossUnderSlow =
mcs[0].fast < mcs[0].slow
&& !(mcs[1].fast <= mcs[1].slow)
;
bool isMCFastCrossOverSlow =
mcs[0].fast > mcs[0].slow
&& !(mcs[1].fast >= mcs[1].slow)
;
//
if (
isMCFastCrossUnderSlow
&& xmaMCLongConds.mcFastCrossUnderSlowTime == 0
) {
//
xmaMCLongConds.crossUnderMCFast = mcs[0].fast;
xmaMCLongConds.crossUnderMCSlow = mcs[0].slow;
xmaMCLongConds.mcFastCrossUnderSlowTime = barTime;
return;
}
//
if (
isMCFastCrossUnderSlow
&& xmaMCLongConds.mcFastCrossUnderSlowTime > 0
) {
//
ClearXMAMCLongSignalConditions();
//
xmaMCLongConds.crossUnderMCFast = mcs[0].fast;
xmaMCLongConds.crossUnderMCSlow = mcs[0].slow;
xmaMCLongConds.mcFastCrossUnderSlowTime = barTime;
return;
}
//
if (
isMCFastCrossOverSlow
&& xmaMCLongConds.mcFastCrossUnderSlowTime > 0
&& xmaMCLongConds.mcFastCrossOverSlowTime == 0
) {
//
xmaMCLongConds.crossOverMCFast = mcs[0].fast;
xmaMCLongConds.crossOverMCSlow = mcs[0].slow;
xmaMCLongConds.mcFastCrossOverSlowTime = barTime;
return;
}
//
if (
xmaMCLongConds.mcFastCrossUnderSlowTime > 0
&& xmaMCLongConds.mcFastCrossOverSlowTime > 0
&& mcs[0].fast > xmaMCLongConds.crossUnderMCSlow
&& xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime == 0
) {
//
xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime = barTime;
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXMAMCLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r, // Risk to Reward ratio ...
const double shpDetectMult,
const double smoother = 50
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (
!ValidateXMAMCLongConditions(
marketLen,
shpDetectMult,
smoother
)
) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
3
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r;
//
double sl = 0;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_XMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXMAMCLongConditions(
const int marketLen,
const double shpDetectMult,
const double smoother = 50
) {
//
bool isConditionsFilled =
xmaMCLongConds.crossOverMCSlow > 0
&& xmaMCLongConds.crossOverMCFast > 0
&& xmaMCLongConds.crossUnderMCFast > 0
&& xmaMCLongConds.crossUnderMCSlow > 0
&& xmaMCLongConds.mcFastCrossOverSlowTime != 0
&& xmaMCLongConds.mcFastCrossUnderSlowTime != 0
&& xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime != 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
xmaMCLongConds.mcFastCrossUnderSlowTime
);
//
int crossOverAndBiggerBarIndex = iBarShift(
_Symbol,
_Period,
xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime
);
//
int cycleMarketLen = MathMin(
MathAbs(crossUnderBarIndex - crossOverAndBiggerBarIndex),
marketLen * 2
);
double hh = GetMarketHighestHigh(
crossOverAndBiggerBarIndex,
cycleMarketLen
);
double ll = GetMarketLowestLow(
crossOverAndBiggerBarIndex,
cycleMarketLen
);
//
double high = iHigh(
_Symbol,
_Period,
crossOverAndBiggerBarIndex
);
double pcHigh = iHigh(
_Symbol,
_Period,
crossOverAndBiggerBarIndex + 1
);
//
double diff = (hh - ll);
double shpValue = shpDetectMult * _Point;
//
bool isPriceRegular =
//
true
//
&&
(
diff < shpValue
|| diff < shpValue - (smoother * _Point)
)
&&
!(
high == hh
|| pcHigh == hh
|| MathAbs(hh - high) < (smoother * _Point)
|| MathAbs(hh - pcHigh) < (smoother * _Point)
)
;
//
// LogMessage("Price Regular: " + isPriceRegular);
//
isBLFilled =
isPriceRegular
&& xmaMCLongConds.mcFastCrossUnderSlowTime < xmaMCLongConds.mcFastCrossOverSlowTime
&& xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime >= xmaMCLongConds.mcFastCrossUnderSlowTime
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXMAMCLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXMAMCLongSignalConditions() {
//
xmaMCLongConds.mcFastCrossUnderSlowTime = 0;
xmaMCLongConds.crossUnderMCFast = 0;
xmaMCLongConds.crossUnderMCSlow = 0;
//
xmaMCLongConds.mcFastCrossOverSlowTime = 0;
xmaMCLongConds.crossOverMCFast = 0;
xmaMCLongConds.crossOverMCSlow = 0;
//
xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXMAMCLongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
int countRangedCandles = 0;
bool isMarketRanging = false;
for (int i = 1; i < marketLen; i++) {
//
double high = iHigh(
_Symbol,
_Period,
i
);
//
double low = iLow(
_Symbol,
_Period,
i
);
//
bool isRanging =
//
high > states[i].mc.fast
&& high > states[i].mc.slow
//
&& low < states[i].mc.fast
&& low < states[i].mc.slow
;
if (isRanging) {
countRangedCandles++;
}
}
//
XStateInfo info = ParseXMAStates(states);
double mmSlope = GetSlope(
1,
states[1].marketMiddleage,
2,
states[0].marketMiddleage
);
double mmSlope1 = GetSlope(
1,
states[2].marketMiddleage,
2,
states[1].marketMiddleage
);
double mmSlopeDiff = mmSlope - mmSlope1;
//
isMarketRanging = countRangedCandles > 0;
//
result =
//
true
//
&& mmSlope > 0
&& mmSlope1 > 0
&& mmSlopeDiff > 0
&& !isMarketRanging
&& states[0].marketMiddleage < info.mmMax
;
// if (result) {
// LogMessage("mmSlope: " + mmSlope + ", mmSlope1: " + mmSlope1 + ", Diff: " + mmSlopeDiff);
// }
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,338 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 XMA Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// XMA Based Signal Conditions ...
struct XMAMMLongSignalConditions {
//
datetime crossUnderTime;
//
datetime crossOverTime;
};
//
static XMAMMLongSignalConditions xmaMMLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXMAMMLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult,
//
int lcFMult,
int lcSMult,
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
XState states[];
ArrayResize(
states,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < marketLen; i++) {
//
XState state = GetXState(
i,
marketLen,
//
stp,
mxm,
scFMult,
scSMult,
mcFMult,
mcSMult,
lcFMult,
lcSMult
);
//
states[index] = state;
//
index++;
}
//
bool isCrossUnder =
states[1].marketMiddleage < states[1].sc.fast
&& !(states[2].marketMiddleage < states[2].sc.fast)
;
//
bool isCrossOver =
states[1].marketMiddleage > states[1].sc.fast
&& !(states[2].marketMiddleage > states[2].sc.fast)
;
//
if (
isCrossUnder
&& xmaMMLongConds.crossUnderTime == 0
) {
//
xmaMMLongConds.crossUnderTime = barTime;
return;
}
//
if (
isCrossOver
&& xmaMMLongConds.crossUnderTime > 0
&& xmaMMLongConds.crossOverTime == 0
) {
//
xmaMMLongConds.crossOverTime = barTime;
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXMAMMLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateXMAMMLongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = 300 * _Point; // risk * r2r;
//
double sl = 0; // entryPrice - (300 * _Point); // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_XMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXMAMMLongConditions() {
//
bool isConditionsFilled =
true
&& xmaMMLongConds.crossOverTime > 0
&& xmaMMLongConds.crossUnderTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
xmaMMLongConds.crossOverTime
);
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
xmaMMLongConds.crossUnderTime
);
//
isBLFilled =
true
//
&& (crossUnderBarIndex - crossOverBarIndex) > 5
//
&& xmaMMLongConds.crossOverTime > xmaMMLongConds.crossUnderTime
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXMAMMLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXMAMMLongSignalConditions() {
//
xmaMMLongConds.crossOverTime = 0;
xmaMMLongConds.crossUnderTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXMAMMLongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
result =
//
true
//
// && states[0].parabolicSAR < states[0].marketMiddleage
// && !(
// states[0].parabolicSAR < states[0].mc.fast
// && states[0].parabolicSAR < states[0].mc.slow
// )
//
// && states[0].mc.fast > states[0].mc.slow
//
// && MathAbs(states[0].mc.fast - states[0].mc.slow) > (150 * _Point)
;
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,360 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 XMA Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// XMA Based Signal Conditions ...
struct XMASCLongSignalConditions {
//
datetime scFastCrossUnderSlowTime;
double crossUnderSCFast;
double crossUnderSCSlow;
//
datetime scFastCrossOverSlowTime;
double crossOverSCFast;
double crossOverSCSlow;
//
datetime scFastBiggerThanCrossUnderSlowTime;
};
//
static XMASCLongSignalConditions xmaSCLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXMASCLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult
) {
//
XCycleState scs[];
int positionsMarketLen = bar_index + marketLen;
//
// Retrieve Bar Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// Resize Arrays ...
ArrayResize(
scs,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < positionsMarketLen; i++) {
//
XCycleState sc = GetXMASC(
i,
marketLen,
scFMult,
scSMult
);
scs[index] = sc;
//
index++;
}
//
bool isSCFastCrossUnderSlow =
scs[0].fast < scs[0].slow
&& !(scs[1].fast <= scs[1].slow)
;
bool isSCFastCrossOverSlow =
scs[0].fast > scs[0].slow
&& !(scs[1].fast >= scs[1].slow)
;
//
if (
isSCFastCrossUnderSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime == 0
) {
//
xmaSCLongConds.crossUnderSCFast = scs[0].fast;
xmaSCLongConds.crossUnderSCSlow = scs[0].slow;
xmaSCLongConds.scFastCrossUnderSlowTime = barTime;
return;
}
//
if (
isSCFastCrossOverSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime > 0
&& xmaSCLongConds.scFastCrossOverSlowTime == 0
) {
//
xmaSCLongConds.crossOverSCFast = scs[0].fast;
xmaSCLongConds.crossOverSCSlow = scs[0].slow;
xmaSCLongConds.scFastCrossOverSlowTime = barTime;
return;
}
//
if (
xmaSCLongConds.scFastCrossUnderSlowTime > 0
&& xmaSCLongConds.scFastCrossOverSlowTime > 0
&& scs[0].fast > xmaSCLongConds.crossUnderSCSlow
&& xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime == 0
) {
//
xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime = barTime;
return;
}
//
if (
isSCFastCrossUnderSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime > 0
&& xmaSCLongConds.scFastCrossOverSlowTime > 0
) {
//
ClearXMASCLongSignalConditions();
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXMASCLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
//
// const double shpDetectMultiplier
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateXMASCLongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index + 1
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index + 1
);
// //
// double sharpDetectValue = shpDetectMultiplier * _Point;
// double lowPrice = iLow(
// _Symbol,
// _Period,
// bar_index + 1
// );
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r;
//
double sl = 0;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_XMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXMASCLongConditions() {
//
bool isConditionsFilled =
xmaSCLongConds.crossOverSCSlow > 0
&& xmaSCLongConds.crossOverSCFast > 0
&& xmaSCLongConds.crossUnderSCFast > 0
&& xmaSCLongConds.crossUnderSCSlow > 0
&& xmaSCLongConds.scFastCrossOverSlowTime != 0
&& xmaSCLongConds.scFastCrossUnderSlowTime != 0
&& xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime !=0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
isBLFilled =
xmaSCLongConds.crossOverSCFast > xmaSCLongConds.crossUnderSCSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime < xmaSCLongConds.scFastCrossOverSlowTime
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXMASCLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXMASCLongSignalConditions() {
//
xmaSCLongConds.crossUnderSCFast = 0;
xmaSCLongConds.crossUnderSCSlow = 0;
xmaSCLongConds.scFastCrossUnderSlowTime = 0;
//
xmaSCLongConds.crossOverSCFast = 0;
xmaSCLongConds.crossOverSCSlow = 0;
xmaSCLongConds.scFastCrossOverSlowTime = 0;
//
xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXMASCLongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
result =
//
true
//
&& states[0].sc.fast > states[0].sc.slow
&& states[1].sc.fast > states[1].sc.slow
;
//
return result;
}
//
// END Functions ...
//
+780
View File
@@ -0,0 +1,780 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XST Strategy Expert Advisor
// ---------------------------------------------
// saherelm implementation of strategy expert advisor ...
// in this EA, we try to combine multiple tools, to ashive best
// results ...
//
// ShortName: XST
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
// +989121694056
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XST Strategy Expert Advisor"
#property strict
//
// START Inputs ...
//
//
// Signal Prefixe ...
input string signalPrefix = "XST"; // Signal Prefix
//
// Signal Draw Specifications ...
input string bullishSignalLabel = "X_BUY"; // Bullish Signal Label
input color bullishSignalColor = clrAqua; // Bullish Signal Color
//
input string bearishSignalLabel = "X_SELL"; // Bearish Signal Label
input color bearishSignalColor = clrFuchsia; // Bearish Signal Color
//
input 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 = 1.5; // Risk to Reward Ratio
// input double maxTPMultiplier = 1000; // Max Allowed TP
//
// 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.05; // Maximum DrawDown Per Trade
input double minBalancePercent = 0.5; // Minimum Balance for Trading
input double maxEquityPercent = 0.1; // Maximum Trade Equity
input int closeAllOpenTradesAfterCandle = 408; // Close All Open Trades After Passed Candles
input bool closeAllInProfitOpenTradesWhenMaxOpenTradesReached = false; // Close All In Profit Open Trades When Max Open Trades Reached and New Signal Income
//
// Indicators ...
//
// CCI Inputs ...
input double step = 0.01; // SAR Step
input double maximum = 0.1; // SAR Maximum
//
// XMA Inputs ...
//
input int shortCycleFastMultiplier = 2; // Short Cycle Fast Multiplier
input int shortCycleSlowMultiplier = 4; // Short Cycle Slow Multiplier
input int mediumCycleFastMultiplier = 6; // Medium Cycle Fast Multiplier
input int mediumCycleSlowMultiplier = 12; // Medium Cycle Slow Multiplier
input int longCycleFastMultiplier = 36; // Long Cycle Fast Multiplier
input int longCycleSlowMultiplier = 72; // Long Cycle Slow Multiplier
//
// SHPD Indicator ...
input double sharpDetectMultiplier = 800; // Sharp Detect Multiplier
//
// 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.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
//
// XMA ...
//
// Validate Short Cycle ...
|| shortCycleFastMultiplier <= 0
|| shortCycleSlowMultiplier <= 0
|| shortCycleFastMultiplier >= shortCycleSlowMultiplier
//
// Validate Medium Cycle ...
|| mediumCycleFastMultiplier <= 0
|| mediumCycleSlowMultiplier <= 0
|| mediumCycleFastMultiplier >= mediumCycleSlowMultiplier
//
// Validate Long Cycle ...
|| longCycleFastMultiplier <= 0
|| longCycleSlowMultiplier <= 0
|| longCycleFastMultiplier >= longCycleSlowMultiplier
//
// Validate Series of Multipliers ...
|| shortCycleFastMultiplier >= mediumCycleFastMultiplier
|| mediumCycleFastMultiplier >= longCycleFastMultiplier
;
//
if (inputsNotValiid) {
return INIT_PARAMETERS_INCORRECT;
}
//
totalSignals = 0;
totalLongSignals = 0;
totalShortSignals = 0;
//
initialBalance = 0;
//
// START Define Array Series ...
//
//
// END Define Array Series ...
//
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XST";
// //
// // Set Event Timer on One Seccond ...
// bool isEventSet = EventSetTimer(1);
// if (!isEventSet) {
// LogMessage("Error: " + GetLastError());
// return INIT_FAILED;
// }
//
ClearSignalConditions();
//
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason) {
//
// Killing Event Timer ...
EventKillTimer();
}
//
// Ticker Event Handler ...
void OnTick() {
//
isNewDay = IsNewDay();
if (isNewDay) {
//
LogMessage(
StringConcatenate(
"New Day: ", TimeCurrent()
)
);
}
//
// Process Signals to Open Positions ...
ProcessSignals();
//
// Checking State for Signal Handling ...
CheckState();
//
// Process Open Positions for Trailing Stop Loss or Close ...
ProcessOpenPositions();
}
//
// Timer Event Handler ...
void OnTimer() {
//
CheckState();
//
ProcessOpenPositions();
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Check State for Signal Handling ...
void CheckState() {
//
// Here we Must to Check Market State for enable or disable
// Signal Handlers and also make dection to close all long/short
// trades ...
// //
// closeLongTrades = xCloseLongTrades;
// waitForLongSignals = xWaitForLongSignals;
// //
// closeShortTrades = xCloseShortTrades;
// waitForShortSignals = xWaitForShortSignals;
// //
// xCloseLongTrades = false;
// xCloseShortTrades = false;
}
//
// Calculate Signals and Process Based on Exists Signals ...
void ProcessSignals() {
//
XSignalRequest request = {};
request.type = X_SIGNAL_NONE;
request.hasSignal = false;
//
// Prevent Multiple Calculating on Same Bars ...
isNewBar = IsNewBar();
if (isNewBar) {
countedBars++;
}
//
if (countedBars < longCycleSlowMultiplier * marketLength) {
return;
}
//
bool allowDoTrade = true;
//
// Check Balance ...
if (initialBalance > 0) {
//
// Retrieve Account Balance ...
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double minimumBalanceForTrade =
balance > initialBalance
?
minBalancePercent * balance
:
minBalancePercent * initialBalance;
//
// Retrieve Account Equity ...
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
double maxAllowedEquity = balance - (balance * maxEquityPercent);
//
// Retrieve Free Marigin ...
double freeMargin = AccountFreeMargin();
double maximumMariginRisk = balance - (balance * maxEquityPercent);
//
if (
//
// Do not Open Positions if equity not passed ...
equity < maxAllowedEquity ||
//
// Do not Open Positions if free margin not passed ...
freeMargin <= maximumMariginRisk ||
//
// Do not open positions if balance less than minimum ...
balance <= minimumBalanceForTrade
) {
//
allowDoTrade = false;
// //
// string message = StringConcatenate(
// "Trading Pause => ",
// "Balance: ", balance,
// ", Equity: ", equity,
// ", FreeMargin: ", freeMargin
// );
// //
// LogMessage(message);
// SendAlert(message);
}
}
//
// Retrieve Signal Exists ...
request = GenerateSignal(0);
//
// Prevent doing anything else, if there is no signals ...
if (
!allowDoTrade ||
!request.hasSignal ||
request.type == X_SIGNAL_NONE
) {
return;
}
//
bool hasLongSignal = request.type == X_SIGNAL_LONG;
//
// Check For Bot State ...
if (
(hasLongSignal && !waitForLongSignals)
|| (!hasLongSignal && !waitForShortSignals)
) {
//
// Clear Signal Conditions ...
if (hasLongSignal) {
ClearLongSignalConditions();
} else {
ClearShortSignalConditions();
}
//
return;
}
//
// Check last Signalled Bar with Counted Bars ...
// Prevent Multiple Signalling on Same Bar ...
bool isInLastSignalledBars = false;
for (int i=0; i < marketLength; i++) {
//
isInLastSignalledBars =
isInLastSignalledBars
|| lastSignalledBar == countedBars - i
;
}
if (isInLastSignalledBars) {
//
// Clear Signal Conditions ...
if (hasLongSignal) {
ClearLongSignalConditions();
} else {
ClearShortSignalConditions();
}
//
return;
}
//
// increase last signalled bar ...
lastSignalledBar = countedBars;
//
// Calculate Can Trade or not ...
allowDoTrade = allowTrade
&& (
hasLongSignal ?
allowLongTrades :
allowShortTrades
);
//
// Chack Maximum Open Positions ...
int openTrades = CountOpenTrades();
if (maxOpenTrades > 0) {
//
if (openTrades >= maxOpenTrades) {
//
allowDoTrade = false;
//
if (closeAllInProfitOpenTradesWhenMaxOpenTradesReached) {
//
// Close All In Profit Trades ...
bool hasClosedInProfitTrade = CloseAllInProfitTrades();
if (hasClosedInProfitTrade) {
//
openTrades = CountOpenTrades();
//
allowDoTrade = !(openTrades >= maxOpenTrades);
}
}
//
if (!allowDoTrade) {
//
string message = StringConcatenate(
"Trading Pause => ",
"Max Open Trades (",
maxOpenTrades,
") reached ..."
);
//
LogMessage(message);
SendAlert(message);
}
}
}
//
// Check Trading is Enable or not ...
// nothing to do if trading is disabled ...
if (!allowDoTrade) {
//
// Clear Signal Conditions ...
if (hasLongSignal) {
ClearLongSignalConditions();
} else {
ClearShortSignalConditions();
}
// //
// string message = StringConcatenate(
// "Trading Not Allowed ..."
// );
// //
// LogMessage(message);
// SendAlert(message);
return;
}
//
bool isPositionOpened = TradeSignal(
request.signal,
signalPrefix,
lotsPerTradePercent,
//
bullishSignalLabel,
bullishSignalColor,
bearishSignalLabel,
bearishSignalColor
);
//
totalSignals++;
if (hasLongSignal) {
//
totalLongSignals++;
ClearLongSignalConditions();
} else {
//
totalShortSignals++;
ClearShortSignalConditions();
}
//
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.entry,
", TP: ", request.signal.tp
);
//
// Terminal Alert ...
if (terminalAlert) {
Alert(message);
}
//
// Push Alert ...
if (pushAlert) {
SendNotification(message);
}
}
}
}
//
// Process All Open Positions ...
void ProcessOpenPositions() {
//
// this comes from check state ...
if (closeLongTrades) {
//
closeLongTrades = false;
//
bool isAllLongTradesClosed = CloseAllLongTrades();
if (isAllLongTradesClosed) {
}
}
//
// this comes from check state ...
if (closeShortTrades) {
//
closeShortTrades = false;
//
bool isAllShortTradesClosed = CloseAllShortTrades();
if (isAllShortTradesClosed) {
}
}
//
bool hasClosedLongTimeTrade = CloseAllLongTimeTrades(
closeAllOpenTradesAfterCandle
);
//
// Close Maximum DrawDown Passed Trades ...
bool hasClosedInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades(
maxDrawdownPercentPerPTrade
);
//
if (
hasClosedLongTimeTrade
|| hasClosedInDrawDownLongTrade
) {
//
// waitForLongSignals = 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 ...
//
//
//
// Calculate Signal ...
// in this function we calculate a signal exists in
// specific bar or not ...
XSignalRequest GenerateSignal(
const int bar_index // Bar Index ...
) {
//
// create temp result ...
XSignalRequest result = {};
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
bool hasSignal = false;
bool hasLongSignal = false;
bool hasShortSignal = false;
//
XSignal signal = {};
//
// Retrieve XMA States ...
// based on medium cycle slow ...
XState states[];
ArrayFree(states);
ArrayResize(
states,
marketLength
);
//
int index = 0;
for (int i = bar_index; i < bar_index + marketLength; i++) {
//
states[index] = GetXState(
i,
marketLength,
//
step,
maximum,
//
shortCycleFastMultiplier,
shortCycleSlowMultiplier,
mediumCycleFastMultiplier,
mediumCycleSlowMultiplier,
longCycleFastMultiplier,
longCycleSlowMultiplier
);
//
index++;
}
//
CheckXLongSignalConditions(
bar_index,
marketLength,
states
);
//
CheckXShortSignalConditions(
bar_index,
marketLength,
states
);
//
XSignalRequest xLongSignalRequest = GenerateXSignal(
X_SIGNAL_LONG,
bar_index,
marketLength,
riskToRewardRatio,
states
);
//
XSignalRequest xShortSignalRequest = GenerateXSignal(
X_SIGNAL_SHORT,
bar_index,
marketLength,
riskToRewardRatio,
states
);
//
if (xLongSignalRequest.hasSignal) {
//
// Here we can Check and Filter Signals Based On State ...
bool isReady = IsReadyForXSignals(
xLongSignalRequest.signal,
states,
marketLength
);
//
if (isReady) {
//
hasLongSignal = true;
signal = xLongSignalRequest.signal;
} else {
ClearXLongSignalConditions();
}
} else if (xShortSignalRequest.hasSignal) {
//
// Here we can Check and Filter Signals Based On State ...
bool isReady = IsReadyForXSignals(
xShortSignalRequest.signal,
states,
marketLength
);
//
if (isReady) {
//
hasShortSignal = true;
signal = xShortSignalRequest.signal;
} else {
ClearXShortSignalConditions();
}
}
//
hasSignal = hasLongSignal || hasShortSignal;
//
if (!hasSignal) {
//
signal.type = X_SIGNAL_NONE;
result.type = X_SIGNAL_NONE;
}
//
// Normalize TP, SL and Entry Price ...
signal.tp = NormalizeDouble(signal.tp, _Digits);
signal.sl = NormalizeDouble(signal.sl, _Digits);
signal.entry = NormalizeDouble(signal.entry, _Digits);
//
result.signal = signal;
result.type = signal.type;
result.hasSignal = hasSignal;
result.provider = signal.provider;
//
// Return Result ...
return result;
}
@@ -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,257 @@
/////////////////////////////////////////////////////////////////
//
// 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 2
//
// also we have 2 line for draw on this indicator ...
#property indicator_plots 2
//
// 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
//
// 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
//
double fastOSCBuffer[];
double slowOSCBuffer[];
//
// 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);
//
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;
}
//
// 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,402 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XSHPD 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 XSHPD Indicator"
#property strict
//
// START Inputs ...
//
input int marketLength = 7; // Market Length ...
input double sharpDetectMultiplier = 70; // Sharp Detect Multiplier
//
input bool drawLabels = true; // Draw Labels on Founded Sharps
//
input string sharpBullishLabel = "SH_BULL"; // Sharp Bullish Label
input color sharpBullishColor = clrAqua; // Sharp Bullish color
//
input string sharpBearishLabel = "SH_BEAR"; // Sharp Bearish Label
input color sharpBearishColor = clrFuchsia; // Sharp Bearish color
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 4
//
// Declare Buffers ...
#define marketHighestHighBufferIndex 0
#define marketLowestLowBufferIndex 1
#define sharpBullishBufferIndex 2
#define sharpBearishBufferIndex 3
//
double marketHighestHighBuffer[];
double marketLowestLowBuffer[];
double sharpBullishBuffer[];
double sharpBearishBuffer[];
//
#include "../Libraries/x-saherelm.lib.mq4"
#include "../Libraries/x-saherelm.draw.lib.mq4"
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
if (
marketLength <= 0
) {
return INIT_PARAMETERS_INCORRECT;
}
//
enableLogging = true;
//
logTag = "X_SHPD";
//
// Highest High ...
SetIndexLabel(marketHighestHighBufferIndex, "");
SetIndexBuffer(marketHighestHighBufferIndex, marketHighestHighBuffer);
SetIndexStyle(
marketHighestHighBufferIndex,
DRAW_LINE, // DRAW_NONE,
STYLE_DOT,
1, // 0,
clrAqua // clrNONE
);
//
// Lowest Low ...
SetIndexLabel(marketLowestLowBufferIndex, "");
SetIndexBuffer(marketLowestLowBufferIndex, marketLowestLowBuffer);
SetIndexStyle(
marketLowestLowBufferIndex,
DRAW_NONE,
STYLE_DOT,
0,
clrNONE
);
//
// Sharp Bullish Buffer ...
SetIndexLabel(sharpBullishBufferIndex, "");
SetIndexBuffer(sharpBullishBufferIndex, sharpBullishBuffer);
SetIndexStyle(
sharpBullishBufferIndex,
DRAW_NONE,
STYLE_DOT,
0,
clrNONE
);
//
// Sharp Bearish Buffer ...
SetIndexLabel(sharpBearishBufferIndex, "");
SetIndexBuffer(sharpBearishBufferIndex, sharpBearishBuffer);
SetIndexStyle(
sharpBearishBufferIndex,
DRAW_NONE,
STYLE_DOT,
0,
clrNONE
);
//
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason) {
//
RemoveDraws(logTag);
}
//
// 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, marketLength);
//
// 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 Sharp ...
CalculateSharp(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculating Sharp ...
void CalculateSharp(
const int &bar_index
) {
//
int index = 0;
//
double high = iHigh(
_Symbol,
_Period,
bar_index + 1
);
//
double low = iLow(
_Symbol,
_Period,
bar_index + 1
);
//
double open = iOpen(
_Symbol,
_Period,
bar_index + 1
);
//
double close = iClose(
_Symbol,
_Period,
bar_index + 1
);
//
marketHighestHighBuffer[bar_index] = GetMarketHighestHigh(
bar_index,
marketLength
);
//
marketLowestLowBuffer[bar_index] = GetMarketLowestLow(
bar_index,
marketLength
);
//
double maHHs[];
ArrayResize(
maHHs,
marketLength
);
//
double maLLs[];
ArrayResize(
maLLs,
marketLength
);
//
index = 0;
for (int i = bar_index; i < bar_index + marketLength; i++) {
//
maLLs[index] = marketLowestLowBuffer[i];
maHHs[index] = marketHighestHighBuffer[i];
//
index++;
}
//
int maxHighIdx = ArrayMaximum(maHHs);
double maxHigh = maHHs[maxHighIdx];
//
int minHighIdx = ArrayMinimum(maHHs);
double minHigh = maHHs[minHighIdx];
//
double highDiffRate = (maxHigh - minHigh) / 100;
//
int maxLowIdx = ArrayMaximum(maLLs);
double maxLow = maLLs[maxLowIdx];
//
int minLowIdx = ArrayMinimum(maLLs);
double minLow = maLLs[minLowIdx];
//
double lowDiffRate = (maxLow - minLow) / 100;
//
bool isSharpBullishDetected =
high == maxHigh
&& low > minLow
&& marketHighestHighBuffer[bar_index] == maxHigh
&& maxHigh - minHigh > highDiffRate * sharpDetectMultiplier
;
sharpBullishBuffer[bar_index] = isSharpBullishDetected ? 1 : 0;
//
bool isSharpBearishDetected =
low == minLow
&& high < maxHigh
&& marketLowestLowBuffer[bar_index] == minLow
&& maxLow - minLow > lowDiffRate * sharpDetectMultiplier
;
sharpBearishBuffer[bar_index] = isSharpBearishDetected ? 1 : 0;
//
if (
drawLabels
&& (
isSharpBearishDetected
|| isSharpBullishDetected
)
) {
//
datetime time = iTime(
_Symbol,
_Period,
bar_index
);
//
string lbl = StringConcatenate(
logTag,
isSharpBullishDetected ? "Bullish_" : "Bearish_",
bar_index
);
//
double price =
isSharpBullishDetected
?
marketLowestLowBuffer[bar_index] - (10 * _Point)
:
marketHighestHighBuffer[bar_index] + (10 * _Point)
;
//
uchar arrowCode =
isSharpBullishDetected
?
SYMBOL_ARROWUP
:
SYMBOL_ARROWDOWN
;
//
ENUM_ARROW_ANCHOR anchor =
isSharpBullishDetected
?
ANCHOR_BOTTOM
:
ANCHOR_TOP
;
//
color clr =
isSharpBullishDetected
?
sharpBullishColor
:
sharpBearishColor
;
//
string lblText =
isSharpBullishDetected
?
sharpBullishLabel
:
sharpBearishLabel
;
//
DrawText(
0,
lbl,
0,
time,
price,
lblText,
"Tahoma",
5,
clr
);
}
}
//
// END Functions ...
//
@@ -0,0 +1,250 @@
///////////////////////////////////////////////////////
//
// 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
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
#property indicator_chart_window
//
// #property indicator_buffers 3
//
// Declare Buffers ...
//
datetime startTime;
double lHigh;
double lLow;
//
datetime highTimes[];
//
datetime lowTimes[];
//
// 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;
}
//
// 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 ...
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
startTime
);
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
if (startTime == 0) {
//
startTime = barTime;
return;
}
//
if (
startTime > 0
&& startBarIndex - bar_index == length
) {
//
int hhIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
length,
bar_index
);
datetime hhTime = iTime(
_Symbol,
_Period,
hhIdx
);
double hh = iHigh(
_Symbol,
_Period,
hhIdx
);
//
int hhSize = ArraySize(highTimes);
datetime tempTimes[];
ArrayResize(
tempTimes,
hhSize
);
ArrayCopy(
tempTimes,
highTimes
);
ArrayResize(
highTimes,
hhSize + 1
);
highTimes[0] = hhTime;
ArrayCopy(
highTimes,
tempTimes,
1
);
//
int llIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
length,
bar_index
);
datetime llTime = iTime(
_Symbol,
_Period,
llIdx
);
double ll = iLow(
_Symbol,
_Period,
llIdx
);
//
int llSize = ArraySize(lowTimes);
ArrayFree(tempTimes);
ArrayResize(
tempTimes,
llSize
);
ArrayCopy(
tempTimes,
lowTimes
);
ArrayResize(
lowTimes,
llSize + 1
);
lowTimes[0] = llTime;
ArrayCopy(
lowTimes,
tempTimes,
1
);
//
startTime = 0;
ArrayFree(tempTimes);
}
}
//
// END Functions ...
//
@@ -0,0 +1,422 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XBand Indicator
// ---------------------------------------------
// saherelm implementation of xBand Indicator ...
//
// 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 XBND Indicator"
#property strict
//
#include "../Libraries/x-saherelm.lib.mq4"
#include "../Libraries/x-saherelm.draw.lib.mq4"
//
// START Inputs ...
//
input int marketLength = 5; // Averaging Length
input int ignoreLastCross = 4; // Ignore Last Cross
input int shift = 0; // Averaging Shift
input ENUM_MA_METHOD method = MODE_SMA; // Averaging Mode
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
#property indicator_chart_window
//
#property indicator_buffers 4
//
// Declare Buffers ...
//
// High ...
#property indicator_width1 1
#property indicator_color1 clrAqua
#property indicator_type1 DRAW_LINE
#property indicator_style1 STYLE_DASHDOT
//
// Open ...
#property indicator_width2 1
#property indicator_color2 clrGreen
#property indicator_type2 DRAW_LINE
#property indicator_style2 STYLE_DASH
//
// Close ...
#property indicator_width3 1
#property indicator_color3 clrRed
#property indicator_type3 DRAW_LINE
#property indicator_style3 STYLE_DASH
//
// Low ...
#property indicator_width4 1
#property indicator_color4 clrFuchsia
#property indicator_type4 DRAW_LINE
#property indicator_style4 STYLE_DASHDOT
//
#define highBufferIndex 0
#define openBufferIndex 1
#define closeBufferIndex 2
#define lowBufferIndex 3
//
double highBuffer[];
double openBuffer[];
double closeBuffer[];
double lowBuffer[];
//
datetime lastCrossTime;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
//
// Validating Input Parameters ...
if (marketLength < 5) {
return INIT_PARAMETERS_INCORRECT;
}
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XBND";
//
// High ...
string highLabel = StringConcatenate(
"High(", marketLength, ")"
);
SetIndexBuffer(highBufferIndex, highBuffer);
SetIndexLabel(highBufferIndex, highLabel);
//
// Open ...
string openLabel = StringConcatenate(
"Open(", marketLength, ")"
);
SetIndexBuffer(openBufferIndex, openBuffer);
SetIndexLabel(openBufferIndex, openLabel);
//
// Close ...
string closeLabel = StringConcatenate(
"Close(", marketLength, ")"
);
SetIndexBuffer(closeBufferIndex, closeBuffer);
SetIndexLabel(closeBufferIndex, closeLabel);
//
// Low ...
string lowLabel = StringConcatenate(
"Low(", marketLength, ")"
);
SetIndexBuffer(lowBufferIndex, lowBuffer);
SetIndexLabel(lowBufferIndex, lowLabel);
//
// 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(0, marketLength);
//
// 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 Buffers ...
CalculateBuffers(i);
//
// Calculate Market Changes ...
CalculateInfo(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
void CalculateBuffers(
const int bar_index
) {
//
// High ...
double high = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_HIGH,
bar_index
);
//
highBuffer[bar_index] = high;
//
// Open ...
double open = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_OPEN,
bar_index
);
//
openBuffer[bar_index] = open;
//
// Close ...
double close = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_CLOSE,
bar_index
);
//
closeBuffer[bar_index] = close;
//
// Low ...
double low = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_LOW,
bar_index
);
//
lowBuffer[bar_index] = low;
}
//
void CalculateInfo(
const int bar_index
) {
//
XOHCL pCandle = GetCandleModel(bar_index);
//
bool isTrendingUp =
pCandle.low > highBuffer[bar_index]
&& pCandle.high > highBuffer[bar_index];
//
bool isTrendingDown =
pCandle.high < lowBuffer[bar_index]
&& pCandle.low < lowBuffer[bar_index];
//
bool isOpenCrossOverClose =
true
&&
(
pCandle.high > highBuffer[bar_index + 1]
|| pCandle.low < lowBuffer[bar_index + 1]
)
&& openBuffer[bar_index + 1] > closeBuffer[bar_index + 1]
&& !(openBuffer[bar_index + 2] >= closeBuffer[bar_index + 2])
;
//
bool isOpenCrossUnderClose =
true
&&
(
pCandle.high > highBuffer[bar_index + 1]
|| pCandle.low < lowBuffer[bar_index + 1]
)
&& openBuffer[bar_index + 1] < closeBuffer[bar_index + 1]
&& !(openBuffer[bar_index + 2] <= closeBuffer[bar_index + 2])
;
//
isTrendingUp = isOpenCrossUnderClose;
isTrendingDown = isOpenCrossOverClose;
//
datetime time = iTime(
_Symbol,
_Period,
bar_index
);
//
if (
isTrendingUp
|| isTrendingDown
) {
//
if (lastCrossTime == 0) {
lastCrossTime = time;
} else {
//
int lastCrossBarIndex = iBarShift(
_Symbol,
_Period,
lastCrossTime
);
//
int diff = lastCrossBarIndex - bar_index;
if (diff <= ignoreLastCross) {
return;
} else {
lastCrossTime = time;
}
}
}
//
string lbl = StringConcatenate(
logTag,
"_Arrow_",
isTrendingUp ? "UP" : "Down",
"_", time
);
//
color clr = isTrendingUp ?
clrAqua :
clrFuchsia;
//
ENUM_ARROW_ANCHOR anchor = isTrendingUp ?
ANCHOR_BOTTOM :
ANCHOR_TOP;
//
uchar arrowCode = isTrendingUp ?
SYMBOL_ARROWUP :
SYMBOL_ARROWDOWN;
//
double price = isTrendingUp ?
pCandle.low - 20 * _Point :
pCandle.high + 20 * _Point;
//
if (isTrendingUp) {
//
// this means Market Going Up ...
}
//
if (isTrendingDown) {
//
// this means Market Going Downm ...
}
//
if (
isTrendingUp
|| isTrendingDown
) {
//
bool isDrawn = DrawArrow(
0,
lbl,
0,
time,
price,
arrowCode,
anchor,
clr
);
}
}
//
// END Functions ...
//
@@ -0,0 +1,695 @@
///////////////////////////////////////////////////////
//
// 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 ...
//
//
// Market Specifications ...
input int marketLength = 7; // Market Length
input double step = 0.02; // SAR Step
input double maximum = 0.2; // SAR Maximum
//
// Cycle Definitions ...
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 showPSar = true; // Show Parabolic Sar
input bool showMarketMiddle = true; // Show Market Middle
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 pSarColor = clrCornflowerBlue; // Parabolic Sar Color
input color shortCycleFastColor = clrGreen; // Short Cycle Fast Color
input color shortCycleSlowColor = clrRed; // Short Cycle Slow Color
input color mediumCycleFastColor = clrAqua; // Medium Cycle Fast Color
input color mediumCycleSlowColor = clrFuchsia; // Medium Cycle Slow Color
input color longCycleFastColor = clrGoldenrod; // Medium Cycle Fast Color
input color longCycleSlowColor = clrBrown; // Medium Cycle Slow Color
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
// define indicator buffers ...
#property indicator_buffers 8
#property indicator_plots 8
//
// Declare Buffers ...
#define scFastBufferIndex 0
#define scSlowBufferIndex 1
#define mcFastBufferIndex 2
#define mcSlowBufferIndex 3
#define lcFastBufferIndex 4
#define lcSlowBufferIndex 5
#define midBufferIndex 6
#define pSarBufferIndex 7
//
double scFastBuffer[];
double scSlowBuffer[];
double mcFastBuffer[];
double mcSlowBuffer[];
double lcFastBuffer[];
double lcSlowBuffer[];
double midBuffer[];
double pSarBuffer[];
//
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);
SetIndexLabel(midBufferIndex, "Market Mid");
//
// Parabolic Sar ...
SetIndexBuffer(pSarBufferIndex, pSarBuffer);
SetIndexLabel(pSarBufferIndex, "P Sar");
SetIndexStyle(
pSarBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
showPSar ?
pSarColor :
clrNONE
);
//
// Market Middle ...
SetIndexBuffer(midBufferIndex, midBuffer);
SetIndexLabel(midBufferIndex, "Mid");
SetIndexStyle(
midBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
showMarketMiddle ?
clrAntiqueWhite :
clrNONE
);
//
// 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);
//
// Calculate Parabolic Sar ...
CalculateParabolicSar(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 ...
//
}
void CalculateParabolicSar(
const int bar_index
) {
//
double sarValue = iSAR(
NULL,
_Period,
step,
maximum,
bar_index
);
//
pSarBuffer[bar_index] = sarValue;
}
//
// END Functions ...
//
@@ -0,0 +1,394 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XMKT Indicator
// ---------------------------------------------
// retrieve market base info ...
//
// 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 XMKT Indicator"
#property strict
//
// START Inputs ...
//
//
// Market Specifications ...
input int marketLength = 7; // Market Length
//
input bool showHighestHigh = true; // Show Market Highest High
input bool showHighestLow = true; // Show Market Highest Low
input bool showHighestOpen = true; // Show Market Highest Open
input bool showHighestClose = true; // Show Market Highest Close
input bool showLowestHigh = true; // Show Market Lowest High
input bool showLowestLow = true; // Show Market Lowest Low
input bool showLowestOpen = true; // Show Market Lowest Open
input bool showLowestClose = true; // Show Market Lowest Close
//
input color highestHighColor = clrDeepPink; // Market Highest High Color
input color highestLowColor = clrDarkOrange; // Market Highest Low Color
input color highestOpenColor = clrDodgerBlue; // Market Highest Open Color
input color highestCloseColor = clrOrchid; // Market Highest Close Color
input color lowestHighColor = clrHotPink; // Market Lowest High Color
input color lowestLowColor = clrOrange; // Market Lowest Low Color
input color lowestOpenColor = clrPowderBlue; // Market Lowest Open Color
input color lowestCloseColor = clrMediumOrchid; // Market Lowest Close Color
//
input ENUM_LINE_STYLE highestHighStyle = STYLE_DOT; // Market Highest High Line Style
input ENUM_LINE_STYLE highestLowStyle = STYLE_DOT; // Market Highest Low Line Style
input ENUM_LINE_STYLE highestOpenStyle = STYLE_DOT; // Market Highest Open Line Style
input ENUM_LINE_STYLE highestCloseStyle = STYLE_DOT; // Market Highest Close Line Style
input ENUM_LINE_STYLE lowestHighStyle = STYLE_DOT; // Market Lowest High Line Style
input ENUM_LINE_STYLE lowestLowStyle = STYLE_DOT; // Market Lowest Low Line Style
input ENUM_LINE_STYLE lowestOpenStyle = STYLE_DOT; // Market Lowest Open Line Style
input ENUM_LINE_STYLE lowestCloseStyle = STYLE_DOT; // Market Lowest Close Line Style
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
// define indicator buffers ...
#property indicator_buffers 8
#property indicator_plots 8
//
// Declare Buffers ...
#define marketHighestHighBufferIndex 0
#define marketHighestLowBufferIndex 1
#define marketHighestOpenBufferIndex 2
#define marketHighestCloseBufferIndex 3
#define marketLowestHighBufferIndex 4
#define marketLowestLowBufferIndex 5
#define marketLowestOpenBufferIndex 6
#define marketLowestCloseBufferIndex 7
//
double marketHighestHighBuffer[];
double marketHighestLowBuffer[];
double marketHighestOpenBuffer[];
double marketHighestCloseBuffer[];
double marketLowestHighBuffer[];
double marketLowestLowBuffer[];
double marketLowestOpenBuffer[];
double marketLowestCloseBuffer[];
//
// 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 (marketLength <= 0) {
return INIT_PARAMETERS_INCORRECT;
}
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XST_XMKT";
//
// Highest High ...
string highestHighLbl = StringConcatenate("HH(", marketLength,")");
SetIndexLabel(marketHighestHighBufferIndex, highestHighLbl);
SetIndexBuffer(marketHighestHighBufferIndex, marketHighestHighBuffer);
SetIndexStyle(
marketHighestHighBufferIndex,
showHighestHigh ?
DRAW_LINE :
DRAW_NONE,
highestHighStyle,
1,
showHighestHigh ?
highestHighColor :
clrNONE
);
//
// Highest Low ...
string highestLowLbl = StringConcatenate("HL(", marketLength,")");
SetIndexLabel(marketHighestLowBufferIndex, highestLowLbl);
SetIndexBuffer(marketHighestLowBufferIndex, marketHighestLowBuffer);
SetIndexStyle(
marketHighestLowBufferIndex,
showHighestLow ?
DRAW_LINE :
DRAW_NONE,
highestLowStyle,
1,
showHighestLow ?
highestLowColor :
clrNONE
);
//
// Highest Open ...
string highestOpenLbl = StringConcatenate("HO(", marketLength,")");
SetIndexLabel(marketHighestOpenBufferIndex, highestOpenLbl);
SetIndexBuffer(marketHighestOpenBufferIndex, marketHighestOpenBuffer);
SetIndexStyle(
marketHighestOpenBufferIndex,
showHighestOpen ?
DRAW_LINE :
DRAW_NONE,
highestOpenStyle,
1,
showHighestOpen ?
highestOpenColor :
clrNONE
);
//
// Highest Close ...
string highestCloseLbl = StringConcatenate("HC(", marketLength,")");
SetIndexLabel(marketHighestCloseBufferIndex, highestCloseLbl);
SetIndexBuffer(marketHighestCloseBufferIndex, marketHighestCloseBuffer);
SetIndexStyle(
marketHighestCloseBufferIndex,
showHighestClose ?
DRAW_LINE :
DRAW_NONE,
highestCloseStyle,
1,
showHighestClose ?
highestCloseColor :
clrNONE
);
//
// Lowest High ...
string lowestHighLbl = StringConcatenate("LH(", marketLength,")");
SetIndexLabel(marketLowestHighBufferIndex, lowestHighLbl);
SetIndexBuffer(marketLowestHighBufferIndex, marketLowestHighBuffer);
SetIndexStyle(
marketLowestHighBufferIndex,
showLowestHigh ?
DRAW_LINE :
DRAW_NONE,
lowestHighStyle,
1,
showLowestHigh ?
lowestHighColor :
clrNONE
);
//
// Lowest Low ...
string lowestLowLbl = StringConcatenate("LL(", marketLength,")");
SetIndexLabel(marketLowestLowBufferIndex, lowestLowLbl);
SetIndexBuffer(marketLowestLowBufferIndex, marketLowestLowBuffer);
SetIndexStyle(
marketLowestLowBufferIndex,
showLowestLow ?
DRAW_LINE :
DRAW_NONE,
lowestLowStyle,
1,
showLowestLow ?
lowestLowColor :
clrNONE
);
//
// Lowest Open ...
string lowestOpenLbl = StringConcatenate("LO(", marketLength,")");
SetIndexLabel(marketLowestOpenBufferIndex, lowestOpenLbl);
SetIndexBuffer(marketLowestOpenBufferIndex, marketLowestOpenBuffer);
SetIndexStyle(
marketLowestOpenBufferIndex,
showLowestOpen ?
DRAW_LINE :
DRAW_NONE,
lowestOpenStyle,
1,
showLowestOpen ?
lowestOpenColor :
clrNONE
);
//
// Lowest Close ...
string lowestCloseLbl = StringConcatenate("LC(", marketLength,")");
SetIndexLabel(marketLowestCloseBufferIndex, lowestCloseLbl);
SetIndexBuffer(marketLowestCloseBufferIndex, marketLowestCloseBuffer);
SetIndexStyle(
marketLowestCloseBufferIndex,
showLowestClose ?
DRAW_LINE :
DRAW_NONE,
lowestCloseStyle,
1,
showLowestClose ?
lowestCloseColor :
clrNONE
);
//
// 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, 3);
//
// 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 ...
CalculateBuffers(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculate Short Cycle ...
void CalculateBuffers(
const int bar_index
) {
//
// Highest High ...
double highestHighValue = GetMarketHighestHigh(
bar_index,
marketLength
);
marketHighestHighBuffer[bar_index] = highestHighValue;
//
// Highest Low ...
double highestLowValue = GetMarketHighestLow(
bar_index,
marketLength
);
marketHighestLowBuffer[bar_index] = highestLowValue;
//
// Highest Open ...
double highestOpenValue = GetMarketHighestOpen(
bar_index,
marketLength
);
marketHighestOpenBuffer[bar_index] = highestOpenValue;
//
// Highest Close ...
double highestCloseValue = GetMarketHighestClose(
bar_index,
marketLength
);
marketHighestCloseBuffer[bar_index] = highestCloseValue;
//
// Lowest High ...
double lowestHighValue = GetMarketLowestHigh(
bar_index,
marketLength
);
marketLowestHighBuffer[bar_index] = lowestHighValue;
//
// Lowest Low ...
double lowestLowValue = GetMarketLowestLow(
bar_index,
marketLength
);
marketLowestLowBuffer[bar_index] = lowestLowValue;
//
// Lowest Open ...
double lowestOpenValue = GetMarketLowestOpen(
bar_index,
marketLength
);
marketLowestOpenBuffer[bar_index] = lowestOpenValue;
//
// Lowest Close ...
double lowestCloseValue = GetMarketLowestClose(
bar_index,
marketLength
);
marketLowestCloseBuffer[bar_index] = lowestCloseValue;
}
//
// END Functions ...
//
@@ -0,0 +1,221 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XMTR Indicator
// ---------------------------------------------
// retrieve market base info ...
//
// 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 XMKT Indicator"
#property strict
//
// START Inputs ...
//
//
// Market Specifications ...
input int marketLength = 20; // Market Length
input int atrMultiplier = 1; // ATR Multiplier
input int atrLength = 5; // ATR Period
input ENUM_APPLIED_PRICE source = PRICE_CLOSE; // Source
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
// define indicator buffers ...
#property indicator_buffers 3
#property indicator_plots 3
//
// Declare Buffers ...
#define trendBufferIndex 0
#define upTrendBufferIndex 1
#define downTrendBufferIndex 2
//
double trendBuffer[];
double upTrendBuffer[];
double downTrendBuffer[];
//
// 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 (marketLength <= 0) {
return INIT_PARAMETERS_INCORRECT;
}
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XMTR";
//
// TREND ...
SetIndexLabel(trendBufferIndex, "Trend");
SetIndexBuffer(trendBufferIndex, trendBuffer);
SetIndexStyle(
trendBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
clrNONE
);
//
// UP Trend ...
SetIndexLabel(upTrendBufferIndex, "Up Trend");
SetIndexBuffer(upTrendBufferIndex, upTrendBuffer);
SetIndexStyle(
upTrendBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
clrNONE
);
//
// DOWN Trend ...
SetIndexLabel(downTrendBufferIndex, "Down Trend");
SetIndexBuffer(downTrendBufferIndex, downTrendBuffer);
SetIndexStyle(
downTrendBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
clrNONE
);
//
// 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, 3);
//
// 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 ...
CalculateBuffers(
i,
low
);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculate Short Cycle ...
void CalculateBuffers(
const int bar_index,
const double &low[]
) {
//
double atr = GetMarketTRSMA(
bar_index,
atrLength
);
//
double smoothedAtr = (atr * atrMultiplier);
double upTrend = low[bar_index] - smoothedAtr;
double downTrend = low[bar_index] + smoothedAtr;
//
double cciValue = GetMarketCCI(
bar_index,
marketLength,
source
);
//
// TODO: Complete this ...
}
//
// 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 ...
//
@@ -0,0 +1,472 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 CCI Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// Based Signal Conditions ...
struct XCCILongSignalConditions {
//
datetime start;
//
datetime crossOverMinusHundredTime;
datetime crossUnderMinusHundredTime;
//
double crossOverSlope;
};
//
static XCCILongSignalConditions cciLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill Signal Conditions ...
void CheckCCILongSignalConditions(
const int bar_index,
const int marketLen,
//
const double smoother = 10
) {
//
// Retrieve Bar Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// LONG:
// wait for cci cross under -100
// then wait for cross over -100
// slope of crossing over ??? ...
if (cciLongConds.start == 0) {
// LogMessage("Start");
cciLongConds.start = barTime;
return;
}
//
// Check Start Time ...
if (cciLongConds.start == 0) {
return;
}
//
// Read current, prev, and prevPrev CCI ...
double cci = GetMarketCCI(
bar_index,
marketLen
);
double cci1 = GetMarketCCI(
bar_index + 1,
marketLen
);
double cci2 = GetMarketCCI(
bar_index + 2,
marketLen
);
//
// Find Cross Under -100 ...
bool isCrossUnderMinusHundred =
cci < -105 && !(cci1 < -105)
&& MathAbs(MathAbs(cci) - MathAbs(cci1)) > smoother
;
//
// Find Cross Over -100 ...
bool isCrossOverMinusHundred =
cci > -105 && !(cci1 > -105)
&& MathAbs(cci - cci1) > smoother
;
//
// Fill Conditions ...
if (
isCrossUnderMinusHundred
&& cciLongConds.crossUnderMinusHundredTime == 0
&& cciLongConds.crossOverMinusHundredTime == 0
) {
// LogMessage("Cross Under ...");
cciLongConds.crossUnderMinusHundredTime = barTime;
return;
}
//
// Fill Conditions ...
if (
isCrossOverMinusHundred
&& cciLongConds.crossOverMinusHundredTime == 0
&& cciLongConds.crossUnderMinusHundredTime != 0
) {
//
// LogMessage("Cross Over ...");
cciLongConds.crossOverMinusHundredTime = barTime;
}
//
// Prevent Going forward untill Cross Under Happens ...
if (cciLongConds.crossUnderMinusHundredTime == 0) {
return;
}
//
// Prevent from Going forward untill Cross Over Happens ...
if (cciLongConds.crossOverMinusHundredTime == 0) {
return;
}
//
// Calculate Slope ...
double x1 = 0;
double y1 = cci1;
double x2 = 1;
double y2 = cci;
//
// Calculat Line Slope ...
double tSlope = GetSlope(
x1, y1, x2, y2
);
//
cciLongConds.crossOverSlope = tSlope;
// LogMessage("Slope: " + tSlope);
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateCCILongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateCCILongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
int llIdx = GetLowestLowOFCCILongPeriodIndex();
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
// GetLowestLowOFCCILongPeriod();
//
int hhIdx = GetHighestHighOfCCILongPeriodIndex();
double hh = GetHighestHighOfCCILongPeriod();
// GetMarketHighestHigh(
// bar_index,
// marketLen
// );
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r;
//
double sl = 0; // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_CCI_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_CCI_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateCCILongConditions() {
//
int crossUnderBarIndex =
cciLongConds.crossUnderMinusHundredTime != 0
? iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
)
: -1
;
//
int crossOverBarIndex =
cciLongConds.crossOverMinusHundredTime != 0
? iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
)
: -1
;
//
bool isConditionsFilled =
//
cciLongConds.start != 0
&& cciLongConds.crossUnderMinusHundredTime != 0
&& cciLongConds.crossOverMinusHundredTime != 0
&& cciLongConds.crossUnderMinusHundredTime >= cciLongConds.start
&& cciLongConds.crossOverMinusHundredTime > cciLongConds.crossUnderMinusHundredTime
;
//
bool isLogicPassed =
//
crossOverBarIndex > 0
&& crossUnderBarIndex > 0
&& crossUnderBarIndex > crossOverBarIndex
&& (crossUnderBarIndex - crossOverBarIndex) >= 5
;
//
bool result =
//
isConditionsFilled
&& isLogicPassed
&& cciLongConds.crossOverSlope > 0
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearCCILongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearCCILongSignalConditions() {
//
cciLongConds.start = 0;
cciLongConds.crossOverSlope = 0;
cciLongConds.crossOverMinusHundredTime = 0;
cciLongConds.crossUnderMinusHundredTime = 0;
}
//
int GetHighestHighOfCCILongPeriodIndex() {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
);
//
int result = iHighest(
_Symbol,
_Period,
MODE_HIGH,
crossUnderBarIndex - crossOverBarIndex,
crossOverBarIndex
);
//
return result;
}
//
double GetHighestHighOfCCILongPeriod() {
//
int index = GetHighestHighOfCCILongPeriodIndex();
//
double result = iHigh(
_Symbol,
_Period,
index
);
//
return result;
}
//
int GetLowestLowOFCCILongPeriodIndex() {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
);
//
int result = iLowest(
_Symbol,
_Period,
MODE_LOW,
crossUnderBarIndex - crossOverBarIndex,
crossOverBarIndex
);
//
return result;
}
//
double GetLowestLowOFCCILongPeriod() {
//
int index = GetLowestLowOFCCILongPeriodIndex();
//
double result = iLow(
_Symbol,
_Period,
index
);
//
return result;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForCCILongSignals(
const XState &states[]
) {
//
bool result = false;
//
XStateInfo info = ParseXMAStates(states);
//
result =
//
true
//
// && states[1].mc.fast > states[1].mc.slow
// && MathAbs(states[1].mc.fast - states[1].mc.slow) > 100 * _Point
// && states[1].marketMiddleage > states[1].sc.fast
// && states[1].marketMiddleage > states[1].mc.fast
;
//
return result;
}
//
// END Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,941 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 Indicator 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
static double zigZags[];
//
// END Global Requirement Functions ...
//
//
// START Indicator Reading Data ...
//
//
// START XMKT Data ...
//
XMKTState GetXMKT(
const int bar_index,
const int marketLen,
//
const bool showHighestHigh = true,
const bool showHighestLow = true,
const bool showHighestOpen = true,
const bool showHighestClose = true,
const bool showLowestHigh = true,
const bool showLowestLow = true,
const bool showLowestOpen = true,
const bool showLowestClose = true,
const color highestHighColor = clrDeepPink,
const color highestLowColor = clrDarkOrange,
const color highestOpenColor = clrDodgerBlue,
const color highestCloseColor = clrOrchid,
const color lowestHighColor = clrHotPink,
const color lowestLowColor = clrOrange,
const color lowestOpenColor = clrPowderBlue,
const color lowestCloseColor = clrMediumOrchid,
const ENUM_LINE_STYLE highestHighStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestLowStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestOpenStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestCloseStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestHighStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestLowStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestOpenStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestCloseStyle = STYLE_DOT
) {
//
XMKTState result = {};
//
string xmktIndName = "x-saherelm.xmarket";
//
int highestHighBufferIndex = 0;
int highestLowBufferIndex = 1;
int highestOpenBufferIndex = 2;
int highestCloseBufferIndex = 3;
int lowestHighBufferIndex = 4;
int lowestLowBufferIndex = 5;
int lowestOpenBufferIndex = 6;
int lowestCloseBufferIndex = 7;
//
// Highest High ...
double highestHigh = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestHighBufferIndex, // Buffer Index ...
bar_index
);
result.highestHigh = highestHigh;
//
// Highest Low ...
double highestLow = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestLowBufferIndex, // Buffer Index ...
bar_index
);
result.highestLow = highestLow;
//
// Highest Open ...
double highestOpen = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestOpenBufferIndex, // Buffer Index ...
bar_index
);
result.highestOpen = highestOpen;
//
// Highest Close ...
double highestClose = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestCloseBufferIndex, // Buffer Index ...
bar_index
);
result.highestClose = highestClose;
//
// Lowest High ...
double lowestHigh = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestHighBufferIndex, // Buffer Index ...
bar_index
);
result.lowestHigh = lowestHigh;
//
// Lowest Low ...
double lowestLow = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestLowBufferIndex, // Buffer Index ...
bar_index
);
result.lowestLow = lowestLow;
//
// Lowest Open ...
double lowestOpen = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestOpenBufferIndex, // Buffer Index ...
bar_index
);
result.lowestOpen = lowestOpen;
//
// Lowest Close ...
double lowestClose = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestCloseBufferIndex, // Buffer Index ...
bar_index
);
result.lowestClose = lowestClose;
//
return result;
}
//
// END XMKT Data ...
//
//
// START XOSC Data ...
//
XCycleState GetXOSC(
const int bar_index,
const int marketLen,
//
const int fastMult,
const int slowMult,
//
const double fastMMul = 1.0,
const double slowMMul = 3.0
) {
//
XCycleState result = {};
//
string oscIndName = "x-saherelm.osc";
//
// Prepare OSC Inputs ...
//
int fastLength = fastMult * marketLen;
int slowLength = slowMult * marketLen;
//
// Fast ...
double fast = iCustom(
_Symbol,
_Period,
oscIndName,
//
// Inputs ...
fastLength,
fastMMul,
slowLength,
slowMMul,
//
0, // Buffer Index ...
bar_index
);
result.fast = fast;
//
// Slow ...
double slow = iCustom(
_Symbol,
_Period,
oscIndName,
//
// Inputs ...
fastLength,
fastMMul,
slowLength,
slowMMul,
//
1, // Buffer Index ...
bar_index
);
result.slow = slow;
//
return result;
}
//
// END XOSC Data ...
//
//
// START XBND Data ...
//
XBndState GetXBND(
const int bar_index,
//
const int marketLen = 10, // Market Length ...
const int shift = 0, // MA Shift ...
const ENUM_MA_METHOD method = MODE_SMA // MA Method ...
) {
//
XBndState result = {};
//
double high = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_HIGH
);
result.high = high;
//
double open = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_OPEN
);
result.open = open;
//
double close = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_CLOSE
);
result.close = close;
//
double low = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_LOW
);
result.low = low;
//
return result;
}
//
// END XBND Data ...
//
//
// START ZigZag Data ...
//
void PrepareZigZagState(
const int bar_index,
//
const int depth = 12,
const int deviation = 5,
const int backStep = 3
) {
//
string zigzagIndName = "x-saherelm.zigzag";
//
ArrayFree(zigZags);
ArrayResize(
zigZags,
3
);
//
double zigZag = 0;
int index = 0;
int i = bar_index;
while (index < 3) {
//
zigZag = iCustom(
_Symbol,
_Period,
zigzagIndName,
//
// Inputs ...
depth,
deviation,
backStep,
//
0, // Buffer Index ...
i
);
//
if (zigZag > 0) {
//
zigZags[index] = zigZag;
index++;
}
//
i++;
}
}
//
// END ZigZag Data ...
//
//
// START XMA Data ...
//
//
// Retrieve Short Cycle ...
XCycleState GetXMASC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow= slow;
//
return result;
}
//
// Retrieve Medium Cycle ...
XCycleState GetXMAMC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow= slow;
//
return result;
}
//
// Retrieve Long Cycle ...
XCycleState GetXMALC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow = slow;
//
return result;
}
//
// Retrieve Long Cycle ...
XCycleState GetXMANN(
const int bar_index,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = 10;
int slowLength = 50;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow = slow;
//
return result;
}
//
// Retrieve Middle ...
double GetXMAMM(
const int bar_index,
const int marketLen,
const double multiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_EMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_MEDIAN
) {
//
double result = 0;
//
int length = (int)(marketLen * multiplier);
//
double middle = iMA(
_Symbol,
_Period,
length,
shift,
method,
appliedPrice,
bar_index
);
result = middle;
//
return result;
}
//
// Retrieve XMA Parabolic SAR ...
double GetXMAPSAR(
const int bar_index,
//
double stp = 0.02,
double mxm = 0.2
) {
//
double result = 0;
//
double pSar = iSAR(
_Symbol,
_Period,
stp,
mxm,
bar_index
);
result = pSar;
//
return result;
}
//
XState GetXState(
const int bar_index,
const int marketLen,
//
const double stp,
const double mxm,
//
const int shortCycleFastMult,
const int shortCycleSlowMult,
const int mediumCycleFastMult,
const int mediumCycleSlowMult,
const int longCycleFastMult,
const int longCycleSlowMult
) {
//
XState result = {};
//
// Short Cycle ...
XCycleState sc = GetXMASC(
bar_index,
marketLen,
shortCycleFastMult,
shortCycleSlowMult
);
result.sc = sc;
//
// Medium Cycle ...
XCycleState mc = GetXMAMC(
bar_index,
marketLen,
mediumCycleFastMult,
mediumCycleSlowMult
);
result.mc = mc;
//
// Long Cycle ...
XCycleState lc = GetXMALC(
bar_index,
marketLen,
longCycleFastMult,
longCycleSlowMult
);
result.lc = lc;
//
// OSC ...
XCycleState osc = GetXOSC(
//
bar_index,
marketLen,
//
shortCycleFastMult,
shortCycleSlowMult
);
result.osc = osc;
//
// Parabolic SAR ...
double parabolicSAR = GetXMAPSAR(
bar_index,
stp,
mxm
);
result.parabolicSAR = parabolicSAR;
//
// Market Middleage ...
double marketMiddleage = GetXMAMM(
bar_index,
marketLen,
1.5
);
result.marketMiddleage = marketMiddleage;
// //
// int cciMarketLength = longCycleSlowMult * marketLen;
// double cci = GetMarketCCI(
// bar_index,
// cciMarketLength
// );
// result.cci = cci;
//
XBndState bnd = GetXBND(
bar_index
);
result.bnd = bnd;
//
XMKTState mkt = GetXMKT(
bar_index,
marketLen
);
result.mkt = mkt;
//
return result;
}
//
// END XMA Data ...
//
//
// END Indicator Reading Data ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,91 @@
///////////////////////////////////////////////////////
//
// 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);
}
//
// this used for logging series ...
void LogSeries(
double &series[], // which series to Log ...
int length = 0, // number of items to Log, 0 means all ...
int skip = 0 // number of items which skip before logging ...
) {
//
string msg = "";
//
int seriesSize = ArraySize(series);
if (
skip < 0
|| length < 0
|| seriesSize == 0
|| skip > seriesSize
|| skip + length > seriesSize
) {
return;
}
//
length = length == 0 ?
seriesSize :
length;
int start = skip > 1 ?
skip - 1 :
skip == 1 ?
1 :
0;
//
// Loop through series items ...
for (int i = start; i < start + length; i++) {
//
msg += StringConcatenate(
"i[", i, "]: ", series[i], ", "
);
}
//
LogMessage(msg);
}
//
// End Log Messages ...
//
@@ -0,0 +1,222 @@
///////////////////////////////////////////////////////
//
// 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 STATIC Variables ...
//
//
static int totalSignals = 0;
static int totalLongSignals = 0;
static int totalShortSignals = 0;
//
static double initialBalance = 0;
//
static int countedBars = 0;
static bool isNewBar = false;
static bool isNewDay = false;
//
// END STATIC Variables ...
//
//
// Start Models ...
//
//
// Signal Providers ...
enum ENUM_X_SIGNAL_PROVIDER {
X_UNKNOWN_PROVIDER,
X_OSC_PROVIDER,
X_CCI_PROVIDER,
X_SHP_PROVIDER,
X_XMA_PROVIDER,
X_RMA_PROVIDER,
X_XXX_PROVIDER
};
//
// these are different signal types ...
enum ENUM_X_SIGNAL_TYPE {
X_SIGNAL_NONE,
X_SIGNAL_LONG,
X_SIGNAL_SHORT,
};
//
// we Model each signals as this type ...
struct XSignal {
//
// Signal Symbol ...
string symbol;
//
// Signal Type ...
ENUM_X_SIGNAL_TYPE type;
//
// Signal ID ...
int id;
//
// Signal Ticket Number, when Opening Trade ...
int ticket;
//
// Signal Provider ...
ENUM_X_SIGNAL_PROVIDER provider;
//
// Target Point ...
double tp;
//
// Stop Loss ...
double sl;
//
// Signal Entry Price ...
double entry;
//
// Signalling Time ...
datetime time;
//
// Signal Comments ...
string comment;
};
//
// this is Signal Request Response model ...
struct XSignalRequest {
bool hasSignal;
XSignal signal;
ENUM_X_SIGNAL_TYPE type;
ENUM_X_SIGNAL_PROVIDER provider;
};
//
struct XBndState {
double high;
double open;
double close;
double low;
};
//
struct XMKTState {
//
double highestHigh;
double highestLow;
double highestOpen;
double highestClose;
//
double lowestHigh;
double lowestLow;
double lowestOpen;
double lowestClose;
};
//
struct XCycleState {
double fast;
double slow;
};
//
// Define a Model to Represent Snapshot of XMA Indicator ...
struct XState {
//
// SC ...
XCycleState sc;
//
// MC ...
XCycleState mc;
//
// LC ...
XCycleState lc;
//
// OSC ...
XCycleState osc;
//
// MIDDLEAGE ...
double marketMiddleage;
//
// PARABOLIC-SAR ...
double parabolicSAR;
//
double cci;
//
XBndState bnd;
//
XMKTState mkt;
};
//
// Parsed XMA Buffer ...
struct XStateInfo {
//
// Check Market Cross Exists or not ...
//
bool isSCFastCrossOverSlow;
bool isSCFastCrossUnderSlow;
//
double scMin;
double scMax;
//
bool isMCFastCrossOverSlow;
bool isMCFastCrossUnderSlow;
//
double mcMin;
double mcMax;
bool isLCFastCrossOverSlow;
bool isLCFastCrossUnderSlow;
//
double lcMin;
double lcMax;
//
bool isMMCrossOverSCFast;
bool isMMCrossUnderSCFast;
//
bool isMMCrossOverMCFast;
bool isMMCrossUnderMCFast;
//
double mmMin;
double mmMax;
};
//
// End Models ...
//
@@ -0,0 +1,363 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 OSC Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// SHP Based Signal Conditions ...
struct XOSCLongSignalConditions {
//
datetime crossOverTime;
double slowOnCrossOver;
//
datetime crossUnderTime;
double slowOnCrossUnder;
};
//
static XOSCLongSignalConditions oscLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckOSCLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult,
//
int lcFMult,
int lcSMult,
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
XState states[];
ArrayResize(
states,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < marketLen; i++) {
//
XState state = GetXState(
i,
marketLen,
//
stp,
mxm,
scFMult,
scSMult,
mcFMult,
mcSMult,
lcFMult,
lcSMult
);
//
states[index] = state;
//
index++;
}
//
bool isCrossUnder =
states[0].osc.fast < 0
&& !(states[1].osc.fast < 0)
;
//
bool isCrossOver =
states[0].osc.fast > 0
&& !(states[1].osc.fast > 0)
;
//
int oneTouches = 0;
int halfTouches = 0;
int minusOneTouches = 0;
for (int i = 0; i < marketLen - 1; i++) {
//
// One Touches ...
if (
states[i].osc.fast > 1
&& !(states[i + 1].osc.fast > 1)
) {
oneTouches++;
}
//
// Half Touches ...
if (
states[i].osc.fast > 0.5
&& !(states[i + 1].osc.fast > 0.5)
) {
halfTouches++;
}
//
// Minus One Touches ...
if (
states[i].osc.fast < -1
&& !(states[i + 1].osc.fast < -1)
) {
minusOneTouches++;
}
}
//
if (
isCrossUnder
&& oscLongConds.crossUnderTime == 0
) {
//
oscLongConds.crossUnderTime = barTime;
oscLongConds.slowOnCrossUnder = states[0].osc.slow;
return;
}
//
if (
isCrossOver
&& oscLongConds.crossUnderTime > 0
&& oscLongConds.crossOverTime == 0
) {
//
oscLongConds.crossOverTime = barTime;
oscLongConds.slowOnCrossOver = states[0].osc.slow;
return;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateOSCLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateOSCLongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r; // 300 * _Point;
//
double sl = 0; // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_OSC_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_OSC_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateOSCLongConditions() {
//
bool isConditionsFilled =
oscLongConds.crossOverTime > 0
&& oscLongConds.crossUnderTime > 0
&& oscLongConds.slowOnCrossOver > 0
&& oscLongConds.slowOnCrossUnder > 0
&& oscLongConds.crossOverTime > oscLongConds.crossUnderTime
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
oscLongConds.crossUnderTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
oscLongConds.crossOverTime
);
//
isBLFilled =
crossUnderBarIndex > crossOverBarIndex
// && oscLongConds.slowOnCrossOver > oscLongConds.slowOnCrossUnder
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearOSCLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearOSCLongSignalConditions() {
//
oscLongConds.crossOverTime = 0;;
oscLongConds.crossUnderTime = 0;;
}
//
// Check State for Long Signals ...
bool IsReadyForOSCLongSignals(
const XSignal &signal,
const XState &states[]
) {
//
bool result = false;
//
result =
//
true
;
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,363 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 RMA Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// RMA Based Signal Conditions ...
struct XRMALongSignalConditions {
//
datetime crossUnderTime;
//
datetime crossOverTime;
};
//
static XRMALongSignalConditions xrmaLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXRMALongSignalConditions(
const int bar_index,
const int marketLen,
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
XCycleState states[];
ArrayResize(
states,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < marketLen; i++) {
//
XCycleState state = GetXMANN(i);
//
states[index] = state;
//
index++;
}
//
bool isCrossUnder =
states[1].fast < states[1].slow
&& !(states[2].fast < states[2].slow)
;
//
bool isCrossOver =
states[1].fast > states[1].slow
&& !(states[2].fast > states[2].slow)
;
//
if (
isCrossUnder
&& xrmaLongConds.crossUnderTime == 0
) {
//
xrmaLongConds.crossUnderTime = barTime;
return;
}
//
if (
isCrossOver
&& xrmaLongConds.crossUnderTime > 0
&& xrmaLongConds.crossOverTime == 0
) {
//
xrmaLongConds.crossOverTime = barTime;
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXRMALongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateXRMALongConditions(marketLen)) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r; // 300 * _Point;
//
double sl = 0; // entryPrice - (300 * _Point); // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_RMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_RMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXRMALongConditions(
const int marketLen
) {
//
bool isConditionsFilled =
true
&& xrmaLongConds.crossOverTime > 0
&& xrmaLongConds.crossUnderTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
xrmaLongConds.crossOverTime
);
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
xrmaLongConds.crossUnderTime
);
//
XCycleState stateOnCrossUnder = GetXMANN(
crossUnderBarIndex
);
//
XCycleState stateOnCrossOver = GetXMANN(
crossOverBarIndex
);
//
double maC = iMA(
_Symbol,
_Period,
14,
0,
MODE_SMA,
PRICE_CLOSE,
crossOverBarIndex
);
// //
// double rmaOnCrossOver = GetRMA(
// crossOverBarIndex,
// 10
// );
// //
// double rmaOnMarketLength = GetRMA(
// crossOverBarIndex + marketLen,
// 10
// );
// //
// double prevCandleHigh = iHigh(
// _Symbol,
// _Period,
// crossOverBarIndex
// );
// //
// PrepareZigZagState(crossOverBarIndex);
// double zigZagDelta = zigZags[1] - zigZags[2];
// bool isZigZagWaitForHigh = zigZagDelta < 0;
//
isBLFilled =
true
//
&& (crossUnderBarIndex - crossOverBarIndex) > 5
//
&& xrmaLongConds.crossOverTime > xrmaLongConds.crossUnderTime
//
&& stateOnCrossOver.slow < stateOnCrossUnder.slow
//
&& MathAbs(stateOnCrossOver.fast - stateOnCrossOver.slow) > (70 * _Point)
//
&& maC >= stateOnCrossOver.slow
// //
// && !(rmaOnCrossOver < stateOnCrossOver.slow)
// //
// && MathAbs(rmaOnCrossOver - rmaOnMarketLength) < (600 * _Point)
// //
// && !isZigZagWaitForHigh
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXRMALongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXRMALongSignalConditions() {
//
xrmaLongConds.crossOverTime = 0;
xrmaLongConds.crossUnderTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXRMALongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
result =
//
true
;
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,391 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 SHP Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// SHP Based Signal Conditions ...
struct XSHPLongSignalConditions {
//
datetime start;
datetime stop;
};
//
static XSHPLongSignalConditions shpLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckSHPLongSignalConditions(
const int bar_index,
const int marketLen,
const double shpDetectMult,
const double smoother = 30
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
double high = iHigh(
_Symbol,
_Period,
bar_index
);
//
double low = iLow(
_Symbol,
_Period,
bar_index + 1
);
//
double mHH = GetMarketHighestHigh(
bar_index,
marketLen
);
//
double mLL = GetMarketLowestLow(
bar_index,
marketLen
);
double m2LL = GetMarketLowestLow(
bar_index,
marketLen * 2
);
//
int mHLIdx = iHighest(
_Symbol,
_Period,
MODE_LOW,
marketLen,
bar_index
);
datetime mHLTime = iTime(
_Symbol,
_Period,
mHLIdx
);
double mHL = iHigh(
_Symbol,
_Period,
mHLIdx
);
//
double hlDiff = (mHL - mLL);
double sharpDetectValue = shpDetectMult * _Point;
//
bool isSharpDetected =
// (
// low == mLL
// || MathAbs(mLL - low) < (smoother * _Point)
// )
// &&
// !(
// mLL > m2LL
// && MathAbs(m2LL - mLL) > sharpDetectValue / 2
// )
// &&
(
hlDiff > sharpDetectValue
|| hlDiff > sharpDetectValue - (smoother * _Point)
)
;
//
if (isSharpDetected) {
//
shpLongConds.start = mHLTime;
shpLongConds.stop = barTime;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateSHPLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r, // Risk to Reward ratio ...
const double shpDetectMultiplier // Sharp Detect Multiplier ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateSHPLongConditions(shpDetectMultiplier)) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = 300 * _Point; // risk * r2r;
//
double sl = 0; // ll;
//
// this means Market Lowest Low ...
double shpValue = shpDetectMultiplier * _Point;
if (
reward == 0
|| reward < 20 * _Point
) {
reward = shpValue;
}
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_SHP_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_SHP_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateSHPLongConditions(
const double shpDetectMultiplier
) {
//
double shpDetectValue = shpDetectMultiplier * _Point;
//
bool isConditionsFilled =
shpLongConds.stop != 0
&& shpLongConds.start != 0
&& shpLongConds.stop > shpLongConds.start
;
//
bool isBLFilled = true;
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearSHPLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearSHPLongSignalConditions() {
//
shpLongConds.stop = 0;
shpLongConds.start = 0;
}
//
// Check State for Long Signals ...
bool IsReadyForSHPLongSignals(
const XSignal &signal,
const XState &states[]
) {
//
bool result = false;
//
XStateInfo info = ParseXMAStates(states);
//
int xmaMarketLen = ArraySize(states);
double mHH = GetMarketHighestHigh(0, xmaMarketLen);
double m2HH = GetMarketHighestHigh(0, (int) (xmaMarketLen * 1.5));
//
int lcUpDownTouches = 0;
int cciHundredTouches = 0;
for (int i = 0; i < xmaMarketLen; i++) {
//
double high = iHigh(
_Symbol,
_Period,
i
);
//
double low = iLow(
_Symbol,
_Period,
i
);
//
double up = MathMax(states[i].lc.fast, states[i].lc.slow);
double down = MathMax(states[i].lc.fast, states[i].lc.slow);
//
if (high >= up && low <= down) {
lcUpDownTouches++;
}
//
if (
i < xmaMarketLen - 1
&& i < 10
) {
if (
states[i].cci < 100
&& states[i + 1].cci > 100
) {
cciHundredTouches++;
}
}
}
//
result =
//
true
//
&& states[0].mc.fast > states[0].mc.slow
&& states[0].lc.fast > states[0].lc.slow
//
&& states[0].sc.fast < states[0].sc.slow
&& states[1].sc.fast < states[1].sc.slow
//
&& states[0].marketMiddleage < states[0].sc.fast
&& states[1].marketMiddleage < states[1].sc.fast
&& !(
states[1].sc.fast < states[1].mc.fast
&& states[1].sc.slow < states[1].mc.fast
&& states[1].sc.fast > states[1].mc.slow
&& states[1].sc.slow > states[1].mc.slow
)
&& !(
states[0].marketMiddleage < states[0].mc.fast
&& states[0].marketMiddleage > states[0].mc.slow
)
//
&& mHH != m2HH
&& lcUpDownTouches == 0
&& cciHundredTouches == 0
;
//
return result;
}
//
// END Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,592 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 X Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// X Based Signal Conditions ...
struct XSignalConditions {
datetime startTime;
datetime signalTime;
};
//
static XSignalConditions xLongConds;
static XSignalConditions xShortConds;
//
static bool xWaitForLongSignals = true;
static bool xCloseLongTrades = false;
//
static bool xWaitForShortSignals = true;
static bool xCloseShortTrades = false;
//
bool isLastTrendUp = false;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill Long Signal Conditions ...
void CheckXLongSignalConditions(
const int bar_index,
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
// //
// bool isCrossUnder =
// states[1].osc.fast < states[1].osc.slow
// && !(states[2].osc.fast < states[2].osc.slow)
// ;
// //
// bool isCrossOver =
// states[1].osc.fast > states[1].osc.slow
// && !(states[2].osc.fast > states[2].osc.slow)
// ;
//
XOHCL pCandle = GetCandleModel(1);
//
bool isTrendingUp =
pCandle.low > states[0].bnd.high
&& pCandle.high > states[0].bnd.high;
//
bool isTrendingDown =
pCandle.high < states[0].bnd.low
&& pCandle.low < states[0].bnd.low;
//
bool isCrossUnder =
isTrendingDown
&& !isTrendingUp
;
//
bool isCrossOver =
isTrendingUp
&& !isTrendingDown
;
// //
// if (isTrendingUp && !isTrendingDown) {
// isLastTrendUp = true;
// } else if (isTrendingDown && !isTrendingUp) {
// isLastTrendUp = false;
// }
//
// if (isLastTrendUp) {
//
// LogMessage(
// StringConcatenate(
// "isLastTrendUp: ", isLastTrendUp
// )
// );
// }
//
if (
isCrossUnder
&& xLongConds.startTime == 0
) {
//
xLongConds.startTime = barTime;
return;
}
//
if (
isCrossOver
&& xLongConds.startTime > 0
&& xLongConds.signalTime == 0
) {
//
xLongConds.signalTime = barTime;
return;
}
}
//
// Check and Fill Short Signal Conditions ...
void CheckXShortSignalConditions(
const int bar_index,
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
bool isCrossUnder =
states[1].osc.fast < states[1].osc.slow
&& !(states[2].osc.fast < states[2].osc.slow)
;
//
bool isCrossOver =
states[1].osc.fast > states[1].osc.slow
&& !(states[2].osc.fast > states[2].osc.slow)
;
//
if (
isCrossOver
&& xShortConds.startTime == 0
) {
//
xShortConds.startTime = barTime;
return;
}
//
if (
isCrossUnder
&& xShortConds.startTime > 0
&& xShortConds.signalTime == 0
) {
//
xShortConds.signalTime = barTime;
return;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateXSignal(
const ENUM_X_SIGNAL_TYPE type, // Signal Type ...
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r, // Risk to Reward ratio ...
const XState &states[],
//
const double smoother = 5
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
bool requestLong = type == X_SIGNAL_LONG;
//
if (requestLong) {
//
if (
!ValidateXLongConditions(
marketLen,
states,
smoother
)
) {
return result;
}
} else {
//
if (
!ValidateXShortConditions(
marketLen,
states,
smoother
)
) {
return result;
}
}
//
// Price Calculations ...
//
RefreshRates();
//
double askPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double bidPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double entryPrice = requestLong ?
askPrice :
bidPrice;
//
double exitPrice = requestLong ?
bidPrice :
askPrice;
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double hh =
GetMarketHighestHigh(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = requestLong ?
MathMin(openPrice, closePrice) - ll :
hh - MathMax(openPrice, closePrice);
double reward = risk * r2r; // risk * r2r; // 300 * _Point;
// if (risk > (500 * _Point)) {
// reward = 300 * _Point;
// }
//
double sl = 0; // ll;
double tp = requestLong ?
entryPrice + reward :
entryPrice - reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = type;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XXX_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = type;
result.provider = X_XXX_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateXLongConditions(
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
bool isConditionsFilled =
xLongConds.startTime > 0
&& xLongConds.signalTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
xLongConds.startTime
);
//
int signalBarIndex = iBarShift(
_Symbol,
_Period,
xLongConds.signalTime
);
//
isBLFilled =
//
xLongConds.signalTime > xLongConds.startTime
&& MathAbs(signalBarIndex - startBarIndex) > 2
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
&& xWaitForLongSignals
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXLongSignalConditions();
}
//
return result;
}
bool ValidateXShortConditions(
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
bool isConditionsFilled =
xShortConds.startTime > 0
&& xShortConds.signalTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
xShortConds.startTime
);
//
int signalBarIndex = iBarShift(
_Symbol,
_Period,
xShortConds.signalTime
);
//
isBLFilled =
//
xShortConds.signalTime > xShortConds.startTime
&& MathAbs(signalBarIndex - startBarIndex) > 2
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
&& xWaitForLongSignals
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXShortSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXLongSignalConditions() {
//
xLongConds.startTime = 0;
xLongConds.signalTime = 0;
}
//
// Clear Short Signal Conditions for New One ...
void ClearXShortSignalConditions() {
//
xShortConds.startTime = 0;
xShortConds.signalTime = 0;
}
//
// Check State for Long Signals ...
bool IsReadyForXSignals(
const XSignal &signal,
const XState &states[],
const int marketLen,
//
double smoother = 100
) {
//
bool result = false;
//
bool isSCTrendUp =
states[1].sc.fast > states[1].sc.slow
&& states[2].sc.fast > states[2].sc.slow;
// //
// bool isSCTrendDown =
// states[1].sc.fast < states[1].sc.slow
// && states[2].sc.fast < states[2].sc.slow;
//
bool isMCTrendUp =
states[1].mc.fast > states[1].mc.slow
&& states[2].mc.fast > states[2].mc.slow;
// //
// bool isMCTrendDown =
// states[1].mc.fast < states[1].mc.slow
// && states[2].mc.fast < states[2].mc.slow;
//
bool isLCTrendUp =
states[1].lc.fast > states[1].lc.slow
&& states[2].lc.fast > states[2].lc.slow;
// //
// bool isLCTrendDown =
// states[1].lc.fast < states[1].lc.slow
// && states[2].lc.fast < states[2].lc.slow;
// //
// bool isTrendingUp =
// pCandle.low > states[0].bnd.high
// && pCandle.high > states[0].bnd.high;
// //
// bool isTrendingDown =
// pCandle.high < states[0].bnd.low
// && pCandle.low < states[0].bnd.low;
// //
// if (isTrendingUp && !isTrendingDown) {
// isLastTrendUp = true;
// } else if (isTrendingDown && !isTrendingUp) {
// isLastTrendUp = false;
// }
// //
// if (isLastTrendUp) {
// //
// LogMessage(
// StringConcatenate(
// "isLastTrendUp: ", isLastTrendUp
// )
// );
// }
//
// XOHCL pCandle = GetCandleModel(1);
//
if (signal.type == X_SIGNAL_LONG) {
//
result =
//
true
//
&& isSCTrendUp
&& isMCTrendUp
&& isLCTrendUp
//
&& (
(
states[1].mc.slow < states[1].bnd.low
&& states[1].mc.fast < MathMin(states[1].bnd.open, states[1].bnd.close)
) || (
states[1].lc.fast > states[1].bnd.low
&& states[1].lc.fast > states[1].mc.fast
)
)
&& MathAbs(states[1].mc.fast - states[1].bnd.low) > 50 * _Point
;
} else if (signal.type == X_SIGNAL_SHORT) {
//
result =
false
;
}
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,490 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 XMA Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// XMA Based Signal Conditions ...
struct XMAMCLongSignalConditions {
//
datetime mcFastCrossUnderSlowTime;
double crossUnderMCFast;
double crossUnderMCSlow;
//
datetime mcFastCrossOverSlowTime;
double crossOverMCFast;
double crossOverMCSlow;
//
datetime mcFastBiggerThanCrossUnderSlowTime;
};
//
static XMAMCLongSignalConditions xmaMCLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXMAMCLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult
) {
//
XCycleState mcs[];
int positionsMarketLen = bar_index + marketLen;
//
// Retrieve Bar Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// Resize Arrays ...
ArrayResize(
mcs,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < positionsMarketLen; i++) {
//
XCycleState mc = GetXMAMC(
i,
marketLen,
mcFMult,
mcSMult
);
mcs[index] = mc;
//
index++;
}
//
bool isMCFastCrossUnderSlow =
mcs[0].fast < mcs[0].slow
&& !(mcs[1].fast <= mcs[1].slow)
;
bool isMCFastCrossOverSlow =
mcs[0].fast > mcs[0].slow
&& !(mcs[1].fast >= mcs[1].slow)
;
//
if (
isMCFastCrossUnderSlow
&& xmaMCLongConds.mcFastCrossUnderSlowTime == 0
) {
//
xmaMCLongConds.crossUnderMCFast = mcs[0].fast;
xmaMCLongConds.crossUnderMCSlow = mcs[0].slow;
xmaMCLongConds.mcFastCrossUnderSlowTime = barTime;
return;
}
//
if (
isMCFastCrossUnderSlow
&& xmaMCLongConds.mcFastCrossUnderSlowTime > 0
) {
//
ClearXMAMCLongSignalConditions();
//
xmaMCLongConds.crossUnderMCFast = mcs[0].fast;
xmaMCLongConds.crossUnderMCSlow = mcs[0].slow;
xmaMCLongConds.mcFastCrossUnderSlowTime = barTime;
return;
}
//
if (
isMCFastCrossOverSlow
&& xmaMCLongConds.mcFastCrossUnderSlowTime > 0
&& xmaMCLongConds.mcFastCrossOverSlowTime == 0
) {
//
xmaMCLongConds.crossOverMCFast = mcs[0].fast;
xmaMCLongConds.crossOverMCSlow = mcs[0].slow;
xmaMCLongConds.mcFastCrossOverSlowTime = barTime;
return;
}
//
if (
xmaMCLongConds.mcFastCrossUnderSlowTime > 0
&& xmaMCLongConds.mcFastCrossOverSlowTime > 0
&& mcs[0].fast > xmaMCLongConds.crossUnderMCSlow
&& xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime == 0
) {
//
xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime = barTime;
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXMAMCLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r, // Risk to Reward ratio ...
const double shpDetectMult,
const double smoother = 50
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (
!ValidateXMAMCLongConditions(
marketLen,
shpDetectMult,
smoother
)
) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
3
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r;
//
double sl = 0;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_XMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXMAMCLongConditions(
const int marketLen,
const double shpDetectMult,
const double smoother = 50
) {
//
bool isConditionsFilled =
xmaMCLongConds.crossOverMCSlow > 0
&& xmaMCLongConds.crossOverMCFast > 0
&& xmaMCLongConds.crossUnderMCFast > 0
&& xmaMCLongConds.crossUnderMCSlow > 0
&& xmaMCLongConds.mcFastCrossOverSlowTime != 0
&& xmaMCLongConds.mcFastCrossUnderSlowTime != 0
&& xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime != 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
xmaMCLongConds.mcFastCrossUnderSlowTime
);
//
int crossOverAndBiggerBarIndex = iBarShift(
_Symbol,
_Period,
xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime
);
//
int cycleMarketLen = MathMin(
MathAbs(crossUnderBarIndex - crossOverAndBiggerBarIndex),
marketLen * 2
);
double hh = GetMarketHighestHigh(
crossOverAndBiggerBarIndex,
cycleMarketLen
);
double ll = GetMarketLowestLow(
crossOverAndBiggerBarIndex,
cycleMarketLen
);
//
double high = iHigh(
_Symbol,
_Period,
crossOverAndBiggerBarIndex
);
double pcHigh = iHigh(
_Symbol,
_Period,
crossOverAndBiggerBarIndex + 1
);
//
double diff = (hh - ll);
double shpValue = shpDetectMult * _Point;
//
bool isPriceRegular =
//
true
//
&&
(
diff < shpValue
|| diff < shpValue - (smoother * _Point)
)
&&
!(
high == hh
|| pcHigh == hh
|| MathAbs(hh - high) < (smoother * _Point)
|| MathAbs(hh - pcHigh) < (smoother * _Point)
)
;
//
// LogMessage("Price Regular: " + isPriceRegular);
//
isBLFilled =
isPriceRegular
&& xmaMCLongConds.mcFastCrossUnderSlowTime < xmaMCLongConds.mcFastCrossOverSlowTime
&& xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime >= xmaMCLongConds.mcFastCrossUnderSlowTime
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXMAMCLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXMAMCLongSignalConditions() {
//
xmaMCLongConds.mcFastCrossUnderSlowTime = 0;
xmaMCLongConds.crossUnderMCFast = 0;
xmaMCLongConds.crossUnderMCSlow = 0;
//
xmaMCLongConds.mcFastCrossOverSlowTime = 0;
xmaMCLongConds.crossOverMCFast = 0;
xmaMCLongConds.crossOverMCSlow = 0;
//
xmaMCLongConds.mcFastBiggerThanCrossUnderSlowTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXMAMCLongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
int countRangedCandles = 0;
bool isMarketRanging = false;
for (int i = 1; i < marketLen; i++) {
//
double high = iHigh(
_Symbol,
_Period,
i
);
//
double low = iLow(
_Symbol,
_Period,
i
);
//
bool isRanging =
//
high > states[i].mc.fast
&& high > states[i].mc.slow
//
&& low < states[i].mc.fast
&& low < states[i].mc.slow
;
if (isRanging) {
countRangedCandles++;
}
}
//
XStateInfo info = ParseXMAStates(states);
double mmSlope = GetSlope(
1,
states[1].marketMiddleage,
2,
states[0].marketMiddleage
);
double mmSlope1 = GetSlope(
1,
states[2].marketMiddleage,
2,
states[1].marketMiddleage
);
double mmSlopeDiff = mmSlope - mmSlope1;
//
isMarketRanging = countRangedCandles > 0;
//
result =
//
true
//
&& mmSlope > 0
&& mmSlope1 > 0
&& mmSlopeDiff > 0
&& !isMarketRanging
&& states[0].marketMiddleage < info.mmMax
;
// if (result) {
// LogMessage("mmSlope: " + mmSlope + ", mmSlope1: " + mmSlope1 + ", Diff: " + mmSlopeDiff);
// }
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,338 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 XMA Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// XMA Based Signal Conditions ...
struct XMAMMLongSignalConditions {
//
datetime crossUnderTime;
//
datetime crossOverTime;
};
//
static XMAMMLongSignalConditions xmaMMLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXMAMMLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult,
//
int lcFMult,
int lcSMult,
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
XState states[];
ArrayResize(
states,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < marketLen; i++) {
//
XState state = GetXState(
i,
marketLen,
//
stp,
mxm,
scFMult,
scSMult,
mcFMult,
mcSMult,
lcFMult,
lcSMult
);
//
states[index] = state;
//
index++;
}
//
bool isCrossUnder =
states[1].marketMiddleage < states[1].sc.fast
&& !(states[2].marketMiddleage < states[2].sc.fast)
;
//
bool isCrossOver =
states[1].marketMiddleage > states[1].sc.fast
&& !(states[2].marketMiddleage > states[2].sc.fast)
;
//
if (
isCrossUnder
&& xmaMMLongConds.crossUnderTime == 0
) {
//
xmaMMLongConds.crossUnderTime = barTime;
return;
}
//
if (
isCrossOver
&& xmaMMLongConds.crossUnderTime > 0
&& xmaMMLongConds.crossOverTime == 0
) {
//
xmaMMLongConds.crossOverTime = barTime;
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXMAMMLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateXMAMMLongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = 300 * _Point; // risk * r2r;
//
double sl = 0; // entryPrice - (300 * _Point); // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_XMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXMAMMLongConditions() {
//
bool isConditionsFilled =
true
&& xmaMMLongConds.crossOverTime > 0
&& xmaMMLongConds.crossUnderTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
xmaMMLongConds.crossOverTime
);
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
xmaMMLongConds.crossUnderTime
);
//
isBLFilled =
true
//
&& (crossUnderBarIndex - crossOverBarIndex) > 5
//
&& xmaMMLongConds.crossOverTime > xmaMMLongConds.crossUnderTime
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXMAMMLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXMAMMLongSignalConditions() {
//
xmaMMLongConds.crossOverTime = 0;
xmaMMLongConds.crossUnderTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXMAMMLongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
result =
//
true
//
// && states[0].parabolicSAR < states[0].marketMiddleage
// && !(
// states[0].parabolicSAR < states[0].mc.fast
// && states[0].parabolicSAR < states[0].mc.slow
// )
//
// && states[0].mc.fast > states[0].mc.slow
//
// && MathAbs(states[0].mc.fast - states[0].mc.slow) > (150 * _Point)
;
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,360 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 XMA Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// XMA Based Signal Conditions ...
struct XMASCLongSignalConditions {
//
datetime scFastCrossUnderSlowTime;
double crossUnderSCFast;
double crossUnderSCSlow;
//
datetime scFastCrossOverSlowTime;
double crossOverSCFast;
double crossOverSCSlow;
//
datetime scFastBiggerThanCrossUnderSlowTime;
};
//
static XMASCLongSignalConditions xmaSCLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXMASCLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult
) {
//
XCycleState scs[];
int positionsMarketLen = bar_index + marketLen;
//
// Retrieve Bar Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// Resize Arrays ...
ArrayResize(
scs,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < positionsMarketLen; i++) {
//
XCycleState sc = GetXMASC(
i,
marketLen,
scFMult,
scSMult
);
scs[index] = sc;
//
index++;
}
//
bool isSCFastCrossUnderSlow =
scs[0].fast < scs[0].slow
&& !(scs[1].fast <= scs[1].slow)
;
bool isSCFastCrossOverSlow =
scs[0].fast > scs[0].slow
&& !(scs[1].fast >= scs[1].slow)
;
//
if (
isSCFastCrossUnderSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime == 0
) {
//
xmaSCLongConds.crossUnderSCFast = scs[0].fast;
xmaSCLongConds.crossUnderSCSlow = scs[0].slow;
xmaSCLongConds.scFastCrossUnderSlowTime = barTime;
return;
}
//
if (
isSCFastCrossOverSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime > 0
&& xmaSCLongConds.scFastCrossOverSlowTime == 0
) {
//
xmaSCLongConds.crossOverSCFast = scs[0].fast;
xmaSCLongConds.crossOverSCSlow = scs[0].slow;
xmaSCLongConds.scFastCrossOverSlowTime = barTime;
return;
}
//
if (
xmaSCLongConds.scFastCrossUnderSlowTime > 0
&& xmaSCLongConds.scFastCrossOverSlowTime > 0
&& scs[0].fast > xmaSCLongConds.crossUnderSCSlow
&& xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime == 0
) {
//
xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime = barTime;
return;
}
//
if (
isSCFastCrossUnderSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime > 0
&& xmaSCLongConds.scFastCrossOverSlowTime > 0
) {
//
ClearXMASCLongSignalConditions();
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXMASCLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
//
// const double shpDetectMultiplier
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateXMASCLongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index + 1
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index + 1
);
// //
// double sharpDetectValue = shpDetectMultiplier * _Point;
// double lowPrice = iLow(
// _Symbol,
// _Period,
// bar_index + 1
// );
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r;
//
double sl = 0;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_XMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXMASCLongConditions() {
//
bool isConditionsFilled =
xmaSCLongConds.crossOverSCSlow > 0
&& xmaSCLongConds.crossOverSCFast > 0
&& xmaSCLongConds.crossUnderSCFast > 0
&& xmaSCLongConds.crossUnderSCSlow > 0
&& xmaSCLongConds.scFastCrossOverSlowTime != 0
&& xmaSCLongConds.scFastCrossUnderSlowTime != 0
&& xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime !=0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
isBLFilled =
xmaSCLongConds.crossOverSCFast > xmaSCLongConds.crossUnderSCSlow
&& xmaSCLongConds.scFastCrossUnderSlowTime < xmaSCLongConds.scFastCrossOverSlowTime
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXMASCLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXMASCLongSignalConditions() {
//
xmaSCLongConds.crossUnderSCFast = 0;
xmaSCLongConds.crossUnderSCSlow = 0;
xmaSCLongConds.scFastCrossUnderSlowTime = 0;
//
xmaSCLongConds.crossOverSCFast = 0;
xmaSCLongConds.crossOverSCSlow = 0;
xmaSCLongConds.scFastCrossOverSlowTime = 0;
//
xmaSCLongConds.scFastBiggerThanCrossUnderSlowTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXMASCLongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
result =
//
true
//
&& states[0].sc.fast > states[0].sc.slow
&& states[1].sc.fast > states[1].sc.slow
;
//
return result;
}
//
// END Functions ...
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+790
View File
@@ -0,0 +1,790 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XST Strategy Expert Advisor
// ---------------------------------------------
// saherelm implementation of strategy expert advisor ...
// in this EA, we try to combine multiple tools, to ashive best
// results ...
//
// ShortName: XST
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
// +989121694056
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XST Strategy Expert Advisor"
#property strict
//
// START Inputs ...
//
//
// Signal Prefixe ...
input string signalPrefix = "XST"; // Signal Prefix
//
// Signal Draw Specifications ...
input string bullishSignalLabel = "X_BUY"; // Bullish Signal Label
input color bullishSignalColor = clrAqua; // Bullish Signal Color
//
input string bearishSignalLabel = "X_SELL"; // Bearish Signal Label
input color bearishSignalColor = clrFuchsia; // Bearish Signal Color
//
input 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 = 1.5; // Risk to Reward Ratio
// input double maxTPMultiplier = 1000; // Max Allowed TP
//
// 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.05; // Maximum DrawDown Per Trade
input double minBalancePercent = 0.5; // Minimum Balance for Trading
input double maxEquityPercent = 0.1; // Maximum Trade Equity
input int closeAllOpenTradesAfterCandle = 408; // Close All Open Trades After Passed Candles
input bool closeAllInProfitOpenTradesWhenMaxOpenTradesReached = false; // Close All In Profit Open Trades When Max Open Trades Reached and New Signal Income
//
// Indicators ...
//
// CCI Inputs ...
input double step = 0.01; // SAR Step
input double maximum = 0.1; // SAR Maximum
//
// XMA Inputs ...
//
input int shortCycleFastMultiplier = 2; // Short Cycle Fast Multiplier
input int shortCycleSlowMultiplier = 4; // Short Cycle Slow Multiplier
input int mediumCycleFastMultiplier = 6; // Medium Cycle Fast Multiplier
input int mediumCycleSlowMultiplier = 12; // Medium Cycle Slow Multiplier
input int longCycleFastMultiplier = 36; // Long Cycle Fast Multiplier
input int longCycleSlowMultiplier = 72; // Long Cycle Slow Multiplier
//
// SHPD Indicator ...
input double sharpDetectMultiplier = 800; // Sharp Detect Multiplier
//
// 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.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
//
// XMA ...
//
// Validate Short Cycle ...
|| shortCycleFastMultiplier <= 0
|| shortCycleSlowMultiplier <= 0
|| shortCycleFastMultiplier >= shortCycleSlowMultiplier
//
// Validate Medium Cycle ...
|| mediumCycleFastMultiplier <= 0
|| mediumCycleSlowMultiplier <= 0
|| mediumCycleFastMultiplier >= mediumCycleSlowMultiplier
//
// Validate Long Cycle ...
|| longCycleFastMultiplier <= 0
|| longCycleSlowMultiplier <= 0
|| longCycleFastMultiplier >= longCycleSlowMultiplier
//
// Validate Series of Multipliers ...
|| shortCycleFastMultiplier >= mediumCycleFastMultiplier
|| mediumCycleFastMultiplier >= longCycleFastMultiplier
;
//
if (inputsNotValiid) {
return INIT_PARAMETERS_INCORRECT;
}
//
totalSignals = 0;
totalLongSignals = 0;
totalShortSignals = 0;
//
initialBalance = 0;
//
// START Define Array Series ...
//
//
// END Define Array Series ...
//
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XST";
// //
// // Set Event Timer on One Seccond ...
// bool isEventSet = EventSetTimer(1);
// if (!isEventSet) {
// LogMessage("Error: " + GetLastError());
// return INIT_FAILED;
// }
//
ClearSignalConditions();
//
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason) {
//
// Killing Event Timer ...
EventKillTimer();
}
//
// Ticker Event Handler ...
void OnTick() {
//
isNewDay = IsNewDay();
if (isNewDay) {
//
LogMessage(
StringConcatenate(
"New Day: ", TimeCurrent()
)
);
}
//
// Process Signals to Open Positions ...
ProcessSignals();
//
// Checking State for Signal Handling ...
CheckState();
//
// Process Open Positions for Trailing Stop Loss or Close ...
ProcessOpenPositions();
}
//
// Timer Event Handler ...
void OnTimer() {
//
CheckState();
//
ProcessOpenPositions();
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Check State for Signal Handling ...
void CheckState() {
//
// Here we Must to Check Market State for enable or disable
// Signal Handlers and also make dection to close all long/short
// trades ...
// //
// closeLongTrades = xCloseLongTrades;
// waitForLongSignals = xWaitForLongSignals;
// //
// closeShortTrades = xCloseShortTrades;
// waitForShortSignals = xWaitForShortSignals;
// //
// xCloseLongTrades = false;
// xCloseShortTrades = false;
}
//
// Calculate Signals and Process Based on Exists Signals ...
void ProcessSignals() {
//
XSignalRequest request = {};
request.type = X_SIGNAL_NONE;
request.hasSignal = false;
//
// Prevent Multiple Calculating on Same Bars ...
isNewBar = IsNewBar();
if (isNewBar) {
countedBars++;
}
//
if (countedBars < longCycleSlowMultiplier * marketLength) {
return;
}
//
bool allowDoTrade = true;
//
// Check Balance ...
if (initialBalance > 0) {
//
// Retrieve Account Balance ...
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double minimumBalanceForTrade =
balance > initialBalance
?
minBalancePercent * balance
:
minBalancePercent * initialBalance;
//
// Retrieve Account Equity ...
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
double maxAllowedEquity = balance - (balance * maxEquityPercent);
//
// Retrieve Free Marigin ...
double freeMargin = AccountFreeMargin();
double maximumMariginRisk = balance - (balance * maxEquityPercent);
//
if (
//
// Do not Open Positions if equity not passed ...
equity < maxAllowedEquity ||
//
// Do not Open Positions if free margin not passed ...
freeMargin <= maximumMariginRisk ||
//
// Do not open positions if balance less than minimum ...
balance <= minimumBalanceForTrade
) {
//
allowDoTrade = false;
// //
// string message = StringConcatenate(
// "Trading Pause => ",
// "Balance: ", balance,
// ", Equity: ", equity,
// ", FreeMargin: ", freeMargin
// );
// //
// LogMessage(message);
// SendAlert(message);
}
}
//
// Retrieve Signal Exists ...
request = GenerateSignal(0);
//
// Prevent doing anything else, if there is no signals ...
if (
!allowDoTrade ||
!request.hasSignal ||
request.type == X_SIGNAL_NONE
) {
return;
}
//
bool hasLongSignal = request.type == X_SIGNAL_LONG;
//
// Check For Bot State ...
if (
(hasLongSignal && !waitForLongSignals)
|| (!hasLongSignal && !waitForShortSignals)
) {
//
// Clear Signal Conditions ...
if (hasLongSignal) {
ClearLongSignalConditions();
} else {
ClearShortSignalConditions();
}
//
return;
}
//
// Check last Signalled Bar with Counted Bars ...
// Prevent Multiple Signalling on Same Bar ...
bool isInLastSignalledBars = false;
for (int i=0; i < marketLength; i++) {
//
isInLastSignalledBars =
isInLastSignalledBars
|| lastSignalledBar == countedBars - i
;
}
if (isInLastSignalledBars) {
//
// Clear Signal Conditions ...
if (hasLongSignal) {
ClearLongSignalConditions();
} else {
ClearShortSignalConditions();
}
//
return;
}
//
// increase last signalled bar ...
lastSignalledBar = countedBars;
//
// Calculate Can Trade or not ...
allowDoTrade = allowTrade
&& (
hasLongSignal ?
allowLongTrades :
allowShortTrades
);
//
// Chack Maximum Open Positions ...
int openTrades = CountOpenTrades();
if (maxOpenTrades > 0) {
//
if (openTrades >= maxOpenTrades) {
//
allowDoTrade = false;
//
if (closeAllInProfitOpenTradesWhenMaxOpenTradesReached) {
//
// Close All In Profit Trades ...
bool hasClosedInProfitTrade = CloseAllInProfitTrades();
if (hasClosedInProfitTrade) {
//
openTrades = CountOpenTrades();
//
allowDoTrade = !(openTrades >= maxOpenTrades);
}
}
//
if (!allowDoTrade) {
//
string message = StringConcatenate(
"Trading Pause => ",
"Max Open Trades (",
maxOpenTrades,
") reached ..."
);
//
LogMessage(message);
SendAlert(message);
}
}
}
//
// Check Trading is Enable or not ...
// nothing to do if trading is disabled ...
if (!allowDoTrade) {
//
// Clear Signal Conditions ...
if (hasLongSignal) {
ClearLongSignalConditions();
} else {
ClearShortSignalConditions();
}
// //
// string message = StringConcatenate(
// "Trading Not Allowed ..."
// );
// //
// LogMessage(message);
// SendAlert(message);
return;
}
//
bool isPositionOpened = TradeSignal(
request.signal,
signalPrefix,
lotsPerTradePercent,
//
bullishSignalLabel,
bullishSignalColor,
bearishSignalLabel,
bearishSignalColor
);
//
totalSignals++;
if (hasLongSignal) {
//
totalLongSignals++;
ClearLongSignalConditions();
} else {
//
totalShortSignals++;
ClearShortSignalConditions();
}
//
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.entry,
", TP: ", request.signal.tp
);
//
// Terminal Alert ...
if (terminalAlert) {
Alert(message);
}
//
// Push Alert ...
if (pushAlert) {
SendNotification(message);
}
}
}
}
//
// Process All Open Positions ...
void ProcessOpenPositions() {
//
// this comes from check state ...
if (closeLongTrades) {
//
closeLongTrades = false;
//
bool isAllLongTradesClosed = CloseAllLongTrades();
if (isAllLongTradesClosed) {
}
}
//
// this comes from check state ...
if (closeShortTrades) {
//
closeShortTrades = false;
//
bool isAllShortTradesClosed = CloseAllShortTrades();
if (isAllShortTradesClosed) {
}
}
//
// Close All XXX Provided Signals on it's Specific Condition ...
if (xCloseLongTrades) {
//
CloseAllProviderLongTrades(X_XXX_PROVIDER);
//
xCloseLongTrades = false;
}
//
bool hasClosedLongTimeTrade = CloseAllLongTimeTrades(
closeAllOpenTradesAfterCandle
);
//
// Close Maximum DrawDown Passed Trades ...
bool hasClosedInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades(
maxDrawdownPercentPerPTrade
);
//
if (
hasClosedLongTimeTrade
|| hasClosedInDrawDownLongTrade
) {
//
// waitForLongSignals = 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 ...
//
//
//
// Calculate Signal ...
// in this function we calculate a signal exists in
// specific bar or not ...
XSignalRequest GenerateSignal(
const int bar_index // Bar Index ...
) {
//
// create temp result ...
XSignalRequest result = {};
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
bool hasSignal = false;
bool hasLongSignal = false;
bool hasShortSignal = false;
//
XSignal signal = {};
//
// Retrieve XMA States ...
// based on medium cycle slow ...
XState states[];
ArrayFree(states);
ArrayResize(
states,
marketLength
);
//
int index = 0;
for (int i = bar_index; i < bar_index + marketLength; i++) {
//
states[index] = GetXState(
i,
marketLength,
//
step,
maximum,
//
shortCycleFastMultiplier,
shortCycleSlowMultiplier,
mediumCycleFastMultiplier,
mediumCycleSlowMultiplier,
longCycleFastMultiplier,
longCycleSlowMultiplier
);
//
index++;
}
//
CheckXLongSignalConditions(
bar_index,
marketLength,
states
);
//
CheckXShortSignalConditions(
bar_index,
marketLength,
states
);
//
XSignalRequest xLongSignalRequest = GenerateXSignal(
X_SIGNAL_LONG,
bar_index,
marketLength,
riskToRewardRatio,
states
);
//
XSignalRequest xShortSignalRequest = GenerateXSignal(
X_SIGNAL_SHORT,
bar_index,
marketLength,
riskToRewardRatio,
states
);
//
if (xLongSignalRequest.hasSignal) {
//
// Here we can Check and Filter Signals Based On State ...
bool isReady = IsReadyForXSignals(
xLongSignalRequest.signal,
states,
marketLength
);
//
if (isReady && xWaitForLongSignals) {
//
hasLongSignal = true;
signal = xLongSignalRequest.signal;
} else {
ClearXLongSignalConditions();
}
} else if (xShortSignalRequest.hasSignal) {
//
// Here we can Check and Filter Signals Based On State ...
bool isReady = IsReadyForXSignals(
xShortSignalRequest.signal,
states,
marketLength
);
//
if (isReady) {
//
hasShortSignal = true;
signal = xShortSignalRequest.signal;
} else {
ClearXShortSignalConditions();
}
}
//
hasSignal = hasLongSignal || hasShortSignal;
//
if (!hasSignal) {
//
signal.type = X_SIGNAL_NONE;
result.type = X_SIGNAL_NONE;
}
//
// Normalize TP, SL and Entry Price ...
signal.tp = NormalizeDouble(signal.tp, _Digits);
signal.sl = NormalizeDouble(signal.sl, _Digits);
signal.entry = NormalizeDouble(signal.entry, _Digits);
//
result.signal = signal;
result.type = signal.type;
result.hasSignal = hasSignal;
result.provider = signal.provider;
//
// Return Result ...
return result;
}
+335
View File
@@ -0,0 +1,335 @@
//+------------------------------------------------------------------+
//| ROCv2.1.mq4 |
//| Copyright 2015, mrak297. |
//| https://www.mql5.com/ru/users/mrak297 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, mrak297."
#property link "https://www.mql5.com/ru/users/mrak297"
#property version "2.1"
#property strict
#property indicator_separate_window
//--- input parameters
input string Pairs="USDJPY,AUDUSD,EURJPY,EURCHF,EURGBP,EURUSD,GBPUSD,USDCHF,USDCAD";
input ENUM_TIMEFRAMES TimeFrame=PERIOD_D1;//Period for calculating
input ENUM_TIMEFRAMES Per = PERIOD_M15; //Period for new opened charts
input color UPcolor = clrLimeGreen; //Color when moved up
input color DownColor = clrTomato; //Color when moved down
input int PSize = 6; // Pair string size including pre- & suffix
input bool InverseUSD = false; // Invert USDXXX pairs to XXXUSD
//---
int Size=10; //Font size
string Font= "Arial Black";
int BGcolor; //Bars background color
int cF = 100; //Coefficient of scale
int num,Zero,Wbar,Hbar,Xsize,Ysize;
string PairsArray[]; //Array for Pairs Name
double ChangeArray[]; //Array for Pairs Change
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OnInit()
{
EventSetMillisecondTimer(250);
//---
IndicatorShortName("Rate Of Change ("+PeriodToString(TimeFrame)+")");
IndicatorSetDouble(INDICATOR_MAXIMUM,1);
IndicatorSetDouble(INDICATOR_MINIMUM,-1);
//---
BGcolor=(int)ChartGetInteger(0,CHART_COLOR_BACKGROUND);
//---
ushort sep=StringGetCharacter(Pairs,PSize);
num=StringSplit(Pairs,sep,PairsArray);
//---
ArrayResize(ChangeArray,num,num);
//---
Xsize = (int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,1);
Ysize = (int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,1);
//---
Zero=(int)MathRound(ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,1)/2);
//---
Wbar=(int)MathRound((Xsize-15)/num);
//---
if(MathRound(Wbar/5)<MathRound(Ysize/7))
Size=PixToPoints((int)MathRound(Wbar/5));
else Size=PixToPoints((int)MathRound(Ysize/7));
//---
int j=5;
//---
for(int i=0; i<num; i++)
{
CreateRecLabel(PairsArray[i]+"Bar",j,Zero,Wbar,10);
if(InverseUSD){
if(StringFind(PairsArray[i],"USDJPY",0)!=-1){
CreateTextLabel(PairsArray[i]+"Text",j,Zero,"JPYUSD",ANCHOR_LEFT_UPPER);
}
else if(StringFind(PairsArray[i],"USDCHF",0)!=-1){
CreateTextLabel(PairsArray[i]+"Text",j,Zero,"CHFUSD",ANCHOR_LEFT_UPPER);
}
else if(StringFind(PairsArray[i],"USDCAD",0)!=-1){
CreateTextLabel(PairsArray[i]+"Text",j,Zero,"CADUSD",ANCHOR_LEFT_UPPER);
}
else CreateTextLabel(PairsArray[i]+"Text",j,Zero,PairsArray[i],ANCHOR_LEFT_UPPER);
}
if(!InverseUSD){
CreateTextLabel(PairsArray[i]+"Text",j,Zero,PairsArray[i],ANCHOR_LEFT_UPPER);
}
CreateTextLabel(PairsArray[i]+"Change",j,Zero,"NaN",ANCHOR_LEFT_LOWER);
j+=Wbar+1;
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
EventKillTimer();
//---
for(int i=0; i<num; i++)
{
ObjectDelete(PairsArray[i]+"Bar");
ObjectDelete(PairsArray[i]+"Text");
ObjectDelete(PairsArray[i]+"Change");
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
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[])
{
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnTimer()
{
for(int i=0; i<num; i++)
{
if(InverseUSD){
if(StringFind(PairsArray[i],"USDJPY",0)!=-1){
ChangeArray[i]=SymbolChange2(PairsArray[i],TimeFrame);
}
else if(StringFind(PairsArray[i],"USDCHF",0)!=-1){
ChangeArray[i]=SymbolChange2(PairsArray[i],TimeFrame);
}
else if(StringFind(PairsArray[i],"USDCAD",0)!=-1){
ChangeArray[i]=SymbolChange2(PairsArray[i],TimeFrame);
}
else ChangeArray[i]=SymbolChange(PairsArray[i],TimeFrame);
}
if(!InverseUSD){
ChangeArray[i]=SymbolChange(PairsArray[i],TimeFrame);
}
//---
if(ChangeArray[i]<0)
{
ObjectSetInteger(0,PairsArray[i]+"Bar",OBJPROP_YSIZE,(int)MathAbs(ChangeArray[i]*cF));
ObjectSetInteger(0,PairsArray[i]+"Bar",OBJPROP_COLOR,DownColor);
ObjectSetInteger(0,PairsArray[i]+"Text",OBJPROP_COLOR,DownColor);
ObjectSetInteger(0,PairsArray[i]+"Change",OBJPROP_COLOR,DownColor);
ObjectSetInteger(0,PairsArray[i]+"Text",OBJPROP_ANCHOR,ANCHOR_LEFT_LOWER);
ObjectSetInteger(0,PairsArray[i]+"Change",OBJPROP_ANCHOR,ANCHOR_LEFT_UPPER);
ObjectSetString(0,PairsArray[i]+"Change",OBJPROP_TEXT,DoubleToString(ChangeArray[i],2)+"%");
}
else
{
ObjectSetInteger(0,PairsArray[i]+"Bar",OBJPROP_YDISTANCE,(int)(Zero-ChangeArray[i]*cF));
ObjectSetInteger(0,PairsArray[i]+"Bar",OBJPROP_YSIZE,(int)(ChangeArray[i]*cF));
ObjectSetInteger(0,PairsArray[i]+"Bar",OBJPROP_COLOR,UPcolor);
ObjectSetInteger(0,PairsArray[i]+"Text",OBJPROP_COLOR,UPcolor);
ObjectSetInteger(0,PairsArray[i]+"Change",OBJPROP_COLOR,UPcolor);
ObjectSetInteger(0,PairsArray[i]+"Text",OBJPROP_ANCHOR,ANCHOR_LEFT_UPPER);
ObjectSetInteger(0,PairsArray[i]+"Change",OBJPROP_ANCHOR,ANCHOR_LEFT_LOWER);
ObjectSetString(0,PairsArray[i]+"Change",OBJPROP_TEXT,DoubleToString(ChangeArray[i],2)+"%");
}
}
int max = ArrayMaximum(ChangeArray, WHOLE_ARRAY, 0);
int min = ArrayMinimum(ChangeArray, WHOLE_ARRAY, 0);
//---
double tmp=0;
//---
if(ChangeArray[max]>MathAbs(ChangeArray[min])) tmp=ChangeArray[max];
else tmp=MathAbs(ChangeArray[min]);
//---
if(tmp*cF>Ysize/2) cF--;
if((Ysize/2-tmp*cF)>20) cF++;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
if(id==CHARTEVENT_OBJECT_CLICK)
{
string name=StringSubstr(sparam,0,6);
ChartOpen(name,Per);
}
if(id==CHARTEVENT_CHART_CHANGE) OnInit();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double SymbolChange(string symbol,ENUM_TIMEFRAMES period)
{
SymbolSelect(symbol,true);
double perf = 0;
double open = iOpen(symbol, period, 0);
double close = iClose(symbol, period, 0);
//---
if(open!=0)
{
perf=(close-open);
perf /= open;
perf *= 100;
}
else Print("Change NaN");
//---
return(NormalizeDouble(perf, 2));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double SymbolChange2(string symbol,ENUM_TIMEFRAMES period)
{
SymbolSelect(symbol,true);
double perf = 0;
double open = iOpen(symbol, period, 0);
double close = iClose(symbol, period, 0);
//---
if(open!=0)
{
perf=(open-close);
perf /= open;
perf *= 100;
}
else Print("Change NaN");
//---
return(NormalizeDouble(perf, 2));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CreateTextLabel(string name,int x,int y,string text,ENUM_ANCHOR_POINT anchor)
{
ObjectDelete(0,name);
ResetLastError();
//---
if(ObjectCreate(0,name,OBJ_LABEL,1,0,0))
{
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER);
ObjectSetString(0,name,OBJPROP_TEXT,text);
ObjectSetString(0,name,OBJPROP_FONT,Font);
ObjectSetInteger(0,name,OBJPROP_FONTSIZE,Size);
ObjectSetDouble(0,name,OBJPROP_ANGLE,0.0);
ObjectSetInteger(0,name,OBJPROP_ANCHOR,anchor);
ObjectSetInteger(0,name,OBJPROP_COLOR,clrBlue);
ObjectSetInteger(0,name,OBJPROP_BACK,false);
ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
ObjectSetInteger(0,name,OBJPROP_ZORDER,1);
ObjectSetString(0,name,OBJPROP_TOOLTIP,"\n");
}
else Print("ERROR Creating object.",GetLastError());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CreateRecLabel(string name,int x,int y,int xsize,int ysize)
{
ObjectDelete(0,name);
ResetLastError();
//---
if(ObjectCreate(0,name,OBJ_RECTANGLE_LABEL,1,0,0))
{
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
ObjectSetInteger(0,name,OBJPROP_XSIZE,xsize);
ObjectSetInteger(0,name,OBJPROP_YSIZE,ysize);
ObjectSetInteger(0,name,OBJPROP_BGCOLOR,BGcolor);
ObjectSetInteger(0,name,OBJPROP_BORDER_TYPE,BORDER_FLAT);
ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER);
ObjectSetInteger(0,name,OBJPROP_COLOR,clrDodgerBlue);
ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID);
ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
ObjectSetInteger(0,name,OBJPROP_BACK,false);
ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
ObjectSetInteger(0,name,OBJPROP_ZORDER,0);
ObjectSetString(0,name,OBJPROP_TOOLTIP,"\n");
}
else Print("ERROR Creating object.",GetLastError());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int PixToPoints(int pix)
{
int pt=0;
int ems[28][2]=
{
6,8,7,9,7,10,8,11,9,12,10,13,10,14,11,15,12,16,13,17,13,18,14,19,14,20,15,21,16,22,
17,23,18,24,20,26,22,29,24,32,26,35,27,36,28,37,29,38,30,40,32,42,34,45,36,48
};
//---
if(pix<8)
return(6);
if(pix>48)
return(36);
//---
for(int i=0; i<28; i++)
{
if(pix==ems[i][1])
{
pt=ems[i][0];
break;
}
}
return(pt);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string PeriodToString(ENUM_TIMEFRAMES tframe)
{
string result=" ";
string PeriodArray[9][2]=
{
"M1","1",
"M5","5",
"M15","15",
"M30","30",
"H1","60",
"H4","240",
"D1","1440",
"W1","10080",
"MN1","43200"
};
for(int i=0; i<9; i++)
{
if((string)tframe==PeriodArray[i][1])
{
result=PeriodArray[i][0];
break;
}
}
return(result);
}
//+--------------------------------------------------------------------+
+62
View File
@@ -0,0 +1,62 @@
#property copyright "www.forex-station.com"
#property link "www.forex-station.com"
//---- indicator settings
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern int RPeriod = 10;
extern bool UsePercent = false;
//---- indicator buffers
double RateOfChange[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- drawing settings
SetIndexStyle(0, DRAW_LINE);
SetIndexDrawBegin(0, RPeriod);
IndicatorDigits(Digits + 1);
//---- indicator buffers mapping
if(!SetIndexBuffer(0, RateOfChange))
Print("cannot set indicator buffers!");
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("ROC(" + RPeriod + ")");
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence |
//+------------------------------------------------------------------+
int start()
{
int limit;
double ROC, CurrentClose, PrevClose;
int counted_bars = IndicatorCounted();
//---- check for possible errors
if(counted_bars < 0)
return(-1);
//---- last counted bar will be recounted
if(counted_bars > 0)
counted_bars--;
limit = MathMin(Bars - counted_bars,Bars-1);
//---- ROC calculation
for(int i = 0; i < limit; i++)
{
CurrentClose = iClose(NULL, 0, i);
PrevClose = iClose(NULL, 0, i + RPeriod);
ROC = CurrentClose - PrevClose;
//----
if(UsePercent)
{
if(PrevClose != 0)
RateOfChange[i] = 100 * ROC / PrevClose;
}
else
RateOfChange[i] = ROC;
}
//---- done
return(0);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,190 @@
#property copyright "www.forex-station.com"
#property link "www.forex-station.com"
//---- indicator settings
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern string strROC = "ROC Period for lookback";
extern int RPeriod = 10;
extern string sep0 = "----------------------------------";
extern string strMA = "MA input parameters";
extern int MAPeriod=14;
extern string sep1 = "----------------------------------";
extern string strType = "Moving Average Types" ;
extern string str0 = "0 = SMA, 1 = EMA, 2 = SMMA";
extern string str1 = "3 = LWMA, 4 = LSMA, 5 = NLMA";
extern int MAType = 1;
extern string sep2 = "----------------------------------";
extern string strAP = "Applied Price Types";
extern string str2 = "0=close, 1=open, 2=high";
extern string str3 = "3=low, 4=median(high+low)/2";
extern string str4 = " 5=typical(high+low+close)/3";
extern string str5 = "6=weighted(high+low+close+close)/4";
extern int MAAppliedPrice = 0;
extern string sep3 = "----------------------------------";
extern string str6 = "NonLagMA Deviation";
extern double Deviation = 0;
extern bool UsePercent = false;
//---- indicator buffers
double RateOfChange[];
//---- variables
int MAMode;
string strMAType;
// Variables for NonLag
int Phase;
double Len;
double Cycle = 4;
double pi = 3.1415926535;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- drawing settings
SetIndexStyle(0,DRAW_LINE);
SetIndexDrawBegin(0,RPeriod);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+1);
//---- indicator buffers mapping
if(!SetIndexBuffer(0,RateOfChange))
Print("cannot set indicator buffers!");
switch (MAType)
{
case 1: strMAType="EMA"; MAMode=MODE_EMA; break;
case 2: strMAType="SMMA"; MAMode=MODE_SMMA; break;
case 3: strMAType="LWMA"; MAMode=MODE_LWMA; break;
case 4: strMAType="LSMA"; break;
case 5: strMAType="NLMA";break;
default: strMAType="SMA"; MAMode=MODE_SMA; break;
}
IndicatorShortName( "ROC (" + RPeriod + ")_Smoothed_" + strMAType+ " (" +MAPeriod + ") ");
//---- name for DataWindow and indicator subwindow label
SetIndexLabel(0,"ROC_Smoothed");
// Variables for NonLag
Phase = MAPeriod-1;
Len = MAPeriod*Cycle + Phase;
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| LSMA with PriceMode |
//| PrMode 0=close, 1=open, 2=high, 3=low, 4=median(high+low)/2, |
//| 5=typical(high+low+close)/3, 6=weighted(high+low+close+close)/4 |
//+------------------------------------------------------------------+
double LSMA(int Rperiod, int prMode, int shift)
{
int i;
double sum, pr;
int length;
double lengthvar;
double tmp;
double wt;
length = Rperiod;
sum = 0;
for(i = length; i >= 1 ; i--)
{
lengthvar = length + 1;
lengthvar /= 3;
tmp = 0;
switch (prMode)
{
case 0: pr = Close[length-i+shift];break;
case 1: pr = Open[length-i+shift];break;
case 2: pr = High[length-i+shift];break;
case 3: pr = Low[length-i+shift];break;
case 4: pr = (High[length-i+shift] + Low[length-i+shift])/2;break;
case 5: pr = (High[length-i+shift] + Low[length-i+shift] + Close[length-i+shift])/3;break;
case 6: pr = (High[length-i+shift] + Low[length-i+shift] + Close[length-i+shift] + Close[length-i+shift])/4;break;
}
tmp = ( i - lengthvar)*pr;
sum+=tmp;
}
wt = MathFloor(sum*6/(length*(length+1))/Point)*Point;
return(wt);
}
double NonLag(int RPeriod, int myLen, double myPhase, int myShift)
{
int i;
double alfa, beta, t, Sum, Weight,g;
double myPrice;
double Coeff = 3*pi;
Weight=0; Sum=0; t=0;
for (i=0;i<=myLen-1;i++)
{
g = 1.0/(Coeff*t+1);
if (t <= 0.5 ) g = 1;
beta = MathCos(pi*t);
alfa = g * beta;
myPrice = iMA(NULL,0,1,0,MODE_SMA,MAAppliedPrice,myShift+i);
Sum += alfa*myPrice;
Weight += alfa;
if ( t < 1 ) t += 1.0/(myPhase-1);
else if ( t < myLen-1 ) t += (2*Cycle-1)/(Cycle*RPeriod-1);
}
if (Weight > 0) Weight = (1.0+Deviation/100)*Sum/Weight;
Weight = MathFloor(Weight/Point)*Point;
return (Weight);
}
//+------------------------------------------------------------------+
//| Rate of Change Smoothed |
//+------------------------------------------------------------------+
int start()
{
int limit;
double ROC, MA_Cur, MA_Prev;
int counted_bars=IndicatorCounted();
//---- check for possible errors
if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
//---- ROC calculation
for(int i=0; i<limit; i++)
{
if (MAType == 4)
{
MA_Cur = LSMA(MAPeriod, MAAppliedPrice,i);
MA_Prev = LSMA(MAPeriod, MAAppliedPrice,i+RPeriod);
}
else if (MAType == 5)
{
MA_Cur = NonLag(MAPeriod, Len, Phase, i);
MA_Prev = NonLag(MAPeriod, Len, Phase, i+RPeriod);
}
else
{
MA_Cur = iMA(NULL,0,MAPeriod,0,MAMode, MAAppliedPrice,i);
MA_Prev = iMA(NULL,0,MAPeriod,0,MAMode, MAAppliedPrice,i+RPeriod);
}
ROC=MA_Cur-MA_Prev;
if (UsePercent)
{
RateOfChange[i] = 100 * ROC / MA_Prev;
}
else
{
RateOfChange[i] = NormalizeDouble(ROC/Point,1);
}
}
//---- done
return(0);
}
@@ -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,257 @@
/////////////////////////////////////////////////////////////////
//
// 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 2
//
// also we have 2 line for draw on this indicator ...
#property indicator_plots 2
//
// 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
//
// 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
//
double fastOSCBuffer[];
double slowOSCBuffer[];
//
// 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);
//
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;
}
//
// 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,402 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XSHPD 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 XSHPD Indicator"
#property strict
//
// START Inputs ...
//
input int marketLength = 7; // Market Length ...
input double sharpDetectMultiplier = 70; // Sharp Detect Multiplier
//
input bool drawLabels = true; // Draw Labels on Founded Sharps
//
input string sharpBullishLabel = "SH_BULL"; // Sharp Bullish Label
input color sharpBullishColor = clrAqua; // Sharp Bullish color
//
input string sharpBearishLabel = "SH_BEAR"; // Sharp Bearish Label
input color sharpBearishColor = clrFuchsia; // Sharp Bearish color
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 4
//
// Declare Buffers ...
#define marketHighestHighBufferIndex 0
#define marketLowestLowBufferIndex 1
#define sharpBullishBufferIndex 2
#define sharpBearishBufferIndex 3
//
double marketHighestHighBuffer[];
double marketLowestLowBuffer[];
double sharpBullishBuffer[];
double sharpBearishBuffer[];
//
#include "../Libraries/x-saherelm.lib.mq4"
#include "../Libraries/x-saherelm.draw.lib.mq4"
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
if (
marketLength <= 0
) {
return INIT_PARAMETERS_INCORRECT;
}
//
enableLogging = true;
//
logTag = "X_SHPD";
//
// Highest High ...
SetIndexLabel(marketHighestHighBufferIndex, "");
SetIndexBuffer(marketHighestHighBufferIndex, marketHighestHighBuffer);
SetIndexStyle(
marketHighestHighBufferIndex,
DRAW_LINE, // DRAW_NONE,
STYLE_DOT,
1, // 0,
clrAqua // clrNONE
);
//
// Lowest Low ...
SetIndexLabel(marketLowestLowBufferIndex, "");
SetIndexBuffer(marketLowestLowBufferIndex, marketLowestLowBuffer);
SetIndexStyle(
marketLowestLowBufferIndex,
DRAW_NONE,
STYLE_DOT,
0,
clrNONE
);
//
// Sharp Bullish Buffer ...
SetIndexLabel(sharpBullishBufferIndex, "");
SetIndexBuffer(sharpBullishBufferIndex, sharpBullishBuffer);
SetIndexStyle(
sharpBullishBufferIndex,
DRAW_NONE,
STYLE_DOT,
0,
clrNONE
);
//
// Sharp Bearish Buffer ...
SetIndexLabel(sharpBearishBufferIndex, "");
SetIndexBuffer(sharpBearishBufferIndex, sharpBearishBuffer);
SetIndexStyle(
sharpBearishBufferIndex,
DRAW_NONE,
STYLE_DOT,
0,
clrNONE
);
//
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason) {
//
RemoveDraws(logTag);
}
//
// 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, marketLength);
//
// 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 Sharp ...
CalculateSharp(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculating Sharp ...
void CalculateSharp(
const int &bar_index
) {
//
int index = 0;
//
double high = iHigh(
_Symbol,
_Period,
bar_index + 1
);
//
double low = iLow(
_Symbol,
_Period,
bar_index + 1
);
//
double open = iOpen(
_Symbol,
_Period,
bar_index + 1
);
//
double close = iClose(
_Symbol,
_Period,
bar_index + 1
);
//
marketHighestHighBuffer[bar_index] = GetMarketHighestHigh(
bar_index,
marketLength
);
//
marketLowestLowBuffer[bar_index] = GetMarketLowestLow(
bar_index,
marketLength
);
//
double maHHs[];
ArrayResize(
maHHs,
marketLength
);
//
double maLLs[];
ArrayResize(
maLLs,
marketLength
);
//
index = 0;
for (int i = bar_index; i < bar_index + marketLength; i++) {
//
maLLs[index] = marketLowestLowBuffer[i];
maHHs[index] = marketHighestHighBuffer[i];
//
index++;
}
//
int maxHighIdx = ArrayMaximum(maHHs);
double maxHigh = maHHs[maxHighIdx];
//
int minHighIdx = ArrayMinimum(maHHs);
double minHigh = maHHs[minHighIdx];
//
double highDiffRate = (maxHigh - minHigh) / 100;
//
int maxLowIdx = ArrayMaximum(maLLs);
double maxLow = maLLs[maxLowIdx];
//
int minLowIdx = ArrayMinimum(maLLs);
double minLow = maLLs[minLowIdx];
//
double lowDiffRate = (maxLow - minLow) / 100;
//
bool isSharpBullishDetected =
high == maxHigh
&& low > minLow
&& marketHighestHighBuffer[bar_index] == maxHigh
&& maxHigh - minHigh > highDiffRate * sharpDetectMultiplier
;
sharpBullishBuffer[bar_index] = isSharpBullishDetected ? 1 : 0;
//
bool isSharpBearishDetected =
low == minLow
&& high < maxHigh
&& marketLowestLowBuffer[bar_index] == minLow
&& maxLow - minLow > lowDiffRate * sharpDetectMultiplier
;
sharpBearishBuffer[bar_index] = isSharpBearishDetected ? 1 : 0;
//
if (
drawLabels
&& (
isSharpBearishDetected
|| isSharpBullishDetected
)
) {
//
datetime time = iTime(
_Symbol,
_Period,
bar_index
);
//
string lbl = StringConcatenate(
logTag,
isSharpBullishDetected ? "Bullish_" : "Bearish_",
bar_index
);
//
double price =
isSharpBullishDetected
?
marketLowestLowBuffer[bar_index] - (10 * _Point)
:
marketHighestHighBuffer[bar_index] + (10 * _Point)
;
//
uchar arrowCode =
isSharpBullishDetected
?
SYMBOL_ARROWUP
:
SYMBOL_ARROWDOWN
;
//
ENUM_ARROW_ANCHOR anchor =
isSharpBullishDetected
?
ANCHOR_BOTTOM
:
ANCHOR_TOP
;
//
color clr =
isSharpBullishDetected
?
sharpBullishColor
:
sharpBearishColor
;
//
string lblText =
isSharpBullishDetected
?
sharpBullishLabel
:
sharpBearishLabel
;
//
DrawText(
0,
lbl,
0,
time,
price,
lblText,
"Tahoma",
5,
clr
);
}
}
//
// END Functions ...
//
@@ -0,0 +1,250 @@
///////////////////////////////////////////////////////
//
// 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
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
#property indicator_chart_window
//
// #property indicator_buffers 3
//
// Declare Buffers ...
//
datetime startTime;
double lHigh;
double lLow;
//
datetime highTimes[];
//
datetime lowTimes[];
//
// 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;
}
//
// 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 ...
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
startTime
);
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
if (startTime == 0) {
//
startTime = barTime;
return;
}
//
if (
startTime > 0
&& startBarIndex - bar_index == length
) {
//
int hhIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
length,
bar_index
);
datetime hhTime = iTime(
_Symbol,
_Period,
hhIdx
);
double hh = iHigh(
_Symbol,
_Period,
hhIdx
);
//
int hhSize = ArraySize(highTimes);
datetime tempTimes[];
ArrayResize(
tempTimes,
hhSize
);
ArrayCopy(
tempTimes,
highTimes
);
ArrayResize(
highTimes,
hhSize + 1
);
highTimes[0] = hhTime;
ArrayCopy(
highTimes,
tempTimes,
1
);
//
int llIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
length,
bar_index
);
datetime llTime = iTime(
_Symbol,
_Period,
llIdx
);
double ll = iLow(
_Symbol,
_Period,
llIdx
);
//
int llSize = ArraySize(lowTimes);
ArrayFree(tempTimes);
ArrayResize(
tempTimes,
llSize
);
ArrayCopy(
tempTimes,
lowTimes
);
ArrayResize(
lowTimes,
llSize + 1
);
lowTimes[0] = llTime;
ArrayCopy(
lowTimes,
tempTimes,
1
);
//
startTime = 0;
ArrayFree(tempTimes);
}
}
//
// END Functions ...
//
@@ -0,0 +1,412 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center X Indicator
// ---------------------------------------------
// saherelm implementation of above indicator ...
//
// 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 X Indicator"
#property strict
//
// START Inputs ...
//
//
input int marketLength = 7; // Market Length
//
input int shortCycleMultiplier = 2; // Market Short Cycle Multiplier
input int mediumCycleMultiplier = 6; // Market Medium Cycle Multiplier
input int longCycleMultiplier = 36; // Market Medium Cycle Multiplier
//
input ENUM_MA_METHOD maMethod = MODE_SMA; // Ma Method
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
#property indicator_buffers 6
//
#property indicator_plots 6
//
// Start Define Indicator Buffer Styles ...
//
//
// Short Cycle Highest High Buffer ...
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//
// Short Cycle Lowest Low Buffer ...
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
// Medium Cycle Highest High Buffer ...
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrAqua
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
// Medium Cycle Lowest Low Buffer ...
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrFuchsia
#property indicator_style4 STYLE_DOT
#property indicator_width4 1
//
// Long Cycle Highest High Buffer ...
#property indicator_type5 DRAW_LINE
#property indicator_color5 C'62,82,6'
#property indicator_style5 STYLE_DOT
#property indicator_width5 1
//
// Long Cycle Lowest Low Buffer ...
#property indicator_type6 DRAW_LINE
#property indicator_color6 C'255,81,0'
#property indicator_style6 STYLE_DOT
#property indicator_width6 1
//
// End Define Indicator Buffer Styles ...
//
//
// Buffers ...
//
// HH Buffers ...
#define scHHBufferIndex 0
#define scLLBufferIndex 1
#define mcHHBufferIndex 2
#define mcLLBufferIndex 3
#define lcHHBufferIndex 4
#define lcLLBufferIndex 5
double scHHBuffer[];
double scLLBuffer[];
double mcHHBuffer[];
double mcLLBuffer[];
double lcHHBuffer[];
double lcLLBuffer[];
//
// Variables ...
int shortCycleLength;
int mediumCycleLength;
int longCycleLength;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
if (
marketLength <= 0 ||
shortCycleMultiplier <= 0 ||
mediumCycleMultiplier <= 0 ||
shortCycleMultiplier > mediumCycleMultiplier
) {
return INIT_PARAMETERS_INCORRECT;
}
//
// Start Set Index Buffers ...
//
shortCycleLength = shortCycleMultiplier * marketLength;
mediumCycleLength = mediumCycleMultiplier * marketLength;
longCycleLength = longCycleMultiplier * marketLength;
//
// Highest High and Lowest Low Buffers ...
//
// Short Cycle Highest High ...
string scHHLbl = StringConcatenate(
"SC HH(", shortCycleLength, ")"
);
SetIndexBuffer(scHHBufferIndex, scHHBuffer);
SetIndexLabel(scHHBufferIndex, scHHLbl);
//
// Short Cycle Lowest Low ...
string scLLLbl = StringConcatenate(
"SC LL(", shortCycleLength, ")"
);
SetIndexBuffer(scLLBufferIndex, scLLBuffer);
SetIndexLabel(scLLBufferIndex, scLLLbl);
//
// Medium Cycle Highest High ...
string mcHHLbl = StringConcatenate(
"MC HH(", mediumCycleLength, ")"
);
SetIndexBuffer(mcHHBufferIndex, mcHHBuffer);
SetIndexLabel(mcHHBufferIndex, mcHHLbl);
//
// Medium Cycle Lowest Low ...
string mcLLLbl = StringConcatenate(
"MC LL(", mediumCycleLength, ")"
);
SetIndexBuffer(mcLLBufferIndex, mcLLBuffer);
SetIndexLabel(mcLLBufferIndex, mcLLLbl);
//
// Long Cycle Highest High ...
string lcHHLbl = StringConcatenate(
"LC HH(", longCycleLength, ")"
);
SetIndexBuffer(lcHHBufferIndex, lcHHBuffer);
SetIndexLabel(lcHHBufferIndex, lcHHLbl);
//
// Long Cycle Lowest Low ...
string lcLLLbl = StringConcatenate(
"LC LL(", longCycleLength, ")"
);
SetIndexBuffer(lcLLBufferIndex, lcLLBuffer);
SetIndexLabel(lcLLBufferIndex, lcLLLbl);
//
// 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, marketLength);
//
// 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 ...
//
// Calculat Ma's ...
//
CalculateShortCycle(i);
//
CalculateMediumCycle(i);
//
CalculateLongCycle(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculating Short Cycle ...
void CalculateShortCycle(
const int &bar_index
) {
//
// Short Cycle Highest High ...
//
int scHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
shortCycleLength,
bar_index
);
//
double scHH = iHigh(
_Symbol,
_Period,
scHHIdx
);
//
scHHBuffer[bar_index] = scHH;
//
// Short Cycle Lowest Low ...
//
int scLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
shortCycleLength,
bar_index
);
//
double scLL = iLow(
_Symbol,
_Period,
scLLIdx
);
//
scLLBuffer[bar_index] = scLL;
}
//
// Calculating Medium Cycle ...
void CalculateMediumCycle(
const int &bar_index
) {
//
// Medium Cycle Highest High ...
//
int mcHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
mediumCycleLength,
bar_index
);
//
double mcHH = iHigh(
_Symbol,
_Period,
mcHHIdx
);
//
mcHHBuffer[bar_index] = mcHH;
//
// Medium Cycle Lowest Low ...
//
int mcLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
mediumCycleLength,
bar_index
);
//
double mcLL = iLow(
_Symbol,
_Period,
mcLLIdx
);
//
mcLLBuffer[bar_index] = mcLL;
}
//
// Calculating Long Cycle ...
void CalculateLongCycle(
const int &bar_index
) {
//
// Long Cycle Highest High ...
//
int lcHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
longCycleLength,
bar_index
);
//
double lcHH = iHigh(
_Symbol,
_Period,
lcHHIdx
);
//
lcHHBuffer[bar_index] = lcHH;
//
// Long Cycle Lowest Low ...
//
int lcLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
longCycleLength,
bar_index
);
//
double lcLL = iLow(
_Symbol,
_Period,
lcLLIdx
);
//
lcLLBuffer[bar_index] = lcLL;
}
//
// END Functions ...
//
@@ -0,0 +1,355 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center X Indicator
// ---------------------------------------------
// saherelm implementation of above indicator ...
//
// 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 X Indicator"
#property strict
//
// START Inputs ...
//
//
input int marketLength = 7; // Market Length
//
input int shortCycleMultiplier = 2; // Market Short Cycle Multiplier
input int mediumCycleMultiplier = 6; // Market Medium Cycle Multiplier
input int longCycleMultiplier = 36; // Market Medium Cycle Multiplier
//
input ENUM_MA_METHOD maMethod = MODE_SMA; // Ma Method
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
#property indicator_buffers 6
//
#property indicator_plots 6
//
// Start Define Indicator Buffer Styles ...
//
//
// Short Cycle Fast Buffer ...
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//
// Short Cycle Slow Buffer ...
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
// Medium Cycle Fast Buffer ...
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrAqua
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
// Medium Cycle Slow Buffer ...
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrFuchsia
#property indicator_style4 STYLE_DOT
#property indicator_width4 1
//
// Long Cycle Fast Buffer ...
#property indicator_type5 DRAW_LINE
#property indicator_color5 C'62,82,6'
#property indicator_style5 STYLE_DOT
#property indicator_width5 1
//
// Long Cycle Slow Buffer ...
#property indicator_type6 DRAW_LINE
#property indicator_color6 C'255,81,0'
#property indicator_style6 STYLE_DOT
#property indicator_width6 1
//
// End Define Indicator Buffer Styles ...
//
//
// Buffers ...
//
// Ma Buffers ...
#define scFastBufferIndex 0
#define scSlowBufferIndex 1
#define mcFastBufferIndex 2
#define mcSlowBufferIndex 3
#define lcFastBufferIndex 4
#define lcSlowBufferIndex 5
double scFastBuffer[];
double scSlowBuffer[];
double mcFastBuffer[];
double mcSlowBuffer[];
double lcFastBuffer[];
double lcSlowBuffer[];
//
// Variables ...
int shortCycleLength;
int mediumCycleLength;
int longCycleLength;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
if (
marketLength <= 0 ||
shortCycleMultiplier <= 0 ||
mediumCycleMultiplier <= 0 ||
shortCycleMultiplier > mediumCycleMultiplier
) {
return INIT_PARAMETERS_INCORRECT;
}
//
// Start Set Index Buffers ...
//
shortCycleLength = shortCycleMultiplier * marketLength;
mediumCycleLength = mediumCycleMultiplier * marketLength;
longCycleLength = longCycleMultiplier * marketLength;
//
// Ma Buffers ...
//
// Short Cycle ...
string scFLbl = StringConcatenate(
"SC F(", shortCycleLength, ")"
);
SetIndexBuffer(scFastBufferIndex, scFastBuffer);
SetIndexLabel(scFastBufferIndex, scFLbl);
//
string scSLbl = StringConcatenate(
"SC S(", shortCycleLength, ")"
);
SetIndexBuffer(scSlowBufferIndex, scSlowBuffer);
SetIndexLabel(scSlowBufferIndex, scSLbl);
//
// Medium Cycle ...
string mcFLbl = StringConcatenate(
"MC F(", mediumCycleLength, ")"
);
SetIndexBuffer(mcFastBufferIndex, mcFastBuffer);
SetIndexLabel(mcFastBufferIndex, mcFLbl);
//
string mcSLbl = StringConcatenate(
"MC S(", mediumCycleLength, ")"
);
SetIndexBuffer(mcSlowBufferIndex, mcSlowBuffer);
SetIndexLabel(mcSlowBufferIndex, mcSLbl);
//
// Long Cycle ...
string lcFLbl = StringConcatenate(
"LC F(", longCycleLength, ")"
);
SetIndexBuffer(lcFastBufferIndex, lcFastBuffer);
SetIndexLabel(lcFastBufferIndex, lcFLbl);
//
string lcSLbl = StringConcatenate(
"LC S(", longCycleLength, ")"
);
SetIndexBuffer(lcSlowBufferIndex, lcSlowBuffer);
SetIndexLabel(lcSlowBufferIndex, lcSLbl);
//
// 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, marketLength);
//
// 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 ...
//
// Calculat Ma's ...
//
CalculateShortCycle(i);
//
CalculateMediumCycle(i);
//
CalculateLongCycle(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculating Short Cycle ...
void CalculateShortCycle(
const int &bar_index
) {
//
double scFast = iMA(
_Symbol,
_Period,
shortCycleLength,
0,
maMethod,
PRICE_OPEN,
bar_index
);
scFastBuffer[bar_index] = scFast;
//
double scSlow = iMA(
_Symbol,
_Period,
shortCycleLength,
0,
maMethod,
PRICE_CLOSE,
bar_index
);
scSlowBuffer[bar_index] = scSlow;
}
//
// Calculating Medium Cycle ...
void CalculateMediumCycle(
const int &bar_index
) {
//
double mcFast = iMA(
_Symbol,
_Period,
mediumCycleLength,
0,
maMethod,
PRICE_OPEN,
bar_index
);
mcFastBuffer[bar_index] = mcFast;
//
double mcSlow = iMA(
_Symbol,
_Period,
mediumCycleLength,
0,
maMethod,
PRICE_CLOSE,
bar_index
);
mcSlowBuffer[bar_index] = mcSlow;
}
//
// Calculating Long Cycle ...
void CalculateLongCycle(
const int &bar_index
) {
//
double lcFast = iMA(
_Symbol,
_Period,
longCycleLength,
0,
maMethod,
PRICE_OPEN,
bar_index
);
lcFastBuffer[bar_index] = lcFast;
//
double lcSlow = iMA(
_Symbol,
_Period,
longCycleLength,
0,
maMethod,
PRICE_CLOSE,
bar_index
);
lcSlowBuffer[bar_index] = lcSlow;
}
//
// END Functions ...
//
@@ -0,0 +1,425 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XBand Indicator
// ---------------------------------------------
// saherelm implementation of xBand Indicator ...
//
// 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 XBND Indicator"
#property strict
//
#include "../Libraries/x-saherelm.lib.mq4"
#include "../Libraries/x-saherelm.draw.lib.mq4"
//
// START Inputs ...
//
input int marketLength = 5; // Averaging Length
input int ignoreLastCross = 4; // Ignore Last Cross
input int shift = 0; // Averaging Shift
input ENUM_MA_METHOD method = MODE_SMA; // Averaging Mode
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
#property indicator_chart_window
//
#property indicator_buffers 4
//
// Declare Buffers ...
//
// High ...
#property indicator_width1 1
#property indicator_color1 clrAqua
#property indicator_type1 DRAW_LINE
#property indicator_style1 STYLE_DASHDOT
//
// Open ...
#property indicator_width2 1
#property indicator_color2 clrGreen
#property indicator_type2 DRAW_LINE
#property indicator_style2 STYLE_DASH
//
// Close ...
#property indicator_width3 1
#property indicator_color3 clrRed
#property indicator_type3 DRAW_LINE
#property indicator_style3 STYLE_DASH
//
// Low ...
#property indicator_width4 1
#property indicator_color4 clrFuchsia
#property indicator_type4 DRAW_LINE
#property indicator_style4 STYLE_DASHDOT
//
#define highBufferIndex 0
#define openBufferIndex 1
#define closeBufferIndex 2
#define lowBufferIndex 3
//
double highBuffer[];
double openBuffer[];
double closeBuffer[];
double lowBuffer[];
//
datetime lastCrossTime;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
//
// Validating Input Parameters ...
if (
marketLength < 2
|| ignoreLastCross < 0
) {
return INIT_PARAMETERS_INCORRECT;
}
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XBND";
//
// High ...
string highLabel = StringConcatenate(
"High(", marketLength, ")"
);
SetIndexBuffer(highBufferIndex, highBuffer);
SetIndexLabel(highBufferIndex, highLabel);
//
// Open ...
string openLabel = StringConcatenate(
"Open(", marketLength, ")"
);
SetIndexBuffer(openBufferIndex, openBuffer);
SetIndexLabel(openBufferIndex, openLabel);
//
// Close ...
string closeLabel = StringConcatenate(
"Close(", marketLength, ")"
);
SetIndexBuffer(closeBufferIndex, closeBuffer);
SetIndexLabel(closeBufferIndex, closeLabel);
//
// Low ...
string lowLabel = StringConcatenate(
"Low(", marketLength, ")"
);
SetIndexBuffer(lowBufferIndex, lowBuffer);
SetIndexLabel(lowBufferIndex, lowLabel);
//
// 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(0, marketLength);
//
// 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 Buffers ...
CalculateBuffers(i);
//
// Calculate Market Changes ...
CalculateInfo(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
void CalculateBuffers(
const int bar_index
) {
//
// High ...
double high = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_HIGH,
bar_index
);
//
highBuffer[bar_index] = high;
//
// Open ...
double open = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_OPEN,
bar_index
);
//
openBuffer[bar_index] = open;
//
// Close ...
double close = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_CLOSE,
bar_index
);
//
closeBuffer[bar_index] = close;
//
// Low ...
double low = iMA(
_Symbol,
_Period,
marketLength,
shift,
method,
PRICE_LOW,
bar_index
);
//
lowBuffer[bar_index] = low;
}
//
void CalculateInfo(
const int bar_index
) {
//
XOHCL pCandle = GetCandleModel(bar_index);
//
bool isTrendingUp =
pCandle.low > highBuffer[bar_index]
&& pCandle.high > highBuffer[bar_index];
//
bool isTrendingDown =
pCandle.high < lowBuffer[bar_index]
&& pCandle.low < lowBuffer[bar_index];
//
bool isOpenCrossOverClose =
true
// &&
// (
// pCandle.high > highBuffer[bar_index + 1]
// || pCandle.low < lowBuffer[bar_index + 1]
// )
&& openBuffer[bar_index + 1] > closeBuffer[bar_index + 1]
&& !(openBuffer[bar_index + 2] >= closeBuffer[bar_index + 2])
;
//
bool isOpenCrossUnderClose =
true
// &&
// (
// pCandle.high > highBuffer[bar_index + 1]
// || pCandle.low < lowBuffer[bar_index + 1]
// )
&& openBuffer[bar_index + 1] < closeBuffer[bar_index + 1]
&& !(openBuffer[bar_index + 2] <= closeBuffer[bar_index + 2])
;
//
isTrendingUp = isOpenCrossUnderClose;
isTrendingDown = isOpenCrossOverClose;
//
datetime time = iTime(
_Symbol,
_Period,
bar_index
);
//
if (
isTrendingUp
|| isTrendingDown
) {
//
if (lastCrossTime == 0) {
lastCrossTime = time;
} else {
//
int lastCrossBarIndex = iBarShift(
_Symbol,
_Period,
lastCrossTime
);
//
int diff = lastCrossBarIndex - bar_index;
if (diff <= ignoreLastCross) {
return;
} else {
lastCrossTime = time;
}
}
}
//
string lbl = StringConcatenate(
logTag,
"_Arrow_",
isTrendingUp ? "UP" : "Down",
"_", time
);
//
color clr = isTrendingUp ?
clrAqua :
clrFuchsia;
//
ENUM_ARROW_ANCHOR anchor = isTrendingUp ?
ANCHOR_BOTTOM :
ANCHOR_TOP;
//
uchar arrowCode = isTrendingUp ?
SYMBOL_ARROWUP :
SYMBOL_ARROWDOWN;
//
double price = isTrendingUp ?
pCandle.low - 20 * _Point :
pCandle.high + 20 * _Point;
//
if (isTrendingUp) {
//
// this means Market Going Up ...
}
//
if (isTrendingDown) {
//
// this means Market Going Downm ...
}
//
if (
isTrendingUp
|| isTrendingDown
) {
//
bool isDrawn = DrawArrow(
0,
lbl,
0,
time,
price,
arrowCode,
anchor,
clr
);
}
}
//
// END Functions ...
//
@@ -0,0 +1,410 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XHH 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 XHH Indicator"
#property strict
//
// START Inputs ...
//
//
input int marketLength = 7; // Market Length
//
input int shortCycleMultiplier = 4; // Market Short Cycle Multiplier
input int mediumCycleMultiplier = 14; // Market Medium Cycle Multiplier
input int longCycleMultiplier = 27; // Market Medium Cycle Multiplier
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
#property indicator_buffers 6
//
#property indicator_plots 6
//
// Start Define Indicator Buffer Styles ...
//
//
// Short Cycle Highest High Buffer ...
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//
// Short Cycle Lowest Low Buffer ...
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
// Medium Cycle Highest High Buffer ...
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrAqua
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
// Medium Cycle Lowest Low Buffer ...
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrFuchsia
#property indicator_style4 STYLE_DOT
#property indicator_width4 1
//
// Long Cycle Highest High Buffer ...
#property indicator_type5 DRAW_LINE
#property indicator_color5 C'62,82,6'
#property indicator_style5 STYLE_DOT
#property indicator_width5 1
//
// Long Cycle Lowest Low Buffer ...
#property indicator_type6 DRAW_LINE
#property indicator_color6 C'255,81,0'
#property indicator_style6 STYLE_DOT
#property indicator_width6 1
//
// End Define Indicator Buffer Styles ...
//
//
// Buffers ...
#define shortCycleHighestHighBufferIndex 0
#define shortCycleLowestLowBufferIndex 1
#define mediumCycleHighestHighBufferIndex 2
#define mediumCycleLowestLowBufferIndex 3
#define longCycleHighestHighBufferIndex 4
#define longCycleLowestLowBufferIndex 5
double shortCycleHighestHighBuffer[];
double shortCycleLowestLowBuffer[];
double mediumCycleHighestHighBuffer[];
double mediumCycleLowestLowBuffer[];
double longCycleHighestHighBuffer[];
double longCycleLowestLowBuffer[];
//
// Variables ...
int shortCycleLength;
int mediumCycleLength;
int longCycleLength;
//
double highestHighTimes[];
double lowestLowTimes[];
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// Start Event Handlers ...
//
//
// Initialization ...
int OnInit() {
//
// Initialize what we want ...
if (
marketLength <= 0 ||
shortCycleMultiplier <= 0 ||
mediumCycleMultiplier <= 0 ||
shortCycleMultiplier > mediumCycleMultiplier
) {
return INIT_PARAMETERS_INCORRECT;
}
//
// Start Set Index Buffers ...
//
shortCycleLength = shortCycleMultiplier * marketLength;
mediumCycleLength = mediumCycleMultiplier * marketLength;
longCycleLength = longCycleMultiplier * marketLength;
//
// Short Cycle Highest High ...
string scHHLbl = StringConcatenate(
"SC HH(", shortCycleLength, ")"
);
SetIndexBuffer(shortCycleHighestHighBufferIndex, shortCycleHighestHighBuffer);
SetIndexLabel(shortCycleHighestHighBufferIndex, scHHLbl);
//
// Short Cycle Lowest Low ...
string scLLLbl = StringConcatenate(
"SC LL(", shortCycleLength, ")"
);
SetIndexBuffer(shortCycleLowestLowBufferIndex, shortCycleLowestLowBuffer);
SetIndexLabel(shortCycleLowestLowBufferIndex, scLLLbl);
//
// Medium Cycle Highest High ...
string mcHHLbl = StringConcatenate(
"MC HH(", mediumCycleLength, ")"
);
SetIndexBuffer(mediumCycleHighestHighBufferIndex, mediumCycleHighestHighBuffer);
SetIndexLabel(mediumCycleHighestHighBufferIndex, mcHHLbl);
//
// Medium Cycle Lowest Low ...
string mcLLLbl = StringConcatenate(
"MC LL(", mediumCycleLength, ")"
);
SetIndexBuffer(mediumCycleLowestLowBufferIndex, mediumCycleLowestLowBuffer);
SetIndexLabel(mediumCycleLowestLowBufferIndex, mcLLLbl);
//
// Long Cycle Highest High ...
string lcHHLbl = StringConcatenate(
"LC HH(", longCycleLength, ")"
);
SetIndexBuffer(longCycleHighestHighBufferIndex, longCycleHighestHighBuffer);
SetIndexLabel(longCycleHighestHighBufferIndex, lcHHLbl);
//
// Long Cycle Lowest Low ...
string lcLLLbl = StringConcatenate(
"LC LL(", longCycleLength, ")"
);
SetIndexBuffer(longCycleLowestLowBufferIndex, longCycleLowestLowBuffer);
SetIndexLabel(longCycleLowestLowBufferIndex, lcLLLbl);
//
// 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, marketLength);
//
// 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 ...
//
CalculateShortCycle(i);
//
CalculateMediumCycle(i);
//
CalculateLongCycle(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculating Short Cycle ...
void CalculateShortCycle(
const int &bar_index
) {
//
// Short Cycle Highest High ...
//
int scHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
shortCycleLength,
bar_index
);
//
double scHH = iHigh(
_Symbol,
_Period,
scHHIdx
);
//
shortCycleHighestHighBuffer[bar_index] = scHH;
//
// Short Cycle Lowest Low ...
//
int scLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
shortCycleLength,
bar_index
);
//
double scLL = iLow(
_Symbol,
_Period,
scLLIdx
);
//
shortCycleLowestLowBuffer[bar_index] = scLL;
}
//
// Calculating Medium Cycle ...
void CalculateMediumCycle(
const int &bar_index
) {
//
// Medium Cycle Highest High ...
//
int mcHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
mediumCycleLength,
bar_index
);
//
double mcHH = iHigh(
_Symbol,
_Period,
mcHHIdx
);
//
mediumCycleHighestHighBuffer[bar_index] = mcHH;
//
// Medium Cycle Lowest Low ...
//
int mcLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
mediumCycleLength,
bar_index
);
//
double mcLL = iLow(
_Symbol,
_Period,
mcLLIdx
);
//
mediumCycleLowestLowBuffer[bar_index] = mcLL;
}
//
// Calculating Long Cycle ...
void CalculateLongCycle(
const int &bar_index
) {
//
// Long Cycle Highest High ...
//
int lcHHIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
longCycleLength,
bar_index
);
//
double lcHH = iHigh(
_Symbol,
_Period,
lcHHIdx
);
//
longCycleHighestHighBuffer[bar_index] = lcHH;
//
// Long Cycle Lowest Low ...
//
int lcLLIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
longCycleLength,
bar_index
);
//
double lcLL = iLow(
_Symbol,
_Period,
lcLLIdx
);
//
longCycleLowestLowBuffer[bar_index] = lcLL;
}
//
// END Functions ...
//
@@ -0,0 +1,695 @@
///////////////////////////////////////////////////////
//
// 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 ...
//
//
// Market Specifications ...
input int marketLength = 7; // Market Length
input double step = 0.02; // SAR Step
input double maximum = 0.2; // SAR Maximum
//
// Cycle Definitions ...
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 showPSar = true; // Show Parabolic Sar
input bool showMarketMiddle = true; // Show Market Middle
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 pSarColor = clrCornflowerBlue; // Parabolic Sar Color
input color shortCycleFastColor = clrGreen; // Short Cycle Fast Color
input color shortCycleSlowColor = clrRed; // Short Cycle Slow Color
input color mediumCycleFastColor = clrAqua; // Medium Cycle Fast Color
input color mediumCycleSlowColor = clrFuchsia; // Medium Cycle Slow Color
input color longCycleFastColor = clrGoldenrod; // Medium Cycle Fast Color
input color longCycleSlowColor = clrBrown; // Medium Cycle Slow Color
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
// define indicator buffers ...
#property indicator_buffers 8
#property indicator_plots 8
//
// Declare Buffers ...
#define scFastBufferIndex 0
#define scSlowBufferIndex 1
#define mcFastBufferIndex 2
#define mcSlowBufferIndex 3
#define lcFastBufferIndex 4
#define lcSlowBufferIndex 5
#define midBufferIndex 6
#define pSarBufferIndex 7
//
double scFastBuffer[];
double scSlowBuffer[];
double mcFastBuffer[];
double mcSlowBuffer[];
double lcFastBuffer[];
double lcSlowBuffer[];
double midBuffer[];
double pSarBuffer[];
//
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);
SetIndexLabel(midBufferIndex, "Market Mid");
//
// Parabolic Sar ...
SetIndexBuffer(pSarBufferIndex, pSarBuffer);
SetIndexLabel(pSarBufferIndex, "P Sar");
SetIndexStyle(
pSarBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
showPSar ?
pSarColor :
clrNONE
);
//
// Market Middle ...
SetIndexBuffer(midBufferIndex, midBuffer);
SetIndexLabel(midBufferIndex, "Mid");
SetIndexStyle(
midBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
showMarketMiddle ?
clrAntiqueWhite :
clrNONE
);
//
// 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);
//
// Calculate Parabolic Sar ...
CalculateParabolicSar(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 ...
//
}
void CalculateParabolicSar(
const int bar_index
) {
//
double sarValue = iSAR(
NULL,
_Period,
step,
maximum,
bar_index
);
//
pSarBuffer[bar_index] = sarValue;
}
//
// END Functions ...
//
@@ -0,0 +1,394 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XMKT Indicator
// ---------------------------------------------
// retrieve market base info ...
//
// 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 XMKT Indicator"
#property strict
//
// START Inputs ...
//
//
// Market Specifications ...
input int marketLength = 7; // Market Length
//
input bool showHighestHigh = true; // Show Market Highest High
input bool showHighestLow = true; // Show Market Highest Low
input bool showHighestOpen = true; // Show Market Highest Open
input bool showHighestClose = true; // Show Market Highest Close
input bool showLowestHigh = true; // Show Market Lowest High
input bool showLowestLow = true; // Show Market Lowest Low
input bool showLowestOpen = true; // Show Market Lowest Open
input bool showLowestClose = true; // Show Market Lowest Close
//
input color highestHighColor = clrDeepPink; // Market Highest High Color
input color highestLowColor = clrDarkOrange; // Market Highest Low Color
input color highestOpenColor = clrDodgerBlue; // Market Highest Open Color
input color highestCloseColor = clrOrchid; // Market Highest Close Color
input color lowestHighColor = clrHotPink; // Market Lowest High Color
input color lowestLowColor = clrOrange; // Market Lowest Low Color
input color lowestOpenColor = clrPowderBlue; // Market Lowest Open Color
input color lowestCloseColor = clrMediumOrchid; // Market Lowest Close Color
//
input ENUM_LINE_STYLE highestHighStyle = STYLE_DOT; // Market Highest High Line Style
input ENUM_LINE_STYLE highestLowStyle = STYLE_DOT; // Market Highest Low Line Style
input ENUM_LINE_STYLE highestOpenStyle = STYLE_DOT; // Market Highest Open Line Style
input ENUM_LINE_STYLE highestCloseStyle = STYLE_DOT; // Market Highest Close Line Style
input ENUM_LINE_STYLE lowestHighStyle = STYLE_DOT; // Market Lowest High Line Style
input ENUM_LINE_STYLE lowestLowStyle = STYLE_DOT; // Market Lowest Low Line Style
input ENUM_LINE_STYLE lowestOpenStyle = STYLE_DOT; // Market Lowest Open Line Style
input ENUM_LINE_STYLE lowestCloseStyle = STYLE_DOT; // Market Lowest Close Line Style
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
// define indicator buffers ...
#property indicator_buffers 8
#property indicator_plots 8
//
// Declare Buffers ...
#define marketHighestHighBufferIndex 0
#define marketHighestLowBufferIndex 1
#define marketHighestOpenBufferIndex 2
#define marketHighestCloseBufferIndex 3
#define marketLowestHighBufferIndex 4
#define marketLowestLowBufferIndex 5
#define marketLowestOpenBufferIndex 6
#define marketLowestCloseBufferIndex 7
//
double marketHighestHighBuffer[];
double marketHighestLowBuffer[];
double marketHighestOpenBuffer[];
double marketHighestCloseBuffer[];
double marketLowestHighBuffer[];
double marketLowestLowBuffer[];
double marketLowestOpenBuffer[];
double marketLowestCloseBuffer[];
//
// 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 (marketLength <= 0) {
return INIT_PARAMETERS_INCORRECT;
}
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XST_XMKT";
//
// Highest High ...
string highestHighLbl = StringConcatenate("HH(", marketLength,")");
SetIndexLabel(marketHighestHighBufferIndex, highestHighLbl);
SetIndexBuffer(marketHighestHighBufferIndex, marketHighestHighBuffer);
SetIndexStyle(
marketHighestHighBufferIndex,
showHighestHigh ?
DRAW_LINE :
DRAW_NONE,
highestHighStyle,
1,
showHighestHigh ?
highestHighColor :
clrNONE
);
//
// Highest Low ...
string highestLowLbl = StringConcatenate("HL(", marketLength,")");
SetIndexLabel(marketHighestLowBufferIndex, highestLowLbl);
SetIndexBuffer(marketHighestLowBufferIndex, marketHighestLowBuffer);
SetIndexStyle(
marketHighestLowBufferIndex,
showHighestLow ?
DRAW_LINE :
DRAW_NONE,
highestLowStyle,
1,
showHighestLow ?
highestLowColor :
clrNONE
);
//
// Highest Open ...
string highestOpenLbl = StringConcatenate("HO(", marketLength,")");
SetIndexLabel(marketHighestOpenBufferIndex, highestOpenLbl);
SetIndexBuffer(marketHighestOpenBufferIndex, marketHighestOpenBuffer);
SetIndexStyle(
marketHighestOpenBufferIndex,
showHighestOpen ?
DRAW_LINE :
DRAW_NONE,
highestOpenStyle,
1,
showHighestOpen ?
highestOpenColor :
clrNONE
);
//
// Highest Close ...
string highestCloseLbl = StringConcatenate("HC(", marketLength,")");
SetIndexLabel(marketHighestCloseBufferIndex, highestCloseLbl);
SetIndexBuffer(marketHighestCloseBufferIndex, marketHighestCloseBuffer);
SetIndexStyle(
marketHighestCloseBufferIndex,
showHighestClose ?
DRAW_LINE :
DRAW_NONE,
highestCloseStyle,
1,
showHighestClose ?
highestCloseColor :
clrNONE
);
//
// Lowest High ...
string lowestHighLbl = StringConcatenate("LH(", marketLength,")");
SetIndexLabel(marketLowestHighBufferIndex, lowestHighLbl);
SetIndexBuffer(marketLowestHighBufferIndex, marketLowestHighBuffer);
SetIndexStyle(
marketLowestHighBufferIndex,
showLowestHigh ?
DRAW_LINE :
DRAW_NONE,
lowestHighStyle,
1,
showLowestHigh ?
lowestHighColor :
clrNONE
);
//
// Lowest Low ...
string lowestLowLbl = StringConcatenate("LL(", marketLength,")");
SetIndexLabel(marketLowestLowBufferIndex, lowestLowLbl);
SetIndexBuffer(marketLowestLowBufferIndex, marketLowestLowBuffer);
SetIndexStyle(
marketLowestLowBufferIndex,
showLowestLow ?
DRAW_LINE :
DRAW_NONE,
lowestLowStyle,
1,
showLowestLow ?
lowestLowColor :
clrNONE
);
//
// Lowest Open ...
string lowestOpenLbl = StringConcatenate("LO(", marketLength,")");
SetIndexLabel(marketLowestOpenBufferIndex, lowestOpenLbl);
SetIndexBuffer(marketLowestOpenBufferIndex, marketLowestOpenBuffer);
SetIndexStyle(
marketLowestOpenBufferIndex,
showLowestOpen ?
DRAW_LINE :
DRAW_NONE,
lowestOpenStyle,
1,
showLowestOpen ?
lowestOpenColor :
clrNONE
);
//
// Lowest Close ...
string lowestCloseLbl = StringConcatenate("LC(", marketLength,")");
SetIndexLabel(marketLowestCloseBufferIndex, lowestCloseLbl);
SetIndexBuffer(marketLowestCloseBufferIndex, marketLowestCloseBuffer);
SetIndexStyle(
marketLowestCloseBufferIndex,
showLowestClose ?
DRAW_LINE :
DRAW_NONE,
lowestCloseStyle,
1,
showLowestClose ?
lowestCloseColor :
clrNONE
);
//
// 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, 3);
//
// 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 ...
CalculateBuffers(i);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculate Short Cycle ...
void CalculateBuffers(
const int bar_index
) {
//
// Highest High ...
double highestHighValue = GetMarketHighestHigh(
bar_index,
marketLength
);
marketHighestHighBuffer[bar_index] = highestHighValue;
//
// Highest Low ...
double highestLowValue = GetMarketHighestLow(
bar_index,
marketLength
);
marketHighestLowBuffer[bar_index] = highestLowValue;
//
// Highest Open ...
double highestOpenValue = GetMarketHighestOpen(
bar_index,
marketLength
);
marketHighestOpenBuffer[bar_index] = highestOpenValue;
//
// Highest Close ...
double highestCloseValue = GetMarketHighestClose(
bar_index,
marketLength
);
marketHighestCloseBuffer[bar_index] = highestCloseValue;
//
// Lowest High ...
double lowestHighValue = GetMarketLowestHigh(
bar_index,
marketLength
);
marketLowestHighBuffer[bar_index] = lowestHighValue;
//
// Lowest Low ...
double lowestLowValue = GetMarketLowestLow(
bar_index,
marketLength
);
marketLowestLowBuffer[bar_index] = lowestLowValue;
//
// Lowest Open ...
double lowestOpenValue = GetMarketLowestOpen(
bar_index,
marketLength
);
marketLowestOpenBuffer[bar_index] = lowestOpenValue;
//
// Lowest Close ...
double lowestCloseValue = GetMarketLowestClose(
bar_index,
marketLength
);
marketLowestCloseBuffer[bar_index] = lowestCloseValue;
}
//
// END Functions ...
//
@@ -0,0 +1,221 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XMTR Indicator
// ---------------------------------------------
// retrieve market base info ...
//
// 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 XMKT Indicator"
#property strict
//
// START Inputs ...
//
//
// Market Specifications ...
input int marketLength = 20; // Market Length
input int atrMultiplier = 1; // ATR Multiplier
input int atrLength = 5; // ATR Period
input ENUM_APPLIED_PRICE source = PRICE_CLOSE; // Source
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
#property indicator_chart_window
//
// define indicator buffers ...
#property indicator_buffers 3
#property indicator_plots 3
//
// Declare Buffers ...
#define trendBufferIndex 0
#define upTrendBufferIndex 1
#define downTrendBufferIndex 2
//
double trendBuffer[];
double upTrendBuffer[];
double downTrendBuffer[];
//
// 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 (marketLength <= 0) {
return INIT_PARAMETERS_INCORRECT;
}
//
// here we specify logging enabled or not ...
enableLogging = true;
//
// this is a Tag which attached to our Logger ...
logTag = "XMTR";
//
// TREND ...
SetIndexLabel(trendBufferIndex, "Trend");
SetIndexBuffer(trendBufferIndex, trendBuffer);
SetIndexStyle(
trendBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
clrNONE
);
//
// UP Trend ...
SetIndexLabel(upTrendBufferIndex, "Up Trend");
SetIndexBuffer(upTrendBufferIndex, upTrendBuffer);
SetIndexStyle(
upTrendBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
clrNONE
);
//
// DOWN Trend ...
SetIndexLabel(downTrendBufferIndex, "Down Trend");
SetIndexBuffer(downTrendBufferIndex, downTrendBuffer);
SetIndexStyle(
downTrendBufferIndex,
DRAW_LINE,
STYLE_DOT,
1,
clrNONE
);
//
// 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, 3);
//
// 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 ...
CalculateBuffers(
i,
low
);
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Calculate Short Cycle ...
void CalculateBuffers(
const int bar_index,
const double &low[]
) {
//
double atr = GetMarketTRSMA(
bar_index,
atrLength
);
//
double smoothedAtr = (atr * atrMultiplier);
double upTrend = low[bar_index] - smoothedAtr;
double downTrend = low[bar_index] + smoothedAtr;
//
double cciValue = GetMarketCCI(
bar_index,
marketLength,
source
);
//
// TODO: Complete this ...
}
//
// 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 ...
//
@@ -0,0 +1,472 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 CCI Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// Based Signal Conditions ...
struct XCCILongSignalConditions {
//
datetime start;
//
datetime crossOverMinusHundredTime;
datetime crossUnderMinusHundredTime;
//
double crossOverSlope;
};
//
static XCCILongSignalConditions cciLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill Signal Conditions ...
void CheckCCILongSignalConditions(
const int bar_index,
const int marketLen,
//
const double smoother = 10
) {
//
// Retrieve Bar Time ...
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
// LONG:
// wait for cci cross under -100
// then wait for cross over -100
// slope of crossing over ??? ...
if (cciLongConds.start == 0) {
// LogMessage("Start");
cciLongConds.start = barTime;
return;
}
//
// Check Start Time ...
if (cciLongConds.start == 0) {
return;
}
//
// Read current, prev, and prevPrev CCI ...
double cci = GetMarketCCI(
bar_index,
marketLen
);
double cci1 = GetMarketCCI(
bar_index + 1,
marketLen
);
double cci2 = GetMarketCCI(
bar_index + 2,
marketLen
);
//
// Find Cross Under -100 ...
bool isCrossUnderMinusHundred =
cci < -105 && !(cci1 < -105)
&& MathAbs(MathAbs(cci) - MathAbs(cci1)) > smoother
;
//
// Find Cross Over -100 ...
bool isCrossOverMinusHundred =
cci > -105 && !(cci1 > -105)
&& MathAbs(cci - cci1) > smoother
;
//
// Fill Conditions ...
if (
isCrossUnderMinusHundred
&& cciLongConds.crossUnderMinusHundredTime == 0
&& cciLongConds.crossOverMinusHundredTime == 0
) {
// LogMessage("Cross Under ...");
cciLongConds.crossUnderMinusHundredTime = barTime;
return;
}
//
// Fill Conditions ...
if (
isCrossOverMinusHundred
&& cciLongConds.crossOverMinusHundredTime == 0
&& cciLongConds.crossUnderMinusHundredTime != 0
) {
//
// LogMessage("Cross Over ...");
cciLongConds.crossOverMinusHundredTime = barTime;
}
//
// Prevent Going forward untill Cross Under Happens ...
if (cciLongConds.crossUnderMinusHundredTime == 0) {
return;
}
//
// Prevent from Going forward untill Cross Over Happens ...
if (cciLongConds.crossOverMinusHundredTime == 0) {
return;
}
//
// Calculate Slope ...
double x1 = 0;
double y1 = cci1;
double x2 = 1;
double y2 = cci;
//
// Calculat Line Slope ...
double tSlope = GetSlope(
x1, y1, x2, y2
);
//
cciLongConds.crossOverSlope = tSlope;
// LogMessage("Slope: " + tSlope);
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateCCILongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateCCILongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
int llIdx = GetLowestLowOFCCILongPeriodIndex();
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
// GetLowestLowOFCCILongPeriod();
//
int hhIdx = GetHighestHighOfCCILongPeriodIndex();
double hh = GetHighestHighOfCCILongPeriod();
// GetMarketHighestHigh(
// bar_index,
// marketLen
// );
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r;
//
double sl = 0; // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_CCI_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_CCI_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateCCILongConditions() {
//
int crossUnderBarIndex =
cciLongConds.crossUnderMinusHundredTime != 0
? iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
)
: -1
;
//
int crossOverBarIndex =
cciLongConds.crossOverMinusHundredTime != 0
? iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
)
: -1
;
//
bool isConditionsFilled =
//
cciLongConds.start != 0
&& cciLongConds.crossUnderMinusHundredTime != 0
&& cciLongConds.crossOverMinusHundredTime != 0
&& cciLongConds.crossUnderMinusHundredTime >= cciLongConds.start
&& cciLongConds.crossOverMinusHundredTime > cciLongConds.crossUnderMinusHundredTime
;
//
bool isLogicPassed =
//
crossOverBarIndex > 0
&& crossUnderBarIndex > 0
&& crossUnderBarIndex > crossOverBarIndex
&& (crossUnderBarIndex - crossOverBarIndex) >= 5
;
//
bool result =
//
isConditionsFilled
&& isLogicPassed
&& cciLongConds.crossOverSlope > 0
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearCCILongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearCCILongSignalConditions() {
//
cciLongConds.start = 0;
cciLongConds.crossOverSlope = 0;
cciLongConds.crossOverMinusHundredTime = 0;
cciLongConds.crossUnderMinusHundredTime = 0;
}
//
int GetHighestHighOfCCILongPeriodIndex() {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
);
//
int result = iHighest(
_Symbol,
_Period,
MODE_HIGH,
crossUnderBarIndex - crossOverBarIndex,
crossOverBarIndex
);
//
return result;
}
//
double GetHighestHighOfCCILongPeriod() {
//
int index = GetHighestHighOfCCILongPeriodIndex();
//
double result = iHigh(
_Symbol,
_Period,
index
);
//
return result;
}
//
int GetLowestLowOFCCILongPeriodIndex() {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossUnderMinusHundredTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
cciLongConds.crossOverMinusHundredTime
);
//
int result = iLowest(
_Symbol,
_Period,
MODE_LOW,
crossUnderBarIndex - crossOverBarIndex,
crossOverBarIndex
);
//
return result;
}
//
double GetLowestLowOFCCILongPeriod() {
//
int index = GetLowestLowOFCCILongPeriodIndex();
//
double result = iLow(
_Symbol,
_Period,
index
);
//
return result;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForCCILongSignals(
const XState &states[]
) {
//
bool result = false;
//
XStateInfo info = ParseXMAStates(states);
//
result =
//
true
//
// && states[1].mc.fast > states[1].mc.slow
// && MathAbs(states[1].mc.fast - states[1].mc.slow) > 100 * _Point
// && states[1].marketMiddleage > states[1].sc.fast
// && states[1].marketMiddleage > states[1].mc.fast
;
//
return result;
}
//
// END Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,948 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 Indicator 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
static double zigZags[];
//
// END Global Requirement Functions ...
//
//
// START Indicator Reading Data ...
//
//
// START XMKT Data ...
//
XMKTState GetXMKT(
const int bar_index,
const int marketLen,
//
const bool showHighestHigh = true,
const bool showHighestLow = true,
const bool showHighestOpen = true,
const bool showHighestClose = true,
const bool showLowestHigh = true,
const bool showLowestLow = true,
const bool showLowestOpen = true,
const bool showLowestClose = true,
const color highestHighColor = clrDeepPink,
const color highestLowColor = clrDarkOrange,
const color highestOpenColor = clrDodgerBlue,
const color highestCloseColor = clrOrchid,
const color lowestHighColor = clrHotPink,
const color lowestLowColor = clrOrange,
const color lowestOpenColor = clrPowderBlue,
const color lowestCloseColor = clrMediumOrchid,
const ENUM_LINE_STYLE highestHighStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestLowStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestOpenStyle = STYLE_DOT,
const ENUM_LINE_STYLE highestCloseStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestHighStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestLowStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestOpenStyle = STYLE_DOT,
const ENUM_LINE_STYLE lowestCloseStyle = STYLE_DOT
) {
//
XMKTState result = {};
//
string xmktIndName = "x-saherelm.xmarket";
//
int highestHighBufferIndex = 0;
int highestLowBufferIndex = 1;
int highestOpenBufferIndex = 2;
int highestCloseBufferIndex = 3;
int lowestHighBufferIndex = 4;
int lowestLowBufferIndex = 5;
int lowestOpenBufferIndex = 6;
int lowestCloseBufferIndex = 7;
//
// Highest High ...
double highestHigh = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestHighBufferIndex, // Buffer Index ...
bar_index
);
result.highestHigh = highestHigh;
//
// Highest Low ...
double highestLow = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestLowBufferIndex, // Buffer Index ...
bar_index
);
result.highestLow = highestLow;
//
// Highest Open ...
double highestOpen = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestOpenBufferIndex, // Buffer Index ...
bar_index
);
result.highestOpen = highestOpen;
//
// Highest Close ...
double highestClose = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
highestCloseBufferIndex, // Buffer Index ...
bar_index
);
result.highestClose = highestClose;
//
// Lowest High ...
double lowestHigh = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestHighBufferIndex, // Buffer Index ...
bar_index
);
result.lowestHigh = lowestHigh;
//
// Lowest Low ...
double lowestLow = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestLowBufferIndex, // Buffer Index ...
bar_index
);
result.lowestLow = lowestLow;
//
// Lowest Open ...
double lowestOpen = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestOpenBufferIndex, // Buffer Index ...
bar_index
);
result.lowestOpen = lowestOpen;
//
// Lowest Close ...
double lowestClose = iCustom(
_Symbol,
_Period,
xmktIndName,
//
// Inputs ...
marketLen,
showHighestHigh,
showHighestLow,
showHighestOpen,
showHighestClose,
showLowestHigh,
showLowestLow,
showLowestOpen,
showLowestClose,
highestHighColor,
highestLowColor,
highestOpenColor,
highestCloseColor,
lowestHighColor,
lowestLowColor,
lowestOpenColor,
lowestCloseColor,
highestHighStyle,
highestLowStyle,
highestOpenStyle,
highestCloseStyle,
lowestHighStyle,
lowestLowStyle,
lowestOpenStyle,
lowestCloseStyle,
//
lowestCloseBufferIndex, // Buffer Index ...
bar_index
);
result.lowestClose = lowestClose;
//
return result;
}
//
// END XMKT Data ...
//
//
// START XOSC Data ...
//
XCycleState GetXOSC(
const int bar_index,
const int marketLen,
//
const int fastMult,
const int slowMult,
//
const double fastMMul = 1.0,
const double slowMMul = 3.0
) {
//
XCycleState result = {};
//
string oscIndName = "x-saherelm.osc";
//
// Prepare OSC Inputs ...
//
int fastLength = fastMult * marketLen;
int slowLength = slowMult * marketLen;
//
// Fast ...
double fast = iCustom(
_Symbol,
_Period,
oscIndName,
//
// Inputs ...
fastLength,
fastMMul,
slowLength,
slowMMul,
//
0, // Buffer Index ...
bar_index
);
result.fast = fast;
//
// Slow ...
double slow = iCustom(
_Symbol,
_Period,
oscIndName,
//
// Inputs ...
fastLength,
fastMMul,
slowLength,
slowMMul,
//
1, // Buffer Index ...
bar_index
);
result.slow = slow;
//
return result;
}
//
// END XOSC Data ...
//
//
// START XBND Data ...
//
XBndState GetXBND(
const int bar_index,
//
const int marketLen = 10, // Market Length ...
const int shift = 0, // MA Shift ...
const ENUM_MA_METHOD method = MODE_SMA // MA Method ...
) {
//
XBndState result = {};
//
double high = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_HIGH
);
result.high = high;
//
double open = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_OPEN
);
result.open = open;
//
double close = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_CLOSE
);
result.close = close;
//
double low = GetMA(
bar_index,
marketLen,
shift,
method,
PRICE_LOW
);
result.low = low;
//
return result;
}
//
// END XBND Data ...
//
//
// START ZigZag Data ...
//
void PrepareZigZagState(
const int bar_index,
//
const int depth = 12,
const int deviation = 5,
const int backStep = 3
) {
//
string zigzagIndName = "x-saherelm.zigzag";
//
ArrayFree(zigZags);
ArrayResize(
zigZags,
3
);
//
double zigZag = 0;
int index = 0;
int i = bar_index;
while (index < 3) {
//
zigZag = iCustom(
_Symbol,
_Period,
zigzagIndName,
//
// Inputs ...
depth,
deviation,
backStep,
//
0, // Buffer Index ...
i
);
//
if (zigZag > 0) {
//
zigZags[index] = zigZag;
index++;
}
//
i++;
}
}
//
// END ZigZag Data ...
//
//
// START XMA Data ...
//
//
// Retrieve Short Cycle ...
XCycleState GetXMASC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow= slow;
//
return result;
}
//
// Retrieve Medium Cycle ...
XCycleState GetXMAMC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow= slow;
//
return result;
}
//
// Retrieve Long Cycle ...
XCycleState GetXMALC(
const int bar_index,
const int marketLen,
const int fastMultiplier,
const int slowMultiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = marketLen * fastMultiplier;
int slowLength = marketLen * slowMultiplier;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow = slow;
//
return result;
}
//
// Retrieve Long Cycle ...
XCycleState GetXMANN(
const int bar_index,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_SMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE
) {
//
XCycleState result = {};
//
int fastLength = 10;
int slowLength = 50;
//
double fast = iMA(
_Symbol,
_Period,
fastLength,
shift,
method,
appliedPrice,
bar_index
);
result.fast = fast;
//
double slow = iMA(
_Symbol,
_Period,
slowLength,
shift,
method,
appliedPrice,
bar_index
);
result.slow = slow;
//
return result;
}
//
// Retrieve Middle ...
double GetXMAMM(
const int bar_index,
const int marketLen,
const double multiplier,
//
const int shift = 0,
const ENUM_MA_METHOD method = MODE_EMA,
const ENUM_APPLIED_PRICE appliedPrice = PRICE_MEDIAN
) {
//
double result = 0;
//
int length = (int)(marketLen * multiplier);
//
double middle = iMA(
_Symbol,
_Period,
length,
shift,
method,
appliedPrice,
bar_index
);
result = middle;
//
return result;
}
//
// Retrieve XMA Parabolic SAR ...
double GetXMAPSAR(
const int bar_index,
//
double stp = 0.02,
double mxm = 0.2
) {
//
double result = 0;
//
double pSar = iSAR(
_Symbol,
_Period,
stp,
mxm,
bar_index
);
result = pSar;
//
return result;
}
//
XState GetXState(
const int bar_index,
const int marketLen,
//
const double stp,
const double mxm,
//
const int shortCycleFastMult,
const int shortCycleSlowMult,
const int mediumCycleFastMult,
const int mediumCycleSlowMult,
const int longCycleFastMult,
const int longCycleSlowMult
) {
//
XState result = {};
//
// Short Cycle ...
XCycleState sc = GetXMASC(
bar_index,
marketLen,
shortCycleFastMult,
shortCycleSlowMult
);
result.sc = sc;
//
// Medium Cycle ...
XCycleState mc = GetXMAMC(
bar_index,
marketLen,
mediumCycleFastMult,
mediumCycleSlowMult
);
result.mc = mc;
//
// Long Cycle ...
XCycleState lc = GetXMALC(
bar_index,
marketLen,
longCycleFastMult,
longCycleSlowMult
);
result.lc = lc;
// //
// // OSC ...
// XCycleState osc = GetXOSC(
// //
// bar_index,
// marketLen,
// //
// shortCycleFastMult,
// shortCycleSlowMult
// );
// result.osc = osc;
//
// Market Middleage ...
double marketMiddleage = GetXMAMM(
bar_index,
marketLen,
1.5
);
result.marketMiddleage = marketMiddleage;
//
// Parabolic SAR ...
double parabolicSAR = GetXMAPSAR(
bar_index,
stp,
mxm
);
result.parabolicSAR = parabolicSAR;
// //
// int cciMarketLength = longCycleSlowMult * marketLen;
// double cci = GetMarketCCI(
// bar_index,
// cciMarketLength
// );
// result.cci = cci;
//
XBndState bnd = GetXBND(
bar_index
);
result.bnd = bnd;
//
XMKTState mkt = GetXMKT(
bar_index,
marketLen
);
result.mkt = mkt;
//
double longCycleHighestHigh = GetMarketHighestHigh(
bar_index,
longCycleFastMult * marketLen
);
result.longCycleHighestHigh = longCycleHighestHigh;
//
return result;
}
//
// END XMA Data ...
//
//
// END Indicator Reading Data ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,91 @@
///////////////////////////////////////////////////////
//
// 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);
}
//
// this used for logging series ...
void LogSeries(
double &series[], // which series to Log ...
int length = 0, // number of items to Log, 0 means all ...
int skip = 0 // number of items which skip before logging ...
) {
//
string msg = "";
//
int seriesSize = ArraySize(series);
if (
skip < 0
|| length < 0
|| seriesSize == 0
|| skip > seriesSize
|| skip + length > seriesSize
) {
return;
}
//
length = length == 0 ?
seriesSize :
length;
int start = skip > 1 ?
skip - 1 :
skip == 1 ?
1 :
0;
//
// Loop through series items ...
for (int i = start; i < start + length; i++) {
//
msg += StringConcatenate(
"i[", i, "]: ", series[i], ", "
);
}
//
LogMessage(msg);
}
//
// End Log Messages ...
//
@@ -0,0 +1,225 @@
///////////////////////////////////////////////////////
//
// 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 STATIC Variables ...
//
//
static int totalSignals = 0;
static int totalLongSignals = 0;
static int totalShortSignals = 0;
//
static double initialBalance = 0;
//
static int countedBars = 0;
static bool isNewBar = false;
static bool isNewDay = false;
//
// END STATIC Variables ...
//
//
// Start Models ...
//
//
// Signal Providers ...
enum ENUM_X_SIGNAL_PROVIDER {
X_UNKNOWN_PROVIDER,
X_OSC_PROVIDER,
X_CCI_PROVIDER,
X_SHP_PROVIDER,
X_XMA_PROVIDER,
X_RMA_PROVIDER,
X_XXX_PROVIDER
};
//
// these are different signal types ...
enum ENUM_X_SIGNAL_TYPE {
X_SIGNAL_NONE,
X_SIGNAL_LONG,
X_SIGNAL_SHORT,
};
//
// we Model each signals as this type ...
struct XSignal {
//
// Signal Symbol ...
string symbol;
//
// Signal Type ...
ENUM_X_SIGNAL_TYPE type;
//
// Signal ID ...
int id;
//
// Signal Ticket Number, when Opening Trade ...
int ticket;
//
// Signal Provider ...
ENUM_X_SIGNAL_PROVIDER provider;
//
// Target Point ...
double tp;
//
// Stop Loss ...
double sl;
//
// Signal Entry Price ...
double entry;
//
// Signalling Time ...
datetime time;
//
// Signal Comments ...
string comment;
};
//
// this is Signal Request Response model ...
struct XSignalRequest {
bool hasSignal;
XSignal signal;
ENUM_X_SIGNAL_TYPE type;
ENUM_X_SIGNAL_PROVIDER provider;
};
//
struct XBndState {
double high;
double open;
double close;
double low;
};
//
struct XMKTState {
//
double highestHigh;
double highestLow;
double highestOpen;
double highestClose;
//
double lowestHigh;
double lowestLow;
double lowestOpen;
double lowestClose;
};
//
struct XCycleState {
double fast;
double slow;
};
//
// Define a Model to Represent Snapshot of XMA Indicator ...
struct XState {
//
// SC ...
XCycleState sc;
//
// MC ...
XCycleState mc;
//
// LC ...
XCycleState lc;
//
// OSC ...
// XCycleState osc;
//
// MIDDLEAGE ...
double marketMiddleage;
//
// PARABOLIC-SAR ...
double parabolicSAR;
//
double cci;
//
XBndState bnd;
//
XMKTState mkt;
//
double longCycleHighestHigh;
};
//
// Parsed XMA Buffer ...
struct XStateInfo {
//
// Check Market Cross Exists or not ...
//
bool isSCFastCrossOverSlow;
bool isSCFastCrossUnderSlow;
//
double scMin;
double scMax;
//
bool isMCFastCrossOverSlow;
bool isMCFastCrossUnderSlow;
//
double mcMin;
double mcMax;
bool isLCFastCrossOverSlow;
bool isLCFastCrossUnderSlow;
//
double lcMin;
double lcMax;
//
bool isMMCrossOverSCFast;
bool isMMCrossUnderSCFast;
//
bool isMMCrossOverMCFast;
bool isMMCrossUnderMCFast;
//
double mmMin;
double mmMax;
};
//
// End Models ...
//
@@ -0,0 +1,363 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 OSC Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// SHP Based Signal Conditions ...
struct XOSCLongSignalConditions {
//
datetime crossOverTime;
double slowOnCrossOver;
//
datetime crossUnderTime;
double slowOnCrossUnder;
};
//
static XOSCLongSignalConditions oscLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckOSCLongSignalConditions(
const int bar_index,
const int marketLen,
//
double stp,
double mxm,
//
int scFMult,
int scSMult,
//
int mcFMult,
int mcSMult,
//
int lcFMult,
int lcSMult,
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
XState states[];
ArrayResize(
states,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < marketLen; i++) {
//
XState state = GetXState(
i,
marketLen,
//
stp,
mxm,
scFMult,
scSMult,
mcFMult,
mcSMult,
lcFMult,
lcSMult
);
//
states[index] = state;
//
index++;
}
//
bool isCrossUnder =
states[0].osc.fast < 0
&& !(states[1].osc.fast < 0)
;
//
bool isCrossOver =
states[0].osc.fast > 0
&& !(states[1].osc.fast > 0)
;
//
int oneTouches = 0;
int halfTouches = 0;
int minusOneTouches = 0;
for (int i = 0; i < marketLen - 1; i++) {
//
// One Touches ...
if (
states[i].osc.fast > 1
&& !(states[i + 1].osc.fast > 1)
) {
oneTouches++;
}
//
// Half Touches ...
if (
states[i].osc.fast > 0.5
&& !(states[i + 1].osc.fast > 0.5)
) {
halfTouches++;
}
//
// Minus One Touches ...
if (
states[i].osc.fast < -1
&& !(states[i + 1].osc.fast < -1)
) {
minusOneTouches++;
}
}
//
if (
isCrossUnder
&& oscLongConds.crossUnderTime == 0
) {
//
oscLongConds.crossUnderTime = barTime;
oscLongConds.slowOnCrossUnder = states[0].osc.slow;
return;
}
//
if (
isCrossOver
&& oscLongConds.crossUnderTime > 0
&& oscLongConds.crossOverTime == 0
) {
//
oscLongConds.crossOverTime = barTime;
oscLongConds.slowOnCrossOver = states[0].osc.slow;
return;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateOSCLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateOSCLongConditions()) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r; // 300 * _Point;
//
double sl = 0; // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_OSC_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_OSC_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateOSCLongConditions() {
//
bool isConditionsFilled =
oscLongConds.crossOverTime > 0
&& oscLongConds.crossUnderTime > 0
&& oscLongConds.slowOnCrossOver > 0
&& oscLongConds.slowOnCrossUnder > 0
&& oscLongConds.crossOverTime > oscLongConds.crossUnderTime
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
oscLongConds.crossUnderTime
);
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
oscLongConds.crossOverTime
);
//
isBLFilled =
crossUnderBarIndex > crossOverBarIndex
// && oscLongConds.slowOnCrossOver > oscLongConds.slowOnCrossUnder
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearOSCLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearOSCLongSignalConditions() {
//
oscLongConds.crossOverTime = 0;;
oscLongConds.crossUnderTime = 0;;
}
//
// Check State for Long Signals ...
bool IsReadyForOSCLongSignals(
const XSignal &signal,
const XState &states[]
) {
//
bool result = false;
//
result =
//
true
;
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,363 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 RMA Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// RMA Based Signal Conditions ...
struct XRMALongSignalConditions {
//
datetime crossUnderTime;
//
datetime crossOverTime;
};
//
static XRMALongSignalConditions xrmaLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckXRMALongSignalConditions(
const int bar_index,
const int marketLen,
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
XCycleState states[];
ArrayResize(
states,
marketLen
);
//
int index = 0;
for (int i = bar_index; i < marketLen; i++) {
//
XCycleState state = GetXMANN(i);
//
states[index] = state;
//
index++;
}
//
bool isCrossUnder =
states[1].fast < states[1].slow
&& !(states[2].fast < states[2].slow)
;
//
bool isCrossOver =
states[1].fast > states[1].slow
&& !(states[2].fast > states[2].slow)
;
//
if (
isCrossUnder
&& xrmaLongConds.crossUnderTime == 0
) {
//
xrmaLongConds.crossUnderTime = barTime;
return;
}
//
if (
isCrossOver
&& xrmaLongConds.crossUnderTime > 0
&& xrmaLongConds.crossOverTime == 0
) {
//
xrmaLongConds.crossOverTime = barTime;
return;
}
}
//
// Convert XMA Long Signal Conditions to XSignal ...
XSignalRequest GenerateXRMALongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r // Risk to Reward ratio ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateXRMALongConditions(marketLen)) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = risk * r2r; // 300 * _Point;
//
double sl = 0; // entryPrice - (300 * _Point); // ll;
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_RMA_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_RMA_PROVIDER;
//
return result;
}
//
// Validate XMA Signal Conditions ...
bool ValidateXRMALongConditions(
const int marketLen
) {
//
bool isConditionsFilled =
true
&& xrmaLongConds.crossOverTime > 0
&& xrmaLongConds.crossUnderTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int crossOverBarIndex = iBarShift(
_Symbol,
_Period,
xrmaLongConds.crossOverTime
);
//
int crossUnderBarIndex = iBarShift(
_Symbol,
_Period,
xrmaLongConds.crossUnderTime
);
//
XCycleState stateOnCrossUnder = GetXMANN(
crossUnderBarIndex
);
//
XCycleState stateOnCrossOver = GetXMANN(
crossOverBarIndex
);
//
double maC = iMA(
_Symbol,
_Period,
14,
0,
MODE_SMA,
PRICE_CLOSE,
crossOverBarIndex
);
// //
// double rmaOnCrossOver = GetRMA(
// crossOverBarIndex,
// 10
// );
// //
// double rmaOnMarketLength = GetRMA(
// crossOverBarIndex + marketLen,
// 10
// );
// //
// double prevCandleHigh = iHigh(
// _Symbol,
// _Period,
// crossOverBarIndex
// );
// //
// PrepareZigZagState(crossOverBarIndex);
// double zigZagDelta = zigZags[1] - zigZags[2];
// bool isZigZagWaitForHigh = zigZagDelta < 0;
//
isBLFilled =
true
//
&& (crossUnderBarIndex - crossOverBarIndex) > 5
//
&& xrmaLongConds.crossOverTime > xrmaLongConds.crossUnderTime
//
&& stateOnCrossOver.slow < stateOnCrossUnder.slow
//
&& MathAbs(stateOnCrossOver.fast - stateOnCrossOver.slow) > (70 * _Point)
//
&& maC >= stateOnCrossOver.slow
// //
// && !(rmaOnCrossOver < stateOnCrossOver.slow)
// //
// && MathAbs(rmaOnCrossOver - rmaOnMarketLength) < (600 * _Point)
// //
// && !isZigZagWaitForHigh
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXRMALongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXRMALongSignalConditions() {
//
xrmaLongConds.crossOverTime = 0;
xrmaLongConds.crossUnderTime = 0;
}
//
// Check XMA State for Long Signals ...
bool IsReadyForXRMALongSignals(
const XSignal &signal,
const XState &states[],
const int marketLen
) {
//
bool result = false;
//
result =
//
true
;
//
return result;
}
//
// END Functions ...
//
@@ -0,0 +1,391 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 SHP Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// SHP Based Signal Conditions ...
struct XSHPLongSignalConditions {
//
datetime start;
datetime stop;
};
//
static XSHPLongSignalConditions shpLongConds;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill CC Signal Conditions ...
void CheckSHPLongSignalConditions(
const int bar_index,
const int marketLen,
const double shpDetectMult,
const double smoother = 30
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
double high = iHigh(
_Symbol,
_Period,
bar_index
);
//
double low = iLow(
_Symbol,
_Period,
bar_index + 1
);
//
double mHH = GetMarketHighestHigh(
bar_index,
marketLen
);
//
double mLL = GetMarketLowestLow(
bar_index,
marketLen
);
double m2LL = GetMarketLowestLow(
bar_index,
marketLen * 2
);
//
int mHLIdx = iHighest(
_Symbol,
_Period,
MODE_LOW,
marketLen,
bar_index
);
datetime mHLTime = iTime(
_Symbol,
_Period,
mHLIdx
);
double mHL = iHigh(
_Symbol,
_Period,
mHLIdx
);
//
double hlDiff = (mHL - mLL);
double sharpDetectValue = shpDetectMult * _Point;
//
bool isSharpDetected =
// (
// low == mLL
// || MathAbs(mLL - low) < (smoother * _Point)
// )
// &&
// !(
// mLL > m2LL
// && MathAbs(m2LL - mLL) > sharpDetectValue / 2
// )
// &&
(
hlDiff > sharpDetectValue
|| hlDiff > sharpDetectValue - (smoother * _Point)
)
;
//
if (isSharpDetected) {
//
shpLongConds.start = mHLTime;
shpLongConds.stop = barTime;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateSHPLongSignal(
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r, // Risk to Reward ratio ...
const double shpDetectMultiplier // Sharp Detect Multiplier ...
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
if (!ValidateSHPLongConditions(shpDetectMultiplier)) {
return result;
}
//
// Price Calculations ...
//
RefreshRates();
//
double entryPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double exitPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = MathMin(openPrice, closePrice) - ll;
double reward = 300 * _Point; // risk * r2r;
//
double sl = 0; // ll;
//
// this means Market Lowest Low ...
double shpValue = shpDetectMultiplier * _Point;
if (
reward == 0
|| reward < 20 * _Point
) {
reward = shpValue;
}
double tp = entryPrice + reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = X_SIGNAL_LONG;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_SHP_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = X_SIGNAL_LONG;
result.provider = X_SHP_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateSHPLongConditions(
const double shpDetectMultiplier
) {
//
double shpDetectValue = shpDetectMultiplier * _Point;
//
bool isConditionsFilled =
shpLongConds.stop != 0
&& shpLongConds.start != 0
&& shpLongConds.stop > shpLongConds.start
;
//
bool isBLFilled = true;
//
bool result =
isBLFilled
&& isConditionsFilled
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearSHPLongSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearSHPLongSignalConditions() {
//
shpLongConds.stop = 0;
shpLongConds.start = 0;
}
//
// Check State for Long Signals ...
bool IsReadyForSHPLongSignals(
const XSignal &signal,
const XState &states[]
) {
//
bool result = false;
//
XStateInfo info = ParseXMAStates(states);
//
int xmaMarketLen = ArraySize(states);
double mHH = GetMarketHighestHigh(0, xmaMarketLen);
double m2HH = GetMarketHighestHigh(0, (int) (xmaMarketLen * 1.5));
//
int lcUpDownTouches = 0;
int cciHundredTouches = 0;
for (int i = 0; i < xmaMarketLen; i++) {
//
double high = iHigh(
_Symbol,
_Period,
i
);
//
double low = iLow(
_Symbol,
_Period,
i
);
//
double up = MathMax(states[i].lc.fast, states[i].lc.slow);
double down = MathMax(states[i].lc.fast, states[i].lc.slow);
//
if (high >= up && low <= down) {
lcUpDownTouches++;
}
//
if (
i < xmaMarketLen - 1
&& i < 10
) {
if (
states[i].cci < 100
&& states[i + 1].cci > 100
) {
cciHundredTouches++;
}
}
}
//
result =
//
true
//
&& states[0].mc.fast > states[0].mc.slow
&& states[0].lc.fast > states[0].lc.slow
//
&& states[0].sc.fast < states[0].sc.slow
&& states[1].sc.fast < states[1].sc.slow
//
&& states[0].marketMiddleage < states[0].sc.fast
&& states[1].marketMiddleage < states[1].sc.fast
&& !(
states[1].sc.fast < states[1].mc.fast
&& states[1].sc.slow < states[1].mc.fast
&& states[1].sc.fast > states[1].mc.slow
&& states[1].sc.slow > states[1].mc.slow
)
&& !(
states[0].marketMiddleage < states[0].mc.fast
&& states[0].marketMiddleage > states[0].mc.slow
)
//
&& mHH != m2HH
&& lcUpDownTouches == 0
&& cciHundredTouches == 0
;
//
return result;
}
//
// END Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,678 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL4 X Signal 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 library ...
#include "../Libraries/x-saherelm.lib.mq4"
//
// Includes Indicator library ...
#include "../Libraries/x-saherelm.indicator.lib.mq4"
//
// Includes Models library ...
#include "../Libraries/x-saherelm.models.lib.mq4"
//
// START Global Requirement Functions ...
//
//
// X Based Signal Conditions ...
struct XSignalConditions {
datetime startTime;
datetime signalTime;
};
//
static XSignalConditions xLongConds;
static XSignalConditions xShortConds;
//
static bool xCloseLongTrades = false;
static bool xWaitForLongSignals = true;
static datetime xWaitForLongSignalChangeTime;
//
static bool xWaitForShortSignals = true;
static bool xCloseShortTrades = false;
//
// END Global Requirement Functions ...
//
//
// START Functions ...
//
//
// Check and Fill Long Signal Conditions ...
void CheckXLongSignalConditions(
const int bar_index,
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
// //
// bool isCrossUnder =
// states[1].osc.fast < states[1].osc.slow
// && !(states[2].osc.fast < states[2].osc.slow)
// ;
// //
// bool isCrossOver =
// states[1].osc.fast > states[1].osc.slow
// && !(states[2].osc.fast > states[2].osc.slow)
// ;
//
XOHCL pCandle = GetCandleModel(1);
// //
// bool isTrendingUp =
// pCandle.low > states[0].bnd.high
// && pCandle.high > states[0].bnd.high;
// //
// bool isTrendingDown =
// pCandle.high < states[0].bnd.low
// && pCandle.low < states[0].bnd.low;
//
bool isTrendingUp =
states[1].bnd.open < states[1].bnd.close
&& !(states[2].bnd.open < states[2].bnd.close)
;
//
bool isTrendingDown =
states[1].bnd.open > states[1].bnd.close
&& !(states[2].bnd.open > states[2].bnd.close)
;
//
bool isCrossUnder =
isTrendingDown
&& !isTrendingUp
;
//
bool isCrossOver =
isTrendingUp
&& !isTrendingDown
;
//
// Check Market For Enable/Disable Signal Handlers ...
// Checking Market for Long Signals ...
if (xWaitForLongSignals) {
//
bool isLCFastOnTrendingUpTouchLowestLow =
//
// LC Trending Up ...
states[1].lc.fast > states[1].lc.slow
&& states[2].lc.fast > states[2].lc.slow
//
// LC Fast Touch Market Lowest Low ...
&& states[1].lc.fast > states[1].mkt.lowestLow
&& !(states[2].lc.fast > states[2].mkt.lowestLow)
;
//
bool isMCSlowCrossOverBNDHigh =
states[1].mc.fast > states[1].mc.slow
&& states[1].mc.slow > states[1].bnd.high
&& !(states[2].mc.slow > states[2].bnd.high)
;
//
// Disable Long Trade Handlers ...
if (
isMCSlowCrossOverBNDHigh
|| isLCFastOnTrendingUpTouchLowestLow
) {
//
xWaitForLongSignals = false;
xWaitForLongSignalChangeTime = TimeCurrent();
LogMessage("Disable Long ...");
}
} else {
//
bool isAllTrendingUp =
//
// SC ...
states[1].sc.fast > states[1].sc.slow
//
// MC ...
&& states[1].mc.fast > states[1].mc.slow
&& !(states[2].mc.fast > states[2].mc.slow)
//
// LC ...
&& states[1].lc.fast > states[1].lc.slow
;
//
int lastWaitChangeBarIndex = iBarShift(
_Symbol,
_Period,
xWaitForLongSignalChangeTime
);
//
// Enable Long Trade Handlers ...
if (
isAllTrendingUp
&& lastWaitChangeBarIndex - bar_index >= marketLen
) {
xWaitForLongSignals = true;
LogMessage("Enable Long ...");
}
}
//
if (
isCrossUnder
&& xLongConds.startTime == 0
) {
//
xLongConds.startTime = barTime;
return;
}
//
if (
isCrossOver
&& xLongConds.startTime > 0
&& xLongConds.signalTime == 0
) {
//
xLongConds.signalTime = barTime;
return;
}
}
//
// Check and Fill Short Signal Conditions ...
void CheckXShortSignalConditions(
const int bar_index,
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
bool isCrossUnder =
false;
//
bool isCrossOver =
false;
// //
// bool isCrossUnder =
// states[1].osc.fast < states[1].osc.slow
// && !(states[2].osc.fast < states[2].osc.slow)
// ;
// //
// bool isCrossOver =
// states[1].osc.fast > states[1].osc.slow
// && !(states[2].osc.fast > states[2].osc.slow)
// ;
//
if (
isCrossOver
&& xShortConds.startTime == 0
) {
//
xShortConds.startTime = barTime;
return;
}
//
if (
isCrossUnder
&& xShortConds.startTime > 0
&& xShortConds.signalTime == 0
) {
//
xShortConds.signalTime = barTime;
return;
}
}
//
// Convert Long Signal Conditions to XSignal ...
XSignalRequest GenerateXSignal(
const ENUM_X_SIGNAL_TYPE type, // Signal Type ...
const int bar_index, // Bar Index ...
const int marketLen, // MarketLength for TP and SL ...
const double r2r, // Risk to Reward ratio ...
const XState &states[],
//
const double smoother = 5
) {
//
XSignalRequest result = {};
//
result.hasSignal = false;
result.type = X_SIGNAL_NONE;
result.provider = X_UNKNOWN_PROVIDER;
//
bool requestLong = type == X_SIGNAL_LONG;
//
if (requestLong) {
//
if (
!ValidateXLongConditions(
marketLen,
states,
smoother
)
) {
return result;
}
} else {
//
if (
!ValidateXShortConditions(
marketLen,
states,
smoother
)
) {
return result;
}
}
//
// Price Calculations ...
//
RefreshRates();
//
double askPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
//
double bidPrice = SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
//
double entryPrice = requestLong ?
askPrice :
bidPrice;
//
double exitPrice = requestLong ?
bidPrice :
askPrice;
//
double priceGap = MathAbs(entryPrice - exitPrice);
//
double ll =
GetMarketLowestLow(
bar_index,
marketLen
);
//
double hh =
GetMarketHighestHigh(
bar_index,
marketLen
);
//
double openPrice = iOpen(
_Symbol,
_Period,
bar_index
);
//
double closePrice = iClose(
_Symbol,
_Period,
bar_index
);
//
double risk = requestLong ?
MathMin(openPrice, closePrice) - ll :
hh - MathMax(openPrice, closePrice);
double reward = risk * r2r; // risk * r2r; // 300 * _Point;
// if (risk > (500 * _Point)) {
// reward = 300 * _Point;
// }
//
double sl = 0; // ll;
double tp = requestLong ?
entryPrice + reward :
entryPrice - reward;
//
datetime barTime = iTime(
_Symbol,
_Period,
bar_index
);
//
result.signal.tp = tp;
result.signal.sl = sl;
result.signal.symbol = _Symbol;
result.signal.type = type;
result.signal.id = totalSignals + 1;
result.signal.entry = entryPrice;
result.signal.provider = X_XXX_PROVIDER;
result.signal.time = barTime;
//
result.hasSignal = true;
result.type = type;
result.provider = X_XXX_PROVIDER;
//
return result;
}
//
// Validate Signal Conditions ...
bool ValidateXLongConditions(
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
bool isConditionsFilled =
xLongConds.startTime > 0
&& xLongConds.signalTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
xLongConds.startTime
);
//
int signalBarIndex = iBarShift(
_Symbol,
_Period,
xLongConds.signalTime
);
//
isBLFilled =
//
xLongConds.signalTime > xLongConds.startTime
&& MathAbs(signalBarIndex - startBarIndex) > 2
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
&& xWaitForLongSignals
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXLongSignalConditions();
}
//
return result;
}
bool ValidateXShortConditions(
const int marketLen,
const XState &states[],
//
const double smoother = 5
) {
//
bool isConditionsFilled =
xShortConds.startTime > 0
&& xShortConds.signalTime > 0
;
//
bool isBLFilled = false;
if (isConditionsFilled) {
//
int startBarIndex = iBarShift(
_Symbol,
_Period,
xShortConds.startTime
);
//
int signalBarIndex = iBarShift(
_Symbol,
_Period,
xShortConds.signalTime
);
//
isBLFilled =
//
xShortConds.signalTime > xShortConds.startTime
&& MathAbs(signalBarIndex - startBarIndex) > 2
;
}
//
bool result =
isBLFilled
&& isConditionsFilled
&& xWaitForLongSignals
;
//
// Since maybe Conditions Filled but
// Slope is Negative, for Handling Next Signals and
// Prevent from infinity loop, here we Clear Signal Conditions ...
if (
!result
&& isConditionsFilled
) {
ClearXShortSignalConditions();
}
//
return result;
}
//
// Clear Long Signal Conditions for New One ...
void ClearXLongSignalConditions() {
//
xLongConds.startTime = 0;
xLongConds.signalTime = 0;
}
//
// Clear Short Signal Conditions for New One ...
void ClearXShortSignalConditions() {
//
xShortConds.startTime = 0;
xShortConds.signalTime = 0;
}
//
// Check State for Long Signals ...
bool IsReadyForXSignals(
const XSignal &signal,
const XState &states[],
const int marketLen,
//
double smoother = 100
) {
//
bool result = false;
//
bool isSCTrendUp =
states[1].sc.fast > states[1].sc.slow
&& states[2].sc.fast > states[2].sc.slow;
// //
// bool isSCTrendDown =
// states[1].sc.fast < states[1].sc.slow
// && states[2].sc.fast < states[2].sc.slow;
//
bool isMCTrendUp =
states[1].mc.fast > states[1].mc.slow
&& states[2].mc.fast > states[2].mc.slow;
// //
// bool isMCTrendDown =
// states[1].mc.fast < states[1].mc.slow
// && states[2].mc.fast < states[2].mc.slow;
//
bool isLCTrendUp =
states[1].lc.fast > states[1].lc.slow
&& states[2].lc.fast > states[2].lc.slow;
// //
// bool isLCTrendDown =
// states[1].lc.fast < states[1].lc.slow
// && states[2].lc.fast < states[2].lc.slow;
// //
// bool isTrendingUp =
// pCandle.low > states[0].bnd.high
// && pCandle.high > states[0].bnd.high;
// //
// bool isTrendingDown =
// pCandle.high < states[0].bnd.low
// && pCandle.low < states[0].bnd.low;
//
XOHCL candle = GetCandleModel(0);
XOHCL pCandle = GetCandleModel(1);
//
// Verify Long Signals ...
if (signal.type == X_SIGNAL_LONG) {
//
result =
//
// Starter ...
true
//
// Trending State ...
&& isSCTrendUp
&& isMCTrendUp
&& isLCTrendUp
//
// Checking Signal Entry ...
&& (
signal.entry < candle.high
|| signal.entry < states[0].mkt.highestHigh
)
//
// Checking Signal TP ...
&& (
signal.tp < states[1].longCycleHighestHigh
&& MathAbs(states[1].longCycleHighestHigh - signal.tp) > 100 * _Point
)
//
// Checking Market Sharpness ...
&&
(
pCandle.high < states[1].longCycleHighestHigh
&& !(MathAbs(states[1].longCycleHighestHigh - pCandle.high) < 20 * _Point)
)
//
// Checking Special Conditions ...
// Condition 1 ...
&& (
states[1].lc.fast > states[1].mc.fast
&& states[1].lc.slow > states[1].mc.fast
?
states[1].lc.slow < states[1].mkt.lowestLow
:
true
)
//
// Condition 2 ...
&& !(
states[1].lc.fast > states[1].mkt.highestHigh
&& states[1].lc.slow < states[1].mkt.lowestLow
)
//
// Condition 3 ...
&& MathAbs(states[1].sc.fast - states[1].sc.slow) > 20 * _Point
;
} else
//
// Verify Short Signals ...
if (signal.type == X_SIGNAL_SHORT) {
//
result =
false
;
}
//
return result;
}
//
// END Functions ...
//

Some files were not shown because too many files have changed in this diff Show More