Initial Commit ...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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 ...
|
||||
//
|
||||
@@ -0,0 +1,330 @@
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center OSC Indicator
|
||||
// -------------------------------------------------------------
|
||||
// this indicator provides OSC ...
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm OSC Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
// FastOSC ...
|
||||
// Short Cycle (Fast OSC) ...
|
||||
input int fastOSCLength = 10; // FastOSC Length
|
||||
input double fastOSCMultiplier = 1.0; // FastOSC Multiplier
|
||||
|
||||
//
|
||||
// SlowOSC ...
|
||||
// Medium Cycle (Slow OSC) ...
|
||||
input int slowOSCLength = 30; // SlowOSC Length
|
||||
input double slowOSCMultiplier = 3.0; // SlowOSC Multiplier
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// Includes our shared library ...
|
||||
#include "../Libraries/x-saherelm.lib.mq4"
|
||||
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
// we have 2 buffer in this indicator ...
|
||||
#property indicator_buffers 5
|
||||
|
||||
//
|
||||
// also we have 2 line for draw on this indicator ...
|
||||
#property indicator_plots 5
|
||||
|
||||
//
|
||||
// Fast OSC ...
|
||||
#property indicator_width1 1
|
||||
#property indicator_color1 clrAqua
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
|
||||
//
|
||||
// Slow OSC ...
|
||||
#property indicator_width2 1
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrFuchsia
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
|
||||
//
|
||||
// Power OSC ...
|
||||
#property indicator_width3 1
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrYellow
|
||||
#property indicator_style3 STYLE_DASHDOTDOT
|
||||
|
||||
//
|
||||
// Var OSC ...
|
||||
#property indicator_width4 1
|
||||
#property indicator_type4 DRAW_HISTOGRAM
|
||||
#property indicator_color4 clrBlueViolet
|
||||
#property indicator_style4 STYLE_SOLID
|
||||
|
||||
//
|
||||
// Tan Fast/Slow OSC ...
|
||||
#property indicator_width5 0
|
||||
#property indicator_type5 DRAW_NONE
|
||||
#property indicator_color5 clrNONE
|
||||
#property indicator_style5 STYLE_SOLID
|
||||
|
||||
//
|
||||
//#property indicator_minimum 0
|
||||
//#property indicator_maximum 1
|
||||
|
||||
//
|
||||
// set color of horizontal levels ...
|
||||
#property indicator_levelcolor clrGray
|
||||
|
||||
//
|
||||
// set style of horizontal levels ...
|
||||
#property indicator_levelstyle STYLE_DOT
|
||||
|
||||
//
|
||||
// Declare Buffers ...
|
||||
#define fastOSCBufferIndex 0
|
||||
#define slowOSCBufferIndex 1
|
||||
#define powerOSCBufferIndex 2
|
||||
#define varOSCBufferIndex 3
|
||||
#define fastSlowOSCAngleBufferIndex 4
|
||||
|
||||
//
|
||||
double fastOSCBuffer[];
|
||||
double slowOSCBuffer[];
|
||||
double fastSlowOSCAngleBuffer[];
|
||||
double powerOSCBuffer[];
|
||||
double varOSCBuffer[];
|
||||
|
||||
//
|
||||
// Used Indicators List ...
|
||||
string rmaIndicatorName = "x-saherelm.rma";
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// Start Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit() {
|
||||
//
|
||||
// Initialize what we want ...
|
||||
|
||||
//
|
||||
// Validating Input Parameters ...
|
||||
if (
|
||||
fastOSCLength < 0 ||
|
||||
slowOSCLength < 0 ||
|
||||
slowOSCLength <= fastOSCLength
|
||||
) {
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// here we specify logging enabled or not ...
|
||||
enableLogging = true;
|
||||
|
||||
//
|
||||
// this is a Tag which attached to our Logger ...
|
||||
logTag = "XS_OSC";
|
||||
|
||||
//
|
||||
// set descriptions of horizontal levels ...
|
||||
SetLevelValue(0, 0.0);
|
||||
IndicatorSetString(INDICATOR_LEVELTEXT,0,"");
|
||||
|
||||
//
|
||||
// set descriptions of horizontal levels ...
|
||||
SetLevelValue(1, 0.5);
|
||||
IndicatorSetString(INDICATOR_LEVELTEXT,1,"");
|
||||
|
||||
//
|
||||
// set descriptions of horizontal levels ...
|
||||
SetLevelValue(2, 1);
|
||||
IndicatorSetString(INDICATOR_LEVELTEXT,2,"");
|
||||
|
||||
//
|
||||
// Fast OSC Buffer ...
|
||||
SetIndexBuffer(fastOSCBufferIndex, fastOSCBuffer);
|
||||
SetIndexLabel(fastOSCBufferIndex, "Fast OSC");
|
||||
SetIndexDrawBegin(fastOSCBufferIndex, fastOSCLength - 1);
|
||||
|
||||
//
|
||||
// Slow OSC Buffer ...
|
||||
SetIndexBuffer(slowOSCBufferIndex, slowOSCBuffer);
|
||||
SetIndexLabel(slowOSCBufferIndex, "Slow OSC");
|
||||
SetIndexDrawBegin(slowOSCBufferIndex, slowOSCLength - 1);
|
||||
|
||||
//
|
||||
// Power OSC Buffer ...
|
||||
SetIndexBuffer(powerOSCBufferIndex, powerOSCBuffer);
|
||||
SetIndexLabel(powerOSCBufferIndex, "Power OSC");
|
||||
|
||||
//
|
||||
// Var OSC Buffer ...
|
||||
SetIndexBuffer(varOSCBufferIndex, varOSCBuffer);
|
||||
SetIndexLabel(varOSCBufferIndex, "Var OSC");
|
||||
|
||||
//
|
||||
// Tan Fast/Slow OSC Buffer ...
|
||||
SetIndexBuffer(fastSlowOSCAngleBufferIndex, fastSlowOSCAngleBuffer);
|
||||
SetIndexLabel(fastSlowOSCAngleBufferIndex, "F/L OSC Angle");
|
||||
|
||||
//
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//
|
||||
// Do Calculation ...
|
||||
int OnCalculate(
|
||||
const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[]
|
||||
) {
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// because in some cases we may have more than one input for
|
||||
// calculation and we must prevent any calculation
|
||||
// untill we pass the biggest input length, here we get max Input length
|
||||
// and then wait until pass it ...
|
||||
int maxLength = MathMax(fastOSCLength, slowOSCLength);
|
||||
|
||||
//
|
||||
// input variable, we return 0 means nothing passed ...
|
||||
if (rates_total < maxLength) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// found which candles calculated before ...
|
||||
limit = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1;
|
||||
|
||||
//
|
||||
// this is the main loop of calculations, for each bar index ...
|
||||
for (int i = limit - 1; i >= 0; i--) {
|
||||
//
|
||||
// Start Calculation here ...
|
||||
// i is bar_index ...
|
||||
|
||||
//
|
||||
CalculateOscillators(close, i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
|
||||
//
|
||||
// De Initialization ...
|
||||
void OnDeinit(const int reason) {
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
void CalculateOscillators(
|
||||
const double &close[],
|
||||
const int &bar_index
|
||||
) {
|
||||
//
|
||||
// FastOSC ...
|
||||
// Short Cycle Calculations ...
|
||||
int scl = fastOSCLength / 2;
|
||||
int scl2 = scl / 2;
|
||||
double maScl = iCustom(_Symbol, _Period, rmaIndicatorName, scl, 0, bar_index);
|
||||
double scmAtr = iATR(_Symbol, _Period, scl, bar_index);
|
||||
double scmOff = fastOSCMultiplier * scmAtr;
|
||||
double maScl2 = iCustom(_Symbol, _Period, rmaIndicatorName, scl2, 0, bar_index);
|
||||
double sctParam = maScl2 != 0 ? maScl2 : close[bar_index + 1];
|
||||
double sct = sctParam + scmOff;
|
||||
double scb = sctParam - scmOff;
|
||||
|
||||
//
|
||||
// SlowOSC ...
|
||||
// Medium Cycle Calculations ...
|
||||
int mcl = slowOSCLength / 2;
|
||||
int mcl2 = mcl / 2;
|
||||
double maMcl = iCustom(_Symbol, _Period, rmaIndicatorName, mcl, 0, bar_index);
|
||||
double mcmAtr = iATR(_Symbol, _Period, mcl, bar_index);
|
||||
double mcmOff = slowOSCMultiplier * mcmAtr;
|
||||
double maMcl2 = iCustom(_Symbol, _Period, rmaIndicatorName, mcl2, 0, bar_index);
|
||||
double mctParam = maMcl2 != 0 ? maMcl2 : close[bar_index + 1];
|
||||
double mct = mctParam + mcmOff;
|
||||
double mcb = mctParam - mcmOff;
|
||||
|
||||
//
|
||||
double scMM = (sct + scb) / 2;
|
||||
|
||||
//
|
||||
double fastOCS = (close[bar_index] - mcb) / (mct - mcb);
|
||||
fastOSCBuffer[bar_index] = fastOCS;
|
||||
|
||||
//
|
||||
double slowOCS = (scMM - mcb) / (mct - mcb);
|
||||
slowOSCBuffer[bar_index] = slowOCS;
|
||||
|
||||
//
|
||||
// Signal Power ...
|
||||
// Difference Variant between FastOSC and Slow OSC ...
|
||||
double powerOSC = fastOCS - slowOCS;
|
||||
powerOSCBuffer[bar_index] = powerOSC;
|
||||
|
||||
//
|
||||
// Var OSC ...
|
||||
double varOSC = fastOCS - 0.5;
|
||||
varOSCBuffer[bar_index] = varOSC;
|
||||
|
||||
//
|
||||
// Calculate Tan Fast/Slow OSC ...
|
||||
double fastOSCSlope = fastOSCBuffer[bar_index] - fastOSCBuffer[bar_index + 1];
|
||||
double slowOSCSlope = slowOSCBuffer[bar_index] - slowOSCBuffer[bar_index + 1];
|
||||
double tanFastSlowOSC = MathAbs(
|
||||
(fastOSCSlope - slowOSCSlope) / (1 + (fastOSCSlope * slowOSCSlope))
|
||||
);
|
||||
|
||||
//
|
||||
// here we pass Tan of angle ...
|
||||
// fastSlowOSCAngleBuffer[bar_index] = tanFastSlowOSC;
|
||||
|
||||
//
|
||||
// here we pass degree of angle ...
|
||||
fastSlowOSCAngleBuffer[bar_index] = MathArctan(tanFastSlowOSC);
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,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 ...
|
||||
//
|
||||
@@ -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 ...
|
||||
//
|
||||
@@ -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
@@ -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,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);
|
||||
}
|
||||
//+--------------------------------------------------------------------+
|
||||
@@ -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
Reference in New Issue
Block a user