last works ... add new Ocillators ...
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| CumulativeDelta.mq5 |
|
||||
//| Copyright © 2023, YourName |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "YourName"
|
||||
#property link "https://www.yourwebsite.com"
|
||||
#property version "1.00"
|
||||
|
||||
//
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 3
|
||||
|
||||
//
|
||||
//--- Plot settings for Line
|
||||
#property indicator_label1 "Cumulative Delta"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrYellow
|
||||
|
||||
//
|
||||
//--- Plot settings for Histogram
|
||||
#property indicator_label2 "Delta"
|
||||
#property indicator_type2 DRAW_HISTOGRAM
|
||||
#property indicator_color2 clrGray
|
||||
|
||||
//
|
||||
//--- Plot settings for Moving Average line
|
||||
#property indicator_label3 "Signal"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrOrchid
|
||||
|
||||
//
|
||||
//--- Input parameters
|
||||
input int MAPeriod = 14; // Period for the moving average
|
||||
|
||||
//
|
||||
//--- Indicator buffers
|
||||
double MABuffer[];
|
||||
double DeltaBuffer[];
|
||||
double CumulativeDeltaBuffer[];
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Attach buffer to the indicator
|
||||
SetIndexBuffer(2, MABuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, DeltaBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(0, CumulativeDeltaBuffer, INDICATOR_DATA);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Cumulative Delta");
|
||||
|
||||
//
|
||||
return (INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
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[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Start from the first uncalculated bar
|
||||
int start = MathMax(prev_calculated - 1, 0);
|
||||
|
||||
//
|
||||
// Loop through bars
|
||||
for (int i = start; i < rates_total; i++)
|
||||
{
|
||||
//
|
||||
// Calculate Delta based on bar-level data
|
||||
double delta = 0.0;
|
||||
if (close[i] > open[i])
|
||||
{
|
||||
delta = (double)tick_volume[i]; // Buying pressure (bullish bar)
|
||||
}
|
||||
else if (close[i] < open[i])
|
||||
{
|
||||
delta = -(double)tick_volume[i]; // Selling pressure (bearish bar)
|
||||
}
|
||||
|
||||
//
|
||||
// Accumulate cumulative delta
|
||||
if (i == 0)
|
||||
{
|
||||
//
|
||||
DeltaBuffer[i] = delta;
|
||||
CumulativeDeltaBuffer[i] = delta; // First bar starts with delta
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
DeltaBuffer[i] = DeltaBuffer[i - 1] + delta;
|
||||
CumulativeDeltaBuffer[i] = CumulativeDeltaBuffer[i - 1] + delta;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Moving Average of Cumulative Delta
|
||||
if (i >= MAPeriod - 1)
|
||||
{
|
||||
//
|
||||
double sum = 0.0;
|
||||
for (int j = 0; j < MAPeriod; j++)
|
||||
{
|
||||
sum += CumulativeDeltaBuffer[i - j];
|
||||
}
|
||||
|
||||
//
|
||||
MABuffer[i] = sum / MAPeriod; // Simple Moving Average
|
||||
}
|
||||
else
|
||||
{
|
||||
MABuffer[i] = EMPTY_VALUE; // Not enough data for MA
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return (rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,210 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| BuySellVolumes.mq5 |
|
||||
//| Copyright © 2023, YourName |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "YourName"
|
||||
#property link "https://www.yourwebsite.com"
|
||||
#property version "1.00"
|
||||
|
||||
//
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 4
|
||||
#property indicator_plots 4
|
||||
|
||||
//--- Plot settings for Buy Volume
|
||||
#property indicator_label1 "Buy Volume"
|
||||
#property indicator_type1 DRAW_HISTOGRAM
|
||||
#property indicator_color1 clrLime
|
||||
|
||||
//--- Plot settings for Sell Volume
|
||||
#property indicator_label2 "Sell Volume"
|
||||
#property indicator_type2 DRAW_HISTOGRAM
|
||||
#property indicator_color2 clrRed
|
||||
|
||||
//--- Plot settings for Buy Volume MA
|
||||
#property indicator_label3 "Buy Volume MA"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrGreen
|
||||
|
||||
//--- Plot settings for Sell Volume MA
|
||||
#property indicator_label4 "Sell Volume MA"
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrRed
|
||||
|
||||
//--- Input parameters
|
||||
input int MAPeriod = 14; // Period for the moving average
|
||||
|
||||
//--- Indicator buffers
|
||||
double BuyVolumeBuffer[]; // Buffer for Buy Volume
|
||||
double SellVolumeBuffer[]; // Buffer for Sell Volume
|
||||
double BuyVolumeMABuffer[]; // Buffer for Buy Volume Moving Average
|
||||
double SellVolumeMABuffer[]; // Buffer for Sell Volume Moving Average
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Attach buffers to the indicator
|
||||
SetIndexBuffer(0, BuyVolumeBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, SellVolumeBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, BuyVolumeMABuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(3, SellVolumeMABuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
// Set short name for the indicator
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Buy and Sell Volumes");
|
||||
|
||||
//
|
||||
return (INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
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[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Start from the first uncalculated bar
|
||||
int start = MathMax(prev_calculated - 1, 0);
|
||||
|
||||
//
|
||||
// Loop through bars
|
||||
for (int i = start; i < rates_total; i++)
|
||||
{
|
||||
//
|
||||
// Calculate Buy and Sell Volumes based on bar-level data
|
||||
double buyVolume = 0.0;
|
||||
double sellVolume = 0.0;
|
||||
|
||||
//
|
||||
if (close[i] > open[i])
|
||||
{
|
||||
//
|
||||
buyVolume = (double)tick_volume[i]; // Buying pressure (bullish bar)
|
||||
sellVolume = 0.0;
|
||||
}
|
||||
else if (close[i] < open[i])
|
||||
{
|
||||
//
|
||||
sellVolume = (double)tick_volume[i]; // Selling pressure (bearish bar)
|
||||
buyVolume = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Neutral bar: split volume equally between buy and sell
|
||||
buyVolume = tick_volume[i] / 2.0;
|
||||
sellVolume = tick_volume[i] / 2.0;
|
||||
}
|
||||
|
||||
//
|
||||
// Store Buy and Sell Volumes in their respective buffers
|
||||
BuyVolumeBuffer[i] = buyVolume;
|
||||
SellVolumeBuffer[i] = sellVolume;
|
||||
|
||||
//
|
||||
// Calculate Moving Averages for Buy and Sell Volumes
|
||||
if (i >= MAPeriod - 1)
|
||||
{
|
||||
//
|
||||
// Calculate Simple Moving Average for Buy Volume
|
||||
double buySum = 0.0;
|
||||
for (int j = 0; j < MAPeriod; j++)
|
||||
buySum += BuyVolumeBuffer[i - j];
|
||||
BuyVolumeMABuffer[i] = buySum / MAPeriod;
|
||||
|
||||
//
|
||||
// Calculate Simple Moving Average for Sell Volume
|
||||
double sellSum = 0.0;
|
||||
for (int j = 0; j < MAPeriod; j++)
|
||||
sellSum += SellVolumeBuffer[i - j];
|
||||
SellVolumeMABuffer[i] = sellSum / MAPeriod;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Not enough data for MA
|
||||
BuyVolumeMABuffer[i] = EMPTY_VALUE;
|
||||
SellVolumeMABuffer[i] = EMPTY_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Normalize all values between 0 and 100
|
||||
// NormalizeValues(rates_total);
|
||||
|
||||
//
|
||||
return (rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Normalize all values between 0 and 100 |
|
||||
//+------------------------------------------------------------------+
|
||||
void NormalizeValues(int rates_total)
|
||||
{
|
||||
//
|
||||
// Find the maximum and minimum values across all buffers
|
||||
double maxValue = 0.0;
|
||||
double minValue = DBL_MAX;
|
||||
|
||||
//
|
||||
for (int i = 0; i < rates_total; i++)
|
||||
{
|
||||
//
|
||||
if (BuyVolumeBuffer[i] != EMPTY_VALUE && BuyVolumeBuffer[i] > maxValue)
|
||||
maxValue = BuyVolumeBuffer[i];
|
||||
if (SellVolumeBuffer[i] != EMPTY_VALUE && SellVolumeBuffer[i] > maxValue)
|
||||
maxValue = SellVolumeBuffer[i];
|
||||
if (BuyVolumeMABuffer[i] != EMPTY_VALUE && BuyVolumeMABuffer[i] > maxValue)
|
||||
maxValue = BuyVolumeMABuffer[i];
|
||||
if (SellVolumeMABuffer[i] != EMPTY_VALUE && SellVolumeMABuffer[i] > maxValue)
|
||||
maxValue = SellVolumeMABuffer[i];
|
||||
|
||||
//
|
||||
if (BuyVolumeBuffer[i] != EMPTY_VALUE && BuyVolumeBuffer[i] < minValue)
|
||||
minValue = BuyVolumeBuffer[i];
|
||||
if (SellVolumeBuffer[i] != EMPTY_VALUE && SellVolumeBuffer[i] < minValue)
|
||||
minValue = SellVolumeBuffer[i];
|
||||
if (BuyVolumeMABuffer[i] != EMPTY_VALUE && BuyVolumeMABuffer[i] < minValue)
|
||||
minValue = BuyVolumeMABuffer[i];
|
||||
if (SellVolumeMABuffer[i] != EMPTY_VALUE && SellVolumeMABuffer[i] < minValue)
|
||||
minValue = SellVolumeMABuffer[i];
|
||||
}
|
||||
|
||||
//
|
||||
// Avoid division by zero
|
||||
if (maxValue == minValue)
|
||||
return;
|
||||
|
||||
//
|
||||
// Normalize all values
|
||||
for (int i = 0; i < rates_total; i++)
|
||||
{
|
||||
//
|
||||
if (BuyVolumeBuffer[i] != EMPTY_VALUE)
|
||||
BuyVolumeBuffer[i] = ((BuyVolumeBuffer[i] - minValue) / (maxValue - minValue)) * 100.0;
|
||||
|
||||
if (SellVolumeBuffer[i] != EMPTY_VALUE)
|
||||
SellVolumeBuffer[i] = ((SellVolumeBuffer[i] - minValue) / (maxValue - minValue)) * 100.0;
|
||||
|
||||
if (BuyVolumeMABuffer[i] != EMPTY_VALUE)
|
||||
BuyVolumeMABuffer[i] = ((BuyVolumeMABuffer[i] - minValue) / (maxValue - minValue)) * 100.0;
|
||||
|
||||
if (SellVolumeMABuffer[i] != EMPTY_VALUE)
|
||||
SellVolumeMABuffer[i] = ((SellVolumeMABuffer[i] - minValue) / (maxValue - minValue)) * 100.0;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -825,7 +825,7 @@ class XC121SMCCycleHelper : public XCBase
|
||||
}
|
||||
|
||||
//
|
||||
datetime GetNearestCloseOverX3MAFast(
|
||||
datetime DetectNearestCloseOverX3MAFast(
|
||||
XOHCL &bar,
|
||||
int maxAllowedBars = 20 //
|
||||
)
|
||||
@@ -891,7 +891,7 @@ class XC121SMCCycleHelper : public XCBase
|
||||
}
|
||||
|
||||
//
|
||||
datetime GetNearestCloseUnderX3MAFast(
|
||||
datetime DetectNearestCloseUnderX3MAFast(
|
||||
XOHCL &bar,
|
||||
int maxAllowedBars = 20 //
|
||||
)
|
||||
|
||||
@@ -0,0 +1,521 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Ocillator
|
||||
// -------------------------------------------------
|
||||
// Name: X121 XDelta
|
||||
// Description: Detect Comulative Volumes Delta ...
|
||||
//
|
||||
//
|
||||
// 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 XDelta Ocillator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
|
||||
//
|
||||
#define ShortName "X121_XDELTA"
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
|
||||
//
|
||||
// Makret ...
|
||||
input group "Market";
|
||||
input int maLength = 14; // Moving Averge Length
|
||||
input ENUM_X_MA_METHOD maMethod = X_MA_MODE_EMA; // Moving Averge Method
|
||||
|
||||
//
|
||||
// Presentation ...
|
||||
input group "Presentation";
|
||||
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||
input bool showDeltaLine = true; // Show Delta Line
|
||||
input bool showDeltaHistogram = true; // Show Delta Histogram
|
||||
input bool showDeltaMa = true; // Show Delta Moving Average
|
||||
|
||||
//
|
||||
// Buffers Props ...
|
||||
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 3
|
||||
|
||||
//
|
||||
#define hideColorIDX 0
|
||||
#define bullishColorIDX 1
|
||||
#define bearishColorIDX 2
|
||||
|
||||
//
|
||||
// Buffers ...
|
||||
|
||||
//
|
||||
#define deltaLineBufferIndex 0
|
||||
double deltaLineBuffer[];
|
||||
|
||||
#property indicator_label1 "Delta Line"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrYellow
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
#define deltaHistogramBufferIndex 1
|
||||
double deltaHistogramBuffer[];
|
||||
|
||||
//
|
||||
#define deltaHistogramColorBufferIndex 2
|
||||
double deltaHistogramColorBuffer[];
|
||||
|
||||
#property indicator_label2 "Delta Histogram"
|
||||
#property indicator_type2 DRAW_COLOR_HISTOGRAM
|
||||
#property indicator_color2 CLR_NONE, clrGreen, clrDarkRed
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
|
||||
//
|
||||
#define deltaMaBufferIndex 3
|
||||
double deltaMaBuffer[];
|
||||
|
||||
#property indicator_label3 "Delta MA"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrOrchid
|
||||
#property indicator_style3 STYLE_SOLID
|
||||
#property indicator_width3 1
|
||||
|
||||
//
|
||||
// Data Buffers ...
|
||||
|
||||
#define mLastBufferIndex 3
|
||||
|
||||
//
|
||||
#define rawDeltaBufferIndex mLastBufferIndex + 1
|
||||
double rawDeltaBuffer[];
|
||||
|
||||
//
|
||||
// Variables, Properties and etc ...
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
int maxLength;
|
||||
|
||||
//
|
||||
// Event Handlers ...
|
||||
|
||||
/**
|
||||
* Initialize Indicator ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize Indicator Handlers ...
|
||||
|
||||
//
|
||||
// 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();
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||
|
||||
//
|
||||
// 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
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||
? rates_total
|
||||
: (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// 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 = maLength > 0 &&
|
||||
IsValid(maMethod);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract Max Length of Inputs ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int ExtractMaxLengthOfInputs()
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
result = MathMax(0, maLength);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
*/
|
||||
void SetIndicatorName()
|
||||
{
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define Required Buffers ...
|
||||
*/
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// Plot Buffers ...
|
||||
|
||||
//
|
||||
// Delta Line ...
|
||||
ENUM_DRAW_TYPE deltaLineDrawType = showDeltaLine ? DRAW_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(deltaLineBuffer, true);
|
||||
SetIndexBuffer(deltaLineBufferIndex, deltaLineBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetDouble(deltaLineBufferIndex, PLOT_EMPTY_VALUE, 0.0);
|
||||
PlotIndexSetInteger(deltaLineBufferIndex, PLOT_SHOW_DATA, showDeltaLine);
|
||||
PlotIndexSetInteger(deltaLineBufferIndex, PLOT_DRAW_TYPE, deltaLineDrawType);
|
||||
|
||||
//
|
||||
// Delta Histogram ...
|
||||
ENUM_DRAW_TYPE deltaHistogramDrawType = showDeltaHistogram ? DRAW_COLOR_HISTOGRAM : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(deltaHistogramBuffer, true);
|
||||
SetIndexBuffer(deltaHistogramBufferIndex, deltaHistogramBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetDouble(deltaHistogramBufferIndex, PLOT_EMPTY_VALUE, 0.0);
|
||||
PlotIndexSetInteger(deltaHistogramBufferIndex, PLOT_SHOW_DATA, showDeltaHistogram);
|
||||
PlotIndexSetInteger(deltaHistogramBufferIndex, PLOT_DRAW_TYPE, deltaHistogramDrawType);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(deltaHistogramColorBuffer, true);
|
||||
SetIndexBuffer(deltaHistogramColorBufferIndex, deltaHistogramColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// Delta Ma ...
|
||||
ENUM_DRAW_TYPE deltaMaDrawType = showDeltaMa ? DRAW_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(deltaMaBuffer, true);
|
||||
SetIndexBuffer(deltaMaBufferIndex, deltaMaBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetDouble(deltaMaBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
PlotIndexSetInteger(deltaMaBufferIndex, PLOT_SHOW_DATA, showDeltaMa);
|
||||
PlotIndexSetInteger(deltaMaBufferIndex, PLOT_DRAW_TYPE, deltaMaDrawType);
|
||||
|
||||
//
|
||||
// Data Buffers ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(rawDeltaBuffer, true);
|
||||
SetIndexBuffer(rawDeltaBufferIndex, rawDeltaBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
//
|
||||
// bool canCalculate = true;
|
||||
bool canCalculate =
|
||||
barsLimit == 0 ||
|
||||
bar_index <= barsLimit;
|
||||
if (canCalculate)
|
||||
{
|
||||
//
|
||||
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)
|
||||
{
|
||||
//
|
||||
rawDeltaBuffer[barIndex] = 0.0;
|
||||
deltaLineBuffer[barIndex] = 0.0;
|
||||
deltaHistogramBuffer[barIndex] = 0.0;
|
||||
deltaMaBuffer[barIndex] = EMPTY_VALUE;
|
||||
deltaHistogramColorBuffer[barIndex] = hideColorIDX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Vales ...
|
||||
*
|
||||
* @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 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[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
XOHCL bar;
|
||||
bool has = bar.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double iDelta = 0.0;
|
||||
|
||||
//
|
||||
// Detecting Delta Volume ...
|
||||
if (bar.IsBullish())
|
||||
{
|
||||
iDelta = (double)bar.volume;
|
||||
}
|
||||
else if (bar.IsBearish())
|
||||
{
|
||||
iDelta = -(double)bar.volume;
|
||||
}
|
||||
|
||||
//
|
||||
// Checking First Bar Conditions ...
|
||||
bool isFirstBar =
|
||||
startCalculationForLastBars > 0
|
||||
? bar_index == startCalculationForLastBars
|
||||
: bar_index == ratesTotal;
|
||||
if (isFirstBar)
|
||||
{
|
||||
//
|
||||
deltaLineBuffer[bar_index] = iDelta;
|
||||
deltaHistogramBuffer[bar_index] = iDelta;
|
||||
|
||||
//
|
||||
rawDeltaBuffer[bar_index] = iDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
iDelta += deltaLineBuffer[bar_index + 1];
|
||||
|
||||
//
|
||||
rawDeltaBuffer[bar_index] = iDelta;
|
||||
deltaLineBuffer[bar_index] = iDelta;
|
||||
deltaHistogramBuffer[bar_index] = iDelta;
|
||||
|
||||
//
|
||||
// deltaLineBuffer[bar_index] = deltaLineBuffer[bar_index + 1] + iDelta;
|
||||
// deltaHistogramBuffer[bar_index] = deltaHistogramBuffer[bar_index + 1] + iDelta;
|
||||
|
||||
// //
|
||||
// rawDeltaBuffer[bar_index] = rawDeltaBuffer[bar_index + 1] + iDelta;
|
||||
}
|
||||
|
||||
//
|
||||
double iDeltaColor = iDelta > 0
|
||||
? bullishColorIDX
|
||||
: iDelta < 0
|
||||
? bearishColorIDX
|
||||
: hideColorIDX;
|
||||
deltaHistogramColorBuffer[bar_index] = iDeltaColor;
|
||||
|
||||
//
|
||||
// Calculate Moving Averages ...
|
||||
int deltaMAsCount = iMAOnBuffer(
|
||||
ratesTotal,
|
||||
prevCalculated,
|
||||
bar_index,
|
||||
maLength,
|
||||
rawDeltaBuffer,
|
||||
deltaMaBuffer,
|
||||
maMethod //
|
||||
);
|
||||
|
||||
//
|
||||
bar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -0,0 +1,544 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Ocillator
|
||||
// -------------------------------------------------
|
||||
// Name: X121 XVolume
|
||||
// Description: Detect Bullish/Bearish Volumes ...
|
||||
//
|
||||
//
|
||||
// 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 XVolume Ocillator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
|
||||
//
|
||||
#define ShortName "X121_XVOLUME"
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
|
||||
//
|
||||
// Makret ...
|
||||
input group "Market";
|
||||
input int maLength = 14; // Moving Averge Length
|
||||
input ENUM_X_MA_METHOD maMethod = X_MA_MODE_EMA; // Moving Averge Method
|
||||
|
||||
//
|
||||
// Presentation ...
|
||||
input group "Presentation";
|
||||
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||
input bool showBullishVolume = true; // Show Bullish Volume
|
||||
input bool showBullishVolumeMa = true; // Show Bullish Volume Moving Average
|
||||
input bool showBearishVolume = true; // Show Bearish Volume
|
||||
input bool showBearishVolumeMa = true; // Show Bearish Volume Moving Average
|
||||
|
||||
//
|
||||
// Buffers Props ...
|
||||
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 6
|
||||
#property indicator_plots 4
|
||||
|
||||
//
|
||||
// Buffers ...
|
||||
|
||||
//
|
||||
#define bullishVolumeBufferIndex 0
|
||||
double bullishVolumeBuffer[];
|
||||
|
||||
#property indicator_label1 "Bullish Volume"
|
||||
#property indicator_type1 DRAW_HISTOGRAM
|
||||
#property indicator_color1 clrLime
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
#define bullishVolumeMaBufferIndex 1
|
||||
double bullishVolumeMaBuffer[];
|
||||
|
||||
#property indicator_label2 "Bullish Volume MA"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrLime
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
|
||||
//
|
||||
#define bearishVolumeBufferIndex 2
|
||||
double bearishVolumeBuffer[];
|
||||
|
||||
#property indicator_label3 "Bearish Volume"
|
||||
#property indicator_type3 DRAW_HISTOGRAM
|
||||
#property indicator_color3 clrRed
|
||||
#property indicator_style3 STYLE_DOT
|
||||
#property indicator_width3 1
|
||||
|
||||
//
|
||||
#define bearishVolumeMaBufferIndex 3
|
||||
double bearishVolumeMaBuffer[];
|
||||
|
||||
#property indicator_label4 "Bearish Volume MA"
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrRed
|
||||
#property indicator_style4 STYLE_SOLID
|
||||
#property indicator_width4 1
|
||||
|
||||
//
|
||||
// Data Buffers ...
|
||||
|
||||
#define mLastBufferIndex 3
|
||||
|
||||
//
|
||||
#define rawBullishVolumeBufferIndex mLastBufferIndex + 1
|
||||
double rawBullishVolumeBuffer[];
|
||||
|
||||
//
|
||||
#define rawBearishVolumeBufferIndex mLastBufferIndex + 2
|
||||
double rawBearishVolumeBuffer[];
|
||||
|
||||
//
|
||||
// Variables, Properties and etc ...
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
int maxLength;
|
||||
|
||||
//
|
||||
// Event Handlers ...
|
||||
|
||||
/**
|
||||
* Initialize Indicator ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize Indicator Handlers ...
|
||||
|
||||
//
|
||||
// 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();
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||
|
||||
//
|
||||
// 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
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||
? rates_total
|
||||
: (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// 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 = maLength > 0 &&
|
||||
IsValid(maMethod);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract Max Length of Inputs ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int ExtractMaxLengthOfInputs()
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
result = MathMax(0, maLength);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
*/
|
||||
void SetIndicatorName()
|
||||
{
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define Required Buffers ...
|
||||
*/
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// Plot Buffers ...
|
||||
|
||||
//
|
||||
// Bullish ...
|
||||
|
||||
//
|
||||
// Volume ...
|
||||
ENUM_DRAW_TYPE bullishVolumeDrawType = showBullishVolume ? DRAW_HISTOGRAM : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(bullishVolumeBuffer, true);
|
||||
SetIndexBuffer(bullishVolumeBufferIndex, bullishVolumeBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetDouble(bullishVolumeBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
PlotIndexSetInteger(bullishVolumeBufferIndex, PLOT_SHOW_DATA, showBullishVolume);
|
||||
PlotIndexSetInteger(bullishVolumeBufferIndex, PLOT_DRAW_TYPE, bullishVolumeDrawType);
|
||||
|
||||
//
|
||||
// Average ...
|
||||
ENUM_DRAW_TYPE bullishVolumeMaDrawType = showBullishVolumeMa ? DRAW_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(bullishVolumeMaBuffer, true);
|
||||
SetIndexBuffer(bullishVolumeMaBufferIndex, bullishVolumeMaBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetDouble(bullishVolumeMaBufferIndex, PLOT_EMPTY_VALUE, 0.0);
|
||||
PlotIndexSetInteger(bullishVolumeMaBufferIndex, PLOT_SHOW_DATA, showBullishVolumeMa);
|
||||
PlotIndexSetInteger(bullishVolumeMaBufferIndex, PLOT_DRAW_TYPE, bullishVolumeMaDrawType);
|
||||
|
||||
//
|
||||
// Bearish ...
|
||||
|
||||
//
|
||||
// Volume ...
|
||||
ENUM_DRAW_TYPE bearishVolumeDrawType = showBearishVolume ? DRAW_HISTOGRAM : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(bearishVolumeBuffer, true);
|
||||
SetIndexBuffer(bearishVolumeBufferIndex, bearishVolumeBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetDouble(bearishVolumeBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
PlotIndexSetInteger(bearishVolumeBufferIndex, PLOT_SHOW_DATA, showBearishVolume);
|
||||
PlotIndexSetInteger(bearishVolumeBufferIndex, PLOT_DRAW_TYPE, bearishVolumeDrawType);
|
||||
|
||||
//
|
||||
// Average ...
|
||||
ENUM_DRAW_TYPE bearishVolumeMaDrawType = showBearishVolumeMa ? DRAW_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(bearishVolumeMaBuffer, true);
|
||||
SetIndexBuffer(bearishVolumeMaBufferIndex, bearishVolumeMaBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetDouble(bearishVolumeMaBufferIndex, PLOT_EMPTY_VALUE, 0.0);
|
||||
PlotIndexSetInteger(bearishVolumeMaBufferIndex, PLOT_SHOW_DATA, showBearishVolumeMa);
|
||||
PlotIndexSetInteger(bearishVolumeMaBufferIndex, PLOT_DRAW_TYPE, bearishVolumeMaDrawType);
|
||||
|
||||
//
|
||||
// Data Buffers ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(rawBullishVolumeBuffer, true);
|
||||
SetIndexBuffer(rawBullishVolumeBufferIndex, rawBullishVolumeBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(rawBearishVolumeBuffer, true);
|
||||
SetIndexBuffer(rawBearishVolumeBufferIndex, rawBearishVolumeBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
//
|
||||
// bool canCalculate = true;
|
||||
bool canCalculate =
|
||||
barsLimit == 0 ||
|
||||
bar_index <= barsLimit;
|
||||
if (canCalculate)
|
||||
{
|
||||
//
|
||||
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)
|
||||
{
|
||||
//
|
||||
bullishVolumeBuffer[barIndex] = EMPTY_VALUE;
|
||||
bullishVolumeMaBuffer[barIndex] = EMPTY_VALUE;
|
||||
rawBullishVolumeBuffer[barIndex] = 0;
|
||||
|
||||
//
|
||||
bearishVolumeBuffer[barIndex] = EMPTY_VALUE;
|
||||
bearishVolumeMaBuffer[barIndex] = EMPTY_VALUE;
|
||||
rawBearishVolumeBuffer[barIndex] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Vales ...
|
||||
*
|
||||
* @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 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[] //
|
||||
)
|
||||
{
|
||||
//
|
||||
XOHCL bar;
|
||||
bool has = bar.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double iBullishVolume = 0;
|
||||
double iBearishVolume = 0;
|
||||
|
||||
//
|
||||
if (bar.IsBullish())
|
||||
{
|
||||
//
|
||||
iBullishVolume = (double)bar.volume;
|
||||
iBearishVolume = 0;
|
||||
}
|
||||
else if (bar.IsBearish())
|
||||
{
|
||||
//
|
||||
iBearishVolume = (double)bar.volume;
|
||||
iBullishVolume = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
double volume = ((double)bar.volume) / 2.0;
|
||||
iBullishVolume = volume;
|
||||
iBearishVolume = volume;
|
||||
}
|
||||
|
||||
//
|
||||
bullishVolumeBuffer[bar_index] =
|
||||
iBullishVolume == 0
|
||||
? EMPTY_VALUE
|
||||
: iBullishVolume;
|
||||
rawBullishVolumeBuffer[bar_index] = iBullishVolume;
|
||||
|
||||
//
|
||||
bearishVolumeBuffer[bar_index] =
|
||||
iBearishVolume == 0
|
||||
? EMPTY_VALUE
|
||||
: iBearishVolume;
|
||||
rawBearishVolumeBuffer[bar_index] = iBearishVolume;
|
||||
|
||||
//
|
||||
// Calculate Moving Averages ...
|
||||
|
||||
//
|
||||
int bullishMAsCount = iMAOnBuffer(
|
||||
ratesTotal,
|
||||
prevCalculated,
|
||||
bar_index,
|
||||
maLength,
|
||||
rawBullishVolumeBuffer,
|
||||
bullishVolumeMaBuffer,
|
||||
maMethod //
|
||||
);
|
||||
|
||||
//
|
||||
int bearishMAsCount = iMAOnBuffer(
|
||||
ratesTotal,
|
||||
prevCalculated,
|
||||
bar_index,
|
||||
maLength,
|
||||
rawBearishVolumeBuffer,
|
||||
bearishVolumeMaBuffer,
|
||||
maMethod //
|
||||
);
|
||||
|
||||
//
|
||||
bar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -34,6 +34,7 @@ struct XOHCL
|
||||
double open;
|
||||
double close;
|
||||
double low;
|
||||
long volume;
|
||||
double spread;
|
||||
|
||||
//
|
||||
@@ -112,6 +113,13 @@ struct XOHCL
|
||||
);
|
||||
spread = NormalizePrice(spread, mSymbol);
|
||||
|
||||
//
|
||||
volume = iTickVolume(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
barIndex //
|
||||
);
|
||||
|
||||
//
|
||||
bool result = IsValid();
|
||||
|
||||
@@ -151,40 +159,6 @@ struct XOHCL
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool Init(
|
||||
string mSymbol = NULL, // Trading Symbol
|
||||
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period
|
||||
double mOpen = 0, // Open
|
||||
double mHigh = 0, // High
|
||||
double mClose = 0, // Close
|
||||
double mLow = 0, // Low
|
||||
datetime mTime = NULL // Bar Time
|
||||
)
|
||||
{
|
||||
//
|
||||
mSymbol = NormalizeSymbol(mSymbol);
|
||||
mPeriod = NormalizePeriod(mPeriod);
|
||||
|
||||
//
|
||||
symbol = mSymbol;
|
||||
period = mPeriod;
|
||||
|
||||
//
|
||||
int barIndex = GetBarIndex(
|
||||
symbol,
|
||||
period,
|
||||
mTime //
|
||||
);
|
||||
|
||||
//
|
||||
return Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
barIndex //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
@@ -197,6 +171,7 @@ struct XOHCL
|
||||
open = 0;
|
||||
close = 0;
|
||||
spread = 0;
|
||||
volume = 0;
|
||||
|
||||
//
|
||||
time = NULL;
|
||||
@@ -221,7 +196,8 @@ struct XOHCL
|
||||
high > 0 &&
|
||||
open > 0 &&
|
||||
close > 0 &&
|
||||
spread > 0
|
||||
spread > 0 &&
|
||||
volume > 0
|
||||
//
|
||||
;
|
||||
|
||||
|
||||
@@ -475,6 +475,9 @@ class XC121SMCCycleHelper : public XCBase
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
bool GeneratePVBox(
|
||||
XBoxZone &box,
|
||||
@@ -825,7 +828,7 @@ class XC121SMCCycleHelper : public XCBase
|
||||
}
|
||||
|
||||
//
|
||||
datetime GetNearestCloseOverX3MAFast(
|
||||
datetime DetectNearestCloseOverX3MAFast(
|
||||
XOHCL &bar,
|
||||
int maxAllowedBars = 20 //
|
||||
)
|
||||
@@ -891,7 +894,7 @@ class XC121SMCCycleHelper : public XCBase
|
||||
}
|
||||
|
||||
//
|
||||
datetime GetNearestCloseUnderX3MAFast(
|
||||
datetime DetectNearestCloseUnderX3MAFast(
|
||||
XOHCL &bar,
|
||||
int maxAllowedBars = 20 //
|
||||
)
|
||||
@@ -956,6 +959,94 @@ class XC121SMCCycleHelper : public XCBase
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool DetectNearestTenKijCross(
|
||||
XOHCL &bar,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
int barIndex = 0,
|
||||
int maxAllowedBars = 20 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bar.Clean();
|
||||
dir = X_DIRECTION_NONE;
|
||||
barIndex = NormalizeInt(barIndex, 0);
|
||||
maxAllowedBars = NormalizeInt(maxAllowedBars, 20);
|
||||
|
||||
//
|
||||
// Looping Through LoopBack Period ...
|
||||
// for Detecting Result ...
|
||||
for (int i = barIndex; i < barIndex + maxAllowedBars; i++)
|
||||
{
|
||||
//
|
||||
XOHCL iBar;
|
||||
result = iBar.Init(
|
||||
GetSymbol(),
|
||||
GetPeriod(),
|
||||
i //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
iBar.Clean();
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
double iTSen = mX121Helper.xichHelper.GetTenkanSen(i);
|
||||
double iTSenP = mX121Helper.xichHelper.GetTenkanSen(i + 1);
|
||||
|
||||
//
|
||||
double iKSen = mX121Helper.xichHelper.GetKijunSen(i);
|
||||
double iKSenP = mX121Helper.xichHelper.GetKijunSen(i + 1);
|
||||
|
||||
//
|
||||
bool isTSenOverKSen = iTSen > iKSen;
|
||||
bool isTSenOverKSenP = iTSenP > iKSenP;
|
||||
|
||||
//
|
||||
bool isTSenUnderKSen = iTSen < iKSen;
|
||||
bool isTSenUnderKSenP = iTSenP < iKSenP;
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
bool isTSenCrossedOverKSen = isTSenOverKSen &&
|
||||
!isTSenOverKSenP;
|
||||
|
||||
//
|
||||
bool isTSenCrossedUnderKSen = isTSenUnderKSen &&
|
||||
!isTSenUnderKSenP;
|
||||
|
||||
//
|
||||
result = isTSenCrossedOverKSen ||
|
||||
isTSenCrossedUnderKSen;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
bar = iBar;
|
||||
|
||||
//
|
||||
dir = isTSenCrossedOverKSen
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Virtuals ...
|
||||
|
||||
@@ -3753,6 +3844,9 @@ struct X121SMCStrategyConditionParser
|
||||
cBar.high < vXConditions.senkouMin &&
|
||||
vBearishScore > (vBullishScore * 1.5);
|
||||
|
||||
//
|
||||
// ichimokou ...
|
||||
|
||||
//
|
||||
// Bullish Conditions ...
|
||||
isBullish =
|
||||
|
||||
@@ -37,6 +37,7 @@ const string X121SMCStrategyToken = "X121SMC";
|
||||
|
||||
//
|
||||
const string X121SMCXWZToken = "X121XWZ";
|
||||
const string X121SMCXICHToken = "X121XICH";
|
||||
|
||||
//
|
||||
// X121 SMC Providers ...
|
||||
@@ -45,6 +46,7 @@ enum ENUM_X_121_SMC_PROVIDERS
|
||||
//
|
||||
X_121_SMC_PROVIDER_NONE,
|
||||
X_121_SMC_PROVIDER_XWZ,
|
||||
X_121_SMC_PROVIDER_XICH,
|
||||
};
|
||||
|
||||
//
|
||||
@@ -700,6 +702,11 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value)
|
||||
case X_121_SMC_PROVIDER_XWZ:
|
||||
result = X121SMCXWZToken;
|
||||
break;
|
||||
|
||||
//
|
||||
case X_121_SMC_PROVIDER_XICH:
|
||||
result = X121SMCXICHToken;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -729,6 +736,10 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value)
|
||||
{
|
||||
result = X_121_SMC_PROVIDER_XWZ;
|
||||
}
|
||||
else if (Contains(X121SMCXICHToken, value))
|
||||
{
|
||||
result = X_121_SMC_PROVIDER_XICH;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,225 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 X121 SMC Signal Class
|
||||
// -------------------------------------------------
|
||||
// Name: XICH
|
||||
// Description: provide all Signalling functions ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
// #include "../../Libraries/x-trade.lib"
|
||||
#include "../Classes/x-121.smc.market.cycle.helper.class.mq5"
|
||||
#include "../Libraries/x-121.smc.guard.lib.mq5"
|
||||
#include "../Libraries/x-121.smc.lib.mq5"
|
||||
|
||||
//
|
||||
// Provided Signals Enumeration ...
|
||||
enum ENUM_X121SMC_XICH_PROVIDERS
|
||||
{
|
||||
X121SMC_XICH_PROVIDER_NONE,
|
||||
X121SMC_XICH_PROVIDER_XTKKUMO,
|
||||
};
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
|
||||
//
|
||||
// XICH Signal Conditions ...
|
||||
struct X121SMCStrategyXICHSignalConditions
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
string symbol;
|
||||
ENUM_TIMEFRAMES period;
|
||||
|
||||
//
|
||||
double sl;
|
||||
ENUM_X_DIRECTION dir;
|
||||
ENUM_X_POSITION_TYPES type;
|
||||
|
||||
//
|
||||
// Setup Props ...
|
||||
|
||||
//
|
||||
datetime setupTime;
|
||||
datetime triggerTime;
|
||||
|
||||
//
|
||||
double pivot;
|
||||
double point;
|
||||
double sls[];
|
||||
double targets[];
|
||||
|
||||
//
|
||||
XBoxZone signalBox;
|
||||
|
||||
//
|
||||
ENUM_X121SMC_XICH_PROVIDERS provider;
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
X121SMCStrategyXICHSignalConditions()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* Cleaning Up ...
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
sl = 0;
|
||||
|
||||
//
|
||||
dir = X_DIRECTION_NONE;
|
||||
type = X_POSITION_TYPE_NONE;
|
||||
|
||||
//
|
||||
symbol = NULL;
|
||||
period = NULL;
|
||||
setupTime = NULL;
|
||||
triggerTime = NULL;
|
||||
|
||||
//
|
||||
ExtensionClean();
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Condition is Setting Up ...
|
||||
*
|
||||
* @param dir: ENUM_X_DIRECTION member, Setting Up Direction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsSetuped()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = IsValid(setupTime) &&
|
||||
HasDirection(dir);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Setup Age ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int GetSetupAge()
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
if (!IsSetuped())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect How we Can Trigger Signal ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool CanTrigger()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
sl > 0 &&
|
||||
IsValid(symbol) &&
|
||||
IsValid(period) &&
|
||||
IsValid(triggerTime) &&
|
||||
type != X_POSITION_TYPE_ALL &&
|
||||
type != X_POSITION_TYPE_NONE
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Extensions ...
|
||||
|
||||
/**
|
||||
* Clean Additional Properties ...
|
||||
*/
|
||||
void ExtensionClean()
|
||||
{
|
||||
//
|
||||
pivot = 0;
|
||||
point = 0;
|
||||
|
||||
//
|
||||
Clean(sls);
|
||||
Clean(targets);
|
||||
signalBox.Clean();
|
||||
|
||||
//
|
||||
provider = X121SMC_XICH_PROVIDER_NONE;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
void UpdateTo(datetime value = NULL)
|
||||
{
|
||||
//
|
||||
value = NormalizeTime(value);
|
||||
|
||||
//
|
||||
int count = 0;
|
||||
bool has = false;
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
//
|
||||
// Extension Functions ...
|
||||
|
||||
//
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "../Classes/x-121.smc.market.cycle.helper.class.mq5"
|
||||
|
||||
//
|
||||
#include "../Signals/x-121.smc.xich.signal.class.mq5"
|
||||
#include "../Signals/x-121.smc.xwz.signal.class.mq5"
|
||||
|
||||
//
|
||||
@@ -42,8 +43,11 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
//
|
||||
// Props ...
|
||||
bool useXWZSignal;
|
||||
bool useXICHSignal;
|
||||
bool useXWZSignalGuard;
|
||||
bool useXICHSignalGuard;
|
||||
XCX121SMCXWZSignalDetector *mXWZSignalDetector;
|
||||
XCX121SMCXICHSignalDetector *mXICHSignalDetector;
|
||||
X121SMCStrategySignalProviderData cycleProvider;
|
||||
|
||||
//
|
||||
@@ -64,6 +68,12 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
_symbol,
|
||||
_period //
|
||||
);
|
||||
|
||||
//
|
||||
mXICHSignalDetector = new XCX121SMCXICHSignalDetector(
|
||||
_symbol,
|
||||
_period //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -121,6 +131,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
|
||||
//
|
||||
ZeroMemory(mXWZSignalDetector);
|
||||
ZeroMemory(mXICHSignalDetector);
|
||||
|
||||
//
|
||||
cycleProvider.Destroy();
|
||||
@@ -203,9 +214,9 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
|
||||
//
|
||||
bool hasXWZSignal = false;
|
||||
bool hasXICHSignal = false;
|
||||
|
||||
//
|
||||
// XSupDemOBS Signal ...
|
||||
X121SMCStrategyXWZSignalConditions mXWZConditions;
|
||||
if (useXWZSignal && !hasSignal)
|
||||
{
|
||||
@@ -217,6 +228,18 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
hasSignal = hasXWZSignal;
|
||||
}
|
||||
|
||||
//
|
||||
X121SMCStrategyXICHSignalConditions mXICHConditions;
|
||||
if (useXICHSignal && !hasSignal)
|
||||
{
|
||||
//
|
||||
hasXICHSignal = DetectXICHSignal(
|
||||
conditions,
|
||||
mXICHConditions //
|
||||
);
|
||||
hasSignal = hasXICHSignal;
|
||||
}
|
||||
|
||||
//
|
||||
result = hasSignal;
|
||||
if (!result)
|
||||
@@ -400,6 +423,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
|
||||
//
|
||||
mXWZConditions.Clean();
|
||||
mXICHConditions.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
@@ -455,6 +479,34 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
Clean(xwzGuards);
|
||||
}
|
||||
|
||||
//
|
||||
// XICH Guard Detection ...
|
||||
if (useXICHSignal &&
|
||||
useXICHSignalGuard)
|
||||
{
|
||||
//
|
||||
X121SMCGuard xichGuards[];
|
||||
bool hasGuard = mXICHSignalDetector.DetectGuards(
|
||||
xichGuards,
|
||||
positions,
|
||||
cycleProvider //
|
||||
);
|
||||
|
||||
//
|
||||
if (hasGuard)
|
||||
{
|
||||
//
|
||||
Copy(
|
||||
xichGuards,
|
||||
guards,
|
||||
false //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
Clean(xichGuards);
|
||||
}
|
||||
|
||||
//
|
||||
count = ArraySize(guards);
|
||||
result = IsValidSize(count);
|
||||
@@ -676,6 +728,180 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XICH Signal ...
|
||||
bool DetectXICHSignal(
|
||||
X121SMCStrategyConditions &conditions,
|
||||
X121SMCStrategyXICHSignalConditions &xICHConditions //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isBullish = false;
|
||||
bool isBearish = false;
|
||||
|
||||
//
|
||||
int zIndex = 0;
|
||||
int cIndex = zIndex + 1;
|
||||
int pIndex = cIndex + 1;
|
||||
int ppIndex = pIndex + 1;
|
||||
|
||||
//
|
||||
string symbol = GetSymbol();
|
||||
ENUM_TIMEFRAMES period = GetPeriod();
|
||||
|
||||
//
|
||||
datetime cTime = TimeCurrent();
|
||||
|
||||
//
|
||||
ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XICH;
|
||||
string providerStr = ToString(provider);
|
||||
|
||||
//
|
||||
// Detect Setup Conditions ...
|
||||
datetime setupTime = mXICHSignalDetector.mConditions.setupTime;
|
||||
bool isSetuped = mXICHSignalDetector.mConditions.IsSetuped();
|
||||
ENUM_X_DIRECTION setupDir = mXICHSignalDetector.mConditions.dir;
|
||||
if (!isSetuped)
|
||||
{
|
||||
//
|
||||
// Detect Signal Setup ...
|
||||
isSetuped = mXICHSignalDetector.DetectSignalSetup(
|
||||
cycleProvider //
|
||||
);
|
||||
|
||||
//
|
||||
setupDir = mXICHSignalDetector.mConditions.dir;
|
||||
setupTime = mXICHSignalDetector.mConditions.setupTime;
|
||||
|
||||
//
|
||||
if (isSetuped)
|
||||
{
|
||||
//
|
||||
int items = mXICHSignalDetector
|
||||
.AddConditionsIfNotExists();
|
||||
|
||||
//
|
||||
mXICHSignalDetector.mConditions.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
int conditionsCount = ArraySize(mXICHSignalDetector.mConditionsCollection);
|
||||
result = IsValidSize(conditionsCount);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Looking For Conditions ...
|
||||
int selectedIndex = 0;
|
||||
X121SMCStrategyXICHSignalConditions mTmpConditions[];
|
||||
Copy(
|
||||
mXICHSignalDetector.mConditionsCollection,
|
||||
mTmpConditions //
|
||||
);
|
||||
X121SMCStrategyXICHSignalConditions mConditions;
|
||||
for (int i = 0; i < conditionsCount; i++)
|
||||
{
|
||||
//
|
||||
// Check Triggers ...
|
||||
bool canTrigger = mTmpConditions[i].CanTrigger();
|
||||
datetime triggerTime = mTmpConditions[i].triggerTime;
|
||||
if (!canTrigger)
|
||||
{
|
||||
//
|
||||
// Detect Signal Trigger ...
|
||||
canTrigger = mXICHSignalDetector
|
||||
.DetectSignalTrigger(
|
||||
mTmpConditions[i],
|
||||
cycleProvider //
|
||||
);
|
||||
|
||||
//
|
||||
result = canTrigger;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
bool isISetuped = mTmpConditions[i].IsSetuped();
|
||||
if (!isISetuped)
|
||||
{
|
||||
//
|
||||
ArrayRemove(
|
||||
mXICHSignalDetector.mConditionsCollection,
|
||||
i,
|
||||
1 //
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
triggerTime = mTmpConditions[i].triggerTime;
|
||||
}
|
||||
|
||||
//
|
||||
if (canTrigger)
|
||||
{
|
||||
//
|
||||
selectedIndex = i;
|
||||
mConditions = mTmpConditions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = IsValid(mConditions.setupTime) &&
|
||||
HasDirection(mConditions.dir);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Remove Selected Index from Main Collection ...
|
||||
ArrayRemove(
|
||||
mXICHSignalDetector.mConditionsCollection,
|
||||
selectedIndex,
|
||||
1 //
|
||||
);
|
||||
|
||||
//
|
||||
// Check Signal Direction ...
|
||||
isBullish = IsBullish(mConditions.dir);
|
||||
isBearish = IsBearish(mConditions.dir);
|
||||
result = isBullish ||
|
||||
isBearish;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Issues Signal on Conditions ...
|
||||
conditions.sl = mConditions.sl;
|
||||
conditions.provider = providerStr;
|
||||
conditions.signalDir = mConditions.dir;
|
||||
|
||||
//
|
||||
Copy(
|
||||
mConditions.targets,
|
||||
conditions.targets //
|
||||
);
|
||||
|
||||
//
|
||||
xICHConditions = mConditions;
|
||||
|
||||
//
|
||||
mConditions.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
@@ -691,9 +917,13 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
void InitialHelpers()
|
||||
{
|
||||
//
|
||||
useXWZSignal = true;
|
||||
useXWZSignal = false;
|
||||
useXWZSignalGuard = false;
|
||||
|
||||
//
|
||||
useXICHSignal = true;
|
||||
useXICHSignalGuard = false;
|
||||
|
||||
//
|
||||
string symbol = GetSymbol();
|
||||
ENUM_TIMEFRAMES period = GetPeriod();
|
||||
@@ -865,7 +1095,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
x121Inputs.xichInputs.showChikouSpan = showAll || true;
|
||||
x121Inputs.xichInputs.showSenkouSpanA = showAll || true;
|
||||
x121Inputs.xichInputs.showSenkouSpanB = showAll || true;
|
||||
x121Inputs.xichInputs.showKumo = showAll || false;
|
||||
x121Inputs.xichInputs.showKumo = showAll || true;
|
||||
|
||||
//
|
||||
// Initialize Cycle Helpers ...
|
||||
|
||||
Reference in New Issue
Block a user