2452 lines
58 KiB
Plaintext
2452 lines
58 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Indicator
|
|
// -------------------------------------------------
|
|
// Name: X121 X3MA
|
|
// Description: X3MA ...
|
|
//
|
|
//
|
|
// 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 X121 XCZone Indicator"
|
|
#property strict
|
|
|
|
//
|
|
// Definitions ...
|
|
//
|
|
#define ShortName "X121 XCZone"
|
|
|
|
//
|
|
// Includes Common Library ...
|
|
#include "../Classes/x-saherelm.x-alert.class.mq5"
|
|
#include "../Classes/x-saherelm.x-bar.analyser.class.mq5"
|
|
#include "../Classes/x-saherelm.x-poi.drawer.class.mq5"
|
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
|
#include "../Libraries/x-saherelm.x-poi.lib.mq5"
|
|
|
|
//
|
|
// Inputs ...
|
|
input group "Market";
|
|
input ENUM_X_PERIOD_METHOD trendPeriodMethod = X_PERIOD_AUTO; // How to Find Trend Period
|
|
input ENUM_TIMEFRAMES trendPeriod = NULL; // Trend Time Period
|
|
input ENUM_MA_METHOD trendMode = MODE_SMA; // Trend Mode
|
|
input ENUM_APPLIED_PRICE trendAppliedTo = PRICE_CLOSE; // Trend Applied To
|
|
input double sarStep = 0.02; // Sar Step
|
|
input double sarMax = 0.2; // Sar Maximum
|
|
input int adxLength = 14; // ADX Length
|
|
input double adxThreshold = 25.0; // ADX Threshold
|
|
input int rsiLength = 14; // RSI Length
|
|
input double rsiOBLevel = 70.0; // RSI OB Level
|
|
input double rsiOSLevel = 30.0; // RSI OS Level
|
|
input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // RSI Applied To
|
|
input int deltaSignalLength = 14; // Delta Signal Length
|
|
input ENUM_X_MA_METHOD deltaSignalMethod = X_MA_MODE_EMA; // Delta Signalling Method
|
|
input int volumeSignalLength = 14; // Volume Signal Length
|
|
input ENUM_X_MA_METHOD volumeSignalMethod = X_MA_MODE_EMA; // Volume Signalling Method
|
|
|
|
//
|
|
// Validating ...
|
|
input group "Validating";
|
|
input int minZoneLength = 7; // Minimum Length of Consolidation Zone
|
|
input double maxZoneRangeInPoints = 70; // Max Zone Range in Point
|
|
input double maxAllowedEntryDistance = 30; // Max Allowed Entry Distance
|
|
input bool forceGapBarsBreakout = true; // Force Zone's Gap Bar's Breakes Out
|
|
input bool forceHasSwing = true; // Force Zone's Has Propper Swing
|
|
input bool forceHasPinBarEntry = true; // Force Zone's Ends with a Pin Bar
|
|
|
|
//
|
|
// Filtering ...
|
|
input group "Filtering";
|
|
input bool filterBasedOnSar = false; // Filter Pivots Based on Sar
|
|
input bool filterBasedOnRSI = false; // Filter Pivots Based on RSI
|
|
input bool filterBasedOnADX = false; // Filter Pivots Based on ADX
|
|
input bool filterBasedOnTrend = false; // Filter Pivots Based on Trend
|
|
|
|
//
|
|
// Presentation ...
|
|
input group "Presentation";
|
|
input bool showSar = false; // Show Sar
|
|
input bool showTrend = false; // Show Trend
|
|
input bool rayLeft = false; // Ray to Left
|
|
input bool drawZones = true; // Draw Detected Zones
|
|
input bool drawRRofZones = true; // Draw Zone's Risk Reward Ratios
|
|
input int boxWidth = 2; // Box Width
|
|
input color bullishColor = clrLime; // Bullish Color
|
|
input color bearishColor = clrRed; // Bearish Color
|
|
input ENUM_LINE_STYLE boxStyle = STYLE_SOLID; // Box Style
|
|
|
|
//
|
|
input int startCalculationForLastBars = 5000; // Calculate Last n Bars
|
|
int sarArrowCode = 159; // Sar Arrow Code
|
|
int rrZoneLength = 7; // Draw Risk Reward Ratio till n Bars
|
|
|
|
//
|
|
// Alert ...
|
|
input group "Alerts";
|
|
input string alertPrefix = ""; // Alert Prefix
|
|
input bool _logAlerts = true; // Log Alerts
|
|
input bool _pushAlerts = true; // Push Alerts
|
|
input bool _mailAlerts = false; // Mail Alerts
|
|
input bool _terminalAlerts = true; // Terminal Alerts
|
|
|
|
//
|
|
// Buffers ...
|
|
|
|
//
|
|
#define hideColorIDX 0
|
|
#define bullishColorIDX 1
|
|
#define bearishColorIDX 2
|
|
#define neuturalColorIDX 3
|
|
|
|
//
|
|
#define bullishState 1
|
|
#define neuturalState 0
|
|
#define bearishState -1
|
|
|
|
//
|
|
#define emptyValue 0.0
|
|
|
|
//
|
|
#property indicator_chart_window
|
|
|
|
//
|
|
#property indicator_buffers 16
|
|
#property indicator_plots 2
|
|
|
|
//
|
|
// Plot Buffers ...
|
|
|
|
//
|
|
// TREND ...
|
|
|
|
//
|
|
#define trendBufferIndex 0
|
|
#define trendBufferPlotIndex 0
|
|
double trendBuffer[];
|
|
|
|
//
|
|
#define trendColorBufferIndex 1
|
|
double trendColorBuffer[];
|
|
|
|
//
|
|
#property indicator_label1 "X121 Trend"
|
|
#property indicator_type1 DRAW_COLOR_LINE
|
|
#property indicator_color1 CLR_NONE, clrAqua, clrMagenta, clrGray
|
|
#property indicator_style1 STYLE_DASH
|
|
#property indicator_width1 2
|
|
|
|
//
|
|
// SAR ...
|
|
|
|
//
|
|
#define sarBufferIndex 2
|
|
#define sarBufferPlotIndex 2
|
|
double sarBuffer[];
|
|
|
|
//
|
|
#define sarColorBufferIndex 3
|
|
double sarColorBuffer[];
|
|
|
|
//
|
|
#property indicator_label2 "X121 SAR"
|
|
#property indicator_type2 DRAW_COLOR_ARROW
|
|
#property indicator_color2 CLR_NONE, clrAqua, clrMagenta, clrGray
|
|
#property indicator_width2 2
|
|
|
|
//
|
|
// Data Buffers ...
|
|
|
|
#define mLastBufferIndex 3
|
|
|
|
//
|
|
// TREND State ...
|
|
|
|
//
|
|
#define trendStateBufferIndex mLastBufferIndex + 1
|
|
double trendStateBuffer[];
|
|
|
|
//
|
|
// SAR ...
|
|
|
|
//
|
|
#define sarStateBufferIndex mLastBufferIndex + 2
|
|
double sarStateBuffer[];
|
|
|
|
//
|
|
// RSI ...
|
|
|
|
//
|
|
#define rsiBufferIndex mLastBufferIndex + 3
|
|
double rsiBuffer[];
|
|
|
|
//
|
|
// ADX ...
|
|
|
|
//
|
|
#define adxBufferIndex mLastBufferIndex + 4
|
|
double adxBuffer[];
|
|
|
|
//
|
|
#define adxpBufferIndex mLastBufferIndex + 5
|
|
double adxpBuffer[];
|
|
|
|
//
|
|
#define adxnBufferIndex mLastBufferIndex + 6
|
|
double adxnBuffer[];
|
|
|
|
//
|
|
// DELTA ...
|
|
|
|
//
|
|
#define deltaBufferIndex mLastBufferIndex + 7
|
|
double deltaBuffer[];
|
|
|
|
//
|
|
#define deltaSignalBufferIndex mLastBufferIndex + 8
|
|
double deltaSignalBuffer[];
|
|
|
|
//
|
|
// VOLUMES ...
|
|
|
|
//
|
|
#define bullishVolumeBufferIndex mLastBufferIndex + 9
|
|
double bullishVolumeBuffer[];
|
|
|
|
//
|
|
#define bearishVolumeBufferIndex mLastBufferIndex + 10
|
|
double bearishVolumeBuffer[];
|
|
|
|
//
|
|
#define bullishVolumeSignalBufferIndex mLastBufferIndex + 11
|
|
double bullishVolumeSignalBuffer[];
|
|
|
|
//
|
|
#define bearishVolumeSignalBufferIndex mLastBufferIndex + 12
|
|
double bearishVolumeSignalBuffer[];
|
|
|
|
//
|
|
// Variables, Properties and etc ...
|
|
|
|
//
|
|
int limit;
|
|
|
|
//
|
|
int maxLength;
|
|
|
|
//
|
|
int firstBarIndex;
|
|
|
|
//
|
|
XCAlert *alert;
|
|
double mPoints = 0;
|
|
CArrayObj mObjects;
|
|
XCPOIDrawer *drawer;
|
|
bool mEnableAlerts = false;
|
|
XCBarAnalyser *barAnalyser;
|
|
int mTrendPeriodLength = 0;
|
|
int sarHandler = INVALID_HANDLE;
|
|
int rsiHandler = INVALID_HANDLE;
|
|
int adxHandler = INVALID_HANDLE;
|
|
int trendHandler = INVALID_HANDLE;
|
|
ENUM_TIMEFRAMES mTrendPeriod = NULL;
|
|
|
|
//
|
|
// Event Handlers ...
|
|
|
|
/**
|
|
* Initialize Indicator ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int OnInit()
|
|
{
|
|
//
|
|
// Validate Inputs ...
|
|
if (!ValidateInputs())
|
|
{
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
}
|
|
|
|
//
|
|
// Initialize Indicator Handlers ...
|
|
|
|
//
|
|
// Configure Alert ...
|
|
alert = new XCAlert();
|
|
mEnableAlerts =
|
|
_logAlerts ||
|
|
_pushAlerts ||
|
|
_mailAlerts ||
|
|
_terminalAlerts;
|
|
string mPrefix = ShortName +
|
|
(!IsValid(alertPrefix)
|
|
? ""
|
|
: "[" + alertPrefix + "]");
|
|
alert.SetPrefix(mPrefix);
|
|
alert.SetLogAlerts(_logAlerts);
|
|
alert.SetMailAlerts(_mailAlerts);
|
|
alert.SetPushAlerts(_pushAlerts);
|
|
alert.SetEnableAlerts(mEnableAlerts);
|
|
alert.SetTerminalAlerts(_terminalAlerts);
|
|
|
|
//
|
|
drawer = new XCPOIDrawer();
|
|
barAnalyser = new XCBarAnalyser();
|
|
|
|
//
|
|
// Initializing TrendPeriod ...
|
|
int cPeriodSeconds = PeriodSeconds(_Period);
|
|
if (trendPeriodMethod == X_PERIOD_AUTO)
|
|
{
|
|
//
|
|
// Select Period ...
|
|
mTrendPeriod = GetCyclePeriod(
|
|
X_MARKET_CYCLE_HIND,
|
|
_Period //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
mTrendPeriod = trendPeriod;
|
|
}
|
|
if (IsValid(mTrendPeriod))
|
|
{
|
|
mTrendPeriodLength = PeriodSeconds(mTrendPeriod) / cPeriodSeconds;
|
|
}
|
|
|
|
//
|
|
// SAR ...
|
|
sarHandler = iSAR(
|
|
_Symbol,
|
|
_Period,
|
|
sarStep,
|
|
sarMax //
|
|
);
|
|
bool isInited = sarHandler != INVALID_HANDLE;
|
|
if (!isInited)
|
|
{
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
// RSI ...
|
|
rsiHandler = iRSI(
|
|
_Symbol,
|
|
_Period,
|
|
rsiLength,
|
|
rsiAppliedTo //
|
|
);
|
|
isInited = rsiHandler != INVALID_HANDLE;
|
|
if (!isInited)
|
|
{
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
// ADX ...
|
|
adxHandler = iADX(
|
|
_Symbol,
|
|
_Period,
|
|
adxLength //
|
|
);
|
|
isInited = adxHandler != INVALID_HANDLE;
|
|
if (!isInited)
|
|
{
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
// TREND ...
|
|
trendHandler = iMA(
|
|
_Symbol,
|
|
_Period,
|
|
mTrendPeriodLength,
|
|
0,
|
|
trendMode,
|
|
trendAppliedTo //
|
|
);
|
|
isInited = trendHandler != INVALID_HANDLE;
|
|
if (!isInited)
|
|
{
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
mPoints = GetPoints(_Symbol);
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
/**
|
|
* De Initialize Indicator ...
|
|
*
|
|
* @param reason: Integer, De Initialization Reason ...
|
|
*/
|
|
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
|
|
|
|
//
|
|
mObjects.Clear();
|
|
|
|
//
|
|
delete alert;
|
|
delete drawer;
|
|
|
|
//
|
|
ZeroMemory(alert);
|
|
ZeroMemory(drawer);
|
|
ZeroMemory(barAnalyser);
|
|
|
|
//
|
|
IndicatorRelease(sarHandler);
|
|
IndicatorRelease(rsiHandler);
|
|
IndicatorRelease(adxHandler);
|
|
IndicatorRelease(trendHandler);
|
|
}
|
|
|
|
/**
|
|
* Calculate Bars ...
|
|
*
|
|
* @param rates_total: Integer, Total Bars on Chart ...
|
|
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
|
|
* @param time: DateTime Array, History of Open Time ...
|
|
* @param open: Double Array, History of Open Prices ...
|
|
* @param high: Double Array, History of High Prices ...
|
|
* @param low: Double Array, History of Low Prices ...
|
|
* @param close: Double Array, History of Close Prices ...
|
|
* @param tick_volume: Long, History of Tick Volumes on Bar ...
|
|
* @param volume: Long, History of Trade Volumes ...
|
|
* @param spread: Double, History of Spread Price ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
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[] //
|
|
)
|
|
{
|
|
//
|
|
// Prepare Buffers ...
|
|
ArraySetAsSeries(time, true);
|
|
ArraySetAsSeries(open, true);
|
|
ArraySetAsSeries(high, true);
|
|
ArraySetAsSeries(low, true);
|
|
ArraySetAsSeries(close, true);
|
|
ArraySetAsSeries(tick_volume, true);
|
|
ArraySetAsSeries(volume, true);
|
|
ArraySetAsSeries(spread, true);
|
|
|
|
//
|
|
// Validate Calculated Bars ...
|
|
|
|
//
|
|
// SAR ...
|
|
int sarCalculatedBars = BarsCalculated(sarHandler);
|
|
|
|
//
|
|
// RSI ...
|
|
int rsiCalculatedBars = BarsCalculated(rsiHandler);
|
|
|
|
//
|
|
// ADX ...
|
|
int adxCalculatedBars = BarsCalculated(adxHandler);
|
|
|
|
//
|
|
// TREND ...
|
|
int trendCalculatedBars = BarsCalculated(trendHandler);
|
|
|
|
//
|
|
bool isPassedRequiredCalculatedBars =
|
|
//
|
|
// SAR ...
|
|
sarCalculatedBars >= maxLength &&
|
|
//
|
|
// RSI ...
|
|
rsiCalculatedBars >= maxLength &&
|
|
//
|
|
// ADX ...
|
|
adxCalculatedBars >= maxLength &&
|
|
//
|
|
// TREND ...
|
|
trendCalculatedBars >= maxLength
|
|
//
|
|
;
|
|
if (!isPassedRequiredCalculatedBars)
|
|
{
|
|
return prev_calculated;
|
|
}
|
|
|
|
//
|
|
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
|
? rates_total
|
|
: (rates_total - prev_calculated) + 1;
|
|
|
|
//
|
|
// Buffers Copy ...
|
|
|
|
//
|
|
// SAR ...
|
|
int copiedSars = CopyBuffer(sarHandler, MAIN_LINE, 0, limit, sarBuffer);
|
|
|
|
//
|
|
// RSI ...
|
|
int copiedRSIs = CopyBuffer(rsiHandler, MAIN_LINE, 0, limit, rsiBuffer);
|
|
|
|
//
|
|
// ADX ...
|
|
int copiedADXs = CopyBuffer(adxHandler, MAIN_LINE, 0, limit, adxBuffer);
|
|
|
|
//
|
|
// ADX Plus ...
|
|
int copiedADXPs = CopyBuffer(adxHandler, PLUSDI_LINE, 0, limit, adxpBuffer);
|
|
|
|
//
|
|
// ADX Negative ...
|
|
int copiedADXNs = CopyBuffer(adxHandler, MINUSDI_LINE, 0, limit, adxnBuffer);
|
|
|
|
//
|
|
// TREND ...
|
|
int copiedTrends = CopyBuffer(trendHandler, MAIN_LINE, 0, limit, trendBuffer);
|
|
|
|
//
|
|
// Validate Copied Items ...
|
|
bool isPassedRequiredCopiedItems =
|
|
//
|
|
// SAR ...
|
|
copiedSars >= limit &&
|
|
//
|
|
// RSI ...
|
|
copiedRSIs >= limit &&
|
|
//
|
|
// TREND ...
|
|
copiedTrends >= limit
|
|
//
|
|
;
|
|
if (!isPassedRequiredCopiedItems)
|
|
{
|
|
return prev_calculated;
|
|
}
|
|
|
|
//
|
|
// Main Loop ...
|
|
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
|
|
{
|
|
//
|
|
CalculateBuffers(
|
|
i,
|
|
prev_calculated,
|
|
rates_total,
|
|
//
|
|
open,
|
|
high,
|
|
close,
|
|
low,
|
|
tick_volume //
|
|
);
|
|
}
|
|
|
|
//
|
|
return rates_total;
|
|
}
|
|
|
|
//
|
|
// Functions ...
|
|
|
|
/**
|
|
* Validate Input Args for Initialization ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool ValidateInputs()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
sarMax > 0 &&
|
|
sarStep > 0 &&
|
|
adxLength > 0 &&
|
|
rsiLength > 0 &&
|
|
rsiOBLevel > 0 &&
|
|
rsiOSLevel > 0 &&
|
|
sarMax > sarStep &&
|
|
minZoneLength > 2 &&
|
|
deltaSignalLength > 2 &&
|
|
volumeSignalLength > 2 &&
|
|
deltaSignalMethod != X_MA_MODE_NONE &&
|
|
volumeSignalMethod != X_MA_MODE_NONE &&
|
|
IsValid(trendPeriodMethod, trendPeriod)
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extract Max Length of Inputs ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractMaxLengthOfInputs()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
result = MathMax(minZoneLength, rsiLength);
|
|
result = MathMax(result, adxLength);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Define Required Buffers ...
|
|
*/
|
|
void DefineBuffers()
|
|
{
|
|
//
|
|
// Plot Buffers ...
|
|
|
|
//
|
|
// TREND ...
|
|
|
|
//
|
|
ArraySetAsSeries(trendBuffer, true);
|
|
SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_DATA);
|
|
|
|
//
|
|
PlotIndexSetInteger(trendBufferPlotIndex, PLOT_SHOW_DATA, showTrend);
|
|
|
|
//
|
|
PlotIndexSetDouble(trendBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue);
|
|
|
|
//
|
|
ArraySetAsSeries(trendColorBuffer, true);
|
|
SetIndexBuffer(trendColorBufferIndex, trendColorBuffer, INDICATOR_COLOR_INDEX);
|
|
|
|
//
|
|
// SAR ...
|
|
|
|
//
|
|
ArraySetAsSeries(sarBuffer, true);
|
|
SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_DATA);
|
|
|
|
//
|
|
PlotIndexSetInteger(sarBufferPlotIndex, PLOT_SHOW_DATA, showSar);
|
|
|
|
//
|
|
PlotIndexSetDouble(sarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue);
|
|
PlotIndexSetInteger(sarBufferPlotIndex, PLOT_ARROW, sarArrowCode);
|
|
|
|
//
|
|
ArraySetAsSeries(sarColorBuffer, true);
|
|
SetIndexBuffer(sarColorBufferIndex, sarColorBuffer, INDICATOR_COLOR_INDEX);
|
|
|
|
//
|
|
// Data Buffers ...
|
|
|
|
//
|
|
ArraySetAsSeries(trendStateBuffer, true);
|
|
SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS);
|
|
|
|
//
|
|
ArraySetAsSeries(sarStateBuffer, true);
|
|
SetIndexBuffer(sarStateBufferIndex, sarStateBuffer, INDICATOR_CALCULATIONS);
|
|
|
|
//
|
|
ArraySetAsSeries(rsiBuffer, true);
|
|
SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS);
|
|
|
|
//
|
|
ArraySetAsSeries(adxBuffer, true);
|
|
SetIndexBuffer(adxBufferIndex, adxBuffer, INDICATOR_CALCULATIONS);
|
|
|
|
//
|
|
ArraySetAsSeries(adxpBuffer, true);
|
|
SetIndexBuffer(adxpBufferIndex, adxpBuffer, INDICATOR_CALCULATIONS);
|
|
|
|
//
|
|
ArraySetAsSeries(adxnBuffer, true);
|
|
SetIndexBuffer(adxnBufferIndex, adxnBuffer, INDICATOR_CALCULATIONS);
|
|
|
|
//
|
|
// DELTA ...
|
|
|
|
//
|
|
ArraySetAsSeries(deltaBuffer, true);
|
|
SetIndexBuffer(deltaBufferIndex, deltaBuffer, INDICATOR_CALCULATIONS);
|
|
|
|
//
|
|
ArraySetAsSeries(deltaSignalBuffer, true);
|
|
SetIndexBuffer(deltaSignalBufferIndex, deltaSignalBuffer, INDICATOR_CALCULATIONS);
|
|
|
|
//
|
|
// VOLUME ...
|
|
|
|
//
|
|
ArraySetAsSeries(bullishVolumeBuffer, true);
|
|
SetIndexBuffer(bullishVolumeBufferIndex, bullishVolumeBuffer, INDICATOR_CALCULATIONS);
|
|
|
|
//
|
|
ArraySetAsSeries(bearishVolumeBuffer, true);
|
|
SetIndexBuffer(bearishVolumeBufferIndex, bearishVolumeBuffer, INDICATOR_CALCULATIONS);
|
|
|
|
//
|
|
ArraySetAsSeries(bullishVolumeSignalBuffer, true);
|
|
SetIndexBuffer(bullishVolumeSignalBufferIndex, bullishVolumeSignalBuffer, INDICATOR_CALCULATIONS);
|
|
|
|
//
|
|
ArraySetAsSeries(bearishVolumeSignalBuffer, true);
|
|
SetIndexBuffer(bearishVolumeSignalBufferIndex, bearishVolumeSignalBuffer, INDICATOR_CALCULATIONS);
|
|
}
|
|
|
|
/**
|
|
* Set Indicator Short Name and also we can define Buffers Labels ...
|
|
*/
|
|
void SetIndicatorName()
|
|
{
|
|
//
|
|
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
|
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
|
}
|
|
|
|
/**
|
|
* Calculate Custom Buffers ...
|
|
*
|
|
* @param bar_index: Integer, Represent Current Bar ...
|
|
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
|
|
* @param ratesTotal: Integer, Represents All Available Bars ...
|
|
* @param open: Double Array, History of Open Prices ...
|
|
* @param high: Double Array, History of High Prices ...
|
|
* @param close: Double Array, History of Close Prices ...
|
|
* @param low: Double Array, History of Low Prices ...
|
|
* @param tickVolume: Long, History of Tick Volumes on Bar ...
|
|
*/
|
|
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[],
|
|
const long &tickVolume[] //
|
|
)
|
|
{
|
|
//
|
|
int barsLimit = startCalculationForLastBars > 0
|
|
? startCalculationForLastBars
|
|
: 0;
|
|
if (barsLimit == 0)
|
|
{
|
|
//
|
|
barsLimit = ratesTotal;
|
|
firstBarIndex = barsLimit - 1;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
firstBarIndex = startCalculationForLastBars;
|
|
}
|
|
|
|
//
|
|
// bool canCalculate = true;
|
|
bool canCalculate =
|
|
bar_index <= barsLimit;
|
|
if (canCalculate)
|
|
{
|
|
//
|
|
// Calculate Values ...
|
|
CalculateValues(
|
|
bar_index,
|
|
prevCalculated,
|
|
ratesTotal,
|
|
open,
|
|
high,
|
|
close,
|
|
low,
|
|
tickVolume //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
FillBuffersZero(bar_index);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
|
|
*
|
|
* @param barIndex: Integer ...
|
|
*/
|
|
void FillBuffersZero(int barIndex)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Calculate Values ...
|
|
*
|
|
* @param bar_index: int, Specified Bar Index ...
|
|
* @param prevCalculated: int, Provides Previous Calculated Bars ...
|
|
* @param ratesTotal: int, Provides All Availabled Bars ...
|
|
* @param open: double Collection, Provides Open Prices Time Series ...
|
|
* @param high: double Collection, Provides High Prices Time Series ...
|
|
* @param close: double Collection, Provides Close Prices Time Series ...
|
|
* @param low: double Collection, Provides Low Prices Time Series ...
|
|
* @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ...
|
|
*/
|
|
void CalculateValues(
|
|
int bar_index, // Selected Bar Index
|
|
const int prevCalculated,
|
|
const int ratesTotal,
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &close[],
|
|
const double &low[],
|
|
const long &tickVolume[] //
|
|
)
|
|
{
|
|
//
|
|
int lastBarIndex = bar_index + 1;
|
|
bool isFirstBar =
|
|
startCalculationForLastBars > 0
|
|
? bar_index == startCalculationForLastBars
|
|
: bar_index == firstBarIndex;
|
|
|
|
//
|
|
// Bar Info ...
|
|
double iLow = high[bar_index];
|
|
double iHigh = high[bar_index];
|
|
double iClose = close[bar_index];
|
|
double iOpen = open[bar_index];
|
|
double iVolume = (double)iVolume(_Symbol, _Period, bar_index);
|
|
|
|
//
|
|
bool isBullish = iClose > iOpen;
|
|
bool isBearish = iClose < iOpen;
|
|
|
|
//
|
|
double points = GetPoints(_Symbol);
|
|
|
|
//
|
|
// Calculate Sar Color Buffer ...
|
|
double iSar = sarBuffer[bar_index];
|
|
|
|
//
|
|
double iSarState = neuturalState;
|
|
double iSarColor = neuturalColorIDX;
|
|
if (iLow > iSar)
|
|
{
|
|
//
|
|
iSarState = bullishState;
|
|
iSarColor = !showSar
|
|
? hideColorIDX
|
|
: bullishColorIDX;
|
|
}
|
|
else if (iHigh < iSar)
|
|
{
|
|
//
|
|
iSarState = bearishState;
|
|
iSarColor = !showSar
|
|
? hideColorIDX
|
|
: bearishColorIDX;
|
|
}
|
|
sarStateBuffer[bar_index] = iSarState;
|
|
sarColorBuffer[bar_index] = iSarColor;
|
|
|
|
//
|
|
// Calculate Trend Color Buffer ...
|
|
double iTrend = trendBuffer[bar_index];
|
|
|
|
//
|
|
double iTrendState = neuturalState;
|
|
double iTrendColor = neuturalColorIDX;
|
|
if (iClose > iTrend)
|
|
{
|
|
//
|
|
iTrendState = bullishState;
|
|
iTrendColor = !showTrend
|
|
? hideColorIDX
|
|
: bullishColorIDX;
|
|
}
|
|
else if (iClose < iTrend)
|
|
{
|
|
//
|
|
iTrendState = bearishState;
|
|
iTrendColor = !showTrend
|
|
? hideColorIDX
|
|
: bearishColorIDX;
|
|
}
|
|
trendStateBuffer[bar_index] = iTrendState;
|
|
trendColorBuffer[bar_index] = iTrendColor;
|
|
|
|
//
|
|
// DELTA ...
|
|
double lastDelta =
|
|
isFirstBar
|
|
? emptyValue
|
|
: deltaBuffer[lastBarIndex];
|
|
double iAppliedVolume =
|
|
isBullish
|
|
? iVolume
|
|
: -1 * iVolume;
|
|
double iDelta =
|
|
lastDelta + iAppliedVolume;
|
|
deltaBuffer[bar_index] = iDelta;
|
|
|
|
//
|
|
// Calculate Delta Signal ...
|
|
int deltaSignalsCount = iMAOnBuffer(
|
|
ratesTotal,
|
|
prevCalculated,
|
|
bar_index,
|
|
deltaSignalLength,
|
|
deltaBuffer,
|
|
deltaSignalBuffer,
|
|
deltaSignalMethod //
|
|
);
|
|
|
|
//
|
|
// VOLUME ...
|
|
|
|
//
|
|
double iBullishVolume = emptyValue;
|
|
double iBearishVolume = emptyValue;
|
|
if (isBullish)
|
|
{
|
|
iBullishVolume = iVolume;
|
|
}
|
|
else if (isBearish)
|
|
{
|
|
iBearishVolume = iVolume;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
double iHalfVolume = iVolume / 2;
|
|
|
|
//
|
|
iBullishVolume = iHalfVolume;
|
|
iBearishVolume = iHalfVolume;
|
|
}
|
|
bullishVolumeBuffer[bar_index] = iBullishVolume;
|
|
bearishVolumeBuffer[bar_index] = iBearishVolume;
|
|
|
|
//
|
|
// Calculate Volume Signals ...
|
|
|
|
//
|
|
int bullishVolumeSignalsCount = iMAOnBuffer(
|
|
ratesTotal,
|
|
prevCalculated,
|
|
bar_index,
|
|
volumeSignalLength,
|
|
bullishVolumeBuffer,
|
|
bullishVolumeSignalBuffer,
|
|
volumeSignalMethod //
|
|
);
|
|
|
|
//
|
|
int bearishVolumeSignalsCount = iMAOnBuffer(
|
|
ratesTotal,
|
|
prevCalculated,
|
|
bar_index,
|
|
volumeSignalLength,
|
|
bearishVolumeBuffer,
|
|
bearishVolumeSignalBuffer,
|
|
volumeSignalMethod //
|
|
);
|
|
|
|
//
|
|
// Detect Trigger Zone ...
|
|
DetectTriggerZone(
|
|
bar_index,
|
|
prevCalculated,
|
|
ratesTotal,
|
|
open,
|
|
high,
|
|
close,
|
|
low,
|
|
tickVolume //
|
|
);
|
|
}
|
|
|
|
//
|
|
void DetectTriggerZone(
|
|
int bar_index, // Selected Bar Index
|
|
const int prevCalculated,
|
|
const int ratesTotal,
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &close[],
|
|
const double &low[],
|
|
const long &tickVolume[] //
|
|
)
|
|
{
|
|
//
|
|
// Check Prev Bar ...
|
|
|
|
//
|
|
int lastBarIndex = bar_index + 1;
|
|
int maxBarIndex = startCalculationForLastBars > 0
|
|
? startCalculationForLastBars
|
|
: ratesTotal;
|
|
bool isFirstBar =
|
|
bar_index == maxBarIndex;
|
|
|
|
//
|
|
// Prevent Calculation ...
|
|
if (maxBarIndex - bar_index < minZoneLength)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int zIDX = 0;
|
|
int cIDX = 0;
|
|
int pIDX = 0;
|
|
int p2IDX = 0;
|
|
int p3IDX = 0;
|
|
int p4IDX = 0;
|
|
double ll = 0;
|
|
double hh = 0;
|
|
bool has = false;
|
|
ENUM_X_DIRECTION iDir;
|
|
|
|
//
|
|
// Retrieve Required Bars ...
|
|
|
|
//
|
|
XOHCL zBar; // Current Start Checking Bar (Usually Used for Triggering) ...
|
|
XOHCL cBar; // Current Finished Bar which Start Detecting Structures based on it ( End of Block and FVG Bar ) ...
|
|
XOHCL pBar; // Determines Block Gap Bar (all Filtering must applied and Check using this Bar and it's Next Bar) ...
|
|
XOHCL p2Bar; // Determines FVG's Start Bar in a Block ...
|
|
XOHCL p3Bar; // First Verification of Block ...
|
|
XOHCL p4Bar; // Seccond Verification of Block ...
|
|
|
|
//
|
|
has = zBar.Init(
|
|
_Symbol,
|
|
_Period,
|
|
bar_index //
|
|
);
|
|
has =
|
|
has &&
|
|
zBar.GetPreviousBar(cBar);
|
|
has =
|
|
has &&
|
|
cBar.GetPreviousBar(pBar);
|
|
has =
|
|
has &&
|
|
pBar.GetPreviousBar(p2Bar);
|
|
has =
|
|
has &&
|
|
p2Bar.GetPreviousBar(p3Bar);
|
|
has =
|
|
has &&
|
|
p3Bar.GetPreviousBar(p4Bar);
|
|
if (!has)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Define Zone Structure ...
|
|
XBoxZone zone;
|
|
|
|
//
|
|
// Detect Based Order Block using CBar ...
|
|
has = barAnalyser.IsOB(
|
|
cBar,
|
|
zone,
|
|
true, // Force FVG Bar Type ...
|
|
true // Force Block Two Bar Checking ...
|
|
);
|
|
|
|
//
|
|
// Ensure a Block is Detected ...
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
zIDX = zBar.Index();
|
|
cIDX = cBar.Index();
|
|
pIDX = pBar.Index();
|
|
p2IDX = p2Bar.Index();
|
|
p3IDX = p3Bar.Index();
|
|
p4IDX = p4Bar.Index();
|
|
|
|
//
|
|
bool isBullish =
|
|
has &&
|
|
zone.IsBullish();
|
|
|
|
//
|
|
bool isBearish =
|
|
has &&
|
|
zone.IsBearish();
|
|
|
|
//
|
|
int toIDX = zone.ToIndex();
|
|
int fromIDX = zone.FromIndex();
|
|
|
|
//
|
|
// Validating p2Bar and p3Bar Direction ...
|
|
if (has)
|
|
{
|
|
//
|
|
iDir = Opposit(zone.dir);
|
|
|
|
//
|
|
has =
|
|
iDir == p3Bar.GetDirection() ||
|
|
iDir == p4Bar.GetDirection();
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Start Validating Block based on
|
|
// Detected One ...
|
|
|
|
//
|
|
// Validating Using Max Range ...
|
|
has = maxZoneRangeInPoints > 0;
|
|
if (has)
|
|
{
|
|
//
|
|
double range = zone.GetRange();
|
|
has = range <= maxZoneRangeInPoints * mPoints;
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate Gap Endup with PinBar ...
|
|
has = forceHasPinBarEntry;
|
|
if (has)
|
|
{
|
|
//
|
|
bool isBullishRejected =
|
|
isBullish &&
|
|
cBar.IsBullish() &&
|
|
cBar.GetLowShadow() > cBar.GetHighShadow();
|
|
|
|
//
|
|
bool isBearishRejected =
|
|
isBearish &&
|
|
cBar.IsBearish() &&
|
|
cBar.GetLowShadow() < cBar.GetHighShadow();
|
|
|
|
//
|
|
has = isBullishRejected ||
|
|
isBearishRejected;
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validating Gap Bar must a Momentum Bar and
|
|
// Breakes out Zone's Directional Edge ...
|
|
// for Bullish: Upper
|
|
// for Bearish: Lower
|
|
has = forceGapBarsBreakout;
|
|
if (has)
|
|
{
|
|
//
|
|
// Gap Bar is PBar ...
|
|
|
|
//
|
|
// Check Gap Bar is Momentum Bar ...
|
|
has = barAnalyser.IsMomentum(
|
|
pBar,
|
|
iDir //
|
|
);
|
|
bool isBullishMomentum =
|
|
has &&
|
|
IsBullish(iDir);
|
|
bool isBearishMomentum =
|
|
has &&
|
|
IsBearish(iDir);
|
|
|
|
//
|
|
// Check Gap Bar's Breakout ...
|
|
|
|
//
|
|
bool isBullishBreakedout =
|
|
isBullish &&
|
|
pBar.IsBullish() &&
|
|
isBullishMomentum &&
|
|
pBar.GetUp() > zone.upper &&
|
|
pBar.GetDown() < zone.upper;
|
|
|
|
//
|
|
bool isBearishBreakedout =
|
|
isBearish &&
|
|
pBar.IsBearish() &&
|
|
isBearishMomentum &&
|
|
pBar.GetUp() > zone.lower &&
|
|
pBar.GetDown() < zone.lower;
|
|
|
|
//
|
|
has = isBullishBreakedout ||
|
|
isBearishBreakedout;
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate Zone Has Propper Swing ...
|
|
// for Bullish: p2Bar or p3Bar must be a Swing Low ...
|
|
// for Bearish: p2Bar or p3Bar must be a Swing High ...
|
|
has = forceHasSwing;
|
|
if (has)
|
|
{
|
|
//
|
|
// p2Bar ...
|
|
bool isP2BarSwing =
|
|
barAnalyser
|
|
.IsSimpleSwing(
|
|
p2Bar,
|
|
iDir //
|
|
);
|
|
bool isP2BarSwingLow =
|
|
isP2BarSwing &&
|
|
IsBullish(iDir);
|
|
bool isP2BarSwingHigh =
|
|
isP2BarSwing &&
|
|
IsBearish(iDir);
|
|
|
|
//
|
|
// p3Bar ...
|
|
bool isP3BarSwing =
|
|
barAnalyser
|
|
.IsSimpleSwing(
|
|
p3Bar,
|
|
iDir //
|
|
);
|
|
bool isP3BarSwingLow =
|
|
isP3BarSwing &&
|
|
IsBullish(iDir);
|
|
bool isP3BarSwingHigh =
|
|
isP3BarSwing &&
|
|
IsBearish(iDir);
|
|
|
|
//
|
|
bool hasSwingLow =
|
|
isBullish &&
|
|
(isP2BarSwingLow ||
|
|
isP3BarSwingLow);
|
|
|
|
//
|
|
bool hasSwingHigh =
|
|
isBearish &&
|
|
(isP2BarSwingHigh ||
|
|
isP3BarSwingHigh);
|
|
|
|
//
|
|
has =
|
|
hasSwingLow ||
|
|
hasSwingHigh;
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validating Using Swing Length ...
|
|
has = minZoneLength > 0;
|
|
if (has)
|
|
{
|
|
//
|
|
XOHCL fromBar;
|
|
has = zone.FromBar(fromBar);
|
|
if (has)
|
|
{
|
|
//
|
|
// Retrieve HH and LL ...
|
|
ll = fromBar.FindLowest(minZoneLength, MODE_LOW);
|
|
hh = fromBar.FindHighest(minZoneLength, MODE_HIGH);
|
|
|
|
//
|
|
// Validate Using HH and LL ...
|
|
|
|
//
|
|
bool isBullishValid =
|
|
isBullish &&
|
|
ll >= zone.lower;
|
|
|
|
//
|
|
bool isBearishValid =
|
|
isBearish &&
|
|
hh <= zone.upper;
|
|
|
|
//
|
|
has = isBullishValid ||
|
|
isBearishValid;
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Update Zone's From Time ...
|
|
zone.from = GetBarTime(
|
|
zone.symbol,
|
|
zone.period,
|
|
fromBar.Index() + minZoneLength //
|
|
);
|
|
}
|
|
|
|
//
|
|
fromBar.Clean();
|
|
}
|
|
|
|
//
|
|
// Validate Max Allowed Entry Distance ...
|
|
has = maxAllowedEntryDistance > 0;
|
|
if (has)
|
|
{
|
|
//
|
|
double base =
|
|
isBullish
|
|
? zone.upper
|
|
: zone.lower;
|
|
double entryDistance = MathAbs(zBar.open - base);
|
|
has = entryDistance <= maxAllowedEntryDistance * mPoints;
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Here we Ensure which have a Valid Zone using Different Applied Validations ...
|
|
// from now we are Going to Filtered Validate Zones ...
|
|
|
|
//
|
|
// Check Exists Filters or not ...
|
|
has = filterBasedOnSar ||
|
|
filterBasedOnRSI ||
|
|
filterBasedOnADX ||
|
|
filterBasedOnTrend;
|
|
if (has)
|
|
{
|
|
//
|
|
// Do Apply Several Exists Filters ...
|
|
|
|
//
|
|
// SAR Filter ...
|
|
if (filterBasedOnSar)
|
|
{
|
|
//
|
|
// Reading Conditions Values ...
|
|
|
|
//
|
|
double zSar = sarBuffer[zIDX];
|
|
double cSar = sarBuffer[cIDX];
|
|
double pSar = sarBuffer[pIDX];
|
|
double p2Sar = sarBuffer[p2IDX];
|
|
double p3Sar = sarBuffer[p3IDX];
|
|
double p4Sar = sarBuffer[p4IDX];
|
|
|
|
//
|
|
// Create Required Conditions ...
|
|
|
|
//
|
|
bool isZSarBullish = zSar < zBar.low;
|
|
bool isZSarBearish = zSar > zBar.high;
|
|
|
|
//
|
|
bool isCSarBullish = cSar < cBar.low;
|
|
bool isCSarBearish = cSar > cBar.high;
|
|
|
|
//
|
|
bool isPSarBullish = pSar < pBar.low;
|
|
bool isPSarBearish = pSar > pBar.high;
|
|
|
|
//
|
|
bool isP2SarBullish = p2Sar < p2Bar.low;
|
|
bool isP2SarBearish = p2Sar > p2Bar.high;
|
|
|
|
//
|
|
bool isCSarSwitchedToBullish =
|
|
isZSarBullish &&
|
|
isCSarBullish &&
|
|
!isPSarBullish &&
|
|
cBar.IsBullish() &&
|
|
cBar.GetUp() > pSar;
|
|
|
|
//
|
|
bool isCSarSwitchedToBearish =
|
|
isZSarBearish &&
|
|
isCSarBearish &&
|
|
!isPSarBearish &&
|
|
cBar.IsBearish() &&
|
|
cBar.GetDown() < pSar;
|
|
|
|
//
|
|
bool isPSarSwitchedToBullish =
|
|
isZSarBullish &&
|
|
isCSarBullish &&
|
|
isPSarBullish &&
|
|
!isP2SarBullish &&
|
|
pBar.IsBullish() &&
|
|
pBar.GetUp() > p2Sar;
|
|
|
|
//
|
|
bool isPSarSwitchedToBearish =
|
|
isZSarBearish &&
|
|
isCSarBearish &&
|
|
isPSarBearish &&
|
|
!isP2SarBearish &&
|
|
pBar.IsBearish() &&
|
|
pBar.GetDown() < p2Sar;
|
|
|
|
//
|
|
// Summarize Filtering ...
|
|
|
|
//
|
|
bool isBullishFiltered =
|
|
isBullish &&
|
|
(isCSarSwitchedToBullish ||
|
|
isPSarSwitchedToBullish);
|
|
|
|
//
|
|
bool isBearishFiltered =
|
|
isBearish &&
|
|
(isCSarSwitchedToBearish ||
|
|
isPSarSwitchedToBearish);
|
|
|
|
//
|
|
has =
|
|
isBullishFiltered ||
|
|
isBearishFiltered;
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// RSI Filter ...
|
|
if (filterBasedOnRSI)
|
|
{
|
|
//
|
|
// Reading Conditions Values ...
|
|
|
|
//
|
|
double rsiTrend = (rsiOBLevel + rsiOSLevel) / 2;
|
|
|
|
//
|
|
double zRSI = rsiBuffer[zIDX];
|
|
double cRSI = rsiBuffer[cIDX];
|
|
double pRSI = rsiBuffer[pIDX];
|
|
double p2RSI = rsiBuffer[p2IDX];
|
|
double p3RSI = rsiBuffer[p3IDX];
|
|
double p4RSI = rsiBuffer[p4IDX];
|
|
|
|
//
|
|
// Create Required Conditions ...
|
|
|
|
//
|
|
bool isZRSIBullish = zRSI > rsiTrend;
|
|
bool isZRSIBearish = zRSI < rsiTrend;
|
|
|
|
//
|
|
bool isCRSIBullish = cRSI > rsiTrend;
|
|
bool isCRSIBearish = cRSI < rsiTrend;
|
|
|
|
//
|
|
bool isPRSIBullish = pRSI > rsiTrend;
|
|
bool isPRSIBearish = pRSI < rsiTrend;
|
|
|
|
//
|
|
bool isP2RSIBullish = p2RSI > rsiTrend;
|
|
bool isP2RSIBearish = p2RSI < rsiTrend;
|
|
|
|
//
|
|
bool isP3RSIBullish = p3RSI > rsiTrend;
|
|
bool isP3RSIBearish = p3RSI < rsiTrend;
|
|
|
|
//
|
|
// Trending Conditions ...
|
|
|
|
//
|
|
bool isCRSISwitchedToBullish =
|
|
isZRSIBullish &&
|
|
isCRSIBullish &&
|
|
!isPRSIBullish;
|
|
|
|
//
|
|
bool isCRSISwitchedToBearish =
|
|
isZRSIBearish &&
|
|
isCRSIBearish &&
|
|
!isPRSIBearish;
|
|
|
|
//
|
|
bool isPRSISwitchedToBullish =
|
|
isZRSIBullish &&
|
|
isCRSIBullish &&
|
|
isPRSIBullish &&
|
|
!isP2RSIBullish;
|
|
|
|
//
|
|
bool isPRSISwitchedToBearish =
|
|
isZRSIBearish &&
|
|
isCRSIBearish &&
|
|
isPRSIBearish &&
|
|
!isP2RSIBearish;
|
|
|
|
//
|
|
bool isP2RSISwitchedToBullish =
|
|
isZRSIBullish &&
|
|
isCRSIBullish &&
|
|
isPRSIBullish &&
|
|
isP2RSIBullish &&
|
|
!isP3RSIBullish;
|
|
|
|
//
|
|
bool isP2RSISwitchedToBearish =
|
|
isZRSIBearish &&
|
|
isCRSIBearish &&
|
|
isPRSIBearish &&
|
|
isP2RSIBearish &&
|
|
!isP3RSIBearish;
|
|
|
|
//
|
|
// Crosses Conditions ...
|
|
|
|
//
|
|
bool isCBarCrossedOverOS =
|
|
zRSI > rsiOSLevel &&
|
|
cRSI > rsiOSLevel &&
|
|
pRSI <= rsiOSLevel;
|
|
|
|
//
|
|
bool isCBarCrossedUnderOB =
|
|
zRSI < rsiOBLevel &&
|
|
cRSI < rsiOBLevel &&
|
|
pRSI >= rsiOBLevel;
|
|
|
|
//
|
|
bool isPBarCrossedOverOS =
|
|
zRSI > rsiOSLevel &&
|
|
cRSI > rsiOSLevel &&
|
|
pRSI > rsiOSLevel &&
|
|
p2RSI <= rsiOSLevel;
|
|
|
|
//
|
|
bool isPBarCrossedUnderOB =
|
|
zRSI < rsiOBLevel &&
|
|
cRSI < rsiOBLevel &&
|
|
pRSI < rsiOBLevel &&
|
|
p2RSI >= rsiOBLevel;
|
|
|
|
//
|
|
// V Pattern Conditions ...
|
|
|
|
//
|
|
bool isCRSIHasVBullishPattern =
|
|
zRSI >= cRSI &&
|
|
cRSI > pRSI &&
|
|
p2RSI > pRSI &&
|
|
cRSI >= p2RSI;
|
|
|
|
//
|
|
bool isCRSIHasVBearishPattern =
|
|
zRSI <= cRSI &&
|
|
cRSI < pRSI &&
|
|
p2RSI < pRSI &&
|
|
cRSI <= p2RSI;
|
|
|
|
//
|
|
// Continuation Conditions ...
|
|
|
|
//
|
|
bool isRSIUp =
|
|
zRSI >= cRSI &&
|
|
(cRSI >= pRSI ||
|
|
pRSI >= p2RSI ||
|
|
p2RSI >= p3RSI);
|
|
|
|
//
|
|
bool isRSIDown =
|
|
zRSI <= cRSI &&
|
|
(cRSI <= pRSI ||
|
|
pRSI <= p2RSI ||
|
|
p2RSI <= p3RSI);
|
|
|
|
//
|
|
// Summarize Filtering ...
|
|
|
|
//
|
|
bool isBullishFiltered =
|
|
isBullish &&
|
|
(
|
|
//
|
|
// Grows ...
|
|
isRSIUp
|
|
//
|
|
||
|
|
//
|
|
// Crosses ...
|
|
(isCBarCrossedOverOS ||
|
|
isPBarCrossedOverOS)
|
|
//
|
|
||
|
|
//
|
|
// V Pattern ...
|
|
isCRSIHasVBullishPattern
|
|
//
|
|
||
|
|
//
|
|
// Trending ...
|
|
(isCRSISwitchedToBullish ||
|
|
isPRSISwitchedToBullish ||
|
|
isP2RSISwitchedToBullish)
|
|
//
|
|
);
|
|
|
|
//
|
|
bool isBearishFiltered =
|
|
isBearish &&
|
|
(
|
|
//
|
|
// Grows ...
|
|
isRSIDown
|
|
//
|
|
||
|
|
//
|
|
// Crosses ...
|
|
(isCBarCrossedUnderOB ||
|
|
isPBarCrossedUnderOB)
|
|
//
|
|
||
|
|
//
|
|
// V Pattern ...
|
|
isCRSIHasVBearishPattern
|
|
//
|
|
||
|
|
//
|
|
// Trending ...
|
|
(isCRSISwitchedToBearish ||
|
|
isPRSISwitchedToBearish ||
|
|
isP2RSISwitchedToBearish)
|
|
//
|
|
);
|
|
|
|
//
|
|
has =
|
|
isBullishFiltered ||
|
|
isBearishFiltered;
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// ADX Filter ...
|
|
if (filterBasedOnADX)
|
|
{
|
|
//
|
|
// Reading Conditions Values ...
|
|
|
|
//
|
|
// ADX ...
|
|
double zADX = adxBuffer[zIDX];
|
|
double cADX = adxBuffer[cIDX];
|
|
double pADX = adxBuffer[pIDX];
|
|
double p2ADX = adxBuffer[p2IDX];
|
|
double p3ADX = adxBuffer[p3IDX];
|
|
double p4ADX = adxBuffer[p4IDX];
|
|
|
|
//
|
|
// ADX +DI ...
|
|
double zADXP = adxpBuffer[zIDX];
|
|
double cADXP = adxpBuffer[cIDX];
|
|
double pADXP = adxpBuffer[pIDX];
|
|
double p2ADXP = adxpBuffer[p2IDX];
|
|
double p3ADXP = adxpBuffer[p3IDX];
|
|
double p4ADXP = adxpBuffer[p4IDX];
|
|
|
|
//
|
|
// ADX -DI ...
|
|
double zADXN = adxnBuffer[zIDX];
|
|
double cADXN = adxnBuffer[cIDX];
|
|
double pADXN = adxnBuffer[pIDX];
|
|
double p2ADXN = adxnBuffer[p2IDX];
|
|
double p3ADXN = adxnBuffer[p3IDX];
|
|
double p4ADXN = adxnBuffer[p4IDX];
|
|
|
|
//
|
|
// Create Required Conditions ...
|
|
|
|
//
|
|
// Grows ...
|
|
|
|
//
|
|
bool isADXUp =
|
|
zADX >= cADX &&
|
|
(cADX >= pADX ||
|
|
pADX >= p2ADX);
|
|
|
|
//
|
|
bool isADXDown =
|
|
zADX <= cADX &&
|
|
(cADX <= pADX ||
|
|
pADX <= p2ADX);
|
|
|
|
//
|
|
// Trending ...
|
|
|
|
//
|
|
bool isZADXBullish = zADX > adxThreshold;
|
|
bool isZADXBearish = zADX < adxThreshold;
|
|
|
|
//
|
|
bool isCADXBullish = cADX > adxThreshold;
|
|
bool isCADXBearish = cADX < adxThreshold;
|
|
|
|
//
|
|
bool isPADXBullish = pADX > adxThreshold;
|
|
bool isPADXBearish = pADX < adxThreshold;
|
|
|
|
//
|
|
bool isP2ADXBullish = p2ADX > adxThreshold;
|
|
bool isP2ADXBearish = p2ADX < adxThreshold;
|
|
|
|
//
|
|
bool isP3ADXBullish = p3ADX > adxThreshold;
|
|
bool isP3ADXBearish = p3ADX < adxThreshold;
|
|
|
|
//
|
|
bool isP4ADXBullish = p4ADX > adxThreshold;
|
|
bool isP4ADXBearish = p4ADX < adxThreshold;
|
|
|
|
//
|
|
bool isCADXSwitchedToBullish =
|
|
isZADXBullish &&
|
|
isCADXBullish &&
|
|
!isPADXBullish;
|
|
|
|
//
|
|
bool isCADXSwitchedToBearish =
|
|
isZADXBearish &&
|
|
isCADXBearish &&
|
|
!isPADXBearish;
|
|
|
|
//
|
|
bool isPADXSwitchedToBullish =
|
|
isZADXBullish &&
|
|
isCADXBullish &&
|
|
isPADXBullish &&
|
|
!isP2ADXBullish;
|
|
|
|
//
|
|
bool isPADXSwitchedToBearish =
|
|
isZADXBearish &&
|
|
isCADXBearish &&
|
|
isPADXBearish &&
|
|
!isP2ADXBearish;
|
|
|
|
//
|
|
// Powering ...
|
|
|
|
//
|
|
bool isZADXHasBullishPower = zADXP > zADXN;
|
|
bool isZADXHasBearishPower = zADXN > zADXP;
|
|
|
|
//
|
|
bool isCADXHasBullishPower = cADXP > cADXN;
|
|
bool isCADXHasBearishPower = cADXN > cADXP;
|
|
|
|
//
|
|
bool isPADXHasBullishPower = pADXP > pADXN;
|
|
bool isPADXHasBearishPower = pADXN > pADXP;
|
|
|
|
//
|
|
bool isP2ADXHasBullishPower = p2ADXP > p2ADXN;
|
|
bool isP2ADXHasBearishPower = p2ADXN > p2ADXP;
|
|
|
|
//
|
|
bool isP3ADXHasBullishPower = p3ADXP > p3ADXN;
|
|
bool isP3ADXHasBearishPower = p3ADXN > p3ADXP;
|
|
|
|
//
|
|
bool isP4ADXHasBullishPower = p4ADXP > p4ADXN;
|
|
bool isP4ADXHasBearishPower = p4ADXN > p4ADXP;
|
|
|
|
//
|
|
bool isCADXSwitchedToBullishPower =
|
|
isZADXHasBullishPower &&
|
|
isCADXHasBullishPower &&
|
|
!isPADXHasBullishPower;
|
|
|
|
//
|
|
bool isCADXSwitchedToBearishPower =
|
|
isZADXHasBearishPower &&
|
|
isCADXHasBearishPower &&
|
|
!isPADXHasBearishPower;
|
|
|
|
//
|
|
bool isPADXSwitchedToBullishPower =
|
|
isZADXHasBullishPower &&
|
|
isCADXHasBullishPower &&
|
|
isPADXHasBullishPower &&
|
|
!isP2ADXHasBullishPower;
|
|
|
|
//
|
|
bool isPADXSwitchedToBearishPower =
|
|
isZADXHasBearishPower &&
|
|
isCADXHasBearishPower &&
|
|
isPADXHasBearishPower &&
|
|
!isP2ADXHasBearishPower;
|
|
|
|
//
|
|
// Summarize Filtering ...
|
|
|
|
//
|
|
bool isBullishFiltered =
|
|
isBullish &&
|
|
(
|
|
//
|
|
// Grows ...
|
|
isADXUp
|
|
//
|
|
||
|
|
//
|
|
// Trending ...
|
|
(isCADXSwitchedToBullish ||
|
|
isPADXSwitchedToBullish)
|
|
//
|
|
||
|
|
//
|
|
// Powering ...
|
|
(isCADXSwitchedToBullishPower ||
|
|
isPADXSwitchedToBullishPower)
|
|
//
|
|
);
|
|
|
|
//
|
|
bool isBearishFiltered =
|
|
isBearish &&
|
|
(
|
|
//
|
|
// Grows ...
|
|
isADXDown
|
|
//
|
|
||
|
|
//
|
|
// Trending ...
|
|
(isCADXSwitchedToBearish ||
|
|
isPADXSwitchedToBearish)
|
|
//
|
|
||
|
|
//
|
|
// Powering ...
|
|
(isCADXSwitchedToBearishPower ||
|
|
isPADXSwitchedToBearishPower)
|
|
//
|
|
);
|
|
|
|
//
|
|
has =
|
|
isBullishFiltered ||
|
|
isBearishFiltered;
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// TREND Filter ...
|
|
if (filterBasedOnTrend)
|
|
{
|
|
//
|
|
// Reading Conditions Values ...
|
|
|
|
//
|
|
double zTrend = trendBuffer[zIDX];
|
|
double cTrend = trendBuffer[cIDX];
|
|
double pTrend = trendBuffer[pIDX];
|
|
double p2Trend = trendBuffer[p2IDX];
|
|
double p3Trend = trendBuffer[p3IDX];
|
|
double p4Trend = trendBuffer[p4IDX];
|
|
|
|
//
|
|
double trends[] = {
|
|
zTrend,
|
|
cTrend,
|
|
pTrend,
|
|
p2Trend,
|
|
p3Trend,
|
|
p4Trend //
|
|
};
|
|
double trendsMin = GetMin(trends);
|
|
double trendsMax = GetMax(trends);
|
|
double trendsAVG = GetAverage(trends);
|
|
|
|
//
|
|
double zTrendState = trendStateBuffer[zIDX];
|
|
double cTrendState = trendStateBuffer[cIDX];
|
|
double pTrendState = trendStateBuffer[pIDX];
|
|
double p2TrendState = trendStateBuffer[p2IDX];
|
|
double p3TrendState = trendStateBuffer[p3IDX];
|
|
double p4TrendState = trendStateBuffer[p4IDX];
|
|
|
|
//
|
|
// Create Required Conditions ...
|
|
|
|
//
|
|
// Grows ...
|
|
|
|
//
|
|
bool isTrendUp =
|
|
zTrend >= cTrend &&
|
|
cTrend >= trendsAVG &&
|
|
cTrend > trendsMin;
|
|
|
|
//
|
|
bool isTrendDown =
|
|
zTrend <= cTrend &&
|
|
cTrend <= trendsAVG &&
|
|
cTrend < trendsMax;
|
|
|
|
//
|
|
// Stating ...
|
|
|
|
//
|
|
bool isCTrendBullish =
|
|
zTrendState > 0 &&
|
|
cTrendState > 0;
|
|
|
|
//
|
|
bool isCTrendBearish =
|
|
zTrendState < 0 &&
|
|
cTrendState < 0;
|
|
|
|
//
|
|
bool isPTrendBullish =
|
|
zTrendState > 0 &&
|
|
cTrendState > 0 &&
|
|
pTrendState > 0;
|
|
|
|
//
|
|
bool isPTrendBearish =
|
|
zTrendState < 0 &&
|
|
cTrendState < 0 &&
|
|
pTrendState < 0;
|
|
|
|
//
|
|
bool isP2TrendBullish =
|
|
zTrendState > 0 &&
|
|
cTrendState > 0 &&
|
|
pTrendState > 0 &&
|
|
p2TrendState > 0;
|
|
|
|
//
|
|
bool isP2TrendBearish =
|
|
zTrendState < 0 &&
|
|
cTrendState < 0 &&
|
|
pTrendState < 0 &&
|
|
p2TrendState < 0;
|
|
|
|
//
|
|
bool isCTrendSwitchedToBullish =
|
|
isCTrendBullish &&
|
|
!isPTrendBullish;
|
|
|
|
//
|
|
bool isCTrendSwitchedToBearish =
|
|
isCTrendBearish &&
|
|
!isPTrendBearish;
|
|
|
|
//
|
|
bool isPTrendSwitchedToBullish =
|
|
isCTrendBullish &&
|
|
isPTrendBullish &&
|
|
!isP2TrendBullish;
|
|
|
|
//
|
|
bool isPTrendSwitchedToBearish =
|
|
isCTrendBearish &&
|
|
isPTrendBearish &&
|
|
!isP2TrendBearish;
|
|
|
|
//
|
|
// Summarize Filtering ...
|
|
|
|
//
|
|
bool isBullishFiltered =
|
|
isBullish &&
|
|
(
|
|
//
|
|
// Grows ...
|
|
isTrendUp
|
|
//
|
|
||
|
|
//
|
|
// Trend Stating ...
|
|
(isCTrendBullish &&
|
|
isPTrendBullish)
|
|
//
|
|
||
|
|
//
|
|
// Switching ...
|
|
(isCTrendSwitchedToBullish ||
|
|
isPTrendSwitchedToBullish)
|
|
//
|
|
);
|
|
|
|
//
|
|
bool isBearishFiltered =
|
|
isBearish &&
|
|
(
|
|
//
|
|
// Grows ...
|
|
isTrendDown
|
|
//
|
|
||
|
|
//
|
|
// Trend Stating ...
|
|
(isCTrendBearish &&
|
|
isPTrendBearish)
|
|
//
|
|
||
|
|
//
|
|
// Switching ...
|
|
(isCTrendSwitchedToBearish ||
|
|
isPTrendSwitchedToBearish)
|
|
//
|
|
);
|
|
|
|
//
|
|
has =
|
|
isBullishFiltered ||
|
|
isBearishFiltered;
|
|
if (!has)
|
|
{
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// SCORE Filter ...
|
|
|
|
//
|
|
// VOLUME Filter ...
|
|
}
|
|
|
|
//
|
|
// Detect Left Side of Box ...
|
|
XOHCL zoneLeftBar;
|
|
int idx = fromIDX + 1;
|
|
bool isBaseValid = true;
|
|
while (isBaseValid)
|
|
{
|
|
//
|
|
// Retrieve iteration Bar ...
|
|
has = zoneLeftBar.Init(
|
|
_Symbol,
|
|
_Period,
|
|
idx //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
zoneLeftBar.Clean();
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Check Bar's Validation ...
|
|
|
|
//
|
|
bool isBullishPassed =
|
|
isBullish &&
|
|
zoneLeftBar.low >= zone.lower;
|
|
|
|
//
|
|
bool isBearishPassed =
|
|
isBearish &&
|
|
zoneLeftBar.high <= zone.upper;
|
|
|
|
//
|
|
// Summarize Conditions ...
|
|
has =
|
|
isBullishPassed ||
|
|
isBearishPassed;
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
idx++;
|
|
}
|
|
|
|
//
|
|
// Ray to Left Side Zone, if Provided ...
|
|
if (rayLeft)
|
|
{
|
|
//
|
|
// Update Value ...
|
|
fromIDX = zone.FromIndex();
|
|
|
|
//
|
|
// Check Last Iteration Bar is Valid Bar ...
|
|
// then Update Zone from Time ...
|
|
has = zoneLeftBar.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
zone.from = zoneLeftBar.time;
|
|
fromIDX = zone.FromIndex();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draw Detected Zone ...
|
|
if (drawZones)
|
|
{
|
|
//
|
|
XCBoxObject *iZoneObj;
|
|
has = drawer.DrawBox(
|
|
zone,
|
|
iZoneObj //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
ApplyStyle(iZoneObj, zone.dir);
|
|
|
|
//
|
|
mObjects.Add(iZoneObj);
|
|
|
|
//
|
|
// TODO: Enable This for Debugging ...
|
|
// string message = ToString(zone.dir) + " Zone Detected (" + cBar.time + ") ...";
|
|
// Print(message);
|
|
}
|
|
ZeroMemory(iZoneObj);
|
|
}
|
|
|
|
//
|
|
// Draw RR Tool ...
|
|
if (drawRRofZones)
|
|
{
|
|
//
|
|
double rr[]{
|
|
1,
|
|
1.5,
|
|
2,
|
|
3,
|
|
4,
|
|
5,
|
|
6,
|
|
7,
|
|
8,
|
|
9,
|
|
10 //
|
|
};
|
|
XCRRObject *iRRObj;
|
|
iRRObj = new XCRRObject();
|
|
has = iRRObj.CreateBoxRR(
|
|
drawer.ChartIdentification(),
|
|
drawer.SubWindowIdentification(),
|
|
zone,
|
|
rr,
|
|
rrZoneLength //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
int iWidth = 2;
|
|
ENUM_LINE_STYLE iStyle = STYLE_SOLID;
|
|
|
|
//
|
|
iRRObj.TPWidth(iWidth);
|
|
iRRObj.SLWidth(iWidth);
|
|
iRRObj.EntryWidth(iWidth);
|
|
iRRObj.TargetWidth(iWidth);
|
|
|
|
//
|
|
iRRObj.TPStyle(iStyle);
|
|
iRRObj.SLStyle(iStyle);
|
|
iRRObj.EntryStyle(iStyle);
|
|
iRRObj.TargetStyle(iStyle);
|
|
|
|
//
|
|
iRRObj.TPColor(clrLime);
|
|
iRRObj.SLColor(clrRed);
|
|
iRRObj.EntryColor(clrYellow);
|
|
iRRObj.TargetColor(clrLightBlue);
|
|
|
|
//
|
|
mObjects.Add(iRRObj);
|
|
}
|
|
ZeroMemory(iRRObj);
|
|
}
|
|
|
|
//
|
|
// Handle Alerst ...
|
|
bool canAlert =
|
|
mEnableAlerts &&
|
|
prevCalculated > 0;
|
|
bool canLogOnly =
|
|
mEnableAlerts &&
|
|
prevCalculated == 0;
|
|
if (canAlert || canLogOnly)
|
|
{
|
|
//
|
|
string message =
|
|
zone.symbol + "," +
|
|
ToString(zone.period) + "> " +
|
|
ToString(zone.dir) +
|
|
" Zone Detected at: " + ToString(zone.to);
|
|
|
|
//
|
|
if (canLogOnly)
|
|
{
|
|
alert.LogAlert(message);
|
|
}
|
|
else if (canAlert)
|
|
{
|
|
alert.SendAlert(message);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
zone.Clean();
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
p2Bar.Clean();
|
|
p3Bar.Clean();
|
|
p4Bar.Clean();
|
|
zoneLeftBar.Clean();
|
|
}
|
|
|
|
//
|
|
void ApplyStyle(
|
|
XCBoxObject *iObj,
|
|
ENUM_X_DIRECTION dir //
|
|
)
|
|
{
|
|
//
|
|
if (!HasDirection(dir) || iObj == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int width = boxWidth > 0
|
|
? boxWidth
|
|
: 1;
|
|
int clr = IsBullish(dir)
|
|
? bullishColor
|
|
: bearishColor;
|
|
|
|
//
|
|
iObj.BoxColor(clr);
|
|
iObj.BoxWidth(width);
|
|
iObj.BoxStyle(boxStyle);
|
|
|
|
//
|
|
}
|
|
|
|
// |