This commit is contained in:
2025-06-01 14:01:55 +03:30
parent 24a40b19ad
commit a03a739e16
33 changed files with 0 additions and 55813 deletions
-243
View File
@@ -1,243 +0,0 @@
//+------------------------------------------------------------------+
//| SpikeDetectorEA.mq5 |
//| Copyright 2025, Your Name/Company |
//| https://www.example.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Your Name/Company"
#property link "https://www.example.com"
#property version "1.01" // Incremented version
#property description "Expert Advisor to detect and draw price spikes (pin bars)."
//--- Input Parameters
input group "Spike Definition" input double InpMinWickToBodyRatio = 2.0; // Minimum ratio of the main wick to the body (e.g., 2.0 means wick is 2x body)
input double InpMaxOppositeWickToBodyRatio = 1.0; // Maximum ratio of the opposite wick to the body (e.g., 1.0 means opposite wick <= body)
input double InpMaxBodyToTotalRangeRatio = 0.33; // Maximum ratio of body to total candle range (H-L) (e.g., 0.33 means body is < 1/3 of range)
input group "Drawing Settings" input int InpArrowOffsetPoints = 10; // Arrow offset from High/Low in points
input color InpBullishSpikeColor = clrLimeGreen; // Color for bullish spike arrows
input color InpBearishSpikeColor = clrRed; // Color for bearish spike arrows
input int InpLookbackForDrawing = 200; // How many past bars to check on EA load/recompile
// Wingdings Arrow Codes (commonly used for OBJ_ARROW)
#define WINGDINGS_ARROW_UP 241
#define WINGDINGS_ARROW_DOWN 242
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
// You can add any one-time initialization logic here if needed
Print("SpikeDetectorEA initialized. Symbol: ", _Symbol, ", Timeframe: ", EnumToString((ENUM_TIMEFRAMES)Period()));
//---
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
// Optional: Clean up objects when EA is removed or chart is closed
// For more targeted deletion, you might loop through objects and check names
// ObjectsDeleteAll(0, "SpikeArrow_Bearish_" + _Symbol);
// ObjectsDeleteAll(0, "SpikeArrow_Bullish_" + _Symbol);
// A more robust way if you have many EAs or indicators:
long chart_id = ChartID();
for (int i = ObjectsTotal(chart_id, -1, OBJ_ARROW) - 1; i >= 0; i--)
{
string obj_name = ObjectName(chart_id, i, -1, OBJ_ARROW);
if (StringFind(obj_name, "SpikeArrow_Bearish_" + _Symbol + "_" + EnumToString((ENUM_TIMEFRAMES)Period())) == 0 ||
StringFind(obj_name, "SpikeArrow_Bullish_" + _Symbol + "_" + EnumToString((ENUM_TIMEFRAMES)Period())) == 0)
{
ObjectDelete(chart_id, obj_name);
}
}
Print("SpikeDetectorEA deinitialized. Reason: ", reason);
}
//+------------------------------------------------------------------+
//| Expert tick function (not used for bar analysis in this EA) |
//+------------------------------------------------------------------+
void OnTick()
{
//---
// We will use OnCalculate for bar-based analysis
}
//+------------------------------------------------------------------+
//| Chart event function (not strictly needed for this EA) |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//---
// Can be used to handle chart events if necessary
}
//+------------------------------------------------------------------+
//| Expert new bar function / Indicator calculation event |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, // Size of the price[] arrays
const int prev_calculated, // Bars calculated at the previous call
const datetime &time[], // Time array
const double &open[], // Open price array
const double &high[], // High price array
const double &low[], // Low price array
const double &close[], // Close price array
const long &tick_volume[], // Tick Volume array
const long &volume[], // Real Volume array
const int &spread[]) // Spread array
{
//--- Check for minimal rates_total
if (rates_total < 2) // Need at least one closed bar to compare
return (0);
//--- Determine how many bars to calculate
int first_bar_to_calculate;
// On the very first call of OnCalculate (prev_calculated == 0) or if history was changed drastically
if (prev_calculated == 0 || prev_calculated > rates_total || rates_total - prev_calculated > InpLookbackForDrawing + 10) // Added a buffer for safety
{
first_bar_to_calculate = MathMax(0, rates_total - InpLookbackForDrawing);
Print("SpikeDetectorEA: First run or history refresh. Processing up to ", InpLookbackForDrawing, " bars from bar index ", first_bar_to_calculate);
// Clean up old arrows if doing a full refresh to avoid orphaned objects if bar times change
long chart_id = ChartID();
for (int k = ObjectsTotal(chart_id, -1, OBJ_ARROW) - 1; k >= 0; k--)
{
string obj_name_check = ObjectName(chart_id, k, -1, OBJ_ARROW);
if (StringFind(obj_name_check, "SpikeArrow_Bearish_" + _Symbol + "_" + EnumToString((ENUM_TIMEFRAMES)Period())) == 0 ||
StringFind(obj_name_check, "SpikeArrow_Bullish_" + _Symbol + "_" + EnumToString((ENUM_TIMEFRAMES)Period())) == 0)
{
ObjectDelete(chart_id, obj_name_check);
}
}
}
else
{
// prev_calculated is the number of bars calculated by the previous call.
// We want to start from one bar before the last one calculated by the previous call,
// to catch updates to the forming bar that has now closed, plus any new bars.
// rates_total - prev_calculated gives the number of new bars.
// We process (rates_total - prev_calculated) + 1 bars (the forming bar that closed + new bars)
// So, start from rates_total - (rates_total - prev_calculated + 1) = prev_calculated - 1
first_bar_to_calculate = prev_calculated - 1;
}
// Ensure we don't go out of bounds (e.g. if prev_calculated was 0 due to error or very few bars)
first_bar_to_calculate = MathMax(0, first_bar_to_calculate);
// We don't want to process the current, still-forming bar (index rates_total - 1 usually)
// So loop up to rates_total - 1 (or < rates_total)
// If we are processing historical bars, i can go up to rates_total - 1
// If we are processing only new bars, the last bar is rates_total - 1.
//--- Main loop for processing bars
// We iterate up to rates_total-1 because the last bar (rates_total-1) is the current forming bar
// We are interested in closed bars. So, the last closed bar is at index rates_total-2 if rates_total > 1.
// However, if we start from prev_calculated-1, this logic handles it correctly.
// The loop should go up to `rates_total - 1` to process all available historical bars.
// The current bar (index rates_total - 1) will be processed on the next tick once it closes and a new bar forms.
for (int i = first_bar_to_calculate; i < rates_total; i++)
{
// Skip the current forming bar (bar 0 in terminal, index rates_total-1 in array if processing live)
// This logic is implicitly handled by how OnCalculate is typically called.
// The loop goes from an older bar up to the most recent *available* bar data.
// The last bar in the `time`, `open`, etc. arrays is `rates_total - 1`.
// If `i == rates_total - 1`, it's the current, potentially unclosed bar.
// We generally want to analyze closed bars. Let's adjust the loop to `i < rates_total -1` if we only want confirmed closed bars.
// However, for drawing on historical data, `i < rates_total` is fine.
// The key is that `prev_calculated` helps us only recalculate what's necessary.
// Let's assume we process up to the last available bar, and if it's the current forming bar,
// its spike status might change. The object deletion logic handles this.
// If it's the very first bar available (index 0) and it has no history to form wicks properly, skip.
// This check might be too simplistic, but helps avoid issues with incomplete data at the start of history.
// if (i == 0 && rates_total < 3) continue; // This might be too restrictive.
// Define object names for this bar to manage them
// Using time ensures uniqueness per bar. Adding symbol and timeframe for robustness.
string obj_time_str = TimeToString(time[i], TIME_DATE | TIME_MINUTES | TIME_SECONDS); // Added seconds for more uniqueness
string bearish_obj_name = StringFormat("SpikeArrow_Bearish_%s_%s_%s", _Symbol, EnumToString((ENUM_TIMEFRAMES)Period()), obj_time_str);
string bullish_obj_name = StringFormat("SpikeArrow_Bullish_%s_%s_%s", _Symbol, EnumToString((ENUM_TIMEFRAMES)Period()), obj_time_str);
// Delete existing arrows for this bar before re-evaluating
// This allows settings changes to reflect immediately and removes arrows if a spike no longer qualifies
ObjectDelete(0, bearish_obj_name);
ObjectDelete(0, bullish_obj_name);
// Get OHLC for the current bar i
double O = open[i];
double H = high[i];
double L = low[i];
double C = close[i];
// Calculate candle components
double body_size = MathAbs(O - C);
double total_range = H - L;
double upper_wick = H - MathMax(O, C);
double lower_wick = MathMin(O, C) - L;
// Avoid division by zero or issues with flat candles (doji, etc.)
if (total_range < _Point * 0.1) // If candle range is very small, skip (e.g. less than 0.1 points)
continue;
bool is_bearish_spike = false;
bool is_bullish_spike = false;
double body_plus_epsilon = body_size + (_Point * 0.01); // Add a very small value related to point size
// --- Bearish Spike Detection (Spike High) ---
// 1. Body is a small part of the total range
// 2. Upper wick is significantly larger than the body
// 3. Lower wick is small compared to the body (or upper wick)
if (body_size / total_range <= InpMaxBodyToTotalRangeRatio &&
upper_wick / body_plus_epsilon >= InpMinWickToBodyRatio &&
lower_wick / body_plus_epsilon <= InpMaxOppositeWickToBodyRatio &&
upper_wick > lower_wick) // Ensure upper wick is dominant
{
is_bearish_spike = true;
}
// --- Bullish Spike Detection (Spike Low) ---
// 1. Body is a small part of the total range
// 2. Lower wick is significantly larger than the body
// 3. Upper wick is small compared to the body (or lower wick)
if (body_size / total_range <= InpMaxBodyToTotalRangeRatio &&
lower_wick / body_plus_epsilon >= InpMinWickToBodyRatio &&
upper_wick / body_plus_epsilon <= InpMaxOppositeWickToBodyRatio &&
lower_wick > upper_wick) // Ensure lower wick is dominant
{
is_bullish_spike = true;
}
// --- Drawing ---
double arrow_offset_actual = InpArrowOffsetPoints * _Point;
if (is_bearish_spike)
{
if (ObjectCreate(0, bearish_obj_name, OBJ_ARROW, 0, time[i], H + arrow_offset_actual))
{
ObjectSetInteger(0, bearish_obj_name, OBJPROP_ARROWCODE, WINGDINGS_ARROW_DOWN); // Corrected
ObjectSetInteger(0, bearish_obj_name, OBJPROP_COLOR, InpBearishSpikeColor);
ObjectSetInteger(0, bearish_obj_name, OBJPROP_WIDTH, 1);
ObjectSetInteger(0, bearish_obj_name, OBJPROP_STYLE, STYLE_SOLID);
ObjectSetString(0, bearish_obj_name, OBJPROP_TOOLTIP, "Bearish Spike");
}
// else { PrintFormat("Failed to create bearish spike arrow for bar at %s. Error: %d", TimeToString(time[i]), GetLastError()); }
}
if (is_bullish_spike)
{
if (ObjectCreate(0, bullish_obj_name, OBJ_ARROW, 0, time[i], L - arrow_offset_actual))
{
ObjectSetInteger(0, bullish_obj_name, OBJPROP_ARROWCODE, WINGDINGS_ARROW_UP); // Corrected
ObjectSetInteger(0, bullish_obj_name, OBJPROP_COLOR, InpBullishSpikeColor);
ObjectSetInteger(0, bullish_obj_name, OBJPROP_WIDTH, 1);
ObjectSetInteger(0, bullish_obj_name, OBJPROP_STYLE, STYLE_SOLID);
ObjectSetString(0, bullish_obj_name, OBJPROP_TOOLTIP, "Bullish Spike");
}
// else { PrintFormat("Failed to create bullish spike arrow for bar at %s. Error: %d", TimeToString(time[i]), GetLastError()); }
}
}
//--- Return value of prev_calculated for next call
return (rates_total);
}
//+------------------------------------------------------------------+
-233
View File
@@ -1,233 +0,0 @@
//+------------------------------------------------------------------+
//| Consolidation Detector EA |
//| Detects consolidations using multiple methods |
//+------------------------------------------------------------------+
#property copyright "Your Name"
#property link "https://www.example.com"
#property version "1.01"
// Input Parameters
input group "Consolidation Detection Settings"
input bool UsePriceRange = true; // Enable Price Range Analysis
input int PriceRangeBars = 20; // Bars for Price Range
input double PriceRangeThreshold = 0.5; // Price Range Threshold (% of ATR)
input bool UseBollingerSqueeze = true; // Enable Bollinger Bands Squeeze
input int BollingerPeriod = 20; // Bollinger Bands Period
input double BollingerThreshold = 0.02; // Bollinger Bandwidth Threshold
input bool UseATRCrossover = true; // Enable ATR Crossover
input int FastATRPeriod = 5; // Fast ATR Period
input int SlowATRPeriod = 20; // Slow ATR Period
input bool UseVolumeAnalysis = true; // Enable Volume Analysis
input int VolumeBars = 20; // Bars for Volume Analysis
input double VolumeThreshold = 0.7; // Volume Threshold (% of Avg Volume)
input group "Visualization and Alerts"
input bool DrawZones = true; // Draw Consolidation Zones
input bool EnableAlerts = true; // Enable Alerts for Consolidation
input color ZoneColor = clrPurple; // Color for Consolidation Zones
// Global Variables
datetime lastBarTime; // Track last processed bar time
int bollingerHandle; // Handle for Bollinger Bands
int fastATRHandle; // Handle for Fast ATR
int slowATRHandle; // Handle for Slow ATR
int priceATRHandle; // Handle for Price Range ATR
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Initialize Bollinger Bands handle
bollingerHandle = iBands(_Symbol, PERIOD_CURRENT, BollingerPeriod, 0, 2.0, PRICE_CLOSE);
if (bollingerHandle == INVALID_HANDLE)
{
Print("Failed to initialize Bollinger Bands");
return(INIT_FAILED);
}
// Initialize ATR handles
priceATRHandle = iATR(_Symbol, PERIOD_CURRENT, PriceRangeBars);
fastATRHandle = iATR(_Symbol, PERIOD_CURRENT, FastATRPeriod);
slowATRHandle = iATR(_Symbol, PERIOD_CURRENT, SlowATRPeriod);
if (priceATRHandle == INVALID_HANDLE || fastATRHandle == INVALID_HANDLE || slowATRHandle == INVALID_HANDLE)
{
Print("Failed to initialize ATR indicators");
return(INIT_FAILED);
}
// Set last bar time to avoid processing same bar multiple times
lastBarTime = TimeCurrent();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Release indicator handles
IndicatorRelease(bollingerHandle);
IndicatorRelease(priceATRHandle);
IndicatorRelease(fastATRHandle);
IndicatorRelease(slowATRHandle);
// Clean up chart objects
ObjectsDeleteAll(0, "Consolidation_");
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Process only on new bar
datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
if (currentBarTime == lastBarTime)
return;
lastBarTime = currentBarTime;
bool isConsolidation = false;
string consolidationMethods = "";
// Get high and low for visualization
double high = iHigh(_Symbol, PERIOD_CURRENT, 1);
double low = iLow(_Symbol, PERIOD_CURRENT, 1);
datetime startTime = iTime(_Symbol, PERIOD_CURRENT, PriceRangeBars);
datetime endTime = currentBarTime;
// Check Price Range Consolidation
// if (UsePriceRange && IsPriceRangeConsolidation(PriceRangeBars, PriceRangeThreshold))
// {
// isConsolidation = true;
// consolidationMethods += "Price Range, ";
// }
// // Check Bollinger Bands Squeeze
// if (UseBollingerSqueeze && IsBollingerSqueeze(BollingerPeriod, BollingerThreshold))
// {
// isConsolidation = true;
// consolidationMethods += "Bollinger Squeeze, ";
// }
// // Check ATR Crossover
// if (UseATRCrossover && IsATRConsolidation(FastATRPeriod, SlowATRPeriod))
// {
// isConsolidation = true;
// consolidationMethods += "ATR Crossover, ";
// }
// // Check Volume Analysis
// if (UseVolumeAnalysis && IsVolumeConsolidation(VolumeBars, VolumeThreshold))
// {
// isConsolidation = true;
// consolidationMethods += "Volume Analysis, ";
// }
// Output and Visualization
if (isConsolidation)
{
string message = "Consolidation detected by: " + consolidationMethods;
Print(message);
if (EnableAlerts)
Alert(message);
if (DrawZones)
DrawConsolidationZone(high, low, startTime, endTime);
}
else
{
Print("No consolidation detected");
}
}
//+------------------------------------------------------------------+
//| Price Range Consolidation Detection |
//+------------------------------------------------------------------+
bool IsPriceRangeConsolidation(int bars, double threshold)
{
double rangeSum = 0.0;
double high[], low[], atr[];
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(atr, true);
CopyHigh(_Symbol, PERIOD_CURRENT, 1, bars, high);
CopyLow(_Symbol, PERIOD_CURRENT, 1, bars, low);
CopyBuffer(priceATRHandle, 0, 1, 1, atr); // Get ATR for shift 1
for (int i = 0; i < bars; i++)
rangeSum += high[i] - low[i];
double avgRange = rangeSum / bars;
return (avgRange < threshold * atr[0]);
}
//+------------------------------------------------------------------+
//| Bollinger Bands Squeeze Detection |
//+------------------------------------------------------------------+
bool IsBollingerSqueeze(int period, double threshold)
{
double upper[], lower[], middle[];
ArraySetAsSeries(upper, true);
ArraySetAsSeries(lower, true);
ArraySetAsSeries(middle, true);
CopyBuffer(bollingerHandle, 0, 0, 3, middle); // Middle band
CopyBuffer(bollingerHandle, 1, 0, 3, upper); // Upper band
CopyBuffer(bollingerHandle, 2, 0, 3, lower); // Lower band
double bandwidth = (upper[1] - lower[1]) / middle[1];
return (bandwidth < threshold);
}
//+------------------------------------------------------------------+
//| ATR Crossover Consolidation Detection |
//+------------------------------------------------------------------+
bool IsATRConsolidation(int fastPeriod, int slowPeriod)
{
double fastATR[], slowATR[];
ArraySetAsSeries(fastATR, true);
ArraySetAsSeries(slowATR, true);
CopyBuffer(fastATRHandle, 0, 1, 1, fastATR); // Fast ATR for shift 1
CopyBuffer(slowATRHandle, 0, 1, 1, slowATR); // Slow ATR for shift 1
return (fastATR[0] < slowATR[0]);
}
//+------------------------------------------------------------------+
//| Volume Analysis Consolidation Detection |
//+------------------------------------------------------------------+
bool IsVolumeConsolidation(int bars, double threshold)
{
double volume[];
ArraySetAsSeries(volume, true);
CopyBuffer(iVolume(_Symbol, PERIOD_CURRENT, 0), 0, 0, bars, volume);
double avgVolume = 0.0;
for (int i = 0; i < bars; i++)
avgVolume += volume[i];
avgVolume /= bars;
double currentVolume = volume[1];
return (currentVolume < threshold * avgVolume);
}
//+------------------------------------------------------------------+
//| Draw Consolidation Zone on Chart |
//+------------------------------------------------------------------+
void DrawConsolidationZone(double high, double low, datetime start, datetime end)
{
string objName = "Consolidation_" + TimeToString(start);
ObjectCreate(0, objName, OBJ_RECTANGLE, 0, start, high, end, low);
ObjectSetInteger(0, objName, OBJPROP_COLOR, ZoneColor);
ObjectSetInteger(0, objName, OBJPROP_STYLE, STYLE_SOLID);
ObjectSetInteger(0, objName, OBJPROP_FILL, true);
ObjectSetInteger(0, objName, OBJPROP_BACK, true);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-647
View File
@@ -1,647 +0,0 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XCond2 MQL5 Script
// -------------------------------------------------
// Name: XCAEA
// Description: an Exper Advisor which used Panels
//
// 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 XCAEA Cond2 Script"
#property strict
//
// Imports ...
//
// Classes ...
#include "../../Classes/x-saherelm.x-poi.class.mq5"
//
// Libraries ...
#include "../../Libraries/x-saherelm.common.lib.mq5"
#include "../../Libraries/x-saherelm.x-poi.lib.mq5"
//
// Helpers ...
#include "../Helpers/xcaea.helper.mq5"
//
// Definitions ...
//
// Holds Drawn Objects ...
CArrayObj mObjects;
//
// Required Objects ...
int mLoopback = 10;
XCAEAInputs mInputs;
XBarTracker mBarTracker;
XCAEAConditions mConditions;
XCXCAEAHelper *helper = NULL;
//
// Event Handlers ...
/**
* Initialize Script ...
*
* @return ( int )
*/
int OnInit()
{
//
// Initialize Helper ...
bool isInited = InitHelper();
if (!isInited)
{
return INIT_FAILED;
}
//
return INIT_SUCCEEDED;
}
/**
* De Initialize Script ...
*
* @param reason: Argument 1
*/
void OnDeinit(const int reason)
{
//
mInputs.Clean();
mConditions.Clean();
//
ZeroMemory(helper);
}
/**
* Handle Tick Event ...
*/
void OnTick()
{
//
bool has = false;
//
// Run on New Bar ...
bool isNewBar = mBarTracker.IsNewBar();
if (!isNewBar)
{
return;
}
//
// Setting Bar Index ...
int barIndex = 0;
//
// Retrieve Conditions ...
has = helper.GetConditions(
mConditions,
barIndex,
mLoopback //
);
if (!has)
{
return;
}
//
// Handling Logic ...
HandleLogic();
}
//
// Custom Functions ...
/**
* Initialize Helper ...
*
* @return ( bool )
*/
bool InitHelper()
{
//
bool result = false;
//
mInputs.Default();
//
// Configure Inputs ...
//
// Oscilators ...
mInputs.showAC = false;
mInputs.showAD = false;
mInputs.showADX = false;
mInputs.showATR = false;
mInputs.showCCI = false;
mInputs.showRSI = false;
mInputs.showMFI = false;
mInputs.showRVI = false;
mInputs.showMACD = false;
mInputs.showMomentum = false;
mInputs.showStochastic = false;
//
// XCT ...
mInputs.ctInputs.showCandleTime = true;
//
// XCC ...
mInputs.ccInputs.showCandles = true;
//
// X3MA ...
mInputs.x3maInputs.showFast = false;
mInputs.x3maInputs.showSlow = false;
mInputs.x3maInputs.showMedium = false;
//
// XOSC ...
// mInputs.oscsInputs;
//
// XCA ...
mInputs.caInputs.showKI = false;
mInputs.caInputs.showSar = false;
mInputs.caInputs.showTKI = false;
mInputs.caInputs.showMAH = true;
mInputs.caInputs.showMAL = true;
mInputs.caInputs.showMAC = true;
mInputs.caInputs.showVidya = false;
mInputs.caInputs.showTrend = false;
mInputs.caInputs.showSwings = false;
mInputs.caInputs.showLongCycle = false;
mInputs.caInputs.showHindCycle = false;
mInputs.caInputs.showShortCycle = false;
mInputs.caInputs.showFiboLevel1 = true;
mInputs.caInputs.showFiboLevel2 = false;
mInputs.caInputs.showFiboLevel3 = true;
mInputs.caInputs.showMediumCycle = false;
mInputs.caInputs.showPeaksAndVales = false;
mInputs.caInputs.showPeakAndValeGolden = false;
mInputs.caInputs.showSupportAndResistance = true;
//
// Initialize Helper ...
helper = new XCXCAEAHelper();
result = helper.Init(
_Symbol,
_Period,
mInputs //
);
if (!result)
{
return result;
}
//
// Initialize Bar Tracker ...
result = mBarTracker.Init(
_Symbol,
_Period //
);
if (!result)
{
return result;
}
//
return result;
}
/**
* Handle Logic of Script ...
*/
void HandleLogic()
{
//
// Defining Requirements ...
//
int zIDX = 0;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
//
bool has = false;
//
// Reading Required Values ...
//
// PEAK ...
double zPeak = mConditions.peakBuffer[zIDX];
double cPeak = mConditions.peakBuffer[cIDX];
double pPeak = mConditions.peakBuffer[pIDX];
double p2Peak = mConditions.peakBuffer[p2IDX];
//
// VALE ...
double zVale = mConditions.valeBuffer[zIDX];
double cVale = mConditions.valeBuffer[cIDX];
double pVale = mConditions.valeBuffer[pIDX];
double p2Vale = mConditions.valeBuffer[p2IDX];
//
// SAR ...
double zSar = mConditions.sarBuffer[zIDX];
double cSar = mConditions.sarBuffer[cIDX];
double pSar = mConditions.sarBuffer[pIDX];
double p2Sar = mConditions.sarBuffer[p2IDX];
//
// KI ...
double zKI = mConditions.kiBuffer[zIDX];
double cKI = mConditions.kiBuffer[cIDX];
double pKI = mConditions.kiBuffer[pIDX];
double p2KI = mConditions.kiBuffer[p2IDX];
//
// KI State ...
double zKIState = mConditions.kiStateBuffer[zIDX];
double cKIState = mConditions.kiStateBuffer[cIDX];
double pKIState = mConditions.kiStateBuffer[pIDX];
double p2KIState = mConditions.kiStateBuffer[p2IDX];
//
// TKI ...
double zTKI = mConditions.tkiBuffer[zIDX];
double cTKI = mConditions.tkiBuffer[cIDX];
double pTKI = mConditions.tkiBuffer[pIDX];
double p2TKI = mConditions.tkiBuffer[p2IDX];
//
// TKI State ...
double zTKIState = mConditions.tkiStateBuffer[zIDX];
double cTKIState = mConditions.tkiStateBuffer[cIDX];
double pTKIState = mConditions.tkiStateBuffer[pIDX];
double p2TKIState = mConditions.tkiStateBuffer[p2IDX];
//
// MAH ...
double zMAH = mConditions.mahBuffer[zIDX];
double cMAH = mConditions.mahBuffer[cIDX];
double pMAH = mConditions.mahBuffer[pIDX];
double p2MAH = mConditions.mahBuffer[p2IDX];
//
// MAL ...
double zMAL = mConditions.malBuffer[zIDX];
double cMAL = mConditions.malBuffer[cIDX];
double pMAL = mConditions.malBuffer[pIDX];
double p2MAL = mConditions.malBuffer[p2IDX];
//
// MAC ...
double zMAC = mConditions.macBuffer[zIDX];
double cMAC = mConditions.macBuffer[cIDX];
double pMAC = mConditions.macBuffer[pIDX];
double p2MAC = mConditions.macBuffer[p2IDX];
//
// TREND ...
double zTrend = mConditions.trendBuffer[zIDX];
double cTrend = mConditions.trendBuffer[cIDX];
double pTrend = mConditions.trendBuffer[pIDX];
double p2Trend = mConditions.trendBuffer[p2IDX];
//
// TREND State ...
double zTrendState = mConditions.trendStateBuffer[zIDX];
double cTrendState = mConditions.trendStateBuffer[cIDX];
double pTrendState = mConditions.trendStateBuffer[pIDX];
double p2TrendState = mConditions.trendStateBuffer[p2IDX];
//
// RESISTANCE ...
double zResistance = mConditions.resistanceBuffer[zIDX];
double cResistance = mConditions.resistanceBuffer[cIDX];
double pResistance = mConditions.resistanceBuffer[pIDX];
double p2Resistance = mConditions.resistanceBuffer[p2IDX];
//
// SUPPORT ...
double zSupport = mConditions.supportBuffer[zIDX];
double cSupport = mConditions.supportBuffer[cIDX];
double pSupport = mConditions.supportBuffer[pIDX];
double p2Support = mConditions.supportBuffer[p2IDX];
//
// VIDYA ...
double zVIDYA = mConditions.vidyaBuffer[zIDX];
double cVIDYA = mConditions.vidyaBuffer[cIDX];
double pVIDYA = mConditions.vidyaBuffer[pIDX];
double p2VIDYA = mConditions.vidyaBuffer[p2IDX];
//
// VIDYA State ...
double zVIDYAState = mConditions.vidyaStateBuffer[zIDX];
double cVIDYAState = mConditions.vidyaStateBuffer[cIDX];
double pVIDYAState = mConditions.vidyaStateBuffer[pIDX];
double p2VIDYAState = mConditions.vidyaStateBuffer[p2IDX];
//
// SWING Low ...
double zSwingLow = mConditions.swingLowBuffer[zIDX];
double cSwingLow = mConditions.swingLowBuffer[cIDX];
double pSwingLow = mConditions.swingLowBuffer[pIDX];
double p2SwingLow = mConditions.swingLowBuffer[p2IDX];
//
// SWING High ...
double zSwingHigh = mConditions.swingHighBuffer[zIDX];
double cSwingHigh = mConditions.swingHighBuffer[cIDX];
double pSwingHigh = mConditions.swingHighBuffer[pIDX];
double p2SwingHigh = mConditions.swingHighBuffer[p2IDX];
//
// FIBO Level 1 ...
double zFiboLevel1 = mConditions.fiboLevel1Buffer[zIDX];
double cFiboLevel1 = mConditions.fiboLevel1Buffer[cIDX];
double pFiboLevel1 = mConditions.fiboLevel1Buffer[pIDX];
double p2FiboLevel1 = mConditions.fiboLevel1Buffer[p2IDX];
//
// FIBO Level 2 ...
double zFiboLevel2 = mConditions.fiboLevel2Buffer[zIDX];
double cFiboLevel2 = mConditions.fiboLevel2Buffer[cIDX];
double pFiboLevel2 = mConditions.fiboLevel2Buffer[pIDX];
double p2FiboLevel2 = mConditions.fiboLevel2Buffer[p2IDX];
//
// FIBO Level 3 ...
double zFiboLevel3 = mConditions.fiboLevel3Buffer[zIDX];
double cFiboLevel3 = mConditions.fiboLevel3Buffer[cIDX];
double pFiboLevel3 = mConditions.fiboLevel3Buffer[pIDX];
double p2FiboLevel3 = mConditions.fiboLevel3Buffer[p2IDX];
//
// X3MA ...
//
// FAST ...
//
double z3MAFast = mConditions.fastBuffer[zIDX];
double c3MAFast = mConditions.fastBuffer[cIDX];
double p3MAFast = mConditions.fastBuffer[pIDX];
double p23MAFast = mConditions.fastBuffer[p2IDX];
//
double z3MAFastState = mConditions.fastStateBuffer[zIDX];
double c3MAFastState = mConditions.fastStateBuffer[cIDX];
double p3MAFastState = mConditions.fastStateBuffer[pIDX];
double p23MAFastState = mConditions.fastStateBuffer[p2IDX];
//
// MEDIUM ...
//
double z3MAMedium = mConditions.mediumBuffer[zIDX];
double c3MAMedium = mConditions.mediumBuffer[cIDX];
double p3MAMedium = mConditions.mediumBuffer[pIDX];
double p23MAMedium = mConditions.mediumBuffer[p2IDX];
//
double z3MAMediumState = mConditions.mediumStateBuffer[zIDX];
double c3MAMediumState = mConditions.mediumStateBuffer[cIDX];
double p3MAMediumState = mConditions.mediumStateBuffer[pIDX];
double p23MAMediumState = mConditions.mediumStateBuffer[p2IDX];
//
// SLOW ...
//
double z3MASlow = mConditions.slowBuffer[zIDX];
double c3MASlow = mConditions.slowBuffer[cIDX];
double p3MASlow = mConditions.slowBuffer[pIDX];
double p23MASlow = mConditions.slowBuffer[p2IDX];
//
double z3MASlowState = mConditions.slowStateBuffer[zIDX];
double c3MASlowState = mConditions.slowStateBuffer[cIDX];
double p3MASlowState = mConditions.slowStateBuffer[pIDX];
double p23MASlowState = mConditions.slowStateBuffer[p2IDX];
//
// RSI ...
double zRSI = mConditions.rsiBuffer[zIDX];
double cRSI = mConditions.rsiBuffer[cIDX];
double pRSI = mConditions.rsiBuffer[pIDX];
double p2RSI = mConditions.rsiBuffer[p2IDX];
//
// Reading Bars ...
//
XOHCL zBar;
XOHCL cBar;
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
XOHCL p4Bar;
has = zBar.Init(
_Symbol,
_Period,
zIDX //
);
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;
}
//
// Reading Bars Related Data ...
//
// Score ...
//
double bullishScore = 0;
double bearishScore = 0;
mConditions.GenerateScore(
bullishScore,
bearishScore //
);
//
bool isScoreBullish =
bullishScore > bearishScore;
//
bool isScoreBearish =
bearishScore > bullishScore;
//
// Generating Conditions Summary ...
string summary =
mConditions
.GenerateSummary();
//
// Calculating Range Volumes ...
//
double bullishVolume = 0;
double bearishVolume = 0;
int volumeRangeLoopback = 5;
helper.barAnalyser.CalculateRangeVolume(
cBar,
bullishVolume,
bearishVolume,
volumeRangeLoopback //
);
//
double rangeVolume = bullishVolume = bearishVolume;
double rangeVolumeAvg = rangeVolume / volumeRangeLoopback;
//
// Preparing Complex Conditions ...
//
bool isRSIBullish =
cRSI > pRSI &&
!mConditions.isRSIOB;
//
bool isRSIBearish =
cRSI < pRSI &&
!mConditions.isRSIOS;
//
bool isVolumeBullish = bullishVolume > bearishVolume;
bool isVolumeBearish = bullishVolume < bearishVolume;
bool isVolumeOverLast = cBar.volume > pBar.volume;
bool isVolumeOverAvg = cBar.volume > rangeVolumeAvg;
//
// Cond2 ...
//
bool isCond2Bullish =
//
mConditions.isUnderMal &&
mConditions.isValeIsPivot &&
// mConditions.swingLowBuffer[cIDX] > mConditions.valeBuffer[cIDX] &&
mConditions.swingLowBuffer[cIDX] < mConditions.fiboLevel3Buffer[cIDX]
//
;
//
bool isCond2Bearish =
//
false // &&
//
;
//
bool isCond2 = isCond2Bullish ||
isCond2Bearish;
if (isCond2)
{
//
// Print("Cond2");
// isCond2Bullish = false;
// isCond2Bearish = false;
}
//
// Check Results ...
//
bool isBullish = isCond2Bullish;
bool isBearish = isCond2Bearish;
//
bool result = isBullish ||
isBearish;
if (result)
{
//
datetime time = zBar.time;
//
ENUM_X_DIRECTION iDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
// Handle Works ...
if (isCond2)
{
//
string name = "Cond2_" + ToString(iDir);
//
color clr = isBullish
? clrAqua
: clrMagenta;
//
CChartObjectHLine *iObj;
iObj = new CChartObjectHLine();
has = iObj.Create(
0,
name,
0,
time //
);
if (has)
{
//
// Style Object ...
iObj.Width(1);
iObj.Color(clr);
iObj.Style(STYLE_DOT);
//
// Store Object ...
mObjects.Add(iObj);
}
}
}
}
//
@@ -1,167 +0,0 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: XCXCAEADataCollector ...
// Description: Class for XCAEA Data Collector ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm Class for XCAEA Data Collector"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.base.class.mq5"
//
// Definitions ...
//
// Implementation ...
class XCXCAEADataCollector : public XCBase
{
//
// Public ...
public:
//
// Constructors ...
XCXCAEADataCollector()
{
}
//
// Deconstructor ...
~XCXCAEADataCollector()
{
}
//
// Properties ...
//
string Path()
{
return mPath;
}
//
void Path(string value)
{
//
// Normalizing Collector Path ...
if (IsValid(value))
{
mPath = value;
}
else
{
mPath = "XCXCAEADataCollector";
}
}
//
// Tools ...
//
string GetFilePath(string fileName)
{
//
string result = "";
//
result =
//
mPath + "\\" + fileName + ".x121.log"
//
;
//
return result;
}
//
int GetFileHandlerForWrite(string filePath)
{
//
int result = INVALID_HANDLE;
//
if (!IsValid(filePath))
{
return result;
}
//
result = FileOpen(
filePath,
FILE_READ | FILE_WRITE | FILE_TXT //
);
//
return result;
}
/**
* Save Specified Content into Specified File Name ...
*
* @param fileName: string, file name ...
* @param content: string, content ...
*
* @return ( bool )
*/
bool Save(
string fileName,
string content //
)
{
//
bool result = false;
//
result = IsValid(content);
if (!result)
{
return result;
}
//
//
int mHandler = GetFileHandlerForWrite(fileName);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
FileWrite(mHandler, content);
FileFlush(mHandler);
FileClose(mHandler);
//
return result;
}
//
// Protected ...
protected:
//
// Private ...
private:
//
// Props ...
//
string mPath; // Base Collector Path ...
};
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,961 +0,0 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XCAEA MQL5 Expert Advisor
// -------------------------------------------------
// Name: XCAEA
// Description: an Exper Advisor which used Panels
//
// 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 XCAEA EA"
#property strict
//
// Imports ...
#include "../Classes/x-saherelm.x-alert.class.mq5"
#include "../Classes/x-saherelm.x-trade.class.mq5"
#include "../Classes/x-saherelm.x-volume.class.mq5"
#include "../XCAEA/Classes/xcaea.x-trade.manager.class.mq5"
#include "../XCAEA/Signals/xcaea.signaller.class.mq5"
//
#define ShortName "XCAEAEA"
//
// Inputs ...
//
// Common ...
input group "Common";
input long eaMagicNumber = 78692110; // Magic Number
input int eaSlippage = 10; // Slippgae
input string eaLogSuffix = ""; // Log Suffix
input ENUM_TIMEFRAMES eaAnalysisPeriod = PERIOD_H1; // Analysis Period
//
// Symbols ...
//
// -------------------------------------------------------
// ----------
// eaSymbols:
// ----------
// - if EMPTY use Current Symbol;
// - for Multi Symbol use Comma Separated Symbols:
// EURUSDb,XAUUSDb
//
// ------------------
// eaSymbolSessions:
// ------------------
// - if EMPTY use WHOLE Times;
// - for each Symbol use Comma Separated:
// (XEURS1_02:00_14:00),(XEURS2_19:00_23:00)|
// -------------------------------------------------------
input group "Symbols";
input string eaSymbols = ""; // Symbols Description
input string eaSymbolSessions = ""; // Symbols Sessions
//
// Volume ...
input group "Volume";
input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_EQUITY; // Volume Applying Type
input double eaStaticVoluem = 0.0; // Static Volume
input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume
input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing
input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade
input double eaConstantPercent = 0.5; // Constant Percent of Balance Per Trade
input double eaConstantBalance = 0.0; // Constant Balance for Calculations
//
// Management ...
input group "Management";
input bool eaAllowTrade = true; // Allow Trade on Signals
input bool eaAllowLongs = true; // Allow Long Trades
input bool eaAllowShorts = true; // Allow Short Trades
input ENUM_XCAEA_TRADE_RESTRICTION_PERIOD eaRestrictionsPeriod = XCAEA_TRADE_RESTRICATION_DAILY; // Trade Restrictions Period
input int eaMaxAllowedTPs = 2; // Max Allowed TP(s) per Day
input int eaMaxAllowedSLs = 2; // Max Allowed SL(s) per Day
input int eaMaxAllowedTrades = 3; // Max Allowed Trades per Day
input int eaMaxAllowedPositions = 5; // Max Allowed Same Time Trades
input double eaMaxAllowedSpread = 25; // Max Allowed Spread For Trade
input double eaMaxAllowedDrawdownFactor = 0.3; // Max Allowed DrawDown for Trade
input string eaCloseAllOpenTradesAt = ""; // Close All Open Trades per Day At Specified Time
//
// Alert ...
// Here we Provider All Requirements for
// Configuring Alert Provider ...
input group "Alert";
input bool eaEnableAlerts = true; // Enable Alerts
input bool eaLogAlerts = true; // Log Alerts
input bool eaMailAlerts = false; // Mail Alerts
input bool eaPushAlerts = false; // Push Alerts
input bool eaTerminalAlerts = false; // Terminal Alerts
//
// Time Report ...
input group "Reports";
input bool eaReportNewMonths = false; // Report New Month
input bool eaReportNewWeeks = false; // Report New Weeks
input bool eaReportNewDays = true; // Report New Days
input bool eaReportNewHours = false; // Report New Hours
input bool eaReportTrades = true; // Report Trades
input bool eaReportSignals = true; // Report Signals
input bool eaReportProtector = true; // Report Protector Actions
input bool eaReportAfterTradesBalance = true; // Report Balance after a Trade Finished
//
// Variables, Instances ...
XCAlert *eaAlert;
XCTrade *eaTrade;
XSignal eaSignal;
XCVolume *eaVolume;
XTimeTracker eaTimeTracker;
XCXCAEASignaller *eaSignallers[];
XCXCAEATradeManager *eaTradeManager;
XCAEAStrategyConditions eaConditions;
//
string eaTag = "";
//
// Event Handlers ...
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs and Required Parameters
// for EA to Works fine ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Timer ...
if (!InitTimer())
{
return INIT_FAILED;
}
//
// Initial Requirements ...
InitRequirements();
//
// Initialize Volume Manger ...
if (!InitVolume())
{
return INIT_FAILED;
}
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
//
// DeInitialization ...
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
//
ZeroMemory(eaAlert);
ZeroMemory(eaTrade);
ZeroMemory(eaVolume);
//
eaSignal.Clean();
eaConditions.Clean();
eaTimeTracker.Clean();
//
int count = ArraySize(eaSignallers);
for (int i = 0; i < count; i++)
{
//
eaSignallers[i].DeInit();
ZeroMemory(eaSignallers[i]);
}
Clean(eaSignallers);
//
DestroyTimer();
}
//
// On Tick Handler ...
void OnTick()
{
//
int idx = -1;
int count = 0;
bool has = false;
//
HandleTimeReport();
//
// Handle Position Management / Protections ...
eaTradeManager.Manage();
//
eaSignal.Clean();
eaConditions.Clean();
//
double r2r = 4;
string provider = "XCAEA";
datetime cTime = TimeCurrent();
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
//
bool hasLong = false;
bool hasShort = false;
//
// Checking Signallers ...
has = HasChild(eaSignallers);
if (!has)
{
return;
}
//
int signallersCount = ArraySize(eaSignallers);
for (int is = 0; is < signallersCount; is++)
{
//
// Start Calculations ...
//
// Retrieve Common Data ...
string symbol = eaSignallers[is].GetSymbol();
ENUM_TIMEFRAMES period = eaSignallers[is].GetPeriod();
//
// Required Value For SL/TP Calculations ...
double points = GetPoints(symbol);
double pip = GetPipPrice(symbol);
double pip2 = 2 * pip;
//
// Detect Signal Setups ...
has = eaSignallers[is].DetectSignalSetup(r2r);
if (has)
{
//
count = eaSignallers[is]
.AddConditionsIfNotExists();
//
eaSignallers[is].mConditions.Clean();
}
//
// Check Setuped Conditions Exists ...
count = ArraySize(eaSignallers[is].mConditionsCollection);
has = IsValidSize(count);
if (!has)
{
continue;
}
//
// Loop through Setuped Conditions for
// Validating or Looking up Triggers ...
for (int i = 0; i < count; i++)
{
//
// Check Signal Triggered or not ...
has = eaSignallers[is]
.DetectSignalTrigger(eaSignallers[is]
.mConditionsCollection[i]);
//
// If Triggered ...
if (has)
{
//
idx = i;
eaConditions = eaSignallers[is].mConditionsCollection[i];
break;
}
//
// Check Condition Validation ...
has = eaSignallers[is].mConditionsCollection[i].IsValid() &&
eaSignallers[is].mConditionsCollection[i].IsSetuped();
if (!has)
{
idx = i;
break;
}
}
//
// Remove Setuped Condition if provided IDX ...
has = IsValidIndex(idx);
if (has)
{
//
ArrayRemove(
eaSignallers[is].mConditionsCollection,
idx,
1 //
);
}
//
// Check EA Conditions is Valid or not ...
has = eaConditions.IsSetuped() &&
eaConditions.CanTrigger();
if (!has)
{
//
eaSignal.Clean();
eaConditions.Clean();
//
continue;
}
//
// Setting Time to Conditions ...
eaConditions.time = cTime;
has = ToPositionType(
type,
eaConditions.type //
);
if (!has)
{
//
eaSignal.Clean();
eaConditions.Clean();
//
continue;
}
//
// Checking Trigger Direction ...
hasLong = eaConditions.HasBullishSignal();
hasShort = eaConditions.HasBearishSignal();
has = hasLong ||
hasShort;
if (!has)
{
//
eaSignal.Clean();
eaConditions.Clean();
//
continue;
}
//
// Preparing Signal ...
eaSignal.mode = mode;
eaSignal.type = type;
eaSignal.entry = GetEntry(
eaConditions.symbol,
eaConditions.dir //
);
eaSignal.provider = provider;
eaSignal.sl = eaConditions.sl;
eaSignal.tp = eaConditions.tp;
eaSignal.volume = X_MIN_VOLUME;
eaSignal.time = eaConditions.time;
eaSignal.symbol = eaConditions.symbol;
eaSignal.period = eaConditions.period;
//
// Handling Targets ...
ApplyTargetsOnSignal(
eaConditions.dir,
eaConditions.targets,
eaSignal //
);
//
// Validate Signal ...
has = eaSignal.IsValid();
if (!has)
{
//
eaSignal.Clean();
eaConditions.Clean();
//
continue;
}
//
// Handle Volume Management ...
double iVolume = eaVolume.CalculateVolume(eaSignal);
if (iVolume > X_MIN_VOLUME &&
iVolume != eaSignal.volume)
{
eaSignal.volume = iVolume;
}
//
// Execute Signal ...
has = eaTradeManager.Execute(
eaSignal,
eaConditions //
);
//
eaSignal.Clean();
eaConditions.Clean();
}
}
//
// Handle On Trade Event ...
void OnTrade()
{
eaTrade.HandleOnTrade();
}
//
// On Timer ...
void OnTimer()
{
}
//
// Chart Event Handler ...
void OnChartEvent(
const int id,
const long &lparam,
const double &dparam,
const string &sparam //
)
{
}
//
// Event Listeners ...
/**
* Handle StopLoss Triggered Positions ...
*
* @param deal: XDeal instance ...
*/
void OnStopLossTriggered(const XDeal &deal)
{
eaTradeManager.HandleSL(deal);
}
/**
* Handle Take Profit Triggered Positions ...
*
* @param deal: XDeal instance ...
*/
void OnTakeProfitTriggered(const XDeal &deal)
{
eaTradeManager.HandleTP(deal);
}
/**
* Handle Force Close a Position ...
*
* @param ticket: ULONG ...
* @param position: XPosition instance ...
* @param comment: string ...
*/
void OnPositionForceClosed(
const ulong ticket,
const XPosition &position,
const string comment //
)
{
eaTradeManager.HandleForceClose(position);
}
/**
* Handle Position Partially Closed Event ...
*
* @param ticket: ULONG ...
* @param profit: double ...
* @param comment: string ...
*/
void OnPositionPartiallyClosed(
const ulong ticket,
const double profit,
const string comment //
)
{
eaTradeManager.HandlePartiallyClosed(
ticket,
profit,
comment //
);
}
/**
* Handle Deals Changes ...
*
* @param count: Integer, Number of Changes ...
*/
void OnDealsChanged(int count)
{
}
/**
* Handle Orders Changes ...
*
* @param count: Integer, Number of Changes ...
*/
void OnOrdersChanged(int count)
{
}
/**
* Handle Positions Changes ...
*
* @param count: Integer, Number of Changes ...
*/
void OnPositionsChanged(int count)
{
}
//
// Custom Functions ...
/**
* Validate all Inputs of Expert Adviser ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
string errMessage = "";
//
bool isCommonValid = (
//
eaSlippage > 0 &&
eaMagicNumber > 0
//
);
if (!isCommonValid)
{
//
errMessage += "common configurations error;" + "\n";
}
//
result =
//
// Common ...
isCommonValid &&
//
// Otere ...
true
//
;
//
if (!result)
{
//
// Since here Logger not Initiallized, we Use Raw Print Command ...
Print(ShortName + " Errors: \n", errMessage);
}
//
return result;
}
/**
* Initialize Timer ...
*
* @return ( bool )
*/
bool InitTimer()
{
//
bool result = false;
//
// TODO: Initialize Timer if necessary ...
// result = EventSetTimer(1);
// result = EventSetMillisecondTimer(100);
result = true;
//
return result;
}
/**
* Destroy Timer ...
*/
void DestroyTimer()
{
//
// TODO: Use This ...
// EventKillTimer();
}
/**
* Initial Volume Manager Class Based on Given Configuration ...
*
* @return ( bool )
*/
bool InitVolume()
{
//
bool result = false;
//
eaVolume = new XCVolume();
//
result = eaVolume.Init(
eaVolumeSelect,
eaStaticVoluem,
eaDynamicVolumeStepBalance,
eaDynamicVolumeStepVolume,
eaConstantRiskBalance,
eaConstantPercent,
eaConstantBalance //
);
//
return result;
}
/**
* Initial Requirements of EA ...
*/
void InitRequirements()
{
//
// Preparing Tags ...
eaTag =
(IsValid(eaLogSuffix)
? eaLogSuffix + "_"
: "") +
ShortName;
//
// EA Alert ...
eaAlert = new XCAlert(
eaTag,
eaEnableAlerts,
eaLogAlerts,
eaTerminalAlerts,
eaMailAlerts,
eaPushAlerts //
);
//
// EA Trade ...
eaTrade = new XCTrade(
eaSlippage,
eaMagicNumber,
eaMaxAllowedSpread,
eaMaxAllowedPositions,
eaMaxAllowedDrawdownFactor //
);
eaTrade.AddOnStopLossEventHandler(OnStopLossTriggered);
eaTrade.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
eaTrade.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
eaTrade.AddOnPartialClosePositionEventHandler(OnPositionPartiallyClosed);
//
// EA Trae Manager ...
eaTradeManager = new XCXCAEATradeManager(
eaTrade //
);
eaTradeManager.SaveTrades(true);
eaTradeManager.SetAlertEnableAlerts(eaEnableAlerts);
eaTradeManager.SetAlertPrefix(eaTag);
eaTradeManager.SetAlertLogAlerts(eaLogAlerts);
eaTradeManager.SetAlertMailAlerts(eaMailAlerts);
eaTradeManager.SetAlertPushAlerts(eaPushAlerts);
eaTradeManager.SetAlertTerminalAlerts(eaTerminalAlerts);
//
// Setting Trade Reports ...
eaTradeManager
.SetTradeReports(
eaReportTrades,
eaReportSignals,
eaReportProtector,
eaReportAfterTradesBalance //
);
//
// Setting Trade Permissions ...
eaTradeManager
.SetTradePermissions(
eaAllowTrade,
eaAllowLongs,
eaAllowShorts //
);
//
// Setting Trade Restrictions ...
eaTradeManager
.SetTradeRestrictions(
eaRestrictionsPeriod,
eaMaxAllowedTPs,
eaMaxAllowedSLs,
eaMaxAllowedTrades //
);
//
InitSymbolSessions();
//
}
/**
* Initial Symbols and Active Sessions of EA ...
*/
void InitSymbolSessions()
{
//
string symbols[];
string sessions[];
string iSymbol = NULL;
XCXCAEASignaller *iSignaller;
//
// Parse Symbols ...
int symbolsCount = 0;
bool isMultiSymbol = IsValid(eaSymbols);
if (isMultiSymbol)
{
//
symbolsCount = SplitContent(
symbols,
eaSymbols //
);
isMultiSymbol = IsValidSize(symbolsCount);
}
if (!isMultiSymbol)
{
//
Add(
_Symbol,
symbols //
);
//
symbolsCount = 1;
}
//
// Parse Sessions ...
int sessionsCount = 0;
bool hasSession = IsValid(eaSymbolSessions);
if (hasSession)
{
//
// Extract Per Symbol Sessions ...
sessionsCount = SplitContent(
sessions,
eaSymbolSessions,
"|" //
);
}
//
// Setting Up Symbols ...
bool has = false;
//
for (int i = 0; i < symbolsCount; i++)
{
//
iSymbol = symbols[i];
//
// EA Signaller ...
iSignaller = new XCXCAEASignaller(
iSymbol,
_Period,
eaAnalysisPeriod // Analysing Period ...
);
//
Add(
iSignaller,
eaSignallers //
);
//
ZeroMemory(iSignaller);
}
//
// Setting Up Sessions ...
if (hasSession)
{
//
for (int i = 0; i < symbolsCount; i++)
{
//
iSymbol = symbols[i];
//
if (i < sessionsCount)
{
//
// Extract Per Symbol Sessions ...
string iSymbolSessionsStr[];
int iSymbolSessionsCount = SplitContent(
iSymbolSessionsStr,
sessions[i],
"," //
);
//
has = IsValidSize(iSymbolSessionsCount);
if (has)
{
//
// Loop through Symbols Sessions ...
for (int j = 0; j < iSymbolSessionsCount; j++)
{
//
string iSessionDescriptorStr = ExtractString(iSymbolSessionsStr[j]);
has = IsValid(iSessionDescriptorStr);
if (has)
{
//
// Extract Session Descriptor Data ...
string parts[];
int partsCount = SplitContent(
parts,
iSessionDescriptorStr,
"_" //
);
has = IsValidSize(partsCount) && partsCount == 3;
if (has)
{
//
string iName = parts[0];
string iStart = parts[1];
string iEnd = parts[2];
has = IsValid(iName) &&
IsValid(iStart) &&
IsValid(iEnd);
if (has)
{
//
eaTradeManager
.SetTradeSession(
iSymbol,
iStart,
iEnd,
iName //
);
}
}
//
Clean(parts);
}
}
}
//
Clean(iSymbolSessionsStr);
}
}
}
//
Clean(symbols);
Clean(sessions);
ZeroMemory(iSignaller);
}
/**
* Handling Time Reporting ...
*/
void HandleTimeReport()
{
//
// Monthly Report ....
if (eaReportNewMonths &&
eaTimeTracker.IsNewMonth())
{
//
string msg = "New Month ...";
//
eaAlert.SendAlert(msg);
}
//
// Weekly Report ....
if (eaReportNewWeeks &&
eaTimeTracker.IsNewWeek())
{
//
string msg = "New Week ...";
//
eaAlert.SendAlert(msg);
}
//
// Daily Report ....
if (eaReportNewDays &&
eaTimeTracker.IsNewDay())
{
//
string msg = "New Day ...";
//
eaAlert.SendAlert(msg);
}
//
// Hourly Report ....
if (eaReportNewHours &&
eaTimeTracker.IsNewHour())
{
//
string msg = "New Hour ...";
//
eaAlert.SendAlert(msg);
}
}
//
-942
View File
@@ -1,942 +0,0 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XCATB MQL5 Expert Advisor
// -------------------------------------------------
// Name: XCAEA
// Description: an Exper Advisor which used XCATB
//
// 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 "EA based on X121 XCATB indicator"
#property strict
//
// Include Common Library ...
#include "../Classes/x-saherelm.x-alert.class.mq5"
#include "../Classes/x-saherelm.x-trade.class.mq5"
#include "../Classes/x-saherelm.x-volume.class.mq5"
#include "../Helpers/x-saherelm.x121.xcatb.helper.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
#include "../Libraries/x-saherelm.x121.xcatb.lib.mq5"
#include "../XCAEA/Classes/xcaea.x-trade.manager.class.mq5"
//
#define ShortName "XCATB_EA"
//
// Inputs ...
//
// Common ...
input group "Common";
input long eaMagicNumber = 78692110; // Magic Number
input int eaSlippage = 10; // Slippgae
input string eaLogSuffix = ""; // Log Suffix
//
// Detector ...
input group "Detector";
//
// Validating ...
input group "Validations";
input bool eaForceHasSwing = false; // Force Blocks to Have Swing
input bool eaForceObBarType = false; // Force Block Has Reversal Bar
input bool eaForceOBFVGBarType = false; // Force FVG Has Same Bars
input bool eaForceHasFLiquidity = false; // Force Blocks to Have Following Liquidity
input bool eaForceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity
input bool eaValidateGapSequence = false; // Validate Block's Gap Sequence
input bool eaValidateBlockEdgeBreakout = false; // Validate Block's Edge Breakout
//
// Filtering ...
input group "Filters";
input bool eaFilterBasedOnPV = false; // Filter Based on Peak and Vale
input bool eaFilterBasedOnSar = false; // Filter Based on Sar
input bool eaFilterBasedOnRSI = false; // Filter Based on RSI
input bool eaFilterBasedOnADX = false; // Filter Based on ADX
input bool eaFilterBasedOnATR = false; // Filter Based on ATR
input bool eaFilterBasedOnTrend = false; // Filter Based on Trend
input bool eaFilterBasedOnDelta = false; // Filter Based on Delta
input bool eaFilterBasedOnVolume = false; // Filter Based on Volume
input bool eaFilterBasedOnSignalBar = false; // Filter Based on Signal Bar
input bool eaFilterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar
//
// Signal ...
input group "Signal";
input int eaSignalR2R = 3; // Risk Reward Ratio
input double eaSLAtrMultiplier = 0.5; // ATR Multiplier for SL
//
// Volume ...
input group "Volume";
input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_EQUITY; // Volume Applying Type
input double eaStaticVoluem = 0.0; // Static Volume
input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume
input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing
input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade
input double eaConstantPercent = 0.5; // Constant Percent of Balance Per Trade
input double eaConstantBalance = 0.0; // Constant Balance for Calculations
//
// Management ...
input group "Management";
input bool eaAllowTrade = true; // Allow Trade on Signals
input bool eaAllowLongs = true; // Allow Long Trades
input bool eaAllowShorts = true; // Allow Short Trades
input ENUM_XCAEA_TRADE_RESTRICTION_PERIOD eaRestrictionsPeriod = XCAEA_TRADE_RESTRICATION_NONE; // Trade Restrictions Period
input int eaMaxAllowedTPs = 0; // Max Allowed TP(s) per Day
input int eaMaxAllowedSLs = 0; // Max Allowed SL(s) per Day
input int eaMaxAllowedTrades = 0; // Max Allowed Trades per Day
input int eaMaxAllowedPositions = 5; // Max Allowed Same Time Trades
input double eaMaxAllowedSpread = 25; // Max Allowed Spread For Trade
input double eaMaxAllowedDrawdownFactor = 0.3; // Max Allowed DrawDown for Trade
input string eaCloseAllOpenTradesAt = ""; // Close All Open Trades per Day At Specified Time
//
// Alert ...
// Here we Provider All Requirements for
// Configuring Alert Provider ...
input group "Alert";
input bool eaEnableAlerts = true; // Enable Alerts
input bool eaLogAlerts = true; // Log Alerts
input bool eaMailAlerts = false; // Mail Alerts
input bool eaPushAlerts = true; // Push Alerts
input bool eaTerminalAlerts = true; // Terminal Alerts
//
// Time Report ...
input group "Reports";
input bool eaReportNewMonths = false; // Report New Month
input bool eaReportNewWeeks = false; // Report New Weeks
input bool eaReportNewDays = true; // Report New Days
input bool eaReportNewHours = false; // Report New Hours
input bool eaReportTrades = true; // Report Trades
input bool eaReportSignals = true; // Report Signals
input bool eaReportProtector = true; // Report Protector Actions
input bool eaReportAfterTradesBalance = true; // Report Balance after a Trade Finished
//
// Variables ...
//
XCAlert *eaAlert;
XCTrade *eaTrade;
XSignal eaSignal;
XCVolume *eaVolume;
X121XCatbInputs eaInputs;
XCX121XCatbHelper *eaHelper;
XBarTracker eaBarTraker;
XTimeTracker eaTimeTracker;
XCXCAEATradeManager *eaTradeManager;
XCAEAStrategyConditions eaConditions;
//
XTriggerBlock eaTB;
//
CArrayObj *eaObjects;
//
string eaTag = "";
//
// Event Handlers ...
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs and Required Parameters
// for EA to Works fine ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initial Requirements ...
InitRequirements();
//
// Initialize Volume Manger ...
if (!InitVolume())
{
return INIT_FAILED;
}
//
return (INIT_SUCCEEDED);
}
//
// DeInitialization ...
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
// eaObjects.Clear();
//
delete eaHelper;
ZeroMemory(eaHelper);
//
delete eaAlert;
ZeroMemory(eaAlert);
//
delete eaTrade;
ZeroMemory(eaTrade);
//
delete eaVolume;
ZeroMemory(eaVolume);
//
eaSignal.Clean();
eaBarTraker.Clean();
eaConditions.Clean();
eaTimeTracker.Clean();
//
DestroyTimer();
}
//
// On Tick Handler ...
void OnTick()
{
//
HandleTimeReport();
//
// Handle Position Management / Protections ...
// eaTradeManager.Manage();
// //
// eaSignal.Clean();
// eaConditions.Clean();
//
// Check Bar Processing ...
if (!eaBarTraker.CanProcessBar())
{
return;
}
//
bool has = false;
//
// Retrieve Bars ...
// XOHCL zBar;
// XOHCL cBar;
// has = zBar.Init(
// _Symbol,
// _Period,
// 0 //
// );
// has =
// has &&
// zBar.GetPreviousBar(cBar);
// if (!has)
// {
// //
// zBar.Clean();
// cBar.Clean();
// //
// return;
// }
//
// double bid = GetBid(zBar.symbol);
//
// XTriggerBlock iTB;
// has = GetNewestX121TriggerBlock(
// _Symbol,
// _Period,
// iTB //
// );
// if (has)
// {
// //
// // Check Newest TB is Newer Than Exists TB ...
// bool canPass =
// !eaTB.IsValid()
// ? true
// : iTB.ToIndex() < eaTB.ToIndex();
// if (canPass)
// {
// //
// eaTB = iTB;
// eaSignal = iTB.signal;
// //
// // Prepare eaConditions if Reuqired ...
// }
// }
//
// has = eaSignal.IsValid();
// if (has)
// {
// //
// // Here we ensure which has a New Signal and must
// // prepare and Execute it ...
// Print("new Signal Detected ...");
// }
//
// eaTB.Clean();
// zBar.Clean();
// cBar.Clean();
// eaSignal.Clean();
// eaConditions.Clean();
}
//
// Handle On Trade Event ...
void OnTrade()
{
eaTrade.HandleOnTrade();
}
//
// On Timer ...
void OnTimer()
{
}
//
// Chart Event Handler ...
void OnChartEvent(
const int id,
const long &lparam,
const double &dparam,
const string &sparam //
)
{
}
//
// Event Listeners ...
/**
* Handle StopLoss Triggered Positions ...
*
* @param deal: XDeal instance ...
*/
void OnStopLossTriggered(const XDeal &deal)
{
eaTradeManager.HandleSL(deal);
}
/**
* Handle Take Profit Triggered Positions ...
*
* @param deal: XDeal instance ...
*/
void OnTakeProfitTriggered(const XDeal &deal)
{
eaTradeManager.HandleTP(deal);
}
/**
* Handle Force Close a Position ...
*
* @param ticket: ULONG ...
* @param position: XPosition instance ...
* @param comment: string ...
*/
void OnPositionForceClosed(
const ulong ticket,
const XPosition &position,
const string comment //
)
{
eaTradeManager.HandleForceClose(position);
}
/**
* Handle Position Partially Closed Event ...
*
* @param ticket: ULONG ...
* @param profit: double ...
* @param comment: string ...
*/
void OnPositionPartiallyClosed(
const ulong ticket,
const double profit,
const string comment //
)
{
eaTradeManager.HandlePartiallyClosed(
ticket,
profit,
comment //
);
}
/**
* Handle Deals Changes ...
*
* @param count: Integer, Number of Changes ...
*/
void OnDealsChanged(int count)
{
}
/**
* Handle Orders Changes ...
*
* @param count: Integer, Number of Changes ...
*/
void OnOrdersChanged(int count)
{
}
/**
* Handle Positions Changes ...
*
* @param count: Integer, Number of Changes ...
*/
void OnPositionsChanged(int count)
{
}
//
// Custom Functions ...
/**
* Validate all Inputs of Expert Adviser ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
string errMessage = "";
//
bool isCommonValid = (
//
eaSlippage > 0 &&
eaMagicNumber > 0
//
);
if (!isCommonValid)
{
//
errMessage += "common configurations error;" + "\n";
}
//
result =
//
// Common ...
isCommonValid &&
//
// Otere ...
true
//
;
//
if (!result)
{
//
// Since here Logger not Initiallized, we Use Raw Print Command ...
Print(ShortName + " Errors: \n", errMessage);
}
//
return result;
}
/**
* Initialize Timer ...
*
* @return ( bool )
*/
bool InitTimer()
{
//
bool result = false;
//
// TODO: Initialize Timer if necessary ...
// result = EventSetTimer(1);
// result = EventSetMillisecondTimer(100);
result = true;
//
return result;
}
/**
* Destroy Timer ...
*/
void DestroyTimer()
{
//
// TODO: Use This ...
// EventKillTimer();
}
/**
* Initial Volume Manager Class Based on Given Configuration ...
*
* @return ( bool )
*/
bool InitVolume()
{
//
bool result = false;
//
eaVolume = new XCVolume();
//
result = eaVolume.Init(
eaVolumeSelect,
eaStaticVoluem,
eaDynamicVolumeStepBalance,
eaDynamicVolumeStepVolume,
eaConstantRiskBalance,
eaConstantPercent,
eaConstantBalance //
);
//
return result;
}
/**
* Initial Requirements of EA ...
*/
void InitRequirements()
{
//
// Initial Bar Tracker ...
eaBarTraker.Init(
_Symbol,
_Period //
);
//
// Preparing Tags ...
eaTag =
(IsValid(eaLogSuffix)
? eaLogSuffix + "_"
: "") +
ShortName;
//
eaAlert = new XCAlert();
eaAlert.SetPrefix(eaLogSuffix);
eaAlert.SetLogAlerts(eaLogAlerts);
eaAlert.SetMailAlerts(eaMailAlerts);
eaAlert.SetPushAlerts(eaPushAlerts);
eaAlert.SetEnableAlerts(eaEnableAlerts);
eaAlert.SetTerminalAlerts(eaTerminalAlerts);
//
// Objects ...
eaObjects = new CArrayObj();
//
// Configure XCA ...
eaInputs.Default();
//
// Hide all Visible Buffers ...
eaInputs.Hide();
//
// we Can make Show all requirements here ...
//
eaInputs.showATRBand = true;
// //
// // Signal ...
// eaInputs.signalR2R = eaSignalR2R;
// eaInputs.slAtrMultiplier = eaSLAtrMultiplier;
// //
// // Set Validators ...
// eaInputs.forceHasSwing = eaForceHasSwing;
// eaInputs.forceObBarType = eaForceObBarType;
// eaInputs.forceOBFVGBarType = eaForceOBFVGBarType;
// eaInputs.forceHasFLiquidity = eaForceHasFLiquidity;
// eaInputs.forceHasRLiquidity = eaForceHasRLiquidity;
// eaInputs.validateGapSequence = eaValidateGapSequence;
// eaInputs.validateBlockEdgeBreakout = eaValidateBlockEdgeBreakout;
// //
// // Set Filters ...
// eaInputs.filterBasedOnPV = eaFilterBasedOnPV;
// eaInputs.filterBasedOnSar = eaFilterBasedOnSar;
// eaInputs.filterBasedOnRSI = eaFilterBasedOnRSI;
// eaInputs.filterBasedOnADX = eaFilterBasedOnADX;
// eaInputs.filterBasedOnATR = eaFilterBasedOnATR;
// eaInputs.filterBasedOnTrend = eaFilterBasedOnTrend;
// eaInputs.filterBasedOnDelta = eaFilterBasedOnDelta;
// eaInputs.filterBasedOnVolume = eaFilterBasedOnVolume;
// eaInputs.filterBasedOnSignalBar = eaFilterBasedOnSignalBar;
// eaInputs.filterBasedOnHKSignalBar = eaFilterBasedOnHKSignalBar;
// //
// // Alerts ...
// // eaInputs.alertPrefix = eaTag;
// // eaInputs.logAlerts = eaLogAlerts;
// // eaInputs.pushAlerts = eaMailAlerts;
// // eaInputs.mailAlerts = eaPushAlerts;
// // eaInputs.terminalAlerts = eaTerminalAlerts;
//
// eaHelper = new XCX121XCatbHelper();
// bool isInited = eaHelper.Init(
// _Symbol,
// _Period,
// eaInputs //
// );
// //
// // EA Trade ...
// eaTrade = new XCTrade(
// eaSlippage,
// eaMagicNumber,
// eaMaxAllowedSpread,
// eaMaxAllowedPositions,
// eaMaxAllowedDrawdownFactor //
// );
// eaTrade.AddOnStopLossEventHandler(OnStopLossTriggered);
// eaTrade.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
// eaTrade.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
// eaTrade.AddOnPartialClosePositionEventHandler(OnPositionPartiallyClosed);
// //
// // EA Trae Manager ...
// eaTradeManager = new XCXCAEATradeManager(
// eaTrade //
// );
// eaTradeManager.SaveTrades(true);
// eaTradeManager.SetAlertEnableAlerts(eaEnableAlerts);
// eaTradeManager.SetAlertPrefix(eaTag);
// eaTradeManager.SetAlertLogAlerts(eaLogAlerts);
// eaTradeManager.SetAlertMailAlerts(eaMailAlerts);
// eaTradeManager.SetAlertPushAlerts(eaPushAlerts);
// eaTradeManager.SetAlertTerminalAlerts(eaTerminalAlerts);
// //
// // Setting Trade Reports ...
// eaTradeManager
// .SetTradeReports(
// eaReportTrades,
// eaReportSignals,
// eaReportProtector,
// eaReportAfterTradesBalance //
// );
// //
// // Setting Trade Permissions ...
// eaTradeManager
// .SetTradePermissions(
// eaAllowTrade,
// eaAllowLongs,
// eaAllowShorts //
// );
// //
// // Setting Trade Restrictions ...
// eaTradeManager
// .SetTradeRestrictions(
// eaRestrictionsPeriod,
// eaMaxAllowedTPs,
// eaMaxAllowedSLs,
// eaMaxAllowedTrades //
// );
}
/**
* Handling Time Reporting ...
*/
void HandleTimeReport()
{
//
if (eaAlert == NULL)
{
return;
}
//
// Monthly Report ....
if (eaReportNewMonths &&
eaTimeTracker.IsNewMonth())
{
//
string msg = "New Month ...";
//
eaAlert.SendAlert(msg);
}
//
// Weekly Report ....
if (eaReportNewWeeks &&
eaTimeTracker.IsNewWeek())
{
//
string msg = "New Week ...";
//
eaAlert.SendAlert(msg);
}
//
// Daily Report ....
if (eaReportNewDays &&
eaTimeTracker.IsNewDay())
{
//
string msg = "New Day ...";
//
eaAlert.SendAlert(msg);
}
//
// Hourly Report ....
if (eaReportNewHours &&
eaTimeTracker.IsNewHour())
{
//
string msg = "New Hour ...";
//
eaAlert.SendAlert(msg);
}
}
//
// Apply Signal Targets ...
// void ApplySignalTargets(XSignal &signal)
// {
// //
// bool has = signal.IsValid();
// if (!has)
// {
// return;
// }
// //
// // Clean Signal Targets ...
// Clean(signal.targets);
// //
// // Calculate Requirements ...
// double r2r = 1;
// // maxAllowedR2R > 0
// // ? maxAllowedR2R
// // : 1;
// double risk = signal.GetRisk();
// double reward = risk * r2r;
// //
// double isLong = IsLong(signal.type);
// //
// // Handling Signal TP ...
// signal.tp =
// isLong
// ? signal.entry + reward
// : signal.entry - reward;
// //
// // Try to Apply Money Management ...
// //
// if (r2r <= 1)
// {
// return;
// }
// //
// // XTarget iTarget;
// // //
// // // Partial Close 0.5 of Position on Reward 1 ...
// // reward = risk * 1;
// // iTarget.target =
// // isLong
// // ? signal.entry + reward
// // : signal.entry - reward;
// // iTarget.volumeMultiplier = 0.5;
// // //
// // AddRef(iTarget, signal.targets);
// // iTarget.Clean();
// // //
// // if (r2r <= 2)
// // {
// // return;
// // }
// //
// // Making Loop ...
// // for (int i = 2; i < ((int)r2r - 1); i++)
// // {
// // //
// // iTarget.Clean();
// // //
// // reward = i * risk;
// // iTarget.target =
// // isLong
// // ? signal.entry + reward
// // : signal.entry - reward;
// // iTarget.volumeMultiplier = 1 / (r2r - 2);
// // //
// // AddRef(iTarget, signal.targets);
// // }
// //
// // Sort Targets ...
// ENUM_X_DIRECTION sortingDir =
// isLong
// ? X_DIRECTION_BULLISH
// : X_DIRECTION_BEARISH;
// ApplySortOnTargets(
// sortingDir,
// signal.targets //
// );
// }
/////////////////////////////////////////////////////
//
static XTriggerBlock mX121TriggerBlocks[];
//
int HasX121TriggerBlocks()
{
return HasChild(mX121TriggerBlocks);
}
//
int CountX121TriggerBlocks()
{
return ArraySize(mX121TriggerBlocks);
}
//
void CleanX121TriggerBlocks(int maxAllowed = 0)
{
//
if (maxAllowed <= 0)
{
Clean(mX121TriggerBlocks);
}
else if (maxAllowed > 0)
{
//
CleanupArray(
mX121TriggerBlocks,
maxAllowed //
);
}
}
//
bool GetNewestX121TriggerBlock(
string forSymbol,
ENUM_TIMEFRAMES forPeriod,
XTriggerBlock &tb //
)
{
//
bool result = false;
//
tb.Clean();
//
result =
IsValid(forSymbol) &&
IsValid(forPeriod) &&
HasX121TriggerBlocks();
if (!result)
{
return result;
}
//
// Loop Through Trigger Blocks to Find Filtered Newest ...
int count = CountX121TriggerBlocks();
for (int i = 0; i < count; i++)
{
//
bool canSet = !tb.IsValid()
? true
: tb.ToIndex() < mX121TriggerBlocks[i].ToIndex();
if (canSet)
{
tb = mX121TriggerBlocks[i];
}
}
//
result = tb.IsValid();
if (!result)
{
tb.Clean();
}
//
return result;
}
///////////////////////////////////////////////////
//
// Add Trigger Block to Collection
// and Cleanup Unuseds ...
AddRef(
tb,
mX121TriggerBlocks //
);
CleanX121TriggerBlocks(20);
-218
View File
@@ -1,218 +0,0 @@
//
// Detect Block Based Trigger ...
XBoxZone ob;
XOHCL swing;
XOHCL breaker;
XOHCL outSide;
ENUM_X_DIRECTION passedDir;
bool isPassed = helper.IsBlockBasedTriggerBar(
ob,
swing,
breaker,
outSide,
passedDir,
1, // Bar Index ...
50, // Loopback ...
3 // Swing Length ...
);
if (isPassed)
{
//
// Draw Block Based Trigger ...
//
// Draw OB ...
XCBoxObject *obObject;
has = helper.poiDrawer.DrawBox(
ob,
obObject //
);
if (has)
{
//
obObject.BoxWidth(2);
obObject.BoxStyle(STYLE_SOLID);
//
color obColor =
ob.IsBullish()
? clrAqua
: clrMagenta;
obObject.BoxColor(obColor);
//
mObjects.Add(obObject);
//
ZeroMemory(obObject);
}
//
double breakPrice =
ob.IsBullish()
? swing.high
: swing.low;
//
// Draw Swing and Breake ...
CChartObjectTrend *tObj;
tObj = new CChartObjectTrend();
string tName = "Swing_For_" + ToString(ob.dir) + "_" + ToString(breakPrice);
has = tObj.Create(
0,
tName,
0,
swing.time,
breakPrice,
breaker.time,
breakPrice //
);
if (has)
{
//
tObj.Width(2);
tObj.Style(STYLE_SOLID);
//
color tColor = ob.IsBullish()
? clrRed
: clrLime;
tObj.Color(tColor);
//
mObjects.Add(tObj);
//
ZeroMemory(tObj);
}
//
Print("Passed Bar ...");
}
ob.Clean();
swing.Clean();
breaker.Clean();
outSide.Clean();
//////////////////////////////////////////////////////////
/**
* Check Specified Bar is Swing or not ...
*
* @param bar: XOHCL instance reference, Specified Swing Bar ...
* @param forDir: ENUM_X_DIRECTION member, Specified Direction of Swing ...
* @param barIndex: int, Specified Bar Index to Check ...
* @param loopback: int, Specified Loopback for BothSide Checking ...
*
* @return ( bool )
*/
bool IsSwingSide(
XOHCL &bar,
ENUM_X_DIRECTION forDir,
int loopback = 7 //
)
{
//
bool result = false;
//
result = bar.IsValid() &&
HasDirection(forDir);
if (!result)
{
return result;
}
//
bool isSwingLow = IsBullish(forDir);
bool isSwingHigh = IsBearish(forDir);
//
string symbol = bar.symbol;
ENUM_TIMEFRAMES period = bar.period;
//
int totalBars = iBars(
symbol,
period //
);
int barIndex = bar.Index();
loopback = NormalizeInt(loopback, 3);
result =
barIndex - loopback > 0 &&
barIndex + 1 + loopback <= totalBars;
if (!result)
{
return result;
}
//
for (int i = 0; i < loopback; i++)
{
//
XOHCL iPBar;
XOHCL iNBar;
result = iPBar.Init(
symbol,
period,
barIndex + i //
);
result =
result &&
iNBar.Init(
symbol,
period,
barIndex - i //
);
if (!result)
{
//
iPBar.Clean();
iNBar.Clean();
//
break;
}
//
isSwingLow =
isSwingLow &&
bar.low < iPBar.low &&
bar.low < iNBar.low;
//
isSwingHigh =
isSwingHigh &&
bar.high > iPBar.high &&
bar.high > iNBar.high;
//
result = isSwingLow ||
isSwingHigh;
if (!result)
{
//
iPBar.Clean();
iNBar.Clean();
//
break;
}
//
iPBar.Clean();
iNBar.Clean();
}
//
if (!result)
{
bar.Clean();
}
//
return result;
}
-317
View File
@@ -1,317 +0,0 @@
//+------------------------------------------------------------------+
//| RSI_Div.mq5 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.metaquotes.net/"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 8
#property indicator_plots 2
#property indicator_label1 "RSI"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_label2 "Signal"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrOrange
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//--- Input parameters
input int InpRSIPeriod = 14; // RSI Period
input ENUM_APPLIED_PRICE InpRSIPrice = PRICE_CLOSE; // RSI Applied Price
input int InpLeftBars = 5; // Left bars to check
input int InpRightBars = 5; // Right bars to check
input double InpMinDivergence = 5.0; // Minimum divergence in %
input bool ShowRegularBullish = true; // Show Regular Bullish
input bool ShowRegularBearish = true; // Show Regular Bearish
input bool ShowHiddenBullish = true; // Show Hidden Bullish
input bool ShowHiddenBearish = true; // Show Hidden Bearish
//--- Indicator buffers
double RSIBuffer[];
double SignalBuffer[];
double HighBuffer[];
double LowBuffer[];
double BullishDivBuffer[];
double BearishDivBuffer[];
double HiddenBullishDivBuffer[];
double HiddenBearishDivBuffer[];
//--- Handles
int rsiHandle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Indicator buffers mapping
SetIndexBuffer(0, RSIBuffer, INDICATOR_DATA);
SetIndexBuffer(1, SignalBuffer, INDICATOR_DATA);
SetIndexBuffer(2, HighBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(3, LowBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(4, BullishDivBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(5, BearishDivBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(6, HiddenBullishDivBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(7, HiddenBearishDivBuffer, INDICATOR_CALCULATIONS);
//--- Set accuracy
IndicatorSetInteger(INDICATOR_DIGITS, 2);
//--- Set first bar from what index will be drawn
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, InpRSIPeriod);
//--- Create RSI handle
rsiHandle = iRSI(NULL, 0, InpRSIPeriod, InpRSIPrice);
if (rsiHandle == INVALID_HANDLE)
{
Print("Failed to create RSI handle");
return (INIT_FAILED);
}
//--- Set buffer names
string short_name = "RSI Divergence(" + string(InpRSIPeriod) + ")";
IndicatorSetString(INDICATOR_SHORTNAME, short_name);
//--- Set empty value
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
//--- Initialize arrays as series
ArraySetAsSeries(RSIBuffer, true);
ArraySetAsSeries(SignalBuffer, true);
ArraySetAsSeries(HighBuffer, true);
ArraySetAsSeries(LowBuffer, true);
ArraySetAsSeries(BullishDivBuffer, true);
ArraySetAsSeries(BearishDivBuffer, true);
ArraySetAsSeries(HiddenBullishDivBuffer, true);
ArraySetAsSeries(HiddenBearishDivBuffer, true);
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[])
{
//--- Check for data sufficiency
if (rates_total < InpRSIPeriod + InpLeftBars + InpRightBars)
return (0);
//--- Get RSI values
if (CopyBuffer(rsiHandle, 0, 0, rates_total, RSIBuffer) <= 0)
{
Print("Failed to copy RSI buffer");
return (0);
}
//--- Calculate signal line (just for visualization)
for (int i = 0; i < rates_total; i++)
SignalBuffer[i] = 30 + (70 - 30) / 2;
//--- Find divergences
FindDivergences(rates_total, prev_calculated, high, low, close, time);
return (rates_total);
}
//+------------------------------------------------------------------+
//| Find divergences between price and RSI |
//+------------------------------------------------------------------+
void FindDivergences(const int rates_total,
const int prev_calculated,
const double &high[],
const double &low[],
const double &close[],
const datetime &time[])
{
int start_bar = MathMax(InpRSIPeriod + InpLeftBars + InpRightBars, prev_calculated);
for (int i = start_bar; i < rates_total && !IsStopped(); i++)
{
//--- Reset buffers
BullishDivBuffer[i] = 0;
BearishDivBuffer[i] = 0;
HiddenBullishDivBuffer[i] = 0;
HiddenBearishDivBuffer[i] = 0;
//--- Check array boundaries
if (i - InpLeftBars < 0 || i + InpRightBars >= rates_total)
continue;
//--- Find highest high and lowest low in left bars
int highest_high_bar = Highest(high, i - InpLeftBars, InpLeftBars + InpRightBars + 1);
int lowest_low_bar = Lowest(low, i - InpLeftBars, InpLeftBars + InpRightBars + 1);
//--- Check for regular bullish divergence
if (ShowRegularBullish && lowest_low_bar >= 0)
{
int rsi_lowest_bar = LowestRSI(i - InpLeftBars, InpLeftBars + InpRightBars + 1);
if (rsi_lowest_bar >= 0 && rsi_lowest_bar != lowest_low_bar &&
low[i - lowest_low_bar] < low[i] &&
RSIBuffer[i - rsi_lowest_bar] > RSIBuffer[i] &&
MathAbs(RSIBuffer[i - rsi_lowest_bar] - RSIBuffer[i]) >= InpMinDivergence)
{
BullishDivBuffer[i] = RSIBuffer[i] - 5;
if (i < ArraySize(time) && i < ArraySize(low))
ObjectCreate(0, "BullDiv" + IntegerToString(i), OBJ_ARROW_UP, 0, time[i], low[i] - 50 * _Point);
}
}
//--- Check for regular bearish divergence
if (ShowRegularBearish && highest_high_bar >= 0)
{
int rsi_highest_bar = HighestRSI(i - InpLeftBars, InpLeftBars + InpRightBars + 1);
if (rsi_highest_bar >= 0 && rsi_highest_bar != highest_high_bar &&
high[i - highest_high_bar] > high[i] &&
RSIBuffer[i - rsi_highest_bar] < RSIBuffer[i] &&
MathAbs(RSIBuffer[i - rsi_highest_bar] - RSIBuffer[i]) >= InpMinDivergence)
{
BearishDivBuffer[i] = RSIBuffer[i] + 5;
if (i < ArraySize(time) && i < ArraySize(high))
ObjectCreate(0, "BearDiv" + IntegerToString(i), OBJ_ARROW_DOWN, 0, time[i], high[i] + 50 * _Point);
}
}
//--- Check for hidden bullish divergence
if (ShowHiddenBullish && lowest_low_bar >= 0)
{
int rsi_lowest_bar = LowestRSI(i - InpLeftBars, InpLeftBars + InpRightBars + 1);
if (rsi_lowest_bar >= 0 && rsi_lowest_bar != lowest_low_bar &&
low[i - lowest_low_bar] > low[i] &&
RSIBuffer[i - rsi_lowest_bar] < RSIBuffer[i] &&
MathAbs(RSIBuffer[i - rsi_lowest_bar] - RSIBuffer[i]) >= InpMinDivergence)
{
HiddenBullishDivBuffer[i] = RSIBuffer[i] - 8;
if (i < ArraySize(time) && i < ArraySize(low))
ObjectCreate(0, "HidBullDiv" + IntegerToString(i), OBJ_ARROW_UP, 0, time[i], low[i] - 80 * _Point);
}
}
//--- Check for hidden bearish divergence
if (ShowHiddenBearish && highest_high_bar >= 0)
{
int rsi_highest_bar = HighestRSI(i - InpLeftBars, InpLeftBars + InpRightBars + 1);
if (rsi_highest_bar >= 0 && rsi_highest_bar != highest_high_bar &&
high[i - highest_high_bar] < high[i] &&
RSIBuffer[i - rsi_highest_bar] > RSIBuffer[i] &&
MathAbs(RSIBuffer[i - rsi_highest_bar] - RSIBuffer[i]) >= InpMinDivergence)
{
HiddenBearishDivBuffer[i] = RSIBuffer[i] + 8;
if (i < ArraySize(time) && i < ArraySize(high))
ObjectCreate(0, "HidBearDiv" + IntegerToString(i), OBJ_ARROW_DOWN, 0, time[i], high[i] + 80 * _Point);
}
}
}
}
//+------------------------------------------------------------------+
//| Find bar with highest price in range |
//+------------------------------------------------------------------+
int Highest(const double &price[], int start_pos, int count)
{
if (start_pos < 0 || count <= 0 || start_pos + count > ArraySize(price))
return -1;
int highest_pos = start_pos;
double highest_val = price[start_pos];
for (int i = start_pos + 1; i < start_pos + count; i++)
{
if (price[i] > highest_val)
{
highest_val = price[i];
highest_pos = i;
}
}
return highest_pos - start_pos;
}
//+------------------------------------------------------------------+
//| Find bar with lowest price in range |
//+------------------------------------------------------------------+
int Lowest(const double &price[], int start_pos, int count)
{
if (start_pos < 0 || count <= 0 || start_pos + count > ArraySize(price))
return -1;
int lowest_pos = start_pos;
double lowest_val = price[start_pos];
for (int i = start_pos + 1; i < start_pos + count; i++)
{
if (price[i] < lowest_val)
{
lowest_val = price[i];
lowest_pos = i;
}
}
return lowest_pos - start_pos;
}
//+------------------------------------------------------------------+
//| Find bar with highest RSI in range |
//+------------------------------------------------------------------+
int HighestRSI(int start_pos, int count)
{
if (start_pos < 0 || count <= 0 || start_pos + count > ArraySize(RSIBuffer))
return -1;
int highest_pos = start_pos;
double highest_val = RSIBuffer[start_pos];
for (int i = start_pos + 1; i < start_pos + count; i++)
{
if (RSIBuffer[i] > highest_val)
{
highest_val = RSIBuffer[i];
highest_pos = i;
}
}
return highest_pos - start_pos;
}
//+------------------------------------------------------------------+
//| Find bar with lowest RSI in range |
//+------------------------------------------------------------------+
int LowestRSI(int start_pos, int count)
{
if (start_pos < 0 || count <= 0 || start_pos + count > ArraySize(RSIBuffer))
return -1;
int lowest_pos = start_pos;
double lowest_val = RSIBuffer[start_pos];
for (int i = start_pos + 1; i < start_pos + count; i++)
{
if (RSIBuffer[i] < lowest_val)
{
lowest_val = RSIBuffer[i];
lowest_pos = i;
}
}
return lowest_pos - start_pos;
}
-198
View File
@@ -1,198 +0,0 @@
//+------------------------------------------------------------------+
//| RSIDivergence.mq5|
//| Custom RSI Divergence Detection Indicator |
//+------------------------------------------------------------------+
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 0
//--- Input parameters
input int RSI_Period = 14; // RSI Period
input double Deviation = 0.0001; // Minimum price move to consider a swing
input int MaxBarsBack = 300; // Number of bars to analyze
//--- Global handles
double rsiBuffer[];
int rsiHandle;
//--- For divergence detection
struct SwingPoint
{
int index;
double price;
double rsi;
};
SwingPoint priceSwings[];
SwingPoint rsiSwings[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, rsiBuffer, INDICATOR_DATA);
rsiHandle = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE);
if (rsiHandle == INVALID_HANDLE)
{
Print("Could not create RSI handle");
return (INIT_FAILED);
}
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Main 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[])
{
//--- Get RSI values
ArraySetAsSeries(rsiBuffer, true);
CopyBuffer(rsiHandle, 0, 0, MaxBarsBack, rsiBuffer);
//--- Detect swings
DetectSwingPoints(close, priceSwings);
DetectSwingPoints(rsiBuffer, rsiSwings);
//--- Find and draw divergences
FindAndDrawDivergences(time, close);
return (rates_total);
}
//+------------------------------------------------------------------+
//| Detect swing highs/lows |
//+------------------------------------------------------------------+
void DetectSwingPoints(const double &values[], SwingPoint &swings[])
{
ArrayResize(swings, 0); // Clear previous swings
int count = 0;
int size = ArraySize(values);
if (size < 3)
return; // Not enough data
// Pre-allocate a safe amount of space
ArrayResize(swings, size / 2); // Max possible swings ~50% of total bars
for (int i = 2; i < size - 2; i++)
{
// Bounds check
if (i - 1 < 0 || i + 1 >= size)
continue;
// Check for swing high
if (values[i] > values[i - 1] && values[i] > values[i + 1])
{
// Ensure we have space in the swings array
if (count >= ArraySize(swings))
ArrayResize(swings, ArraySize(swings) + 10);
swings[count].index = i;
swings[count].price = values[i];
count++;
}
// Check for swing low
else if (values[i] < values[i - 1] && values[i] < values[i + 1])
{
// Ensure we have space in the swings array
if (count >= ArraySize(swings))
ArrayResize(swings, ArraySize(swings) + 10);
swings[count].index = i;
swings[count].price = values[i];
count++;
}
}
// Final resize to actual number of swings found
ArrayResize(swings, count);
}
//+------------------------------------------------------------------+
//| Find and draw divergence |
//+------------------------------------------------------------------+
void FindAndDrawDivergences(const datetime &time[], const double &close[])
{
static int lastAlertBar = 0;
int limit = MathMin(MaxBarsBack - 2, Bars(_Symbol, _Period));
for (int i = 0; i < ArraySize(priceSwings) - 1; i++)
{
for (int j = 0; j < ArraySize(rsiSwings) - 1; j++)
{
int p1 = priceSwings[i].index;
int p2 = priceSwings[i + 1].index;
int r1 = rsiSwings[j].index;
int r2 = rsiSwings[j + 1].index;
if (MathAbs(p1 - r1) < 3 && MathAbs(p2 - r2) < 3)
{
double price1 = close[p1];
double price2 = close[p2];
double rsi1 = rsiBuffer[r1];
double rsi2 = rsiBuffer[r2];
// Bullish Divergence
if (price2 < price1 && rsi2 > rsi1)
{
string name;
StringConcatenate(name, "BullishDiv", IntegerToString(p2));
DrawArrow(name, time[p2], close[p2], clrLime);
// DrawLine("BullishLineP" + IntegerToString(p2), time[p2], close[p2], time[p1], close[p1], clrLime);
// DrawLine("BullishLineR" + IntegerToString(p2), time[p2], rsi2, time[p1], rsi1, clrLime);
}
// Bearish Divergence
if (price2 > price1 && rsi2 < rsi1)
{
string name;
StringConcatenate(name, "BearishDiv", IntegerToString(p2));
DrawArrow(name, time[p2], close[p2], clrRed);
// DrawLine("BearishLineP" + IntegerToString(p2), time[p2], close[p2], time[p1], close[p1], clrRed);
// DrawLine("BearishLineR" + IntegerToString(p2), time[p2], rsi2, time[p1], rsi1, clrRed);
}
}
}
}
}
//+------------------------------------------------------------------+
//| Draw arrow on chart |
//+------------------------------------------------------------------+
void DrawArrow(string name, datetime time, double price, color col)
{
ObjectCreate(0, name, OBJ_ARROW, 0, time, price);
ObjectSetInteger(0, name, OBJPROP_ARROWCODE, 233); // Up arrow
ObjectSetInteger(0, name, OBJPROP_COLOR, col);
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
}
//+------------------------------------------------------------------+
//| Draw line |
//+------------------------------------------------------------------+
void DrawLine(string name, datetime t1, double p1, datetime t2, double p2, color col)
{
// Delete existing object if any
ObjectDelete(0, name);
// Create trendline (use 1 for OBJ_TRENDLINE if undefined)
ObjectCreate(0, name, 1, 0, t1, p1, t2, p2);
ObjectSetInteger(0, name, OBJPROP_COLOR, col);
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DASHDOT);
ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
}
//
File diff suppressed because it is too large Load Diff
-181
View File
@@ -1,181 +0,0 @@
#property copyright "Your Name"
#property link "https://www.yourwebsite.com"
#property version "1.02"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
//--- Input parameters
input int atr_period = 14; // ATR Period
input double atr_threshold = 0.0005; // ATR Threshold for Consolidation (e.g., 0.0005 for EURUSD, 5.0 for XAUUSD)
input int range_period = 20; // Period to check price range
input double range_multiplier = 2.0; // Price range multiplier (relative to ATR)
input bool enable_alerts = true; // Enable breakout alerts
input bool draw_rectangles = true; // Draw rectangles for consolidation zones
//--- Indicator buffers
double UpperBuffer[];
double LowerBuffer[];
//--- Global variables
int atr_handle = INVALID_HANDLE;
int zone_count = 0; // For unique rectangle names
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Set indicator buffers
SetIndexBuffer(0, UpperBuffer, INDICATOR_DATA);
SetIndexBuffer(1, LowerBuffer, INDICATOR_DATA);
PlotIndexSetString(0, PLOT_LABEL, "Upper Consolidation");
PlotIndexSetString(1, PLOT_LABEL, "Lower Consolidation");
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE);
PlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE_SOLID);
PlotIndexSetInteger(1, PLOT_LINE_STYLE, STYLE_SOLID);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrRed);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, clrBlue);
//--- Create ATR handle
atr_handle = iATR(_Symbol, _Period, atr_period);
if(atr_handle == INVALID_HANDLE)
{
Print("Failed to create ATR handle, error: ", GetLastError());
return(INIT_FAILED);
}
//--- Check available bars
int available_bars = Bars(_Symbol, _Period);
if(available_bars < range_period + atr_period)
{
Print("Insufficient bars: ", available_bars, ", required: ", range_period + atr_period);
return(INIT_FAILED);
}
//--- Log initialization
Print("Indicator initialized. Symbol: ", _Symbol, ", Timeframe: ", Period(),
", ATR Period: ", atr_period, ", Range Period: ", range_period);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(atr_handle != INVALID_HANDLE)
IndicatorRelease(atr_handle);
ObjectsDeleteAll(0, "Consolidation_"); // Remove all rectangles
Print("Indicator deinitialized, reason: ", reason);
}
//+------------------------------------------------------------------+
//| 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[])
{
//--- Ensure enough bars
if(rates_total < range_period + atr_period)
{
Print("Not enough bars: ", rates_total, ", required: ", range_period + atr_period);
return(0);
}
//--- Set arrays as series
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(time, true);
ArraySetAsSeries(UpperBuffer, true);
ArraySetAsSeries(LowerBuffer, true);
//--- Calculate ATR
double atr[];
ArraySetAsSeries(atr, true);
ArrayResize(atr, rates_total);
if(CopyBuffer(atr_handle, 0, 0, rates_total, atr) <= 0)
{
Print("Failed to copy ATR buffer, error: ", GetLastError());
return(0);
}
//--- Initialize buffers for first calculation
if(prev_calculated == 0)
{
ArrayInitialize(UpperBuffer, EMPTY_VALUE);
ArrayInitialize(LowerBuffer, EMPTY_VALUE);
}
//--- Loop through bars
int start = prev_calculated == 0 ? range_period : MathMax(range_period, prev_calculated - 1);
for(int i = start; i < rates_total && !IsStopped(); i++)
{
//--- Calculate range over range_period
int max_idx = ArrayMaximum(high, i - range_period + 1, range_period);
int min_idx = ArrayMinimum(low, i - range_period + 1, range_period);
if(max_idx == -1 || min_idx == -1)
{
Print("Error: Invalid array index at bar ", i);
continue;
}
double max_high = high[max_idx];
double min_low = low[min_idx];
double price_range = max_high - min_low;
//--- Log values for debugging
if(i == rates_total - 1) // Log only for the latest bar
{
Print("Bar ", i, ": ATR = ", DoubleToString(atr[i], _Digits),
", Price Range = ", DoubleToString(price_range, _Digits),
", Threshold = ", DoubleToString(atr_threshold, _Digits),
", Range Limit = ", DoubleToString(atr[i] * range_multiplier, _Digits));
}
//--- Check for consolidation
if(atr[i] < atr_threshold && price_range < atr[i] * range_multiplier)
{
UpperBuffer[i] = max_high;
LowerBuffer[i] = min_low;
//--- Draw rectangle for the consolidation zone
if(draw_rectangles && i >= range_period)
{
string obj_name = "Consolidation_" + IntegerToString(zone_count++) + "_" + TimeToString(time[i]);
ObjectCreate(0, obj_name, OBJ_RECTANGLE, 0, time[i], max_high, time[i - range_period + 1], min_low);
ObjectSetInteger(0, obj_name, OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, obj_name, OBJPROP_STYLE, STYLE_SOLID);
ObjectSetInteger(0, obj_name, OBJPROP_WIDTH, 1);
ObjectSetInteger(0, obj_name, OBJPROP_FILL, false);
ObjectSetInteger(0, obj_name, OBJPROP_BACK, false);
}
//--- Check for breakout (on latest bar only)
if(enable_alerts && i == rates_total - 1)
{
if(close[i] > UpperBuffer[i] && (i == 0 || close[i-1] <= UpperBuffer[i-1]))
Alert("Breakout Up at ", TimeToString(time[i]), ": Price = ", DoubleToString(close[i], _Digits));
if(close[i] < LowerBuffer[i] && (i == 0 || close[i-1] >= LowerBuffer[i-1]))
Alert("Breakout Down at ", TimeToString(time[i]), ": Price = ", DoubleToString(close[i], _Digits));
}
}
else
{
UpperBuffer[i] = EMPTY_VALUE;
LowerBuffer[i] = EMPTY_VALUE;
}
}
return(rates_total);
}
-137
View File
@@ -1,137 +0,0 @@
//+------------------------------------------------------------------+
//| VPattern.mq5 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.metaquotes.net/"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 2
#property indicator_label1 "V Pattern Top"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrGreen
#property indicator_width1 2
#property indicator_label2 "V Pattern Bottom"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrRed
#property indicator_width2 2
//--- Input parameters
input int LookbackPeriod=20; // Bars to analyze for pattern
input double MinDeclinePercent=2.0; // Minimum decline percentage
input double MinRisePercent=2.0; // Minimum rise percentage
input bool ShowAlerts=true; // Show alert messages
input color ArrowUpColor=clrGreen; // Up arrow color
input color ArrowDownColor=clrRed; // Down arrow color
//--- Indicator buffers
double VTopBuffer[];
double VBottomBuffer[];
double TempHighBuffer[];
double TempLowBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0, VTopBuffer, INDICATOR_DATA);
SetIndexBuffer(1, VBottomBuffer, INDICATOR_DATA);
SetIndexBuffer(2, TempHighBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(3, TempLowBuffer, INDICATOR_CALCULATIONS);
//--- setting arrow codes
PlotIndexSetInteger(0, PLOT_ARROW, 233); // Up arrow
PlotIndexSetInteger(1, PLOT_ARROW, 234); // Down arrow
//--- setting arrow colors
PlotIndexSetInteger(0, PLOT_LINE_COLOR, ArrowUpColor);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, ArrowDownColor);
//--- setting buffer values as EMPTY_VALUE
ArrayInitialize(VTopBuffer, EMPTY_VALUE);
ArrayInitialize(VBottomBuffer, EMPTY_VALUE);
//--- name for DataWindow and indicator subwindow label
IndicatorSetString(INDICATOR_SHORTNAME, "V-Pattern Detector ("+string(LookbackPeriod)+")");
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[])
{
//--- check for minimum bars required
if(rates_total < LookbackPeriod)
return(0);
//--- start calculation from bar determined by prev_calculated
int start;
if(prev_calculated == 0)
start = LookbackPeriod;
else
start = prev_calculated - 1;
//--- main calculation loop
for(int i=start; i<rates_total && !IsStopped(); i++)
{
// Reset buffers
VTopBuffer[i] = EMPTY_VALUE;
VBottomBuffer[i] = EMPTY_VALUE;
// Find the lowest low in the lookback period
int lowestBar = iLowest(NULL, 0, MODE_LOW, LookbackPeriod, i-LookbackPeriod+1);
double lowestLow = low[lowestBar];
// Find the highest high before the lowest low
int highBeforeLow = iHighest(NULL, 0, MODE_HIGH, lowestBar-(i-LookbackPeriod+1)+1, i-LookbackPeriod+1);
double highestBefore = high[highBeforeLow];
// Find the highest high after the lowest low
int highAfterLow = iHighest(NULL, 0, MODE_HIGH, i-lowestBar, lowestBar+1);
double highestAfter = high[highAfterLow];
// Calculate percentage moves
double declinePercent = (highestBefore - lowestLow) / highestBefore * 100;
double risePercent = (highestAfter - lowestLow) / lowestLow * 100;
// Check if we have a V pattern
if(declinePercent >= MinDeclinePercent && risePercent >= MinRisePercent)
{
// Check if the low is in the middle third of the lookback period
int lowPosition = lowestBar - (i-LookbackPeriod+1);
if(lowPosition > LookbackPeriod/3 && lowPosition < 2*LookbackPeriod/3)
{
// Mark the pattern on chart
VTopBuffer[highBeforeLow] = high[highBeforeLow];
VBottomBuffer[lowestBar] = low[lowestBar];
VTopBuffer[highAfterLow] = high[highAfterLow];
// Show alert if enabled
if(ShowAlerts && i == rates_total-1)
{
string alertText = StringFormat("V-Pattern detected! Decline: %.2f%%, Rise: %.2f%%",
declinePercent, risePercent);
Alert(alertText);
Comment(alertText);
}
}
}
}
return(rates_total);
}
//+------------------------------------------------------------------+
-770
View File
@@ -1,770 +0,0 @@
// hasTB &&
// tb.IsBullish() &&
//
// isPeakOverLast &&
// isSarBullishStart
// &&
// isTrendBullishStart &&
// isADXBullishStart &&
// &&
// isSBarBullishStart
// &&
// isHKSBarBullishStart
//
//
// hasTB &&
// tb.IsBearish() &&
//
// isValeUnderLast &&
// isSarBearishStart
// &&
// isTrendBearishStart &&
// isADXBearishStart &&
// &&
// isSBarBearishStart
// &&
// isHKSBarBearishStart
//
bool DetectTriggerBlock(
XCPOIDrawer *drawer,
XCX121XCatbHelper *helper,
XCBarAnalyser *barAnalyser,
X121XCatbConditions &conditions,
XTriggerBlock &tb,
int barIndex = 0,
int loopback = 10 //
)
{
//
bool result = false;
//
// Normalize Args ...
tb.Clean();
conditions.Clean();
barIndex = NormalizeInt(barIndex, 0);
loopback = NormalizeInt(loopback, 0);
//
// Validate Args ...
result = helper != NULL;
if (!result)
{
return result;
}
//
// Reading Market Conditions ...
result = helper.GetConditions(
conditions,
barIndex,
loopback //
);
if (!result)
{
//
tb.Clean();
conditions.Clean();
}
//
int zIDX = 0;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
int p3IDX = p2IDX + 1;
int p4IDX = p3IDX + 1;
//
// Checking Conditions ...
//
// Detect Bar Verifications ...
//
ENUM_X_DIRECTION iDir;
//
// Rejected ...
bool isRejected =
barAnalyser
.IsRejected(
conditions.bars[cIDX],
iDir //
);
bool isBullishRejected =
isRejected &&
IsBullish(iDir);
bool isBearishRejected =
isRejected &&
IsBearish(iDir);
//
// Engulfed ...
bool isEngulfed =
barAnalyser
.IsEngulfed(
conditions.bars[cIDX],
iDir //
);
bool isBullishEngulfed =
isEngulfed &&
IsBullish(iDir);
bool isBearishEngulfed =
isEngulfed &&
IsBearish(iDir);
//
// Momentum ...
bool isMomentum =
barAnalyser
.IsMomentum(
conditions.bars[cIDX],
iDir //
);
bool isBullishMomentum =
isMomentum &&
IsBullish(iDir);
bool isBearishMomentum =
isMomentum &&
IsBearish(iDir);
//
bool isBarBullishPressured =
isBullishRejected ||
isBullishEngulfed ||
isBullishMomentum;
//
bool isBarBearishPressured =
isBearishRejected ||
isBearishEngulfed ||
isBearishMomentum;
//
// Detect Indicator Base Start Directional Movement ...
//
// SAR ...
//
bool isSarBullishStart =
//
(
//
// Current SAR is Directional ...
conditions.isSarBullish &&
//
// Previous InDirectional Sar Exists ...
helper.lastSarBearish.IsValid() &&
//
// Current Close is Over previous Sar ...
conditions.bars[cIDX].close > helper.lastSarBearish.after &&
//
// Before Close is not Over previous Sar ...
conditions.bars[pIDX].close <= helper.lastSarBearish.after
//
)
//
;
//
bool isSarBearishStart =
//
(
//
// Current SAR is Directional ...
conditions.isSarBearish &&
//
// Previous InDirectional Sar Exists ...
helper.lastSarBullish.IsValid() &&
//
// Current Close is Under previous ...
conditions.bars[cIDX].close < helper.lastSarBullish.after &&
//
// Before Close is not Under previous ...
conditions.bars[pIDX].close >= helper.lastSarBullish.after
//
)
//
;
//
// TREND ...
//
bool isTrendBullishStart =
//
(
//
// Current Trend is Directional ...
conditions.isTrendBullish &&
//
// Previous InDirectiona; Trend Exists ...
helper.lastTrendBearish.IsValid() &&
//
// Current Close is Over previous ...
conditions.bars[cIDX].close > helper.lastTrendBearish.after &&
//
// Before close is not Over previous ...
conditions.bars[pIDX].close <= helper.lastTrendBearish.after
//
)
//
;
//
bool isTrendBearishStart =
//
(
//
// Current Trend is Directional ...
conditions.isTrendBearish &&
//
// Previous InDirectiona; Trend Exists ...
helper.lastTrendBullish.IsValid() &&
//
// Current Close is Under previous ...
conditions.bars[cIDX].close < helper.lastTrendBullish.after &&
//
// Before close is not Under previous ...
conditions.bars[pIDX].close >= helper.lastTrendBullish.after
//
)
//
;
//
// ADX ...
//
bool isADXBullishStart =
//
(
//
// ADX Value is Switched to Strong ...
conditions.adxBuffer[cIDX] > conditions.adxThreshold &&
conditions.adxBuffer[pIDX] <= conditions.adxThreshold &&
//
// ADX must Up ...
conditions.adxBuffer[cIDX] > conditions.adxBuffer[pIDX] &&
//
// ADX +DI is Bigger than -DI ...
conditions.adxpBuffer[cIDX] > conditions.adxnBuffer[cIDX] &&
//
// ADX +DI is Up ...
conditions.adxpBuffer[cIDX] > conditions.adxpBuffer[pIDX]
//
)
//
;
//
bool isADXBearishStart =
//
(
//
// ADX Value is Switched to Strong ...
conditions.adxBuffer[cIDX] > conditions.adxThreshold &&
conditions.adxBuffer[pIDX] <= conditions.adxThreshold &&
//
// ADX must Up ...
conditions.adxBuffer[cIDX] > conditions.adxBuffer[pIDX] &&
//
// ADX -DI is Bigger than +DI ...
conditions.adxnBuffer[cIDX] > conditions.adxpBuffer[cIDX] &&
//
// ADX -DI is Up ...
conditions.adxnBuffer[cIDX] > conditions.adxnBuffer[pIDX]
//
)
//
;
//
// DELTA ...
//
bool isDeltaBullishStart =
//
// Check State ...
(
//
// Delta is Up ...
conditions.deltaBuffer[cIDX] > conditions.deltaBuffer[pIDX] &&
//
// Delta Signal is Up ...
conditions.deltaSignalBuffer[cIDX] > conditions.deltaSignalBuffer[pIDX] &&
//
// Delta Crossed Over Delta Signal ...
conditions.deltaBuffer[cIDX] > conditions.deltaSignalBuffer[cIDX]
//
)
//
&&
//
// Check Last InDirectional Exists ...
helper.lastDeltaBearish.IsValid() &&
//
// Current Close is Over last ...
conditions.bars[cIDX].close > helper.lastDeltaBearish.after &&
//
// Before Close is not Over last ...
conditions.bars[pIDX].close <= helper.lastDeltaBearish.after
//
;
//
bool isDeltaBearishStart =
//
// Check State ...
(
//
// Delta is Down ...
conditions.deltaBuffer[cIDX] < conditions.deltaBuffer[pIDX] &&
//
// Delta Signal is Down ...
conditions.deltaSignalBuffer[cIDX] < conditions.deltaSignalBuffer[pIDX] &&
//
// Delta Crossed Under Delta Signal ...
conditions.deltaBuffer[cIDX] < conditions.deltaSignalBuffer[cIDX]
//
)
//
&&
//
// Check Last InDirectional Exists ...
helper.lastDeltaBullish.IsValid() &&
//
// Current Close is Under last ...
conditions.bars[cIDX].close < helper.lastDeltaBullish.after &&
//
// Before Close is not Under last ...
conditions.bars[pIDX].close >= helper.lastDeltaBullish.after
//
;
//
// VOLUME ...
//
bool isVolumeBullishStart =
//
(
//
//
// Volume is Up ...
conditions.bullishVolumeBuffer[1] > conditions.bullishVolumeBuffer[2] &&
//
// Volume Signal is Up ...
conditions.bullishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[2] &&
//
// Volume Signals Crossed Over ...
conditions.bullishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[1]
//
)
//
&&
//
// Check Last InDirectional Exists ...
helper.lastVolumeBearish.IsValid() &&
//
// Current Close is Over last ...
conditions.bars[cIDX].close > helper.lastVolumeBearish.after &&
//
// Before Close is not Over last ...
conditions.bars[pIDX].close <= helper.lastVolumeBearish.after
//
;
//
bool isVolumeBearishStart =
//
(
//
//
// Volume is Up ...
conditions.bearishVolumeBuffer[1] > conditions.bearishVolumeBuffer[2] &&
//
// Volume Signal is Up ...
conditions.bearishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[2] &&
//
// Volume Signals Crossed Over ...
conditions.bearishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[1]
//
)
//
&&
//
// Check Last InDirectional Exists ...
helper.lastVolumeBullish.IsValid() &&
//
// Current Close is Over last ...
conditions.bars[cIDX].close < helper.lastVolumeBullish.after &&
//
// Before Close is not Over last ...
conditions.bars[pIDX].close >= helper.lastVolumeBullish.after
//
;
//
// SIGNAL Bar ...
//
bool isSBarBullishStart =
//
(
//
// Check Direction ...
conditions.isSBarBullish &&
//
// Previous InDirectional Exists ...
helper.lastSignalBarBearish.IsValid() &&
//
// Current Signal Bar close over prev ...
conditions.sBarCloseBuffer[cIDX] > helper.lastSignalBarBearish.after &&
//
// Prev Signal Bar not close over prev ...
conditions.sBarCloseBuffer[pIDX] <= helper.lastSignalBarBearish.after
//
)
//
;
//
bool isSBarBearishStart =
//
(
//
// Check Direction ...
conditions.isSBarBearish &&
//
// Previous InDirectional Exists ...
helper.lastSignalBarBullish.IsValid() &&
//
// Current Signal Bar close over prev ...
conditions.sBarCloseBuffer[cIDX] < helper.lastSignalBarBullish.after &&
//
// Prev Signal Bar not close over prev ...
conditions.sBarCloseBuffer[pIDX] >= helper.lastSignalBarBullish.after
//
)
//
;
//
// HKSIGNAL Bar ...
//
bool isHKSBarBullishStart =
//
(
//
// Check Direction ...
conditions.isHKSBarBullish &&
//
// Previous InDirectional Exists ...
helper.lastHKSignalBarBearish.IsValid() &&
//
// Current Signal Bar close over prev ...
conditions.hkSBarCloseBuffer[cIDX] > helper.lastHKSignalBarBearish.after &&
//
// Prev Signal Bar not close over prev ...
conditions.hkSBarCloseBuffer[pIDX] <= helper.lastHKSignalBarBearish.after
//
)
//
;
//
bool isHKSBarBearishStart =
//
(
//
// Check Direction ...
conditions.isHKSBarBearish &&
//
// Previous InDirectional Exists ...
helper.lastHKSignalBarBullish.IsValid() &&
//
// Current Signal Bar close over prev ...
conditions.hkSBarCloseBuffer[cIDX] < helper.lastHKSignalBarBullish.after &&
//
// Prev Signal Bar not close over prev ...
conditions.hkSBarCloseBuffer[pIDX] >= helper.lastHKSignalBarBullish.after
//
)
//
;
//
// Check for Vale and Peak ...
//
bool isPeakOverLast =
//
(conditions.peakBuffer[cIDX] > conditions.peakBuffer[pIDX] &&
conditions.peakBuffer[pIDX] <= conditions.peakBuffer[p2IDX] &&
conditions.bars[cIDX].close > conditions.peakBuffer[pIDX])
//
||
//
(conditions.peakBuffer[pIDX] > conditions.peakBuffer[p2IDX] &&
conditions.peakBuffer[p2IDX] <= conditions.peakBuffer[p3IDX] &&
conditions.bars[pIDX].close > conditions.peakBuffer[p2IDX])
//
||
//
(conditions.peakBuffer[p2IDX] > conditions.peakBuffer[p3IDX] &&
conditions.peakBuffer[p3IDX] <= conditions.peakBuffer[p4IDX] &&
conditions.bars[p2IDX].close > conditions.peakBuffer[p3IDX])
//
;
//
bool isValeUnderLast =
//
(conditions.valeBuffer[cIDX] < conditions.valeBuffer[pIDX] &&
conditions.valeBuffer[pIDX] >= conditions.valeBuffer[p2IDX] &&
conditions.bars[cIDX].close < conditions.valeBuffer[pIDX])
//
||
//
(conditions.valeBuffer[pIDX] < conditions.valeBuffer[p2IDX] &&
conditions.valeBuffer[p2IDX] >= conditions.valeBuffer[p3IDX] &&
conditions.bars[pIDX].close < conditions.valeBuffer[p2IDX])
//
||
//
(conditions.valeBuffer[p2IDX] < conditions.valeBuffer[p3IDX] &&
conditions.valeBuffer[p3IDX] >= conditions.valeBuffer[p4IDX] &&
conditions.bars[p2IDX].close < conditions.valeBuffer[p3IDX])
//
;
//
// if (isValeUnderLast)
// {
// Print("SALAM");
// }
//
// Try to Summarize Conditions ...
//
bool isBullishPassed =
//
(isPeakOverLast &&
isDeltaBullishStart &&
isVolumeBullishStart &&
isBarBullishPressured)
//
;
//
bool isBearishPassed =
(isValeUnderLast &&
isDeltaBearishStart &&
isVolumeBearishStart &&
isBarBearishPressured)
//
;
//
// Try to Detect Trigger Block ...
bool hasTB = false;
int tbLoopback = 100;
X121XCatbInputs mInputs = helper.GetInputs();
for (int i = barIndex; i < barIndex + tbLoopback; i++)
{
//
// Update Helper ...
helper.Update(i);
//
// Check TB ...
hasTB = DetectTriggerBlock(
//
conditions.symbol,
conditions.period,
//
tb,
//
drawer,
barAnalyser,
//
// Required Buffers ...
helper.atrBuffer,
helper.rsiBuffer,
helper.adxBuffer,
helper.adxpBuffer,
helper.adxnBuffer,
helper.peakBuffer,
helper.valeBuffer,
helper.deltaBuffer,
helper.sarBuffer,
helper.sarStateBuffer,
helper.trendBuffer,
helper.trendStateBuffer,
helper.atrUpperBuffer,
helper.atrLowerBuffer,
helper.sBarOpenBuffer,
helper.sBarCloseBuffer,
helper.hkSBarOpenBuffer,
helper.hkSBarCloseBuffer,
helper.peakGoldenBuffer,
helper.valeGoldenBuffer,
helper.deltaSignalBuffer,
helper.bullishVolumeSignalBuffer,
helper.bearishVolumeSignalBuffer,
//
i + 1,
//
// Signalling ...
mInputs.signalR2R,
mInputs.slAtrMultiplier,
//
// Configs ...
mInputs.rsiOBLevel,
mInputs.rsiOSLevel,
mInputs.adxThreshold,
//
// Validators ...
mInputs.forceObBarType,
mInputs.forceOBFVGBarType,
mInputs.forceHasSwing,
mInputs.forceHasFLiquidity,
mInputs.forceHasRLiquidity,
mInputs.validateGapSequence,
mInputs.validateBlockEdgeBreakout,
//
// Filters ...
mInputs.filterBasedOnPV,
mInputs.filterBasedOnSar,
mInputs.filterBasedOnRSI,
mInputs.filterBasedOnADX,
mInputs.filterBasedOnATR,
mInputs.filterBasedOnTrend,
mInputs.filterBasedOnDelta,
mInputs.filterBasedOnVolume,
mInputs.filterBasedOnSignalBar,
mInputs.filterBasedOnHKSignalBar //
);
//
// Checking Trigger Block Validation ...
hasTB =
//
hasTB &&
//
(
//
(isBullishPassed &&
tb.IsBullish())
//
||
//
(isBearishPassed &&
tb.IsBearish())
//
);
if (hasTB)
{
//
break;
}
//
tb.Clean();
}
//
// isBullishPassed = false;
// isBearishPassed = false;
//
// Draw Line for Detect Conditions States on Chart ...
if (hasTB && (isBullishPassed ||
isBearishPassed))
{
//
color iColor = isBullishPassed
? clrAqua
: clrMagenta;
//
datetime iTime = conditions.bars[cIDX].time;
//
string iName = "VL_" + ToFormatString(iTime);
//
long chartID = drawer.ChartIdentification();
int subWindow = drawer.SubWindowIdentification();
//
CChartObjectVLine *iObj;
iObj = new CChartObjectVLine();
bool isDrawn = iObj.Create(
chartID,
iName,
subWindow,
iTime //
);
if (isDrawn)
{
//
iObj.Color(iColor);
}
//
CArrayObj *tbObjects = new CArrayObj();
DrawTriggerBlock(
tb,
drawer,
tbObjects,
conditions.bars[0].time //
);
//
tb.Clean();
}
//
// Summarizing result ...
//
result = (isBullishPassed ||
isBearishPassed);
//
// Cleanup Resources ...
//
if (!result)
{
//
tb.Clean();
conditions.Clean();
}
//
return result;
}
//
// has = DetectTriggerBlock(
// eaDrawer,
// eaHelper,
// eaBarAnalyser,
// iConditions,
// iTB,
// barIndex,
// 10 //
// );
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-316
View File
@@ -1,316 +0,0 @@
//
// Market ...
ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Short Period
ENUM_TIMEFRAMES scPeriod = NULL; // Short Period
ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Medium Period
ENUM_TIMEFRAMES mcPeriod = NULL; // Medium Period
ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Long Period
ENUM_TIMEFRAMES lcPeriod = NULL; // Long Period
ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Hind Period
ENUM_TIMEFRAMES hcPeriod = NULL; // Hind Period
ENUM_X_MARKET_CYCLES appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle
//
// Signal ...
int signalR2R = 4; // Risk Reward Ratio
bool drawSignals = true; // Draw Signal
double slAtrMultiplier = 1.0; // ATR Multiplier for SL
//
// Validating ...
bool forceHasSwing = false; // Force Blocks to Have Swing
bool forceObBarType = false; // Force Block Has Reversal Bar
bool forceOBFVGBarType = false; // Force FVG Has Same Bars
bool forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity
bool forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity
bool validateGapSequence = false; // Validate Block's Gap Sequence
bool validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout
//
// Filtering ...
bool filterBasedOnPV = false; // Filter Based on Peak and Vale
bool filterBasedOnSar = false; // Filter Based on Sar
bool filterBasedOnRSI = false; // Filter Based on RSI
bool filterBasedOnADX = false; // Filter Based on ADX
bool filterBasedOnATR = false; // Filter Based on ATR
bool filterBasedOnTrend = false; // Filter Based on Trend
bool filterBasedOnDelta = false; // Filter Based on Delta
bool filterBasedOnVolume = false; // Filter Based on Volume
bool filterBasedOnSignalBar = false; // Filter Based on Signal Bar
bool filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar
//
// Alert ...
string mAlertPrefix = ""; // Alert Prefix
bool _logAlerts = true; // Log Alerts
bool _pushAlerts = false; // Push Alerts
bool _mailAlerts = false; // Mail Alerts
bool _terminalAlerts = true; // Terminal Alerts
//
// Presentation ...
bool showBars = true; // Show Bars
bool showPV = false; // Show PV
bool showPVGolden = false; // Show PV Golden
bool showSar = false; // Show Sar
bool showTrend = false; // Show Trend
bool showATRBand = false; // Show ATR Band
bool showTrendBars = false; // Show Trend Bars
bool showSignalBars = false; // Show Signal Bars
bool showHKSignalBars = false; // Show Hiken Ashi Signal Bars
//
int startCalculationForLastBars = 1500; // Calculate Last n Bars
/////////////////////////////////////////////////////////////////
//
// Market ...
ENUM_X_PERIOD_METHOD scMethod; // How to Find Short Period
ENUM_TIMEFRAMES scPeriod; // Short Period
ENUM_X_PERIOD_METHOD mcMethod; // How to Find Medium Period
ENUM_TIMEFRAMES mcPeriod; // Medium Period
ENUM_X_PERIOD_METHOD lcMethod; // How to Find Long Period
ENUM_TIMEFRAMES lcPeriod; // Long Period
ENUM_X_PERIOD_METHOD hcMethod; // How to Find Hind Period
ENUM_TIMEFRAMES hcPeriod; // Hind Period
ENUM_X_MARKET_CYCLES appliedCycle; // Applied Cycle
//
// Signal ...
int signalR2R; // Risk Reward Ratio
bool drawSignals; // Draw Signal
double slAtrMultiplier; // ATR Multiplier for SL
//
// Validating ...
bool forceHasSwing; // Force Blocks to Have Swing
bool forceObBarType; // Force Block Has Reversal Bar
bool forceOBFVGBarType; // Force FVG Has Same Bars
bool forceHasFLiquidity; // Force Blocks to Have Following Liquidity
bool forceHasRLiquidity; // Force Blocks to Have Reversal Liquidity
bool validateGapSequence; // Validate Block's Gap Sequence
bool validateBlockEdgeBreakout; // Validate Block's Edge Breakout
//
// Filtering ...
bool filterBasedOnPV; // Filter Based on Peak and Vale
bool filterBasedOnSar; // Filter Based on Sar
bool filterBasedOnRSI; // Filter Based on RSI
bool filterBasedOnADX; // Filter Based on ADX
bool filterBasedOnATR; // Filter Based on ATR
bool filterBasedOnTrend; // Filter Based on Trend
bool filterBasedOnDelta; // Filter Based on Delta
bool filterBasedOnVolume; // Filter Based on Volume
bool filterBasedOnSignalBar; // Filter Based on Signal Bar
bool filterBasedOnHKSignalBar; // Filter Based on Hiken Ashi Signal Bar
//
// Alert ...
string alertPrefix; // Alert Prefix
bool logAlerts; // Log Alerts
bool pushAlerts; // Push Alerts
bool mailAlerts; // Mail Alerts
bool terminalAlerts; // Terminal Alerts
//
// Presentation ...
bool showBars; // Show Bars
bool showPV; // Show PV
bool showPVGolden; // Show PV Golden
bool showSar; // Show Sar
bool showTrend; // Show Trend
bool showATRBand; // Show ATR Band
bool showTrendBars; // Show Trend Bars
bool showSignalBars; // Show Signal Bars
bool showHKSignalBars; // Show Hiken Ashi Signal Bars
//
int startCalculationForLastBars; // Calculate Last n Bars
//////////////////////////////////////////////////////////////////////
//
// Market ...
scMethod = X_PERIOD_AUTO; // How to Find Short Period
scPeriod = NULL; // Short Period
mcMethod = X_PERIOD_AUTO; // How to Find Medium Period
mcPeriod = NULL; // Medium Period
lcMethod = X_PERIOD_AUTO; // How to Find Long Period
lcPeriod = NULL; // Long Period
hcMethod = X_PERIOD_AUTO; // How to Find Hind Period
hcPeriod = NULL; // Hind Period
appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle
//
// Signal ...
signalR2R = 4; // Risk Reward Ratio
drawSignals = true; // Draw Signal
slAtrMultiplier = 1.0; // ATR Multiplier for SL
//
// Validating ...
forceHasSwing = false; // Force Blocks to Have Swing
forceObBarType = false; // Force Block Has Reversal Bar
forceOBFVGBarType = false; // Force FVG Has Same Bars
forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity
forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity
validateGapSequence = false; // Validate Block's Gap Sequence
validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout
//
// Filtering ...
filterBasedOnPV = false; // Filter Based on Peak and Vale
filterBasedOnSar = false; // Filter Based on Sar
filterBasedOnRSI = false; // Filter Based on RSI
filterBasedOnADX = false; // Filter Based on ADX
filterBasedOnATR = false; // Filter Based on ATR
filterBasedOnTrend = false; // Filter Based on Trend
filterBasedOnDelta = false; // Filter Based on Delta
filterBasedOnVolume = false; // Filter Based on Volume
filterBasedOnSignalBar = false; // Filter Based on Signal Bar
filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar
//
// Alert ...
mAlertPrefix = ""; // Alert Prefix
_logAlerts = true; // Log Alerts
_pushAlerts = false; // Push Alerts
_mailAlerts = false; // Mail Alerts
_terminalAlerts = true; // Terminal Alerts
//
// Presentation ...
showBars = true; // Show Bars
showPV = false; // Show PV
showPVGolden = false; // Show PV Golden
showSar = false; // Show Sar
showTrend = false; // Show Trend
showATRBand = false; // Show ATR Band
showTrendBars = false; // Show Trend Bars
showSignalBars = false; // Show Signal Bars
showHKSignalBars = false; // Show Hiken Ashi Signal Bars
//
startCalculationForLastBars = 1500; // Calculate Last n Bars
//////////////////////////////////////////////////////////////////////////////
X121_XCATB_SAR_LINE
sarBuffer
X121_XCATB_SAR_STATE_LINE
sarStateBuffer
X121_XCATB_PEAK_LINE
peakBuffer
X121_XCATB_VALE_LINE
valeBuffer
X121_XCATB_PEAK_GOLDEN_LINE
peakGoldenBuffer
X121_XCATB_VALE_GOLDEN_LINE
valeGoldenBuffer
X121_XCATB_ATR_BAND_UPPER_LINE
atrUpperBuffer
X121_XCATB_ATR_BAND_LOWER_LINE
atrLowerBuffer
X121_XCATB_TREND_LINE
trendBuffer
X121_XCATB_TREND_STATE_LINE
trendStateBuffer
X121_XCATB_SBAR_O_LINE
sBarOpenSBuffer
X121_XCATB_SBAR_C_LINE
sBarCloseBuffer
X121_XCATB_HK_SBAR_O_LINE
hkSBarOpenBuffer
X121_XCATB_HK_SBAR_C_LINE
hkSBarCloseBuffer
X121_XCATB_S_HH_LINE
sHHBuffer
X121_XCATB_S_LL_LINE
sLLBuffer
X121_XCATB_M_HH_LINE
mHHBuffer
X121_XCATB_M_LL_LINE
mLLBuffer
X121_XCATB_L_HH_LINE
lHHBuffer
X121_XCATB_L_LL_LINE
lLLBuffer
X121_XCATB_H_HH_LINE
hHHBuffer
X121_XCATB_H_LL_LINE
hLLBuffer
X121_XCATB_RSI_LINE
rsiBuffer
X121_XCATB_ADX_LINE
adxBuffer
X121_XCATB_ADXP_LINE
adxpBuffer
X121_XCATB_ADXN_LINE
adxnBuffer
X121_XCATB_DELTA_LINE
deltaBuffer
X121_XCATB_DELTA_SIGNAL_LINE
deltaSignalBuffer
X121_XCATB_VOLUME_BULLISH_LINE
bullishVolumeBuffer
X121_XCATB_VOLUME_BEARISH_LINE
bearishVolumeBuffer
X121_XCATB_VOLUME_VOLUME_BULLISH_SIGNAL_LINE
bullishVolumeSignalBuffer
X121_XCATB_VOLUME_VOLUME_BEARISH_SIGNAL_LINE
bearishVolumeSignalBuffer
X121_XCATB_ATR_LINE
atrBuffer
X121_XCATB_ATR_BAND_RAW_UPPER_LINE
atrUpperBuffer
X121_XCATB_ATR_BAND_RAW_LOWER_LINE
atrLowerBuffer
X121_XCATB_HK_BAR_O_LINE
hkOpenBuffer
X121_XCATB_HK_BAR_H_LINE
hkHighBuffer
X121_XCATB_HK_BAR_L_LINE
hkLowBuffer
X121_XCATB_HK_BAR_C_LINE
hkCloseBuffer
File diff suppressed because it is too large Load Diff