remove bkp ...
This commit is contained in:
@@ -1,196 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| HH_LH_LL_HL.mq5 |
|
|
||||||
//| Indicator for detecting HH, LH, LL, HL |
|
|
||||||
//| Created by [Your Name] |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
#property copyright "Your Name"
|
|
||||||
#property link "yourwebsite.com"
|
|
||||||
#property version "1.00"
|
|
||||||
#property indicator_chart_window
|
|
||||||
#property indicator_buffers 4
|
|
||||||
#property indicator_plots 4
|
|
||||||
|
|
||||||
//--- Input parameters
|
|
||||||
input int LookbackPeriod = 20; // Number of bars to look back for pattern detection
|
|
||||||
|
|
||||||
//--- Buffer declarations
|
|
||||||
double HH_Buffer[]; // Buffer for Higher Highs
|
|
||||||
double HL_Buffer[]; // Buffer for Higher Lows
|
|
||||||
double LH_Buffer[]; // Buffer for Lower Highs
|
|
||||||
double LL_Buffer[]; // Buffer for Lower Lows
|
|
||||||
|
|
||||||
//--- Plot settings
|
|
||||||
#property indicator_label1 "Higher Highs"
|
|
||||||
#property indicator_type1 DRAW_ARROW
|
|
||||||
#property indicator_color1 clrGreen
|
|
||||||
#property indicator_style1 STYLE_SOLID
|
|
||||||
#property indicator_width1 1
|
|
||||||
|
|
||||||
#property indicator_label2 "Higher Lows"
|
|
||||||
#property indicator_type2 DRAW_ARROW
|
|
||||||
#property indicator_color2 clrBlue
|
|
||||||
#property indicator_style2 STYLE_SOLID
|
|
||||||
#property indicator_width2 1
|
|
||||||
|
|
||||||
#property indicator_label3 "Lower Highs"
|
|
||||||
#property indicator_type3 DRAW_ARROW
|
|
||||||
#property indicator_color3 clrRed
|
|
||||||
#property indicator_style3 STYLE_SOLID
|
|
||||||
#property indicator_width3 1
|
|
||||||
|
|
||||||
#property indicator_label4 "Lower Lows"
|
|
||||||
#property indicator_type4 DRAW_ARROW
|
|
||||||
#property indicator_color4 clrYellow
|
|
||||||
#property indicator_style4 STYLE_SOLID
|
|
||||||
#property indicator_width4 1
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Initialization function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
int OnInit()
|
|
||||||
{
|
|
||||||
// Set buffer properties
|
|
||||||
SetIndexBuffer(0, HH_Buffer);
|
|
||||||
SetIndexBuffer(1, HL_Buffer);
|
|
||||||
SetIndexBuffer(2, LH_Buffer);
|
|
||||||
SetIndexBuffer(3, LL_Buffer);
|
|
||||||
|
|
||||||
// Clear buffers at each bar
|
|
||||||
ArrayInitialize(HH_Buffer, 0.0);
|
|
||||||
ArrayInitialize(HL_Buffer, 0.0);
|
|
||||||
ArrayInitialize(LH_Buffer, 0.0);
|
|
||||||
ArrayInitialize(LL_Buffer, 0.0);
|
|
||||||
|
|
||||||
return(INIT_SUCCEEDED);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Deinitialization function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
// Cleanup if necessary
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Calculate function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
int OnCalculate(const int rates_total,
|
|
||||||
const int prev_calculated,
|
|
||||||
const datetime &time[],
|
|
||||||
const double &open[],
|
|
||||||
const double &high[],
|
|
||||||
const double &low[],
|
|
||||||
const double &close[],
|
|
||||||
const long &tick_volume[],
|
|
||||||
const long &volume[],
|
|
||||||
const int &spread[])
|
|
||||||
{
|
|
||||||
// Start from the last calculated bar
|
|
||||||
int start_bar = MathMax(prev_calculated - 1, 0);
|
|
||||||
|
|
||||||
// Loop through bars
|
|
||||||
for (int i = start_bar; i < rates_total; i++)
|
|
||||||
{
|
|
||||||
// Get current high and low
|
|
||||||
double current_high = high[i];
|
|
||||||
double current_low = low[i];
|
|
||||||
|
|
||||||
// Check for Higher High (HH)
|
|
||||||
if (IsHigherHigh(i, high, LookbackPeriod))
|
|
||||||
{
|
|
||||||
HH_Buffer[i] = current_high;
|
|
||||||
HL_Buffer[i] = 0.0; // Reset other buffers
|
|
||||||
LH_Buffer[i] = 0.0;
|
|
||||||
LL_Buffer[i] = 0.0;
|
|
||||||
}
|
|
||||||
// Check for Higher Low (HL)
|
|
||||||
else if (IsHigherLow(i, low, LookbackPeriod))
|
|
||||||
{
|
|
||||||
HL_Buffer[i] = current_low;
|
|
||||||
HH_Buffer[i] = 0.0;
|
|
||||||
LH_Buffer[i] = 0.0;
|
|
||||||
LL_Buffer[i] = 0.0;
|
|
||||||
}
|
|
||||||
// Check for Lower High (LH)
|
|
||||||
else if (IsLowerHigh(i, high, LookbackPeriod))
|
|
||||||
{
|
|
||||||
LH_Buffer[i] = current_high;
|
|
||||||
HH_Buffer[i] = 0.0;
|
|
||||||
HL_Buffer[i] = 0.0;
|
|
||||||
LL_Buffer[i] = 0.0;
|
|
||||||
}
|
|
||||||
// Check for Lower Low (LL)
|
|
||||||
else if (IsLowerLow(i, low, LookbackPeriod))
|
|
||||||
{
|
|
||||||
LL_Buffer[i] = current_low;
|
|
||||||
HH_Buffer[i] = 0.0;
|
|
||||||
HL_Buffer[i] = 0.0;
|
|
||||||
LH_Buffer[i] = 0.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Reset all buffers if no pattern is detected
|
|
||||||
HH_Buffer[i] = 0.0;
|
|
||||||
HL_Buffer[i] = 0.0;
|
|
||||||
LH_Buffer[i] = 0.0;
|
|
||||||
LL_Buffer[i] = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return rates_total;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Function to detect Higher High |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool IsHigherHigh(int index, const double &high[], int lookback)
|
|
||||||
{
|
|
||||||
for (int i = 1; i <= lookback; i++)
|
|
||||||
{
|
|
||||||
if (index - i < 0) continue; // Ensure we don't go out of bounds
|
|
||||||
if (high[index] <= high[index - i]) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Function to detect Higher Low |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool IsHigherLow(int index, const double &low[], int lookback)
|
|
||||||
{
|
|
||||||
for (int i = 1; i <= lookback; i++)
|
|
||||||
{
|
|
||||||
if (index - i < 0) continue; // Ensure we don't go out of bounds
|
|
||||||
if (low[index] <= low[index - i]) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Function to detect Lower High |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool IsLowerHigh(int index, const double &high[], int lookback)
|
|
||||||
{
|
|
||||||
for (int i = 1; i <= lookback; i++)
|
|
||||||
{
|
|
||||||
if (index - i < 0) continue; // Ensure we don't go out of bounds
|
|
||||||
if (high[index] >= high[index - i]) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Function to detect Lower Low |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool IsLowerLow(int index, const double &low[], int lookback)
|
|
||||||
{
|
|
||||||
for (int i = 1; i <= lookback; i++)
|
|
||||||
{
|
|
||||||
if (index - i < 0) continue; // Ensure we don't go out of bounds
|
|
||||||
if (low[index] >= low[index - i]) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
-10874
File diff suppressed because it is too large
Load Diff
@@ -1,243 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Test.mq5 |
|
|
||||||
//| Copyright 2025, MetaQuotes Ltd. |
|
|
||||||
//| https://www.mql5.com |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
#property copyright "Copyright 2025, MetaQuotes Ltd."
|
|
||||||
#property link "https://www.mql5.com"
|
|
||||||
#property version "1.00"
|
|
||||||
|
|
||||||
//
|
|
||||||
#include "../Classes/x-saherelm.x-bar.analyser.class.mq5"
|
|
||||||
#include "../Classes/x-saherelm.x-poi.class.mq5"
|
|
||||||
#include "../Classes/x-saherelm.x-poi.drawer.class.mq5"
|
|
||||||
|
|
||||||
//
|
|
||||||
XCPOIDrawer *mPOIDrawer;
|
|
||||||
XCPOIDetector *mPOIDetector;
|
|
||||||
XCBarAnalyser *mBarAnalyser;
|
|
||||||
|
|
||||||
//
|
|
||||||
XBarTracker mBarTracker;
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Expert initialization function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
int OnInit()
|
|
||||||
{
|
|
||||||
//---
|
|
||||||
mPOIDetector = new XCPOIDetector(
|
|
||||||
_Symbol,
|
|
||||||
_Period //
|
|
||||||
);
|
|
||||||
mPOIDetector.Init();
|
|
||||||
|
|
||||||
//---
|
|
||||||
mPOIDrawer = new XCPOIDrawer();
|
|
||||||
|
|
||||||
//---
|
|
||||||
mBarAnalyser = new XCBarAnalyser();
|
|
||||||
|
|
||||||
//---
|
|
||||||
mBarTracker.Init(
|
|
||||||
_Symbol,
|
|
||||||
_Period //
|
|
||||||
);
|
|
||||||
|
|
||||||
//---
|
|
||||||
return (INIT_SUCCEEDED);
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Expert deinitialization function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
//---
|
|
||||||
ZeroMemory(mPOIDrawer);
|
|
||||||
ZeroMemory(mBarAnalyser);
|
|
||||||
ZeroMemory(mPOIDetector);
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Expert tick function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isNewBar = mBarTracker.IsNewBar();
|
|
||||||
if (!isNewBar)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
ENUM_XPOI_EVENTS mPOIEvents[];
|
|
||||||
mPOIDetector.Update(mPOIEvents);
|
|
||||||
|
|
||||||
//
|
|
||||||
XPOIState mPOIState;
|
|
||||||
mPOIDetector.GetState(mPOIState);
|
|
||||||
|
|
||||||
//
|
|
||||||
bool has = Contains(
|
|
||||||
X_BULLISH_FVG_DETECTED,
|
|
||||||
mPOIEvents //
|
|
||||||
) ||
|
|
||||||
Contains(
|
|
||||||
X_BEARISH_FVG_DETECTED,
|
|
||||||
mPOIEvents //
|
|
||||||
);
|
|
||||||
if (has)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
XCFVG *fvg;
|
|
||||||
int idx = GetYoungest(mPOIState.fairValueGaps);
|
|
||||||
has = IsValidIndex(idx);
|
|
||||||
if (has)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
fvg = mPOIState.fairValueGaps[idx];
|
|
||||||
|
|
||||||
//
|
|
||||||
XCBaseObject *iObj;
|
|
||||||
has = mPOIDrawer.CreateFairValueGap(
|
|
||||||
fvg,
|
|
||||||
iObj //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
if (has)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
Print("New Fair Value Gap ...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// //
|
|
||||||
// bool has = mPOIState.HasFairValueGaps();
|
|
||||||
// if (has)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// int count = mPOIState.CountFairValueGaps();
|
|
||||||
// for (int i = 0; i < count; i++)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// mPOIState.fairValueGaps[i].To(TimeCurrent());
|
|
||||||
|
|
||||||
// //
|
|
||||||
// XCBaseObject *iObj;
|
|
||||||
// bool isCreated = mPOIDrawer.CreateFairValueGap(
|
|
||||||
// mPOIState.fairValueGaps[i],
|
|
||||||
// iObj //
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
//
|
|
||||||
// Print("Salam");
|
|
||||||
|
|
||||||
//
|
|
||||||
return;
|
|
||||||
|
|
||||||
// //
|
|
||||||
// XOHCL bar;
|
|
||||||
// bool isInited = bar.Init(
|
|
||||||
// _Symbol,
|
|
||||||
// _Period,
|
|
||||||
// 0 //
|
|
||||||
// );
|
|
||||||
// if (!isInited)
|
|
||||||
// {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //
|
|
||||||
// int index = 0;
|
|
||||||
// ENUM_X_DIRECTION sameBarDir;
|
|
||||||
// bool hasSameBars = mBarAnalyser.HasSameBars(
|
|
||||||
// bar,
|
|
||||||
// sameBarDir,
|
|
||||||
// index,
|
|
||||||
// 3 //
|
|
||||||
// );
|
|
||||||
// if (hasSameBars)
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //
|
|
||||||
// // Detect Fair Value Gap ...
|
|
||||||
// XOHCL fvgEndBar;
|
|
||||||
// XOHCL fvgStartBar;
|
|
||||||
// ENUM_X_DIRECTION fvgDir;
|
|
||||||
// bool hasFVG = mBarAnalyser.HasFairValueGap(
|
|
||||||
// bar,
|
|
||||||
// fvgStartBar,
|
|
||||||
// fvgEndBar,
|
|
||||||
// fvgDir,
|
|
||||||
// 3 //
|
|
||||||
// );
|
|
||||||
// if (hasFVG)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// XCFVG *fvg;
|
|
||||||
// fvg = new XCFVG();
|
|
||||||
// bool isInit = fvg.Init(
|
|
||||||
// fvgStartBar,
|
|
||||||
// fvgEndBar,
|
|
||||||
// fvgDir //
|
|
||||||
// );
|
|
||||||
// // if (isInit)
|
|
||||||
// // {
|
|
||||||
// // //
|
|
||||||
// // XCBaseObject *iObj;
|
|
||||||
// // bool isCreated = mPOIDrawer.CreateFairValueGap(
|
|
||||||
// // fvg,
|
|
||||||
// // iObj //
|
|
||||||
// // );
|
|
||||||
// //
|
|
||||||
// // //
|
|
||||||
// // if (isCreated)
|
|
||||||
// // {
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //
|
|
||||||
// XOHCL obBar;
|
|
||||||
// ENUM_X_DIRECTION obDir;
|
|
||||||
// bool hasOB = mBarAnalyser.HasOrderBlock(
|
|
||||||
// bar,
|
|
||||||
// obBar,
|
|
||||||
// obDir,
|
|
||||||
// 3 //
|
|
||||||
// );
|
|
||||||
// if (hasOB)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// XCOrderBlock *ob;
|
|
||||||
// ob = new XCOrderBlock();
|
|
||||||
// bool isInit = ob.Init(
|
|
||||||
// obBar,
|
|
||||||
// obDir //
|
|
||||||
// );
|
|
||||||
// if (isInit)
|
|
||||||
// {
|
|
||||||
// // //
|
|
||||||
// // XCBaseObject *iObj;
|
|
||||||
// // bool isCreated = mPOIDrawer.CreateOrderBlock(
|
|
||||||
// // ob,
|
|
||||||
// // iObj //
|
|
||||||
// // );
|
|
||||||
|
|
||||||
// // //
|
|
||||||
// // if (isCreated)
|
|
||||||
// // {
|
|
||||||
// // Print("Order Block ...");
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
@@ -1,418 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| SMC_OrderBlock_EA.mq5|
|
|
||||||
//| Copyright 2023, MetaQuotes Software Corp. |
|
|
||||||
//| https://www.mql5.com |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
#property copyright "Copyright 2023, MetaQuotes Software Corp."
|
|
||||||
#property link "https://www.mql5.com"
|
|
||||||
#property version "1.00"
|
|
||||||
#property strict
|
|
||||||
|
|
||||||
#include <Trade/AccountInfo.mqh>
|
|
||||||
#include <Trade/Trade.mqh>
|
|
||||||
|
|
||||||
//
|
|
||||||
// Input parameters
|
|
||||||
input ENUM_TIMEFRAMES TimeFrame = PERIOD_M15; // Timeframe for analysis
|
|
||||||
input double RiskPercent = 1.0; // Risk per trade (1-2%)
|
|
||||||
input int ATR_Period = 14; // ATR period for volatility
|
|
||||||
input int OrderBlockLength = 20; // Bars for consolidation
|
|
||||||
input int ConfirmationCandles = 3; // Candles to confirm breakout
|
|
||||||
input double StopLossMultiplier = 1.5; // Stop loss buffer
|
|
||||||
input double TakeProfitRatio = 2.0; // Risk:Reward ratio
|
|
||||||
input int TrailingStopPips = 50; // Trailing stop in pips
|
|
||||||
|
|
||||||
//
|
|
||||||
CTrade trade;
|
|
||||||
CAccountInfo accountInfo;
|
|
||||||
|
|
||||||
//
|
|
||||||
double Ask = 0;
|
|
||||||
double Bid = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Order Block structure
|
|
||||||
struct OrderBlock
|
|
||||||
{
|
|
||||||
datetime startTime;
|
|
||||||
double high;
|
|
||||||
double low;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
int atrHandler = INVALID_HANDLE;
|
|
||||||
int maFastHandler = INVALID_HANDLE;
|
|
||||||
int maSlowHandler = INVALID_HANDLE;
|
|
||||||
|
|
||||||
//
|
|
||||||
double atrs[];
|
|
||||||
double fastMAs[];
|
|
||||||
double slowMAs[];
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Expert initialization function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
int OnInit()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
trade.SetExpertMagicNumber(123456); // Unique magic number
|
|
||||||
|
|
||||||
//
|
|
||||||
atrHandler = iATR(_Symbol, TimeFrame, ATR_Period);
|
|
||||||
maFastHandler = iMA(_Symbol, TimeFrame, 20, 0, MODE_SMA, PRICE_CLOSE);
|
|
||||||
maSlowHandler = iMA(_Symbol, TimeFrame, 50, 0, MODE_SMA, PRICE_CLOSE);
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isValid =
|
|
||||||
atrHandler != INVALID_HANDLE &&
|
|
||||||
maFastHandler != INVALID_HANDLE &&
|
|
||||||
maSlowHandler != INVALID_HANDLE;
|
|
||||||
if (!isValid)
|
|
||||||
{
|
|
||||||
return (INIT_FAILED);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
return (INIT_SUCCEEDED);
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Expert deinitialization function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Cleanup code if needed ...
|
|
||||||
IndicatorRelease(atrHandler);
|
|
||||||
IndicatorRelease(maFastHandler);
|
|
||||||
IndicatorRelease(maSlowHandler);
|
|
||||||
|
|
||||||
//
|
|
||||||
ZeroMemory(atrs);
|
|
||||||
ZeroMemory(fastMAs);
|
|
||||||
ZeroMemory(slowMAs);
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Expert tick function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
// Avoid multiple orders
|
|
||||||
if (CheckOpenOrders())
|
|
||||||
return;
|
|
||||||
|
|
||||||
//
|
|
||||||
CopyBuffer(atrHandler, MAIN_LINE, 0, 200, atrs);
|
|
||||||
|
|
||||||
//
|
|
||||||
CopyBuffer(maFastHandler, MAIN_LINE, 0, 2, fastMAs);
|
|
||||||
CopyBuffer(maSlowHandler, MAIN_LINE, 0, 2, slowMAs);
|
|
||||||
|
|
||||||
//
|
|
||||||
Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits); // Get the Ask Price
|
|
||||||
Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits); // Get the Bid Price
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check for trend and execute trades
|
|
||||||
if (IsUptrend())
|
|
||||||
{
|
|
||||||
OrderBlock block = FindBullishOrderBlock();
|
|
||||||
if (block.startTime != 0 && IsPriceInBlock(block))
|
|
||||||
{
|
|
||||||
if (ConfirmBullishEntry())
|
|
||||||
ExecuteTrade(block, ORDER_TYPE_BUY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (IsDowntrend())
|
|
||||||
{
|
|
||||||
OrderBlock block = FindBearishOrderBlock();
|
|
||||||
if (block.startTime != 0 && IsPriceInBlock(block))
|
|
||||||
{
|
|
||||||
if (ConfirmBearishEntry())
|
|
||||||
ExecuteTrade(block, ORDER_TYPE_SELL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage trailing stops
|
|
||||||
TrailStop();
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Check if price is within the order block |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool IsPriceInBlock(OrderBlock &block)
|
|
||||||
{
|
|
||||||
double currentPrice = (Ask + Bid) / 2; // Mid-price
|
|
||||||
return (currentPrice >= block.low && currentPrice <= block.high);
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Detect uptrend using moving averages |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool IsUptrend()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
double maFast = fastMAs[0];
|
|
||||||
double maSlow = slowMAs[0];
|
|
||||||
|
|
||||||
//
|
|
||||||
return (maFast > maSlow);
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Detect downtrend using moving averages |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool IsDowntrend()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
double maFast = fastMAs[0];
|
|
||||||
double maSlow = slowMAs[0];
|
|
||||||
|
|
||||||
//
|
|
||||||
return (maFast < maSlow);
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Find bullish order blocks |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
OrderBlock FindBullishOrderBlock()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
OrderBlock block;
|
|
||||||
block.startTime = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
for (int i = 1; i < 100; i++)
|
|
||||||
{
|
|
||||||
double prevHigh = iHigh(NULL, TimeFrame, i);
|
|
||||||
double prevLow = iLow(NULL, TimeFrame, i);
|
|
||||||
double prevClose = iClose(NULL, TimeFrame, i);
|
|
||||||
double prevOpen = iOpen(NULL, TimeFrame, i);
|
|
||||||
|
|
||||||
double atr = atrs[i];
|
|
||||||
if (prevClose - prevOpen > 1.5 * atr)
|
|
||||||
{ // Strong bullish candle
|
|
||||||
double consolidationHigh = prevHigh;
|
|
||||||
double consolidationLow = prevLow;
|
|
||||||
bool isConsolidation = true;
|
|
||||||
|
|
||||||
for (int j = 1; j <= OrderBlockLength; j++)
|
|
||||||
{
|
|
||||||
double newHigh = iHigh(NULL, TimeFrame, i - j);
|
|
||||||
double newLow = iLow(NULL, TimeFrame, i - j);
|
|
||||||
consolidationHigh = MathMax(consolidationHigh, newHigh);
|
|
||||||
consolidationLow = MathMin(consolidationLow, newLow);
|
|
||||||
|
|
||||||
if ((consolidationHigh - consolidationLow) > 0.5 * atr)
|
|
||||||
{
|
|
||||||
isConsolidation = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isConsolidation)
|
|
||||||
{
|
|
||||||
block.high = consolidationHigh;
|
|
||||||
block.low = consolidationLow;
|
|
||||||
block.startTime = iTime(NULL, TimeFrame, i);
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Find bearish order blocks |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
OrderBlock FindBearishOrderBlock()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
OrderBlock block;
|
|
||||||
block.startTime = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
for (int i = 1; i < 100; i++)
|
|
||||||
{
|
|
||||||
double prevHigh = iHigh(NULL, TimeFrame, i);
|
|
||||||
double prevLow = iLow(NULL, TimeFrame, i);
|
|
||||||
double prevClose = iClose(NULL, TimeFrame, i);
|
|
||||||
double prevOpen = iOpen(NULL, TimeFrame, i);
|
|
||||||
|
|
||||||
double atr = atrs[i];
|
|
||||||
if (prevOpen - prevClose > 1.5 * atr)
|
|
||||||
{ // Strong bearish candle
|
|
||||||
double consolidationHigh = prevHigh;
|
|
||||||
double consolidationLow = prevLow;
|
|
||||||
bool isConsolidation = true;
|
|
||||||
|
|
||||||
for (int j = 1; j <= OrderBlockLength; j++)
|
|
||||||
{
|
|
||||||
double newHigh = iHigh(NULL, TimeFrame, i - j);
|
|
||||||
double newLow = iLow(NULL, TimeFrame, i - j);
|
|
||||||
consolidationHigh = MathMax(consolidationHigh, newHigh);
|
|
||||||
consolidationLow = MathMin(consolidationLow, newLow);
|
|
||||||
|
|
||||||
if ((consolidationHigh - consolidationLow) > 0.5 * atr)
|
|
||||||
{
|
|
||||||
isConsolidation = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isConsolidation)
|
|
||||||
{
|
|
||||||
block.high = consolidationHigh;
|
|
||||||
block.low = consolidationLow;
|
|
||||||
block.startTime = iTime(NULL, TimeFrame, i);
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Confirm bullish entry with candle pattern |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool ConfirmBullishEntry()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
int shift = iBarShift(NULL, TimeFrame, TimeCurrent());
|
|
||||||
double prevLow = iLow(NULL, TimeFrame, shift + 1);
|
|
||||||
double currentClose = iClose(NULL, TimeFrame, shift);
|
|
||||||
return (currentClose > prevLow && iOpen(NULL, TimeFrame, shift) < currentClose);
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Confirm bearish entry with candle pattern |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool ConfirmBearishEntry()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
int shift = iBarShift(NULL, TimeFrame, TimeCurrent());
|
|
||||||
double prevHigh = iHigh(NULL, TimeFrame, shift + 1);
|
|
||||||
double currentClose = iClose(NULL, TimeFrame, shift);
|
|
||||||
return (currentClose < prevHigh && iOpen(NULL, TimeFrame, shift) > currentClose);
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Execute trade with risk management |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void ExecuteTrade(OrderBlock &block, ENUM_ORDER_TYPE orderType)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
double atr = atrs[0];
|
|
||||||
double stopLoss, takeProfit, lotSize;
|
|
||||||
double entryPrice = (orderType == ORDER_TYPE_BUY) ? Ask : Bid;
|
|
||||||
|
|
||||||
// Calculate stop loss and take profit
|
|
||||||
if (orderType == ORDER_TYPE_BUY)
|
|
||||||
{
|
|
||||||
stopLoss = block.low - StopLossMultiplier * atr;
|
|
||||||
takeProfit = entryPrice + (entryPrice - stopLoss) * TakeProfitRatio;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stopLoss = block.high + StopLossMultiplier * atr;
|
|
||||||
takeProfit = entryPrice - (stopLoss - entryPrice) * TakeProfitRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate lot size based on risk
|
|
||||||
lotSize = CalculateLotSize(stopLoss, entryPrice, orderType);
|
|
||||||
if (lotSize <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Place order
|
|
||||||
if (orderType == ORDER_TYPE_BUY)
|
|
||||||
{
|
|
||||||
trade.Buy(lotSize, _Symbol, entryPrice, stopLoss, takeProfit, "SMC Bullish Order Block");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
trade.Sell(lotSize, _Symbol, entryPrice, stopLoss, takeProfit, "SMC Bearish Order Block");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Calculate lot size based on risk per trade |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
double CalculateLotSize(double stopLoss, double entryPrice, ENUM_ORDER_TYPE orderType)
|
|
||||||
{
|
|
||||||
double riskAmount = AccountBalance() * RiskPercent / 100;
|
|
||||||
double stopLossPips = MathAbs((entryPrice - stopLoss) / SymbolInfoDouble(_Symbol, SYMBOL_POINT));
|
|
||||||
|
|
||||||
if (stopLossPips == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
double pipValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
|
||||||
double lotSize = riskAmount / (stopLossPips * pipValue);
|
|
||||||
lotSize = NormalizeDouble(lotSize, 2); // Adjust to symbol's lot precision
|
|
||||||
|
|
||||||
return MathMax(lotSize, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN));
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Check for existing open orders |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool CheckOpenOrders()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < PositionsTotal(); i++)
|
|
||||||
{
|
|
||||||
if (PositionGetSymbol(i) == _Symbol)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Trailing stop logic |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void TrailStop()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < PositionsTotal(); i++)
|
|
||||||
{
|
|
||||||
if (PositionGetSymbol(i) != _Symbol)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ulong ticket = PositionGetInteger(POSITION_TICKET);
|
|
||||||
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
|
||||||
double currentPrice = (type == POSITION_TYPE_BUY) ? Bid : Ask;
|
|
||||||
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
|
||||||
double stopLoss = PositionGetDouble(POSITION_SL);
|
|
||||||
double trailingStopPrice = (type == POSITION_TYPE_BUY)
|
|
||||||
? currentPrice - TrailingStopPips * SymbolInfoDouble(_Symbol, SYMBOL_POINT)
|
|
||||||
: currentPrice + TrailingStopPips * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
|
||||||
|
|
||||||
// Update stop loss if price moves favorably
|
|
||||||
if ((type == POSITION_TYPE_BUY && trailingStopPrice > stopLoss) ||
|
|
||||||
(type == POSITION_TYPE_SELL && trailingStopPrice < stopLoss))
|
|
||||||
{
|
|
||||||
trade.PositionModify(ticket, trailingStopPrice, PositionGetDouble(POSITION_TP));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Calculate Account Balance |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
double AccountBalance()
|
|
||||||
{
|
|
||||||
return accountInfo.Balance();
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
@@ -1,275 +0,0 @@
|
|||||||
//+------------------------------------------------------------------+
|
|
||||||
//| OrderBlockDetector.mq5|
|
|
||||||
//| Copyright 2023, MetaQuotes Software Corp. |
|
|
||||||
//| https://www.mql5.com|
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
#property strict
|
|
||||||
|
|
||||||
//
|
|
||||||
// Input Parameters
|
|
||||||
input int ConsolidationPeriod = 20; // Bars for consolidation detection
|
|
||||||
input int AtrPeriod = 14; // ATR period for volatility
|
|
||||||
input double AtrMultiplier = 2.0; // Threshold multiplier (ATR * multiplier)
|
|
||||||
input int VolumeThreshold = 1000; // Minimum volume for breakout
|
|
||||||
input bool RequireRetest = true; // Retest confirmation required?
|
|
||||||
input int VpvrBars = 50; // Bars for VPVR calculation
|
|
||||||
input int TrendCheckPeriod = 30; // Bars for trend structure analysis
|
|
||||||
input int MACDFast = 12; // MACD Fast EMA period
|
|
||||||
input int MACDSlow = 26; // MACD Slow EMA period
|
|
||||||
input int MACDSignal = 9; // MACD Signal period
|
|
||||||
input int RSIPeriod = 14; // RSI period
|
|
||||||
input double RSILevel = 50; // RSI threshold level
|
|
||||||
|
|
||||||
// Global Variables
|
|
||||||
int ObjectId = 0;
|
|
||||||
string Prefix = "OrderBlock_";
|
|
||||||
|
|
||||||
//
|
|
||||||
enum ENUM_X_DIRECTION
|
|
||||||
{
|
|
||||||
X_DIRECTION_NONE,
|
|
||||||
X_DIRECTION_BULISH,
|
|
||||||
X_DIRECTION_BEARISH,
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
int atrHandler = INVALID_HANDLE;
|
|
||||||
double atrBuffer[];
|
|
||||||
|
|
||||||
//
|
|
||||||
int rsiHandler = INVALID_HANDLE;
|
|
||||||
double rsiBuffer[];
|
|
||||||
|
|
||||||
//
|
|
||||||
int macdHandler = INVALID_HANDLE;
|
|
||||||
double macdMainBuffer[];
|
|
||||||
double macdSignalBuffer[];
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Expert initialization function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
int OnInit()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
ArraySetAsSeries(atrBuffer, true);
|
|
||||||
atrHandler = iATR(_Symbol, _Period, AtrPeriod);
|
|
||||||
|
|
||||||
//
|
|
||||||
ArraySetAsSeries(rsiBuffer, true);
|
|
||||||
rsiHandler = iRSI(_Symbol, _Period, RSIPeriod, PRICE_CLOSE);
|
|
||||||
|
|
||||||
//
|
|
||||||
ArraySetAsSeries(macdMainBuffer, true);
|
|
||||||
ArraySetAsSeries(macdSignalBuffer, true);
|
|
||||||
macdHandler = iMACD(_Symbol, _Period, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE);
|
|
||||||
|
|
||||||
//
|
|
||||||
ObjectsDeleteAll(0, Prefix);
|
|
||||||
return (INIT_SUCCEEDED);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Expert deinitialization function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
IndicatorRelease(atrHandler);
|
|
||||||
ObjectsDeleteAll(0, Prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Expert tick function |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
DetectOrderBlocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Detect Order Blocks with ATR Dynamic Threshold |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void DetectOrderBlocks()
|
|
||||||
{
|
|
||||||
double high, low, vpvrPrice, atr, dynamicThreshold;
|
|
||||||
datetime startTime, endTime;
|
|
||||||
bool isBullish, isBearish;
|
|
||||||
int bars = Bars(_Symbol, _Period);
|
|
||||||
|
|
||||||
for (int i = ConsolidationPeriod; i < bars; i++)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Get consolidation range
|
|
||||||
high = iHigh(_Symbol, _Period, iHighest(_Symbol, _Period, MODE_HIGH, ConsolidationPeriod, i));
|
|
||||||
low = iLow(_Symbol, _Period, iLowest(_Symbol, _Period, MODE_LOW, ConsolidationPeriod, i));
|
|
||||||
double range = high - low;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Calculate dynamic threshold using ATR
|
|
||||||
CopyBuffer(atrHandler, MAIN_LINE, i, 2, atrBuffer);
|
|
||||||
atr = atrBuffer[0];
|
|
||||||
dynamicThreshold = atr * AtrMultiplier;
|
|
||||||
|
|
||||||
// Check if consolidation range is within ATR-based threshold
|
|
||||||
if (range <= dynamicThreshold)
|
|
||||||
{
|
|
||||||
// VPVR Integration
|
|
||||||
vpvrPrice = CalculateVPVR(i, ConsolidationPeriod);
|
|
||||||
bool validVPVR = (vpvrPrice > low && vpvrPrice < high);
|
|
||||||
|
|
||||||
// Check breakout direction
|
|
||||||
isBullish = iClose(_Symbol, _Period, i - ConsolidationPeriod) > high;
|
|
||||||
isBearish = iClose(_Symbol, _Period, i - ConsolidationPeriod) < low;
|
|
||||||
|
|
||||||
// Trend Verification
|
|
||||||
ENUM_X_DIRECTION trend = CheckTrendStructure(TrendCheckPeriod);
|
|
||||||
|
|
||||||
// MACD/RSI Verification
|
|
||||||
bool macdValid = CheckMACD(trend);
|
|
||||||
bool rsiValid = CheckRSI(trend);
|
|
||||||
|
|
||||||
// Validate all conditions
|
|
||||||
if ((isBullish || isBearish) && validVPVR &&
|
|
||||||
(trend != -1) && macdValid && rsiValid)
|
|
||||||
{
|
|
||||||
double breakoutVolume = (double)iVolume(_Symbol, _Period, i - ConsolidationPeriod);
|
|
||||||
if (breakoutVolume < VolumeThreshold)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Define order block time window
|
|
||||||
startTime = iTime(_Symbol, _Period, i);
|
|
||||||
endTime = iTime(_Symbol, _Period, i + ConsolidationPeriod);
|
|
||||||
|
|
||||||
// Check retest (if required)
|
|
||||||
if (RequireRetest)
|
|
||||||
{
|
|
||||||
bool retestFound = false;
|
|
||||||
for (int j = i - ConsolidationPeriod; j > 0; j--)
|
|
||||||
{
|
|
||||||
if ((isBullish && iLow(_Symbol, _Period, j) <= low && iLow(_Symbol, _Period, j) >= high) ||
|
|
||||||
(isBearish && iHigh(_Symbol, _Period, j) >= high && iHigh(_Symbol, _Period, j) <= low))
|
|
||||||
{
|
|
||||||
retestFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!retestFound)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw order block with ATR annotation
|
|
||||||
string name = Prefix + IntegerToString(ObjectId++);
|
|
||||||
DrawOrderBlock(name, startTime, endTime, low, high,
|
|
||||||
isBullish ? clrGreen : clrRed, vpvrPrice, dynamicThreshold);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Trend Detection using Price Structure |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
ENUM_X_DIRECTION CheckTrendStructure(int period)
|
|
||||||
{
|
|
||||||
int currentStart = 1;
|
|
||||||
int previousStart = period + 1;
|
|
||||||
|
|
||||||
double currentHigh = iHigh(_Symbol, _Period, iHighest(_Symbol, _Period, MODE_HIGH, period, currentStart));
|
|
||||||
double previousHigh = iHigh(_Symbol, _Period, iHighest(_Symbol, _Period, MODE_HIGH, period, previousStart));
|
|
||||||
double currentLow = iLow(_Symbol, _Period, iLowest(_Symbol, _Period, MODE_LOW, period, currentStart));
|
|
||||||
double previousLow = iLow(_Symbol, _Period, iLowest(_Symbol, _Period, MODE_LOW, period, previousStart));
|
|
||||||
|
|
||||||
if (currentHigh > previousHigh && currentLow > previousLow)
|
|
||||||
return (X_DIRECTION_BULISH); // Uptrend
|
|
||||||
else if (currentHigh < previousHigh && currentLow < previousLow)
|
|
||||||
return (X_DIRECTION_BEARISH); // Downtrend
|
|
||||||
else
|
|
||||||
return (X_DIRECTION_NONE); // No clear trend
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| MACD Trend Verification |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool CheckMACD(ENUM_X_DIRECTION trend)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
CopyBuffer(macdHandler, MAIN_LINE, 0, 1, macdMainBuffer);
|
|
||||||
CopyBuffer(macdHandler, SIGNAL_LINE, 0, 1, macdSignalBuffer);
|
|
||||||
double macdMain = macdMainBuffer[0];
|
|
||||||
double macdSignal = macdSignalBuffer[0];
|
|
||||||
|
|
||||||
//
|
|
||||||
if (trend == X_DIRECTION_BULISH)
|
|
||||||
return (macdMain > macdSignal);
|
|
||||||
if (trend == X_DIRECTION_BEARISH)
|
|
||||||
return (macdMain < macdSignal);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| RSI Trend Verification |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
bool CheckRSI(ENUM_X_DIRECTION trend)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
CopyBuffer(rsiHandler, MAIN_LINE, 0, 1, rsiBuffer);
|
|
||||||
double rsiValue = rsiBuffer[0];
|
|
||||||
|
|
||||||
//
|
|
||||||
if (trend == X_DIRECTION_BULISH)
|
|
||||||
return (rsiValue > RSILevel);
|
|
||||||
if (trend == X_DIRECTION_BEARISH)
|
|
||||||
return (rsiValue < RSILevel);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Calculate VPVR High Volume Node |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
double CalculateVPVR(int startIdx, int period)
|
|
||||||
{
|
|
||||||
double maxVolume = 0;
|
|
||||||
double vpvrPrice = 0;
|
|
||||||
double price, volume;
|
|
||||||
|
|
||||||
for (int i = startIdx; i < startIdx + period; i++)
|
|
||||||
{
|
|
||||||
price = (iHigh(_Symbol, _Period, i) + iLow(_Symbol, _Period, i)) / 2;
|
|
||||||
volume = (double)iVolume(_Symbol, _Period, i);
|
|
||||||
if (volume > maxVolume)
|
|
||||||
{
|
|
||||||
maxVolume = volume;
|
|
||||||
vpvrPrice = price;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (vpvrPrice);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
//| Draw Order Block with ATR Annotation |
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
void DrawOrderBlock(string name, datetime startTime, datetime endTime,
|
|
||||||
double bottom, double top, color clr, double vpvrPrice, double atrThreshold)
|
|
||||||
{
|
|
||||||
// Draw rectangle
|
|
||||||
ObjectCreate(0, name + "_rect", OBJ_RECTANGLE, 0, startTime, top, endTime, bottom);
|
|
||||||
ObjectSetInteger(0, name + "_rect", OBJPROP_COLOR, clr);
|
|
||||||
ObjectSetInteger(0, name + "_rect", OBJPROP_FILL, true);
|
|
||||||
ObjectSetInteger(0, name + "_rect", OBJPROP_BACK, true);
|
|
||||||
ObjectSetInteger(0, name + "_rect", OBJPROP_WIDTH, 2);
|
|
||||||
|
|
||||||
// Draw VPVR marker
|
|
||||||
if (vpvrPrice > 0)
|
|
||||||
{
|
|
||||||
ObjectCreate(0, name + "_vpvr", OBJ_HLINE, 0, 0, vpvrPrice);
|
|
||||||
ObjectSetInteger(0, name + "_vpvr", OBJPROP_COLOR, clrYellow);
|
|
||||||
ObjectSetInteger(0, name + "_vpvr", OBJPROP_WIDTH, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add ATR threshold label
|
|
||||||
string atrLabel = StringFormat("ATR Threshold: %.5f", atrThreshold);
|
|
||||||
ObjectCreate(0, name + "_atr", OBJ_TEXT, 0, startTime, top);
|
|
||||||
ObjectSetString(0, name + "_atr", OBJPROP_TEXT, atrLabel);
|
|
||||||
ObjectSetInteger(0, name + "_atr", OBJPROP_COLOR, clrWhite);
|
|
||||||
}
|
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
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
Reference in New Issue
Block a user