1190 lines
28 KiB
Plaintext
1190 lines
28 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
// SaherElm IT Center MQL5 Indicator
|
|
// -------------------------------------------
|
|
// Name: XCHCHE
|
|
// Description: XCHCHE Cycles ...
|
|
//
|
|
// 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 XCHCHE Indicator"
|
|
#property strict
|
|
|
|
//
|
|
#define ShortName "XCHCHE"
|
|
|
|
//
|
|
// Includes Common Library ...
|
|
#include <MovingAverages.mqh>
|
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
|
|
|
//
|
|
// Inputs ...
|
|
|
|
//
|
|
input group "Market";
|
|
input int length = 35; // Length
|
|
input int loopback = 26; // Loopback
|
|
input double multiplier1 = 3.0; // 1st Multiplier
|
|
input double multiplier2 = 3.5; // 2nd Multiplier
|
|
|
|
//
|
|
input group "Calculation";
|
|
input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to
|
|
input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to
|
|
|
|
//
|
|
input group "Cycles";
|
|
|
|
//
|
|
input group "Short";
|
|
input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period
|
|
input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period
|
|
|
|
//
|
|
input group "Medium";
|
|
input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period
|
|
input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period
|
|
|
|
//
|
|
input group "Long";
|
|
input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period
|
|
input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period
|
|
|
|
//
|
|
input group "Hind";
|
|
input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period
|
|
input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period
|
|
|
|
//
|
|
// Presentation ...
|
|
input group "Presentation";
|
|
|
|
//
|
|
input bool showLE1 = true; // Show Long Exit 1
|
|
input bool showLE2 = true; // Show Long Exit 2
|
|
input bool showSE1 = true; // Show Short Exit 1
|
|
input bool showSE2 = true; // Show Short Exit 2
|
|
|
|
//
|
|
input bool showCurrent = true; // Show Current Cycle
|
|
input bool showShort = true; // Show Short Cycle
|
|
input bool showMedium = true; // Show Medium Cycle
|
|
input bool showLong = true; // Show Long Cycle
|
|
input bool showHind = true; // Show Hind Cycle
|
|
|
|
//
|
|
// Buffers ...
|
|
|
|
//
|
|
#define hideColorIDX 0
|
|
#define bullishColorIDX 1
|
|
#define bearishColorIDX 2
|
|
|
|
//
|
|
#property indicator_chart_window
|
|
|
|
//
|
|
#property indicator_buffers 20
|
|
#property indicator_plots 20
|
|
|
|
//
|
|
// Current ...
|
|
|
|
//
|
|
// Long Exit 1 ...
|
|
#define cLE1BufferIndex 0
|
|
double cLE1Buffer[];
|
|
|
|
//
|
|
#property indicator_label1 "XCHCHE C LE 1"
|
|
#property indicator_type1 DRAW_LINE
|
|
#property indicator_color1 clrLime
|
|
#property indicator_style1 STYLE_DOT
|
|
|
|
//
|
|
// Short Exit 1 ...
|
|
#define cSE1BufferIndex 1
|
|
double cSE1Buffer[];
|
|
|
|
//
|
|
#property indicator_label2 "XCHCHE C SE 1"
|
|
#property indicator_type2 DRAW_LINE
|
|
#property indicator_style2 STYLE_DOT
|
|
#property indicator_color2 clrRed
|
|
|
|
//
|
|
// Long Exit 2 ...
|
|
#define cLE2BufferIndex 2
|
|
double cLE2Buffer[];
|
|
|
|
//
|
|
#property indicator_label3 "XCHCHE C LE 2"
|
|
#property indicator_type3 DRAW_LINE
|
|
#property indicator_style3 STYLE_DOT
|
|
#property indicator_color3 clrAqua
|
|
|
|
//
|
|
// Short Exit 2 ...
|
|
#define cSE2BufferIndex 3
|
|
double cSE2Buffer[];
|
|
|
|
//
|
|
#property indicator_label4 "XCHCHE C SE 2"
|
|
#property indicator_type4 DRAW_LINE
|
|
#property indicator_style4 STYLE_DOT
|
|
#property indicator_color4 clrMagenta
|
|
|
|
//
|
|
// Short ...
|
|
|
|
//
|
|
// Long Exit 1 ...
|
|
#define sLE1BufferIndex 4
|
|
double sLE1Buffer[];
|
|
|
|
//
|
|
#property indicator_label5 "XCHCHE S LE 1"
|
|
#property indicator_type5 DRAW_LINE
|
|
#property indicator_color5 clrLime
|
|
#property indicator_style5 STYLE_DOT
|
|
|
|
//
|
|
// Short Exit 1 ...
|
|
#define sSE1BufferIndex 5
|
|
double sSE1Buffer[];
|
|
|
|
//
|
|
#property indicator_label6 "XCHCHE S SE 1"
|
|
#property indicator_type6 DRAW_LINE
|
|
#property indicator_style6 STYLE_DOT
|
|
#property indicator_color6 clrRed
|
|
|
|
//
|
|
// Long Exit 2 ...
|
|
#define sLE2BufferIndex 6
|
|
double sLE2Buffer[];
|
|
|
|
//
|
|
#property indicator_label7 "XCHCHE S LE 2"
|
|
#property indicator_type7 DRAW_LINE
|
|
#property indicator_style7 STYLE_DOT
|
|
#property indicator_color7 clrAqua
|
|
|
|
//
|
|
// Short Exit 2 ...
|
|
#define sSE2BufferIndex 7
|
|
double sSE2Buffer[];
|
|
|
|
//
|
|
#property indicator_label8 "XCHCHE S SE 2"
|
|
#property indicator_type8 DRAW_LINE
|
|
#property indicator_style8 STYLE_DOT
|
|
#property indicator_color8 clrMagenta
|
|
|
|
//
|
|
// Medium ...
|
|
|
|
//
|
|
// Long Exit 1 ...
|
|
#define mLE1BufferIndex 8
|
|
double mLE1Buffer[];
|
|
|
|
//
|
|
#property indicator_label9 "XCHCHE M LE 1"
|
|
#property indicator_type9 DRAW_LINE
|
|
#property indicator_color9 clrLime
|
|
#property indicator_style9 STYLE_DOT
|
|
|
|
//
|
|
// Short Exit 1 ...
|
|
#define mSE1BufferIndex 9
|
|
double mSE1Buffer[];
|
|
|
|
//
|
|
#property indicator_label10 "XCHCHE M SE 1"
|
|
#property indicator_type10 DRAW_LINE
|
|
#property indicator_style10 STYLE_DOT
|
|
#property indicator_color10 clrRed
|
|
|
|
//
|
|
// Long Exit 2 ...
|
|
#define mLE2BufferIndex 10
|
|
double mLE2Buffer[];
|
|
|
|
//
|
|
#property indicator_label11 "XCHCHE M LE 2"
|
|
#property indicator_type11 DRAW_LINE
|
|
#property indicator_style11 STYLE_DOT
|
|
#property indicator_color11 clrAqua
|
|
|
|
//
|
|
// Short Exit 2 ...
|
|
#define mSE2BufferIndex 11
|
|
double mSE2Buffer[];
|
|
|
|
//
|
|
#property indicator_label12 "XCHCHE M SE 2"
|
|
#property indicator_type12 DRAW_LINE
|
|
#property indicator_style12 STYLE_DOT
|
|
#property indicator_color12 clrMagenta
|
|
|
|
//
|
|
// Long ...
|
|
|
|
//
|
|
// Long Exit 1 ...
|
|
#define lLE1BufferIndex 12
|
|
double lLE1Buffer[];
|
|
|
|
//
|
|
#property indicator_label13 "XCHCHE L LE 1"
|
|
#property indicator_type13 DRAW_LINE
|
|
#property indicator_color13 clrLime
|
|
#property indicator_style13 STYLE_DOT
|
|
|
|
//
|
|
// Short Exit 1 ...
|
|
#define lSE1BufferIndex 13
|
|
double lSE1Buffer[];
|
|
|
|
//
|
|
#property indicator_label14 "XCHCHE L SE 1"
|
|
#property indicator_type14 DRAW_LINE
|
|
#property indicator_style14 STYLE_DOT
|
|
#property indicator_color14 clrRed
|
|
|
|
//
|
|
// Long Exit 2 ...
|
|
#define lLE2BufferIndex 14
|
|
double lLE2Buffer[];
|
|
|
|
//
|
|
#property indicator_label15 "XCHCHE L LE 2"
|
|
#property indicator_type15 DRAW_LINE
|
|
#property indicator_style15 STYLE_DOT
|
|
#property indicator_color15 clrAqua
|
|
|
|
//
|
|
// Short Exit 2 ...
|
|
#define lSE2BufferIndex 15
|
|
double lSE2Buffer[];
|
|
|
|
//
|
|
#property indicator_label16 "XCHCHE L SE 2"
|
|
#property indicator_type16 DRAW_LINE
|
|
#property indicator_style16 STYLE_DOT
|
|
#property indicator_color16 clrMagenta
|
|
|
|
//
|
|
// Hind ...
|
|
|
|
//
|
|
// Long Exit 1 ...
|
|
#define hLE1BufferIndex 16
|
|
double hLE1Buffer[];
|
|
|
|
//
|
|
#property indicator_label17 "XCHCHE H LE 1"
|
|
#property indicator_type17 DRAW_LINE
|
|
#property indicator_color17 clrLime
|
|
#property indicator_style17 STYLE_DOT
|
|
|
|
//
|
|
// Short Exit 1 ...
|
|
#define hSE1BufferIndex 17
|
|
double hSE1Buffer[];
|
|
|
|
//
|
|
#property indicator_label18 "XCHCHE H SE 1"
|
|
#property indicator_type18 DRAW_LINE
|
|
#property indicator_style18 STYLE_DOT
|
|
#property indicator_color18 clrRed
|
|
|
|
//
|
|
// Long Exit 2 ...
|
|
#define hLE2BufferIndex 18
|
|
double hLE2Buffer[];
|
|
|
|
//
|
|
#property indicator_label19 "XCHCHE H LE 2"
|
|
#property indicator_type19 DRAW_LINE
|
|
#property indicator_style19 STYLE_DOT
|
|
#property indicator_color19 clrAqua
|
|
|
|
//
|
|
// Short Exit 2 ...
|
|
#define hSE2BufferIndex 19
|
|
double hSE2Buffer[];
|
|
|
|
//
|
|
#property indicator_label20 "XCHCHE H SE 2"
|
|
#property indicator_type20 DRAW_LINE
|
|
#property indicator_style20 STYLE_DOT
|
|
#property indicator_color20 clrMagenta
|
|
|
|
//
|
|
// Variables, Properties and etc ...
|
|
|
|
//
|
|
int maxLength;
|
|
|
|
//
|
|
#define hi1Idx 0
|
|
#define lo1Idx 1
|
|
#define hi2Idx 2
|
|
#define lo2Idx 3
|
|
#define trend1Idx 4
|
|
#define trend2Idx 5
|
|
|
|
//
|
|
// Current ...
|
|
int mCSMLength = length;
|
|
double cWork[][6];
|
|
|
|
//
|
|
// Short ...
|
|
int mSCLength = 0;
|
|
int mSSMLength = 0;
|
|
ENUM_TIMEFRAMES mSCPeriod = NULL;
|
|
double sWork[][6];
|
|
|
|
//
|
|
// Medium ...
|
|
int mMCLength = 0;
|
|
int mMSMLength = 0;
|
|
ENUM_TIMEFRAMES mMCPeriod = NULL;
|
|
double mWork[][6];
|
|
|
|
//
|
|
// Long ...
|
|
int mLCLength = 0;
|
|
int mLSMLength = 0;
|
|
ENUM_TIMEFRAMES mLCPeriod = NULL;
|
|
double lWork[][6];
|
|
|
|
//
|
|
// Hind ...
|
|
int mHCLength = 0;
|
|
int mHSMLength = 0;
|
|
ENUM_TIMEFRAMES mHCPeriod = NULL;
|
|
double hWork[][6];
|
|
|
|
//
|
|
// Event Handlers ...
|
|
|
|
//
|
|
// Initialization ...
|
|
int OnInit()
|
|
{
|
|
//
|
|
// Validate Inputs ...
|
|
if (!ValidateInputs())
|
|
{
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
}
|
|
|
|
//
|
|
if (!InitMarketCycles())
|
|
{
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
}
|
|
|
|
//
|
|
// 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 ...
|
|
maxLength = ExtractMaxLengthOfInputs();
|
|
|
|
//
|
|
// Define Index Buffers ...
|
|
DefineBuffers();
|
|
|
|
//
|
|
// Set Indicator ShortName ...
|
|
SetIndicatorName();
|
|
|
|
//
|
|
// Init Succeed ...
|
|
return INIT_SUCCEEDED;
|
|
}
|
|
|
|
//
|
|
// DeInitialization ...
|
|
void OnDeinit(const int reason)
|
|
{
|
|
//
|
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
|
// REASON_REMOVE 1 Program removed from a chart
|
|
// REASON_RECOMPILE 2 Program recompiled
|
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
|
// REASON_CHARTCLOSE 4 Chart closed
|
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
|
// REASON_TEMPLATE 7 Another chart template applied
|
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
|
// REASON_CLOSE 9 Terminal closed
|
|
}
|
|
|
|
//
|
|
// Calculating what we want ...
|
|
int OnCalculate(
|
|
const int rates_total, // Total Bars on Chart ...
|
|
const int prev_calculated, // Total Calculated Bars on Charts ...
|
|
const datetime &time[], // History of Open Time ...
|
|
const double &open[], // History of Open Price ...
|
|
const double &high[], // History of High Price ...
|
|
const double &low[], // History of Low Price ...
|
|
const double &close[], // History of Close Price ...
|
|
const long &tick_volume[], // History of Tick Volumes on Bar ...
|
|
const long &volume[], // History of Trade Volumes ...
|
|
const int &spread[] // History of Spread Price ...
|
|
)
|
|
{
|
|
//
|
|
if (Bars(_Symbol, _Period) < rates_total)
|
|
{
|
|
return (prev_calculated);
|
|
}
|
|
|
|
//
|
|
if (ArrayRange(cWork, 0) != rates_total)
|
|
{
|
|
//
|
|
ArrayResize(cWork, rates_total);
|
|
ArrayResize(sWork, rates_total);
|
|
ArrayResize(mWork, rates_total);
|
|
ArrayResize(lWork, rates_total);
|
|
ArrayResize(hWork, rates_total);
|
|
}
|
|
|
|
//
|
|
// this counts Available Bars ...
|
|
int limit;
|
|
|
|
//
|
|
limit = prev_calculated - 1;
|
|
if (limit < 0)
|
|
{
|
|
limit = 0;
|
|
}
|
|
|
|
//
|
|
// Main Loop ...
|
|
for (int i = limit; i < rates_total && !IsStopped(); i++)
|
|
{
|
|
//
|
|
CalculateBuffers(
|
|
//
|
|
i,
|
|
prev_calculated,
|
|
rates_total,
|
|
//
|
|
open,
|
|
high,
|
|
low,
|
|
close //
|
|
);
|
|
}
|
|
|
|
//
|
|
return rates_total;
|
|
}
|
|
|
|
//
|
|
// Functions ...
|
|
|
|
//
|
|
// Validate Input Args for Initialization ...
|
|
bool ValidateInputs()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
length >= 2 &&
|
|
loopback >= 0 &&
|
|
//
|
|
(IsValid(scMethod, scPeriod) &&
|
|
IsValid(mcMethod, mcPeriod) &&
|
|
IsValid(lcMethod, lcPeriod) &&
|
|
IsValid(hcMethod, hcPeriod))
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Initialize Market Cycles ...
|
|
bool InitMarketCycles()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Current Cycle Initialization ...
|
|
|
|
//
|
|
int cPeriodSeconds = PeriodSeconds(_Period);
|
|
|
|
//
|
|
// Short Cycle Initialization ...
|
|
|
|
//
|
|
// Find Cycle Period ...
|
|
if (scMethod == X_PERIOD_AUTO)
|
|
{
|
|
//
|
|
// Select Period ...
|
|
mSCPeriod = GetCyclePeriod(
|
|
X_MARKET_CYCLE_SHORT,
|
|
_Period //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
mSCPeriod = scPeriod;
|
|
}
|
|
|
|
//
|
|
result = IsValid(mSCPeriod);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mSCLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds;
|
|
mSSMLength = mSCLength * mCSMLength;
|
|
result = mSCLength > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Medium Cycle Initialization ...
|
|
|
|
//
|
|
// Find Cycle Period ...
|
|
if (mcMethod == X_PERIOD_AUTO)
|
|
{
|
|
//
|
|
// Select Period ...
|
|
mMCPeriod = GetCyclePeriod(
|
|
X_MARKET_CYCLE_MEDIUM,
|
|
_Period //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
mMCPeriod = mcPeriod;
|
|
}
|
|
|
|
//
|
|
result = IsValid(mMCPeriod);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mMCLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds;
|
|
mMSMLength = mMCLength * mCSMLength;
|
|
result = mMCLength > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Long Cycle Initialization ...
|
|
|
|
//
|
|
// Find Cycle Period ...
|
|
if (lcMethod == X_PERIOD_AUTO)
|
|
{
|
|
//
|
|
// Select Period ...
|
|
mLCPeriod = GetCyclePeriod(
|
|
X_MARKET_CYCLE_LONG,
|
|
_Period //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
mLCPeriod = lcPeriod;
|
|
}
|
|
|
|
//
|
|
result = IsValid(mLCPeriod);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mLCLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds;
|
|
mLSMLength = mLCLength * mCSMLength;
|
|
result = mLCLength > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Hind Cycle Initialization ...
|
|
|
|
//
|
|
// Find Cycle Period ...
|
|
if (hcMethod == X_PERIOD_AUTO)
|
|
{
|
|
//
|
|
// Select Period ...
|
|
mHCPeriod = GetCyclePeriod(
|
|
X_MARKET_CYCLE_HIND,
|
|
_Period //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
mHCPeriod = hcPeriod;
|
|
}
|
|
|
|
//
|
|
result = IsValid(mHCPeriod);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mHCLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds;
|
|
mHSMLength = mHCLength * mCSMLength;
|
|
result = mHCLength > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve all Exists Input Max Length ...
|
|
// use for Start Of Drawing ...
|
|
int ExtractMaxLengthOfInputs()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
result = MathMax(mCSMLength, mSSMLength);
|
|
result = MathMax(result, mMSMLength);
|
|
result = MathMax(result, mLSMLength);
|
|
result = MathMax(result, mHSMLength);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Define Indexes and Styles ...
|
|
void DefineBuffers()
|
|
{
|
|
//
|
|
// Current ...
|
|
|
|
//
|
|
// Long Exit 1 ...
|
|
bool canShowCLE1 = showCurrent && showLE1;
|
|
ENUM_DRAW_TYPE cLE1DrawType = canShowCLE1 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(cLE1BufferIndex, cLE1Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(cLE1BufferIndex, PLOT_SHOW_DATA, canShowCLE1);
|
|
PlotIndexSetInteger(cLE1BufferIndex, PLOT_DRAW_TYPE, cLE1DrawType);
|
|
|
|
//
|
|
// Long Exit 2 ...
|
|
bool canShowCLE2 = showCurrent && showLE2;
|
|
ENUM_DRAW_TYPE cLE2DrawType = canShowCLE2 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(cLE2BufferIndex, cLE2Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(cLE2BufferIndex, PLOT_SHOW_DATA, canShowCLE2);
|
|
PlotIndexSetInteger(cLE2BufferIndex, PLOT_DRAW_TYPE, cLE2DrawType);
|
|
|
|
//
|
|
// Short Exit 1 ...
|
|
bool canShowCSE1 = showCurrent && showSE1;
|
|
ENUM_DRAW_TYPE cSE1DrawType = canShowCSE1 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(cSE1BufferIndex, cSE1Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(cSE1BufferIndex, PLOT_SHOW_DATA, canShowCSE1);
|
|
PlotIndexSetInteger(cSE1BufferIndex, PLOT_DRAW_TYPE, cSE1DrawType);
|
|
|
|
//
|
|
// Short Exit 2 ...
|
|
bool canShowCSE2 = showCurrent && showSE2;
|
|
ENUM_DRAW_TYPE cSE2DrawType = canShowCSE2 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(cSE2BufferIndex, cSE2Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(cSE2BufferIndex, PLOT_SHOW_DATA, canShowCSE2);
|
|
PlotIndexSetInteger(cSE2BufferIndex, PLOT_DRAW_TYPE, cSE2DrawType);
|
|
|
|
//
|
|
// Short ...
|
|
|
|
//
|
|
// Long Exit 1 ...
|
|
bool canShowSLE1 = showShort && showLE1;
|
|
ENUM_DRAW_TYPE sLE1DrawType = canShowSLE1 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(sLE1BufferIndex, sLE1Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(sLE1BufferIndex, PLOT_SHOW_DATA, canShowSLE1);
|
|
PlotIndexSetInteger(sLE1BufferIndex, PLOT_DRAW_TYPE, sLE1DrawType);
|
|
|
|
//
|
|
// Long Exit 2 ...
|
|
bool canShowSLE2 = showShort && showLE2;
|
|
ENUM_DRAW_TYPE sLE2DrawType = canShowSLE2 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(sLE2BufferIndex, sLE2Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(sLE2BufferIndex, PLOT_SHOW_DATA, canShowSLE2);
|
|
PlotIndexSetInteger(sLE2BufferIndex, PLOT_DRAW_TYPE, sLE2DrawType);
|
|
|
|
//
|
|
bool canShowSSE1 = showShort && showSE1;
|
|
// Short Exit 1 ...
|
|
ENUM_DRAW_TYPE sSE1DrawType = canShowSSE1 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(sSE1BufferIndex, sSE1Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(sSE1BufferIndex, PLOT_SHOW_DATA, canShowSSE1);
|
|
PlotIndexSetInteger(sSE1BufferIndex, PLOT_DRAW_TYPE, sSE1DrawType);
|
|
|
|
//
|
|
// Short Exit 2 ...
|
|
bool canShowSSE2 = showShort && showSE2;
|
|
ENUM_DRAW_TYPE sSE2DrawType = canShowSSE2 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(sSE2BufferIndex, sSE2Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(sSE2BufferIndex, PLOT_SHOW_DATA, canShowSSE2);
|
|
PlotIndexSetInteger(sSE2BufferIndex, PLOT_DRAW_TYPE, sSE2DrawType);
|
|
|
|
//
|
|
// Medium ...
|
|
|
|
//
|
|
// Long Exit 1 ...
|
|
bool canShowMLE1 = showMedium && showLE1;
|
|
ENUM_DRAW_TYPE mLE1DrawType = canShowMLE1 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(mLE1BufferIndex, mLE1Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(mLE1BufferIndex, PLOT_SHOW_DATA, canShowMLE1);
|
|
PlotIndexSetInteger(mLE1BufferIndex, PLOT_DRAW_TYPE, mLE1DrawType);
|
|
|
|
//
|
|
// Long Exit 2 ...
|
|
bool canShowMLE2 = showMedium && showLE2;
|
|
ENUM_DRAW_TYPE mLE2DrawType = canShowMLE2 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(mLE2BufferIndex, mLE2Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(mLE2BufferIndex, PLOT_SHOW_DATA, canShowMLE2);
|
|
PlotIndexSetInteger(mLE2BufferIndex, PLOT_DRAW_TYPE, mLE2DrawType);
|
|
|
|
//
|
|
// Short Exit 1 ...
|
|
bool canShowMSE1 = showMedium && showSE1;
|
|
ENUM_DRAW_TYPE mSE1DrawType = canShowMSE1 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(mSE1BufferIndex, mSE1Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(mSE1BufferIndex, PLOT_SHOW_DATA, canShowMSE1);
|
|
PlotIndexSetInteger(mSE1BufferIndex, PLOT_DRAW_TYPE, mSE1DrawType);
|
|
|
|
//
|
|
// Short Exit 2 ...
|
|
bool canShowMSE2 = showMedium && showSE2;
|
|
ENUM_DRAW_TYPE mSE2DrawType = canShowMSE2 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(mSE2BufferIndex, mSE2Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(mSE2BufferIndex, PLOT_SHOW_DATA, canShowMSE2);
|
|
PlotIndexSetInteger(mSE2BufferIndex, PLOT_DRAW_TYPE, mSE2DrawType);
|
|
|
|
//
|
|
// Long ...
|
|
|
|
//
|
|
// Long Exit 1 ...
|
|
bool canShowLLE1 = showLong && showLE1;
|
|
ENUM_DRAW_TYPE lLE1DrawType = canShowLLE1 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(lLE1BufferIndex, lLE1Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(lLE1BufferIndex, PLOT_SHOW_DATA, canShowLLE1);
|
|
PlotIndexSetInteger(lLE1BufferIndex, PLOT_DRAW_TYPE, lLE1DrawType);
|
|
|
|
//
|
|
// Long Exit 2 ...
|
|
bool canShowLLE2 = showLong && showLE2;
|
|
ENUM_DRAW_TYPE lLE2DrawType = canShowLLE2 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(lLE2BufferIndex, lLE2Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(lLE2BufferIndex, PLOT_SHOW_DATA, canShowLLE2);
|
|
PlotIndexSetInteger(lLE2BufferIndex, PLOT_DRAW_TYPE, lLE2DrawType);
|
|
|
|
//
|
|
// Short Exit 1 ...
|
|
bool canShowLSE1 = showLong && showSE1;
|
|
ENUM_DRAW_TYPE lSE1DrawType = canShowLSE1 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(lSE1BufferIndex, lSE1Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(lSE1BufferIndex, PLOT_SHOW_DATA, canShowLSE1);
|
|
PlotIndexSetInteger(lSE1BufferIndex, PLOT_DRAW_TYPE, lSE1DrawType);
|
|
|
|
//
|
|
// Short Exit 2 ...
|
|
bool canShowLSE2 = showLong && showSE2;
|
|
ENUM_DRAW_TYPE lSE2DrawType = canShowLSE2 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(lSE2BufferIndex, lSE2Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(lSE2BufferIndex, PLOT_SHOW_DATA, canShowLSE2);
|
|
PlotIndexSetInteger(lSE2BufferIndex, PLOT_DRAW_TYPE, lSE2DrawType);
|
|
|
|
//
|
|
// Hind ...
|
|
|
|
//
|
|
// Long Exit 1 ...
|
|
bool canShowHLE1 = showHind && showLE1;
|
|
ENUM_DRAW_TYPE hLE1DrawType = canShowHLE1 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(hLE1BufferIndex, hLE1Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(hLE1BufferIndex, PLOT_SHOW_DATA, canShowHLE1);
|
|
PlotIndexSetInteger(hLE1BufferIndex, PLOT_DRAW_TYPE, hLE1DrawType);
|
|
|
|
//
|
|
// Long Exit 2 ...
|
|
bool canShowHLE2 = showHind && showLE2;
|
|
ENUM_DRAW_TYPE hLE2DrawType = canShowHLE2 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(hLE2BufferIndex, hLE2Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(hLE2BufferIndex, PLOT_SHOW_DATA, canShowHLE2);
|
|
PlotIndexSetInteger(hLE2BufferIndex, PLOT_DRAW_TYPE, hLE2DrawType);
|
|
|
|
//
|
|
// Short Exit 1 ...
|
|
bool canShowHSE1 = showHind && showSE1;
|
|
ENUM_DRAW_TYPE hSE1DrawType = canShowHSE1 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(hSE1BufferIndex, hSE1Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(hSE1BufferIndex, PLOT_SHOW_DATA, canShowHSE1);
|
|
PlotIndexSetInteger(hSE1BufferIndex, PLOT_DRAW_TYPE, hSE1DrawType);
|
|
|
|
//
|
|
// Short Exit 2 ...
|
|
bool canShowHSE2 = showHind && showSE2;
|
|
ENUM_DRAW_TYPE hSE2DrawType = canShowHSE2 ? DRAW_LINE : DRAW_NONE;
|
|
SetIndexBuffer(hSE2BufferIndex, hSE2Buffer, INDICATOR_DATA);
|
|
PlotIndexSetInteger(hSE2BufferIndex, PLOT_SHOW_DATA, canShowHSE2);
|
|
PlotIndexSetInteger(hSE2BufferIndex, PLOT_DRAW_TYPE, hSE2DrawType);
|
|
}
|
|
|
|
//
|
|
// Set Indicator Short Name and also we can define Buffers Labels ...
|
|
void SetIndicatorName()
|
|
{
|
|
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
|
}
|
|
|
|
//
|
|
// Calculations ...
|
|
|
|
//
|
|
// Calculate Buffers ...
|
|
void CalculateBuffers(
|
|
int bar_index, // Selected Bar Index
|
|
const int prevCalculated,
|
|
const int ratesTotal,
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &close[],
|
|
const double &low[] //
|
|
)
|
|
{
|
|
//
|
|
CalculateCycles(
|
|
bar_index,
|
|
prevCalculated,
|
|
ratesTotal,
|
|
open,
|
|
high,
|
|
close,
|
|
low //
|
|
);
|
|
}
|
|
|
|
//
|
|
void CalculateCycles(
|
|
int bar_index, // Selected Bar Index
|
|
const int prevCalculated,
|
|
const int ratesTotal,
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &close[],
|
|
const double &low[] //
|
|
)
|
|
{
|
|
//
|
|
// CURRENT ...
|
|
CalculateCycle(
|
|
bar_index,
|
|
prevCalculated,
|
|
ratesTotal,
|
|
open,
|
|
high,
|
|
close,
|
|
low,
|
|
mCSMLength,
|
|
cWork,
|
|
cLE1Buffer,
|
|
cLE2Buffer,
|
|
cSE1Buffer,
|
|
cSE2Buffer //
|
|
);
|
|
|
|
//
|
|
// SHORT ...
|
|
CalculateCycle(
|
|
bar_index,
|
|
prevCalculated,
|
|
ratesTotal,
|
|
open,
|
|
high,
|
|
close,
|
|
low,
|
|
mSSMLength,
|
|
sWork,
|
|
sLE1Buffer,
|
|
sLE2Buffer,
|
|
sSE1Buffer,
|
|
sSE2Buffer //
|
|
);
|
|
|
|
//
|
|
// MEDIUM ...
|
|
CalculateCycle(
|
|
bar_index,
|
|
prevCalculated,
|
|
ratesTotal,
|
|
open,
|
|
high,
|
|
close,
|
|
low,
|
|
mMSMLength,
|
|
mWork,
|
|
mLE1Buffer,
|
|
mLE2Buffer,
|
|
mSE1Buffer,
|
|
mSE2Buffer //
|
|
);
|
|
|
|
//
|
|
// LONG ...
|
|
CalculateCycle(
|
|
bar_index,
|
|
prevCalculated,
|
|
ratesTotal,
|
|
open,
|
|
high,
|
|
close,
|
|
low,
|
|
mLSMLength,
|
|
lWork,
|
|
lLE1Buffer,
|
|
lLE2Buffer,
|
|
lSE1Buffer,
|
|
lSE2Buffer //
|
|
);
|
|
|
|
//
|
|
// HIND ...
|
|
CalculateCycle(
|
|
bar_index,
|
|
prevCalculated,
|
|
ratesTotal,
|
|
open,
|
|
high,
|
|
close,
|
|
low,
|
|
mHSMLength,
|
|
hWork,
|
|
hLE1Buffer,
|
|
hLE2Buffer,
|
|
hSE1Buffer,
|
|
hSE2Buffer //
|
|
);
|
|
}
|
|
|
|
//
|
|
void CalculateCycle(
|
|
int bar_index, // Selected Bar Index
|
|
const int prevCalculated,
|
|
const int ratesTotal,
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &close[],
|
|
const double &low[],
|
|
//
|
|
int _length, // Calculation Length
|
|
double &work[][], // Working Array
|
|
//
|
|
double &le1[],
|
|
double &le2[],
|
|
double &se1[],
|
|
double &se2[] //
|
|
)
|
|
{
|
|
//
|
|
// Cleanup Buffers ...
|
|
le1[bar_index] = se1[bar_index] = EMPTY_VALUE;
|
|
le2[bar_index] = se2[bar_index] = EMPTY_VALUE;
|
|
|
|
//
|
|
int start = MathMax(bar_index - loopback, 0);
|
|
|
|
//
|
|
// Calculate ATR Value ...
|
|
double atrValue = 0;
|
|
for (int k = 1; k <= _length && (bar_index - k - 1) >= 0; k++)
|
|
{
|
|
//
|
|
atrValue += MathMax(high[bar_index - k], close[MathMax(bar_index - k - 1, 0)]) -
|
|
MathMin(low[bar_index - k], close[MathMax(bar_index - k - 1, 0)]);
|
|
}
|
|
atrValue /= (double)_length;
|
|
|
|
//
|
|
// Retrieve Highest High and Lowest Lows ...
|
|
double loopbackMax = high[ArrayMaximum(high, start, loopback)];
|
|
double loopbackMin = low[ArrayMinimum(low, start, loopback)];
|
|
|
|
//
|
|
// Fill Multi Dimesional Working Array ...
|
|
work[bar_index][hi1Idx] = loopbackMax - multiplier1 * atrValue;
|
|
work[bar_index][lo1Idx] = loopbackMin + multiplier1 * atrValue;
|
|
work[bar_index][hi2Idx] = loopbackMax - multiplier2 * atrValue;
|
|
work[bar_index][lo2Idx] = loopbackMin + multiplier2 * atrValue;
|
|
work[bar_index][trend1Idx] = (bar_index > 0) ? work[bar_index - 1][trend1Idx] : 0;
|
|
work[bar_index][trend2Idx] = (bar_index > 0) ? work[bar_index - 1][trend2Idx] : 0;
|
|
|
|
//
|
|
if (bar_index > 0)
|
|
{
|
|
//
|
|
// Calculate Trends ...
|
|
if (close[bar_index] > work[bar_index - 1][lo1Idx])
|
|
{
|
|
work[bar_index][trend1Idx] = 1;
|
|
}
|
|
|
|
//
|
|
if (close[bar_index] < work[bar_index - 1][hi1Idx])
|
|
{
|
|
work[bar_index][trend1Idx] = -1;
|
|
}
|
|
|
|
//
|
|
if (close[bar_index] > work[bar_index - 1][lo2Idx])
|
|
{
|
|
work[bar_index][trend2Idx] = 1;
|
|
}
|
|
|
|
//
|
|
if (close[bar_index] < work[bar_index - 1][hi2Idx])
|
|
{
|
|
work[bar_index][trend2Idx] = -1;
|
|
}
|
|
|
|
//
|
|
// Calculate Exit Values ...
|
|
|
|
//
|
|
// Exit 1 ...
|
|
|
|
//
|
|
// Long ...
|
|
if (multiplier1 > 0 && work[bar_index][trend1Idx] == 1)
|
|
{
|
|
//
|
|
if (work[bar_index][hi1Idx] < work[bar_index - 1][hi1Idx])
|
|
{
|
|
work[bar_index][hi1Idx] = work[bar_index - 1][hi1Idx];
|
|
}
|
|
|
|
//
|
|
le1[bar_index] = work[bar_index][hi1Idx];
|
|
|
|
// //
|
|
// if (le1[bar_index - 1] == EMPTY_VALUE)
|
|
// {
|
|
// longExit1StartBuffer[bar_index] = le1[bar_index];
|
|
// }
|
|
}
|
|
|
|
//
|
|
// Short ...
|
|
if (multiplier1 > 0 && work[bar_index][trend1Idx] == -1)
|
|
{
|
|
//
|
|
if (work[bar_index][lo1Idx] > work[bar_index - 1][lo1Idx])
|
|
{
|
|
work[bar_index][lo1Idx] = work[bar_index - 1][lo1Idx];
|
|
}
|
|
|
|
//
|
|
se1[bar_index] = work[bar_index][lo1Idx];
|
|
|
|
// //
|
|
// if (se1[bar_index - 1] == EMPTY_VALUE)
|
|
// {
|
|
// shortExit1StartBuffer[bar_index] = se1[bar_index];
|
|
// }
|
|
}
|
|
|
|
//
|
|
// Exit 2 ...
|
|
|
|
//
|
|
// Long ...
|
|
if (multiplier2 > 0 && work[bar_index][trend2Idx] == 1)
|
|
{
|
|
if (work[bar_index][hi2Idx] < work[bar_index - 1][hi2Idx])
|
|
{
|
|
work[bar_index][hi2Idx] = work[bar_index - 1][hi2Idx];
|
|
}
|
|
|
|
//
|
|
le2[bar_index] = work[bar_index][hi2Idx];
|
|
|
|
// //
|
|
// if (le2[bar_index - 1] == EMPTY_VALUE)
|
|
// {
|
|
// longExit2StartBuffer[bar_index] = le2[bar_index];
|
|
// }
|
|
}
|
|
|
|
//
|
|
// Short ...
|
|
if (multiplier2 > 0 && work[bar_index][trend2Idx] == -1)
|
|
{
|
|
//
|
|
if (work[bar_index][lo2Idx] > work[bar_index - 1][lo2Idx])
|
|
{
|
|
work[bar_index][lo2Idx] = work[bar_index - 1][lo2Idx];
|
|
}
|
|
|
|
//
|
|
se2[bar_index] = work[bar_index][lo2Idx];
|
|
|
|
// //
|
|
// if (se2[bar_index - 1] == EMPTY_VALUE)
|
|
// {
|
|
// shortExit2StartBuffer[bar_index] = se2[bar_index];
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
|
|
// |